aboutsummaryrefslogtreecommitdiff
path: root/iterator
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2016-09-27 21:11:07 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2016-09-27 21:11:07 +0000
commit27c2fff0f2fef695b0599fc3931cacfc16376e88 (patch)
treeb2599c622858ea78bd8237ce2ee38b62725dabf9 /iterator
parenta6533d88996e7570cf04db0d99b6012d25a953d3 (diff)
Diffstat (limited to 'iterator')
-rw-r--r--iterator/iter_hints.c1
-rw-r--r--iterator/iter_utils.c33
-rw-r--r--iterator/iterator.c38
-rw-r--r--iterator/iterator.h8
4 files changed, 67 insertions, 13 deletions
diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c
index 217dfa2578ba..5fd90177aff0 100644
--- a/iterator/iter_hints.c
+++ b/iterator/iter_hints.c
@@ -147,6 +147,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
if(!ah(dp, "B.ROOT-SERVERS.NET.", "2001:500:84::b")) goto failed;
if(!ah(dp, "C.ROOT-SERVERS.NET.", "2001:500:2::c")) goto failed;
if(!ah(dp, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) goto failed;
+ if(!ah(dp, "E.ROOT-SERVERS.NET.", "2001:500:a8::e")) goto failed;
if(!ah(dp, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) goto failed;
if(!ah(dp, "H.ROOT-SERVERS.NET.", "2001:500:1::53")) goto failed;
if(!ah(dp, "I.ROOT-SERVERS.NET.", "2001:7fe::53")) goto failed;
diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c
index a5aefa9602c2..874dd6850e4e 100644
--- a/iterator/iter_utils.c
+++ b/iterator/iter_utils.c
@@ -360,6 +360,39 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
}
}
*selected_rtt = low_rtt;
+
+ if (env->cfg->prefer_ip6) {
+ int got_num6 = 0;
+ int low_rtt6 = 0;
+ int i;
+ prev = NULL;
+ a = dp->result_list;
+ for(i = 0; i < got_num; i++) {
+ swap_to_front = 0;
+ if(a->addr.ss_family == AF_INET6) {
+ got_num6++;
+ swap_to_front = 1;
+ if(low_rtt6 == 0 || a->sel_rtt < low_rtt6) {
+ low_rtt6 = a->sel_rtt;
+ }
+ }
+ /* swap to front if IPv6, or move to next result */
+ if(swap_to_front && prev) {
+ n = a->next_result;
+ prev->next_result = n;
+ a->next_result = dp->result_list;
+ dp->result_list = a;
+ a = n;
+ } else {
+ prev = a;
+ a = a->next_result;
+ }
+ }
+ if(got_num6 > 0) {
+ got_num = got_num6;
+ *selected_rtt = low_rtt6;
+ }
+ }
return got_num;
}
diff --git a/iterator/iterator.c b/iterator/iterator.c
index 139cae4bae0a..cc7e9378c9e7 100644
--- a/iterator/iterator.c
+++ b/iterator/iterator.c
@@ -148,6 +148,7 @@ iter_new(struct module_qstate* qstate, int id)
iq->qchase = qstate->qinfo;
outbound_list_init(&iq->outlist);
iq->minimise_count = 0;
+ iq->minimise_timeout_count = 0;
if (qstate->env->cfg->qname_minimisation)
iq->minimisation_state = INIT_MINIMISE_STATE;
else
@@ -215,6 +216,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA) {
/* mark address as failed. */
struct delegpt_ns* dpns = NULL;
+ super_iq->num_target_queries--;
if(super_iq->dp)
dpns = delegpt_find_ns(super_iq->dp,
qstate->qinfo.qname, qstate->qinfo.qname_len);
@@ -234,7 +236,6 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super)
log_err("out of memory adding missing");
}
dpns->resolved = 1; /* mark as failed */
- super_iq->num_target_queries--;
}
if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) {
/* prime failed to get delegation */
@@ -2008,7 +2009,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->dp->name))) {
iq->qinfo_out.qname = iq->dp->name;
iq->qinfo_out.qname_len = iq->dp->namelen;
- iq->qinfo_out.qtype = LDNS_RR_TYPE_NS;
+ iq->qinfo_out.qtype = LDNS_RR_TYPE_A;
iq->qinfo_out.qclass = iq->qchase.qclass;
iq->minimise_count = 0;
}
@@ -2023,6 +2024,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
iq->qinfo_out.qname = iq->qchase.qname;
iq->qinfo_out.qname_len = iq->qchase.qname_len;
iq->minimise_count++;
+ iq->minimise_timeout_count = 0;
+
+ iter_dec_attempts(iq->dp, 1);
/* Limit number of iterations for QNAMEs with more
* than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
@@ -2059,8 +2063,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
&iq->qinfo_out.qname_len,
labdiff-1);
}
- if(labdiff < 1 ||
- (labdiff < 2 && iq->qchase.qtype == LDNS_RR_TYPE_DS))
+ if(labdiff < 1 || (labdiff < 2
+ && (iq->qchase.qtype == LDNS_RR_TYPE_DS
+ || iq->qchase.qtype == LDNS_RR_TYPE_A)))
/* Stop minimising this query, resolve "as usual" */
iq->minimisation_state = DONOT_MINIMISE_STATE;
else {
@@ -2077,10 +2082,17 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
return 1;
}
}
- if(iq->minimisation_state == SKIP_MINIMISE_STATE)
- /* Do not increment qname, continue incrementing next
- * iteration */
- iq->minimisation_state = MINIMISE_STATE;
+ if(iq->minimisation_state == SKIP_MINIMISE_STATE) {
+ iq->minimise_timeout_count++;
+ if(iq->minimise_timeout_count < MAX_MINIMISE_TIMEOUT_COUNT)
+ /* Do not increment qname, continue incrementing next
+ * iteration */
+ iq->minimisation_state = MINIMISE_STATE;
+ else
+ /* Too many time-outs detected for this QNAME and QTYPE.
+ * We give up, disable QNAME minimisation. */
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
+ }
if(iq->minimisation_state == DONOT_MINIMISE_STATE)
iq->qinfo_out = iq->qchase;
@@ -2158,7 +2170,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
iq->num_current_queries--;
if(iq->response == NULL) {
/* Don't increment qname when QNAME minimisation is enabled */
- if (qstate->env->cfg->qname_minimisation)
+ if(qstate->env->cfg->qname_minimisation)
iq->minimisation_state = SKIP_MINIMISE_STATE;
iq->chase_to_rd = 0;
iq->dnssec_lame_query = 0;
@@ -2649,6 +2661,10 @@ processTargetResponse(struct module_qstate* qstate, int id,
log_query_info(VERB_ALGO, "processTargetResponse", &qstate->qinfo);
log_query_info(VERB_ALGO, "processTargetResponse super", &forq->qinfo);
+ /* Tell the originating event that this target query has finished
+ * (regardless if it succeeded or not). */
+ foriq->num_target_queries--;
+
/* check to see if parent event is still interested (in orig name). */
if(!foriq->dp) {
verbose(VERB_ALGO, "subq: parent not interested, was reset");
@@ -2664,10 +2680,6 @@ processTargetResponse(struct module_qstate* qstate, int id,
return;
}
- /* Tell the originating event that this target query has finished
- * (regardless if it succeeded or not). */
- foriq->num_target_queries--;
-
/* if iq->query_for_pside_glue then add the pside_glue (marked lame) */
if(iq->pside_glue) {
/* if the pside_glue is NULL, then it could not be found,
diff --git a/iterator/iterator.h b/iterator/iterator.h
index 7c32a74f800b..5585f578958d 100644
--- a/iterator/iterator.h
+++ b/iterator/iterator.h
@@ -69,6 +69,9 @@ struct rbtree_t;
* QNAMEs with a lot of labels.
*/
#define MAX_MINIMISE_COUNT 10
+/* max number of time-outs for minimised query. Prevents resolving failures
+ * when the QNAME minimisation QTYPE is blocked. */
+#define MAX_MINIMISE_TIMEOUT_COUNT 3
/**
* number of labels from QNAME that are always send individually when using
* QNAME minimisation, even when the number of labels of the QNAME is bigger
@@ -377,6 +380,11 @@ struct iter_qstate {
* outgoing queries when QNAME minimisation is enabled.
*/
int minimise_count;
+
+ /**
+ * Count number of time-outs. Used to prevent resolving failures when
+ * the QNAME minimisation QTYPE is blocked. */
+ int minimise_timeout_count;
};
/**