From 830407e88f9d40d954356c3754f2647f91d5c06a Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 17:26:00 +0200 Subject: Adding upstream version 5.6.0. Signed-off-by: Daniel Baumann --- .clang-tidy | 11 + .dir-locals.el | 10 + .luacheckrc | 99 + .mailmap | 57 + AUTHORS | 85 + CONTRIBUTING.md | 19 + COPYING | 695 + CodingStyle | 5 + Dockerfile | 78 + NEWS | 1305 + README.md | 75 + bench/bench_lru.c | 242 + bench/bench_lru_set1.tsv | 65536 +++++++++++++++++++ bench/meson.build | 24 + ci/deckard_commit_check.sh | 13 + ci/fix-meson-junit.sh | 5 + ci/gh_actions.py | 58 + ci/images/README.md | 41 + ci/images/build.sh | 13 + ci/images/debian-11-coverity/Dockerfile | 43 + ci/images/debian-11/Dockerfile | 144 + ci/images/debian-buster/Dockerfile | 145 + ci/images/push.sh | 8 + ci/images/update.sh | 22 + ci/images/vars.sh | 13 + ci/no_assert_check.sh | 3 + ci/pkgtest.yaml | 300 + ci/respdiff/kresd.config | 26 + ci/respdiff/respdiff-tcp.conf | 52 + ci/respdiff/respdiff-tls.conf | 52 + ci/respdiff/respdiff-udp.conf | 52 + ci/respdiff/restart-bind.sh | 3 + ci/respdiff/restart-kresd.sh | 12 + ci/respdiff/restart-unbound.sh | 4 + ci/respdiff/run-respdiff-tests.sh | 27 + ci/respdiff/start-resolvers.sh | 13 + client/.packaging/test.sh | 5 + contrib/base32hex.c | 277 + contrib/base32hex.h | 60 + contrib/base32hex.spdx | 10 + contrib/base64.c | 260 + contrib/base64.h | 95 + contrib/base64.spdx | 10 + contrib/base64url.c | 287 + contrib/base64url.h | 103 + contrib/ccan/asprintf/LICENSE | 1 + contrib/ccan/asprintf/asprintf.c | 57 + contrib/ccan/asprintf/asprintf.h | 51 + contrib/ccan/asprintf/asprintf.spdx | 10 + contrib/ccan/compiler/LICENSE | 1 + contrib/ccan/compiler/compiler.h | 232 + contrib/ccan/compiler/compiler.spdx | 10 + contrib/ccan/json/LICENSE | 1 + contrib/ccan/json/json.c | 1362 + contrib/ccan/json/json.h | 99 + contrib/ccan/json/json.spdx | 10 + contrib/cleanup.h | 25 + contrib/config.h | 7 + contrib/dynarray.h | 112 + contrib/dynarray.spdx | 10 + contrib/licenses/BSD-MIT | 21 + contrib/licenses/CC0 | 32 + contrib/licenses/LGPL2 | 506 + contrib/mempattern.c | 151 + contrib/mempattern.h | 92 + contrib/meson.build | 28 + contrib/murmurhash3/LICENSE | 1 + contrib/murmurhash3/murmurhash3.c | 76 + contrib/murmurhash3/murmurhash3.h | 9 + contrib/murmurhash3/murmurhash3.spdx | 10 + contrib/ucw/LICENSE | 1 + contrib/ucw/alloc.h | 38 + contrib/ucw/config.h | 58 + contrib/ucw/lib.h | 125 + contrib/ucw/libucw.spdx | 10 + contrib/ucw/mempool-fmt.c | 99 + contrib/ucw/mempool.c | 601 + contrib/ucw/mempool.h | 572 + daemon/.packaging/centos/7/builddeps | 13 + daemon/.packaging/centos/7/pre-build.sh | 9 + daemon/.packaging/centos/7/pre-run.sh | 8 + daemon/.packaging/centos/7/rundeps | 6 + daemon/.packaging/centos/8/builddeps | 14 + daemon/.packaging/centos/8/pre-build.sh | 9 + daemon/.packaging/centos/8/pre-run.sh | 7 + daemon/.packaging/centos/8/rundeps | 6 + daemon/.packaging/debian/10/builddeps | 12 + daemon/.packaging/debian/10/pre-build.sh | 11 + daemon/.packaging/debian/10/pre-run.sh | 11 + daemon/.packaging/debian/10/rundeps | 15 + daemon/.packaging/debian/9/builddeps | 12 + daemon/.packaging/debian/9/pre-build.sh | 11 + daemon/.packaging/debian/9/pre-run.sh | 11 + daemon/.packaging/debian/9/rundeps | 15 + daemon/.packaging/fedora/31/builddeps | 14 + daemon/.packaging/fedora/31/pre-build.sh | 7 + daemon/.packaging/fedora/31/pre-run.sh | 6 + daemon/.packaging/fedora/31/rundeps | 7 + daemon/.packaging/fedora/32/builddeps | 14 + daemon/.packaging/fedora/32/pre-build.sh | 7 + daemon/.packaging/fedora/32/pre-run.sh | 6 + daemon/.packaging/fedora/32/rundeps | 7 + daemon/.packaging/leap/15.2/builddeps | 14 + daemon/.packaging/leap/15.2/pre-build.sh | 6 + daemon/.packaging/leap/15.2/pre-run.sh | 3 + daemon/.packaging/leap/15.2/rundeps | 4 + daemon/.packaging/leap/docker-image-name | 1 + daemon/.packaging/test.config | 2 + daemon/.packaging/ubuntu/16.04/builddeps | 16 + daemon/.packaging/ubuntu/16.04/pre-build.sh | 12 + daemon/.packaging/ubuntu/16.04/pre-run.sh | 12 + daemon/.packaging/ubuntu/16.04/rundeps | 15 + daemon/.packaging/ubuntu/18.04/builddeps | 16 + daemon/.packaging/ubuntu/18.04/pre-build.sh | 12 + daemon/.packaging/ubuntu/18.04/pre-run.sh | 12 + daemon/.packaging/ubuntu/18.04/rundeps | 15 + daemon/.packaging/ubuntu/20.04/builddeps | 16 + daemon/.packaging/ubuntu/20.04/pre-build.sh | 12 + daemon/.packaging/ubuntu/20.04/pre-run.sh | 12 + daemon/.packaging/ubuntu/20.04/rundeps | 15 + daemon/bindings/api.h | 12 + daemon/bindings/cache.c | 382 + daemon/bindings/cache.rst | 338 + daemon/bindings/event.c | 209 + daemon/bindings/event.rst | 139 + daemon/bindings/impl.c | 95 + daemon/bindings/impl.h | 90 + daemon/bindings/modules.c | 77 + daemon/bindings/modules.rst | 43 + daemon/bindings/net.c | 1260 + daemon/bindings/net_client.rst | 34 + daemon/bindings/net_dns_tweaks.rst | 35 + daemon/bindings/net_server.rst | 225 + daemon/bindings/net_tlssrv.rst | 188 + daemon/bindings/net_xdpsrv.rst | 140 + daemon/bindings/worker.c | 81 + daemon/bindings/worker.rst | 35 + daemon/cache.test/clear.test.lua | 215 + .../cache.test/insert_ns.test.integr/deckard.yaml | 14 + .../insert_ns.test.integr/kresd_config.j2 | 89 + .../insert_ns.test.integr/nondelegated_auth.rpl | 59 + daemon/cache.test/testroot.zone | 1257 + daemon/cache.test/testroot.zone.unsigned | 216 + daemon/engine.c | 892 + daemon/engine.h | 84 + daemon/ffimodule.c | 304 + daemon/ffimodule.h | 36 + daemon/http.c | 953 + daemon/http.h | 85 + daemon/io.c | 1169 + daemon/io.h | 80 + daemon/lua/controlsock.test.lua | 169 + daemon/lua/distro-preconfig.lua.in | 19 + daemon/lua/kluautil.lua | 94 + daemon/lua/kres-gen-30.lua | 638 + daemon/lua/kres-gen-31.lua | 647 + daemon/lua/kres-gen-32.lua | 648 + daemon/lua/kres-gen.sh | 353 + daemon/lua/kres.lua | 1143 + daemon/lua/krprint.lua | 340 + daemon/lua/krprint.test.lua | 292 + daemon/lua/log.test.lua | 42 + daemon/lua/map.test.integr/deckard.yaml | 38 + daemon/lua/map.test.integr/kresd_config.j2 | 193 + .../map.test.integr/query-while-map-is-running.rpl | 312 + daemon/lua/meson.build | 118 + daemon/lua/postconfig.lua | 70 + daemon/lua/sandbox.lua.in | 833 + daemon/lua/trust_anchors.lua.in | 532 + daemon/lua/trust_anchors.rst | 123 + daemon/lua/trust_anchors.test/bootstrap.test.lua | 112 + .../lua/trust_anchors.test/err_attr_extra_attr.xml | 16 + .../err_attr_validfrom_invalid.xml | 16 + .../err_attr_validfrom_missing.xml | 16 + daemon/lua/trust_anchors.test/err_elem_extra.xml | 17 + daemon/lua/trust_anchors.test/err_elem_missing.xml | 16 + daemon/lua/trust_anchors.test/err_multi_ta.xml | 19 + daemon/lua/trust_anchors.test/ok0_badtimes.xml | 16 + daemon/lua/trust_anchors.test/ok1.xml | 10 + daemon/lua/trust_anchors.test/ok1_expired1.xml | 16 + daemon/lua/trust_anchors.test/ok1_notyet1.xml | 16 + daemon/lua/trust_anchors.test/ok2.xml | 16 + daemon/lua/trust_anchors.test/regen.sh | 3 + daemon/lua/trust_anchors.test/root.keys | 1 + daemon/lua/trust_anchors.test/ta.test.lua | 85 + daemon/lua/trust_anchors.test/unsupp_nonroot.xml | 10 + daemon/lua/trust_anchors.test/unsupp_xml_v11.xml | 10 + daemon/lua/trust_anchors.test/webserv.lua | 236 + daemon/lua/trust_anchors.test/x509/ca-key.pem | 182 + daemon/lua/trust_anchors.test/x509/ca.pem | 24 + daemon/lua/trust_anchors.test/x509/ca.tmpl | 4 + daemon/lua/trust_anchors.test/x509/gen.sh | 13 + daemon/lua/trust_anchors.test/x509/server-key.pem | 182 + daemon/lua/trust_anchors.test/x509/server.pem | 27 + daemon/lua/trust_anchors.test/x509/server.tmpl | 7 + daemon/lua/trust_anchors.test/x509/wrongca-key.pem | 182 + daemon/lua/trust_anchors.test/x509/wrongca.pem | 24 + daemon/lua/trust_anchors.test/x509/wrongca.tmpl | 4 + daemon/lua/zonefile.lua | 93 + daemon/main.c | 613 + daemon/meson.build | 68 + daemon/network.c | 928 + daemon/network.h | 162 + daemon/proxyv2.c | 290 + daemon/proxyv2.h | 50 + daemon/proxyv2.test/deckard.yaml | 25 + daemon/proxyv2.test/dnsdist_config.j2 | 11 + daemon/proxyv2.test/kresd_config.j2 | 63 + daemon/proxyv2.test/proxyv2_valid.rpl | 72 + daemon/scripting.rst | 398 + daemon/session.c | 834 + daemon/session.h | 165 + daemon/tls.c | 1214 + daemon/tls.h | 235 + daemon/tls_ephemeral_credentials.c | 237 + daemon/tls_session_ticket-srv.c | 245 + daemon/udp_queue.c | 145 + daemon/udp_queue.h | 16 + daemon/worker.c | 2252 + daemon/worker.h | 195 + daemon/zimport.c | 741 + daemon/zimport.h | 48 + daemon/zimport.test/tz-rfc-a1-bad.zone | 14 + daemon/zimport.test/tz-rfc-a1.zone | 14 + daemon/zimport.test/tz-rfc-a2.zone | 35 + daemon/zimport.test/tz-rfc-a3.zone | 31 + daemon/zimport.test/tz-rfc-a4.zone | 37 + daemon/zimport.test/tz-rfc-a5.zone | 48 + daemon/zimport.test/zimport.test.lua | 47 + distro/config/apkg.toml | 12 + distro/pkg/arch/PKGBUILD | 71 + distro/pkg/deb/changelog | 6 + distro/pkg/deb/clean | 3 + distro/pkg/deb/compat | 1 + distro/pkg/deb/control | 140 + distro/pkg/deb/copyright | 440 + distro/pkg/deb/knot-resolver-doc.doc-base | 11 + distro/pkg/deb/knot-resolver-doc.docs | 1 + distro/pkg/deb/knot-resolver-doc.info | 2 + distro/pkg/deb/knot-resolver-doc.links | 2 + distro/pkg/deb/knot-resolver-module-dnstap.install | 1 + distro/pkg/deb/knot-resolver-module-http.install | 7 + distro/pkg/deb/knot-resolver-module-http.links | 5 + distro/pkg/deb/knot-resolver-module-http.preinst | 26 + distro/pkg/deb/knot-resolver.dirs | 2 + distro/pkg/deb/knot-resolver.docs | 4 + distro/pkg/deb/knot-resolver.install | 38 + distro/pkg/deb/knot-resolver.links | 2 + distro/pkg/deb/knot-resolver.manpages | 2 + distro/pkg/deb/knot-resolver.postinst | 38 + distro/pkg/deb/knot-resolver.postrm | 9 + distro/pkg/deb/knot-resolver.preinst | 26 + distro/pkg/deb/knot-resolver.triggers | 1 + distro/pkg/deb/not-installed | 7 + distro/pkg/deb/rules | 51 + distro/pkg/deb/source/format | 1 + distro/pkg/nix/default.nix | 126 + distro/pkg/nix/top-level.nix | 12 + distro/pkg/rpm/knot-resolver.spec | 384 + distro/tests/.ansible.cfg | 8 + distro/tests/README.md | 42 + .../ansible-roles/knot_resolver/defaults/main.yaml | 6 + .../knot_resolver/tasks/configure_dnstap.yaml | 10 + .../knot_resolver/tasks/configure_doh.yaml | 10 + .../knot_resolver/tasks/configure_doh2.yaml | 8 + .../ansible-roles/knot_resolver/tasks/main.yaml | 71 + .../knot_resolver/tasks/restart_kresd.yaml | 16 + .../knot_resolver/tasks/test_dnssec.yaml | 15 + .../knot_resolver/tasks/test_doh.yaml | 9 + .../knot_resolver/tasks/test_doh2.yaml | 24 + .../knot_resolver/tasks/test_kres_cache_gc.yaml | 4 + .../knot_resolver/tasks/test_tcp.yaml | 8 + .../knot_resolver/tasks/test_tls.yaml | 8 + .../knot_resolver/tasks/test_udp.yaml | 8 + .../ansible-roles/knot_resolver/vars/CentOS.yaml | 6 + .../ansible-roles/knot_resolver/vars/Debian.yaml | 6 + .../ansible-roles/knot_resolver/vars/Fedora.yaml | 6 + .../ansible-roles/knot_resolver/vars/Rocky.yaml | 6 + .../ansible-roles/knot_resolver/vars/Ubuntu.yaml | 6 + .../knot_resolver/vars/openSUSE_Leap.yaml | 6 + .../knot_resolver/vars/openSUSE_Tumbleweed.yaml | 7 + .../ansible-roles/obs_repos/defaults/main.yaml | 4 + .../ansible-roles/obs_repos/tasks/CentOS.yaml | 18 + .../ansible-roles/obs_repos/tasks/Debian.yaml | 15 + .../ansible-roles/obs_repos/tasks/Fedora.yaml | 8 + .../tests/ansible-roles/obs_repos/tasks/Rocky.yaml | 13 + .../ansible-roles/obs_repos/tasks/Ubuntu.yaml | 14 + .../tests/ansible-roles/obs_repos/tasks/main.yaml | 12 + .../obs_repos/tasks/openSUSE_Leap.yaml | 19 + .../obs_repos/tasks/openSUSE_Tumbleweed.yaml | 13 + .../tests/ansible-roles/obs_repos/vars/CentOS.yaml | 3 + .../ansible-roles/obs_repos/vars/Debian_10.yaml | 3 + .../ansible-roles/obs_repos/vars/Debian_11.yaml | 1 + .../ansible-roles/obs_repos/vars/Debian_9.yaml | 3 + .../tests/ansible-roles/obs_repos/vars/Fedora.yaml | 3 + .../tests/ansible-roles/obs_repos/vars/Rocky.yaml | 3 + .../tests/ansible-roles/obs_repos/vars/Ubuntu.yaml | 3 + .../obs_repos/vars/openSUSE_Leap.yaml | 3 + .../obs_repos/vars/openSUSE_Tumbleweed.yaml | 3 + distro/tests/centos7/Vagrantfile | 30 + distro/tests/centos7/ansible.cfg | 1 + distro/tests/debian10/Vagrantfile | 28 + distro/tests/debian10/ansible.cfg | 1 + distro/tests/debian11/Vagrantfile | 27 + distro/tests/debian11/ansible.cfg | 1 + distro/tests/debian9/Vagrantfile | 27 + distro/tests/debian9/ansible.cfg | 1 + distro/tests/fedora35/Vagrantfile | 30 + distro/tests/fedora35/ansible.cfg | 1 + distro/tests/fedora36/Vagrantfile | 30 + distro/tests/fedora36/ansible.cfg | 1 + distro/tests/knot-resolver-pkgtest.yaml | 13 + distro/tests/leap15/Vagrantfile | 29 + distro/tests/leap15/ansible.cfg | 1 + distro/tests/repos.yaml | 4 + distro/tests/rocky8/Vagrantfile | 30 + distro/tests/rocky8/ansible.cfg | 1 + distro/tests/test-distro.sh | 26 + distro/tests/ubuntu1804/Vagrantfile | 30 + distro/tests/ubuntu1804/ansible.cfg | 1 + distro/tests/ubuntu2004/Vagrantfile | 30 + distro/tests/ubuntu2004/ansible.cfg | 1 + distro/tests/ubuntu2204/Vagrantfile | 30 + distro/tests/ubuntu2204/ansible.cfg | 1 + doc/.packaging/centos/7/NOTSUPPORTED | 0 doc/.packaging/centos/8/NOTSUPPORTED | 0 doc/.packaging/debian/10/build.sh | 19 + doc/.packaging/debian/10/builddeps | 4 + doc/.packaging/debian/10/install.sh | 3 + doc/.packaging/debian/9/build.sh | 19 + doc/.packaging/debian/9/builddeps | 4 + doc/.packaging/debian/9/install.sh | 3 + doc/.packaging/fedora/31/build.sh | 20 + doc/.packaging/fedora/31/builddeps | 4 + doc/.packaging/fedora/31/install.sh | 3 + doc/.packaging/fedora/32/30/build.sh | 20 + doc/.packaging/fedora/32/30/builddeps | 4 + doc/.packaging/fedora/32/30/install.sh | 3 + doc/.packaging/fedora/32/build.sh | 20 + doc/.packaging/fedora/32/builddeps | 4 + doc/.packaging/fedora/32/install.sh | 3 + doc/.packaging/leap/15.2/build.sh | 20 + doc/.packaging/leap/15.2/builddeps | 4 + doc/.packaging/leap/15.2/install.sh | 3 + doc/.packaging/test.sh | 3 + doc/.packaging/ubuntu/16.04/build.sh | 19 + doc/.packaging/ubuntu/16.04/builddeps | 4 + doc/.packaging/ubuntu/16.04/install.sh | 3 + doc/.packaging/ubuntu/18.04/build.sh | 19 + doc/.packaging/ubuntu/18.04/builddeps | 4 + doc/.packaging/ubuntu/18.04/install.sh | 3 + doc/.packaging/ubuntu/20.04/build.sh | 19 + doc/.packaging/ubuntu/20.04/builddeps | 4 + doc/.packaging/ubuntu/20.04/install.sh | 3 + doc/Doxyfile | 23 + doc/NEWS.rst | 36 + doc/README.md | 27 + doc/_static/.gitignore | 0 doc/_static/css/custom.css | 6 + doc/_static/logo-negativ.svg | 40 + doc/build.rst | 291 + doc/conf.py | 95 + doc/config-answer-reordering.rst | 17 + doc/config-debugging.rst | 35 + doc/config-dnssec.rst | 17 + doc/config-experimental.rst | 14 + doc/config-logging-header.rst | 9 + doc/config-logging-monitoring.rst | 101 + doc/config-network-forwarding.rst | 38 + doc/config-network.rst | 64 + doc/config-no-systemd-privileges.rst | 65 + doc/config-no-systemd-processes.rst | 25 + doc/config-no-systemd.rst | 37 + doc/config-overview.rst | 98 + doc/config-performance.rst | 36 + doc/config-policy.rst | 41 + doc/daemon-bindings-cache.rst | 1 + doc/daemon-bindings-net_client.rst | 1 + doc/daemon-bindings-net_dns_tweaks.rst | 1 + doc/daemon-bindings-net_server.rst | 1 + doc/daemon-bindings-net_tlssrv.rst | 1 + doc/daemon-bindings-net_xdpsrv.rst | 1 + doc/daemon-bindings-worker.rst | 1 + doc/daemon-scripting.rst | 1 + doc/flowcharts/io_and_worker.dia | Bin 0 -> 13771 bytes doc/flowcharts/task_ERD.dia | Bin 0 -> 2700 bytes doc/flowcharts/tcp_task.dia | Bin 0 -> 10812 bytes doc/flowcharts/udp_task.dia | Bin 0 -> 4316 bytes doc/index.rst | 63 + doc/kresd.8.in | 122 + doc/lib.rst | 70 + doc/meson.build | 79 + doc/modules-bogus_log.rst | 1 + doc/modules-daf.rst | 1 + doc/modules-detect_time_jump.rst | 1 + doc/modules-detect_time_skew.rst | 1 + doc/modules-dns64.rst | 1 + doc/modules-dnstap.rst | 1 + doc/modules-edns_keepalive.rst | 1 + doc/modules-experimental_dot_auth.rst | 1 + doc/modules-hints.rst | 1 + doc/modules-http-custom-services.rst | 1 + doc/modules-http-trace.rst | 1 + doc/modules-http.rst | 1 + doc/modules-nsid.rst | 1 + doc/modules-policy.rst | 1 + doc/modules-predict.rst | 1 + doc/modules-prefill.rst | 1 + doc/modules-priming.rst | 1 + doc/modules-rebinding.rst | 1 + doc/modules-refuse_nord.rst | 1 + doc/modules-renumber.rst | 1 + doc/modules-rfc7706.rst | 1 + doc/modules-serve_stale.rst | 1 + doc/modules-stats.rst | 1 + doc/modules-ta_sentinel.rst | 1 + doc/modules-ta_signal_query.rst | 1 + doc/modules-view.rst | 1 + doc/modules-watchdog.rst | 1 + doc/modules_api.rst | 6 + doc/quickstart-config.rst | 209 + doc/quickstart-install.rst | 73 + doc/quickstart-startup.rst | 47 + doc/requirements.txt | 2 + doc/resolution.png | Bin 0 -> 95991 bytes doc/server_terminology.fodg | 869 + doc/server_terminology.svg | 1106 + doc/systemd-multiinst.rst | 1 + doc/upgrading.rst | 332 + doc/worker_api.rst | 7 + etc/config/config.cluster | 36 + etc/config/config.docker | 97 + etc/config/config.internal | 18 + etc/config/config.isp | 64 + etc/config/config.personal | 21 + etc/config/config.privacy | 36 + etc/config/config.splitview | 30 + etc/config/meson.build | 35 + etc/icann-ca.pem | 82 + etc/meson.build | 37 + etc/root.hints | 92 + etc/root.keys | 1 + lib/README.rst | 313 + lib/cache/README.rst | 69 + lib/cache/api.c | 1029 + lib/cache/api.h | 194 + lib/cache/cdb_api.h | 97 + lib/cache/cdb_lmdb.c | 868 + lib/cache/cdb_lmdb.h | 16 + lib/cache/entry_list.c | 301 + lib/cache/entry_pkt.c | 206 + lib/cache/entry_rr.c | 115 + lib/cache/impl.h | 439 + lib/cache/knot_pkt.c | 94 + lib/cache/nsec1.c | 488 + lib/cache/nsec3.c | 481 + lib/cache/overflow.test.integr/deckard.yaml | 22 + lib/cache/overflow.test.integr/kresd_config.j2 | 91 + .../overflow.test.integr/world_cz_vutbr_www.rpl | 298 + lib/cache/peek.c | 774 + lib/cache/test.integr/cache_minimal_nsec3.rpl | 4120 ++ lib/cache/test.integr/deckard.yaml | 13 + lib/cache/test.integr/kresd_config.j2 | 69 + lib/cache/util.h | 4 + lib/cookies/alg_containers.c | 59 + lib/cookies/alg_containers.h | 37 + lib/cookies/alg_sha.c | 110 + lib/cookies/alg_sha.h | 18 + lib/cookies/control.h | 37 + lib/cookies/helper.c | 268 + lib/cookies/helper.h | 74 + lib/cookies/lru_cache.c | 58 + lib/cookies/lru_cache.h | 57 + lib/cookies/nonce.c | 20 + lib/cookies/nonce.h | 31 + lib/defines.h | 106 + lib/dnssec.c | 601 + lib/dnssec.h | 191 + lib/dnssec/nsec.c | 315 + lib/dnssec/nsec.h | 69 + lib/dnssec/nsec3.c | 722 + lib/dnssec/nsec3.h | 83 + lib/dnssec/signature.c | 304 + lib/dnssec/signature.h | 29 + lib/dnssec/ta.c | 154 + lib/dnssec/ta.h | 61 + lib/generic/README.rst | 48 + lib/generic/array.h | 157 + lib/generic/lru.c | 249 + lib/generic/lru.h | 240 + lib/generic/pack.h | 221 + lib/generic/queue.c | 140 + lib/generic/queue.h | 230 + lib/generic/test_array.c | 99 + lib/generic/test_lru.c | 111 + lib/generic/test_pack.c | 68 + lib/generic/test_queue.c | 71 + lib/generic/test_trie.c | 154 + lib/generic/trie.c | 923 + lib/generic/trie.h | 150 + lib/generic/trie.spdx | 10 + lib/layer.h | 107 + lib/layer/cache.c | 20 + lib/layer/iterate.c | 1235 + lib/layer/iterate.h | 25 + lib/layer/mode.rst | 26 + lib/layer/test.integr/deckard.yaml | 13 + lib/layer/test.integr/iter_cname_length.rpl | 226 + lib/layer/test.integr/iter_limit_bad_glueless.rpl | 220 + lib/layer/test.integr/iter_limit_refuse.rpl | 150 + lib/layer/test.integr/kresd_config.j2 | 107 + lib/layer/validate.c | 1366 + lib/layer/validate.test.integr/deckard.yaml | 10 + .../fwd_insecure_but_rrsig_signer_invalid.rpl | 294 + lib/layer/validate.test.integr/kresd_config.j2 | 52 + lib/log.c | 328 + lib/log.h | 278 + lib/meson.build | 121 + lib/module.c | 148 + lib/module.h | 112 + lib/resolve.c | 1695 + lib/resolve.h | 420 + lib/rplan.c | 291 + lib/rplan.h | 221 + lib/selection.c | 795 + lib/selection.h | 269 + lib/selection_forward.c | 136 + lib/selection_forward.h | 17 + lib/selection_iter.c | 378 + lib/selection_iter.h | 14 + lib/test_module.c | 39 + lib/test_rplan.c | 75 + lib/test_utils.c | 147 + lib/test_zonecut.c | 58 + lib/utils.c | 1393 + lib/utils.h | 608 + lib/zonecut.c | 590 + lib/zonecut.h | 164 + meson.build | 357 + meson_options.txt | 219 + modules/README.rst | 251 + modules/bogus_log/.packaging/test.config | 4 + modules/bogus_log/README.rst | 45 + modules/bogus_log/bogus_log.c | 135 + modules/bogus_log/meson.build | 21 + modules/bogus_log/test.integr/deckard.yaml | 13 + modules/bogus_log/test.integr/kresd_config.j2 | 90 + .../test.integr/val_minimal_expiredsignature.rpl | 125 + modules/cookies/README.rst | 56 + modules/cookies/cookiectl.c | 689 + modules/cookies/cookiectl.h | 35 + modules/cookies/cookiemonster.c | 464 + modules/cookies/cookiemonster.h | 15 + modules/cookies/cookies.c | 78 + modules/daf/.packaging/test.config | 4 + modules/daf/README.rst | 146 + modules/daf/daf.js | 295 + modules/daf/daf.lua | 392 + modules/daf/daf.test.lua | 80 + modules/daf/daf_http.test.lua | 216 + modules/daf/meson.build | 21 + modules/daf/test.integr/deckard.yaml | 12 + modules/daf/test.integr/kresd_config.j2 | 65 + modules/daf/test.integr/module_daf.rpl | 30 + modules/detect_time_jump/.packaging/test.config | 4 + modules/detect_time_jump/README.rst | 22 + modules/detect_time_jump/detect_time_jump.lua | 45 + modules/detect_time_skew/.packaging/test.config | 4 + modules/detect_time_skew/README.rst | 23 + modules/detect_time_skew/detect_time_skew.lua | 83 + modules/dns64/.packaging/test.config | 4 + modules/dns64/README.rst | 62 + modules/dns64/dns64.lua | 220 + modules/dns64/dns64.test.lua | 53 + modules/dnstap/.packaging/centos/7/builddeps | 3 + modules/dnstap/.packaging/centos/7/rundeps | 2 + modules/dnstap/.packaging/centos/8/builddeps | 3 + modules/dnstap/.packaging/centos/8/rundeps | 2 + modules/dnstap/.packaging/debian/10/builddeps | 3 + modules/dnstap/.packaging/debian/10/rundeps | 2 + modules/dnstap/.packaging/debian/9/builddeps | 3 + modules/dnstap/.packaging/debian/9/rundeps | 2 + modules/dnstap/.packaging/fedora/31/builddeps | 3 + modules/dnstap/.packaging/fedora/31/rundeps | 2 + modules/dnstap/.packaging/fedora/32/builddeps | 3 + modules/dnstap/.packaging/fedora/32/rundeps | 2 + modules/dnstap/.packaging/leap/15.2/builddeps | 3 + modules/dnstap/.packaging/leap/15.2/rundeps | 2 + modules/dnstap/.packaging/test.config | 4 + modules/dnstap/.packaging/ubuntu/16.04/builddeps | 3 + modules/dnstap/.packaging/ubuntu/16.04/rundeps | 2 + modules/dnstap/.packaging/ubuntu/18.04/builddeps | 3 + modules/dnstap/.packaging/ubuntu/18.04/rundeps | 2 + modules/dnstap/.packaging/ubuntu/20.04/builddeps | 3 + modules/dnstap/.packaging/ubuntu/20.04/rundeps | 2 + modules/dnstap/README.rst | 42 + modules/dnstap/dnstap.c | 524 + modules/dnstap/dnstap.proto | 273 + modules/dnstap/meson.build | 57 + modules/edns_keepalive/.packaging/test.config | 10 + modules/edns_keepalive/README.rst | 22 + modules/edns_keepalive/edns_keepalive.c | 61 + modules/edns_keepalive/meson.build | 17 + modules/etcd/.packaging/centos/7/pre-test.sh | 1 + modules/etcd/.packaging/centos/7/rundeps | 6 + modules/etcd/.packaging/centos/8/NOTSUPPORTED | 0 modules/etcd/.packaging/debian/10/pre-test.sh | 1 + modules/etcd/.packaging/debian/10/rundeps | 4 + modules/etcd/.packaging/debian/9/pre-test.sh | 1 + modules/etcd/.packaging/debian/9/rundeps | 4 + modules/etcd/.packaging/fedora/31/NOTSUPPORTED | 16 + modules/etcd/.packaging/fedora/32/NOTSUPPORTED | 16 + modules/etcd/.packaging/leap/15.2/pre-test.sh | 1 + modules/etcd/.packaging/leap/15.2/rundeps | 6 + modules/etcd/.packaging/test.config | 4 + modules/etcd/.packaging/ubuntu/16.04/pre-test.sh | 1 + modules/etcd/.packaging/ubuntu/16.04/rundeps | 3 + modules/etcd/.packaging/ubuntu/18.04/pre-test.sh | 1 + modules/etcd/.packaging/ubuntu/18.04/rundeps | 3 + modules/etcd/.packaging/ubuntu/20.04/pre-test.sh | 1 + modules/etcd/.packaging/ubuntu/20.04/rundeps | 4 + modules/etcd/README.rst | 46 + modules/etcd/etcd.lua | 56 + .../.packaging/centos/7/rundeps | 1 + .../.packaging/centos/8/rundeps | 1 + .../.packaging/debian/10/rundeps | 1 + .../.packaging/debian/9/rundeps | 1 + .../.packaging/fedora/31/rundeps | 1 + .../.packaging/fedora/32/rundeps | 1 + .../.packaging/leap/15.2/NOTSUPPORTED | 6 + .../.packaging/leap/15.2/pre-test.sh | 1 + .../.packaging/leap/15.2/rundeps | 4 + .../experimental_dot_auth/.packaging/test.config | 4 + .../.packaging/ubuntu/16.04/NOTSUPPORTED | 0 .../.packaging/ubuntu/18.04/rundeps | 1 + .../.packaging/ubuntu/20.04/rundeps | 1 + modules/experimental_dot_auth/README.rst | 91 + .../experimental_dot_auth.lua | 122 + modules/experimental_dot_auth/meson.build | 13 + modules/extended_error/extended_error.c | 47 + modules/extended_error/meson.build | 20 + modules/graphite/.packaging/centos/7/rundeps | 1 + modules/graphite/.packaging/centos/8/rundeps | 1 + modules/graphite/.packaging/debian/10/rundeps | 1 + modules/graphite/.packaging/debian/9/rundeps | 1 + modules/graphite/.packaging/fedora/31/rundeps | 1 + modules/graphite/.packaging/fedora/32/rundeps | 1 + modules/graphite/.packaging/leap/15.2/NOTSUPPORTED | 6 + modules/graphite/.packaging/leap/15.2/pre-test.sh | 1 + modules/graphite/.packaging/leap/15.2/rundeps | 6 + modules/graphite/.packaging/test.config | 4 + modules/graphite/.packaging/ubuntu/16.04/rundeps | 1 + modules/graphite/.packaging/ubuntu/18.04/rundeps | 1 + modules/graphite/.packaging/ubuntu/20.04/rundeps | 1 + modules/graphite/README.rst | 49 + modules/graphite/graphite.lua | 146 + modules/hints/.packaging/test.config | 4 + modules/hints/README.rst | 145 + modules/hints/hints.c | 677 + modules/hints/meson.build | 24 + modules/hints/tests/hints.test.hosts | 1 + modules/hints/tests/hints.test.lua | 64 + modules/hints/tests/hints_test.zone | 2 + modules/http/.packaging/centos/7/rundeps | 1 + modules/http/.packaging/centos/8/rundeps | 1 + modules/http/.packaging/debian/10/rundeps | 1 + modules/http/.packaging/debian/9/rundeps | 1 + modules/http/.packaging/fedora/31/rundeps | 1 + modules/http/.packaging/fedora/32/rundeps | 1 + modules/http/.packaging/leap/15.2/NOTSUPPORTED | 5 + modules/http/.packaging/leap/15.2/pre-test.sh | 1 + modules/http/.packaging/leap/15.2/rundeps | 7 + modules/http/.packaging/test.config | 4 + modules/http/.packaging/ubuntu/16.04/NOTSUPPORTED | 0 modules/http/.packaging/ubuntu/18.04/rundeps | 1 + modules/http/.packaging/ubuntu/20.04/rundeps | 1 + modules/http/README.rst | 188 + modules/http/custom_services.rst | 145 + modules/http/debug_opensslkeylog.c | 369 + modules/http/http.lua.in | 418 + modules/http/http.test.lua | 128 + modules/http/http_doh.lua | 116 + modules/http/http_doh.test.lua | 419 + modules/http/http_tls_cert.lua | 186 + modules/http/http_trace.lua | 77 + modules/http/meson.build | 61 + modules/http/prometheus.lua | 178 + modules/http/prometheus.rst | 45 + modules/http/static/bootstrap-theme.min.css | 6 + modules/http/static/bootstrap-theme.min.css.spdx | 11 + modules/http/static/bootstrap.min.css | 11 + modules/http/static/bootstrap.min.css.spdx | 11 + modules/http/static/bootstrap.min.js | 7 + modules/http/static/bootstrap.min.js.spdx | 11 + modules/http/static/d3.js | 6 + modules/http/static/d3.spdx | 12 + modules/http/static/datamaps.world.min.js | 3 + modules/http/static/datamaps.world.min.spdx | 11 + modules/http/static/dygraph.min.js | 7 + modules/http/static/dygraph.min.js.spdx | 12 + modules/http/static/epoch.css | 2 + modules/http/static/epoch.js | 4 + modules/http/static/epoch.spdx | 11 + modules/http/static/favicon.ico | Bin 0 -> 1545 bytes .../http/static/glyphicons-halflings-regular.spdx | 11 + .../http/static/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes modules/http/static/jquery.js | 5 + modules/http/static/jquery.spdx | 12 + modules/http/static/kresd.css | 44 + modules/http/static/kresd.js | 367 + modules/http/static/main.tpl | 87 + modules/http/static/selectize.bootstrap3.css | 418 + modules/http/static/selectize.min.js | 4 + modules/http/static/selectize.spdx | 11 + modules/http/static/topojson.js | 2 + modules/http/static/topojson.spdx | 12 + modules/http/test_tls/broken.crt | 3 + modules/http/test_tls/broken.key | Bin 0 -> 512 bytes modules/http/test_tls/ca.crt | 20 + modules/http/test_tls/chain.crt | 41 + modules/http/test_tls/test.crt | 20 + modules/http/test_tls/test.key | 27 + modules/http/test_tls/tls.test.lua | 193 + modules/http/trace.rst | 43 + modules/meson.build | 59 + modules/nsid/.packaging/test.config | 4 + modules/nsid/README.rst | 35 + modules/nsid/meson.build | 24 + modules/nsid/nsid.c | 114 + modules/nsid/nsid.test.lua | 22 + modules/policy/.packaging/test.config | 4 + modules/policy/README.rst | 774 + modules/policy/lua-aho-corasick/LICENSE | 28 + modules/policy/lua-aho-corasick/Makefile | 134 + modules/policy/lua-aho-corasick/README.md | 40 + modules/policy/lua-aho-corasick/ac.cxx | 101 + modules/policy/lua-aho-corasick/ac.h | 49 + modules/policy/lua-aho-corasick/ac_fast.cxx | 468 + modules/policy/lua-aho-corasick/ac_fast.hpp | 124 + modules/policy/lua-aho-corasick/ac_lua.cxx | 173 + modules/policy/lua-aho-corasick/ac_slow.cxx | 318 + modules/policy/lua-aho-corasick/ac_slow.hpp | 158 + modules/policy/lua-aho-corasick/ac_util.hpp | 69 + modules/policy/lua-aho-corasick/load_ac.lua | 90 + modules/policy/lua-aho-corasick/mytest.cxx | 200 + modules/policy/lua-aho-corasick/tests/Makefile | 65 + modules/policy/lua-aho-corasick/tests/ac_bench.cxx | 519 + .../policy/lua-aho-corasick/tests/ac_test_aggr.cxx | 135 + .../lua-aho-corasick/tests/ac_test_simple.cxx | 275 + .../policy/lua-aho-corasick/tests/dict/README.txt | 1 + .../policy/lua-aho-corasick/tests/dict/dict1.txt | 11 + .../policy/lua-aho-corasick/tests/load_ac_test.lua | 82 + modules/policy/lua-aho-corasick/tests/lua_test.lua | 67 + .../policy/lua-aho-corasick/tests/test_base.hpp | 60 + .../policy/lua-aho-corasick/tests/test_bigfile.cxx | 167 + .../policy/lua-aho-corasick/tests/test_main.cxx | 33 + modules/policy/meson.build | 50 + modules/policy/noipv6.test.integr/broken-ipv6.rpl | 47 + modules/policy/noipv6.test.integr/deckard.yaml | 12 + modules/policy/noipv6.test.integr/kresd_config.j2 | 59 + modules/policy/noipvx.test.integr/broken-ipvx.rpl | 35 + modules/policy/noipvx.test.integr/deckard.yaml | 12 + modules/policy/noipvx.test.integr/kresd_config.j2 | 60 + modules/policy/policy.lua | 1109 + modules/policy/policy.rpz.test.lua | 65 + modules/policy/policy.slice.test.lua | 109 + modules/policy/policy.test.lua | 145 + modules/policy/policy.test.rpz | 18 + modules/policy/policy.test.rpz.soa | 5 + modules/policy/test.integr/deckard.yaml | 12 + modules/policy/test.integr/kresd_config.j2 | 59 + modules/policy/test.integr/refuse.rpl | 44 + modules/predict/.packaging/test.config | 4 + modules/predict/README.rst | 67 + modules/predict/predict.lua | 189 + modules/predict/predict.test.lua | 61 + modules/prefill/.packaging/test.config | 4 + modules/prefill/README.rst | 43 + modules/prefill/prefill.lua | 199 + modules/prefill/prefill.test/empty.zone | 0 modules/prefill/prefill.test/example.com.zone | 12 + modules/prefill/prefill.test/prefill.test.lua | 123 + modules/prefill/prefill.test/random.zone | 2 + modules/prefill/prefill.test/testroot.zone | 59 + .../prefill/prefill.test/testroot.zone.unsigned | 4 + modules/prefill/prefill.test/testroot_no_soa.zone | 52 + modules/priming/.packaging/test.config | 4 + modules/priming/README.rst | 18 + modules/priming/priming.lua | 130 + modules/rebinding/.packaging/test.config | 4 + modules/rebinding/README.rst | 29 + modules/rebinding/rebinding.lua | 115 + modules/rebinding/test.integr/deckard.yaml | 12 + modules/rebinding/test.integr/kresd_config.j2 | 59 + modules/rebinding/test.integr/module_rebinding.rpl | 834 + modules/refuse_nord/.packaging/test.config | 3 + modules/refuse_nord/README.rst | 16 + modules/refuse_nord/meson.build | 21 + modules/refuse_nord/refuse_nord.c | 38 + modules/refuse_nord/test.integr/deckard.yaml | 12 + modules/refuse_nord/test.integr/kresd_config.j2 | 56 + modules/refuse_nord/test.integr/refuse_nord.rpl | 24 + modules/renumber/.packaging/test.config | 4 + modules/renumber/README.rst | 36 + modules/renumber/renumber.lua | 181 + modules/renumber/renumber.test.lua | 103 + modules/rfc7706.rst | 12 + modules/serve_stale/.packaging/test.config | 4 + modules/serve_stale/README.rst | 23 + modules/serve_stale/serve_stale.lua | 42 + modules/serve_stale/test.integr/deckard.yaml | 12 + modules/serve_stale/test.integr/kresd_config.j2 | 70 + .../serve_stale/test.integr/module_serve_stale.rpl | 280 + modules/stats/.packaging/test.config | 4 + modules/stats/README.rst | 211 + modules/stats/meson.build | 25 + modules/stats/stats.c | 534 + modules/stats/test.integr/deckard.yaml | 12 + modules/stats/test.integr/kresd_config.j2 | 114 + modules/stats/test.integr/stats.rpl | 194 + modules/ta_sentinel/.packaging/test.config | 4 + modules/ta_sentinel/README.rst | 18 + modules/ta_sentinel/ta_sentinel.lua | 80 + modules/ta_signal_query/.packaging/test.config | 4 + modules/ta_signal_query/README.rst | 31 + modules/ta_signal_query/ta_signal_query.lua | 64 + modules/ta_update/.packaging/test.config | 4 + modules/ta_update/meson.build | 21 + modules/ta_update/root.keys | 1 + modules/ta_update/ta_update.lua | 349 + .../ta_update/ta_update.test.integr/deckard.yaml | 12 + .../ta_update.test.integr/kresd_config.j2 | 56 + .../rfc5011-monotonictime.rpl | 5755 ++ .../ta_update/ta_update.test.integr/rfc5011/README | 13 + .../ta_update.test.integr/rfc5011/dns2rpl.py | 222 + .../ta_update.test.integr/rfc5011/empty.rpl | 20 + .../ta_update.test.integr/rfc5011/genkeyszones.sh | 174 + .../ta_update.test.integr/rfc5011/knot.root.conf | 26 + .../ta_update.test.integr/rfc5011/pydnstest | 1 + .../rfc5011/unsigned_check.db | 8 + .../ta_update.test.integr/rfc5011/unsigned_ok.db | 8 + .../rfc5011_unsupported_key_rollover.rpl | 91 + modules/ta_update/ta_update.test.lua | 84 + .../deckard.yaml | 12 + .../kresd_config.j2 | 72 + .../ta_update.unmanagedkey.test.integr/rfc5011 | 1 + .../unmanagedkey-missing-monotonictime.rpl | 758 + .../unmanagedkey-present-monotonictime.rpl | 757 + .../unmanagedkey-revoke-monotonictime.rpl | 762 + modules/view/.packaging/test.config | 4 + modules/view/README.rst | 92 + modules/view/addr.test.integr/deckard.yaml | 12 + modules/view/addr.test.integr/kresd_config.j2 | 62 + modules/view/addr.test.integr/module_view_addr.rpl | 79 + modules/view/meson.build | 11 + modules/view/tsig.test.integr/deckard.yaml | 12 + modules/view/tsig.test.integr/kresd_config.j2 | 64 + modules/view/tsig.test.integr/module_view_tsig.rpl | 114 + modules/view/view.lua | 121 + modules/watchdog/.packaging/test.config | 4 + modules/watchdog/README.rst | 43 + modules/watchdog/watchdog.lua | 129 + modules/workarounds/.packaging/test.config | 4 + modules/workarounds/README.rst | 11 + modules/workarounds/workarounds.lua | 23 + scripts/bench.sh | 12 + scripts/bugreport-journals.py | 194 + scripts/build-in-obs.sh | 32 + scripts/coverage_c_combine.sh | 26 + scripts/coverage_env.sh | 42 + scripts/doh_b64encode_query.py | 26 + scripts/gen-cdefs.sh | 82 + scripts/gen-pgp-keyblock.sh | 38 + scripts/get-date.sh | 14 + scripts/kresd-host.lua | 115 + scripts/kresd-query.lua | 63 + scripts/kresd.apparmor | 29 + scripts/luacov_gen_empty.sh | 18 + scripts/luacov_to_info.lua | 57 + scripts/make-archive.sh | 38 + scripts/make-doc.sh | 42 + scripts/make-obs.sh | 59 + scripts/map_install_src.lua | 168 + scripts/run-pylint.sh | 12 + scripts/run-scanbuild-with-args.sh | 51 + scripts/test-config.sh | 32 + scripts/test-integration-prepare.sh | 8 + scripts/update-authors.sh | 41 + scripts/update-root-hints.sh | 28 + security.txt | 9 + systemd/README.rst | 11 + systemd/kres-cache-gc.service.in | 19 + systemd/kresd.systemd.7.in | 100 + systemd/kresd.target | 9 + systemd/kresd@.service.in | 30 + systemd/meson.build | 66 + systemd/multiinst.rst | 99 + systemd/sysusers.d/knot-resolver.conf.in | 5 + systemd/tmpfiles.d/knot-resolver.conf.in | 6 + tests/.gitignore | 6 + tests/README.rst | 94 + tests/config/basic.test.lua | 211 + tests/config/cache.test.lua | 67 + tests/config/doh2.test.lua | 524 + tests/config/lru.test.lua | 84 + tests/config/meson.build | 41 + tests/config/net.test.lua | 67 + tests/config/tapered/.travis.yml | 40 + tests/config/tapered/.travis/platform.sh | 15 + tests/config/tapered/.travis/setenv_lua.sh | 3 + tests/config/tapered/.travis/setup_lua.sh | 122 + tests/config/tapered/CHANGES.md | 70 + tests/config/tapered/LICENSE.md | 27 + tests/config/tapered/README.md | 116 + tests/config/tapered/doc/changes.html | 104 + tests/config/tapered/doc/index.html | 111 + tests/config/tapered/doc/license.html | 40 + tests/config/tapered/doc/normalize.css | 439 + tests/config/tapered/doc/screen.css | 109 + tests/config/tapered/make-doc.bash | 55 + tests/config/tapered/src/tapered.lua | 205 + tests/config/tapered/tapered-1.1-0.rockspec | 21 + tests/config/tapered/tapered-1.2.0-1.rockspec | 21 + tests/config/tapered/tapered-1.2.1-1.rockspec | 21 + tests/config/tapered/tapered-2.0.0-1.rockspec | 21 + tests/config/tapered/tapered-2.0.1-1.rockspec | 21 + tests/config/tapered/tapered-2.1.0-1.rockspec | 21 + tests/config/tapered/tapered-2.2.0-1.rockspec | 22 + tests/config/tapered/tapered-2.3.0-1.rockspec | 22 + tests/config/tapered/test/.luacov | 55 + tests/config/tapered/test/boom-result.txt | 7 + tests/config/tapered/test/boom-test.lua | 19 + tests/config/tapered/test/done-failure-result.txt | 2 + tests/config/tapered/test/done-failure-test.lua | 5 + tests/config/tapered/test/done-success-result.txt | 2 + tests/config/tapered/test/done-success-test.lua | 5 + .../tapered/test/dynamic-setup-teardown-result.txt | 10 + .../tapered/test/dynamic-setup-teardown-test.lua | 27 + tests/config/tapered/test/exit-failure-test.lua | 6 + tests/config/tapered/test/exit-success-test.lua | 6 + .../tapered/test/informational-fields-result.txt | 4 + .../tapered/test/informational-fields-test.lua | 8 + tests/config/tapered/test/is-isnt-result.txt | 43 + tests/config/tapered/test/is-isnt-test.lua | 36 + tests/config/tapered/test/like-unlike-result.txt | 13 + tests/config/tapered/test/like-unlike-test.lua | 16 + tests/config/tapered/test/ok-nok-result.txt | 7 + tests/config/tapered/test/ok-nok-test.lua | 11 + tests/config/tapered/test/pass-fail-result.txt | 4 + tests/config/tapered/test/pass-fail-test.lua | 11 + tests/config/tapered/test/result_test03.txt | 55 + tests/config/tapered/test/runner.bash | 71 + tests/config/tapered/test/same-result.txt | 31 + tests/config/tapered/test/same-test.lua | 74 + .../config/tapered/test/setup-teardown-result.txt | 4 + tests/config/tapered/test/setup-teardown-test.lua | 14 + tests/config/test.cfg | 46 + tests/config/test_dns_generators.lua | 134 + tests/config/test_utils.lua | 121 + tests/config/tls.test.lua | 29 + tests/config/worker.test.lua | 65 + tests/dnstap/meson.build | 11 + tests/dnstap/src/dnstap-test/config | 14 + tests/dnstap/src/dnstap-test/main.go | 247 + tests/dnstap/src/dnstap-test/run.sh | 31 + tests/dnstap/src/dnstap-test/vendor/manifest | 55 + tests/integration/deckard/LICENSE | 23 + tests/integration/deckard/README.rst | 95 + tests/integration/deckard/ci/README.rst | 4 + tests/integration/deckard/ci/__init__.py | 0 tests/integration/deckard/ci/common.sh | 17 + tests/integration/deckard/ci/compare-rplint.sh | 31 + tests/integration/deckard/ci/compare-tests.sh | 30 + tests/integration/deckard/ci/junit-compare.py | 38 + tests/integration/deckard/ci/mypy-run.sh | 17 + tests/integration/deckard/ci/pylint-run.sh | 12 + tests/integration/deckard/ci/raw_id.py | 20 + tests/integration/deckard/ci/raw_id_check.sh | 7 + tests/integration/deckard/ci/runlocally.sh | 41 + tests/integration/deckard/configs/getdns.yaml | 12 + .../integration/deckard/configs/knotd_master.yaml | 10 + tests/integration/deckard/configs/knotd_slave.yaml | 10 + tests/integration/deckard/configs/kresd.yaml | 9 + tests/integration/deckard/configs/named.yaml | 15 + tests/integration/deckard/configs/pdns.yaml | 15 + tests/integration/deckard/configs/unbound.yaml | 13 + tests/integration/deckard/conftest.py | 126 + tests/integration/deckard/contrib/__init__.py | 0 tests/integration/deckard/contrib/deckard.vim | 26 + tests/integration/deckard/contrib/licenses/ISC | 15 + tests/integration/deckard/contrib/namespaces.py | 125 + tests/integration/deckard/contrib/namespaces.spdx | 10 + tests/integration/deckard/deckard.py | 253 + tests/integration/deckard/deckard_pytest.ini | 8 + tests/integration/deckard/deckard_pytest.py | 167 + tests/integration/deckard/doc/devel_guide.rst | 6 + tests/integration/deckard/doc/scenario_example.rst | 337 + tests/integration/deckard/doc/scenario_guide.rst | 431 + tests/integration/deckard/doc/user_guide.rst | 286 + tests/integration/deckard/getdns_run.sh | 63 + tests/integration/deckard/knotd_master_run.sh | 6 + tests/integration/deckard/knotd_slave_run.sh | 6 + tests/integration/deckard/kresd_run.sh | 5 + tests/integration/deckard/mypy.ini | 3 + tests/integration/deckard/named_run.sh | 11 + tests/integration/deckard/networking.py | 93 + tests/integration/deckard/pdns_run.sh | 5 + tests/integration/deckard/pydnstest/__init__.py | 0 tests/integration/deckard/pydnstest/augwrap.py | 226 + tests/integration/deckard/pydnstest/deckard.aug | 94 + tests/integration/deckard/pydnstest/empty.rpl | 20 + tests/integration/deckard/pydnstest/matchpart.py | 238 + tests/integration/deckard/pydnstest/mock_client.py | 136 + tests/integration/deckard/pydnstest/scenario.py | 888 + .../deckard/pydnstest/tests/__init__.py | 0 .../deckard/pydnstest/tests/test_parse_config.py | 17 + .../deckard/pydnstest/tests/test_scenario.py | 55 + tests/integration/deckard/pydnstest/testserver.py | 309 + tests/integration/deckard/pylintrc | 27 + tests/integration/deckard/requirements.txt | 9 + tests/integration/deckard/rplint.py | 352 + tests/integration/deckard/rplint.sh | 5 + tests/integration/deckard/rplint_pytest.ini | 4 + tests/integration/deckard/run.sh | 18 + .../deckard/sets/knotd/master/example.com.zone | 22 + .../deckard/sets/knotd/master/iter_ns.rpl | 28 + .../deckard/sets/knotd/slave/iter_ns.rpl | 78 + tests/integration/deckard/sets/resolver/LICENSE | 30 + .../deckard/sets/resolver/black_data.rpl | 302 + .../deckard/sets/resolver/black_dnskey.rpl | 510 + .../integration/deckard/sets/resolver/black_ds.rpl | 431 + .../deckard/sets/resolver/black_ent.rpl | 464 + .../deckard/sets/resolver/black_prime.rpl | 302 + .../sets/resolver/fwd_val_cname_sibling.rpl | 168 + .../deckard/sets/resolver/iter_badglue.rpl | 274 + .../deckard/sets/resolver/iter_badraw.rpl | 18839 ++++++ .../deckard/sets/resolver/iter_cname_badauth.rpl | 269 + .../deckard/sets/resolver/iter_cname_cache.rpl | 299 + .../deckard/sets/resolver/iter_cname_double.rpl | 296 + .../deckard/sets/resolver/iter_cname_nx.rpl | 290 + .../deckard/sets/resolver/iter_cname_qnamecopy.rpl | 356 + .../deckard/sets/resolver/iter_cycle.rpl | 260 + .../deckard/sets/resolver/iter_cycle_noh.rpl | 416 + .../deckard/sets/resolver/iter_dname_insec.rpl | 1138 + .../sets/resolver/iter_dnsseclame_ds_ok.rpl | 371 + .../sets/resolver/iter_dnsseclame_ta_ok.rpl | 307 + .../deckard/sets/resolver/iter_domain_sale.rpl | 271 + .../sets/resolver/iter_domain_sale_nschange.rpl | 350 + .../deckard/sets/resolver/iter_donotq127.rpl | 198 + .../deckard/sets/resolver/iter_ds_locate_ns.rpl | 146 + .../sets/resolver/iter_ds_locate_ns_nosoa.rpl | 146 + .../sets/resolver/iter_escape_bailiwick.rpl | 220 + .../deckard/sets/resolver/iter_hint_lame.rpl | 172 + .../deckard/sets/resolver/iter_lame_aaaa.rpl | 180 + .../deckard/sets/resolver/iter_lame_noaa.rpl | 126 + .../deckard/sets/resolver/iter_lame_nosoa.rpl | 293 + .../deckard/sets/resolver/iter_lame_root.rpl | 35 + .../deckard/sets/resolver/iter_lamescrub.rpl | 152 + .../deckard/sets/resolver/iter_minim_a.rpl | 95 + .../sets/resolver/iter_minim_a_nxdomain.rpl | 106 + .../deckard/sets/resolver/iter_minim_nonempty.rpl | 134 + .../deckard/sets/resolver/iter_minim_ns.rpl | 128 + .../deckard/sets/resolver/iter_minmaxttl.rpl | 194 + .../integration/deckard/sets/resolver/iter_mod.rpl | 219 + .../deckard/sets/resolver/iter_multiple_A.rpl | 172 + .../deckard/sets/resolver/iter_ns_badaa.rpl | 176 + .../deckard/sets/resolver/iter_ns_badglue.rpl | 240 + .../deckard/sets/resolver/iter_ns_badip.rpl | 270 + .../deckard/sets/resolver/iter_ns_noglue.rpl | 222 + .../deckard/sets/resolver/iter_ns_spoof.rpl | 276 + .../deckard/sets/resolver/iter_pc_a.rpl | 232 + .../deckard/sets/resolver/iter_pc_aaaa.rpl | 284 + .../deckard/sets/resolver/iter_pcdiff.rpl | 210 + .../deckard/sets/resolver/iter_pcdirect.rpl | 313 + .../deckard/sets/resolver/iter_pcname.rpl | 278 + .../deckard/sets/resolver/iter_pcnamech.rpl | 423 + .../deckard/sets/resolver/iter_pcnamechrec.rpl | 402 + .../deckard/sets/resolver/iter_pcnamerec.rpl | 276 + .../deckard/sets/resolver/iter_pcttl.rpl | 355 + .../deckard/sets/resolver/iter_reclame_one.rpl | 318 + .../deckard/sets/resolver/iter_reclame_two.rpl | 357 + .../deckard/sets/resolver/iter_recurse.rpl | 314 + .../deckard/sets/resolver/iter_req_qname.rpl | 122 + .../deckard/sets/resolver/iter_resolve.rpl | 221 + .../deckard/sets/resolver/iter_tcbit.rpl | 89 + .../deckard/sets/resolver/iter_timeouted_ns.rpl | 318 + .../sets/resolver/iter_unexpectedrrtype.rpl | 61 + .../deckard/sets/resolver/iter_validate.rpl | 211 + .../resolver/iter_validate_child_zone_noaddr.rpl | 209 + .../sets/resolver/iter_validate_extradata.rpl | 214 + .../sets/resolver/iter_validate_nsec_nxdomain.rpl | 154 + .../deckard/sets/resolver/module_dns64.rpl | 206 + .../deckard/sets/resolver/module_hint_static.rpl | 45 + .../sets/resolver/module_policy_deny_all.rpl | 98 + .../sets/resolver/module_policy_deny_suff_comm.rpl | 150 + .../sets/resolver/module_policy_deny_suff_patt.rpl | 150 + .../deckard/sets/resolver/module_policy_drop.rpl | 26 + .../sets/resolver/module_policy_forward.rpl | 40 + .../sets/resolver/module_policy_pass_deny.rpl | 69 + .../deckard/sets/resolver/module_policy_tc.rpl | 26 + .../deckard/sets/resolver/module_renumber.rpl | 88 + .../resolver/module_workarounds_disable_0x20.rpl | 83 + .../deckard/sets/resolver/nsec3_aggr_cache.rpl | 5281 ++ .../resolver/nsec3_wildcard_no_data_response.rpl | 112 + .../deckard/sets/resolver/nsec_aggr_cache.rpl | 6395 ++ .../resolver/nsec_name_error_response-part2.rpl | 229 + .../sets/resolver/nsec_name_error_response.rpl | 242 + .../sets/resolver/nsec_no_data_response.rpl | 203 + .../sets/resolver/nsec_ref_to_unsigned1.rpl | 198 + .../sets/resolver/nsec_ref_to_unsigned2.rpl | 199 + .../sets/resolver/nsec_ref_to_unsigned3.rpl | 199 + .../resolver/nsec_wildcard_answer_response.rpl | 420 + .../nsec_wildcard_answer_response/K.+008+41524.key | 5 + .../K.+008+41524.private | 13 + .../nsec_wildcard_answer_response/root.zone | 8 + .../nsec_wildcard_no_data_response-part2.rpl | 259 + .../resolver/nsec_wildcard_no_data_response.rpl | 284 + .../deckard/sets/resolver/val_ad_qtype_ds.rpl | 198 + .../deckard/sets/resolver/val_adbit.rpl | 174 + .../deckard/sets/resolver/val_adcopy.rpl | 166 + .../deckard/sets/resolver/val_anchor_nx_nosig.rpl | 220 + .../deckard/sets/resolver/val_ans_dsent.rpl | 248 + .../deckard/sets/resolver/val_ans_nx.rpl | 250 + .../deckard/sets/resolver/val_bogus_nodata.rpl | 247 + .../deckard/sets/resolver/val_cname_loop1.rpl | 144 + .../deckard/sets/resolver/val_cname_loop1_3.rpl | 184 + .../deckard/sets/resolver/val_cname_loop3.rpl | 166 + .../deckard/sets/resolver/val_cname_new_signer.rpl | 241 + .../deckard/sets/resolver/val_cname_oob.rpl | 183 + .../sets/resolver/val_cname_to_unsigned.rpl | 204 + .../resolver/val_cname_to_unsigned_fake_rrsig.rpl | 215 + .../sets/resolver/val_cname_trust_domains.rpl | 440 + .../deckard/sets/resolver/val_cnamenx_dblnsec.rpl | 180 + .../deckard/sets/resolver/val_cnameqtype.rpl | 232 + .../deckard/sets/resolver/val_deleg_nons.rpl | 273 + .../deckard/sets/resolver/val_dname.rpl | 318 + .../deckard/sets/resolver/val_dname_bogus.rpl | 319 + .../deckard/sets/resolver/val_ds_afterprime.rpl | 183 + .../deckard/sets/resolver/val_ds_cname.rpl | 206 + .../deckard/sets/resolver/val_ds_cnamesub.rpl | 279 + .../deckard/sets/resolver/val_faildnskey.rpl | 173 + .../deckard/sets/resolver/val_iter_high.rpl | 239 + .../deckard/sets/resolver/val_mal_wc.rpl | 153 + .../val_minimal_anotherdomainsignature.rpl | 99 + .../val_minimal_anotherrrtypesignature.rpl | 87 + .../resolver/val_minimal_baddnskeyalgorithm.rpl | 88 + .../sets/resolver/val_minimal_baddnskeyflags.rpl | 88 + .../resolver/val_minimal_baddnskeyprotocol.rpl | 88 + .../sets/resolver/val_minimal_baddsalgorithm.rpl | 87 + .../sets/resolver/val_minimal_baddsdigest.rpl | 87 + .../sets/resolver/val_minimal_baddsdigesttype.rpl | 87 + .../sets/resolver/val_minimal_baddskeytag.rpl | 87 + .../sets/resolver/val_minimal_badpublickey.rpl | 88 + .../resolver/val_minimal_badrrsigalgorithm.rpl | 88 + .../resolver/val_minimal_badrrsigexpiration.rpl | 88 + .../resolver/val_minimal_badrrsiginception.rpl | 88 + .../sets/resolver/val_minimal_badrrsiglabels.rpl | 88 + .../resolver/val_minimal_badrrsigsignature.rpl | 88 + .../sets/resolver/val_minimal_badrrsigtag.rpl | 88 + .../sets/resolver/val_minimal_badrrsigttl.rpl | 88 + .../sets/resolver/val_minimal_beforeinception.rpl | 87 + .../sets/resolver/val_minimal_expiredsignature.rpl | 87 + .../deckard/sets/resolver/val_minimal_noerror.rpl | 89 + .../deckard/sets/resolver/val_negcache_ds.rpl | 217 + .../deckard/sets/resolver/val_noadwhennodo.rpl | 149 + .../deckard/sets/resolver/val_nodata_hasdata.rpl | 165 + .../deckard/sets/resolver/val_nodata_zonecut.rpl | 163 + .../deckard/sets/resolver/val_nodatawc_badce.rpl | 165 + .../deckard/sets/resolver/val_nokeyprime.rpl | 166 + .../sets/resolver/val_nsec3_b1_nameerror.rpl | 163 + .../sets/resolver/val_nsec3_b1_nameerror_noce.rpl | 147 + .../sets/resolver/val_nsec3_b1_nameerror_nonc.rpl | 149 + .../sets/resolver/val_nsec3_b1_nameerror_nowc.rpl | 154 + .../sets/resolver/val_nsec3_b21_nodataent.rpl | 118 + .../sets/resolver/val_nsec3_b21_nodataent_wr.rpl | 138 + .../deckard/sets/resolver/val_nsec3_b2_nodata.rpl | 119 + .../sets/resolver/val_nsec3_b2_nodata_nons.rpl | 144 + .../deckard/sets/resolver/val_nsec3_b3_optout.rpl | 208 + .../sets/resolver/val_nsec3_b3_optout_negcache.rpl | 211 + .../sets/resolver/val_nsec3_b3_optout_noce.rpl | 257 + .../sets/resolver/val_nsec3_b3_optout_nonc.rpl | 258 + .../deckard/sets/resolver/val_nsec3_b4_wild.rpl | 176 + .../sets/resolver/val_nsec3_b5_wcnodata.rpl | 157 + .../sets/resolver/val_nsec3_b5_wcnodata_noce.rpl | 167 + .../sets/resolver/val_nsec3_b5_wcnodata_nonc.rpl | 167 + .../sets/resolver/val_nsec3_b5_wcnodata_nowc.rpl | 167 + .../resolver/val_nsec3_cnametocnamewctoposwc.rpl | 244 + .../resolver/val_nsec3_entnodata_optout_badopt.rpl | 201 + .../sets/resolver/val_nsec3_nods_badsig.rpl | 240 + .../deckard/sets/resolver/val_nsec3_nods_soa.rpl | 256 + .../deckard/sets/resolver/val_nsec3_noopt_ref.rpl | 232 + .../deckard/sets/resolver/val_nsec3_optout_ad.rpl | 363 + .../sets/resolver/val_nsec3_optout_ns_ad.rpl | 205 + .../sets/resolver/val_nsec3_optout_unsec_cache.rpl | 256 + tests/integration/deckard/sets/resolver/val_nx.rpl | 156 + .../deckard/sets/resolver/val_nx_nodeny.rpl | 166 + .../deckard/sets/resolver/val_nx_nowc.rpl | 166 + .../deckard/sets/resolver/val_pos_truncns.rpl | 152 + .../deckard/sets/resolver/val_positive_nosigs.rpl | 184 + .../deckard/sets/resolver/val_qds_oneanc.rpl | 224 + .../deckard/sets/resolver/val_qds_twoanc.rpl | 225 + .../deckard/sets/resolver/val_referral_nods.rpl | 207 + .../deckard/sets/resolver/val_root_ds.rpl | 88 + .../deckard/sets/resolver/val_rrsig.rpl | 171 + .../deckard/sets/resolver/val_secds.rpl | 215 + .../deckard/sets/resolver/val_secds_nosig.rpl | 235 + .../deckard/sets/resolver/val_ta_sentinel.rpl | 587 + .../sets/resolver/val_ta_sentinel/K.+008+48409.key | 5 + .../resolver/val_ta_sentinel/K.+008+48409.private | 13 + .../deckard/sets/resolver/val_ta_sentinel/root.db | 61 + .../sets/resolver/val_ta_sentinel_insecure.rpl | 377 + .../sets/resolver/val_ta_sentinel_nokey.rpl | 362 + .../deckard/sets/resolver/val_unalgo_ds.rpl | 204 + .../resolver/val_unknown_algorithm_insecure.rpl | 162 + .../K.+008+17002.key | 5 + .../K.+008+17002.private | 13 + .../root_unknown_ds_algo_and_digest.db | 11 + .../val_unknown_algorithm_insecure/test.db | 5 + .../val_unknown_algorithm_insecure/test2.db | 5 + .../deckard/sets/resolver/val_unsecds.rpl | 195 + .../deckard/sets/resolver/val_unsecds_negcache.rpl | 196 + .../deckard/sets/resolver/val_unsecds_qtypeds.rpl | 211 + .../deckard/sets/resolver/val_wild_pos.rpl | 163 + .../deckard/sets/resolver/val_wild_pos_multi.rpl | 239 + .../resolver/val_wild_pos_multi/K.+008+41524.key | 5 + .../val_wild_pos_multi/K.+008+41524.private | 13 + .../sets/resolver/val_wild_pos_multi/dsset-. | 2 + .../sets/resolver/val_wild_pos_multi/root.zone | 10 + .../resolver/val_wild_pos_multi/root.zone.signed | 114 + .../deckard/sets/resolver/world_cz_lidovky_www.rpl | 933 + .../deckard/sets/resolver/world_cz_rhybar.rpl | 296 + .../deckard/sets/resolver/world_cz_turris_api.rpl | 325 + .../deckard/sets/resolver/world_cz_vutbr_www.rpl | 298 + .../deckard/sets/resolver/world_mx_nic_www.rpl | 408 + tests/integration/deckard/setup.py | 36 + .../integration/deckard/template/dnssec_getdns.j2 | 3 + tests/integration/deckard/template/getdns.j2 | 6 + tests/integration/deckard/template/hints_zone.j2 | 9 + tests/integration/deckard/template/knotd_master.j2 | 29 + tests/integration/deckard/template/knotd_slave.j2 | 28 + tests/integration/deckard/template/kresd.j2 | 138 + tests/integration/deckard/template/named.j2 | 106 + tests/integration/deckard/template/pdns_dnssec.j2 | 5 + .../integration/deckard/template/pdns_recursor.j2 | 326 + tests/integration/deckard/template/unbound.j2 | 801 + .../integration/deckard/template/unbound_dnssec.j2 | 3 + tests/integration/deckard/tests/__init__.py | 0 tests/integration/deckard/tests/deckard_raw_id.rpl | 14 + tests/integration/deckard/tests/deckard_raw_id.yml | 6 + tests/integration/deckard/tests/test_deckard.py | 30 + tests/integration/deckard/tools/answer_checker.py | 84 + tests/integration/deckard/tools/conftest.py | 19 + tests/integration/deckard/tools/divide_tests.sh | 77 + tests/integration/deckard/tools/forwarder_check.py | 387 + .../integration/deckard/tools/generate_answers.py | 26 + tests/integration/deckard/tools/invalid_dsa.py | 83 + tests/integration/deckard/tools/network_check.py | 136 + tests/integration/deckard/tools/parse.py | 21 + tests/integration/deckard/tools/pydnstest | 1 + tests/integration/deckard/unbound_run.sh | 5 + tests/integration/hints_zone.j2 | 10 + tests/integration/meson.build | 68 + .../testdata_notimpl/iter_class_any.rpl | 150 + .../testdata_notimpl/iter_dnsseclame_bug.rpl | 465 + .../testdata_notimpl/iter_dnsseclame_ds.rpl | 414 + .../testdata_notimpl/iter_dnsseclame_ds_ok.rpl | 367 + .../testdata_notimpl/iter_dnsseclame_ta.rpl | 327 + .../testdata_notimpl/iter_dnsseclame_ta_ok.rpl | 303 + .../testdata_notimpl/iter_dp_turnsuseless.rpl | 166 + .../testdata_notimpl/iter_ds_locate_ns.rpl | 145 + .../testdata_notimpl/iter_ds_locate_ns_cname.rpl | 155 + .../testdata_notimpl/iter_ds_locate_ns_detach.rpl | 296 + .../testdata_notimpl/iter_ds_locate_ns_nosoa.rpl | 145 + .../integration/testdata_notimpl/iter_emptydp.rpl | 263 + .../testdata_notimpl/iter_emptydp_for_glue.rpl | 493 + .../integration/testdata_notimpl/iter_fwdfirst.rpl | 157 + .../testdata_notimpl/iter_fwdfirstequal.rpl | 157 + .../integration/testdata_notimpl/iter_fwdstub.rpl | 218 + .../testdata_notimpl/iter_fwdstubroot.rpl | 175 + .../integration/testdata_notimpl/iter_got6only.rpl | 135 + tests/integration/testdata_notimpl/iter_pcdiff.rpl | 210 + .../testdata_notimpl/iter_pcnamerec.rpl | 275 + .../testdata_notimpl/iter_primenoglue.rpl | 383 + .../integration/testdata_notimpl/iter_privaddr.rpl | 285 + .../testdata_notimpl/iter_ranoaa_lame.rpl | 293 + .../testdata_notimpl/iter_scrub_cname_an.rpl | 181 + .../testdata_notimpl/iter_scrub_dname_insec.rpl | 250 + .../testdata_notimpl/iter_scrub_dname_sec.rpl | 212 + .../integration/testdata_notimpl/iter_scrub_ns.rpl | 103 + .../testdata_notimpl/iter_scrub_ns_fwd.rpl | 103 + .../testdata_notimpl/iter_scrub_ns_side.rpl | 103 + .../testdata_notimpl/iter_stub_noroot.rpl | 64 + .../testdata_notimpl/iter_stubfirst.rpl | 157 + .../testdata_notimpl/iter_stublastresort.rpl | 259 + .../testdata_notimpl/iter_timeout_ra_aaaa.rpl | 244 + tests/meson.build | 61 + tests/packaging/README.rst | 87 + tests/packaging/conftest.py | 10 + tests/packaging/test_packaging.py | 494 + tests/pytests/README.rst | 56 + tests/pytests/certs/tt-certgen-expired.sh | 19 + tests/pytests/certs/tt-certgen.sh | 5 + tests/pytests/certs/tt-expired.cert.pem | 80 + tests/pytests/certs/tt-expired.key.pem | 27 + tests/pytests/certs/tt.cert.pem | 22 + tests/pytests/certs/tt.conf | 353 + tests/pytests/certs/tt.key.pem | 28 + tests/pytests/conftest.py | 102 + tests/pytests/conn_flood.py | 85 + tests/pytests/kresd.py | 306 + tests/pytests/meson.build | 77 + tests/pytests/proxy.py | 161 + tests/pytests/proxy/tls-proxy.c | 1038 + tests/pytests/proxy/tls-proxy.h | 34 + tests/pytests/proxy/tlsproxy.c | 198 + tests/pytests/pylintrc | 33 + tests/pytests/requirements.txt | 5 + tests/pytests/templates/kresd.conf.j2 | 62 + tests/pytests/test_conn_mgmt.py | 214 + tests/pytests/test_edns.py | 22 + tests/pytests/test_prefix.py | 114 + tests/pytests/test_random_close.py | 54 + tests/pytests/test_rehandshake.py | 52 + tests/pytests/test_tls.py | 83 + tests/pytests/utils.py | 136 + tests/unit/meson.build | 37 + tests/unit/mock_cmodule.c | 21 + tests/unit/packaging/debian/10/builddeps | 1 + tests/unit/packaging/test.sh | 2 + tests/unit/test.h | 110 + utils/cache_gc/.gitignore | 2 + utils/cache_gc/README.rst | 20 + utils/cache_gc/categories.c | 56 + utils/cache_gc/categories.h | 10 + utils/cache_gc/db.c | 280 + utils/cache_gc/db.h | 37 + utils/cache_gc/kr_cache_gc.c | 326 + utils/cache_gc/kr_cache_gc.h | 41 + utils/cache_gc/main.c | 163 + utils/cache_gc/meson.build | 31 + utils/cache_gc/test.integr/deckard.yaml | 37 + utils/cache_gc/test.integr/val_rrsig.rpl | 737 + utils/client/kresc.c | 458 + utils/client/meson.build | 37 + utils/meson.build | 8 + utils/upgrade/meson.build | 13 + utils/upgrade/upgrade-4-to-5.lua.in | 87 + 1347 files changed, 266670 insertions(+) create mode 100644 .clang-tidy create mode 100644 .dir-locals.el create mode 100644 .luacheckrc create mode 100644 .mailmap create mode 100644 AUTHORS create mode 100644 CONTRIBUTING.md create mode 100644 COPYING create mode 100644 CodingStyle create mode 100644 Dockerfile create mode 100644 NEWS create mode 100644 README.md create mode 100644 bench/bench_lru.c create mode 100644 bench/bench_lru_set1.tsv create mode 100644 bench/meson.build create mode 100755 ci/deckard_commit_check.sh create mode 100755 ci/fix-meson-junit.sh create mode 100755 ci/gh_actions.py create mode 100644 ci/images/README.md create mode 100755 ci/images/build.sh create mode 100644 ci/images/debian-11-coverity/Dockerfile create mode 100644 ci/images/debian-11/Dockerfile create mode 100644 ci/images/debian-buster/Dockerfile create mode 100755 ci/images/push.sh create mode 100755 ci/images/update.sh create mode 100755 ci/images/vars.sh create mode 100755 ci/no_assert_check.sh create mode 100644 ci/pkgtest.yaml create mode 100644 ci/respdiff/kresd.config create mode 100644 ci/respdiff/respdiff-tcp.conf create mode 100644 ci/respdiff/respdiff-tls.conf create mode 100644 ci/respdiff/respdiff-udp.conf create mode 100755 ci/respdiff/restart-bind.sh create mode 100755 ci/respdiff/restart-kresd.sh create mode 100755 ci/respdiff/restart-unbound.sh create mode 100755 ci/respdiff/run-respdiff-tests.sh create mode 100755 ci/respdiff/start-resolvers.sh create mode 100755 client/.packaging/test.sh create mode 100644 contrib/base32hex.c create mode 100644 contrib/base32hex.h create mode 100644 contrib/base32hex.spdx create mode 100644 contrib/base64.c create mode 100644 contrib/base64.h create mode 100644 contrib/base64.spdx create mode 100644 contrib/base64url.c create mode 100644 contrib/base64url.h create mode 120000 contrib/ccan/asprintf/LICENSE create mode 100644 contrib/ccan/asprintf/asprintf.c create mode 100644 contrib/ccan/asprintf/asprintf.h create mode 100644 contrib/ccan/asprintf/asprintf.spdx create mode 120000 contrib/ccan/compiler/LICENSE create mode 100644 contrib/ccan/compiler/compiler.h create mode 100644 contrib/ccan/compiler/compiler.spdx create mode 120000 contrib/ccan/json/LICENSE create mode 100644 contrib/ccan/json/json.c create mode 100644 contrib/ccan/json/json.h create mode 100644 contrib/ccan/json/json.spdx create mode 100644 contrib/cleanup.h create mode 100644 contrib/config.h create mode 100644 contrib/dynarray.h create mode 100644 contrib/dynarray.spdx create mode 100644 contrib/licenses/BSD-MIT create mode 100644 contrib/licenses/CC0 create mode 100644 contrib/licenses/LGPL2 create mode 100644 contrib/mempattern.c create mode 100644 contrib/mempattern.h create mode 100644 contrib/meson.build create mode 120000 contrib/murmurhash3/LICENSE create mode 100644 contrib/murmurhash3/murmurhash3.c create mode 100644 contrib/murmurhash3/murmurhash3.h create mode 100644 contrib/murmurhash3/murmurhash3.spdx create mode 120000 contrib/ucw/LICENSE create mode 100644 contrib/ucw/alloc.h create mode 100644 contrib/ucw/config.h create mode 100644 contrib/ucw/lib.h create mode 100644 contrib/ucw/libucw.spdx create mode 100644 contrib/ucw/mempool-fmt.c create mode 100644 contrib/ucw/mempool.c create mode 100644 contrib/ucw/mempool.h create mode 100644 daemon/.packaging/centos/7/builddeps create mode 100755 daemon/.packaging/centos/7/pre-build.sh create mode 100755 daemon/.packaging/centos/7/pre-run.sh create mode 100644 daemon/.packaging/centos/7/rundeps create mode 100644 daemon/.packaging/centos/8/builddeps create mode 100755 daemon/.packaging/centos/8/pre-build.sh create mode 100755 daemon/.packaging/centos/8/pre-run.sh create mode 100644 daemon/.packaging/centos/8/rundeps create mode 100644 daemon/.packaging/debian/10/builddeps create mode 100755 daemon/.packaging/debian/10/pre-build.sh create mode 100755 daemon/.packaging/debian/10/pre-run.sh create mode 100644 daemon/.packaging/debian/10/rundeps create mode 100644 daemon/.packaging/debian/9/builddeps create mode 100755 daemon/.packaging/debian/9/pre-build.sh create mode 100755 daemon/.packaging/debian/9/pre-run.sh create mode 100644 daemon/.packaging/debian/9/rundeps create mode 100644 daemon/.packaging/fedora/31/builddeps create mode 100755 daemon/.packaging/fedora/31/pre-build.sh create mode 100755 daemon/.packaging/fedora/31/pre-run.sh create mode 100644 daemon/.packaging/fedora/31/rundeps create mode 100644 daemon/.packaging/fedora/32/builddeps create mode 100755 daemon/.packaging/fedora/32/pre-build.sh create mode 100755 daemon/.packaging/fedora/32/pre-run.sh create mode 100644 daemon/.packaging/fedora/32/rundeps create mode 100644 daemon/.packaging/leap/15.2/builddeps create mode 100755 daemon/.packaging/leap/15.2/pre-build.sh create mode 100755 daemon/.packaging/leap/15.2/pre-run.sh create mode 100644 daemon/.packaging/leap/15.2/rundeps create mode 100644 daemon/.packaging/leap/docker-image-name create mode 100644 daemon/.packaging/test.config create mode 100644 daemon/.packaging/ubuntu/16.04/builddeps create mode 100755 daemon/.packaging/ubuntu/16.04/pre-build.sh create mode 100755 daemon/.packaging/ubuntu/16.04/pre-run.sh create mode 100644 daemon/.packaging/ubuntu/16.04/rundeps create mode 100644 daemon/.packaging/ubuntu/18.04/builddeps create mode 100755 daemon/.packaging/ubuntu/18.04/pre-build.sh create mode 100755 daemon/.packaging/ubuntu/18.04/pre-run.sh create mode 100644 daemon/.packaging/ubuntu/18.04/rundeps create mode 100644 daemon/.packaging/ubuntu/20.04/builddeps create mode 100755 daemon/.packaging/ubuntu/20.04/pre-build.sh create mode 100755 daemon/.packaging/ubuntu/20.04/pre-run.sh create mode 100644 daemon/.packaging/ubuntu/20.04/rundeps create mode 100644 daemon/bindings/api.h create mode 100644 daemon/bindings/cache.c create mode 100644 daemon/bindings/cache.rst create mode 100644 daemon/bindings/event.c create mode 100644 daemon/bindings/event.rst create mode 100644 daemon/bindings/impl.c create mode 100644 daemon/bindings/impl.h create mode 100644 daemon/bindings/modules.c create mode 100644 daemon/bindings/modules.rst create mode 100644 daemon/bindings/net.c create mode 100644 daemon/bindings/net_client.rst create mode 100644 daemon/bindings/net_dns_tweaks.rst create mode 100644 daemon/bindings/net_server.rst create mode 100644 daemon/bindings/net_tlssrv.rst create mode 100644 daemon/bindings/net_xdpsrv.rst create mode 100644 daemon/bindings/worker.c create mode 100644 daemon/bindings/worker.rst create mode 100644 daemon/cache.test/clear.test.lua create mode 100644 daemon/cache.test/insert_ns.test.integr/deckard.yaml create mode 100644 daemon/cache.test/insert_ns.test.integr/kresd_config.j2 create mode 100644 daemon/cache.test/insert_ns.test.integr/nondelegated_auth.rpl create mode 100644 daemon/cache.test/testroot.zone create mode 100644 daemon/cache.test/testroot.zone.unsigned create mode 100644 daemon/engine.c create mode 100644 daemon/engine.h create mode 100644 daemon/ffimodule.c create mode 100644 daemon/ffimodule.h create mode 100644 daemon/http.c create mode 100644 daemon/http.h create mode 100644 daemon/io.c create mode 100644 daemon/io.h create mode 100644 daemon/lua/controlsock.test.lua create mode 100644 daemon/lua/distro-preconfig.lua.in create mode 100644 daemon/lua/kluautil.lua create mode 100644 daemon/lua/kres-gen-30.lua create mode 100644 daemon/lua/kres-gen-31.lua create mode 100644 daemon/lua/kres-gen-32.lua create mode 100755 daemon/lua/kres-gen.sh create mode 100644 daemon/lua/kres.lua create mode 100644 daemon/lua/krprint.lua create mode 100644 daemon/lua/krprint.test.lua create mode 100644 daemon/lua/log.test.lua create mode 100644 daemon/lua/map.test.integr/deckard.yaml create mode 100644 daemon/lua/map.test.integr/kresd_config.j2 create mode 100644 daemon/lua/map.test.integr/query-while-map-is-running.rpl create mode 100644 daemon/lua/meson.build create mode 100644 daemon/lua/postconfig.lua create mode 100644 daemon/lua/sandbox.lua.in create mode 100644 daemon/lua/trust_anchors.lua.in create mode 100644 daemon/lua/trust_anchors.rst create mode 100644 daemon/lua/trust_anchors.test/bootstrap.test.lua create mode 100644 daemon/lua/trust_anchors.test/err_attr_extra_attr.xml create mode 100644 daemon/lua/trust_anchors.test/err_attr_validfrom_invalid.xml create mode 100644 daemon/lua/trust_anchors.test/err_attr_validfrom_missing.xml create mode 100644 daemon/lua/trust_anchors.test/err_elem_extra.xml create mode 100644 daemon/lua/trust_anchors.test/err_elem_missing.xml create mode 100644 daemon/lua/trust_anchors.test/err_multi_ta.xml create mode 100644 daemon/lua/trust_anchors.test/ok0_badtimes.xml create mode 100644 daemon/lua/trust_anchors.test/ok1.xml create mode 100644 daemon/lua/trust_anchors.test/ok1_expired1.xml create mode 100644 daemon/lua/trust_anchors.test/ok1_notyet1.xml create mode 100644 daemon/lua/trust_anchors.test/ok2.xml create mode 100755 daemon/lua/trust_anchors.test/regen.sh create mode 100644 daemon/lua/trust_anchors.test/root.keys create mode 100644 daemon/lua/trust_anchors.test/ta.test.lua create mode 100644 daemon/lua/trust_anchors.test/unsupp_nonroot.xml create mode 100644 daemon/lua/trust_anchors.test/unsupp_xml_v11.xml create mode 100644 daemon/lua/trust_anchors.test/webserv.lua create mode 100644 daemon/lua/trust_anchors.test/x509/ca-key.pem create mode 100644 daemon/lua/trust_anchors.test/x509/ca.pem create mode 100644 daemon/lua/trust_anchors.test/x509/ca.tmpl create mode 100755 daemon/lua/trust_anchors.test/x509/gen.sh create mode 100644 daemon/lua/trust_anchors.test/x509/server-key.pem create mode 100644 daemon/lua/trust_anchors.test/x509/server.pem create mode 100644 daemon/lua/trust_anchors.test/x509/server.tmpl create mode 100644 daemon/lua/trust_anchors.test/x509/wrongca-key.pem create mode 100644 daemon/lua/trust_anchors.test/x509/wrongca.pem create mode 100644 daemon/lua/trust_anchors.test/x509/wrongca.tmpl create mode 100644 daemon/lua/zonefile.lua create mode 100644 daemon/main.c create mode 100644 daemon/meson.build create mode 100644 daemon/network.c create mode 100644 daemon/network.h create mode 100644 daemon/proxyv2.c create mode 100644 daemon/proxyv2.h create mode 100644 daemon/proxyv2.test/deckard.yaml create mode 100644 daemon/proxyv2.test/dnsdist_config.j2 create mode 100644 daemon/proxyv2.test/kresd_config.j2 create mode 100644 daemon/proxyv2.test/proxyv2_valid.rpl create mode 100644 daemon/scripting.rst create mode 100644 daemon/session.c create mode 100644 daemon/session.h create mode 100644 daemon/tls.c create mode 100644 daemon/tls.h create mode 100644 daemon/tls_ephemeral_credentials.c create mode 100644 daemon/tls_session_ticket-srv.c create mode 100644 daemon/udp_queue.c create mode 100644 daemon/udp_queue.h create mode 100644 daemon/worker.c create mode 100644 daemon/worker.h create mode 100644 daemon/zimport.c create mode 100644 daemon/zimport.h create mode 100644 daemon/zimport.test/tz-rfc-a1-bad.zone create mode 100644 daemon/zimport.test/tz-rfc-a1.zone create mode 100644 daemon/zimport.test/tz-rfc-a2.zone create mode 100644 daemon/zimport.test/tz-rfc-a3.zone create mode 100644 daemon/zimport.test/tz-rfc-a4.zone create mode 100644 daemon/zimport.test/tz-rfc-a5.zone create mode 100644 daemon/zimport.test/zimport.test.lua create mode 100644 distro/config/apkg.toml create mode 100644 distro/pkg/arch/PKGBUILD create mode 100644 distro/pkg/deb/changelog create mode 100644 distro/pkg/deb/clean create mode 100644 distro/pkg/deb/compat create mode 100644 distro/pkg/deb/control create mode 100644 distro/pkg/deb/copyright create mode 100644 distro/pkg/deb/knot-resolver-doc.doc-base create mode 100644 distro/pkg/deb/knot-resolver-doc.docs create mode 100644 distro/pkg/deb/knot-resolver-doc.info create mode 100644 distro/pkg/deb/knot-resolver-doc.links create mode 100644 distro/pkg/deb/knot-resolver-module-dnstap.install create mode 100644 distro/pkg/deb/knot-resolver-module-http.install create mode 100644 distro/pkg/deb/knot-resolver-module-http.links create mode 100644 distro/pkg/deb/knot-resolver-module-http.preinst create mode 100644 distro/pkg/deb/knot-resolver.dirs create mode 100644 distro/pkg/deb/knot-resolver.docs create mode 100644 distro/pkg/deb/knot-resolver.install create mode 100644 distro/pkg/deb/knot-resolver.links create mode 100644 distro/pkg/deb/knot-resolver.manpages create mode 100644 distro/pkg/deb/knot-resolver.postinst create mode 100644 distro/pkg/deb/knot-resolver.postrm create mode 100644 distro/pkg/deb/knot-resolver.preinst create mode 100644 distro/pkg/deb/knot-resolver.triggers create mode 100644 distro/pkg/deb/not-installed create mode 100755 distro/pkg/deb/rules create mode 100644 distro/pkg/deb/source/format create mode 100644 distro/pkg/nix/default.nix create mode 100644 distro/pkg/nix/top-level.nix create mode 100644 distro/pkg/rpm/knot-resolver.spec create mode 100644 distro/tests/.ansible.cfg create mode 100644 distro/tests/README.md create mode 100644 distro/tests/ansible-roles/knot_resolver/defaults/main.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/configure_dnstap.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/configure_doh.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/configure_doh2.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/main.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/restart_kresd.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/test_dnssec.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/test_doh.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/test_doh2.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/test_kres_cache_gc.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/test_tcp.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/test_tls.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/tasks/test_udp.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/vars/CentOS.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/vars/Debian.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/vars/Fedora.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/vars/Rocky.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/vars/Ubuntu.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Leap.yaml create mode 100644 distro/tests/ansible-roles/knot_resolver/vars/openSUSE_Tumbleweed.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/defaults/main.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/CentOS.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/Debian.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/Fedora.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/Rocky.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/Ubuntu.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/main.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Leap.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/tasks/openSUSE_Tumbleweed.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/CentOS.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/Debian_10.yaml create mode 120000 distro/tests/ansible-roles/obs_repos/vars/Debian_11.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/Debian_9.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/Fedora.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/Rocky.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/Ubuntu.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/openSUSE_Leap.yaml create mode 100644 distro/tests/ansible-roles/obs_repos/vars/openSUSE_Tumbleweed.yaml create mode 100644 distro/tests/centos7/Vagrantfile create mode 120000 distro/tests/centos7/ansible.cfg create mode 100644 distro/tests/debian10/Vagrantfile create mode 120000 distro/tests/debian10/ansible.cfg create mode 100644 distro/tests/debian11/Vagrantfile create mode 120000 distro/tests/debian11/ansible.cfg create mode 100644 distro/tests/debian9/Vagrantfile create mode 120000 distro/tests/debian9/ansible.cfg create mode 100644 distro/tests/fedora35/Vagrantfile create mode 120000 distro/tests/fedora35/ansible.cfg create mode 100644 distro/tests/fedora36/Vagrantfile create mode 120000 distro/tests/fedora36/ansible.cfg create mode 100644 distro/tests/knot-resolver-pkgtest.yaml create mode 100644 distro/tests/leap15/Vagrantfile create mode 120000 distro/tests/leap15/ansible.cfg create mode 100644 distro/tests/repos.yaml create mode 100644 distro/tests/rocky8/Vagrantfile create mode 120000 distro/tests/rocky8/ansible.cfg create mode 100755 distro/tests/test-distro.sh create mode 100644 distro/tests/ubuntu1804/Vagrantfile create mode 120000 distro/tests/ubuntu1804/ansible.cfg create mode 100644 distro/tests/ubuntu2004/Vagrantfile create mode 120000 distro/tests/ubuntu2004/ansible.cfg create mode 100644 distro/tests/ubuntu2204/Vagrantfile create mode 120000 distro/tests/ubuntu2204/ansible.cfg create mode 100644 doc/.packaging/centos/7/NOTSUPPORTED create mode 100644 doc/.packaging/centos/8/NOTSUPPORTED create mode 100755 doc/.packaging/debian/10/build.sh create mode 100644 doc/.packaging/debian/10/builddeps create mode 100755 doc/.packaging/debian/10/install.sh create mode 100755 doc/.packaging/debian/9/build.sh create mode 100644 doc/.packaging/debian/9/builddeps create mode 100755 doc/.packaging/debian/9/install.sh create mode 100755 doc/.packaging/fedora/31/build.sh create mode 100644 doc/.packaging/fedora/31/builddeps create mode 100755 doc/.packaging/fedora/31/install.sh create mode 100755 doc/.packaging/fedora/32/30/build.sh create mode 100644 doc/.packaging/fedora/32/30/builddeps create mode 100755 doc/.packaging/fedora/32/30/install.sh create mode 100755 doc/.packaging/fedora/32/build.sh create mode 100644 doc/.packaging/fedora/32/builddeps create mode 100755 doc/.packaging/fedora/32/install.sh create mode 100755 doc/.packaging/leap/15.2/build.sh create mode 100644 doc/.packaging/leap/15.2/builddeps create mode 100755 doc/.packaging/leap/15.2/install.sh create mode 100755 doc/.packaging/test.sh create mode 100755 doc/.packaging/ubuntu/16.04/build.sh create mode 100644 doc/.packaging/ubuntu/16.04/builddeps create mode 100755 doc/.packaging/ubuntu/16.04/install.sh create mode 100755 doc/.packaging/ubuntu/18.04/build.sh create mode 100644 doc/.packaging/ubuntu/18.04/builddeps create mode 100755 doc/.packaging/ubuntu/18.04/install.sh create mode 100755 doc/.packaging/ubuntu/20.04/build.sh create mode 100644 doc/.packaging/ubuntu/20.04/builddeps create mode 100755 doc/.packaging/ubuntu/20.04/install.sh create mode 100644 doc/Doxyfile create mode 100644 doc/NEWS.rst create mode 100644 doc/README.md create mode 100644 doc/_static/.gitignore create mode 100644 doc/_static/css/custom.css create mode 100644 doc/_static/logo-negativ.svg create mode 100644 doc/build.rst create mode 100644 doc/conf.py create mode 100644 doc/config-answer-reordering.rst create mode 100644 doc/config-debugging.rst create mode 100644 doc/config-dnssec.rst create mode 100644 doc/config-experimental.rst create mode 100644 doc/config-logging-header.rst create mode 100644 doc/config-logging-monitoring.rst create mode 100644 doc/config-network-forwarding.rst create mode 100644 doc/config-network.rst create mode 100644 doc/config-no-systemd-privileges.rst create mode 100644 doc/config-no-systemd-processes.rst create mode 100644 doc/config-no-systemd.rst create mode 100644 doc/config-overview.rst create mode 100644 doc/config-performance.rst create mode 100644 doc/config-policy.rst create mode 120000 doc/daemon-bindings-cache.rst create mode 120000 doc/daemon-bindings-net_client.rst create mode 120000 doc/daemon-bindings-net_dns_tweaks.rst create mode 120000 doc/daemon-bindings-net_server.rst create mode 120000 doc/daemon-bindings-net_tlssrv.rst create mode 120000 doc/daemon-bindings-net_xdpsrv.rst create mode 120000 doc/daemon-bindings-worker.rst create mode 120000 doc/daemon-scripting.rst create mode 100644 doc/flowcharts/io_and_worker.dia create mode 100644 doc/flowcharts/task_ERD.dia create mode 100644 doc/flowcharts/tcp_task.dia create mode 100644 doc/flowcharts/udp_task.dia create mode 100644 doc/index.rst create mode 100644 doc/kresd.8.in create mode 100644 doc/lib.rst create mode 100644 doc/meson.build create mode 120000 doc/modules-bogus_log.rst create mode 120000 doc/modules-daf.rst create mode 120000 doc/modules-detect_time_jump.rst create mode 120000 doc/modules-detect_time_skew.rst create mode 120000 doc/modules-dns64.rst create mode 120000 doc/modules-dnstap.rst create mode 120000 doc/modules-edns_keepalive.rst create mode 120000 doc/modules-experimental_dot_auth.rst create mode 120000 doc/modules-hints.rst create mode 120000 doc/modules-http-custom-services.rst create mode 120000 doc/modules-http-trace.rst create mode 120000 doc/modules-http.rst create mode 120000 doc/modules-nsid.rst create mode 120000 doc/modules-policy.rst create mode 120000 doc/modules-predict.rst create mode 120000 doc/modules-prefill.rst create mode 120000 doc/modules-priming.rst create mode 120000 doc/modules-rebinding.rst create mode 120000 doc/modules-refuse_nord.rst create mode 120000 doc/modules-renumber.rst create mode 120000 doc/modules-rfc7706.rst create mode 120000 doc/modules-serve_stale.rst create mode 120000 doc/modules-stats.rst create mode 120000 doc/modules-ta_sentinel.rst create mode 120000 doc/modules-ta_signal_query.rst create mode 120000 doc/modules-view.rst create mode 120000 doc/modules-watchdog.rst create mode 100644 doc/modules_api.rst create mode 100644 doc/quickstart-config.rst create mode 100644 doc/quickstart-install.rst create mode 100644 doc/quickstart-startup.rst create mode 100644 doc/requirements.txt create mode 100644 doc/resolution.png create mode 100644 doc/server_terminology.fodg create mode 100644 doc/server_terminology.svg create mode 120000 doc/systemd-multiinst.rst create mode 100644 doc/upgrading.rst create mode 100644 doc/worker_api.rst create mode 100644 etc/config/config.cluster create mode 100644 etc/config/config.docker create mode 100644 etc/config/config.internal create mode 100644 etc/config/config.isp create mode 100644 etc/config/config.personal create mode 100644 etc/config/config.privacy create mode 100644 etc/config/config.splitview create mode 100644 etc/config/meson.build create mode 100644 etc/icann-ca.pem create mode 100644 etc/meson.build create mode 100644 etc/root.hints create mode 100644 etc/root.keys create mode 100644 lib/README.rst create mode 100644 lib/cache/README.rst create mode 100644 lib/cache/api.c create mode 100644 lib/cache/api.h create mode 100644 lib/cache/cdb_api.h create mode 100644 lib/cache/cdb_lmdb.c create mode 100644 lib/cache/cdb_lmdb.h create mode 100644 lib/cache/entry_list.c create mode 100644 lib/cache/entry_pkt.c create mode 100644 lib/cache/entry_rr.c create mode 100644 lib/cache/impl.h create mode 100644 lib/cache/knot_pkt.c create mode 100644 lib/cache/nsec1.c create mode 100644 lib/cache/nsec3.c create mode 100644 lib/cache/overflow.test.integr/deckard.yaml create mode 100644 lib/cache/overflow.test.integr/kresd_config.j2 create mode 100644 lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl create mode 100644 lib/cache/peek.c create mode 100644 lib/cache/test.integr/cache_minimal_nsec3.rpl create mode 100644 lib/cache/test.integr/deckard.yaml create mode 100644 lib/cache/test.integr/kresd_config.j2 create mode 100644 lib/cache/util.h create mode 100644 lib/cookies/alg_containers.c create mode 100644 lib/cookies/alg_containers.h create mode 100644 lib/cookies/alg_sha.c create mode 100644 lib/cookies/alg_sha.h create mode 100644 lib/cookies/control.h create mode 100644 lib/cookies/helper.c create mode 100644 lib/cookies/helper.h create mode 100644 lib/cookies/lru_cache.c create mode 100644 lib/cookies/lru_cache.h create mode 100644 lib/cookies/nonce.c create mode 100644 lib/cookies/nonce.h create mode 100644 lib/defines.h create mode 100644 lib/dnssec.c create mode 100644 lib/dnssec.h create mode 100644 lib/dnssec/nsec.c create mode 100644 lib/dnssec/nsec.h create mode 100644 lib/dnssec/nsec3.c create mode 100644 lib/dnssec/nsec3.h create mode 100644 lib/dnssec/signature.c create mode 100644 lib/dnssec/signature.h create mode 100644 lib/dnssec/ta.c create mode 100644 lib/dnssec/ta.h create mode 100644 lib/generic/README.rst create mode 100644 lib/generic/array.h create mode 100644 lib/generic/lru.c create mode 100644 lib/generic/lru.h create mode 100644 lib/generic/pack.h create mode 100644 lib/generic/queue.c create mode 100644 lib/generic/queue.h create mode 100644 lib/generic/test_array.c create mode 100644 lib/generic/test_lru.c create mode 100644 lib/generic/test_pack.c create mode 100644 lib/generic/test_queue.c create mode 100644 lib/generic/test_trie.c create mode 100644 lib/generic/trie.c create mode 100644 lib/generic/trie.h create mode 100644 lib/generic/trie.spdx create mode 100644 lib/layer.h create mode 100644 lib/layer/cache.c create mode 100644 lib/layer/iterate.c create mode 100644 lib/layer/iterate.h create mode 100644 lib/layer/mode.rst create mode 100644 lib/layer/test.integr/deckard.yaml create mode 100644 lib/layer/test.integr/iter_cname_length.rpl create mode 100644 lib/layer/test.integr/iter_limit_bad_glueless.rpl create mode 100644 lib/layer/test.integr/iter_limit_refuse.rpl create mode 100644 lib/layer/test.integr/kresd_config.j2 create mode 100644 lib/layer/validate.c create mode 100644 lib/layer/validate.test.integr/deckard.yaml create mode 100644 lib/layer/validate.test.integr/fwd_insecure_but_rrsig_signer_invalid.rpl create mode 100644 lib/layer/validate.test.integr/kresd_config.j2 create mode 100644 lib/log.c create mode 100644 lib/log.h create mode 100644 lib/meson.build create mode 100644 lib/module.c create mode 100644 lib/module.h create mode 100644 lib/resolve.c create mode 100644 lib/resolve.h create mode 100644 lib/rplan.c create mode 100644 lib/rplan.h create mode 100644 lib/selection.c create mode 100644 lib/selection.h create mode 100644 lib/selection_forward.c create mode 100644 lib/selection_forward.h create mode 100644 lib/selection_iter.c create mode 100644 lib/selection_iter.h create mode 100644 lib/test_module.c create mode 100644 lib/test_rplan.c create mode 100644 lib/test_utils.c create mode 100644 lib/test_zonecut.c create mode 100644 lib/utils.c create mode 100644 lib/utils.h create mode 100644 lib/zonecut.c create mode 100644 lib/zonecut.h create mode 100644 meson.build create mode 100644 meson_options.txt create mode 100644 modules/README.rst create mode 100644 modules/bogus_log/.packaging/test.config create mode 100644 modules/bogus_log/README.rst create mode 100644 modules/bogus_log/bogus_log.c create mode 100644 modules/bogus_log/meson.build create mode 100644 modules/bogus_log/test.integr/deckard.yaml create mode 100644 modules/bogus_log/test.integr/kresd_config.j2 create mode 100644 modules/bogus_log/test.integr/val_minimal_expiredsignature.rpl create mode 100644 modules/cookies/README.rst create mode 100644 modules/cookies/cookiectl.c create mode 100644 modules/cookies/cookiectl.h create mode 100644 modules/cookies/cookiemonster.c create mode 100644 modules/cookies/cookiemonster.h create mode 100644 modules/cookies/cookies.c create mode 100644 modules/daf/.packaging/test.config create mode 100644 modules/daf/README.rst create mode 100644 modules/daf/daf.js create mode 100644 modules/daf/daf.lua create mode 100644 modules/daf/daf.test.lua create mode 100644 modules/daf/daf_http.test.lua create mode 100644 modules/daf/meson.build create mode 100644 modules/daf/test.integr/deckard.yaml create mode 100644 modules/daf/test.integr/kresd_config.j2 create mode 100644 modules/daf/test.integr/module_daf.rpl create mode 100644 modules/detect_time_jump/.packaging/test.config create mode 100644 modules/detect_time_jump/README.rst create mode 100644 modules/detect_time_jump/detect_time_jump.lua create mode 100644 modules/detect_time_skew/.packaging/test.config create mode 100644 modules/detect_time_skew/README.rst create mode 100644 modules/detect_time_skew/detect_time_skew.lua create mode 100644 modules/dns64/.packaging/test.config create mode 100644 modules/dns64/README.rst create mode 100644 modules/dns64/dns64.lua create mode 100644 modules/dns64/dns64.test.lua create mode 100644 modules/dnstap/.packaging/centos/7/builddeps create mode 100644 modules/dnstap/.packaging/centos/7/rundeps create mode 100644 modules/dnstap/.packaging/centos/8/builddeps create mode 100644 modules/dnstap/.packaging/centos/8/rundeps create mode 100644 modules/dnstap/.packaging/debian/10/builddeps create mode 100644 modules/dnstap/.packaging/debian/10/rundeps create mode 100644 modules/dnstap/.packaging/debian/9/builddeps create mode 100644 modules/dnstap/.packaging/debian/9/rundeps create mode 100644 modules/dnstap/.packaging/fedora/31/builddeps create mode 100644 modules/dnstap/.packaging/fedora/31/rundeps create mode 100644 modules/dnstap/.packaging/fedora/32/builddeps create mode 100644 modules/dnstap/.packaging/fedora/32/rundeps create mode 100644 modules/dnstap/.packaging/leap/15.2/builddeps create mode 100644 modules/dnstap/.packaging/leap/15.2/rundeps create mode 100644 modules/dnstap/.packaging/test.config create mode 100644 modules/dnstap/.packaging/ubuntu/16.04/builddeps create mode 100644 modules/dnstap/.packaging/ubuntu/16.04/rundeps create mode 100644 modules/dnstap/.packaging/ubuntu/18.04/builddeps create mode 100644 modules/dnstap/.packaging/ubuntu/18.04/rundeps create mode 100644 modules/dnstap/.packaging/ubuntu/20.04/builddeps create mode 100644 modules/dnstap/.packaging/ubuntu/20.04/rundeps create mode 100644 modules/dnstap/README.rst create mode 100644 modules/dnstap/dnstap.c create mode 100644 modules/dnstap/dnstap.proto create mode 100644 modules/dnstap/meson.build create mode 100644 modules/edns_keepalive/.packaging/test.config create mode 100644 modules/edns_keepalive/README.rst create mode 100644 modules/edns_keepalive/edns_keepalive.c create mode 100644 modules/edns_keepalive/meson.build create mode 100755 modules/etcd/.packaging/centos/7/pre-test.sh create mode 100644 modules/etcd/.packaging/centos/7/rundeps create mode 100644 modules/etcd/.packaging/centos/8/NOTSUPPORTED create mode 100755 modules/etcd/.packaging/debian/10/pre-test.sh create mode 100644 modules/etcd/.packaging/debian/10/rundeps create mode 100755 modules/etcd/.packaging/debian/9/pre-test.sh create mode 100644 modules/etcd/.packaging/debian/9/rundeps create mode 100644 modules/etcd/.packaging/fedora/31/NOTSUPPORTED create mode 100644 modules/etcd/.packaging/fedora/32/NOTSUPPORTED create mode 100755 modules/etcd/.packaging/leap/15.2/pre-test.sh create mode 100644 modules/etcd/.packaging/leap/15.2/rundeps create mode 100644 modules/etcd/.packaging/test.config create mode 100755 modules/etcd/.packaging/ubuntu/16.04/pre-test.sh create mode 100644 modules/etcd/.packaging/ubuntu/16.04/rundeps create mode 100755 modules/etcd/.packaging/ubuntu/18.04/pre-test.sh create mode 100644 modules/etcd/.packaging/ubuntu/18.04/rundeps create mode 100755 modules/etcd/.packaging/ubuntu/20.04/pre-test.sh create mode 100644 modules/etcd/.packaging/ubuntu/20.04/rundeps create mode 100644 modules/etcd/README.rst create mode 100644 modules/etcd/etcd.lua create mode 100644 modules/experimental_dot_auth/.packaging/centos/7/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/centos/8/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/debian/10/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/debian/9/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/fedora/31/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/fedora/32/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/leap/15.2/NOTSUPPORTED create mode 100755 modules/experimental_dot_auth/.packaging/leap/15.2/pre-test.sh create mode 100644 modules/experimental_dot_auth/.packaging/leap/15.2/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/test.config create mode 100644 modules/experimental_dot_auth/.packaging/ubuntu/16.04/NOTSUPPORTED create mode 100644 modules/experimental_dot_auth/.packaging/ubuntu/18.04/rundeps create mode 100644 modules/experimental_dot_auth/.packaging/ubuntu/20.04/rundeps create mode 100644 modules/experimental_dot_auth/README.rst create mode 100644 modules/experimental_dot_auth/experimental_dot_auth.lua create mode 100644 modules/experimental_dot_auth/meson.build create mode 100644 modules/extended_error/extended_error.c create mode 100644 modules/extended_error/meson.build create mode 100644 modules/graphite/.packaging/centos/7/rundeps create mode 100644 modules/graphite/.packaging/centos/8/rundeps create mode 100644 modules/graphite/.packaging/debian/10/rundeps create mode 100644 modules/graphite/.packaging/debian/9/rundeps create mode 100644 modules/graphite/.packaging/fedora/31/rundeps create mode 100644 modules/graphite/.packaging/fedora/32/rundeps create mode 100644 modules/graphite/.packaging/leap/15.2/NOTSUPPORTED create mode 100755 modules/graphite/.packaging/leap/15.2/pre-test.sh create mode 100644 modules/graphite/.packaging/leap/15.2/rundeps create mode 100644 modules/graphite/.packaging/test.config create mode 100644 modules/graphite/.packaging/ubuntu/16.04/rundeps create mode 100644 modules/graphite/.packaging/ubuntu/18.04/rundeps create mode 100644 modules/graphite/.packaging/ubuntu/20.04/rundeps create mode 100644 modules/graphite/README.rst create mode 100644 modules/graphite/graphite.lua create mode 100644 modules/hints/.packaging/test.config create mode 100644 modules/hints/README.rst create mode 100644 modules/hints/hints.c create mode 100644 modules/hints/meson.build create mode 100644 modules/hints/tests/hints.test.hosts create mode 100644 modules/hints/tests/hints.test.lua create mode 100644 modules/hints/tests/hints_test.zone create mode 100644 modules/http/.packaging/centos/7/rundeps create mode 100644 modules/http/.packaging/centos/8/rundeps create mode 100644 modules/http/.packaging/debian/10/rundeps create mode 100644 modules/http/.packaging/debian/9/rundeps create mode 100644 modules/http/.packaging/fedora/31/rundeps create mode 100644 modules/http/.packaging/fedora/32/rundeps create mode 100644 modules/http/.packaging/leap/15.2/NOTSUPPORTED create mode 100755 modules/http/.packaging/leap/15.2/pre-test.sh create mode 100644 modules/http/.packaging/leap/15.2/rundeps create mode 100644 modules/http/.packaging/test.config create mode 100644 modules/http/.packaging/ubuntu/16.04/NOTSUPPORTED create mode 100644 modules/http/.packaging/ubuntu/18.04/rundeps create mode 100644 modules/http/.packaging/ubuntu/20.04/rundeps create mode 100644 modules/http/README.rst create mode 100644 modules/http/custom_services.rst create mode 100644 modules/http/debug_opensslkeylog.c create mode 100644 modules/http/http.lua.in create mode 100644 modules/http/http.test.lua create mode 100644 modules/http/http_doh.lua create mode 100644 modules/http/http_doh.test.lua create mode 100644 modules/http/http_tls_cert.lua create mode 100644 modules/http/http_trace.lua create mode 100644 modules/http/meson.build create mode 100644 modules/http/prometheus.lua create mode 100644 modules/http/prometheus.rst create mode 100644 modules/http/static/bootstrap-theme.min.css create mode 100644 modules/http/static/bootstrap-theme.min.css.spdx create mode 100644 modules/http/static/bootstrap.min.css create mode 100644 modules/http/static/bootstrap.min.css.spdx create mode 100644 modules/http/static/bootstrap.min.js create mode 100644 modules/http/static/bootstrap.min.js.spdx create mode 100644 modules/http/static/d3.js create mode 100644 modules/http/static/d3.spdx create mode 100644 modules/http/static/datamaps.world.min.js create mode 100644 modules/http/static/datamaps.world.min.spdx create mode 100644 modules/http/static/dygraph.min.js create mode 100644 modules/http/static/dygraph.min.js.spdx create mode 100644 modules/http/static/epoch.css create mode 100644 modules/http/static/epoch.js create mode 100644 modules/http/static/epoch.spdx create mode 100644 modules/http/static/favicon.ico create mode 100644 modules/http/static/glyphicons-halflings-regular.spdx create mode 100644 modules/http/static/glyphicons-halflings-regular.woff2 create mode 100644 modules/http/static/jquery.js create mode 100644 modules/http/static/jquery.spdx create mode 100644 modules/http/static/kresd.css create mode 100644 modules/http/static/kresd.js create mode 100644 modules/http/static/main.tpl create mode 100644 modules/http/static/selectize.bootstrap3.css create mode 100644 modules/http/static/selectize.min.js create mode 100644 modules/http/static/selectize.spdx create mode 100644 modules/http/static/topojson.js create mode 100644 modules/http/static/topojson.spdx create mode 100644 modules/http/test_tls/broken.crt create mode 100644 modules/http/test_tls/broken.key create mode 100644 modules/http/test_tls/ca.crt create mode 100644 modules/http/test_tls/chain.crt create mode 100644 modules/http/test_tls/test.crt create mode 100644 modules/http/test_tls/test.key create mode 100644 modules/http/test_tls/tls.test.lua create mode 100644 modules/http/trace.rst create mode 100644 modules/meson.build create mode 100644 modules/nsid/.packaging/test.config create mode 100644 modules/nsid/README.rst create mode 100644 modules/nsid/meson.build create mode 100644 modules/nsid/nsid.c create mode 100644 modules/nsid/nsid.test.lua create mode 100644 modules/policy/.packaging/test.config create mode 100644 modules/policy/README.rst create mode 100644 modules/policy/lua-aho-corasick/LICENSE create mode 100644 modules/policy/lua-aho-corasick/Makefile create mode 100644 modules/policy/lua-aho-corasick/README.md create mode 100644 modules/policy/lua-aho-corasick/ac.cxx create mode 100644 modules/policy/lua-aho-corasick/ac.h create mode 100644 modules/policy/lua-aho-corasick/ac_fast.cxx create mode 100644 modules/policy/lua-aho-corasick/ac_fast.hpp create mode 100644 modules/policy/lua-aho-corasick/ac_lua.cxx create mode 100644 modules/policy/lua-aho-corasick/ac_slow.cxx create mode 100644 modules/policy/lua-aho-corasick/ac_slow.hpp create mode 100644 modules/policy/lua-aho-corasick/ac_util.hpp create mode 100644 modules/policy/lua-aho-corasick/load_ac.lua create mode 100644 modules/policy/lua-aho-corasick/mytest.cxx create mode 100644 modules/policy/lua-aho-corasick/tests/Makefile create mode 100644 modules/policy/lua-aho-corasick/tests/ac_bench.cxx create mode 100644 modules/policy/lua-aho-corasick/tests/ac_test_aggr.cxx create mode 100644 modules/policy/lua-aho-corasick/tests/ac_test_simple.cxx create mode 100644 modules/policy/lua-aho-corasick/tests/dict/README.txt create mode 100644 modules/policy/lua-aho-corasick/tests/dict/dict1.txt create mode 100644 modules/policy/lua-aho-corasick/tests/load_ac_test.lua create mode 100644 modules/policy/lua-aho-corasick/tests/lua_test.lua create mode 100644 modules/policy/lua-aho-corasick/tests/test_base.hpp create mode 100644 modules/policy/lua-aho-corasick/tests/test_bigfile.cxx create mode 100644 modules/policy/lua-aho-corasick/tests/test_main.cxx create mode 100644 modules/policy/meson.build create mode 100644 modules/policy/noipv6.test.integr/broken-ipv6.rpl create mode 100644 modules/policy/noipv6.test.integr/deckard.yaml create mode 100644 modules/policy/noipv6.test.integr/kresd_config.j2 create mode 100644 modules/policy/noipvx.test.integr/broken-ipvx.rpl create mode 100644 modules/policy/noipvx.test.integr/deckard.yaml create mode 100644 modules/policy/noipvx.test.integr/kresd_config.j2 create mode 100644 modules/policy/policy.lua create mode 100644 modules/policy/policy.rpz.test.lua create mode 100644 modules/policy/policy.slice.test.lua create mode 100644 modules/policy/policy.test.lua create mode 100644 modules/policy/policy.test.rpz create mode 100644 modules/policy/policy.test.rpz.soa create mode 100644 modules/policy/test.integr/deckard.yaml create mode 100644 modules/policy/test.integr/kresd_config.j2 create mode 100644 modules/policy/test.integr/refuse.rpl create mode 100644 modules/predict/.packaging/test.config create mode 100644 modules/predict/README.rst create mode 100644 modules/predict/predict.lua create mode 100644 modules/predict/predict.test.lua create mode 100644 modules/prefill/.packaging/test.config create mode 100644 modules/prefill/README.rst create mode 100644 modules/prefill/prefill.lua create mode 100644 modules/prefill/prefill.test/empty.zone create mode 100644 modules/prefill/prefill.test/example.com.zone create mode 100644 modules/prefill/prefill.test/prefill.test.lua create mode 100644 modules/prefill/prefill.test/random.zone create mode 100644 modules/prefill/prefill.test/testroot.zone create mode 100644 modules/prefill/prefill.test/testroot.zone.unsigned create mode 100644 modules/prefill/prefill.test/testroot_no_soa.zone create mode 100644 modules/priming/.packaging/test.config create mode 100644 modules/priming/README.rst create mode 100644 modules/priming/priming.lua create mode 100644 modules/rebinding/.packaging/test.config create mode 100644 modules/rebinding/README.rst create mode 100644 modules/rebinding/rebinding.lua create mode 100644 modules/rebinding/test.integr/deckard.yaml create mode 100644 modules/rebinding/test.integr/kresd_config.j2 create mode 100644 modules/rebinding/test.integr/module_rebinding.rpl create mode 100644 modules/refuse_nord/.packaging/test.config create mode 100644 modules/refuse_nord/README.rst create mode 100644 modules/refuse_nord/meson.build create mode 100644 modules/refuse_nord/refuse_nord.c create mode 100644 modules/refuse_nord/test.integr/deckard.yaml create mode 100644 modules/refuse_nord/test.integr/kresd_config.j2 create mode 100644 modules/refuse_nord/test.integr/refuse_nord.rpl create mode 100644 modules/renumber/.packaging/test.config create mode 100644 modules/renumber/README.rst create mode 100644 modules/renumber/renumber.lua create mode 100644 modules/renumber/renumber.test.lua create mode 100644 modules/rfc7706.rst create mode 100644 modules/serve_stale/.packaging/test.config create mode 100644 modules/serve_stale/README.rst create mode 100644 modules/serve_stale/serve_stale.lua create mode 100644 modules/serve_stale/test.integr/deckard.yaml create mode 100644 modules/serve_stale/test.integr/kresd_config.j2 create mode 100644 modules/serve_stale/test.integr/module_serve_stale.rpl create mode 100644 modules/stats/.packaging/test.config create mode 100644 modules/stats/README.rst create mode 100644 modules/stats/meson.build create mode 100644 modules/stats/stats.c create mode 100644 modules/stats/test.integr/deckard.yaml create mode 100644 modules/stats/test.integr/kresd_config.j2 create mode 100644 modules/stats/test.integr/stats.rpl create mode 100644 modules/ta_sentinel/.packaging/test.config create mode 100644 modules/ta_sentinel/README.rst create mode 100644 modules/ta_sentinel/ta_sentinel.lua create mode 100644 modules/ta_signal_query/.packaging/test.config create mode 100644 modules/ta_signal_query/README.rst create mode 100644 modules/ta_signal_query/ta_signal_query.lua create mode 100644 modules/ta_update/.packaging/test.config create mode 100644 modules/ta_update/meson.build create mode 100644 modules/ta_update/root.keys create mode 100644 modules/ta_update/ta_update.lua create mode 100644 modules/ta_update/ta_update.test.integr/deckard.yaml create mode 100644 modules/ta_update/ta_update.test.integr/kresd_config.j2 create mode 100644 modules/ta_update/ta_update.test.integr/rfc5011-monotonictime.rpl create mode 100644 modules/ta_update/ta_update.test.integr/rfc5011/README create mode 100755 modules/ta_update/ta_update.test.integr/rfc5011/dns2rpl.py create mode 100644 modules/ta_update/ta_update.test.integr/rfc5011/empty.rpl create mode 100755 modules/ta_update/ta_update.test.integr/rfc5011/genkeyszones.sh create mode 100644 modules/ta_update/ta_update.test.integr/rfc5011/knot.root.conf create mode 120000 modules/ta_update/ta_update.test.integr/rfc5011/pydnstest create mode 100644 modules/ta_update/ta_update.test.integr/rfc5011/unsigned_check.db create mode 100644 modules/ta_update/ta_update.test.integr/rfc5011/unsigned_ok.db create mode 100644 modules/ta_update/ta_update.test.integr/rfc5011_unsupported_key_rollover.rpl create mode 100644 modules/ta_update/ta_update.test.lua create mode 100644 modules/ta_update/ta_update.unmanagedkey.test.integr/deckard.yaml create mode 100644 modules/ta_update/ta_update.unmanagedkey.test.integr/kresd_config.j2 create mode 120000 modules/ta_update/ta_update.unmanagedkey.test.integr/rfc5011 create mode 100644 modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-missing-monotonictime.rpl create mode 100644 modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-present-monotonictime.rpl create mode 100644 modules/ta_update/ta_update.unmanagedkey.test.integr/unmanagedkey-revoke-monotonictime.rpl create mode 100644 modules/view/.packaging/test.config create mode 100644 modules/view/README.rst create mode 100644 modules/view/addr.test.integr/deckard.yaml create mode 100644 modules/view/addr.test.integr/kresd_config.j2 create mode 100644 modules/view/addr.test.integr/module_view_addr.rpl create mode 100644 modules/view/meson.build create mode 100644 modules/view/tsig.test.integr/deckard.yaml create mode 100644 modules/view/tsig.test.integr/kresd_config.j2 create mode 100644 modules/view/tsig.test.integr/module_view_tsig.rpl create mode 100644 modules/view/view.lua create mode 100644 modules/watchdog/.packaging/test.config create mode 100644 modules/watchdog/README.rst create mode 100644 modules/watchdog/watchdog.lua create mode 100644 modules/workarounds/.packaging/test.config create mode 100644 modules/workarounds/README.rst create mode 100644 modules/workarounds/workarounds.lua create mode 100755 scripts/bench.sh create mode 100755 scripts/bugreport-journals.py create mode 100755 scripts/build-in-obs.sh create mode 100755 scripts/coverage_c_combine.sh create mode 100755 scripts/coverage_env.sh create mode 100755 scripts/doh_b64encode_query.py create mode 100755 scripts/gen-cdefs.sh create mode 100755 scripts/gen-pgp-keyblock.sh create mode 100755 scripts/get-date.sh create mode 100755 scripts/kresd-host.lua create mode 100755 scripts/kresd-query.lua create mode 100644 scripts/kresd.apparmor create mode 100755 scripts/luacov_gen_empty.sh create mode 100755 scripts/luacov_to_info.lua create mode 100755 scripts/make-archive.sh create mode 100755 scripts/make-doc.sh create mode 100755 scripts/make-obs.sh create mode 100755 scripts/map_install_src.lua create mode 100755 scripts/run-pylint.sh create mode 100755 scripts/run-scanbuild-with-args.sh create mode 100755 scripts/test-config.sh create mode 100755 scripts/test-integration-prepare.sh create mode 100755 scripts/update-authors.sh create mode 100755 scripts/update-root-hints.sh create mode 100644 security.txt create mode 100644 systemd/README.rst create mode 100644 systemd/kres-cache-gc.service.in create mode 100644 systemd/kresd.systemd.7.in create mode 100644 systemd/kresd.target create mode 100644 systemd/kresd@.service.in create mode 100644 systemd/meson.build create mode 100644 systemd/multiinst.rst create mode 100644 systemd/sysusers.d/knot-resolver.conf.in create mode 100644 systemd/tmpfiles.d/knot-resolver.conf.in create mode 100644 tests/.gitignore create mode 100644 tests/README.rst create mode 100644 tests/config/basic.test.lua create mode 100644 tests/config/cache.test.lua create mode 100644 tests/config/doh2.test.lua create mode 100644 tests/config/lru.test.lua create mode 100644 tests/config/meson.build create mode 100644 tests/config/net.test.lua create mode 100644 tests/config/tapered/.travis.yml create mode 100644 tests/config/tapered/.travis/platform.sh create mode 100644 tests/config/tapered/.travis/setenv_lua.sh create mode 100644 tests/config/tapered/.travis/setup_lua.sh create mode 100644 tests/config/tapered/CHANGES.md create mode 100644 tests/config/tapered/LICENSE.md create mode 100644 tests/config/tapered/README.md create mode 100644 tests/config/tapered/doc/changes.html create mode 100644 tests/config/tapered/doc/index.html create mode 100644 tests/config/tapered/doc/license.html create mode 100644 tests/config/tapered/doc/normalize.css create mode 100644 tests/config/tapered/doc/screen.css create mode 100755 tests/config/tapered/make-doc.bash create mode 100644 tests/config/tapered/src/tapered.lua create mode 100644 tests/config/tapered/tapered-1.1-0.rockspec create mode 100644 tests/config/tapered/tapered-1.2.0-1.rockspec create mode 100644 tests/config/tapered/tapered-1.2.1-1.rockspec create mode 100644 tests/config/tapered/tapered-2.0.0-1.rockspec create mode 100644 tests/config/tapered/tapered-2.0.1-1.rockspec create mode 100644 tests/config/tapered/tapered-2.1.0-1.rockspec create mode 100644 tests/config/tapered/tapered-2.2.0-1.rockspec create mode 100644 tests/config/tapered/tapered-2.3.0-1.rockspec create mode 100644 tests/config/tapered/test/.luacov create mode 100644 tests/config/tapered/test/boom-result.txt create mode 100755 tests/config/tapered/test/boom-test.lua create mode 100644 tests/config/tapered/test/done-failure-result.txt create mode 100644 tests/config/tapered/test/done-failure-test.lua create mode 100644 tests/config/tapered/test/done-success-result.txt create mode 100644 tests/config/tapered/test/done-success-test.lua create mode 100644 tests/config/tapered/test/dynamic-setup-teardown-result.txt create mode 100755 tests/config/tapered/test/dynamic-setup-teardown-test.lua create mode 100755 tests/config/tapered/test/exit-failure-test.lua create mode 100755 tests/config/tapered/test/exit-success-test.lua create mode 100644 tests/config/tapered/test/informational-fields-result.txt create mode 100755 tests/config/tapered/test/informational-fields-test.lua create mode 100644 tests/config/tapered/test/is-isnt-result.txt create mode 100755 tests/config/tapered/test/is-isnt-test.lua create mode 100644 tests/config/tapered/test/like-unlike-result.txt create mode 100755 tests/config/tapered/test/like-unlike-test.lua create mode 100644 tests/config/tapered/test/ok-nok-result.txt create mode 100755 tests/config/tapered/test/ok-nok-test.lua create mode 100644 tests/config/tapered/test/pass-fail-result.txt create mode 100755 tests/config/tapered/test/pass-fail-test.lua create mode 100644 tests/config/tapered/test/result_test03.txt create mode 100755 tests/config/tapered/test/runner.bash create mode 100644 tests/config/tapered/test/same-result.txt create mode 100644 tests/config/tapered/test/same-test.lua create mode 100644 tests/config/tapered/test/setup-teardown-result.txt create mode 100755 tests/config/tapered/test/setup-teardown-test.lua create mode 100644 tests/config/test.cfg create mode 100644 tests/config/test_dns_generators.lua create mode 100644 tests/config/test_utils.lua create mode 100644 tests/config/tls.test.lua create mode 100644 tests/config/worker.test.lua create mode 100644 tests/dnstap/meson.build create mode 100644 tests/dnstap/src/dnstap-test/config create mode 100644 tests/dnstap/src/dnstap-test/main.go create mode 100755 tests/dnstap/src/dnstap-test/run.sh create mode 100644 tests/dnstap/src/dnstap-test/vendor/manifest create mode 100644 tests/integration/deckard/LICENSE create mode 100644 tests/integration/deckard/README.rst create mode 100644 tests/integration/deckard/ci/README.rst create mode 100644 tests/integration/deckard/ci/__init__.py create mode 100644 tests/integration/deckard/ci/common.sh create mode 100755 tests/integration/deckard/ci/compare-rplint.sh create mode 100755 tests/integration/deckard/ci/compare-tests.sh create mode 100755 tests/integration/deckard/ci/junit-compare.py create mode 100755 tests/integration/deckard/ci/mypy-run.sh create mode 100755 tests/integration/deckard/ci/pylint-run.sh create mode 100755 tests/integration/deckard/ci/raw_id.py create mode 100755 tests/integration/deckard/ci/raw_id_check.sh create mode 100755 tests/integration/deckard/ci/runlocally.sh create mode 100644 tests/integration/deckard/configs/getdns.yaml create mode 100644 tests/integration/deckard/configs/knotd_master.yaml create mode 100644 tests/integration/deckard/configs/knotd_slave.yaml create mode 100644 tests/integration/deckard/configs/kresd.yaml create mode 100644 tests/integration/deckard/configs/named.yaml create mode 100644 tests/integration/deckard/configs/pdns.yaml create mode 100644 tests/integration/deckard/configs/unbound.yaml create mode 100644 tests/integration/deckard/conftest.py create mode 100644 tests/integration/deckard/contrib/__init__.py create mode 100644 tests/integration/deckard/contrib/deckard.vim create mode 100644 tests/integration/deckard/contrib/licenses/ISC create mode 100644 tests/integration/deckard/contrib/namespaces.py create mode 100644 tests/integration/deckard/contrib/namespaces.spdx create mode 100755 tests/integration/deckard/deckard.py create mode 100644 tests/integration/deckard/deckard_pytest.ini create mode 100755 tests/integration/deckard/deckard_pytest.py create mode 100644 tests/integration/deckard/doc/devel_guide.rst create mode 100644 tests/integration/deckard/doc/scenario_example.rst create mode 100644 tests/integration/deckard/doc/scenario_guide.rst create mode 100644 tests/integration/deckard/doc/user_guide.rst create mode 100755 tests/integration/deckard/getdns_run.sh create mode 100755 tests/integration/deckard/knotd_master_run.sh create mode 100755 tests/integration/deckard/knotd_slave_run.sh create mode 100755 tests/integration/deckard/kresd_run.sh create mode 100644 tests/integration/deckard/mypy.ini create mode 100755 tests/integration/deckard/named_run.sh create mode 100644 tests/integration/deckard/networking.py create mode 100755 tests/integration/deckard/pdns_run.sh create mode 100644 tests/integration/deckard/pydnstest/__init__.py create mode 100644 tests/integration/deckard/pydnstest/augwrap.py create mode 100644 tests/integration/deckard/pydnstest/deckard.aug create mode 100644 tests/integration/deckard/pydnstest/empty.rpl create mode 100644 tests/integration/deckard/pydnstest/matchpart.py create mode 100644 tests/integration/deckard/pydnstest/mock_client.py create mode 100644 tests/integration/deckard/pydnstest/scenario.py create mode 100644 tests/integration/deckard/pydnstest/tests/__init__.py create mode 100644 tests/integration/deckard/pydnstest/tests/test_parse_config.py create mode 100644 tests/integration/deckard/pydnstest/tests/test_scenario.py create mode 100644 tests/integration/deckard/pydnstest/testserver.py create mode 100644 tests/integration/deckard/pylintrc create mode 100644 tests/integration/deckard/requirements.txt create mode 100755 tests/integration/deckard/rplint.py create mode 100755 tests/integration/deckard/rplint.sh create mode 100644 tests/integration/deckard/rplint_pytest.ini create mode 100755 tests/integration/deckard/run.sh create mode 100644 tests/integration/deckard/sets/knotd/master/example.com.zone create mode 100644 tests/integration/deckard/sets/knotd/master/iter_ns.rpl create mode 100644 tests/integration/deckard/sets/knotd/slave/iter_ns.rpl create mode 100644 tests/integration/deckard/sets/resolver/LICENSE create mode 100644 tests/integration/deckard/sets/resolver/black_data.rpl create mode 100644 tests/integration/deckard/sets/resolver/black_dnskey.rpl create mode 100644 tests/integration/deckard/sets/resolver/black_ds.rpl create mode 100644 tests/integration/deckard/sets/resolver/black_ent.rpl create mode 100644 tests/integration/deckard/sets/resolver/black_prime.rpl create mode 100644 tests/integration/deckard/sets/resolver/fwd_val_cname_sibling.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_badglue.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_badraw.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_cname_badauth.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_cname_cache.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_cname_double.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_cname_nx.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_cname_qnamecopy.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_cycle.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_cycle_noh.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_dname_insec.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_dnsseclame_ds_ok.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_dnsseclame_ta_ok.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_domain_sale.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_domain_sale_nschange.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_donotq127.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_ds_locate_ns.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_ds_locate_ns_nosoa.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_escape_bailiwick.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_hint_lame.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_lame_aaaa.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_lame_noaa.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_lame_nosoa.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_lame_root.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_lamescrub.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_minim_a.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_minim_a_nxdomain.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_minim_nonempty.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_minim_ns.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_minmaxttl.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_mod.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_multiple_A.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_ns_badaa.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_ns_badglue.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_ns_badip.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_ns_noglue.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_ns_spoof.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pc_a.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pc_aaaa.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pcdiff.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pcdirect.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pcname.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pcnamech.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pcnamechrec.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pcnamerec.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_pcttl.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_reclame_one.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_reclame_two.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_recurse.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_req_qname.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_resolve.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_tcbit.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_timeouted_ns.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_unexpectedrrtype.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_validate.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_validate_child_zone_noaddr.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_validate_extradata.rpl create mode 100644 tests/integration/deckard/sets/resolver/iter_validate_nsec_nxdomain.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_dns64.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_hint_static.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_policy_deny_all.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_policy_deny_suff_comm.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_policy_deny_suff_patt.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_policy_drop.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_policy_forward.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_policy_pass_deny.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_policy_tc.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_renumber.rpl create mode 100644 tests/integration/deckard/sets/resolver/module_workarounds_disable_0x20.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec3_aggr_cache.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec3_wildcard_no_data_response.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_aggr_cache.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_name_error_response-part2.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_name_error_response.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_no_data_response.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned1.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned2.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_ref_to_unsigned3.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.key create mode 100644 tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/K.+008+41524.private create mode 100644 tests/integration/deckard/sets/resolver/nsec_wildcard_answer_response/root.zone create mode 100644 tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response-part2.rpl create mode 100644 tests/integration/deckard/sets/resolver/nsec_wildcard_no_data_response.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ad_qtype_ds.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_adbit.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_adcopy.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_anchor_nx_nosig.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ans_dsent.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ans_nx.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_bogus_nodata.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_loop1.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_loop1_3.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_loop3.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_new_signer.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_oob.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_to_unsigned.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_to_unsigned_fake_rrsig.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cname_trust_domains.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cnamenx_dblnsec.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_cnameqtype.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_deleg_nons.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_dname.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_dname_bogus.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ds_afterprime.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ds_cname.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ds_cnamesub.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_faildnskey.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_iter_high.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_mal_wc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_anotherdomainsignature.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_anotherrrtypesignature.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_baddnskeyalgorithm.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_baddnskeyflags.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_baddnskeyprotocol.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_baddsalgorithm.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_baddsdigest.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_baddsdigesttype.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_baddskeytag.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badpublickey.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badrrsigalgorithm.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badrrsigexpiration.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badrrsiginception.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badrrsiglabels.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badrrsigsignature.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badrrsigtag.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_badrrsigttl.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_beforeinception.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_expiredsignature.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_minimal_noerror.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_negcache_ds.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_noadwhennodo.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nodata_hasdata.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nodata_zonecut.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nodatawc_badce.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nokeyprime.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_noce.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nonc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b1_nameerror_nowc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b21_nodataent_wr.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b2_nodata_nons.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b3_optout.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_negcache.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_noce.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b3_optout_nonc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b4_wild.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_noce.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nonc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_b5_wcnodata_nowc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_cnametocnamewctoposwc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_entnodata_optout_badopt.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_nods_badsig.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_nods_soa.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_noopt_ref.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_optout_ad.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_optout_ns_ad.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nsec3_optout_unsec_cache.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nx.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nx_nodeny.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_nx_nowc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_pos_truncns.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_positive_nosigs.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_qds_oneanc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_qds_twoanc.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_referral_nods.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_root_ds.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_rrsig.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_secds.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_secds_nosig.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ta_sentinel.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.key create mode 100644 tests/integration/deckard/sets/resolver/val_ta_sentinel/K.+008+48409.private create mode 100644 tests/integration/deckard/sets/resolver/val_ta_sentinel/root.db create mode 100644 tests/integration/deckard/sets/resolver/val_ta_sentinel_insecure.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_ta_sentinel_nokey.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_unalgo_ds.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.key create mode 100644 tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/K.+008+17002.private create mode 100644 tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/root_unknown_ds_algo_and_digest.db create mode 100644 tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test.db create mode 100644 tests/integration/deckard/sets/resolver/val_unknown_algorithm_insecure/test2.db create mode 100644 tests/integration/deckard/sets/resolver/val_unsecds.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_unsecds_negcache.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_unsecds_qtypeds.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_wild_pos.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_wild_pos_multi.rpl create mode 100644 tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.key create mode 100644 tests/integration/deckard/sets/resolver/val_wild_pos_multi/K.+008+41524.private create mode 100644 tests/integration/deckard/sets/resolver/val_wild_pos_multi/dsset-. create mode 100644 tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone create mode 100644 tests/integration/deckard/sets/resolver/val_wild_pos_multi/root.zone.signed create mode 100644 tests/integration/deckard/sets/resolver/world_cz_lidovky_www.rpl create mode 100644 tests/integration/deckard/sets/resolver/world_cz_rhybar.rpl create mode 100644 tests/integration/deckard/sets/resolver/world_cz_turris_api.rpl create mode 100644 tests/integration/deckard/sets/resolver/world_cz_vutbr_www.rpl create mode 100644 tests/integration/deckard/sets/resolver/world_mx_nic_www.rpl create mode 100644 tests/integration/deckard/setup.py create mode 100644 tests/integration/deckard/template/dnssec_getdns.j2 create mode 100644 tests/integration/deckard/template/getdns.j2 create mode 100644 tests/integration/deckard/template/hints_zone.j2 create mode 100644 tests/integration/deckard/template/knotd_master.j2 create mode 100644 tests/integration/deckard/template/knotd_slave.j2 create mode 100644 tests/integration/deckard/template/kresd.j2 create mode 100644 tests/integration/deckard/template/named.j2 create mode 100644 tests/integration/deckard/template/pdns_dnssec.j2 create mode 100644 tests/integration/deckard/template/pdns_recursor.j2 create mode 100644 tests/integration/deckard/template/unbound.j2 create mode 100644 tests/integration/deckard/template/unbound_dnssec.j2 create mode 100644 tests/integration/deckard/tests/__init__.py create mode 100644 tests/integration/deckard/tests/deckard_raw_id.rpl create mode 100644 tests/integration/deckard/tests/deckard_raw_id.yml create mode 100644 tests/integration/deckard/tests/test_deckard.py create mode 100644 tests/integration/deckard/tools/answer_checker.py create mode 100644 tests/integration/deckard/tools/conftest.py create mode 100644 tests/integration/deckard/tools/divide_tests.sh create mode 100644 tests/integration/deckard/tools/forwarder_check.py create mode 100644 tests/integration/deckard/tools/generate_answers.py create mode 100644 tests/integration/deckard/tools/invalid_dsa.py create mode 100644 tests/integration/deckard/tools/network_check.py create mode 100644 tests/integration/deckard/tools/parse.py create mode 120000 tests/integration/deckard/tools/pydnstest create mode 100755 tests/integration/deckard/unbound_run.sh create mode 100644 tests/integration/hints_zone.j2 create mode 100644 tests/integration/meson.build create mode 100644 tests/integration/testdata_notimpl/iter_class_any.rpl create mode 100644 tests/integration/testdata_notimpl/iter_dnsseclame_bug.rpl create mode 100644 tests/integration/testdata_notimpl/iter_dnsseclame_ds.rpl create mode 100644 tests/integration/testdata_notimpl/iter_dnsseclame_ds_ok.rpl create mode 100644 tests/integration/testdata_notimpl/iter_dnsseclame_ta.rpl create mode 100644 tests/integration/testdata_notimpl/iter_dnsseclame_ta_ok.rpl create mode 100644 tests/integration/testdata_notimpl/iter_dp_turnsuseless.rpl create mode 100644 tests/integration/testdata_notimpl/iter_ds_locate_ns.rpl create mode 100644 tests/integration/testdata_notimpl/iter_ds_locate_ns_cname.rpl create mode 100644 tests/integration/testdata_notimpl/iter_ds_locate_ns_detach.rpl create mode 100644 tests/integration/testdata_notimpl/iter_ds_locate_ns_nosoa.rpl create mode 100644 tests/integration/testdata_notimpl/iter_emptydp.rpl create mode 100644 tests/integration/testdata_notimpl/iter_emptydp_for_glue.rpl create mode 100644 tests/integration/testdata_notimpl/iter_fwdfirst.rpl create mode 100644 tests/integration/testdata_notimpl/iter_fwdfirstequal.rpl create mode 100644 tests/integration/testdata_notimpl/iter_fwdstub.rpl create mode 100644 tests/integration/testdata_notimpl/iter_fwdstubroot.rpl create mode 100644 tests/integration/testdata_notimpl/iter_got6only.rpl create mode 100644 tests/integration/testdata_notimpl/iter_pcdiff.rpl create mode 100644 tests/integration/testdata_notimpl/iter_pcnamerec.rpl create mode 100644 tests/integration/testdata_notimpl/iter_primenoglue.rpl create mode 100644 tests/integration/testdata_notimpl/iter_privaddr.rpl create mode 100644 tests/integration/testdata_notimpl/iter_ranoaa_lame.rpl create mode 100644 tests/integration/testdata_notimpl/iter_scrub_cname_an.rpl create mode 100644 tests/integration/testdata_notimpl/iter_scrub_dname_insec.rpl create mode 100644 tests/integration/testdata_notimpl/iter_scrub_dname_sec.rpl create mode 100644 tests/integration/testdata_notimpl/iter_scrub_ns.rpl create mode 100644 tests/integration/testdata_notimpl/iter_scrub_ns_fwd.rpl create mode 100644 tests/integration/testdata_notimpl/iter_scrub_ns_side.rpl create mode 100644 tests/integration/testdata_notimpl/iter_stub_noroot.rpl create mode 100644 tests/integration/testdata_notimpl/iter_stubfirst.rpl create mode 100644 tests/integration/testdata_notimpl/iter_stublastresort.rpl create mode 100644 tests/integration/testdata_notimpl/iter_timeout_ra_aaaa.rpl create mode 100644 tests/meson.build create mode 100644 tests/packaging/README.rst create mode 100644 tests/packaging/conftest.py create mode 100644 tests/packaging/test_packaging.py create mode 100644 tests/pytests/README.rst create mode 100755 tests/pytests/certs/tt-certgen-expired.sh create mode 100755 tests/pytests/certs/tt-certgen.sh create mode 100644 tests/pytests/certs/tt-expired.cert.pem create mode 100644 tests/pytests/certs/tt-expired.key.pem create mode 100644 tests/pytests/certs/tt.cert.pem create mode 100644 tests/pytests/certs/tt.conf create mode 100644 tests/pytests/certs/tt.key.pem create mode 100644 tests/pytests/conftest.py create mode 100644 tests/pytests/conn_flood.py create mode 100644 tests/pytests/kresd.py create mode 100644 tests/pytests/meson.build create mode 100644 tests/pytests/proxy.py create mode 100644 tests/pytests/proxy/tls-proxy.c create mode 100644 tests/pytests/proxy/tls-proxy.h create mode 100644 tests/pytests/proxy/tlsproxy.c create mode 100644 tests/pytests/pylintrc create mode 100644 tests/pytests/requirements.txt create mode 100644 tests/pytests/templates/kresd.conf.j2 create mode 100644 tests/pytests/test_conn_mgmt.py create mode 100644 tests/pytests/test_edns.py create mode 100644 tests/pytests/test_prefix.py create mode 100644 tests/pytests/test_random_close.py create mode 100644 tests/pytests/test_rehandshake.py create mode 100644 tests/pytests/test_tls.py create mode 100644 tests/pytests/utils.py create mode 100644 tests/unit/meson.build create mode 100644 tests/unit/mock_cmodule.c create mode 100644 tests/unit/packaging/debian/10/builddeps create mode 100755 tests/unit/packaging/test.sh create mode 100644 tests/unit/test.h create mode 100644 utils/cache_gc/.gitignore create mode 100644 utils/cache_gc/README.rst create mode 100644 utils/cache_gc/categories.c create mode 100644 utils/cache_gc/categories.h create mode 100644 utils/cache_gc/db.c create mode 100644 utils/cache_gc/db.h create mode 100644 utils/cache_gc/kr_cache_gc.c create mode 100644 utils/cache_gc/kr_cache_gc.h create mode 100644 utils/cache_gc/main.c create mode 100644 utils/cache_gc/meson.build create mode 100644 utils/cache_gc/test.integr/deckard.yaml create mode 100644 utils/cache_gc/test.integr/val_rrsig.rpl create mode 100644 utils/client/kresc.c create mode 100644 utils/client/meson.build create mode 100644 utils/meson.build create mode 100644 utils/upgrade/meson.build create mode 100644 utils/upgrade/upgrade-4-to-5.lua.in 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 +Alex Forster +Ali Asad Lotia +Anbang Wen +Anbang Wen +Andreas Rammhold +Daniel Kahn Gillmor +Daniel Salzman +daurnimator +David Beitey +Grigorii Demidov +Hasnat +Jiří Helebrant +Ivana Krumlová +Jakub RužiÄka +Jan Hák +Jan HoluÅ¡a +Jan Pavlinec +Jan VÄelák +Jan VÄelák +Jayson Reis +Jonathan Coetzee +Josh Soref +Karel Slaný +Libor Peltan +Lukáš Ježek +Manu Bretelle +Marek VavruÅ¡a Marek Vavrusa +Marek VavruÅ¡a Marek VavrusÌŒa +Marek VavruÅ¡a Marek VavrusÌŒa +Marek VavruÅ¡a +Marek VavruÅ¡a +Michal Karm BabáÄek +Michal LupeÄka +OndÅ™ej Surý +Oto Šťáva +Paul Hoffman +Paul Hoffman +Pavel Doležal +Pavel Valach +Petr Å paÄek +rickhg12hs +Robert Å efr +SH +Simon South +Å tÄ›pán Balážik +Å tÄ›pán Kotek Stepan Kotek +Å tÄ›pán Kotek +The Gitter Badger +Tomáš Hozza +Tomáš Křížek +Ulrich Wisser +Leo Vandewoestijne +VaÅ¡ek Å raier +Vicky Shrestha +VítÄ›zslav Kříž +Vladimír ÄŒunát 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 +Alex Forster +Ali Asad Lotia +Anbang Wen +Andreas Rammhold +Christophe Nowicki +cronfy +Daniel Kahn Gillmor +Daniel Salzman +daurnimator +David Beitey +Grigorii Demidov +Hasnat +Héctor Molinero Fernández +Ivana Krumlová +Jakub Jirutka +Jakub RužiÄka +Jan Hák +Jan HoluÅ¡a +Jan Pavlinec +Jan VÄelák +Jayson Reis +Jiří Helebrant +Jonathan Coetzee +Josh Soref +Karel Slaný +Konstantin Amelichev +Leo Vandewoestijne +Libor Peltan +Lukáš Ježek +Manu Bretelle +Marek VavruÅ¡a +Michal Karm BabáÄek +Michal LupeÄka +OndÅ™ej Surý +Oto Šťáva +Paul Hoffman +Pavel Doležal +Pavel Valach +Peter Keresztes Schmidt +Petr Å paÄek +realPy +rickhg12hs +Robert Å efr +SH +Simon South +Å tÄ›pán Balážik +Å tÄ›pán Kotek +The Gitter Badger +Tomáš Hozza +Tomáš Křížek +Tom Herbers +Ulrich Wisser +VaÅ¡ek Å raier +Vicky Shrestha +VítÄ›zslav Kříž +Vladimír ÄŒunát + +Knot Resolver source tree also bundles code and content published by: +Austin Appleby +Dan Vanderkam +Jonathan Allard +Joseph A. Adams +Mark DiMarco +Michael Bostock +Rusty Russell +Thomas Park +Vincent Bernat +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. + 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. + + + Copyright (C) + + 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 . + +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: + + Copyright (C) + 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 +. + + 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 +. + + 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 = 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include + +#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 [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||\n|g' -i "$@" +sed -e '//,/<\/testcase>/s/<\(\/\?\)system-\(out\|err\)>/<\1failure>/g' \ + -e 's///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 +# >= 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 +# >= 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 +# >= 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 '\' -- $(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 '' -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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "base32hex.h" + +#include +#include + +/*! \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. + * 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 + +/*! + * \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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "base64.h" +#include "libknot/errcode.h" + +#include +#include + +/*! \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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ +/*! + * \file + * + * \brief Base64 implementation (RFC 4648). + * + * \addtogroup contrib + * @{ + */ + +#pragma once + +#include + +/*! + * \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. + + 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 . + */ + +#include "contrib/base64url.h" +#include "libknot/errcode.h" + +#include +#include +#include + +/*! \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. + + 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 . + */ + +/*! + * \brief Base64url implementation (RFC 4648). + */ + +#pragma once + +#include + +/*! + * \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 +#include +#include + +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 +#include + +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 + +/** + * 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 +#else +#include +/** + * 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 +#include +#include +#include +#include + +#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 +#include +#include + +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. + * SPDX-License-Identifier: GPL-3.0-or-later +*/ +/** + * Cleanup attributes. + * @cond internal + */ +#pragma once +#include +#include +#include + +#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. + * 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 +#include + +#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. + + + Copyright (C) + + 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. + + , 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. + + 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 . + */ + +#include + +#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. + + 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 . + */ + +/*! + * \brief Memory allocation related functions. + */ + +#pragma once + +#include +#include "contrib/ucw/mempool.h" +#include "lib/defines.h" +#include +#include + +/*! \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 +#include + +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 + * 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 <>, <> and <>. The memory + * it allocates is left uninitialized. + **/ +extern struct ucw_allocator ucw_allocator_std; + +/** + * [[zeroing]] + * This allocator uses <>, <> and <>. 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 + * (c) 2006 Robert Spalek + * + * 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 +#include + +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 + * (c) 2005--2014 Tomas Valla + * (c) 2006 Robert Spalek + * (c) 2007 Pavel Charvat + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * Source: https://www.ucw.cz/libucw/ + */ + +#ifndef _UCW_LIB_H +#define _UCW_LIB_H + +#include +#include +#include + +#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 <> and 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 + * (c) 2007 Pavel Charvat + * SPDX-License-Identifier: LGPL-2.1-or-later + * Source: https://www.ucw.cz/libucw/ + */ + +#include +#include + +#include +#include + +/* 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, "", "World"); + fputs(x, stdout); + x = mp_printf_append(mp, x, ""); + fputs(x, stdout); + x = mp_printf(mp, "\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 + * (c) 2007--2015 Pavel Charvat + * + * SPDX-License-Identifier: LGPL-2.1-or-later + * Source: https://www.ucw.cz/libucw/ + */ + +#undef LOCAL_DEBUG + +#include +#include +#include +#include + +#include +#include + +/* 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 +#include +#include +#include + +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 + * (c) 2007 Pavel Charvat + * 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 +#include +#include +#include + +#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 <>, see <>. + **/ +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 <>, see <>. + **/ +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 <>. + * 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 <> 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 <>`(@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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +/** 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. + * 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 `. + + 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 ` 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "daemon/bindings/impl.h" + +#include +#include + +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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include + + +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 ""; + 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "daemon/engine.h" +#include "daemon/worker.h" /* the_worker is often useful */ + +#include +#include +/* 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 . */ +#if (LUA_VERSION_NUM) != 501 || !defined(LUA_LJDIR) + #error "Incorrect Lua version in #include - 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. + * 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. + * 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 + +#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 = ): %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 `_. Further details can be found at `DNS Flag Day 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 `)","``xdp``" + ":ref:`dns-over-tls`","``tls``" + ":ref:`dns-over-https`","``doh2``" + ":ref:`Web management `","``webmgmt``" + ":ref:`Control socket `","``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 `)","``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 `","``net.listen('192.0.2.123', 8453, { kind = 'webmgmt' })``" + ":ref:`Control socket `","``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 `_ +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 ` 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.`` 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 `_ + or `the article itself `_. + +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 +`_. + +.. _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 `_ and `More DOH + `_ by Geoff Huston and + `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 `_. + + .. 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 `_. 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 rx-flow-hash udp4 sdfn + ethtool -N rx-flow-hash udp6 sdfn + ethtool -L combined + ethtool -G rx tx + 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 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. + * 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 ` (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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "lib/defines.h" +#include "lib/layer.h" +#include +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 + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include + +#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 + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include + +#if ENABLE_DOH2 +#include +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "daemon/io.h" + +#include +#include +#include +#include +#include + +#if ENABLE_XDP + #include + #include + #include +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include +#include +#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/; s/\/_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 ' }, + { 'tname': 'struct timeval', 'incl' : '#include ' }, + { 'tname': 'zs_scanner_t', 'incl': '#include ', 'dep': libzscanner }, + { 'tname': 'knot_pkt_t', 'incl' : '#include ', '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.` => `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. = ` +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]+).->([^<]+)", 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, '', 1) + assert_str_match(xml, '.', 1) + assert_str_match(xml, '', 1) + + -- Parse root trust anchor, one digest at a time, converting to a zone-file-style string. + local keydigests = {} + string.gsub(xml, "]*)>(.-)", 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 @@ + + +. + +19036 +8 +2 +49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 + + +20326 +8 +2 +E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D + + 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 @@ + + +. + +19036 +8 +2 +49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 + + +20326 +8 +2 +E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D + + 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 @@ + + +. + +19036 +8 +2 +49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 + + +20326 +8 +2 +E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D + + 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 @@ + + +. + +19036 +8 +2 +49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 + + +20326 +8 +2 +E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D +E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D + + 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 @@ + + +. + +19036 +8 +2 +49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5 + + +20326 +8 + +E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D + + 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 @@ + + +. + +2 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + + +test. + +2 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + 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 @@ + + +. + +1 +8 +2 +EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE + + +2 +8 +2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + + 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 @@ + + +. + +2 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + 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 @@ + + +. + +1 +8 +2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + + +2 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + 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 @@ + + +. + +1 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + +2 +8 +2 +FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF + + 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 @@ + + +. + +1 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + +2 +8 +2 +2222222222222222222222222222222222222222222222222222222222222222 + + 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 @@ + + +test. + +2 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + 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 @@ + + +. + +2 +8 +2 +1111111111111111111111111111111111111111111111111111111111111111 + + 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 + +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. + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#if ENABLE_CAP_NG +#include +#endif + +#include +#include +#if ENABLE_LIBSYSTEMD +#include +#endif +#include + +#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 +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 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. + * 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 +#endif + +#include +#include +#include +#include + +/** 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. + * 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 +#include + +#include +#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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#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() + `_ 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#include +#include +#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 + * OndÅ™ej Surý + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include + +#include +#include + +#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, ¶m_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 +#include +#include +#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(¶ms, 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 + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#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. + * 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 + + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "kresconfig.h" +#include "daemon/worker.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#if defined(__GLIBC__) && defined(_GNU_SOURCE) +#include +#endif +#include +#include +#include + +#if ENABLE_XDP + #include +#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. + * 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. + * 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 /* PRIu64 */ +#include +#include +#include +#include +#include + +#include +#include + +#include +#define ENABLE_ZONEMD (KNOT_VERSION_HEX >= 0x030100) +#if ENABLE_ZONEMD + #include + + #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 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#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 +# Contributor: OndÅ™ej Surý +# 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 {{ 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 +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 + 2006-2009 Stefan Metzmacher + 2013 Andreas Schneider +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 + 2016 Paul Miller + 2011 Robert Konigsberg + 2013 David Eberlein +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ý +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 . + . + 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 . + . + 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 < 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 {}; + +(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 - {{ 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 diff --git a/doc/.packaging/centos/8/NOTSUPPORTED b/doc/.packaging/centos/8/NOTSUPPORTED new file mode 100644 index 0000000..e69de29 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 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 @@ + + + + + + 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 ``_. + +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 `_ +-- Linux on x86_64 is unaffected but `Linux on aarch64 is +`_. + +.. 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 ``_CFLAGS`` and ``_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 + `_. + +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 `_, search for "Build-Depends". + +* **CentOS/Fedora/RHEL/openSUSE** - Fresh list of dependencies can be found in `RPM spec file in our repo `_, 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 `_. + +Compilation +----------- + +.. note:: + + Knot Resolver uses `Meson Build system `_. + Shell snippets below should be sufficient for basic usage + but users unfamiliar with Meson Build might want to read introductory + article `Using Meson `_. + +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 + `_. + +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 +`_. 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 ``_ + +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 +`_ 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 `_. + +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 `. 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 ` or as :ref:`an HTTP service `. + +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 ` + :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 Binary files /dev/null and b/doc/flowcharts/io_and_worker.dia differ diff --git a/doc/flowcharts/task_ERD.dia b/doc/flowcharts/task_ERD.dia new file mode 100644 index 0000000..2bc065b Binary files /dev/null and b/doc/flowcharts/task_ERD.dia differ diff --git a/doc/flowcharts/tcp_task.dia b/doc/flowcharts/tcp_task.dia new file mode 100644 index 0000000..6ad58f3 Binary files /dev/null and b/doc/flowcharts/tcp_task.dia differ diff --git a/doc/flowcharts/udp_task.dia b/doc/flowcharts/udp_task.dia new file mode 100644 index 0000000..6fb8628 Binary files /dev/null and b/doc/flowcharts/udp_task.dia 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 +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 +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 +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 +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 +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 +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 `_. +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 ` which combines query source information with :ref:`policy rules `. +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 `: + +.. 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 `_, `the article itself `_) + - `Bert Hubert. 2019. 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 ` 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 `, 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 + +

