aboutsummaryrefslogtreecommitdiff
path: root/external/unbound/iterator
diff options
context:
space:
mode:
authorRiccardo Spagni <ric@spagni.net>2015-12-30 12:57:50 +0200
committerRiccardo Spagni <ric@spagni.net>2015-12-30 12:57:50 +0200
commit2d43ae806359c89818c0519d81a65ded768746d8 (patch)
treec5ca4144a8f721efb0b4d051ee604f2694e6df64 /external/unbound/iterator
parentno longer need to pass the size to rapidjson (diff)
downloadmonero-2d43ae806359c89818c0519d81a65ded768746d8.tar.xz
update unbound, fix unbound openssl issue on OS X
Diffstat (limited to 'external/unbound/iterator')
-rw-r--r--external/unbound/iterator/iter_hints.c4
-rw-r--r--external/unbound/iterator/iter_scrub.c38
-rw-r--r--external/unbound/iterator/iter_utils.c4
-rw-r--r--external/unbound/iterator/iterator.c132
-rw-r--r--external/unbound/iterator/iterator.h37
5 files changed, 203 insertions, 12 deletions
diff --git a/external/unbound/iterator/iter_hints.c b/external/unbound/iterator/iter_hints.c
index 25cae0723..d7f8158d1 100644
--- a/external/unbound/iterator/iter_hints.c
+++ b/external/unbound/iterator/iter_hints.c
@@ -135,7 +135,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
if(!ah(dp, "E.ROOT-SERVERS.NET.", "192.203.230.10")) goto failed;
if(!ah(dp, "F.ROOT-SERVERS.NET.", "192.5.5.241")) goto failed;
if(!ah(dp, "G.ROOT-SERVERS.NET.", "192.112.36.4")) goto failed;
- if(!ah(dp, "H.ROOT-SERVERS.NET.", "128.63.2.53")) goto failed;
+ if(!ah(dp, "H.ROOT-SERVERS.NET.", "198.97.190.53")) goto failed;
if(!ah(dp, "I.ROOT-SERVERS.NET.", "192.36.148.17")) goto failed;
if(!ah(dp, "J.ROOT-SERVERS.NET.", "192.58.128.30")) goto failed;
if(!ah(dp, "K.ROOT-SERVERS.NET.", "193.0.14.129")) goto failed;
@@ -148,7 +148,7 @@ compile_time_root_prime(int do_ip4, int do_ip6)
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, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) goto failed;
- if(!ah(dp, "H.ROOT-SERVERS.NET.", "2001:500:1::803f:235")) 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;
if(!ah(dp, "J.ROOT-SERVERS.NET.", "2001:503:c27::2:30")) goto failed;
if(!ah(dp, "K.ROOT-SERVERS.NET.", "2001:7fd::1")) goto failed;
diff --git a/external/unbound/iterator/iter_scrub.c b/external/unbound/iterator/iter_scrub.c
index cc05867c0..8a3fc170c 100644
--- a/external/unbound/iterator/iter_scrub.c
+++ b/external/unbound/iterator/iter_scrub.c
@@ -405,7 +405,43 @@ scrub_normalize(sldns_buffer* pkt, struct msg_parse* msg,
/* Follow the CNAME chain. */
if(rrset->type == LDNS_RR_TYPE_CNAME) {
+ struct rrset_parse* nx = rrset->rrset_all_next;
uint8_t* oldsname = sname;
+ /* see if the next one is a DNAME, if so, swap them */
+ if(nx && nx->section == LDNS_SECTION_ANSWER &&
+ nx->type == LDNS_RR_TYPE_DNAME &&
+ nx->rr_count == 1 &&
+ pkt_strict_sub(pkt, sname, nx->dname)) {
+ /* there is a DNAME after this CNAME, it
+ * is in the ANSWER section, and the DNAME
+ * applies to the name we cover */
+ /* check if the alias of the DNAME equals
+ * this CNAME */
+ uint8_t alias[LDNS_MAX_DOMAINLEN+1];
+ size_t aliaslen = 0;
+ uint8_t* t = NULL;
+ size_t tlen = 0;
+ if(synth_cname(sname, snamelen, nx, alias,
+ &aliaslen, pkt) &&
+ parse_get_cname_target(rrset, &t, &tlen) &&
+ dname_pkt_compare(pkt, alias, t) == 0) {
+ /* the synthesized CNAME equals the
+ * current CNAME. This CNAME is the
+ * one that the DNAME creates, and this
+ * CNAME is better capitalised */
+ verbose(VERB_ALGO, "normalize: re-order of DNAME and its CNAME");
+ if(prev) prev->rrset_all_next = nx;
+ else msg->rrset_first = nx;
+ if(nx->rrset_all_next == NULL)
+ msg->rrset_last = rrset;
+ rrset->rrset_all_next =
+ nx->rrset_all_next;
+ nx->rrset_all_next = rrset;
+ prev = nx;
+ }
+ }
+
+ /* move to next name in CNAME chain */
if(!parse_get_cname_target(rrset, &sname, &snamelen))
return 0;
prev = rrset;
@@ -638,7 +674,7 @@ scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg,
* children of the originating zone. The idea here is that,
* as far as we know, the server that we contacted is ONLY
* authoritative for the originating zone. It, of course, MAY
- * be authoriative for any other zones, and of course, MAY
+ * be authoritative for any other zones, and of course, MAY
* NOT be authoritative for some subdomains of the originating
* zone. */
prev = NULL;
diff --git a/external/unbound/iterator/iter_utils.c b/external/unbound/iterator/iter_utils.c
index bc94ef682..58e62fbeb 100644
--- a/external/unbound/iterator/iter_utils.c
+++ b/external/unbound/iterator/iter_utils.c
@@ -255,7 +255,7 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
return -1; /* server is lame */
else if(rtt >= USEFUL_SERVER_TOP_TIMEOUT)
/* server is unresponsive,
- * we used to return TOP_TIMOUT, but fairly useless,
+ * we used to return TOP_TIMEOUT, but fairly useless,
* because if == TOP_TIMEOUT is dropped because
* blacklisted later, instead, remove it here, so
* other choices (that are not blacklisted) can be
@@ -306,7 +306,7 @@ iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
return got_it;
}
-/** filter the addres list, putting best targets at front,
+/** filter the address list, putting best targets at front,
* returns number of best targets (or 0, no suitable targets) */
static int
iter_filter_order(struct iter_env* iter_env, struct module_env* env,
diff --git a/external/unbound/iterator/iterator.c b/external/unbound/iterator/iterator.c
index 96918fa97..b1bf902d5 100644
--- a/external/unbound/iterator/iterator.c
+++ b/external/unbound/iterator/iterator.c
@@ -64,6 +64,7 @@
#include "util/random.h"
#include "sldns/rrdef.h"
#include "sldns/wire2str.h"
+#include "sldns/str2wire.h"
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
@@ -81,6 +82,21 @@ iter_init(struct module_env* env, int id)
log_err("iterator: could not apply configuration settings.");
return 0;
}
+ if(env->cfg->qname_minimisation) {
+ uint8_t dname[LDNS_MAX_DOMAINLEN+1];
+ size_t len = sizeof(dname);
+ if(sldns_str2wire_dname_buf("ip6.arpa.", dname, &len) != 0) {
+ log_err("ip6.arpa. parse error");
+ return 0;
+ }
+ iter_env->ip6arpa_dname = (uint8_t*)malloc(len);
+ if(!iter_env->ip6arpa_dname) {
+ log_err("malloc failure");
+ return 0;
+ }
+ memcpy(iter_env->ip6arpa_dname, dname, len);
+ }
+
return 1;
}
@@ -101,6 +117,7 @@ iter_deinit(struct module_env* env, int id)
if(!env || !env->modinfo[id])
return;
iter_env = (struct iter_env*)env->modinfo[id];
+ free(iter_env->ip6arpa_dname);
free(iter_env->target_fetch_policy);
priv_delete(iter_env->priv);
donotq_delete(iter_env->donotq);
@@ -145,6 +162,12 @@ iter_new(struct module_qstate* qstate, int id)
/* Start with the (current) qname. */
iq->qchase = qstate->qinfo;
outbound_list_init(&iq->outlist);
+ if (qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = INIT_MINIMISE_STATE;
+ else
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
+
+ memset(&iq->qinfo_out, 0, sizeof(struct query_info));
return 1;
}
@@ -176,7 +199,7 @@ next_state(struct iter_qstate* iq, enum iter_state nextstate)
/**
* Transition an event to its final state. Final states always either return
* a result up the module chain, or reactivate a dependent event. Which
- * final state to transtion to is set in the module state for the event when
+ * final state to transition to is set in the module state for the event when
* it was created, and depends on the original purpose of the event.
*
* The response is stored in the qstate->buf buffer.
@@ -506,7 +529,7 @@ target_count_increase(struct iter_qstate* iq, int num)
/**
* Generate a subrequest.
* Generate a local request event. Local events are tied to this module, and
- * have a correponding (first tier) event that is waiting for this event to
+ * have a corresponding (first tier) event that is waiting for this event to
* resolve to continue.
*
* @param qname The query name for this request.
@@ -590,6 +613,11 @@ generate_sub_request(uint8_t* qname, size_t qnamelen, uint16_t qtype,
subiq->qchase = subq->qinfo;
subiq->chase_flags = subq->query_flags;
subiq->refetch_glue = 0;
+ if(qstate->env->cfg->qname_minimisation)
+ subiq->minimisation_state = INIT_MINIMISE_STATE;
+ else
+ subiq->minimisation_state = DONOT_MINIMISE_STATE;
+ memset(&subiq->qinfo_out, 0, sizeof(struct query_info));
}
return 1;
}
@@ -1042,6 +1070,8 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
iq->query_restart_count++;
iq->sent_count = 0;
sock_list_insert(&qstate->reply_origin, NULL, 0, qstate->region);
+ if(qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = INIT_MINIMISE_STATE;
return next_state(iq, INIT_REQUEST_STATE);
}
@@ -1062,6 +1092,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
iq->refetch_glue = 0;
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
/* the request has been forwarded.
* forwarded requests need to be immediately sent to the
* next state, QUERYTARGETS. */
@@ -1599,6 +1630,8 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq,
iq->refetch_glue = 1;
iq->query_restart_count++;
iq->sent_count = 0;
+ if(qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = INIT_MINIMISE_STATE;
return next_state(iq, INIT_REQUEST_STATE);
}
}
@@ -1975,9 +2008,78 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
}
+ if(iq->minimisation_state == INIT_MINIMISE_STATE) {
+ /* (Re)set qinfo_out to (new) delegation point, except
+ * when qinfo_out is already a subdomain of dp. This happens
+ * when resolving ip6.arpa dnames. */
+ if(!(iq->qinfo_out.qname_len
+ && dname_subdomain_c(iq->qchase.qname,
+ iq->qinfo_out.qname)
+ && dname_subdomain_c(iq->qinfo_out.qname,
+ 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.qclass = iq->qchase.qclass;
+ }
+
+ iq->minimisation_state = MINIMISE_STATE;
+ }
+ if(iq->minimisation_state == MINIMISE_STATE) {
+ int labdiff = dname_count_labels(iq->qchase.qname) -
+ dname_count_labels(iq->qinfo_out.qname);
+
+ iq->qinfo_out.qname = iq->qchase.qname;
+ iq->qinfo_out.qname_len = iq->qchase.qname_len;
+
+ /* Special treatment for ip6.arpa lookups.
+ * Reverse IPv6 dname has 34 labels, increment the IP part
+ * (usually first 32 labels) by 8 labels (7 more than the
+ * default 1 label increment). */
+ if(labdiff <= 32 &&
+ dname_subdomain_c(iq->qchase.qname, ie->ip6arpa_dname)) {
+ labdiff -= 7;
+ /* Small chance of zone cut after first label. Stop
+ * minimising */
+ if(labdiff <= 1)
+ labdiff = 0;
+ }
+
+ if(labdiff > 1) {
+ verbose(VERB_QUERY, "removing %d labels", labdiff-1);
+ dname_remove_labels(&iq->qinfo_out.qname,
+ &iq->qinfo_out.qname_len,
+ labdiff-1);
+ }
+ if(labdiff < 1 ||
+ (labdiff < 2 && iq->qchase.qtype == LDNS_RR_TYPE_DS))
+ /* Stop minimising this query, resolve "as usual" */
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
+ else {
+ struct dns_msg* msg = dns_cache_lookup(qstate->env,
+ iq->qinfo_out.qname, iq->qinfo_out.qname_len,
+ iq->qinfo_out.qtype, iq->qinfo_out.qclass,
+ qstate->query_flags, qstate->region,
+ qstate->env->scratch);
+ if(msg && msg->rep->an_numrrsets == 0
+ && FLAGS_GET_RCODE(msg->rep->flags) ==
+ LDNS_RCODE_NOERROR)
+ /* no need to send query if it is already
+ * cached as NOERROR/NODATA */
+ 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 == DONOT_MINIMISE_STATE)
+ iq->qinfo_out = iq->qchase;
+
/* We have a valid target. */
if(verbosity >= VERB_QUERY) {
- log_query_info(VERB_QUERY, "sending query:", &iq->qchase);
+ log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out);
log_name_addr(VERB_QUERY, "sending to target:", iq->dp->name,
&target->addr, target->addrlen);
verbose(VERB_ALGO, "dnssec status: %s%s",
@@ -1986,8 +2088,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
}
fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
outq = (*qstate->env->send_query)(
- iq->qchase.qname, iq->qchase.qname_len,
- iq->qchase.qtype, iq->qchase.qclass,
+ iq->qinfo_out.qname, iq->qinfo_out.qname_len,
+ iq->qinfo_out.qtype, iq->qinfo_out.qclass,
iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD,
iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
ie, iq), &target->addr, target->addrlen, iq->dp->name,
@@ -2042,6 +2144,9 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
enum response_type type;
iq->num_current_queries--;
if(iq->response == NULL) {
+ /* Don't increment qname when QNAME minimisation is enabled */
+ if (qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = SKIP_MINIMISE_STATE;
iq->chase_to_rd = 0;
iq->dnssec_lame_query = 0;
verbose(VERB_ALGO, "query response was timeout");
@@ -2142,6 +2247,15 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
sock_list_insert(&qstate->reply_origin,
&qstate->reply->addr, qstate->reply->addrlen,
qstate->region);
+ if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
+ /* Best effort qname-minimisation.
+ * Stop minimising and send full query when RCODE
+ * is not NOERROR */
+ if(FLAGS_GET_RCODE(iq->response->rep->flags) !=
+ LDNS_RCODE_NOERROR)
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
+ return next_state(iq, QUERYTARGETS_STATE);
+ }
return final_state(iq);
} else if(type == RESPONSE_TYPE_REFERRAL) {
/* REFERRAL type responses get a reset of the
@@ -2201,6 +2315,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
* point to the referral. */
iq->deleg_msg = iq->response;
iq->dp = delegpt_from_message(iq->response, qstate->region);
+ if (qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = INIT_MINIMISE_STATE;
if(!iq->dp)
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
if(!cache_fill_missing(qstate->env, iq->qchase.qclass,
@@ -2280,6 +2396,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* set the current request's qname to the new value. */
iq->qchase.qname = sname;
iq->qchase.qname_len = snamelen;
+ if (qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = INIT_MINIMISE_STATE;
/* Clear the query state, since this is a query restart. */
iq->deleg_msg = NULL;
iq->dp = NULL;
@@ -2353,6 +2471,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq,
/* LAME, THROWAWAY and "unknown" all end up here.
* Recycle to the QUERYTARGETS state to hopefully try a
* different target. */
+ if (qstate->env->cfg->qname_minimisation)
+ iq->minimisation_state = DONOT_MINIMISE_STATE;
return next_state(iq, QUERYTARGETS_STATE);
}
@@ -2968,7 +3088,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
prs->flags &= ~BIT_CD;
/* normalize and sanitize: easy to delete items from linked lists */
- if(!scrub_message(pkt, prs, &iq->qchase, iq->dp->name,
+ if(!scrub_message(pkt, prs, &iq->qinfo_out, iq->dp->name,
qstate->env->scratch, qstate->env, ie)) {
/* if 0x20 enabled, start fallback, but we have no message */
if(event == module_event_capsfail && !iq->caps_fallback) {
diff --git a/external/unbound/iterator/iterator.h b/external/unbound/iterator/iterator.h
index aaf0fb383..b7aa82ebe 100644
--- a/external/unbound/iterator/iterator.h
+++ b/external/unbound/iterator/iterator.h
@@ -54,7 +54,7 @@ struct iter_priv;
struct rbtree_t;
/** max number of targets spawned for a query and its subqueries */
-#define MAX_TARGET_COUNT 32
+#define MAX_TARGET_COUNT 64
/** max number of query restarts. Determines max number of CNAME chain. */
#define MAX_RESTART_COUNT 8
/** max number of referrals. Makes sure resolver does not run away */
@@ -112,6 +112,32 @@ struct iter_env {
* array of max_dependency_depth+1 size.
*/
int* target_fetch_policy;
+
+ /** ip6.arpa dname in wireformat, used for qname-minimisation */
+ uint8_t* ip6arpa_dname;
+};
+
+/**
+ * QNAME minimisation state
+ */
+enum minimisation_state {
+ /**
+ * (Re)start minimisation. Outgoing QNAME should be set to dp->name.
+ * State entered on new query or after following refferal or CNAME.
+ */
+ INIT_MINIMISE_STATE = 0,
+ /**
+ * QNAME minimisataion ongoing. Increase QNAME on every iteration.
+ */
+ MINIMISE_STATE,
+ /**
+ * Don't increment QNAME this iteration
+ */
+ SKIP_MINIMISE_STATE,
+ /**
+ * Send out full QNAME + original QTYPE
+ */
+ DONOT_MINIMISE_STATE,
};
/**
@@ -322,6 +348,15 @@ struct iter_qstate {
/** list of pending queries to authoritative servers. */
struct outbound_list outlist;
+
+ /** QNAME minimisation state */
+ enum minimisation_state minimisation_state;
+
+ /**
+ * The query info that is sent upstream. Will be a subset of qchase
+ * when qname minimisation is enabled.
+ */
+ struct query_info qinfo_out;
};
/**