Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 May 2018 11:55:58 +0000 (UTC)
From:      =?UTF-8?Q?Dag-Erling_Sm=c3=b8rgrav?= <des@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-vendor@freebsd.org
Subject:   svn commit: r333543 - in vendor/unbound/dist: . cachedb contrib daemon dns64 dnscrypt doc edns-subnet iterator libunbound libunbound/python/doc/examples pythonmod pythonmod/doc pythonmod/doc/exampl...
Message-ID:  <201805121155.w4CBtw7H019898@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: des
Date: Sat May 12 11:55:57 2018
New Revision: 333543
URL: https://svnweb.freebsd.org/changeset/base/333543

Log:
  Vendor import of Unbound 1.6.7.

Modified:
  vendor/unbound/dist/cachedb/cachedb.c
  vendor/unbound/dist/configure
  vendor/unbound/dist/configure.ac
  vendor/unbound/dist/contrib/aaaa-filter-iterator.patch
  vendor/unbound/dist/contrib/parseunbound.pl
  vendor/unbound/dist/daemon/remote.c
  vendor/unbound/dist/daemon/stats.c
  vendor/unbound/dist/daemon/unbound.c
  vendor/unbound/dist/daemon/worker.c
  vendor/unbound/dist/dns64/dns64.c
  vendor/unbound/dist/dnscrypt/dnscrypt.c
  vendor/unbound/dist/dnscrypt/dnscrypt.h
  vendor/unbound/dist/doc/Changelog
  vendor/unbound/dist/doc/README
  vendor/unbound/dist/doc/example.conf.in
  vendor/unbound/dist/doc/libunbound.3.in
  vendor/unbound/dist/doc/requirements.txt
  vendor/unbound/dist/doc/unbound-anchor.8.in
  vendor/unbound/dist/doc/unbound-checkconf.8.in
  vendor/unbound/dist/doc/unbound-control.8.in
  vendor/unbound/dist/doc/unbound-host.1.in
  vendor/unbound/dist/doc/unbound.8.in
  vendor/unbound/dist/doc/unbound.conf.5.in
  vendor/unbound/dist/edns-subnet/addrtree.h
  vendor/unbound/dist/edns-subnet/subnetmod.c
  vendor/unbound/dist/edns-subnet/subnetmod.h
  vendor/unbound/dist/iterator/iter_utils.h
  vendor/unbound/dist/iterator/iterator.c
  vendor/unbound/dist/iterator/iterator.h
  vendor/unbound/dist/libunbound/context.h
  vendor/unbound/dist/libunbound/libunbound.c
  vendor/unbound/dist/libunbound/libworker.c
  vendor/unbound/dist/libunbound/python/doc/examples/example7.rst
  vendor/unbound/dist/libunbound/unbound.h
  vendor/unbound/dist/pythonmod/doc/examples/example2.rst
  vendor/unbound/dist/pythonmod/doc/examples/example3.rst
  vendor/unbound/dist/pythonmod/doc/examples/example5.rst
  vendor/unbound/dist/pythonmod/doc/examples/example6.rst
  vendor/unbound/dist/pythonmod/doc/modules/functions.rst
  vendor/unbound/dist/pythonmod/doc/modules/struct.rst
  vendor/unbound/dist/pythonmod/doc/usecase.rst
  vendor/unbound/dist/pythonmod/examples/edns.py
  vendor/unbound/dist/pythonmod/examples/inplace_callbacks.py
  vendor/unbound/dist/pythonmod/interface.i
  vendor/unbound/dist/services/cache/dns.c
  vendor/unbound/dist/services/cache/dns.h
  vendor/unbound/dist/services/mesh.c
  vendor/unbound/dist/services/outside_network.c
  vendor/unbound/dist/services/view.h
  vendor/unbound/dist/sldns/parse.c
  vendor/unbound/dist/sldns/parse.h
  vendor/unbound/dist/sldns/parseutil.c
  vendor/unbound/dist/sldns/parseutil.h
  vendor/unbound/dist/sldns/rrdef.h
  vendor/unbound/dist/sldns/sbuffer.h
  vendor/unbound/dist/sldns/str2wire.c
  vendor/unbound/dist/sldns/wire2str.c
  vendor/unbound/dist/smallapp/unbound-anchor.c
  vendor/unbound/dist/smallapp/unbound-control.c
  vendor/unbound/dist/smallapp/unbound-host.c
  vendor/unbound/dist/testcode/checklocks.h
  vendor/unbound/dist/testcode/unitecs.c
  vendor/unbound/dist/testdata/autotrust_10key.rpl
  vendor/unbound/dist/testdata/autotrust_addpend_2exceed.rpl
  vendor/unbound/dist/testdata/autotrust_addpend_early.rpl
  vendor/unbound/dist/testdata/autotrust_addpend_nosign.rpl
  vendor/unbound/dist/testdata/autotrust_addpend_nosignnew.rpl
  vendor/unbound/dist/testdata/autotrust_addpend_once.rpl
  vendor/unbound/dist/testdata/autotrust_addpend_twice.rpl
  vendor/unbound/dist/testdata/autotrust_init.rpl
  vendor/unbound/dist/testdata/autotrust_init_ds.rpl
  vendor/unbound/dist/testdata/autotrust_init_fail.rpl
  vendor/unbound/dist/testdata/autotrust_init_failsig.rpl
  vendor/unbound/dist/testdata/autotrust_init_legacy.rpl
  vendor/unbound/dist/testdata/autotrust_init_sigs.rpl
  vendor/unbound/dist/testdata/autotrust_init_zsk.rpl
  vendor/unbound/dist/testdata/autotrust_missing.rpl
  vendor/unbound/dist/testdata/autotrust_missing_all.rpl
  vendor/unbound/dist/testdata/autotrust_missing_returns.rpl
  vendor/unbound/dist/testdata/autotrust_probefail.rpl
  vendor/unbound/dist/testdata/autotrust_probefailsig.rpl
  vendor/unbound/dist/testdata/autotrust_revoked_use.rpl
  vendor/unbound/dist/testdata/autotrust_revoked_with_invalid.rpl
  vendor/unbound/dist/testdata/autotrust_revtp.rpl
  vendor/unbound/dist/testdata/autotrust_revtp_use.rpl
  vendor/unbound/dist/testdata/autotrust_rollalgo.rpl
  vendor/unbound/dist/testdata/autotrust_rollalgo_unknown.rpl
  vendor/unbound/dist/testdata/autotrust_rollover.rpl
  vendor/unbound/dist/testdata/autotrust_valid_use.rpl
  vendor/unbound/dist/testdata/black_data.rpl
  vendor/unbound/dist/testdata/black_dnskey.rpl
  vendor/unbound/dist/testdata/black_ds.rpl
  vendor/unbound/dist/testdata/black_ds_entry.rpl
  vendor/unbound/dist/testdata/black_ent.rpl
  vendor/unbound/dist/testdata/black_key_entry.rpl
  vendor/unbound/dist/testdata/black_prime.rpl
  vendor/unbound/dist/testdata/black_prime_entry.rpl
  vendor/unbound/dist/testdata/dlv_anchor.rpl
  vendor/unbound/dist/testdata/dlv_ask_higher.rpl
  vendor/unbound/dist/testdata/dlv_below_ta.rpl
  vendor/unbound/dist/testdata/dlv_delegation.rpl
  vendor/unbound/dist/testdata/dlv_ds_lookup.rpl
  vendor/unbound/dist/testdata/dlv_insecure.rpl
  vendor/unbound/dist/testdata/dlv_insecure_negcache.rpl
  vendor/unbound/dist/testdata/dlv_keyretry.rpl
  vendor/unbound/dist/testdata/dlv_negnx.rpl
  vendor/unbound/dist/testdata/dlv_optout.rpl
  vendor/unbound/dist/testdata/dlv_remove_pos.rpl
  vendor/unbound/dist/testdata/dlv_unused.rpl
  vendor/unbound/dist/testdata/fwddlv_parse.rpl
  vendor/unbound/dist/testdata/ipsecmod_bogus_ipseckey.crpl
  vendor/unbound/dist/testdata/ipsecmod_ignore_bogus_ipseckey.crpl
  vendor/unbound/dist/testdata/iter_class_any.rpl
  vendor/unbound/dist/testdata/iter_dnsseclame_bug.rpl
  vendor/unbound/dist/testdata/iter_dnsseclame_ds.rpl
  vendor/unbound/dist/testdata/iter_dnsseclame_ds_ok.rpl
  vendor/unbound/dist/testdata/iter_dnsseclame_ta.rpl
  vendor/unbound/dist/testdata/iter_dnsseclame_ta_ok.rpl
  vendor/unbound/dist/testdata/iter_emptydp.rpl
  vendor/unbound/dist/testdata/iter_emptydp_for_glue.rpl
  vendor/unbound/dist/testdata/iter_primenoglue.rpl
  vendor/unbound/dist/testdata/iter_scrub_dname_rev.rpl
  vendor/unbound/dist/testdata/iter_scrub_dname_sec.rpl
  vendor/unbound/dist/testdata/local_cname.rpl
  vendor/unbound/dist/testdata/net_signed_servfail.rpl
  vendor/unbound/dist/testdata/nomem_cnametopos.rpl
  vendor/unbound/dist/testdata/stop_nxdomain.rpl
  vendor/unbound/dist/testdata/stop_nxdomain_minimised.rpl
  vendor/unbound/dist/testdata/subnet_cached.crpl
  vendor/unbound/dist/testdata/subnet_val_positive.crpl
  vendor/unbound/dist/testdata/subnet_val_positive_client.crpl
  vendor/unbound/dist/testdata/val_adbit.rpl
  vendor/unbound/dist/testdata/val_anchor_nx.rpl
  vendor/unbound/dist/testdata/val_ans_dsent.rpl
  vendor/unbound/dist/testdata/val_ans_nx.rpl
  vendor/unbound/dist/testdata/val_any.rpl
  vendor/unbound/dist/testdata/val_any_cname.rpl
  vendor/unbound/dist/testdata/val_any_dname.rpl
  vendor/unbound/dist/testdata/val_cnameinsectopos.rpl
  vendor/unbound/dist/testdata/val_cnamenx_dblnsec.rpl
  vendor/unbound/dist/testdata/val_cnamenx_rcodenx.rpl
  vendor/unbound/dist/testdata/val_cnameqtype.rpl
  vendor/unbound/dist/testdata/val_cnametocloser.rpl
  vendor/unbound/dist/testdata/val_cnametocloser_nosig.rpl
  vendor/unbound/dist/testdata/val_cnametocnamewctoposwc.rpl
  vendor/unbound/dist/testdata/val_cnametodname.rpl
  vendor/unbound/dist/testdata/val_cnametodnametocnametopos.rpl
  vendor/unbound/dist/testdata/val_cnametoinsecure.rpl
  vendor/unbound/dist/testdata/val_cnametonodata.rpl
  vendor/unbound/dist/testdata/val_cnametonodata_nonsec.rpl
  vendor/unbound/dist/testdata/val_cnametonsec.rpl
  vendor/unbound/dist/testdata/val_cnametonx.rpl
  vendor/unbound/dist/testdata/val_cnametooptin.rpl
  vendor/unbound/dist/testdata/val_cnametooptout.rpl
  vendor/unbound/dist/testdata/val_cnametopos.rpl
  vendor/unbound/dist/testdata/val_cnametoposnowc.rpl
  vendor/unbound/dist/testdata/val_cnametoposwc.rpl
  vendor/unbound/dist/testdata/val_cnamewctonodata.rpl
  vendor/unbound/dist/testdata/val_cnamewctonx.rpl
  vendor/unbound/dist/testdata/val_cnamewctoposwc.rpl
  vendor/unbound/dist/testdata/val_deleg_nons.rpl
  vendor/unbound/dist/testdata/val_dnametopos.rpl
  vendor/unbound/dist/testdata/val_dnametoposwc.rpl
  vendor/unbound/dist/testdata/val_dnamewc.rpl
  vendor/unbound/dist/testdata/val_ds_afterprime.rpl
  vendor/unbound/dist/testdata/val_ds_cname.rpl
  vendor/unbound/dist/testdata/val_ds_cnamesub.rpl
  vendor/unbound/dist/testdata/val_ds_gost.crpl
  vendor/unbound/dist/testdata/val_ds_gost_downgrade.crpl
  vendor/unbound/dist/testdata/val_ds_sha2.crpl
  vendor/unbound/dist/testdata/val_ds_sha2_downgrade.crpl
  vendor/unbound/dist/testdata/val_ds_sha2_lenient.crpl
  vendor/unbound/dist/testdata/val_dsnsec.rpl
  vendor/unbound/dist/testdata/val_faildnskey.rpl
  vendor/unbound/dist/testdata/val_faildnskey_ok.rpl
  vendor/unbound/dist/testdata/val_fwdds.rpl
  vendor/unbound/dist/testdata/val_keyprefetch.rpl
  vendor/unbound/dist/testdata/val_keyprefetch_verify.rpl
  vendor/unbound/dist/testdata/val_mal_wc.rpl
  vendor/unbound/dist/testdata/val_negcache_ds.rpl
  vendor/unbound/dist/testdata/val_negcache_dssoa.rpl
  vendor/unbound/dist/testdata/val_noadwhennodo.rpl
  vendor/unbound/dist/testdata/val_nodata.rpl
  vendor/unbound/dist/testdata/val_nodata_ent.rpl
  vendor/unbound/dist/testdata/val_nodata_entnx.rpl
  vendor/unbound/dist/testdata/val_nodata_entwc.rpl
  vendor/unbound/dist/testdata/val_nodata_failsig.rpl
  vendor/unbound/dist/testdata/val_nodata_hasdata.rpl
  vendor/unbound/dist/testdata/val_nodata_zonecut.rpl
  vendor/unbound/dist/testdata/val_nodatawc.rpl
  vendor/unbound/dist/testdata/val_nodatawc_badce.rpl
  vendor/unbound/dist/testdata/val_nodatawc_nodeny.rpl
  vendor/unbound/dist/testdata/val_nodatawc_one.rpl
  vendor/unbound/dist/testdata/val_nokeyprime.rpl
  vendor/unbound/dist/testdata/val_nsec3_b1_nameerror.rpl
  vendor/unbound/dist/testdata/val_nsec3_b1_nameerror_noce.rpl
  vendor/unbound/dist/testdata/val_nsec3_b1_nameerror_nonc.rpl
  vendor/unbound/dist/testdata/val_nsec3_b1_nameerror_nowc.rpl
  vendor/unbound/dist/testdata/val_nsec3_b21_nodataent.rpl
  vendor/unbound/dist/testdata/val_nsec3_b21_nodataent_wr.rpl
  vendor/unbound/dist/testdata/val_nsec3_b2_nodata.rpl
  vendor/unbound/dist/testdata/val_nsec3_b2_nodata_nons.rpl
  vendor/unbound/dist/testdata/val_nsec3_b3_optout.rpl
  vendor/unbound/dist/testdata/val_nsec3_b3_optout_negcache.rpl
  vendor/unbound/dist/testdata/val_nsec3_b3_optout_noce.rpl
  vendor/unbound/dist/testdata/val_nsec3_b3_optout_nonc.rpl
  vendor/unbound/dist/testdata/val_nsec3_b4_wild.rpl
  vendor/unbound/dist/testdata/val_nsec3_b4_wild_wr.rpl
  vendor/unbound/dist/testdata/val_nsec3_b5_wcnodata.rpl
  vendor/unbound/dist/testdata/val_nsec3_b5_wcnodata_noce.rpl
  vendor/unbound/dist/testdata/val_nsec3_b5_wcnodata_nonc.rpl
  vendor/unbound/dist/testdata/val_nsec3_b5_wcnodata_nowc.rpl
  vendor/unbound/dist/testdata/val_nsec3_cname_ds.rpl
  vendor/unbound/dist/testdata/val_nsec3_cname_par.rpl
  vendor/unbound/dist/testdata/val_nsec3_cname_sub.rpl
  vendor/unbound/dist/testdata/val_nsec3_cnametocnamewctoposwc.rpl
  vendor/unbound/dist/testdata/val_nsec3_entnodata_optout.rpl
  vendor/unbound/dist/testdata/val_nsec3_entnodata_optout_badopt.rpl
  vendor/unbound/dist/testdata/val_nsec3_entnodata_optout_match.rpl
  vendor/unbound/dist/testdata/val_nsec3_iter_high.rpl
  vendor/unbound/dist/testdata/val_nsec3_nodatawccname.rpl
  vendor/unbound/dist/testdata/val_nsec3_nods.rpl
  vendor/unbound/dist/testdata/val_nsec3_nods_badopt.rpl
  vendor/unbound/dist/testdata/val_nsec3_nods_badsig.rpl
  vendor/unbound/dist/testdata/val_nsec3_nods_negcache.rpl
  vendor/unbound/dist/testdata/val_nsec3_nods_soa.rpl
  vendor/unbound/dist/testdata/val_nsec3_optout_ad.rpl
  vendor/unbound/dist/testdata/val_nsec3_optout_cache.rpl
  vendor/unbound/dist/testdata/val_nsec3_wcany.rpl
  vendor/unbound/dist/testdata/val_nsec3_wcany_nodeny.rpl
  vendor/unbound/dist/testdata/val_nx.rpl
  vendor/unbound/dist/testdata/val_nx_nodeny.rpl
  vendor/unbound/dist/testdata/val_nx_nowc.rpl
  vendor/unbound/dist/testdata/val_nx_nsec3_collision.rpl
  vendor/unbound/dist/testdata/val_nx_nsec3_params.rpl
  vendor/unbound/dist/testdata/val_nx_overreach.rpl
  vendor/unbound/dist/testdata/val_pos_truncns.rpl
  vendor/unbound/dist/testdata/val_positive.rpl
  vendor/unbound/dist/testdata/val_positive_nosigs.rpl
  vendor/unbound/dist/testdata/val_positive_wc.rpl
  vendor/unbound/dist/testdata/val_positive_wc_nodeny.rpl
  vendor/unbound/dist/testdata/val_qds_oneanc.rpl
  vendor/unbound/dist/testdata/val_qds_twoanc.rpl
  vendor/unbound/dist/testdata/val_refer_unsignadd.rpl
  vendor/unbound/dist/testdata/val_referd.rpl
  vendor/unbound/dist/testdata/val_referglue.rpl
  vendor/unbound/dist/testdata/val_secds.rpl
  vendor/unbound/dist/testdata/val_secds_nosig.rpl
  vendor/unbound/dist/testdata/val_spurious_ns.rpl
  vendor/unbound/dist/testdata/val_stub_noroot.rpl
  vendor/unbound/dist/testdata/val_stubds.rpl
  vendor/unbound/dist/testdata/val_ta_algo_dnskey.rpl
  vendor/unbound/dist/testdata/val_ta_algo_dnskey_dp.rpl
  vendor/unbound/dist/testdata/val_ta_algo_missing.rpl
  vendor/unbound/dist/testdata/val_ta_algo_missing_dp.rpl
  vendor/unbound/dist/testdata/val_twocname.rpl
  vendor/unbound/dist/testdata/val_unalgo_dlv.rpl
  vendor/unbound/dist/testdata/val_unalgo_ds.rpl
  vendor/unbound/dist/testdata/val_unsec_cname.rpl
  vendor/unbound/dist/testdata/val_unsecds.rpl
  vendor/unbound/dist/testdata/val_unsecds_negcache.rpl
  vendor/unbound/dist/testdata/val_unsecds_qtypeds.rpl
  vendor/unbound/dist/testdata/val_wild_pos.rpl
  vendor/unbound/dist/util/config_file.c
  vendor/unbound/dist/util/config_file.h
  vendor/unbound/dist/util/configlexer.c
  vendor/unbound/dist/util/configlexer.lex
  vendor/unbound/dist/util/configparser.c
  vendor/unbound/dist/util/configparser.h
  vendor/unbound/dist/util/configparser.y
  vendor/unbound/dist/util/data/msgreply.c
  vendor/unbound/dist/util/data/msgreply.h
  vendor/unbound/dist/util/fptr_wlist.c
  vendor/unbound/dist/util/module.h
  vendor/unbound/dist/util/netevent.c
  vendor/unbound/dist/util/shm_side/shm_main.c
  vendor/unbound/dist/util/storage/slabhash.h
  vendor/unbound/dist/util/ub_event.h
  vendor/unbound/dist/validator/autotrust.c
  vendor/unbound/dist/validator/val_nsec3.c
  vendor/unbound/dist/validator/val_secalgo.c
  vendor/unbound/dist/validator/val_sigcrypt.c
  vendor/unbound/dist/validator/val_utils.h
  vendor/unbound/dist/validator/validator.c