Next steps

+ +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 `_ package repository `home:CZ-NIC:knot-resolver-latest `_ 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 Binary files /dev/null and b/doc/resolution.png 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 @@ + + + + Petr Å paÄek2020-01-09T14:38:06.40621582518PT27M21S2020-02-14T17:28:07.033132897Petr Å paÄekLibreOffice/6.4.0.3$Linux_X86_64 LibreOffice_project/40$Build-3Basic DNS terminologySPDX-License-Identifier: GPL-3.0-or-later + + + 2884 + -318 + 23019 + 23865 + + + view1 + false + false + true + true + false + false + false + false + true + 1500 + false + Hw== + Hw== + + false + true + true + 0 + 0 + true + true + true + 4 + 0 + 2884 + -318 + 23020 + 23866 + 1000 + 1000 + 100 + 100 + 100 + 1 + 100 + 1 + false + 1500 + false + false + + + + + true + $(brandbaseurl)/share/palette%3B$(user)/config/standard.sob + 0 + $(brandbaseurl)/share/palette%3B$(user)/config/standard.soc + $(brandbaseurl)/share/palette%3B$(user)/config/standard.sod + 1250 + true + true + false + true + false + + + cs + CZ + + + + + + $(brandbaseurl)/share/palette%3B$(user)/config/standard.sog + $(brandbaseurl)/share/palette%3B$(user)/config/standard.soh + false + false + true + true + false + false + true + false + false + false + $(brandbaseurl)/share/palette%3B$(user)/config/standard.soe + false + 3 + 4 + false + 0 + low-resolution + HP_LaserJet_M2727nf_MFP + false + 1wH+/0hQX0xhc2VySmV0X00yNzI3bmZfTUZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQ1VQUzpIUF9MYXNlckpldF9NMjcyN25mX01GUAAAAAAWAAMA8wAAAAAAAAAEAAhSAAAEdAAASm9iRGF0YSAxCnByaW50ZXI9SFBfTGFzZXJKZXRfTTI3MjduZl9NRlAKb3JpZW50YXRpb249UG9ydHJhaXQKY29waWVzPTEKY29sbGF0ZT1mYWxzZQptYXJnaW5kYWp1c3RtZW50PTAsMCwwLDAKY29sb3JkZXB0aD0yNApwc2xldmVsPTAKcGRmZGV2aWNlPTEKY29sb3JkZXZpY2U9MApQUERDb250ZXhEYXRhClBhZ2VTaXplOkE0AER1cGxleDpEdXBsZXhOb1R1bWJsZQBIUEVjb25vTW9kZTpGYWxzZQBJbnB1dFNsb3Q6QXV0bwAAEgBDT01QQVRfRFVQTEVYX01PREUUAER1cGxleE1vZGU6OkxvbmdFZGdl + true + false + 1 + 1 + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 + + + + + iVBORw0KGgoAAAANSUhEUgAAAD0AAABWCAYAAAB8UZ5wAAABO0lEQVR4nO2Z7Q6CMAxFJeH9 + XxmtyUzFgRtf2t5zfikjccduDnvHaZpuaoz+zTAMab+BR3GH8volnVnYML8iPpYLv53SNRTx + sTbol0Jklor5IZ1F2DCXmni10tlBWoVm6fnemO/9s8ePhEpHw6+OnpURWnorSEdj649ds/S3 + Dzh7/EhCV3orSKuAtKHQUKDSKjyllzoM2XhrDPoLhSv/6h1Bz3x1l7cazUdWtD1f5ltb5ulj + nZo8sU52iHU8WYQNYh0H0ioQ66gQWlou1tnzQBVWek/jI6y0QazTQehKbwVpFZA2FBoKVFoF + Yh1/A7FOMpA2iHUSQKxDrDPj34+nVoh1HBxZKiC9BrFOcEJLE+t0EFaaWKcTYh0VkFYBaUOh + oUClVSDW8TcQ6yQD6TUy7XkqrQLSnn8/ovZwB2IfDVe+8hdvAAAAAElFTkSuQmCC + + + data, server, database, router, hardware + + + + authoritativeserver + + + + + + + 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 + + + + + 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= + + + + + + Knot Resolver + + + + + + + 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 + + + + + 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= + + + data, server, database,db, hosting + + + + upstreamresolver + + + + + + + client + + + + + 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 + + + + + iVBORw0KGgoAAAANSUhEUgAAAEcAAABDCAYAAADOIRgJAAABJklEQVR4nO3ZyRKCMBAAUVPF + //8yGk8WhGadJGD3wZO4PMcQimEcx5eVG/JDSkmhSZ+hSUPrD9Fz4kAznDxOLT5I60pLi5MD + iQOJA63iPPU0v2VtdXIgcSBxoN04d90HHVk7nRxIHEgcSBxIHEgcSBxIHEgcSBxIHEgcSBxI + HEgcSBxIHEgcSBxIHEgcSBxoN85Tbw+XcnIgcSBxoFWcu97+vSInBxIHEgea4fzTPmYtJwcS + BxIH+uLU3MtM17Sl9976vMicHEgcSBxIHEgcSByoOU7PlytVcc5A5GNr73Wq4Fw1Hb+vUwMq + HCfqb1NjkkJxSjBHv1CLtanqmnPml87HToGipycMJ+LCsQQUWfNTec9Vw+l5P7OUkwOJA4kD + heE84TbyGynKUBIg/xD7AAAAAElFTkSuQmCC + + + data, server, database, monitor, terminal + + + + + + + + + + + + + + recursion + unencrypted DNS + + + + + (optional) + forwarding + unencrypted DNS + DNS-over-TLS + + + + + + + + + recursion + + + + + + client asking questions + unencrypted DNSDNS-over-TLSDNS-over-HTTPS + HTTP management API + + + + + + + + + + + ... as server + + + + + ... as client + + + + + + \ 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 @@ + +image/svg+xml + + + + + + + + + + + + + + + + + + + + + + data, server, database, router, hardware + + + + + + + + + + + + + + + + + + + + + + + + + authoritativeserver + + + + + + + + + + + + + + + + + + + + Knot Resolver + + + + + + + data, server, database,db, hosting + + + + + + + + + + + + + + + + + + + upstreamresolvers + + + + + + + + + clients + + + + + data, server, database, monitor, terminal + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + recursionunencrypted DNS + + + + + + + (optional)forwardingunencrypted DNSDNS-over-TLS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + recursion + + + + + + + + clients asking questionsunencrypted DNSDNS-over-TLSDNS-over-HTTPSHTTP management API + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ... as server + + + + + + + ... as client + + + + + + + + + \ 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 + `_. + 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 ` (``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 `_ 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 `. + 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 `_ + 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 `_. +* 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 `_. +* 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 `_; + 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 + `_). 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 + `_. + +.. _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 ` 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 `_. + +.. _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 . " +; 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 ` 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 `, 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 ` 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 ` documentation for the complete overview of the services. + +The library offers following services: + +- :ref:`Cache ` - MVCC cache interface for retrieving/storing resource records. +- :ref:`Resolution plan ` - 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 ` - 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 ` 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 ` 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#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 = ""; + } 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include +#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. + * SPDX-License-Identifier: GPL-3.0-or-later +*/ + +#pragma once + +#include + +#include + +/* 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. + * SPDX-License-Identifier: GPL-3.0-or-later +*/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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. + * 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. + * 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. + * 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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Header internal for cache implementation(s). + * Only LMDB works for now. + */ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include + +#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. + * 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. + * 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. + * 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 + +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. + * 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 + +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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include + +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include + +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include + +#if ENABLE_COOKIES +#include +#include +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include +#include +#include + +/* 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "lib/defines.h" +#include "lib/utils.h" +#include + +/** + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#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(¶ms, 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, ¶ms, 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(¶ms); + 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(¶ms, nsec3); + if (ret != 0) + goto fail; + + ret = hash_name(&name_hash, ¶ms, 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(¶ms); + 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(¶ms, nsec3); + if (ret != 0) + goto fail; + + ret = hash_name(&name_hash, ¶ms, 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(¶ms); + 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +/** 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include + +/** + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include "lib/defines.h" +#include "lib/generic/trie.h" +#include + +/** + * 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. + * 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 + +/** 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. + * 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. + * 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 +#include +#include + +#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. + * 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 +#include +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "lib/generic/queue.h" +#include + +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. + * 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 +#include +#include +#include + +/** @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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include + +#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. + * 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. + * 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. + * 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. + * 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 +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include + +#include +#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. + * 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. + * 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. + * 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 +#include + +#include +#include +#include +#include + +#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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "kresconfig.h" + +#include +#include +#include +#include "contrib/ucw/mempool.h" +#include "lib/log.h" +#include "lib/resolve.h" + +#if ENABLE_LIBSYSTEMD +#include +#include +#include +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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include + +#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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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, ×tamp); + 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 = ¶m->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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include + +#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. + * 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. + * 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. + * 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. + * 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. + * 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. + * 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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include + +#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. + * 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 +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#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[] = ""; + 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 "#". + * \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 "#". + * 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. + * 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 +#include +#include + +#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. + * 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 ') + +### 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 ') +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 `" + "``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 `_, 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 `. + +.. 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 `). + +.. 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 `). +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 +#include +#include +#include + +#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: , name: , type: }, ... ] + */ +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 `_ 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include + +#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. + * 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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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. + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include + +#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. + * 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 ` 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/", "GET", "Retrieve a rule matching given ID." + "/daf/", "DELETE", "Delete a rule matching given ID." + "/daf///", "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(''+item.text+''); + } else if (dafg.action[key]) { + var item = parseOption([key].concat(tok)); + res.push(''+item.text+''); + tok.splice(0, tok.length); + } else if (dafg.conj[key]) { + var item = parseOption([key]); + res.push(''+item.text+''); + } + } + 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( + '' + ); + }, + }); +} + +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 = $(''); + row.append('' + formatRule(rule.info) + ''); + row.append('' + rule.count + ''); + row.append(''); + row.append('' + + '
' + + '' + + '' + + '
'); + 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('RuleMatchesRate') + 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 '
' + escape(item.text) + ''; + }, + }, + }); + /* 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( + '' + ); + }); + }); +}); 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 ' ' + 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 = +-- rule = | +-- action = PASS | DENY | DROP | TC | FORWARD +-- query = +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', [[ + +
+
+
+ +
+
+ +
+
+
+
+
+ + +
No rules here yet.
+
+
+ ]]} +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 `. + +.. 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 `_ 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 +#include +#include +#include +#include + +#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. + * 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 +#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 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 `_ 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 `_. + +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 `_ 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 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 `_ 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 + +#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 `_ 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 ` 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 ` + (e.g. :ref:`forwarding actions ` 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. + * 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 +#include +#include +#include +#include +#include + +#include "daemon/engine.h" +#include "lib/zonecut.h" +#include "lib/module.h" +#include "lib/layer.h" + +#include +#include + +/* 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 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 ` 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 `_? + +.. 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 ` from :ref:`mod-stats` in JSON format." + "``/metrics``", "Prometheus metrics", "Exported metrics for Prometheus_." + "``/trace/:name/:type``", "Tracking", ":ref:`Trace resolution ` 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 `_ (>= 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 `_ 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 `_. + +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', '

