diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:26:00 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 15:26:00 +0000 |
commit | 830407e88f9d40d954356c3754f2647f91d5c06a (patch) | |
tree | d6a0ece6feea91f3c656166dbaa884ef8a29740e /lib/cache | |
parent | Initial commit. (diff) | |
download | knot-resolver-upstream/5.6.0.tar.xz knot-resolver-upstream/5.6.0.zip |
Adding upstream version 5.6.0.upstream/5.6.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'lib/cache')
-rw-r--r-- | lib/cache/README.rst | 69 | ||||
-rw-r--r-- | lib/cache/api.c | 1029 | ||||
-rw-r--r-- | lib/cache/api.h | 194 | ||||
-rw-r--r-- | lib/cache/cdb_api.h | 97 | ||||
-rw-r--r-- | lib/cache/cdb_lmdb.c | 868 | ||||
-rw-r--r-- | lib/cache/cdb_lmdb.h | 16 | ||||
-rw-r--r-- | lib/cache/entry_list.c | 301 | ||||
-rw-r--r-- | lib/cache/entry_pkt.c | 206 | ||||
-rw-r--r-- | lib/cache/entry_rr.c | 115 | ||||
-rw-r--r-- | lib/cache/impl.h | 439 | ||||
-rw-r--r-- | lib/cache/knot_pkt.c | 94 | ||||
-rw-r--r-- | lib/cache/nsec1.c | 488 | ||||
-rw-r--r-- | lib/cache/nsec3.c | 481 | ||||
-rw-r--r-- | lib/cache/overflow.test.integr/deckard.yaml | 22 | ||||
-rw-r--r-- | lib/cache/overflow.test.integr/kresd_config.j2 | 91 | ||||
-rw-r--r-- | lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl | 298 | ||||
-rw-r--r-- | lib/cache/peek.c | 774 | ||||
-rw-r--r-- | lib/cache/test.integr/cache_minimal_nsec3.rpl | 4120 | ||||
-rw-r--r-- | lib/cache/test.integr/deckard.yaml | 13 | ||||
-rw-r--r-- | lib/cache/test.integr/kresd_config.j2 | 69 | ||||
-rw-r--r-- | lib/cache/util.h | 4 |
21 files changed, 9788 insertions, 0 deletions
diff --git a/lib/cache/README.rst b/lib/cache/README.rst new file mode 100644 index 0000000..767c4c0 --- /dev/null +++ b/lib/cache/README.rst @@ -0,0 +1,69 @@ +.. SPDX-License-Identifier: GPL-3.0-or-later + +.. _cache_sizing: + +Cache sizing +------------ + +For personal use-cases and small deployments cache size around 100 MB is more than enough. + +For large deployments we recommend to run Knot Resolver on a dedicated machine, and to allocate 90% of machine's free memory for resolver's cache. + +For example, imagine you have a machine with 16 GB of memory. +After machine restart you use command ``free -m`` to determine amount of free memory (without swap): + +.. code-block:: bash + + $ free -m + total used free + Mem: 15907 979 14928 + +Now you can configure cache size to be 90% of the free memory 14 928 MB, i.e. 13 453 MB: + +.. code-block:: lua + + -- 90 % of free memory after machine restart + cache.size = 13453 * MB + +.. _cache_persistence: + +Cache persistence +----------------- +.. tip:: Using tmpfs for cache improves performance and reduces disk I/O. + +By default the cache is saved on a persistent storage device +so the content of the cache is persisted during system reboot. +This usually leads to smaller latency after restart etc., +however in certain situations a non-persistent cache storage might be preferred, e.g.: + + - Resolver handles high volume of queries and I/O performance to disk is too low. + - Threat model includes attacker getting access to disk content in power-off state. + - Disk has limited number of writes (e.g. flash memory in routers). + +If non-persistent cache is desired configure cache directory to be on +tmpfs_ filesystem, a temporary in-memory file storage. +The cache content will be saved in memory, and thus have faster access +and will be lost on power-off or reboot. + + +.. note:: In most of the Unix-like systems ``/tmp`` and ``/var/run`` are commonly mounted to tmpfs. + While it is technically possible to move the cache to an existing + tmpfs filesystem, it is *not recommended*: The path to cache is specified in + multiple systemd units, and a shared tmpfs space could be used up by other + applications, leading to ``SIGBUS`` errors during runtime. + +Mounting the cache directory as tmpfs_ is recommended approach. +Make sure to use appropriate ``size=`` option and don't forget to adjust the +size in the config file as well. + +.. code-block:: + + # /etc/fstab + tmpfs /var/cache/knot-resolver tmpfs rw,size=2G,uid=knot-resolver,gid=knot-resolver,nosuid,nodev,noexec,mode=0700 0 0 + +.. code-block:: lua + + # /etc/knot-resolver/config + cache.size = 2 * GB + +.. _tmpfs: https://en.wikipedia.org/wiki/Tmpfs diff --git a/lib/cache/api.c b/lib/cache/api.c new file mode 100644 index 0000000..116d775 --- /dev/null +++ b/lib/cache/api.c @@ -0,0 +1,1029 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include <errno.h> +#include <limits.h> +#include <sys/stat.h> +#include <sys/time.h> +#include <time.h> +#include <unistd.h> + +#include <libknot/descriptor.h> +#include <libknot/dname.h> +#include <libknot/errcode.h> +#include <libknot/rrtype/rrsig.h> + +#include <uv.h> + +#include "contrib/base32hex.h" +#include "contrib/cleanup.h" +#include "contrib/ucw/lib.h" +#include "lib/cache/api.h" +#include "lib/cache/cdb_lmdb.h" +#include "lib/defines.h" +#include "lib/dnssec/nsec3.h" +#include "lib/generic/trie.h" +#include "lib/resolve.h" +#include "lib/rplan.h" +#include "lib/utils.h" + +#include "lib/cache/impl.h" + +/* TODO: + * - Reconsider when RRSIGs are put in and retrieved from the cache. + * Currently it's always done, which _might_ be spurious, depending + * on how kresd will use the returned result. + * There's also the "problem" that kresd ATM does _not_ ask upstream + * with DO bit in some cases. + */ + + +/** Cache version */ +static const uint16_t CACHE_VERSION = 6; +/** Key size */ +#define KEY_HSIZE (sizeof(uint8_t) + sizeof(uint16_t)) +#define KEY_SIZE (KEY_HSIZE + KNOT_DNAME_MAXLEN) + + +/** @internal Forward declarations of the implementation details + * \param needs_pkt[out] optionally set *needs_pkt = true; + * We do that when some RRset wasn't stashed to aggressive cache, + * even though it might have taken part in a successful DNSSEC proof: + * 1. any opt-out NSEC3, as they typically aren't much use aggressively anyway + * 2. some kinds of minimal NSEC* ranges, as they'd seem more trouble than worth: + * - extremely short range of covered names limits the benefits severely + * - the type-set is often a lie, either a working lie, e.g. CloudFlare's + * black lies, or even a non-working lie, e.g. DVE-2018-0003 + * 3. some kinds of "weird" RRsets, to get at least some caching on them + */ +static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry, + const knot_rrset_t *rr, const knot_rrset_t *rr_sigs, uint32_t timestamp, + uint8_t rank, trie_t *nsec_pmap, knot_mm_t *pool, bool *needs_pkt); +/** Preliminary checks before stash_rrset(). Don't call if returns <= 0. */ +static int stash_rrset_precond(const knot_rrset_t *rr, const struct kr_query *qry/*logs*/); + +/** @internal Ensure the cache version is right, possibly by clearing it. */ +static int assert_right_version(struct kr_cache *cache) +{ + /* Check cache ABI version. */ + /* CACHE_KEY_DEF: to avoid collisions with kr_cache_match(). */ + uint8_t key_str[4] = "VERS"; + knot_db_val_t key = { .data = key_str, .len = sizeof(key_str) }; + knot_db_val_t val = { NULL, 0 }; + int ret = cache_op(cache, read, &key, &val, 1); + if (ret == 0 && val.len == sizeof(CACHE_VERSION) + && memcmp(val.data, &CACHE_VERSION, sizeof(CACHE_VERSION)) == 0) { + ret = kr_ok(); + } else { + int oldret = ret; + /* Version doesn't match or we were unable to read it, possibly because DB is empty. + * Recreate cache and write version key. */ + ret = cache_op(cache, count); + if (ret != 0) { /* Log for non-empty cache to limit noise on fresh start. */ + kr_log_info(CACHE, "incompatible cache database detected, purging\n"); + if (oldret) { + kr_log_debug(CACHE, "reading version returned: %d\n", oldret); + } else if (val.len != sizeof(CACHE_VERSION)) { + kr_log_debug(CACHE, "version has bad length: %d\n", (int)val.len); + } else { + uint16_t ver; + memcpy(&ver, val.data, sizeof(ver)); + kr_log_debug(CACHE, "version has bad value: %d instead of %d\n", + (int)ver, (int)CACHE_VERSION); + } + } + ret = cache_op(cache, clear); + } + /* Rewrite the entry even if it isn't needed. Because of cache-size-changing + * possibility it's good to always perform some write during opening of cache. */ + if (ret == 0) { + /* Key/Val is invalidated by cache purge, recreate it */ + val.data = /*const-cast*/(void *)&CACHE_VERSION; + val.len = sizeof(CACHE_VERSION); + ret = cache_op(cache, write, &key, &val, 1); + } + kr_cache_commit(cache); + return ret; +} + +int kr_cache_open(struct kr_cache *cache, const struct kr_cdb_api *api, struct kr_cdb_opts *opts, knot_mm_t *mm) +{ + if (kr_fails_assert(cache)) + return kr_error(EINVAL); + memset(cache, 0, sizeof(*cache)); + /* Open cache */ + if (!api) + api = kr_cdb_lmdb(); + cache->api = api; + int ret = cache->api->open(&cache->db, &cache->stats, opts, mm); + if (ret == 0) { + ret = assert_right_version(cache); + // The included write also committed maxsize increase to the file. + } + if (ret == 0 && opts->maxsize) { + /* If some maxsize is requested and it's smaller than in-file maxsize, + * LMDB only restricts our env without changing the in-file maxsize. + * That is worked around by reopening (found no other reliable way). */ + cache->api->close(cache->db, &cache->stats); + struct kr_cdb_opts opts2; + memcpy(&opts2, opts, sizeof(opts2)); + opts2.maxsize = 0; + ret = cache->api->open(&cache->db, &cache->stats, &opts2, mm); + } + + char *fpath = kr_absolutize_path(opts->path, "data.mdb"); + if (kr_fails_assert(fpath)) { + /* non-critical, but still */ + fpath = "<ENOMEM>"; + } else { + kr_cache_emergency_file_to_remove = fpath; + } + + if (ret == 0 && opts->maxsize) { + size_t maxsize = cache->api->get_maxsize(cache->db); + if (maxsize > opts->maxsize) kr_log_warning(CACHE, + "Warning: real cache size is %zu instead of the requested %zu bytes." + " To reduce the size you need to remove the file '%s' by hand.\n", + maxsize, opts->maxsize, fpath); + } + if (ret != 0) + return ret; + cache->ttl_min = KR_CACHE_DEFAULT_TTL_MIN; + cache->ttl_max = KR_CACHE_DEFAULT_TTL_MAX; + kr_cache_make_checkpoint(cache); + return 0; +} + +const char *kr_cache_emergency_file_to_remove = NULL; + + +#define cache_isvalid(cache) ((cache) && (cache)->api && (cache)->db) + +void kr_cache_close(struct kr_cache *cache) +{ + kr_cache_check_health(cache, -1); + if (cache_isvalid(cache)) { + cache_op(cache, close); + cache->db = NULL; + } + free(/*const-cast*/(char*)kr_cache_emergency_file_to_remove); + kr_cache_emergency_file_to_remove = NULL; +} + +int kr_cache_commit(struct kr_cache *cache) +{ + if (!cache_isvalid(cache)) { + return kr_error(EINVAL); + } + if (cache->api->commit) { + return cache_op(cache, commit); + } + return kr_ok(); +} + +int kr_cache_clear(struct kr_cache *cache) +{ + if (!cache_isvalid(cache)) { + return kr_error(EINVAL); + } + int ret = cache_op(cache, clear); + if (ret == 0) { + kr_cache_make_checkpoint(cache); + ret = assert_right_version(cache); + } + return ret; +} + +/* When going stricter, BEWARE of breaking entry_h_consistent_NSEC() */ +struct entry_h * entry_h_consistent_E(knot_db_val_t data, uint16_t type) +{ + (void) type; /* unused, for now */ + if (!data.data) return NULL; + /* Length checks. */ + if (data.len < offsetof(struct entry_h, data)) + return NULL; + const struct entry_h *eh = data.data; + if (eh->is_packet) { + uint16_t pkt_len; + if (data.len < offsetof(struct entry_h, data) + sizeof(pkt_len)) { + return NULL; + } + memcpy(&pkt_len, eh->data, sizeof(pkt_len)); + if (data.len < offsetof(struct entry_h, data) + sizeof(pkt_len) + + pkt_len) { + return NULL; + } + } + + bool ok = true; + ok = ok && kr_rank_check(eh->rank); + ok = ok && (!kr_rank_test(eh->rank, KR_RANK_BOGUS) + || eh->is_packet); + ok = ok && (eh->is_packet || !eh->has_optout); + + return ok ? /*const-cast*/(struct entry_h *)eh : NULL; +} + +int32_t get_new_ttl(const struct entry_h *entry, const struct kr_query *qry, + const knot_dname_t *owner, uint16_t type, uint32_t now) +{ + int32_t diff = now - entry->time; + if (diff < 0) { + /* We may have obtained the record *after* the request started. */ + diff = 0; + } + int32_t res = entry->ttl - diff; + if (res < 0 && owner && qry && qry->stale_cb) { + /* Stale-serving decision, delegated to a callback. */ + int res_stale = qry->stale_cb(res, owner, type, qry); + if (res_stale >= 0) { + VERBOSE_MSG(qry, "responding with stale answer\n"); + /* LATER: Perhaps we could use a more specific Stale + * NXDOMAIN Answer code for applicable responses. */ + kr_request_set_extended_error(qry->request, KNOT_EDNS_EDE_STALE, "6Q6X"); + return res_stale; + } + } + return res; +} + +int32_t kr_cache_ttl(const struct kr_cache_p *peek, const struct kr_query *qry, + const knot_dname_t *name, uint16_t type) +{ + const struct entry_h *eh = peek->raw_data; + return get_new_ttl(eh, qry, name, type, qry->timestamp.tv_sec); +} + +/** Check that no label contains a zero character, incl. a log trace. + * + * We refuse to work with those, as LF and our cache keys might become ambiguous. + * Assuming uncompressed name, as usual. + * CACHE_KEY_DEF + */ +static bool check_dname_for_lf(const knot_dname_t *n, const struct kr_query *qry/*logging*/) +{ + const bool ret = knot_dname_size(n) == strlen((const char *)n) + 1; + if (!ret && kr_log_is_debug_qry(CACHE, qry)) { + auto_free char *n_str = kr_dname_text(n); + VERBOSE_MSG(qry, "=> skipping zero-containing name %s\n", n_str); + } + return ret; +} + +/** Return false on types to be ignored. Meant both for sname and direct cache requests. */ +static bool check_rrtype(uint16_t type, const struct kr_query *qry/*logging*/) +{ + const bool ret = !knot_rrtype_is_metatype(type) + && type != KNOT_RRTYPE_RRSIG; + if (!ret && kr_log_is_debug_qry(CACHE, qry)) { + auto_free char *type_str = kr_rrtype_text(type); + VERBOSE_MSG(qry, "=> skipping RR type %s\n", type_str); + } + return ret; +} + +/** Like key_exact_type() but omits a couple checks not holding for pkt cache. */ +knot_db_val_t key_exact_type_maypkt(struct key *k, uint16_t type) +{ + if (kr_fails_assert(check_rrtype(type, NULL))) + return (knot_db_val_t){ NULL, 0 }; + switch (type) { + case KNOT_RRTYPE_RRSIG: /* no RRSIG query caching, at least for now */ + kr_assert(false); + return (knot_db_val_t){ NULL, 0 }; + /* xNAME lumped into NS. */ + case KNOT_RRTYPE_CNAME: + case KNOT_RRTYPE_DNAME: + type = KNOT_RRTYPE_NS; + default: + break; + } + + int name_len = k->buf[0]; + k->buf[name_len + 1] = 0; /* make sure different names can never match */ + k->buf[name_len + 2] = 'E'; /* tag for exact name+type matches */ + memcpy(k->buf + name_len + 3, &type, 2); + k->type = type; + /* CACHE_KEY_DEF: key == dname_lf + '\0' + 'E' + RRTYPE */ + return (knot_db_val_t){ k->buf + 1, name_len + 4 }; +} + + +/** The inside for cache_peek(); implementation separated to ./peek.c */ +int peek_nosync(kr_layer_t *ctx, knot_pkt_t *pkt); +/** function for .produce phase */ +int cache_peek(kr_layer_t *ctx, knot_pkt_t *pkt) +{ + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; + /* We first check various exit-conditions and then call the _real function. */ + + if (!kr_cache_is_open(&req->ctx->cache) + || ctx->state & (KR_STATE_FAIL|KR_STATE_DONE) || qry->flags.NO_CACHE + || (qry->flags.CACHE_TRIED && !qry->stale_cb) + || !check_rrtype(qry->stype, qry) /* LATER: some other behavior for some of these? */ + || qry->sclass != KNOT_CLASS_IN) { + return ctx->state; /* Already resolved/failed or already tried, etc. */ + } + /* ATM cache only peeks for qry->sname and that would be useless + * to repeat on every iteration, so disable it from now on. + * LATER(optim.): assist with more precise QNAME minimization. */ + qry->flags.CACHE_TRIED = true; + + if (qry->stype == KNOT_RRTYPE_NSEC) { + VERBOSE_MSG(qry, "=> skipping stype NSEC\n"); + return ctx->state; + } + if (!check_dname_for_lf(qry->sname, qry)) { + return ctx->state; + } + + int ret = peek_nosync(ctx, pkt); + kr_cache_commit(&req->ctx->cache); + return ret; +} + + + +/** It's simply inside of cycle taken out to decrease indentation. \return error code. */ +static int stash_rrarray_entry(ranked_rr_array_t *arr, int arr_i, + const struct kr_query *qry, struct kr_cache *cache, + int *unauth_cnt, trie_t *nsec_pmap, bool *needs_pkt); +/** Stash a single nsec_p. \return 0 (errors are ignored). */ +static int stash_nsec_p(const knot_dname_t *dname, const char *nsec_p_v, + struct kr_cache *cache, uint32_t timestamp, knot_mm_t *pool, + const struct kr_query *qry/*logging*/); + +/** The whole .consume phase for the cache module. */ +int cache_stash(kr_layer_t *ctx, knot_pkt_t *pkt) +{ + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; + struct kr_cache *cache = &req->ctx->cache; + + /* Note: we cache even in KR_STATE_FAIL. For example, + * BOGUS answer can go to +cd cache even without +cd request. */ + if (!kr_cache_is_open(cache) || !qry + || qry->flags.CACHED || !check_rrtype(knot_pkt_qtype(pkt), qry) + || qry->sclass != KNOT_CLASS_IN) { + return ctx->state; + } + /* Do not cache truncated answers, at least for now. LATER */ + if (knot_wire_get_tc(pkt->wire)) { + return ctx->state; + } + int unauth_cnt = 0; + bool needs_pkt = false; + if (qry->flags.STUB) { + needs_pkt = true; + goto stash_packet; + } + + /* Stash individual records. */ + ranked_rr_array_t *selected[] = kr_request_selected(req); + trie_t *nsec_pmap = trie_create(&req->pool); + if (kr_fails_assert(nsec_pmap)) + goto finally; + for (int psec = KNOT_ANSWER; psec <= KNOT_ADDITIONAL; ++psec) { + ranked_rr_array_t *arr = selected[psec]; + /* uncached entries are located at the end */ + for (ssize_t i = arr->len - 1; i >= 0; --i) { + ranked_rr_array_entry_t *entry = arr->at[i]; + if (entry->qry_uid != qry->uid || entry->dont_cache) { + continue; + /* TODO: probably safe to break on uid mismatch but maybe not worth it */ + } + int ret = stash_rrarray_entry( + arr, i, qry, cache, &unauth_cnt, nsec_pmap, + /* ADDITIONAL RRs are considered non-essential + * in our (resolver) answers */ + (psec == KNOT_ADDITIONAL ? NULL : &needs_pkt)); + if (ret) { + VERBOSE_MSG(qry, "=> stashing RRs errored out\n"); + goto finally; + } + /* LATER(optim.): maybe filter out some type-rank combinations + * that won't be useful as separate RRsets. */ + } + } + + trie_it_t *it; + for (it = trie_it_begin(nsec_pmap); !trie_it_finished(it); trie_it_next(it)) { + stash_nsec_p((const knot_dname_t *)trie_it_key(it, NULL), + (const char *)*trie_it_val(it), + cache, qry->timestamp.tv_sec, &req->pool, req->current_query); + } + trie_it_free(it); + /* LATER(optim.): typically we also have corresponding NS record in the list, + * so we might save a cache operation. */ +stash_packet: + if (qry->flags.PKT_IS_SANE && check_dname_for_lf(knot_pkt_qname(pkt), qry)) { + stash_pkt(pkt, qry, req, needs_pkt); + } + +finally: + if (unauth_cnt) { + VERBOSE_MSG(qry, "=> stashed also %d nonauth RRsets\n", unauth_cnt); + }; + kr_cache_commit(cache); + return ctx->state; /* we ignore cache-stashing errors */ +} + +/** Preliminary checks before stash_rrset(). Don't call if returns <= 0. */ +static int stash_rrset_precond(const knot_rrset_t *rr, const struct kr_query *qry/*logs*/) +{ + if (kr_fails_assert(rr && rr->rclass == KNOT_CLASS_IN)) + return kr_error(EINVAL); + if (!check_rrtype(rr->type, qry)) + return kr_ok(); + if (!check_dname_for_lf(rr->owner, qry)) + return kr_ok(); + return 1/*proceed*/; +} + +/** Return true on some cases of NSEC* RRsets covering minimal ranges. + * Also include some abnormal RR cases; qry is just for logging. */ +static bool rrset_has_min_range_or_weird(const knot_rrset_t *rr, const struct kr_query *qry) +{ + if (rr->rrs.count != 1) { + kr_assert(rr->rrs.count > 0); + if (rr->type == KNOT_RRTYPE_NSEC || rr->type == KNOT_RRTYPE_NSEC3 + || rr->rrs.count == 0) { + return true; /*< weird */ + } + } + bool ret; /**< NOT used for the weird cases */ + if (rr->type == KNOT_RRTYPE_NSEC) { + if (!check_dname_for_lf(rr->owner, qry)) + return true; /*< weird, probably filtered even before this point */ + ret = !check_dname_for_lf(knot_nsec_next(rr->rrs.rdata), qry); + /* ^^ Zero inside the next-name label means it's probably a minimal range, + * and anyway it's problematic for our aggressive cache (comparisons). + * Real-life examples covered: + * NSEC: name -> \000.name (e.g. typical foobar.CloudFlare.net) + * NSEC: name -> name\000 (CloudFlare on delegations) + */ + } else if (rr->type == KNOT_RRTYPE_NSEC3) { + if (knot_nsec3_next_len(rr->rrs.rdata) != NSEC3_HASH_LEN + || *rr->owner != NSEC3_HASH_TXT_LEN) { + return true; /*< weird */ + } + /* Let's work on the binary hashes. Find if they "differ by one", + * by constructing the owner hash incremented by one and comparing. */ + uint8_t owner_hash[NSEC3_HASH_LEN]; + if (base32hex_decode(rr->owner + 1, NSEC3_HASH_TXT_LEN, + owner_hash, NSEC3_HASH_LEN) != NSEC3_HASH_LEN) { + return true; /*< weird */ + } + for (int i = NSEC3_HASH_LEN - 1; i >= 0; --i) { + if (++owner_hash[i] != 0) break; + } + const uint8_t *next_hash = knot_nsec3_next(rr->rrs.rdata); + ret = memcmp(owner_hash, next_hash, NSEC3_HASH_LEN) == 0; + } else { + return false; + } + if (ret) VERBOSE_MSG(qry, "=> minimized NSEC* range detected\n"); + return ret; +} + +static ssize_t stash_rrset(struct kr_cache *cache, const struct kr_query *qry, + const knot_rrset_t *rr, const knot_rrset_t *rr_sigs, uint32_t timestamp, + uint8_t rank, trie_t *nsec_pmap, knot_mm_t *pool, bool *needs_pkt) +{ + if (kr_rank_test(rank, KR_RANK_BOGUS)) { + WITH_VERBOSE(qry) { + auto_free char *type_str = kr_rrtype_text(rr->type); + VERBOSE_MSG(qry, "=> skipping bogus RR set %s\n", type_str); + } + return kr_ok(); + } + if (rr->type == KNOT_RRTYPE_NSEC3 && rr->rrs.count + && knot_nsec3_iters(rr->rrs.rdata) > KR_NSEC3_MAX_ITERATIONS) { + /* This shouldn't happen often, thanks to downgrades during validation. */ + VERBOSE_MSG(qry, "=> skipping NSEC3 with too many iterations\n"); + return kr_ok(); + } + if (kr_fails_assert(cache && stash_rrset_precond(rr, qry) > 0)) + return kr_error(EINVAL); + + int ret = kr_ok(); + if (rrset_has_min_range_or_weird(rr, qry)) + goto return_needs_pkt; + const int wild_labels = rr_sigs == NULL ? 0 : + knot_dname_labels(rr->owner, NULL) - knot_rrsig_labels(rr_sigs->rrs.rdata); + if (wild_labels < 0) + goto return_needs_pkt; + const knot_dname_t *encloser = rr->owner; /**< the closest encloser name */ + for (int i = 0; i < wild_labels; ++i) { + encloser = knot_wire_next_label(encloser, NULL); + } + + /* Construct the key under which RRs will be stored, + * and add corresponding nsec_pmap item (if necessary). */ + struct key k_storage, *k = &k_storage; + knot_db_val_t key; + switch (rr->type) { + case KNOT_RRTYPE_NSEC3: + /* Skip opt-out NSEC3 sets. */ + if (KNOT_NSEC3_FLAG_OPT_OUT & knot_nsec3_flags(rr->rrs.rdata)) + goto return_needs_pkt; + /* fall through */ + case KNOT_RRTYPE_NSEC: + /* Skip any NSEC*s that aren't validated or are suspicious. */ + if (!kr_rank_test(rank, KR_RANK_SECURE) || rr->rrs.count != 1) + goto return_needs_pkt; + if (kr_fails_assert(rr_sigs && rr_sigs->rrs.count && rr_sigs->rrs.rdata)) { + ret = kr_error(EINVAL); + goto return_needs_pkt; + } + const knot_dname_t *signer = knot_rrsig_signer_name(rr_sigs->rrs.rdata); + const int signer_size = knot_dname_size(signer); + k->zlf_len = signer_size - 1; + + void **npp = NULL; + if (nsec_pmap) { + npp = trie_get_ins(nsec_pmap, (const char *)signer, signer_size); + if (kr_fails_assert(npp)) + return kr_error(ENOMEM); + } + if (rr->type == KNOT_RRTYPE_NSEC) { + key = key_NSEC1(k, encloser, wild_labels); + break; + } + + kr_require(rr->type == KNOT_RRTYPE_NSEC3); + const knot_rdata_t * const rdata = rr->rrs.rdata; + if (rdata->len <= 4) { + ret = kr_error(EILSEQ); /*< data from outside; less trust */ + goto return_needs_pkt; + } + const int np_dlen = nsec_p_rdlen(rdata->data); + if (np_dlen > rdata->len) { + ret = kr_error(EILSEQ); + goto return_needs_pkt; + } + key = key_NSEC3(k, encloser, nsec_p_mkHash(rdata->data)); + if (npp && !*npp) { + *npp = mm_alloc(pool, np_dlen); + if (kr_fails_assert(*npp)) + break; + memcpy(*npp, rdata->data, np_dlen); + } + break; + default: + ret = kr_dname_lf(k->buf, encloser, wild_labels); + if (kr_fails_assert(ret == 0)) + goto return_needs_pkt; + key = key_exact_type(k, rr->type); + } + + /* Compute in-cache size for the new data. */ + const knot_rdataset_t *rds_sigs = rr_sigs ? &rr_sigs->rrs : NULL; + const int rr_ssize = rdataset_dematerialize_size(&rr->rrs); + if (kr_fails_assert(rr_ssize == to_even(rr_ssize))) + return kr_error(EINVAL); + knot_db_val_t val_new_entry = { + .data = NULL, + .len = offsetof(struct entry_h, data) + rr_ssize + + rdataset_dematerialize_size(rds_sigs), + }; + + /* Prepare raw memory for the new entry. */ + ret = entry_h_splice(&val_new_entry, rank, key, k->type, rr->type, + rr->owner, qry, cache, timestamp); + if (ret) return kr_ok(); /* some aren't really errors */ + if (kr_fails_assert(val_new_entry.data)) + return kr_error(EFAULT); + + /* Write the entry itself. */ + struct entry_h *eh = val_new_entry.data; + memset(eh, 0, offsetof(struct entry_h, data)); + eh->time = timestamp; + eh->ttl = rr->ttl; + eh->rank = rank; + rdataset_dematerialize(&rr->rrs, eh->data); + rdataset_dematerialize(rds_sigs, eh->data + rr_ssize); + if (kr_fails_assert(entry_h_consistent_E(val_new_entry, rr->type))) + return kr_error(EINVAL); + + #if 0 /* Occasionally useful when debugging some kinds of changes. */ + { + kr_cache_commit(cache); + knot_db_val_t val = { NULL, 0 }; + ret = cache_op(cache, read, &key, &val, 1); + if (ret != kr_error(ENOENT)) { // ENOENT might happen in some edge case, I guess + kr_assert(!ret); + entry_list_t el; + entry_list_parse(val, el); + } + } + #endif + + /* Verbose-log some not-too-common cases. */ + WITH_VERBOSE(qry) { if (kr_rank_test(rank, KR_RANK_AUTH) + || rr->type == KNOT_RRTYPE_NS) { + auto_free char *type_str = kr_rrtype_text(rr->type), + *encl_str = kr_dname_text(encloser); + VERBOSE_MSG(qry, "=> stashed %s%s %s, rank 0%.2o, " + "%d B total, incl. %d RRSIGs\n", + (wild_labels ? "*." : ""), encl_str, type_str, rank, + (int)val_new_entry.len, (rr_sigs ? rr_sigs->rrs.count : 0) + ); + } } + + return (ssize_t) val_new_entry.len; +return_needs_pkt: + if (needs_pkt) *needs_pkt = true; + return ret; +} + +static int stash_rrarray_entry(ranked_rr_array_t *arr, int arr_i, + const struct kr_query *qry, struct kr_cache *cache, + int *unauth_cnt, trie_t *nsec_pmap, bool *needs_pkt) +{ + ranked_rr_array_entry_t *entry = arr->at[arr_i]; + if (entry->cached) { + return kr_ok(); + } + const knot_rrset_t *rr = entry->rr; + if (rr->type == KNOT_RRTYPE_RRSIG) { + return kr_ok(); /* reduce verbose logging from the following call */ + } + int ret = stash_rrset_precond(rr, qry); + if (ret <= 0) { + return ret; + } + + /* Try to find corresponding signatures, always. LATER(optim.): speed. */ + ranked_rr_array_entry_t *entry_rrsigs = NULL; + const knot_rrset_t *rr_sigs = NULL; + for (ssize_t j = arr->len - 1; j >= 0; --j) { + /* TODO: ATM we assume that some properties are the same + * for all RRSIGs in the set (esp. label count). */ + ranked_rr_array_entry_t *e = arr->at[j]; + if (kr_fails_assert(!e->in_progress)) + return kr_error(EINVAL); + bool ok = e->qry_uid == qry->uid && !e->cached + && e->rr->type == KNOT_RRTYPE_RRSIG + && knot_rrsig_type_covered(e->rr->rrs.rdata) == rr->type + && knot_dname_is_equal(rr->owner, e->rr->owner); + if (!ok) continue; + entry_rrsigs = e; + rr_sigs = e->rr; + break; + } + + ssize_t written = stash_rrset(cache, qry, rr, rr_sigs, qry->timestamp.tv_sec, + entry->rank, nsec_pmap, &qry->request->pool, needs_pkt); + if (written < 0) { + kr_log_error(CACHE, "[%05u.%02u] stash failed, ret = %d\n", qry->request->uid, + qry->uid, ret); + return (int) written; + } + + if (written > 0) { + /* Mark entry as cached for the rest of the query processing */ + entry->cached = true; + if (entry_rrsigs) { + entry_rrsigs->cached = true; + } + if (!kr_rank_test(entry->rank, KR_RANK_AUTH) && rr->type != KNOT_RRTYPE_NS) { + *unauth_cnt += 1; + } + } + + return kr_ok(); +} + +static int stash_nsec_p(const knot_dname_t *dname, const char *nsec_p_v, + struct kr_cache *cache, uint32_t timestamp, knot_mm_t *pool, + const struct kr_query *qry/*logging*/) +{ + uint32_t valid_until = timestamp + cache->ttl_max; + /* LATER(optim.): be more precise here ^^ and reduce calls. */ + static const int32_t ttl_margin = 3600; + const uint8_t *nsec_p = (const uint8_t *)nsec_p_v; + int data_stride = sizeof(valid_until) + nsec_p_rdlen(nsec_p); + + unsigned int log_hash = 0xFeeeFeee; /* this type is simpler for printf args */ + auto_free char *log_dname = NULL; + WITH_VERBOSE(qry) { + log_hash = nsec_p_v ? nsec_p_mkHash((const uint8_t *)nsec_p_v) : 0; + log_dname = kr_dname_text(dname); + } + /* Find what's in the cache. */ + struct key k_storage, *k = &k_storage; + int ret = kr_dname_lf(k->buf, dname, false); + if (ret) return kr_error(ret); + knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_NS); + knot_db_val_t val_orig = { NULL, 0 }; + ret = cache_op(cache, read, &key, &val_orig, 1); + if (ret && ret != -ABS(ENOENT)) { + VERBOSE_MSG(qry, "=> EL read failed (ret: %d)\n", ret); + return kr_ok(); + } + /* Prepare new entry_list_t so we can just write at el[0]. */ + entry_list_t el; + int log_refresh_by = 0; + if (ret == -ABS(ENOENT)) { + memset(el, 0, sizeof(el)); + } else { + ret = entry_list_parse(val_orig, el); + if (ret) { + VERBOSE_MSG(qry, "=> EL parse failed (ret: %d)\n", ret); + return kr_error(0); + } + /* Find the index to replace. */ + int i_replace = ENTRY_APEX_NSECS_CNT - 1; + for (int i = 0; i < ENTRY_APEX_NSECS_CNT; ++i) { + if (el[i].len != data_stride) continue; + if (nsec_p && memcmp(nsec_p, (uint8_t *)el[i].data + sizeof(uint32_t), + data_stride - sizeof(uint32_t)) != 0) { + continue; + } + /* Save a cache operation if TTL extended only a little. */ + uint32_t valid_orig; + memcpy(&valid_orig, el[i].data, sizeof(valid_orig)); + const int32_t ttl_extended_by = valid_until - valid_orig; + if (ttl_extended_by < ttl_margin) { + VERBOSE_MSG(qry, + "=> nsec_p stash for %s skipped (extra TTL: %d, hash: %x)\n", + log_dname, ttl_extended_by, log_hash); + return kr_ok(); + } + i_replace = i; + log_refresh_by = ttl_extended_by; + break; + } + /* Shift the other indices: move the first `i_replace` blocks + * by one position. */ + if (i_replace) { + memmove(&el[1], &el[0], sizeof(el[0]) * i_replace); + } + } + /* Prepare old data into a buffer. See entry_h_splice() for why. LATER(optim.) */ + el[0].len = data_stride; + el[0].data = NULL; + knot_db_val_t val; + val.len = entry_list_serial_size(el), + val.data = mm_alloc(pool, val.len), + entry_list_memcpy(val.data, el); + /* Prepare the new data chunk */ + memcpy(el[0].data, &valid_until, sizeof(valid_until)); + if (nsec_p) { + memcpy((uint8_t *)el[0].data + sizeof(valid_until), nsec_p, + data_stride - sizeof(valid_until)); + } + /* Write it all to the cache */ + ret = cache_op(cache, write, &key, &val, 1); + mm_free(pool, val.data); + if (ret || !val.data) { + VERBOSE_MSG(qry, "=> EL write failed (ret: %d)\n", ret); + return kr_ok(); + } + if (log_refresh_by) { + VERBOSE_MSG(qry, "=> nsec_p stashed for %s (refresh by %d, hash: %x)\n", + log_dname, log_refresh_by, log_hash); + } else { + VERBOSE_MSG(qry, "=> nsec_p stashed for %s (new, hash: %x)\n", + log_dname, log_hash); + } + return kr_ok(); +} + +int kr_cache_insert_rr(struct kr_cache *cache, + const knot_rrset_t *rr, const knot_rrset_t *rrsig, + uint8_t rank, uint32_t timestamp, bool ins_nsec_p) +{ + int err = stash_rrset_precond(rr, NULL); + if (err <= 0) { + return kr_ok(); + } + + trie_t *nsec_pmap = NULL; + knot_mm_t *pool = NULL; + if (ins_nsec_p && (rr->type == KNOT_RRTYPE_NSEC || rr->type == KNOT_RRTYPE_NSEC3)) { + pool = mm_ctx_mempool2(4096); + nsec_pmap = trie_create(pool); + kr_assert(pool && nsec_pmap); + } + + ssize_t written = stash_rrset(cache, NULL, rr, rrsig, timestamp, rank, + nsec_pmap, pool, NULL); + + if (nsec_pmap) { + trie_it_t *it; + for (it = trie_it_begin(nsec_pmap); !trie_it_finished(it); trie_it_next(it)) { + stash_nsec_p((const knot_dname_t *)trie_it_key(it, NULL), + (const char *)*trie_it_val(it), + cache, timestamp, pool, NULL); + } + trie_it_free(it); + mm_ctx_delete(pool); + } + + if (written >= 0) { + return kr_ok(); + } + + return (int) written; +} + +static int peek_exact_real(struct kr_cache *cache, const knot_dname_t *name, uint16_t type, + struct kr_cache_p *peek) +{ + if (!check_rrtype(type, NULL) || !check_dname_for_lf(name, NULL)) { + return kr_error(ENOTSUP); + } + struct key k_storage, *k = &k_storage; + + int ret = kr_dname_lf(k->buf, name, false); + if (ret) return kr_error(ret); + + knot_db_val_t key = key_exact_type(k, type); + knot_db_val_t val = { NULL, 0 }; + ret = cache_op(cache, read, &key, &val, 1); + if (!ret) ret = entry_h_seek(&val, type); + if (ret) return kr_error(ret); + + const struct entry_h *eh = entry_h_consistent_E(val, type); + if (!eh || eh->is_packet) { + // TODO: no packets, but better get rid of whole kr_cache_peek_exact(). + return kr_error(ENOENT); + } + *peek = (struct kr_cache_p){ + .time = eh->time, + .ttl = eh->ttl, + .rank = eh->rank, + .raw_data = val.data, + .raw_bound = knot_db_val_bound(val), + }; + return kr_ok(); +} +int kr_cache_peek_exact(struct kr_cache *cache, const knot_dname_t *name, uint16_t type, + struct kr_cache_p *peek) +{ /* Just wrap with extra verbose logging. */ + const int ret = peek_exact_real(cache, name, type, peek); + if (false && kr_log_is_debug(CACHE, NULL)) { /* too noisy for usual --verbose */ + auto_free char *type_str = kr_rrtype_text(type), + *name_str = kr_dname_text(name); + const char *result_str = (ret == kr_ok() ? "hit" : + (ret == kr_error(ENOENT) ? "miss" : "error")); + VERBOSE_MSG(NULL, "_peek_exact: %s %s %s (ret: %d)", + type_str, name_str, result_str, ret); + } + return ret; +} + +int kr_cache_remove(struct kr_cache *cache, const knot_dname_t *name, uint16_t type) +{ + if (!cache_isvalid(cache)) { + return kr_error(EINVAL); + } + if (!cache->api->remove) { + return kr_error(ENOSYS); + } + struct key k_storage, *k = &k_storage; + int ret = kr_dname_lf(k->buf, name, false); + if (ret) return kr_error(ret); + + knot_db_val_t key = key_exact_type(k, type); + return cache_op(cache, remove, &key, 1); +} + +int kr_cache_match(struct kr_cache *cache, const knot_dname_t *name, + bool exact_name, knot_db_val_t keyval[][2], int maxcount) +{ + if (!cache_isvalid(cache)) { + return kr_error(EINVAL); + } + if (!cache->api->match) { + return kr_error(ENOSYS); + } + + struct key k_storage, *k = &k_storage; + + int ret = kr_dname_lf(k->buf, name, false); + if (ret) return kr_error(ret); + + // use a mock type + knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_A); + /* CACHE_KEY_DEF */ + key.len -= sizeof(uint16_t); /* the type */ + if (!exact_name) { + key.len -= 2; /* '\0' 'E' */ + if (name[0] == '\0') ++key.len; /* the root name is special ATM */ + } + return cache_op(cache, match, &key, keyval, maxcount); +} + +int kr_unpack_cache_key(knot_db_val_t key, knot_dname_t *buf, uint16_t *type) +{ + if (key.data == NULL || buf == NULL || type == NULL) { + return kr_error(EINVAL); + } + + int len = -1; + const char *tag, *key_data = key.data; + for (tag = key_data + 1; tag < key_data + key.len; ++tag) { + /* CACHE_KEY_DEF */ + if (tag[-1] == '\0' && (tag == key_data + 1 || tag[-2] == '\0')) { + if (tag[0] != 'E') return kr_error(EINVAL); + len = tag - 1 - key_data; + break; + } + } + + if (len == -1 || len > KNOT_DNAME_MAXLEN) { + return kr_error(EINVAL); + } + + int ret = knot_dname_lf2wire(buf, len, key.data); + if (ret < 0) { + return kr_error(ret); + } + + /* CACHE_KEY_DEF: jump over "\0 E/1" */ + memcpy(type, tag + 1, sizeof(uint16_t)); + + return kr_ok(); +} + + +int kr_cache_remove_subtree(struct kr_cache *cache, const knot_dname_t *name, + bool exact_name, int maxcount) +{ + if (!cache_isvalid(cache)) { + return kr_error(EINVAL); + } + + knot_db_val_t keyval[maxcount][2], keys[maxcount]; + int ret = kr_cache_match(cache, name, exact_name, keyval, maxcount); + if (ret <= 0) { /* ENOENT -> nothing to remove */ + return (ret == KNOT_ENOENT) ? 0 : ret; + } + const int count = ret; + /* Duplicate the key strings, as deletion may invalidate the pointers. */ + int i; + for (i = 0; i < count; ++i) { + keys[i].len = keyval[i][0].len; + keys[i].data = malloc(keys[i].len); + if (!keys[i].data) { + ret = kr_error(ENOMEM); + goto cleanup; + } + memcpy(keys[i].data, keyval[i][0].data, keys[i].len); + } + ret = cache_op(cache, remove, keys, count); +cleanup: + kr_cache_commit(cache); /* Sync even after just kr_cache_match(). */ + /* Free keys */ + while (--i >= 0) { + free(keys[i].data); + } + return ret; +} + +static void health_timer_cb(uv_timer_t *health_timer) +{ + struct kr_cache *cache = health_timer->data; + if (cache) + cache_op(cache, check_health); + /* We don't do anything with the return code. For example, in some situations + * the file may not exist (temporarily), and we just expect to be more lucky + * when the timer fires again. */ +} + +int kr_cache_check_health(struct kr_cache *cache, int interval) +{ + if (interval == 0) + return cache_op(cache, check_health); + if (interval < 0) { + if (!cache->health_timer) + return kr_ok(); // tolerate stopping a "stopped" timer + uv_close((uv_handle_t *)cache->health_timer, (uv_close_cb)free); + cache->health_timer->data = NULL; + cache->health_timer = NULL; + return kr_ok(); + } + + if (!cache->health_timer) { + /* We avoid depending on daemon's symbols by using uv_default_loop. */ + cache->health_timer = malloc(sizeof(*cache->health_timer)); + if (!cache->health_timer) return kr_error(ENOMEM); + uv_loop_t *loop = uv_default_loop(); + kr_require(loop); + int ret = uv_timer_init(loop, cache->health_timer); + if (ret) { + free(cache->health_timer); + cache->health_timer = NULL; + return kr_error(ret); + } + cache->health_timer->data = cache; + } + kr_assert(cache->health_timer->data); + return kr_error(uv_timer_start(cache->health_timer, health_timer_cb, interval, interval)); +} + diff --git a/lib/cache/api.h b/lib/cache/api.h new file mode 100644 index 0000000..0abe920 --- /dev/null +++ b/lib/cache/api.h @@ -0,0 +1,194 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#pragma once + +#include <libknot/consts.h> +#include <libknot/rrset.h> +#include <sys/time.h> +#include "lib/cache/cdb_api.h" +#include "lib/defines.h" +#include "contrib/ucw/config.h" /*uint*/ + +#include "lib/module.h" +/* Prototypes for the 'cache' module implementation. */ +int cache_peek(kr_layer_t *ctx, knot_pkt_t *pkt); +int cache_stash(kr_layer_t *ctx, knot_pkt_t *pkt); + + +/** + * Cache structure, keeps API, instance and metadata. + */ +struct kr_cache +{ + kr_cdb_pt db; /**< Storage instance */ + const struct kr_cdb_api *api; /**< Storage engine */ + struct kr_cdb_stats stats; + uint32_t ttl_min, ttl_max; /**< TTL limits; enforced primarily in iterator actually. */ + + /* A pair of stamps for detection of real-time shifts during runtime. */ + struct timeval checkpoint_walltime; /**< Wall time on the last check-point. */ + uint64_t checkpoint_monotime; /**< Monotonic milliseconds on the last check-point. */ + + uv_timer_t *health_timer; /**< Timer used for kr_cache_check_health() */ +}; +// https://datatracker.ietf.org/doc/html/rfc2181#section-8 +#define TTL_MAX_MAX ((1u << 31) - 1) + +/** + * Open/create cache with provided storage options. + * @param cache cache structure to be initialized + * @param api storage engine API + * @param opts storage-specific options (may be NULL for default) + * @param mm memory context. + * @return 0 or an error code + */ +KR_EXPORT +int kr_cache_open(struct kr_cache *cache, const struct kr_cdb_api *api, struct kr_cdb_opts *opts, knot_mm_t *mm); + +/** + * Path to cache file to remove on critical out-of-space error. (do NOT modify it) + */ +KR_EXPORT extern +const char *kr_cache_emergency_file_to_remove; + +/** + * Close persistent cache. + * @note This doesn't clear the data, just closes the connection to the database. + * @param cache structure + */ +KR_EXPORT +void kr_cache_close(struct kr_cache *cache); + +/** Run after a row of operations to release transaction/lock if needed. */ +KR_EXPORT +int kr_cache_commit(struct kr_cache *cache); + +/** + * Return true if cache is open and enabled. + */ +static inline bool kr_cache_is_open(struct kr_cache *cache) +{ + return cache->db != NULL; +} + +/** (Re)set the time pair to the current values. */ +static inline void kr_cache_make_checkpoint(struct kr_cache *cache) +{ + cache->checkpoint_monotime = kr_now(); + gettimeofday(&cache->checkpoint_walltime, NULL); +} + +/** + * Insert RRSet into cache, replacing any existing data. + * @param cache cache structure + * @param rr inserted RRSet + * @param rrsig RRSIG for inserted RRSet (optional) + * @param rank rank of the data + * @param timestamp current time (as-if; if the RR are older, their timestamp is appropriate) + * @param ins_nsec_p update NSEC* parameters if applicable + * @return 0 or an errcode + */ +KR_EXPORT +int kr_cache_insert_rr(struct kr_cache *cache, + const knot_rrset_t *rr, const knot_rrset_t *rrsig, + uint8_t rank, uint32_t timestamp, bool ins_nsec_p); + +/** + * Clear all items from the cache. + * @param cache cache structure + * @return if nonzero is returned, there's a big problem - you probably want to abort(), + * perhaps except for kr_error(EAGAIN) which probably indicates transient errors. + */ +KR_EXPORT +int kr_cache_clear(struct kr_cache *cache); + + +/* ** This interface is temporary. ** */ + +struct kr_cache_p { + uint32_t time; /**< The time of inception. */ + uint32_t ttl; /**< TTL at inception moment. Assuming it fits into int32_t ATM. */ + uint8_t rank; /**< See enum kr_rank */ + struct { + /* internal: pointer to eh struct */ + void *raw_data, *raw_bound; + }; +}; +KR_EXPORT +int kr_cache_peek_exact(struct kr_cache *cache, const knot_dname_t *name, uint16_t type, + struct kr_cache_p *peek); +/* Parameters (qry, name, type) are used for timestamp and stale-serving decisions. */ +KR_EXPORT +int32_t kr_cache_ttl(const struct kr_cache_p *peek, const struct kr_query *qry, + const knot_dname_t *name, uint16_t type); + +KR_EXPORT +int kr_cache_materialize(knot_rdataset_t *dst, const struct kr_cache_p *ref, + knot_mm_t *pool); + + +/** + * Remove an entry from cache. + * @param cache cache structure + * @param name dname + * @param type rr type + * @return number of deleted records, or negative error code + * @note only "exact hits" are considered ATM, and + * some other information may be removed alongside. + */ +KR_EXPORT +int kr_cache_remove(struct kr_cache *cache, const knot_dname_t *name, uint16_t type); + +/** + * Get keys matching a dname lf prefix + * @param cache cache structure + * @param name dname + * @param exact_name whether to only consider exact name matches + * @param keyval matched key-value pairs + * @param maxcount limit on the number of returned key-value pairs + * @return result count or an errcode + * @note the cache keys are matched by prefix, i.e. it very much depends + * on their structure; CACHE_KEY_DEF. + */ +KR_EXPORT +int kr_cache_match(struct kr_cache *cache, const knot_dname_t *name, + bool exact_name, knot_db_val_t keyval[][2], int maxcount); + +/** + * Remove a subtree in cache. It's like _match but removing them instead of returning. + * @return number of deleted entries or an errcode + */ +KR_EXPORT +int kr_cache_remove_subtree(struct kr_cache *cache, const knot_dname_t *name, + bool exact_name, int maxcount); + +/** + * Find the closest cached zone apex for a name (in cache). + * @param is_DS start searching one name higher + * @return the number of labels to remove from the name, or negative error code + * @note timestamp is found by a syscall, and stale-serving is not considered + */ +KR_EXPORT +int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS, + knot_dname_t **apex); + +/** + * Unpack dname and type from db key + * @param key db key representation + * @param buf output buffer of domain name in dname format + * @param type output for type + * @return length of dname or an errcode + * @note only "exact hits" are considered ATM, moreover xNAME records + * are "hidden" as NS. (see comments in struct entry_h) + */ +KR_EXPORT +int kr_unpack_cache_key(knot_db_val_t key, knot_dname_t *buf, uint16_t *type); + +/** Periodic kr_cdb_api::check_health(). + * @param interval in milliseconds. 0 for one-time check, -1 to stop the checks. + * @return see check_health() for one-time check; otherwise normal kr_error() code. */ +KR_EXPORT +int kr_cache_check_health(struct kr_cache *cache, int interval); + diff --git a/lib/cache/cdb_api.h b/lib/cache/cdb_api.h new file mode 100644 index 0000000..fcca8a9 --- /dev/null +++ b/lib/cache/cdb_api.h @@ -0,0 +1,97 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later +*/ + +#pragma once + +#include <stdint.h> + +#include <libknot/db/db.h> + +/* Cache options. */ +struct kr_cdb_opts { + const char *path; /*!< Cache URI path. */ + size_t maxsize; /*!< Suggested cache size in bytes; pass 0 to keep unchanged/default. */ +}; + +struct kr_cdb_stats { + uint64_t open; + uint64_t close; + uint64_t count; + uint64_t count_entries; + uint64_t clear; + uint64_t commit; + uint64_t read; + uint64_t read_miss; + uint64_t write; + uint64_t remove; + uint64_t remove_miss; + uint64_t match; + uint64_t match_miss; + uint64_t read_leq; + uint64_t read_leq_miss; + double usage_percent; +}; + +/*! Pointer to a cache structure. + * + * This struct is opaque and never defined; the purpose is to get better + * type safety than with void *. + */ +typedef struct kr_cdb *kr_cdb_pt; + +/*! Cache database API. + * This is a simplified version of generic DB API from libknot, + * that is tailored to caching purposes. + */ +struct kr_cdb_api { + const char *name; + + /* Context operations */ + + int (*open)(kr_cdb_pt *db, struct kr_cdb_stats *stat, struct kr_cdb_opts *opts, knot_mm_t *mm); + void (*close)(kr_cdb_pt db, struct kr_cdb_stats *stat); + int (*count)(kr_cdb_pt db, struct kr_cdb_stats *stat); + int (*clear)(kr_cdb_pt db, struct kr_cdb_stats *stat); + + /** Run after a row of operations to release transaction/lock if needed. */ + int (*commit)(kr_cdb_pt db, struct kr_cdb_stats *stat); + + /* Data access */ + + int (*read)(kr_cdb_pt db, struct kr_cdb_stats *stat, + const knot_db_val_t *key, knot_db_val_t *val, int maxcount); + int (*write)(kr_cdb_pt db, struct kr_cdb_stats *stat, const knot_db_val_t *key, + knot_db_val_t *val, int maxcount); + + /** Remove maxcount keys. + * \returns the number of successfully removed keys or the first error code + * It returns on first error, but ENOENT is not considered an error. */ + int (*remove)(kr_cdb_pt db, struct kr_cdb_stats *stat, + knot_db_val_t keys[], int maxcount); + + /* Specialised operations */ + + /** Find key-value pairs that are prefixed by the given key, limited by maxcount. + * \return the number of pairs or negative error. */ + int (*match)(kr_cdb_pt db, struct kr_cdb_stats *stat, + knot_db_val_t *key, knot_db_val_t keyval[][2], int maxcount); + + /** Less-or-equal search (lexicographic ordering). + * On successful return, key->data and val->data point to DB-owned data. + * return: 0 for equality, > 0 for less, < 0 kr_error */ + int (*read_leq)(kr_cdb_pt db, struct kr_cdb_stats *stat, + knot_db_val_t *key, knot_db_val_t *val); + + /** Return estimated space usage (0--100). */ + double (*usage_percent)(kr_cdb_pt db); + + /** Return the current cache size limit in bytes; could be cached by check_health(). */ + size_t (*get_maxsize)(kr_cdb_pt db); + + /** Perform maintenance. + * In LMDB case it checks whether data.mdb is still the same + * and reopens it if it isn't; it errors out if the file doesn't exist anymore. + * \return 0 if OK, 1 if reopened OK, < 0 kr_error */ + int (*check_health)(kr_cdb_pt db, struct kr_cdb_stats *stat); +}; diff --git a/lib/cache/cdb_lmdb.c b/lib/cache/cdb_lmdb.c new file mode 100644 index 0000000..80c7372 --- /dev/null +++ b/lib/cache/cdb_lmdb.c @@ -0,0 +1,868 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later +*/ + +#include <fcntl.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <unistd.h> +#include <lmdb.h> + +#include "contrib/cleanup.h" +#include "contrib/ucw/lib.h" +#include "lib/cache/cdb_lmdb.h" +#include "lib/cache/cdb_api.h" +#include "lib/utils.h" + + +/* Defines */ +#define LMDB_DIR_MODE 0770 +#define LMDB_FILE_MODE 0660 + +/* TODO: we rely on mirrors of these two structs not changing layout + * in libknot and knot resolver! */ +struct lmdb_env +{ + size_t mapsize; + MDB_dbi dbi; + MDB_env *env; + + /** Cached transactions + * + * - only one of (ro,rw) may be active at once + * - non-NULL .ro may be active or reset + * - non-NULL .rw is always active + */ + struct { + bool ro_active, ro_curs_active; + MDB_txn *ro, *rw; + MDB_cursor *ro_curs; + } txn; + + /* Cached part of struct stat for data.mdb. */ + dev_t st_dev; + ino_t st_ino; + off_t st_size; + const char *mdb_data_path; /**< path to data.mdb, for convenience */ +}; + +struct libknot_lmdb_env { + bool shared; + unsigned dbi; + void *env; + knot_mm_t *pool; +}; + +/** Type-safe conversion helper. + * + * We keep lmdb_env as a separate type from kr_db_pt, as different implementation of API + * would need to define the contents differently. + */ +static inline struct lmdb_env * db2env(kr_cdb_pt db) +{ + return (struct lmdb_env *)db; +} +static inline kr_cdb_pt env2db(struct lmdb_env *env) +{ + return (kr_cdb_pt)env; +} + +static int cdb_commit(kr_cdb_pt db, struct kr_cdb_stats *stats); + +/** @brief Convert LMDB error code. */ +static int lmdb_error(int error) +{ + switch (error) { + case MDB_SUCCESS: + return kr_ok(); + case MDB_NOTFOUND: + return kr_error(ENOENT); + case ENOSPC: + case MDB_MAP_FULL: + case MDB_TXN_FULL: + return kr_error(ENOSPC); + default: + kr_log_error(CACHE, "LMDB error: %s\n", mdb_strerror(error)); + return kr_error(error); + } +} + +/** Conversion between knot and lmdb structs for values. */ +static inline knot_db_val_t val_mdb2knot(MDB_val v) +{ + return (knot_db_val_t){ .len = v.mv_size, .data = v.mv_data }; +} +static inline MDB_val val_knot2mdb(knot_db_val_t v) +{ + return (MDB_val){ .mv_size = v.len, .mv_data = v.data }; +} + +/** Refresh mapsize value from file, including env->mapsize. + * It's much lighter than reopen_env(). */ +static int refresh_mapsize(struct lmdb_env *env) +{ + int ret = cdb_commit(env2db(env), NULL); + if (!ret) ret = lmdb_error(mdb_env_set_mapsize(env->env, 0)); + if (ret) return ret; + + MDB_envinfo info; + ret = lmdb_error(mdb_env_info(env->env, &info)); + if (ret) return ret; + + env->mapsize = info.me_mapsize; + if (env->mapsize != env->st_size) { + kr_log_info(CACHE, "suspicious size of cache file '%s'" + ": file size %zu != LMDB map size %zu\n", + env->mdb_data_path, (size_t)env->st_size, env->mapsize); + } + return kr_ok(); +} + +static void clear_stale_readers(struct lmdb_env *env) +{ + int cleared; + int ret = mdb_reader_check(env->env, &cleared); + if (ret != MDB_SUCCESS) { + kr_log_error(CACHE, "failed to clear stale reader locks: " + "LMDB error %d %s\n", ret, mdb_strerror(ret)); + } else if (cleared != 0) { + kr_log_info(CACHE, "cleared %d stale reader locks\n", cleared); + } +} + +#define FLAG_RENEW (2*MDB_RDONLY) +/** mdb_txn_begin or _renew + handle retries in some situations + * + * The retrying logic is so ugly that it has its own function. + * \note this assumes no transactions are active + * \return MDB_ errcode, not usual kr_error(...) + */ +static int txn_get_noresize(struct lmdb_env *env, unsigned int flag, MDB_txn **txn) +{ + if (kr_fails_assert(!env->txn.rw && (!env->txn.ro || !env->txn.ro_active))) + return kr_error(1); + int attempts = 0; + int ret; +retry: + /* Do a few attempts in case we encounter multiple issues at once. */ + if (++attempts > 2) + return kr_error(1); + + if (flag == FLAG_RENEW) { + ret = mdb_txn_renew(*txn); + } else { + ret = mdb_txn_begin(env->env, NULL, flag, txn); + } + + if (unlikely(ret == MDB_MAP_RESIZED)) { + kr_log_info(CACHE, "detected size increased by another process\n"); + ret = refresh_mapsize(env); + if (ret == 0) + goto retry; + } else if (unlikely(ret == MDB_READERS_FULL)) { + clear_stale_readers(env); + goto retry; + } + return ret; +} + +/** Obtain a transaction. (they're cached in env->txn) */ +static int txn_get(struct lmdb_env *env, MDB_txn **txn, bool rdonly) +{ + if (kr_fails_assert(env && txn)) + return kr_error(EINVAL); + if (env->txn.rw) { + /* Reuse the *open* RW txn even if only reading is requested. + * We leave the management of this to the cdb_commit command. + * The user may e.g. want to do some reads between the writes. */ + *txn = env->txn.rw; + return kr_ok(); + } + + if (!rdonly) { + /* avoid two active transactions */ + if (env->txn.ro && env->txn.ro_active) { + mdb_txn_reset(env->txn.ro); + env->txn.ro_active = false; + env->txn.ro_curs_active = false; + } + int ret = txn_get_noresize(env, 0/*RW*/, &env->txn.rw); + if (ret == MDB_SUCCESS) { + *txn = env->txn.rw; + kr_assert(*txn); + } + return lmdb_error(ret); + } + + /* Get an active RO txn and return it. */ + int ret = MDB_SUCCESS; + if (!env->txn.ro) { //:unlikely + ret = txn_get_noresize(env, MDB_RDONLY, &env->txn.ro); + } else if (!env->txn.ro_active) { + ret = txn_get_noresize(env, FLAG_RENEW, &env->txn.ro); + } + if (ret != MDB_SUCCESS) { + return lmdb_error(ret); + } + env->txn.ro_active = true; + *txn = env->txn.ro; + kr_assert(*txn); + return kr_ok(); +} + +static int cdb_commit(kr_cdb_pt db, struct kr_cdb_stats *stats) +{ + struct lmdb_env *env = db2env(db); + int ret = kr_ok(); + if (env->txn.rw) { + if (stats) stats->commit++; + ret = lmdb_error(mdb_txn_commit(env->txn.rw)); + env->txn.rw = NULL; /* the transaction got freed even in case of errors */ + } else if (env->txn.ro && env->txn.ro_active) { + mdb_txn_reset(env->txn.ro); + env->txn.ro_active = false; + env->txn.ro_curs_active = false; + } + return ret; +} + +/** Obtain a read-only cursor (and a read-only transaction). */ +static int txn_curs_get(struct lmdb_env *env, MDB_cursor **curs, struct kr_cdb_stats *stats) +{ + if (kr_fails_assert(env && curs)) + return kr_error(EINVAL); + if (env->txn.ro_curs_active) + goto success; + /* Only in a read-only txn; TODO: it's a bit messy/coupled */ + if (env->txn.rw) { + int ret = cdb_commit(env2db(env), stats); + if (ret) return ret; + } + MDB_txn *txn = NULL; + int ret = txn_get(env, &txn, true); + if (ret) return ret; + + if (env->txn.ro_curs) { + ret = mdb_cursor_renew(txn, env->txn.ro_curs); + } else { + ret = mdb_cursor_open(txn, env->dbi, &env->txn.ro_curs); + } + if (ret) return lmdb_error(ret); + env->txn.ro_curs_active = true; +success: + kr_assert(env->txn.ro_curs_active && env->txn.ro && env->txn.ro_active + && !env->txn.rw); + *curs = env->txn.ro_curs; + kr_assert(*curs); + return kr_ok(); +} + +static void txn_free_ro(struct lmdb_env *env) +{ + if (env->txn.ro_curs) { + mdb_cursor_close(env->txn.ro_curs); + env->txn.ro_curs = NULL; + } + if (env->txn.ro) { + mdb_txn_abort(env->txn.ro); + env->txn.ro = NULL; + } +} + +/** Abort all transactions. + * + * This is useful after an error happens, as those (always?) require abortion. + * It's possible that _reset() would suffice and marking cursor inactive, + * but these errors should be rare so let's close them completely. */ +static void txn_abort(struct lmdb_env *env) +{ + txn_free_ro(env); + if (env->txn.rw) { + mdb_txn_abort(env->txn.rw); + env->txn.rw = NULL; /* the transaction got freed even in case of errors */ + } +} + +/*! \brief Close the database. */ +static void cdb_close_env(struct lmdb_env *env, struct kr_cdb_stats *stats) +{ + if (kr_fails_assert(env && env->env)) + return; + + /* Get rid of any transactions. */ + txn_free_ro(env); + cdb_commit(env2db(env), stats); + + mdb_env_sync(env->env, 1); + stats->close++; + mdb_dbi_close(env->env, env->dbi); + mdb_env_close(env->env); + free_const(env->mdb_data_path); + memset(env, 0, sizeof(*env)); +} + +/** We assume that *env is zeroed and we return it zeroed on errors. */ +static int cdb_open_env(struct lmdb_env *env, const char *path, const size_t mapsize, + struct kr_cdb_stats *stats) +{ + int ret = mkdir(path, LMDB_DIR_MODE); + if (ret && errno != EEXIST) return kr_error(errno); + + stats->open++; + ret = mdb_env_create(&env->env); + if (ret != MDB_SUCCESS) return lmdb_error(ret); + + env->mdb_data_path = kr_absolutize_path(path, "data.mdb"); + if (!env->mdb_data_path) { + ret = ENOMEM; + goto error_sys; + } + + /* Set map size, rounded to page size. */ + errno = 0; + const long pagesize = sysconf(_SC_PAGESIZE); + if (errno) { + ret = errno; + goto error_sys; + } + + const bool size_requested = mapsize; + if (size_requested) { + env->mapsize = (mapsize / pagesize) * pagesize; + ret = mdb_env_set_mapsize(env->env, env->mapsize); + if (ret != MDB_SUCCESS) goto error_mdb; + } + + /* Cache doesn't require durability, we can be + * loose with the requirements as a tradeoff for speed. */ + const unsigned flags = MDB_WRITEMAP | MDB_MAPASYNC | MDB_NOTLS; + ret = mdb_env_open(env->env, path, flags, LMDB_FILE_MODE); + if (ret != MDB_SUCCESS) goto error_mdb; + + mdb_filehandle_t fd = -1; + ret = mdb_env_get_fd(env->env, &fd); + if (ret != MDB_SUCCESS) goto error_mdb; + + struct stat st; + if (fstat(fd, &st)) { + ret = errno; + goto error_sys; + } + env->st_dev = st.st_dev; + env->st_ino = st.st_ino; + env->st_size = st.st_size; + + /* Get the real mapsize. Shrinking can be restricted, etc. + * Unfortunately this is only reliable when not setting the size explicitly. */ + if (!size_requested) { + ret = refresh_mapsize(env); + if (ret) goto error_sys; + } + + /* Open the database. */ + MDB_txn *txn = NULL; + ret = mdb_txn_begin(env->env, NULL, 0, &txn); + if (ret != MDB_SUCCESS) goto error_mdb; + + ret = mdb_dbi_open(txn, NULL, 0, &env->dbi); + if (ret != MDB_SUCCESS) { + mdb_txn_abort(txn); + goto error_mdb; + } + +#if !defined(__MACOSX__) && !(defined(__APPLE__) && defined(__MACH__)) + if (size_requested) { + ret = posix_fallocate(fd, 0, MAX(env->mapsize, env->st_size)); + } else { + ret = 0; + } + if (ret == EINVAL || ret == EOPNOTSUPP) { + /* POSIX says this can happen when the feature isn't supported by the FS. + * We haven't seen this happen on Linux+glibc but it was reported on + * Linux+musl and FreeBSD. */ + kr_log_info(CACHE, "space pre-allocation failed and ignored; " + "your (file)system probably doesn't support it.\n"); + } else if (ret != 0) { + mdb_txn_abort(txn); + goto error_sys; + } +#endif + + stats->commit++; + ret = mdb_txn_commit(txn); + if (ret != MDB_SUCCESS) goto error_mdb; + + /* Stale RO transactions could have been left behind by a cashing process + * (e.g. one whose termination lead to spawning the current one). + * According to docs they might hold onto some space until we clear them. */ + clear_stale_readers(env); + + return kr_ok(); + +error_mdb: + ret = lmdb_error(ret); +error_sys: + free_const(env->mdb_data_path); + stats->close++; + mdb_env_close(env->env); + memset(env, 0, sizeof(*env)); + return kr_error(ret); +} + +static int cdb_init(kr_cdb_pt *db, struct kr_cdb_stats *stats, + struct kr_cdb_opts *opts, knot_mm_t *pool) +{ + if (!db || !stats || !opts) { + return kr_error(EINVAL); + } + + /* Open the database. */ + struct lmdb_env *env = calloc(1, sizeof(*env)); + if (!env) { + return kr_error(ENOMEM); + } + int ret = cdb_open_env(env, opts->path, opts->maxsize, stats); + if (ret != 0) { + free(env); + return ret; + } + + *db = env2db(env); + return 0; +} + +static void cdb_deinit(kr_cdb_pt db, struct kr_cdb_stats *stats) +{ + cdb_close_env(db2env(db), stats); + free(db); +} + +static int cdb_count(kr_cdb_pt db, struct kr_cdb_stats *stats) +{ + struct lmdb_env *env = db2env(db); + MDB_txn *txn = NULL; + int ret = txn_get(env, &txn, true); + if (ret != 0) { + return ret; + } + + MDB_stat stat; + stats->count++; + ret = mdb_stat(txn, env->dbi, &stat); + + if (ret == MDB_SUCCESS) { + return stat.ms_entries; + } else { + txn_abort(env); + return lmdb_error(ret); + } +} + +static int reopen_env(struct lmdb_env *env, struct kr_cdb_stats *stats, const size_t mapsize) +{ + /* Keep copy as it points to current handle internals. */ + const char *path; + int ret = mdb_env_get_path(env->env, &path); + if (ret != MDB_SUCCESS) { + return lmdb_error(ret); + } + auto_free char *path_copy = strdup(path); + cdb_close_env(env, stats); + return cdb_open_env(env, path_copy, mapsize, stats); +} + +static int cdb_check_health(kr_cdb_pt db, struct kr_cdb_stats *stats) +{ + struct lmdb_env *env = db2env(db); + + struct stat st; + if (stat(env->mdb_data_path, &st)) { + int ret = errno; + return kr_error(ret); + } + + if (st.st_dev != env->st_dev || st.st_ino != env->st_ino) { + kr_log_debug(CACHE, "cache file has been replaced, reopening\n"); + int ret = reopen_env(env, stats, 0); // we accept mapsize from the new file + return ret == 0 ? 1 : ret; + } + + /* Cache check through file size works OK without reopening, + * contrary to methods based on mdb_env_info(). */ + if (st.st_size == env->st_size) + return kr_ok(); + kr_log_info(CACHE, "detected size change (by another instance?) of file '%s'" + ": file size %zu -> file size %zu\n", + env->mdb_data_path, (size_t)env->st_size, (size_t)st.st_size); + env->st_size = st.st_size; // avoid retrying in cycle even if we fail + return refresh_mapsize(env); +} + +/** Obtain exclusive (advisory) lock by creating a file, returning FD or negative kr_error(). + * The lock is auto-released by OS in case the process finishes in any way (file remains). */ +static int lockfile_get(const char *path) +{ + if (kr_fails_assert(path)) + return kr_error(EINVAL); + const int fd = open(path, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP); + if (fd < 0) + return kr_error(errno); + + struct flock lock_info; + memset(&lock_info, 0, sizeof(lock_info)); + lock_info.l_type = F_WRLCK; + lock_info.l_whence = SEEK_SET; + lock_info.l_start = 0; + lock_info.l_len = 1; // it's OK for locks to extend beyond the end of the file + int err; + do { + err = fcntl(fd, F_SETLK, &lock_info); + } while (err == -1 && errno == EINTR); + if (err) { + close(fd); + return kr_error(errno); + } + return fd; +} + +/** Release and remove lockfile created by lockfile_get(). Return kr_error(). */ +static int lockfile_release(int fd) +{ + if (kr_fails_assert(fd > 0)) // fd == 0 is surely a mistake, in our case at least + return kr_error(EINVAL); + if (close(fd)) { + return kr_error(errno); + } else { + return kr_ok(); + } +} + +static int cdb_clear(kr_cdb_pt db, struct kr_cdb_stats *stats) +{ + struct lmdb_env *env = db2env(db); + stats->clear++; + /* First try mdb_drop() to clear the DB; this may fail with ENOSPC. */ + { + MDB_txn *txn = NULL; + int ret = txn_get(env, &txn, false); + if (ret == kr_ok()) { + ret = lmdb_error(mdb_drop(txn, env->dbi, 0)); + if (ret == kr_ok()) { + ret = cdb_commit(db, stats); + } + if (ret == kr_ok()) { + return ret; + } + } + kr_log_info(CACHE, "clearing error, falling back\n"); + } + /* Fallback: we'll remove the database files and reopen. + * Other instances can continue to use the removed lmdb, + * though it's best for them to reopen soon. */ + + /* We are about to switch to a different file, so end all txns, to be sure. */ + txn_free_ro(env); + (void) cdb_commit(db, stats); + + const char *path = NULL; + int ret = mdb_env_get_path(env->env, &path); + if (ret != MDB_SUCCESS) { + return lmdb_error(ret); + } + auto_free char *mdb_lockfile = kr_strcatdup(2, path, "/lock.mdb"); + auto_free char *lockfile = kr_strcatdup(2, path, "/krcachelock"); + if (!mdb_lockfile || !lockfile) { + return kr_error(ENOMEM); + } + + /* Find if we get a lock on lockfile. */ + const int lockfile_fd = lockfile_get(lockfile); + if (lockfile_fd < 0) { + kr_log_error(CACHE, "clearing failed to get ./krcachelock (%s); retry later\n", + kr_strerror(lockfile_fd)); + /* As we're out of space (almost certainly - mdb_drop didn't work), + * we will retry on the next failing write operation. */ + return kr_error(EAGAIN); + } + + /* We acquired lockfile. Now find whether *.mdb are what we have open now. + * If they are not we don't want to remove them; most likely they have been + * cleaned by another instance. */ + ret = cdb_check_health(db, stats); + if (ret != 0) { + if (ret == 1) // file changed and reopened successfully + ret = kr_ok(); + // else pass some other error + } else { + kr_log_debug(CACHE, "clear: identical files, unlinking\n"); + // coverity[toctou] + unlink(env->mdb_data_path); + unlink(mdb_lockfile); + ret = reopen_env(env, stats, env->mapsize); + } + + /* Environment updated, release lockfile. */ + int lrerr = lockfile_release(lockfile_fd); + if (lrerr) { + kr_log_error(CACHE, "failed to release ./krcachelock: %s\n", + kr_strerror(lrerr)); + } + return ret; +} + +static int cdb_readv(kr_cdb_pt db, struct kr_cdb_stats *stats, + const knot_db_val_t *key, knot_db_val_t *val, int maxcount) +{ + struct lmdb_env *env = db2env(db); + MDB_txn *txn = NULL; + int ret = txn_get(env, &txn, true); + if (ret) { + return ret; + } + + for (int i = 0; i < maxcount; ++i) { + /* Convert key structs */ + MDB_val _key = val_knot2mdb(key[i]); + MDB_val _val = val_knot2mdb(val[i]); + stats->read++; + ret = mdb_get(txn, env->dbi, &_key, &_val); + if (ret != MDB_SUCCESS) { + if (ret == MDB_NOTFOUND) { + stats->read_miss++; + } else { + txn_abort(env); + } + ret = lmdb_error(ret); + if (ret == kr_error(ENOSPC)) { + /* we're likely to be forced to cache clear anyway */ + ret = kr_error(ENOENT); + } + return ret; + } + /* Update the result. */ + val[i] = val_mdb2knot(_val); + } + return kr_ok(); +} + +static int cdb_write(struct lmdb_env *env, MDB_txn **txn, const knot_db_val_t *key, + knot_db_val_t *val, unsigned flags, + struct kr_cdb_stats *stats) +{ + /* Convert key structs and write */ + MDB_val _key = val_knot2mdb(*key); + MDB_val _val = val_knot2mdb(*val); + stats->write++; + int ret = mdb_put(*txn, env->dbi, &_key, &_val, flags); + + /* We don't try to recover from MDB_TXN_FULL. */ + if (ret != MDB_SUCCESS) { + txn_abort(env); + return lmdb_error(ret); + } + + /* Update the result. */ + val->data = _val.mv_data; + val->len = _val.mv_size; + return kr_ok(); +} + +static int cdb_writev(kr_cdb_pt db, struct kr_cdb_stats *stats, + const knot_db_val_t *key, knot_db_val_t *val, int maxcount) +{ + struct lmdb_env *env = db2env(db); + MDB_txn *txn = NULL; + int ret = txn_get(env, &txn, false); + + for (int i = 0; ret == kr_ok() && i < maxcount; ++i) { + /* This is LMDB specific optimisation, + * if caller specifies value with NULL data and non-zero length, + * LMDB will preallocate the entry for caller and leave write + * transaction open, caller is responsible for syncing thus committing transaction. + */ + unsigned mdb_flags = 0; + if (val[i].len > 0 && val[i].data == NULL) { + mdb_flags |= MDB_RESERVE; + } + ret = cdb_write(env, &txn, &key[i], &val[i], mdb_flags, stats); + } + + return ret; +} + +static int cdb_remove(kr_cdb_pt db, struct kr_cdb_stats *stats, + knot_db_val_t keys[], int maxcount) +{ + struct lmdb_env *env = db2env(db); + MDB_txn *txn = NULL; + int ret = txn_get(env, &txn, false); + int deleted = 0; + + for (int i = 0; ret == kr_ok() && i < maxcount; ++i) { + MDB_val _key = val_knot2mdb(keys[i]); + MDB_val val = { 0, NULL }; + stats->remove++; + ret = lmdb_error(mdb_del(txn, env->dbi, &_key, &val)); + if (ret == kr_ok()) + deleted++; + else if (ret == KNOT_ENOENT) { + stats->remove_miss++; + ret = kr_ok(); /* skip over non-existing entries */ + } else { + txn_abort(env); + break; + } + } + + return ret < 0 ? ret : deleted; +} + +static int cdb_match(kr_cdb_pt db, struct kr_cdb_stats *stats, + knot_db_val_t *key, knot_db_val_t keyval[][2], int maxcount) +{ + struct lmdb_env *env = db2env(db); + MDB_txn *txn = NULL; + int ret = txn_get(env, &txn, true); + if (ret != 0) { + return ret; + } + + /* LATER(optim.): use txn_curs_get() instead, to save resources. */ + MDB_cursor *cur = NULL; + ret = mdb_cursor_open(txn, env->dbi, &cur); + if (ret != 0) { + txn_abort(env); + return lmdb_error(ret); + } + + MDB_val cur_key = val_knot2mdb(*key); + MDB_val cur_val = { 0, NULL }; + stats->match++; + ret = mdb_cursor_get(cur, &cur_key, &cur_val, MDB_SET_RANGE); + if (ret != MDB_SUCCESS) { + mdb_cursor_close(cur); + if (ret != MDB_NOTFOUND) { + txn_abort(env); + } + return lmdb_error(ret); + } + + int results = 0; + while (ret == MDB_SUCCESS) { + /* Retrieve current key and compare with prefix */ + if (cur_key.mv_size < key->len || memcmp(cur_key.mv_data, key->data, key->len) != 0) { + break; + } + /* Add to result set */ + if (results < maxcount) { + keyval[results][0] = val_mdb2knot(cur_key); + keyval[results][1] = val_mdb2knot(cur_val); + ++results; + } else { + break; + } + stats->match++; + ret = mdb_cursor_get(cur, &cur_key, &cur_val, MDB_NEXT); + } + + mdb_cursor_close(cur); + if (ret != MDB_SUCCESS && ret != MDB_NOTFOUND) { + txn_abort(env); + return lmdb_error(ret); + } else if (results == 0) { + stats->match_miss++; + } + return results; +} + + +static int cdb_read_leq(kr_cdb_pt db, struct kr_cdb_stats *stats, + knot_db_val_t *key, knot_db_val_t *val) +{ + if (kr_fails_assert(db && key && key->data && val)) + return kr_error(EINVAL); + struct lmdb_env *env = db2env(db); + MDB_cursor *curs = NULL; + int ret = txn_curs_get(env, &curs, stats); + if (ret) return ret; + + MDB_val key2_m = val_knot2mdb(*key); + MDB_val val2_m = { 0, NULL }; + stats->read_leq++; + ret = mdb_cursor_get(curs, &key2_m, &val2_m, MDB_SET_RANGE); + if (ret) goto failure; + /* test for equality //:unlikely */ + if (key2_m.mv_size == key->len + && memcmp(key2_m.mv_data, key->data, key->len) == 0) { + ret = 0; /* equality */ + goto success; + } + stats->read_leq_miss++; + + /* we must be greater than key; do one step to smaller */ + stats->read_leq++; + ret = mdb_cursor_get(curs, &key2_m, &val2_m, MDB_PREV); + if (ret) goto failure; + ret = 1; +success: + /* finalize the output */ + *key = val_mdb2knot(key2_m); + *val = val_mdb2knot(val2_m); + return ret; +failure: + if (ret == MDB_NOTFOUND) { + stats->read_leq_miss++; + } else { + txn_abort(env); + } + return lmdb_error(ret); +} + +static double cdb_usage_percent(kr_cdb_pt db) +{ + knot_db_t *kdb = kr_cdb_pt2knot_db_t(db); + const size_t db_size = knot_db_lmdb_get_mapsize(kdb); + const size_t db_usage_abs = knot_db_lmdb_get_usage(kdb); + const double db_usage = (double)db_usage_abs / db_size * 100.0; + free(kdb); + return db_usage; +} + +static size_t cdb_get_maxsize(kr_cdb_pt db) +{ + return db2env(db)->mapsize; +} + +/** Conversion between knot and lmdb structs. */ +knot_db_t *kr_cdb_pt2knot_db_t(kr_cdb_pt db) +{ + /* this is struct lmdb_env as in resolver/cdb_lmdb.c */ + const struct lmdb_env *kres_db = db2env(db); + struct libknot_lmdb_env *libknot_db = malloc(sizeof(*libknot_db)); + if (libknot_db != NULL) { + libknot_db->shared = false; + libknot_db->pool = NULL; + libknot_db->env = kres_db->env; + libknot_db->dbi = kres_db->dbi; + } + return libknot_db; +} + +const struct kr_cdb_api *kr_cdb_lmdb(void) +{ + static const struct kr_cdb_api api = { + "lmdb", + cdb_init, cdb_deinit, cdb_count, cdb_clear, cdb_commit, + cdb_readv, cdb_writev, cdb_remove, + cdb_match, + cdb_read_leq, + cdb_usage_percent, + cdb_get_maxsize, + cdb_check_health, + }; + + return &api; +} diff --git a/lib/cache/cdb_lmdb.h b/lib/cache/cdb_lmdb.h new file mode 100644 index 0000000..988fccf --- /dev/null +++ b/lib/cache/cdb_lmdb.h @@ -0,0 +1,16 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later +*/ + +#pragma once + +#include "lib/cache/cdb_api.h" +#include "lib/defines.h" + +KR_EXPORT KR_CONST +const struct kr_cdb_api *kr_cdb_lmdb(void); + +/** Create a pointer for knot_db_lmdb_api. You free() it to release it. */ +KR_EXPORT +knot_db_t *kr_cdb_pt2knot_db_t(kr_cdb_pt db); + diff --git a/lib/cache/entry_list.c b/lib/cache/entry_list.c new file mode 100644 index 0000000..4dced2f --- /dev/null +++ b/lib/cache/entry_list.c @@ -0,0 +1,301 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Implementation of chaining in struct entry_h. Prototypes in ./impl.h + */ + +#include "lib/cache/impl.h" +#include "lib/utils.h" + + +static int entry_h_len(knot_db_val_t val); + + +void entry_list_memcpy(struct entry_apex *ea, entry_list_t list) +{ + if (kr_fails_assert(ea)) + return; + memset(ea, 0, offsetof(struct entry_apex, data)); + ea->has_ns = list[EL_NS ].len; + ea->has_cname = list[EL_CNAME ].len; + ea->has_dname = list[EL_DNAME ].len; + for (int i = 0; i < ENTRY_APEX_NSECS_CNT; ++i) { + ea->nsecs[i] = list[i].len == 0 ? 0 : + (list[i].len == 4 ? 1 : 3); + } + uint8_t *it = ea->data; + for (int i = 0; i < EL_LENGTH; ++i) { + if (list[i].data) { + memcpy(it, list[i].data, list[i].len); + /* LATER(optim.): coalesce consecutive writes? */ + } else { + list[i].data = it; + } + it += to_even(list[i].len); + } +} + +int entry_list_parse(const knot_db_val_t val, entry_list_t list) +{ + if (kr_fails_assert(val.data && val.len && list)) + return kr_error(EINVAL); + /* Parse the apex itself (nsec parameters). */ + const struct entry_apex *ea = entry_apex_consistent(val); + if (!ea) { + return kr_error(EILSEQ); + } + const uint8_t *it = ea->data, + *it_bound = knot_db_val_bound(val); + for (int i = 0; i < ENTRY_APEX_NSECS_CNT; ++i) { + if (it > it_bound) { + return kr_error(EILSEQ); + } + list[i].data = (void *)it; + switch (ea->nsecs[i]) { + case 0: + list[i].len = 0; + break; + case 1: + list[i].len = sizeof(uint32_t); /* just timestamp */ + break; + case 3: { /* timestamp + NSEC3PARAM wire */ + if (it + sizeof(uint32_t) + 4 > it_bound) { + return kr_error(EILSEQ); + } + list[i].len = sizeof(uint32_t) + + nsec_p_rdlen(it + sizeof(uint32_t)); + break; + } + default: + return kr_error(EILSEQ); + }; + it += to_even(list[i].len); + } + /* Parse every entry_h. */ + for (int i = ENTRY_APEX_NSECS_CNT; i < EL_LENGTH; ++i) { + list[i].data = (void *)it; + bool has_type; + switch (i) { + case EL_NS: has_type = ea->has_ns; break; + case EL_CNAME: has_type = ea->has_cname; break; + case EL_DNAME: has_type = ea->has_dname; break; + default: + kr_assert(!EINVAL); + return kr_error(EINVAL); /* something very bad */ + } + if (!has_type) { + list[i].len = 0; + continue; + } + if (kr_fails_assert(it < it_bound)) + return kr_error(EILSEQ); + const int len = entry_h_len( + (knot_db_val_t){ .data = (void *)it, .len = it_bound - it }); + if (kr_fails_assert(len >= 0)) + return kr_error(len); + list[i].len = len; + it += to_even(len); + } + if (kr_fails_assert(it == it_bound)) /* better not use it; might be "damaged" */ + return kr_error(EILSEQ); + return kr_ok(); +} + +/** Given a valid entry header, find its length (i.e. offset of the next entry). + * \param val The beginning of the data and the bound (read only). + */ +static int entry_h_len(const knot_db_val_t val) +{ + const bool ok = val.data && ((ssize_t)val.len) > 0; + if (!ok) return kr_error(EINVAL); + const struct entry_h *eh = val.data; + const uint8_t *d = eh->data; /* iterates over the data in entry */ + const uint8_t *data_bound = knot_db_val_bound(val); + if (d >= data_bound) return kr_error(EILSEQ); + if (!eh->is_packet) { /* Positive RRset + its RRsig set (may be empty). */ + int sets = 2; + while (sets-- > 0) { + d += KR_CACHE_RR_COUNT_SIZE + rdataset_dematerialized_size(d, NULL); + if (kr_fails_assert(d <= data_bound)) + return kr_error(EILSEQ); + } + } else { /* A "packet" (opaque ATM). */ + uint16_t len; + if (d + sizeof(len) > data_bound) return kr_error(EILSEQ); + memcpy(&len, d, sizeof(len)); + d += 2 + to_even(len); + } + if (kr_fails_assert(d <= data_bound)) + return kr_error(EILSEQ); + return d - (uint8_t *)val.data; +} + +struct entry_apex * entry_apex_consistent(knot_db_val_t val) +{ + //XXX: check lengths, etc. + return val.data; +} + +/* See the header file. */ +int entry_h_seek(knot_db_val_t *val, uint16_t type) +{ + int i = -1; + switch (type) { + case KNOT_RRTYPE_NS: i = EL_NS; break; + case KNOT_RRTYPE_CNAME: i = EL_CNAME; break; + case KNOT_RRTYPE_DNAME: i = EL_DNAME; break; + default: return kr_ok(); + } + + entry_list_t el; + int ret = entry_list_parse(*val, el); + if (ret) return ret; + *val = el[i]; + return val->len ? kr_ok() : kr_error(ENOENT); +} + +static int cache_write_or_clear(struct kr_cache *cache, const knot_db_val_t *key, + knot_db_val_t *val, const struct kr_query *qry) +{ + static uint64_t ignoring_errors_until = 0; /// zero or a timestamp + int ret = cache_op(cache, write, key, val, 1); + if (!ret) { + ignoring_errors_until = 0; + return kr_ok(); + } + VERBOSE_MSG(qry, "=> failed backend write, ret = %d\n", ret); + + if (ret == kr_error(ENOSPC) && cache->api->usage_percent(cache->db) > 90) { + // Cache seems overfull. Maybe kres-cache-gc service doesn't work. + goto recovery; + } + + /* If we get ENOSPC with usage < 90% (especially just above 80% when GC fires), + * it most likely isn't real overfull state but some LMDB bug related + * to transactions. Upstream seems unlikely to address it: + https://lists.openldap.org/hyperkitty/list/openldap-technical@openldap.org/thread/QHOTE2Y3WZ6E7J27OOKI44P344ETUOSF/ + * + * In real life we see all processes getting a LMDB failure + * but it should recover after the transactions get reopened. + * + * Fortunately the kresd cache can afford to be slightly lossy, + * so we ignore this and other errors for a short while. + */ + const uint64_t now = kr_now(); + if (!ignoring_errors_until) { // First error after a success. + kr_log_info(CACHE, "LMDB refusing writes (ignored for 5-9s): %s\n", + kr_strerror(ret)); + ignoring_errors_until = now + 5000 + kr_rand_bytes(2)/16; + return kr_error(ret); + } + if (now < ignoring_errors_until) + return kr_error(ret); + // We've lost patience with cache writes not working continuously. + +recovery: // Try to recover by clearing cache. + ret = kr_cache_clear(cache); + switch (ret) { + default: + kr_log_crit(CACHE, "CRITICAL: clearing cache failed: %s; fatal error, aborting\n", + kr_strerror(ret)); + abort(); + case 0: + kr_log_info(CACHE, "stuck cache cleared\n"); + ignoring_errors_until = 0; + case -EAGAIN: // fall-through; krcachelock race -> retry later + return kr_error(ENOSPC); + } +} + + +/* See the header file. */ +int entry_h_splice( + knot_db_val_t *val_new_entry, uint8_t rank, + const knot_db_val_t key, const uint16_t ktype, const uint16_t type, + const knot_dname_t *owner/*log only*/, + const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp) +{ + //TODO: another review, perhaps including the API + if (kr_fails_assert(val_new_entry && val_new_entry->len > 0)) + return kr_error(EINVAL); + + int i_type; + switch (type) { + case KNOT_RRTYPE_NS: i_type = EL_NS; break; + case KNOT_RRTYPE_CNAME: i_type = EL_CNAME; break; + case KNOT_RRTYPE_DNAME: i_type = EL_DNAME; break; + default: i_type = 0; + } + + /* Get eh_orig (original entry), and also el list if multi-entry case. */ + const struct entry_h *eh_orig = NULL; + entry_list_t el; + int ret = -1; + if (!kr_rank_test(rank, KR_RANK_SECURE) || ktype == KNOT_RRTYPE_NS) { + knot_db_val_t val; + ret = cache_op(cache, read, &key, &val, 1); + if (i_type) { + if (!ret) ret = entry_list_parse(val, el); + if (ret) memset(el, 0, sizeof(el)); + val = el[i_type]; + } + /* val is on the entry, in either case (or error) */ + if (!ret) { + eh_orig = entry_h_consistent_E(val, type); + } + } else { + /* We want to fully overwrite the entry, so don't even read it. */ + memset(el, 0, sizeof(el)); + } + + if (!kr_rank_test(rank, KR_RANK_SECURE) && eh_orig) { + /* If equal rank was accepted, spoofing a *single* answer would be + * enough to e.g. override NS record in AUTHORITY section. + * This way they would have to hit the first answer + * (whenever TTL nears expiration). + * Stale-serving is NOT considered, but TTL 1 would be considered + * as expiring anyway, ... */ + int32_t old_ttl = get_new_ttl(eh_orig, qry, NULL, 0, timestamp); + if (old_ttl > 0 && !is_expiring(eh_orig->ttl, old_ttl) + && rank <= eh_orig->rank) { + WITH_VERBOSE(qry) { + auto_free char *type_str = kr_rrtype_text(type), + *owner_str = kr_dname_text(owner); + VERBOSE_MSG(qry, "=> not overwriting %s %s\n", + type_str, owner_str); + } + return kr_error(EEXIST); + } + } + + if (!i_type) { + /* The non-list types are trivial now. */ + return cache_write_or_clear(cache, &key, val_new_entry, qry); + } + /* Now we're in trouble. In some cases, parts of data to be written + * is an lmdb entry that may be invalidated by our write request. + * (lmdb does even in-place updates!) Therefore we copy all into a buffer. + * LATER(optim.): do this only when necessary, or perhaps another approach. + * This is also complicated by the fact that the val_new_entry part + * is to be written *afterwards* by the caller. + */ + el[i_type] = (knot_db_val_t){ + .len = val_new_entry->len, + .data = NULL, /* perhaps unclear in the entry_h_splice() API */ + }; + knot_db_val_t val = { + .len = entry_list_serial_size(el), + .data = NULL, + }; + uint8_t buf[val.len]; + entry_list_memcpy((struct entry_apex *)buf, el); + ret = cache_write_or_clear(cache, &key, &val, qry); + if (ret) return kr_error(ret); + memcpy(val.data, buf, val.len); /* we also copy the "empty" space, but well... */ + val_new_entry->data = (uint8_t *)val.data + + ((uint8_t *)el[i_type].data - buf); + return kr_ok(); +} + diff --git a/lib/cache/entry_pkt.c b/lib/cache/entry_pkt.c new file mode 100644 index 0000000..884bfaa --- /dev/null +++ b/lib/cache/entry_pkt.c @@ -0,0 +1,206 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Implementation of packet-caching. Prototypes in ./impl.h + * + * The packet is stashed in entry_h::data as uint16_t length + full packet wire format. + */ + +#include "lib/utils.h" +#include "lib/layer/iterate.h" /* kr_response_classify */ +#include "lib/cache/impl.h" + + +/** Compute TTL for a packet. It's minimum TTL or zero. (You can apply limits.) */ +KR_EXPORT +uint32_t packet_ttl(const knot_pkt_t *pkt) +{ + bool has_ttl = false; + uint32_t ttl = TTL_MAX_MAX; + for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) { + const knot_pktsection_t *sec = knot_pkt_section(pkt, i); + for (unsigned k = 0; k < sec->count; ++k) { + const knot_rrset_t *rr = knot_pkt_rr(sec, k); + ttl = MIN(ttl, rr->ttl); + has_ttl = true; + } + } + return has_ttl ? ttl : 0; +} + + +void stash_pkt(const knot_pkt_t *pkt, const struct kr_query *qry, + const struct kr_request *req, const bool needs_pkt) +{ + /* In some cases, stash also the packet. */ + const bool is_negative = kr_response_classify(pkt) + & (PKT_NODATA|PKT_NXDOMAIN); + const struct kr_qflags * const qf = &qry->flags; + const bool want_negative = qf->DNSSEC_INSECURE || !qf->DNSSEC_WANT; + const bool want_pkt = qf->DNSSEC_BOGUS /*< useful for +cd answers */ + || (is_negative && want_negative) || needs_pkt; + + if (!want_pkt || !knot_wire_get_aa(pkt->wire) + || pkt->parsed != pkt->size /*< malformed packet; still can't detect KNOT_EFEWDATA */ + ) { + return; + } + + /* Compute rank. If cd bit is set or we got answer via non-validated + * forwarding, make the rank bad; otherwise it depends on flags. + * TODO: probably make validator attempt validation even with +cd. */ + uint8_t rank = KR_RANK_AUTH; + const bool risky_vldr = is_negative && qf->FORWARD && qf->CNAME; + /* ^^ CNAME'ed NXDOMAIN answer in forwarding mode can contain + * unvalidated records; original commit: d6e22f476. */ + if (knot_wire_get_cd(req->qsource.packet->wire) || qf->STUB || risky_vldr) { + kr_rank_set(&rank, KR_RANK_OMIT); + } else { + if (qf->DNSSEC_BOGUS) { + kr_rank_set(&rank, KR_RANK_BOGUS); + } else if (qf->DNSSEC_INSECURE) { + kr_rank_set(&rank, KR_RANK_INSECURE); + } else if (!qf->DNSSEC_WANT) { + /* no TAs at all, leave _RANK_AUTH */ + } else if (needs_pkt) { + /* All bad cases should be filtered above, + * at least the same way as pktcache in kresd 1.5.x. */ + kr_rank_set(&rank, KR_RANK_SECURE); + } else kr_assert(false); + } + + const uint16_t pkt_type = knot_pkt_qtype(pkt); + const knot_dname_t *owner = knot_pkt_qname(pkt); /* qname can't be compressed */ + + // LATER: nothing exists under NXDOMAIN. Implement that (optionally)? +#if 0 + if (knot_wire_get_rcode(pkt->wire) == KNOT_RCODE_NXDOMAIN + /* && !qf->DNSSEC_INSECURE */ ) { + pkt_type = KNOT_RRTYPE_NS; + } +#endif + + /* Construct the key under which the pkt will be stored. */ + struct key k_storage, *k = &k_storage; + knot_db_val_t key; + int ret = kr_dname_lf(k->buf, owner, false); + if (ret) { + /* A server might (incorrectly) reply with QDCOUNT=0. */ + kr_assert(owner == NULL); + return; + } + key = key_exact_type_maypkt(k, pkt_type); + + /* For now we stash the full packet byte-exactly as it came from upstream. */ + const uint16_t pkt_size = pkt->size; + knot_db_val_t val_new_entry = { + .data = NULL, + .len = offsetof(struct entry_h, data) + sizeof(pkt_size) + pkt->size, + }; + /* Prepare raw memory for the new entry and fill it. */ + struct kr_cache *cache = &req->ctx->cache; + ret = entry_h_splice(&val_new_entry, rank, key, k->type, pkt_type, + owner, qry, cache, qry->timestamp.tv_sec); + if (ret || kr_fails_assert(val_new_entry.data)) return; /* some aren't really errors */ + struct entry_h *eh = val_new_entry.data; + memset(eh, 0, offsetof(struct entry_h, data)); + eh->time = qry->timestamp.tv_sec; + eh->ttl = MAX(MIN(packet_ttl(pkt), cache->ttl_max), cache->ttl_min); + eh->rank = rank; + eh->is_packet = true; + eh->has_optout = qf->DNSSEC_OPTOUT; + memcpy(eh->data, &pkt_size, sizeof(pkt_size)); + memcpy(eh->data + sizeof(pkt_size), pkt->wire, pkt_size); + + WITH_VERBOSE(qry) { + auto_free char *type_str = kr_rrtype_text(pkt_type), + *owner_str = kr_dname_text(owner); + VERBOSE_MSG(qry, "=> stashed packet: rank 0%.2o, TTL %d, " + "%s %s (%d B)\n", + eh->rank, eh->ttl, + type_str, owner_str, (int)val_new_entry.len); + } +} + + +int answer_from_pkt(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type, + const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl) +{ + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; + + const uint16_t msgid = knot_wire_get_id(pkt->wire); + + /* Ensure the wire buffer is large enough. Strategy: fit and at least double. */ + uint16_t pkt_len; + memcpy(&pkt_len, eh->data, sizeof(pkt_len)); + if (pkt_len > pkt->max_size) { + pkt->max_size = MIN(KNOT_WIRE_MAX_PKTSIZE, + MAX(pkt->max_size * 2, pkt_len)); + mm_free(&ctx->req->pool, pkt->wire); /* no-op, but... */ + pkt->wire = mm_alloc(&ctx->req->pool, pkt->max_size); + pkt->compr.wire = pkt->wire; + /* TODO: ^^ nicer way how to replace knot_pkt_t::wire ? */ + } + kr_require(pkt->max_size >= pkt_len); + + /* Copy answer and reparse it, but keep the original message id. */ + knot_pkt_clear(pkt); + memcpy(pkt->wire, eh->data + 2, pkt_len); + pkt->size = pkt_len; + int ret = knot_pkt_parse(pkt, 0); + if (ret == KNOT_EFEWDATA || ret == KNOT_EMALF) { + return kr_error(ENOENT); + /* LATER(opt): try harder to avoid stashing such packets */ + } + if (kr_fails_assert(ret == KNOT_EOK)) + return kr_error(ret); + knot_wire_set_id(pkt->wire, msgid); + + /* Add rank into the additional field. */ + for (size_t i = 0; i < pkt->rrset_count; ++i) { + kr_assert(!pkt->rr[i].additional); + uint8_t *rr_rank = mm_alloc(&pkt->mm, sizeof(*rr_rank)); + if (!rr_rank) { + return kr_error(ENOMEM); + } + *rr_rank = eh->rank; + pkt->rr[i].additional = rr_rank; + } + + /* Adjust TTL in each record. */ + const uint32_t drift = eh->ttl - new_ttl; + for (knot_section_t i = KNOT_ANSWER; i <= KNOT_ADDITIONAL; ++i) { + const knot_pktsection_t *sec = knot_pkt_section(pkt, i); + for (unsigned k = 0; k < sec->count; ++k) { + knot_rrset_t *rrs = // vv FIXME?? + /*const-cast*/(knot_rrset_t *)knot_pkt_rr(sec, k); + /* We need to be careful: due to enforcing minimum TTL + * on packet, some records may be below that value. + * We keep those records at TTL 0. */ + if (rrs->ttl >= drift) { + rrs->ttl -= drift; + } else { + rrs->ttl = 0; + } + } + } + + /* Finishing touches. TODO: perhaps factor out */ + struct kr_qflags * const qf = &qry->flags; + qf->EXPIRING = is_expiring(eh->ttl, new_ttl); + qf->CACHED = true; + qf->NO_MINIMIZE = true; + qf->DNSSEC_INSECURE = kr_rank_test(eh->rank, KR_RANK_INSECURE); + qf->DNSSEC_BOGUS = kr_rank_test(eh->rank, KR_RANK_BOGUS); + if (qf->DNSSEC_INSECURE || qf->DNSSEC_BOGUS) { + qf->DNSSEC_WANT = false; + } + qf->DNSSEC_OPTOUT = eh->has_optout; + VERBOSE_MSG(qry, "=> satisfied by exact packet: rank 0%.2o, new TTL %d\n", + eh->rank, new_ttl); + return kr_ok(); +} + diff --git a/lib/cache/entry_rr.c b/lib/cache/entry_rr.c new file mode 100644 index 0000000..3239e7e --- /dev/null +++ b/lib/cache/entry_rr.c @@ -0,0 +1,115 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Implementation of RRset (de)materialization, i.e. (de)serialization to storage + * format used in cache (some repeated fields are omitted). Prototypes in ./impl.h + */ + +#include "lib/cache/impl.h" + +void rdataset_dematerialize(const knot_rdataset_t *rds, uint8_t * restrict data) +{ + /* FIXME: either give up on even alignment and thus direct usability + * of rdatasets as they are in lmdb, or align inside cdb_* functions + * (request sizes one byte longer and shift iff on an odd address). */ + //if ((size_t)data & 1) VERBOSE_MSG(NULL, "dematerialize: odd address\n"); + //const uint8_t *data0 = data; + kr_require(data); + const uint16_t rr_count = rds ? rds->count : 0; + memcpy(data, &rr_count, sizeof(rr_count)); + data += sizeof(rr_count); + if (rr_count) { + memcpy(data, rds->rdata, rds->size); + data += rds->size; + } + //VERBOSE_MSG(NULL, "dematerialized to %d B\n", (int)(data - data0)); + (void)data; // silence analyzers +} + +/** Materialize a knot_rdataset_t from cache with given TTL. + * Return the number of bytes consumed or an error code. + */ +static int rdataset_materialize(knot_rdataset_t * restrict rds, const uint8_t * const data, + const uint8_t *data_bound, knot_mm_t *pool) +{ + if (kr_fails_assert(rds && data && data_bound && data_bound > data && !rds->rdata + /*&& !((size_t)data & 1)*/)) + return kr_error(EINVAL); + kr_assert(pool); /* not required, but that's our current usage; guard leaks */ + const uint8_t *d = data; /* iterates over the cache data */ + /* First sum up the sizes for wire format length. */ + /* TODO: we might overrun here already, but we need to trust cache anyway...*/ + rds->size = rdataset_dematerialized_size(d, &rds->count); + d += KR_CACHE_RR_COUNT_SIZE; + if (d + rds->size > data_bound) { + VERBOSE_MSG(NULL, "materialize: EILSEQ!\n"); + return kr_error(EILSEQ); + } + if (!rds->count) { /* avoid mm_alloc(pool, 0); etc. */ + rds->rdata = NULL; + return d - data; + } + rds->rdata = mm_alloc(pool, rds->size); + if (!rds->rdata) { + return kr_error(ENOMEM); + } + memcpy(rds->rdata, d, rds->size); + d += rds->size; + //VERBOSE_MSG(NULL, "materialized from %d B\n", (int)(d - data)); + return d - data; +} + +int kr_cache_materialize(knot_rdataset_t *dst, const struct kr_cache_p *ref, + knot_mm_t *pool) +{ + struct entry_h *eh = ref->raw_data; + return rdataset_materialize(dst, eh->data, ref->raw_bound, pool); +} + + +int entry2answer(struct answer *ans, int id, + const struct entry_h *eh, const uint8_t *eh_bound, + const knot_dname_t *owner, uint16_t type, uint32_t new_ttl) +{ + /* We assume it's zeroed. Do basic sanity check. */ + const bool not_ok = ans->rrsets[id].set.rr || ans->rrsets[id].sig_rds.rdata + || (type == KNOT_RRTYPE_NSEC && ans->nsec_p.raw) + || (type == KNOT_RRTYPE_NSEC3 && !ans->nsec_p.raw); + if (kr_fails_assert(!not_ok)) + return kr_error(EINVAL); + /* Materialize the base RRset. */ + knot_rrset_t *rr = ans->rrsets[id].set.rr + = knot_rrset_new(owner, type, KNOT_CLASS_IN, new_ttl, ans->mm); + if (kr_fails_assert(rr)) + return kr_error(ENOMEM); + int ret = rdataset_materialize(&rr->rrs, eh->data, eh_bound, ans->mm); + if (kr_fails_assert(ret >= 0)) goto fail; + size_t data_off = ret; + ans->rrsets[id].set.rank = eh->rank; + ans->rrsets[id].set.expiring = is_expiring(eh->ttl, new_ttl); + /* Materialize the RRSIG RRset for the answer in (pseudo-)packet. */ + bool want_rrsigs = true; /* LATER(optim.): might be omitted in some cases. */ + if (want_rrsigs) { + ret = rdataset_materialize(&ans->rrsets[id].sig_rds, eh->data + data_off, + eh_bound, ans->mm); + if (kr_fails_assert(ret >= 0)) goto fail; + /* Sanity check: we consumed exactly all data. */ + int unused_bytes = eh_bound - (uint8_t *)eh->data - data_off - ret; + if (kr_fails_assert(unused_bytes == 0)) { + kr_log_error(CACHE, "entry2answer ERROR: unused bytes: %d\n", + unused_bytes); + ret = kr_error(EILSEQ); + goto fail; /* to be on the safe side */ + } + } + return kr_ok(); +fail: + /* Cleanup the item that we might've (partially) written to. */ + knot_rrset_free(ans->rrsets[id].set.rr, ans->mm); + knot_rdataset_clear(&ans->rrsets[id].sig_rds, ans->mm); + memset(&ans->rrsets[id], 0, sizeof(ans->rrsets[id])); + return kr_error(ret); +} + diff --git a/lib/cache/impl.h b/lib/cache/impl.h new file mode 100644 index 0000000..305f36e --- /dev/null +++ b/lib/cache/impl.h @@ -0,0 +1,439 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Header internal for cache implementation(s). + * Only LMDB works for now. + */ +#pragma once + +#include <stdbool.h> +#include <stdint.h> + +#include <libdnssec/error.h> +#include <libdnssec/nsec.h> +#include <libknot/consts.h> +#include <libknot/db/db.h> +#include <libknot/dname.h> + +#include "contrib/cleanup.h" +#include "contrib/murmurhash3/murmurhash3.h" /* hash() for nsec_p_hash() */ +#include "lib/cache/cdb_api.h" +#include "lib/resolve.h" + +/* Cache entry values - binary layout. + * + * It depends on type which is recognizable by the key. + * Code depending on the contents of the key is marked by CACHE_KEY_DEF. + * + * 'E' entry (exact hit): + * - ktype == NS: struct entry_apex - multiple types inside (NS and xNAME); + * - ktype != NS: struct entry_h + * * is_packet: uint16_t length, the rest is opaque and handled by ./entry_pkt.c + * * otherwise RRset + its RRSIG set (possibly empty). + * '1' or '3' entry (NSEC or NSEC3) + * - struct entry_h, contents is the same as for exact hit + * - flags don't make sense there + */ + +struct entry_h { + uint32_t time; /**< The time of inception. */ + uint32_t ttl; /**< TTL at inception moment. Assuming it fits into int32_t ATM. */ + uint8_t rank : 6; /**< See enum kr_rank */ + bool is_packet : 1; /**< Negative-answer packet for insecure/bogus name. */ + bool has_optout : 1; /**< Only for packets; persisted DNSSEC_OPTOUT. */ + uint8_t _pad; /**< We need even alignment for data now. */ + uint8_t data[]; +/* Well, we don't really need packing or alignment changes, + * but due to LMDB the whole structure may not be stored at an aligned address, + * and we need compilers (for non-x86) to know it to avoid SIGBUS (test: UBSAN). */ +} __attribute__ ((packed,aligned(1))); +struct entry_apex; + +/** Check basic consistency of entry_h for 'E' entries, not looking into ->data. + * (for is_packet the length of data is checked) + */ +KR_EXPORT +struct entry_h * entry_h_consistent_E(knot_db_val_t data, uint16_t type); + +struct entry_apex * entry_apex_consistent(knot_db_val_t val); + +/** Consistency check, ATM common for NSEC and NSEC3. */ +static inline struct entry_h * entry_h_consistent_NSEC(knot_db_val_t data) +{ + /* ATM it's enough to just extend the checks for exact entries. */ + const struct entry_h *eh = entry_h_consistent_E(data, KNOT_RRTYPE_NSEC); + bool ok = eh != NULL; + ok = ok && !eh->is_packet && !eh->has_optout; + return ok ? /*const-cast*/(struct entry_h *)eh : NULL; +} + +static inline struct entry_h * entry_h_consistent(knot_db_val_t data, uint16_t type) +{ + switch (type) { + case KNOT_RRTYPE_NSEC: + case KNOT_RRTYPE_NSEC3: + return entry_h_consistent_NSEC(data); + default: + return entry_h_consistent_E(data, type); + } +} + +/* nsec_p* - NSEC* chain parameters */ + +static inline int nsec_p_rdlen(const uint8_t *rdata) +{ + //TODO: do we really need the zero case? + return rdata ? 5 + rdata[4] : 0; /* rfc5155 4.2 and 3.2. */ +} +static const int NSEC_P_MAXLEN = sizeof(uint32_t) + 5 + 255; // TODO: remove?? + +/** Hash of NSEC3 parameters, used as a tag to separate different chains for same zone. */ +typedef uint32_t nsec_p_hash_t; +static inline nsec_p_hash_t nsec_p_mkHash(const uint8_t *nsec_p) +{ + kr_require(nsec_p && !(KNOT_NSEC3_FLAG_OPT_OUT & nsec_p[1])); + return hash((const char *)nsec_p, nsec_p_rdlen(nsec_p)); +} + +/** NSEC* parameters for the chain. */ +struct nsec_p { + const uint8_t *raw; /**< Pointer to raw NSEC3 parameters; NULL for NSEC. */ + nsec_p_hash_t hash; /**< Hash of `raw`, used for cache keys. */ + dnssec_nsec3_params_t libknot; /**< Format for libknot; owns malloced memory! */ +}; + + + +/** LATER(optim.): this is overshot, but struct key usage should be cheap ATM. */ +#define KR_CACHE_KEY_MAXLEN (KNOT_DNAME_MAXLEN + 100) /* CACHE_KEY_DEF */ + +struct key { + const knot_dname_t *zname; /**< current zone name (points within qry->sname) */ + uint8_t zlf_len; /**< length of current zone's lookup format */ + + /** Corresponding key type; e.g. NS for CNAME. + * Note: NSEC type is ambiguous (exact and range key). */ + uint16_t type; + /** The key data start at buf+1, and buf[0] contains some length. + * For details see key_exact* and key_NSEC* functions. */ + uint8_t buf[KR_CACHE_KEY_MAXLEN]; + /* LATER(opt.): ^^ probably change the anchoring, so that kr_dname_lf() + * doesn't need to move data after knot_dname_lf(). */ +}; + +static inline size_t key_nwz_off(const struct key *k) +{ + /* CACHE_KEY_DEF: zone name lf + 0 ('1' or '3'). + * NSEC '1' case continues just with the name within zone. */ + return k->zlf_len + 2; +} +static inline size_t key_nsec3_hash_off(const struct key *k) +{ + /* CACHE_KEY_DEF NSEC3: tag (nsec_p_hash_t) + 20 bytes NSEC3 name hash) */ + return key_nwz_off(k) + sizeof(nsec_p_hash_t); +} +/** Hash is always SHA1; I see no plans to standardize anything else. + * https://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml#dnssec-nsec3-parameters-3 + */ +static const int NSEC3_HASH_LEN = 20, + NSEC3_HASH_TXT_LEN = 32; + +/** Finish constructing string key for for exact search. + * It's assumed that kr_dname_lf(k->buf, owner, *) had been ran. + */ +knot_db_val_t key_exact_type_maypkt(struct key *k, uint16_t type); + +/** Like key_exact_type_maypkt but with extra checks if used for RRs only. */ +static inline knot_db_val_t key_exact_type(struct key *k, uint16_t type) +{ + switch (type) { + /* Sanity check: forbidden types represented in other way(s). */ + case KNOT_RRTYPE_NSEC: + case KNOT_RRTYPE_NSEC3: + kr_assert(false); + return (knot_db_val_t){ NULL, 0 }; + } + return key_exact_type_maypkt(k, type); +} + + +/* entry_h chaining; implementation in ./entry_list.c */ + +enum { ENTRY_APEX_NSECS_CNT = 2 }; + +/** Header of 'E' entry with ktype == NS. Inside is private to ./entry_list.c + * + * We store xNAME at NS type to lower the number of searches in closest_NS(). + * CNAME is only considered for equal name, of course. + * We also store NSEC* parameters at NS type. + */ +struct entry_apex { + /* ENTRY_H_FLAGS */ + bool has_ns : 1; + bool has_cname : 1; + bool has_dname : 1; + + uint8_t pad_; /**< 1 byte + 2 bytes + x bytes would be weird; let's do 2+2+x. */ + + /** We have two slots for NSEC* parameters. + * + * This array describes how they're filled; + * values: 0: none, 1: NSEC, 3: NSEC3. + * + * Two slots are a compromise to smoothly handle normal rollovers + * (either changing NSEC3 parameters or between NSEC and NSEC3). */ + int8_t nsecs[ENTRY_APEX_NSECS_CNT]; + uint8_t data[]; + /* XXX: if not first, stamp of last being the first? + * Purpose: save cache operations if rolled the algo/params long ago. */ +}; + +/** Indices for decompressed entry_list_t. */ +enum EL { + EL_NS = ENTRY_APEX_NSECS_CNT, + EL_CNAME, + EL_DNAME, + EL_LENGTH +}; +/** Decompressed entry_apex. It's an array of unparsed entry_h references. + * Note: arrays are passed "by reference" to functions (in C99). */ +typedef knot_db_val_t entry_list_t[EL_LENGTH]; + +static inline uint16_t EL2RRTYPE(enum EL i) +{ + switch (i) { + case EL_NS: return KNOT_RRTYPE_NS; + case EL_CNAME: return KNOT_RRTYPE_CNAME; + case EL_DNAME: return KNOT_RRTYPE_DNAME; + default: kr_assert(false); return 0; + } +} + +/** There may be multiple entries within, so rewind `val` to the one we want. + * + * ATM there are multiple types only for the NS ktype - it also accommodates xNAMEs. + * \note `val->len` represents the bound of the whole list, not of a single entry. + * \note in case of ENOENT, `val` is still rewound to the beginning of the next entry. + * \return error code + * TODO: maybe get rid of this API? + */ +int entry_h_seek(knot_db_val_t *val, uint16_t type); + +/** Prepare space to insert an entry. + * + * Some checks are performed (rank, TTL), the current entry in cache is copied + * with a hole ready for the new entry (old one of the same type is cut out). + * + * \param val_new_entry The only changing parameter; ->len is read, ->data written. + * \return error code + */ +int entry_h_splice( + knot_db_val_t *val_new_entry, uint8_t rank, + const knot_db_val_t key, const uint16_t ktype, const uint16_t type, + const knot_dname_t *owner/*log only*/, + const struct kr_query *qry, struct kr_cache *cache, uint32_t timestamp); + +/** Parse an entry_apex into individual items. @return error code. */ +KR_EXPORT int entry_list_parse(const knot_db_val_t val, entry_list_t list); + +static inline size_t to_even(size_t n) +{ + return n + (n & 1); +} + +static inline int entry_list_serial_size(const entry_list_t list) +{ + int size = offsetof(struct entry_apex, data); + for (int i = 0; i < EL_LENGTH; ++i) { + size += to_even(list[i].len); + } + return size; +} + +/** Fill contents of an entry_apex. + * + * @note NULL pointers are overwritten - caller may like to fill the space later. + */ +void entry_list_memcpy(struct entry_apex *ea, entry_list_t list); + + + +/* Packet caching; implementation in ./entry_pkt.c */ + +/** Stash the packet into cache (if suitable, etc.) + * \param needs_pkt we need the packet due to not stashing some RRs; + * see stash_rrset() for details + * It assumes check_dname_for_lf(). */ +void stash_pkt(const knot_pkt_t *pkt, const struct kr_query *qry, + const struct kr_request *req, bool needs_pkt); + +/** Try answering from packet cache, given an entry_h. + * + * This assumes the TTL is OK and entry_h_consistent, but it may still return error. + * On success it handles all the rest, incl. qry->flags. + */ +int answer_from_pkt(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type, + const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl); + + +/** Record is expiring if it has less than 1% TTL (or less than 5s) */ +static inline bool is_expiring(uint32_t orig_ttl, uint32_t new_ttl) +{ + int64_t nttl = new_ttl; /* avoid potential over/under-flow */ + return 100 * (nttl - 5) < orig_ttl; +} + +/** Returns signed result so you can inspect how much stale the RR is. + * + * @param owner name for stale-serving decisions. You may pass NULL to disable stale. + * @note: NSEC* uses zone name ATM; for NSEC3 the owner may not even be knowable. + * @param type for stale-serving. + */ +int32_t get_new_ttl(const struct entry_h *entry, const struct kr_query *qry, + const knot_dname_t *owner, uint16_t type, uint32_t now); + + +/* RRset (de)materialization; implementation in ./entry_rr.c */ + +/** Size of the RR count field */ +#define KR_CACHE_RR_COUNT_SIZE sizeof(uint16_t) + +/** Compute size of serialized rdataset. NULL is accepted as empty set. */ +static inline int rdataset_dematerialize_size(const knot_rdataset_t *rds) +{ + return KR_CACHE_RR_COUNT_SIZE + (rds == NULL ? 0 : rds->size); +} + +/** Analyze the length of a dematerialized rdataset. + * Note that in the data it's KR_CACHE_RR_COUNT_SIZE and then this returned size. */ +static inline int rdataset_dematerialized_size(const uint8_t *data, uint16_t *rdataset_count) +{ + uint16_t count; + static_assert(sizeof(count) == KR_CACHE_RR_COUNT_SIZE, + "Unexpected KR_CACHE_RR_COUNT_SIZE."); + memcpy(&count, data, sizeof(count)); + const uint8_t *rdata = data + sizeof(count); + if (rdataset_count) // memcpy is safe for unaligned case (on non-x86) + memcpy(rdataset_count, &count, sizeof(count)); + for (int i = 0; i < count; ++i) { + __typeof__(((knot_rdata_t *)NULL)->len) len; // memcpy as above + memcpy(&len, rdata + offsetof(knot_rdata_t, len), sizeof(len)); + rdata += knot_rdata_size(len); + } + return rdata - (data + sizeof(count)); +} + +/** Serialize an rdataset. It may be NULL as short-hand for empty. */ +void rdataset_dematerialize(const knot_rdataset_t *rds, uint8_t * restrict data); + + +/** Partially constructed answer when gathering RRsets from cache. */ +struct answer { + int rcode; /**< PKT_NODATA, etc. */ + struct nsec_p nsec_p; /**< Don't mix different NSEC* parameters in one answer. */ + knot_mm_t *mm; /**< Allocator for rrsets */ + struct answer_rrset { + ranked_rr_array_entry_t set; /**< set+rank for the main data */ + knot_rdataset_t sig_rds; /**< RRSIG data, if any */ + } rrsets[1+1+3]; /**< see AR_ANSWER and friends; only required records are filled */ +}; +enum { + AR_ANSWER = 0, /**< Positive answer record. It might be wildcard-expanded. */ + AR_SOA, /**< SOA record. */ + AR_NSEC, /**< NSEC* covering or matching the SNAME (next closer name in NSEC3 case). */ + AR_WILD, /**< NSEC* covering or matching the source of synthesis. */ + AR_CPE, /**< NSEC3 matching the closest provable encloser. */ +}; + +/** Materialize RRset + RRSIGs into ans->rrsets[id]. + * LATER(optim.): it's slightly wasteful that we allocate knot_rrset_t for the packet + * + * \return error code. They are all bad conditions and "guarded" by kresd's assertions. + */ +int entry2answer(struct answer *ans, int id, + const struct entry_h *eh, const uint8_t *eh_bound, + const knot_dname_t *owner, uint16_t type, uint32_t new_ttl); + + +/* Preparing knot_pkt_t for cache answer from RRs; implementation in ./knot_pkt.c */ + +/** Prepare answer packet to be filled by RRs (without RR data in wire). */ +int pkt_renew(knot_pkt_t *pkt, const knot_dname_t *name, uint16_t type); + +/** Append RRset + its RRSIGs into the current section (*shallow* copy), with given rank. + * + * \note it works with empty set as well (skipped) + * \note pkt->wire is not updated in any way + * \note KNOT_CLASS_IN is assumed + * \note Whole RRsets are put into the pseudo-packet; + * normal parsed packets would only contain single-RR sets. + */ +int pkt_append(knot_pkt_t *pkt, const struct answer_rrset *rrset, uint8_t rank); + + + +/* NSEC (1) stuff. Implementation in ./nsec1.c */ + +/** Construct a string key for for NSEC (1) predecessor-search. + * \param add_wildcard Act as if the name was extended by "*." + * \note k->zlf_len is assumed to have been correctly set */ +knot_db_val_t key_NSEC1(struct key *k, const knot_dname_t *name, bool add_wildcard); + +/** Closest encloser check for NSEC (1). + * To understand the interface, see the call point. + * \param k space to store key + input: zname and zlf_len + * \return 0: success; >0: try other (NSEC3); <0: exit cache immediately. */ +int nsec1_encloser(struct key *k, struct answer *ans, + const int sname_labels, int *clencl_labels, + knot_db_val_t *cover_low_kwz, knot_db_val_t *cover_hi_kwz, + const struct kr_query *qry, struct kr_cache *cache); + +/** Source of synthesis (SS) check for NSEC (1). + * To understand the interface, see the call point. + * \return 0: continue; <0: exit cache immediately; + * AR_SOA: skip to adding SOA (SS was covered or matched for NODATA). */ +int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name, + knot_db_val_t cover_low_kwz, knot_db_val_t cover_hi_kwz, + const struct kr_query *qry, struct kr_cache *cache); + + +/* NSEC3 stuff. Implementation in ./nsec3.c */ + +/** Construct a string key for for NSEC3 predecessor-search, from an NSEC3 name. + * \note k->zlf_len is assumed to have been correctly set */ +knot_db_val_t key_NSEC3(struct key *k, const knot_dname_t *nsec3_name, + const nsec_p_hash_t nsec_p_hash); + +/** TODO. See nsec1_encloser(...) */ +int nsec3_encloser(struct key *k, struct answer *ans, + const int sname_labels, int *clencl_labels, + const struct kr_query *qry, struct kr_cache *cache); + +/** TODO. See nsec1_src_synth(...) */ +int nsec3_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name, + const struct kr_query *qry, struct kr_cache *cache); + + + +#define VERBOSE_MSG(qry, ...) kr_log_q((qry), CACHE, ## __VA_ARGS__) +#define WITH_VERBOSE(qry) if (kr_log_is_debug_qry(CACHE, (qry))) + +/** Shorthand for operations on cache backend */ +#define cache_op(cache, op, ...) (cache)->api->op((cache)->db, &(cache)->stats, ## __VA_ARGS__) + + +static inline uint16_t get_uint16(const void *address) +{ + uint16_t tmp; + memcpy(&tmp, address, sizeof(tmp)); + return tmp; +} + +/** Useful pattern, especially as void-pointer arithmetic isn't standard-compliant. */ +static inline uint8_t * knot_db_val_bound(knot_db_val_t val) +{ + return (uint8_t *)val.data + val.len; +} + diff --git a/lib/cache/knot_pkt.c b/lib/cache/knot_pkt.c new file mode 100644 index 0000000..31fa7e9 --- /dev/null +++ b/lib/cache/knot_pkt.c @@ -0,0 +1,94 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Implementation of preparing knot_pkt_t for filling with RRs. + * Prototypes in ./impl.h + */ + +#include "lib/cache/impl.h" + +int pkt_renew(knot_pkt_t *pkt, const knot_dname_t *name, uint16_t type) +{ + /* Update packet question if needed. */ + if (!knot_dname_is_equal(knot_pkt_qname(pkt), name) + || knot_pkt_qtype(pkt) != type || knot_pkt_qclass(pkt) != KNOT_CLASS_IN) { + int ret = kr_pkt_recycle(pkt); + if (ret) return kr_error(ret); + ret = knot_pkt_put_question(pkt, name, KNOT_CLASS_IN, type); + if (ret) return kr_error(ret); + } + + pkt->parsed = pkt->size = KR_PKT_SIZE_NOWIRE; + knot_wire_set_qr(pkt->wire); + knot_wire_set_aa(pkt->wire); + return kr_ok(); +} + +/** Reserve space for additional `count` RRsets. + * \note pkt->rr_info gets correct length but is always zeroed + */ +static int pkt_alloc_space(knot_pkt_t *pkt, int count) +{ + size_t allocd_orig = pkt->rrset_allocd; + if (pkt->rrset_count + count <= allocd_orig) { + return kr_ok(); + } + /* A simple growth strategy, amortized O(count). */ + pkt->rrset_allocd = MAX( + pkt->rrset_count + count, + pkt->rrset_count + allocd_orig); + + pkt->rr = mm_realloc(&pkt->mm, pkt->rr, + sizeof(pkt->rr[0]) * pkt->rrset_allocd, + sizeof(pkt->rr[0]) * allocd_orig); + if (!pkt->rr) { + return kr_error(ENOMEM); + } + /* Allocate pkt->rr_info to be certain, but just leave it zeroed. */ + mm_free(&pkt->mm, pkt->rr_info); + pkt->rr_info = mm_calloc(&pkt->mm, pkt->rrset_allocd, sizeof(pkt->rr_info[0])); + if (!pkt->rr_info) { + return kr_error(ENOMEM); + } + return kr_ok(); +} + +int pkt_append(knot_pkt_t *pkt, const struct answer_rrset *rrset, uint8_t rank) +{ + /* allocate space, to be sure */ + int rrset_cnt = (rrset->set.rr->rrs.count > 0) + (rrset->sig_rds.count > 0); + int ret = pkt_alloc_space(pkt, rrset_cnt); + if (ret) return kr_error(ret); + /* write both sets */ + const knot_rdataset_t *rdss[2] = { &rrset->set.rr->rrs, &rrset->sig_rds }; + for (int i = 0; i < rrset_cnt; ++i) { + if (kr_fails_assert(rdss[i]->count)) + return kr_error(EINVAL); + /* allocate rank */ + uint8_t *rr_rank = mm_alloc(&pkt->mm, sizeof(*rr_rank)); + if (!rr_rank) return kr_error(ENOMEM); + *rr_rank = (i == 0) ? rank : (KR_RANK_OMIT | KR_RANK_AUTH); + /* rank for RRSIGs isn't really useful: ^^ */ + if (i == 0) { + pkt->rr[pkt->rrset_count] = *rrset->set.rr; + pkt->rr[pkt->rrset_count].additional = rr_rank; + } else { + /* append the RR array */ + pkt->rr[pkt->rrset_count] = (knot_rrset_t){ + .owner = knot_dname_copy(rrset->set.rr->owner, &pkt->mm), + /* ^^ well, another copy isn't really needed */ + .ttl = rrset->set.rr->ttl, + .type = KNOT_RRTYPE_RRSIG, + .rclass = KNOT_CLASS_IN, + .rrs = *rdss[i], + .additional = rr_rank, + }; + } + ++pkt->rrset_count; + ++(pkt->sections[pkt->current].count); + } + return kr_ok(); +} + diff --git a/lib/cache/nsec1.c b/lib/cache/nsec1.c new file mode 100644 index 0000000..4554303 --- /dev/null +++ b/lib/cache/nsec1.c @@ -0,0 +1,488 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Implementation of NSEC (1) handling. Prototypes in ./impl.h + */ + +#include "lib/cache/impl.h" +#include "lib/dnssec/nsec.h" +#include "lib/layer/iterate.h" + + +/** Reconstruct a name into a buffer (assuming length at least KNOT_DNAME_MAXLEN). + * \return kr_ok() or error code (<0). */ +static int dname_wire_reconstruct(knot_dname_t *buf, const struct key *k, + knot_db_val_t kwz) +{ + /* Reconstruct from key: first the ending, then zone name. */ + int ret = knot_dname_lf2wire(buf, kwz.len, kwz.data); + if (kr_fails_assert(ret >= 0)) { + VERBOSE_MSG(NULL, "=> NSEC: LF2wire ret = %d\n", ret); + return ret; + } + /* The last written byte is the zero label for root -> overwrite. */ + knot_dname_t *zone_start = buf + ret - 1; + if (kr_fails_assert(*zone_start == '\0')) + return kr_error(EFAULT); + ret = knot_dname_to_wire(zone_start, k->zname, KNOT_DNAME_MAXLEN - kwz.len); + if (kr_fails_assert(ret == k->zlf_len + 1)) + return ret < 0 ? ret : kr_error(EILSEQ); + return kr_ok(); +} + + +knot_db_val_t key_NSEC1(struct key *k, const knot_dname_t *name, bool add_wildcard) +{ + /* we basically need dname_lf with two bytes added + * on a correct place within the name (the cut) */ + int ret; + const bool ok = k && name + && !(ret = kr_dname_lf(k->buf, name, add_wildcard)); + if (kr_fails_assert(ok)) + return (knot_db_val_t){ NULL, 0 }; + + uint8_t *begin = k->buf + 1 + k->zlf_len; /* one byte after zone's zero */ + uint8_t *end = k->buf + 1 + k->buf[0]; /* we don't use the final zero in key, + * but move it anyway */ + if (kr_fails_assert(end >= begin)) + return (knot_db_val_t){ NULL, 0 }; + int key_len; + if (end > begin) { + memmove(begin + 2, begin, end - begin); + key_len = k->buf[0] + 1; + } else { + key_len = k->buf[0] + 2; + } + /* CACHE_KEY_DEF: key == zone's dname_lf + '\0' + '1' + dname_lf + * of the name within the zone without the final 0. Iff the latter is empty, + * there's no zero to cut and thus the key_len difference. + */ + begin[0] = 0; + begin[1] = '1'; /* tag for NSEC1 */ + k->type = KNOT_RRTYPE_NSEC; + + /* + VERBOSE_MSG(NULL, "<> key_NSEC1; name: "); + kr_dname_print(name, add_wildcard ? "*." : "" , " "); + kr_log_debug(CACHE, "(zone name LF length: %d; total key length: %d)\n", + k->zlf_len, key_len); + */ + + return (knot_db_val_t){ k->buf + 1, key_len }; +} + + +/** Assuming that k1 < k4, find where k2 is. (Considers DNS wrap-around.) + * + * \return Intuition: position of k2 among kX. + * 0: k2 < k1; 1: k1 == k2; 2: k1 is a prefix of k2 < k4; + * 3: k1 < k2 < k4 (and not 2); 4: k2 == k4; 5: k2 > k4 + * \note k1.data may be NULL, meaning assumption that k1 < k2 and not a prefix + * (i.e. return code will be > 2) + */ +static int kwz_between(knot_db_val_t k1, knot_db_val_t k2, knot_db_val_t k4) +{ + kr_require(k2.data && k4.data); + /* CACHE_KEY_DEF; we need to beware of one key being a prefix of another */ + int ret_maybe; /**< result, assuming we confirm k2 < k4 */ + if (k1.data) { + const int cmp12 = memcmp(k1.data, k2.data, MIN(k1.len, k2.len)); + if (cmp12 == 0 && k1.len == k2.len) /* iff k1 == k2 */ + return 1; + if (cmp12 > 0 || (cmp12 == 0 && k1.len > k2.len)) /* iff k1 > k2 */ + return 0; + ret_maybe = cmp12 == 0 ? 2 : 3; + } else { + ret_maybe = 3; + } + if (k4.len == 0) { /* wrap-around */ + return k2.len > 0 ? ret_maybe : 4; + } else { + const int cmp24 = memcmp(k2.data, k4.data, MIN(k2.len, k4.len)); + if (cmp24 == 0 && k2.len == k4.len) /* iff k2 == k4 */ + return 4; + if (cmp24 > 0 || (cmp24 == 0 && k2.len > k4.len)) /* iff k2 > k4 */ + return 5; + return ret_maybe; + } +} + + +/** NSEC1 range search. + * + * \param key Pass output of key_NSEC1(k, ...) + * \param value[out] The raw data of the NSEC cache record (optional; consistency checked). + * \param exact_match[out] Whether the key was matched exactly or just covered (optional). + * \param kwz_low[out] Output the low end of covering NSEC, pointing within DB (optional). + * \param kwz_high[in,out] Storage for the high end of covering NSEC (optional). + * It's only set if !exact_match. + * \param new_ttl[out] New TTL of the NSEC (optional). + * \return Error message or NULL. + * \note The function itself does *no* bitmap checks, e.g. RFC 6840 sec. 4. + */ +static const char * find_leq_NSEC1(struct kr_cache *cache, const struct kr_query *qry, + const knot_db_val_t key, const struct key *k, knot_db_val_t *value, + bool *exact_match, knot_db_val_t *kwz_low, knot_db_val_t *kwz_high, + uint32_t *new_ttl) +{ + /* Do the cache operation. */ + const size_t nwz_off = key_nwz_off(k); + if (kr_fails_assert(key.data && key.len >= nwz_off)) + return "range search ERROR"; + knot_db_val_t key_nsec = key; + knot_db_val_t val = { NULL, 0 }; + int ret = cache_op(cache, read_leq, &key_nsec, &val); + if (ret < 0) { + if (kr_fails_assert(ret == kr_error(ENOENT))) { + return "range search ERROR"; + } else { + return "range search miss"; + } + } + if (value) { + *value = val; + } + /* Check consistency, TTL, rank. */ + const bool is_exact = (ret == 0); + if (exact_match) { + *exact_match = is_exact; + } + const struct entry_h *eh = entry_h_consistent_NSEC(val); + if (!eh) { + /* This might be just finding something else than NSEC1 entry, + * in case we searched before the very first one in the zone. */ + return "range search found inconsistent entry"; + } + /* Passing just zone name instead of owner, as we don't + * have it reconstructed at this point. */ + int32_t new_ttl_ = get_new_ttl(eh, qry, k->zname, KNOT_RRTYPE_NSEC, + qry->timestamp.tv_sec); + if (new_ttl_ < 0 || !kr_rank_test(eh->rank, KR_RANK_SECURE)) { + return "range search found stale or insecure entry"; + /* TODO: remove the stale record *and* retry, + * in case we haven't run off. Perhaps start by in_zone check. */ + } + if (new_ttl) { + *new_ttl = new_ttl_; + } + if (kwz_low) { + *kwz_low = (knot_db_val_t){ + .data = (uint8_t *)key_nsec.data + nwz_off, + .len = key_nsec.len - nwz_off, + }; /* CACHE_KEY_DEF */ + } + if (is_exact) { + /* Nothing else to do. */ + return NULL; + } + /* The NSEC starts strictly before our target name; + * now check that it still belongs into that zone. */ + const bool nsec_in_zone = key_nsec.len >= nwz_off + /* CACHE_KEY_DEF */ + && memcmp(key.data, key_nsec.data, nwz_off) == 0; + if (!nsec_in_zone) { + return "range search miss (!nsec_in_zone)"; + } + /* We know it starts before sname, so let's check the other end. + * 1. construct the key for the next name - kwz_hi. */ + /* it's *full* name ATM */ + /* Technical complication: memcpy is safe for unaligned case (on non-x86) */ + __typeof__(((knot_rdata_t *)NULL)->len) next_len; + const uint8_t *next_data; + { /* next points to knot_rdata_t but possibly unaligned */ + const uint8_t *next = eh->data + KR_CACHE_RR_COUNT_SIZE; + memcpy(&next_len, next + offsetof(knot_rdata_t, len), sizeof(next_len)); + next_data = next + offsetof(knot_rdata_t, data); + } + if (kr_fails_assert(KR_CACHE_RR_COUNT_SIZE == 2 && get_uint16(eh->data) != 0)) { + return "ERROR"; /* TODO: more checks? */ + } + /* + WITH_VERBOSE { + VERBOSE_MSG(qry, "=> NSEC: next name: "); + kr_dname_print(next, "", "\n"); + } + */ + knot_dname_t ch_buf[KNOT_DNAME_MAXLEN]; + knot_dname_t *chs = kwz_high ? kwz_high->data : ch_buf; + if (kr_fails_assert(chs)) + return "EINVAL"; + + { + /* Lower-case chs; see also RFC 6840 5.1. + * LATER(optim.): we do lots of copying etc. */ + knot_dname_t lower_buf[KNOT_DNAME_MAXLEN]; + ret = knot_dname_to_wire(lower_buf, next_data, + MIN(next_len, KNOT_DNAME_MAXLEN)); + if (ret < 0) { /* _ESPACE */ + return "range search found record with incorrect contents"; + } + knot_dname_to_lower(lower_buf); + ret = kr_dname_lf(chs, lower_buf, false); + } + + if (kr_fails_assert(ret == 0)) + return "ERROR"; + knot_db_val_t kwz_hi = { /* skip the zone name */ + .data = chs + 1 + k->zlf_len, + .len = chs[0] - k->zlf_len, + }; + if (kr_fails_assert((ssize_t)(kwz_hi.len) >= 0)) + return "ERROR"; + /* 2. do the actual range check. */ + const knot_db_val_t kwz_sname = { + .data = (void *)/*const-cast*/(k->buf + 1 + nwz_off), + .len = k->buf[0] - k->zlf_len, + }; + if (kr_fails_assert((ssize_t)(kwz_sname.len) >= 0)) + return "ERROR"; + bool covers = /* we know for sure that the low end is before kwz_sname */ + 3 == kwz_between((knot_db_val_t){ NULL, 0 }, kwz_sname, kwz_hi); + if (!covers) { + return "range search miss (!covers)"; + } + if (kwz_high) { + *kwz_high = kwz_hi; + } + return NULL; +} + + +int nsec1_encloser(struct key *k, struct answer *ans, + const int sname_labels, int *clencl_labels, + knot_db_val_t *cover_low_kwz, knot_db_val_t *cover_hi_kwz, + const struct kr_query *qry, struct kr_cache *cache) +{ + static const int ESKIP = ABS(ENOENT); + /* Basic sanity check. */ + const bool ok = k && ans && clencl_labels && cover_low_kwz && cover_hi_kwz + && qry && cache; + if (kr_fails_assert(ok)) + return kr_error(EINVAL); + + /* Find a previous-or-equal name+NSEC in cache covering the QNAME, + * checking TTL etc. */ + knot_db_val_t key = key_NSEC1(k, qry->sname, false); + knot_db_val_t val = { NULL, 0 }; + bool exact_match; + uint32_t new_ttl; + const char *err = find_leq_NSEC1(cache, qry, key, k, &val, + &exact_match, cover_low_kwz, cover_hi_kwz, &new_ttl); + if (err) { + VERBOSE_MSG(qry, "=> NSEC sname: %s\n", err); + return ESKIP; + } + + /* Get owner name of the record. */ + const knot_dname_t *owner; + knot_dname_t owner_buf[KNOT_DNAME_MAXLEN]; + if (exact_match) { + owner = qry->sname; + } else { + int ret = dname_wire_reconstruct(owner_buf, k, *cover_low_kwz); + if (unlikely(ret)) return ESKIP; + owner = owner_buf; + } + /* Basic checks OK -> materialize data. */ + { + const struct entry_h *nsec_eh = val.data; + int ret = entry2answer(ans, AR_NSEC, nsec_eh, knot_db_val_bound(val), + owner, KNOT_RRTYPE_NSEC, new_ttl); + if (ret) return kr_error(ret); + } + + /* Final checks, split for matching vs. covering our sname. */ + const knot_rrset_t *nsec_rr = ans->rrsets[AR_NSEC].set.rr; + const uint8_t *bm = knot_nsec_bitmap(nsec_rr->rrs.rdata); + uint16_t bm_size = knot_nsec_bitmap_len(nsec_rr->rrs.rdata); + if (kr_fails_assert(bm)) + return kr_error(EFAULT); + + if (exact_match) { + if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) != 0) { + VERBOSE_MSG(qry, + "=> NSEC sname: match but failed type check\n"); + return ESKIP; + } + /* NODATA proven; just need to add SOA+RRSIG later */ + VERBOSE_MSG(qry, "=> NSEC sname: match proved NODATA, new TTL %d\n", + new_ttl); + ans->rcode = PKT_NODATA; + return kr_ok(); + } /* else */ + + /* Inexact match. First check if sname is delegated by that NSEC. */ + const int nsec_matched = knot_dname_matched_labels(nsec_rr->owner, qry->sname); + const bool is_sub = nsec_matched == knot_dname_labels(nsec_rr->owner, NULL); + if (is_sub && kr_nsec_children_in_zone_check(bm, bm_size) != 0) { + VERBOSE_MSG(qry, "=> NSEC sname: covered but delegated (or error)\n"); + return ESKIP; + } + /* NXDOMAIN proven *except* for wildcards. */ + WITH_VERBOSE(qry) { + auto_free char *owner_str = kr_dname_text(nsec_rr->owner), + *next_str = kr_dname_text(knot_nsec_next(nsec_rr->rrs.rdata)); + VERBOSE_MSG(qry, "=> NSEC sname: covered by: %s -> %s, new TTL %d\n", + owner_str, next_str, new_ttl); + } + + /* Find label count of the closest encloser. + * Both endpoints in an NSEC do exist (though possibly in a child zone) + * and any prefixes of those names as well (empty non-terminals), + * but nothing else exists inside this "triangle". + * + * Note that we have to lower-case the next name for comparison, + * even though we have canonicalized NSEC already; see RFC 6840 5.1. + * LATER(optim.): it might be faster to use the LFs we already have. + */ + knot_dname_t next[KNOT_DNAME_MAXLEN]; + int ret = knot_dname_to_wire(next, knot_nsec_next(nsec_rr->rrs.rdata), sizeof(next)); + if (kr_fails_assert(ret >= 0)) + return kr_error(ret); + knot_dname_to_lower(next); + *clencl_labels = MAX( + nsec_matched, + knot_dname_matched_labels(qry->sname, next) + ); + + /* Empty non-terminals don't need to have + * a matching NSEC record. */ + if (sname_labels == *clencl_labels) { + ans->rcode = PKT_NODATA; + VERBOSE_MSG(qry, + "=> NSEC sname: empty non-terminal by the same RR\n"); + } else { + ans->rcode = PKT_NXDOMAIN; + } + return kr_ok(); +} + +/** Verify non-existence after kwz_between() call. */ +static bool nonexistence_ok(int cmp, const knot_rrset_t *rrs) +{ + if (cmp == 3) { + return true; + } + if (cmp != 2) { + return false; + } + const uint8_t *bm = knot_nsec_bitmap(rrs->rrs.rdata); + uint16_t bm_size = knot_nsec_bitmap_len(rrs->rrs.rdata); + return kr_nsec_children_in_zone_check(bm, bm_size) != 0; +} + +int nsec1_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name, + knot_db_val_t cover_low_kwz, knot_db_val_t cover_hi_kwz, + const struct kr_query *qry, struct kr_cache *cache) +{ + /* Construct key for the source of synthesis. */ + knot_db_val_t key = key_NSEC1(k, clencl_name, true); + const size_t nwz_off = key_nwz_off(k); + if (kr_fails_assert(key.data && key.len >= nwz_off)) + return kr_error(1); + /* Check if our sname-covering NSEC also covers/matches SS. */ + knot_db_val_t kwz = { + .data = (uint8_t *)key.data + nwz_off, + .len = key.len - nwz_off, + }; + if (kr_fails_assert((ssize_t)(kwz.len) >= 0)) + return kr_error(EINVAL); + const int cmp = kwz_between(cover_low_kwz, kwz, cover_hi_kwz); + if (nonexistence_ok(cmp, ans->rrsets[AR_NSEC].set.rr)) { + VERBOSE_MSG(qry, "=> NSEC wildcard: covered by the same RR\n"); + return AR_SOA; + } + const knot_rrset_t *nsec_rr = NULL; /**< the wildcard proof NSEC */ + bool exact_match; /**< whether it matches the source of synthesis */ + if (cmp == 1) { + exact_match = true; + nsec_rr = ans->rrsets[AR_NSEC].set.rr; + } else { + /* Try to find the NSEC for SS. */ + knot_db_val_t val = { NULL, 0 }; + knot_db_val_t wild_low_kwz = { NULL, 0 }; + uint32_t new_ttl; + const char *err = find_leq_NSEC1(cache, qry, key, k, &val, + &exact_match, &wild_low_kwz, NULL, &new_ttl); + if (err) { + VERBOSE_MSG(qry, "=> NSEC wildcard: %s\n", err); + return kr_ok(); + } + /* Materialize the record into answer (speculatively). */ + knot_dname_t owner[KNOT_DNAME_MAXLEN]; + int ret = dname_wire_reconstruct(owner, k, wild_low_kwz); + if (ret) return kr_error(ret); + const struct entry_h *nsec_eh = val.data; + ret = entry2answer(ans, AR_WILD, nsec_eh, knot_db_val_bound(val), + owner, KNOT_RRTYPE_NSEC, new_ttl); + if (ret) return kr_error(ret); + nsec_rr = ans->rrsets[AR_WILD].set.rr; + } + + if (kr_fails_assert(nsec_rr)) + return kr_error(EFAULT); + const uint8_t *bm = knot_nsec_bitmap(nsec_rr->rrs.rdata); + uint16_t bm_size = knot_nsec_bitmap_len(nsec_rr->rrs.rdata); + int ret; + struct answer_rrset * const arw = &ans->rrsets[AR_WILD]; + if (kr_fails_assert(bm)) { + ret = kr_error(EFAULT); + goto clean_wild; + } + if (!exact_match) { + /* Finish verification that the source of synthesis doesn't exist. */ + const int nsec_matched = + knot_dname_matched_labels(nsec_rr->owner, clencl_name); + /* we don't need to use the full source of synthesis ^ */ + const bool is_sub = + nsec_matched == knot_dname_labels(nsec_rr->owner, NULL); + if (is_sub && kr_nsec_children_in_zone_check(bm, bm_size) != 0) { + VERBOSE_MSG(qry, + "=> NSEC wildcard: covered but delegated (or error)\n"); + ret = kr_ok(); + goto clean_wild; + } + /* We have a record proving wildcard non-existence. */ + WITH_VERBOSE(qry) { + auto_free char *owner_str = kr_dname_text(nsec_rr->owner), + *next_str = kr_dname_text(knot_nsec_next(nsec_rr->rrs.rdata)); + VERBOSE_MSG(qry, "=> NSEC wildcard: covered by: %s -> %s, new TTL %d\n", + owner_str, next_str, nsec_rr->ttl); + } + return AR_SOA; + } + + /* The wildcard exists. Find if it's NODATA - check type bitmap. */ + if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) == 0) { + /* NODATA proven; just need to add SOA+RRSIG later */ + WITH_VERBOSE(qry) { + const char *msg_start = "=> NSEC wildcard: match proved NODATA"; + if (arw->set.rr) { + auto_free char *owner_str = kr_dname_text(nsec_rr->owner); + VERBOSE_MSG(qry, "%s: %s, new TTL %d\n", + msg_start, owner_str, nsec_rr->ttl); + } else { + /* don't repeat the RR if it's the same */ + VERBOSE_MSG(qry, "%s, by the same RR\n", msg_start); + } + } + ans->rcode = PKT_NODATA; + return AR_SOA; + + } /* else */ + /* The data probably exists -> don't add this NSEC + * and (later) try to find the real wildcard data */ + VERBOSE_MSG(qry, "=> NSEC wildcard: should exist (or error)\n"); + ans->rcode = PKT_NOERROR; + ret = kr_ok(); +clean_wild: + if (arw->set.rr) { /* we may have matched AR_NSEC */ + knot_rrset_free(arw->set.rr, ans->mm); + arw->set.rr = NULL; + knot_rdataset_clear(&arw->sig_rds, ans->mm); + } + return ret; +} + diff --git a/lib/cache/nsec3.c b/lib/cache/nsec3.c new file mode 100644 index 0000000..0b70775 --- /dev/null +++ b/lib/cache/nsec3.c @@ -0,0 +1,481 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +/** @file + * Implementation of NSEC3 handling. Prototypes in ./impl.h + */ + +#include "lib/cache/impl.h" + +#include "contrib/base32hex.h" +#include "lib/dnssec/nsec.h" +#include "lib/dnssec/nsec3.h" +#include "lib/layer/iterate.h" + +#include <libknot/rrtype/nsec3.h> + +static const knot_db_val_t VAL_EMPTY = { NULL, 0 }; + +/** Common part: write all but the NSEC3 hash. */ +static knot_db_val_t key_NSEC3_common(struct key *k, const knot_dname_t *zname, + const nsec_p_hash_t nsec_p_hash) +{ + if (kr_fails_assert(k && zname && !kr_dname_lf(k->buf, zname, false))) + return VAL_EMPTY; + + /* CACHE_KEY_DEF: key == zone's dname_lf + '\0' + '3' + nsec_p hash (4B) + * + NSEC3 hash (20B == NSEC3_HASH_LEN binary!) + * LATER(optim.) nsec_p hash: perhaps 2B would give a sufficient probability + * of avoiding collisions. + */ + uint8_t *begin = k->buf + 1 + k->zlf_len; /* one byte after zone's zero */ + begin[0] = 0; + begin[1] = '3'; /* tag for NSEC3 */ + k->type = KNOT_RRTYPE_NSEC3; + memcpy(begin + 2, &nsec_p_hash, sizeof(nsec_p_hash)); + return (knot_db_val_t){ + .data = k->buf + 1, + .len = begin + 2 + sizeof(nsec_p_hash) - (k->buf + 1), + }; +} + +knot_db_val_t key_NSEC3(struct key *k, const knot_dname_t *nsec3_name, + const nsec_p_hash_t nsec_p_hash) +{ + knot_db_val_t val = key_NSEC3_common(k, nsec3_name /*only zname required*/, + nsec_p_hash); + if (!val.data) return val; + int len = base32hex_decode(nsec3_name + 1, nsec3_name[0], + knot_db_val_bound(val), KR_CACHE_KEY_MAXLEN - val.len); + if (len != NSEC3_HASH_LEN) { + return VAL_EMPTY; + } + val.len += len; + return val; +} + +/** Construct a string key for for NSEC3 predecessor-search, from an non-NSEC3 name. + * \note k->zlf_len and k->zname are assumed to have been correctly set */ +static knot_db_val_t key_NSEC3_name(struct key *k, const knot_dname_t *name, + const bool add_wildcard, const struct nsec_p *nsec_p) +{ + bool ok = k && name && nsec_p && nsec_p->raw; + if (!ok) return VAL_EMPTY; + knot_db_val_t val = key_NSEC3_common(k, k->zname, nsec_p->hash); + if (!val.data) return val; + + /* Make `name` point to correctly wildcarded owner name. */ + uint8_t buf[KNOT_DNAME_MAXLEN]; + int name_len; + if (add_wildcard) { + buf[0] = '\1'; + buf[1] = '*'; + name_len = knot_dname_to_wire(buf + 2, name, sizeof(buf) - 2); + if (name_len < 0) return VAL_EMPTY; /* wants wildcard but doesn't fit */ + name = buf; + name_len += 2; + } else { + name_len = knot_dname_size(name); + } + /* Append the NSEC3 hash. */ + const dnssec_binary_t dname = { + .size = name_len, + .data = (uint8_t *)/*const-cast*/name, + }; + + if (kr_fails_assert(nsec_p->libknot.iterations <= KR_NSEC3_MAX_ITERATIONS)) { + /* This is mainly defensive; it shouldn't happen thanks to downgrades. */ + return VAL_EMPTY; + } + #if 0 // LATER(optim.): this requires a patched libdnssec - tries to realloc() + dnssec_binary_t hash = { + .size = KR_CACHE_KEY_MAXLEN - val.len, + .data = val.data + val.len, + }; + int ret = dnssec_nsec3_hash(&dname, &nsec_p->libknot, &hash); + if (ret != DNSSEC_EOK) return VAL_EMPTY; + if (kr_fails_assert(hash.size == NSEC3_HASH_LEN)) + return VAL_EMPTY; + + #else + dnssec_binary_t hash = { .size = 0, .data = NULL }; + int ret = dnssec_nsec3_hash(&dname, &nsec_p->libknot, &hash); + if (ret != DNSSEC_EOK) return VAL_EMPTY; + if (kr_fails_assert(hash.size == NSEC3_HASH_LEN && hash.data)) + return VAL_EMPTY; + memcpy(knot_db_val_bound(val), hash.data, NSEC3_HASH_LEN); + free(hash.data); + #endif + + val.len += hash.size; + return val; +} + +/** Return h1 < h2, semantically on NSEC3 hashes. */ +static inline bool nsec3_hash_ordered(const uint8_t *h1, const uint8_t *h2) +{ + return memcmp(h1, h2, NSEC3_HASH_LEN) < 0; +} + +/** NSEC3 range search. + * + * \param key Pass output of key_NSEC3(k, ...) + * \param nsec_p Restrict to this NSEC3 parameter-set. + * \param value[out] The raw data of the NSEC3 cache record (optional; consistency checked). + * \param exact_match[out] Whether the key was matched exactly or just covered (optional). + * \param hash_low[out] Output the low end hash of covering NSEC3, pointing within DB (optional). + * \param new_ttl[out] New TTL of the NSEC3 (optional). + * \return Error message or NULL. + * \note The function itself does *no* bitmap checks, e.g. RFC 6840 sec. 4. + */ +static const char * find_leq_NSEC3(struct kr_cache *cache, const struct kr_query *qry, + const knot_db_val_t key, const struct key *k, const struct nsec_p *nsec_p, + knot_db_val_t *value, bool *exact_match, const uint8_t **hash_low, + uint32_t *new_ttl) +{ + /* Do the cache operation. */ + const size_t hash_off = key_nsec3_hash_off(k); + if (kr_fails_assert(key.data && key.len >= hash_off)) + return "range search ERROR"; + knot_db_val_t key_found = key; + knot_db_val_t val = { NULL, 0 }; + int ret = cache_op(cache, read_leq, &key_found, &val); + /* ^^ LATER(optim.): incrementing key and doing less-than search + * would probably be slightly more efficient with LMDB, + * but the code complexity would grow considerably. */ + if (ret < 0) { + if (kr_fails_assert(ret == kr_error(ENOENT))) { + return "range search ERROR"; + } else { + return "range search miss"; + } + } + if (value) { + *value = val; + } + /* Check consistency, TTL, rank. */ + const bool is_exact = (ret == 0); + if (exact_match) { + *exact_match = is_exact; + } + const struct entry_h *eh = entry_h_consistent_NSEC(val); + if (!eh) { + /* This might be just finding something else than NSEC3 entry, + * in case we searched before the very first one in the zone. */ + return "range search found inconsistent entry"; + } + /* Passing just zone name instead of owner. */ + int32_t new_ttl_ = get_new_ttl(eh, qry, k->zname, KNOT_RRTYPE_NSEC3, + qry->timestamp.tv_sec); + if (new_ttl_ < 0 || !kr_rank_test(eh->rank, KR_RANK_SECURE)) { + return "range search found stale or insecure entry"; + /* TODO: remove the stale record *and* retry, + * in case we haven't run off. Perhaps start by in_zone check. */ + } + if (new_ttl) { + *new_ttl = new_ttl_; + } + if (hash_low) { + *hash_low = (uint8_t *)key_found.data + hash_off; + } + if (is_exact) { + /* Nothing else to do. */ + return NULL; + } + /* The NSEC3 starts strictly before our target name; + * now check that it still belongs into that zone and chain. */ + const uint8_t *nsec_p_raw = eh->data + KR_CACHE_RR_COUNT_SIZE + + 2 /* RDLENGTH from rfc1034 */; + const int nsec_p_len = nsec_p_rdlen(nsec_p_raw); + const bool same_chain = key_found.len == hash_off + NSEC3_HASH_LEN + /* CACHE_KEY_DEF */ + && memcmp(key.data, key_found.data, hash_off) == 0 + /* exact comparison of NSEC3 parameters */ + && nsec_p_len == nsec_p_rdlen(nsec_p->raw) + && memcmp(nsec_p_raw, nsec_p->raw, nsec_p_len) == 0; + if (!same_chain) { + return "range search miss (!same_chain)"; + } + /* We know it starts before sname, so let's check the other end. + * A. find the next hash and check its length. */ + if (kr_fails_assert(KR_CACHE_RR_COUNT_SIZE == 2 && get_uint16(eh->data) != 0)) + return "ERROR"; /* TODO: more checks? Also, `next` computation is kinda messy. */ + const uint8_t *hash_next = nsec_p_raw + nsec_p_len + + sizeof(uint8_t) /* hash length from rfc5155 */; + if (hash_next[-1] != NSEC3_HASH_LEN) { + return "unexpected next hash length"; + } + /* B. do the actual range check. */ + const uint8_t * const hash_searched = (uint8_t *)key.data + hash_off; + bool covers = /* we know for sure that the low end is before the searched name */ + nsec3_hash_ordered(hash_searched, hash_next) + /* and the wrap-around case */ + || nsec3_hash_ordered(hash_next, (const uint8_t *)key_found.data + hash_off); + if (!covers) { + return "range search miss (!covers)"; + } + return NULL; +} + +/** Extract textual representation of NSEC3 hash from a cache key. + * \param text must have length at least NSEC3_HASH_TXT_LEN+1 (will get 0-terminated). */ +static void key_NSEC3_hash2text(const knot_db_val_t key, char *text) +{ + kr_require(key.data && key.len > NSEC3_HASH_LEN); + const uint8_t *hash_raw = knot_db_val_bound(key) - NSEC3_HASH_LEN; + /* CACHE_KEY_DEF ^^ */ + int len = base32hex_encode(hash_raw, NSEC3_HASH_LEN, (uint8_t *)text, + NSEC3_HASH_TXT_LEN); + kr_assert(len == NSEC3_HASH_TXT_LEN); + text[NSEC3_HASH_TXT_LEN] = '\0'; +} + +/** Reconstruct a name into a buffer (assuming length at least KNOT_DNAME_MAXLEN). + * \return kr_ok() or error code (<0). */ +static int dname_wire_reconstruct(knot_dname_t *buf, const knot_dname_t *zname, + const uint8_t *hash_raw) +{ + int len = base32hex_encode(hash_raw, NSEC3_HASH_LEN, buf + 1, NSEC3_HASH_TXT_LEN); + if (kr_fails_assert(len == NSEC3_HASH_TXT_LEN)) + return kr_error(EINVAL); + buf[0] = len; + int ret = knot_dname_to_wire(buf + 1 + len, zname, KNOT_DNAME_MAXLEN - 1 - len); + return ret < 0 ? kr_error(ret) : kr_ok(); +} + +static void nsec3_hash2text(const knot_dname_t *owner, char *text) +{ + kr_require(owner[0] == NSEC3_HASH_TXT_LEN); + memcpy(text, owner + 1, MIN(owner[0], NSEC3_HASH_TXT_LEN)); + text[NSEC3_HASH_TXT_LEN] = '\0'; +} + +int nsec3_encloser(struct key *k, struct answer *ans, + const int sname_labels, int *clencl_labels, + const struct kr_query *qry, struct kr_cache *cache) +{ + static const int ESKIP = ABS(ENOENT); + /* Basic sanity check. */ + const bool ok = k && k->zname && ans && clencl_labels + && qry && cache; + if (kr_fails_assert(ok)) + return kr_error(EINVAL); + + /*** Find the closest encloser - cycle: name starting at sname, + * proceeding while longer than zname, shortening by one label on step. + * We need a pair where a name doesn't exist *and* its parent does. */ + /* LATER(optim.): perhaps iterate in the other order - that + * should help significantly against deep queries where we have + * a shallow proof in the cache. We can also optimize by using + * only exact search unless we had a match in the previous iteration. */ + const int zname_labels = knot_dname_labels(k->zname, NULL); + int last_nxproven_labels = -1; + const knot_dname_t *name = qry->sname; + for (int name_labels = sname_labels; name_labels >= zname_labels; + --name_labels, name += 1 + name[0]) { + /* Find a previous-or-equal NSEC3 in cache covering the name, + * checking TTL etc. */ + const knot_db_val_t key = key_NSEC3_name(k, name, false, &ans->nsec_p); + if (!key.data) continue; + WITH_VERBOSE(qry) { + char hash_txt[NSEC3_HASH_TXT_LEN + 1]; + key_NSEC3_hash2text(key, hash_txt); + VERBOSE_MSG(qry, "=> NSEC3 depth %d: hash %s\n", + name_labels - zname_labels, hash_txt); + } + knot_db_val_t val = { NULL, 0 }; + bool exact_match; + uint32_t new_ttl; + const uint8_t *hash_low; + const char *err = find_leq_NSEC3(cache, qry, key, k, &ans->nsec_p, &val, + &exact_match, &hash_low, &new_ttl); + if (err) { + WITH_VERBOSE(qry) { + auto_free char *name_str = kr_dname_text(name); + VERBOSE_MSG(qry, "=> NSEC3 encloser error for %s: %s\n", + name_str, err); + } + continue; + } + if (exact_match && name_labels != sname_labels + && name_labels + 1 != last_nxproven_labels) { + /* This name exists (checked rank and TTL), and it's + * neither of the two interesting cases, so we do not + * keep searching for non-existence above this name. */ + VERBOSE_MSG(qry, + "=> NSEC3 encloser: only found existence of an ancestor\n"); + return ESKIP; + } + /* Optimization: avoid the rest of the last iteration if pointless. */ + if (!exact_match && name_labels == zname_labels + && last_nxproven_labels != name_labels + 1) { + break; + } + + /* Basic checks OK -> materialize data, cleaning any previous + * records on that answer index (unsuccessful attempts). */ + knot_dname_t owner[KNOT_DNAME_MAXLEN]; + { + int ret = dname_wire_reconstruct(owner, k->zname, hash_low); + if (unlikely(ret)) continue; + } + const int ans_id = (exact_match && name_labels + 1 == last_nxproven_labels) + ? AR_CPE : AR_NSEC; + { + const struct entry_h *nsec_eh = val.data; + memset(&ans->rrsets[ans_id], 0, sizeof(ans->rrsets[ans_id])); + int ret = entry2answer(ans, ans_id, nsec_eh, knot_db_val_bound(val), + owner, KNOT_RRTYPE_NSEC3, new_ttl); + if (ret) return kr_error(ret); + } + + if (!exact_match) { + /* Non-existence proven, but we don't know if `name` + * is the next closer name. + * Note: we don't need to check for the sname being + * delegated away by this record, as with NSEC3 only + * *exact* match on an ancestor could do that. */ + last_nxproven_labels = name_labels; + WITH_VERBOSE(qry) { + char hash_low_txt[NSEC3_HASH_TXT_LEN + 1]; + nsec3_hash2text(owner, hash_low_txt); + VERBOSE_MSG(qry, + "=> NSEC3 depth %d: covered by %s -> TODO, new TTL %d\n", + name_labels - zname_labels, hash_low_txt, new_ttl); + } + continue; + } + + /* Exactly matched NSEC3: two cases, one after another. */ + const knot_rrset_t *nsec_rr = ans->rrsets[ans_id].set.rr; + const uint8_t *bm = knot_nsec3_bitmap(nsec_rr->rrs.rdata); + uint16_t bm_size = knot_nsec3_bitmap_len(nsec_rr->rrs.rdata); + if (kr_fails_assert(bm)) + return kr_error(EFAULT); + if (name_labels == sname_labels) { + if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, + nsec_rr->owner) != 0) { + VERBOSE_MSG(qry, + "=> NSEC3 sname: match but failed type check\n"); + return ESKIP; + } + /* NODATA proven; just need to add SOA+RRSIG later */ + VERBOSE_MSG(qry, + "=> NSEC3 sname: match proved NODATA, new TTL %d\n", + new_ttl); + ans->rcode = PKT_NODATA; + return kr_ok(); + + } /* else */ + + if (kr_fails_assert(name_labels + 1 == last_nxproven_labels)) + return kr_error(EINVAL); + if (kr_nsec_children_in_zone_check(bm, bm_size) != 0) { + VERBOSE_MSG(qry, + "=> NSEC3 encloser: found but delegated (or error)\n"); + return ESKIP; + } + /* NXDOMAIN proven *except* for wildcards. */ + WITH_VERBOSE(qry) { + auto_free char *name_str = kr_dname_text(name); + VERBOSE_MSG(qry, + "=> NSEC3 encloser: confirmed as %s, new TTL %d\n", + name_str, new_ttl); + } + *clencl_labels = name_labels; + ans->rcode = PKT_NXDOMAIN; + /* Avoid repeated NSEC3 - remove either if the hashes match. + * This is very unlikely in larger zones: 1/size (per attempt). + * Well, deduplication would happen anyway when the answer + * from cache is read by kresd (internally). */ + if (unlikely(0 == memcmp(ans->rrsets[AR_NSEC].set.rr->owner + 1, + ans->rrsets[AR_CPE ].set.rr->owner + 1, + NSEC3_HASH_LEN))) { + memset(&ans->rrsets[AR_CPE], 0, sizeof(ans->rrsets[AR_CPE])); + /* LATER(optim.): perhaps check this earlier and avoid some work? */ + } + return kr_ok(); + } + + /* We've ran out of options. */ + if (last_nxproven_labels > 0) { + /* We didn't manage to prove existence of the closest encloser, + * meaning the only chance left is a *positive* wildcard record. */ + *clencl_labels = last_nxproven_labels - 1; + ans->rcode = PKT_NXDOMAIN; + /* FIXME: review */ + } + return ESKIP; +} + +int nsec3_src_synth(struct key *k, struct answer *ans, const knot_dname_t *clencl_name, + const struct kr_query *qry, struct kr_cache *cache) +{ + /* Find a previous-or-equal NSEC3 in cache covering or matching + * the source of synthesis, checking TTL etc. */ + const knot_db_val_t key = key_NSEC3_name(k, clencl_name, true, &ans->nsec_p); + if (!key.data) return kr_error(1); + WITH_VERBOSE(qry) { + char hash_txt[NSEC3_HASH_TXT_LEN + 1]; + key_NSEC3_hash2text(key, hash_txt); + VERBOSE_MSG(qry, "=> NSEC3 wildcard: hash %s\n", hash_txt); + } + knot_db_val_t val = { NULL, 0 }; + bool exact_match; + uint32_t new_ttl; + const uint8_t *hash_low; + const char *err = find_leq_NSEC3(cache, qry, key, k, &ans->nsec_p, &val, + &exact_match, &hash_low, &new_ttl); + if (err) { + VERBOSE_MSG(qry, "=> NSEC3 wildcard: %s\n", err); + return kr_ok(); + } + + /* LATER(optim.): avoid duplicities in answer. */ + + /* Basic checks OK -> materialize the data (speculatively). */ + knot_dname_t owner[KNOT_DNAME_MAXLEN]; + { + int ret = dname_wire_reconstruct(owner, k->zname, hash_low); + if (unlikely(ret)) return kr_ok(); + const struct entry_h *nsec_eh = val.data; + ret = entry2answer(ans, AR_WILD, nsec_eh, knot_db_val_bound(val), + owner, KNOT_RRTYPE_NSEC3, new_ttl); + if (ret) return kr_error(ret); + } + const knot_rrset_t *nsec_rr = ans->rrsets[AR_WILD].set.rr; + + if (!exact_match) { + /* The record proves wildcard non-existence. */ + WITH_VERBOSE(qry) { + char hash_low_txt[NSEC3_HASH_TXT_LEN + 1]; + nsec3_hash2text(owner, hash_low_txt); + VERBOSE_MSG(qry, + "=> NSEC3 wildcard: covered by %s -> TODO, new TTL %d\n", + hash_low_txt, new_ttl); + } + return AR_SOA; + } + + /* The wildcard exists. Find if it's NODATA - check type bitmap. */ + const uint8_t *bm = knot_nsec3_bitmap(nsec_rr->rrs.rdata); + uint16_t bm_size = knot_nsec3_bitmap_len(nsec_rr->rrs.rdata); + if (kr_fails_assert(bm)) + return kr_error(EFAULT); + if (kr_nsec_bitmap_nodata_check(bm, bm_size, qry->stype, nsec_rr->owner) == 0) { + /* NODATA proven; just need to add SOA+RRSIG later */ + VERBOSE_MSG(qry, "=> NSEC3 wildcard: match proved NODATA, new TTL %d\n", + new_ttl); + ans->rcode = PKT_NODATA; + return AR_SOA; + + } /* else */ + /* The data probably exists -> don't add this NSEC3 + * and (later) try to find the real wildcard data */ + VERBOSE_MSG(qry, "=> NSEC3 wildcard: should exist (or error)\n"); + ans->rcode = PKT_NOERROR; + memset(&ans->rrsets[AR_WILD], 0, sizeof(ans->rrsets[AR_WILD])); + return kr_ok(); +} + diff --git a/lib/cache/overflow.test.integr/deckard.yaml b/lib/cache/overflow.test.integr/deckard.yaml new file mode 100644 index 0000000..61032fb --- /dev/null +++ b/lib/cache/overflow.test.integr/deckard.yaml @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +programs: +- name: kresd1 + binary: kresd + additional: + - -n + templates: + - lib/cache/overflow.test.integr/kresd_config.j2 + - tests/config/test_dns_generators.lua + configs: + - config + - dns_gen.lua +- name: kresd2 + binary: kresd + additional: + - -n + templates: + - lib/cache/overflow.test.integr/kresd_config.j2 + - tests/config/test_dns_generators.lua + configs: + - config + - dns_gen.lua diff --git a/lib/cache/overflow.test.integr/kresd_config.j2 b/lib/cache/overflow.test.integr/kresd_config.j2 new file mode 100644 index 0000000..63841ff --- /dev/null +++ b/lib/cache/overflow.test.integr/kresd_config.j2 @@ -0,0 +1,91 @@ +-- SPDX-License-Identifier: GPL-3.0-or-later + +trust_anchors.remove('.') +{% for TAF in TRUST_ANCHOR_FILES %} +trust_anchors.add_file('{{TAF}}') +{% endfor %} + +modules.load("hints") +hints.root({['{{ROOT_NAME}}'] = '{{ROOT_ADDR}}'}) + +{% raw %} +-- Disable RFC5011 TA update +if ta_update then + modules.unload('ta_update') +end + +-- Disable RFC8145 signaling, scenario doesn't provide expected answers +if ta_signal_query then + modules.unload('ta_signal_query') +end + +-- Disable RFC8109 priming, scenario doesn't provide expected answers +if priming then + modules.unload('priming') +end + +-- Disable this module because it make one priming query +if detect_time_skew then + modules.unload('detect_time_skew') +end + +log_level('debug') +policy.add(policy.all(policy.DEBUG_ALWAYS)) + +cache.open(1*MB) + +{% endraw %} + +{% if DO_IP6 == "true" %} +net.ipv6 = true +{% else %} +net.ipv6 = false +{% endif %} + +{% if DO_IP4 == "true" %} +net.ipv4 = true +{% else %} +net.ipv4 = false +{% endif %} + +-- both instances listen on both addresses +-- so queries get distributed between them randomly +net.listen('{{programs[0]["address"]}}') +net.listen('{{programs[1]["address"]}}') + +{% raw %} +-- Self-checks on globals +assert(help() ~= nil) +assert(worker.id ~= nil) +-- Self-checks on facilities +assert(cache.stats() ~= nil) +assert(cache.backends() ~= nil) +assert(worker.stats() ~= nil) +assert(net.interfaces() ~= nil) +-- Self-checks on loaded stuff +{% endraw %} + +assert(net.list()[1].transport.ip == '{{programs[0]["address"]}}') + +{% raw %} +assert(#modules.list() > 0) +-- Self-check timers +ev = event.recurrent(1 * sec, function (ev) return 1 end) +event.cancel(ev) +ev = event.after(0, function (ev) return 1 end) + +local ffi = require('ffi') +local kr_cach = kres.context().cache + +-- canary for cache overflow +local kr_rrset = kres.rrset( + todname('www.example.com'), + kres.type.A, + kres.class.IN, + 604800) +assert(kr_rrset:add_rdata('\192\000\002\001', 4)) +assert(kr_cach:insert(kr_rrset, nil, ffi.C.KR_RANK_SECURE)) + +local generators = dofile('./dns_gen.lua') +event.after(0, generators.gen_batch) +{% endraw %} diff --git a/lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl b/lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl new file mode 100644 index 0000000..eddfbd0 --- /dev/null +++ b/lib/cache/overflow.test.integr/world_cz_vutbr_www.rpl @@ -0,0 +1,298 @@ +do-ip4: no + +; test with real world Internet data +; attempt to resolve www.vutbr.cz. A leads to CNAME piranha.ro.vutbr.cz. +; sub-trees vutbr.cz and ro.vutbr.cz. are in separate zones +; hosted on the same servers with different DNSKEYs + +val-override-date: 20170124180319 +trust-anchor: ". 172800 IN DS 19036 8 2 49aac11d7b6f6446702e54a1607371607a1a41855200fd2ce1cdde32f24e8fb5" +stub-addr: 2001:dc3::35 +CONFIG_END + +SCENARIO_BEGIN www.vutbr.cz. CNAME kresd issue #130 + +; DNS root ; M.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 2001:dc3::35 + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO NOERROR +SECTION QUESTION +. IN DNSKEY +SECTION ANSWER +. 16567 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0= +. 16567 IN DNSKEY 256 3 8 AwEAAYvgWbYkpeGgdPKaKTJU3Us4YSTRgy7+dzvfArIhi2tKoZ/WR1Df w883SOU6Uw7tpVRkLarN0oIMK/xbOBD1DcXnyfElBwKsz4sVVWmfyr/x +igD/UjrcJ5zEBUrUmVtHyjar7ccaVc1/3ntkhZjI1hcungAlOhPhHlk MeX+5Azx6GdX//An5OgrdyH3o/JmOPMDX1mt806JI/hf0EwAp1pBwo5e 8SrSuR1tD3sgNjr6IzCdrKSgqi92z49zcdis3EaY199WFW60DCS7ydu+ +T5Xa+GyOw1quagwf/JUC/mEpeBQYWrnpkBbpDB3sy4+P2i8iCvavehb RyVm9U0MlIc= +. 16567 IN RRSIG DNSKEY 8 0 172800 20170201000000 20170111000000 19036 . Sh+EpofvZgk3J9szMD2B94FxFgyIUKz3hkbCjgWSTqPQyhqNgqVU8QlS EtOo8YLmS4AX98eit5Gmmb2ObpkGoXBmAzu5w/Qt5WsGsWzLQhYrsy9s lDmFQ2JKUoCyfdwqhlJ8VxjzdFdMUiVl+/GPnv4yjxjM8Ke3VAtBkn6n BO7JkcxxOfcgZdZ4MuvSr40K/SenZE+JlLLL1LF4TMCGqaZTTdOx6kFF KSSgy2AS884htWcK0tnwRc630g6nAI2wdvjlRLBeisbfXanI4v8iiPyT FnMmnV7wJGWJ4gtRJ0UH3u5RWXUPZ+s1tKytk3slXbLyQ9xkEDveuD+h b659gQ== +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR DO NOERROR +SECTION QUESTION +cz. IN NS +SECTION AUTHORITY +cz. 172800 IN NS d.ns.nic.cz. +cz. 172800 IN NS a.ns.nic.cz. +cz. 172800 IN NS c.ns.nic.cz. +cz. 172800 IN NS b.ns.nic.cz. +cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06 +cz. 86400 IN RRSIG DS 8 1 86400 20170202170000 20170120160000 61045 . ig2BBmA1kOuTqhVogqLciH40Ina7BCrG/fcaNARSWoaFHGOcC/7KsBZO uMttn/hKDJkH3RPsed2Oswl9bXZ+zrhjeXluUqC0zmsUJDBkS+AkiFJL HCpMSIZaXu/w1ZMADGfyQXl7XWCRbl+eyXi2eTG0SdLtRHNhm3CGJP3C xjzVuOTr9oPEyL0U81jhhlJPCFe8xDD441wLLzpEuVX8VP9N2S1QnIjO BhCEE9OTkPgpS7fMPEl0Yq2gfpRl+DCw1Dd0VB3Hh5M3hmrXuFqNYZQK b0JqDFGYhzvcpUs3EiB9IG7rJt51n6pxCTek1M2w+s6mLYzawVfq+b1Q uQD98A== +SECTION ADDITIONAL +a.ns.nic.cz. 172800 IN A 194.0.12.1 +b.ns.nic.cz. 172800 IN A 194.0.13.1 +c.ns.nic.cz. 172800 IN A 194.0.14.1 +d.ns.nic.cz. 172800 IN A 193.29.206.1 +a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1 +b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1 +c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1 +d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1 +ENTRY_END +; end of M.ROOT-SERVERS.NET. +RANGE_END + + +; domains: cz. ; ?.ns.nic.cz. +RANGE_BEGIN 0 100 + ADDRESS 194.0.12.1 + ADDRESS 194.0.13.1 + ADDRESS 194.0.14.1 + ADDRESS 193.29.206.1 + ADDRESS 2001:678:f::1 + ADDRESS 2001:678:10::1 + ADDRESS 2001:678:11::1 + ADDRESS 2001:678:1::1 + + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +cz. IN DNSKEY +SECTION ANSWER +cz. 18000 IN DNSKEY 256 3 10 AwEAAc9e2YFnG56xtTXu42GLGAkwsrFOBBwOZphNat7HQdBmfi0CbmDf oywCUsaSkObNmm+Zu9MYLNJDHsD+vxsZbtHClpYaSEhMEmHrbnj0BMPV A6hwY6YDGFhKudJ62RmB/rmhQ3iwmICsEdRn2w5fu1rHZv8UJOUMkeWd 6GA48mW3 +cz. 18000 IN DNSKEY 256 3 10 AwEAAdWL2Br92Vx0dLEOOB8y02ss8LtKIyGlLJ2ymJ02WqR3AAEEZN0f NPKF77kdKsjlG8DlzmSIOR12aa9EhpXqyHOwWI0kHOMJVnn6ZKFIAl71 JP/dYIcshYUxKZZMe+zEAUrVtzlLVDtM6cDOPDuBNa1ujYec3eJl9Ipq eUEG6gAH +cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0= +cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170127000000 20170120000000 54576 cz. Fdl//hMdLoZq8//gLt/+3a7LfWqB5/psW9YR3AWNPQGfvrEAcKRBcah+ ikbSCmpAZ6j834xZP1zPd5xMoN33PGXf23iqcgjHvUn50Uq48KRBVYwU H885xNJBl/Po0N8STeG0WNZz2mbUbBbPCGN7CI5yl08usvqOvf2fV8+D 0m//+Fa1cWaqMXpHc6OnhWZ+BN4VdcxxwNbGhH2TZxyiGEMMscEGoIxn yL1pVY8T93LOMwQmuFJ71f8Scij3vYouW/mNuEma/UUZM1bEn8vR1UrP /6JTGPGTG+snHvCxiVtAxCNnqoIJDD+xuonpZLeKN5XU7UDMZPDTtSgX vtzjww== +cz. 18000 IN RRSIG DNSKEY 10 1 18000 20170205002523 20170123080953 58211 cz. MZ6KTtQisTde4iOBH6oasl7bVrRM5ly7Yxdv2l+2gk1YYk4zX6L3m6oB P26SKi+fj8pM77775bRK7uCI9FlyqXa3MJclLU/GmnRANm6T4sSdz0zs F3FK4UfUmHnzdnWXWTnueDfIZr44yF1y1+4I3E96/9/nEYGO+xsifvIj iks= +ENTRY_END + +ENTRY_BEGIN +MATCH opcode subdomain +ADJUST copy_id copy_query +REPLY QR DO NOERROR +SECTION QUESTION +vutbr.cz. IN NS +SECTION AUTHORITY +vutbr.cz. 18000 IN NS pipit.cis.vutbr.cz. +vutbr.cz. 18000 IN NS rhino.cis.vutbr.cz. +vutbr.cz. 18000 IN DS 5512 5 2 78510F9433A4D536A5B9099193E9D58EE5B5CF71F14D983B4DA2EB16 29CFA1E9 +vutbr.cz. 18000 IN RRSIG DS 10 2 18000 20170204213601 20170123080953 58211 cz. lXNBswz/r/1NY7VQq+BlisC+1yqFmUBIaF30L8XDAbiHLcj/AIj0dEy6 PlBlkEeDAi4W9DvR0jo9LjHvFFJLs54cuEEd3pHTdlw8x0dLd1X7Zkh7 cezfAt2EEqdux/ce/sc86lUKOpLnDtry2piWwVf2EqFg9NlW4cHTm78U gsY= +SECTION ADDITIONAL +pipit.cis.vutbr.cz. 18000 IN A 77.93.219.110 +rhino.cis.vutbr.cz. 18000 IN A 147.229.3.10 +pipit.cis.vutbr.cz. 18000 IN AAAA 2a01:430:120::4d5d:db6e +rhino.cis.vutbr.cz. 18000 IN AAAA 2001:67c:1220:e000::93e5:30a +ENTRY_END + +; end of domain cz.: servers ?.ns.nic.cz. +RANGE_END + + +; domains: vutbr.cz. + ro.vutbr.cz. +; servers: pipit.cis.vutbr.cz. + rhino.cis.vutbr.cz. + shark.ro.vutbr.cz. +; shark.ro.vutbr.cz. in fact serves both domains but is listed only in ro.vutbr.cz NS +RANGE_BEGIN 0 100 + ADDRESS 77.93.219.110 + ADDRESS 147.229.3.10 + ADDRESS 147.229.2.59 + ADDRESS 2a01:430:120::4d5d:db6e + ADDRESS 2001:67c:1220:e000::93e5:30a + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO +SECTION QUESTION +vutbr.cz. IN NS +SECTION ANSWER +vutbr.cz. 28800 IN NS rhino.cis.vutbr.cz. +vutbr.cz. 28800 IN NS pipit.cis.vutbr.cz. +vutbr.cz. 28800 IN RRSIG NS 5 2 28800 20170216060902 20170117060902 39756 vutbr.cz. y6Jj5vfvdlLeecB/++/qyhjCzfnFJyY1sX1Ja+wV0ulq3laeCVV7ICXh PKG+CjHUu/nDOrzT9QJP4qxYDCANneI0yxI82XKhhoTN5O/TxyWH/DyT k8JarRoMooHv2RwKd8jtLIxvj1SaJ+AvlP0pOPraaVgbHtn1SJ4ubxQD cFc= +SECTION ADDITIONAL +pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110 +pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e +rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10 +rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a +pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ= +pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8= +rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw= +rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU= +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO +SECTION QUESTION +vutbr.cz. IN DNSKEY +SECTION ANSWER +vutbr.cz. 28800 IN DNSKEY 256 3 5 AwEAAfwRRuGjpt9v4fzuIWFA9MtGfxDrIKhoFA7DNq6B+iCOoQb6t0HZ I9lGDUSR5DRswDGP569NJ/uVD4tJxGnaK2SBQVxIu+bEP1Ouzk+O43iO 8odw50NBWetljjNDP32B3zHpgJRpxyEqzDQaQ6B4Zer6sDZm9wo5SVJe r9LjJV9p +vutbr.cz. 28800 IN DNSKEY 257 3 5 AwEAAfhR+s/4SLZZNA+kD2u1UgYBUu+X3Avi60QCaE1o2STterM405s8 mWMWJOlZGtjjIky3TEMxQ0+ZtMbEeJu2wNDLdV/XglX+pJAjyy728WJH 4u2/gJR8ZWsEIc0Jwb4FjwmBiF2Koz0SGVvrzEZ9T1H7dHq2X6f8KzYB otJyrAIWr9tZi/9tHrngZJ5wXELmMPWCfEFapdQMoKWoNvzrMYFli17R Mz7gJzCmNxMRV8/WkjsNPgYsTKpsAT8qEsXiTN9987AIKPHvc5j+/njq +fTXdOqGVpIgSiso+qJMddEMBcu/MBBYVFOwRQe1ez2tMwIX7y5mwDvK 0wsmyRvHugfFuxSnfiJvQr05kSnj0wxD9s9LNhrF4PocrcYqnBN/lBx9 D6633jJ3zT3T5Foe/Vj9A/X7F2oN6FOkdwO+YSEUot980pJQut6DR22U P4bLakyDMiTdOQ31c/dRIoTsccxw+838pXFyEPgiqOHRSeN/w9km6BID cl+32Xq97kXSMQH6AxOUsx9/Mxdj7ISwbS4utaAWoP460+TMcnfJfWfB NEWhuFvnfB9l63ZjZToB2PUVhrTxRwKUlfMLegSJKoZfiae82kK1pN4x FYyquKSykm/oXsM2w4OQvpqGcTwAXzZ5s95J45f7PsCap0bscGKumxsH cDswWpUz/UVosIrr +vutbr.cz. 28800 IN RRSIG DNSKEY 5 2 28800 20170216060902 20170117060902 5512 vutbr.cz. QHw07MAjA4NFi3On8zaMw/q4IuADXVp4TODfK5PHb8OUIX2Yy+bKLrSX /Cc9ClWUpE69x80F9dFEeRZGJiYOwstNQGQVeq/EKNytm1XmhS8cp3SW CYHBpLjZGPrlhvqPhWd0S4vqPNiD8hDzgFAgaCNfwXDDKXhF2/qtpQ0V pDnytMP6pNPLPMpF2hzaLfCMzABShxcEOAr7+KTbxbffOik4YneG8seu XDtBvCVjP8lJcSU+q+UbotLnjyOgn8vV8pliTNqcvRsJTdtvTlJKHu8B iLkFeCE1DpRhyrVT5zC9NSOcoIv7tau2NE2oUPgtRzK76el6i9L9LcSs G+59j02AINefpAtc6W2khmTnGthibeOy/F9FuFkXUy6AmqIdNszMAj++ 8Mzv3A1OHfsfpIS3tLmC4drhdSHr2ab0Pe0lYQq2a9FSeQzSk6s9gwwZ gMVPVQHbouyvn6BCHaRVDjTV8GPKlk3C8GNaHcHb1hAGSPpw3kqL41dd K92Un4tLIoOYomxUYoyMtyxxwddXyR7ivToUHF7e/yv8MACMEo72N9sf y4zLEqkL1mJ1pCp3csI1bKaaA/c7sqb7PX93iqvoY06k55Pd7kT+lAF1 7QvXGg4U1kDrwytQPyocN8wmsX3//CpWUD07v8fCUqKOcIrVNGnoPmPC PpNe3AtpJoE= +vutbr.cz. 28800 IN RRSIG DNSKEY 5 2 28800 20170216060902 20170117060902 39756 vutbr.cz. CNDE7Ht7xm8Jo9tuOlJ8N9+vI/Htfpk53MI0HG7B1EZJws/yEV7YFOOL SIAt3rzu1OHjaxr4CG/baqGRPtsaWSBHuLSdSduivxXw8xiQcMKzP6Cz 7xhJkQZxzDJ4oO5L2K2zWHcAJ8lfP1/3NHHoH1p2RATLN5sI7ofQE//W +ck= +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO +SECTION QUESTION +www.vutbr.cz. IN A +SECTION ANSWER +www.vutbr.cz. 300 IN CNAME piranha.ro.vutbr.cz. +www.vutbr.cz. 300 IN RRSIG CNAME 5 3 300 20170216060902 20170117060902 39756 vutbr.cz. 9B3UC5SOEw1+yKlYlOTINEuNq0Kdglywc5IYJwzeSzQ3ykptzZo3ABSy bYhTqImVkhm/4NFM9/4HWMHPDzTmrWS0mCI/ljCd/oe/PxW/uESvo4P5 EQzlcuH6xBzc1KdEFAJOSmRzFjj3vyK1QN3k/c+1y2oMFOYOR2oOzCw+ MIE= +piranha.ro.vutbr.cz. 3600 IN A 147.229.2.90 +piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I= +SECTION AUTHORITY +ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz. +ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz. +ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz. +ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw= +SECTION ADDITIONAL +rhino.cis.vutbr.cz. 83217 IN A 147.229.3.10 +rhino.cis.vutbr.cz. 83217 IN AAAA 2001:67c:1220:e000::93e5:30a +shark.ro.vutbr.cz. 3600 IN A 147.229.2.59 +pipit.cis.vutbr.cz. 14794 IN A 77.93.219.110 +pipit.cis.vutbr.cz. 14794 IN AAAA 2a01:430:120::4d5d:db6e +rhino.cis.vutbr.cz. 83217 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw= +rhino.cis.vutbr.cz. 83217 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU= +shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8= +pipit.cis.vutbr.cz. 85923 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ= +pipit.cis.vutbr.cz. 85923 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8= +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO +SECTION QUESTION +ro.vutbr.cz. IN NS +SECTION ANSWER +ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz. +ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz. +ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz. +ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw= +SECTION ADDITIONAL +rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10 +rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a +shark.ro.vutbr.cz. 3600 IN A 147.229.2.59 +pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110 +pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e +rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw= +rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU= +shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8= +pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ= +pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8= +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO +SECTION QUESTION +ro.vutbr.cz. IN DS +SECTION ANSWER +ro.vutbr.cz. 28800 IN DS 16627 5 2 1AEE56EAF9D01A51C8C524E55A7FAE0E27207911F0FA6126052CE5B3 39335FC8 +ro.vutbr.cz. 28800 IN DS 16627 5 1 BFDFD0FB1EDFCEBFB9ECB13C93F9CA65755217BA +ro.vutbr.cz. 28800 IN RRSIG DS 5 3 28800 20170216060902 20170117060902 39756 vutbr.cz. OOJfGI14bRHqeWhRLMOa75pfHo+clR4rMJpvO3PPjmheownqy2awA7u3 xR5FJko7A6e+difoJdAWCMzN7x1qcrd1htOOKOc7wtcb+QC2JH8B/e0G 0gNPw2UKsFL1Qw9HQkSqxyIaCGg3nMLO1hh3AVccZadw2f/jLpAzw5/1 pLA= +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO +SECTION QUESTION +ro.vutbr.cz. IN DNSKEY +SECTION ANSWER +ro.vutbr.cz. 3600 IN DNSKEY 256 3 5 AwEAAb4tyN4pqltB48s1xQS3ZPXnTZJMvgXxiouXU9xtzj4wnhjhZp45 H7ozslWuksrwQWhZ8AASAD5kPFbQRbwpQ7xbEb3xdKHaWCFpyRCTkrqa ZQZQy4gaVqO+oRW42dIQ9K08A/WfvRuRDtw3VWDATp9pUkgpvb1n6+lp 71YK19RX +ro.vutbr.cz. 3600 IN DNSKEY 257 3 5 AwEAAef6bqTAl94KddNHvit41gw6QBKkiYjUeS+UP58VHybV29RC7sSE +rYmkXabaMOLmoqMQRMepBEaUdM5OoZBWibHrPAbG0Wf+vlMOoWD5+EC 2mCxrUntIlOuS4XpMTh22+l0k1xSPiMGKjY0BDR95Iu3dDezCVl9PkPp tHj/rAnRTH7Q0fH9Mip8sigosd/CmsoY03I0AcZT4z1+XpGsq5Npxwtj 7cz0SRTI/eV5nynNYK+vr6kOfU1fw7p8/wxIfXkks0Xy8ktXa26DFdw1 RoqVlTS1s1diFyF5niCOT6Ei2kAlf0fggZJBypwoK+6J42wwD2OhORX+ lKrhooaN4TU9AcHwgv25XTXhUq4tYh+veazdXNWDjEb3ZyLM8fKERCa9 YtDBFoHM7yFOHbsOhHKMn8F6T2Boi73hU/+wspjL/n8taKevyyygGg+U g4ugo2pTIouAs5DNnv+nUrpctcKZ5nMEUVl+3XBsXplIyz9QEKHWdFzL gyfIZEok8WdYHebcIy1vJrxzqCNw9ixnTn+OK1lwlMToVH1AGpvRKRPo wGSFaIrDyXxKul34j2jEhP9TWRcJqncy166Ueu3c0BKmclM29N8jeWbP 3TqRJ3RRxNj/vk6c/UGmmrHEz8YdNp2L0hv3JgItr2GujCvPApUvLNPW C7DSErQ3JsjV3gah +ro.vutbr.cz. 3600 IN RRSIG DNSKEY 5 3 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. pN+8YElj24dhtnOQ20sjWxJTjx+FLTMrPms1lWIJKZtp2evQBG5AnAep 6w0QeMUTIh9ter58Dh6wu2IN4uA1h3ThxnSgwLraOChUFBtPTO8h5y8J mAq4KXSfqbEcHzZO/nBAtxSUk7aUz7yWf09xE+iozW3ORRWIXovMYci5 eEw= +ro.vutbr.cz. 3600 IN RRSIG DNSKEY 5 3 3600 20170222120032 20170123120032 16627 ro.vutbr.cz. DSaIAl+iyToM8+ai9xuRVcRshYyI66XHWkOz0XEbIAwbc8aEMEeFCA91 1vpuBb6H92MXvM8hYsBhZHNIA0ApoIE4bdyEGZY05XN3GYgJ4BEhXJVM RR+inJf+vGGqdlRP6F2sPO+rCqfxWBvSoUFU7DpCpkl7hz2Ex0Clm9C9 YnWgL+tGmAH33s2Y8lTA3hG/0W0NxD5zy1LiyDa8Ls3vV4MC6gVxyloT Capd8FkDL9PmgW0gMRNtIWmc5Hw+j/HRMoy+oRCe8PIfUL/Dpx3iTAH8 iN3wV8apV2uPa0L8QgpixK4Tc87aSainCopVY+NOc5t0HErUzj8i7qA9 J/cRtQvlUzln5vBsrQsVIzIeNV4o8/cM3zFyfdKkHh1tWYKLJKkjfXc5 +7VMvF8PnoHceT/Zr2gCc8tnygRobypzgqy3p69bRJqiT0/eCAgpGusV 1DCOJY0sdiGDZEtpqeINbAgGKAMmmNwjIwYSFowRzdawip1wNd+90RhI +8hvx8Sc5+K5Mom2BF2wGHf/2Kv/ArzyXxqqcNozM61L1AjxIsBHjnLZ TzPlLntmiHUVaqET9Yc3G0K/RdsIpqz4M79N0BX66a58x2a3fLqQdrEC QshZPNxk2S4eCsrVRjHvU4a7e74Rbf/zXp89Y+jmwBbDMdnp+2/h9s6U J0sEBCYyo9M= +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA DO +SECTION QUESTION +piranha.ro.vutbr.cz. IN A +SECTION ANSWER +piranha.ro.vutbr.cz. 3600 IN A 147.229.2.90 +piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I= +SECTION AUTHORITY +ro.vutbr.cz. 86400 IN NS shark.ro.vutbr.cz. +ro.vutbr.cz. 86400 IN NS rhino.cis.vutbr.cz. +ro.vutbr.cz. 86400 IN NS pipit.cis.vutbr.cz. +ro.vutbr.cz. 86400 IN RRSIG NS 5 3 86400 20170222120032 20170123120032 12150 ro.vutbr.cz. HAQ8A+QNsS1WIXdW/fbT3jP+IxObBBvgUmvzsmJBXo8HMtnMAcuCQGmB 2JBQsQethQXsdyLnMK8to/5A9VRkqkAa7edxUoy7SdDi/mzGeLAVhF+5 kXSPD6t1vjiNdnIYAMpiOQbodCGxAnq6jnNyrjEzffdq3qw+5IkFNdG4 7Pw= +SECTION ADDITIONAL +rhino.cis.vutbr.cz. 86400 IN A 147.229.3.10 +rhino.cis.vutbr.cz. 86400 IN AAAA 2001:67c:1220:e000::93e5:30a +shark.ro.vutbr.cz. 3600 IN A 147.229.2.59 +pipit.cis.vutbr.cz. 86400 IN A 77.93.219.110 +pipit.cis.vutbr.cz. 86400 IN AAAA 2a01:430:120::4d5d:db6e +rhino.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. X/tDf8e3JEV0LxiItfpQnBzeaRIq693VG8d30iCH4/1I0uqyCfxboWmm /CBpn9A8MCJu9NEEv+4+povNlfUfqi2yjsqJEVj8ztHxD4g9cc284Cv6 ySjxrSZ9axVqoaopEXujiTwwWJUFcgF6pxqyXVksW7sgKJrboM4VSlQD +Sw= +rhino.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. T3Yf5PAkSeJtoOH90ea9zZBG9FC3iFhiCSerDn6d9up8GRfzxDsavYJC zQu+3vnOySySn+3TMzQSSFcWdJC2iO7ulaDGr177Gof9QJbKSVSMW7jt YDE2f4/R4Go3NZVwjk/HfpCInoR6pHNA1s/9hMnWtiVopmBdfzyd3/sW YOU= +shark.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. SmhgyF48yX/6yH7AdSmGX60NL/xaiKH/oAzB0rnPfQZ6j+UfV57ginVV lj798K9A8jjucUpqE8ua2mZ6/aOhpqlV2iI0CZXG44zOupsCY1/OXBDx YNetBcjoXDQCBQRLLLEUL5FerDVxqT74ngdLdKubwRdrB0TLQlvpBr+F Tc8= +pipit.cis.vutbr.cz. 86400 IN RRSIG A 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. Cz9etHnEOQTzu+6rYJEqx/SQ1tQgPOCyf8HSj4KOsx89jtgiHNC6pep6 ZE0SphMGAs3jC/uGIhlaFNZ3i38OQIMuqwacbz+XZyW5bByvV3QZrhqh dFxMDfmPuNiCAT3crFpUkvVW1OE3YfGHzZGXX7JP5wb1b8A3X6Qih7fV +nQ= +pipit.cis.vutbr.cz. 86400 IN RRSIG AAAA 5 4 86400 20170204080646 20170105080646 28257 cis.vutbr.cz. piafjh6my2fooZRrzwCu9RQ95gYaMQkhIkDaGX/fT6wXzSdmgFZkS1Nl EMIKdDCQaPrLGMG3p32ptMkAm4esPekeyNtLSMBtXwZyUkgEGn6h1QM2 Yr3TOo8cixfk5nmRRdlYadf5krLb8yI9exiqeymgEQLa1YNRz/bWArlX bn8= +ENTRY_END + +; end of pipit.cis.vutbr.cz. & rhino.cis.vutbr.cz. +RANGE_END + + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.vutbr.cz. IN A +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH flags rcode question answer +REPLY QR RD RA NOERROR +SECTION QUESTION +www.vutbr.cz. IN A +SECTION ANSWER +www.vutbr.cz. IN CNAME piranha.ro.vutbr.cz. +piranha.ro.vutbr.cz. IN A 147.229.2.90 +ENTRY_END + +STEP 20 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +www.vutbr.cz. IN A +ENTRY_END + +STEP 21 CHECK_ANSWER +ENTRY_BEGIN +MATCH flags rcode question answer +REPLY QR RD RA AD NOERROR +SECTION QUESTION +www.vutbr.cz. IN A +SECTION ANSWER +www.vutbr.cz. IN CNAME piranha.ro.vutbr.cz. +www.vutbr.cz. IN RRSIG CNAME 5 3 300 20170216060902 20170117060902 39756 vutbr.cz. 9B3UC5SOEw1+yKlYlOTINEuNq0Kdglywc5IYJwzeSzQ3ykptzZo3ABSy bYhTqImVkhm/4NFM9/4HWMHPDzTmrWS0mCI/ljCd/oe/PxW/uESvo4P5 EQzlcuH6xBzc1KdEFAJOSmRzFjj3vyK1QN3k/c+1y2oMFOYOR2oOzCw+ MIE= +piranha.ro.vutbr.cz. IN A 147.229.2.90 +piranha.ro.vutbr.cz. 3600 IN RRSIG A 5 4 3600 20170222120032 20170123120032 12150 ro.vutbr.cz. Jz8bcAADQjCKTCcF70IK1aHGQlM4ukyN0myABlxoPaqid1mHX5jwR91b kdQmUAh2xDitlgRLbFjbUUgmjSPzQ5Qt7GAFUsVmqxvjbOLZjqHER1dh zmiWO0fDvvP647Osv3RiAP822rNUJcJrUBZU9LmeP05gwIHcpJrhdVBT b7I= +ENTRY_END + +SCENARIO_END diff --git a/lib/cache/peek.c b/lib/cache/peek.c new file mode 100644 index 0000000..e1901ac --- /dev/null +++ b/lib/cache/peek.c @@ -0,0 +1,774 @@ +/* Copyright (C) CZ.NIC, z.s.p.o. <knot-resolver@labs.nic.cz> + * SPDX-License-Identifier: GPL-3.0-or-later + */ + +#include "lib/cache/impl.h" + +#include "lib/dnssec/ta.h" +#include "lib/layer/iterate.h" + +/* The whole file only exports peek_nosync(). + * Forwards for larger chunks of code: */ + +static int found_exact_hit(kr_layer_t *ctx, knot_pkt_t *pkt, knot_db_val_t val, + uint8_t lowest_rank); +static int closest_NS(struct kr_cache *cache, struct key *k, entry_list_t el, + struct kr_query *qry, bool only_NS, bool is_DS); +static int answer_simple_hit(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type, + const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl); +static int answer_dname_hit(kr_layer_t *ctx, knot_pkt_t *pkt, const knot_dname_t *dname_owner, + const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl); +static int try_wild(struct key *k, struct answer *ans, const knot_dname_t *clencl_name, + uint16_t type, uint8_t lowest_rank, + const struct kr_query *qry, struct kr_cache *cache); + +static int peek_encloser( + struct key *k, struct answer *ans, int sname_labels, + uint8_t lowest_rank, const struct kr_query *qry, struct kr_cache *cache); + + +static int nsec_p_init(struct nsec_p *nsec_p, knot_db_val_t nsec_p_entry, bool with_knot) +{ + const size_t stamp_len = sizeof(uint32_t); + if (nsec_p_entry.len <= stamp_len) { /* plain NSEC if equal */ + nsec_p->raw = NULL; + nsec_p->hash = 0; + return kr_ok(); + } + nsec_p->raw = (uint8_t *)nsec_p_entry.data + stamp_len; + nsec_p->hash = nsec_p_mkHash(nsec_p->raw); + if (!with_knot) return kr_ok(); + /* Convert NSEC3 params to another format. */ + const dnssec_binary_t rdata = { + .size = nsec_p_rdlen(nsec_p->raw), + .data = (uint8_t *)/*const-cast*/nsec_p->raw, + }; + int ret = dnssec_nsec3_params_from_rdata(&nsec_p->libknot, &rdata); + return ret == DNSSEC_EOK ? kr_ok() : kr_error(ret); +} + +static void nsec_p_cleanup(struct nsec_p *nsec_p) +{ + dnssec_binary_free(&nsec_p->libknot.salt); + /* We don't really need to clear it, but it's not large. (`salt` zeroed above) */ + memset(nsec_p, 0, sizeof(*nsec_p)); +} + +/** Compute new TTL for nsec_p entry, using SOA serial arith. + * \param new_ttl (optionally) write the new TTL (even if negative) + * \return error code, e.g. kr_error(ESTALE) */ +static int nsec_p_ttl(knot_db_val_t entry, const uint32_t timestamp, int32_t *new_ttl) +{ + if (kr_fails_assert(entry.data)) + return kr_error(EINVAL); + uint32_t stamp; + if (!entry.len) + return kr_error(ENOENT); + if (kr_fails_assert(entry.len >= sizeof(stamp))) + return kr_error(EILSEQ); + memcpy(&stamp, entry.data, sizeof(stamp)); + int32_t newttl = stamp - timestamp; + if (new_ttl) *new_ttl = newttl; + return newttl < 0 ? kr_error(ESTALE) : kr_ok(); +} + +static uint8_t get_lowest_rank(const struct kr_query *qry, const knot_dname_t *name, const uint16_t type) +{ + /* Shut up linters. */ + kr_require(qry && qry->request); + /* TODO: move rank handling into the iterator (DNSSEC_* flags)? */ + const bool allow_unverified = + knot_wire_get_cd(qry->request->qsource.packet->wire) || qry->flags.STUB; + /* in stub mode we don't trust RRs anyway ^^ */ + if (qry->flags.NONAUTH) { + return KR_RANK_INITIAL; + /* Note: there's little sense in validation status for non-auth records. + * In case of using NONAUTH to get NS IPs, knowing that you ask correct + * IP doesn't matter much for security; it matters whether you can + * validate the answers from the NS. + */ + } else if (!allow_unverified) { + /* Records not present under any TA don't have their security + * verified at all, so we also accept low ranks in that case. */ + const bool ta_covers = kr_ta_closest(qry->request->ctx, name, type); + /* ^ TODO: performance? TODO: stype - call sites */ + if (ta_covers) { + return KR_RANK_INSECURE | KR_RANK_AUTH; + } /* else fallthrough */ + } + return KR_RANK_INITIAL | KR_RANK_AUTH; +} + + +/** Almost whole .produce phase for the cache module. + * \note we don't transition to KR_STATE_FAIL even in case of "unexpected errors". + */ +int peek_nosync(kr_layer_t *ctx, knot_pkt_t *pkt) +{ + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; + struct kr_cache *cache = &req->ctx->cache; + + struct key k_storage, *k = &k_storage; + int ret = kr_dname_lf(k->buf, qry->sname, false); + if (kr_fails_assert(ret == 0)) + return ctx->state; + + const uint8_t lowest_rank = get_lowest_rank(qry, qry->sname, qry->stype); + + /**** 1. find the name or the closest (available) zone, not considering wildcards + **** 1a. exact name+type match (can be negative, mainly in insecure zones) */ + { + knot_db_val_t key = key_exact_type_maypkt(k, qry->stype); + knot_db_val_t val = { NULL, 0 }; + ret = cache_op(cache, read, &key, &val, 1); + if (!ret) { + /* found an entry: test conditions, materialize into pkt, etc. */ + ret = found_exact_hit(ctx, pkt, val, lowest_rank); + } + } + if (!ret) { + return KR_STATE_DONE; + } else if (kr_fails_assert(ret == kr_error(ENOENT))) { + VERBOSE_MSG(qry, "=> exact hit error: %d %s\n", ret, kr_strerror(ret)); + return ctx->state; + } + + /* Avoid aggressive answers in STUB mode. + * As STUB mode doesn't validate, it wouldn't save the necessary records. + * Moreover, this special case avoids unintentional NXDOMAIN on grafted subtrees. */ + if (qry->flags.STUB) + return ctx->state; + + /**** 1b. otherwise, find the longest prefix zone/xNAME (with OK time+rank). [...] */ + k->zname = qry->sname; + ret = kr_dname_lf(k->buf, k->zname, false); /* LATER(optim.): probably remove */ + if (kr_fails_assert(ret == 0)) + return ctx->state; + entry_list_t el; + ret = closest_NS(cache, k, el, qry, false, qry->stype == KNOT_RRTYPE_DS); + if (ret) { + if (kr_fails_assert(ret == kr_error(ENOENT)) || !el[0].len) { + return ctx->state; + } + } + switch (k->type) { + case KNOT_RRTYPE_CNAME: { + const knot_db_val_t v = el[EL_CNAME]; + if (kr_fails_assert(v.data && v.len)) + return ctx->state; + const int32_t new_ttl = get_new_ttl(v.data, qry, qry->sname, + KNOT_RRTYPE_CNAME, qry->timestamp.tv_sec); + ret = answer_simple_hit(ctx, pkt, KNOT_RRTYPE_CNAME, v.data, + knot_db_val_bound(v), new_ttl); + return ret == kr_ok() ? KR_STATE_DONE : ctx->state; + } + case KNOT_RRTYPE_DNAME: { + const knot_db_val_t v = el[EL_DNAME]; + if (kr_fails_assert(v.data && v.len)) + return ctx->state; + /* TTL: for simplicity, we just ask for TTL of the generated CNAME. */ + const int32_t new_ttl = get_new_ttl(v.data, qry, qry->sname, + KNOT_RRTYPE_CNAME, qry->timestamp.tv_sec); + ret = answer_dname_hit(ctx, pkt, k->zname, v.data, + knot_db_val_bound(v), new_ttl); + return ret == kr_ok() ? KR_STATE_DONE : ctx->state; + } + } + + /* We have to try proving from NSEC*. */ + auto_free char *log_zname = NULL; + WITH_VERBOSE(qry) { + log_zname = kr_dname_text(k->zname); + if (!el[0].len) { + VERBOSE_MSG(qry, "=> no NSEC* cached for zone: %s\n", log_zname); + } + } + +#if 0 + if (!eh) { /* fall back to root hints? */ + ret = kr_zonecut_set_sbelt(req->ctx, &qry->zone_cut); + if (ret) return ctx->state; + kr_assert(!qry->zone_cut.parent); + + //VERBOSE_MSG(qry, "=> using root hints\n"); + //qry->flags.AWAIT_CUT = false; + return ctx->state; + } + + /* Now `eh` points to the closest NS record that we've found, + * and that's the only place to start - we may either find + * a negative proof or we may query upstream from that point. */ + kr_zonecut_set(&qry->zone_cut, k->zname); + ret = kr_make_query(qry, pkt); // TODO: probably not yet - qname minimization + if (ret) return ctx->state; +#endif + + /** Structure for collecting multiple NSEC* + RRSIG records, + * in preparation for the answer, and for tracking the progress. */ + struct answer ans; + memset(&ans, 0, sizeof(ans)); + ans.mm = &pkt->mm; + const int sname_labels = knot_dname_labels(qry->sname, NULL); + + /* Try the NSEC* parameters in order, until success. + * Let's not mix different parameters for NSEC* RRs in a single proof. */ + for (int i = 0; ;) { + int32_t log_new_ttl = -123456789; /* visually recognizable value */ + ret = nsec_p_ttl(el[i], qry->timestamp.tv_sec, &log_new_ttl); + if (!ret || kr_log_is_debug_qry(CACHE, qry)) { + nsec_p_init(&ans.nsec_p, el[i], !ret); + } + if (ret) { + VERBOSE_MSG(qry, "=> skipping zone: %s, %s, hash %x;" + "new TTL %d, ret %d\n", + log_zname, (ans.nsec_p.raw ? "NSEC3" : "NSEC"), + (unsigned)ans.nsec_p.hash, (int)log_new_ttl, ret); + /* no need for nsec_p_cleanup() in this case */ + goto cont; + } + VERBOSE_MSG(qry, "=> trying zone: %s, %s, hash %x\n", + log_zname, (ans.nsec_p.raw ? "NSEC3" : "NSEC"), + (unsigned)ans.nsec_p.hash); + /**** 2. and 3. inside */ + ret = peek_encloser(k, &ans, sname_labels, + lowest_rank, qry, cache); + nsec_p_cleanup(&ans.nsec_p); + if (!ret) break; + if (ret < 0) return ctx->state; + cont: + /* Otherwise we try another nsec_p, if available. */ + if (++i == ENTRY_APEX_NSECS_CNT) return ctx->state; + /* clear possible partial answers in `ans` (no need to deallocate) */ + ans.rcode = 0; + memset(&ans.rrsets, 0, sizeof(ans.rrsets)); + } + + /**** 4. add SOA iff needed */ + if (ans.rcode != PKT_NOERROR) { + /* Assuming k->buf still starts with zone's prefix, + * look up the SOA in cache. */ + k->buf[0] = k->zlf_len; + knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_SOA); + knot_db_val_t val = { NULL, 0 }; + ret = cache_op(cache, read, &key, &val, 1); + const struct entry_h *eh; + if (ret || !(eh = entry_h_consistent_E(val, KNOT_RRTYPE_SOA))) { + kr_assert(ret); /* only want to catch `eh` failures */ + VERBOSE_MSG(qry, "=> SOA missed\n"); + return ctx->state; + } + /* Check if the record is OK. */ + int32_t new_ttl = get_new_ttl(eh, qry, k->zname, KNOT_RRTYPE_SOA, + qry->timestamp.tv_sec); + if (new_ttl < 0 || eh->rank < lowest_rank || eh->is_packet) { + VERBOSE_MSG(qry, "=> SOA unfit %s: rank 0%.2o, new TTL %d\n", + (eh->is_packet ? "packet" : "RR"), + eh->rank, new_ttl); + return ctx->state; + } + /* Add the SOA into the answer. */ + ret = entry2answer(&ans, AR_SOA, eh, knot_db_val_bound(val), + k->zname, KNOT_RRTYPE_SOA, new_ttl); + if (ret) return ctx->state; + } + + /* Find our target RCODE. */ + int real_rcode; + switch (ans.rcode) { + case PKT_NODATA: + case PKT_NOERROR: /* positive wildcarded response */ + real_rcode = KNOT_RCODE_NOERROR; + break; + case PKT_NXDOMAIN: + real_rcode = KNOT_RCODE_NXDOMAIN; + break; + default: + kr_assert(false); + case 0: /* i.e. nothing was found */ + /* LATER(optim.): zone cut? */ + VERBOSE_MSG(qry, "=> cache miss\n"); + return ctx->state; + } + + if (pkt_renew(pkt, qry->sname, qry->stype) + || knot_pkt_begin(pkt, KNOT_ANSWER) + ) { + kr_assert(false); + return ctx->state; + } + knot_wire_set_rcode(pkt->wire, real_rcode); + + bool expiring = false; // TODO + for (int i = 0; i < sizeof(ans.rrsets) / sizeof(ans.rrsets[0]); ++i) { + if (i == 1) knot_pkt_begin(pkt, KNOT_AUTHORITY); + if (!ans.rrsets[i].set.rr) continue; + expiring = expiring || ans.rrsets[i].set.expiring; + ret = pkt_append(pkt, &ans.rrsets[i], ans.rrsets[i].set.rank); + if (kr_fails_assert(ret == 0)) + return ctx->state; + } + + /* Finishing touches. */ + struct kr_qflags * const qf = &qry->flags; + qf->EXPIRING = expiring; + qf->CACHED = true; + qf->NO_MINIMIZE = true; + + return KR_STATE_DONE; +} + +/** + * This is where the high-level "business logic" of aggressive cache is. + * \return 0: success (may need SOA); >0: try other nsec_p; <0: exit cache immediately. + */ +static int peek_encloser( + struct key *k, struct answer *ans, const int sname_labels, + uint8_t lowest_rank, const struct kr_query *qry, struct kr_cache *cache) +{ + /** Start of NSEC* covering the sname; + * it's part of key - the one within zone (read only) */ + knot_db_val_t cover_low_kwz = { NULL, 0 }; + knot_dname_t cover_hi_storage[KNOT_DNAME_MAXLEN]; + /** End of NSEC* covering the sname. */ + knot_db_val_t cover_hi_kwz = { + .data = cover_hi_storage, + .len = sizeof(cover_hi_storage), + }; + + /**** 2. Find a closest (provable) encloser (of sname). */ + int clencl_labels = -1; + bool clencl_is_tentative = false; + if (!ans->nsec_p.raw) { /* NSEC */ + int ret = nsec1_encloser(k, ans, sname_labels, &clencl_labels, + &cover_low_kwz, &cover_hi_kwz, qry, cache); + if (ret) return ret; + } else { + int ret = nsec3_encloser(k, ans, sname_labels, &clencl_labels, + qry, cache); + clencl_is_tentative = ret == ABS(ENOENT) && clencl_labels >= 0; + /* ^^ Last chance: *positive* wildcard record under this clencl. */ + if (ret && !clencl_is_tentative) return ret; + } + + /* We should have either a match or a cover at this point. */ + if (kr_fails_assert(ans->rcode == PKT_NODATA || ans->rcode == PKT_NXDOMAIN)) + return kr_error(EINVAL); + const bool ncloser_covered = ans->rcode == PKT_NXDOMAIN; + + /** Name of the closest (provable) encloser. */ + const knot_dname_t *clencl_name = qry->sname; + for (int l = sname_labels; l > clencl_labels; --l) + clencl_name = knot_wire_next_label(clencl_name, NULL); + + /**** 3. source of synthesis checks, in case the next closer name was covered. + **** 3a. We want to query for NSEC* of source of synthesis (SS) or its + * predecessor, providing us with a proof of its existence or non-existence. */ + if (ncloser_covered && !ans->nsec_p.raw) { + int ret = nsec1_src_synth(k, ans, clencl_name, + cover_low_kwz, cover_hi_kwz, qry, cache); + if (ret == AR_SOA) return 0; + kr_assert(ret <= 0); + if (ret) return ret; + + } else if (ncloser_covered && ans->nsec_p.raw && !clencl_is_tentative) { + int ret = nsec3_src_synth(k, ans, clencl_name, qry, cache); + if (ret == AR_SOA) return 0; + kr_assert(ret <= 0); + if (ret) return ret; + + } /* else (!ncloser_covered) so no wildcard checks needed, + * as we proved that sname exists. */ + + /**** 3b. find wildcarded answer, if next closer name was covered + * and we don't have a full proof yet. (common for NSEC*) */ + if (!ncloser_covered) + return kr_ok(); /* decrease indentation */ + /* Construct key for exact qry->stype + source of synthesis. */ + int ret = kr_dname_lf(k->buf, clencl_name, true); + if (kr_fails_assert(ret == 0)) + return kr_error(ret); + const uint16_t types[] = { qry->stype, KNOT_RRTYPE_CNAME }; + for (int i = 0; i < (2 - (qry->stype == KNOT_RRTYPE_CNAME)); ++i) { + ret = try_wild(k, ans, clencl_name, types[i], + lowest_rank, qry, cache); + if (ret == kr_ok()) { + return kr_ok(); + } else if (kr_fails_assert(ret == kr_error(ENOENT) || ret == kr_error(ESTALE))) { + return kr_error(ret); + } + /* else continue */ + } + /* Neither attempt succeeded, but the NSEC* proofs were found, + * so skip trying other parameters, as it seems very unlikely + * to turn out differently than by the same wildcard search. */ + return kr_error(ENOENT); +} + +static void answer_simple_qflags(struct kr_qflags *qf, const struct entry_h *eh, + uint32_t new_ttl) +{ + /* Finishing touches. */ + qf->EXPIRING = is_expiring(eh->ttl, new_ttl); + qf->CACHED = true; + qf->NO_MINIMIZE = true; + qf->DNSSEC_INSECURE = kr_rank_test(eh->rank, KR_RANK_INSECURE); + if (qf->DNSSEC_INSECURE) { + qf->DNSSEC_WANT = false; + } +} + +#define CHECK_RET(ret) do { \ + if (kr_fails_assert((ret) >= 0)) return kr_error((ret)); \ +} while (false) + +static int answer_simple_hit(kr_layer_t *ctx, knot_pkt_t *pkt, uint16_t type, + const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl) +{ + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; + + /* All OK, so start constructing the (pseudo-)packet. */ + int ret = pkt_renew(pkt, qry->sname, qry->stype); + CHECK_RET(ret); + + /* Materialize the sets for the answer in (pseudo-)packet. */ + struct answer ans; + memset(&ans, 0, sizeof(ans)); + ans.mm = &pkt->mm; + ret = entry2answer(&ans, AR_ANSWER, eh, eh_bound, + qry->sname, type, new_ttl); + CHECK_RET(ret); + /* Put links to the materialized data into the pkt. */ + ret = pkt_append(pkt, &ans.rrsets[AR_ANSWER], eh->rank); + CHECK_RET(ret); + + answer_simple_qflags(&qry->flags, eh, new_ttl); + + VERBOSE_MSG(qry, "=> satisfied by exact %s: rank 0%.2o, new TTL %d\n", + (type == KNOT_RRTYPE_CNAME ? "CNAME" : "RRset"), + eh->rank, new_ttl); + return kr_ok(); +} + +static int answer_dname_hit(kr_layer_t *ctx, knot_pkt_t *pkt, const knot_dname_t *dname_owner, + const struct entry_h *eh, const void *eh_bound, uint32_t new_ttl) +{ + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; + + /* All OK, so start constructing the (pseudo-)packet. */ + int ret = pkt_renew(pkt, qry->sname, qry->stype); + CHECK_RET(ret); + + /* Materialize the DNAME for the answer in (pseudo-)packet. */ + struct answer ans; + memset(&ans, 0, sizeof(ans)); + ans.mm = &pkt->mm; + ret = entry2answer(&ans, AR_ANSWER, eh, eh_bound, + dname_owner, KNOT_RRTYPE_DNAME, new_ttl); + CHECK_RET(ret); + /* Put link to the RRset into the pkt. */ + ret = pkt_append(pkt, &ans.rrsets[AR_ANSWER], eh->rank); + CHECK_RET(ret); + const knot_dname_t *dname_target = + knot_dname_target(ans.rrsets[AR_ANSWER].set.rr->rrs.rdata); + + /* Generate CNAME RRset for the answer in (pseudo-)packet. */ + const int AR_CNAME = AR_SOA; + knot_rrset_t *rr = ans.rrsets[AR_CNAME].set.rr + = knot_rrset_new(qry->sname, KNOT_RRTYPE_CNAME, KNOT_CLASS_IN, + new_ttl, ans.mm); + CHECK_RET(rr ? kr_ok() : -ENOMEM); + const knot_dname_t *cname_target = knot_dname_replace_suffix(qry->sname, + knot_dname_labels(dname_owner, NULL), dname_target, ans.mm); + CHECK_RET(cname_target ? kr_ok() : -ENOMEM); + const int rdata_len = knot_dname_size(cname_target); + + if (rdata_len <= KNOT_DNAME_MAXLEN + && knot_dname_labels(cname_target, NULL) <= KNOT_DNAME_MAXLABELS) { + /* Normal case: the target name fits. */ + rr->rrs.count = 1; + rr->rrs.size = knot_rdata_size(rdata_len); + rr->rrs.rdata = mm_alloc(ans.mm, rr->rrs.size); + CHECK_RET(rr->rrs.rdata ? kr_ok() : -ENOMEM); + knot_rdata_init(rr->rrs.rdata, rdata_len, cname_target); + /* Put link to the RRset into the pkt. */ + ret = pkt_append(pkt, &ans.rrsets[AR_CNAME], eh->rank); + CHECK_RET(ret); + } else { + /* Note that it's basically a successful answer; name just doesn't fit. */ + knot_wire_set_rcode(pkt->wire, KNOT_RCODE_YXDOMAIN); + } + + answer_simple_qflags(&qry->flags, eh, new_ttl); + VERBOSE_MSG(qry, "=> satisfied by DNAME+CNAME: rank 0%.2o, new TTL %d\n", + eh->rank, new_ttl); + return kr_ok(); +} + +#undef CHECK_RET + +/** TODO: description; see the single call site for now. */ +static int found_exact_hit(kr_layer_t *ctx, knot_pkt_t *pkt, knot_db_val_t val, + uint8_t lowest_rank) +{ + struct kr_request *req = ctx->req; + struct kr_query *qry = req->current_query; + + int ret = entry_h_seek(&val, qry->stype); + if (ret) return ret; + const struct entry_h *eh = entry_h_consistent_E(val, qry->stype); + if (kr_fails_assert(eh)) + return kr_error(ENOENT); + // LATER: recovery in case of error, perhaps via removing the entry? + // LATER(optim): perhaps optimize the zone cut search + + int32_t new_ttl = get_new_ttl(eh, qry, qry->sname, qry->stype, + qry->timestamp.tv_sec); + if (new_ttl < 0 || eh->rank < lowest_rank) { + /* Positive record with stale TTL or bad rank. + * LATER(optim.): It's unlikely that we find a negative one, + * so we might theoretically skip all the cache code. */ + + VERBOSE_MSG(qry, "=> skipping exact %s: rank 0%.2o (min. 0%.2o), new TTL %d\n", + eh->is_packet ? "packet" : "RR", eh->rank, lowest_rank, new_ttl); + return kr_error(ENOENT); + } + + const uint8_t *eh_bound = knot_db_val_bound(val); + if (eh->is_packet) { + /* Note: we answer here immediately, even if it's (theoretically) + * possible that we could generate a higher-security negative proof. + * Rank is high-enough so we take it to save time searching; + * in practice this also helps in some incorrect zones (live-signed). */ + return answer_from_pkt (ctx, pkt, qry->stype, eh, eh_bound, new_ttl); + } else { + return answer_simple_hit(ctx, pkt, qry->stype, eh, eh_bound, new_ttl); + } +} + + +/** Try to satisfy via wildcard (positively). See the single call site. */ +static int try_wild(struct key *k, struct answer *ans, const knot_dname_t *clencl_name, + const uint16_t type, const uint8_t lowest_rank, + const struct kr_query *qry, struct kr_cache *cache) +{ + knot_db_val_t key = key_exact_type(k, type); + /* Find the record. */ + knot_db_val_t val = { NULL, 0 }; + int ret = cache_op(cache, read, &key, &val, 1); + if (!ret) { + ret = entry_h_seek(&val, type); + } + if (ret) { + if (kr_fails_assert(ret == kr_error(ENOENT))) + VERBOSE_MSG(qry, "=> wildcard: hit error %d %s\n", + ret, strerror(abs(ret))); + WITH_VERBOSE(qry) { + auto_free char *clencl_str = kr_dname_text(clencl_name), + *type_str = kr_rrtype_text(type); + VERBOSE_MSG(qry, "=> wildcard: not found: *.%s %s\n", + clencl_str, type_str); + } + return ret; + } + /* Check if the record is OK. */ + const struct entry_h *eh = entry_h_consistent_E(val, type); + if (kr_fails_assert(eh)) + return kr_error(ret); + // LATER: recovery in case of error, perhaps via removing the entry? + int32_t new_ttl = get_new_ttl(eh, qry, qry->sname, type, qry->timestamp.tv_sec); + /* ^^ here we use the *expanded* wildcard name */ + if (new_ttl < 0 || eh->rank < lowest_rank || eh->is_packet) { + /* Wildcard record with stale TTL, bad rank or packet. */ + VERBOSE_MSG(qry, "=> wildcard: skipping %s, rank 0%.2o, new TTL %d\n", + eh->is_packet ? "packet" : "RR", eh->rank, new_ttl); + return kr_error(ESTALE); + } + /* Add the RR into the answer. */ + ret = entry2answer(ans, AR_ANSWER, eh, knot_db_val_bound(val), + qry->sname, type, new_ttl); + VERBOSE_MSG(qry, "=> wildcard: answer expanded, ret = %d, new TTL %d\n", + ret, (int)new_ttl); + if (ret) return kr_error(ret); + ans->rcode = PKT_NOERROR; + return kr_ok(); +} + +int kr_cache_closest_apex(struct kr_cache *cache, const knot_dname_t *name, bool is_DS, + knot_dname_t ** apex) +{ + if (kr_fails_assert(cache && cache->db && name && apex && *apex == NULL)) + return kr_error(EINVAL); + struct key k_storage, *k = &k_storage; + int ret = kr_dname_lf(k->buf, name, false); + if (ret) + return kr_error(ret); + entry_list_t el_; + k->zname = name; + ret = closest_NS(cache, k, el_, NULL, true, is_DS); + if (ret && ret != -abs(ENOENT)) + return ret; + *apex = knot_dname_copy(k->zname, NULL); + if (!*apex) + return kr_error(ENOMEM); + return kr_ok(); +} + +/** \internal for closest_NS. Check suitability of a single entry, setting k->type if OK. + * \return error code, negative iff whole list should be skipped. + */ +static int check_NS_entry(struct key *k, knot_db_val_t entry, int i, + bool exact_match, bool is_DS, + const struct kr_query *qry, uint32_t timestamp); + +/** + * Find the longest prefix zone/xNAME (with OK time+rank), starting at k->*. + * + * The found type is returned via k->type; the values are returned in el. + * \note we use k->type = KNOT_RRTYPE_NS also for the nsec_p result. + * \param qry can be NULL (-> gettimeofday(), but you lose the stale-serve hook) + * \param only_NS don't consider xNAMEs + * \return error code + */ +static int closest_NS(struct kr_cache *cache, struct key *k, entry_list_t el, + struct kr_query *qry, const bool only_NS, const bool is_DS) +{ + /* get the current timestamp */ + uint32_t timestamp; + if (qry) { + timestamp = qry->timestamp.tv_sec; + } else { + struct timeval tv; + if (gettimeofday(&tv, NULL)) return kr_error(errno); + timestamp = tv.tv_sec; + } + + int zlf_len = k->buf[0]; + + // LATER(optim): if stype is NS, we check the same value again + bool exact_match = true; + bool need_zero = true; + /* Inspect the NS/xNAME entries, shortening by a label on each iteration. */ + do { + k->buf[0] = zlf_len; + knot_db_val_t key = key_exact_type(k, KNOT_RRTYPE_NS); + knot_db_val_t val; + int ret = cache_op(cache, read, &key, &val, 1); + if (ret == kr_error(ENOENT)) goto next_label; + if (kr_fails_assert(ret == 0)) { + if (need_zero) memset(el, 0, sizeof(entry_list_t)); + return kr_error(ret); + } + + /* Check consistency, find any type; + * using `goto` for shortening by another label. */ + ret = entry_list_parse(val, el); + if (kr_fails_assert(ret == 0)) // do something about it? + goto next_label; + need_zero = false; + /* More types are possible; try in order. + * For non-fatal failures just "continue;" to try the next type. */ + /* Now a complication - we need to try EL_DNAME before NSEC* + * (Unfortunately that's not easy to write very nicely.) */ + if (!only_NS) { + const int i = EL_DNAME; + ret = check_NS_entry(k, el[i], i, exact_match, is_DS, + qry, timestamp); + if (ret < 0) goto next_label; else + if (!ret) { + /* We found our match. */ + k->zlf_len = zlf_len; + return kr_ok(); + } + } + const int el_count = only_NS ? EL_NS + 1 : EL_LENGTH; + for (int i = 0; i < el_count; ++i) { + if (i == EL_DNAME) continue; + ret = check_NS_entry(k, el[i], i, exact_match, is_DS, + qry, timestamp); + if (ret < 0) goto next_label; else + if (!ret) { + /* We found our match. */ + k->zlf_len = zlf_len; + return kr_ok(); + } + } + + next_label: + /* remove one more label */ + exact_match = false; + if (k->zname[0] == 0) { + /* We miss root NS in cache, but let's at least assume it exists. */ + k->type = KNOT_RRTYPE_NS; + k->zlf_len = zlf_len; + kr_assert(zlf_len == 0); + if (need_zero) memset(el, 0, sizeof(entry_list_t)); + return kr_error(ENOENT); + } + zlf_len -= (k->zname[0] + 1); + k->zname += (k->zname[0] + 1); + k->buf[zlf_len + 1] = 0; + } while (true); +} + +static int check_NS_entry(struct key *k, const knot_db_val_t entry, const int i, + const bool exact_match, const bool is_DS, + const struct kr_query *qry, uint32_t timestamp) +{ + const int ESKIP = ABS(ENOENT); + if (!entry.len + /* On a zone cut we want DS from the parent zone. */ + || (exact_match && is_DS) + /* CNAME is interesting only if we + * directly hit the name that was asked. + * Note that we want it even in the DS case. */ + || (i == EL_CNAME && !exact_match) + /* DNAME is interesting only if we did NOT + * directly hit the name that was asked. */ + || (i == EL_DNAME && exact_match) + ) { + return ESKIP; + } + + uint16_t type; + if (i < ENTRY_APEX_NSECS_CNT) { + type = KNOT_RRTYPE_NS; + int32_t log_new_ttl = -123456789; /* visually recognizable value */ + const int err = nsec_p_ttl(entry, timestamp, &log_new_ttl); + if (err) { + VERBOSE_MSG(qry, + "=> skipping unfit nsec_p: new TTL %d, error %d\n", + (int)log_new_ttl, err); + return ESKIP; + } + } else { + type = EL2RRTYPE(i); + /* Find the entry for the type, check positivity, TTL */ + const struct entry_h *eh = entry_h_consistent_E(entry, type); + if (kr_fails_assert(eh)) { + VERBOSE_MSG(qry, "=> EH not consistent\n"); + return kr_error(EILSEQ); + } + const int32_t log_new_ttl = get_new_ttl(eh, qry, k->zname, type, timestamp); + + const bool ok = /* Not interested in negative bogus or outdated RRs. */ + !eh->is_packet && log_new_ttl >= 0 + /* For NS any kr_rank is accepted, as insecure or even nonauth is OK */ + && (type == KNOT_RRTYPE_NS + || eh->rank >= get_lowest_rank(qry, k->zname, type)); + + WITH_VERBOSE(qry) { if (!ok) { + auto_free char *type_str = kr_rrtype_text(type); + const char *packet_str = eh->is_packet ? "packet" : "RR"; + VERBOSE_MSG(qry, + "=> skipping unfit %s %s: rank 0%.2o, new TTL %d\n", + type_str, packet_str, eh->rank, (int)log_new_ttl); + } } + if (!ok) return ESKIP; + } + k->type = type; + return kr_ok(); +} + diff --git a/lib/cache/test.integr/cache_minimal_nsec3.rpl b/lib/cache/test.integr/cache_minimal_nsec3.rpl new file mode 100644 index 0000000..7c4a5cf --- /dev/null +++ b/lib/cache/test.integr/cache_minimal_nsec3.rpl @@ -0,0 +1,4120 @@ +; SPDX-License-Identifier: GPL-3.0-or-later + trust-anchor: ". IN DS 20326 8 2 E06D44B80B8F1D39A95C0B0D7C65D08458E880409BBC683457104237C7F8EC8D" + val-override-date: 20190625160934 + stub-addr: 2001:503:ba3e::2:30 +CONFIG_END + +SCENARIO_BEGIN Test that minimal NSEC3 range does not trigger agressive cache (workaround for buggy auths, optimization to improve cache hit rate on correct auths using black lies) + +; Group's zones: +; . +; root-servers.net. +; Server names: +; f.root-servers.net. +; a.root-servers.net. +; j.root-servers.net. +; e.root-servers.net. +; i.root-servers.net. +; d.root-servers.net. +; m.root-servers.net. +; h.root-servers.net. +; c.root-servers.net. +; l.root-servers.net. +; g.root-servers.net. +; b.root-servers.net. +; k.root-servers.net. +RANGE_BEGIN 0 1000 + ADDRESS 2001:500:2f::f + ADDRESS 2001:503:ba3e::2:30 + ADDRESS 2001:500:12::d0d + ADDRESS 202.12.27.33 + ADDRESS 2001:7fd::1 + ADDRESS 2001:503:c27::2:30 + ADDRESS 2001:500:200::b + ADDRESS 198.97.190.53 + ADDRESS 192.58.128.30 + ADDRESS 198.41.0.4 + ADDRESS 199.7.91.13 + ADDRESS 2001:dc3::35 + ADDRESS 192.36.148.17 + ADDRESS 192.203.230.10 + ADDRESS 192.5.5.241 + ADDRESS 199.9.14.201 + ADDRESS 193.0.14.129 + ADDRESS 2001:7fe::53 + ADDRESS 2001:500:9f::42 + ADDRESS 2001:500:a8::e + ADDRESS 2001:500:2d::d + ADDRESS 192.112.36.4 + ADDRESS 2001:500:2::c + ADDRESS 192.33.4.12 + ADDRESS 199.7.83.42 + ADDRESS 2001:500:1::53 + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +i.root-servers.net. IN AAAA +SECTION ANSWER +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +g.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +e.root-servers.net. IN A +SECTION ANSWER +e.root-servers.net. 3600000 IN A 192.203.230.10 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +i.root-servers.net. IN A +SECTION ANSWER +i.root-servers.net. 3600000 IN A 192.36.148.17 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +root-servers.net. IN DS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.root-servers.net. IN A +SECTION ANSWER +c.root-servers.net. 3600000 IN A 192.33.4.12 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.root-servers.net. IN A +SECTION ANSWER +d.root-servers.net. 3600000 IN A 199.7.91.13 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.root-servers.net. IN AAAA +SECTION ANSWER +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. 518400 IN NS a.root-servers.net. +. 518400 IN NS b.root-servers.net. +. 518400 IN NS c.root-servers.net. +. 518400 IN NS d.root-servers.net. +. 518400 IN NS e.root-servers.net. +. 518400 IN NS f.root-servers.net. +. 518400 IN NS g.root-servers.net. +. 518400 IN NS h.root-servers.net. +. 518400 IN NS i.root-servers.net. +. 518400 IN NS j.root-servers.net. +. 518400 IN NS k.root-servers.net. +. 518400 IN NS l.root-servers.net. +. 518400 IN NS m.root-servers.net. +. 518400 IN RRSIG NS 8 0 518400 20190708050000 20190625040000 25266 . IwbmJVqFUjJz5WwRbYqOWejRck85QWW8 eIGID2J+Qhw89iUDDz2lgvysed4WQfks 8Y2XZu79T0+RJF+mj1UUiE+Y6RdOmFDU Qx3ovGkYwOXcr1anreBD+Wn5tv1WW6El NbKf40pXdtDX6Ad1qx6hCHHR4hieQPww psNHmrGDg+Eog+VqYjwwRj9EaYEms5dU PRJmiHiACe85DZMCjxl6f+kp7ZXyFD/L coLi7QzXiRWYOPHhWKk3pqYGD1j7I7YB Oq7UujK+jPscWCDuArGmZwlhAtAPaPLe 5TZHIGE39c6eYpuXwSXZ1EPM545/9WsI HihzUQ75ltuiPXwjv0OpQg== +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +j.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.root-servers.net. IN A +SECTION ANSWER +a.root-servers.net. 3600000 IN A 198.41.0.4 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +h.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +g.root-servers.net. IN A +SECTION ANSWER +g.root-servers.net. 3600000 IN A 192.112.36.4 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +k.root-servers.net. IN A +SECTION ANSWER +k.root-servers.net. 3600000 IN A 193.0.14.129 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +m.root-servers.net. IN AAAA +SECTION ANSWER +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +. IN DNSKEY +SECTION ANSWER +. 172800 IN DNSKEY 256 3 8 AwEAAcTQyaIe6nt3xSPOG2L/YfwBkOVT JN6mlnZ249O5Rtt3ZSRQHxQSW61AODYw 6bvgxrrGq8eeOuenFjcSYgNAMcBYoEYY mKDW6e9EryW4ZaT/MCq+8Am06oR40xAA 3fClOM6QjRcT85tP41Go946AicBGP8XO P/Aj1aI/oPRGzRnboUPUok/AzTNnW5np BU69+BuiIwYE7mQOiNBFePyvjQBdoiuY bmuD3Py0IyjlBxzZUXbqLsRL9gYFkCqe TY29Ik7usuzMTa+JRSLz6KGS5RSJ7CTS MjZg8aNaUbN2dvGhakJPh92HnLvMA3Te fFgbKJphFNPA3BWSKLZ02cRWXqM= +. 172800 IN DNSKEY 256 3 8 AwEAAeVDC34GZILwsQJy97K2Fst4P3XY ZrXLyrkausYzSqEjSUulgh+iLgHg0y7F IF890+sIjXsk7KLJUmCOWfYWPorNKEOK Lk5Zx/4M6D3IHZE3O3m/Eahrc28qQzmT LxiMZAW65MvR2UO3LxVtYOPBEBiDgAQD 47x2JLsJYtavCzNL5WiUk59OgvHmDqmc C7VXYBhK8V8Tic089XJgExGeplKWUt9y yc31ra1swJX51XsOaQz17+vyLVH8AZP2 6KvKFiZeoRbaq6vl+hc8HQnI2ug5rA2z oz3MsSQBvP1f/HvqsWxLqwXXKyDD1QM6 39U+XzVB8CYigyscRP22QCnwKIU= +. 172800 IN DNSKEY 257 3 8 AwEAAaz/tAm8yTn4Mfeh5eyI96WSVexT BAvkMgJzkKTOiW1vkIbzxeF3+/4RgWOq 7HrxRixHlFlExOLAJr5emLvN7SWXgnLh 4+B5xQlNVz8Og8kvArMtNROxVQuCaSnI DdD5LKyWbRd2n9WGe2R8PzgCmr3EgVLr jyBxWezF0jLHwVN8efS3rCj/EWgvIWgb 9tarpVUDK/b58Da+sqqls3eNbuv7pr+e oZG+SrDK6nWeL3c6H5Apxz7LjVc1uTId sIXxuOLYA4/ilBmSVIzuDWfdRUfhHdY6 +cn8HFRm+2hM8AnXGXws9555KrUB5qih ylGa8subX2Nn6UwNR1AkUTV74bU= +. 172800 IN RRSIG DNSKEY 8 0 172800 20190711000000 20190620000000 20326 . LeNUOIxGGe+xAKxr13YIXNqMAxVH7RuD XQyVclUuxA9aENp0+yYkeIL+/lkTteEh dHXNVZqYch8QrvcsuCpDN2gKx5D5M04g KAjR5ywgvEdsZHr9DhjCZ3uvXKvbPsi6 14QpjYCxxvtq/ZZE6dhm59K3N3T8Mhm5 l36b6w+fR1F3Kc+eeJqy2ZjVxNe9CClE 4Qy6q78Yu6rS1vZkuzG1l2AT9Gko72St WbdsU2Ry9fBk+uCJOLxej37z5Rfi5EAz FcnfwQYryqCRt2go9PuD0/AulqG8wmTV z23tnwnaxowkYKxFH2yE0d7pDiFjvOyU HdGPXYwl/+GDmjrQsN6JPQ== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +k.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +. IN DS +SECTION AUTHORITY +. 86400 IN NSEC aaa. NS SOA RRSIG NSEC DNSKEY +. 86400 IN RRSIG NSEC 8 0 86400 20190708050000 20190625040000 25266 . fAYegvNXOW8j+x++y5EWtNQlie56/WO+ w6PlDWJ87oZPgUJuYPxqCIpoKJttfUBR o1nOzZaUlxQeOE0Daep/fnlo8OtAfauK w5J+l5rZqcaM6C9MA7cB7ZswPVd1p609 rPqgGoxSvuNuX/iFPBqPQhRw5JyiVuwF Q4PSB3Etq85BXUEhlpfcQAt6z3scHlLa ARoZoea3/u9z/xuB+296IgZHOQkp3WJL zJivnrQFisO7vQ7o01t0x6WxtskBwbf3 GXwHg/2DbHY/7QJ4hVWO0/L+tdeJciTM 92+RC/U7GkUPDb0rvfOfntB2MKz0rZhU g5m+qJOJYpG8HGN69f4dyQ== +. 86400 IN RRSIG SOA 8 0 86400 20190708050000 20190625040000 25266 . kYJsFlFDsY3FO94BM5DRROo34/8EZODz iOXejYh397rIJqr5bjx315WJabGoAf3p gtQ5U6QXDJnrKnuZYK/4b+mYyef722if vfNdKclJxKp5vwdDGKLEu7Z2Ey09K4WD MPeyemaIIlbDw3F7lYzz0ZiZubagtrZu OeD2CUOJO4qauzUpGtXf4cx0r+aQJkPq 4eXQyBQ4gg6Mdh4iBNgjGhYB9SLFNMtb eRMNpJG2ifhjP+pNWd27+TGHOhHTu082 osz2lNYKibuMoEfQeHNlINGIU+8oTa/K 3O7IlOAp1APvDmbKnLgy9FFf+6yCMo5y r+A0RVMZheQA3iEXBGug+g== +. 86400 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019062500 1800 900 604800 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.root-servers.net. IN AAAA +SECTION ANSWER +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +l.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.root-servers.net. IN A +SECTION ANSWER +b.root-servers.net. 3600000 IN A 199.9.14.201 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +m.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR RD NOERROR +SECTION QUESTION +csas.cz. IN DS +SECTION AUTHORITY +cz. 172800 IN NS a.ns.nic.cz. +cz. 172800 IN NS b.ns.nic.cz. +cz. 172800 IN NS c.ns.nic.cz. +cz. 172800 IN NS d.ns.nic.cz. +cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2 +cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw== +SECTION ADDITIONAL +a.ns.nic.cz. 172800 IN A 194.0.12.1 +a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1 +b.ns.nic.cz. 172800 IN A 194.0.13.1 +b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1 +c.ns.nic.cz. 172800 IN A 194.0.14.1 +c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1 +d.ns.nic.cz. 172800 IN A 193.29.206.1 +d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +g.root-servers.net. IN AAAA +SECTION ANSWER +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +cz. IN DS +SECTION ANSWER +cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2 +cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +j.root-servers.net. IN AAAA +SECTION ANSWER +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.root-servers.net. IN AAAA +SECTION ANSWER +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +l.root-servers.net. IN AAAA +SECTION ANSWER +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.root-servers.net. IN AAAA +SECTION ANSWER +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +e.root-servers.net. IN AAAA +SECTION ANSWER +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +j.root-servers.net. IN A +SECTION ANSWER +j.root-servers.net. 3600000 IN A 192.58.128.30 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +i.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +k.root-servers.net. IN AAAA +SECTION ANSWER +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +net. IN DS +SECTION ANSWER +net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee +net. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . EK4wI33V5RQyA5SAxBfX1oTiDeGfOzXr u0OA6KaXALQOMELkugzUD3NipvVpzO7B 0ZYSsnNn+Kk1h0qJBE/ZWpHHZyvZCg1o zo+kq1Z7gGJvlV4Y9XfuwIGPZKL0tlkm LBVSBd36yQy/x4gFyBKvRgIDd1IyKrjT xJYENyNwvtj3MkrT+Njsg1NWXP5ORRx1 r0zVlq2snbJsp8ze+sLYrSqVXbihg4mq JoMe7NB4M9EYEMfBOUcWo8Wrj73jiYRx 0uJ3HfvOHBqBgVFyhMcr4FeCiN9F9V6C xTQBQnL3lQF1TnOhN//Z7h7TvLulxHRu DeKEsZDcoC4el8u1Fx7t/w== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.root-servers.net. IN A +SECTION ANSWER +f.root-servers.net. 3600000 IN A 192.5.5.241 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.root-servers.net. IN A +SECTION ANSWER +f.root-servers.net. 3600000 IN A 192.5.5.241 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.root-servers.net. IN AAAA +SECTION ANSWER +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +h.root-servers.net. IN AAAA +SECTION ANSWER +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +e.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.root-servers.net. IN AAAA +SECTION ANSWER +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR RD NOERROR +SECTION QUESTION +gtld-servers.net. IN DS +SECTION AUTHORITY +net. 172800 IN NS a.gtld-servers.net. +net. 172800 IN NS b.gtld-servers.net. +net. 172800 IN NS c.gtld-servers.net. +net. 172800 IN NS d.gtld-servers.net. +net. 172800 IN NS e.gtld-servers.net. +net. 172800 IN NS f.gtld-servers.net. +net. 172800 IN NS g.gtld-servers.net. +net. 172800 IN NS h.gtld-servers.net. +net. 172800 IN NS i.gtld-servers.net. +net. 172800 IN NS j.gtld-servers.net. +net. 172800 IN NS k.gtld-servers.net. +net. 172800 IN NS l.gtld-servers.net. +net. 172800 IN NS m.gtld-servers.net. +net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee +net. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . EK4wI33V5RQyA5SAxBfX1oTiDeGfOzXr u0OA6KaXALQOMELkugzUD3NipvVpzO7B 0ZYSsnNn+Kk1h0qJBE/ZWpHHZyvZCg1o zo+kq1Z7gGJvlV4Y9XfuwIGPZKL0tlkm LBVSBd36yQy/x4gFyBKvRgIDd1IyKrjT xJYENyNwvtj3MkrT+Njsg1NWXP5ORRx1 r0zVlq2snbJsp8ze+sLYrSqVXbihg4mq JoMe7NB4M9EYEMfBOUcWo8Wrj73jiYRx 0uJ3HfvOHBqBgVFyhMcr4FeCiN9F9V6C xTQBQnL3lQF1TnOhN//Z7h7TvLulxHRu DeKEsZDcoC4el8u1Fx7t/w== +SECTION ADDITIONAL +a.gtld-servers.net. 172800 IN A 192.5.6.30 +a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 +b.gtld-servers.net. 172800 IN A 192.33.14.30 +b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 +c.gtld-servers.net. 172800 IN A 192.26.92.30 +c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30 +d.gtld-servers.net. 172800 IN A 192.31.80.30 +d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30 +e.gtld-servers.net. 172800 IN A 192.12.94.30 +e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30 +f.gtld-servers.net. 172800 IN A 192.35.51.30 +f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30 +g.gtld-servers.net. 172800 IN A 192.42.93.30 +g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30 +h.gtld-servers.net. 172800 IN A 192.54.112.30 +h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30 +i.gtld-servers.net. 172800 IN A 192.43.172.30 +i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30 +j.gtld-servers.net. 172800 IN A 192.48.79.30 +j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30 +k.gtld-servers.net. 172800 IN A 192.52.178.30 +k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30 +l.gtld-servers.net. 172800 IN A 192.41.162.30 +l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30 +m.gtld-servers.net. 172800 IN A 192.55.83.30 +m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR RD NOERROR +SECTION QUESTION +nstld.com. IN DS +SECTION AUTHORITY +com. 172800 IN NS a.gtld-servers.net. +com. 172800 IN NS b.gtld-servers.net. +com. 172800 IN NS c.gtld-servers.net. +com. 172800 IN NS d.gtld-servers.net. +com. 172800 IN NS e.gtld-servers.net. +com. 172800 IN NS f.gtld-servers.net. +com. 172800 IN NS g.gtld-servers.net. +com. 172800 IN NS h.gtld-servers.net. +com. 172800 IN NS i.gtld-servers.net. +com. 172800 IN NS j.gtld-servers.net. +com. 172800 IN NS k.gtld-servers.net. +com. 172800 IN NS l.gtld-servers.net. +com. 172800 IN NS m.gtld-servers.net. +com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766 +com. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . h8CYVMqouUO2IAPlG4Iqf06ykpl07wny KuM2dRGhrfx5hQbF0CpzGRwT2B6i2drI td9i7BSA4GVKLlTYr9n3Xd+BcAHKwywv 44A2WmTAo3xWMv4THwowwu29B4bAKe0V WQKDfmZ92m1yn8T3MCNZWtuGGaLcY6+g fKgyuHu5fEakVn2GFMdAMayBBFTF0bp4 hVFuNSJBe/1EnFZMcxU9aNuCyC8xup25 7K3x1rcM0hthHr8o0Vevpima1YXsWDGb RDIkDyStPDIQ1c0C9LHMaaGR+MA+fxoL 2x4w2lwOptCK//zpfyPvj11oIyouwgdh Fe3PCf9hS03Y1FsiY+mtWw== +SECTION ADDITIONAL +a.gtld-servers.net. 172800 IN A 192.5.6.30 +a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 +b.gtld-servers.net. 172800 IN A 192.33.14.30 +b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 +c.gtld-servers.net. 172800 IN A 192.26.92.30 +c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30 +d.gtld-servers.net. 172800 IN A 192.31.80.30 +d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30 +e.gtld-servers.net. 172800 IN A 192.12.94.30 +e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30 +f.gtld-servers.net. 172800 IN A 192.35.51.30 +f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30 +g.gtld-servers.net. 172800 IN A 192.42.93.30 +g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30 +h.gtld-servers.net. 172800 IN A 192.54.112.30 +h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30 +i.gtld-servers.net. 172800 IN A 192.43.172.30 +i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30 +j.gtld-servers.net. 172800 IN A 192.48.79.30 +j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30 +k.gtld-servers.net. 172800 IN A 192.52.178.30 +k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30 +l.gtld-servers.net. 172800 IN A 192.41.162.30 +l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30 +m.gtld-servers.net. 172800 IN A 192.55.83.30 +m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +m.root-servers.net. IN A +SECTION ANSWER +m.root-servers.net. 3600000 IN A 202.12.27.33 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +h.root-servers.net. IN A +SECTION ANSWER +h.root-servers.net. 3600000 IN A 198.97.190.53 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +com. IN DS +SECTION ANSWER +com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766 +com. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . h8CYVMqouUO2IAPlG4Iqf06ykpl07wny KuM2dRGhrfx5hQbF0CpzGRwT2B6i2drI td9i7BSA4GVKLlTYr9n3Xd+BcAHKwywv 44A2WmTAo3xWMv4THwowwu29B4bAKe0V WQKDfmZ92m1yn8T3MCNZWtuGGaLcY6+g fKgyuHu5fEakVn2GFMdAMayBBFTF0bp4 hVFuNSJBe/1EnFZMcxU9aNuCyC8xup25 7K3x1rcM0hthHr8o0Vevpima1YXsWDGb RDIkDyStPDIQ1c0C9LHMaaGR+MA+fxoL 2x4w2lwOptCK//zpfyPvj11oIyouwgdh Fe3PCf9hS03Y1FsiY+mtWw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR RD NOERROR +SECTION QUESTION +nic.cz. IN DS +SECTION AUTHORITY +cz. 172800 IN NS a.ns.nic.cz. +cz. 172800 IN NS b.ns.nic.cz. +cz. 172800 IN NS c.ns.nic.cz. +cz. 172800 IN NS d.ns.nic.cz. +cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2 +cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw== +SECTION ADDITIONAL +a.ns.nic.cz. 172800 IN A 194.0.12.1 +a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1 +b.ns.nic.cz. 172800 IN A 194.0.13.1 +b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1 +c.ns.nic.cz. 172800 IN A 194.0.14.1 +c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1 +d.ns.nic.cz. 172800 IN A 193.29.206.1 +d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +l.root-servers.net. IN A +SECTION ANSWER +l.root-servers.net. 3600000 IN A 199.7.83.42 +SECTION AUTHORITY +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.root-servers.net. IN NS +SECTION AUTHORITY +root-servers.net. 3600000 IN SOA a.root-servers.net. nstld.verisign-grs.com. 2019061700 14400 7200 1209600 3600000 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +root-servers.net. IN NS +SECTION ANSWER +root-servers.net. 3600000 IN NS a.root-servers.net. +root-servers.net. 3600000 IN NS b.root-servers.net. +root-servers.net. 3600000 IN NS c.root-servers.net. +root-servers.net. 3600000 IN NS d.root-servers.net. +root-servers.net. 3600000 IN NS e.root-servers.net. +root-servers.net. 3600000 IN NS f.root-servers.net. +root-servers.net. 3600000 IN NS g.root-servers.net. +root-servers.net. 3600000 IN NS h.root-servers.net. +root-servers.net. 3600000 IN NS i.root-servers.net. +root-servers.net. 3600000 IN NS j.root-servers.net. +root-servers.net. 3600000 IN NS k.root-servers.net. +root-servers.net. 3600000 IN NS l.root-servers.net. +root-servers.net. 3600000 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 3600000 IN A 198.41.0.4 +a.root-servers.net. 3600000 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 3600000 IN A 199.9.14.201 +b.root-servers.net. 3600000 IN AAAA 2001:500:200::b +c.root-servers.net. 3600000 IN A 192.33.4.12 +c.root-servers.net. 3600000 IN AAAA 2001:500:2::c +d.root-servers.net. 3600000 IN A 199.7.91.13 +d.root-servers.net. 3600000 IN AAAA 2001:500:2d::d +e.root-servers.net. 3600000 IN A 192.203.230.10 +e.root-servers.net. 3600000 IN AAAA 2001:500:a8::e +f.root-servers.net. 3600000 IN A 192.5.5.241 +f.root-servers.net. 3600000 IN AAAA 2001:500:2f::f +g.root-servers.net. 3600000 IN A 192.112.36.4 +g.root-servers.net. 3600000 IN AAAA 2001:500:12::d0d +h.root-servers.net. 3600000 IN A 198.97.190.53 +h.root-servers.net. 3600000 IN AAAA 2001:500:1::53 +i.root-servers.net. 3600000 IN A 192.36.148.17 +i.root-servers.net. 3600000 IN AAAA 2001:7fe::53 +j.root-servers.net. 3600000 IN A 192.58.128.30 +j.root-servers.net. 3600000 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 3600000 IN A 193.0.14.129 +k.root-servers.net. 3600000 IN AAAA 2001:7fd::1 +l.root-servers.net. 3600000 IN A 199.7.83.42 +l.root-servers.net. 3600000 IN AAAA 2001:500:9f::42 +m.root-servers.net. 3600000 IN A 202.12.27.33 +m.root-servers.net. 3600000 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR RD NOERROR +SECTION QUESTION +cz. IN NS +SECTION AUTHORITY +cz. 172800 IN NS a.ns.nic.cz. +cz. 172800 IN NS b.ns.nic.cz. +cz. 172800 IN NS c.ns.nic.cz. +cz. 172800 IN NS d.ns.nic.cz. +cz. 86400 IN DS 20237 13 2 cff0f3ecdbc529c1f0031ba1840bfb835853b9209ed1e508fff48451d7b778e2 +cz. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . r7Lxqu4C80oW46tP7BNfJWrXs2K5YEqn IkEKfzXSFqur0cSfnj630EPQfokTYO2Q RCOT/JaNpbUi69MS+d81xFZb5efzzoYE tL3tCE8axm39kzuHKhk2EOSIN8sQPCTC isLppgCbLRPbzKima8Jk5kGs7pV+FK9K vCExdukQ4aB7MYvIZaKzHKP8NAOgKdVk x/BrrGl8IV0T+YvUDo9e8gpdcbhLFXoN w+qZ9xVNIvhSsjzzL1fxrkjJIEdTPzrS HXdUjK8v56KppQJ0pr+XSq2CicRbcn5b ur5HQz4yKfIr2q7aH9CMGuwbMLNDWnjO G+iHdA/ekKLYQ5afWOxaqw== +SECTION ADDITIONAL +a.ns.nic.cz. 172800 IN A 194.0.12.1 +a.ns.nic.cz. 172800 IN AAAA 2001:678:f::1 +b.ns.nic.cz. 172800 IN A 194.0.13.1 +b.ns.nic.cz. 172800 IN AAAA 2001:678:10::1 +c.ns.nic.cz. 172800 IN A 194.0.14.1 +c.ns.nic.cz. 172800 IN AAAA 2001:678:11::1 +d.ns.nic.cz. 172800 IN A 193.29.206.1 +d.ns.nic.cz. 172800 IN AAAA 2001:678:1::1 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR RD NOERROR +SECTION QUESTION +net. IN NS +SECTION AUTHORITY +net. 172800 IN NS a.gtld-servers.net. +net. 172800 IN NS b.gtld-servers.net. +net. 172800 IN NS c.gtld-servers.net. +net. 172800 IN NS d.gtld-servers.net. +net. 172800 IN NS e.gtld-servers.net. +net. 172800 IN NS f.gtld-servers.net. +net. 172800 IN NS g.gtld-servers.net. +net. 172800 IN NS h.gtld-servers.net. +net. 172800 IN NS i.gtld-servers.net. +net. 172800 IN NS j.gtld-servers.net. +net. 172800 IN NS k.gtld-servers.net. +net. 172800 IN NS l.gtld-servers.net. +net. 172800 IN NS m.gtld-servers.net. +net. 86400 IN DS 35886 8 2 7862b27f5f516ebe19680444d4ce5e762981931842c465f00236401d8bd973ee +net. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . EK4wI33V5RQyA5SAxBfX1oTiDeGfOzXr u0OA6KaXALQOMELkugzUD3NipvVpzO7B 0ZYSsnNn+Kk1h0qJBE/ZWpHHZyvZCg1o zo+kq1Z7gGJvlV4Y9XfuwIGPZKL0tlkm LBVSBd36yQy/x4gFyBKvRgIDd1IyKrjT xJYENyNwvtj3MkrT+Njsg1NWXP5ORRx1 r0zVlq2snbJsp8ze+sLYrSqVXbihg4mq JoMe7NB4M9EYEMfBOUcWo8Wrj73jiYRx 0uJ3HfvOHBqBgVFyhMcr4FeCiN9F9V6C xTQBQnL3lQF1TnOhN//Z7h7TvLulxHRu DeKEsZDcoC4el8u1Fx7t/w== +SECTION ADDITIONAL +a.gtld-servers.net. 172800 IN A 192.5.6.30 +a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 +b.gtld-servers.net. 172800 IN A 192.33.14.30 +b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 +c.gtld-servers.net. 172800 IN A 192.26.92.30 +c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30 +d.gtld-servers.net. 172800 IN A 192.31.80.30 +d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30 +e.gtld-servers.net. 172800 IN A 192.12.94.30 +e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30 +f.gtld-servers.net. 172800 IN A 192.35.51.30 +f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30 +g.gtld-servers.net. 172800 IN A 192.42.93.30 +g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30 +h.gtld-servers.net. 172800 IN A 192.54.112.30 +h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30 +i.gtld-servers.net. 172800 IN A 192.43.172.30 +i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30 +j.gtld-servers.net. 172800 IN A 192.48.79.30 +j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30 +k.gtld-servers.net. 172800 IN A 192.52.178.30 +k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30 +l.gtld-servers.net. 172800 IN A 192.41.162.30 +l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30 +m.gtld-servers.net. 172800 IN A 192.55.83.30 +m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR RD NOERROR +SECTION QUESTION +com. IN NS +SECTION AUTHORITY +com. 172800 IN NS a.gtld-servers.net. +com. 172800 IN NS b.gtld-servers.net. +com. 172800 IN NS c.gtld-servers.net. +com. 172800 IN NS d.gtld-servers.net. +com. 172800 IN NS e.gtld-servers.net. +com. 172800 IN NS f.gtld-servers.net. +com. 172800 IN NS g.gtld-servers.net. +com. 172800 IN NS h.gtld-servers.net. +com. 172800 IN NS i.gtld-servers.net. +com. 172800 IN NS j.gtld-servers.net. +com. 172800 IN NS k.gtld-servers.net. +com. 172800 IN NS l.gtld-servers.net. +com. 172800 IN NS m.gtld-servers.net. +com. 86400 IN DS 30909 8 2 e2d3c916f6deeac73294e8268fb5885044a833fc5459588f4a9184cfc41a5766 +com. 86400 IN RRSIG DS 8 1 86400 20190708050000 20190625040000 25266 . h8CYVMqouUO2IAPlG4Iqf06ykpl07wny KuM2dRGhrfx5hQbF0CpzGRwT2B6i2drI td9i7BSA4GVKLlTYr9n3Xd+BcAHKwywv 44A2WmTAo3xWMv4THwowwu29B4bAKe0V WQKDfmZ92m1yn8T3MCNZWtuGGaLcY6+g fKgyuHu5fEakVn2GFMdAMayBBFTF0bp4 hVFuNSJBe/1EnFZMcxU9aNuCyC8xup25 7K3x1rcM0hthHr8o0Vevpima1YXsWDGb RDIkDyStPDIQ1c0C9LHMaaGR+MA+fxoL 2x4w2lwOptCK//zpfyPvj11oIyouwgdh Fe3PCf9hS03Y1FsiY+mtWw== +SECTION ADDITIONAL +a.gtld-servers.net. 172800 IN A 192.5.6.30 +a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 +b.gtld-servers.net. 172800 IN A 192.33.14.30 +b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 +c.gtld-servers.net. 172800 IN A 192.26.92.30 +c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30 +d.gtld-servers.net. 172800 IN A 192.31.80.30 +d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30 +e.gtld-servers.net. 172800 IN A 192.12.94.30 +e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30 +f.gtld-servers.net. 172800 IN A 192.35.51.30 +f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30 +g.gtld-servers.net. 172800 IN A 192.42.93.30 +g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30 +h.gtld-servers.net. 172800 IN A 192.54.112.30 +h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30 +i.gtld-servers.net. 172800 IN A 192.43.172.30 +i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30 +j.gtld-servers.net. 172800 IN A 192.48.79.30 +j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30 +k.gtld-servers.net. 172800 IN A 192.52.178.30 +k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30 +l.gtld-servers.net. 172800 IN A 192.41.162.30 +l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30 +m.gtld-servers.net. 172800 IN A 192.55.83.30 +m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30 +ENTRY_END + + + + +RANGE_END + + + +; Group's zones: +; cz. +; nic.cz. +; Server names: +; a.ns.nic.cz. +; b.ns.nic.cz. +; c.ns.nic.cz. +; d.ns.nic.cz. +RANGE_BEGIN 0 1000 + ADDRESS 194.0.14.1 + ADDRESS 194.0.13.1 + ADDRESS 193.29.206.1 + ADDRESS 2001:678:1::1 + ADDRESS 2001:678:11::1 + ADDRESS 2001:678:10::1 + ADDRESS 2001:678:f::1 + ADDRESS 194.0.12.1 + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ns.nic.cz. IN NS +SECTION AUTHORITY +jnp2uc34hha9de64l3rjf6ulp4pra74n.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 jsdlj2k5hipr7eb12ne8bads7lshvo1k +jnp2uc34hha9de64l3rjf6ulp4pra74n.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707164247 20190624124001 10486 nic.cz. lrFJPPGpHyoC5l4uM8l94ye/HG1kTVw7 dR98um06iG+2XK82Dib+wnzqoNNIqbaA FeaAkjfqgCHA8kDySAP+5g== +nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw== +nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.ns.nic.cz. IN A +SECTION ANSWER +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +nic.cz. IN DNSKEY +SECTION ANSWER +nic.cz. 1800 IN DNSKEY 256 3 13 SmMYG4VjCgj4rAxB4sqgvIzcGtESoX1H m7Dsoekap6HJwj8WOEiFciSg537caOPl 4+7Dyp/b5JwkBemxQQRL9Q== +nic.cz. 1800 IN DNSKEY 257 3 13 LM4zvjUgZi2XZKsYooDE0HFYGfWp242f KB+O8sLsuox8S6MJTowY8lBDjZD7JKbm aNot3+1H8zU9TrDzWmmHwQ== +nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190707163411 20190624124001 61281 nic.cz. ggHlmuzLOTZOCYcbZ8TrNoTXOAg7xJ9N B+QLdmZYyny53ODMkRfDv28SSMkwtuc1 rZXfC+/c7oArzsBbbncTRA== +nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190708092836 20190624124001 10486 nic.cz. lFYLLcm5ICS0BSdB0+dA8m7XxdRbB49+ 5N1w8AHOaPNDTWp9GlXA935IUk18C2to 1ghYmP2RZaNOTchSVRgWzA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.ns.nic.cz. IN A +SECTION ANSWER +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.ns.nic.cz. IN AAAA +SECTION ANSWER +b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1 +b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg== +SECTION AUTHORITY +nic.cz. 1800 IN NS a.ns.nic.cz. +nic.cz. 1800 IN NS b.ns.nic.cz. +nic.cz. 1800 IN NS d.ns.nic.cz. +nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg== +SECTION ADDITIONAL +a.ns.nic.cz. 1800 IN A 194.0.12.1 +a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1 +a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg== +a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ== +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +d.ns.nic.cz. 1800 IN A 193.29.206.1 +d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1 +d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA== +d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.ns.nic.cz. IN A +SECTION ANSWER +c.ns.nic.cz. 1800 IN A 194.0.14.1 +c.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708123232 20190624124001 10486 nic.cz. ln7Q9H73Ba6dEbIrhA6QrK3OMMEIu4QA h4fJ3xeUIW4US+XU21wylj09Zaf6ALE+ V3E9jTWdPfo1UTGnuW1VUw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.ns.nic.cz. IN AAAA +SECTION ANSWER +d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1 +d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew== +SECTION AUTHORITY +nic.cz. 1800 IN NS a.ns.nic.cz. +nic.cz. 1800 IN NS b.ns.nic.cz. +nic.cz. 1800 IN NS d.ns.nic.cz. +nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg== +SECTION ADDITIONAL +a.ns.nic.cz. 1800 IN A 194.0.12.1 +a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1 +a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg== +a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ== +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg== +d.ns.nic.cz. 1800 IN A 193.29.206.1 +d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.ns.nic.cz. IN AAAA +SECTION ANSWER +b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1 +b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.ns.nic.cz. IN NS +SECTION AUTHORITY +51npp2qit2otcucer39ql8d4q4h9mr5d.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 52jm0s7pifluesur7b9p840f8fkcpcsi A AAAA RRSIG +51npp2qit2otcucer39ql8d4q4h9mr5d.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190708102945 20190624124001 10486 nic.cz. ScbUA0IlzL0o1h34t007ViOD53YFHe+V zn2ge8gqiNeT29FW/sCwiyVsrUpMZ7nW O9gmXfdNjjtmyTA7iWbVTA== +nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw== +nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.ns.nic.cz. IN A +SECTION ANSWER +c.ns.nic.cz. 1800 IN A 194.0.14.1 +c.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708123232 20190624124001 10486 nic.cz. ln7Q9H73Ba6dEbIrhA6QrK3OMMEIu4QA h4fJ3xeUIW4US+XU21wylj09Zaf6ALE+ V3E9jTWdPfo1UTGnuW1VUw== +SECTION AUTHORITY +nic.cz. 1800 IN NS a.ns.nic.cz. +nic.cz. 1800 IN NS b.ns.nic.cz. +nic.cz. 1800 IN NS d.ns.nic.cz. +nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg== +SECTION ADDITIONAL +a.ns.nic.cz. 1800 IN A 194.0.12.1 +a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1 +a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg== +a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ== +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg== +d.ns.nic.cz. 1800 IN A 193.29.206.1 +d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1 +d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA== +d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +nic.cz. IN DS +SECTION ANSWER +nic.cz. 3600 IN DS 61281 13 2 4104d40c8fe2030bf7a09a199fcf37b36f7ec8ddd16f5a84f2e61c248d3afd0f +nic.cz. 3600 IN RRSIG DS 13 2 3600 20190705064642 20190622210528 6318 cz. h4tSy9MopxkbCg2mPu0s/CoE+DtoKUTL 5iw1cpQZOF1MJMZhTYo3yZjYiIkIrih8 xigA0UNFXtZEAxzsqI6omA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.ns.nic.cz. IN AAAA +SECTION ANSWER +c.ns.nic.cz. 1800 IN AAAA 2001:678:11::1 +c.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707153808 20190624124001 10486 nic.cz. 2n+SYd+Eh6pFujzSb5u/ZFbJkfHGB3aB wo5vSKAp+s8RgEtwMawcs54psA6LWKc5 swrxP1C1xVyMLQ6L7eifGA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.ns.nic.cz. IN AAAA +SECTION ANSWER +a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1 +a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ== +SECTION AUTHORITY +nic.cz. 1800 IN NS a.ns.nic.cz. +nic.cz. 1800 IN NS b.ns.nic.cz. +nic.cz. 1800 IN NS d.ns.nic.cz. +nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg== +SECTION ADDITIONAL +a.ns.nic.cz. 1800 IN A 194.0.12.1 +a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg== +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg== +d.ns.nic.cz. 1800 IN A 193.29.206.1 +d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1 +d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA== +d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.ns.nic.cz. IN NS +SECTION AUTHORITY +CNTVMLLA2O27TCBC4MEP7IV9P54L7FLE.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 co07u5iiiqhl96t3hlmgkchj3203eqqj A AAAA RRSIG +CNTVMLLA2O27TCBC4MEP7IV9P54L7FLE.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707155010 20190624124001 10486 nic.cz. osfB/CgwWbwa/BX/fYo+gzrImuam0bhT bD9xmAH6w+acJ8GrCNHNcCgFdimdacEA rSx2ztVVWCiALLlqzFP1WQ== +nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw== +nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.ns.nic.cz. IN A +SECTION ANSWER +d.ns.nic.cz. 1800 IN A 193.29.206.1 +d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA== +SECTION AUTHORITY +nic.cz. 1800 IN NS a.ns.nic.cz. +nic.cz. 1800 IN NS b.ns.nic.cz. +nic.cz. 1800 IN NS d.ns.nic.cz. +nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg== +SECTION ADDITIONAL +a.ns.nic.cz. 1800 IN A 194.0.12.1 +a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1 +a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg== +a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ== +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg== +d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1 +d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +nic.cz. IN DNSKEY +SECTION ANSWER +nic.cz. 1800 IN DNSKEY 256 3 13 SmMYG4VjCgj4rAxB4sqgvIzcGtESoX1H m7Dsoekap6HJwj8WOEiFciSg537caOPl 4+7Dyp/b5JwkBemxQQRL9Q== +nic.cz. 1800 IN DNSKEY 257 3 13 LM4zvjUgZi2XZKsYooDE0HFYGfWp242f KB+O8sLsuox8S6MJTowY8lBDjZD7JKbm aNot3+1H8zU9TrDzWmmHwQ== +nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190707163411 20190624124001 61281 nic.cz. ggHlmuzLOTZOCYcbZ8TrNoTXOAg7xJ9N B+QLdmZYyny53ODMkRfDv28SSMkwtuc1 rZXfC+/c7oArzsBbbncTRA== +nic.cz. 1800 IN RRSIG DNSKEY 13 2 1800 20190708092836 20190624124001 10486 nic.cz. lFYLLcm5ICS0BSdB0+dA8m7XxdRbB49+ 5N1w8AHOaPNDTWp9GlXA935IUk18C2to 1ghYmP2RZaNOTchSVRgWzA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.ns.nic.cz. IN NS +SECTION AUTHORITY +cntvmlla2o27tcbc4mep7iv9p54l7fle.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 co07u5iiiqhl96t3hlmgkchj3203eqqj A AAAA RRSIG +cntvmlla2o27tcbc4mep7iv9p54l7fle.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707155010 20190624124001 10486 nic.cz. osfB/CgwWbwa/BX/fYo+gzrImuam0bhT bD9xmAH6w+acJ8GrCNHNcCgFdimdacEA rSx2ztVVWCiALLlqzFP1WQ== +nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw== +nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.ns.nic.cz. IN NS +SECTION AUTHORITY +cu82t3qracdj063olk907dv20ine9dea.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 d2749lueihj9moq02lt0k9i8tnbgest1 A AAAA RRSIG +cu82t3qracdj063olk907dv20ine9dea.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190708122905 20190624124001 10486 nic.cz. fg5ypFDXqZlnzSbndkPm2VjZieL0t5NT zKu0cfcWHu4TlWB/OxxuaD4C2oGx5nki Pchj+FQNobNZJfCXKOa4ug== +nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw== +nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +csas.cz. IN DS +SECTION ANSWER +csas.cz. 3600 IN DS 8196 7 2 c5c7974e1dc3bf036f8744a4d919e03ef01d8d6167db6201940ca87059558ee3 +csas.cz. 3600 IN RRSIG DS 13 2 3600 20190706080140 20190622110535 6318 cz. 5V0ZvjpT8zWMsVwPpyhsMc9DRFVMQtP2 D2o7S/dLbZ7YL4Mqd8P9n+o+4NQgaqQw 7VPBHnN3VzVDYvWjmr+rfw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ns.nic.cz. IN NS +SECTION AUTHORITY +JNP2UC34HHA9DE64L3RJF6ULP4PRA74N.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 jsdlj2k5hipr7eb12ne8bads7lshvo1k +JNP2UC34HHA9DE64L3RJF6ULP4PRA74N.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190707164247 20190624124001 10486 nic.cz. lrFJPPGpHyoC5l4uM8l94ye/HG1kTVw7 dR98um06iG+2XK82Dib+wnzqoNNIqbaA FeaAkjfqgCHA8kDySAP+5g== +nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw== +nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.ns.nic.cz. IN NS +SECTION AUTHORITY +nic.cz. 1800 IN RRSIG SOA 13 2 1800 20190708100906 20190624124001 10486 nic.cz. 1mDJpihqjobv42BXF8H1dT0/vLtPTpb/ k7flS9wr8tEPe57o6GrkimcSWZlS/lm5 OyhvjIpvU9Da8n2ezGiGHw== +nic.cz. 1800 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561383601 10800 3600 1209600 7200 +on20qsre8qs9a2asfdatp5cs6g2i5ssq.nic.cz. 7200 IN NSEC3 1 0 10 879ec89c91d874a8 onv9qnjm1krm9qdk0n6o6o23doo5jfug A AAAA RRSIG +on20qsre8qs9a2asfdatp5cs6g2i5ssq.nic.cz. 7200 IN RRSIG NSEC3 13 3 7200 20190708041440 20190624124001 10486 nic.cz. WkMEKZUDwPTv5Y3KG/C9LTVTynACPb16 1OuoxTij1reZR4LzHVoGQKDf0Dbj2Rau 9LrBW5PI5PSDQ6BmUKRj6A== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.ns.nic.cz. IN AAAA +SECTION ANSWER +a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1 +a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.ns.nic.cz. IN A +SECTION ANSWER +a.ns.nic.cz. 1800 IN A 194.0.12.1 +a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +cz. IN DS +SECTION AUTHORITY +cz. 3600 IN RRSIG SOA 13 1 3600 20190707192652 20190625123528 6318 cz. BYXtAj/BIXIb5xlT6TBQYaFhbloeuo0H RqJTdPu9gVVyuBKbvV6YmQbS4BBMM4qA Cp2Vw7yBK9+dONHp9JAmuA== +cz. 3600 IN SOA a.ns.nic.cz. hostmaster.nic.cz. 1561469728 900 300 604800 900 +fu65o5n6kmh8a04mps1e4a73s37jr72u.cz. 900 IN NSEC3 1 0 10 357dda080afe0ef8 fu677p5qqp6ihbeeloacm3sr4ieklu7m NS SOA RRSIG DNSKEY NSEC3PARAM +fu65o5n6kmh8a04mps1e4a73s37jr72u.cz. 900 IN RRSIG NSEC3 13 2 900 20190706134746 20190622170523 6318 cz. EsElag8LQ5TcunX40efTh35IN3GoQnPq XAZZ0cSPHT6GOohzp8iD1LSLLbwZUiNE yB4hCp1yqEi0pINRoHglNA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +cz. IN DNSKEY +SECTION ANSWER +cz. 18000 IN DNSKEY 256 3 13 7t+ZoZGIrV27M/PEAH8OKSjEXVAJhV6O o5ESS+Vry5ZhfoWogIKAXzvda/qY/WTA L09BEk+ko16oGRRktvzWEw== +cz. 18000 IN DNSKEY 257 3 13 nqzH7xP1QU5UOVy/VvxFSlrB/XgX9JDJ zj51PzIj35TXjZTyalTlAT/f7PAfaSD5 mEG1N8Vk9NmI2nxgQqhzDQ== +cz. 18000 IN RRSIG DNSKEY 13 1 18000 20190705000000 20190621000000 20237 cz. kJ1zRR76FpPS4SLyFuLbrQBvVnq6GY+x 5sOV2ayq6rt4D1sjpxROufFfBfi/6wAv qo3VZ0iUJSB03djeX8gk5A== +cz. 18000 IN RRSIG DNSKEY 13 1 18000 20190709092856 20190625123528 6318 cz. Lpz5UZi8lVH1TCdz6DyjWvoUciOVqA4Z d+3TVxNF2GsLzM15nwc34FnaQF3dxhJZ mdf6dET7iOUmy2SN3majVg== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.ns.nic.cz. IN AAAA +SECTION ANSWER +c.ns.nic.cz. 1800 IN AAAA 2001:678:11::1 +c.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707153808 20190624124001 10486 nic.cz. 2n+SYd+Eh6pFujzSb5u/ZFbJkfHGB3aB wo5vSKAp+s8RgEtwMawcs54psA6LWKc5 swrxP1C1xVyMLQ6L7eifGA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.ns.nic.cz. IN A +SECTION ANSWER +d.ns.nic.cz. 1800 IN A 193.29.206.1 +d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.ns.nic.cz. IN AAAA +SECTION ANSWER +d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1 +d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew== +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR RD NOERROR +SECTION QUESTION +csas.cz. IN NS +SECTION AUTHORITY +csas.cz. 3600 IN DS 8196 7 2 c5c7974e1dc3bf036f8744a4d919e03ef01d8d6167db6201940ca87059558ee3 +csas.cz. 3600 IN NS ddnsa.csas.cz. +csas.cz. 3600 IN NS ddnsb.csas.cz. +csas.cz. 3600 IN RRSIG DS 13 2 3600 20190706080140 20190622110535 6318 cz. 5V0ZvjpT8zWMsVwPpyhsMc9DRFVMQtP2 D2o7S/dLbZ7YL4Mqd8P9n+o+4NQgaqQw 7VPBHnN3VzVDYvWjmr+rfw== +SECTION ADDITIONAL +ddnsa.csas.cz. 3600 IN A 194.50.240.64 +ddnsb.csas.cz. 3600 IN A 194.50.240.192 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +nic.cz. IN NS +SECTION ANSWER +nic.cz. 1800 IN NS a.ns.nic.cz. +nic.cz. 1800 IN NS b.ns.nic.cz. +nic.cz. 1800 IN NS d.ns.nic.cz. +nic.cz. 1800 IN RRSIG NS 13 2 1800 20190707221726 20190624124001 10486 nic.cz. JhCrQB0nVFkti/j3weaalBPxqDG7PyiC KLV7hj61SLdRGcue9/fI9IN7lIanFWhL A1b7/L5DYejIY7WpHVU3Jg== +SECTION ADDITIONAL +a.ns.nic.cz. 1800 IN A 194.0.12.1 +a.ns.nic.cz. 1800 IN AAAA 2001:678:f::1 +a.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708050633 20190624124001 10486 nic.cz. 18u1P3Wvg0xoz3fTRtqVNlTHiZPOuGW7 C8nsMIBTCTT9mPYN0z+CcBDfRwVLNnfJ eNTfHXA9zERxbAT3WCHEXg== +a.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707232622 20190624124001 10486 nic.cz. qY1Rm171qERHJwykmMYDKXlIGUnHdMhX gYlvOZPGONNuapbsqzTQos9Vd7v4IQfp k6j8sVTjSId1/q/75D4vNQ== +b.ns.nic.cz. 1800 IN A 194.0.13.1 +b.ns.nic.cz. 1800 IN AAAA 2001:678:10::1 +b.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708030702 20190624124001 10486 nic.cz. bV+9iqB6KDNUCZrcoo9fXj3X1BHhCpgh MGSXx8q4JWJ9mm9Hz6h63UfXTWPthvJy +J18PantZQVPScwMoXVzuw== +b.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190707133636 20190624124001 10486 nic.cz. OuH2sPy1tH6CENbjioxaaYzCB8yxB1sP FyQXAcY4VpNmLnqthfGKTn5dONZuG4UD I9ihrEaPsV3RsDse0GpMqg== +d.ns.nic.cz. 1800 IN A 193.29.206.1 +d.ns.nic.cz. 1800 IN AAAA 2001:678:1::1 +d.ns.nic.cz. 1800 IN RRSIG A 13 4 1800 20190708114823 20190624124001 10486 nic.cz. p2nhRTWBo56GXRdL19wT+y/XyNb6wjrz Oy3AndSR2/L9BDZrX/mkGYh20x5KpdUV +r+DPy9XFXEmvGrwAD5meA== +d.ns.nic.cz. 1800 IN RRSIG AAAA 13 4 1800 20190708121635 20190624124001 10486 nic.cz. QeqTWoaOuL+L+QdiGOIne/WCi+D0V6EH 0h96aDuMs2eySLXSWPC54ICz28gwudmh wX4oEdQf1nYVneO7iEDFew== +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +cz. IN NS +SECTION ANSWER +cz. 3600 IN NS a.ns.nic.cz. +cz. 3600 IN NS b.ns.nic.cz. +cz. 3600 IN NS c.ns.nic.cz. +cz. 3600 IN NS d.ns.nic.cz. +cz. 3600 IN RRSIG NS 13 1 3600 20190705184721 20190622030526 6318 cz. SzhZGIFskUTnlxipSleB+IghUpyhS1eV PubDzCU/CC0LmDBoAVwfiY8zKWdPSu0X 5544N2KzZ5JrPoasQkOLzg== +SECTION ADDITIONAL +a.ns.nic.cz. 3600 IN A 194.0.12.1 +a.ns.nic.cz. 3600 IN AAAA 2001:678:f::1 +b.ns.nic.cz. 3600 IN A 194.0.13.1 +b.ns.nic.cz. 3600 IN AAAA 2001:678:10::1 +d.ns.nic.cz. 3600 IN A 193.29.206.1 +d.ns.nic.cz. 3600 IN AAAA 2001:678:1::1 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +cz. IN NS +SECTION ANSWER +cz. 3600 IN NS a.ns.nic.cz. +cz. 3600 IN NS b.ns.nic.cz. +cz. 3600 IN NS c.ns.nic.cz. +cz. 3600 IN NS d.ns.nic.cz. +cz. 3600 IN RRSIG NS 13 1 3600 20190705184721 20190622030526 6318 cz. SzhZGIFskUTnlxipSleB+IghUpyhS1eV PubDzCU/CC0LmDBoAVwfiY8zKWdPSu0X 5544N2KzZ5JrPoasQkOLzg== +ENTRY_END + + + + +RANGE_END + + + +; Group's zones: +; csas.cz. +; Server names: +; ddnsa.csas.cz. +; ddnsb.csas.cz. +; ddnsc.csas.cz. +; ddnsd.csas.cz. +RANGE_BEGIN 0 1000 + ADDRESS 194.50.240.64 + ADDRESS 194.50.240.192 + ADDRESS 194.50.240.194 + ADDRESS 194.50.240.66 + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsd.csas.cz. IN NS +SECTION AUTHORITY +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 gfr9qt699hmcloa9radenpk7pqeikiu9 TXT +gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. OWtiEsmO7VnUV2MQp3gZJmOAQw4n81DH 9c5FFJW6MBE3afaIqGTvWYCgRipEEvZF qPBVxGpptVsMbuELagewwZYtR+EEh2A/ qMf/wVC//t2c67YFIxMILi9ijleYS5y8 m5Mu+logobk2Resxs0kC47kwNP9KSh7s gm3SFjK1LXRXg19UmiabMIINoOoAE1M0 XePGhiaqhFwros32p++2JrCdaYrPXLWy VuENN0chZ/hE55ic4M7KpxZ12+oPzigk tIeh9sqTaKpGJBZk4vlJQLq2zfL/gnKZ CRRN8bJQ/ZsSZG//rL0nqZcgyxQqXI9w As8TBPtQ9IQWq2K5MxjKHg== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +csas.cz. IN AAAA +SECTION AUTHORITY +8b6896cv5m6qpdd29hb4s12lagep7utq.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 8b6896cv5m6qpdd29hb4s12lagep7utr NS SOA RRSIG DNSKEY NSEC3PARAM +8b6896cv5m6qpdd29hb4s12lagep7utq.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. SNkUAfA3do4t3pyNw1I0zfdiGnWufjIW S4DnHV7Sz+LNOfbe36ipmpUevus+12DG qgG+fQNzxAbCByk7e5fqieyXLVyGfRla 1H9UwCj42/TWATKqDQUFADVEaZ4nHrnN E2yZWkaNNW3jBX7LTIvgwHHVXuM5HQwd Q3/be9B6oz92QLs7ds2zhtjB1NYCUeFD OwYOxSekxZV/ePEfytrXbw1NPcji9GsO v6+HLgYLLy2qIQKMS5xavb4+4/eDMsq4 vJ+uvrmc66JHL7rFyrwd/x1NNsHXwqac czV+GifY3m8svOydXETd9tTC8sTsiU9x ZFTAOcTlxlo211UwuHnwkA== +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsc.csas.cz. IN NS +SECTION AUTHORITY +c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 c1c03am0n36kncp4iqb4buoqo1ectql5 TXT +c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. FKjWbcw5aP2HzHFy2t+M462dxM1ph0FW 02Tohh/aJQOp1iKQOi6u1V2tI3H9CMXW xeIAktZ+xiUDRYLX50fNuJZMaSsn7r5A LYjVAKGzwMPncIf6IlEDYkj1I1rdp6z8 LvWsWNO1wfIPq1Dw2geN60bcz3D7r/sY WfjU/7jO9f0nekZZXI2qFsMSYd9Dkaq7 mlpP0NrWnUbCjL+BfuLFNebh8g3D8f5w Tq3R9czwW5YTVXUquBIrjiZ0Ko9INgQ/ 4pvJqJ1bsTpmzdODfAssEtpu+es4wLwt ZTe8Ll9VeDB20RqEnAyHZwQRXXVF2t+F vdJU7Desbpu6rElA7IXwRw== +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsd.csas.cz. IN AAAA +SECTION AUTHORITY +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 gfr9qt699hmcloa9radenpk7pqeikiu9 TXT +gfr9qt699hmcloa9radenpk7pqeikiu8.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. OWtiEsmO7VnUV2MQp3gZJmOAQw4n81DH 9c5FFJW6MBE3afaIqGTvWYCgRipEEvZF qPBVxGpptVsMbuELagewwZYtR+EEh2A/ qMf/wVC//t2c67YFIxMILi9ijleYS5y8 m5Mu+logobk2Resxs0kC47kwNP9KSh7s gm3SFjK1LXRXg19UmiabMIINoOoAE1M0 XePGhiaqhFwros32p++2JrCdaYrPXLWy VuENN0chZ/hE55ic4M7KpxZ12+oPzigk tIeh9sqTaKpGJBZk4vlJQLq2zfL/gnKZ CRRN8bJQ/ZsSZG//rL0nqZcgyxQqXI9w As8TBPtQ9IQWq2K5MxjKHg== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +csas.cz. IN DNSKEY +SECTION ANSWER +csas.cz. 7200 IN DNSKEY 256 3 7 AwEAAaNjFdWEB091Zv/uWznXJXbFaDYD cG4GvutyTPMM1nWDLu1ZTR/ujYhwEoWM 1DYyq8QkIFJS7PVnu312O8pkiWcvV9Fl hVv9AYJ8OCbixXjSrwXL1yfBhhzJxxjA RXi49Xn/NTPNiTeK6lVed2QMLbwucpTy 4GEduAcXWDi7/OnDD3UmaFtxXQ2LKc7d +of4okGQWYdka9b+KeyJtXwhDuuzGf/v m8E3Tdjt5ldgOpofh/BO5lifl6mAXgnW E6z+p0fb1ksyq1hGu9ssizxr8A10amUa repR+zcOFoDJNv5IxGWi5rriAvBW4NAl U1wy1P6BSDgMZuc8JBj3VikbI6U= +csas.cz. 7200 IN DNSKEY 256 3 7 AwEAAbk21ZXai9JsSCmuW8InRPINGI+o 2vxokpQ0imk6iDPHqF3QhJSs5QcFG+Hq yZ3mWLkb5cT/u0zKZ+Onri0s2zSm4ASk /A86BQSEaPXG90GiD+waH7qF5vorF5Gx 1BvzdtLz9vtbsQ0G1GfdbvlouvlU05t2 GlSuAXqsj6RI5WaWHejKJ1fcOtR7hQTt tH5+oir5t1eJ1riQsOyPzC2y9V+Q28Tf cD5F6oxghhn9+YieAIqMMp5r7txouxp0 DFG+oVMbTmt07B9MIClXOMMTOYDTOj0c fpdx5/WHoigkgNdcUh5ulsva9OK9EWZX WkicdtzfYfe7fi3LqFxWc0DMiY0= +csas.cz. 7200 IN DNSKEY 257 3 7 AwEAAcMXtJYlvIshn+O541gOW48wNlgh szwYVFeSUd+qB+BfejKueV+4vo9IY1A8 cKxfLcOwT0F/XyEZXhpigZPXf2OQrLWi R6aK0cDErhLUp30AWdEwB/T8QnfePzM1 LX30rgAP5JhGLckrfoVbSZi28S6vvuxA GbFmgEpGkKVgMg9pKAcjrRUd/bmyNaQR yECq40cwgHFaDm9SPeAavgMxn1l88dAv qIwKDvpN2Er+K/Gl5GRApDFxSt9x+7rt NIrpFV4Apl/j81Rcxyj7v7HXEu3P8BNQ 6s0cVg8RmtY+R0J59sTsZyJGI2krq5Ap k2K1S2RA7QZxHQCMKx+caRyLwk6KqjmF EYMILxpYWER+iPddpeo5w0AYJNxDYYeE 2cUYuBXNi7SM4UZGDbMZ+j2xlzGNyAsE mWXlrR4qCgYKO7JxK0Yw3otZzNyrcJhS fT1E0tNvDv3zH/j8riqIyW36EK1yjVav dcI3a+GGSh5oylb/7SuLFNKEW0g2fo5q W+rITI77k+MRR798XNXqSKTT19LNiqWc xhlA4aGzHzKZieEWR4d6FHhOKzNoo+Ce j7b00rg5v2hwSAEEHcC3lwuStya1J5IX g6sfdNxWqJ0yydI/PGOn0ZgakX2oEE4b zGJchx/aHKogs2L+bZJfi7N1OmU7AU0D mY6kTxEYC1lBFb1h +csas.cz. 7200 IN DNSKEY 257 3 7 AwEAAcoflVKUA6KreqNnC7qYr0B+UiYS Fqoja50or7jBmrrmxok5mR9Ea+L3D0PK ynffMxFMMQm1JekaJYH66eUGgWWqTHRQ nAKVQchHCv37Bf0nFEetKo/qf4KJbdDD Ar3sXjfkClaQQlqMPDeCQQbfxSWpdvQo ip7pX35KsatTObINwqnMsl3tsvsugybw 6+xujlYWOpmJcjHri7cdZA5NSx3k3Sdb 16/GEpcwFe0Z8Oi4TgbcVEaAziyOm0zC to1SW1L4VovdZkadAa3RMQ7QpyR/wIOr TjqS/weDkOyKgGNnbVL5l8dUAD8rk/Do cXhQuXxNqHB9PVNxBCsfnVVj6fbk09eo 6stXAdJbwoa1NoPBlHsCV5+EN65XXsGO eLZneUt213RDGkphcKTWaF3dvIRXtWbt Rz2bCrxs12ADhhXisyH2EGntyI3LX3zY ISbKaZnRzbU1nKIdcNzFJ1p8aoUPgzX7 YhpXVkhfcaB8aAG38Ys6EXvcACFdoqma V7b0VnvU1tPsI9bAesU4d5K4EjCNrana yfvFgakYdmoi3GrpWeHim7CDK9s5yrh3 Dou59pU7a/1xugGvuCkDllo8Z70hWzJq tVNFrSv7jwLA7+77pRKBF7Vl88Y0i/6h zUkllh7mBCMilyU50AX9bGJsd6PFJn6P iZ8x+XoCel0oZqz3 +csas.cz. 7200 IN RRSIG DNSKEY 7 2 7200 20190630181024 20190623181024 26663 csas.cz. cPZVp/k5lPxsjnRhCc8zXkKGf2VQjg93 Rwyrwjm6wPg/B7n3iTzLA+TUROwMgcAB rlEru/TNaySpWR36rDQdg/w8JZsB17Wf HIO0t1GxjQdEjPYD9T4x0b5u/Ra/ienZ XgHwuto1tQCghttwv7ioECzf1+52asf+ oxe8il1W4HdMH8/wiEyOyPm8n9ou6siX tcVjqbRTy0xLcPoFm/ATvUBMGBrbMedy hGWn88cLoIQA4IPm4zAIAWunPV8sFNKY l12HDNzQlfrO6ukJqtFTjQREeTWFC0qP KXWSPJeX9fTfrT6zHfyV/YQd3tGRP0J8 KTzXmUMYi2vrVbeagR00Vg== +csas.cz. 7200 IN RRSIG DNSKEY 7 2 7200 20190630181024 20190623181024 8196 csas.cz. t8HaIHf6FCi91a3ppWC4bAiN+WvZPdbf ESinQ+iYFSWk7NlCw45eT/0SpRWNQ5jQ fvWkkvBDDuHDv9FVdmqkvAuMCf0/GgnM 2bdOQt/q2Hp3E91eFpHW1fx7YtQabj+r 9Ww30ewUplDE2v6JlHnJzm53mYsbUUum l+rAtq+QJnb8sjjn2JceDtQLBkZaLsLe vUuFL/Hz/WvvMgjYUyuxbK4xxJByiymo hZIDxA8TWcaoFFyiP+Rv4leqaxVLXun4 VsWsCE2YYtOqrYRaq2UJvbSIFAPdix5Q EL44TXYlJ00NbngD480tJ8TwyNTm4CLp 8Z85xtmpYfKO3VFAycL0zV/7fOJRkoPQ LrBxClIbeQJlQapm1FMQQK/FFfHKSVRq 659VLfDbxfbTU/yWOmlUldaB8r7y6BhD iq4u/IZqIU5eTIbeoMd3HBerKREo0vOy UPCoW4OJ3Q9/WQ18cPsVW+BKjkKRrV4T VQKc52jwkPufUq8fNuVeuZ+8cvgIaUfD 8Xie+N2Trlh5tfaAAg9etgu0EmoEAP8V 1mTzT54losWySfSh5JNx5fDtUaxZI/q3 2+mbgnO4QlGB9eAhoA6JRHByWf+Gf9rR hEktuZqg2Uw4ifOebJsQE4atFr8Tr910 xihtrgtx/y6HwpB9nIr7V91ewn6lKMEz d4ordmuS+1Q= +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsa.csas.cz. IN A +SECTION ANSWER +ddnsa.csas.cz. 7200 IN A 194.50.240.64 +ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg== +SECTION AUTHORITY +csas.cz. 7200 IN NS ddnsa.csas.cz. +csas.cz. 7200 IN NS ddnsb.csas.cz. +csas.cz. 7200 IN NS ddnsc.csas.cz. +csas.cz. 7200 IN NS ddnsd.csas.cz. +csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ== +SECTION ADDITIONAL +ddnsb.csas.cz. 7200 IN A 194.50.240.192 +ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg== +ddnsc.csas.cz. 7200 IN A 194.50.240.66 +ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw== +ddnsd.csas.cz. 7200 IN A 194.50.240.194 +ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsb.csas.cz. IN AAAA +SECTION AUTHORITY +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 kl8ko9vcu5os0r0marmli019btprhvds TXT +kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. ebbykapJt+h+uDJlz84Yu4rpx7spx8aY bbR/BCMIVJ6HjziYnwwbBQuyyd6t281+ pdn+2Dxo5tUJ0Kw4oatMPVhID8Psasd3 2Za8bZrouTk8RcQislJCj1jPi2HMIQUI dvJ1aCMC6vn1vI++ZMvcxfptxgmWyL46 i4P3xZAwtrB6hCVrctQ0dbbp1nswh1go YFIf3Hzxu2NHfXZYMdXXb1cLuOZ5L17g UZlqqgcrudLORc2cHj0NcjVT2PscMeoy a/jFNJwCHmkfI3nCAeXmemz/txQUY01u SxBNjkd/y2DVSIgvDPY/Zz0dW4gYdcMG 4T4D43oBTG6w06CgBg1QQw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +csas.cz. IN A +SECTION ANSWER +csas.cz. 120 IN A 194.50.240.198 +csas.cz. 120 IN A 194.50.240.70 +csas.cz. 120 IN RRSIG A 7 2 120 20190701063211 20190624063211 26663 csas.cz. UXxlRUL6nBVmcrcP4kkryr7lfVxnQHs4 z2WahLZEIaQdf56Iw/+bxddThPD9l3a0 rBCwURI8QMspgPks+7UprWN5TESIifiP W9qJLDuvtD+sVoLgunBAwgi1sE8KfRas asbiISaRpot+3IqJYzYi9X9O5JMdYCuS H9nfayDebVlbC4ChAo5Rcdpkzfb7DwFp gDFKdn+Lmp7IdImSlvJQQT2Mqxpew+gd vMBr5ZN82G8zlsrrHz4n2/kF/SqCYTCG q1WLZUsMvLsP+ha3TAR1t/iG9ayw5Mll 8N2c+AejB2lMwTIlBX+zLlJYT0MoNCyF cMNoCxwjENtDMbq9QZKowA== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsc.csas.cz. IN A +SECTION ANSWER +ddnsc.csas.cz. 7200 IN A 194.50.240.66 +ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw== +SECTION AUTHORITY +csas.cz. 7200 IN NS ddnsa.csas.cz. +csas.cz. 7200 IN NS ddnsb.csas.cz. +csas.cz. 7200 IN NS ddnsc.csas.cz. +csas.cz. 7200 IN NS ddnsd.csas.cz. +csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ== +SECTION ADDITIONAL +ddnsa.csas.cz. 7200 IN A 194.50.240.64 +ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg== +ddnsb.csas.cz. 7200 IN A 194.50.240.192 +ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg== +ddnsd.csas.cz. 7200 IN A 194.50.240.194 +ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NXDOMAIN +SECTION QUESTION +csas.cz. IN DS +SECTION AUTHORITY +cz. 60 IN SOA cecf53-ant-MS2A-1.csin.cz. hostmaster.cecf53-ant-MS2A-1.csin.cz. 2019061307 10800 3600 604800 60 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsb.csas.cz. IN NS +SECTION AUTHORITY +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 kl8ko9vcu5os0r0marmli019btprhvds TXT +kl8ko9vcu5os0r0marmli019btprhvdr.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. ebbykapJt+h+uDJlz84Yu4rpx7spx8aY bbR/BCMIVJ6HjziYnwwbBQuyyd6t281+ pdn+2Dxo5tUJ0Kw4oatMPVhID8Psasd3 2Za8bZrouTk8RcQislJCj1jPi2HMIQUI dvJ1aCMC6vn1vI++ZMvcxfptxgmWyL46 i4P3xZAwtrB6hCVrctQ0dbbp1nswh1go YFIf3Hzxu2NHfXZYMdXXb1cLuOZ5L17g UZlqqgcrudLORc2cHj0NcjVT2PscMeoy a/jFNJwCHmkfI3nCAeXmemz/txQUY01u SxBNjkd/y2DVSIgvDPY/Zz0dW4gYdcMG 4T4D43oBTG6w06CgBg1QQw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsb.csas.cz. IN A +SECTION ANSWER +ddnsb.csas.cz. 7200 IN A 194.50.240.192 +ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg== +SECTION AUTHORITY +csas.cz. 7200 IN NS ddnsa.csas.cz. +csas.cz. 7200 IN NS ddnsb.csas.cz. +csas.cz. 7200 IN NS ddnsc.csas.cz. +csas.cz. 7200 IN NS ddnsd.csas.cz. +csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ== +SECTION ADDITIONAL +ddnsa.csas.cz. 7200 IN A 194.50.240.64 +ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg== +ddnsc.csas.cz. 7200 IN A 194.50.240.66 +ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw== +ddnsd.csas.cz. 7200 IN A 194.50.240.194 +ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsd.csas.cz. IN A +SECTION ANSWER +ddnsd.csas.cz. 7200 IN A 194.50.240.194 +ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ== +SECTION AUTHORITY +csas.cz. 7200 IN NS ddnsa.csas.cz. +csas.cz. 7200 IN NS ddnsb.csas.cz. +csas.cz. 7200 IN NS ddnsc.csas.cz. +csas.cz. 7200 IN NS ddnsd.csas.cz. +csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ== +SECTION ADDITIONAL +ddnsa.csas.cz. 7200 IN A 194.50.240.64 +ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg== +ddnsb.csas.cz. 7200 IN A 194.50.240.192 +ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg== +ddnsc.csas.cz. 7200 IN A 194.50.240.66 +ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsa.csas.cz. IN AAAA +SECTION AUTHORITY +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 j0hp68elhot3j046r6mr0tnqlns1dbc8 TXT +j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. gUyltGyzdD2L6M29xgqWXMO834aavtFc Si2oAbET0rEJZ5w9ewhEJdVT65MMUUlK wvVX239N7PtsyL+fQvxu5TZ8du0ML8Oi KBp3gao/stajg/lZFd6zVvDWliC3+psL 7PFmD5au5qcrYc6HLc8m8D4hHFPREyd6 1tLGA98RevbQGfrDYODXi6G28vwbxoYU POn4mo82MnVVTZhh58cu7nKRRvKAtay6 VZVWZBOuxy8u+LNsrj3vpDbaOIiWzHd0 pRACsv3LqGpxQNH8avSalWLBvLWchAHj 0T2M+doO8UVaCsyFo/3wF2TXdgFcOAr3 xDIdhHCCoanRVFZ+gFAwIw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsa.csas.cz. IN NS +SECTION AUTHORITY +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 j0hp68elhot3j046r6mr0tnqlns1dbc8 TXT +j0hp68elhot3j046r6mr0tnqlns1dbc7.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. gUyltGyzdD2L6M29xgqWXMO834aavtFc Si2oAbET0rEJZ5w9ewhEJdVT65MMUUlK wvVX239N7PtsyL+fQvxu5TZ8du0ML8Oi KBp3gao/stajg/lZFd6zVvDWliC3+psL 7PFmD5au5qcrYc6HLc8m8D4hHFPREyd6 1tLGA98RevbQGfrDYODXi6G28vwbxoYU POn4mo82MnVVTZhh58cu7nKRRvKAtay6 VZVWZBOuxy8u+LNsrj3vpDbaOIiWzHd0 pRACsv3LqGpxQNH8avSalWLBvLWchAHj 0T2M+doO8UVaCsyFo/3wF2TXdgFcOAr3 xDIdhHCCoanRVFZ+gFAwIw== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +ddnsc.csas.cz. IN AAAA +SECTION AUTHORITY +c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN NSEC3 1 0 1 31245099125aedf7 c1c03am0n36kncp4iqb4buoqo1ectql5 TXT +c1c03am0n36kncp4iqb4buoqo1ectql4.csas.cz. 120 IN RRSIG NSEC3 7 3 120 20190702130338 20190625130338 26663 csas.cz. FKjWbcw5aP2HzHFy2t+M462dxM1ph0FW 02Tohh/aJQOp1iKQOi6u1V2tI3H9CMXW xeIAktZ+xiUDRYLX50fNuJZMaSsn7r5A LYjVAKGzwMPncIf6IlEDYkj1I1rdp6z8 LvWsWNO1wfIPq1Dw2geN60bcz3D7r/sY WfjU/7jO9f0nekZZXI2qFsMSYd9Dkaq7 mlpP0NrWnUbCjL+BfuLFNebh8g3D8f5w Tq3R9czwW5YTVXUquBIrjiZ0Ko9INgQ/ 4pvJqJ1bsTpmzdODfAssEtpu+es4wLwt ZTe8Ll9VeDB20RqEnAyHZwQRXXVF2t+F vdJU7Desbpu6rElA7IXwRw== +csas.cz. 120 IN RRSIG SOA 7 2 120 20190630054550 20190623054550 26663 csas.cz. c/sxvp5WLJOsDGgnhxPOk9oBwXRtsUXa enyWg5rd8yBcquHqfFKQu1v8wEPjJjAH B6joG1tJXq99nxtCN4jlDipPKLIzWxba aYIxE8Pab199qiHrR5vxO4KgPxRXbg5d gzIVrrhB+h23DZDacQ+l+kQWSAcycjPh xFvNjAZrH4obU/F+jHt4ix5XqEVuDrPQ YTGBGEUpl7YbcyaROzVP3dtCQZamkfaB CQYoNAJlNw6YFG1qulPm3pn3jJHhu88f dFgCisWfp7TjMYn7Id7aYJtliagE47xu ASnhOtaeXAVxDGUIkOI5u8uUCC/jAiHr MgARE5rcqh2AIZeSv0BiMQ== +csas.cz. 120 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +csas.cz. IN NS +SECTION ANSWER +csas.cz. 7200 IN NS ddnsa.csas.cz. +csas.cz. 7200 IN NS ddnsb.csas.cz. +csas.cz. 7200 IN NS ddnsc.csas.cz. +csas.cz. 7200 IN NS ddnsd.csas.cz. +csas.cz. 7200 IN RRSIG NS 7 2 7200 20190630180929 20190623180929 26663 csas.cz. PLqM9UHNFbb8GmE+SlzSCjAEKYsklbgt CnWf9G26HkwtacOyJkIHe+T0m94rJZTd 6Mnn32Sw/at6idSvVNGQfE6DIKr2rtK6 lJNe0HPMxYWC9Tr5zpzW1/SjLVooMw6n m8K+18RBI33PBI69UgXyuePnWefdTYOJ g4SK3rR2wUlFxnELEFGfYkytZ6tLi1Cd bTgch93lDnXNBRZ2t/mu5jPyv4NTdKCo WgIMJJcuFdPr/YRVRaemkVEup7qVYImk pa4n+7MMERTL/dw+GxtnZ2YKqyxcepYo rPib3FSTaOFZjEPqNPDNfXXYW+bPmWFP 9ESqUtgmvZ1rMDZbr8lbgQ== +SECTION ADDITIONAL +ddnsa.csas.cz. 7200 IN A 194.50.240.64 +ddnsa.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. QJCNptf+bgoFFzW6vh6lMnevBqaHq1Qk p7UB7hJZfqewhVJsf4/aZlUJg9Ulq990 xe1K+Vw2H7zFKRmS+BhLL0NVS6F/uo3g VWU7UkiLCUdICMNmBlUfv6dTJmovHydF DeCtS8eunKTYKnvSklmr/aLKnFFEaeoi SUF8hkHM2fADZekxqTEMS2ATjlY0rbTb biDd4c1tZdSDeUV7z4B4pHVdgVFBOi6+ kL4MtMM2AY4o9h31jOUGFnfA0cJPmxNN Cx+qgBAl0zKL9+uFrBqB6nYgmd0a1pRa UEQCcVVKkSjDX3gWHtO/nqflFmyDNV4Y OlVLcHVCDNqRtwIRwucUOg== +ddnsb.csas.cz. 7200 IN A 194.50.240.192 +ddnsb.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. CXelkXBmt3nR60+gTwRcTXTVH1OBpfAE McYGfcEmxk8t+wFwLrCfM+6mJUWbV3a8 cIggoBHU8gJxarnIX4K5bXNel2QRzlTa +qTTPPTxH5LwHayDwoo5edk6c2HkCrY3 qChg5SyjuNxxsF4ybqvqIU0d/kM6wqG7 pKPmplD9BNJmzVIVQ8aTBMhdrvIcqK/f 81TGgNxMqJxfpTYKmnA8vVqpJ3C1kbfn no+ux39NY7Wj58NwI+UIcDlmBj414MSz Z4wEfYSgtVnEA8fO+ufZ3jaxjk6NClz+ XMP1gYj/y08bj0h5ACIKJqci2uqPujoi TNBYzQWn6LVPqNIM8O7eSg== +ddnsc.csas.cz. 7200 IN A 194.50.240.66 +ddnsc.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. AHQJp3i/UzKmjm/hhmEM1mhV7gPAq2rX 0z4ZOF+ZDyL57nXSHnzGqz4sdd3Q0E1H pmGENdgiOR1Grabo6X3QIp7mZbuAR14T 5TQYHSDoTZ+aTOkqvxCxfUCpEYLVHlbP whE+ntazt0gmkko3eGUBMefMv+JVmuwy tirS7pxlNL1VRnKtbfDsWJ2zmJuur/WK wGzHCMybt4fITB0Og/I9pnwMwykdxhpF bo/MQAa35oTefzvWsD3uFKOhrAc7CP2N MyqDFzv0QDN00s0yFXHHxNg3QFXLAg16 4khZaKT076k+F5N/ufsoIeU/AbByx82T PxpLg8NCh9nNvzgqoCEccw== +ddnsd.csas.cz. 7200 IN A 194.50.240.194 +ddnsd.csas.cz. 7200 IN RRSIG A 7 3 7200 20190630180929 20190623180929 26663 csas.cz. nsWIVa/SusXOatYzHtX8IPkETOBo90yd Zz8ce1PQhUawbQamihm1di90qJSQJ/i4 QCdL5ulxKJdMv8jLBjIBGe1H08d43luD OmLwkiBNoROZ1apKKabSQAmJTuwIxZCD sqYti2+rEbmOaRC1n96fIH2HWL9pYAnn C0GrvoWEDeVkSHI70Ei9CUCpUNOrPzhS BZc3PrB0DhojkzlXj359e4OhO1gH2QDp 2Uj05suhlIEzQf3lsvvIRUOrMPG2i6Fh j3yThN21+kuVyasrsN5Pv6Dp52U1k60l Y7AuwQwMUXrsdrK3/15DyxSS+pHenpsq cBI3Rb8P4Z6uVxZv9sQ4rQ== +ENTRY_END + + + + +RANGE_END + + + +; Group's zones: +; com. +; net. +; Server names: +; a.gtld-servers.net. +; j.gtld-servers.net. +; e.gtld-servers.net. +; i.gtld-servers.net. +; d.gtld-servers.net. +; m.gtld-servers.net. +; h.gtld-servers.net. +; c.gtld-servers.net. +; l.gtld-servers.net. +; g.gtld-servers.net. +; b.gtld-servers.net. +; k.gtld-servers.net. +; f.gtld-servers.net. +RANGE_BEGIN 0 1000 + ADDRESS 2001:502:8cc::30 + ADDRESS 2001:503:eea3::30 + ADDRESS 192.5.6.30 + ADDRESS 192.33.14.30 + ADDRESS 192.43.172.30 + ADDRESS 192.12.94.30 + ADDRESS 192.48.79.30 + ADDRESS 2001:502:1ca1::30 + ADDRESS 192.54.112.30 + ADDRESS 2001:500:856e::30 + ADDRESS 2001:503:a83e::2:30 + ADDRESS 192.52.178.30 + ADDRESS 2001:503:d2d::30 + ADDRESS 192.26.92.30 + ADDRESS 192.41.162.30 + ADDRESS 192.31.80.30 + ADDRESS 2001:503:83eb::30 + ADDRESS 192.42.93.30 + ADDRESS 2001:503:39c1::30 + ADDRESS 2001:503:231d::2:30 + ADDRESS 192.35.51.30 + ADDRESS 2001:500:d937::30 + ADDRESS 2001:503:d414::30 + ADDRESS 2001:502:7094::30 + ADDRESS 2001:501:b1f9::30 + ADDRESS 192.55.83.30 + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +nstld.com. IN DS +SECTION AUTHORITY +5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG +5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20190630044250 20190623033250 3800 com. NlBOkX84YgGooJJ2vp+Z/O16Vkz6z1gC Jy1Va3fJyEXfZr/GIm8J3KJ6Eq+xxp1A x3ZWxwUjNH3TGUEme7pDrmusqRpx/TZF Za3dVAYIvsaVgIWtDCn4BLBPrg0HXcon HE60KLgWGQmezzFKrNsy5Tzz9TajUSgQ uOTQHB7TFDg= +CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM +CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20190702044530 20190625033530 3800 com. BMWhk6USUrb7TNJ3dSObn8QEPWvpzedW kP9i4RRPz7V9c2yVPmHSPt29QKsHOYTg iF4uyHt+K8RK8DBIziB19nrOjbb8iRDY 7m5koEj/OrS2peMuF6rqRRmkI6SY/ACy XHb/hRGE4tZd2gThNb7evZkk02IVuhEo njO3NBjCrsw= +com. 900 IN RRSIG SOA 8 1 900 20190702140912 20190625125912 3800 com. c6kEiaL24fAOXZf4AexmGfQejNxB+Na5 Omftkar0u1SFkd7I03ieGTsJt/aiFVND ucQklNtxUqTC4SQpGLmNYlzIDRvb2vYC GL7tSomPB/Tt4xYczPvNIOJKQOtFAjoL hJn5hj1jCo56iBD5OmbLwQcq8XI/W7xs yvTMfjKpeEQ= +com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471752 1800 900 604800 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +root-servers.net. IN DS +SECTION AUTHORITY +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM= +T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG +T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20190630054523 20190623043523 2129 net. adpeQf+K6Hr5amhmF9DNK56LVWWnfGHK Dz9t9e7swG/P+4clc4yMKmUvK0OF9aTA kBzDwnzeB+FT+nsg1cWdibs4559AKQCL RtNErPhZRMojUFo6TLM9lQoXhv9i5rZB AJGmirHgSwiAvaUK7tgxX3nr1Atahyew iwHDQIVPhw4= +net. 900 IN RRSIG SOA 8 1 900 20190702140916 20190625125916 2129 net. cMaAZOeBq2v9urE/L5RZEBRSTmY4/MMJ ADm+GUhaqP3FQ0RD3fO6IU7qdP3jCmlZ QmCl68ZVaMyZvVIcNcv7fokWbqTm9r4j 2NB0W9j/B/ZIOzCV4myDqaylU62tNTUA okGZMzclPCSd2n8ZDHZ3RysudhiZ/8WG FVdsHHtp67c= +net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471756 1800 900 604800 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +net. IN DS +SECTION AUTHORITY +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM= +net. 900 IN RRSIG SOA 8 1 900 20190702140916 20190625125916 2129 net. cMaAZOeBq2v9urE/L5RZEBRSTmY4/MMJ ADm+GUhaqP3FQ0RD3fO6IU7qdP3jCmlZ QmCl68ZVaMyZvVIcNcv7fokWbqTm9r4j 2NB0W9j/B/ZIOzCV4myDqaylU62tNTUA okGZMzclPCSd2n8ZDHZ3RysudhiZ/8WG FVdsHHtp67c= +net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471756 1800 900 604800 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +com. IN DS +SECTION AUTHORITY +CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM +CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20190702044530 20190625033530 3800 com. BMWhk6USUrb7TNJ3dSObn8QEPWvpzedW kP9i4RRPz7V9c2yVPmHSPt29QKsHOYTg iF4uyHt+K8RK8DBIziB19nrOjbb8iRDY 7m5koEj/OrS2peMuF6rqRRmkI6SY/ACy XHb/hRGE4tZd2gThNb7evZkk02IVuhEo njO3NBjCrsw= +com. 900 IN RRSIG SOA 8 1 900 20190702140912 20190625125912 3800 com. c6kEiaL24fAOXZf4AexmGfQejNxB+Na5 Omftkar0u1SFkd7I03ieGTsJt/aiFVND ucQklNtxUqTC4SQpGLmNYlzIDRvb2vYC GL7tSomPB/Tt4xYczPvNIOJKQOtFAjoL hJn5hj1jCo56iBD5OmbLwQcq8XI/W7xs yvTMfjKpeEQ= +com. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471752 1800 900 604800 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +net. IN DNSKEY +SECTION ANSWER +net. 86400 IN DNSKEY 256 3 8 AQPB6mADOfWU6hTegl+pTl1wtjTll+Zn WIuRb8+cU9XNWNPpc3mX+rUqPeiw0RpK kD4QkTqTefWjMqjXMvYn2TxX4V4FMQXY MJr0bgiZXGosA9C9Aa7RgYyt4GJCToXq lM+mTqBjXDkh7yBa8I2X3p6Tt/PoKhiq CtmNl6sggTanJw== +net. 86400 IN DNSKEY 257 3 8 AQOYBnzqWXIEj6mlgXg4LWC0HP2n8eK8 XqgHlmJ/69iuIHsa1TrHDG6TcOra/pye GKwH0nKZhTmXSuUFGh9BCNiwVDuyyb6O BGy2Nte9Kr8NwWg4q+zhSoOf4D+gC9dE zg0yFdwT0DKEvmNPt0K4jbQDS4Yimb+u PKuF6yieWWrPYYCrv8C9KC8JMze2uT6N uWBfsl2fDUoV4l65qMww06D7n+p7Rbdw WkAZ0fA63mXVXBZF6kpDtsYD7SUB9jhh fLQE/r85bvg3FaSs5Wi2BaqN06SzGWI1 DHu7axthIOeHwg00zxlhTpoYCH0ldoQz +S65zWYi/fRJiyLSBb6JZOvn +net. 86400 IN RRSIG DNSKEY 8 1 86400 20190704153857 20190619153357 35886 net. T0Dcg9EVsoYzu+hywAW4mW11X/+oW/zt 0tQ8TdsKgY/5+/RL0tZCoU1EqbkBfM5h PxZgupQ0SQ//haveGagTgXOAOpa2nmUa o26dJC0xyZRTHuViy5708DONc88JZt+U pAgFcmJYjTXLu2QNywtyCXhcjnCuYAVG lTrarCn0rzW7PZp94xyGTCegkK9TysCt aqnIS0z/LVA2PjF+5etoEl7nWxCa1iUY 7as3zQ8CYlSDLwf7Sx4pUA/4hLZftwdO gNvb/pUdy7Zy/+6SGS3K4CPFkWG9kfs/ /76iMG6GkV2loGJApIFtYlui5iFaNfIM YBTD29dqC2I9ofe4WJnmpg== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +com. IN DNSKEY +SECTION ANSWER +com. 86400 IN DNSKEY 256 3 8 AQOcWJruwENIaapq3h3lKJlflLx6rWJz 2aKRBV6CBJRTxZu4ge2iDX164dQ7Hpc9 b8C9z2gqWyx1XyjvbQisgSid24voeUHQ gD0weedVDQjD6B9By7zMI6Yz+cM/w6H8 zB8ZRn6qZuWZAxFOjKvzoz+3vf32tyZE 7QmLFnXDgQpFxw== +com. 86400 IN DNSKEY 257 3 8 AQPDzldNmMvZFX4NcNJ0uEnKDg7tmv/F 3MyQR0lpBmVcNcsIszxNFxsBfKNW9JYC Yqpik8366LE7VbIcNRzfp2h9OO8HRl+H +E08zauK8k7evWEmu/6od+2boggPoiEf GNyvNPaSI7FOIroDsnw/taggzHRX1Z7S OiOiPWPNIwSUyWOZ79VmcQ1GLkC6NlYv G3HwYmynQv6oFwGv/KELSw7ZSdrbTQ0H XvZbqMUI7BaMskmvgm1G7oKZ1YiF7O9i oVNc0+7ASbqmZN7Z98EGU/Qh2K/BgUe8 Hs0XVcdPKrtyYnoQHd2ynKPcMMlTEih2 /2HDHjRPJ2aywIpKNnv4oPo/ +com. 86400 IN RRSIG DNSKEY 8 1 86400 20190706182533 20190621182033 30909 com. v4xbl08Oyis8hHQ/7k9DuSLa75uMshqc V4783gXEEq1+dbgwBct8I2Td4+9mjIql fD1UO6Wu6VSYUtef39VQe4DuIWqtRrh/ WA/EOrrEY5Qieem9LTPL/zHWGQiILaHz CUHk1iUGFyZy4IRnZPkigTYKm1M7ZRXv qTTYSLemVZsna2/siDVYAdAhXWvJHQGl DkT3WDAvryFPpuEOrhUWkfhWAGy/ZsmD 87OiTX50TG/3ISEqFyzow/GZjViZnG5C tBmwdX/E8CIN6lVJV3LU3bMRYmuAHYEE lM+lVKAEyooxuRBNOdtZHD9tM8V6cfyd t89aE9LaiSn1DsFjUqFu/A== +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +gtld-servers.net. IN DS +SECTION AUTHORITY +5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG +5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN RRSIG NSEC3 8 2 86400 20190629054715 20190622043715 2129 net. fvRKJkn9D2H3DFGE0zpk/tAkyjaoEZY4 4TkN6XtCAibjzQS8R0SCaXmZlQQujnjG wp0Rjhy0gMQaFUrJ8QuUbJSDZQaicAl7 pCESVKd95GZOSgi07BXSKwdUMAPROSjz gDkYGzHcUB5Kfe23gkL2eQ05YVigHYhI l0YCHui1wHE= +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM= +net. 900 IN RRSIG SOA 8 1 900 20190702140916 20190625125916 2129 net. cMaAZOeBq2v9urE/L5RZEBRSTmY4/MMJ ADm+GUhaqP3FQ0RD3fO6IU7qdP3jCmlZ QmCl68ZVaMyZvVIcNcv7fokWbqTm9r4j 2NB0W9j/B/ZIOzCV4myDqaylU62tNTUA okGZMzclPCSd2n8ZDHZ3RysudhiZ/8WG FVdsHHtp67c= +net. 900 IN SOA a.gtld-servers.net. nstld.verisign-grs.com. 1561471756 1800 900 604800 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR RD NOERROR +SECTION QUESTION +gtld-servers.net. IN NS +SECTION AUTHORITY +5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN NSEC3 1 1 0 - 5qdppotuk27kkp9ligtrb0k1cbvm9cim NS DS RRSIG +5QDO29Q2PS5ARBKHB6R0BRN6NDSTSN90.net. 86400 IN RRSIG NSEC3 8 2 86400 20190629054715 20190622043715 2129 net. fvRKJkn9D2H3DFGE0zpk/tAkyjaoEZY4 4TkN6XtCAibjzQS8R0SCaXmZlQQujnjG wp0Rjhy0gMQaFUrJ8QuUbJSDZQaicAl7 pCESVKd95GZOSgi07BXSKwdUMAPROSjz gDkYGzHcUB5Kfe23gkL2eQ05YVigHYhI l0YCHui1wHE= +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM= +gtld-servers.net. 172800 IN NS av1.nstld.com. +gtld-servers.net. 172800 IN NS av2.nstld.com. +gtld-servers.net. 172800 IN NS av3.nstld.com. +gtld-servers.net. 172800 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR RD NOERROR +SECTION QUESTION +root-servers.net. IN NS +SECTION AUTHORITY +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN NSEC3 1 1 0 - a1ruuffjkct2q54p78f8ejgj8jbk7i8b NS SOA RRSIG DNSKEY NSEC3PARAM +A1RT98BS5QGC9NFI51S9HCI47ULJG6JH.net. 86400 IN RRSIG NSEC3 8 2 86400 20190702055539 20190625044539 2129 net. KgEWjLXuYdPBhlNh2epfnKU879hg4GGf F4m4Fo7ZW+S3uhNqq8pF7sMJCvSs8ZZA Ctcm88XThCeIAxDxLZ5moOlMIWaweVX3 7B7s3mw+3K0cnkYF6J4FqBO8o7x6J3i2 c6kxI3q0DKub23GcXpWZu3x2yIkWuN0I ZgceikGAPpM= +T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN NSEC3 1 1 0 - t2ukct9k5i0uhv7b3m3na6jaigdjm0gr NS DS RRSIG +T2UF21DR03E0BNPB42UQMVUF38P2TA8D.net. 86400 IN RRSIG NSEC3 8 2 86400 20190630054523 20190623043523 2129 net. adpeQf+K6Hr5amhmF9DNK56LVWWnfGHK Dz9t9e7swG/P+4clc4yMKmUvK0OF9aTA kBzDwnzeB+FT+nsg1cWdibs4559AKQCL RtNErPhZRMojUFo6TLM9lQoXhv9i5rZB AJGmirHgSwiAvaUK7tgxX3nr1Atahyew iwHDQIVPhw4= +root-servers.net. 172800 IN NS a.root-servers.net. +root-servers.net. 172800 IN NS b.root-servers.net. +root-servers.net. 172800 IN NS c.root-servers.net. +root-servers.net. 172800 IN NS d.root-servers.net. +root-servers.net. 172800 IN NS e.root-servers.net. +root-servers.net. 172800 IN NS f.root-servers.net. +root-servers.net. 172800 IN NS g.root-servers.net. +root-servers.net. 172800 IN NS h.root-servers.net. +root-servers.net. 172800 IN NS i.root-servers.net. +root-servers.net. 172800 IN NS j.root-servers.net. +root-servers.net. 172800 IN NS k.root-servers.net. +root-servers.net. 172800 IN NS l.root-servers.net. +root-servers.net. 172800 IN NS m.root-servers.net. +SECTION ADDITIONAL +a.root-servers.net. 172800 IN A 198.41.0.4 +a.root-servers.net. 172800 IN AAAA 2001:503:ba3e::2:30 +b.root-servers.net. 172800 IN A 199.9.14.201 +b.root-servers.net. 172800 IN AAAA 2001:500:200::b +c.root-servers.net. 172800 IN A 192.33.4.12 +c.root-servers.net. 172800 IN AAAA 2001:500:2::c +d.root-servers.net. 172800 IN A 199.7.91.13 +d.root-servers.net. 172800 IN AAAA 2001:500:2d::d +e.root-servers.net. 172800 IN A 192.203.230.10 +e.root-servers.net. 172800 IN AAAA 2001:500:a8::e +f.root-servers.net. 172800 IN A 192.5.5.241 +f.root-servers.net. 172800 IN AAAA 2001:500:2f::f +g.root-servers.net. 172800 IN A 192.112.36.4 +g.root-servers.net. 172800 IN AAAA 2001:500:12::d0d +h.root-servers.net. 172800 IN A 198.97.190.53 +h.root-servers.net. 172800 IN AAAA 2001:500:1::53 +i.root-servers.net. 172800 IN A 192.36.148.17 +i.root-servers.net. 172800 IN AAAA 2001:7fe::53 +j.root-servers.net. 172800 IN A 192.58.128.30 +j.root-servers.net. 172800 IN AAAA 2001:503:c27::2:30 +k.root-servers.net. 172800 IN A 193.0.14.129 +k.root-servers.net. 172800 IN AAAA 2001:7fd::1 +l.root-servers.net. 172800 IN A 199.7.83.42 +l.root-servers.net. 172800 IN AAAA 2001:500:9f::42 +m.root-servers.net. 172800 IN A 202.12.27.33 +m.root-servers.net. 172800 IN AAAA 2001:dc3::35 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR RD NOERROR +SECTION QUESTION +nstld.com. IN NS +SECTION AUTHORITY +5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN NSEC3 1 1 0 - 5v13q049b9ittui4fbdtm34dtev47bgj NS DS RRSIG +5V12UURISSGGLPAS52GE1V3R0V7KR5BS.com. 86400 IN RRSIG NSEC3 8 2 86400 20190630044250 20190623033250 3800 com. NlBOkX84YgGooJJ2vp+Z/O16Vkz6z1gC Jy1Va3fJyEXfZr/GIm8J3KJ6Eq+xxp1A x3ZWxwUjNH3TGUEme7pDrmusqRpx/TZF Za3dVAYIvsaVgIWtDCn4BLBPrg0HXcon HE60KLgWGQmezzFKrNsy5Tzz9TajUSgQ uOTQHB7TFDg= +CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN NSEC3 1 1 0 - ck0q1gin43n1arrc9osm6qpqr81h5m9a NS SOA RRSIG DNSKEY NSEC3PARAM +CK0POJMG874LJREF7EFN8430QVIT8BSM.com. 86400 IN RRSIG NSEC3 8 2 86400 20190702044530 20190625033530 3800 com. BMWhk6USUrb7TNJ3dSObn8QEPWvpzedW kP9i4RRPz7V9c2yVPmHSPt29QKsHOYTg iF4uyHt+K8RK8DBIziB19nrOjbb8iRDY 7m5koEj/OrS2peMuF6rqRRmkI6SY/ACy XHb/hRGE4tZd2gThNb7evZkk02IVuhEo njO3NBjCrsw= +nstld.com. 172800 IN NS av1.nstld.com. +nstld.com. 172800 IN NS av2.nstld.com. +nstld.com. 172800 IN NS av3.nstld.com. +nstld.com. 172800 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 172800 IN A 192.42.177.30 +av1.nstld.com. 172800 IN AAAA 2001:500:124::30 +av2.nstld.com. 172800 IN A 192.42.178.30 +av2.nstld.com. 172800 IN AAAA 2001:500:125::30 +av3.nstld.com. 172800 IN A 192.82.133.30 +av3.nstld.com. 172800 IN AAAA 2001:500:126::30 +av4.nstld.com. 172800 IN A 192.82.134.30 +av4.nstld.com. 172800 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +net. IN NS +SECTION ANSWER +net. 172800 IN NS a.gtld-servers.net. +net. 172800 IN NS b.gtld-servers.net. +net. 172800 IN NS c.gtld-servers.net. +net. 172800 IN NS d.gtld-servers.net. +net. 172800 IN NS e.gtld-servers.net. +net. 172800 IN NS f.gtld-servers.net. +net. 172800 IN NS g.gtld-servers.net. +net. 172800 IN NS h.gtld-servers.net. +net. 172800 IN NS i.gtld-servers.net. +net. 172800 IN NS j.gtld-servers.net. +net. 172800 IN NS k.gtld-servers.net. +net. 172800 IN NS l.gtld-servers.net. +net. 172800 IN NS m.gtld-servers.net. +net. 172800 IN RRSIG NS 8 1 172800 20190630055417 20190623044417 2129 net. WUAzfzoslC7YpzfY7qJ+vPaYpL/TN1fq Ak97qaEsQbPEka9AfUyL/ZKgGucOrDmB e0GK55jGT1B1XXiQasdlB8/SThSPm+Oc V/aQ8zUopPJ6gzCCRfEZOWCRvRbXa3am f6apMdig+NSxXgYQpVjZmka8XX8xDJar 3c4G5gZS9rA= +SECTION ADDITIONAL +a.gtld-servers.net. 172800 IN A 192.5.6.30 +a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 +b.gtld-servers.net. 172800 IN A 192.33.14.30 +b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 +c.gtld-servers.net. 172800 IN A 192.26.92.30 +c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30 +d.gtld-servers.net. 172800 IN A 192.31.80.30 +d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30 +e.gtld-servers.net. 172800 IN A 192.12.94.30 +e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30 +f.gtld-servers.net. 172800 IN A 192.35.51.30 +f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30 +g.gtld-servers.net. 172800 IN A 192.42.93.30 +g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30 +h.gtld-servers.net. 172800 IN A 192.54.112.30 +h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30 +i.gtld-servers.net. 172800 IN A 192.43.172.30 +i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30 +j.gtld-servers.net. 172800 IN A 192.48.79.30 +j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30 +k.gtld-servers.net. 172800 IN A 192.52.178.30 +k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30 +l.gtld-servers.net. 172800 IN A 192.41.162.30 +l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30 +m.gtld-servers.net. 172800 IN A 192.55.83.30 +m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +com. IN NS +SECTION ANSWER +com. 172800 IN NS a.gtld-servers.net. +com. 172800 IN NS b.gtld-servers.net. +com. 172800 IN NS c.gtld-servers.net. +com. 172800 IN NS d.gtld-servers.net. +com. 172800 IN NS e.gtld-servers.net. +com. 172800 IN NS f.gtld-servers.net. +com. 172800 IN NS g.gtld-servers.net. +com. 172800 IN NS h.gtld-servers.net. +com. 172800 IN NS i.gtld-servers.net. +com. 172800 IN NS j.gtld-servers.net. +com. 172800 IN NS k.gtld-servers.net. +com. 172800 IN NS l.gtld-servers.net. +com. 172800 IN NS m.gtld-servers.net. +com. 172800 IN RRSIG NS 8 1 172800 20190702044530 20190625033530 3800 com. F4MEGl13z9h8iv22sko8S8/JjSskipqt COrmfpx4p5XeRutUOpr/6wAEdSXWJ7yu 5Z/PMTBDjTo37WxfEhyvvYyiOLTzYOf+ AvFeeGDAxdOAlfjQ+6etggDPz1bsqIhE 2FX5i7dhfk0WYshBIUqCJmmPMdnVgLNN Bh4zYoT5irQ= +SECTION ADDITIONAL +a.gtld-servers.net. 172800 IN A 192.5.6.30 +a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30 +b.gtld-servers.net. 172800 IN A 192.33.14.30 +b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30 +c.gtld-servers.net. 172800 IN A 192.26.92.30 +c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30 +d.gtld-servers.net. 172800 IN A 192.31.80.30 +d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30 +e.gtld-servers.net. 172800 IN A 192.12.94.30 +e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30 +f.gtld-servers.net. 172800 IN A 192.35.51.30 +f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30 +g.gtld-servers.net. 172800 IN A 192.42.93.30 +g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30 +h.gtld-servers.net. 172800 IN A 192.54.112.30 +h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30 +i.gtld-servers.net. 172800 IN A 192.43.172.30 +i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30 +j.gtld-servers.net. 172800 IN A 192.48.79.30 +j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30 +k.gtld-servers.net. 172800 IN A 192.52.178.30 +k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30 +l.gtld-servers.net. 172800 IN A 192.41.162.30 +l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30 +m.gtld-servers.net. 172800 IN A 192.55.83.30 +m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30 +ENTRY_END + + + + +RANGE_END + + + +; Group's zones: +; gtld-servers.net. +; nstld.com. +; Server names: +; av1.nstld.com. +; av2.nstld.com. +; av3.nstld.com. +; av4.nstld.com. +RANGE_BEGIN 0 1000 + ADDRESS 192.42.178.30 + ADDRESS 2001:500:125::30 + ADDRESS 192.82.133.30 + ADDRESS 192.42.177.30 + ADDRESS 2001:500:124::30 + ADDRESS 192.82.134.30 + ADDRESS 2001:500:126::30 + ADDRESS 2001:500:127::30 + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +h.gtld-servers.net. IN A +SECTION ANSWER +h.gtld-servers.net. 86400 IN A 192.54.112.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +i.gtld-servers.net. IN AAAA +SECTION ANSWER +i.gtld-servers.net. 86400 IN AAAA 2001:503:39c1::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av3.nstld.com. IN A +SECTION ANSWER +av3.nstld.com. 300 IN A 192.82.133.30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN A 192.42.178.30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN A 192.82.134.30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av1.nstld.com. IN A +SECTION ANSWER +av1.nstld.com. 300 IN A 192.42.177.30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN A 192.42.178.30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN A 192.82.133.30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN A 192.82.134.30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +j.gtld-servers.net. IN AAAA +SECTION ANSWER +j.gtld-servers.net. 86400 IN AAAA 2001:502:7094::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av2.nstld.com. IN AAAA +SECTION ANSWER +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN A 192.42.178.30 +av3.nstld.com. 300 IN A 192.82.133.30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN A 192.82.134.30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +k.gtld-servers.net. IN AAAA +SECTION ANSWER +k.gtld-servers.net. 86400 IN AAAA 2001:503:d2d::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av1.nstld.com. IN NS +SECTION AUTHORITY +nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.gtld-servers.net. IN AAAA +SECTION ANSWER +f.gtld-servers.net. 86400 IN AAAA 2001:503:d414::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +j.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +l.gtld-servers.net. IN AAAA +SECTION ANSWER +l.gtld-servers.net. 86400 IN AAAA 2001:500:d937::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.gtld-servers.net. IN A +SECTION ANSWER +f.gtld-servers.net. 86400 IN A 192.35.51.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +e.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +i.gtld-servers.net. IN A +SECTION ANSWER +i.gtld-servers.net. 86400 IN A 192.43.172.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.gtld-servers.net. IN AAAA +SECTION ANSWER +d.gtld-servers.net. 86400 IN AAAA 2001:500:856e::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +m.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av3.nstld.com. IN NS +SECTION AUTHORITY +nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +g.gtld-servers.net. IN A +SECTION ANSWER +g.gtld-servers.net. 86400 IN A 192.42.93.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +j.gtld-servers.net. IN A +SECTION ANSWER +j.gtld-servers.net. 86400 IN A 192.48.79.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +f.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av2.nstld.com. IN NS +SECTION AUTHORITY +nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +h.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av1.nstld.com. IN AAAA +SECTION ANSWER +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av2.nstld.com. 300 IN A 192.42.178.30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN A 192.82.133.30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN A 192.82.134.30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +k.gtld-servers.net. IN A +SECTION ANSWER +k.gtld-servers.net. 86400 IN A 192.52.178.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +h.gtld-servers.net. IN AAAA +SECTION ANSWER +h.gtld-servers.net. 86400 IN AAAA 2001:502:8cc::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.gtld-servers.net. IN AAAA +SECTION ANSWER +a.gtld-servers.net. 86400 IN AAAA 2001:503:a83e::2:30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +l.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.gtld-servers.net. IN AAAA +SECTION ANSWER +b.gtld-servers.net. 86400 IN AAAA 2001:503:231d::2:30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +l.gtld-servers.net. IN A +SECTION ANSWER +l.gtld-servers.net. 86400 IN A 192.41.162.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +d.gtld-servers.net. IN A +SECTION ANSWER +d.gtld-servers.net. 86400 IN A 192.31.80.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +e.gtld-servers.net. IN AAAA +SECTION ANSWER +e.gtld-servers.net. 86400 IN AAAA 2001:502:1ca1::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +k.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av3.nstld.com. IN AAAA +SECTION ANSWER +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN A 192.42.178.30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN A 192.82.133.30 +av4.nstld.com. 300 IN A 192.82.134.30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.gtld-servers.net. IN A +SECTION ANSWER +a.gtld-servers.net. 86400 IN A 192.5.6.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av4.nstld.com. IN AAAA +SECTION ANSWER +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN A 192.42.178.30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN A 192.82.133.30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN A 192.82.134.30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +g.gtld-servers.net. IN AAAA +SECTION ANSWER +g.gtld-servers.net. 86400 IN AAAA 2001:503:eea3::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.gtld-servers.net. IN A +SECTION ANSWER +c.gtld-servers.net. 86400 IN A 192.26.92.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av4.nstld.com. IN NS +SECTION AUTHORITY +nstld.com. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2018073100 7200 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +a.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +m.gtld-servers.net. IN AAAA +SECTION ANSWER +m.gtld-servers.net. 86400 IN AAAA 2001:501:b1f9::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +m.gtld-servers.net. IN A +SECTION ANSWER +m.gtld-servers.net. 86400 IN A 192.55.83.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +i.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +g.gtld-servers.net. IN NS +SECTION AUTHORITY +gtld-servers.net. 86400 IN SOA av4.nstld.com. nstld.verisign-grs.com. 2017061500 3600 900 1209600 86400 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +c.gtld-servers.net. IN AAAA +SECTION ANSWER +c.gtld-servers.net. 86400 IN AAAA 2001:503:83eb::30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av2.nstld.com. IN A +SECTION ANSWER +av2.nstld.com. 300 IN A 192.42.178.30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN A 192.82.133.30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN A 192.82.134.30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +av4.nstld.com. IN A +SECTION ANSWER +av4.nstld.com. 300 IN A 192.82.134.30 +SECTION AUTHORITY +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN A 192.42.178.30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN A 192.82.133.30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +b.gtld-servers.net. IN A +SECTION ANSWER +b.gtld-servers.net. 86400 IN A 192.33.14.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH qname qtype +ADJUST copy_id +REPLY QR AA RD NOERROR +SECTION QUESTION +e.gtld-servers.net. IN A +SECTION ANSWER +e.gtld-servers.net. 86400 IN A 192.12.94.30 +SECTION AUTHORITY +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +gtld-servers.net. IN NS +SECTION ANSWER +gtld-servers.net. 86400 IN NS av1.nstld.com. +gtld-servers.net. 86400 IN NS av2.nstld.com. +gtld-servers.net. 86400 IN NS av3.nstld.com. +gtld-servers.net. 86400 IN NS av4.nstld.com. +ENTRY_END + + +ENTRY_BEGIN +MATCH subdomain +ADJUST copy_id copy_query +REPLY QR AA RD NOERROR +SECTION QUESTION +nstld.com. IN NS +SECTION ANSWER +nstld.com. 86400 IN NS av1.nstld.com. +nstld.com. 86400 IN NS av2.nstld.com. +nstld.com. 86400 IN NS av3.nstld.com. +nstld.com. 86400 IN NS av4.nstld.com. +SECTION ADDITIONAL +av1.nstld.com. 300 IN A 192.42.177.30 +av1.nstld.com. 300 IN AAAA 2001:500:124::30 +av2.nstld.com. 300 IN A 192.42.178.30 +av2.nstld.com. 300 IN AAAA 2001:500:125::30 +av3.nstld.com. 300 IN A 192.82.133.30 +av3.nstld.com. 300 IN AAAA 2001:500:126::30 +av4.nstld.com. 300 IN A 192.82.134.30 +av4.nstld.com. 300 IN AAAA 2001:500:127::30 +ENTRY_END + + + + +RANGE_END + + + + + +; Sequence of queries made by browser + +; 1st query for AAAA +STEP 10 QUERY +ENTRY_BEGIN +REPLY RD AD +SECTION QUESTION +csas.cz. IN AAAA +ENTRY_END + +; answer for AAAA contains minimally covering NSEC3 answer with incorrect bitmap +; it claims that csas.cz A RR is not present +STEP 11 CHECK_ANSWER +ENTRY_BEGIN +MATCH opcode flags rcode question answer +REPLY QR RD RA AD NOERROR +SECTION QUESTION +csas.cz. IN AAAA +SECTION AUTHORITY +csas.cz. 119 IN SOA ddnsa.csas.cz. domainservices.csas.cz. 2019061320 28800 1800 2592000 120 +ENTRY_END + +; 2nd query for A +STEP 21 QUERY +ENTRY_BEGIN +REPLY RD AD +SECTION QUESTION +csas.cz. IN A +ENTRY_END + +; check that A query gets an IP address +; this answer would be empty +; if minimally covering NSEC3 was not exempt from aggressive caching +STEP 22 CHECK_ANSWER +ENTRY_BEGIN +MATCH opcode flags rcode question answer +REPLY QR RD RA AD NOERROR +SECTION QUESTION +csas.cz. IN A +SECTION ANSWER +csas.cz. 120 IN A 194.50.240.198 +csas.cz. 120 IN A 194.50.240.70 +ENTRY_END + +SCENARIO_END diff --git a/lib/cache/test.integr/deckard.yaml b/lib/cache/test.integr/deckard.yaml new file mode 100644 index 0000000..df88f83 --- /dev/null +++ b/lib/cache/test.integr/deckard.yaml @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-3.0-or-later +programs: +- name: kresd + binary: kresd + additional: + - --noninteractive + templates: + - lib/cache/test.integr/kresd_config.j2 + - tests/integration/hints_zone.j2 + configs: + - config + - hints +noclean: True diff --git a/lib/cache/test.integr/kresd_config.j2 b/lib/cache/test.integr/kresd_config.j2 new file mode 100644 index 0000000..c4c286f --- /dev/null +++ b/lib/cache/test.integr/kresd_config.j2 @@ -0,0 +1,69 @@ +-- SPDX-License-Identifier: GPL-3.0-or-later +{% for TAF in TRUST_ANCHOR_FILES %} +-- trust_anchors.add_file('{{TAF}}') +{% endfor %} + +{% raw %} +-- Disable RFC5011 TA update +if ta_update then + modules.unload('ta_update') +end + +-- Disable RFC8145 signaling, scenario doesn't provide expected answers +if ta_signal_query then + modules.unload('ta_signal_query') +end + +-- Disable RFC8109 priming, scenario doesn't provide expected answers +if priming then + modules.unload('priming') +end + +-- Disable this module because it make one priming query +if detect_time_skew then + modules.unload('detect_time_skew') +end + +_hint_root_file('hints') +cache.size = 2*MB +log_level('debug') +policy.add(policy.all(policy.DEBUG_ALWAYS)) +{% endraw %} + +net = { '{{SELF_ADDR}}' } + +{% if DO_IP6 == "true" %} +net.ipv6 = true +{% else %} +net.ipv6 = false +{% endif %} + +{% if DO_IP4 == "true" %} +net.ipv4 = true +{% else %} +net.ipv4 = false +{% endif %} + +{% if QMIN == "false" %} +option('NO_MINIMIZE', true) +{% else %} +option('NO_MINIMIZE', false) +{% endif %} + + +-- Self-checks on globals +assert(help() ~= nil) +assert(worker.id ~= nil) +-- Self-checks on facilities +assert(cache.count() == 0) +assert(cache.stats() ~= nil) +assert(cache.backends() ~= nil) +assert(worker.stats() ~= nil) +assert(net.interfaces() ~= nil) +-- Self-checks on loaded stuff +assert(net.list()[1].transport.ip == '{{SELF_ADDR}}') +assert(#modules.list() > 0) +-- Self-check timers +ev = event.recurrent(1 * sec, function (ev) return 1 end) +event.cancel(ev) +ev = event.after(0, function (ev) return 1 end) diff --git a/lib/cache/util.h b/lib/cache/util.h new file mode 100644 index 0000000..3f81830 --- /dev/null +++ b/lib/cache/util.h @@ -0,0 +1,4 @@ +/* SPDX-License-Identifier: GPL-3.0-or-later */ +#include <libknot/packet/pkt.h> + +uint32_t packet_ttl(const knot_pkt_t *pkt); |