Modified: vendor/unbound/dist/cachedb/cachedb.c
==============================================================================
--- vendor/unbound/dist/cachedb/cachedb.c	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/cachedb/cachedb.c	Sat May 12 11:55:57 2018	(r333543)
@@ -347,6 +347,13 @@ prep_data(struct module_qstate* qstate, struct sldns_b
 
 	if(!qstate->return_msg || !qstate->return_msg->rep)
 		return 0;
+	/* We don't store the reply if its TTL is 0 unless serve-expired is
+	 * enabled.  Such a reply won't be reusable and simply be a waste for
+	 * the backend.  It's also compatible with the default behavior of
+	 * dns_cache_store_msg(). */
+	if(qstate->return_msg->rep->ttl == 0 &&
+		!qstate->env->cfg->serve_expired)
+		return 0;
 	if(verbosity >= VERB_ALGO)
 		log_dns_msg("cachedb encoding", &qstate->return_msg->qinfo,
 	                qstate->return_msg->rep);
@@ -387,32 +394,37 @@ good_expiry_and_qinfo(struct module_qstate* qstate, st
 		&expiry, sizeof(expiry));
 	expiry = be64toh(expiry);
 
-	if((time_t)expiry < *qstate->env->now)
+	if((time_t)expiry < *qstate->env->now &&
+		!qstate->env->cfg->serve_expired)
 		return 0;
 
 	return 1;
 }
 
