[wouter@nlnetlabs.nl: [NLnet Labs Maintainers] Unbound 1.9.0rc1 pre-release]

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

[wouter@nlnetlabs.nl: [NLnet Labs Maintainers] Unbound 1.9.0rc1 pre-release]

Stuart Henderson
Diff against /usr/src/usr.sbin/unbound if anyone is interested in testing
the release candidate (there have been a couple of small fixes since).
Release due approximately Friday.

----- Forwarded message from Wouter Wijngaards <[hidden email]> -----

From: Wouter Wijngaards <[hidden email]>
Date: Tue, 29 Jan 2019 10:22:46 +0100
To: [hidden email], [hidden email]
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0
Subject: [NLnet Labs Maintainers] Unbound 1.9.0rc1 pre-release

Hi,

Unbound 1.9.0rc1 pre-release is available:
https://www.nlnetlabs.nl/downloads/unbound/unbound-1.9.0rc1.tar.gz
sha256 f3536f75b30a3bfdc434bc9489415b52c5a86652412de8cacde5a25913984c30
pgp https://www.nlnetlabs.nl/downloads/unbound/unbound-1.9.0rc1.tar.gz.asc

This is the maintainers pre-release, the actual release follows later.

This release contains the DNS Flag Day changes for Unbound.  See the
reference here, https://dnsflagday.net/ .   Or this presentation:
https://indico.dns-oarc.net/event/29/contributions/662/attachments/634/1063/EDNS_Flag_Day_-_OARC29.pdf
.   The EDNS timeouts are not used to fallback to nonEDNS queries.

Out of order processing is implemented, for TCP and TLS.  It can be
configured with a maximum amount of memory to use to store pending
answers, and the current memory usage is in the statistics output.  This
is with stream-wait-size in unbound.conf and mem.streamwait in
unbound-control stats output.  Streams that cause the total memory
counted to exceed the maximum are dropped, but it is possible to get a
number of responses with little memory used.

There is also TLS session resumption support, that can be enabled with
the tls-session-ticket-keys option.  Together with the already existing
TCP fast open, enabled with --enable-tfo-server --enable-tfo-client,
that enables zero RTT stream reconnections to the server.  Make sure to
also increase incoming-num-tcp if you expect a lot of TCP and TLS users.

Options are added to set the TLS ciphers and TLS ciphersuites from
unbound.conf.  This can be done with the tls-chiphers and
tls-ciphersuites options.

TLS can be used from libunbound, with the ub_ctx_set_tls config call,
use that together with ub_ctx_set_fwd to select DNS over TLS transport.


Features
- log-tag-queryreply: yes in unbound.conf tags the log-queries and
  log-replies in the log file for easier log filter maintenance.
- ip-ratelimit-factor of 1 allows all traffic through, instead of the
  previous blocking everything.
- Fix #4206: support openssl 1.0.2 for TLS hostname verification,
  alongside the 1.1.0 and later support that is already there.
- Add contrib/unbound-fuzzme.patch from Jacob Hoffman-Andrews,
  the patch adds a program used for fuzzing.
- streamtcp option -a send queries consecutively and prints answers
  as they arrive.
- out-of-order processing for TCP and TLS.
- Add stream-wait-size: 4m config option to limit the maximum
  memory used by waiting tcp and tls stream replies.  This avoids
  a denial of service where these replies use up all of the memory.
- unbound-control stats has mem.streamwait that counts TCP and TLS
  waiting result buffers.
- Patch from Manabu Sonoda with tls-ciphers and tls-ciphersuites
  options for unbound.conf.
- Patch for TLS session resumption from Manabu Sonoda,
  enable with tls-session-ticket-keys in unbound.conf.
- ub_ctx_set_tls call for libunbound that enables DoT for the machines
  set with ub_ctx_set_fwd.  Patch from Florian Obser.

Bug Fixes
- Fix that unbound-checkconf does not complains if the config file
  is not placed inside the chroot.
- Refuse to start with no ports.
- Remove clang analysis warnings.
- Patch for typo in unbound.conf man page.
- Fix icon, no ragged edges and nicer resolutions available, for eg.
  Win 7 and Windows 10 display.
- cache-max-ttl also defines upperbound of initial TTL in response.
- Fix config parser memory leaks.
- Fix for FreeBSD port make with dnscrypt and dnstap enabled.
- Fixup openssl 1.0.2 compile
- Fix for crash in dns64 module if response is null.
- On FreeBSD warn if systcl settings do not allow server TCP FASTOPEN,
  and server tcp fastopen is enabled at compile time.
- Document interaction between the tls-upstream option in the server
  section and forward-tls-upstream option in the forward-zone sections.
- Fix syntax in comment of local alias processing.
- Fix NSEC3 record that is returned in wildcard replies from
  auth-zone zones with NSEC3 and wildcards.
- Log query name for looping module errors.
- For caps-for-id fallback, use the whitelist to avoid timeout
  starting a fallback sequence for it.
- increase mesh max activation count for capsforid long fetches.
- Fix for #4219: secondaries not updated after serial change, unbound
  falls back to AXFR after IXFR gives several timeout failures.
- Fix that auth zone after IXFR fallback tries the same master.
- Fix for IXFR fallback to reset counter when IXFR does not timeout.
- Newer aclocal and libtoolize used for generating configure scripts,
  aclocal 1.16.1 and libtoolize 2.4.6.
- Fix unit test for python 3.7 new keyword 'async'.
- clang analysis fixes, assert arc4random buffer in init,
  no check for already checked delegation pointer in iterator,
  in testcode check for NULL packet matches, in perf do not copy
  from NULL start list when growing capacity.  Adjust host and file
  only when present in test header read to please checker.  In
  testcode for unknown macro operand give zero result. Initialise the
  passed argv array in test code.  In test code add EDNS data
  segment copy only when nonempty.
- Patch from Florian Obser fixes some compiler warnings:
  include mini_event.h to have a prototype for mini_ev_cmp
  include edns.h to have a prototype for apply_edns_options
  sldns_wire2str_edns_keepalive_print is only called in the wire2str,
  module declare it static to get rid of compiler warning:
  no previous prototype for function
  infra_find_ip_ratedata() is only called in the infra module,
  declare it static to get rid of compiler warning:
  no previous prototype for function
  do not shadow local variable buf in authzone
  auth_chunks_delete and az_nsec3_findnode are only called in the
  authzone module, declare them static to get rid of compiler warning:
  no previous prototype for function...
  copy_rrset() is only called in the respip module, declare it
  static to get rid of compiler warning:
  no previous prototype for function 'copy_rrset'
  no need for another variable "r"; gets rid of compiler warning:
  declaration shadows a local variable in libunbound.c
  no need for another variable "ns"; gets rid of compiler warning:
  declaration shadows a local variable in iterator.c
- Moved includes and make depend.
- updated contrib/fastrpz.patch to cleanly diff.
- remove compile warnings from libnettle compile.
- output of newer lex 2.6.1 and bison 3.0.5.
- Set build system for added call in the libunbound API.
- List example config for root zone copy locally hosted with auth-zone
  as suggested from draft-ietf-dnsop-7706-bis-02.  But with updated
  B root address.


Best regards, Wouter





_______________________________________________
maintainers mailing list
[hidden email]
https://nlnetlabs.nl/mailman/listinfo/maintainers


----- End forwarded message -----

Index: configure.ac
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/configure.ac,v
retrieving revision 1.30
diff -u -p -r1.30 configure.ac
--- configure.ac 11 Dec 2018 13:49:01 -0000 1.30
+++ configure.ac 29 Jan 2019 12:04:15 -0000
@@ -10,16 +10,16 @@ sinclude(dnscrypt/dnscrypt.m4)
 
 # must be numbers. ac_defun because of later processing
 m4_define([VERSION_MAJOR],[1])
-m4_define([VERSION_MINOR],[8])
-m4_define([VERSION_MICRO],[3])
+m4_define([VERSION_MINOR],[9])
+m4_define([VERSION_MICRO],[0rc1])
 AC_INIT(unbound, m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), [hidden email], unbound)
 AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
 AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
 AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
 
-LIBUNBOUND_CURRENT=8
-LIBUNBOUND_REVISION=3
-LIBUNBOUND_AGE=0
+LIBUNBOUND_CURRENT=9
+LIBUNBOUND_REVISION=0
+LIBUNBOUND_AGE=1
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
 # 1.0.2 had 0:14:0
@@ -85,6 +85,7 @@ LIBUNBOUND_AGE=0
 # 1.8.1 had 8:1:0
 # 1.8.2 had 8:2:0
 # 1.8.3 had 8:3:0
+# 1.8.4 had 9:0:1 # add ub_ctx_set_tls
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -780,12 +781,12 @@ else
  AC_MSG_RESULT([no])
 fi
 AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h],,, [AC_INCLUDES_DEFAULT])
-AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify])
+AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex])
 
 # these check_funcs need -lssl
 BAKLIBS="$LIBS"
 LIBS="-lssl $LIBS"
-AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername])
+AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites])
 LIBS="$BAKLIBS"
 
 AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto], [], [], [
Index: daemon/daemon.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/daemon.c,v
retrieving revision 1.10
diff -u -p -r1.10 daemon.c
--- daemon/daemon.c 8 Oct 2018 16:03:53 -0000 1.10
+++ daemon/daemon.c 29 Jan 2019 12:04:15 -0000
@@ -749,6 +749,7 @@ daemon_delete(struct daemon* daemon)
  free(daemon->pidfile);
  free(daemon->env);
 #ifdef HAVE_SSL
+ listen_sslctx_delete_ticket_keys();
  SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx);
  SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx);
 #endif
Index: daemon/remote.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/remote.c,v
retrieving revision 1.24
diff -u -p -r1.24 remote.c
--- daemon/remote.c 4 Dec 2018 12:05:07 -0000 1.24
+++ daemon/remote.c 29 Jan 2019 12:04:15 -0000
@@ -789,7 +789,8 @@ print_longnum(RES* ssl, const char* desc
 
 /** print mem stats */
 static int
-print_mem(RES* ssl, struct worker* worker, struct daemon* daemon)
+print_mem(RES* ssl, struct worker* worker, struct daemon* daemon,
+ struct ub_stats_info* s)
 {
  size_t msg, rrset, val, iter, respip;
 #ifdef CLIENT_SUBNET
@@ -847,6 +848,9 @@ print_mem(RES* ssl, struct worker* worke
  dnscrypt_nonce))
  return 0;
 #endif /* USE_DNSCRYPT */
+ if(!print_longnum(ssl, "mem.streamwait"SQ,
+ (size_t)s->svr.mem_stream_wait))
+ return 0;
  return 1;
 }
 
@@ -969,6 +973,8 @@ print_ext(RES* ssl, struct ub_stats_info
  (unsigned long)s->svr.qtcp_outgoing)) return 0;
  if(!ssl_printf(ssl, "num.query.tls"SQ"%lu\n",
  (unsigned long)s->svr.qtls)) return 0;
+ if(!ssl_printf(ssl, "num.query.tls.resume"SQ"%lu\n",
+ (unsigned long)s->svr.qtls_resume)) return 0;
  if(!ssl_printf(ssl, "num.query.ipv6"SQ"%lu\n",
  (unsigned long)s->svr.qipv6)) return 0;
  /* flags */
@@ -1088,7 +1094,7 @@ do_stats(RES* ssl, struct daemon_remote*
  if(!print_uptime(ssl, rc->worker, reset))
  return;
  if(daemon->cfg->stat_extended) {
- if(!print_mem(ssl, rc->worker, daemon))
+ if(!print_mem(ssl, rc->worker, daemon, &total))
  return;
  if(!print_hist(ssl, &total))
  return;
Index: daemon/stats.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/stats.c,v
retrieving revision 1.7
diff -u -p -r1.7 stats.c
--- daemon/stats.c 20 Sep 2018 23:15:39 -0000 1.7
+++ daemon/stats.c 29 Jan 2019 12:04:15 -0000
@@ -66,6 +66,9 @@
 #ifdef CLIENT_SUBNET
 #include "edns-subnet/subnetmod.h"
 #endif
+#ifdef HAVE_SSL
+#include <openssl/ssl.h>
+#endif
 
 /** add timers and the values do not overflow or become negative */
 static void
@@ -328,6 +331,8 @@ server_stats_compile(struct worker* work
  }
  lock_rw_unlock(&worker->env.auth_zones->lock);
  }
+ s->svr.mem_stream_wait =
+ (long long)tcp_req_info_get_stream_buffer_size();
 
  /* Set neg cache usage numbers */
  set_neg_cache_stats(worker, &s->svr, reset);
@@ -412,6 +417,7 @@ void server_stats_add(struct ub_stats_in
  total->svr.qtcp += a->svr.qtcp;
  total->svr.qtcp_outgoing += a->svr.qtcp_outgoing;
  total->svr.qtls += a->svr.qtls;
+ total->svr.qtls_resume += a->svr.qtls_resume;
  total->svr.qipv6 += a->svr.qipv6;
  total->svr.qbit_QR += a->svr.qbit_QR;
  total->svr.qbit_AA += a->svr.qbit_AA;
@@ -468,8 +474,13 @@ void server_stats_insquery(struct ub_ser
  stats->qopcode[ LDNS_OPCODE_WIRE(sldns_buffer_begin(c->buffer)) ]++;
  if(c->type != comm_udp) {
  stats->qtcp++;
- if(c->ssl != NULL)
+ if(c->ssl != NULL) {
  stats->qtls++;
+#ifdef HAVE_SSL
+ if(SSL_session_reused(c->ssl))
+ stats->qtls_resume++;
+#endif
+ }
  }
  if(repinfo && addr_is_ip6(&repinfo->addr, repinfo->addrlen))
  stats->qipv6++;
Index: daemon/unbound.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/unbound.c,v
retrieving revision 1.21
diff -u -p -r1.21 unbound.c
--- daemon/unbound.c 8 Oct 2018 16:03:53 -0000 1.21
+++ daemon/unbound.c 29 Jan 2019 12:04:15 -0000
@@ -67,6 +67,7 @@
 #ifdef HAVE_GRP_H
 #include <grp.h>
 #endif
+#include <openssl/ssl.h>
 
 #ifndef S_SPLINT_S
 /* splint chokes on this system header file */
@@ -430,6 +431,23 @@ perform_setup(struct daemon* daemon, str
  if(!(daemon->listen_sslctx = listen_sslctx_create(
  cfg->ssl_service_key, cfg->ssl_service_pem, NULL)))
  fatal_exit("could not set up listen SSL_CTX");
+ if(cfg->tls_ciphers && cfg->tls_ciphers[0]) {
+ if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) {
+ fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers);
+ }
+ }
+#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES
+ if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) {
+ if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) {
+ fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites);
+ }
+ }
+#endif
+ if(cfg->tls_session_ticket_keys.first) {
+ if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) {
+ fatal_exit("could not set session ticket SSL_CTX");
+ }
+ }
  }
  if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL,
  cfg->tls_cert_bundle, cfg->tls_win_cert)))
