From: Karel Slany Date: Thu, 30 Jul 2015 14:06:04 +0000 (+0200) Subject: layer/validate: layer is issuing requests for missing DS records X-Git-Tag: v1.0.0-beta1~53^2~124 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=840dc2db65ee559b869226ae7ae0c16263febafc;p=thirdparty%2Fknot-resolver.git layer/validate: layer is issuing requests for missing DS records --- diff --git a/lib/layer/iterate.c b/lib/layer/iterate.c index fb4e38c6a..02f851430 100644 --- a/lib/layer/iterate.c +++ b/lib/layer/iterate.c @@ -193,6 +193,8 @@ static int update_cut(knot_pkt_t *pkt, const knot_rrset_t *rr, struct kr_request /* Update zone cut name */ if (!knot_dname_is_equal(rr->owner, cut->name)) { + mm_free(cut->pool, cut->parent_name); + cut->parent_name = cut->name; cut->name = NULL; kr_zonecut_set(cut, rr->owner); state = KNOT_STATE_DONE; } diff --git a/lib/layer/rrcache.c b/lib/layer/rrcache.c index 6710c0ea6..0defa46c3 100644 --- a/lib/layer/rrcache.c +++ b/lib/layer/rrcache.c @@ -243,7 +243,7 @@ static int stash_add(const knot_pkt_t *pkt, map_t *stash, const knot_rrset_t *rr if (ret <= 0 || ret >= KNOT_DNAME_MAXLEN) { return kr_error(EILSEQ); } - + /* Check if already exists */ knot_rrset_t *stashed = map_get(stash, key); if (!stashed) { diff --git a/lib/layer/validate.c b/lib/layer/validate.c index 39216a05e..7a3f66442 100644 --- a/lib/layer/validate.c +++ b/lib/layer/validate.c @@ -23,9 +23,11 @@ #include #include #include +#include #include "lib/dnssec.h" #include "lib/layer/iterate.h" +#include "lib/layer/validate.h" #include "lib/resolve.h" #include "lib/rplan.h" #include "lib/defines.h" @@ -626,6 +628,43 @@ static int validate_keyset(struct kr_query *qry, knot_pkt_t *answer) return kr_ok(); } +static const knot_dname_t *section_first_signer_name(knot_pkt_t *pkt, knot_section_t section_id) +{ + const knot_dname_t *sname = NULL; + const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id); + if (!sec) { + return sname; + } + + for (unsigned i = 0; i < sec->count; ++i) { + const knot_rrset_t *rr = knot_pkt_rr(sec, i); + if (rr->type != KNOT_RRTYPE_RRSIG) { + continue; + } + + sname = knot_rrsig_signer_name(&rr->rrs, 0); + break; + } + + return sname; +} + +static const knot_dname_t *first_rrsig_signer_name(knot_pkt_t *answer) +{ + const knot_dname_t *ans_sname = section_first_signer_name(answer, KNOT_ANSWER); + const knot_dname_t *auth_sname = section_first_signer_name(answer, KNOT_AUTHORITY); + + if (!ans_sname) { + return auth_sname; + } else if (!auth_sname) { + return ans_sname; + } else if (knot_dname_is_equal(ans_sname, auth_sname)) { + return ans_sname; + } else { + return NULL; + } +} + static int update_delegation(struct kr_query *qry, knot_pkt_t *answer) { int ret = kr_ok(); @@ -635,11 +674,13 @@ static int update_delegation(struct kr_query *qry, knot_pkt_t *answer) /* New trust anchor. */ knot_rrset_t *new_ds = NULL; - const knot_pktsection_t *sec = knot_pkt_section(answer, KNOT_AUTHORITY); + knot_section_t section_id = (knot_pkt_qtype(answer) == KNOT_RRTYPE_DS) ? KNOT_ANSWER : KNOT_AUTHORITY; + const knot_pktsection_t *sec = knot_pkt_section(answer, section_id); for (unsigned i = 0; i < sec->count; ++i) { const knot_rrset_t *rr = knot_pkt_rr(sec, i); if ((rr->type != KNOT_RRTYPE_DS) || - (knot_dname_cmp(rr->owner, cut->name) != 0)) { + (0)) { +// (knot_dname_cmp(rr->owner, cut->name) != 0)) { continue; } if (new_ds) { @@ -702,6 +743,22 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt) } } + /* Check whether the current zone cut holds keys that can be used + * for validation (i.e. RRSIG signer name matches key owner). + */ + const knot_dname_t *key_own = qry->zone_cut.key ? qry->zone_cut.key->owner : NULL; + const knot_dname_t *sig_name = first_rrsig_signer_name(pkt); + if (key_own && sig_name && !knot_dname_is_equal(key_own, sig_name)) { + mm_free(qry->zone_cut.pool, qry->zone_cut.missing_name); + qry->zone_cut.missing_name = knot_dname_copy(sig_name, qry->zone_cut.pool); + if (!qry->zone_cut.missing_name) { + return KNOT_STATE_FAIL; + } + qry->flags |= QUERY_AWAIT_DS; + qry->flags &= ~QUERY_RESOLVED; + return KNOT_STATE_CONSUME; + } + /* Check if this is a DNSKEY answer, check trust chain and store. */ uint16_t qtype = knot_pkt_qtype(pkt); if (qtype == KNOT_RRTYPE_DNSKEY) { @@ -730,18 +787,23 @@ static int validate(knot_layer_t *ctx, knot_pkt_t *pkt) } /* Update trust anchor. */ - if (qtype == KNOT_RRTYPE_NS) { - ret = update_delegation(qry, pkt); - if (ret != 0) { - return KNOT_STATE_FAIL; - } + ret = update_delegation(qry, pkt); + if (ret != 0) { + return KNOT_STATE_FAIL; + } - if (!qry->zone_cut.key) { - DEBUG_MSG("<= missing keys for new cut\n"); -#warning TODO: set QUERY_AWAIT_CUT for next query in plan ? + if ((qtype == KNOT_RRTYPE_DS) && (qry->parent != NULL) && (qry->parent->zone_cut.trust_anchor == NULL)) { + DEBUG_MSG("updating trust anchor in zone cut\n"); + qry->parent->zone_cut.trust_anchor = knot_rrset_copy(qry->zone_cut.trust_anchor, qry->parent->zone_cut.pool); + if (!qry->parent->zone_cut.trust_anchor) { + return KNOT_STATE_FAIL; } + /* Update zone cut name */ + mm_free(qry->parent->zone_cut.pool, qry->parent->zone_cut.name); + qry->parent->zone_cut.name = knot_dname_copy(qry->zone_cut.trust_anchor->owner, qry->parent->zone_cut.pool); } if ((qtype == KNOT_RRTYPE_DNSKEY) && (qry->parent != NULL) && (qry->parent->zone_cut.key == NULL)) { + DEBUG_MSG("updating keys in zone cut\n"); qry->parent->zone_cut.key = knot_rrset_copy(qry->zone_cut.key, qry->parent->zone_cut.pool); if (!qry->parent->zone_cut.key) { return KNOT_STATE_FAIL; diff --git a/lib/resolve.c b/lib/resolve.c index 03c76efe9..965ad5a9c 100644 --- a/lib/resolve.c +++ b/lib/resolve.c @@ -504,6 +504,28 @@ int kr_resolve_produce(struct kr_request *request, struct sockaddr **dst, int *t qry->flags &= ~QUERY_AWAIT_CUT; } + /* fetch missing DS record. */ + if ((qry->flags & QUERY_AWAIT_DS) && (qry->zone_cut.missing_name)) { + struct kr_query *next = kr_rplan_push(rplan, qry, qry->zone_cut.missing_name, KNOT_CLASS_IN, KNOT_RRTYPE_DS); + if (!next) { + return KNOT_STATE_FAIL; + } + kr_zonecut_set(&next->zone_cut, qry->zone_cut.parent_name); + int ret = kr_zonecut_copy(&next->zone_cut, &qry->zone_cut); + if (ret != 0) { + return KNOT_STATE_FAIL; + } + ret = kr_zonecut_copy_trust(&next->zone_cut, &qry->zone_cut); + if (ret != 0) { + return KNOT_STATE_FAIL; + } + /* The current trust anchor and keys cannot be used. */ + knot_rrset_free(&qry->zone_cut.key, qry->zone_cut.pool); + knot_rrset_free(&qry->zone_cut.trust_anchor, qry->zone_cut.pool); + qry->flags &= ~QUERY_AWAIT_DS; + return KNOT_STATE_PRODUCE; + } + /* Try to fetch missing DNSKEY. */ if (want_secured && !qry->zone_cut.key && qry->stype != KNOT_RRTYPE_DNSKEY) { struct kr_query *next = kr_rplan_push(rplan, qry, qry->zone_cut.name, KNOT_CLASS_IN, KNOT_RRTYPE_DNSKEY); diff --git a/lib/rplan.h b/lib/rplan.h index 214f8f1bf..f317fd617 100644 --- a/lib/rplan.h +++ b/lib/rplan.h @@ -39,7 +39,8 @@ X(EXPIRING , 1 << 9) /**< Query response is cached, but expiring. */ \ X(NO_EXPIRING, 1 << 10) /**< Do not use expiring cached records. */ \ X(DNSSEC_WANT , 1 << 11) /**< Want DNSSEC secured answer. */ \ - X(DNSSEC_BOGUS , 1 << 12) /**< Query response is DNSSEC bogus. */ + X(DNSSEC_BOGUS , 1 << 12) /**< Query response is DNSSEC bogus. */ \ + X(AWAIT_DS , 1 << 13) /**< Query is waiting for DS lookup. */ /** Query flags */ enum kr_query_flag { diff --git a/lib/zonecut.c b/lib/zonecut.c index c9d3bbe8d..10a4751d6 100644 --- a/lib/zonecut.c +++ b/lib/zonecut.c @@ -73,6 +73,8 @@ int kr_zonecut_init(struct kr_zonecut *cut, const knot_dname_t *name, mm_ctx_t * cut->pool = pool; cut->key = NULL; cut->trust_anchor = NULL; + cut->parent_name = NULL; + cut->missing_name = NULL; cut->nsset = map_make(); cut->nsset.malloc = (map_alloc_f) mm_alloc; cut->nsset.free = (map_free_f) mm_free; @@ -98,6 +100,8 @@ void kr_zonecut_deinit(struct kr_zonecut *cut) map_clear(&cut->nsset); knot_rrset_free(&cut->key, cut->pool); knot_rrset_free(&cut->trust_anchor, cut->pool); + mm_free(cut->pool, cut->parent_name); + mm_free(cut->pool, cut->missing_name); } void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name) @@ -108,10 +112,15 @@ void kr_zonecut_set(struct kr_zonecut *cut, const knot_dname_t *name) knot_rrset_t *key, *ta; key = cut->key; cut->key = NULL; ta = cut->trust_anchor; cut->trust_anchor = NULL; + knot_dname_t *parent_name, *missing_name; + parent_name = cut->parent_name; cut->parent_name = NULL; + missing_name = cut->missing_name; cut->missing_name = NULL; kr_zonecut_deinit(cut); kr_zonecut_init(cut, name, cut->pool); cut->key = key; cut->trust_anchor = ta; + cut->parent_name = parent_name; + cut->missing_name = missing_name; } static int copy_addr_set(const char *k, void *v, void *baton) diff --git a/lib/zonecut.h b/lib/zonecut.h index a1a051a58..82d62958e 100644 --- a/lib/zonecut.h +++ b/lib/zonecut.h @@ -32,6 +32,8 @@ struct kr_zonecut { map_t nsset; /**< Map of nameserver => address_set. */ knot_rrset_t* key; /**< Zone cut DNSKEY. */ knot_rrset_t* trust_anchor; /**< Current trust anchor. */ + knot_dname_t *parent_name; /**< Parent zone name after zone cut update. */ + knot_dname_t *missing_name; /**< Missing zone cut name. */ }; /** diff --git a/tests/testdata/iter_validate_child_zone.rpl b/tests/testdata/iter_validate_child_zone.rpl new file mode 100644 index 000000000..7c1bdc93a --- /dev/null +++ b/tests/testdata/iter_validate_child_zone.rpl @@ -0,0 +1,154 @@ +; config options +server: + trust-anchor: ". 3600 IN DS 19036 8 2 49AAC11D7B6F6446702E54A1607371607A1A41855200FD2CE1CDDE32F24E8FB5" + val-override-date: "1436477112" + +stub-zone: + name: "." + stub-addr: 198.41.0.4 # a.root-servers.net. +CONFIG_END + +SCENARIO_BEGIN Test basic validation of AAAA nic.cz. + +; K.ROOT-SERVERS.NET. +RANGE_BEGIN 0 100 + ADDRESS 198.41.0.4 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +. IN NS +SECTION ANSWER +. 518400 IN NS a.root-servers.net. +. 518400 IN NS b.root-servers.net. +. 518400 IN NS c.root-servers.net. +. 518400 IN NS d.root-servers.net. +. 518400 IN NS e.root-servers.net. +. 518400 IN NS f.root-servers.net. +. 518400 IN NS g.root-servers.net. +. 518400 IN NS h.root-servers.net. +. 518400 IN NS i.root-servers.net. +. 518400 IN NS j.root-servers.net. +. 518400 IN NS k.root-servers.net. +. 518400 IN NS l.root-servers.net. +. 518400 IN NS m.root-servers.net. +. 518400 IN RRSIG NS 8 0 518400 20150809050000 20150730040000 1518 . ntWgyA7SjlVedxDStbRA6fXl0Hq5pyBgVtBb6l+LbqgLs8/2mwPhzaEw A/BMM+wr7KQLvNSyxTl/SZny94uMVu7o2fnI6+bCP5C+lo7PWni/GvMU yj3JSq2hPv3iO/D1ch8yaKddtYL/NCwPBn9CgpW0jWIWp8FvwwCR4RAs GzA= +SECTION ADDITIONAL +a.root-servers.net. 518400 IN A 198.41.0.4 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +. IN DNSKEY +SECTION ANSWER +. 172800 IN DNSKEY 257 3 8 AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcCjF FVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJRkxoX bfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efucp2gaD X6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA6G3LQpz W5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQdXfZ57relS Qageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhYB4N7knNnulq QxA+Uk1ihz0= +. 172800 IN DNSKEY 256 3 8 AwEAAa67bQck1JjopOOFc+iMISFcp/osWrEst2wbKbuQSUWu77QC9UHL ipiHgWN7JlqVAEjKITZz49hhkLmOpmLK55pTq+RD2kwoyNWk9cvpc+tS nIxT7i93O+3oVeLYjMWrkDAz7K45rObbHDuSBwYZKrcSIUCZnCpNMUtn PFl/04cb +. 172800 IN RRSIG DNSKEY 8 0 172800 20150804235959 20150721000000 19036 . n9FwNj80Zik2Rr2zTB4F17ydFpiZfUIv8v/XAz4EbSgRxQgFT+TCz3FW i4O7tW5REXUVNHtULiS7fxKLsHZNDPev8DA20DXAw3eEIDi9pDi01O/e 4GnljpkPnP8d5zA62Dob4cxgmhjjFTvhIjtDsH5Dd4jmyHsgBboy4grZ uJNdsez76gD4Ad6WlosZn5Hj5JwqaxZlRph/6I3va4rkp4c32w5DwaQ7 WSne8ffMHX9r7Dn6EbT3FfvnXFDNPE1P6r+qzTzC0t+M/F4R3H+VOdqg cRJcBG6zGCh9ZErhAeoiJh1WAfpjpzx+TUMzqxZCjSC/XL+l2YMKVHtF 8WNg/w== +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +nic.cz. IN AAAA +SECTION AUTHORITY +cz. 172800 IN NS a.ns.nic.cz. +cz. 86400 IN DS 54576 10 2 397E50C85EDE9CDE33F363A9E66FD1B216D788F8DD438A57A423A386 869C8F06 +cz. 86400 IN RRSIG DS 8 1 86400 20150809050000 20150730040000 1518 . HUW1+CxxNeY43PxQvSHkspUAC1izz1VldyD0HtwEzKxSRH2GpVcdX5Gs xqaZW8HESCJL/CyEFqyQtGNnyT4EtWMaHEMkbqHH6sMpdfrAzJ1Qab+2 WI4m6kFJqpUrFh+8a+e8nL+R/zWUWL9811oEMQw80lZNnr13GLQBihn6 oJ4= +SECTION ADDITIONAL +a.ns.nic.cz. 172800 IN A 194.0.12.1 +ENTRY_END +RANGE_END + +;a.ns.nic.cz. +RANGE_BEGIN 0 100 + ADDRESS 194.0.12.1 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +cz. IN DNSKEY +SECTION ANSWER +cz. 18000 IN DNSKEY 256 3 10 AwEAAbwKeyKB5fuLe16/N5MR6OoG/PO8uxEob7HoIjK0w0wNjwINYb2w edLtzhVlA4HJ0AUUBuZiNj41hlJ474SOBlsAA7BQdtbL1V0Ksk8IC5Z8 3ldU9Mp+ynkj9p9Cl2UOBmoVFYfkbwz0BsOptcXruYA52Ayc9rHrmDPI /0Y8gZAL +cz. 18000 IN DNSKEY 257 3 10 AwEAAay0hi4HN2r/BqMQTpIPIVDyjmyF+9ZWvr5Lewx+q+947o/GrRv4 FGFfkZxf9CFfYVUf0jG5Yq4i06pGVNwJl81HS9Ux2oeHRXUvgtLnl5He RVLL+zgI5byx9HSNr4bPO8ZEn5OjoayhkNyGSFr4VWrzQk/K02vLP4d1 cCEzUQy30eyZto2/tG5ZwCU/iRkS1PJOcOW98hiFIfFDZv1XjbEpqEYh T2PATs6rt+BKwSHKGISmg1PNdg+y0rItemYMWr1f9BGAdtTWoPCPCYPj OZMPoIyA4tMscD+ww54Jf/QNoHccY4hO1yHiuAXG7SUn8jo0IKQ9W7JJ xES0aqFCX/0= +cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150802000000 20150719000000 54576 cz. K04ONpLX3wseqHhUu2QLBY7wzSUszVlut5mC6jpCAqbfhgIvGMnyoWP5 lKwSvCLmjie0j1HSv8Q4OmoYGz8L+P/FGAzK4LhMturHrDtHkpuGvQJ6 //UsHQhf4iwCg5tEeHI4ZvaMmqRZI3FhBnSh0OyFjGO73FRbBU9nDrOM sPB1iCUfRfZhQU0sB/rj82ykBUma280sO1aRp3gmQHc/SVNbFfCL1Z8D htBP6sy4Jh0z3Z40d4CFZ8ZCBsIloHO44/GvXGePtr2dW4gJsoU1619B Jz+6cuTRh5RJBiweUNb/nwjBP8fNRkzH1CbjomC2FpDMnBXw7jE1GUiY vLW9Gg== +cz. 18000 IN RRSIG DNSKEY 10 1 18000 20150812154652 20150730120915 39788 cz. VD/wYs1AkTvFjZrPQ8pHVnBVN1ZAL1Lt8+RqFgvPamqpNURFmiL18sTS fKYtXQ0yd2KoNJjomjFnl2+e87KxI2+5wdlZXZdNSViMUcH0xhBY7XGj 40ke9ZxJZS6wEnyAK3WXOTM1iOF7Ig+b75N2/1eCuBxVbRE/leXvPQrN 7no= +ENTRY_END + +; a.ns.nic.cz. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +nic.cz. IN AAAA +SECTION ANSWER +nic.cz. 1800 IN AAAA 2001:1488:0:3::2 +nic.cz. 1800 IN RRSIG AAAA 5 2 1800 20150811224544 20150729075503 24582 nic.cz. NCCXb2Hc5wX0RxIFFhM5hKs+9NvuC23qBMDlZda16Vmn6slva9y8Itn0 Qxe59llMPTGq9iTQnY7zF0DLm5ltZ2phRUIrICYGRgF9iEoWLjMpg2xL bd5IRkgU/FLD/wBCYQn4e8llgIOoyVS2VNwF+K2wv70ZrSuSOJSRwanK Xg4= +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 5 2 1800 20150811123349 20150729075503 24582 nic.cz. nIhW7pXwIgq84c4guDLL+geZR0y2/AD53Ti1bkdqo4USaoy8xy9LL8z9 XY2rBHRO6by6bCrfs0+LB+72DQjJ2nFy0pj4daScOOeCbM52nd8Syn3R oTW5JXAdOFtXg54RykhwYgHk+y5XzEbVpZxY7qJX7H/kIGlNNmmmOYqr acg= +SECTION ADDITIONAL +a.ns.nic.cz. 18000 IN A 194.0.12.1 +b.ns.nic.cz. 18000 IN A 194.0.12.1 +d.ns.nic.cz. 18000 IN A 194.0.12.1 +ENTRY_END + +; a.ns.nic.cz. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +nic.cz. IN DS +SECTION ANSWER +nic.cz. 18000 IN DS 59916 5 1 144130216E45C4EC2BB8595E817916E8B060D87B +nic.cz. 18000 IN RRSIG DS 10 2 18000 20150812001929 20150730003853 39788 cz. FcgPAUawyGjBW8B84bGlCAtaRwdQ2MQR8OQcy+vdWvzY2QfwUZLmQLG3 lZBiqScaa8SorrbM584WiPaRk2HlDFhtLnvo+UuGeYOV2jKHxuR+beIU rQfn0IbIbWVgJvkK3OmfGx59MAK5fnLcBV3prBN/AVsUC2NK2Dm7Rotu VwI= +ENTRY_END + +;a.ns.nic.cz. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +nic.cz. IN DNSKEY +SECTION ANSWER +nic.cz. 1800 IN DNSKEY 256 3 5 AwEAAatglK6e9CpmATmEDtjQfOMqSEGB2KT3xciP+ZuBH3qYQDggHxao Hk9cfL5uXHxEr8AqmiTNA2CJ9oVm2wlZFCTUtQS2Vxz+i30XQpIPoh1y 0fU/XHKmrVmdVGzc9OdgDyZT+8CbUInAyUin+tWM9M7ekUXAllUw5bd8 VC4SJO3z +nic.cz. 1800 IN DNSKEY 257 3 5 BQEAAAABt3LenoCVTV0okqKYPDnnVJqvwCD9MKJNXg8fcOCdLQYncyoe hpwM5RK2UkZDcDxWkMo7yMa35ej+Mhpaji9si4xXD+Syl4Q06LFiFkdN /5GlVlrIdE3GW7zC7Z4sS14Vz8FbYfcRmhsh19Ob718jGZneGfw2UPbv kyxUR8wD7mguZn02fQ6tjj/Ktp4uSW9tpz3bjGMo2rX+iZk4xgbPaesA OlR/AaHdatGZsWC9CPon8mnLZeu6czm8CBDgBmnf3PE8c5+uyWj1Pw4p p0VQmnX5UrnuGpErg7qXhJm7wY2CRVRMcLX3zmjVWXW1uT9JFh2G+/pZ zxnASfKKltZpuw== +nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150812022439 20150729075503 59916 nic.cz. gDihwRHowOqkHMniHhPVylnvpiscTRWVajNQjMYdg2N1kKersQoJHpaL uouLMLpFUAYXI2cG+aMFJ6ym6zDJSua/4KzFPWs+OpW39KC5NAdIkXYq W/c+Wihg5qiRZHusuMeC+hmd6wNb2K0KVdtP2qOXJvxkCLD+Tu7jJCCC 2voH17qXxz3T7/R0mfCG1Dy4yE52WX5o3XF+IHrbeViBqm76CNE977qi J4IntadZJ1VpPq+U5srscBzv0g04SwT8GUaxbKfaorX3h+NxN6AwNmuB BkCqkvBbw9PgkBreASScVpmRV+fa1XC+B4r1a7+XieodWywEq1l11tUT p6vAYw== +nic.cz. 1800 IN RRSIG DNSKEY 5 2 1800 20150812040510 20150729075503 24582 nic.cz. hNPsaMZzcOy80v0FJjHdLmPOb7TNsmTsA5JdrTut4KF8757teGLNgRL/ 8Nv1cDd7O6TOkHXXH7nfhvh0BufLeAzuZu+2LZY/lrH1nVqm388UgmX/ MbEqXjQ277K0HzoGKfraMGSPiYsXdR5j2i4X7bu65ifrEQO3ymZtaxdH ZMQ= +ENTRY_END + +RANGE_END + +STEP 0 TIME_PASSES ELAPSE 1438229000 + +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +nic.cz. IN AAAA +ENTRY_END + +; recursion happens here. +STEP 10 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA AD NOERROR +SECTION QUESTION +nic.cz. IN AAAA +SECTION ANSWER +nic.cz. 1800 IN AAAA 2001:1488:0:3::2 +nic.cz. 1800 IN RRSIG AAAA 5 2 1800 20150811224544 20150729075503 24582 nic.cz. NCCXb2Hc5wX0RxIFFhM5hKs+9NvuC23qBMDlZda16Vmn6slva9y8Itn0 Qxe59llMPTGq9iTQnY7zF0DLm5ltZ2phRUIrICYGRgF9iEoWLjMpg2xL bd5IRkgU/FLD/wBCYQn4e8llgIOoyVS2VNwF+K2wv70ZrSuSOJSRwanK Xg4= +ENTRY_END + +SCENARIO_END