+/* Adjust the TTL of the given RRset by 'subtract'.  If 'subtract' is
+ * negative, set the TTL to 0. */
 static void
 packed_rrset_ttl_subtract(struct packed_rrset_data* data, time_t subtract)
 {
         size_t i;
         size_t total = data->count + data->rrsig_count;
-	if(data->ttl > subtract)
+	if(subtract >= 0 && data->ttl > subtract)
 		data->ttl -= subtract;
 	else	data->ttl = 0;
         for(i=0; i<total; i++) {
-		if(data->rr_ttl[i] > subtract)
+		if(subtract >= 0 && data->rr_ttl[i] > subtract)
                 	data->rr_ttl[i] -= subtract;
                 else	data->rr_ttl[i] = 0;
 	}
 }
 
+/* Adjust the TTL of a DNS message and its RRs by 'adjust'.  If 'adjust' is
+ * negative, set the TTLs to 0. */
 static void
 adjust_msg_ttl(struct dns_msg* msg, time_t adjust)
 {
 	size_t i;
-	if(msg->rep->ttl > adjust)
+	if(adjust >= 0 && msg->rep->ttl > adjust)
 		msg->rep->ttl -= adjust;
 	else	msg->rep->ttl = 0;
 	msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl);
@@ -476,10 +488,26 @@ parse_data(struct module_qstate* qstate, struct sldns_
 	adjust = *qstate->env->now - (time_t)timestamp;
 	if(qstate->return_msg->rep->ttl < adjust) {
 		verbose(VERB_ALGO, "cachedb msg expired");
-		return 0; /* message expired */
+		/* If serve-expired is enabled, we still use an expired message
+		 * setting the TTL to 0. */
+		if(qstate->env->cfg->serve_expired)
+			adjust = -1;
+		else
+			return 0; /* message expired */
 	}
 	verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
 	adjust_msg_ttl(qstate->return_msg, adjust);
+
+	/* Similar to the unbound worker, if serve-expired is enabled and
+	 * the msg would be considered to be expired, mark the state so a
+	 * refetch will be scheduled.  The comparison between 'expiry' and
+	 * 'now' should be redundant given how these values were calculated,
+	 * but we check it just in case as does good_expiry_and_qinfo(). */
+	if(qstate->env->cfg->serve_expired &&
+		(adjust == -1 || (time_t)expiry < *qstate->env->now)) {
+		qstate->need_refetch = 1;
+	}
+
 	return 1;
 }
 