Index: daemon/worker.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/worker.c,v
retrieving revision 1.21
diff -u -p -r1.21 worker.c
--- daemon/worker.c 4 Dec 2018 12:05:07 -0000 1.21
+++ daemon/worker.c 29 Jan 2019 12:04:15 -0000
@@ -1088,7 +1088,7 @@ worker_handle_request(struct comm_point*
  struct ub_packed_rrset_key* alias_rrset = NULL;
  struct reply_info* partial_rep = NULL;
  struct query_info* lookup_qinfo = &qinfo;
- struct query_info qinfo_tmp; /* placeholdoer for lookup_qinfo */
+ struct query_info qinfo_tmp; /* placeholder for lookup_qinfo */
  struct respip_client_info* cinfo = NULL, cinfo_tmp;
  memset(&qinfo, 0, sizeof(qinfo));
 
@@ -1175,7 +1175,7 @@ worker_handle_request(struct comm_point*
  /* See if we are passed through with slip factor */
  if(worker->env.cfg->ip_ratelimit_factor != 0 &&
  ub_random_max(worker->env.rnd,
-  worker->env.cfg->ip_ratelimit_factor) == 1) {
+  worker->env.cfg->ip_ratelimit_factor) == 0) {
 
  char addrbuf[128];
  addr_to_str(&repinfo->addr, repinfo->addrlen,
@@ -1208,7 +1208,7 @@ worker_handle_request(struct comm_point*
  if(worker->env.cfg->log_queries) {
  char ip[128];
  addr_to_str(&repinfo->addr, repinfo->addrlen, ip, sizeof(ip));
- log_nametypeclass(0, ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
+ log_query_in(ip, qinfo.qname, qinfo.qtype, qinfo.qclass);
  }
  if(qinfo.qtype == LDNS_RR_TYPE_AXFR ||
  qinfo.qtype == LDNS_RR_TYPE_IXFR) {
Index: dns64/dns64.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/dns64/dns64.c,v
retrieving revision 1.12
diff -u -p -r1.12 dns64.c
--- dns64/dns64.c 11 Dec 2018 13:46:55 -0000 1.12
+++ dns64/dns64.c 29 Jan 2019 12:04:15 -0000
@@ -628,6 +628,7 @@ handle_event_moddone(struct module_qstat
 
  /* Store the response in cache. */
  if ( (!iq || !iq->started_no_cache_store) &&
+ qstate->return_msg && qstate->return_msg->rep &&
  !dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep,
  0, 0, 0, NULL, qstate->query_flags))
  log_err("out of memory");
Index: doc/Changelog
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/Changelog,v
retrieving revision 1.30
diff -u -p -r1.30 Changelog
--- doc/Changelog 11 Dec 2018 13:49:01 -0000 1.30
+++ doc/Changelog 29 Jan 2019 12:04:16 -0000
@@ -1,10 +1,160 @@
-11 December 2018: Wouter
+28 January 2019: Wouter
+ - ub_ctx_set_tls call for libunbound that enables DoT for the machines
+  set with ub_ctx_set_fwd.  Patch from Florian Obser.
+ - Set build system for added call in the libunbound API.
+ - List example config for root zone copy locally hosted with auth-zone
+  as suggested from draft-ietf-dnsop-7706-bis-02.  But with updated
+  B root address.
+ - set version to 1.9.0 for release.
+
+25 January 2019: Wouter
+ - Fix that tcp for auth zone and outgoing does not remove and
+  then gets the ssl read again applied to the deleted commpoint.
+ - updated contrib/fastrpz.patch to cleanly diff.
+ - no lock when threads disabled in tcp request buffer count.
+ - remove compile warnings from libnettle compile.
+ - output of newer lex 2.6.1 and bison 3.0.5.
+
+24 January 2019: Wouter
+ - Newer aclocal and libtoolize used for generating configure scripts,
+  aclocal 1.16.1 and libtoolize 2.4.6.
+ - Fix unit test for python 3.7 new keyword 'async'.
+ - clang analysis fixes, assert arc4random buffer in init,
+  no check for already checked delegation pointer in iterator,
+  in testcode check for NULL packet matches, in perf do not copy
+  from NULL start list when growing capacity.  Adjust host and file
+  only when present in test header read to please checker.  In
+  testcode for unknown macro operand give zero result. Initialise the
+  passed argv array in test code.  In test code add EDNS data
+  segment copy only when nonempty.
+ - Patch from Florian Obser fixes some compiler warnings:
+  include mini_event.h to have a prototype for mini_ev_cmp
+  include edns.h to have a prototype for apply_edns_options
+  sldns_wire2str_edns_keepalive_print is only called in the wire2str,
+  module declare it static to get rid of compiler warning:
+  no previous prototype for function
+  infra_find_ip_ratedata() is only called in the infra module,
+  declare it static to get rid of compiler warning:
+  no previous prototype for function
+  do not shadow local variable buf in authzone
+  auth_chunks_delete and az_nsec3_findnode are only called in the
+  authzone module, declare them static to get rid of compiler warning:
+  no previous prototype for function...
+  copy_rrset() is only called in the respip module, declare it
+  static to get rid of compiler warning:
+  no previous prototype for function 'copy_rrset'
+  no need for another variable "r"; gets rid of compiler warning:
+  declaration shadows a local variable in libunbound.c
+  no need for another variable "ns"; gets rid of compiler warning:
+  declaration shadows a local variable in iterator.c
+ - Moved includes and make depend.
+
+23 January 2019: Wouter
+ - Patch from Manabu Sonoda with tls-ciphers and tls-ciphersuites
+  options for unbound.conf.
+ - Fixes for the patch, and man page entry.
+ - Fix configure to detect SSL_CTX_set_ciphersuites, for better
+  library compatibility when compiling.
+ - Patch for TLS session resumption from Manabu Sonoda,
+  enable with tls-session-ticket-keys in unbound.conf.
+ - Fixes for patch (includes, declarations, warnings).  Free at end
+  and keep config options in order read from file to keep the first
+  one as the first one.
+ - Fix for IXFR fallback to reset counter when IXFR does not timeout.
+
+22 January 2019: Wouter
+ - Fix space calculation for tcp req buffer size.
+ - Doc for stream-wait-size and unit test.
+ - unbound-control stats has mem.streamwait that counts TCP and TLS
+  waiting result buffers.
+ - Fix for #4219: secondaries not updated after serial change, unbound
+  falls back to AXFR after IXFR gives several timeout failures.
+ - Fix that auth zone after IXFR fallback tries the same master.
+
+21 January 2019: Wouter
+ - Fix tcp idle timeout test, for difference in the tcp reply code.
+ - Unit test for tcp request reorder and timeouts.
+ - Unit tests for ssl out of order processing.
+ - Fix that multiple dns fragments can be carried in one TLS frame.
+ - Add stream-wait-size: 4m config option to limit the maximum
+  memory used by waiting tcp and tls stream replies.  This avoids
+  a denial of service where these replies use up all of the memory.
+
+17 January 2019: Wouter
+ - For caps-for-id fallback, use the whitelist to avoid timeout
+  starting a fallback sequence for it.
+ - increase mesh max activation count for capsforid long fetches.
+
+16 January 2019: Ralph
+ - Get ready for the DNS flag day: remove EDNS lame procedure, do not
+  re-query without EDNS after timeout.
+
+15 January 2019: Wouter
+ - In the out of order processing, reset byte count for (potential)
+  partial read.
+ - Review fixes in out of order processing.
+
+14 January 2019: Wouter
+ - streamtcp option -a send queries consecutively and prints answers
+  as they arrive.
+ - Fix for out of order processing administration quit cleanup.
+ - unit test for tcp out of order processing.
+
+11 January 2019: Wouter
+ - Initial commit for out-of-order processing for TCP and TLS.
+
+9 January 2019: Wouter
+ - Log query name for looping module errors.
+
+8 January 2019: Wouter
+ - Fix syntax in comment of local alias processing.
+ - Fix NSEC3 record that is returned in wildcard replies from
+  auth-zone zones with NSEC3 and wildcards.
+
+7 January 2019: Wouter
+ - On FreeBSD warn if systcl settings do not allow server TCP FASTOPEN,
+  and server tcp fastopen is enabled at compile time.
+ - Document interaction between the tls-upstream option in the server
+  section and forward-tls-upstream option in the forward-zone sections.
+ - Add contrib/unbound-fuzzme.patch from Jacob Hoffman-Andrews,
+  the patch adds a program used for fuzzing.
+
+12 December 2018: Wouter
+ - Fix for crash in dns64 module if response is null.
+
+10 December 2018: Wouter
+ - Fix config parser memory leaks.
+ - ip-ratelimit-factor of 1 allows all traffic through, instead of the
+  previous blocking everything.
+ - Fix for FreeBSD port make with dnscrypt and dnstap enabled.
+ - Fix #4206: support openssl 1.0.2 for TLS hostname verification,
+  alongside the 1.1.0 and later support that is already there.
+ - Fixup openssl 1.0.2 compile
+
+6 December 2018: Wouter
  - Fix dns64 allocation in wrong region for returned internal queries.
- - And 1.8.3 release with this dns64 crash fix included.
+
+3 December 2018: Wouter
+ - Fix icon, no ragged edges and nicer resolutions available, for eg.
+  Win 7 and Windows 10 display.
+ - cache-max-ttl also defines upperbound of initial TTL in response.
+
+30 November 2018: Wouter
+ - Patch for typo in unbound.conf man page.
+ - log-tag-queryreply: yes in unbound.conf tags the log-queries and
+  log-replies in the log file for easier log filter maintenance.
 
 29 November 2018: Wouter
  - iana portlist updated.
  - Fix chroot auth-zone fix to remove chroot prefix.
+ - tag for 1.8.2rc1, which became 1.8.2 on 4 dec 2018, with icon
+  updated.  Trunk contains 1.8.3 in development.
+  Which became 1.8.3 on 11 december with only the dns64 fix of 6 dec.
+  Trunk then became 1.8.4 in development.
+ - Fix that unbound-checkconf does not complains if the config file
+  is not placed inside the chroot.
+ - Refuse to start with no ports.
+ - Remove clang analysis warnings.
 
 28 November 2018: Wouter
  - Fix leak in chroot fix for auth-zone.
Index: doc/README
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/README,v
retrieving revision 1.17
diff -u -p -r1.17 README
--- doc/README 11 Dec 2018 13:49:01 -0000 1.17
+++ doc/README 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-README for Unbound 1.8.3
+README for Unbound 1.9.0rc1
 Copyright 2007 NLnet Labs
 http://unbound.net
 
Index: doc/example.conf.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/example.conf.in,v
retrieving revision 1.21
diff -u -p -r1.21 example.conf.in
--- doc/example.conf.in 11 Dec 2018 13:49:01 -0000 1.21
+++ doc/example.conf.in 29 Jan 2019 12:04:16 -0000
@@ -1,7 +1,7 @@
 #
 # Example configuration file.
 #
-# See unbound.conf(5) man page, version 1.8.3.
+# See unbound.conf(5) man page, version 1.9.0rc1.
 #
 # this is a comment.
 
@@ -123,6 +123,9 @@ server:
  # Suggested values are 512 to 4096. Default is 4096. 65536 disables it.
  # max-udp-size: 4096
 
+ # max memory to use for stream(tcp and tls) waiting result buffers.
+ # stream-wait-size: 4m
+
  # buffer size for handling DNS data. No messages larger than this
  # size can be sent or received, by UDP or TCP. In bytes.
  # msg-buffer-size: 65552
@@ -322,6 +325,10 @@ server:
  # timetoresolve, fromcache and responsesize.
  # log-replies: no
 
+ # log with tag 'query' and 'reply' instead of 'info' for
+ # filtering log-queries and log-replies from the log.
+ # log-tag-queryreply: no
+
  # log the local-zone actions, like local-zone type inform is enabled
  # also for the other local zone types.
  # log-local-actions: no
@@ -708,6 +715,19 @@ server:
  # tls-service-pem: "path/to/publiccertfile.pem"
  # tls-port: 853
 
+ # cipher setting for TLSv1.2
+ # tls-chiphers: "DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256"
+ # cipher setting for TLSv1.3
+ # tls-ciphersuites: "TLS_AES_128_GCM_SHA256:TLS_AES_128_CCM_8_SHA256:TLS_AES_128_CCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256"
+
+ # Add the secret file for TLS Session Ticket.
+ # Secret file must be 80 bytes of random data.
+ # First key use to encrypt and decrypt TLS session tickets.
+ # Other keys use to decrypt only.
+ # requires restart to take effect.
+ # tls-session-ticket-keys: "path/to/secret_file1"
+ # tls-session-ticket-keys: "path/to/secret_file2"
+
  # request upstream over TLS (with plain DNS inside the TLS stream).
  # Default is no.  Can be turned on and off with unbound-control.
  # tls-upstream: no
@@ -886,15 +906,25 @@ remote-control:
 # notifies.
 # auth-zone:
 # name: "."
-# for-downstream: no
+# master: 199.9.14.201         # b.root-servers.net
+# master: 192.33.4.12          # c.root-servers.net
+# master: 199.7.91.13          # d.root-servers.net
+# master: 192.5.5.241          # f.root-servers.net
+# master: 192.112.36.4         # g.root-servers.net
+# master: 193.0.14.129         # k.root-servers.net
+# master: 192.0.47.132         # xfr.cjr.dns.icann.org
+# master: 192.0.32.132         # xfr.lax.dns.icann.org
+# master: 2001:500:200::b      # b.root-servers.net
+# master: 2001:500:2::c        # c.root-servers.net
+# master: 2001:500:2d::d       # d.root-servers.net
+# master: 2001:500:2f::f       # f.root-servers.net
+# master: 2001:500:12::d0d     # g.root-servers.net
+# master: 2001:7fd::1          # k.root-servers.net
+# master: 2620:0:2830:202::132 # xfr.cjr.dns.icann.org
+# master: 2620:0:2d0:202::132  # xfr.lax.dns.icann.org
+# fallback-enabled: yes
+# for-downstream: no
 # for-upstream: yes
-# fallback-enabled: yes
-# master: b.root-servers.net
-# master: c.root-servers.net
-# master: e.root-servers.net
-# master: f.root-servers.net
-# master: g.root-servers.net
-# master: k.root-servers.net
 # auth-zone:
 # name: "example.org"
 # for-downstream: yes
Index: doc/libunbound.3.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/libunbound.3.in,v
retrieving revision 1.19
diff -u -p -r1.19 libunbound.3.in
--- doc/libunbound.3.in 11 Dec 2018 13:49:02 -0000 1.19
+++ doc/libunbound.3.in 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-.TH "libunbound" "3" "Dec 11, 2018" "NLnet Labs" "unbound 1.8.3"
+.TH "libunbound" "3" "Jan 29, 2019" "NLnet Labs" "unbound 1.9.0rc1"
 .\"
 .\" libunbound.3 -- unbound library functions manual
 .\"
@@ -20,6 +20,7 @@
 .B ub_ctx_config,
 .B ub_ctx_set_fwd,
 .B ub_ctx_set_stub,
+.B ub_ctx_set_tls,
 .B ub_ctx_resolvconf,
 .B ub_ctx_hosts,
 .B ub_ctx_add_ta,
@@ -43,7 +44,7 @@
 .B ub_ctx_zone_remove,
 .B ub_ctx_data_add,
 .B ub_ctx_data_remove
-\- Unbound DNS validating resolver 1.8.3 functions.
+\- Unbound DNS validating resolver 1.9.0rc1 functions.
 .SH "SYNOPSIS"
 .B #include <unbound.h>
 .LP
@@ -72,6 +73,9 @@
  \fIint\fR isprime);
 .LP
 \fIint\fR
+\fBub_ctx_set_tls\fR(\fIstruct ub_ctx*\fR ctx, \fIint\fR tls);
+.LP
+\fIint\fR
 \fBub_ctx_resolvconf\fR(\fIstruct ub_ctx*\fR ctx, \fIchar*\fR fname);
 .LP
 \fIint\fR
@@ -224,6 +228,12 @@ IP4 or IP6 address.  If the address is N
 Set isprime true if you configure root hints with it.  Otherwise similar to
 the stub zone item from unbound's config file.  Can be called several times,
 for different zones, or to add multiple addresses for a particular zone.
+At this time it is only possible to set configuration before the
+first resolve is done.
+.TP
+.B ub_ctx_set_tls
+Enable DNS over TLS (DoT) for machines set with
+.B ub_ctx_set_fwd.
 At this time it is only possible to set configuration before the
 first resolve is done.
 .TP
Index: doc/unbound-anchor.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/unbound-anchor.8.in,v
retrieving revision 1.18
diff -u -p -r1.18 unbound-anchor.8.in
--- doc/unbound-anchor.8.in 11 Dec 2018 13:49:02 -0000 1.18
+++ doc/unbound-anchor.8.in 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-.TH "unbound-anchor" "8" "Dec 11, 2018" "NLnet Labs" "unbound 1.8.3"
+.TH "unbound-anchor" "8" "Jan 29, 2019" "NLnet Labs" "unbound 1.9.0rc1"
 .\"
 .\" unbound-anchor.8 -- unbound anchor maintenance utility manual
 .\"
Index: doc/unbound-checkconf.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/unbound-checkconf.8.in,v
retrieving revision 1.18
diff -u -p -r1.18 unbound-checkconf.8.in
--- doc/unbound-checkconf.8.in 11 Dec 2018 13:49:02 -0000 1.18
+++ doc/unbound-checkconf.8.in 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-.TH "unbound-checkconf" "8" "Dec 11, 2018" "NLnet Labs" "unbound 1.8.3"
+.TH "unbound-checkconf" "8" "Jan 29, 2019" "NLnet Labs" "unbound 1.9.0rc1"
 .\"
 .\" unbound-checkconf.8 -- unbound configuration checker manual
 .\"
Index: doc/unbound-control.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/unbound-control.8.in,v
retrieving revision 1.20
diff -u -p -r1.20 unbound-control.8.in
--- doc/unbound-control.8.in 11 Dec 2018 13:49:02 -0000 1.20
+++ doc/unbound-control.8.in 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-.TH "unbound-control" "8" "Dec 11, 2018" "NLnet Labs" "unbound 1.8.3"
+.TH "unbound-control" "8" "Jan 29, 2019" "NLnet Labs" "unbound 1.9.0rc1"
 .\"
 .\" unbound-control.8 -- unbound remote control manual
 .\"
@@ -499,6 +499,10 @@ Memory in bytes in use by the iterator m
 Memory in bytes in use by the validator module. Includes the key cache and
 negative cache.
 .TP
+.I mem.streamwait
+Memory in bytes in used by the TCP and TLS stream wait buffers.  These are
+answers waiting to be written back to the clients.
+.TP
 .I histogram.<sec>.<usec>.to.<sec>.<usec>
 Shows a histogram, summed over all threads. Every element counts the
 recursive queries whose reply time fit between the lower and upper bound.
@@ -533,6 +537,10 @@ other servers.
 .I num.query.tls
 Number of queries that were made using TLS towards the unbound server.
 These are also counted in num.query.tcp, because TLS uses TCP.
+.TP
+.I num.query.tls.resume
+Number of TLS session resumptions, these are queries over TLS towards
+the unbound server where the client negotiated a TLS session resumption key.
 .TP
 .I num.query.ipv6
 Number of queries that were made using IPv6 towards the unbound server.
Index: doc/unbound-host.1.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/unbound-host.1.in,v
retrieving revision 1.20
diff -u -p -r1.20 unbound-host.1.in
--- doc/unbound-host.1.in 11 Dec 2018 13:49:02 -0000 1.20
+++ doc/unbound-host.1.in 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-.TH "unbound\-host" "1" "Dec 11, 2018" "NLnet Labs" "unbound 1.8.3"
+.TH "unbound\-host" "1" "Jan 29, 2019" "NLnet Labs" "unbound 1.9.0rc1"
 .\"
 .\" unbound-host.1 -- unbound DNS lookup utility
 .\"
Index: doc/unbound.8.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/unbound.8.in,v
retrieving revision 1.21
diff -u -p -r1.21 unbound.8.in
--- doc/unbound.8.in 11 Dec 2018 13:49:02 -0000 1.21
+++ doc/unbound.8.in 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-.TH "unbound" "8" "Dec 11, 2018" "NLnet Labs" "unbound 1.8.3"
+.TH "unbound" "8" "Jan 29, 2019" "NLnet Labs" "unbound 1.9.0rc1"
 .\"
 .\" unbound.8 -- unbound manual
 .\"
@@ -9,7 +9,7 @@
 .\"
 .SH "NAME"
 .B unbound
-\- Unbound DNS validating resolver 1.8.3.
+\- Unbound DNS validating resolver 1.9.0rc1.
 .SH "SYNOPSIS"
 .B unbound
 .RB [ \-h ]
Index: doc/unbound.conf.5.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/unbound.conf.5.in,v
retrieving revision 1.24
diff -u -p -r1.24 unbound.conf.5.in
--- doc/unbound.conf.5.in 11 Dec 2018 13:49:02 -0000 1.24
+++ doc/unbound.conf.5.in 29 Jan 2019 12:04:16 -0000
@@ -1,4 +1,4 @@
-.TH "unbound.conf" "5" "Dec 11, 2018" "NLnet Labs" "unbound 1.8.3"
+.TH "unbound.conf" "5" "Jan 29, 2019" "NLnet Labs" "unbound 1.9.0rc1"
 .\"
 .\" unbound.conf.5 -- unbound.conf manual
 .\"
@@ -171,6 +171,16 @@ Maximum UDP response size (not applied t
 udp response size maximum, and uses the choice from the client, always.
 Suggested values are 512 to 4096. Default is 4096.
 .TP
+.B stream\-wait\-size: \fI<number>
+Number of bytes size maximum to use for waiting stream buffers.  Default is
+4 megabytes.  A plain number is in bytes, append 'k', 'm' or 'g' for kilobytes,
+megabytes or gigabytes (1024*1024 bytes in a megabyte).  As TCP and TLS streams
+queue up multiple results, the amount of memory used for these buffers does
+not exceed this number, otherwise the responses are dropped.  This manages
+the total memory usage of the server (under heavy use), the number of requests
+that can be queued up per connection is also limited, with further requests
+waiting in TCP buffers.
+.TP
 .B msg\-buffer\-size: \fI<number>
 Number of bytes size of the message buffers. Default is 65552 bytes, enough
 for 64 Kb packets, the maximum DNS message size. No message larger than this
@@ -284,11 +294,9 @@ Must be set to a power of 2.
 .TP
 .B cache\-max\-ttl: \fI<seconds>
 Time to live maximum for RRsets and messages in the cache. Default is
-86400 seconds (1 day). If the maximum kicks in, responses to clients
-still get decrementing TTLs based on the original (larger) values.
-When the internal TTL expires, the cache item has expired.
+86400 seconds (1 day).  When the TTL expires, the cache item has expired.
 Can be set lower to force the resolver to query for data often, and not
-trust (very large) TTL values.
+trust (very large) TTL values.  Downstream clients also see the lower TTL.
 .TP
 .B cache\-min\-ttl: \fI<seconds>
 Time to live minimum for RRsets and messages in the cache. Default is 0.
@@ -406,13 +414,15 @@ TCP wireformat.  The other server must s
 \fBtls\-service\-key\fR).
 If you enable this, also configure a tls\-cert\-bundle or use tls\-win\-cert to
 load CA certs, otherwise the connections cannot be authenticated.
+This option enables TLS for all of them, but if you do not set this you can
+configure TLS specifically for some forward zones with forward\-tls\-upstream.  And also with stub\-tls\-upstream.
 .TP
 .B ssl\-upstream: \fI<yes or no>
 Alternate syntax for \fBtls\-upstream\fR.  If both are present in the config
 file the last is used.
 .TP
 .B tls\-service\-key: \fI<file>
-If enabled, the server provider TLS service on its TCP sockets.  The clients
+If enabled, the server provides TLS service on its TCP sockets.  The clients
 have to use tls\-upstream: yes.  The file is the private key for the TLS
 session.  The public certificate is in the tls\-service\-pem file.  Default
 is "", turned off.  Requires a restart (a reload is not enough) if changed,
@@ -458,6 +468,27 @@ List portnumbers as tls\-additional\-por
 eg. with the @port suffix, as this port number, they provide dns over TLS
 service.  Can list multiple, each on a new statement.
 .TP
+.B tls-session-ticket-keys: \fI<file>
+If not "", lists files with 80 bytes of random contents that are used to
+perform TLS session resumption for clients using the unbound server.
+These files contain the secret key for the TLS session tickets.
+First key use to encrypt and decrypt TLS session tickets.
+Other keys use to decrypt only.  With this you can roll over to new keys,
+by generating a new first file and allowing decrypt of the old file by
+listing it after the first file for some time, after the wait clients are not
+using the old key any more and the old key can be removed.
+One way to create the file is dd if=/dev/random bs=1 count=80 of=ticket.dat
+The first 16 bytes should be different from the old one if you create a second key, that is the name used to identify the key.  Then there is 32 bytes random
+data for an AES key and then 32 bytes random data for the HMAC key.
+.TP
+.B tls\-ciphers: \fI<string with cipher list>
+Set the list of ciphers to allow when serving TLS.  Use "" for defaults,
+and that is the default.
+.TP
+.B tls\-ciphersuites: \fI<string with ciphersuites list>
+Set the list of ciphersuites to allow when serving TLS.  This is for newer
+TLS 1.3 connections.  Use "" for defaults, and that is the default.
+.TP
 .B use\-systemd: \fI<yes or no>
 Enable or disable systemd socket activation.
 Default is no.
@@ -624,6 +655,11 @@ name, type, class, return code, time to
 Default is no.  Note that it takes time to print these
 lines which makes the server (significantly) slower.  Odd (nonprintable)
 characters in names are printed as '?'.
+.TP
+.B log\-tag\-queryreply: \fI<yes or no>
+Prints the word 'query' and 'reply' with log\-queries and log\-replies.
+This makes filtering logs easier.  The default is off (for backwards
+compatibility).
 .TP
 .B log\-local\-actions: \fI<yes or no>
 Print log lines to inform about local zone actions.  These lines are like the
Index: iterator/iterator.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/iterator/iterator.c,v
retrieving revision 1.20
diff -u -p -r1.20 iterator.c
--- iterator/iterator.c 4 Dec 2018 12:05:07 -0000 1.20
+++ iterator/iterator.c 29 Jan 2019 12:04:16 -0000
@@ -1882,7 +1882,6 @@ processLastResort(struct module_qstate*
  struct delegpt* p = hints_lookup_root(qstate->env->hints,
  iq->qchase.qclass);
  if(p) {
- struct delegpt_ns* ns;
  struct delegpt_addr* a;
  iq->chase_flags &= ~BIT_RD; /* go to authorities */
  for(ns = p->nslist; ns; ns=ns->next) {
@@ -2299,7 +2298,7 @@ processQueryTargets(struct module_qstate
  errinf(qstate, "auth zone lookup failed, fallback is off");
  return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
  }
- if(iq->dp && iq->dp->auth_dp) {
+ if(iq->dp->auth_dp) {
  /* we wanted to fallback, but had no delegpt, only the
  * auth zone generated delegpt, create an actual one */
  iq->auth_zone_avoid = 1;
@@ -3571,7 +3570,7 @@ process_response(struct module_qstate* q
  if(event == module_event_noreply || event == module_event_error) {
  if(event == module_event_noreply && iq->sent_count >= 3 &&
  qstate->env->cfg->use_caps_bits_for_id &&
- !iq->caps_fallback) {
+ !iq->caps_fallback && !is_caps_whitelisted(ie, iq)) {
  /* start fallback */
  iq->caps_fallback = 1;
  iq->caps_server = 0;
Index: libunbound/libunbound.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/libunbound/libunbound.c,v
retrieving revision 1.12
diff -u -p -r1.12 libunbound.c
--- libunbound/libunbound.c 8 Oct 2018 16:03:53 -0000 1.12
+++ libunbound/libunbound.c 29 Jan 2019 12:04:16 -0000
@@ -724,7 +724,7 @@ ub_resolve_event(struct ub_ctx* ctx, con
  *async_id = 0;
  lock_basic_lock(&ctx->cfglock);
  if(!ctx->finalized) {
- int r = context_finalize(ctx);
+ r = context_finalize(ctx);
  if(r) {
  lock_basic_unlock(&ctx->cfglock);
  return r;
@@ -962,6 +962,19 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const
  errno=ENOMEM;
  return UB_NOMEM;
  }
+ lock_basic_unlock(&ctx->cfglock);
+ return UB_NOERROR;
+}
+
+int ub_ctx_set_tls(struct ub_ctx* ctx, int tls)
+{
+ lock_basic_lock(&ctx->cfglock);
+ if(ctx->finalized) {
+ lock_basic_unlock(&ctx->cfglock);
+ errno=EINVAL;
+ return UB_AFTERFINAL;
+ }
+ ctx->env->cfg->ssl_upstream = tls;
  lock_basic_unlock(&ctx->cfglock);
  return UB_NOERROR;
 }
Index: libunbound/ubsyms.def
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/libunbound/ubsyms.def,v
retrieving revision 1.3
diff -u -p -r1.3 ubsyms.def
--- libunbound/ubsyms.def 22 Jun 2016 20:05:40 -0000 1.3
+++ libunbound/ubsyms.def 29 Jan 2019 12:04:16 -0000
@@ -20,6 +20,7 @@ ub_ctx_set_event
 ub_ctx_set_fwd
 ub_ctx_set_option
 ub_ctx_set_stub
+ub_ctx_set_tls
 ub_ctx_trustedkeys
 ub_ctx_zone_add
 ub_ctx_zone_remove
Index: libunbound/unbound.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/libunbound/unbound.h,v
retrieving revision 1.8
diff -u -p -r1.8 unbound.h
--- libunbound/unbound.h 20 Sep 2018 23:15:39 -0000 1.8
+++ libunbound/unbound.h 29 Jan 2019 12:04:16 -0000
@@ -310,6 +310,17 @@ int ub_ctx_config(struct ub_ctx* ctx, co
 int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr);
 
 /**
+ * Use DNS over TLS to send queries to machines set with ub_ctx_set_fwd().
+ *
+ * @param ctx: context.
+ * At this time it is only possible to set configuration before the
+ * first resolve is done.
+ * @param tls: enable or disable DNS over TLS
+ * @return 0 if OK, else error.
+ */
+int ub_ctx_set_tls(struct ub_ctx* ctx, int tls);
+
+/**
  * Add a stub zone, with given address to send to.  This is for custom
  * root hints or pointing to a local authoritative dns server.
  * For dns resolvers and the 'DHCP DNS' ip address, use ub_ctx_set_fwd.
@@ -770,6 +781,10 @@ struct ub_server_stats {
  /** number of queries answered from edns-subnet specific data, and
  * the answer was from the edns-subnet cache. */
  long long num_query_subnet_cache;
+ /** number of bytes in the stream wait buffers */
+ long long mem_stream_wait;
+ /** number of TLS connection resume */
+ long long qtls_resume;
 };
 
 /**
Index: respip/respip.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/respip/respip.c,v
retrieving revision 1.3
diff -u -p -r1.3 respip.c
--- respip/respip.c 8 Oct 2018 16:03:53 -0000 1.3
+++ respip/respip.c 29 Jan 2019 12:04:16 -0000
@@ -451,7 +451,7 @@ respip_views_apply_cfg(struct views* vs,
  * This function returns the copied rrset key on success, and NULL on memory
  * allocation failure.
  */
-struct ub_packed_rrset_key*
+static struct ub_packed_rrset_key*
 copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region)
 {
  struct ub_packed_rrset_key* ck = regional_alloc(region,
Index: services/authzone.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/authzone.c,v
retrieving revision 1.9
diff -u -p -r1.9 authzone.c
--- services/authzone.c 4 Dec 2018 12:05:07 -0000 1.9
+++ services/authzone.c 29 Jan 2019 12:04:16 -0000
@@ -88,6 +88,9 @@
 #define AUTH_HTTPS_PORT 443
 /* max depth for nested $INCLUDEs */
 #define MAX_INCLUDE_DEPTH 10
+/** number of timeouts before we fallback from IXFR to AXFR,
+ * because some versions of servers (eg. dnsmasq) drop IXFR packets. */
+#define NUM_TIMEOUTS_FALLBACK_IXFR 3
 
 /** pick up nextprobe task to start waiting to perform transfer actions */
 static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env,
@@ -1979,7 +1982,7 @@ int auth_zones_apply_cfg(struct auth_zon
  * @param at: transfer structure with chunks list.  The chunks and their
  * data are freed.
  */
-void
+static void
 auth_chunks_delete(struct auth_transfer* at)
 {
  if(at->chunks_first) {
@@ -2618,7 +2621,7 @@ az_nsec3_hashname(struct auth_zone* z, u
 }
 
 /** Find the datanode that covers the nsec3hash-name */
-struct auth_data*
+static struct auth_data*
 az_nsec3_findnode(struct auth_zone* z, uint8_t* hashnm, size_t hashnmlen)
 {
  struct query_info qinfo;
@@ -2743,13 +2746,14 @@ az_nsec3_insert(struct auth_zone* z, str
  * that is an exact match that should exist for it.
  * If that does not exist, a higher exact match + nxproof is enabled
  * (for some sort of opt-out empty nonterminal cases).
+ * ceproof: include ce proof NSEC3 (omitted for wildcard replies).
  * nxproof: include denial of the qname.
  * wcproof: include denial of wildcard (wildcard.ce).
  */
 static int
 az_add_nsec3_proof(struct auth_zone* z, struct regional* region,
  struct dns_msg* msg, uint8_t* cenm, size_t cenmlen, uint8_t* qname,
- size_t qname_len, int nxproof, int wcproof)
+ size_t qname_len, int ceproof, int nxproof, int wcproof)
 {
  int algo;
  size_t iter, saltlen;
@@ -2761,11 +2765,13 @@ az_add_nsec3_proof(struct auth_zone* z,
  if(!az_nsec3_param(z, &algo, &iter, &salt, &saltlen))
  return 1; /* no nsec3 */
  /* find ce that has an NSEC3 */
- node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce,
- algo, iter, salt, saltlen);
- if(no_exact_ce) nxproof = 1;
- if(!az_nsec3_insert(z, region, msg, node))
- return 0;
+ if(ceproof) {
+ node = az_nsec3_find_ce(z, &cenm, &cenmlen, &no_exact_ce,
+ algo, iter, salt, saltlen);
+ if(no_exact_ce) nxproof = 1;
+ if(!az_nsec3_insert(z, region, msg, node))
+ return 0;
+ }
 
  if(nxproof) {
  uint8_t* nx;
@@ -2910,7 +2916,7 @@ az_generate_notype_answer(struct auth_zo
  /* DNSSEC denial NSEC3 */
  if(!az_add_nsec3_proof(z, region, msg, node->name,
  node->namelen, msg->qinfo.qname,
- msg->qinfo.qname_len, 0, 0))
+ msg->qinfo.qname_len, 1, 0, 0))
  return 0;
  }
  return 1;
@@ -2937,7 +2943,7 @@ az_generate_referral_answer(struct auth_
  } else {
  if(!az_add_nsec3_proof(z, region, msg, ce->name,
  ce->namelen, msg->qinfo.qname,
- msg->qinfo.qname_len, 0, 0))
+ msg->qinfo.qname_len, 1, 0, 0))
  return 0;
  }
  }
@@ -3008,9 +3014,12 @@ az_generate_wildcard_answer(struct auth_
  if((nsec=az_find_nsec_cover(z, &node)) != NULL) {
  if(!msg_add_rrset_ns(z, region, msg, node, nsec)) return 0;
  } else if(ce) {
- if(!az_add_nsec3_proof(z, region, msg, ce->name,
- ce->namelen, msg->qinfo.qname,
- msg->qinfo.qname_len, 1, 0))
+ uint8_t* wildup = wildcard->name;
+ size_t wilduplen= wildcard->namelen;
+ dname_remove_label(&wildup, &wilduplen);
+ if(!az_add_nsec3_proof(z, region, msg, wildup,
+ wilduplen, msg->qinfo.qname,
+ msg->qinfo.qname_len, 0, 1, 0))
  return 0;
  }
 
@@ -3036,7 +3045,7 @@ az_generate_nxdomain_answer(struct auth_
  } else if(ce) {
  if(!az_add_nsec3_proof(z, region, msg, ce->name,
  ce->namelen, msg->qinfo.qname,
- msg->qinfo.qname_len, 1, 1))
+ msg->qinfo.qname_len, 1, 1, 1))
  return 0;
  }
  return 1;
@@ -4988,12 +4997,12 @@ xfr_transfer_lookup_host(struct auth_xfe
  qinfo.qtype = LDNS_RR_TYPE_AAAA;
  qinfo.local_alias = NULL;
  if(verbosity >= VERB_ALGO) {
- char buf[512];
+ char buf1[512];
  char buf2[LDNS_MAX_DOMAINLEN+1];
  dname_str(xfr->name, buf2);
- snprintf(buf, sizeof(buf), "auth zone %s: master lookup"
+ snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
  " for task_transfer", buf2);
- log_query_info(VERB_ALGO, buf, &qinfo);
+ log_query_info(VERB_ALGO, buf1, &qinfo);
  }
  edns.edns_present = 1;
  edns.ext_rcode = 0;
@@ -5630,15 +5639,33 @@ auth_xfer_transfer_tcp_callback(struct c
  * and continue task_transfer*/
  verbose(VERB_ALGO, "xfr stopped, connection lost to %s",
  xfr->task_transfer->master->host);
+
+ /* see if IXFR caused the failure, if so, try AXFR */
+ if(xfr->task_transfer->on_ixfr) {
+ xfr->task_transfer->ixfr_possible_timeout_count++;
+ if(xfr->task_transfer->ixfr_possible_timeout_count >=
+ NUM_TIMEOUTS_FALLBACK_IXFR) {
+ verbose(VERB_ALGO, "xfr to %s, fallback "
+ "from IXFR to AXFR (because of timeouts)",
+ xfr->task_transfer->master->host);
+ xfr->task_transfer->ixfr_fail = 1;
+ gonextonfail = 0;
+ }
+ }
+
  failed:
  /* delete transferred data from list */
  auth_chunks_delete(xfr->task_transfer);
  comm_point_delete(xfr->task_transfer->cp);
  xfr->task_transfer->cp = NULL;
- xfr_transfer_nextmaster(xfr);
+ if(gonextonfail)
+ xfr_transfer_nextmaster(xfr);
  xfr_transfer_nexttarget_or_end(xfr, env);
  return 0;
  }
+ /* note that IXFR worked without timeout */
+ if(xfr->task_transfer->on_ixfr)
+ xfr->task_transfer->ixfr_possible_timeout_count = 0;
 
  /* handle returned packet */
  /* if it fails, cleanup and end this transfer */
@@ -6010,12 +6037,12 @@ xfr_probe_lookup_host(struct auth_xfer*
  qinfo.qtype = LDNS_RR_TYPE_AAAA;
  qinfo.local_alias = NULL;
  if(verbosity >= VERB_ALGO) {
- char buf[512];
+ char buf1[512];
  char buf2[LDNS_MAX_DOMAINLEN+1];
  dname_str(xfr->name, buf2);
- snprintf(buf, sizeof(buf), "auth zone %s: master lookup"
+ snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup"
  " for task_probe", buf2);
- log_query_info(VERB_ALGO, buf, &qinfo);
+ log_query_info(VERB_ALGO, buf1, &qinfo);
  }
  edns.edns_present = 1;
  edns.ext_rcode = 0;
Index: services/authzone.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/authzone.h,v
retrieving revision 1.6
diff -u -p -r1.6 authzone.h
--- services/authzone.h 4 Dec 2018 12:05:07 -0000 1.6
+++ services/authzone.h 29 Jan 2019 12:04:16 -0000
@@ -378,6 +378,8 @@ struct auth_transfer {
  * data or add of duplicate data).  Flag is cleared once the retry
  * with axfr is done. */
  int ixfr_fail;
+ /** we saw an ixfr-indicating timeout, count of them */
+ int ixfr_possible_timeout_count;
  /** we are doing IXFR right now */
  int on_ixfr;
  /** did we detect the current AXFR/IXFR serial number yet, 0 not yet,
Index: services/listen_dnsport.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/listen_dnsport.c,v
retrieving revision 1.19
diff -u -p -r1.19 listen_dnsport.c
--- services/listen_dnsport.c 4 Dec 2018 12:05:07 -0000 1.19
+++ services/listen_dnsport.c 29 Jan 2019 12:04:16 -0000
@@ -53,6 +53,9 @@
 #include "util/config_file.h"
 #include "util/net_help.h"
 #include "sldns/sbuffer.h"
+#include "services/mesh.h"
+#include "util/fptr_wlist.h"
+#include "util/locks.h"
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -70,6 +73,18 @@
 /** number of queued TCP connections for listen() */
 #define TCP_BACKLOG 256
 
+/** number of simultaneous requests a client can have */
+#define TCP_MAX_REQ_SIMULTANEOUS 32
+
+#ifndef THREADS_DISABLED
+/** lock on the counter of stream buffer memory */
+static lock_basic_type stream_wait_count_lock;
+#endif
+/** size (in bytes) of stream wait buffers */
+static size_t stream_wait_count = 0;
+/** is the lock initialised for stream wait buffers */
+static int stream_wait_lock_inited = 0;
+
 /**
  * Debug print of the getaddrinfo returned address.
  * @param addr: the address returned.
@@ -838,7 +853,11 @@ create_tcp_accept_sock(struct addrinfo *
    disabled, except when verbosity enabled for debugging */
  if(errno != ENOPROTOOPT || verbosity >= 3)
 #endif
-  log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
+  if(errno == EPERM) {
+   log_warn("Setting TCP Fast Open as server failed: %s ; this could likely be because sysctl net.inet.tcp.fastopen.enabled, net.inet.tcp.fastopen.server_enable, or net.ipv4.tcp_fastopen is disabled", strerror(errno));
+  } else {
+   log_err("Setting TCP Fast Open as server failed: %s", strerror(errno));
+  }
  }
 #endif
  return s;
@@ -1260,6 +1279,10 @@ listen_create(struct comm_base* base, st
  free(front);
  return NULL;
  }
+ if(!stream_wait_lock_inited) {
+ lock_basic_init(&stream_wait_count_lock);
+ stream_wait_lock_inited = 1;
+ }
 
  /* create comm points as needed */
  while(ports) {
@@ -1272,11 +1295,13 @@ listen_create(struct comm_base* base, st
  ports->ftype == listen_type_tcp_dnscrypt)
  cp = comm_point_create_tcp(base, ports->fd,
  tcp_accept_count, tcp_idle_timeout,
- tcp_conn_limit, bufsize, cb, cb_arg);
+ tcp_conn_limit, bufsize, front->udp_buff,
+ cb, cb_arg);
  else if(ports->ftype == listen_type_ssl) {
  cp = comm_point_create_tcp(base, ports->fd,
  tcp_accept_count, tcp_idle_timeout,
- tcp_conn_limit, bufsize, cb, cb_arg);
+ tcp_conn_limit, bufsize, front->udp_buff,
+ cb, cb_arg);
  cp->ssl = sslctx;
  } else if(ports->ftype == listen_type_udpancil ||
   ports->ftype == listen_type_udpancil_dnscrypt)
@@ -1347,6 +1372,10 @@ listen_delete(struct listen_dnsport* fro
 #endif
  sldns_buffer_free(front->udp_buff);
  free(front);
+ if(stream_wait_lock_inited) {
+ stream_wait_lock_inited = 0;
+ lock_basic_destroy(&stream_wait_count_lock);
+ }
 }
 
 struct listen_port*
@@ -1504,3 +1533,367 @@ void listen_start_accept(struct listen_d
  }
 }
 
+struct tcp_req_info*
+tcp_req_info_create(struct sldns_buffer* spoolbuf)
+{
+ struct tcp_req_info* req = (struct tcp_req_info*)malloc(sizeof(*req));
+ if(!req) {
+ log_err("malloc failure for new stream outoforder processing structure");
+ return NULL;
+ }
+ memset(req, 0, sizeof(*req));
+ req->spool_buffer = spoolbuf;
+ return req;
+}
+
+void
+tcp_req_info_delete(struct tcp_req_info* req)
+{
+ if(!req) return;
+ tcp_req_info_clear(req);
+ /* cp is pointer back to commpoint that owns this struct and
+ * called delete on us */
+ /* spool_buffer is shared udp buffer, not deleted here */
+ free(req);
+}
+
+void tcp_req_info_clear(struct tcp_req_info* req)
+{
+ struct tcp_req_open_item* open, *nopen;
+ struct tcp_req_done_item* item, *nitem;
+ if(!req) return;
+
+ /* free outstanding request mesh reply entries */
+ open = req->open_req_list;
+ while(open) {
+ nopen = open->next;
+ mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp);
+ free(open);
+ open = nopen;
+ }
+ req->open_req_list = NULL;
+ req->num_open_req = 0;
+
+ /* free pending writable result packets */
+ item = req->done_req_list;
+ while(item) {
+ nitem = item->next;
+ lock_basic_lock(&stream_wait_count_lock);
+ stream_wait_count -= (sizeof(struct tcp_req_done_item)
+ +item->len);
+ lock_basic_unlock(&stream_wait_count_lock);
+ free(item->buf);
+ free(item);
+ item = nitem;
+ }
+ req->done_req_list = NULL;
+ req->num_done_req = 0;
+ req->read_is_closed = 0;
+}
+
+void
+tcp_req_info_remove_mesh_state(struct tcp_req_info* req, struct mesh_state* m)
+{
+ struct tcp_req_open_item* open, *prev = NULL;
+ if(!req || !m) return;
+ open = req->open_req_list;
+ while(open) {
+ if(open->mesh_state == m) {
+ struct tcp_req_open_item* next;
+ if(prev) prev->next = open->next;
+ else req->open_req_list = open->next;
+ /* caller has to manage the mesh state reply entry */
+ next = open->next;
+ free(open);
+ req->num_open_req --;
+
+ /* prev = prev; */
+ open = next;
+ continue;
+ }
+ prev = open;
+ open = open->next;
+ }
+}
+
+/** setup listening for read or write */
+static void
+tcp_req_info_setup_listen(struct tcp_req_info* req)
+{
+ int wr = 0;
+ int rd = 0;
+
+ if(req->cp->tcp_byte_count != 0) {
+ /* cannot change, halfway through */
+ return;
+ }
+
+ if(!req->cp->tcp_is_reading)
+ wr = 1;
+ if(req->num_open_req + req->num_done_req < TCP_MAX_REQ_SIMULTANEOUS &&
+ !req->read_is_closed)
+ rd = 1;
+
+ if(wr) {
+ req->cp->tcp_is_reading = 0;
+ comm_point_start_listening(req->cp, -1,
+ req->cp->tcp_timeout_msec);
+ } else if(rd) {
+ req->cp->tcp_is_reading = 1;
+ comm_point_start_listening(req->cp, -1,
+ req->cp->tcp_timeout_msec);
+ /* and also read it (from SSL stack buffers), so
+ * no event read event is expected since the remainder of
+ * the TLS frame is sitting in the buffers. */
+ req->read_again = 1;
+ } else {
+ comm_point_start_listening(req->cp, -1,
+ req->cp->tcp_timeout_msec);
+ comm_point_listen_for_rw(req->cp, 0, 0);
+ }
+}
+
+/** remove first item from list of pending results */
+static struct tcp_req_done_item*
+tcp_req_info_pop_done(struct tcp_req_info* req)
+{
+ struct tcp_req_done_item* item;
+ log_assert(req->num_done_req > 0 && req->done_req_list);
+ item = req->done_req_list;
+ lock_basic_lock(&stream_wait_count_lock);
+ stream_wait_count -= (sizeof(struct tcp_req_done_item)+item->len);
+ lock_basic_unlock(&stream_wait_count_lock);
+ req->done_req_list = req->done_req_list->next;
+ req->num_done_req --;
+ return item;
+}
+
+/** Send given buffer and setup to write */
+static void
+tcp_req_info_start_write_buf(struct tcp_req_info* req, uint8_t* buf,
+ size_t len)
+{
+ sldns_buffer_clear(req->cp->buffer);
+ sldns_buffer_write(req->cp->buffer, buf, len);
+ sldns_buffer_flip(req->cp->buffer);
+
+ req->cp->tcp_is_reading = 0; /* we are now writing */
+}
+
+/** pick up the next result and start writing it to the channel */
+static void
+tcp_req_pickup_next_result(struct tcp_req_info* req)
+{
+ if(req->num_done_req > 0) {
+ /* unlist the done item from the list of pending results */
+ struct tcp_req_done_item* item = tcp_req_info_pop_done(req);
+ tcp_req_info_start_write_buf(req, item->buf, item->len);
+ free(item->buf);
+ free(item);
+ }
+}
+
+/** the read channel has closed */
+int
+tcp_req_info_handle_read_close(struct tcp_req_info* req)
+{
+ verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd);
+ /* reset byte count for (potential) partial read */
+ req->cp->tcp_byte_count = 0;
+ /* if we still have results to write, pick up next and write it */
+ if(req->num_done_req != 0) {
+ tcp_req_pickup_next_result(req);
+ tcp_req_info_setup_listen(req);
+ return 1;
+ }
+ /* if nothing to do, this closes the connection */
+ if(req->num_open_req == 0 && req->num_done_req == 0)
+ return 0;
+ /* otherwise, we must be waiting for dns resolve, wait with timeout */
+ req->read_is_closed = 1;
+ tcp_req_info_setup_listen(req);
+ return 1;
+}
+
+void
+tcp_req_info_handle_writedone(struct tcp_req_info* req)
+{
+ /* back to reading state, we finished this write event */
+ sldns_buffer_clear(req->cp->buffer);
+ if(req->num_done_req == 0 && req->read_is_closed) {
+ /* no more to write and nothing to read, close it */
+ comm_point_drop_reply(&req->cp->repinfo);
+ return;
+ }
+ req->cp->tcp_is_reading = 1;
+ /* see if another result needs writing */
+ tcp_req_pickup_next_result(req);
+
+ /* see if there is more to write, if not stop_listening for writing */
+ /* see if new requests are allowed, if so, start_listening
+ * for reading */
+ tcp_req_info_setup_listen(req);
+}
+
+void
+tcp_req_info_handle_readdone(struct tcp_req_info* req)
+{
+ struct comm_point* c = req->cp;
+
+ /* we want to read up several requests, unless there are
+ * pending answers */
+
+ req->is_drop = 0;
+ req->is_reply = 0;
+ req->in_worker_handle = 1;
+ /* handle the current request */
+ /* this calls the worker handle request routine that could give
+ * a cache response, or localdata response, or drop the reply,
+ * or schedule a mesh entry for later */
+ fptr_ok(fptr_whitelist_comm_point(c->callback));
+ if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo) ) {
+ req->in_worker_handle = 0;
+ /* there is an answer, put it up.  It is already in the
+ * c->buffer, just send it. */
+ /* since we were just reading a query, the channel is
+ * clear to write to */
+ send_it:
+ c->tcp_is_reading = 0;
+ comm_point_start_listening(c, -1, c->tcp_timeout_msec);
+ return;
+ }
+ req->in_worker_handle = 0;
+ /* it should be waiting in the mesh for recursion.
+ * If mesh failed to add a new entry and called commpoint_drop_reply.
+ * Then the mesh state has been cleared. */
+ if(req->is_drop) {
+ /* we can now call drop_reply without recursing into ourselves
+ * whilst in the callback */
+ /* we have to close the stream because there is no reply,
+ * no servfail to send, but the query needs an action, for
+ * a stream that is close the connection */
+ sldns_buffer_clear(c->buffer);
+ comm_point_drop_reply(&c->repinfo);
+ return;
+ }
+ /* If mesh failed(mallocfail) and called commpoint_send_reply with
+ * something like servfail then we pick up that reply below. */
+ if(req->is_reply) {
+ goto send_it;
+ }
+
+ sldns_buffer_clear(c->buffer);
+ /* if pending answers, pick up an answer and start sending it */
+ tcp_req_pickup_next_result(req);
+
+ /* if answers pending, start sending answers */
+ /* read more requests if we can have more requests */
+ tcp_req_info_setup_listen(req);
+}
+
+int
+tcp_req_info_add_meshstate(struct tcp_req_info* req,
+ struct mesh_area* mesh, struct mesh_state* m)
+{
+ struct tcp_req_open_item* item;
+ log_assert(req && mesh && m);
+ item = (struct tcp_req_open_item*)malloc(sizeof(*item));
+ if(!item) return 0;
+ item->next = req->open_req_list;
+ item->mesh = mesh;
+ item->mesh_state = m;
+ req->open_req_list = item;
+ req->num_open_req++;
+ return 1;
+}
+
+/** Add a result to the result list.  At the end. */
+static int
+tcp_req_info_add_result(struct tcp_req_info* req, uint8_t* buf, size_t len)
+{
+ struct tcp_req_done_item* last = NULL;
+ struct tcp_req_done_item* item;
+ size_t space;
+
+ /* see if we have space */
+ space = sizeof(struct tcp_req_done_item) + len;
+ lock_basic_lock(&stream_wait_count_lock);
+ if(stream_wait_count + space > stream_wait_max) {
+ lock_basic_unlock(&stream_wait_count_lock);
+ verbose(VERB_ALGO, "drop stream reply, no space left, in stream-wait-size");
+ return 0;
+ }
+ stream_wait_count += space;
+ lock_basic_unlock(&stream_wait_count_lock);
+
+ /* find last element */
+ last = req->done_req_list;
+ while(last && last->next)
+ last = last->next;
+
+ /* create new element */
+ item = (struct tcp_req_done_item*)malloc(sizeof(*item));
+ if(!item) {
+ log_err("malloc failure, for stream result list");
+ return 0;
+ }
+ item->next = NULL;
+ item->len = len;
+ item->buf = memdup(buf, len);
+ if(!item->buf) {
+ free(item);
+ log_err("malloc failure, adding reply to stream result list");
+ return 0;
+ }
+
+ /* link in */
+ if(last) last->next = item;
+ else req->done_req_list = item;
+ req->num_done_req++;
+ return 1;
+}
+
+void
+tcp_req_info_send_reply(struct tcp_req_info* req)
+{
+ if(req->in_worker_handle) {
+ /* It is in the right buffer to answer straight away */
+ req->is_reply = 1;
+ return;
+ }
+ /* now that the query has been handled, that mesh_reply entry
+ * should be removed, from the tcp_req_info list,
+ * the mesh state cleanup removes then with region_cleanup and
+ * replies_sent true. */
+ /* see if we can send it straight away (we are not doing
+ * anything else).  If so, copy to buffer and start */
+ if(req->cp->tcp_is_reading && req->cp->tcp_byte_count == 0) {
+ /* buffer is free, and was ready to read new query into,
+ * but we are now going to use it to send this answer */
+ tcp_req_info_start_write_buf(req,
+ sldns_buffer_begin(req->spool_buffer),
+ sldns_buffer_limit(req->spool_buffer));
+ /* switch to listen to write events */
+ comm_point_stop_listening(req->cp);
+ comm_point_start_listening(req->cp, -1,
+ req->cp->tcp_timeout_msec);
+ return;
+ }
+ /* queue up the answer behind the others already pending */
+ if(!tcp_req_info_add_result(req, sldns_buffer_begin(req->spool_buffer),
+ sldns_buffer_limit(req->spool_buffer))) {
+ /* drop the connection, we are out of resources */
+ comm_point_drop_reply(&req->cp->repinfo);
+ }
+}
+
+size_t tcp_req_info_get_stream_buffer_size(void)
+{
+ size_t s;
+ if(!stream_wait_lock_inited)
+ return stream_wait_count;
+ lock_basic_lock(&stream_wait_count_lock);
+ s = stream_wait_count;
+ lock_basic_unlock(&stream_wait_count_lock);
+ return s;
+}
Index: services/listen_dnsport.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/listen_dnsport.h,v
retrieving revision 1.11
diff -u -p -r1.11 listen_dnsport.h
--- services/listen_dnsport.h 20 Sep 2018 23:15:39 -0000 1.11
+++ services/listen_dnsport.h 29 Jan 2019 12:04:16 -0000
@@ -237,4 +237,134 @@ int create_tcp_accept_sock(struct addrin
  */
 int create_local_accept_sock(const char* path, int* noproto, int use_systemd);
 
+/**
+ * TCP request info.  List of requests outstanding on the channel, that
+ * are asked for but not yet answered back.
+ */
+struct tcp_req_info {
+ /** the TCP comm point for this.  Its buffer is used for read/write */
+ struct comm_point* cp;
+ /** the buffer to use to spool reply from mesh into,
+ * it can then be copied to the result list and written.
+ * it is a pointer to the shared udp buffer. */
+ struct sldns_buffer* spool_buffer;
+ /** are we in worker_handle function call (for recursion callback)*/
+ int in_worker_handle;
+ /** is the comm point dropped (by worker handle).
+ * That means we have to disconnect the channel. */
+ int is_drop;
+ /** is the comm point set to send_reply (by mesh new client in worker
+ * handle), if so answer is available in c.buffer */
+ int is_reply;
+ /** read channel has closed, just write pending results */
+ int read_is_closed;
+ /** read again */
+ int read_again;
+ /** number of outstanding requests */
+ int num_open_req;
+ /** list of outstanding requests */
+ struct tcp_req_open_item* open_req_list;
+ /** number of pending writeable results */
+ int num_done_req;
+ /** list of pending writable result packets, malloced one at a time */
+ struct tcp_req_done_item* done_req_list;
+};
+
+/**
+ * List of open items in TCP channel
+ */
+struct tcp_req_open_item {
+ /** next in list */
+ struct tcp_req_open_item* next;
+ /** the mesh area of the mesh_state */
+ struct mesh_area* mesh;
+ /** the mesh state */
+ struct mesh_state* mesh_state;
+};
+
+/**
+ * List of done items in TCP channel
+ */
+struct tcp_req_done_item {
+ /** next in list */
+ struct tcp_req_done_item* next;
+ /** the buffer with packet contents */
+ uint8_t* buf;
+ /** length of the buffer */
+ size_t len;
+};
+
+/**
+ * Create tcp request info structure that keeps track of open
+ * requests on the TCP channel that are resolved at the same time,
+ * and the pending results that have to get written back to that client.
+ * @param spoolbuf: shared buffer
+ * @return new structure or NULL on alloc failure.
+ */
+struct tcp_req_info* tcp_req_info_create(struct sldns_buffer* spoolbuf);
+
+/**
+ * Delete tcp request structure.  Called by owning commpoint.
+ * Removes mesh entry references and stored results from the lists.
+ * @param req: the tcp request info
+ */
+void tcp_req_info_delete(struct tcp_req_info* req);
+
+/**
+ * Clear tcp request structure.  Removes list entries, sets it up ready
+ * for the next connection.
+ * @param req: tcp request info structure.
+ */
+void tcp_req_info_clear(struct tcp_req_info* req);
+
+/**
+ * Remove mesh state entry from list in tcp_req_info.
+ * caller has to manage the mesh state reply entry in the mesh state.
+ * @param req: the tcp req info that has the entry removed from the list.
+ * @param m: the state removed from the list.
+ */
+void tcp_req_info_remove_mesh_state(struct tcp_req_info* req,
+ struct mesh_state* m);
+
+/**
+ * Handle write done of the last result packet
+ * @param req: the tcp req info.
+ */
+void tcp_req_info_handle_writedone(struct tcp_req_info* req);
+
+/**
+ * Handle read done of a new request from the client
+ * @param req: the tcp req info.
+ */
+void tcp_req_info_handle_readdone(struct tcp_req_info* req);
+
+/**
+ * Add mesh state to the tcp req list of open requests.
+ * So the comm_reply can be removed off the mesh reply list when
+ * the tcp channel has to be closed (for other reasons then that that
+ * request was done, eg. channel closed by client or some format error).
+ * @param req: tcp req info structure.  It keeps track of the simultaneous
+ * requests and results on a tcp (or TLS) channel.
+ * @param mesh: mesh area for the state.
+ * @param m: mesh state to add.
+ * @return 0 on failure (malloc failure).
+ */
+int tcp_req_info_add_meshstate(struct tcp_req_info* req,
+ struct mesh_area* mesh, struct mesh_state* m);
+
+/**
+ * Send reply on tcp simultaneous answer channel.  May queue it up.
+ * @param req: request info structure.
+ */
+void tcp_req_info_send_reply(struct tcp_req_info* req);
+
+/** the read channel has closed
+ * @param req: request. remaining queries are looked up and answered.
+ * @return zero if nothing to do, just close the tcp.
+ */
+int tcp_req_info_handle_read_close(struct tcp_req_info* req);
+
+/** get the size of currently used tcp stream wait buffers (in bytes) */
+size_t tcp_req_info_get_stream_buffer_size(void);
+
 #endif /* LISTEN_DNSPORT_H */
Index: services/mesh.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/mesh.c,v
retrieving revision 1.10
diff -u -p -r1.10 mesh.c
--- services/mesh.c 20 Sep 2018 23:15:39 -0000 1.10
+++ services/mesh.c 29 Jan 2019 12:04:16 -0000
@@ -61,6 +61,7 @@
 #include "services/localzone.h"
 #include "util/data/dname.h"
 #include "respip/respip.h"
+#include "services/listen_dnsport.h"
 
 /** subtract timers and the values do not overflow or become negative */
 static void
@@ -429,6 +430,7 @@ void mesh_new_client(struct mesh_area* m
  /* add reply to s */
  if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) {
  log_err("mesh_new_client: out of memory; SERVFAIL");
+ servfail_mem:
  if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, &s->s,
  NULL, LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch))
  edns->opt_list = NULL;
@@ -439,6 +441,12 @@ void mesh_new_client(struct mesh_area* m
  mesh_state_delete(&s->s);
  return;
  }
+ if(rep->c->tcp_req_info) {
+ if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) {
+ log_err("mesh_new_client: out of memory add tcpreqinfo");
+ goto servfail_mem;
+ }
+ }
  /* update statistics */
  if(was_detached) {
  log_assert(mesh->num_detached_states > 0);
@@ -732,9 +740,13 @@ mesh_state_cleanup(struct mesh_state* ms
  mesh = mstate->s.env->mesh;
  /* drop unsent replies */
  if(!mstate->replies_sent) {
- struct mesh_reply* rep;
+ struct mesh_reply* rep = mstate->reply_list;
  struct mesh_cb* cb;
- for(rep=mstate->reply_list; rep; rep=rep->next) {
+ /* in tcp_req_info, the mstates linked are removed, but
+ * the reply_list is now NULL, so the remove-from-empty-list
+ * takes no time and also it does not do the mesh accounting */
+ mstate->reply_list = NULL;
+ for(; rep; rep=rep->next) {
  comm_point_drop_reply(&rep->query_reply);
  mesh->num_reply_addrs--;
  }
@@ -1031,11 +1043,14 @@ mesh_do_callback(struct mesh_state* m, i
  * @param rcode: if not 0, error code.
  * @param rep: reply to send (or NULL if rcode is set).
  * @param r: reply entry
+ * @param r_buffer: buffer to use for reply entry.
  * @param prev: previous reply, already has its answer encoded in buffer.
+ * @param prev_buffer: buffer for previous reply.
  */
 static void
 mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
- struct mesh_reply* r, struct mesh_reply* prev)
+ struct mesh_reply* r, struct sldns_buffer* r_buffer,
+ struct mesh_reply* prev, struct sldns_buffer* prev_buffer)
 {
  struct timeval end_time;
  struct timeval duration;
@@ -1063,7 +1078,7 @@ mesh_send_reply(struct mesh_state* m, in
  * and still reuse the previous answer if they are the same, but that
  * would be complicated and error prone for the relatively minor case.
  * So we err on the side of safety. */
- if(prev && prev->qflags == r->qflags &&
+ if(prev && prev_buffer && prev->qflags == r->qflags &&
  !prev->local_alias && !r->local_alias &&
  prev->edns.edns_present == r->edns.edns_present &&
  prev->edns.bits == r->edns.bits &&
@@ -1071,13 +1086,11 @@ mesh_send_reply(struct mesh_state* m, in
  edns_opt_list_compare(prev->edns.opt_list, r->edns.opt_list)
  == 0) {
  /* if the previous reply is identical to this one, fix ID */
- if(prev->query_reply.c->buffer != r->query_reply.c->buffer)
- sldns_buffer_copy(r->query_reply.c->buffer,
- prev->query_reply.c->buffer);
- sldns_buffer_write_at(r->query_reply.c->buffer, 0,
- &r->qid, sizeof(uint16_t));
- sldns_buffer_write_at(r->query_reply.c->buffer, 12,
- r->qname, m->s.qinfo.qname_len);
+ if(prev_buffer != r_buffer)
+ sldns_buffer_copy(r_buffer, prev_buffer);
+ sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t));
+ sldns_buffer_write_at(r_buffer, 12, r->qname,
+ m->s.qinfo.qname_len);
  comm_point_send_reply(&r->query_reply);
  } else if(rcode) {
  m->s.qinfo.qname = r->qname;
@@ -1091,8 +1104,8 @@ mesh_send_reply(struct mesh_state* m, in
  &r->edns, NULL, m->s.region))
  r->edns.opt_list = NULL;
  }
- error_encode(r->query_reply.c->buffer, rcode, &m->s.qinfo,
- r->qid, r->qflags, &r->edns);
+ error_encode(r_buffer, rcode, &m->s.qinfo, r->qid,
+ r->qflags, &r->edns);
  comm_point_send_reply(&r->query_reply);
  } else {
  size_t udp_size = r->edns.udp_size;
@@ -1108,16 +1121,15 @@ mesh_send_reply(struct mesh_state* m, in
  m->s.env->cfg, r->query_reply.c,
  m->s.region) ||
  !reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
- r->qflags, r->query_reply.c->buffer, 0, 1,
- m->s.env->scratch, udp_size, &r->edns,
- (int)(r->edns.bits & EDNS_DO), secure))
+ r->qflags, r_buffer, 0, 1, m->s.env->scratch,
+ udp_size, &r->edns, (int)(r->edns.bits & EDNS_DO),
+ secure))
  {
  if(!inplace_cb_reply_servfail_call(m->s.env, &m->s.qinfo, &m->s,
  rep, LDNS_RCODE_SERVFAIL, &r->edns, NULL, m->s.region))
  r->edns.opt_list = NULL;
- error_encode(r->query_reply.c->buffer,
- LDNS_RCODE_SERVFAIL, &m->s.qinfo, r->qid,
- r->qflags, &r->edns);
+ error_encode(r_buffer, LDNS_RCODE_SERVFAIL,
+ &m->s.qinfo, r->qid, r->qflags, &r->edns);
  }
  r->edns = edns_bak;
  comm_point_send_reply(&r->query_reply);
@@ -1132,19 +1144,17 @@ mesh_send_reply(struct mesh_state* m, in
  timeval_add(&m->s.env->mesh->replies_sum_wait, &duration);
  timehist_insert(m->s.env->mesh->histogram, &duration);
  if(m->s.env->cfg->stat_extended) {
- uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(r->
- query_reply.c->buffer, 2));
+ uint16_t rc = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(
+ r_buffer, 2));
  if(secure) m->s.env->mesh->ans_secure++;
  m->s.env->mesh->ans_rcode[ rc ] ++;
- if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r->
- query_reply.c->buffer)) == 0)
+ if(rc == 0 && LDNS_ANCOUNT(sldns_buffer_begin(r_buffer)) == 0)
  m->s.env->mesh->ans_nodata++;
  }
  /* Log reply sent */
  if(m->s.env->cfg->log_replies) {
  log_reply_info(0, &m->s.qinfo, &r->query_reply.addr,
- r->query_reply.addrlen, duration, 0,
- r->query_reply.c->buffer);
+ r->query_reply.addrlen, duration, 0, r_buffer);
  }
 }
 
@@ -1152,6 +1162,7 @@ void mesh_query_done(struct mesh_state*
 {
  struct mesh_reply* r;
  struct mesh_reply* prev = NULL;
+ struct sldns_buffer* prev_buffer = NULL;
  struct mesh_cb* c;
  struct reply_info* rep = (mstate->s.return_msg?
  mstate->s.return_msg->rep:NULL);
@@ -1180,9 +1191,15 @@ void mesh_query_done(struct mesh_state*
  if(mstate->s.is_drop)
  comm_point_drop_reply(&r->query_reply);
  else {
+ struct sldns_buffer* r_buffer = r->query_reply.c->buffer;
+ if(r->query_reply.c->tcp_req_info)
+ r_buffer = r->query_reply.c->tcp_req_info->spool_buffer;
  mesh_send_reply(mstate, mstate->s.return_rcode, rep,
- r, prev);
+ r, r_buffer, prev, prev_buffer);
+ if(r->query_reply.c->tcp_req_info)
+ tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate);
  prev = r;
+ prev_buffer = r_buffer;
  }
  }
  mstate->replies_sent = 1;
@@ -1392,7 +1409,7 @@ mesh_continue(struct mesh_area* mesh, st
  /* module is looping. Stop it. */
  log_err("internal error: looping module (%s) stopped",
  mesh->mods.mod[mstate->s.curmod]->name);
- log_query_info(VERB_QUERY, "pass error for qstate",
+ log_query_info(0, "pass error for qstate",
  &mstate->s.qinfo);
  s = module_error;
  }
@@ -1612,4 +1629,39 @@ void mesh_list_remove(struct mesh_state*
  if(m->prev)
  m->prev->next = m->next;
  else *fp = m->next;
+}
+
+void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
+ struct comm_point* cp)
+{
+ struct mesh_reply* n, *prev = NULL;
+ n = m->reply_list;
+ /* when in mesh_cleanup, it sets the reply_list to NULL, so that
+ * there is no accounting twice */
+ if(!n) return; /* nothing to remove, also no accounting needed */
+ while(n) {
+ if(n->query_reply.c == cp) {
+ /* unlink it */
+ if(prev) prev->next = n->next;
+ else m->reply_list = n->next;
+ /* delete it, but allocated in m region */
+ mesh->num_reply_addrs--;
+
+ /* prev = prev; */
+ n = n->next;
+ continue;
+ }
+ prev = n;
+ n = n->next;
+ }
+ /* it was not detached (because it had a reply list), could be now */
+ if(!m->reply_list && !m->cb_list
+ && m->super_set.count == 0) {
+ mesh->num_detached_states++;
+ }
+ /* if not replies any more in mstate, it is no longer a reply_state */
+ if(!m->reply_list && !m->cb_list) {
+ log_assert(mesh->num_reply_states > 0);
+ mesh->num_reply_states--;
+ }
 }
Index: services/mesh.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/mesh.h,v
retrieving revision 1.5
diff -u -p -r1.5 mesh.h
--- services/mesh.h 20 Sep 2018 23:15:39 -0000 1.5
+++ services/mesh.h 29 Jan 2019 12:04:16 -0000
@@ -65,7 +65,7 @@ struct respip_client_info;
  * Maximum number of mesh state activations. Any more is likely an
  * infinite loop in the module. It is then terminated.
  */
-#define MESH_MAX_ACTIVATION 3000
+#define MESH_MAX_ACTIVATION 10000
 
 /**
  * Max number of references-to-references-to-references.. search size.
@@ -632,5 +632,15 @@ void mesh_list_insert(struct mesh_state*
  */
 void mesh_list_remove(struct mesh_state* m, struct mesh_state** fp,
  struct mesh_state** lp);
+
+/**
+ * Remove mesh reply entry from the reply entry list.  Searches for
+ * the comm_point pointer.
+ * @param mesh: to update the counters.
+ * @param m: the mesh state.
+ * @param cp: the comm_point to remove from the list.
+ */
+void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m,
+ struct comm_point* cp);
 
 #endif /* SERVICES_MESH_H */
Index: services/outside_network.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/outside_network.c,v
retrieving revision 1.12
diff -u -p -r1.12 outside_network.c
--- services/outside_network.c 4 Dec 2018 12:05:07 -0000 1.12
+++ services/outside_network.c 29 Jan 2019 12:04:16 -0000
@@ -63,6 +63,9 @@
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
 #endif
+#ifdef HAVE_X509_VERIFY_PARAM_SET1_HOST
+#include <openssl/x509v3.h>
+#endif
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -385,6 +388,22 @@ outnet_tcp_take_into_use(struct waiting_
  return 0;
  }
  }
