diff options
author | Florian Obser <florian@cvs.openbsd.org> | 2019-03-30 01:54:44 +0000 |
---|---|---|
committer | Florian Obser <florian@cvs.openbsd.org> | 2019-03-30 01:54:44 +0000 |
commit | 00ee853f0854675f3488cfa94b35bfd6f6406dc3 (patch) | |
tree | b236817ee9215f0e11efa14276222afe28eb1c0f /sbin | |
parent | b46f5afffeed0510aca777c9cc9ebec532c59c5a (diff) |
update to libunbound 1.9.1; heavy lifting by sthen in unbound(8)
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/unwind/libunbound/config.h | 9 | ||||
-rw-r--r-- | sbin/unwind/libunbound/iterator/iter_fwd.c | 2 | ||||
-rw-r--r-- | sbin/unwind/libunbound/iterator/iter_hints.c | 2 | ||||
-rw-r--r-- | sbin/unwind/libunbound/iterator/iter_utils.c | 60 | ||||
-rw-r--r-- | sbin/unwind/libunbound/iterator/iterator.c | 24 | ||||
-rw-r--r-- | sbin/unwind/libunbound/libunbound/libworker.c | 5 | ||||
-rw-r--r-- | sbin/unwind/libunbound/respip/respip.c | 8 | ||||
-rw-r--r-- | sbin/unwind/libunbound/services/cache/infra.c | 44 | ||||
-rw-r--r-- | sbin/unwind/libunbound/services/cache/infra.h | 9 | ||||
-rw-r--r-- | sbin/unwind/libunbound/services/listen_dnsport.c | 4 | ||||
-rw-r--r-- | sbin/unwind/libunbound/services/localzone.c | 26 | ||||
-rw-r--r-- | sbin/unwind/libunbound/services/localzone.h | 4 | ||||
-rw-r--r-- | sbin/unwind/libunbound/services/modstack.c | 10 | ||||
-rw-r--r-- | sbin/unwind/libunbound/services/outside_network.c | 31 | ||||
-rw-r--r-- | sbin/unwind/libunbound/util/configlexer.c | 4 | ||||
-rw-r--r-- | sbin/unwind/libunbound/util/configparser.y | 8 | ||||
-rw-r--r-- | sbin/unwind/libunbound/util/net_help.c | 17 | ||||
-rw-r--r-- | sbin/unwind/libunbound/util/netevent.c | 6 |
18 files changed, 211 insertions, 62 deletions
diff --git a/sbin/unwind/libunbound/config.h b/sbin/unwind/libunbound/config.h index 81b42aa2243..7b0ba84679b 100644 --- a/sbin/unwind/libunbound/config.h +++ b/sbin/unwind/libunbound/config.h @@ -70,6 +70,9 @@ /* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ #define HAVE_CRYPTO_CLEANUP_ALL_EX_DATA 1 +/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */ +#define HAVE_CRYPTO_THREADID_SET_CALLBACK 1 + /* Define to 1 if you have the `ctime_r' function. */ #define HAVE_CTIME_R 1 @@ -661,7 +664,7 @@ #define PACKAGE_NAME "unbound" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "unbound 1.9.0" +#define PACKAGE_STRING "unbound 1.9.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "unbound" @@ -670,7 +673,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.9.0" +#define PACKAGE_VERSION "1.9.1" /* default pidfile location */ #define PIDFILE "" @@ -692,7 +695,7 @@ #define ROOT_CERT_FILE "/var/unbound/etc/icannbundle.pem" /* version number for resource files */ -#define RSRC_PACKAGE_VERSION 1,9,0,0 +#define RSRC_PACKAGE_VERSION 1,9,1,0 /* Directory to chdir to */ #define RUN_DIR "/var/unbound/etc" diff --git a/sbin/unwind/libunbound/iterator/iter_fwd.c b/sbin/unwind/libunbound/iterator/iter_fwd.c index 4eb0eb71860..ea3d70e0732 100644 --- a/sbin/unwind/libunbound/iterator/iter_fwd.c +++ b/sbin/unwind/libunbound/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/sbin/unwind/libunbound/iterator/iter_hints.c b/sbin/unwind/libunbound/iterator/iter_hints.c index 0b35a9d9e24..60e518122ed 100644 --- a/sbin/unwind/libunbound/iterator/iter_hints.c +++ b/sbin/unwind/libunbound/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/sbin/unwind/libunbound/iterator/iter_utils.c b/sbin/unwind/libunbound/iterator/iter_utils.c index 4ac8efd0d17..be7965a60e3 100644 --- a/sbin/unwind/libunbound/iterator/iter_utils.c +++ b/sbin/unwind/libunbound/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/sbin/unwind/libunbound/iterator/iterator.c b/sbin/unwind/libunbound/iterator/iterator.c index 8312dfd5331..c73fb517748 100644 --- a/sbin/unwind/libunbound/iterator/iterator.c +++ b/sbin/unwind/libunbound/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); diff --git a/sbin/unwind/libunbound/libunbound/libworker.c b/sbin/unwind/libunbound/libunbound/libworker.c index a886f9a8811..01621927eb5 100644 --- a/sbin/unwind/libunbound/libunbound/libworker.c +++ b/sbin/unwind/libunbound/libunbound/libworker.c @@ -222,11 +222,10 @@ libworker_setup(struct ub_ctx* ctx, int is_bg, struct ub_event_base* eb) } numports = cfg_condense_ports(cfg, &ports); if(numports == 0) { - int locked = !w->is_bg || w->is_bg_thread; - libworker_delete(w); - if(locked) { + if(!w->is_bg || w->is_bg_thread) { lock_basic_unlock(&ctx->cfglock); } + libworker_delete(w); return NULL; } w->back = outside_network_create(w->base, cfg->msg_buffer_size, diff --git a/sbin/unwind/libunbound/respip/respip.c b/sbin/unwind/libunbound/respip/respip.c index bcb31f89224..d61877b556c 100644 --- a/sbin/unwind/libunbound/respip/respip.c +++ b/sbin/unwind/libunbound/respip/respip.c @@ -183,6 +183,8 @@ respip_action_cfg(struct respip_set* set, const char* ipstr, action = respip_inform; else if(strcmp(actnstr, "inform_deny") == 0) action = respip_inform_deny; + else if(strcmp(actnstr, "inform_redirect") == 0) + action = respip_inform_redirect; else if(strcmp(actnstr, "always_transparent") == 0) action = respip_always_transparent; else if(strcmp(actnstr, "always_refuse") == 0) @@ -245,7 +247,8 @@ respip_enter_rr(struct regional* region, struct resp_addr* raddr, struct packed_rrset_data* pd; struct sockaddr* sa; int ret; - if(raddr->action != respip_redirect) { + if(raddr->action != respip_redirect + && raddr->action != respip_inform_redirect) { log_err("cannot parse response-ip-data %s: response-ip " "action for %s is not redirect", rrstr, netblock); return 0; @@ -750,7 +753,8 @@ respip_nodata_answer(uint16_t qtype, enum respip_action action, *new_repp = new_rep; return 1; } else if(action == respip_static || action == respip_redirect || - action == respip_always_nxdomain) { + action == respip_always_nxdomain || + action == respip_inform_redirect) { /* Since we don't know about other types of the owner name, * we generally return NOERROR/NODATA unless an NXDOMAIN action * is explicitly specified. */ diff --git a/sbin/unwind/libunbound/services/cache/infra.c b/sbin/unwind/libunbound/services/cache/infra.c index 07c41928d67..c2484a9f1aa 100644 --- a/sbin/unwind/libunbound/services/cache/infra.c +++ b/sbin/unwind/libunbound/services/cache/infra.c @@ -41,6 +41,8 @@ #include "config.h" #include "sldns/rrdef.h" #include "sldns/str2wire.h" +#include "sldns/sbuffer.h" +#include "sldns/wire2str.h" #include "services/cache/infra.h" #include "util/storage/slabhash.h" #include "util/storage/lookup3.h" @@ -907,7 +909,8 @@ int infra_rate_max(void* data, time_t now) } int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, - size_t namelen, time_t timenow) + size_t namelen, time_t timenow, struct query_info* qinfo, + struct comm_reply* replylist) { int lim, max; struct lruhash_entry* entry; @@ -930,9 +933,19 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, lock_rw_unlock(&entry->lock); if(premax < lim && max >= lim) { - char buf[257]; + char buf[257], qnm[257], ts[12], cs[12], ip[128]; dname_str(name, buf); - verbose(VERB_OPS, "ratelimit exceeded %s %d", buf, lim); + dname_str(qinfo->qname, qnm); + sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts)); + sldns_wire2str_class_buf(qinfo->qclass, cs, sizeof(cs)); + ip[0]=0; + if(replylist) { + addr_to_str((struct sockaddr_storage *)&replylist->addr, + replylist->addrlen, ip, sizeof(ip)); + verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s from %s", buf, lim, qnm, cs, ts, ip); + } else { + verbose(VERB_OPS, "ratelimit exceeded %s %d query %s %s %s", buf, lim, qnm, cs, ts); + } } return (max < lim); } @@ -991,7 +1004,7 @@ infra_get_mem(struct infra_cache* infra) } int infra_ip_ratelimit_inc(struct infra_cache* infra, - struct comm_reply* repinfo, time_t timenow) + struct comm_reply* repinfo, time_t timenow, struct sldns_buffer* buffer) { int max; struct lruhash_entry* entry; @@ -1010,11 +1023,28 @@ int infra_ip_ratelimit_inc(struct infra_cache* infra, lock_rw_unlock(&entry->lock); if(premax < infra_ip_ratelimit && max >= infra_ip_ratelimit) { - char client_ip[128]; + char client_ip[128], qnm[LDNS_MAX_DOMAINLEN+1+12+12]; addr_to_str((struct sockaddr_storage *)&repinfo->addr, repinfo->addrlen, client_ip, sizeof(client_ip)); - verbose(VERB_OPS, "ip_ratelimit exceeded %s %d", - client_ip, infra_ip_ratelimit); + qnm[0]=0; + if(sldns_buffer_limit(buffer)>LDNS_HEADER_SIZE && + LDNS_QDCOUNT(sldns_buffer_begin(buffer))!=0) { + (void)sldns_wire2str_rrquestion_buf( + sldns_buffer_at(buffer, LDNS_HEADER_SIZE), + sldns_buffer_limit(buffer)-LDNS_HEADER_SIZE, + qnm, sizeof(qnm)); + if(strlen(qnm)>0 && qnm[strlen(qnm)-1]=='\n') + qnm[strlen(qnm)-1] = 0; /*remove newline*/ + if(strchr(qnm, '\t')) + *strchr(qnm, '\t') = ' '; + if(strchr(qnm, '\t')) + *strchr(qnm, '\t') = ' '; + verbose(VERB_OPS, "ip_ratelimit exceeded %s %d %s", + client_ip, infra_ip_ratelimit, qnm); + } else { + verbose(VERB_OPS, "ip_ratelimit exceeded %s %d (no query name)", + client_ip, infra_ip_ratelimit); + } } return (max <= infra_ip_ratelimit); } diff --git a/sbin/unwind/libunbound/services/cache/infra.h b/sbin/unwind/libunbound/services/cache/infra.h index 10db796bfcd..e33f2a6c04e 100644 --- a/sbin/unwind/libunbound/services/cache/infra.h +++ b/sbin/unwind/libunbound/services/cache/infra.h @@ -366,12 +366,15 @@ long long infra_get_host_rto(struct infra_cache* infra, * @param name: zone name * @param namelen: zone name length * @param timenow: what time it is now. + * @param qinfo: for logging, query name. + * @param replylist: for logging, querier's address (if any). * @return 1 if it could be incremented. 0 if the increment overshot the * ratelimit or if in the previous second the ratelimit was exceeded. * Failures like alloc failures are not returned (probably as 1). */ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, - size_t namelen, time_t timenow); + size_t namelen, time_t timenow, struct query_info* qinfo, + struct comm_reply* replylist); /** * Decrement the query rate counter for a delegation point. @@ -410,10 +413,12 @@ int infra_find_ratelimit(struct infra_cache* infra, uint8_t* name, * @param infra: infra cache * @param repinfo: information about client * @param timenow: what time it is now. + * @param buffer: with query for logging. * @return 1 if it could be incremented. 0 if the increment overshot the * ratelimit and the query should be dropped. */ int infra_ip_ratelimit_inc(struct infra_cache* infra, - struct comm_reply* repinfo, time_t timenow); + struct comm_reply* repinfo, time_t timenow, + struct sldns_buffer* buffer); /** * Get memory used by the infra cache. diff --git a/sbin/unwind/libunbound/services/listen_dnsport.c b/sbin/unwind/libunbound/services/listen_dnsport.c index 664072aa483..e74d1abcffc 100644 --- a/sbin/unwind/libunbound/services/listen_dnsport.c +++ b/sbin/unwind/libunbound/services/listen_dnsport.c @@ -1636,10 +1636,12 @@ tcp_req_info_setup_listen(struct tcp_req_info* req) if(wr) { req->cp->tcp_is_reading = 0; + comm_point_stop_listening(req->cp); comm_point_start_listening(req->cp, -1, req->cp->tcp_timeout_msec); } else if(rd) { req->cp->tcp_is_reading = 1; + comm_point_stop_listening(req->cp); comm_point_start_listening(req->cp, -1, req->cp->tcp_timeout_msec); /* and also read it (from SSL stack buffers), so @@ -1647,6 +1649,7 @@ tcp_req_info_setup_listen(struct tcp_req_info* req) * the TLS frame is sitting in the buffers. */ req->read_again = 1; } else { + comm_point_stop_listening(req->cp); comm_point_start_listening(req->cp, -1, req->cp->tcp_timeout_msec); comm_point_listen_for_rw(req->cp, 0, 0); @@ -1759,6 +1762,7 @@ tcp_req_info_handle_readdone(struct tcp_req_info* req) * clear to write to */ send_it: c->tcp_is_reading = 0; + comm_point_stop_listening(c); comm_point_start_listening(c, -1, c->tcp_timeout_msec); return; } diff --git a/sbin/unwind/libunbound/services/localzone.c b/sbin/unwind/libunbound/services/localzone.c index 902a29f21d4..6295b17e2fc 100644 --- a/sbin/unwind/libunbound/services/localzone.c +++ b/sbin/unwind/libunbound/services/localzone.c @@ -464,7 +464,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) return 0; } log_assert(z->dclass == rrclass); - if(z->type == local_zone_redirect && + if((z->type == local_zone_redirect || + z->type == local_zone_inform_redirect) && query_dname_compare(z->name, nm) != 0) { log_err("local-data in redirect zone must reside at top of zone" ", not at %s", rrstr); @@ -481,7 +482,8 @@ lz_enter_rr_into_zone(struct local_zone* z, const char* rrstr) /* Reject it if we would end up having CNAME and other data (including * another CNAME) for a redirect zone. */ - if(z->type == local_zone_redirect && node->rrsets) { + if((z->type == local_zone_redirect || + z->type == local_zone_inform_redirect) && node->rrsets) { const char* othertype = NULL; if (rrtype == LDNS_RR_TYPE_CNAME) othertype = "other"; @@ -1323,7 +1325,8 @@ local_data_answer(struct local_zone* z, struct module_env* env, key.name = qinfo->qname; key.namelen = qinfo->qname_len; key.namelabs = labs; - if(lz_type == local_zone_redirect) { + if(lz_type == local_zone_redirect || + lz_type == local_zone_inform_redirect) { key.name = z->name; key.namelen = z->namelen; key.namelabs = z->namelabs; @@ -1355,7 +1358,8 @@ local_data_answer(struct local_zone* z, struct module_env* env, return 0; /* Special case for alias matching. See local_data_answer(). */ - if(lz_type == local_zone_redirect && + if((lz_type == local_zone_redirect || + lz_type == local_zone_inform_redirect) && qinfo->qtype != LDNS_RR_TYPE_CNAME && lr->rrset->rk.type == htons(LDNS_RR_TYPE_CNAME)) { qinfo->local_alias = @@ -1370,7 +1374,8 @@ local_data_answer(struct local_zone* z, struct module_env* env, qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; return 1; } - if(lz_type == local_zone_redirect) { + if(lz_type == local_zone_redirect || + lz_type == local_zone_inform_redirect) { /* convert rrset name to query name; like a wildcard */ struct ub_packed_rrset_key r = *lr->rrset; r.rk.dname = qinfo->qname; @@ -1442,6 +1447,7 @@ lz_zone_answer(struct local_zone* z, struct module_env* env, return 1; } else if(lz_type == local_zone_static || lz_type == local_zone_redirect || + lz_type == local_zone_inform_redirect || lz_type == local_zone_always_nxdomain) { /* for static, reply nodata or nxdomain * for redirect, reply nodata */ @@ -1450,7 +1456,8 @@ lz_zone_answer(struct local_zone* z, struct module_env* env, * or using closest match for NSEC. * or using closest match for returning delegation downwards */ - int rcode = (ld || lz_type == local_zone_redirect)? + int rcode = (ld || lz_type == local_zone_redirect || + lz_type == local_zone_inform_redirect)? LDNS_RCODE_NOERROR:LDNS_RCODE_NXDOMAIN; if(z->soa) return local_encode(qinfo, env, edns, repinfo, buf, temp, @@ -1624,7 +1631,9 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, } } if((env->cfg->log_local_actions || - lzt == local_zone_inform || lzt == local_zone_inform_deny) + lzt == local_zone_inform || + lzt == local_zone_inform_deny || + lzt == local_zone_inform_redirect) && repinfo) lz_inform_print(z, qinfo, repinfo); @@ -1656,6 +1665,7 @@ const char* local_zone_type2str(enum localzone_type t) case local_zone_nodefault: return "nodefault"; case local_zone_inform: return "inform"; case local_zone_inform_deny: return "inform_deny"; + case local_zone_inform_redirect: return "inform_redirect"; case local_zone_always_transparent: return "always_transparent"; case local_zone_always_refuse: return "always_refuse"; case local_zone_always_nxdomain: return "always_nxdomain"; @@ -1682,6 +1692,8 @@ int local_zone_str2type(const char* type, enum localzone_type* t) *t = local_zone_inform; else if(strcmp(type, "inform_deny") == 0) *t = local_zone_inform_deny; + else if(strcmp(type, "inform_redirect") == 0) + *t = local_zone_inform_redirect; else if(strcmp(type, "always_transparent") == 0) *t = local_zone_always_transparent; else if(strcmp(type, "always_refuse") == 0) diff --git a/sbin/unwind/libunbound/services/localzone.h b/sbin/unwind/libunbound/services/localzone.h index dd7aa584c46..1d6caeff2c7 100644 --- a/sbin/unwind/libunbound/services/localzone.h +++ b/sbin/unwind/libunbound/services/localzone.h @@ -83,6 +83,8 @@ enum localzone_type { local_zone_inform, /** log client address, and block (drop) */ local_zone_inform_deny, + /** log client address, and direct */ + local_zone_inform_redirect, /** resolve normally, even when there is local data */ local_zone_always_transparent, /** answer with error, even when there is local data */ @@ -491,6 +493,8 @@ enum respip_action { respip_inform = local_zone_inform, /** log query source and don't answer query */ respip_inform_deny = local_zone_inform_deny, + /** log query source and redirect */ + respip_inform_redirect = local_zone_inform_redirect, /** resolve normally, even when there is response-ip data */ respip_always_transparent = local_zone_always_transparent, /** answer with 'refused' response */ diff --git a/sbin/unwind/libunbound/services/modstack.c b/sbin/unwind/libunbound/services/modstack.c index 136245a9683..05b949d1e33 100644 --- a/sbin/unwind/libunbound/services/modstack.c +++ b/sbin/unwind/libunbound/services/modstack.c @@ -113,8 +113,14 @@ modstack_config(struct module_stack* stack, const char* module_conf) for(i=0; i<stack->num; i++) { stack->mod[i] = module_factory(&module_conf); if(!stack->mod[i]) { - log_err("Unknown value for next module: '%s'", - module_conf); + char md[256]; + snprintf(md, sizeof(md), "%s", module_conf); + if(strchr(md, ' ')) *(strchr(md, ' ')) = 0; + if(strchr(md, '\t')) *(strchr(md, '\t')) = 0; + log_err("Unknown value in module-config, module: '%s'." + " This module is not present (not compiled in)," + " See the list of linked modules with unbound -h", + md); return 0; } } diff --git a/sbin/unwind/libunbound/services/outside_network.c b/sbin/unwind/libunbound/services/outside_network.c index 8ed5de37585..16d63df4395 100644 --- a/sbin/unwind/libunbound/services/outside_network.c +++ b/sbin/unwind/libunbound/services/outside_network.c @@ -1964,7 +1964,6 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, struct serviced_query* sq = (struct serviced_query*)arg; struct outside_network* outnet = sq->outnet; struct timeval now = *sq->outnet->now_tv; - int fallback_tcp = 0; sq->pending = NULL; /* removed after callback */ if(error == NETEVENT_TIMEOUT) { @@ -1996,14 +1995,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, } return 0; } - if(rto >= RTT_MAX_TIMEOUT) { - /* fallback_tcp = 1; */ - /* UDP does not work, fallback to TCP below */ - } else { - serviced_callbacks(sq, NETEVENT_TIMEOUT, c, rep); - return 0; - } - } else if(error != NETEVENT_NOERROR) { + } + if(error != NETEVENT_NOERROR) { /* udp returns error (due to no ID or interface available) */ serviced_callbacks(sq, error, c, rep); return 0; @@ -2016,9 +2009,8 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, sq->zone, sq->zonelen, sq->qbuf, sq->qbuflen, &sq->last_sent_time, sq->outnet->now_tv, c->buffer); #endif - if(!fallback_tcp) { - if( (sq->status == serviced_query_UDP_EDNS - ||sq->status == serviced_query_UDP_EDNS_FRAG) + if( (sq->status == serviced_query_UDP_EDNS + ||sq->status == serviced_query_UDP_EDNS_FRAG) && (LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) == LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE( sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL @@ -2032,7 +2024,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, serviced_callbacks(sq, NETEVENT_CLOSED, c, rep); } return 0; - } else if(sq->status == serviced_query_UDP_EDNS && + } else if(sq->status == serviced_query_UDP_EDNS && !sq->edns_lame_known) { /* now we know that edns queries received answers store that */ log_addr(VERB_ALGO, "serviced query: EDNS works for", @@ -2042,7 +2034,7 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, log_err("Out of memory caching edns works"); } sq->edns_lame_known = 1; - } else if(sq->status == serviced_query_UDP_EDNS_fallback && + } else if(sq->status == serviced_query_UDP_EDNS_fallback && !sq->edns_lame_known && (LDNS_RCODE_WIRE( sldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOERROR || LDNS_RCODE_WIRE(sldns_buffer_begin(c->buffer)) == @@ -2060,12 +2052,12 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, } } else { log_addr(VERB_ALGO, "serviced query: EDNS fails, but " - "not stored because need DNSSEC for", &sq->addr, + "not stored because need DNSSEC for", &sq->addr, sq->addrlen); } sq->status = serviced_query_UDP; - } - if(now.tv_sec > sq->last_sent_time.tv_sec || + } + if(now.tv_sec > sq->last_sent_time.tv_sec || (now.tv_sec == sq->last_sent_time.tv_sec && now.tv_usec > sq->last_sent_time.tv_usec)) { /* convert from microseconds to milliseconds */ @@ -2081,11 +2073,10 @@ serviced_udp_callback(struct comm_point* c, void* arg, int error, sq->last_rtt, (time_t)now.tv_sec)) log_err("out of memory noting rtt."); } - } - } /* end of if_!fallback_tcp */ + } /* perform TC flag check and TCP fallback after updating our * cache entries for EDNS status and RTT times */ - if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer)) || fallback_tcp) { + if(LDNS_TC_WIRE(sldns_buffer_begin(c->buffer))) { /* fallback to TCP */ /* this discards partial UDP contents */ if(sq->status == serviced_query_UDP_EDNS || diff --git a/sbin/unwind/libunbound/util/configlexer.c b/sbin/unwind/libunbound/util/configlexer.c index 52b179de292..8229e64824b 100644 --- a/sbin/unwind/libunbound/util/configlexer.c +++ b/sbin/unwind/libunbound/util/configlexer.c @@ -5,7 +5,7 @@ #define YY_INT_ALIGNED short int -/* $OpenBSD: configlexer.c,v 1.2 2019/02/08 10:35:14 sthen Exp $ */ +/* $OpenBSD: configlexer.c,v 1.3 2019/03/30 01:54:43 florian Exp $ */ /* A lexical scanner generated by flex */ @@ -27,7 +27,7 @@ /* end standard C headers. */ -/* $OpenBSD: configlexer.c,v 1.2 2019/02/08 10:35:14 sthen Exp $ */ +/* $OpenBSD: configlexer.c,v 1.3 2019/03/30 01:54:43 florian Exp $ */ /* flex integer type definitions */ diff --git a/sbin/unwind/libunbound/util/configparser.y b/sbin/unwind/libunbound/util/configparser.y index 5f52f4d7784..c7b916966e2 100644 --- a/sbin/unwind/libunbound/util/configparser.y +++ b/sbin/unwind/libunbound/util/configparser.y @@ -1783,12 +1783,14 @@ server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG && strcmp($3, "always_refuse")!=0 && strcmp($3, "always_nxdomain")!=0 && strcmp($3, "noview")!=0 - && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0) { + && strcmp($3, "inform")!=0 && strcmp($3, "inform_deny")!=0 + && strcmp($3, "inform_redirect") != 0) { yyerror("local-zone type: expected static, deny, " "refuse, redirect, transparent, " "typetransparent, inform, inform_deny, " - "always_transparent, always_refuse, " - "always_nxdomain, noview or nodefault"); + "inform_redirect, always_transparent, " + "always_refuse, always_nxdomain, noview " + "or nodefault"); free($2); free($3); } else if(strcmp($3, "nodefault")==0) { diff --git a/sbin/unwind/libunbound/util/net_help.c b/sbin/unwind/libunbound/util/net_help.c index 1a4fa8a58e6..2b1be92460b 100644 --- a/sbin/unwind/libunbound/util/net_help.c +++ b/sbin/unwind/libunbound/util/net_help.c @@ -1049,11 +1049,19 @@ void* outgoing_ssl_fd(void* sslctx, int fd) static lock_basic_type *ub_openssl_locks = NULL; /** callback that gets thread id for openssl */ +#ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK +static void +ub_crypto_id_cb(CRYPTO_THREADID *id) +{ + CRYPTO_THREADID_set_numeric(id, (unsigned long)log_thread_get()); +} +#else static unsigned long ub_crypto_id_cb(void) { return (unsigned long)log_thread_get(); } +#endif static void ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file), @@ -1078,7 +1086,11 @@ int ub_openssl_lock_init(void) for(i=0; i<CRYPTO_num_locks(); i++) { lock_basic_init(&ub_openssl_locks[i]); } +# ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK + CRYPTO_THREADID_set_callback(&ub_crypto_id_cb); +# else CRYPTO_set_id_callback(&ub_crypto_id_cb); +# endif CRYPTO_set_locking_callback(&ub_crypto_lock_cb); #endif /* OPENSSL_THREADS */ return 1; @@ -1090,7 +1102,11 @@ void ub_openssl_lock_delete(void) int i; if(!ub_openssl_locks) return; +# ifdef HAVE_CRYPTO_THREADID_SET_CALLBACK + CRYPTO_THREADID_set_callback(NULL); +# else CRYPTO_set_id_callback(NULL); +# endif CRYPTO_set_locking_callback(NULL); for(i=0; i<CRYPTO_num_locks(); i++) { lock_basic_destroy(&ub_openssl_locks[i]); @@ -1219,6 +1235,7 @@ listen_sslctx_delete_ticket_keys(void) struct tls_session_ticket_key *key; if(!ticket_keys) return; for(key = ticket_keys; key->key_name != NULL; key++) { + memset(key->key_name, 0xdd, 80); /* wipe key data from memory*/ free(key->key_name); } free(ticket_keys); diff --git a/sbin/unwind/libunbound/util/netevent.c b/sbin/unwind/libunbound/util/netevent.c index a507faf7e41..f33e44058b1 100644 --- a/sbin/unwind/libunbound/util/netevent.c +++ b/sbin/unwind/libunbound/util/netevent.c @@ -989,10 +989,10 @@ tcp_callback_writer(struct comm_point* c) c->tcp_is_reading = 1; c->tcp_byte_count = 0; /* switch from listening(write) to listening(read) */ - comm_point_stop_listening(c); if(c->tcp_req_info) { tcp_req_info_handle_writedone(c->tcp_req_info); } else { + comm_point_stop_listening(c); comm_point_start_listening(c, -1, -1); } } @@ -1006,11 +1006,11 @@ tcp_callback_reader(struct comm_point* c) if(c->tcp_do_toggle_rw) c->tcp_is_reading = 0; c->tcp_byte_count = 0; - if(c->type == comm_tcp) - comm_point_stop_listening(c); if(c->tcp_req_info) { tcp_req_info_handle_readdone(c->tcp_req_info); } else { + if(c->type == comm_tcp) + comm_point_stop_listening(c); fptr_ok(fptr_whitelist_comm_point(c->callback)); if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) { comm_point_start_listening(c, -1, c->tcp_timeout_msec); |