@@ -563,11 +591,15 @@ cachedb_intcache_lookup(struct module_qstate* qstate)
 static void
 cachedb_intcache_store(struct module_qstate* qstate)
 {
+	uint32_t store_flags = qstate->query_flags;
+
+	if(qstate->env->cfg->serve_expired)
+		store_flags |= DNSCACHE_STORE_ZEROTTL;
 	if(!qstate->return_msg)
 		return;
 	(void)dns_cache_store(qstate->env, &qstate->qinfo,
 		qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0,
-		qstate->region, qstate->query_flags);
+		qstate->region, store_flags);
 }
 
 /**

Modified: vendor/unbound/dist/configure
==============================================================================
--- vendor/unbound/dist/configure	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/configure	Sat May 12 11:55:57 2018	(r333543)
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unbound 1.6.6.
+# Generated by GNU Autoconf 2.69 for unbound 1.6.7.
 #
 # Report bugs to <unbound-bugs@nlnetlabs.nl>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='unbound'
 PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.6.6'
-PACKAGE_STRING='unbound 1.6.6'
+PACKAGE_VERSION='1.6.7'
+PACKAGE_STRING='unbound 1.6.7'
 PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl'
 PACKAGE_URL=''
 
@@ -1437,7 +1437,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures unbound 1.6.6 to adapt to many kinds of systems.
+\`configure' configures unbound 1.6.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1502,7 +1502,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of unbound 1.6.6:";;
+     short | recursive ) echo "Configuration of unbound 1.6.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1714,7 +1714,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-unbound configure 1.6.6
+unbound configure 1.6.7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2423,7 +2423,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by unbound $as_me 1.6.6, which was
+It was created by unbound $as_me 1.6.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2775,11 +2775,11 @@ UNBOUND_VERSION_MAJOR=1
 
 UNBOUND_VERSION_MINOR=6
 
-UNBOUND_VERSION_MICRO=6
+UNBOUND_VERSION_MICRO=7
 
 
 LIBUNBOUND_CURRENT=7
-LIBUNBOUND_REVISION=5
+LIBUNBOUND_REVISION=6
 LIBUNBOUND_AGE=5
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
@@ -2836,6 +2836,7 @@ LIBUNBOUND_AGE=5
 # 1.6.4 had 7:3:5
 # 1.6.5 had 7:4:5
 # 1.6.6 had 7:5:5
+# 1.6.7 had 7:6:5
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -2851,7 +2852,7 @@ LIBUNBOUND_AGE=5
 # Current and Age.  Set Revision to 0, since this is the first
 # implementation of the new API.
 #
-# Otherwise, we're changing the binary API and breaking bakward
+# Otherwise, we're changing the binary API and breaking backward
 # compatibility with old binaries.  Increment Current.  Set Age to 0,
 # since we're backward compatible with no previous APIs.  Set Revision
 # to 0 too.
@@ -20693,7 +20694,7 @@ _ACEOF
 
 
 
-version=1.6.6
+version=1.6.7
 
 date=`date +'%b %e, %Y'`
 
@@ -21212,7 +21213,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by unbound $as_me 1.6.6, which was
+This file was extended by unbound $as_me 1.6.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21278,7 +21279,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-unbound config.status 1.6.6
+unbound config.status 1.6.7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 

Modified: vendor/unbound/dist/configure.ac
==============================================================================
--- vendor/unbound/dist/configure.ac	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/configure.ac	Sat May 12 11:55:57 2018	(r333543)
@@ -11,14 +11,14 @@ sinclude(dnscrypt/dnscrypt.m4)
 # must be numbers. ac_defun because of later processing
 m4_define([VERSION_MAJOR],[1])
 m4_define([VERSION_MINOR],[6])
-m4_define([VERSION_MICRO],[6])
+m4_define([VERSION_MICRO],[7])
 AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), unbound-bugs@nlnetlabs.nl, unbound)
 AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
 AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
 AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
 
 LIBUNBOUND_CURRENT=7
-LIBUNBOUND_REVISION=5
+LIBUNBOUND_REVISION=6
 LIBUNBOUND_AGE=5
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
@@ -75,6 +75,7 @@ LIBUNBOUND_AGE=5
 # 1.6.4 had 7:3:5
 # 1.6.5 had 7:4:5
 # 1.6.6 had 7:5:5
+# 1.6.7 had 7:6:5
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -90,7 +91,7 @@ LIBUNBOUND_AGE=5
 # Current and Age.  Set Revision to 0, since this is the first
 # implementation of the new API.
 #
-# Otherwise, we're changing the binary API and breaking bakward
+# Otherwise, we're changing the binary API and breaking backward
 # compatibility with old binaries.  Increment Current.  Set Age to 0,
 # since we're backward compatible with no previous APIs.  Set Revision
 # to 0 too.

Modified: vendor/unbound/dist/contrib/aaaa-filter-iterator.patch
==============================================================================
--- vendor/unbound/dist/contrib/aaaa-filter-iterator.patch	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/contrib/aaaa-filter-iterator.patch	Sat May 12 11:55:57 2018	(r333543)
@@ -1,10 +1,10 @@
 Index: trunk/doc/unbound.conf.5.in
 ===================================================================
---- trunk/doc/unbound.conf.5.in	(revision 3587)
+--- trunk/doc/unbound.conf.5.in	(revision 4357)
 +++ trunk/doc/unbound.conf.5.in	(working copy)
-@@ -593,6 +593,13 @@
- possible. Best effort approach, full QNAME and original QTYPE will be sent when
- upstream replies with a RCODE other than NOERROR. Default is off.
+@@ -701,6 +701,13 @@
+ this option in enabled. Only use if you know what you are doing.
+ This option only has effect when qname-minimisation is enabled. Default is off.
  .TP
 +.B aaaa\-filter: \fI<yes or no>
 +Activate behavior similar to BIND's AAAA-filter.
@@ -18,7 +18,7 @@ Index: trunk/doc/unbound.conf.5.in
  on your private network, and are not allowed to be returned for
 Index: trunk/iterator/iter_scrub.c
 ===================================================================
---- trunk/iterator/iter_scrub.c	(revision 3587)
+--- trunk/iterator/iter_scrub.c	(revision 4357)
 +++ trunk/iterator/iter_scrub.c	(working copy)
 @@ -617,6 +617,32 @@
  }
@@ -75,10 +75,11 @@ Index: trunk/iterator/iter_scrub.c
  	/* At this point, we brutally remove ALL rrsets that aren't 
  	 * children of the originating zone. The idea here is that, 
  	 * as far as we know, the server that we contacted is ONLY 
-@@ -681,6 +715,24 @@
+@@ -680,6 +714,24 @@
+ 	prev = NULL;
  	rrset = msg->rrset_first;
  	while(rrset) {
- 
++
 +		/* ASN: For AAAA records only... */
 +		if((ie->aaaa_filter) && (rrset->type == LDNS_RR_TYPE_AAAA)) {
 +			/* ASN: If this is not a AAAA query, then remove AAAA
@@ -96,13 +97,12 @@ Index: trunk/iterator/iter_scrub.c
 +				LDNS_RR_TYPE_AAAA, qinfo->qclass);
 +		}
 +		/* ASN: End of added code */
-+
+ 
  		/* remove private addresses */
  		if( (rrset->type == LDNS_RR_TYPE_A || 
- 			rrset->type == LDNS_RR_TYPE_AAAA)) {
 Index: trunk/iterator/iter_utils.c
 ===================================================================
---- trunk/iterator/iter_utils.c	(revision 3587)
+--- trunk/iterator/iter_utils.c	(revision 4357)
 +++ trunk/iterator/iter_utils.c	(working copy)
 @@ -175,6 +175,7 @@
  	}
@@ -114,9 +114,9 @@ Index: trunk/iterator/iter_utils.c
  
 Index: trunk/iterator/iterator.c
 ===================================================================
---- trunk/iterator/iterator.c	(revision 3587)
+--- trunk/iterator/iterator.c	(revision 4357)
 +++ trunk/iterator/iterator.c	(working copy)
-@@ -1776,6 +1776,53 @@
+@@ -1847,6 +1847,53 @@
  
  	return 0;
  }