+#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
+ /* openssl 1.0.2 has this function that can be used for
+ * set1_host like verification */
+ if(w->tls_auth_name) {
+ X509_VERIFY_PARAM* param = SSL_get0_param(pend->c->ssl);
+ X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+ if(!X509_VERIFY_PARAM_set1_host(param, w->tls_auth_name, strlen(w->tls_auth_name))) {
+ log_err("X509_VERIFY_PARAM_set1_host failed");
+ pend->c->fd = s;
+ SSL_free(pend->c->ssl);
+ pend->c->ssl = NULL;
+ comm_point_close(pend->c);
+ return 0;
+ }
+ SSL_set_verify(pend->c->ssl, SSL_VERIFY_PEER, NULL);
+ }
 #endif /* HAVE_SSL_SET1_HOST */
  }
  w->pkt = NULL;
@@ -759,7 +778,7 @@ outside_network_create(struct comm_base
  outnet->delay_tv.tv_usec = (delayclose%1000)*1000;
  }
 #endif
- if(numavailports == 0) {
+ if(numavailports == 0 || num_ports == 0) {
  log_err("no outgoing ports available");
  outside_network_delete(outnet);
  return NULL;
@@ -1487,7 +1506,6 @@ serviced_delete(struct serviced_query* s
  /* clear up the pending query */
  if(sq->status == serviced_query_UDP_EDNS ||
  sq->status == serviced_query_UDP ||
- sq->status == serviced_query_PROBE_EDNS ||
  sq->status == serviced_query_UDP_EDNS_FRAG ||
  sq->status == serviced_query_UDP_EDNS_fallback) {
  struct pending* p = (struct pending*)sq->pending;
@@ -1614,15 +1632,7 @@ serviced_udp_send(struct serviced_query*
  sq->last_rtt = rtt;
  verbose(VERB_ALGO, "EDNS lookup known=%d vs=%d", edns_lame_known, vs);
  if(sq->status == serviced_initial) {
- if(edns_lame_known == 0 && rtt > 5000 && rtt < 10001) {
- /* perform EDNS lame probe - check if server is
- * EDNS lame (EDNS queries to it are dropped) */
- verbose(VERB_ALGO, "serviced query: send probe to see "
- " if use of EDNS causes timeouts");
- /* even 700 msec may be too small */
- rtt = 1000;
- sq->status = serviced_query_PROBE_EDNS;
- } else if(vs != -1) {
+ if(vs != -1) {
  sq->status = serviced_query_UDP_EDNS;
  } else {
  sq->status = serviced_query_UDP;
@@ -1959,12 +1969,6 @@ serviced_udp_callback(struct comm_point*
  sq->pending = NULL; /* removed after callback */
  if(error == NETEVENT_TIMEOUT) {
  int rto = 0;
- if(sq->status == serviced_query_PROBE_EDNS) {
- /* non-EDNS probe failed; we do not know its status,
- * keep trying with EDNS, timeout may not be caused
- * by EDNS. */
- sq->status = serviced_query_UDP_EDNS;
- }
  if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000) {
  /* fallback to 1480/1280 */
  sq->status = serviced_query_UDP_EDNS_FRAG;
@@ -2028,18 +2032,6 @@ serviced_udp_callback(struct comm_point*
  serviced_callbacks(sq, NETEVENT_CLOSED, c, rep);
  }
  return 0;
-    } else if(sq->status == serviced_query_PROBE_EDNS) {
- /* probe without EDNS succeeds, so we conclude that this
- * host likely has EDNS packets dropped */
- log_addr(VERB_DETAIL, "timeouts, concluded that connection to "
- "host drops EDNS packets", &sq->addr, sq->addrlen);
- /* only store noEDNS in cache if domain is noDNSSEC */
- if(!sq->want_dnssec)
-  if(!infra_edns_update(outnet->infra, &sq->addr, sq->addrlen,
- sq->zone, sq->zonelen, -1, (time_t)now.tv_sec)) {
- log_err("Out of memory caching no edns for host");
-  }
- sq->status = serviced_query_UDP;
     } else if(sq->status == serviced_query_UDP_EDNS &&
  !sq->edns_lame_known) {
  /* now we know that edns queries received answers store that */
@@ -2403,6 +2395,18 @@ outnet_comm_point_for_http(struct outsid
  return NULL;
  }
  }
+#elif defined(HAVE_X509_VERIFY_PARAM_SET1_HOST)
+ /* openssl 1.0.2 has this function that can be used for
+ * set1_host like verification */
+ if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) {
+ X509_VERIFY_PARAM* param = SSL_get0_param(cp->ssl);
+ X509_VERIFY_PARAM_set_hostflags(param, X509_CHECK_FLAG_NO_PARTIAL_WILDCARDS);
+ if(!X509_VERIFY_PARAM_set1_host(param, host, strlen(host))) {
+ log_err("X509_VERIFY_PARAM_set1_host failed");
+ comm_point_delete(cp);
+ return NULL;
+ }
+ }
 #endif /* HAVE_SSL_SET1_HOST */
  }
 
@@ -2508,7 +2512,6 @@ serviced_get_mem(struct serviced_query*
  s += sizeof(*sb);
  if(sq->status == serviced_query_UDP_EDNS ||
  sq->status == serviced_query_UDP ||
- sq->status == serviced_query_PROBE_EDNS ||
  sq->status == serviced_query_UDP_EDNS_FRAG ||
  sq->status == serviced_query_UDP_EDNS_fallback) {
  s += sizeof(struct pending);
Index: services/outside_network.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/outside_network.h,v
retrieving revision 1.7
diff -u -p -r1.7 outside_network.h
--- services/outside_network.h 17 Sep 2018 09:46:12 -0000 1.7
+++ services/outside_network.h 29 Jan 2019 12:04:16 -0000
@@ -359,8 +359,6 @@ struct serviced_query {
  serviced_query_TCP_EDNS,
  /** TCP without EDNS sent */
  serviced_query_TCP,
- /** probe to test EDNS lameness (EDNS is dropped) */
- serviced_query_PROBE_EDNS,
  /** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */
  serviced_query_UDP_EDNS_fallback,
  /** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */
Index: services/cache/infra.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/cache/infra.c,v
retrieving revision 1.7
diff -u -p -r1.7 infra.c
--- services/cache/infra.c 8 Oct 2018 16:03:53 -0000 1.7
+++ services/cache/infra.c 29 Jan 2019 12:04:16 -0000
@@ -808,7 +808,7 @@ static struct lruhash_entry* infra_find_
 }
 
 /** find data item in array for ip addresses */
-struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
+static struct lruhash_entry* infra_find_ip_ratedata(struct infra_cache* infra,
  struct comm_reply* repinfo, int wr)
 {
  struct ip_rate_key key;
Index: sldns/wire2str.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/sldns/wire2str.c,v
retrieving revision 1.8
diff -u -p -r1.8 wire2str.c
--- sldns/wire2str.c 29 Mar 2018 19:44:35 -0000 1.8
+++ sldns/wire2str.c 29 Jan 2019 12:04:16 -0000
@@ -1908,8 +1908,8 @@ int sldns_wire2str_edns_subnet_print(cha
  return w;
 }
 
-int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl, uint8_t* data,
- size_t len)
+static int sldns_wire2str_edns_keepalive_print(char** s, size_t* sl,
+ uint8_t* data, size_t len)
 {
  int w = 0;
  uint16_t timeout;
Index: smallapp/unbound-checkconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/smallapp/unbound-checkconf.c,v
retrieving revision 1.10
diff -u -p -r1.10 unbound-checkconf.c
--- smallapp/unbound-checkconf.c 20 Sep 2018 23:15:40 -0000 1.10
+++ smallapp/unbound-checkconf.c 29 Jan 2019 12:04:16 -0000
@@ -431,7 +431,7 @@ check_modules_exist(const char* module_c
 
 /** check configuration for errors */
 static void
-morechecks(struct config_file* cfg, const char* fname)
+morechecks(struct config_file* cfg)
 {
  warn_hosts("stub-host", cfg->stubs);
  warn_hosts("forward-host", cfg->forwards);
@@ -463,19 +463,6 @@ morechecks(struct config_file* cfg, cons
  !is_dir(cfg->chrootdir)) {
  fatal_exit("bad chroot directory");
  }
- if(cfg->chrootdir && cfg->chrootdir[0]) {
- char buf[10240];
- buf[0] = 0;
- if(fname[0] != '/') {
- if(getcwd(buf, sizeof(buf)) == NULL)
- fatal_exit("getcwd: %s", strerror(errno));
- (void)strlcat(buf, "/", sizeof(buf));
- }
- (void)strlcat(buf, fname, sizeof(buf));
- if(strncmp(buf, cfg->chrootdir, strlen(cfg->chrootdir)) != 0)
- fatal_exit("config file %s is not inside chroot %s",
- buf, cfg->chrootdir);
- }
  if(cfg->directory && cfg->directory[0]) {
  char* ad = fname_after_chroot(cfg->directory, cfg, 0);
  if(!ad) fatal_exit("out of memory");
@@ -680,7 +667,7 @@ checkconf(const char* cfgfile, const cha
  config_delete(cfg);
  return;
  }
- morechecks(cfg, cfgfile);
+ morechecks(cfg);
  check_mod(cfg, iter_get_funcblock());
  check_mod(cfg, val_get_funcblock());
 #ifdef WITH_PYTHONMODULE
Index: smallapp/unbound-control.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/smallapp/unbound-control.c,v
retrieving revision 1.13
diff -u -p -r1.13 unbound-control.c
--- smallapp/unbound-control.c 4 Dec 2018 12:05:07 -0000 1.13
+++ smallapp/unbound-control.c 29 Jan 2019 12:04:16 -0000
@@ -247,7 +247,8 @@ static void print_uptime(struct ub_shm_s
 }
 
 /** print memory usage */
-static void print_mem(struct ub_shm_stat_info* shm_stat)
+static void print_mem(struct ub_shm_stat_info* shm_stat,
+ struct ub_stats_info* s)
 {
  PR_LL("mem.cache.rrset", shm_stat->mem.rrset);
  PR_LL("mem.cache.message", shm_stat->mem.msg);
@@ -266,6 +267,7 @@ static void print_mem(struct ub_shm_stat
  PR_LL("mem.cache.dnscrypt_nonce",
  shm_stat->mem.dnscrypt_nonce);
 #endif
+ PR_LL("mem.streamwait", s->svr.mem_stream_wait);
 }
 
 /** print histogram */
@@ -328,6 +330,7 @@ static void print_extended(struct ub_sta
  PR_UL("num.query.tcp", s->svr.qtcp);
  PR_UL("num.query.tcpout", s->svr.qtcp_outgoing);
  PR_UL("num.query.tls", s->svr.qtls);
+ PR_UL("num.query.tls_resume", s->svr.qtls_resume);
  PR_UL("num.query.ipv6", s->svr.qipv6);
 
  /* flags */
@@ -399,7 +402,7 @@ static void do_stats_shm(struct config_f
  pr_stats("total", &stats[0]);
  print_uptime(shm_stat);
  if(cfg->stat_extended) {
- print_mem(shm_stat);
+ print_mem(shm_stat, &stats[0]);
  print_hist(stats);
  print_extended(stats);
  }
Index: testcode/fake_event.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/fake_event.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 fake_event.c
--- testcode/fake_event.c 20 Sep 2018 23:14:40 -0000 1.1.1.2
+++ testcode/fake_event.c 29 Jan 2019 12:04:16 -0000
@@ -385,7 +385,7 @@ answer_callback_from_entry(struct replay
  repinfo.addrlen = pend->addrlen;
  memcpy(&repinfo.addr, &pend->addr, pend->addrlen);
  if(!pend->serviced) {
- if(entry->reply_list->next &&
+ if(entry && entry->reply_list->next &&
  pend->tcp_pkt_counter < count_reply_packets(entry)) {
  /* go to next packet next time */
  pend->tcp_pkt_counter++;
@@ -509,7 +509,7 @@ fake_pending_callback(struct replay_runt
  repinfo.addrlen = p->addrlen;
  memcpy(&repinfo.addr, &p->addr, p->addrlen);
  if(!p->serviced) {
- if(todo->match->reply_list->next && !error &&
+ if(todo->match && todo->match->reply_list->next && !error &&
  p->tcp_pkt_counter < count_reply_packets(todo->match)) {
  /* go to next packet next time */
  p->tcp_pkt_counter++;
@@ -1799,6 +1799,26 @@ int outnet_tcp_connect(int ATTR_UNUSED(s
  socklen_t ATTR_UNUSED(addrlen))
 {
  log_assert(0);
+ return 0;
+}
+
+int tcp_req_info_add_meshstate(struct tcp_req_info* ATTR_UNUSED(req),
+        struct mesh_area* ATTR_UNUSED(mesh), struct mesh_state* ATTR_UNUSED(m))
+{
+ log_assert(0);
+ return 0;
+}
+
+void
+tcp_req_info_remove_mesh_state(struct tcp_req_info* ATTR_UNUSED(req),
+ struct mesh_state* ATTR_UNUSED(m))
+{
+ log_assert(0);
+}
+
+size_t
+tcp_req_info_get_stream_buffer_size(void)
+{
  return 0;
 }
 
Index: testcode/perf.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/perf.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 perf.c
--- testcode/perf.c 8 Oct 2018 16:02:24 -0000 1.1.1.2
+++ testcode/perf.c 29 Jan 2019 12:04:16 -0000
@@ -513,10 +513,12 @@ qlist_grow_capacity(struct perfinfo* inf
  uint8_t** d = (uint8_t**)calloc(sizeof(uint8_t*), newcap);
  size_t* l = (size_t*)calloc(sizeof(size_t), newcap);
  if(!d || !l) fatal_exit("out of memory");
- memcpy(d, info->qlist_data, sizeof(uint8_t*)*
- info->qlist_capacity);
- memcpy(l, info->qlist_len, sizeof(size_t)*
- info->qlist_capacity);
+ if(info->qlist_data && info->qlist_capacity)
+ memcpy(d, info->qlist_data, sizeof(uint8_t*)*
+ info->qlist_capacity);
+ if(info->qlist_len && info->qlist_capacity)
+ memcpy(l, info->qlist_len, sizeof(size_t)*
+ info->qlist_capacity);
  free(info->qlist_data);
  free(info->qlist_len);
  info->qlist_data = d;
Index: testcode/petal.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/petal.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 petal.c
--- testcode/petal.c 8 Oct 2018 16:02:24 -0000 1.1.1.2
+++ testcode/petal.c 29 Jan 2019 12:04:16 -0000
@@ -323,9 +323,9 @@ file_name_is_safe(char* s)
  return 1;
 }
 
-/** adjust host and filename */
+/** adjust host */
 static void
-adjust_host_file(char* host, char* file)
+adjust_host(char* host)
 {
  size_t i, len;
  /* remove a port number if present */
@@ -335,6 +335,13 @@ adjust_host_file(char* host, char* file)
  len = strlen(host);
  for(i=0; i<len; i++)
  host[i] = tolower((unsigned char)host[i]);
+}
+
+/** adjust filename */
+static void
+adjust_file(char* file)
+{
+ size_t i, len;
  len = strlen(file);
  for(i=0; i<len; i++)
  file[i] = tolower((unsigned char)file[i]);
@@ -534,7 +541,8 @@ service_ssl(SSL* ssl, struct sockaddr_st
  if(!read_http_headers(ssl, file, sizeof(file), host, sizeof(host),
  &vs))
  return;
- adjust_host_file(host, file);
+ if(host[0] != 0) adjust_host(host);
+ if(file[0] != 0) adjust_file(file);
  if(host[0] == 0 || !host_name_is_safe(host))
  (void)strlcpy(host, "default", sizeof(host));
  if(!file_name_is_safe(file)) {
Index: testcode/replay.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/replay.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 replay.c
--- testcode/replay.c 8 Oct 2018 16:02:25 -0000 1.1.1.2
+++ testcode/replay.c 29 Jan 2019 12:04:16 -0000
@@ -715,6 +715,7 @@ perform_arith(double x, char op, double
  *res = x*y;
  break;
  default:
+ *res = 0;
  return 0;
  }
 
Index: testcode/streamtcp.1
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/streamtcp.1,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 streamtcp.1
--- testcode/streamtcp.1 20 Sep 2018 23:14:39 -0000 1.1.1.2
+++ testcode/streamtcp.1 29 Jan 2019 12:04:16 -0000
@@ -44,6 +44,11 @@ Use UDP instead of TCP. No retries are a
 .B \-n
 Do not wait for the answer.
 .TP
+.B \-a
+Print answers on arrival.  This mean queries are sent in sequence without
+waiting for answer but if answers arrive in this time they are printed out.
+After sending queries the program waits and prints the remainder.
+.TP
 .B \-s
 Use SSL.
 .TP
Index: testcode/streamtcp.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/streamtcp.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 streamtcp.c
--- testcode/streamtcp.c 20 Sep 2018 23:14:39 -0000 1.1.1.2
+++ testcode/streamtcp.c 29 Jan 2019 12:04:16 -0000
@@ -73,6 +73,7 @@ static void usage(char* argv[])
  printf("-f server what ipaddr@portnr to send the queries to\n");
  printf("-u use UDP. No retries are attempted.\n");
  printf("-n do not wait for an answer.\n");
+ printf("-a print answers as they arrive.\n");
  printf("-d secs delay after connection before sending query\n");
  printf("-s use ssl\n");
  printf("-h this help text\n");
@@ -203,13 +204,22 @@ recv_one(int fd, int udp, SSL* ssl, sldn
  uint16_t len;
  if(!udp) {
  if(ssl) {
- if(SSL_read(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
+ int sr = SSL_read(ssl, (void*)&len, (int)sizeof(len));
+ if(sr == 0) {
+ printf("ssl: stream closed\n");
+ exit(1);
+ }
+ if(sr < 0) {
  log_crypto_err("could not SSL_read");
  exit(1);
  }
  } else {
- if(recv(fd, (void*)&len, sizeof(len), 0) <
- (ssize_t)sizeof(len)) {
+ ssize_t r = recv(fd, (void*)&len, sizeof(len), 0);
+ if(r == 0) {
+ printf("recv: stream closed\n");
+ exit(1);
+ }
+ if(r < (ssize_t)sizeof(len)) {
 #ifndef USE_WINSOCK
  perror("read() len failed");
 #else
@@ -267,6 +277,37 @@ recv_one(int fd, int udp, SSL* ssl, sldn
  free(pktstr);
 }
 
+/** see if we can receive any results */
+static void
+print_any_answers(int fd, int udp, SSL* ssl, sldns_buffer* buf,
+ int* num_answers, int wait_all)
+{
+ /* see if the fd can read, if so, print one answer, repeat */
+ int ret;
+ struct timeval tv, *waittv;
+ fd_set rfd;
+ while(*num_answers > 0) {
+ memset(&rfd, 0, sizeof(rfd));
+ memset(&tv, 0, sizeof(tv));
+ FD_ZERO(&rfd);
+ FD_SET(fd, &rfd);
+ if(wait_all) waittv = NULL;
+ else waittv = &tv;
+ ret = select(fd+1, &rfd, NULL, NULL, waittv);
+ if(ret < 0) {
+ if(errno == EINTR || errno == EAGAIN) continue;
+ perror("select() failed");
+ exit(1);
+ }
+ if(ret == 0) {
+ if(wait_all) continue;
+ return;
+ }
+ (*num_answers) -= 1;
+ recv_one(fd, udp, ssl, buf);
+ }
+}
+
 static int get_random(void)
 {
  int r;
@@ -278,12 +319,12 @@ static int get_random(void)
 
 /** send the TCP queries and print answers */
 static void
-send_em(const char* svr, int udp, int usessl, int noanswer, int delay,
- int num, char** qs)
+send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
+ int delay, int num, char** qs)
 {
  sldns_buffer* buf = sldns_buffer_new(65553);
  int fd = open_svr(svr, udp);
- int i;
+ int i, wait_results = 0;
  SSL_CTX* ctx = NULL;
  SSL* ssl = NULL;
  if(!buf) fatal_exit("out of memory");
@@ -325,9 +366,15 @@ send_em(const char* svr, int udp, int us
  write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
  qs[i+1], qs[i+2]);
  /* print at least one result */
- if(!noanswer)
+ if(onarrival) {
+ wait_results += 1; /* one more answer to fetch */
+ print_any_answers(fd, udp, ssl, buf, &wait_results, 0);
+ } else if(!noanswer) {
  recv_one(fd, udp, ssl, buf);
+ }
  }
+ if(onarrival)
+ print_any_answers(fd, udp, ssl, buf, &wait_results, 1);
 
  if(usessl) {
  SSL_shutdown(ssl);
@@ -368,6 +415,7 @@ int main(int argc, char** argv)
  const char* svr = "127.0.0.1";
  int udp = 0;
  int noanswer = 0;
+ int onarrival = 0;
  int usessl = 0;
  int delay = 0;
 
@@ -394,11 +442,14 @@ int main(int argc, char** argv)
  if(argc == 1) {
  usage(argv);
  }
- while( (c=getopt(argc, argv, "f:hnsud:")) != -1) {
+ while( (c=getopt(argc, argv, "af:hnsud:")) != -1) {
  switch(c) {
  case 'f':
  svr = optarg;
  break;
+ case 'a':
+ onarrival = 1;
+ break;
  case 'n':
  noanswer = 1;
  break;
@@ -446,7 +497,7 @@ int main(int argc, char** argv)
  (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
 #endif
  }
- send_em(svr, udp, usessl, noanswer, delay, argc, argv);
+ send_em(svr, udp, usessl, noanswer, onarrival, delay, argc, argv);
  checklock_stop();
 #ifdef USE_WINSOCK
  WSACleanup();
Index: testcode/testbound.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/testbound.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 testbound.c
--- testcode/testbound.c 8 Oct 2018 16:02:25 -0000 1.1.1.2
+++ testcode/testbound.c 29 Jan 2019 12:04:16 -0000
@@ -344,6 +344,7 @@ main(int argc, char* argv[])
 
  /* we do not want the test to depend on the timezone */
  (void)putenv("TZ=UTC");
+ memset(pass_argv, 0, sizeof(pass_argv));
 
  log_init(NULL, 0, NULL);
  /* determine commandline options for the daemon */
Index: testcode/testpkts.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/testcode/testpkts.c,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 testpkts.c
--- testcode/testpkts.c 4 Dec 2018 12:04:14 -0000 1.1.1.3
+++ testcode/testpkts.c 29 Jan 2019 12:04:16 -0000
@@ -513,7 +513,8 @@ add_edns(uint8_t* pktbuf, size_t pktsize
  if(*pktlen + sizeof(edns) + ednslen > pktsize)
  error("not enough space for EDNS OPT record");
  memmove(pktbuf+*pktlen, edns, sizeof(edns));
- memmove(pktbuf+*pktlen+sizeof(edns), ednsdata, ednslen);
+ if(ednsdata && ednslen)
+ memmove(pktbuf+*pktlen+sizeof(edns), ednsdata, ednslen);
  sldns_write_uint16(pktbuf+10, LDNS_ARCOUNT(pktbuf)+1);
  *pktlen += (sizeof(edns) + ednslen);
 }
Index: util/config_file.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/config_file.c,v
retrieving revision 1.19
diff -u -p -r1.19 config_file.c
--- util/config_file.c 4 Dec 2018 12:05:07 -0000 1.19
+++ util/config_file.c 29 Jan 2019 12:04:16 -0000
@@ -76,6 +76,8 @@ uid_t cfg_uid = (uid_t)-1;
 gid_t cfg_gid = (gid_t)-1;
 /** for debug allow small timeout values for fast rollovers */
 int autr_permit_small_holddown = 0;
+/** size (in bytes) of stream wait buffers max */
+size_t stream_wait_max = 4 * 1024 * 1024;
 
 /** global config during parsing */
 struct config_parser_state* cfg_parser = 0;
@@ -119,6 +121,7 @@ config_create(void)
  cfg->log_time_ascii = 0;
  cfg->log_queries = 0;
  cfg->log_replies = 0;
+ cfg->log_tag_queryreply = 0;
  cfg->log_local_actions = 0;
  cfg->log_servfail = 0;
 #ifndef USE_WINSOCK
@@ -139,6 +142,7 @@ config_create(void)
  cfg->outgoing_num_tcp = 2; /* leaves 64-52=12 for: 4if,1stop,thread4 */
  cfg->incoming_num_tcp = 2;
 #endif
+ cfg->stream_wait_size = 4 * 1024 * 1024;
  cfg->edns_buffer_size = 4096; /* 4k from rfc recommendation */
  cfg->msg_buffer_size = 65552; /* 64 k + a small margin */
  cfg->msg_cache_size = 4 * 1024 * 1024;
@@ -483,6 +487,9 @@ int config_set_option(struct config_file
  else S_STRLIST("additional-tls-port:", tls_additional_port)
  else S_STRLIST("tls-additional-ports:", tls_additional_port)
  else S_STRLIST("tls-additional-port:", tls_additional_port)
+ else S_STRLIST_APPEND("tls-session-ticket-keys:", tls_session_ticket_keys)
+ else S_STR("tls-ciphers:", tls_ciphers)
+ else S_STR("tls-ciphersuites:", tls_ciphersuites)
  else S_YNO("interface-automatic:", if_automatic)
  else S_YNO("use-systemd:", use_systemd)
  else S_YNO("do-daemonize:", do_daemonize)
@@ -490,6 +497,7 @@ int config_set_option(struct config_file
  else S_NUMBER_NONZERO("outgoing-range:", outgoing_num_ports)
  else S_SIZET_OR_ZERO("outgoing-num-tcp:", outgoing_num_tcp)
  else S_SIZET_OR_ZERO("incoming-num-tcp:", incoming_num_tcp)
+ else S_MEMSIZE("stream-wait-size:", stream_wait_size)
  else S_SIZET_NONZERO("edns-buffer-size:", edns_buffer_size)
  else S_SIZET_NONZERO("msg-buffer-size:", msg_buffer_size)
  else S_MEMSIZE("msg-cache-size:", msg_cache_size)
@@ -560,6 +568,7 @@ int config_set_option(struct config_file
  else S_YNO("val-log-squelch:", val_log_squelch)
  else S_YNO("log-queries:", log_queries)
  else S_YNO("log-replies:", log_replies)
+ else S_YNO("log-tag-queryreply:", log_tag_queryreply)
  else S_YNO("log-local-actions:", log_local_actions)
  else S_YNO("log-servfail:", log_servfail)
  else S_YNO("val-permissive-mode:", val_permissive_mode)
@@ -875,6 +884,7 @@ config_get_option(struct config_file* cf
  else O_DEC(opt, "outgoing-range", outgoing_num_ports)
  else O_DEC(opt, "outgoing-num-tcp", outgoing_num_tcp)
  else O_DEC(opt, "incoming-num-tcp", incoming_num_tcp)
+ else O_MEM(opt, "stream-wait-size", stream_wait_size)
  else O_DEC(opt, "edns-buffer-size", edns_buffer_size)
  else O_DEC(opt, "msg-buffer-size", msg_buffer_size)
  else O_MEM(opt, "msg-cache-size", msg_cache_size)
@@ -917,6 +927,9 @@ config_get_option(struct config_file* cf
  else O_STR(opt, "tls-cert-bundle", tls_cert_bundle)
  else O_YNO(opt, "tls-win-cert", tls_win_cert)
  else O_LST(opt, "tls-additional-port", tls_additional_port)
+ else O_LST(opt, "tls-session-ticket-keys", tls_session_ticket_keys.first)
+ else O_STR(opt, "tls-ciphers", tls_ciphers)
+ else O_STR(opt, "tls-ciphersuites", tls_ciphersuites)
  else O_YNO(opt, "use-systemd", use_systemd)
  else O_YNO(opt, "do-daemonize", do_daemonize)
  else O_STR(opt, "chroot", chrootdir)
@@ -925,6 +938,7 @@ config_get_option(struct config_file* cf
  else O_STR(opt, "logfile", logfile)
  else O_YNO(opt, "log-queries", log_queries)
  else O_YNO(opt, "log-replies", log_replies)
+ else O_YNO(opt, "log-tag-queryreply", log_tag_queryreply)
  else O_YNO(opt, "log-local-actions", log_local_actions)
  else O_YNO(opt, "log-servfail", log_servfail)
  else O_STR(opt, "pidfile", pidfile)
@@ -1350,6 +1364,9 @@ config_delete(struct config_file* cfg)
  free(cfg->ssl_service_pem);
  free(cfg->tls_cert_bundle);
  config_delstrlist(cfg->tls_additional_port);
+ config_delstrlist(cfg->tls_session_ticket_keys.first);
+ free(cfg->tls_ciphers);
+ free(cfg->tls_ciphersuites);
  free(cfg->log_identity);
  config_del_strarray(cfg->ifs, cfg->num_ifs);
  config_del_strarray(cfg->out_ifs, cfg->num_out_ifs);
@@ -1903,9 +1920,11 @@ config_apply(struct config_file* config)
  EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size;
  MINIMAL_RESPONSES = config->minimal_responses;
  RRSET_ROUNDROBIN = config->rrset_roundrobin;
+ LOG_TAG_QUERYREPLY = config->log_tag_queryreply;
  UNKNOWN_SERVER_NICENESS = config->unknown_server_time_limit;
  log_set_time_asc(config->log_time_ascii);
  autr_permit_small_holddown = config->permit_small_holddown;
+ stream_wait_max = config->stream_wait_size;
 }
 
 void config_lookup_uid(struct config_file* cfg)
Index: util/config_file.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/config_file.h,v
retrieving revision 1.17
diff -u -p -r1.17 config_file.h
--- util/config_file.h 4 Dec 2018 12:05:07 -0000 1.17
+++ util/config_file.h 29 Jan 2019 12:04:16 -0000
@@ -120,6 +120,12 @@ struct config_file {
  int tls_win_cert;
  /** additional tls ports */
  struct config_strlist* tls_additional_port;
+ /** secret key used to encrypt and decrypt TLS session ticket */
+ struct config_strlist_head tls_session_ticket_keys;
+ /** TLS ciphers */
+ char* tls_ciphers;
+ /** TLS chiphersuites (TLSv1.3) */
+ char* tls_ciphersuites;
 
  /** outgoing port range number of ports (per thread) */
  int outgoing_num_ports;
@@ -132,6 +138,8 @@ struct config_file {
 
  /** EDNS buffer size to use */
  size_t edns_buffer_size;
+ /** size of the stream wait buffers, max */
+ size_t stream_wait_size;
  /** number of bytes buffer size for DNS messages */
  size_t msg_buffer_size;
  /** size of the message cache */
@@ -286,6 +294,8 @@ struct config_file {
  int log_queries;
  /** log replies with one line per reply */
  int log_replies;
+ /** tag log_queries and log_replies for filtering */
+ int log_tag_queryreply;
  /** log every local-zone hit **/
  int log_local_actions;
  /** log servfails with a reason */
@@ -573,6 +583,8 @@ extern uid_t cfg_uid;
 extern gid_t cfg_gid;
 /** debug and enable small timeouts */
 extern int autr_permit_small_holddown;
+/** size (in bytes) of stream wait buffers max */
+extern size_t stream_wait_max;
 
 /**
  * Stub config options
Index: util/configlexer.lex
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/configlexer.lex,v
retrieving revision 1.13
diff -u -p -r1.13 configlexer.lex
--- util/configlexer.lex 4 Dec 2018 12:05:07 -0000 1.13
+++ util/configlexer.lex 29 Jan 2019 12:04:16 -0000
@@ -245,6 +245,9 @@ additional-ssl-port{COLON} { YDVAR(1, VA
 additional-tls-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
 tls-additional-ports{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
 tls-additional-port{COLON} { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) }
+tls-session-ticket-keys{COLON} { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) }
+tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) }
+tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) }
 use-systemd{COLON} { YDVAR(1, VAR_USE_SYSTEMD) }
 do-daemonize{COLON} { YDVAR(1, VAR_DO_DAEMONIZE) }
 interface{COLON} { YDVAR(1, VAR_INTERFACE) }
@@ -262,6 +265,7 @@ directory{COLON} { YDVAR(1, VAR_DIRECTO
 logfile{COLON} { YDVAR(1, VAR_LOGFILE) }
 pidfile{COLON} { YDVAR(1, VAR_PIDFILE) }
 root-hints{COLON} { YDVAR(1, VAR_ROOT_HINTS) }
+stream-wait-size{COLON} { YDVAR(1, VAR_STREAM_WAIT_SIZE) }
 edns-buffer-size{COLON} { YDVAR(1, VAR_EDNS_BUFFER_SIZE) }
 msg-buffer-size{COLON} { YDVAR(1, VAR_MSG_BUFFER_SIZE) }
 msg-cache-size{COLON} { YDVAR(1, VAR_MSG_CACHE_SIZE) }
@@ -377,6 +381,7 @@ log-identity{COLON} { YDVAR(1, VAR_LOG_
 log-time-ascii{COLON} { YDVAR(1, VAR_LOG_TIME_ASCII) }
 log-queries{COLON} { YDVAR(1, VAR_LOG_QUERIES) }
 log-replies{COLON} { YDVAR(1, VAR_LOG_REPLIES) }
+log-tag-queryreply{COLON} { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) }
 log-local-actions{COLON}       { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) }
 log-servfail{COLON} { YDVAR(1, VAR_LOG_SERVFAIL) }
 local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) }
Index: util/configparser.y
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/configparser.y,v
retrieving revision 1.13
diff -u -p -r1.13 configparser.y
--- util/configparser.y 4 Dec 2018 12:05:07 -0000 1.13
+++ util/configparser.y 29 Jan 2019 12:04:16 -0000
@@ -164,7 +164,9 @@ extern struct config_parser_state* cfg_p
 %token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
 %token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
 %token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
-%token VAR_UNKNOWN_SERVER_TIME_LIMIT
+%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
+%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES
+%token VAR_TLS_SESSION_TICKET_KEYS
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -263,7 +265,9 @@ content_server: server_num_threads | ser
  server_tls_cert_bundle | server_tls_additional_port | server_low_rtt |
  server_fast_server_permil | server_fast_server_num  | server_tls_win_cert |
  server_tcp_connection_limit | server_log_servfail | server_deny_any |
- server_unknown_server_time_limit
+ server_unknown_server_time_limit | server_log_tag_queryreply |
+ server_stream_wait_size | server_tls_ciphers |
+ server_tls_ciphersuites | server_tls_session_ticket_keys
  ;
 stubstart: VAR_STUB_ZONE
  {
@@ -818,6 +822,28 @@ server_tls_additional_port: VAR_TLS_ADDI
  yyerror("out of memory");
  }
  ;
+server_tls_ciphers: VAR_TLS_CIPHERS STRING_ARG
+ {
+ OUTYY(("P(server_tls_ciphers:%s)\n", $2));
+ free(cfg_parser->cfg->tls_ciphers);
+ cfg_parser->cfg->tls_ciphers = $2;
+ }
+ ;
+server_tls_ciphersuites: VAR_TLS_CIPHERSUITES STRING_ARG
+ {
+ OUTYY(("P(server_tls_ciphersuites:%s)\n", $2));
+ free(cfg_parser->cfg->tls_ciphersuites);
+ cfg_parser->cfg->tls_ciphersuites = $2;
+ }
+ ;
+server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG
+ {
+ OUTYY(("P(server_tls_session_ticket_keys:%s)\n", $2));
+ if(!cfg_strlist_append(&cfg_parser->cfg->tls_session_ticket_keys,
+ $2))
+ yyerror("out of memory");
+ }
+ ;
 server_use_systemd: VAR_USE_SYSTEMD STRING_ARG
  {
  OUTYY(("P(server_use_systemd:%s)\n", $2));
@@ -877,6 +903,15 @@ server_log_replies: VAR_LOG_REPLIES STRI
    free($2);
   }
   ;
+server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG
+  {
+   OUTYY(("P(server_log_tag_queryreply:%s)\n", $2));
+   if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+   yyerror("expected yes or no.");
+   else cfg_parser->cfg->log_tag_queryreply = (strcmp($2, "yes")==0);
+   free($2);
+  }
+  ;
 server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG
  {
  OUTYY(("P(server_log_servfail:%s)\n", $2));
@@ -1118,6 +1153,14 @@ server_ip_freebind: VAR_IP_FREEBIND STRI
         free($2);
     }
     ;
+server_stream_wait_size: VAR_STREAM_WAIT_SIZE STRING_ARG
+ {
+ OUTYY(("P(server_stream_wait_size:%s)\n", $2));
+ if(!cfg_parse_memsize($2, &cfg_parser->cfg->stream_wait_size))
+ yyerror("memory size expected");
+ free($2);
+ }
+ ;
 server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG
  {
  OUTYY(("P(server_edns_buffer_size:%s)\n", $2));
@@ -1460,6 +1503,8 @@ server_access_control: VAR_ACCESS_CONTRO
  yyerror("expected deny, refuse, deny_non_local, "
  "refuse_non_local, allow, allow_setrd or "
  "allow_snoop in access control action");
+ free($2);
+ free($3);
  } else {
  if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3))
  fatal_exit("out of memory adding acl");
@@ -1738,13 +1783,15 @@ server_local_zone: VAR_LOCAL_ZONE STRING
    && 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) {
  yyerror("local-zone type: expected static, deny, "
  "refuse, redirect, transparent, "
  "typetransparent, inform, inform_deny, "
  "always_transparent, always_refuse, "
  "always_nxdomain, noview or nodefault");
- else if(strcmp($3, "nodefault")==0) {
+ free($2);
+ free($3);
+ } else if(strcmp($3, "nodefault")==0) {
  if(!cfg_strlist_insert(&cfg_parser->cfg->
  local_zones_nodefault, $2))
  fatal_exit("out of memory adding local-zone");
@@ -1857,8 +1904,10 @@ server_local_zone_tag: VAR_LOCAL_ZONE_TA
  &len);
  free($3);
  OUTYY(("P(server_local_zone_tag:%s)\n", $2));
- if(!bitlist)
+ if(!bitlist) {
  yyerror("could not parse tags, (define-tag them first)");
+ free($2);
+ }
  if(bitlist) {
  if(!cfg_strbytelist_insert(
  &cfg_parser->cfg->local_zone_tags,
@@ -1876,8 +1925,10 @@ server_access_control_tag: VAR_ACCESS_CO
  &len);
  free($3);
  OUTYY(("P(server_access_control_tag:%s)\n", $2));
- if(!bitlist)
+ if(!bitlist) {
  yyerror("could not parse tags, (define-tag them first)");
+ free($2);
+ }
  if(bitlist) {
  if(!cfg_strbytelist_insert(
  &cfg_parser->cfg->acl_tags,
@@ -1930,8 +1981,6 @@ server_access_control_view: VAR_ACCESS_C
  if(!cfg_str2list_insert(&cfg_parser->cfg->acl_view,
  $2, $3)) {
  yyerror("out of memory");
- free($2);
- free($3);
  }
  }
  ;
@@ -1942,8 +1991,10 @@ server_response_ip_tag: VAR_RESPONSE_IP_
  &len);
  free($3);
  OUTYY(("P(response_ip_tag:%s)\n", $2));
- if(!bitlist)
+ if(!bitlist) {
  yyerror("could not parse tags, (define-tag them first)");
+ free($2);
+ }
  if(bitlist) {
  if(!cfg_strbytelist_insert(
  &cfg_parser->cfg->respip_tags,
@@ -2020,6 +2071,8 @@ server_ratelimit_for_domain: VAR_RATELIM
  OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", $2, $3));
  if(atoi($3) == 0 && strcmp($3, "0") != 0) {
  yyerror("number expected");
+ free($2);
+ free($3);
  } else {
  if(!cfg_str2list_insert(&cfg_parser->cfg->
  ratelimit_for_domain, $2, $3))
@@ -2033,6 +2086,8 @@ server_ratelimit_below_domain: VAR_RATEL
  OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", $2, $3));
  if(atoi($3) == 0 && strcmp($3, "0") != 0) {
  yyerror("number expected");
+ free($2);
+ free($3);
  } else {
  if(!cfg_str2list_insert(&cfg_parser->cfg->
  ratelimit_below_domain, $2, $3))
@@ -2110,10 +2165,10 @@ server_ipsecmod_enabled: VAR_IPSECMOD_EN
  if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
  yyerror("expected yes or no.");
  else cfg_parser->cfg->ipsecmod_enabled = (strcmp($2, "yes")==0);
- free($2);
  #else
  OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
  #endif
+ free($2);
  }
  ;
 server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG
@@ -2123,10 +2178,10 @@ server_ipsecmod_ignore_bogus: VAR_IPSECM
  if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
  yyerror("expected yes or no.");
  else cfg_parser->cfg->ipsecmod_ignore_bogus = (strcmp($2, "yes")==0);
- free($2);
  #else
  OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
  #endif
+ free($2);
  }
  ;
 server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG
@@ -2137,6 +2192,7 @@ server_ipsecmod_hook: VAR_IPSECMOD_HOOK
  cfg_parser->cfg->ipsecmod_hook = $2;
  #else
  OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
  #endif
  }
  ;
@@ -2150,6 +2206,7 @@ server_ipsecmod_max_ttl: VAR_IPSECMOD_MA
  free($2);
  #else
  OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
  #endif
  }
  ;
@@ -2161,6 +2218,7 @@ server_ipsecmod_whitelist: VAR_IPSECMOD_
  yyerror("out of memory");
  #else
  OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
  #endif
  }
  ;
@@ -2174,6 +2232,7 @@ server_ipsecmod_strict: VAR_IPSECMOD_STR
  free($2);
  #else
  OUTYY(("P(Compiled without IPsec module, ignoring)\n"));
+ free($2);
  #endif
  }
  ;
@@ -2381,13 +2440,15 @@ view_local_zone: VAR_LOCAL_ZONE STRING_A
    && 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) {
  yyerror("local-zone type: expected static, deny, "
  "refuse, redirect, transparent, "
  "typetransparent, inform, inform_deny, "
  "always_transparent, always_refuse, "
  "always_nxdomain, noview or nodefault");
- else if(strcmp($3, "nodefault")==0) {
+ free($2);
+ free($3);
+ } else if(strcmp($3, "nodefault")==0) {
  if(!cfg_strlist_insert(&cfg_parser->cfg->views->
  local_zones_nodefault, $2))
  fatal_exit("out of memory adding local-zone");
@@ -2423,7 +2484,6 @@ view_local_data: VAR_LOCAL_DATA STRING_A
  OUTYY(("P(view_local_data:%s)\n", $2));
  if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, $2)) {
  fatal_exit("out of memory adding local-data");
- free($2);
  }
  }
  ;
@@ -2546,6 +2606,7 @@ dt_dnstap_enable: VAR_DNSTAP_ENABLE STRI
  if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap = (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG
@@ -2561,6 +2622,7 @@ dt_dnstap_send_identity: VAR_DNSTAP_SEND
  if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_send_identity = (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG
@@ -2569,6 +2631,7 @@ dt_dnstap_send_version: VAR_DNSTAP_SEND_
  if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_send_version = (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG
@@ -2592,6 +2655,7 @@ dt_dnstap_log_resolver_query_messages: V
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_log_resolver_query_messages =
  (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG
@@ -2601,6 +2665,7 @@ dt_dnstap_log_resolver_response_messages
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_log_resolver_response_messages =
  (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG
@@ -2610,6 +2675,7 @@ dt_dnstap_log_client_query_messages: VAR
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_log_client_query_messages =
  (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG
@@ -2619,6 +2685,7 @@ dt_dnstap_log_client_response_messages:
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_log_client_response_messages =
  (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG
@@ -2628,6 +2695,7 @@ dt_dnstap_log_forwarder_query_messages:
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_log_forwarder_query_messages =
  (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG
@@ -2637,6 +2705,7 @@ dt_dnstap_log_forwarder_response_message
  yyerror("expected yes or no.");
  else cfg_parser->cfg->dnstap_log_forwarder_response_messages =
  (strcmp($2, "yes")==0);
+ free($2);
  }
  ;
 pythonstart: VAR_PYTHON
@@ -2683,15 +2752,14 @@ server_response_ip: VAR_RESPONSE_IP STRI
 server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG
  {
  OUTYY(("P(server_response_ip_data:%s)\n", $2));
- if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
- $2, $3))
- fatal_exit("out of memory adding response-ip-data");
+ if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data,
+ $2, $3))
+ fatal_exit("out of memory adding response-ip-data");
  }
  ;
 dnscstart: VAR_DNSCRYPT
  {
  OUTYY(("\nP(dnscrypt:)\n"));
- OUTYY(("\nP(dnscrypt:)\n"));
  }
  ;
 contents_dnsc: contents_dnsc content_dnsc
@@ -2718,7 +2786,6 @@ dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABL
 dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG
  {
  OUTYY(("P(dnsc_dnscrypt_port:%s)\n", $2));
-
  if(atoi($2) == 0)
  yyerror("port number expected");
  else cfg_parser->cfg->dnscrypt_port = atoi($2);
@@ -2820,6 +2887,7 @@ cachedb_backend_name: VAR_CACHEDB_BACKEN
  cfg_parser->cfg->cachedb_backend = $2;
  #else
  OUTYY(("P(Compiled without cachedb, ignoring)\n"));
+ free($2);
  #endif
  }
  ;
Index: util/edns.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/edns.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 edns.c
--- util/edns.c 20 Sep 2018 23:14:40 -0000 1.1.1.1
+++ util/edns.c 29 Jan 2019 12:04:16 -0000
@@ -40,7 +40,7 @@
  */
 
 #include "config.h"
-
+#include "util/edns.h"
 #include "util/config_file.h"
 #include "util/netevent.h"
 #include "util/regional.h"
Index: util/log.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/log.c,v
retrieving revision 1.5
diff -u -p -r1.5 log.c
--- util/log.c 4 Dec 2018 12:05:07 -0000 1.5
+++ util/log.c 29 Jan 2019 12:04:16 -0000
@@ -382,6 +382,24 @@ log_hex(const char* msg, void* data, siz
  log_hex_f(verbosity, msg, data, length);
 }
 
+void
+log_query(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ log_vmsg(LOG_INFO, "query", format, args);
+ va_end(args);
+}
+
+void
+log_reply(const char *format, ...)
+{
+ va_list args;
+ va_start(args, format);
+ log_vmsg(LOG_INFO, "reply", format, args);
+ va_end(args);
+}
+
 void log_buf(enum verbosity_value level, const char* msg, sldns_buffer* buf)
 {
  if(verbosity < level)
Index: util/log.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/log.h,v
retrieving revision 1.4
diff -u -p -r1.4 log.h
--- util/log.h 4 Dec 2018 12:05:07 -0000 1.4
+++ util/log.h 29 Jan 2019 12:04:16 -0000
@@ -154,6 +154,20 @@ void log_warn(const char* format, ...) A
 void log_hex(const char* msg, void* data, size_t length);
 
 /**
+ * Log query.
+ * Pass printf formatted arguments. No trailing newline is needed.
+ * @param format: printf-style format string. Arguments follow.
+ */
+void log_query(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
+
+/**
+ * Log reply.
+ * Pass printf formatted arguments. No trailing newline is needed.
+ * @param format: printf-style format string. Arguments follow.
+ */
+void log_reply(const char* format, ...) ATTR_FORMAT(printf, 1, 2);
+
+/**
  * Easy alternative for log_hex, takes a sldns_buffer.
  * @param level: verbosity level for this message, compared to global
  * verbosity setting.
Index: util/mini_event.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/mini_event.c,v
retrieving revision 1.3
diff -u -p -r1.3 mini_event.c
--- util/mini_event.c 17 Feb 2017 18:53:32 -0000 1.3
+++ util/mini_event.c 29 Jan 2019 12:04:16 -0000
@@ -41,6 +41,7 @@
  */
 
 #include "config.h"
+#include "util/mini_event.h"
 #ifdef HAVE_TIME_H
 #include <time.h>
 #endif
@@ -48,7 +49,6 @@
 
 #if defined(USE_MINI_EVENT) && !defined(USE_WINSOCK)
 #include <signal.h>
-#include "util/mini_event.h"
 #include "util/fptr_wlist.h"
 
 /** compare events in tree, based on timevalue, ptr for uniqueness */
Index: util/net_help.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/net_help.c,v
retrieving revision 1.13
diff -u -p -r1.13 net_help.c
--- util/net_help.c 20 Sep 2018 23:15:40 -0000 1.13
+++ util/net_help.c 29 Jan 2019 12:04:16 -0000
@@ -43,11 +43,14 @@
 #include "util/data/dname.h"
 #include "util/module.h"
 #include "util/regional.h"
+#include "util/config_file.h"
 #include "sldns/parseutil.h"
 #include "sldns/wire2str.h"
 #include <fcntl.h>
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
 #endif
 #ifdef HAVE_OPENSSL_ERR_H
 #include <openssl/err.h>
@@ -67,6 +70,15 @@ int MINIMAL_RESPONSES = 0;
 /** rrset order roundrobin: default is no */
 int RRSET_ROUNDROBIN = 0;
 
+/** log tag queries with name instead of 'info' for filtering */
+int LOG_TAG_QUERYREPLY = 0;
+
+static struct tls_session_ticket_key {
+ unsigned char *key_name;
+ unsigned char *aes_key;
+ unsigned char *hmac_key;
+} *ticket_keys;
+
 /* returns true is string addr is an ip6 specced address */
 int
 str_is_ip6(const char* str)
@@ -361,6 +373,37 @@ log_nametypeclass(enum verbosity_value v
  log_info("%s %s %s %s", str, buf, ts, cs);
 }
 
+void
+log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass)
+{
+ char buf[LDNS_MAX_DOMAINLEN+1];
+ char t[12], c[12];
+ const char *ts, *cs;
+ dname_str(name, buf);
+ if(type == LDNS_RR_TYPE_TSIG) ts = "TSIG";
+ else if(type == LDNS_RR_TYPE_IXFR) ts = "IXFR";
+ else if(type == LDNS_RR_TYPE_AXFR) ts = "AXFR";
+ else if(type == LDNS_RR_TYPE_MAILB) ts = "MAILB";
+ else if(type == LDNS_RR_TYPE_MAILA) ts = "MAILA";
+ else if(type == LDNS_RR_TYPE_ANY) ts = "ANY";
+ else if(sldns_rr_descript(type) && sldns_rr_descript(type)->_name)
+ ts = sldns_rr_descript(type)->_name;
+ else {
+ snprintf(t, sizeof(t), "TYPE%d", (int)type);
+ ts = t;
+ }
+ if(sldns_lookup_by_id(sldns_rr_classes, (int)dclass) &&
+ sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name)
+ cs = sldns_lookup_by_id(sldns_rr_classes, (int)dclass)->name;
+ else {
+ snprintf(c, sizeof(c), "CLASS%d", (int)dclass);
+ cs = c;
+ }
+ if(LOG_TAG_QUERYREPLY)
+ log_query("%s %s %s %s", str, buf, ts, cs);
+ else log_info("%s %s %s %s", str, buf, ts, cs);
+}
+
 void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone,
  struct sockaddr_storage* addr, socklen_t addrlen)
 {
@@ -1056,3 +1099,128 @@ void ub_openssl_lock_delete(void)
 #endif /* OPENSSL_THREADS */
 }
 
+int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys) {
+#ifdef HAVE_SSL
+ size_t s = 1;
+ struct config_strlist* p;
+ struct tls_session_ticket_key *keys;
+ for(p = tls_session_ticket_keys; p; p = p->next) {
+ s++;
+ }
+ keys = calloc(s, sizeof(struct tls_session_ticket_key));
+ memset(keys, 0, s*sizeof(*keys));
+ ticket_keys = keys;
+
+ for(p = tls_session_ticket_keys; p; p = p->next) {
+ size_t n;
+ unsigned char *data = (unsigned char *)malloc(80);
+ FILE *f = fopen(p->str, "r");
+ if(!f) {
+ log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno));
+ free(data);
+ return 0;
+ }
+ n = fread(data, 1, 80, f);
+ fclose(f);
+
+ if(n != 80) {
+ log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", p->str, (int)n);
+ free(data);
+ return 0;
+ }
+ verbose(VERB_OPS, "read tls-session-ticket-key: %s", p->str);
+
+ keys->key_name = data;
+ keys->aes_key = data + 16;
+ keys->hmac_key = data + 48;
+ keys++;
+ }
+ /* terminate array with NULL key name entry */
+ keys->key_name = NULL;
+ if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) {
+ log_err("no support for TLS session ticket");
+ return 0;
+ }
+ return 1;
+#else
+ (void)sslctx;
+ (void)tls_session_ticket_keys;
+ return 0;
+#endif
+
+}
+
+int tls_session_ticket_key_cb(void *ATTR_UNUSED(sslctx), unsigned char* key_name, unsigned char* iv, void *evp_sctx, void *hmac_ctx, int enc)
+{
+#ifdef HAVE_SSL
+ const EVP_MD *digest;
+ const EVP_CIPHER *cipher;
+ int evp_cipher_length;
+ digest = EVP_sha256();
+ cipher = EVP_aes_256_cbc();
+ evp_cipher_length = EVP_CIPHER_iv_length(cipher);
+ if( enc == 1 ) {
+ /* encrypt */
+ verbose(VERB_CLIENT, "start session encrypt");
+ memcpy(key_name, ticket_keys->key_name, 16);
+ if (RAND_bytes(iv, evp_cipher_length) != 1) {
+ verbose(VERB_CLIENT, "RAND_bytes failed");
+ return -1;
+ }
+ if (EVP_EncryptInit_ex(evp_sctx, cipher, NULL, ticket_keys->aes_key, iv) != 1) {
+ verbose(VERB_CLIENT, "EVP_EncryptInit_ex failed");
+ return -1;
+ }
+ if (HMAC_Init_ex(hmac_ctx, ticket_keys->hmac_key, 32, digest, NULL) != 1) {
+ verbose(VERB_CLIENT, "HMAC_Init_ex failed");
+ return -1;
+ }
+ return 1;
+ } else if (enc == 0) {
+ /* decrypt */
+ struct tls_session_ticket_key *key;
+ verbose(VERB_CLIENT, "start session decrypt");
+ for(key = ticket_keys; key->key_name != NULL; key++) {
+ if (!memcmp(key_name, key->key_name, 16)) {
+ verbose(VERB_CLIENT, "Found session_key");
+ break;
+ }
+ }
+ if(key->key_name == NULL) {
+ verbose(VERB_CLIENT, "Not found session_key");
+ return 0;
+ }
+
+ if (HMAC_Init_ex(hmac_ctx, key->hmac_key, 32, digest, NULL) != 1) {
+ verbose(VERB_CLIENT, "HMAC_Init_ex failed");
+ return -1;
+ }
+ if (EVP_DecryptInit_ex(evp_sctx, cipher, NULL, key->aes_key, iv) != 1) {
+ log_err("EVP_DecryptInit_ex failed");
+ return -1;
+ }
+
+ return (key == ticket_keys) ? 1 : 2;
+ }
+ return -1;
+#else
+ (void)key_name;
+ (void)iv;
+ (void)evp_sctx;
+ (void)hmac_ctx;
+ (void)enc;
+ return 0;
+#endif
+}
+
+void
+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++) {
+ free(key->key_name);
+ }
+ free(ticket_keys);
+ ticket_keys = NULL;
+}
Index: util/net_help.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/net_help.h,v
retrieving revision 1.4
diff -u -p -r1.4 net_help.h
--- util/net_help.h 17 Sep 2018 09:46:12 -0000 1.4
+++ util/net_help.h 29 Jan 2019 12:04:16 -0000
@@ -44,6 +44,7 @@
 #include "util/log.h"
 struct sock_list;
 struct regional;
+struct config_strlist;
 
 /** DNS constants for uint16_t style flag manipulation. host byteorder.
  *                                1  1  1  1  1  1
@@ -99,6 +100,9 @@ extern int MINIMAL_RESPONSES;
 /** rrset order roundrobin */
 extern int RRSET_ROUNDROBIN;
 
+/** log tag queries with name instead of 'info' for filtering */
+extern int LOG_TAG_QUERYREPLY;
+
 /**
  * See if string is ip4 or ip6.
  * @param str: IP specification.
@@ -236,6 +240,12 @@ void log_nametypeclass(enum verbosity_va
  uint8_t* name, uint16_t type, uint16_t dclass);
 
 /**
+ * Like log_nametypeclass, but logs with log_query for query logging
+ */
+void log_query_in(const char* str, uint8_t* name, uint16_t type,
+ uint16_t dclass);
+
+/**
  * Compare two sockaddrs. Imposes an ordering on the addresses.
  * Compares address and port.
  * @param addr1: address 1.
@@ -427,5 +437,31 @@ int ub_openssl_lock_init(void);
  * De-init the allocated openssl locks
  */
 void ub_openssl_lock_delete(void);
+
+/**
+ * setup TLS session ticket
+ * @param sslctx: the SSL_CTX to use (from connect_sslctx_create())
+ * @param tls_session_ticket_keys: TLS ticket secret filenames
+ * @return false on failure (alloc failure).
+ */
+int listen_sslctx_setup_ticket_keys(void* sslctx,
+ struct config_strlist* tls_session_ticket_keys);
+
+/**
+ * callback TLS session ticket encrypt and decrypt
+ * For use with SSL_CTX_set_tlsext_ticket_key_cb
+ * @param s: the SSL_CTX to use (from connect_sslctx_create())
+ * @param key_name: secret name, 16 bytes
+ * @param iv: up to EVP_MAX_IV_LENGTH.
+ * @param evp_ctx: the evp cipher context, function sets this.
+ * @param hmac_ctx: the hmax context, function sets this.
+ * @param enc: 1 is encrypt, 0 is decrypt
+ * @return 0 on no ticket, 1 for okay, and 2 for okay but renew the ticket
+ * (the ticket is decrypt only). and <0 for failures.
+ */
+int tls_session_ticket_key_cb(void *s, unsigned char* key_name,unsigned char* iv, void *evp_ctx, void *hmac_ctx, int enc);
+
+/** Free memory used for TLS session ticket keys */
+void listen_sslctx_delete_ticket_keys(void);
 
 #endif /* NET_HELP_H */
Index: util/netevent.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/netevent.c,v
retrieving revision 1.18
diff -u -p -r1.18 netevent.c
--- util/netevent.c 20 Sep 2018 23:15:40 -0000 1.18
+++ util/netevent.c 29 Jan 2019 12:04:16 -0000
@@ -50,6 +50,7 @@
 #include "sldns/str2wire.h"
 #include "dnstap/dnstap.h"
 #include "dnscrypt/dnscrypt.h"
+#include "services/listen_dnsport.h"
 #ifdef HAVE_OPENSSL_SSL_H
 #include <openssl/ssl.h>
 #endif
@@ -150,7 +151,8 @@ struct internal_signal {
 /** create a tcp handler with a parent */
 static struct comm_point* comm_point_create_tcp_handler(
  struct comm_base *base, struct comm_point* parent, size_t bufsize,
-        comm_point_callback_type* callback, void* callback_arg);
+ struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+ void* callback_arg);
 
 /* -------- End of local definitions -------- */
 
@@ -988,7 +990,11 @@ tcp_callback_writer(struct comm_point* c
  c->tcp_byte_count = 0;
  /* switch from listening(write) to listening(read) */
  comm_point_stop_listening(c);
- comm_point_start_listening(c, -1, -1);
+ if(c->tcp_req_info) {
+ tcp_req_info_handle_writedone(c->tcp_req_info);
+ } else {
+ comm_point_start_listening(c, -1, -1);
+ }
 }
 
 /** do the callback when reading is done */
@@ -1002,9 +1008,13 @@ tcp_callback_reader(struct comm_point* c
  c->tcp_byte_count = 0;
  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);
+ if(c->tcp_req_info) {
+ tcp_req_info_handle_readdone(c->tcp_req_info);
+ } else {
+ 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);
+ }
  }
 }
 
@@ -1163,6 +1173,8 @@ ssl_handle_read(struct comm_point* c)
  c->tcp_byte_count))) <= 0) {
  int want = SSL_get_error(c->ssl, r);
  if(want == SSL_ERROR_ZERO_RETURN) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
  return 0; /* shutdown, closed */
  } else if(want == SSL_ERROR_WANT_READ) {
  ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
@@ -1205,6 +1217,8 @@ ssl_handle_read(struct comm_point* c)
  if(r <= 0) {
  int want = SSL_get_error(c->ssl, r);
  if(want == SSL_ERROR_ZERO_RETURN) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
  return 0; /* shutdown, closed */
  } else if(want == SSL_ERROR_WANT_READ) {
  ub_winsock_tcp_wouldblock(c->ev->ev, UB_EV_READ);
@@ -1365,9 +1379,11 @@ comm_point_tcp_handle_read(int fd, struc
  /* read length bytes */
  r = recv(fd,(void*)sldns_buffer_at(c->buffer,c->tcp_byte_count),
  sizeof(uint16_t)-c->tcp_byte_count, 0);
- if(r == 0)
+ if(r == 0) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
  return 0;
- else if(r == -1) {
+ } else if(r == -1) {
 #ifndef USE_WINSOCK
  if(errno == EINTR || errno == EAGAIN)
  return 1;
@@ -1416,6 +1432,8 @@ comm_point_tcp_handle_read(int fd, struc
  r = recv(fd, (void*)sldns_buffer_current(c->buffer),
  sldns_buffer_remaining(c->buffer), 0);
  if(r == 0) {
+ if(c->tcp_req_info)
+ return tcp_req_info_handle_read_close(c->tcp_req_info);
  return 0;
  } else if(r == -1) {
 #ifndef USE_WINSOCK
@@ -1669,6 +1687,29 @@ comm_point_tcp_handle_write(int fd, stru
  return 1;
 }
 
+/** read again to drain buffers when there could be more to read */
+static void
+tcp_req_info_read_again(int fd, struct comm_point* c)
+{
+ while(c->tcp_req_info->read_again) {
+ int r;
+ c->tcp_req_info->read_again = 0;
+ if(c->tcp_is_reading)
+ r = comm_point_tcp_handle_read(fd, c, 0);
+ else r = comm_point_tcp_handle_write(fd, c);
+ if(!r) {
+ reclaim_tcp_handler(c);
+ if(!c->tcp_do_close) {
+ fptr_ok(fptr_whitelist_comm_point(
+ c->callback));
+ (void)(*c->callback)(c, c->cb_arg,
+ NETEVENT_CLOSED, NULL);
+ }
+ return;
+ }
+ }
+}
+
 void
 comm_point_tcp_handle_callback(int fd, short event, void* arg)
 {
@@ -1698,6 +1739,7 @@ comm_point_tcp_handle_callback(int fd, s
 #endif
 
  if(event&UB_EV_READ) {
+ int has_tcpq = (c->tcp_req_info != NULL);
  if(!comm_point_tcp_handle_read(fd, c, 0)) {
  reclaim_tcp_handler(c);
  if(!c->tcp_do_close) {
@@ -1707,9 +1749,12 @@ comm_point_tcp_handle_callback(int fd, s
  NETEVENT_CLOSED, NULL);
  }
  }
+ if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
+ tcp_req_info_read_again(fd, c);
  return;
  }
  if(event&UB_EV_WRITE) {
+ int has_tcpq = (c->tcp_req_info != NULL);
  if(!comm_point_tcp_handle_write(fd, c)) {
  reclaim_tcp_handler(c);
  if(!c->tcp_do_close) {
@@ -1719,6 +1764,8 @@ comm_point_tcp_handle_callback(int fd, s
  NETEVENT_CLOSED, NULL);
  }
  }
+ if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
+ tcp_req_info_read_again(fd, c);
  return;
  }
  if(event&UB_EV_TIMEOUT) {
@@ -2523,7 +2570,8 @@ comm_point_create_udp_ancil(struct comm_
 static struct comm_point*
 comm_point_create_tcp_handler(struct comm_base *base,
  struct comm_point* parent, size_t bufsize,
-        comm_point_callback_type* callback, void* callback_arg)
+ struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+ void* callback_arg)
 {
  struct comm_point* c = (struct comm_point*)calloc(1,
  sizeof(struct comm_point));
@@ -2579,6 +2627,20 @@ comm_point_create_tcp_handler(struct com
  c->repinfo.c = c;
  c->callback = callback;
  c->cb_arg = callback_arg;
+ if(spoolbuf) {
+ c->tcp_req_info = tcp_req_info_create(spoolbuf);
+ if(!c->tcp_req_info) {
+ log_err("could not create tcp commpoint");
+ sldns_buffer_free(c->buffer);
+ free(c->timeout);
+ free(c->ev);
+ free(c);
+ return NULL;
+ }
+ c->tcp_req_info->cp = c;
+ c->tcp_do_close = 1;
+ c->tcp_do_toggle_rw = 0;
+ }
  /* add to parent free list */
  c->tcp_free = parent->tcp_free;
  parent->tcp_free = c;
@@ -2590,6 +2652,9 @@ comm_point_create_tcp_handler(struct com
  {
  log_err("could not basetset tcphdl event");
  parent->tcp_free = c->tcp_free;
+ tcp_req_info_delete(c->tcp_req_info);
+ sldns_buffer_free(c->buffer);
+ free(c->timeout);
  free(c->ev);
  free(c);
  return NULL;
@@ -2600,7 +2665,8 @@ comm_point_create_tcp_handler(struct com
 struct comm_point*
 comm_point_create_tcp(struct comm_base *base, int fd, int num,
  int idle_timeout, struct tcl_list* tcp_conn_limit, size_t bufsize,
-        comm_point_callback_type* callback, void* callback_arg)
+ struct sldns_buffer* spoolbuf, comm_point_callback_type* callback,
+ void* callback_arg)
 {
  struct comm_point* c = (struct comm_point*)calloc(1,
  sizeof(struct comm_point));
@@ -2667,7 +2733,7 @@ comm_point_create_tcp(struct comm_base *
  /* now prealloc the tcp handlers */
  for(i=0; i<num; i++) {
  c->tcp_handlers[i] = comm_point_create_tcp_handler(base,
- c, bufsize, callback, callback_arg);
+ c, bufsize, spoolbuf, callback, callback_arg);
  if(!c->tcp_handlers[i]) {
  comm_point_delete(c);
  return NULL;
@@ -2949,6 +3015,8 @@ comm_point_close(struct comm_point* c)
  }
  }
  tcl_close_connection(c->tcl_addr);
+ if(c->tcp_req_info)
+ tcp_req_info_clear(c->tcp_req_info);
  /* close fd after removing from event lists, or epoll.. is messed up */
  if(c->fd != -1 && !c->do_not_close) {
  if(c->type == comm_tcp || c->type == comm_http) {
@@ -2992,6 +3060,9 @@ comm_point_delete(struct comm_point* c)
  sldns_buffer_free(c->dnscrypt_buffer);
  }
 #endif
+ if(c->tcp_req_info) {
+ tcp_req_info_delete(c->tcp_req_info);
+ }
  }
  ub_event_free(c->ev->ev);
  free(c->ev);
@@ -3032,8 +3103,12 @@ comm_point_send_reply(struct comm_reply
  dt_msg_send_client_response(repinfo->c->tcp_parent->dtenv,
  &repinfo->addr, repinfo->c->type, repinfo->c->buffer);
 #endif
- comm_point_start_listening(repinfo->c, -1,
- repinfo->c->tcp_timeout_msec);
+ if(repinfo->c->tcp_req_info) {
+ tcp_req_info_send_reply(repinfo->c->tcp_req_info);
+ } else {
+ comm_point_start_listening(repinfo->c, -1,
+ repinfo->c->tcp_timeout_msec);
+ }
  }
 }
 
@@ -3046,6 +3121,8 @@ comm_point_drop_reply(struct comm_reply*
  log_assert(repinfo->c->type != comm_tcp_accept);
  if(repinfo->c->type == comm_udp)
  return;
+ if(repinfo->c->tcp_req_info)
+ repinfo->c->tcp_req_info->is_drop = 1;
  reclaim_tcp_handler(repinfo->c);
 }
 
Index: util/netevent.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/netevent.h,v
retrieving revision 1.12
diff -u -p -r1.12 netevent.h
--- util/netevent.h 20 Sep 2018 23:15:40 -0000 1.12
+++ util/netevent.h 29 Jan 2019 12:04:16 -0000
@@ -268,6 +268,9 @@ struct comm_point {
  /** the entry for the connection. */
  struct tcl_addr* tcl_addr;
 
+ /** the structure to keep track of open requests on this channel */
+ struct tcp_req_info* tcp_req_info;
+
 #ifdef USE_MSG_FASTOPEN
  /** used to track if the sendto() call should be done when using TFO. */
  int tcp_do_fastopen;
@@ -455,6 +458,8 @@ struct comm_point* comm_point_create_udp
  * @param idle_timeout: TCP idle timeout in ms.
  * @param tcp_conn_limit: TCP connection limit info.
  * @param bufsize: size of buffer to create for handlers.
+ * @param spoolbuf: shared spool buffer for tcp_req_info structures.
+ * or NULL to not create those structures in the tcp handlers.
  * @param callback: callback function pointer for TCP handlers.
  * @param callback_arg: will be passed to your callback function.
  * @return: returns the TCP listener commpoint. You can find the
@@ -464,7 +469,8 @@ struct comm_point* comm_point_create_udp
  */
 struct comm_point* comm_point_create_tcp(struct comm_base* base,
  int fd, int num, int idle_timeout, struct tcl_list* tcp_conn_limit,
- size_t bufsize, comm_point_callback_type* callback, void* callback_arg);
+ size_t bufsize, struct sldns_buffer* spoolbuf,
+ comm_point_callback_type* callback, void* callback_arg);
 
 /**
  * Create an outgoing TCP commpoint. No file descriptor is opened, left at -1.
Index: util/data/msgreply.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/data/msgreply.c,v
retrieving revision 1.13
diff -u -p -r1.13 msgreply.c
--- util/data/msgreply.c 8 Oct 2018 16:03:53 -0000 1.13
+++ util/data/msgreply.c 29 Jan 2019 12:04:16 -0000
@@ -195,6 +195,8 @@ rdata_copy(sldns_buffer* pkt, struct pac
  }
  if(*rr_ttl < MIN_TTL)
  *rr_ttl = MIN_TTL;
+ if(*rr_ttl > MAX_TTL)
+ *rr_ttl = MAX_TTL;
  if(*rr_ttl < data->ttl)
  data->ttl = *rr_ttl;
 
@@ -853,7 +855,9 @@ log_reply_info(enum verbosity_value v, s
  addr_to_str(addr, addrlen, clientip_buf, sizeof(clientip_buf));
  if(rcode == LDNS_RCODE_FORMERR)
  {
- log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
+ if(LOG_TAG_QUERYREPLY)
+ log_reply("%s - - - %s - - - ", clientip_buf, rcode_buf);
+ else log_info("%s - - - %s - - - ", clientip_buf, rcode_buf);
  } else {
  if(qinf->qname)
  dname_str(qinf->qname, qname_buf);
@@ -861,7 +865,11 @@ log_reply_info(enum verbosity_value v, s
  pktlen = sldns_buffer_limit(rmsg);
  sldns_wire2str_type_buf(qinf->qtype, type_buf, sizeof(type_buf));
  sldns_wire2str_class_buf(qinf->qclass, class_buf, sizeof(class_buf));
- log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+ if(LOG_TAG_QUERYREPLY)
+     log_reply("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
+ clientip_buf, qname_buf, type_buf, class_buf,
+ rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
+ else log_info("%s %s %s %s %s " ARG_LL "d.%6.6d %d %d",
  clientip_buf, qname_buf, type_buf, class_buf,
  rcode_buf, (long long)dur.tv_sec, (int)dur.tv_usec, cached, (int)pktlen);
  }
Index: validator/val_neg.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_neg.c,v
retrieving revision 1.6
diff -u -p -r1.6 val_neg.c
--- validator/val_neg.c 17 Sep 2018 09:46:12 -0000 1.6
+++ validator/val_neg.c 29 Jan 2019 12:04:16 -0000
@@ -235,6 +235,7 @@ void neg_delete_data(struct val_neg_cach
 
  /* remove it from the lru list */
  neg_lru_remove(neg, el);
+ log_assert(neg->first != el && neg->last != el);
 
  /* go up the tree and reduce counts */
  p = el;
Index: Makefile.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/Makefile.in,v
retrieving revision 1.28
diff -u -p -r1.28 Makefile.in
--- Makefile.in 4 Dec 2018 12:05:06 -0000 1.28
+++ Makefile.in 29 Jan 2019 12:04:15 -0000
@@ -614,6 +614,8 @@ depend:
  -e 's?$$(srcdir)/util/configparser.c?util/configparser.c?g' \
  -e 's?$$(srcdir)/util/configparser.h?util/configparser.h?g' \
  -e 's?$$(srcdir)/dnstap/dnstap_config.h??g' \
+ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.c?dnstap/dnstap.pb-c.c?g' \
+ -e 's?$$(srcdir)/dnstap/dnstap.pb-c.h?dnstap/dnstap.pb-c.h?g' \
  -e 's?$$(srcdir)/dnscrypt/dnscrypt_config.h??g' \
  -e 's?$$(srcdir)/pythonmod/pythonmod.h?$$(PYTHONMOD_HEADER)?g' \
  -e 's?$$(srcdir)/edns-subnet/subnetmod.h $$(srcdir)/edns-subnet/subnet-whitelist.h $$(srcdir)/edns-subnet/edns-subnet.h $$(srcdir)/edns-subnet/addrtree.h?$$(SUBNET_HEADER)?g' \
@@ -743,7 +745,10 @@ listen_dnsport.lo listen_dnsport.o: $(sr
  $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
   $(srcdir)/services/outside_network.h $(srcdir)/util/rbtree.h \
   $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/sbuffer.h
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/services/modstack.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h
 localzone.lo localzone.o: $(srcdir)/services/localzone.c config.h $(srcdir)/services/localzone.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
@@ -761,7 +766,8 @@ mesh.lo mesh.o: $(srcdir)/services/mesh.
  $(srcdir)/util/data/msgencode.h $(srcdir)/util/timehist.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
  $(srcdir)/util/alloc.h $(srcdir)/util/config_file.h $(srcdir)/util/edns.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/sldns/wire2str.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/services/view.h $(srcdir)/util/data/dname.h $(srcdir)/respip/respip.h
+ $(srcdir)/services/view.h $(srcdir)/util/data/dname.h $(srcdir)/respip/respip.h \
+ $(srcdir)/services/listen_dnsport.h
 modstack.lo modstack.o: $(srcdir)/services/modstack.c config.h $(srcdir)/services/modstack.h \
  $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
@@ -770,7 +776,7 @@ modstack.lo modstack.o: $(srcdir)/servic
  $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h $(srcdir)/dns64/dns64.h $(srcdir)/iterator/iterator.h \
  $(srcdir)/services/outbound_list.h $(srcdir)/validator/validator.h $(srcdir)/validator/val_utils.h \
  $(srcdir)/respip/respip.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
- $(srcdir)/services/view.h $(PYTHONMOD_HEADER)
+ $(srcdir)/services/view.h $(PYTHONMOD_HEADER) $(srcdir)/ipsecmod/ipsecmod.h
 view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \
@@ -850,7 +856,7 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/ut
  $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h $(srcdir)/libunbound/context.h \
  $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/unbound-event.h \
  $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h \
- $(PYTHONMOD_HEADER)
+ $(PYTHONMOD_HEADER) $(srcdir)/ipsecmod/ipsecmod.h
 locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h
 log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h
 mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
@@ -869,13 +875,13 @@ netevent.lo netevent.o: $(srcdir)/util/n
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
  $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h \
  $(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/dnstap/dnstap.h \
-  \
+  $(srcdir)/services/listen_dnsport.h \
 
 net_help.lo net_help.o: $(srcdir)/util/net_help.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
  $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/module.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/sldns/parseutil.h \
- $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h \
 
 random.lo random.o: $(srcdir)/util/random.c config.h $(srcdir)/util/random.h $(srcdir)/util/log.h
 rbtree.lo rbtree.o: $(srcdir)/util/rbtree.c config.h $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \
@@ -889,10 +895,10 @@ rtt.lo rtt.o: $(srcdir)/util/rtt.c confi
  $(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
  $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
  $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
-edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/config_file.h $(srcdir)/util/netevent.h \
- $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/regional.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/config_file.h \
+ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h  \
+ $(srcdir)/util/regional.h $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/packed_rrset.h
 dnstree.lo dnstree.o: $(srcdir)/util/storage/dnstree.c config.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
@@ -1043,11 +1049,23 @@ dnstap.lo dnstap.o: $(srcdir)/dnstap/dns
  $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h \
  $(srcdir)/dnscrypt/dnscrypt.h  \
  $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/dnstap/dnstap.pb-c.h
-dnstap.pb-c.lo dnstap.pb-c.o: $(srcdir)/dnstap/dnstap.pb-c.c $(srcdir)/dnstap/dnstap.pb-c.h \
+ dnstap/dnstap.pb-c.h
+dnstap.pb-c.lo dnstap.pb-c.o: dnstap/dnstap.pb-c.c dnstap/dnstap.pb-c.h \
 
-ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h
-ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h
+ipsecmod.lo ipsecmod.o: $(srcdir)/ipsecmod/ipsecmod.c config.h $(srcdir)/ipsecmod/ipsecmod.h \
+ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h $(srcdir)/ipsecmod/ipsecmod-whitelist.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h  $(srcdir)/util/tube.h \
+ $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h $(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/cache/dns.h $(srcdir)/sldns/wire2str.h
+ipsecmod-whitelist.lo ipsecmod-whitelist.o: $(srcdir)/ipsecmod/ipsecmod-whitelist.c config.h \
+ $(srcdir)/ipsecmod/ipsecmod.h $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/rbtree.h \
+ $(srcdir)/ipsecmod/ipsecmod-whitelist.h $(srcdir)/util/storage/dnstree.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/str2wire.h
 unitanchor.lo unitanchor.o: $(srcdir)/testcode/unitanchor.c config.h $(srcdir)/util/log.h $(srcdir)/util/data/dname.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/testcode/unitmain.h \
  $(srcdir)/validator/val_anchor.h $(srcdir)/util/rbtree.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/rrdef.h
@@ -1169,7 +1187,8 @@ stats.lo stats.o: $(srcdir)/daemon/stats
  $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
- $(srcdir)/validator/val_neg.h
+ $(srcdir)/validator/val_neg.h \
+
 unbound.lo unbound.o: $(srcdir)/daemon/unbound.c config.h $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h \
  $(srcdir)/util/locks.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
   $(srcdir)/daemon/remote.h \
@@ -1263,7 +1282,8 @@ stats.lo stats.o: $(srcdir)/daemon/stats
  $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h \
  $(srcdir)/util/rtt.h $(srcdir)/services/authzone.h $(srcdir)/validator/val_kcache.h \
- $(srcdir)/validator/val_neg.h
+ $(srcdir)/validator/val_neg.h \
+
 replay.lo replay.o: $(srcdir)/testcode/replay.c config.h $(srcdir)/util/log.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/config_file.h $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
   $(srcdir)/testcode/testpkts.h $(srcdir)/util/rbtree.h \
Index: aclocal.m4
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/aclocal.m4,v
retrieving revision 1.5
diff -u -p -r1.5 aclocal.m4
--- aclocal.m4 7 Feb 2018 00:24:33 -0000 1.5
+++ aclocal.m4 29 Jan 2019 12:04:15 -0000
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.15.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
 
-# Copyright (C) 1996-2017 Free Software Foundation, Inc.
+# Copyright (C) 1996-2018 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9390,7 +9390,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2017 Free Software Foundation, Inc.
+# Copyright (C) 1997-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -9421,7 +9421,7 @@ AC_CONFIG_COMMANDS_PRE(
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 2006-2017 Free Software Foundation, Inc.
+# Copyright (C) 2006-2018 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
Index: config.guess
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/config.guess,v
retrieving revision 1.2
diff -u -p -r1.2 config.guess
--- config.guess 23 Aug 2017 11:23:51 -0000 1.2
+++ config.guess 29 Jan 2019 12:04:15 -0000
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/usr/bin/sh
 # Attempt to guess a canonical system name.
 #   Copyright 1992-2016 Free Software Foundation, Inc.
 
Index: config.h.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/config.h.in,v
retrieving revision 1.13
diff -u -p -r1.13 config.h.in
--- config.h.in 4 Dec 2018 12:05:06 -0000 1.13
+++ config.h.in 29 Jan 2019 12:04:15 -0000
@@ -178,6 +178,9 @@
 /* Define to 1 if you have the <event.h> header file. */
 #undef HAVE_EVENT_H
 
+/* Define to 1 if you have the `EVP_aes_256_cbc' function. */
+#undef HAVE_EVP_AES_256_CBC
+
 /* Define to 1 if you have the `EVP_cleanup' function. */
 #undef HAVE_EVP_CLEANUP
 
@@ -187,6 +190,9 @@
 /* Define to 1 if you have the `EVP_dss1' function. */
 #undef HAVE_EVP_DSS1
 
+/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */
+#undef HAVE_EVP_ENCRYPTINIT_EX
+
 /* Define to 1 if you have the `EVP_MD_CTX_new' function. */
 #undef HAVE_EVP_MD_CTX_NEW
 
@@ -259,6 +265,9 @@
 /* Define to 1 if you have the <hiredis/hiredis.h> header file. */
 #undef HAVE_HIREDIS_HIREDIS_H
 
+/* Define to 1 if you have the `HMAC_Init_ex' function. */
+#undef HAVE_HMAC_INIT_EX
+
 /* If you have HMAC_Update */
 #undef HAVE_HMAC_UPDATE
 
@@ -451,9 +460,15 @@
 /* Define if you have the SSL libraries installed. */
 #undef HAVE_SSL
 
+/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */
+#undef HAVE_SSL_CTX_SET_CIPHERSUITES
+
 /* Define to 1 if you have the `SSL_CTX_set_security_level' function. */
 #undef HAVE_SSL_CTX_SET_SECURITY_LEVEL
 
+/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_cb' function. */
+#undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_CB
+
 /* Define to 1 if you have the `SSL_get0_peername' function. */
 #undef HAVE_SSL_GET0_PEERNAME
 
@@ -585,6 +600,9 @@
 
 /* Define to 1 if you have the <ws2tcpip.h> header file. */
 #undef HAVE_WS2TCPIP_H
+
+/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */
+#undef HAVE_X509_VERIFY_PARAM_SET1_HOST
 
 /* Define to 1 if you have the `_beginthreadex' function. */
 #undef HAVE__BEGINTHREADEX
Index: config.sub
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/config.sub,v
retrieving revision 1.2
diff -u -p -r1.2 config.sub
--- config.sub 23 Aug 2017 11:23:51 -0000 1.2
+++ config.sub 29 Jan 2019 12:04:15 -0000
@@ -1,4 +1,4 @@
-#! /bin/sh
+#!/usr/bin/sh
 # Configuration validation subroutine script.
 #   Copyright 1992-2016 Free Software Foundation, Inc.
 
Index: configure
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/configure,v
retrieving revision 1.30
diff -u -p -r1.30 configure
--- configure 11 Dec 2018 13:49:01 -0000 1.30
+++ configure 29 Jan 2019 12:04:15 -0000
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for unbound 1.8.3.
+# Generated by GNU Autoconf 2.69 for unbound 1.9.0rc1.
 #
 # Report bugs to <[hidden email]>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='unbound'
 PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.8.3'
-PACKAGE_STRING='unbound 1.8.3'
+PACKAGE_VERSION='1.9.0rc1'
+PACKAGE_STRING='unbound 1.9.0rc1'
 PACKAGE_BUGREPORT='[hidden email]'
 PACKAGE_URL=''
 
@@ -1440,7 +1440,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.8.3 to adapt to many kinds of systems.
+\`configure' configures unbound 1.9.0rc1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1505,7 +1505,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of unbound 1.8.3:";;
+     short | recursive ) echo "Configuration of unbound 1.9.0rc1:";;
    esac
   cat <<\_ACEOF
 
@@ -1722,7 +1722,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-unbound configure 1.8.3
+unbound configure 1.9.0rc1
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2431,7 +2431,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.8.3, which was
+It was created by unbound $as_me 1.9.0rc1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2781,14 +2781,14 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 UNBOUND_VERSION_MAJOR=1
 
-UNBOUND_VERSION_MINOR=8
+UNBOUND_VERSION_MINOR=9
 
-UNBOUND_VERSION_MICRO=3
+UNBOUND_VERSION_MICRO=0rc1
 
 
-LIBUNBOUND_CURRENT=8
-LIBUNBOUND_REVISION=3
-LIBUNBOUND_AGE=0
+LIBUNBOUND_CURRENT=9
+LIBUNBOUND_REVISION=0
+LIBUNBOUND_AGE=1
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
 # 1.0.2 had 0:14:0
@@ -2854,6 +2854,7 @@ LIBUNBOUND_AGE=0
 # 1.8.1 had 8:1:0
 # 1.8.2 had 8:2:0
 # 1.8.3 had 8:3:0
+# 1.8.4 had 9:0:1 # add ub_ctx_set_tls
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -17992,7 +17993,7 @@ fi
 
 done
 
-for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify
+for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify SSL_CTX_set_tlsext_ticket_key_cb EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18008,7 +18009,7 @@ done
 # these check_funcs need -lssl
 BAKLIBS="$LIBS"
 LIBS="-lssl $LIBS"
-for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername
+for ac_func in OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -21147,7 +21148,7 @@ _ACEOF
 
 
 
-version=1.8.3
+version=1.9.0rc1
 
 date=`date +'%b %e, %Y'`
 
@@ -21666,7 +21667,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri
 # 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.8.3, which was
+This file was extended by unbound $as_me 1.9.0rc1, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -21732,7 +21733,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.8.3
+unbound config.status 1.9.0rc1
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
Index: install-sh
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/install-sh,v
retrieving revision 1.2
diff -u -p -r1.2 install-sh
--- install-sh 5 Mar 2016 14:40:34 -0000 1.2
+++ install-sh 29 Jan 2019 12:04:15 -0000
@@ -1,4 +1,4 @@
-#!/bin/sh
+#!/usr/bin/sh
 # install - install a program, script, or datafile
 
 scriptversion=2013-12-25.23; # UTC
Index: ltmain.sh
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/ltmain.sh,v
retrieving revision 1.3
diff -u -p -r1.3 ltmain.sh
--- ltmain.sh 5 Mar 2016 14:40:34 -0000 1.3
+++ ltmain.sh 29 Jan 2019 12:04:15 -0000
@@ -2124,7 +2124,7 @@ fi
 # a configuration failure hint, and exit.
 func_fatal_configuration ()
 {
-    func__fatal_error ${1+"$@"} \
+    func_fatal_error ${1+"$@"} \
       "See the $PACKAGE documentation for more information." \
       "Fatal configuration error."
 }
@@ -7272,10 +7272,12 @@ func_mode_link ()
       # -tp=*                Portland pgcc target processor selection
       # --sysroot=*          for sysroot support
       # -O*, -g*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
+      # -specs=*             GCC specs files
       # -stdlib=*            select c++ std lib with clang
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
       -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
-      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*)
+      -O*|-g*|-flto*|-fwhopr*|-fuse-linker-plugin|-fstack-protector*|-stdlib=*| \
+      -specs=*)
         func_quote_for_eval "$arg"
  arg=$func_quote_for_eval_result
         func_append compile_command " $arg"

Reply | Threaded
Open this post in threaded view
|

Re: [wouter@nlnetlabs.nl: [NLnet Labs Maintainers] Unbound 1.9.0rc1 pre-release]

Stuart Henderson
On 2019/01/30 22:55, Stuart Henderson wrote:
> Diff against /usr/src/usr.sbin/unbound if anyone is interested in testing
> the release candidate (there have been a couple of small fixes since).
> Release due approximately Friday.

1.9.0 is out, the only change since the rc1 diff is a spelling fix in
example.conf.in (which we don't install anyway) so I won't bother to
re-attach, https://junkpile.org/unbound-1.9.0.diff if anyone wants
the full thing.

Any tests / OKs?

> This release contains the DNS Flag Day changes for Unbound.  See the
> reference here, https://dnsflagday.net/ .   Or this presentation:
> https://indico.dns-oarc.net/event/29/contributions/662/attachments/634/1063/EDNS_Flag_Day_-_OARC29.pdf
> .   The EDNS timeouts are not used to fallback to nonEDNS queries.
>
> Out of order processing is implemented, for TCP and TLS.  It can be
> configured with a maximum amount of memory to use to store pending
> answers, and the current memory usage is in the statistics output.  This
> is with stream-wait-size in unbound.conf and mem.streamwait in
> unbound-control stats output.  Streams that cause the total memory
> counted to exceed the maximum are dropped, but it is possible to get a
> number of responses with little memory used.
>
> There is also TLS session resumption support, that can be enabled with
> the tls-session-ticket-keys option.  Together with the already existing
> TCP fast open, enabled with --enable-tfo-server --enable-tfo-client,
> that enables zero RTT stream reconnections to the server.  Make sure to
> also increase incoming-num-tcp if you expect a lot of TCP and TLS users.
>
> Options are added to set the TLS ciphers and TLS ciphersuites from
> unbound.conf.  This can be done with the tls-chiphers and
> tls-ciphersuites options.
>
> TLS can be used from libunbound, with the ub_ctx_set_tls config call,
> use that together with ub_ctx_set_fwd to select DNS over TLS transport.
>
>
> Features
> - log-tag-queryreply: yes in unbound.conf tags the log-queries and
>   log-replies in the log file for easier log filter maintenance.
> - ip-ratelimit-factor of 1 allows all traffic through, instead of the
>   previous blocking everything.
> - Fix #4206: support openssl 1.0.2 for TLS hostname verification,
>   alongside the 1.1.0 and later support that is already there.
> - Add contrib/unbound-fuzzme.patch from Jacob Hoffman-Andrews,
>   the patch adds a program used for fuzzing.
> - streamtcp option -a send queries consecutively and prints answers
>   as they arrive.
> - out-of-order processing for TCP and TLS.
> - Add stream-wait-size: 4m config option to limit the maximum
>   memory used by waiting tcp and tls stream replies.  This avoids
>   a denial of service where these replies use up all of the memory.
> - unbound-control stats has mem.streamwait that counts TCP and TLS
>   waiting result buffers.
> - Patch from Manabu Sonoda with tls-ciphers and tls-ciphersuites
>   options for unbound.conf.
> - Patch for TLS session resumption from Manabu Sonoda,
>   enable with tls-session-ticket-keys in unbound.conf.
> - ub_ctx_set_tls call for libunbound that enables DoT for the machines
>   set with ub_ctx_set_fwd.  Patch from Florian Obser.
>
> Bug Fixes
> - Fix that unbound-checkconf does not complains if the config file
>   is not placed inside the chroot.
> - Refuse to start with no ports.
> - Remove clang analysis warnings.
> - Patch for typo in unbound.conf man page.
> - Fix icon, no ragged edges and nicer resolutions available, for eg.
>   Win 7 and Windows 10 display.
> - cache-max-ttl also defines upperbound of initial TTL in response.
> - Fix config parser memory leaks.
> - Fix for FreeBSD port make with dnscrypt and dnstap enabled.
> - Fixup openssl 1.0.2 compile
> - Fix for crash in dns64 module if response is null.
> - On FreeBSD warn if systcl settings do not allow server TCP FASTOPEN,
>   and server tcp fastopen is enabled at compile time.
> - Document interaction between the tls-upstream option in the server
>   section and forward-tls-upstream option in the forward-zone sections.
> - Fix syntax in comment of local alias processing.
> - Fix NSEC3 record that is returned in wildcard replies from
>   auth-zone zones with NSEC3 and wildcards.
> - Log query name for looping module errors.
> - For caps-for-id fallback, use the whitelist to avoid timeout
>   starting a fallback sequence for it.
> - increase mesh max activation count for capsforid long fetches.
> - Fix for #4219: secondaries not updated after serial change, unbound
>   falls back to AXFR after IXFR gives several timeout failures.
> - Fix that auth zone after IXFR fallback tries the same master.
> - Fix for IXFR fallback to reset counter when IXFR does not timeout.
> - Newer aclocal and libtoolize used for generating configure scripts,
>   aclocal 1.16.1 and libtoolize 2.4.6.
> - Fix unit test for python 3.7 new keyword 'async'.
> - clang analysis fixes, assert arc4random buffer in init,
>   no check for already checked delegation pointer in iterator,
>   in testcode check for NULL packet matches, in perf do not copy
>   from NULL start list when growing capacity.  Adjust host and file
>   only when present in test header read to please checker.  In
>   testcode for unknown macro operand give zero result. Initialise the
>   passed argv array in test code.  In test code add EDNS data
>   segment copy only when nonempty.
> - Patch from Florian Obser fixes some compiler warnings:
>   include mini_event.h to have a prototype for mini_ev_cmp
>   include edns.h to have a prototype for apply_edns_options
>   sldns_wire2str_edns_keepalive_print is only called in the wire2str,
>   module declare it static to get rid of compiler warning:
>   no previous prototype for function
>   infra_find_ip_ratedata() is only called in the infra module,
>   declare it static to get rid of compiler warning:
>   no previous prototype for function
>   do not shadow local variable buf in authzone
>   auth_chunks_delete and az_nsec3_findnode are only called in the
>   authzone module, declare them static to get rid of compiler warning:
>   no previous prototype for function...
>   copy_rrset() is only called in the respip module, declare it
>   static to get rid of compiler warning:
>   no previous prototype for function 'copy_rrset'
>   no need for another variable "r"; gets rid of compiler warning:
>   declaration shadows a local variable in libunbound.c
>   no need for another variable "ns"; gets rid of compiler warning:
>   declaration shadows a local variable in iterator.c
> - Moved includes and make depend.
> - updated contrib/fastrpz.patch to cleanly diff.
> - remove compile warnings from libnettle compile.
> - output of newer lex 2.6.1 and bison 3.0.5.
> - Set build system for added call in the libunbound API.
> - List example config for root zone copy locally hosted with auth-zone
>   as suggested from draft-ietf-dnsop-7706-bis-02.  But with updated
>   B root address.