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) | |
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 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;  };  /** | 
