summaryrefslogtreecommitdiffstats
path: root/usr.sbin/unbound/iterator/iterator.c
diff options
context:
space:
mode:
authorsthen <sthen@openbsd.org>2016-06-22 20:11:09 +0000
committersthen <sthen@openbsd.org>2016-06-22 20:11:09 +0000
commitc9ade66c88e3cf2f3219400390537cad006a2fdd (patch)
treed2cd5be158a6eb510cb32a498cd8478408841c04 /usr.sbin/unbound/iterator/iterator.c
parentbackport r3781, fix segfault in -h (diff)
downloadwireguard-openbsd-c9ade66c88e3cf2f3219400390537cad006a2fdd.tar.xz
wireguard-openbsd-c9ade66c88e3cf2f3219400390537cad006a2fdd.zip
backport r3782, fixing qname-minimisation with various broken DNS servers,
often found at CDNs. - Use QTYPE=A for QNAME minimisation. - Keep track of number of time-outs when performing QNAME minimisation. Stop minimising when number of time-outs for a QNAME/QTYPE pair is more than three.
Diffstat (limited to 'usr.sbin/unbound/iterator/iterator.c')
-rw-r--r--usr.sbin/unbound/iterator/iterator.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/usr.sbin/unbound/iterator/iterator.c b/usr.sbin/unbound/iterator/iterator.c
index 139cae4bae0..749fba6af63 100644
--- a/usr.sbin/unbound/iterator/iterator.c
+++ b/usr.sbin/unbound/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
@@ -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,7 @@ 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;
/* Limit number of iterations for QNAMEs with more
* than MAX_MINIMISE_COUNT labels. Send first MINIMISE_ONE_LAB
@@ -2059,8 +2061,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 +2080,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 +2168,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;