summaryrefslogtreecommitdiff
path: root/iterator
diff options
context:
space:
mode:
authorDag-Erling Smørgrav <des@FreeBSD.org>2019-06-30 14:56:56 +0000
committerDag-Erling Smørgrav <des@FreeBSD.org>2019-06-30 14:56:56 +0000
commit4713c21a1ac91081e50e474d11fcec002b43a562 (patch)
tree3dee8846d50565e925146b25f6b761ceb1ea7b07 /iterator
parent9c9d011eed674ddd7e4a0a148691887afb9e75cd (diff)
Diffstat (limited to 'iterator')
-rw-r--r--iterator/iter_fwd.c2
-rw-r--r--iterator/iter_hints.c2
-rw-r--r--iterator/iter_utils.c60
-rw-r--r--iterator/iterator.c24
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);