@@ -170,7 +170,7 @@ Index: trunk/iterator/iterator.c
  	
  /** 
   * This is the request event state where the request will be sent to one of
-@@ -1823,6 +1870,13 @@
+@@ -1894,6 +1941,13 @@
  		return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
  	}
  	
@@ -184,7 +184,7 @@ Index: trunk/iterator/iterator.c
  	/* Make sure we have a delegation point, otherwise priming failed
  	 * or another failure occurred */
  	if(!iq->dp) {
-@@ -2922,6 +2976,61 @@
+@@ -3095,6 +3149,61 @@
  	return 0;
  }
  
@@ -244,9 +244,9 @@ Index: trunk/iterator/iterator.c
 +/* ASN: End of added code */
 +
  /*
-  * Return priming query results to interestes super querystates.
+  * Return priming query results to interested super querystates.
   * 
-@@ -2941,6 +3050,9 @@
+@@ -3114,6 +3223,9 @@
  	else if(super->qinfo.qtype == LDNS_RR_TYPE_DS && ((struct iter_qstate*)
  		super->minfo[id])->state == DSNS_FIND_STATE)
  		processDSNSResponse(qstate, id, super);
@@ -256,7 +256,7 @@ Index: trunk/iterator/iterator.c
  	else if(qstate->return_rcode != LDNS_RCODE_NOERROR)
  		error_supers(qstate, id, super);
  	else if(qstate->is_priming)
-@@ -2978,6 +3090,9 @@
+@@ -3151,6 +3263,9 @@
  			case INIT_REQUEST_3_STATE:
  				cont = processInitRequest3(qstate, iq, id);
  				break;
@@ -266,7 +266,7 @@ Index: trunk/iterator/iterator.c
  			case QUERYTARGETS_STATE:
  				cont = processQueryTargets(qstate, iq, ie, id);
  				break;
-@@ -3270,6 +3385,8 @@
+@@ -3460,6 +3575,8 @@
  		return "INIT REQUEST STATE (stage 2)";
  	case INIT_REQUEST_3_STATE:
  		return "INIT REQUEST STATE (stage 3)";
@@ -275,7 +275,7 @@ Index: trunk/iterator/iterator.c
  	case QUERYTARGETS_STATE :
  		return "QUERY TARGETS STATE";
  	case PRIME_RESP_STATE :
-@@ -3294,6 +3411,7 @@
+@@ -3484,6 +3601,7 @@
  		case INIT_REQUEST_STATE :
  		case INIT_REQUEST_2_STATE :
  		case INIT_REQUEST_3_STATE :
@@ -285,19 +285,19 @@ Index: trunk/iterator/iterator.c
  			return 0;
 Index: trunk/iterator/iterator.h
 ===================================================================
---- trunk/iterator/iterator.h	(revision 3587)
+--- trunk/iterator/iterator.h	(revision 4357)
 +++ trunk/iterator/iterator.h	(working copy)
-@@ -113,6 +113,9 @@
+@@ -130,6 +130,9 @@
  	 */
  	int* target_fetch_policy;
  
 +	/** ASN: AAAA-filter flag */
 +	int aaaa_filter;
 +
- 	/** ip6.arpa dname in wireformat, used for qname-minimisation */
- 	uint8_t* ip6arpa_dname;
- };
-@@ -163,6 +166,14 @@
+ 	/** lock on ratelimit counter */
+ 	lock_basic_type queries_ratelimit_lock;
+ 	/** number of queries that have been ratelimited */
+@@ -182,6 +185,14 @@
  	INIT_REQUEST_3_STATE,
  
  	/**
@@ -311,26 +311,26 @@ Index: trunk/iterator/iterator.h
 +	/**
  	 * Each time a delegation point changes for a given query or a 
  	 * query times out and/or wakes up, this state is (re)visited. 
- 	 * This state is reponsible for iterating through a list of 
-@@ -346,6 +357,13 @@
+ 	 * This state is responsible for iterating through a list of 
+@@ -364,6 +375,13 @@
+ 	 * be used when creating the state. A higher one will be attempted.
  	 */
  	int refetch_glue;
- 
++
 +	/**
 +	 * ASN: This is a flag that, if true, means that this query is
 +	 * for fetching A records to populate cache and determine if we must
 +	 * return AAAA records or not.
 +	 */
 +	int fetch_a_for_aaaa;
-+
+ 
  	/** list of pending queries to authoritative servers. */
  	struct outbound_list outlist;
- 
 Index: trunk/pythonmod/interface.i
 ===================================================================
---- trunk/pythonmod/interface.i	(revision 3587)
+--- trunk/pythonmod/interface.i	(revision 4357)
 +++ trunk/pythonmod/interface.i	(working copy)
-@@ -632,6 +632,7 @@
+@@ -851,6 +851,7 @@
     int harden_dnssec_stripped;
     int harden_referral_path;
     int use_caps_bits_for_id;
@@ -340,9 +340,9 @@ Index: trunk/pythonmod/interface.i
     size_t unwanted_threshold;
 Index: trunk/util/config_file.c
 ===================================================================
---- trunk/util/config_file.c	(revision 3587)
+--- trunk/util/config_file.c	(revision 4357)
 +++ trunk/util/config_file.c	(working copy)
-@@ -176,6 +176,7 @@
+@@ -195,6 +195,7 @@
  	cfg->harden_referral_path = 0;
  	cfg->harden_algo_downgrade = 0;
  	cfg->use_caps_bits_for_id = 0;
@@ -352,9 +352,9 @@ Index: trunk/util/config_file.c
  	cfg->private_domain = NULL;
 Index: trunk/util/config_file.h
 ===================================================================
---- trunk/util/config_file.h	(revision 3587)
+--- trunk/util/config_file.h	(revision 4357)
 +++ trunk/util/config_file.h	(working copy)
-@@ -179,6 +179,8 @@
+@@ -209,6 +209,8 @@
  	int harden_algo_downgrade;
  	/** use 0x20 bits in query as random ID bits */
  	int use_caps_bits_for_id;
@@ -365,9 +365,9 @@ Index: trunk/util/config_file.h
  	/** strip away these private addrs from answers, no DNS Rebinding */
 Index: trunk/util/configlexer.lex
 ===================================================================
---- trunk/util/configlexer.lex	(revision 3587)
+--- trunk/util/configlexer.lex	(revision 4357)
 +++ trunk/util/configlexer.lex	(working copy)
-@@ -267,6 +267,7 @@
+@@ -279,6 +279,7 @@
  use-caps-for-id{COLON}		{ YDVAR(1, VAR_USE_CAPS_FOR_ID) }
  caps-whitelist{COLON}		{ YDVAR(1, VAR_CAPS_WHITELIST) }
  unwanted-reply-threshold{COLON}	{ YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) }
@@ -377,9 +377,9 @@ Index: trunk/util/configlexer.lex
  prefetch-key{COLON}		{ YDVAR(1, VAR_PREFETCH_KEY) }
 Index: trunk/util/configparser.y
 ===================================================================
---- trunk/util/configparser.y	(revision 3587)
+--- trunk/util/configparser.y	(revision 4357)
 +++ trunk/util/configparser.y	(working copy)
