Here's an update to unbound.

The included diff *only* contains code parts, the full diff has 22K
lines of autoconf/makefile vomit. Do not use the included diff for
testing, use http://junkpile.org/unbound-1.5.8.diff.

Any comments, test reports, OKs?

>From the changelog:

+24 February 2016: Wouter
+       - Fix OpenBSD asynclook lock free that gets used later (fix test code).

... we didn't import the test code so this doesn't apply to us

+       - Fix that NSEC3 negative cache is used when there is no salt.
+
+23 February 2016: Wouter
+       - ub_ctx_set_stub() function for libunbound to config stub zones.
+       - sorted ubsyms.def file with exported libunbound functions.
+
+19 February 2016: Wouter
+       - Print understandable debug log when unusable DS record is seen.
+       - load gost algorithm if digest is seen before key algorithm.
+       - iana portlist update.
+
+17 February 2016: Wouter
+       - Fix that "make install" fails due to "text file busy" error.
+
+16 February 2016: Wouter
+       - Set IPPROTO_IP6 for ipv6 sockets otherwise invalid argument error.
+
+15 February 2016: Wouter
+       - ip-transparent option for FreeBSD with IP_BINDANY socket option.
+       - wait for sendto to drain socket buffers when they are full.
+
+9 February 2016: Wouter
+       - Test for type OPENPGPKEY.
+       - insecure-lan-zones: yesno config option, patch from Dag-Erling
+         Smørgrav.
+
+8 February 2016: Wouter
+       - Fix patch typo in prevuous commit for 734 from Adi Prasaja.
+       - RR Type CSYNC support RFC 7477, in debug printout and config input.
+       - RR Type OPENPGPKEY support (draft-ietf-dane-openpgpkey-07).
+
+29 January 2016: Wouter
+       - Neater cmdline_verbose increment patch from Edgar Pettijohn.
+
+27 January 2016: Wouter
+       - Made netbsd sendmsg test nonfatal, in case of false positives.
+       - Fix #741: log message for dnstap socket connection is more clear.
+
+26 January 2016: Wouter
+       - Fix #734: chown the pidfile if it resides inside the chroot.
+       - Use arc4random instead of random in tests (because it is
+         available, possibly as compat, anyway).
+       - Fix cmsg alignment for argument to sendmsg on NetBSD.
+       - Fix that unbound complains about unimplemented IP_PKTINFO for
+         sendmsg on NetBSD (for interface-automatic).
+
+25 January 2016: Wouter
+       - Fix #738: Swig should not be invoked with CPPFLAGS.
+
+19 January 2016: Wouter
+       - Squelch 'cannot assign requested address' log messages unless
+         verbosity is high, it was spammed after network down.

... I already pulled the log squelch diff across before 5.9

+14 January 2016: Wouter
+       - Fix to simplify empty string checking from Michael McConville.
+       - iana portlist update.
+
+12 January 2016: Wouter
+       - Fix #734: Do not log an error when the PID file cannot be chown'ed.
+         Patch from Simon Deziel.
+
+11 January 2016: Wouter
+       - Fix test if -pthreads unused to use better grep for portability.
+
+06 January 2016: Wouter
+       - Fix mingw crosscompile for recent mingw.
+       - Update aclocal, autoconf output with new versions (1.15, 2.4.6).
+
+05 January 2016: Wouter
+       - #731: tcp-mss, outgoing-tcp-mss options for unbound.conf, patch
+         from Daisuke Higashi.
+       - Support RFC7686: handle ".onion" Special-Use Domain. It is blocked
+         by default, and can be unblocked with "nodefault" localzone config.
+
+04 January 2016: Wouter
+       - Define DEFAULT_SOURCE together with BSD_SOURCE when that is defined,
+         for Linux glibc 2.20.
+       - Fixup contrib/aaaa-filter-iterator.patch for moved contents in the
+         source code, so it applies cleanly again.  Removed unused variable
+         warnings.
+
+15 December 2015: Ralph
+       - Fix #729: omit use of escape sequences in echo since they are not 
+         portable (unbound-control-setup).
+
+11 December 2015: Wouter
+       - remove NULL-checks before free, patch from Michael McConville.
+       - updated ax_pthread.m4 to version 21 with clang support, this
+         removes a warning from compilation.
 


Index: daemon/remote.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/remote.c,v
retrieving revision 1.14
diff -u -p -r1.14 remote.c
--- daemon/remote.c     5 Nov 2015 21:29:02 -0000       1.14
+++ daemon/remote.c     2 Mar 2016 13:44:15 -0000
@@ -389,7 +389,7 @@ add_open(const char* ip, int nr, struct 
 
                /* open fd */
                fd = create_tcp_accept_sock(res, 1, &noproto, 0,
-                       cfg->ip_transparent);
+                       cfg->ip_transparent, 0);
                freeaddrinfo(res);
        }
 