UP!

'} + +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 + * 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 +#ifndef NO_OPENSSL_102_SUPPORT +# include +#endif /* ! NO_OPENSSL_102_SUPPORT */ +#include +#include +#include +#include +#include + +#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('

%s

\n%s
', 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//' + 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 ` 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&&jdocument.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
',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-mo.width?"left":"left"==h&&k.left-lg.top+g.height&&(e.top=g.top+g.height-i)}else{var j=b.left-f,k=b.left+f+c;jg.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:''}),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[a]&&(void 0===e[a+1]||b .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;++ue;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])&&++t0&&(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.t8?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;++aa;){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;++e68?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=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])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];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&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)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?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]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)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(ga(b[0]-w)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)0?0:3:ga(r[0]-e)0?2:1:ga(r[1]-t)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)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)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)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?{x:f,y:ga(t-f)Ca?{x:ga(e-p)Ca?{x:h,y:ga(t-h)Ca?{x:ga(e-g)=-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.yd||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.yr||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.yg){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.xi||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 ir;++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]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=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;++oe;++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.ro;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=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]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++0;h--)o.push(i(l)*h);for(l=0;o[l]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;++oe?[0/0,0/0]:[e>0?a[e-1]:n[0],et?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);++f1&&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]];++t1){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;l9&&(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;++ur)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]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=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(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(;++o1?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=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)=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=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=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=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(;++uu){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;++rr;++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);++ii;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=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;++tn;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;++ar){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++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;++rn?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]:nyc?(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=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,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.xm&&(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=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;++ea*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(;++e0?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;++at;++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;++lf?-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;++i0)for(i=-1;++i=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.xp.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;++ut?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;++oe&&(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);++ie.dx)&&(s=e.dx);++ie&&(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;++ai;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]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="
",d="";b.legendTitle&&(c="

"+b.legendTitle+"

"+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+="
"+d+"
",c+='
 
'}c+="
",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'
'+a.properties.name+"
"},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'
'+b.name+"
"},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;d1)for(var a=1;a=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=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;ai&&(l=i),hr)&&(r=h),(null===n||l=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;rr)&&(r=i),(null===n||i=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_;x0;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;a2&&!t){var r=0;2==e[0][0]&&r++;for(var o=null,s=null,a=r;ae[s][2]&&(s=a)}}var h=e[o],u=e[s];e.splice(r,e.length-r),os?(e.push(u),e.push(h)):e.push(h)}}},o=function(a){r(a);for(var o=0,s=e.length;o1,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=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;ia.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=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=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),l1&&(a.startTimeForDoubleTapMs=null);for(var i=[],n=0;n=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=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 ta?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=0&&i<1&&this.xticks.push({pos:i,label:a,has_tick:r});for(this.yticks=[],t=0;t0&&i<=1&&this.yticks.push({axis:t,pos:i,label:a,has_tick:r})},r.prototype._evaluateAnnotations=function(){var t,e={};for(t=0;t1&&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=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;lc));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=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=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=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&&to){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=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=Math.pow(10,r)||Math.abs(t)=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]+" "+r;if(0===3600*l+60*h+u+.001*d||e>=G.Granularity.DAILY)return g(s)+" "+lt[o];if(eG.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=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=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;ethis.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=0;--u)for(var d=this.layout_.points[u],c=0;c=l.length)){var h=l[s];if(x.isValidPoint(h)){var u=h.canvasy;if(t>h.canvasx&&s+10){var p=(t-h.canvasx)/c;u+=p*(d.canvasy-h.canvasy)}}}else if(t0){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=0){var r=0,o=this.attr_("labels");for(e=1;er&&(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=0){t!=this.lastRow_&&(i=!0),this.lastRow_=t;for(var n=0;n=0&&o=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;t1&&(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=e))for(var a=e;aa[1]&&(a[1]=c),c=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=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;_&&v0;){var n=this.readyFns_.pop();n(this)}},Q.prototype.computeYAxes_=function(){var t,e,a;for(this.axes_=[],t=0;t0&&(_=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;l0&&"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;c0&&f[0]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;m0&&f[0]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=a.length?console.warn("Invalid series number in setVisibility: "+n):a[n]=t[n]);else for(var n=0;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(nt)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;tr.x+r.w||l.canvasyr.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;e0){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=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'
';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';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,"&").replace(/"/g,""").replace(//g,">")};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":" "),a+=""+r.dashHTML+" "+r.labelHTML+"")}return a}a=t.xHTML+":";for(var n=0;n");a+=" "+r.labelHTML+": "+r.yHTML+""}}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=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;i1&&(g=c.rollingAverage(g,e.rollPeriod(),p)),d.push(g)}var f=[];for(t=0;t0)&&(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;tthis.canvasRect_.x||a+1t;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&&tt)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&&tr;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)=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 Binary files /dev/null and b/modules/http/static/favicon.ico 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 Binary files /dev/null and b/modules/http/static/glyphicons-halflings-regular.woff2 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.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;++db;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.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="",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.lengthx",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]*)\/>/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*\s*$/g,ia={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_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>")+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>");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("