-@@ -92,6 +92,7 @@
+@@ -95,6 +95,7 @@
  %token VAR_STATISTICS_CUMULATIVE VAR_OUTGOING_PORT_PERMIT 
  %token VAR_OUTGOING_PORT_AVOID VAR_DLV_ANCHOR_FILE VAR_DLV_ANCHOR
  %token VAR_NEG_CACHE_SIZE VAR_HARDEN_REFERRAL_PATH VAR_PRIVATE_ADDRESS
@@ -387,7 +387,7 @@ Index: trunk/util/configparser.y
  %token VAR_PRIVATE_DOMAIN VAR_REMOTE_CONTROL VAR_CONTROL_ENABLE
  %token VAR_CONTROL_INTERFACE VAR_CONTROL_PORT VAR_SERVER_KEY_FILE
  %token VAR_SERVER_CERT_FILE VAR_CONTROL_KEY_FILE VAR_CONTROL_CERT_FILE
-@@ -169,6 +170,7 @@
+@@ -203,6 +204,7 @@
  	server_dlv_anchor_file | server_dlv_anchor | server_neg_cache_size |
  	server_harden_referral_path | server_private_address |
  	server_private_domain | server_extended_statistics | 
@@ -395,10 +395,12 @@ Index: trunk/util/configparser.y
  	server_local_data_ptr | server_jostle_timeout | 
  	server_unwanted_reply_threshold | server_log_time_ascii | 
  	server_domain_insecure | server_val_sig_skew_min | 
-@@ -893,6 +895,15 @@
+@@ -1183,6 +1185,15 @@
+ 		OUTYY(("P(server_caps_whitelist:%s)\n", $2));
+ 		if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, $2))
  			yyerror("out of memory");
- 	}
- 	;
++	}
++	;
 +server_aaaa_filter: VAR_AAAA_FILTER STRING_ARG
 +	{
 +		OUTYY(("P(server_aaaa_filter:%s)\n", $2));
@@ -406,8 +408,6 @@ Index: trunk/util/configparser.y
 +			yyerror("expected yes or no.");
 +		else cfg_parser->cfg->aaaa_filter = (strcmp($2, "yes")==0);
 +		free($2);
-+	}
-+	;
+ 	}
+ 	;
  server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG
- 	{
- 		OUTYY(("P(server_private_address:%s)\n", $2));

Modified: vendor/unbound/dist/contrib/parseunbound.pl
==============================================================================
--- vendor/unbound/dist/contrib/parseunbound.pl	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/contrib/parseunbound.pl	Sat May 12 11:55:57 2018	(r333543)
@@ -91,7 +91,7 @@ while ( scalar keys %startstats < $numthreads || scala
             $allstats{$inthread}->{outstandingexc} = $4;
         }
         elsif ( $line =~ m/info: average recursion processing time ([0-9\.]+) sec/ ) {
-            $allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to milisec.
+            $allstats{$inthread}->{recursionavg} = int($1 * 1000); # change sec to millisec.
         }
         elsif ( $line =~ m/info: histogram of recursion processing times/ ) {
             next;
@@ -103,7 +103,7 @@ while ( scalar keys %startstats < $numthreads || scala
         }
         elsif ( $line =~ m/info: lower\(secs\) upper\(secs\) recursions/ ) {
             # since after this line we're unsure if we get these numbers
-            # at all, we sould consider this marker as the end of the
+            # at all, we should consider this marker as the end of the
             # block. Chances that we're parsing a file halfway written
             # at this stage are small. Bold statement.
             $donestats{$inthread} = 1;

Modified: vendor/unbound/dist/daemon/remote.c
==============================================================================
--- vendor/unbound/dist/daemon/remote.c	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/daemon/remote.c	Sat May 12 11:55:57 2018	(r333543)
@@ -827,6 +827,7 @@ print_mem(SSL* ssl, struct worker* worker, struct daem
 #endif /* USE_IPSECMOD */
 #ifdef USE_DNSCRYPT
 	size_t dnscrypt_shared_secret = 0;
+	size_t dnscrypt_nonce = 0;
 #endif /* USE_DNSCRYPT */
 	msg = slabhash_get_mem(daemon->env->msg_cache);
 	rrset = slabhash_get_mem(&daemon->env->rrset_cache->table);
@@ -843,6 +844,7 @@ print_mem(SSL* ssl, struct worker* worker, struct daem
 	if(daemon->dnscenv) {
 		dnscrypt_shared_secret = slabhash_get_mem(
 			daemon->dnscenv->shared_secrets_cache);
+		dnscrypt_nonce = slabhash_get_mem(daemon->dnscenv->nonces_cache);
 	}
 #endif /* USE_DNSCRYPT */
 
@@ -868,6 +870,9 @@ print_mem(SSL* ssl, struct worker* worker, struct daem
 	if(!print_longnum(ssl, "mem.cache.dnscrypt_shared_secret"SQ,
 			dnscrypt_shared_secret))
 		return 0;
+	if(!print_longnum(ssl, "mem.cache.dnscrypt_nonce"SQ,
+			dnscrypt_nonce))
+		return 0;
 #endif /* USE_DNSCRYPT */
 	return 1;
 }
@@ -1058,8 +1063,12 @@ print_ext(SSL* ssl, struct ub_stats_info* s)
 #ifdef USE_DNSCRYPT
 	if(!ssl_printf(ssl, "dnscrypt_shared_secret.cache.count"SQ"%u\n",
 		(unsigned)s->svr.shared_secret_cache_count)) return 0;
+	if(!ssl_printf(ssl, "dnscrypt_nonce.cache.count"SQ"%u\n",
+		(unsigned)s->svr.nonce_cache_count)) return 0;
 	if(!ssl_printf(ssl, "num.query.dnscrypt.shared_secret.cachemiss"SQ"%lu\n",
 		(unsigned long)s->svr.num_query_dnscrypt_secret_missed_cache)) return 0;
+	if(!ssl_printf(ssl, "num.query.dnscrypt.replay"SQ"%lu\n",
+		(unsigned long)s->svr.num_query_dnscrypt_replay)) return 0;
 #endif /* USE_DNSCRYPT */
 	return 1;
 }
@@ -1771,7 +1780,7 @@ negative_del_rrset(struct lruhash_entry* e, void* arg)
 	struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key;
 	struct packed_rrset_data* d = (struct packed_rrset_data*)e->data;
 	/* delete the parentside negative cache rrsets,
-	 * these are namerserver rrsets that failed lookup, rdata empty */
+	 * these are nameserver rrsets that failed lookup, rdata empty */
 	if((k->rk.flags & PACKED_RRSET_PARENT_SIDE) && d->count == 1 &&
 		d->rrsig_count == 0 && d->rr_len[0] == 0) {
 		d->ttl = inf->expired;

Modified: vendor/unbound/dist/daemon/stats.c
==============================================================================
--- vendor/unbound/dist/daemon/stats.c	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/daemon/stats.c	Sat May 12 11:55:57 2018	(r333543)
@@ -174,6 +174,21 @@ get_dnscrypt_cache_miss(struct worker* worker, int res
 	lock_basic_unlock(&de->shared_secrets_cache_lock);
 	return r;
 }
+
+/** get the number of replayed queries */
+static size_t
+get_dnscrypt_replay(struct worker* worker, int reset)
+{
+	size_t r;
+	struct dnsc_env* de = worker->daemon->dnscenv;
+
+	lock_basic_lock(&de->nonces_cache_lock);
+	r = de->num_query_dnscrypt_replay;
+	if(reset && !worker->env.cfg->stat_cumulative)
+		de->num_query_dnscrypt_replay = 0;
+	lock_basic_unlock(&de->nonces_cache_lock);
+	return r;
+}
 #endif /* USE_DNSCRYPT */
 
 void
@@ -225,13 +240,21 @@ server_stats_compile(struct worker* worker, struct ub_
 			(long long)get_dnscrypt_cache_miss(worker, reset);
 		s->svr.shared_secret_cache_count = (long long)count_slabhash_entries(
 			worker->daemon->dnscenv->shared_secrets_cache);
+		s->svr.nonce_cache_count = (long long)count_slabhash_entries(
+			worker->daemon->dnscenv->nonces_cache);
+		s->svr.num_query_dnscrypt_replay =
+			(long long)get_dnscrypt_replay(worker, reset);
 	} else {
 		s->svr.num_query_dnscrypt_secret_missed_cache = 0;
 		s->svr.shared_secret_cache_count = 0;
+		s->svr.nonce_cache_count = 0;
+		s->svr.num_query_dnscrypt_replay = 0;
 	}
 #else
 	s->svr.num_query_dnscrypt_secret_missed_cache = 0;
 	s->svr.shared_secret_cache_count = 0;
+	s->svr.nonce_cache_count = 0;
+	s->svr.num_query_dnscrypt_replay = 0;
 #endif /* USE_DNSCRYPT */
 
 	/* get tcp accept usage */

Modified: vendor/unbound/dist/daemon/unbound.c
==============================================================================
--- vendor/unbound/dist/daemon/unbound.c	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/daemon/unbound.c	Sat May 12 11:55:57 2018	(r333543)
@@ -400,7 +400,7 @@ detach(void)
 #endif /* HAVE_DAEMON */
 }
 
-/** daemonize, drop user priviliges and chroot if needed */
+/** daemonize, drop user privileges and chroot if needed */
 static void
 perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
 	const char** cfgfile, int need_pidfile)

Modified: vendor/unbound/dist/daemon/worker.c
==============================================================================
--- vendor/unbound/dist/daemon/worker.c	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/daemon/worker.c	Sat May 12 11:55:57 2018	(r333543)
@@ -1633,7 +1633,8 @@ worker_init(struct worker* worker, struct config_file 
 		cfg->use_caps_bits_for_id, worker->ports, worker->numports,
 		cfg->unwanted_threshold, cfg->outgoing_tcp_mss,
 		&worker_alloc_cleanup, worker,
-		cfg->do_udp, worker->daemon->connect_sslctx, cfg->delay_close,
+		cfg->do_udp || cfg->udp_upstream_without_downstream,
+		worker->daemon->connect_sslctx, cfg->delay_close,
 		dtenv);
 	if(!worker->back) {
 		log_err("could not create outgoing sockets");

Modified: vendor/unbound/dist/dns64/dns64.c
==============================================================================
--- vendor/unbound/dist/dns64/dns64.c	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/dns64/dns64.c	Sat May 12 11:55:57 2018	(r333543)
@@ -792,6 +792,10 @@ dns64_inform_super(struct module_qstate* qstate, int i
 					qstate->return_msg->rep))
 		return;
 
+	/* Use return code from A query in response to client. */
+	if (super->return_rcode != LDNS_RCODE_NOERROR)
+		super->return_rcode = qstate->return_rcode;
+
 	/* Generate a response suitable for the original query. */
 	if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) {
 		dns64_adjust_a(id, super, qstate);

Modified: vendor/unbound/dist/dnscrypt/dnscrypt.c
==============================================================================
--- vendor/unbound/dist/dnscrypt/dnscrypt.c	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/dnscrypt/dnscrypt.c	Sat May 12 11:55:57 2018	(r333543)
@@ -60,6 +60,17 @@ struct shared_secret_cache_key {
 };
 
 
+struct nonce_cache_key {
+    /** the nonce used by the client */
+    uint8_t nonce[crypto_box_HALF_NONCEBYTES];
+    /** the client_magic used by the client, this is associated to 1 cert only */
+    uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN];
+    /** the client public key */
+    uint8_t client_publickey[crypto_box_PUBLICKEYBYTES];
+    /** the hash table entry, data is uint8_t */
+    struct lruhash_entry entry;
+};
+
 /**
  * Generate a key suitable to find shared secret in slabhash.
  * \param[in] key: a uint8_t pointer of size DNSCRYPT_SHARED_SECRET_KEY_LENGTH
@@ -136,6 +147,87 @@ dnsc_shared_secrets_lookup(struct slabhash* cache,
 }
 
 /**
+ * Generate a key hash suitable to find a nonce in slabhash.
+ * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
+ * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
+ * \param[in] pk: The public key of the client. uint8_t pointer of size
+ * crypto_box_PUBLICKEYBYTES.
+ * \return the hash of the key.
+ */
+static uint32_t
+dnsc_nonce_cache_key_hash(const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
+                          const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
+                          const uint8_t pk[crypto_box_PUBLICKEYBYTES])
+{
+    uint32_t h = 0;
+    h = hashlittle(nonce, crypto_box_HALF_NONCEBYTES, h);
+    h = hashlittle(magic_query, DNSCRYPT_MAGIC_HEADER_LEN, h);
+    return hashlittle(pk, crypto_box_PUBLICKEYBYTES, h);
+}
+
+/**
+ * Inserts a nonce, magic_query, pk tuple into the nonces_cache slabhash.
+ * \param[in] cache: the slabhash in which to look for the key.
+ * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
+ * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
+ * \param[in] pk: The public key of the client. uint8_t pointer of size
+ * crypto_box_PUBLICKEYBYTES.
+ * \param[in] hash: the hash of the key.
+ */
+static void
+dnsc_nonce_cache_insert(struct slabhash *cache,
+                        const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
+                        const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
+                        const uint8_t pk[crypto_box_PUBLICKEYBYTES],
+                        uint32_t hash)
+{
+    struct nonce_cache_key* k =
+        (struct nonce_cache_key*)calloc(1, sizeof(*k));
+    if(!k) {
+        free(k);
+        return;
+    }
+    lock_rw_init(&k->entry.lock);
+    memcpy(k->nonce, nonce, crypto_box_HALF_NONCEBYTES);
+    memcpy(k->magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
+    memcpy(k->client_publickey, pk, crypto_box_PUBLICKEYBYTES);
+    k->entry.hash = hash;
+    k->entry.key = k;
+    k->entry.data = NULL;
+    slabhash_insert(cache,
+                    hash, &k->entry,
+                    NULL,
+                    NULL);
+}
+
+/**
+ * Lookup a record in nonces_cache.
+ * \param[in] cache: the slabhash in which to look for the key.
+ * \param[in] nonce: a uint8_t pointer of size crypto_box_HALF_NONCEBYTES
+ * \param[in] magic_query: a uint8_t pointer of size DNSCRYPT_MAGIC_HEADER_LEN
+ * \param[in] pk: The public key of the client. uint8_t pointer of size
+ * crypto_box_PUBLICKEYBYTES.
+ * \param[in] hash: the hash of the key.
+ * \return a pointer to the locked cache entry or NULL on failure.
+ */
+static struct lruhash_entry*
+dnsc_nonces_lookup(struct slabhash* cache,
+                   const uint8_t nonce[crypto_box_HALF_NONCEBYTES],
+                   const uint8_t magic_query[DNSCRYPT_MAGIC_HEADER_LEN],
+                   const uint8_t pk[crypto_box_PUBLICKEYBYTES],
+                   uint32_t hash)
+{
+    struct nonce_cache_key k;
+    memset(&k, 0, sizeof(k));
+    k.entry.hash = hash;
+    memcpy(k.nonce, nonce, crypto_box_HALF_NONCEBYTES);
+    memcpy(k.magic_query, magic_query, DNSCRYPT_MAGIC_HEADER_LEN);
+    memcpy(k.client_publickey, pk, crypto_box_PUBLICKEYBYTES);
+
+    return slabhash_lookup(cache, hash, &k, 0);
+}
+
+/**
  * Decrypt a query using the dnsccert that was found using dnsc_find_cert.
  * The client nonce will be extracted from the encrypted query and stored in
  * client_nonce, a shared secret will be computed and stored in nmkey and the
@@ -163,11 +255,44 @@ dnscrypt_server_uncurve(struct dnsc_env* env,
     struct lruhash_entry* entry;
     uint32_t hash;
 
+    uint32_t nonce_hash;
+
     if (len <= DNSCRYPT_QUERY_HEADER_SIZE) {
         return -1;
     }
 
     query_header = (struct dnscrypt_query_header *)buf;
+
+    /* Detect replay attacks */
+    nonce_hash = dnsc_nonce_cache_key_hash(
+        query_header->nonce,
+        cert->magic_query,
+        query_header->publickey);
+
+    lock_basic_lock(&env->nonces_cache_lock);
+    entry = dnsc_nonces_lookup(
+        env->nonces_cache,
+        query_header->nonce,
+        cert->magic_query,
+        query_header->publickey,
+        nonce_hash);
+
+    if(entry) {
+        lock_rw_unlock(&entry->lock);
+        env->num_query_dnscrypt_replay++;
+        lock_basic_unlock(&env->nonces_cache_lock);
+        return -1;
+    }
+
+    dnsc_nonce_cache_insert(
+        env->nonces_cache,
+        query_header->nonce,
+        cert->magic_query,
+        query_header->publickey,
+        nonce_hash);
+    lock_basic_unlock(&env->nonces_cache_lock);
+
+    /* Find existing shared secret */
     hash = dnsc_shared_secrets_cache_key(key,
                                          cert->es_version[1],
                                          query_header->publickey,
@@ -547,7 +672,7 @@ dnsc_find_cert(struct dnsc_env* dnscenv, struct sldns_
  * In order to be able to serve certs over TXT, we can reuse the local-zone and
  * local-data config option. The zone and qname are infered from the
  * provider_name and the content of the TXT record from the certificate content.
- * returns the number of certtificate TXT record that were loaded.
+ * returns the number of certificate TXT record that were loaded.
  * < 0 in case of error.
  */
 static int
@@ -770,8 +895,16 @@ dnsc_create(void)
 	env = (struct dnsc_env *) calloc(1, sizeof(struct dnsc_env));
 	lock_basic_init(&env->shared_secrets_cache_lock);
 	lock_protect(&env->shared_secrets_cache_lock,
-				 &env->num_query_dnscrypt_secret_missed_cache,
-				 sizeof(env->num_query_dnscrypt_secret_missed_cache));
+                 &env->num_query_dnscrypt_secret_missed_cache,
+                 sizeof(env->num_query_dnscrypt_secret_missed_cache));
+	lock_basic_init(&env->nonces_cache_lock);
+	lock_protect(&env->nonces_cache_lock,
+                 &env->nonces_cache,
+                 sizeof(env->nonces_cache));
+	lock_protect(&env->nonces_cache_lock,
+                 &env->num_query_dnscrypt_replay,
+                 sizeof(env->num_query_dnscrypt_replay));
+
 	return env;
 }
 
@@ -803,6 +936,16 @@ dnsc_apply_cfg(struct dnsc_env *env, struct config_fil
     if(!env->shared_secrets_cache){
         fatal_exit("dnsc_apply_cfg: could not create shared secrets cache.");
     }
+    env->nonces_cache = slabhash_create(
+        cfg->dnscrypt_nonce_cache_slabs,
+        HASH_DEFAULT_STARTARRAY,
+        cfg->dnscrypt_nonce_cache_size,
+        dnsc_nonces_sizefunc,
+        dnsc_nonces_compfunc,
+        dnsc_nonces_delkeyfunc,
+        dnsc_nonces_deldatafunc,
+        NULL
+    );
     return 0;
 }
 
@@ -817,7 +960,9 @@ dnsc_delete(struct dnsc_env *env)
 	sodium_free(env->certs);
 	sodium_free(env->keypairs);
 	slabhash_delete(env->shared_secrets_cache);
+	slabhash_delete(env->nonces_cache);
 	lock_basic_destroy(&env->shared_secrets_cache_lock);
+	lock_basic_destroy(&env->nonces_cache_lock);
 	free(env);
 }
 
@@ -857,4 +1002,52 @@ dnsc_shared_secrets_deldatafunc(void* d, void* ATTR_UN
 {
     uint8_t* data = (uint8_t*)d;
     free(data);
+}
+
+/**
+ * #########################################################
+ * ############### Nonces cache functions ##################
+ * #########################################################
+ */
+
+size_t
+dnsc_nonces_sizefunc(void *k, void* ATTR_UNUSED(d))
+{
+    struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
+    size_t key_size = sizeof(struct nonce_cache_key)
+        + lock_get_mem(&nk->entry.lock);
+    (void)nk; /* otherwise ssk is unused if no threading, or fixed locksize */
+    return key_size;
+}
+
+int
+dnsc_nonces_compfunc(void *m1, void *m2)
+{
+    struct nonce_cache_key *k1 = m1, *k2 = m2;
+    return
+        sodium_memcmp(
+            k1->nonce,
+            k2->nonce,
+            crypto_box_HALF_NONCEBYTES) != 0 ||
+        sodium_memcmp(
+            k1->magic_query,
+            k2->magic_query,
+            DNSCRYPT_MAGIC_HEADER_LEN) != 0 ||
+        sodium_memcmp(
+            k1->client_publickey, k2->client_publickey,
+            crypto_box_PUBLICKEYBYTES) != 0;
+}
+
+void
+dnsc_nonces_delkeyfunc(void *k, void* ATTR_UNUSED(arg))
+{
+    struct nonce_cache_key* nk = (struct nonce_cache_key*)k;
+    lock_rw_destroy(&nk->entry.lock);
+    free(nk);
+}
+
+void
+dnsc_nonces_deldatafunc(void* ATTR_UNUSED(d), void* ATTR_UNUSED(arg))
+{
+    return;
 }

Modified: vendor/unbound/dist/dnscrypt/dnscrypt.h
==============================================================================
--- vendor/unbound/dist/dnscrypt/dnscrypt.h	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/dnscrypt/dnscrypt.h	Sat May 12 11:55:57 2018	(r333543)
@@ -63,11 +63,20 @@ struct dnsc_env {
 	uint64_t nonce_ts_last;
 	unsigned char hash_key[crypto_shorthash_KEYBYTES];
 	char * provider_name;
+
+    /** Caches */
 	struct slabhash *shared_secrets_cache;
 	/** lock on shared secret cache counters */
 	lock_basic_type shared_secrets_cache_lock;
 	/** number of misses from shared_secrets_cache */
 	size_t num_query_dnscrypt_secret_missed_cache;
+
+	/** slabhash keeping track of nonce/cient pk/server sk pairs. */
+	struct slabhash *nonces_cache;
+	/** lock on nonces_cache, used to avoid race condition in updating the hash */
+	lock_basic_type nonces_cache_lock;
+	/** number of replayed queries */
+	size_t num_query_dnscrypt_replay;
 };
 
 struct dnscrypt_query_header {
@@ -138,6 +147,27 @@ void dnsc_shared_secrets_delkeyfunc(void *k, void* arg
  * Function to delete a share secret cache value.
  */
 void dnsc_shared_secrets_deldatafunc(void* d, void* arg);
+
+/**
+ * Computes the size of the nonce cache entry.
+ */
+size_t dnsc_nonces_sizefunc(void *k, void *d);
+
+/**
+ * Compares two nonce cache keys.
+ */
+int dnsc_nonces_compfunc(void *m1, void *m2);
+
+/**
+ * Function to delete a nonce cache key.
+ */
+void dnsc_nonces_delkeyfunc(void *k, void* arg);
+
+/**
+ * Function to delete a nonce cache value.
+ */
+void dnsc_nonces_deldatafunc(void* d, void* arg);
+
 
 #endif /* USE_DNSCRYPT */
 #endif

Modified: vendor/unbound/dist/doc/Changelog
==============================================================================
--- vendor/unbound/dist/doc/Changelog	Sat May 12 11:55:25 2018	(r333542)
+++ vendor/unbound/dist/doc/Changelog	Sat May 12 11:55:57 2018	(r333543)
@@ -1,5 +1,55 @@
+10 October 2017: Wouter 
+	- tag 1.6.7
+
+6 October 2017: Wouter 
+	- Fix spelling in unbound-control man page.
+
+5 October 2017: Wouter 
+	- Fix trust-anchor-signaling works in libunbound.
+	- Fix some more crpls in testdata for different signaling default.
+	- tag 1.6.7rc1

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805121155.w4CBtw7H019898>