Index: daemon/unbound.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/unbound.c,v
retrieving revision 1.11
diff -u -p -r1.11 unbound.c
--- daemon/unbound.c    15 Dec 2015 20:05:03 -0000      1.11
+++ daemon/unbound.c    2 Mar 2016 13:44:15 -0000
@@ -443,6 +443,9 @@ static void
 perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode,
        const char** cfgfile)
 {
+#ifdef HAVE_KILL
+       int pidinchroot;
+#endif
 #ifdef HAVE_GETPWNAM
        struct passwd *pwd = NULL;
 
@@ -481,6 +484,12 @@ perform_setup(struct daemon* daemon, str
 #endif
 
 #ifdef HAVE_KILL
+       /* true if pidfile is inside chrootdir, or nochroot */
+       pidinchroot = !(cfg->chrootdir && cfg->chrootdir[0]) ||
+                               (cfg->chrootdir && cfg->chrootdir[0] &&
+                               strncmp(cfg->pidfile, cfg->chrootdir,
+                               strlen(cfg->chrootdir))==0);
+
        /* check old pid file before forking */
        if(cfg->pidfile && cfg->pidfile[0]) {
                /* calculate position of pidfile */
@@ -490,12 +499,7 @@ perform_setup(struct daemon* daemon, str
                                cfg, 1);
                if(!daemon->pidfile)
                        fatal_exit("pidfile alloc: out of memory");
-               checkoldpid(daemon->pidfile,
-                       /* true if pidfile is inside chrootdir, or nochroot */
-                       !(cfg->chrootdir && cfg->chrootdir[0]) ||
-                       (cfg->chrootdir && cfg->chrootdir[0] &&
-                       strncmp(daemon->pidfile, cfg->chrootdir,
-                               strlen(cfg->chrootdir))==0));
+               checkoldpid(daemon->pidfile, pidinchroot);
        }
 #endif
 
@@ -508,10 +512,11 @@ perform_setup(struct daemon* daemon, str
 #ifdef HAVE_KILL
        if(cfg->pidfile && cfg->pidfile[0]) {
                writepid(daemon->pidfile, getpid());
-               if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1) {
+               if(cfg->username && cfg->username[0] && cfg_uid != (uid_t)-1 &&
+                       pidinchroot) {
 #  ifdef HAVE_CHOWN
                        if(chown(daemon->pidfile, cfg_uid, cfg_gid) == -1) {
-                               log_err("cannot chown %u.%u %s: %s",
+                               verbose(VERB_QUERY, "cannot chown %u.%u %s: %s",
                                        (unsigned)cfg_uid, (unsigned)cfg_gid,
                                        daemon->pidfile, strerror(errno));
                        }
@@ -735,7 +740,7 @@ main(int argc, char* argv[])
 #endif
                        break;
                case 'v':
-                       cmdline_verbose ++;
+                       cmdline_verbose++;
                        verbosity++;
                        break;
                case 'd':
Index: daemon/worker.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/worker.c,v
retrieving revision 1.10
diff -u -p -r1.10 worker.c
--- daemon/worker.c     15 Dec 2015 20:05:03 -0000      1.10
+++ daemon/worker.c     2 Mar 2016 13:44:15 -0000
@@ -1217,7 +1217,8 @@ worker_init(struct worker* worker, struc
                cfg->do_tcp?cfg->outgoing_num_tcp:0, 
                worker->daemon->env->infra_cache, worker->rndstate,
                cfg->use_caps_bits_for_id, worker->ports, worker->numports,
-               cfg->unwanted_threshold, &worker_alloc_cleanup, worker,
+               cfg->unwanted_threshold, cfg->outgoing_tcp_mss,
+               &worker_alloc_cleanup, worker,
                cfg->do_udp, worker->daemon->connect_sslctx, cfg->delay_close,
                dtenv);
        if(!worker->back) {
Index: dnstap/dnstap.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/dnstap/dnstap.c,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 dnstap.c
--- dnstap/dnstap.c     16 Jul 2015 01:42:20 -0000      1.1.1.2
+++ dnstap/dnstap.c     2 Mar 2016 13:44:15 -0000
@@ -128,7 +128,8 @@ dt_create(const char *socket_path, unsig
        struct fstrm_writer *fw;
        struct fstrm_writer_options *fwopt;
 
-       verbose(VERB_OPS, "opening dnstap socket %s", socket_path);
+       verbose(VERB_OPS, "attempting to connect to dnstap socket %s",
+               socket_path);
        log_assert(socket_path != NULL);
        log_assert(num_workers > 0);
 
Index: libunbound/libunbound.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/libunbound/libunbound.c,v
retrieving revision 1.4
diff -u -p -r1.4 libunbound.c
--- libunbound/libunbound.c     15 Dec 2015 20:05:03 -0000      1.4
+++ libunbound/libunbound.c     2 Mar 2016 13:44:15 -0000
@@ -924,6 +924,88 @@ ub_ctx_set_fwd(struct ub_ctx* ctx, const
        return UB_NOERROR;
 }
 
+int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
+       int isprime)
+{
+       char* a;
+       struct config_stub **prev, *elem;
+
+       /* check syntax for zone name */
+       if(zone) {
+               uint8_t* nm;
+               int nmlabs;
+               size_t nmlen;
+               if(!parse_dname(zone, &nm, &nmlen, &nmlabs)) {
+                       errno=EINVAL;
+                       return UB_SYNTAX;
+               }
+               free(nm);
+       } else {
+               zone = ".";
+       }
+
+       /* check syntax for addr (if not NULL) */
+       if(addr) {
+               struct sockaddr_storage storage;
+               socklen_t stlen;
+               if(!extstrtoaddr(addr, &storage, &stlen)) {
+                       errno=EINVAL;
+                       return UB_SYNTAX;
+               }
+       }
+
+       lock_basic_lock(&ctx->cfglock);
+       if(ctx->finalized) {
+               lock_basic_unlock(&ctx->cfglock);
+               errno=EINVAL;
+               return UB_AFTERFINAL;
+       }
+
+       /* arguments all right, now find or add the stub */
+       prev = &ctx->env->cfg->stubs;
+       elem = cfg_stub_find(&prev, zone);
+       if(!elem && !addr) {
+               /* not found and we want to delete, nothing to do */
+               lock_basic_unlock(&ctx->cfglock);
+               return UB_NOERROR;
+       } else if(elem && !addr) {
+               /* found, and we want to delete */
+               *prev = elem->next;
+               config_delstub(elem);
+               lock_basic_unlock(&ctx->cfglock);
+               return UB_NOERROR;
+       } else if(!elem) {
+               /* not found, create the stub entry */
+               elem=(struct config_stub*)calloc(1, sizeof(struct config_stub));
+               if(elem) elem->name = strdup(zone);
+               if(!elem || !elem->name) {
+                       free(elem);
+                       lock_basic_unlock(&ctx->cfglock);
+                       errno = ENOMEM;
+                       return UB_NOMEM;
+               }
+               elem->next = ctx->env->cfg->stubs;
+               ctx->env->cfg->stubs = elem;
+       }
+
+       /* add the address to the list and set settings */
+       elem->isprime = isprime;
+       a = strdup(addr);
+       if(!a) {
+               lock_basic_unlock(&ctx->cfglock);
+               errno = ENOMEM;
+               return UB_NOMEM;
+       }
+       if(!cfg_strlist_insert(&elem->addrs, a)) {
+               lock_basic_unlock(&ctx->cfglock);
+               free(a);
+               errno = ENOMEM;
+               return UB_NOMEM;
+       }
+       lock_basic_unlock(&ctx->cfglock);
+       return UB_NOERROR;
+}
+
 int 
 ub_ctx_resolvconf(struct ub_ctx* ctx, const char* fname)
 {
Index: libunbound/libworker.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/libunbound/libworker.c,v
retrieving revision 1.9
diff -u -p -r1.9 libworker.c
--- libunbound/libworker.c      16 Jul 2015 01:44:00 -0000      1.9
+++ libunbound/libworker.c      2 Mar 2016 13:44:15 -0000
@@ -232,6 +232,7 @@ libworker_setup(struct ub_ctx* ctx, int 
                cfg->do_tcp?cfg->outgoing_num_tcp:0,
                w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id,
                ports, numports, cfg->unwanted_threshold,
+               cfg->outgoing_tcp_mss,
                &libworker_alloc_cleanup, w, cfg->do_udp, w->sslctx,
                cfg->delay_close, NULL);
        if(!w->is_bg || w->is_bg_thread) {
Index: libunbound/unbound.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/libunbound/unbound.h,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 unbound.h
--- libunbound/unbound.h        11 Dec 2014 16:18:15 -0000      1.1.1.5
+++ libunbound/unbound.h        2 Mar 2016 13:44:15 -0000
@@ -304,6 +304,27 @@ int ub_ctx_config(struct ub_ctx* ctx, co
 int ub_ctx_set_fwd(struct ub_ctx* ctx, const char* addr);
 
 /**
+ * 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.
+ * This is similar to a stub-zone entry in unbound.conf.
+ *
+ * @param ctx: context.
+ *     It is only possible to set configuration before the
+ *     first resolve is done.
+ * @param zone: name of the zone, string.
+ * @param addr: address, IP4 or IP6 in string format.
+ *     The addr is added to the list of stub-addresses if the entry exists.
+ *     If the addr is NULL the stub entry is removed.
+ * @param isprime: set to true to set stub-prime to yes for the stub.
+ *     For local authoritative servers, people usually set it to false,
+ *     For root hints it should be set to true.
+ * @return 0 if OK, else error.
+ */
+int ub_ctx_set_stub(struct ub_ctx* ctx, const char* zone, const char* addr,
+       int isprime);
+
+/**
  * Read list of nameservers to use from the filename given.
  * Usually "/etc/resolv.conf". Uses those nameservers as caching proxies.
  * If they do not support DNSSEC, validation may fail.
Index: services/listen_dnsport.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/listen_dnsport.c,v
retrieving revision 1.8
diff -u -p -r1.8 listen_dnsport.c
--- services/listen_dnsport.c   16 Jul 2015 01:44:00 -0000      1.8
+++ services/listen_dnsport.c   2 Mar 2016 13:44:15 -0000
@@ -99,7 +99,7 @@ create_udp_sock(int family, int socktype
        int rcv, int snd, int listen, int* reuseport, int transparent)
 {
        int s;
-#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || 
defined(IPV6_USE_MIN_MTU)  || defined(IP_TRANSPARENT)
+#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || 
defined(IPV6_USE_MIN_MTU)  || defined(IP_TRANSPARENT) || defined(IP_BINDANY)
        int on=1;
 #endif
 #ifdef IPV6_MTU
@@ -114,7 +114,7 @@ create_udp_sock(int family, int socktype
 #ifndef IPV6_V6ONLY
        (void)v6only;
 #endif
-#ifndef IP_TRANSPARENT
+#if !defined(IP_TRANSPARENT) && !defined(IP_BINDANY)
        (void)transparent;
 #endif
        if((s = socket(family, socktype, 0)) == -1) {
@@ -187,7 +187,14 @@ create_udp_sock(int family, int socktype
                        log_warn("setsockopt(.. IP_TRANSPARENT ..) failed: %s",
                        strerror(errno));
                }
-#endif /* IP_TRANSPARENT */
+#elif defined(IP_BINDANY)
+               if (transparent &&
+                   setsockopt(s, (family==AF_INET6? IPPROTO_IPV6:IPPROTO_IP),
+                   IP_BINDANY, (void*)&on, (socklen_t)sizeof(on)) < 0) {
+                       log_warn("setsockopt(.. IP_BINDANY ..) failed: %s",
+                       strerror(errno));
+               }
+#endif /* IP_TRANSPARENT || IP_BINDANY */
        }
        if(rcv) {
 #ifdef SO_RCVBUF
@@ -483,7 +490,7 @@ create_udp_sock(int family, int socktype
 
 int
 create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
-       int* reuseport, int transparent)
+       int* reuseport, int transparent, int mss)
 {
        int s;
 #if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || 
defined(IP_TRANSPARENT)
@@ -512,6 +519,25 @@ create_tcp_accept_sock(struct addrinfo *
 #endif
                return -1;
        }
+       if (mss > 0) {
+#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
+               if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, (void*)&mss,
+                       (socklen_t)sizeof(mss)) < 0) {
+                       #ifndef USE_WINSOCK
+                       log_err(" setsockopt(.. TCP_MAXSEG ..) failed: %s",
+                               strerror(errno));
+                       #else
+                       log_err(" setsockopt(.. TCP_MAXSEG ..) failed: %s",
+                               wsa_strerror(WSAGetLastError()));
+                       #endif
+               } else {
+                       verbose(VERB_ALGO,
+                               " tcp socket mss set to %d", mss);
+               }
+#else
+               log_warn(" setsockopt(TCP_MAXSEG) unsupported");
+#endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */
+       }
 #ifdef SO_REUSEADDR
        if(setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void*)&on, 
                (socklen_t)sizeof(on)) < 0) {
@@ -678,7 +704,7 @@ create_local_accept_sock(const char *pat
 static int
 make_sock(int stype, const char* ifname, const char* port, 
        struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
-       int* reuseport, int transparent)
+       int* reuseport, int transparent, int tcp_mss)
 {
        struct addrinfo *res = NULL;
        int r, s, inuse, noproto;
@@ -714,7 +740,7 @@ make_sock(int stype, const char* ifname,
                }
        } else  {
                s = create_tcp_accept_sock(res, v6only, &noproto, reuseport,
-                       transparent);
+                       transparent, tcp_mss);
                if(s == -1 && noproto && hints->ai_family == AF_INET6){
                        *noip6 = 1;
                }
@@ -727,7 +753,7 @@ make_sock(int stype, const char* ifname,
 static int
 make_sock_port(int stype, const char* ifname, const char* port, 
        struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd,
-       int* reuseport, int transparent)
+       int* reuseport, int transparent, int tcp_mss)
 {
        char* s = strchr(ifname, '@');
        if(s) {
@@ -749,10 +775,10 @@ make_sock_port(int stype, const char* if
                (void)strlcpy(p, s+1, sizeof(p));
                p[strlen(s+1)]=0;
                return make_sock(stype, newif, p, hints, v6only, noip6,
-                       rcv, snd, reuseport, transparent);
+                       rcv, snd, reuseport, transparent, tcp_mss);
        }
        return make_sock(stype, ifname, port, hints, v6only, noip6, rcv, snd,
-               reuseport, transparent);
+               reuseport, transparent, tcp_mss);
 }
 
 /**
@@ -847,19 +873,22 @@ set_recvpktinfo(int s, int family) 
  * @param reuseport: try to set SO_REUSEPORT if nonNULL and true.
  *     set to false on exit if reuseport failed due to no kernel support.
  * @param transparent: set IP_TRANSPARENT socket option.
+ * @param tcp_mss: maximum segment size of tcp socket. default if zero.
  * @return: returns false on error.
  */
 static int
 ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, 
        struct addrinfo *hints, const char* port, struct listen_port** list,
-       size_t rcv, size_t snd, int ssl_port, int* reuseport, int transparent)
+       size_t rcv, size_t snd, int ssl_port, int* reuseport, int transparent,
+       int tcp_mss)
 {
        int s, noip6=0;
        if(!do_udp && !do_tcp)
                return 0;
        if(do_auto) {
                if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, 
-                       &noip6, rcv, snd, reuseport, transparent)) == -1) {
+                       &noip6, rcv, snd, reuseport, transparent,
+                       tcp_mss)) == -1) {
                        if(noip6) {
                                log_warn("IPv6 protocol not available");
                                return 1;
@@ -886,7 +915,8 @@ ports_create_if(const char* ifname, int 
        } else if(do_udp) {
                /* regular udp socket */
                if((s = make_sock_port(SOCK_DGRAM, ifname, port, hints, 1, 
-                       &noip6, rcv, snd, reuseport, transparent)) == -1) {
+                       &noip6, rcv, snd, reuseport, transparent,
+                       tcp_mss)) == -1) {
                        if(noip6) {
                                log_warn("IPv6 protocol not available");
                                return 1;
@@ -907,7 +937,7 @@ ports_create_if(const char* ifname, int 
                        atoi(strchr(ifname, '@')+1) == ssl_port) ||
                        (!strchr(ifname, '@') && atoi(port) == ssl_port));
                if((s = make_sock_port(SOCK_STREAM, ifname, port, hints, 1, 
-                       &noip6, 0, 0, reuseport, transparent)) == -1) {
+                       &noip6, 0, 0, reuseport, transparent, tcp_mss)) == -1) {
                        if(noip6) {
                                /*log_warn("IPv6 protocol not available");*/
                                return 1;
@@ -1064,7 +1094,8 @@ listening_ports_open(struct config_file*
                                &hints, portbuf, &list,
                                cfg->so_rcvbuf, cfg->so_sndbuf,
                                cfg->ssl_port, reuseport,
-                               cfg->ip_transparent)) {
+                               cfg->ip_transparent,
+                               cfg->tcp_mss)) {
                                listening_ports_free(list);
                                return NULL;
                        }
@@ -1076,7 +1107,8 @@ listening_ports_open(struct config_file*
                                &hints, portbuf, &list,
                                cfg->so_rcvbuf, cfg->so_sndbuf,
                                cfg->ssl_port, reuseport,
-                               cfg->ip_transparent)) {
+                               cfg->ip_transparent,
+                               cfg->tcp_mss)) {
                                listening_ports_free(list);
                                return NULL;
                        }
