diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2016-09-27 21:11:07 +0000 |
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2016-09-27 21:11:07 +0000 |
| commit | 27c2fff0f2fef695b0599fc3931cacfc16376e88 (patch) | |
| tree | b2599c622858ea78bd8237ce2ee38b62725dabf9 /iterator | |
| parent | a6533d88996e7570cf04db0d99b6012d25a953d3 (diff) | |
Notes
Diffstat (limited to 'iterator')
| -rw-r--r-- | iterator/iter_hints.c | 1 | ||||
| -rw-r--r-- | iterator/iter_utils.c | 33 | ||||
| -rw-r--r-- | iterator/iterator.c | 38 | ||||
| -rw-r--r-- | iterator/iterator.h | 8 |
4 files changed, 67 insertions, 13 deletions
diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 217dfa2578ba9..5fd90177aff07 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 a5aefa9602c2b..874dd6850e4e1 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 139cae4bae0ac..cc7e9378c9e76 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 7c32a74f800ba..5585f578958dc 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; }; /** |
