diff options
| author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2019-06-30 14:56:56 +0000 | 
|---|---|---|
| committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2019-06-30 14:56:56 +0000 | 
| commit | 4713c21a1ac91081e50e474d11fcec002b43a562 (patch) | |
| tree | 3dee8846d50565e925146b25f6b761ceb1ea7b07 /iterator | |
| parent | 9c9d011eed674ddd7e4a0a148691887afb9e75cd (diff) | |
Diffstat (limited to 'iterator')
| -rw-r--r-- | iterator/iter_fwd.c | 2 | ||||
| -rw-r--r-- | iterator/iter_hints.c | 2 | ||||
| -rw-r--r-- | iterator/iter_utils.c | 60 | ||||
| -rw-r--r-- | iterator/iterator.c | 24 | 
4 files changed, 80 insertions, 8 deletions
| diff --git a/iterator/iter_fwd.c b/iterator/iter_fwd.c index 4eb0eb7186079..ea3d70e07320f 100644 --- a/iterator/iter_fwd.c +++ b/iterator/iter_fwd.c @@ -239,7 +239,7 @@ read_fwds_addr(struct config_stub* s, struct delegpt* dp)  				s->name, p->str);  			return 0;  		} -#ifndef HAVE_SSL_SET1_HOST +#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)  		if(tls_auth_name)  			log_err("no name verification functionality in "  				"ssl library, ignored name for %s", p->str); diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 0b35a9d9e24fd..60e518122ed14 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -252,7 +252,7 @@ read_stubs_addr(struct config_stub* s, struct delegpt* dp)  				s->name, p->str);  			return 0;  		} -#ifndef HAVE_SSL_SET1_HOST +#if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)  		if(auth_name)  			log_err("no name verification functionality in "  				"ssl library, ignored name for %s", p->str); diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index 4ac8efd0d17ac..be7965a60e39b 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -882,10 +882,35 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2)  	return 1;  } +/** compare rrsets and sort canonically.  Compares rrset name, type, class. + * return 0 if equal, +1 if x > y, and -1 if x < y. + */ +static int +rrset_canonical_sort_cmp(const void* x, const void* y) +{ +	struct ub_packed_rrset_key* rrx = *(struct ub_packed_rrset_key**)x; +	struct ub_packed_rrset_key* rry = *(struct ub_packed_rrset_key**)y; +	int r = dname_canonical_compare(rrx->rk.dname, rry->rk.dname); +	if(r != 0) +		return r; +	if(rrx->rk.type != rry->rk.type) { +		if(ntohs(rrx->rk.type) > ntohs(rry->rk.type)) +			return 1; +		else	return -1; +	} +	if(rrx->rk.rrset_class != rry->rk.rrset_class) { +		if(ntohs(rrx->rk.rrset_class) > ntohs(rry->rk.rrset_class)) +			return 1; +		else	return -1; +	} +	return 0; +} +  int   reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)  {  	size_t i; +	struct ub_packed_rrset_key** sorted_p, **sorted_q;  	if(p->flags != q->flags ||  		p->qdcount != q->qdcount ||  		/* do not check TTL, this may differ */ @@ -899,16 +924,43 @@ reply_equal(struct reply_info* p, struct reply_info* q, struct regional* region)  		p->ar_numrrsets != q->ar_numrrsets ||  		p->rrset_count != q->rrset_count)  		return 0; +	/* sort the rrsets in the authority and additional sections before +	 * compare, the query and answer sections are ordered in the sequence +	 * they should have (eg. one after the other for aliases). */ +	sorted_p = (struct ub_packed_rrset_key**)regional_alloc_init( +		region, p->rrsets, sizeof(*sorted_p)*p->rrset_count); +	if(!sorted_p) return 0; +	log_assert(p->an_numrrsets + p->ns_numrrsets + p->ar_numrrsets <= +		p->rrset_count); +	qsort(sorted_p + p->an_numrrsets, p->ns_numrrsets, +		sizeof(*sorted_p), rrset_canonical_sort_cmp); +	qsort(sorted_p + p->an_numrrsets + p->ns_numrrsets, p->ar_numrrsets, +		sizeof(*sorted_p), rrset_canonical_sort_cmp); + +	sorted_q = (struct ub_packed_rrset_key**)regional_alloc_init( +		region, q->rrsets, sizeof(*sorted_q)*q->rrset_count); +	if(!sorted_q) { +		regional_free_all(region); +		return 0; +	} +	log_assert(q->an_numrrsets + q->ns_numrrsets + q->ar_numrrsets <= +		q->rrset_count); +	qsort(sorted_q + q->an_numrrsets, q->ns_numrrsets, +		sizeof(*sorted_q), rrset_canonical_sort_cmp); +	qsort(sorted_q + q->an_numrrsets + q->ns_numrrsets, q->ar_numrrsets, +		sizeof(*sorted_q), rrset_canonical_sort_cmp); + +	/* compare the rrsets */  	for(i=0; i<p->rrset_count; i++) { -		if(!rrset_equal(p->rrsets[i], q->rrsets[i])) { -			if(!rrset_canonical_equal(region, p->rrsets[i], -				q->rrsets[i])) { +		if(!rrset_equal(sorted_p[i], sorted_q[i])) { +			if(!rrset_canonical_equal(region, sorted_p[i], +				sorted_q[i])) {  				regional_free_all(region);  				return 0;  			} -			regional_free_all(region);  		}  	} +	regional_free_all(region);  	return 1;  } diff --git a/iterator/iterator.c b/iterator/iterator.c index 8312dfd53313f..c73fb51774890 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1448,7 +1448,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,  			 * now will also exceed the rate, keeping cache fresh */  			(void)infra_ratelimit_inc(qstate->env->infra_cache,  				iq->dp->name, iq->dp->namelen, -				*qstate->env->now); +				*qstate->env->now, &qstate->qinfo, +				qstate->reply);  			/* see if we are passed through with slip factor */  			if(qstate->env->cfg->ratelimit_factor != 0 &&  				ub_random_max(qstate->env->rnd, @@ -2105,6 +2106,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,  	struct delegpt_addr* target;  	struct outbound_entry* outq;  	int auth_fallback = 0; +	uint8_t* qout_orig = NULL; +	size_t qout_orig_len = 0;  	/* NOTE: a request will encounter this state for each target it   	 * needs to send a query to. That is, at least one per referral,  @@ -2178,6 +2181,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,  		int labdiff = qchaselabs -  			dname_count_labels(iq->qinfo_out.qname); +		qout_orig = iq->qinfo_out.qname; +		qout_orig_len = iq->qinfo_out.qname_len;  		iq->qinfo_out.qname = iq->qchase.qname;  		iq->qinfo_out.qname_len = iq->qchase.qname_len;  		iq->minimise_count++; @@ -2330,6 +2335,13 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,  			/* wait to get all targets, we want to try em */  			verbose(VERB_ALGO, "wait for all targets for fallback");  			qstate->ext_state[id] = module_wait_reply; +			/* undo qname minimise step because we'll get back here +			 * to do it again */ +			if(qout_orig && iq->minimise_count > 0) { +				iq->minimise_count--; +				iq->qinfo_out.qname = qout_orig; +				iq->qinfo_out.qname_len = qout_orig_len; +			}  			return 0;  		}  		/* did we do enough fallback queries already? */ @@ -2463,13 +2475,21 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,  				iq->num_current_queries);  			qstate->ext_state[id] = module_wait_reply;  		} +		/* undo qname minimise step because we'll get back here +		 * to do it again */ +		if(qout_orig && iq->minimise_count > 0) { +			iq->minimise_count--; +			iq->qinfo_out.qname = qout_orig; +			iq->qinfo_out.qname_len = qout_orig_len; +		}  		return 0;  	}  	/* if not forwarding, check ratelimits per delegationpoint name */  	if(!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok) {  		if(!infra_ratelimit_inc(qstate->env->infra_cache, iq->dp->name, -			iq->dp->namelen, *qstate->env->now)) { +			iq->dp->namelen, *qstate->env->now, &qstate->qinfo, +			qstate->reply)) {  			lock_basic_lock(&ie->queries_ratelimit_lock);  			ie->num_queries_ratelimited++;  			lock_basic_unlock(&ie->queries_ratelimit_lock); | 