@@ -1090,7 +1122,8 @@ listening_ports_open(struct config_file*
                                do_tcp, &hints, portbuf, &list, 
                                cfg->so_rcvbuf, cfg->so_sndbuf,
                                cfg->ssl_port, reuseport,
-                               cfg->ip_transparent)) {
+                               cfg->ip_transparent,
+                               cfg->tcp_mss)) {
                                listening_ports_free(list);
                                return NULL;
                        }
@@ -1102,7 +1135,8 @@ listening_ports_open(struct config_file*
                                do_tcp, &hints, portbuf, &list, 
                                cfg->so_rcvbuf, cfg->so_sndbuf,
                                cfg->ssl_port, reuseport,
-                               cfg->ip_transparent)) {
+                               cfg->ip_transparent,
+                               cfg->tcp_mss)) {
                                listening_ports_free(list);
                                return NULL;
                        }
Index: services/listen_dnsport.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/listen_dnsport.h,v
retrieving revision 1.6
diff -u -p -r1.6 listen_dnsport.h
--- services/listen_dnsport.h   16 Jul 2015 01:44:00 -0000      1.6
+++ services/listen_dnsport.h   2 Mar 2016 13:44:15 -0000
@@ -204,10 +204,11 @@ int create_udp_sock(int family, int sock
  * @param reuseport: if nonNULL and true, try to set SO_REUSEPORT on
  *     listening UDP port.  Set to false on return if it failed to do so.
  * @param transparent: set IP_TRANSPARENT socket option.
+ * @param mss: maximum segment size of the socket. if zero, leaves the 
default. 
  * @return: the socket. -1 on error.
  */
 int create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
-       int* reuseport, int transparent);
+       int* reuseport, int transparent, int mss);
 
 /**
  * Create and bind local listening socket
Index: services/localzone.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/localzone.c,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 localzone.c
--- services/localzone.c        16 Jul 2015 01:42:20 -0000      1.1.1.6
+++ services/localzone.c        2 Mar 2016 13:44:15 -0000
@@ -51,6 +51,7 @@
 #include "util/netevent.h"
 #include "util/data/msgreply.h"
 #include "util/data/msgparse.h"
+#include "util/as112.h"
 
 struct local_zones* 
 local_zones_create(void)
@@ -592,10 +593,11 @@ static int
 lz_enter_defaults(struct local_zones* zones, struct config_file* cfg)
 {
        struct local_zone* z;
+       const char** zstr;
 
-       /* this list of zones is from RFC 6303 */
+       /* this list of zones is from RFC 6303 and RFC 7686 */
 
-       /* block localhost level zones, first, later the LAN zones */
+       /* block localhost level zones first, then onion and later the LAN 
zones */
 
        /* localhost. zone */
        if(!lz_exists(zones, "localhost.") &&
@@ -653,111 +655,31 @@ lz_enter_defaults(struct local_zones* zo
                }
                lock_rw_unlock(&z->lock);
        }
+       /* onion. zone (RFC 7686) */
+       if(!lz_exists(zones, "onion.") &&
+               !lz_nodefault(cfg, "onion.")) {
+               if(!(z=lz_enter_zone(zones, "onion.", "static", 
+                       LDNS_RR_CLASS_IN)) ||
+                  !lz_enter_rr_into_zone(z,
+                       "onion. 10800 IN NS localhost.") ||
+                  !lz_enter_rr_into_zone(z,
+                       "onion. 10800 IN SOA localhost. nobody.invalid. "
+                       "1 3600 1200 604800 10800")) {
+                       log_err("out of memory adding default zone");
+                       if(z) { lock_rw_unlock(&z->lock); }
+                       return 0;
+               }
+               lock_rw_unlock(&z->lock);
+       }
 
