+6 October 2009: Wouter
+ - Test set updated to provide additional ns lookup result.
+ The retry would attempt to fetch the data from other nameservers
+ for bogus data, and this needed to be provisioned in the tests.
+
+5 October 2009: Wouter
+ - first validation failure retry code. Retries for data failures.
+ And unit test.
+
2 October 2009: Wouter
- improve 5011 modularization.
- fix unbound-host so -d can be given before -C.
/** time when nameserver glue is said to be 'recent' */
#define SUSPICION_RECENT_EXPIRY 86400
+/** penalty to validation failed blacklisted IPs */
+#define BLACKLIST_PENALTY (USEFUL_SERVER_TOP_TIMEOUT*3)
/** fillup fetch policy array */
static void
* UNKNOWN_SERVER_NICENESS
* If no information is known about the server, this is
* returned. 376 msec or so.
+ * +BLACKLIST_PENALTY (of USEFUL_TOP_TIMEOUT*3) for dnssec failed IPs.
*
* When a final value is chosen that is dnsseclame ; dnsseclameness checking
* is turned off (so we do not discard the reply).
static int
iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
- struct delegpt* dp, int* best_rtt)
+ struct delegpt* dp, int* best_rtt, struct sock_list* blacklist)
{
int got_it = 0;
struct delegpt_addr* a;
a->sel_rtt = iter_filter_unsuitable(iter_env, env,
name, namelen, qtype, now, a);
if(a->sel_rtt != -1) {
+ if(sock_list_find(blacklist, &a->addr, a->addrlen))
+ a->sel_rtt += BLACKLIST_PENALTY;
+
if(!got_it) {
*best_rtt = a->sel_rtt;
got_it = 1;
static int
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, uint16_t qtype, uint32_t now,
- struct delegpt* dp, int* selected_rtt, int open_target)
+ struct delegpt* dp, int* selected_rtt, int open_target,
+ struct sock_list* blacklist)
{
int got_num = 0, low_rtt = 0, swap_to_front;
struct delegpt_addr* a, *n, *prev=NULL;
/* fillup sel_rtt and find best rtt in the bunch */
got_num = iter_fill_rtt(iter_env, env, name, namelen, qtype, now, dp,
- &low_rtt);
+ &low_rtt, blacklist);
if(got_num == 0)
return 0;
if(low_rtt >= USEFUL_SERVER_TOP_TIMEOUT &&
iter_server_selection(struct iter_env* iter_env,
struct module_env* env, struct delegpt* dp,
uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_expected,
- int* chase_to_rd, int open_target)
+ int* chase_to_rd, int open_target, struct sock_list* blacklist)
{
int sel;
int selrtt;
struct delegpt_addr* a, *prev;
int num = iter_filter_order(iter_env, env, name, namelen, qtype,
- *env->now, dp, &selrtt, open_target);
+ *env->now, dp, &selrtt, open_target, blacklist);
if(num == 0)
return NULL;
struct query_info;
struct reply_info;
struct module_qstate;
+struct sock_list;
/**
* Process config options and set iterator module state.
* these are not preferred, but are used as a last resort.
* @param open_target: number of currently outstanding target queries.
* If we wait for these, perhaps more server addresses become available.
+ * @param blacklist: the IP blacklist to use.
* @return best target or NULL if no target.
* if not null, that target is removed from the result list in the dp.
*/
struct delegpt_addr* iter_server_selection(struct iter_env* iter_env,
struct module_env* env, struct delegpt* dp, uint8_t* name,
size_t namelen, uint16_t qtype, int* dnssec_expected,
- int* chase_to_rd, int open_target);
+ int* chase_to_rd, int open_target, struct sock_list* blacklist);
/**
* Allocate dns_msg from parsed msg, in regional.
/* This either results in a query restart (CNAME cache response), a
* terminating response (ANSWER), or a cache miss (null). */
- msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
- iq->qchase.qname_len, iq->qchase.qtype,
- iq->qchase.qclass, qstate->region, qstate->env->scratch);
- if(!msg && qstate->env->neg_cache) {
- /* lookup in negative cache; may result in
- * NOERROR/NODATA or NXDOMAIN answers that need validation */
- msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
- qstate->region, qstate->env->rrset_cache,
- qstate->env->scratch_buffer, *qstate->env->now);
+ if(qstate->blacklist) {
+ /* if cache, or anything else, was blacklisted then
+ * getting older results from cache is a bad idea, no cache */
+ verbose(VERB_ALGO, "cache blacklisted, going to the network");
+ msg = NULL;
+ } else {
+ msg = dns_cache_lookup(qstate->env, iq->qchase.qname,
+ iq->qchase.qname_len, iq->qchase.qtype,
+ iq->qchase.qclass, qstate->region, qstate->env->scratch);
+ if(!msg && qstate->env->neg_cache) {
+ /* lookup in negative cache; may result in
+ * NOERROR/NODATA or NXDOMAIN answers that need validation */
+ msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase,
+ qstate->region, qstate->env->rrset_cache,
+ qstate->env->scratch_buffer, *qstate->env->now);
+ }
}
if(msg) {
/* handle positive cache response */
iq->dp = NULL;
iq->refetch_glue = 0;
iq->query_restart_count++;
+ sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
return next_state(iq, INIT_REQUEST_STATE);
}
+ /* if from cache, NULL, else insert 'cache IP' len=0 */
+ if(qstate->reply_origin)
+ sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
/* it is an answer, response, to final state */
verbose(VERB_ALGO, "returning answer from cache.");
iq->response = msg;
if(verbosity >= VERB_ALGO)
log_dns_msg("no RD requested, using delegation msg",
&iq->response->qinfo, iq->response->rep);
+ if(qstate->reply_origin)
+ sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
return final_state(iq);
}
/* Select the next usable target, filtering out unsuitable targets. */
target = iter_server_selection(ie, qstate->env, iq->dp,
iq->dp->name, iq->dp->namelen, iq->qchase.qtype,
- &iq->dnssec_expected, &iq->chase_to_rd, iq->num_target_queries);
+ &iq->dnssec_expected, &iq->chase_to_rd, iq->num_target_queries,
+ qstate->blacklist);
/* If no usable target was selected... */
if(!target) {
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
+ if(qstate->reply)
+ sock_list_insert(&qstate->reply_origin,
+ &qstate->reply->addr, qstate->reply->addrlen,
+ qstate->region);
return final_state(iq);
} else if(type == RESPONSE_TYPE_REFERRAL) {
/* REFERRAL type responses get a reset of the
qstate->env->detach_subs));
(*qstate->env->detach_subs)(qstate);
iq->num_target_queries = 0;
+ if(qstate->reply)
+ sock_list_insert(&qstate->reply_origin,
+ &qstate->reply->addr, qstate->reply->addrlen,
+ qstate->region);
verbose(VERB_ALGO, "cleared outbound list for query restart");
/* go to INIT_REQUEST_STATE for new qname. */
return next_state(iq, INIT_REQUEST_STATE);
&mstate->s.qinfo);
s = module_error;
}
- if(s == module_wait_module) {
+ if(s == module_wait_module || s == module_restart_next) {
/* start next module */
mstate->s.curmod++;
if(mesh->mods.num == mstate->s.curmod) {
mstate->s.curmod--;
return mesh_continue(mesh, mstate, module_error, ev);
}
+ if(s == module_restart_next) {
+ fptr_ok(fptr_whitelist_mod_clear(
+ mesh->mods.mod[mstate->s.curmod]->clear));
+ (*mesh->mods.mod[mstate->s.curmod]->clear)
+ (&mstate->s, mstate->s.curmod);
+ mstate->s.minfo[mstate->s.curmod] = NULL;
+ }
*ev = module_event_pass;
return 1;
}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091024111500 20090921111500 30899 example.com. nDlOZCE24pNtuoYkmmy9cVvtCn7ykdmlhJX9hYcI9b3DzqJjOrGz3GD5RQvti3uxD74gFcFho0g76NwOKFx/qQ== ;{id = 30899}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091024111500 20090921111500 60946 example.com. qBHDZu0XQmr6kpt51r1DxT5tuyfwSHcoL8qLpwwhyyNFF13OPlvxgmCVl+1v27A9+h8tcuqaNls5f+tcFBwtRg== ;{id = 60946}
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
;;last_queried: ${$t4} ;;${ctime $t4}
;;last_success: ${$t2} ;;${ctime $t2}
;;next_probe_time: ${$t4 + $probe4} ;;${ctime $t4 + $probe4}
-;;query_failed: 1
+;;query_failed: 6
;;query_interval: 5400
;;retry_time: 3600
example.com. 10800 IN DNSKEY 257 3 5 AwEAAeiaUiUIpWMfYz5L0sfJTZWnuN9IyBX4em9VjsoqQTsOD1HDQpNb4buvJo7pN2aBCxNS7e0OL8e2mVB6CLZ+8ek= ;{id = 60946 (ksk), size = 512b} ;;state=1 [ ADDPEND ] ;;count=2 ;;lastchange=${$t1} ;;${ctime $t1}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091024111500 20090921111500 60946 example.com. o+Cbs7DcYPYlSLd4hi3vkSVQpXGnKgKSi9MpHGfu1Uahv5190U2DUOxP1du/HOYbf+IHYL8zLbMZjVEG5wgnTg== ;{id = 60946}
ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
; set date/time to Aug 24 09:46:40 (2009).
;;last_queried: ${$t2} ;;${ctime $t2}
;;last_success: ${$t1} ;;${ctime $t1}
;;next_probe_time: ${$t2 + $probe2} ;;${ctime $t2 + $probe2}
-;;query_failed: 1
+;;query_failed: 6
;;query_interval: 5400
;;retry_time: 3600
example.com. 10800 IN DNSKEY 257 3 5 AwEAAeiaUiUIpWMfYz5L0sfJTZWnuN9IyBX4em9VjsoqQTsOD1HDQpNb4buvJo7pN2aBCxNS7e0OL8e2mVB6CLZ+8ek= ;{id = 60946 (ksk), size = 512b} ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t1} ;;${ctime $t1}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091024111500 20090921111500 60946 example.com. rOxbAROwiW21OR8HjINk3IBs9bsxJKjipQ5EU4wWutiF/jr6KNT6LgtZv0TaFSiBHN/Jqz1wB2ODD2HXwLQ4DQ== ;{id = 60946}
ENTRY_END
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
; set date/time to Aug 24 09:46:40 (2009).
;;last_queried: ${$t2} ;;${ctime $t2}
;;last_success: ${$t1} ;;${ctime $t1}
;;next_probe_time: ${$t2 + $probe2} ;;${ctime $t2 + $probe2}
-;;query_failed: 1
+;;query_failed: 6
;;query_interval: 5400
;;retry_time: 3600
example.com. 10800 IN DNSKEY 257 3 5 AwEAAeiaUiUIpWMfYz5L0sfJTZWnuN9IyBX4em9VjsoqQTsOD1HDQpNb4buvJo7pN2aBCxNS7e0OL8e2mVB6CLZ+8ek= ;{id = 60946 (ksk), size = 512b} ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t1} ;;${ctime $t1}
;example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091124111500 20091018111500 55582 example.com. v/HJbdpeVMpbhwYXrT1EDGpAFMvEgdKQII1cAbP6o8KHYNKDh8TIJ25/pXe3daEXfej6/Z5kpqJ79okPKUoi1Q== ;{id = 55582}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091124111500 20091018111500 60946 example.com. HgXol1hdvbomOM1CFRW8qsHd3D0qOnN72EeMHTcpxIBBiuNLKZn4n1M14Voxj3vo0eAMNuG/y7EjQkxKvSsaDA== ;{id = 60946}
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
; ns.example.com. KSK 55582-REVOKED and 60946
;example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091224111500 20091118111500 55582 example.com. nH/6HauVJI4GGz78UoK/38cOOrEqsYZP0jFzfCC3OyIlclVTjAFvjVPlVMGK7sA5Nw1v20YtFTQkXZgbrRuInQ== ;{id = 55582}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091224111500 20091118111500 60946 example.com. xKSBZr4vOsEUKlVoNb6SOV69DM7xFOJI4gPFKq5Tv4APIMJ/9G3odoDmNcLCVyYGzhoDik5hciJnZio6UHgzAA== ;{id = 60946}
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
; ns.example.com. KSK 60946
;;last_queried: ${$t4} ;;${ctime $t4}
;;last_success: ${$t1} ;;${ctime $t1}
;;next_probe_time: ${$t4 + $probe4} ;;${ctime $t4 + $probe4}
-;;query_failed: 1
+;;query_failed: 6
;;query_interval: 5400
;;retry_time: 3600
example.com. 10800 IN DNSKEY 257 3 5 AwEAAeiaUiUIpWMfYz5L0sfJTZWnuN9IyBX4em9VjsoqQTsOD1HDQpNb4buvJo7pN2aBCxNS7e0OL8e2mVB6CLZ+8ek= ;{id = 60946 (ksk), size = 512b} ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t1} ;;${ctime $t1}
ENTRY_END
RANGE_END
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
; set date/time to Mon Nov 23 10:46:40 2009
;;last_queried: ${$t0} ;;${ctime $t0}
;;last_success: 1258962400 ;;Mon Nov 23 08:46:40 2009
;;next_probe_time: ${$t0+$probe0} ;;${ctime $t0+$probe0}
-;;query_failed: 1
+;;query_failed: 6
;;query_interval: 5400
;;retry_time: 3600
example.com. 10800 IN DNSKEY 257 3 5 AwEAAc3Z5DQDJpH4oPdNtC4BUQHk50XMD+dHr4r8psHmivIa83hxR5CRgCtd9sENCW9Ae8OIO19xw9t/RPaEAqQa+OE= ;{id = 55582 (ksk), size = 512b} ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 08:46:40 2009
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091224111500 20091118111500 60946 example.com. p6lOsJpkmZUbj1KCSwzxip0NbK0SnjV1LKLayqkWTDiVNkTYHHLHHJfOU8Grb63SDTsZ5lyDocIwJSUBiKuhig== ;{id = 60946}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091224111500 20091118111500 55582 example.com. NsC5s2quifzA7yQBnbroWHJ9rHfSrBo0V7+c+kZoii2cViOm8636uqcWlaNTqNtD5UI6vzQ5zXF4P8JGoac6ZQ== ;{id = 55582}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
ENTRY_END
RANGE_END
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091224111500 20091118111500 30899 example.com. jTB+ID5gp3U+cxedEPpRvM3tegrBFuVjGR7y9IL+olrtbs5Yr3qeANJwbfO1WVAWiG+EtG876uHny9epo/tlhQ== ;{id = 30899}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091224111500 20091118111500 55582 example.com. NsC5s2quifzA7yQBnbroWHJ9rHfSrBo0V7+c+kZoii2cViOm8636uqcWlaNTqNtD5UI6vzQ5zXF4P8JGoac6ZQ== ;{id = 55582}
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
; set date/time to Aug 24 09:46:40 (2009).
;;last_queried: ${$t7} ;;${ctime $t7}
;;last_success: ${$t6} ;;${ctime $t6}
;;next_probe_time: ${$t7 + $probe7} ;;${ctime $t7 + $probe7}
-;;query_failed: 1
+;;query_failed: 6
;;query_interval: 5400
;;retry_time: 3600
example.com. 10800 IN DNSKEY 257 3 5 AwEAAeiaUiUIpWMfYz5L0sfJTZWnuN9IyBX4em9VjsoqQTsOD1HDQpNb4buvJo7pN2aBCxNS7e0OL8e2mVB6CLZ+8ek= ;{id = 60946 (ksk), size = 512b} ;;state=2 [ VALID ] ;;count=0 ;;lastchange=${$t4} ;;${ctime $t4}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091124111500 20091018111500 55710 example.com. nu+W3T0afsJc2MrrsnBZ3adysi39TLUJ0o8GYaR/PFYsYSOigSCnr3xo05aKoNZ2oeQXhmwQVAxfwU1M/jXngQ== ;{id = 55710}
example.com. 10800 IN RRSIG DNSKEY 5 2 10800 20091124111500 20091018111500 16486 example.com. LDW5an/v6YzgUhpTm8VJnBCko56WDvzzoqCmjXBwpoGjWXThO2hUyO6w00K90swQvKwgIWsC4y00zFlOgLayJw== ;{id = 16486}
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
ENTRY_END
RANGE_END
;;last_queried: ${$t0} ;;${ctime $t0}
;;last_success: ${$tp} ;;${ctime $tp}
;;next_probe_time: ${$t0 + $probe0} ;;${ctime $t0 + $probe0}
-;;query_failed: 1
+;;query_failed: 6
;;query_interval: 5400
;;retry_time: 3600
example.com. 10800 IN DNSKEY 385 3 5 AwEAAc3Z5DQDJpH4oPdNtC4BUQHk50XMD+dHr4r8psHmivIa83hxR5CRgCtd9sENCW9Ae8OIO19xw9t/RPaEAqQa+OE= ;{id = 55710 (ksk), size = 512b} ;;state=4 [ REVOKED ] ;;count=0 ;;lastchange=${$t0} ;;${ctime $t0}
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.net. IN A
+example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
RANGE_END
; ns.example.net.
;wab.example.net. 3600 IN RRSIG NSEC 5 3 3600 20070926134150 20070829134150 30899 example.net. gl8vkI3xfSWx4Pyv5OdOthiewE6u/13kclY7UG9ptuFBddamdJO3RQqyxM6Xcmq+ToO4kMCCyaKijp01gTDoGg== ;{id = 30899}
SECTION ADDITIONAL
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qname qtype
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.sub.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.net. IN A
+example.net. IN A
SECTION AUTHORITY
example.net. IN NS ns.example.net.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
; ns.example.net.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.5
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.net. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.sub.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+ENTRY_END
+
RANGE_END
STEP 1 QUERY
SECTION AUTHORITY
SECTION ADDITIONAL
ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+ENTRY_END
+
RANGE_END
STEP 1 QUERY
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ADJUST copy_id
REPLY QR AA DO NOERROR
SECTION QUESTION
-mc.c.example. IN MX
+c.example. IN DS
SECTION AUTHORITY
-c.example. NS ns1.c.example.
-c.example. NS ns2.c.example.
-
;; NSEC3 RR that covers the "next closer" name (c.example)
;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
;; NSEC3 RR that matches the closest encloser (example)
;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
-; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
-; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
-
-SECTION ADDITIONAL
-ns1.c.example. A 192.0.2.7
-ns2.c.example. A 192.0.2.8
-
+;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR AA DO NOERROR
SECTION QUESTION
-c.example. IN DS
+c.example. IN MX
SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+
;; NSEC3 RR that covers the "next closer" name (c.example)
;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
;; NSEC3 RR that matches the closest encloser (example)
;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
-;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
-;0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
-ENTRY_END
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
+; 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+ENTRY_END
RANGE_END
; ns1.c.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
; ns2.c.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ADJUST copy_id
REPLY QR AA DO NOERROR
SECTION QUESTION
-mc.c.example. IN MX
+c.example. IN DS
SECTION AUTHORITY
-c.example. NS ns1.c.example.
-c.example. NS ns2.c.example.
-
;; NSEC3 RR that covers the "next closer" name (c.example)
;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
-; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
-; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+;35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+;35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
;; NSEC3 RR that matches the closest encloser (example)
;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
-
-SECTION ADDITIONAL
-ns1.c.example. A 192.0.2.7
-ns2.c.example. A 192.0.2.8
-
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR AA DO NOERROR
SECTION QUESTION
-c.example. IN DS
+c.example. IN MX
SECTION AUTHORITY
+c.example. NS ns1.c.example.
+c.example. NS ns2.c.example.
+
;; NSEC3 RR that covers the "next closer" name (c.example)
;; H(c.example) = 4g6p9u5gvfshp30pqecj98b3maqbn1ck
-;35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
-;35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
+; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. NSEC3 1 1 12 aabbccdd ( b4um86eghhds6nea196smvmlo4ors995 NS DS RRSIG )
+; 35mthgpgcu1qg68fab165klnsnk3dpvl.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. g6jPUUpduAJKRljUsN8gB4UagAX0NxY9shwQ Aynzo8EUWH+z6hEIBlUTPGj15eZll6VhQqgZ XtAIR3chwgW+SA== )
;; NSEC3 RR that matches the closest encloser (example)
;; H(example) = 0p9mhaveqvm6t7vbl5lop2u3t2rp3tom
0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. NSEC3 1 1 12 aabbccdd ( 2t7b4g4vsa5smi47k61mv5bv1a22bojr MX DNSKEY NS SOA NSEC3PARAM RRSIG )
0p9mhaveqvm6t7vbl5lop2u3t2rp3tom.example. RRSIG NSEC3 7 2 3600 20150420235959 20051021000000 ( 40430 example. OSgWSm26B+cS+dDL8b5QrWr/dEWhtCsKlwKL IBHYH6blRxK9rC0bMJPwQ4mLIuw85H2EY762 BOCXJZMnpuwhpA== )
+
+SECTION ADDITIONAL
+ns1.c.example. A 192.0.2.7
+ns2.c.example. A 192.0.2.8
+
ENTRY_END
RANGE_END
; ns1.c.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.7
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
; ns2.c.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.8
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns1.c.example. IN AAAA
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns2.c.example. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode
+MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-. IN A
+example. IN A
SECTION AUTHORITY
example. IN NS ns1.example.
; leave out to make unbound take ns1
; ns1.example.
RANGE_BEGIN 0 100
ADDRESS 192.0.2.1
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id copy_query
+REPLY QR REFUSED
+SECTION QUESTION
+ns1.example. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id copy_query
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.sub.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
-; refer to server one down
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
-www.sub.example.com. IN A
+sub.example.com. IN DS
SECTION AUTHORITY
-sub.example.com. IN NS ns.sub.example.com.
; proof that there is no DS here.
;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
8r1f0ieoutlnjc03meng9e3bn1n0o9pd.example.com. IN NSEC3 1 0 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS RRSIG
8r1f0ieoutlnjc03meng9e3bn1n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCategdxsiQTpOMHED1ehjPT7PO2gIUDJ9f/zGCEUHy/UVp97aOh0RRoks= ;{id = 2854}
-
-SECTION ADDITIONAL
-ns.sub.example.com. IN A 1.2.3.10
ENTRY_END
+; refer to server one down
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-sub.example.com. IN DS
+sub.example.com. IN A
SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
; proof that there is no DS here.
;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
8r1f0ieoutlnjc03meng9e3bn1n0o9pd.example.com. IN NSEC3 1 0 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS RRSIG
8r1f0ieoutlnjc03meng9e3bn1n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQCategdxsiQTpOMHED1ehjPT7PO2gIUDJ9f/zGCEUHy/UVp97aOh0RRoks= ;{id = 2854}
+
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.10
ENTRY_END
+
RANGE_END
; ns.sub.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
-; refer to server one down
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
-www.sub.example.com. IN A
+sub.example.com. IN DS
SECTION AUTHORITY
-sub.example.com. IN NS ns.sub.example.com.
; proof that there is no DS here.
;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS SOA DNSKEY RRSIG
8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC4CFQCeKcyw76yvOvfa2+qtxv8bKcEyJwIVAJBeIGST4Y8Tk8YkQI0suee3Bxb1 ;{id = 2854}
-
-SECTION ADDITIONAL
-ns.sub.example.com. IN A 1.2.3.10
ENTRY_END
+; refer to server one down
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-sub.example.com. IN DS
+sub.example.com. IN A
SECTION AUTHORITY
+sub.example.com. IN NS ns.sub.example.com.
; proof that there is no DS here.
;sub.example.com. 3600 IN DS 2854 DSA 1 be4d46cd7489cce25a31af0dff2968ce0425dd31
;sub.example.com. 3600 IN RRSIG DS 3 3 3600 20070926135752 20070829135752 2854 example.com. MC0CFQC1WMTfb25sTgeUEXCFR4+YiJqecwIUc2R/jrO4amyQxovSnld2reg8eyo= ;{id = 2854}
; sub.example.com. -> 8r1f0ieoutlnjc03meng9e3bn2n0o9pd.
8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. IN NSEC3 1 1 123 aabb00123456bbccdd 8r1f0ieoutlnjc03meng9e3bn3n0o9pd NS SOA DNSKEY RRSIG
8r1f0ieoutlnjc03meng9e3bn2n0o9pd.example.com. 3600 IN RRSIG NSEC3 3 3 3600 20070926135752 20070829135752 2854 example.com. MC4CFQCeKcyw76yvOvfa2+qtxv8bKcEyJwIVAJBeIGST4Y8Tk8YkQI0suee3Bxb1 ;{id = 2854}
+
+SECTION ADDITIONAL
+ns.sub.example.com. IN A 1.2.3.10
ENTRY_END
RANGE_END
; ns.sub.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.10
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.sub.example.com. IN AAAA
+SECTION ANSWER
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN ANY
+example.com. IN ANY
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
ENTRY_END
ENTRY_BEGIN
-MATCH opcode qtype qname
-ADJUST copy_id
+MATCH opcode subdomain
+ADJUST copy_id copy_query
REPLY QR NOERROR
SECTION QUESTION
-www.example.com. IN A
+example.com. IN A
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
+ENTRY_BEGIN
+MATCH opcode qtype qname
+ADJUST copy_id
+REPLY QR AA REFUSED
+SECTION QUESTION
+ns.example.com. IN AAAA
+ENTRY_END
+
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
case module_state_initial: return "module_state_initial";
case module_wait_reply: return "module_wait_reply";
case module_wait_module: return "module_wait_module";
+ case module_restart_next: return "module_restart_next";
case module_wait_subquery: return "module_wait_subquery";
case module_error: return "module_error";
case module_finished: return "module_finished";
module_wait_reply,
/** module is waiting for another module */
module_wait_module,
+ /** module is waiting for another module; that other is restarted */
+ module_restart_next,
/** module is waiting for sub-query */
module_wait_subquery,
/** module could not finish the query */
module_event_error
};
+/** Linked list of sockaddrs */
+struct sock_list {
+ /** next in list */
+ struct sock_list* next;
+ /** sockaddr */
+ struct sockaddr_storage addr;
+ /** length of addr */
+ socklen_t len;
+};
+
/**
* Module state, per query.
*/
struct dns_msg* return_msg;
/** the rcode, in case of error, instead of a reply message */
int return_rcode;
+ /** origin of the reply (can be NULL from cache, list for cnames) */
+ struct sock_list* reply_origin;
+ /** IP blacklist for queries */
+ struct sock_list* blacklist;
/** region for this query. Cleared when query process finishes. */
struct regional* region;
#include "util/net_help.h"
#include "util/log.h"
#include "util/data/dname.h"
+#include "util/module.h"
+#include "util/regional.h"
#include <fcntl.h>
/** max length of an IP address (the address portion) that we allow */
s = (uint8_t*)&((struct sockaddr_in6*)addr)->sin6_addr;
return (memcmp(s, map_prefix, 12) == 0);
}
+
+void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr,
+ socklen_t len, struct regional* region)
+{
+ struct sock_list* add = (struct sock_list*)regional_alloc(region,
+ sizeof(*add));
+ if(!add) {
+ log_err("out of memory in socketlist insert");
+ return;
+ }
+ log_assert(list);
+ add->next = *list;
+ add->len = len;
+ memcpy(&add->addr, addr, len);
+ *list = add;
+}
+
+void sock_list_prepend(struct sock_list** list, struct sock_list* add)
+{
+ struct sock_list* last = add;
+ if(!last)
+ return;
+ while(last->next)
+ last = last->next;
+ last->next = *list;
+ *list = add;
+}
+
+int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr,
+ socklen_t len)
+{
+ while(list) {
+ if(len == list->len) {
+ if(len == 0 || sockaddr_cmp_addr(addr, len,
+ &list->addr, list->len) == 0)
+ return 1;
+ }
+ list = list->next;
+ }
+ return 0;
+}
#ifndef NET_HELP_H
#define NET_HELP_H
#include "util/log.h"
+struct sock_list;
+struct regional;
/** DNS constants for uint16_t style flag manipulation. host byteorder.
* 1 1 1 1 1 1
*/
int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen);
+/**
+ * Insert new socket list item. If fails logs error.
+ * @param list: pointer to pointer to first item.
+ * @param addr: address or NULL if 'cache'.
+ * @param len: length of addr, or 0 if 'cache'.
+ * @param region: where to allocate
+ */
+void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr,
+ socklen_t len, struct regional* region);
+
+/**
+ * Append one list to another. Must both be from same qstate(regional).
+ * @param list: pointer to result list that is modified.
+ * @param add: item(s) to add. They are prepended to list.
+ */
+void sock_list_prepend(struct sock_list** list, struct sock_list* add);
+
+/**
+ * Find addr in list.
+ * @param list: to search in
+ * @param addr: address to look for.
+ * @param len: length. Can be 0, look for 'cache entry'.
+ * @return true if found.
+ */
+int sock_list_find(struct sock_list* list, struct sockaddr_storage* addr,
+ socklen_t len);
+
#endif /* NET_HELP_H */
env->modinfo[id] = NULL;
}
-/** allocate new validator query state */
+/** fill in message structure */
static struct val_qstate*
-val_new(struct module_qstate* qstate, int id)
+val_new_getmsg(struct module_qstate* qstate, struct val_qstate* vq)
{
- struct val_qstate* vq = (struct val_qstate*)regional_alloc(
- qstate->region, sizeof(*vq));
- log_assert(!qstate->minfo[id]);
- if(!vq)
- return NULL;
- memset(vq, 0, sizeof(*vq));
- qstate->minfo[id] = vq;
- vq->state = VAL_INIT_STATE;
if(!qstate->return_msg || qstate->return_rcode != LDNS_RCODE_NOERROR) {
/* create a message to verify */
verbose(VERB_ALGO, "constructing reply for validation");
return vq;
}
+/** allocate new validator query state */
+static struct val_qstate*
+val_new(struct module_qstate* qstate, int id)
+{
+ struct val_qstate* vq = (struct val_qstate*)regional_alloc(
+ qstate->region, sizeof(*vq));
+ log_assert(!qstate->minfo[id]);
+ if(!vq)
+ return NULL;
+ memset(vq, 0, sizeof(*vq));
+ qstate->minfo[id] = vq;
+ vq->state = VAL_INIT_STATE;
+ return val_new_getmsg(qstate, vq);
+}
+
/**
* Exit validation with an error status
*
enum val_classification subtype = val_classify_response(
qstate->query_flags, &qstate->qinfo, &vq->qchase,
vq->orig_msg->rep, vq->rrset_skip);
+ if(vq->restart_count > VAL_MAX_RESTART_COUNT) {
+ verbose(VERB_ALGO, "restart count exceeded");
+ return val_error(qstate, id);
+ }
verbose(VERB_ALGO, "validator classification %s",
val_classification_to_string(subtype));
if(subtype == VAL_CLASS_REFERRAL &&
/* if the result is bogus - set message ttl to bogus ttl to avoid
* endless bogus revalidation */
if(vq->orig_msg->rep->security == sec_status_bogus) {
+ /* see if we can try again to fetch data */
+ if(vq->restart_count < VAL_MAX_RESTART_COUNT) {
+ int restart_count = vq->restart_count+1;
+ verbose(VERB_ALGO, "validation failed, "
+ "blacklist and retry to fetch data");
+ /* debug printout */
+ if(verbosity >= VERB_ALGO) {
+ struct sock_list* p;
+ if(!qstate->reply_origin)
+ verbose(VERB_ALGO, "new blacklist: "
+ "cache");
+ for(p=qstate->reply_origin; p; p=p->next)
+ if(p->len)
+ log_addr(VERB_ALGO,
+ "new blacklist IP",
+ &p->addr, p->len);
+ else verbose(VERB_ALGO, "new "
+ "blacklist: cache");
+ for(p=qstate->blacklist; p; p=p->next)
+ if(p->len)
+ log_addr(VERB_ALGO,
+ "blacklist IP",
+ &p->addr, p->len);
+ else verbose(VERB_ALGO, "blacklist "
+ "cache");
+ }
+ /* blacklist the IPs or the cache */
+ if(qstate->reply_origin)
+ sock_list_prepend(&qstate->blacklist,
+ qstate->reply_origin);
+ else sock_list_insert(&qstate->blacklist, NULL, 0,
+ qstate->region);
+ qstate->reply_origin = NULL;
+ memset(vq, 0, sizeof(*vq));
+ vq->restart_count = restart_count;
+ vq->state = VAL_INIT_STATE;
+ verbose(VERB_ALGO, "pass back to next module");
+ qstate->ext_state[id] = module_restart_next;
+ return 0;
+ }
+
vq->orig_msg->rep->ttl = ve->bogus_ttl;
if(qstate->env->cfg->val_log_level >= 1) {
log_query_info(0, "validation failure", &qstate->qinfo);
qstate->ext_state[id] = module_error;
return;
}
+ } else if(!vq->orig_msg) {
+ if(!val_new_getmsg(qstate, vq)) {
+ log_err("validator: malloc failure");
+ qstate->ext_state[id] = module_error;
+ return;
+ }
}
val_handle(qstate, vq, ve, id);
return;
*/
#define NULL_KEY_TTL 900 /* seconds */
+/** max number of query restarts, number of IPs to probe */
+#define VAL_MAX_RESTART_COUNT 5
+
/**
* Global state for the validator.
*/
*/
struct dns_msg* orig_msg;
+ /**
+ * The query restart count
+ */
+ int restart_count;
+
/**
* The query name we have chased to; qname after following CNAMEs
*/