-       /* if unblock lan-zones, then do not add the zones below.
-        * we do add the zones above, about 127.0.0.1, because localhost is
-        * not on the lan. */
-       if(cfg->unblock_lan_zones)
-               return 1;
-
-       /* block LAN level zones */
-       if (    !add_as112_default(zones, cfg, "10.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "16.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "17.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "18.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "19.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "20.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "21.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "22.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "23.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "24.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "25.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "26.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "27.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "28.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "29.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "30.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "31.172.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "168.192.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "0.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "64.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "65.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "66.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "67.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "68.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "69.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "70.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "71.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "72.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "73.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "74.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "75.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "76.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "77.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "78.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "79.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "80.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "81.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "82.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "83.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "84.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "85.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "86.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "87.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "88.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "89.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "90.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "91.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "92.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "93.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "94.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "95.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "96.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "97.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "98.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "99.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "100.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "101.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "102.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "103.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "104.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "105.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "106.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "107.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "108.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "109.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "110.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "111.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "112.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "113.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "114.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "115.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "116.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "117.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "118.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "119.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "120.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "121.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "122.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "123.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "124.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "125.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "126.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "127.100.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "254.169.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "2.0.192.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "100.51.198.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "113.0.203.in-addr.arpa.") ||
-               !add_as112_default(zones, cfg, "255.255.255.255.in-addr.arpa.") 
||
-               !add_as112_default(zones, cfg, 
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") ||
-               !add_as112_default(zones, cfg, "d.f.ip6.arpa.") ||
-               !add_as112_default(zones, cfg, "8.e.f.ip6.arpa.") ||
-               !add_as112_default(zones, cfg, "9.e.f.ip6.arpa.") ||
-               !add_as112_default(zones, cfg, "a.e.f.ip6.arpa.") ||
-               !add_as112_default(zones, cfg, "b.e.f.ip6.arpa.") ||
-               !add_as112_default(zones, cfg, "8.b.d.0.1.0.0.2.ip6.arpa.")) {
-               log_err("out of memory adding default zone");
-               return 0;
+       /* block AS112 zones, unless asked not to */
+       if(!cfg->unblock_lan_zones) {
+               for(zstr = as112_zones; *zstr; zstr++) {
+                       if(!add_as112_default(zones, cfg, *zstr)) {
+                               log_err("out of memory adding default zone");
+                               return 0;
+                       }
+               }
        }
        return 1;
 }
Index: services/outside_network.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/outside_network.c,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 outside_network.c
--- services/outside_network.c  16 Jul 2015 01:42:20 -0000      1.1.1.7
+++ services/outside_network.c  2 Mar 2016 13:44:15 -0000
@@ -222,6 +222,21 @@ outnet_tcp_take_into_use(struct waiting_
 #endif
                return 0;
        }
+
+       if (w->outnet->tcp_mss > 0) {
+#if defined(IPPROTO_TCP) && defined(TCP_MAXSEG)
+               if(setsockopt(s, IPPROTO_TCP, TCP_MAXSEG,
+                       (void*)&w->outnet->tcp_mss,
+                       (socklen_t)sizeof(w->outnet->tcp_mss)) < 0) {
+                       verbose(VERB_ALGO, "outgoing tcp:"
+                               " setsockopt(.. SO_REUSEADDR ..) failed");
+               }
+#else
+               verbose(VERB_ALGO, "outgoing tcp:"
+                       " setsockopt(TCP_MAXSEG) unsupported");
+#endif /* defined(IPPROTO_TCP) && defined(TCP_MAXSEG) */
+       }
+
        if(!pick_outgoing_tcp(w, s))
                return 0;
 
@@ -590,7 +605,7 @@ outside_network_create(struct comm_base 
        size_t num_ports, char** ifs, int num_ifs, int do_ip4, 
        int do_ip6, size_t num_tcp, struct infra_cache* infra,
        struct ub_randstate* rnd, int use_caps_for_id, int* availports, 
-       int numavailports, size_t unwanted_threshold,
+       int numavailports, size_t unwanted_threshold, int tcp_mss,
        void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
        void* sslctx, int delayclose, struct dt_env* dtenv)
 {
@@ -620,6 +635,7 @@ outside_network_create(struct comm_base 
        outnet->unwanted_param = unwanted_param;
        outnet->use_caps_for_id = use_caps_for_id;
        outnet->do_udp = do_udp;
+       outnet->tcp_mss = tcp_mss;
 #ifndef S_SPLINT_S
        if(delayclose) {
                outnet->delayclose = 1;
Index: services/outside_network.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/outside_network.h,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 outside_network.h
--- services/outside_network.h  20 Nov 2014 00:00:32 -0000      1.1.1.5
+++ services/outside_network.h  2 Mar 2016 13:44:15 -0000
@@ -132,6 +132,8 @@ struct outside_network {
        /** dnstap environment */
        struct dt_env* dtenv;
 #endif
+       /** maximum segment size of tcp socket */
+       int tcp_mss;
 
        /**
         * Array of tcp pending used for outgoing TCP connections.
@@ -392,6 +394,7 @@ struct serviced_query {
  * @param unwanted_threshold: when to take defensive action.
  * @param unwanted_action: the action to take.
  * @param unwanted_param: user parameter to action.
+ * @param tcp_mss: maximum segment size of tcp socket.
  * @param do_udp: if udp is done.
  * @param sslctx: context to create outgoing connections with (if enabled).
  * @param delayclose: if not 0, udp sockets are delayed before timeout closure.
@@ -403,7 +406,7 @@ struct outside_network* outside_network_
        size_t bufsize, size_t num_ports, char** ifs, int num_ifs,
        int do_ip4, int do_ip6, size_t num_tcp, struct infra_cache* infra, 
        struct ub_randstate* rnd, int use_caps_for_id, int* availports, 
-       int numavailports, size_t unwanted_threshold,
+       int numavailports, size_t unwanted_threshold, int tcp_mss,
        void (*unwanted_action)(void*), void* unwanted_param, int do_udp,
        void* sslctx, int delayclose, struct dt_env *dtenv);
 
Index: sldns/rrdef.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/sldns/rrdef.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 rrdef.c
--- sldns/rrdef.c       16 Jul 2015 01:42:20 -0000      1.1.1.1
+++ sldns/rrdef.c       2 Mar 2016 13:44:16 -0000
@@ -144,6 +144,12 @@ static const sldns_rdf_type type_dhcid_w
 static const sldns_rdf_type type_talink_wireformat[] = {
        LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME
 };
+static const sldns_rdf_type type_openpgpkey_wireformat[] = {
+       LDNS_RDF_TYPE_B64
+};
+static const sldns_rdf_type type_csync_wireformat[] = {
+       LDNS_RDF_TYPE_INT32, LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_NSEC
+};
 /* nsec3 is some vars, followed by same type of data of nsec */
 static const sldns_rdf_type type_nsec3_wireformat[] = {
 /*     LDNS_RDF_TYPE_NSEC3_VARS, LDNS_RDF_TYPE_NSEC3_NEXT_OWNER, 
LDNS_RDF_TYPE_NSEC*/
@@ -361,8 +367,10 @@ static sldns_rr_descriptor rdata_field_d
        {LDNS_RR_TYPE_CDS, "CDS", 4, 4, type_ds_wireformat, LDNS_RDF_TYPE_NONE, 
LDNS_RR_NO_COMPRESS, 0 },
        /* 60 */
        {LDNS_RR_TYPE_CDNSKEY, "CDNSKEY", 4, 4, type_dnskey_wireformat, 
LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE61", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, 
LDNS_RR_NO_COMPRESS, 0 },
-{LDNS_RR_TYPE_NULL, "TYPE62", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, 
LDNS_RR_NO_COMPRESS, 0 },
+       /* 61 */
+{LDNS_RR_TYPE_OPENPGPKEY, "OPENPGPKEY", 1, 1, type_openpgpkey_wireformat, 
LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
+       /* 62 */
+       {LDNS_RR_TYPE_CSYNC, "CSYNC", 3, 3, type_csync_wireformat, 
LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE63", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, 
LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE64", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, 
LDNS_RR_NO_COMPRESS, 0 },
 {LDNS_RR_TYPE_NULL, "TYPE65", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, 
LDNS_RR_NO_COMPRESS, 0 },
Index: sldns/rrdef.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/sldns/rrdef.h,v
retrieving revision 1.2
diff -u -p -r1.2 rrdef.h
--- sldns/rrdef.h       5 Nov 2015 21:29:03 -0000       1.2
+++ sldns/rrdef.h       2 Mar 2016 13:44:16 -0000
@@ -182,6 +182,8 @@ enum sldns_enum_rr_type
        LDNS_RR_TYPE_NSEC3PARAM = 51, /* RFC 5155 */
        LDNS_RR_TYPE_NSEC3PARAMS = 51,
        LDNS_RR_TYPE_TLSA = 52, /* RFC 6698 */
+       LDNS_RR_TYPE_SMIMEA = 53, /* draft-ietf-dane-smime, TLSA-like but may
+                                    be extended */
 
        LDNS_RR_TYPE_HIP = 55, /* RFC 5205 */
 
@@ -193,6 +195,8 @@ enum sldns_enum_rr_type
         LDNS_RR_TYPE_TALINK = 58,
        LDNS_RR_TYPE_CDS = 59, /** RFC 7344 */
        LDNS_RR_TYPE_CDNSKEY = 60, /** RFC 7344 */
+       LDNS_RR_TYPE_OPENPGPKEY = 61, /* draft-ietf-dane-openpgpkey */
+       LDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
 
        LDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
 
Index: sldns/str2wire.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/sldns/str2wire.c,v
retrieving revision 1.1.1.1
diff -u -p -r1.1.1.1 str2wire.c
--- sldns/str2wire.c    16 Jul 2015 01:42:20 -0000      1.1.1.1
+++ sldns/str2wire.c    2 Mar 2016 13:44:16 -0000
@@ -204,7 +204,7 @@ rrinternal_get_owner(sldns_buffer* strbu
                        return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL,
                                sldns_buffer_position(strbuf));
                memmove(rr, tocopy, *dname_len);
-       } else if(strlen(token) == 0) {
+       } else if(*token == '\0') {
                /* no ownername was given, try prev, if that fails
                 * origin, else default to root */
                uint8_t* tocopy;
@@ -1091,7 +1091,7 @@ int sldns_str2wire_apl_buf(const char* s
        uint8_t prefix;
        size_t i;
 
-       if(strlen(my_str) == 0) {
+       if(*my_str == '\0') {
                /* empty APL element, no data, no string */
                *len = 0;
                return LDNS_WIREPARSE_ERR_OK;
Index: util/as112.c
===================================================================
RCS file: util/as112.c
diff -N util/as112.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ util/as112.c        2 Mar 2016 13:44:16 -0000
@@ -0,0 +1,143 @@
+/*
+ * util/as112.c - list of local zones.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file provides a list of lan zones.
+ */
+
+#include "util/as112.h"
+
+static const char* as112_zone_array[] = {
+       "10.in-addr.arpa.",
+       "16.172.in-addr.arpa.",
+       "17.172.in-addr.arpa.",
+       "18.172.in-addr.arpa.",
+       "19.172.in-addr.arpa.",
+       "20.172.in-addr.arpa.",
+       "21.172.in-addr.arpa.",
+       "22.172.in-addr.arpa.",
+       "23.172.in-addr.arpa.",
+       "24.172.in-addr.arpa.",
+       "25.172.in-addr.arpa.",
+       "26.172.in-addr.arpa.",
+       "27.172.in-addr.arpa.",
+       "28.172.in-addr.arpa.",
+       "29.172.in-addr.arpa.",
+       "30.172.in-addr.arpa.",
+       "31.172.in-addr.arpa.",
+       "168.192.in-addr.arpa.",
+       "0.in-addr.arpa.",
+       "64.100.in-addr.arpa.",
+       "65.100.in-addr.arpa.",
+       "66.100.in-addr.arpa.",
+       "67.100.in-addr.arpa.",
+       "68.100.in-addr.arpa.",
+       "69.100.in-addr.arpa.",
+       "70.100.in-addr.arpa.",
+       "71.100.in-addr.arpa.",
+       "72.100.in-addr.arpa.",
+       "73.100.in-addr.arpa.",
+       "74.100.in-addr.arpa.",
+       "75.100.in-addr.arpa.",
+       "76.100.in-addr.arpa.",
+       "77.100.in-addr.arpa.",
+       "78.100.in-addr.arpa.",
+       "79.100.in-addr.arpa.",
+       "80.100.in-addr.arpa.",
+       "81.100.in-addr.arpa.",
+       "82.100.in-addr.arpa.",
+       "83.100.in-addr.arpa.",
+       "84.100.in-addr.arpa.",
+       "85.100.in-addr.arpa.",
+       "86.100.in-addr.arpa.",
+       "87.100.in-addr.arpa.",
+       "88.100.in-addr.arpa.",
+       "89.100.in-addr.arpa.",
+       "90.100.in-addr.arpa.",
+       "91.100.in-addr.arpa.",
+       "92.100.in-addr.arpa.",
+       "93.100.in-addr.arpa.",
+       "94.100.in-addr.arpa.",
+       "95.100.in-addr.arpa.",
+       "96.100.in-addr.arpa.",
+       "97.100.in-addr.arpa.",
+       "98.100.in-addr.arpa.",
+       "99.100.in-addr.arpa.",
+       "100.100.in-addr.arpa.",
+       "101.100.in-addr.arpa.",
+       "102.100.in-addr.arpa.",
+       "103.100.in-addr.arpa.",
+       "104.100.in-addr.arpa.",
+       "105.100.in-addr.arpa.",
+       "106.100.in-addr.arpa.",
+       "107.100.in-addr.arpa.",
+       "108.100.in-addr.arpa.",
+       "109.100.in-addr.arpa.",
+       "110.100.in-addr.arpa.",
+       "111.100.in-addr.arpa.",
+       "112.100.in-addr.arpa.",
+       "113.100.in-addr.arpa.",
+       "114.100.in-addr.arpa.",
+       "115.100.in-addr.arpa.",
+       "116.100.in-addr.arpa.",
+       "117.100.in-addr.arpa.",
+       "118.100.in-addr.arpa.",
+       "119.100.in-addr.arpa.",
+       "120.100.in-addr.arpa.",
+       "121.100.in-addr.arpa.",
+       "122.100.in-addr.arpa.",
+       "123.100.in-addr.arpa.",
+       "124.100.in-addr.arpa.",
+       "125.100.in-addr.arpa.",
+       "126.100.in-addr.arpa.",
+       "127.100.in-addr.arpa.",
+       "254.169.in-addr.arpa.",
+       "2.0.192.in-addr.arpa.",
+       "100.51.198.in-addr.arpa.",
+       "113.0.203.in-addr.arpa.",
+       "255.255.255.255.in-addr.arpa.",
+       
"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.",
+       "d.f.ip6.arpa.",
+       "8.e.f.ip6.arpa.",
+       "9.e.f.ip6.arpa.",
+       "a.e.f.ip6.arpa.",
+       "b.e.f.ip6.arpa.",
+       "8.b.d.0.1.0.0.2.ip6.arpa.",
+       0
+};
+
+const char** as112_zones = as112_zone_array;
Index: util/as112.h
===================================================================
RCS file: util/as112.h
diff -N util/as112.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ util/as112.h        2 Mar 2016 13:44:16 -0000
@@ -0,0 +1,57 @@
+/*
+ * util/as112.c - list of local zones.
+ *
+ * Copyright (c) 2007, NLnet Labs. All rights reserved.
+ *
+ * This software is open source.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 
+ * Neither the name of the NLNET LABS nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * \file
+ *
+ * This file provides a list of lan zones
+ */
+
+#ifndef UTIL_AS112_H
+#define UTIL_AS112_H
+
+/** 
+ * Array of text-format domain names of the AS112 zones.
+ * The array ends with NULL.  "AS112" is a service on the internet that
+ * that this array is named after.  The names in this list (or some of them)
+ * are null-routed by this service to avoid load on central servers caused by
+ * mistaken lookups for local content on the global internet.
+ *
+ * This is the list of names that unbound should not normally be sending
+ * on towards the internet, because they are local-use.
+ */
+extern const char** as112_zones;
+
+#endif
Index: util/config_file.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/config_file.c,v
retrieving revision 1.8
diff -u -p -r1.8 config_file.c
--- util/config_file.c  15 Dec 2015 20:05:03 -0000      1.8
+++ util/config_file.c  2 Mar 2016 13:44:16 -0000
@@ -98,6 +98,8 @@ config_create(void)
        cfg->do_udp = 1;
        cfg->do_tcp = 1;
        cfg->tcp_upstream = 0;
+       cfg->tcp_mss = 0;
+       cfg->outgoing_tcp_mss = 0;
        cfg->ssl_service_key = NULL;
        cfg->ssl_service_pem = NULL;
        cfg->ssl_port = 853;
@@ -210,6 +212,7 @@ config_create(void)
        cfg->local_zones_nodefault = NULL;
        cfg->local_data = NULL;
        cfg->unblock_lan_zones = 0;
+       cfg->insecure_lan_zones = 0;
        cfg->python_script = NULL;
        cfg->remote_control_enable = 0;
        cfg->control_ifs = NULL;
@@ -368,6 +371,8 @@ int config_set_option(struct config_file
        else S_YNO("do-udp:", do_udp)
        else S_YNO("do-tcp:", do_tcp)
        else S_YNO("tcp-upstream:", tcp_upstream)
+       else S_NUMBER_NONZERO("tcp-mss:", tcp_mss)
+       else S_NUMBER_NONZERO("outgoing-tcp-mss:", outgoing_tcp_mss)
        else S_YNO("ssl-upstream:", ssl_upstream)
        else S_STR("ssl-service-key:", ssl_service_key)
        else S_STR("ssl-service-pem:", ssl_service_pem)
@@ -458,6 +463,7 @@ int config_set_option(struct config_file
        else S_YNO("rrset-roundrobin:", rrset_roundrobin)
        else S_STRLIST("local-data:", local_data)
        else S_YNO("unblock-lan-zones:", unblock_lan_zones)
+       else S_YNO("insecure-lan-zones:", insecure_lan_zones)
        else S_YNO("control-enable:", remote_control_enable)
        else S_STRLIST("control-interface:", control_ifs)
        else S_NUMBER_NONZERO("control-port:", control_port)
@@ -675,6 +681,8 @@ config_get_option(struct config_file* cf
        else O_YNO(opt, "do-udp", do_udp)
        else O_YNO(opt, "do-tcp", do_tcp)
        else O_YNO(opt, "tcp-upstream", tcp_upstream)
+       else O_DEC(opt, "tcp-mss", tcp_mss)
+       else O_DEC(opt, "outgoing-tcp-mss", outgoing_tcp_mss)
        else O_YNO(opt, "ssl-upstream", ssl_upstream)
        else O_STR(opt, "ssl-service-key", ssl_service_key)
        else O_STR(opt, "ssl-service-pem", ssl_service_pem)
@@ -739,6 +747,7 @@ config_get_option(struct config_file* cf
        else O_YNO(opt, "minimal-responses", minimal_responses)
        else O_YNO(opt, "rrset-roundrobin", rrset_roundrobin)
        else O_YNO(opt, "unblock-lan-zones", unblock_lan_zones)
+       else O_YNO(opt, "insecure-lan-zones", insecure_lan_zones)
        else O_DEC(opt, "max-udp-size", max_udp_size)
        else O_STR(opt, "python-script", python_script)
        else O_DEC(opt, "ratelimit", ratelimit)
@@ -864,6 +873,18 @@ config_read(struct config_file* cfg, con
        return 1;
 }
 
+struct config_stub* cfg_stub_find(struct config_stub*** pp, const char* nm)
+{
+       struct config_stub* p = *(*pp);
+       while(p) {
+               if(strcmp(p->name, nm) == 0)
+                       return p;
+               (*pp) = &p->next;
+               p = p->next;
+       }
+       return NULL;
+}
+
 void
 config_delstrlist(struct config_strlist* p)
 {
@@ -890,15 +911,22 @@ config_deldblstrlist(struct config_str2l
 }
 
 void
+config_delstub(struct config_stub* p)
+{
+       if(!p) return;
+       free(p->name);
+       config_delstrlist(p->hosts);
+       config_delstrlist(p->addrs);
+       free(p);
+}
+
+void
 config_delstubs(struct config_stub* p)
 {
        struct config_stub* np;
        while(p) {
                np = p->next;
-               free(p->name);
-               config_delstrlist(p->hosts);
-               config_delstrlist(p->addrs);
-               free(p);
+               config_delstub(p);
                p = np;
        }
 }
Index: util/config_file.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/config_file.h,v
retrieving revision 1.6
diff -u -p -r1.6 config_file.h
--- util/config_file.h  15 Dec 2015 20:05:03 -0000      1.6
+++ util/config_file.h  2 Mar 2016 13:44:16 -0000
@@ -78,6 +78,10 @@ struct config_file {
        int do_tcp;
        /** tcp upstream queries (no UDP upstream queries) */
        int tcp_upstream;
+       /** maximum segment size of tcp socket which queries are answered */
+       int tcp_mss;
+       /** maximum segment size of tcp socket for outgoing queries */
+       int outgoing_tcp_mss;
 
        /** private key file for dnstcp-ssl service (enabled if not NULL) */
        char* ssl_service_key;
@@ -285,8 +289,10 @@ struct config_file {
        struct config_strlist* local_zones_nodefault;
        /** local data RRs configured */
        struct config_strlist* local_data;
-       /** unblock lan zones (reverse lookups for 10/8 and so on) */
+       /** unblock lan zones (reverse lookups for AS112 zones) */
        int unblock_lan_zones;
+       /** insecure lan zones (don't validate AS112 zones) */
+       int insecure_lan_zones;
 
        /** remote control section. enable toggle. */
        int remote_control_enable;
@@ -554,6 +560,17 @@ int cfg_strlist_insert(struct config_str
 int cfg_str2list_insert(struct config_str2list** head, char* item, char* i2);
 
 /**
+ * Find stub in config list, also returns prevptr (for deletion).
+ * @param pp: call routine with pointer to a pointer to the start of the list,
+ *     if the stub is found, on exit, the value contains a pointer to the
+ *     next pointer that points to the found element (or to the list start
+ *     pointer if it is the first element).
+ * @param nm: name of stub to find.
+ * @return: pointer to config_stub if found, or NULL if not found.
+ */
+struct config_stub* cfg_stub_find(struct config_stub*** pp, const char* nm);
+
+/**
  * Delete items in config string list.
  * @param list: list.
  */
@@ -564,6 +581,12 @@ void config_delstrlist(struct config_str
  * @param list: list.
  */
 void config_deldblstrlist(struct config_str2list* list);
+
+/**
+ * Delete a stub item
+ * @param p: stub item
+ */
+void config_delstub(struct config_stub* p);
 
 /**
  * Delete items in config stub list.
Index: util/configlexer.lex
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/configlexer.lex,v
retrieving revision 1.3
diff -u -p -r1.3 configlexer.lex
--- util/configlexer.lex        15 Dec 2015 20:05:03 -0000      1.3
+++ util/configlexer.lex        2 Mar 2016 13:44:16 -0000
@@ -63,7 +63,7 @@ static void config_start_include(const c
                ub_c_error_msg("too many include files");
                return;
        }
-       if(strlen(filename) == 0) {
+       if(*filename == '\0') {
                ub_c_error_msg("empty include file name");
                return;
        }
@@ -219,6 +219,8 @@ do-ip6{COLON}                       { YDVAR(1, VAR_DO_IP6) }
 do-udp{COLON}                  { YDVAR(1, VAR_DO_UDP) }
 do-tcp{COLON}                  { YDVAR(1, VAR_DO_TCP) }
 tcp-upstream{COLON}            { YDVAR(1, VAR_TCP_UPSTREAM) }
+tcp-mss{COLON}                 { YDVAR(1, VAR_TCP_MSS) }
+outgoing-tcp-mss{COLON}                { YDVAR(1, VAR_OUTGOING_TCP_MSS) }
 ssl-upstream{COLON}            { YDVAR(1, VAR_SSL_UPSTREAM) }
 ssl-service-key{COLON}         { YDVAR(1, VAR_SSL_SERVICE_KEY) }
 ssl-service-pem{COLON}         { YDVAR(1, VAR_SSL_SERVICE_PEM) }
@@ -319,6 +321,7 @@ local-zone{COLON}           { YDVAR(2, VAR_LOCAL_
 local-data{COLON}              { YDVAR(1, VAR_LOCAL_DATA) }
 local-data-ptr{COLON}          { YDVAR(1, VAR_LOCAL_DATA_PTR) }
 unblock-lan-zones{COLON}       { YDVAR(1, VAR_UNBLOCK_LAN_ZONES) }
+insecure-lan-zones{COLON}      { YDVAR(1, VAR_INSECURE_LAN_ZONES) }
 statistics-interval{COLON}     { YDVAR(1, VAR_STATISTICS_INTERVAL) }
 statistics-cumulative{COLON}   { YDVAR(1, VAR_STATISTICS_CUMULATIVE) }
 extended-statistics{COLON}     { YDVAR(1, VAR_EXTENDED_STATISTICS) }
Index: util/configparser.y
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/configparser.y,v
retrieving revision 1.3
diff -u -p -r1.3 configparser.y
--- util/configparser.y 15 Dec 2015 20:05:03 -0000      1.3
+++ util/configparser.y 2 Mar 2016 13:44:16 -0000
@@ -70,6 +70,7 @@ extern struct config_parser_state* cfg_p
 %token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
 %token VAR_OUTGOING_RANGE VAR_INTERFACE
 %token VAR_DO_IP4 VAR_DO_IP6 VAR_DO_UDP VAR_DO_TCP 
+%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS
 %token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
 %token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
 %token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
@@ -106,7 +107,8 @@ extern struct config_parser_state* cfg_p
 %token VAR_IGNORE_CD_FLAG VAR_LOG_QUERIES VAR_TCP_UPSTREAM VAR_SSL_UPSTREAM
 %token VAR_SSL_SERVICE_KEY VAR_SSL_SERVICE_PEM VAR_SSL_PORT VAR_FORWARD_FIRST
 %token VAR_STUB_FIRST VAR_MINIMAL_RESPONSES VAR_RRSET_ROUNDROBIN
-%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE VAR_UNBLOCK_LAN_ZONES
+%token VAR_MAX_UDP_SIZE VAR_DELAY_CLOSE
+%token VAR_UNBLOCK_LAN_ZONES VAR_INSECURE_LAN_ZONES
 %token VAR_INFRA_CACHE_MIN_RTT
 %token VAR_DNS64_PREFIX VAR_DNS64_SYNTHALL
 %token VAR_DNSTAP VAR_DNSTAP_ENABLE VAR_DNSTAP_SOCKET_PATH
@@ -142,6 +144,7 @@ contents_server: contents_server content
 content_server: server_num_threads | server_verbosity | server_port |
        server_outgoing_range | server_do_ip4 |
        server_do_ip6 | server_do_udp | server_do_tcp | 
+       server_tcp_mss | server_outgoing_tcp_mss |
        server_interface | server_chroot | server_username | 
        server_directory | server_logfile | server_pidfile |
        server_msg_cache_size | server_msg_cache_slabs |
@@ -180,7 +183,8 @@ content_server: server_num_threads | ser
        server_log_queries | server_tcp_upstream | server_ssl_upstream |
        server_ssl_service_key | server_ssl_service_pem | server_ssl_port |
        server_minimal_responses | server_rrset_roundrobin | 
server_max_udp_size |
-       server_so_reuseport | server_delay_close | server_unblock_lan_zones |
+       server_so_reuseport | server_delay_close |
+       server_unblock_lan_zones | server_insecure_lan_zones |
        server_dns64_prefix | server_dns64_synthall |
        server_infra_cache_min_rtt | server_harden_algo_downgrade |
        server_ip_transparent | server_ratelimit | server_ratelimit_slabs |
@@ -395,6 +399,24 @@ server_do_tcp: VAR_DO_TCP STRING_ARG
                free($2);
        }
        ;
+server_tcp_mss: VAR_TCP_MSS STRING_ARG
+       {
+               OUTYY(("P(server_tcp_mss:%s)\n", $2));
+                if(atoi($2) == 0 && strcmp($2, "0") != 0)
+                        yyerror("number expected");
+                else cfg_parser->cfg->tcp_mss = atoi($2);
+                free($2);
+       }
+       ;
+server_outgoing_tcp_mss: VAR_OUTGOING_TCP_MSS STRING_ARG
+       {
+               OUTYY(("P(server_outgoing_tcp_mss:%s)\n", $2));
+               if(atoi($2) == 0 && strcmp($2, "0") != 0)
+                       yyerror("number expected");
+               else cfg_parser->cfg->outgoing_tcp_mss = atoi($2);
+               free($2);
+       }
+       ;
 server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
        {
                OUTYY(("P(server_tcp_upstream:%s)\n", $2));
@@ -722,6 +744,16 @@ server_unblock_lan_zones: VAR_UNBLOCK_LA
                free($2);
        }
        ;
+server_insecure_lan_zones: VAR_INSECURE_LAN_ZONES STRING_ARG
+       {
+               OUTYY(("P(server_insecure_lan_zones:%s)\n", $2));
+               if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+                       yyerror("expected yes or no.");
+               else cfg_parser->cfg->insecure_lan_zones = 
+                       (strcmp($2, "yes")==0);
+               free($2);
+       }
+       ;
 server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG
        {
                OUTYY(("P(server_rrset_cache_size:%s)\n", $2));
@@ -978,7 +1010,7 @@ server_module_conf: VAR_MODULE_CONF STRI
 server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG
        {
                OUTYY(("P(server_val_override_date:%s)\n", $2));
-               if(strlen($2) == 0 || strcmp($2, "0") == 0) {
+               if(*$2 == '\0' || strcmp($2, "0") == 0) {
                        cfg_parser->cfg->val_date_override = 0;
                } else if(strlen($2) == 14) {
                        cfg_parser->cfg->val_date_override = 
@@ -996,7 +1028,7 @@ server_val_override_date: VAR_VAL_OVERRI
 server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG
        {
                OUTYY(("P(server_val_sig_skew_min:%s)\n", $2));
-               if(strlen($2) == 0 || strcmp($2, "0") == 0) {
+               if(*$2 == '\0' || strcmp($2, "0") == 0) {
                        cfg_parser->cfg->val_sig_skew_min = 0;
                } else {
                        cfg_parser->cfg->val_sig_skew_min = atoi($2);
@@ -1009,7 +1041,7 @@ server_val_sig_skew_min: VAR_VAL_SIG_SKE
 server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG
        {
                OUTYY(("P(server_val_sig_skew_max:%s)\n", $2));
-               if(strlen($2) == 0 || strcmp($2, "0") == 0) {
+               if(*$2 == '\0' || strcmp($2, "0") == 0) {
                        cfg_parser->cfg->val_sig_skew_max = 0;
                } else {
                        cfg_parser->cfg->val_sig_skew_max = atoi($2);
Index: util/iana_ports.inc
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/iana_ports.inc,v
retrieving revision 1.3
diff -u -p -r1.3 iana_ports.inc
--- util/iana_ports.inc 15 Dec 2015 20:05:03 -0000      1.3
+++ util/iana_ports.inc 2 Mar 2016 13:44:16 -0000
@@ -4777,9 +4777,12 @@
 8207,
 8208,
 8230,
+8231,
+8232,
 8243,
 8276,
 8280,
+8282,
 8292,
 8294,
 8300,
Index: util/mini_event.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/mini_event.c,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 mini_event.c
--- util/mini_event.c   16 Mar 2014 11:38:23 -0000      1.1.1.3
+++ util/mini_event.c   2 Mar 2016 13:44:16 -0000
@@ -261,12 +261,9 @@ void event_base_free(struct event_base* 
 {
        if(!base)
                return;
-       if(base->times)
-               free(base->times);
-       if(base->fds)
-               free(base->fds);
-       if(base->signals)
-               free(base->signals);
+       free(base->times);
+       free(base->fds);
+       free(base->signals);
        free(base);
 }
 
Index: util/netevent.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/netevent.c,v
retrieving revision 1.9
diff -u -p -r1.9 netevent.c
--- util/netevent.c     19 Jan 2016 23:00:02 -0000      1.9
+++ util/netevent.c     2 Mar 2016 13:44:16 -0000
@@ -56,7 +56,9 @@
 /* -------- Start of local definitions -------- */
 /** if CMSG_ALIGN is not defined on this platform, a workaround */
 #ifndef CMSG_ALIGN
-#  ifdef _CMSG_DATA_ALIGN
+#  ifdef __CMSG_ALIGN
+#    define CMSG_ALIGN(n) __CMSG_ALIGN(n)
+#  elif defined(CMSG_DATA_ALIGN)
 #    define CMSG_ALIGN _CMSG_DATA_ALIGN
 #  else
 #    define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1))
@@ -399,6 +401,31 @@ comm_point_send_udp_msg(struct comm_poin
                sldns_buffer_remaining(packet), 0,
                addr, addrlen);
        if(sent == -1) {
+               /* try again and block, waiting for IO to complete,
+                * we want to send the answer, and we will wait for
+                * the ethernet interface buffer to have space. */
+#ifndef USE_WINSOCK
+               if(errno == EAGAIN || 
+#  ifdef EWOULDBLOCK
+                       errno == EWOULDBLOCK ||
+#  endif
+                       errno == ENOBUFS) {
+#else
+               if(WSAGetLastError() == WSAEINPROGRESS ||
+                       WSAGetLastError() == WSAENOBUFS ||
+                       WSAGetLastError() == WSAEWOULDBLOCK) {
+#endif
+                       int e;
+                       fd_set_block(c->fd);
+                       sent = sendto(c->fd, (void*)sldns_buffer_begin(packet), 
+                               sldns_buffer_remaining(packet), 0,
+                               addr, addrlen);
+                       e = errno;
+                       fd_set_nonblock(c->fd);
+                       errno = e;
+               }
+       }
+       if(sent == -1) {
                if(!udp_send_errno_needs_log(addr, addrlen))
                        return 0;
 #ifndef USE_WINSOCK
@@ -552,11 +579,40 @@ comm_point_send_udp_msg_if(struct comm_p
                p_ancil("send_udp over interface", r);
        sent = sendmsg(c->fd, &msg, 0);
        if(sent == -1) {
+               /* try again and block, waiting for IO to complete,
+                * we want to send the answer, and we will wait for
+                * the ethernet interface buffer to have space. */
+#ifndef USE_WINSOCK
+               if(errno == EAGAIN || 
+#  ifdef EWOULDBLOCK
+                       errno == EWOULDBLOCK ||
+#  endif
+                       errno == ENOBUFS) {
+#else
+               if(WSAGetLastError() == WSAEINPROGRESS ||
+                       WSAGetLastError() == WSAENOBUFS ||
+                       WSAGetLastError() == WSAEWOULDBLOCK) {
+#endif
+                       int e;
+                       fd_set_block(c->fd);
+                       sent = sendmsg(c->fd, &msg, 0);
+                       e = errno;
+                       fd_set_nonblock(c->fd);
+                       errno = e;
+               }
+       }
+       if(sent == -1) {
                if(!udp_send_errno_needs_log(addr, addrlen))
                        return 0;
                verbose(VERB_OPS, "sendmsg failed: %s", strerror(errno));
                log_addr(VERB_OPS, "remote address is", 
                        (struct sockaddr_storage*)addr, addrlen);
+#ifdef __NetBSD__
+               /* netbsd 7 has IP_PKTINFO for recv but not send */
+               if(errno == EINVAL && r->srctype == 4)
+                       log_err("sendmsg: No support for sendmsg(IP_PKTINFO). "
+                               "Please disable interface-automatic");
+#endif
                return 0;
        } else if((size_t)sent != sldns_buffer_remaining(packet)) {
                log_err("sent %d in place of %d bytes", 
Index: util/random.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/random.c,v
retrieving revision 1.4
diff -u -p -r1.4 random.c
--- util/random.c       15 Dec 2015 20:05:03 -0000      1.4
+++ util/random.c       2 Mar 2016 13:44:16 -0000
@@ -228,7 +228,6 @@ ub_random_max(struct ub_randstate* state
 void 
 ub_randfree(struct ub_randstate* s)
 {
-       if(s)
-               free(s);
+       free(s);
        /* user app must do RAND_cleanup(); */
 }
Index: util/tube.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/tube.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 tube.c
--- util/tube.c 16 Mar 2014 11:38:23 -0000      1.1.1.5
+++ util/tube.c 2 Mar 2016 13:44:16 -0000
@@ -118,10 +118,8 @@ void tube_remove_bg_listen(struct tube* 
                comm_point_delete(tube->listen_com);
                tube->listen_com = NULL;
        }
-       if(tube->cmd_msg) {
-               free(tube->cmd_msg);
-               tube->cmd_msg = NULL;
-       }
+       free(tube->cmd_msg);
+       tube->cmd_msg = NULL;
 }
 
 void tube_remove_bg_write(struct tube* tube)
Index: util/winsock_event.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/winsock_event.c,v
retrieving revision 1.1.1.3
diff -u -p -r1.1.1.3 winsock_event.c
--- util/winsock_event.c        16 Mar 2014 11:38:23 -0000      1.1.1.3
+++ util/winsock_event.c        2 Mar 2016 13:44:16 -0000
@@ -459,12 +459,9 @@ void event_base_free(struct event_base *
        verbose(VERB_CLIENT, "winsock_event event_base_free");
         if(!base)
                 return;
-       if(base->items)
-               free(base->items);
-        if(base->times)
-                free(base->times);
-        if(base->signals)
-                free(base->signals);
+       free(base->items);
+        free(base->times);
+        free(base->signals);
         free(base);
 }
 
Index: util/data/packed_rrset.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/data/packed_rrset.c,v
retrieving revision 1.1.1.4
diff -u -p -r1.1.1.4 packed_rrset.c
--- util/data/packed_rrset.c    16 Jul 2015 01:42:20 -0000      1.1.1.4
+++ util/data/packed_rrset.c    2 Mar 2016 13:44:16 -0000
@@ -57,11 +57,9 @@ ub_packed_rrset_parsedelete(struct ub_pa
 {
        if(!pkey)
                return;
-       if(pkey->entry.data)
-               free(pkey->entry.data);
+       free(pkey->entry.data);
        pkey->entry.data = NULL;
-       if(pkey->rk.dname)
-               free(pkey->rk.dname);
+       free(pkey->rk.dname);
        pkey->rk.dname = NULL;
        pkey->id = 0;
        alloc_special_release(alloc, pkey);
Index: validator/val_anchor.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_anchor.c,v
retrieving revision 1.1.1.7
diff -u -p -r1.1.1.7 val_anchor.c
--- validator/val_anchor.c      16 Jul 2015 01:42:20 -0000      1.1.1.7
+++ validator/val_anchor.c      2 Mar 2016 13:44:16 -0000
@@ -48,6 +48,7 @@
 #include "util/log.h"
 #include "util/net_help.h"
 #include "util/config_file.h"
+#include "util/as112.h"
 #include "sldns/sbuffer.h"
 #include "sldns/rrdef.h"
 #include "sldns/str2wire.h"
@@ -1044,8 +1045,18 @@ int 
 anchors_apply_cfg(struct val_anchors* anchors, struct config_file* cfg)
 {
        struct config_strlist* f;
+       const char** zstr;
        char* nm;
        sldns_buffer* parsebuf = sldns_buffer_new(65535);
+       if(cfg->insecure_lan_zones) {
+               for(zstr = as112_zones; *zstr; zstr++) {
+                       if(!anchor_insert_insecure(anchors, *zstr)) {
+                               log_err("error in insecure-lan-zones: %s", 
*zstr);
+                               sldns_buffer_free(parsebuf);
+                               return 0;
+                       }
+               }
+       }
        for(f = cfg->domain_insecure; f; f = f->next) {
                if(!f->str || f->str[0] == 0) /* empty "" */
                        continue;
Index: validator/val_neg.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_neg.c,v
retrieving revision 1.2
diff -u -p -r1.2 val_neg.c
--- validator/val_neg.c 9 Dec 2015 00:59:02 -0000       1.2
+++ validator/val_neg.c 2 Mar 2016 13:44:16 -0000
@@ -823,13 +823,22 @@ void neg_insert_data(struct val_neg_cach
                        (h != zone->nsec3_hash || it != zone->nsec3_iter ||
                        slen != zone->nsec3_saltlen || 
                        memcmp(zone->nsec3_salt, s, slen) != 0)) {
-                       uint8_t* sa = memdup(s, slen);
-                       if(sa) {
+
+                       if(slen > 0) {
+                               uint8_t* sa = memdup(s, slen);
+                               if(sa) {
+                                       free(zone->nsec3_salt);
+                                       zone->nsec3_salt = sa;
+                                       zone->nsec3_saltlen = slen;
+                                       zone->nsec3_iter = it;
+                                       zone->nsec3_hash = h;
+                               }
+                       } else {
                                free(zone->nsec3_salt);
-                               zone->nsec3_salt = sa;
-                               zone->nsec3_saltlen = slen;
-                               zone->nsec3_hash = h;
+                               zone->nsec3_salt = NULL;
+                               zone->nsec3_saltlen = 0;
                                zone->nsec3_iter = it;
+                               zone->nsec3_hash = h;
                        }
                }
        }
Index: validator/val_secalgo.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_secalgo.c,v
retrieving revision 1.2
diff -u -p -r1.2 val_secalgo.c
--- validator/val_secalgo.c     15 Dec 2015 20:05:03 -0000      1.2
+++ validator/val_secalgo.c     2 Mar 2016 13:44:16 -0000
@@ -117,6 +117,8 @@ ds_digest_size_supported(int algo)
 #endif
 #ifdef USE_GOST
                case LDNS_HASH_GOST:
+                       /* we support GOST if it can be loaded */
+                       (void)sldns_key_EVP_load_gost_id();
                        if(EVP_get_digestbyname("md_gost94"))
                                return 32;
                        else    return 0;
Index: validator/val_utils.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_utils.c,v
retrieving revision 1.2
diff -u -p -r1.2 val_utils.c
--- validator/val_utils.c       10 Feb 2015 22:07:42 -0000      1.2
+++ validator/val_utils.c       2 Mar 2016 13:44:16 -0000
@@ -54,6 +54,8 @@
 #include "util/net_help.h"
 #include "util/module.h"
 #include "util/regional.h"
+#include "sldns/wire2str.h"
+#include "sldns/parseutil.h"
 
 enum val_classification 
 val_classify_response(uint16_t query_flags, struct query_info* origqinf,
@@ -690,6 +692,31 @@ val_dsset_isusable(struct ub_packed_rrse
                if(ds_digest_algo_is_supported(ds_rrset, i) &&
                        ds_key_algo_is_supported(ds_rrset, i))
                        return 1;
+       }
+       if(verbosity < VERB_ALGO)
+               return 0;
+       if(rrset_get_count(ds_rrset) == 0)
+               verbose(VERB_ALGO, "DS is not usable");
+       else {
+               /* report usability for the first DS RR */
+               sldns_lookup_table *lt;
+               char herr[64], aerr[64];
+               lt = sldns_lookup_by_id(sldns_hashes,
+                       (int)ds_get_digest_algo(ds_rrset, i));
+               if(lt) snprintf(herr, sizeof(herr), "%s", lt->name);
+               else snprintf(herr, sizeof(herr), "%d",
+                       (int)ds_get_digest_algo(ds_rrset, i));
+               lt = sldns_lookup_by_id(sldns_algorithms,
+                       (int)ds_get_key_algo(ds_rrset, i));
+               if(lt) snprintf(aerr, sizeof(aerr), "%s", lt->name);
+               else snprintf(aerr, sizeof(aerr), "%d",
+                       (int)ds_get_key_algo(ds_rrset, i));
+               verbose(VERB_ALGO, "DS unsupported, hash %s %s, "
+                       "key algorithm %s %s", herr,
+                       (ds_digest_algo_is_supported(ds_rrset, 0)?
+                       "(supported)":"(unsupported)"), aerr, 
+                       (ds_key_algo_is_supported(ds_rrset, 0)?
+                       "(supported)":"(unsupported)"));
        }
        return 0;
 }

Reply via email to