As with NSD I've already committed the typo fixes etc. There's a fair bit of
churn for the optional support for nettle instead of OpenSSL which involves
some nsec3 refactoring so it's a bit long..

Notable addition is qname minimisation support (optional privacy
feature, off by default). In short, "Only send minimum required labels
of the QNAME and set QTYPE to NS when possible" - avoids sending full
query to servers that don't need it.




Index: doc/Changelog
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/Changelog,v
retrieving revision 1.13
diff -u -p -r1.13 Changelog
--- doc/Changelog       10 Dec 2015 17:16:46 -0000      1.13
+++ doc/Changelog       10 Dec 2015 17:31:20 -0000
@@ -1,3 +1,99 @@
+8 December 2015: Wouter
+       - Fixup 724 for unbound-control.
+
+7 December 2015: Ralph
+       - Do not minimise forwarded requests.
+
+4 December 2015: Wouter
+       - Removed unneeded whitespace from example.conf.
+
+3 December 2015: Ralph
+       - (after rc1 tag)
+       - Committed fix to qname minimisation and unit test case for it.
+       
+3 December 2015: Wouter
+       - iana portlist update.
+       - 1.5.7rc1 prerelease tag.
+
+2 December 2015: Wouter
+       - Fixup 724: Fix PCA prompt for unbound-service-install.exe.
+         re-enable stdout printout.
+       - For 724: Add Changelog to windows binary dist.
+
+1 December 2015: Ralph
+       - Qname minimisation review fixes
+
+1 December 2015: Wouter
+       - Fixup 724 fix for fname_after_chroot() calls.
+       - Remove stdout printout for unbound-service-install.exe
+       - .gitignore for git users.
+
+30 November 2015: Ralph
+       - Implemented qname minimisation
+
+30 November 2015: Wouter
+       - Fix for #724: conf syntax to read files from run dir (on Windows).
+
+25 November 2015: Wouter
+       - Fix for #720, fix unbound-control-setup windows batch file.
+
+24 November 2015: Wouter
+       - Fix #720: add windows scripts to zip bundle.
+       - iana portlist update.
+
+20 November 2015: Wouter
+       - Added assert on rrset cache correctness.
+       - Fix that malformed EDNS query gets a response without malformed EDNS.
+
+18 November 2015: Wouter
+       - newer acx_nlnetlabs.m4.
+       - spelling fixes from Igor Sobrado Delgado.
+
+17 November 2015: Wouter
+       - Fix #594. libunbound: optionally use libnettle for crypto.
+         Contributed by Luca Bruno.  Added --with-nettle for use with
+         --with-libunbound-only.
+       - refactor nsec3 hash implementation to be more library-portable.
+       - iana portlist update.
+       - Fixup DER encoded DSA signatures for libnettle.
+
+16 November 2015: Wouter
+       - Fix for lenient accept of reverse order DNAME and CNAME.
+
+6 November 2015: Wouter
+       - Change example.conf: ftp.internic.net to https://www.internic.net
+
+5 November 2015: Wouter
+       - ACX_SSL_CHECKS no longer adds -ldl needlessly.
+
+3 November 2015: Wouter
+       - Fix #718: Fix unbound-control-setup with support for env
+         without HEREDOC bash support.
+
+29 October 2015: Wouter
+       - patch from Doug Hogan for SSL_OP_NO_SSLvx options.
+       - Fix #716: nodata proof with empty non-terminals and wildcards.
+
+28 October 2015: Wouter
+       - Fix checklock testcode for linux threads on exit.
+
+27 October 2015: Wouter
+       - isblank() compat implementation.
+       - detect libexpat without xml_StopParser function.
+       - portability fixes.
+       - portability, replace snprintf if return value broken.
+
+23 October 2015: Wouter
+       - Fix #714: Document config to block private-address for IPv4
+         mapped IPv6 addresses.
+
+22 October 2015: Wouter
+       - Fix #712: unbound-anchor appears to not fsync root.key.
+
+20 October 2015: Wouter
+       - 1.5.6 release.
+       - trunk tracks development of 1.5.7.
+
 15 October 2015: Wouter
        - Fix segfault in the dns64 module in the formaterror error path.
        - Fix sldns_wire2str_rdata_scan for malformed RRs.
Index: daemon/unbound.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/unbound.c,v
retrieving revision 1.10
diff -u -p -r1.10 unbound.c
--- daemon/unbound.c    16 Jul 2015 01:44:00 -0000      1.10
+++ daemon/unbound.c    10 Dec 2015 17:31:19 -0000
@@ -180,6 +180,8 @@ static void usage()
                SSLeay_version(SSLEAY_VERSION)
 #elif defined(HAVE_NSS)
                NSS_GetVersion()
+#elif defined(HAVE_NETTLE)
+               "nettle"
 #endif
                );
        printf("linked modules:");
@@ -449,6 +451,9 @@ perform_setup(struct daemon* daemon, str
                        fatal_exit("user '%s' does not exist.", cfg->username);
                /* endpwent below, in case we need pwd for setusercontext */
        }
+#endif
+#ifdef UB_ON_WINDOWS
+       w_config_adjust_directory(cfg);
 #endif
 
        /* init syslog (as root) if needed, before daemonize, otherwise
Index: daemon/worker.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/daemon/worker.c,v
retrieving revision 1.9
diff -u -p -r1.9 worker.c
--- daemon/worker.c     16 Jul 2015 01:44:00 -0000      1.9
+++ daemon/worker.c     10 Dec 2015 17:31:19 -0000
@@ -866,11 +866,16 @@ worker_handle_request(struct comm_point*
                goto send_reply;
        }
        if((ret=parse_edns_from_pkt(c->buffer, &edns)) != 0) {
+               struct edns_data reply_edns;
                verbose(VERB_ALGO, "worker parse edns: formerror.");
                log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
-               sldns_buffer_rewind(c->buffer);
-               LDNS_QR_SET(sldns_buffer_begin(c->buffer));
+               memset(&reply_edns, 0, sizeof(reply_edns));
+               reply_edns.edns_present = 1;
+               reply_edns.udp_size = EDNS_ADVERTISED_SIZE;
                LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret);
+               error_encode(c->buffer, ret, &qinfo,
+                       *(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
+                       sldns_buffer_read_u16_at(c->buffer, 2), &reply_edns);
                server_stats_insrcode(&worker->stats, c->buffer);
                goto send_reply;
        }
Index: doc/example.conf.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/example.conf.in,v
retrieving revision 1.5
diff -u -p -r1.5 example.conf.in
--- doc/example.conf.in 10 Dec 2015 17:58:00 -0000      1.5
+++ doc/example.conf.in 10 Dec 2015 17:58:18 -0000
@@ -1,7 +1,7 @@
 #
 # Example configuration file.
 #
-# See unbound.conf(5) man page, version 1.5.6.
+# See unbound.conf(5) man page, version 1.5.7.
 #
 # this is a comment.
 
@@ -295,6 +295,11 @@ server:
        # advertised in the DS record.  If no, allows the weakest algorithm
        # to validate the zone.
        # harden-algo-downgrade: no
+
+       # Sent minimum amount of information to upstream servers to enhance
+       # privacy. Only sent minimum required labels of the QNAME and set QTYPE
+       # to NS when possible.
+       # qname-minimisation: no
 
        # Use 0x20-encoded random bits in the query to foil spoof attempts.
        # This feature is an experimental implementation of draft dns-0x20.
Index: doc/unbound.conf.5.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/doc/unbound.conf.5.in,v
retrieving revision 1.7
diff -u -p -r1.7 unbound.conf.5.in
--- doc/unbound.conf.5.in       9 Dec 2015 00:59:02 -0000       1.7
+++ doc/unbound.conf.5.in       10 Dec 2015 17:31:20 -0000
@@ -1,4 +1,4 @@
-.TH "unbound.conf" "5" "Oct 20, 2015" "NLnet Labs" "unbound 1.5.6"
+.TH "unbound.conf" "5" "Dec 10, 2015" "NLnet Labs" "unbound 1.5.7"
 .\"
 .\" unbound.conf.5 -- unbound.conf manual
 .\"
@@ -540,23 +540,30 @@ queries.  For domains that do not suppor
 because they keep sending different answers, like some load balancers.
 Can be given multiple times, for different domains.
 .TP
+.B qname\-minimisation: \fI<yes or no>
+Send minimum amount of information to upstream servers to enhance privacy.
+Only sent minimum required labels of the QNAME and set QTYPE to NS when 
+possible. Best effort approach, full QNAME and original QTYPE will be sent when
+upstream replies with a RCODE other than NOERROR. Default is off.
+.TP
 .B private\-address: \fI<IP address or subnet>
 Give IPv4 of IPv6 addresses or classless subnets. These are addresses
-on your private network, and are not allowed to be returned for public
-internet names.  Any occurence of such addresses are removed from
-DNS answers. Additionally, the DNSSEC validator may mark the answers
-bogus. This protects against so\-called DNS Rebinding, where a user browser
-is turned into a network proxy, allowing remote access through the browser
-to other parts of your private network.  Some names can be allowed to
-contain your private addresses, by default all the \fBlocal\-data\fR
-that you configured is allowed to, and you can specify additional
-names using \fBprivate\-domain\fR.  No private addresses are enabled
-by default.  We consider to enable this for the RFC1918 private IP
-address space by default in later releases. That would enable private 
-addresses for 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16 
-fd00::/8 and fe80::/10, since the RFC standards say these addresses 
-should not be visible on the public internet.  Turning on 127.0.0.0/8 
-would hinder many spamblocklists as they use that.
+on your private network, and are not allowed to be returned for
+public internet names.  Any occurrence of such addresses are removed
+from DNS answers. Additionally, the DNSSEC validator may mark the
+answers bogus. This protects against so\-called DNS Rebinding, where
+a user browser is turned into a network proxy, allowing remote access
+through the browser to other parts of your private network.  Some names
+can be allowed to contain your private addresses, by default all the
+\fBlocal\-data\fR that you configured is allowed to, and you can specify
+additional names using \fBprivate\-domain\fR.  No private addresses are
+enabled by default.  We consider to enable this for the RFC1918 private
+IP address space by default in later releases. That would enable private
+addresses for 10.0.0.0/8 172.16.0.0/12 192.168.0.0/16 169.254.0.0/16
+fd00::/8 and fe80::/10, since the RFC standards say these addresses
+should not be visible on the public internet.  Turning on 127.0.0.0/8
+would hinder many spamblocklists as they use that.  Adding ::ffff:0:0/96
+stops IPv4-mapped IPv6 addresses from bypassing the filter.
 .TP
 .B private\-domain: \fI<domain name>
 Allow this domain, and all its subdomains to contain private addresses.
Index: iterator/iter_scrub.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/iterator/iter_scrub.c,v
retrieving revision 1.4
diff -u -p -r1.4 iter_scrub.c
--- iterator/iter_scrub.c       9 Dec 2015 00:59:02 -0000       1.4
+++ iterator/iter_scrub.c       10 Dec 2015 17:31:20 -0000
@@ -405,7 +405,43 @@ scrub_normalize(sldns_buffer* pkt, struc
 
                /* Follow the CNAME chain. */
                if(rrset->type == LDNS_RR_TYPE_CNAME) {
+                       struct rrset_parse* nx = rrset->rrset_all_next;
                        uint8_t* oldsname = sname;
+                       /* see if the next one is a DNAME, if so, swap them */
+                       if(nx && nx->section == LDNS_SECTION_ANSWER &&
+                               nx->type == LDNS_RR_TYPE_DNAME &&
+                               nx->rr_count == 1 &&
+                               pkt_strict_sub(pkt, sname, nx->dname)) {
+                               /* there is a DNAME after this CNAME, it 
+                                * is in the ANSWER section, and the DNAME
+                                * applies to the name we cover */
+                               /* check if the alias of the DNAME equals
+                                * this CNAME */
+                               uint8_t alias[LDNS_MAX_DOMAINLEN+1];
+                               size_t aliaslen = 0;
+                               uint8_t* t = NULL;
+                               size_t tlen = 0;
+                               if(synth_cname(sname, snamelen, nx, alias,
+                                       &aliaslen, pkt) &&
+                                       parse_get_cname_target(rrset, &t, 
&tlen) &&
+                                       dname_pkt_compare(pkt, alias, t) == 0) {
+                                       /* the synthesized CNAME equals the
+                                        * current CNAME.  This CNAME is the
+                                        * one that the DNAME creates, and this
+                                        * CNAME is better capitalised */
+                                       verbose(VERB_ALGO, "normalize: re-order 
of DNAME and its CNAME");
+                                       if(prev) prev->rrset_all_next = nx;
+                                       else msg->rrset_first = nx;
+                                       if(nx->rrset_all_next == NULL)
+                                               msg->rrset_last = rrset;
+                                       rrset->rrset_all_next =
+                                               nx->rrset_all_next;
+                                       nx->rrset_all_next = rrset;
+                                       prev = nx;
+                               }
+                       }
+
+                       /* move to next name in CNAME chain */
                        if(!parse_get_cname_target(rrset, &sname, &snamelen))
                                return 0;
                        prev = rrset;
Index: iterator/iterator.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/iterator/iterator.c,v
retrieving revision 1.7
diff -u -p -r1.7 iterator.c
--- iterator/iterator.c 9 Dec 2015 00:59:02 -0000       1.7
+++ iterator/iterator.c 10 Dec 2015 17:31:20 -0000
@@ -64,6 +64,7 @@
 #include "util/random.h"
 #include "sldns/rrdef.h"
 #include "sldns/wire2str.h"
+#include "sldns/str2wire.h"
 #include "sldns/parseutil.h"
 #include "sldns/sbuffer.h"
 
@@ -81,6 +82,21 @@ iter_init(struct module_env* env, int id
                log_err("iterator: could not apply configuration settings.");
                return 0;
        }
+       if(env->cfg->qname_minimisation) {
+               uint8_t dname[LDNS_MAX_DOMAINLEN+1];
+               size_t len = sizeof(dname);
+               if(sldns_str2wire_dname_buf("ip6.arpa.", dname, &len) != 0) {
+                       log_err("ip6.arpa. parse error");
+                       return 0;
+               }
+               iter_env->ip6arpa_dname = (uint8_t*)malloc(len);
+               if(!iter_env->ip6arpa_dname) {
+                       log_err("malloc failure");
+                       return 0;
+               }
+               memcpy(iter_env->ip6arpa_dname, dname, len);
+       }
+
        return 1;
 }
 
@@ -101,6 +117,7 @@ iter_deinit(struct module_env* env, int 
        if(!env || !env->modinfo[id])
                return;
        iter_env = (struct iter_env*)env->modinfo[id];
+       free(iter_env->ip6arpa_dname);
        free(iter_env->target_fetch_policy);
        priv_delete(iter_env->priv);
        donotq_delete(iter_env->donotq);
@@ -145,6 +162,12 @@ iter_new(struct module_qstate* qstate, i
        /* Start with the (current) qname. */
        iq->qchase = qstate->qinfo;
        outbound_list_init(&iq->outlist);
+       if (qstate->env->cfg->qname_minimisation)
+               iq->minimisation_state = INIT_MINIMISE_STATE;
+       else
+               iq->minimisation_state = DONOT_MINIMISE_STATE;
+       
+       memset(&iq->qinfo_out, 0, sizeof(struct query_info));
        return 1;
 }
 
@@ -590,6 +613,11 @@ generate_sub_request(uint8_t* qname, siz
                subiq->qchase = subq->qinfo;
                subiq->chase_flags = subq->query_flags;
                subiq->refetch_glue = 0;
+               if(qstate->env->cfg->qname_minimisation)
+                       subiq->minimisation_state = INIT_MINIMISE_STATE;
+               else
+                       subiq->minimisation_state = DONOT_MINIMISE_STATE;
+               memset(&subiq->qinfo_out, 0, sizeof(struct query_info));
        }
        return 1;
 }
@@ -1042,6 +1070,8 @@ processInitRequest(struct module_qstate*
                        iq->query_restart_count++;
                        iq->sent_count = 0;
                        sock_list_insert(&qstate->reply_origin, NULL, 0, 
qstate->region);
+                       if(qstate->env->cfg->qname_minimisation)
+                               iq->minimisation_state = INIT_MINIMISE_STATE;
                        return next_state(iq, INIT_REQUEST_STATE);
                }
 
@@ -1062,6 +1092,7 @@ processInitRequest(struct module_qstate*
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
                }
                iq->refetch_glue = 0;
+               iq->minimisation_state = DONOT_MINIMISE_STATE;
                /* the request has been forwarded.
                 * forwarded requests need to be immediately sent to the 
                 * next state, QUERYTARGETS. */
@@ -1599,6 +1630,8 @@ processLastResort(struct module_qstate* 
                        iq->refetch_glue = 1;
                        iq->query_restart_count++;
                        iq->sent_count = 0;
+                       if(qstate->env->cfg->qname_minimisation)
+                               iq->minimisation_state = INIT_MINIMISE_STATE;
                        return next_state(iq, INIT_REQUEST_STATE);
                }
        }
@@ -1975,9 +2008,78 @@ processQueryTargets(struct module_qstate
                }
        }
 
+       if(iq->minimisation_state == INIT_MINIMISE_STATE) {
+               /* (Re)set qinfo_out to (new) delegation point, except
+                * when qinfo_out is already a subdomain of dp. This happens
+                * when resolving ip6.arpa dnames. */
+               if(!(iq->qinfo_out.qname_len 
+                       && dname_subdomain_c(iq->qchase.qname, 
+                               iq->qinfo_out.qname)
+                       && dname_subdomain_c(iq->qinfo_out.qname, 
+                               iq->dp->name))) {
+                       iq->qinfo_out.qname = iq->dp->name;
+                       iq->qinfo_out.qname_len = iq->dp->namelen;
+                       iq->qinfo_out.qtype = LDNS_RR_TYPE_NS;
+                       iq->qinfo_out.qclass = iq->qchase.qclass;
+               }
+
+               iq->minimisation_state = MINIMISE_STATE;
+       }
+       if(iq->minimisation_state == MINIMISE_STATE) {
+               int labdiff = dname_count_labels(iq->qchase.qname) -
+                       dname_count_labels(iq->qinfo_out.qname);
+
+               iq->qinfo_out.qname = iq->qchase.qname;
+               iq->qinfo_out.qname_len = iq->qchase.qname_len;
+
+               /* Special treatment for ip6.arpa lookups.
+                * Reverse IPv6 dname has 34 labels, increment the IP part 
+                * (usually first 32 labels) by 8 labels (7 more than the 
+                * default 1 label increment). */
+               if(labdiff <= 32 &&
+                       dname_subdomain_c(iq->qchase.qname, ie->ip6arpa_dname)) 
{
+                       labdiff -= 7;
+                       /* Small chance of zone cut after first label. Stop
+                        * minimising */
+                       if(labdiff <= 1)
+                               labdiff = 0;
+               }
+
+               if(labdiff > 1) {
+                       verbose(VERB_QUERY, "removing %d labels", labdiff-1);
+                       dname_remove_labels(&iq->qinfo_out.qname, 
+                               &iq->qinfo_out.qname_len, 
+                               labdiff-1);
+               }
+               if(labdiff < 1 || 
+                       (labdiff < 2 && iq->qchase.qtype == LDNS_RR_TYPE_DS))
+                       /* Stop minimising this query, resolve "as usual" */
+                       iq->minimisation_state = DONOT_MINIMISE_STATE;
+               else {
+                       struct dns_msg* msg = dns_cache_lookup(qstate->env, 
+                               iq->qinfo_out.qname, iq->qinfo_out.qname_len, 
+                               iq->qinfo_out.qtype, iq->qinfo_out.qclass, 
+                               qstate->query_flags, qstate->region, 
+                               qstate->env->scratch);
+                       if(msg && msg->rep->an_numrrsets == 0
+                               && FLAGS_GET_RCODE(msg->rep->flags) == 
+                               LDNS_RCODE_NOERROR)
+                               /* no need to send query if it is already 
+                                * cached as NOERROR/NODATA */
+                               return 1;
+               }
+               
+       }
+       if(iq->minimisation_state == SKIP_MINIMISE_STATE)
+               /* Do not increment qname, continue incrementing next 
+                * iteration */
+               iq->minimisation_state = MINIMISE_STATE;
+       if(iq->minimisation_state == DONOT_MINIMISE_STATE)
+               iq->qinfo_out = iq->qchase;
+
        /* We have a valid target. */
        if(verbosity >= VERB_QUERY) {
-               log_query_info(VERB_QUERY, "sending query:", &iq->qchase);
+               log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out);
                log_name_addr(VERB_QUERY, "sending to target:", iq->dp->name, 
                        &target->addr, target->addrlen);
                verbose(VERB_ALGO, "dnssec status: %s%s",
@@ -1986,8 +2088,8 @@ processQueryTargets(struct module_qstate
        }
        fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query));
        outq = (*qstate->env->send_query)(
-               iq->qchase.qname, iq->qchase.qname_len, 
-               iq->qchase.qtype, iq->qchase.qclass, 
+               iq->qinfo_out.qname, iq->qinfo_out.qname_len, 
+               iq->qinfo_out.qtype, iq->qinfo_out.qclass, 
                iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD, 
                iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted(
                ie, iq), &target->addr, target->addrlen, iq->dp->name,
@@ -2042,6 +2144,9 @@ processQueryResponse(struct module_qstat
        enum response_type type;
        iq->num_current_queries--;
        if(iq->response == NULL) {
+               /* Don't increment qname when QNAME minimisation is enabled */
+               if (qstate->env->cfg->qname_minimisation)
+                       iq->minimisation_state = SKIP_MINIMISE_STATE;
                iq->chase_to_rd = 0;
                iq->dnssec_lame_query = 0;
                verbose(VERB_ALGO, "query response was timeout");
@@ -2142,6 +2247,15 @@ processQueryResponse(struct module_qstat
                        sock_list_insert(&qstate->reply_origin, 
                                &qstate->reply->addr, qstate->reply->addrlen, 
                                qstate->region);
+               if(iq->minimisation_state != DONOT_MINIMISE_STATE) {
+                       /* Best effort qname-minimisation. 
+                        * Stop minimising and send full query when RCODE
+                        * is not NOERROR */
+                       if(FLAGS_GET_RCODE(iq->response->rep->flags) != 
+                               LDNS_RCODE_NOERROR)
+                               iq->minimisation_state = DONOT_MINIMISE_STATE;
+                       return next_state(iq, QUERYTARGETS_STATE);
+               }
                return final_state(iq);
        } else if(type == RESPONSE_TYPE_REFERRAL) {
                /* REFERRAL type responses get a reset of the 
@@ -2201,6 +2315,8 @@ processQueryResponse(struct module_qstat
                 * point to the referral. */
                iq->deleg_msg = iq->response;
                iq->dp = delegpt_from_message(iq->response, qstate->region);
+               if (qstate->env->cfg->qname_minimisation)
+                       iq->minimisation_state = INIT_MINIMISE_STATE;
                if(!iq->dp)
                        return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
                if(!cache_fill_missing(qstate->env, iq->qchase.qclass, 
@@ -2280,6 +2396,8 @@ processQueryResponse(struct module_qstat
                /* set the current request's qname to the new value. */
                iq->qchase.qname = sname;
                iq->qchase.qname_len = snamelen;
+               if (qstate->env->cfg->qname_minimisation)
+                       iq->minimisation_state = INIT_MINIMISE_STATE;
                /* Clear the query state, since this is a query restart. */
                iq->deleg_msg = NULL;
                iq->dp = NULL;
@@ -2353,6 +2471,8 @@ processQueryResponse(struct module_qstat
        /* LAME, THROWAWAY and "unknown" all end up here.
         * Recycle to the QUERYTARGETS state to hopefully try a 
         * different target. */
+       if (qstate->env->cfg->qname_minimisation)
+               iq->minimisation_state = DONOT_MINIMISE_STATE;
        return next_state(iq, QUERYTARGETS_STATE);
 }
 
@@ -2968,7 +3088,7 @@ process_response(struct module_qstate* q
        prs->flags &= ~BIT_CD;
 
        /* normalize and sanitize: easy to delete items from linked lists */
-       if(!scrub_message(pkt, prs, &iq->qchase, iq->dp->name, 
+       if(!scrub_message(pkt, prs, &iq->qinfo_out, iq->dp->name, 
                qstate->env->scratch, qstate->env, ie)) {
                /* if 0x20 enabled, start fallback, but we have no message */
                if(event == module_event_capsfail && !iq->caps_fallback) {
Index: iterator/iterator.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/iterator/iterator.h,v
retrieving revision 1.4
diff -u -p -r1.4 iterator.h
--- iterator/iterator.h 5 Nov 2015 21:29:02 -0000       1.4
+++ iterator/iterator.h 10 Dec 2015 17:31:20 -0000
@@ -112,6 +112,32 @@ struct iter_env {
         * array of max_dependency_depth+1 size.
         */
        int* target_fetch_policy;
+
+       /** ip6.arpa dname in wireformat, used for qname-minimisation */
+       uint8_t* ip6arpa_dname;
+};
+
+/**
+ * QNAME minimisation state
+ */
+enum minimisation_state {
+       /**
+        * (Re)start minimisation. Outgoing QNAME should be set to dp->name.
+        * State entered on new query or after following refferal or CNAME.
+        */
+       INIT_MINIMISE_STATE = 0,
+       /**
+        * QNAME minimisataion ongoing. Increase QNAME on every iteration.
+        */
+       MINIMISE_STATE,
+       /**
+        * Don't increment QNAME this iteration
+        */
+       SKIP_MINIMISE_STATE,
+       /**
+        * Send out full QNAME + original QTYPE
+        */
+       DONOT_MINIMISE_STATE,
 };
 
 /**
@@ -322,6 +348,15 @@ struct iter_qstate {
 
        /** list of pending queries to authoritative servers. */
        struct outbound_list outlist;
+
+       /** QNAME minimisation state */
+       enum minimisation_state minimisation_state;
+
+       /**
+        * The query info that is sent upstream. Will be a subset of qchase
+        * when qname minimisation is enabled.
+        */
+       struct query_info qinfo_out;
 };
 
 /**
Index: libunbound/libunbound.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/libunbound/libunbound.c,v
retrieving revision 1.3
diff -u -p -r1.3 libunbound.c
--- libunbound/libunbound.c     5 Nov 2015 21:29:02 -0000       1.3
+++ libunbound/libunbound.c     10 Dec 2015 17:31:20 -0000
@@ -68,6 +68,9 @@
 #ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
 #endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
 
 #if defined(UB_ON_WINDOWS) && defined (HAVE_WINDOWS_H)
 #include <windows.h>
Index: services/cache/rrset.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/services/cache/rrset.c,v
retrieving revision 1.1.1.4
diff -u -p -r1.1.1.4 rrset.c
--- services/cache/rrset.c      16 Jul 2015 01:42:20 -0000      1.1.1.4
+++ services/cache/rrset.c      10 Dec 2015 17:31:20 -0000
@@ -190,6 +190,7 @@ rrset_cache_update(struct rrset_cache* r
        uint16_t rrset_type = ntohs(k->rk.type);
        int equal = 0;
        log_assert(ref->id != 0 && k->id != 0);
+       log_assert(k->rk.dname != NULL);
        /* looks up item with a readlock - no editing! */
        if((e=slabhash_lookup(&r->table, h, k, 0)) != 0) {
                /* return id and key as they will be used in the cache
Index: smallapp/unbound-anchor.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/smallapp/unbound-anchor.c,v
retrieving revision 1.3
diff -u -p -r1.3 unbound-anchor.c
--- smallapp/unbound-anchor.c   9 Dec 2015 00:59:02 -0000       1.3
+++ smallapp/unbound-anchor.c   10 Dec 2015 17:31:20 -0000
@@ -1520,7 +1520,11 @@ xml_entitydeclhandler(void *userData,
        const XML_Char *ATTR_UNUSED(publicId),
        const XML_Char *ATTR_UNUSED(notationName))
 {
+#if HAVE_DECL_XML_STOPPARSER
        (void)XML_StopParser((XML_Parser)userData, XML_FALSE);
+#else
+       (void)userData;
+#endif
 }
 
 /**
@@ -1828,6 +1832,12 @@ write_unsigned_root(const char* root_anc
                        root_anchor_file);
                if(verb && errno != 0) printf("%s\n", strerror(errno));
        }
+       fflush(out);
+#ifdef HAVE_FSYNC
+       fsync(fileno(out));
+#else
+       FlushFileBuffers((HANDLE)_fileno(out));
+#endif
        fclose(out);
 }
 
@@ -1854,6 +1864,12 @@ write_root_anchor(const char* root_ancho
                        root_anchor_file);
                if(verb && errno != 0) printf("%s\n", strerror(errno));
        }
+       fflush(out);
+#ifdef HAVE_FSYNC
+       fsync(fileno(out));
+#else
+       FlushFileBuffers((HANDLE)_fileno(out));
+#endif
        fclose(out);
 }
 
Index: smallapp/unbound-checkconf.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/smallapp/unbound-checkconf.c,v
retrieving revision 1.1.1.6
diff -u -p -r1.1.1.6 unbound-checkconf.c
--- smallapp/unbound-checkconf.c        16 Jul 2015 01:42:20 -0000      1.1.1.6
+++ smallapp/unbound-checkconf.c        10 Dec 2015 17:31:21 -0000
@@ -335,7 +335,9 @@ morechecks(struct config_file* cfg, cons
        if(cfg->edns_buffer_size > cfg->msg_buffer_size)
                fatal_exit("edns-buffer-size larger than msg-buffer-size, "
                        "answers will not fit in processing buffer");
-
+#ifdef UB_ON_WINDOWS
+       w_config_adjust_directory(cfg);
+#endif
        if(cfg->chrootdir && cfg->chrootdir[0] && 
                cfg->chrootdir[strlen(cfg->chrootdir)-1] == '/')
                fatal_exit("chootdir %s has trailing slash '/' please remove.",
Index: smallapp/unbound-control.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/smallapp/unbound-control.c,v
retrieving revision 1.3
diff -u -p -r1.3 unbound-control.c
--- smallapp/unbound-control.c  5 Nov 2015 21:29:03 -0000       1.3
+++ smallapp/unbound-control.c  10 Dec 2015 17:31:21 -0000
@@ -363,6 +363,9 @@ go(const char* cfgfile, char* svr, int q
                fatal_exit("could not read config file");
        if(!cfg->remote_control_enable)
                log_warn("control-enable is 'no' in the config file.");
+#ifdef UB_ON_WINDOWS
+       w_config_adjust_directory(cfg);
+#endif
        ctx = setup_ctx(cfg);
 
        /* contact server */
Index: util/config_file.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/config_file.c,v
retrieving revision 1.7
diff -u -p -r1.7 config_file.c
--- util/config_file.c  5 Nov 2015 21:29:03 -0000       1.7
+++ util/config_file.c  10 Dec 2015 17:31:21 -0000
@@ -240,6 +240,7 @@ config_create(void)
        cfg->ratelimit_for_domain = NULL;
        cfg->ratelimit_below_domain = NULL;
        cfg->ratelimit_factor = 10;
+       cfg->qname_minimisation = 0;
        return cfg;
 error_exit:
        config_delete(cfg); 
@@ -473,6 +474,7 @@ int config_set_option(struct config_file
        else S_MEMSIZE("ratelimit-size:", ratelimit_size)
        else S_POW2("ratelimit-slabs:", ratelimit_slabs)
        else S_NUMBER_OR_ZERO("ratelimit-factor:", ratelimit_factor)
+       else S_YNO("qname-minimisation:", qname_minimisation)
        /* val_sig_skew_min and max are copied into val_env during init,
         * so this does not update val_env with set_option */
        else if(strcmp(opt, "val-sig-skew-min:") == 0)
@@ -747,6 +749,7 @@ config_get_option(struct config_file* cf
        else O_DEC(opt, "ratelimit-factor", ratelimit_factor)
        else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
        else O_DEC(opt, "val-sig-skew-max", val_sig_skew_max)
+       else O_YNO(opt, "qname-minimisation", qname_minimisation)
        /* not here:
         * outgoing-permit, outgoing-avoid - have list of ports
         * local-zone - zones and nodefault variables
@@ -1554,6 +1557,28 @@ w_lookup_reg_str(const char* key, const 
                if(!result) log_err("out of memory");
        }
        return result;
+}
+
+void w_config_adjust_directory(struct config_file* cfg)
+{
+       if(cfg->directory && cfg->directory[0]) {
+               TCHAR dirbuf[2*MAX_PATH+4];
+               if(strcmp(cfg->directory, "%EXECUTABLE%") == 0) {
+                       /* get executable path, and if that contains
+                        * directories, snip off the filename part */
+                       dirbuf[0] = 0;
+                       if(!GetModuleFileName(NULL, dirbuf, MAX_PATH))
+                               log_err("could not GetModuleFileName");
+                       if(strrchr(dirbuf, '\\')) {
+                               (strrchr(dirbuf, '\\'))[0] = 0;
+                       } else log_err("GetModuleFileName had no path");
+                       if(dirbuf[0]) {
+                               /* adjust directory for later lookups to work*/
+                               free(cfg->directory);
+                               cfg->directory = memdup(dirbuf, 
strlen(dirbuf)+1);
+                       }
+               }
+       }
 }
 #endif /* UB_ON_WINDOWS */
 
Index: util/config_file.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/config_file.h,v
retrieving revision 1.5
diff -u -p -r1.5 config_file.h
--- util/config_file.h  9 Dec 2015 00:59:02 -0000       1.5
+++ util/config_file.h  10 Dec 2015 17:31:21 -0000
@@ -364,6 +364,8 @@ struct config_file {
        struct config_str2list* ratelimit_below_domain;
        /** ratelimit factor, 0 blocks all, 10 allows 1/10 of traffic */
        int ratelimit_factor;
+       /** minimise outgoing QNAME and hide original QTYPE if possible */
+       int qname_minimisation;
 };
 
 /** from cfg username, after daemonise setup performed */
@@ -739,6 +741,9 @@ void ub_c_error_msg(const char* fmt, ...
  *     exist on an error (logged with log_err) was encountered.
  */
 char* w_lookup_reg_str(const char* key, const char* name);
+
+/** Modify directory in options for module file name */
+void w_config_adjust_directory(struct config_file* cfg);
 #endif /* UB_ON_WINDOWS */
 
 #endif /* UTIL_CONFIG_FILE_H */
Index: util/configlexer.lex
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/configlexer.lex,v
retrieving revision 1.2
diff -u -p -r1.2 configlexer.lex
--- util/configlexer.lex        5 Nov 2015 21:29:03 -0000       1.2
+++ util/configlexer.lex        10 Dec 2015 17:31:21 -0000
@@ -205,6 +205,7 @@ SQANY     [^\'\n\r\\]|\\.
        /* note that flex makes the longest match and '.' is any but not nl */
        LEXOUT(("comment(%s) ", yytext)); /* ignore */ }
 server{COLON}                  { YDVAR(0, VAR_SERVER) }
+qname-minimisation{COLON}      { YDVAR(1, VAR_QNAME_MINIMISATION) }
 num-threads{COLON}             { YDVAR(1, VAR_NUM_THREADS) }
 verbosity{COLON}               { YDVAR(1, VAR_VERBOSITY) }
 port{COLON}                    { YDVAR(1, VAR_PORT) }
Index: util/configparser.y
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/configparser.y,v
retrieving revision 1.2
diff -u -p -r1.2 configparser.y
--- util/configparser.y 5 Nov 2015 21:29:03 -0000       1.2
+++ util/configparser.y 10 Dec 2015 17:31:21 -0000
@@ -122,6 +122,7 @@ extern struct config_parser_state* cfg_p
 %token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
 %token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN VAR_RATELIMIT_FACTOR
 %token VAR_CAPS_WHITELIST VAR_CACHE_MAX_NEGATIVE_TTL VAR_PERMIT_SMALL_HOLDDOWN
+%token VAR_QNAME_MINIMISATION
 
 %%
 toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -186,7 +187,7 @@ content_server: server_num_threads | ser
        server_ratelimit_size | server_ratelimit_for_domain |
        server_ratelimit_below_domain | server_ratelimit_factor |
        server_caps_whitelist | server_cache_max_negative_ttl |
-       server_permit_small_holddown
+       server_permit_small_holddown | server_qname_minimisation
        ;
 stubstart: VAR_STUB_ZONE
        {
@@ -1315,6 +1316,16 @@ server_ratelimit_factor: VAR_RATELIMIT_F
                if(atoi($2) == 0 && strcmp($2, "0") != 0)
                        yyerror("number expected");
                else cfg_parser->cfg->ratelimit_factor = atoi($2);
+               free($2);
+       }
+       ;
+server_qname_minimisation: VAR_QNAME_MINIMISATION STRING_ARG
+       {
+               OUTYY(("P(server_qname_minimisation:%s)\n", $2));
+               if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+                       yyerror("expected yes or no.");
+               else cfg_parser->cfg->qname_minimisation = 
+                       (strcmp($2, "yes")==0);
                free($2);
        }
        ;
Index: util/iana_ports.inc
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/iana_ports.inc,v
retrieving revision 1.2
diff -u -p -r1.2 iana_ports.inc
--- util/iana_ports.inc 5 Nov 2015 21:29:03 -0000       1.2
+++ util/iana_ports.inc 10 Dec 2015 17:31:21 -0000
@@ -3843,6 +3843,7 @@
 4406,
 4412,
 4413,
+4416,
 4425,
 4426,
 4430,
@@ -4573,6 +4574,7 @@
 7070,
 7071,
 7080,
+7088,
 7095,
 7099,
 7100,
@@ -5384,6 +5386,7 @@
 38203,
 39681,
 40000,
+40023,
 40841,
 40842,
 40843,
Index: util/random.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/util/random.c,v
retrieving revision 1.3
diff -u -p -r1.3 random.c
--- util/random.c       20 Nov 2014 00:11:14 -0000      1.3
+++ util/random.c       10 Dec 2015 17:31:21 -0000
@@ -68,6 +68,8 @@
 /* nss3 */
 #include "secport.h"
 #include "pk11pub.h"
+#elif defined(HAVE_NETTLE)
+#include "yarrow.h"
 #endif
 
 /** 
@@ -76,7 +78,7 @@
  */
 #define MAX_VALUE 0x7fffffff
 
-#ifndef HAVE_NSS
+#if defined(HAVE_SSL)
 void
 ub_systemseed(unsigned int ATTR_UNUSED(seed))
 {
@@ -110,7 +112,7 @@ ub_random_max(struct ub_randstate* state
        return (long)arc4random_uniform((uint32_t)x);
 }
 
-#else
+#elif defined(HAVE_NSS)
 
 /* not much to remember for NSS since we use its pk11_random, placeholder */
 struct ub_randstate {
@@ -144,6 +146,72 @@ long int ub_random(struct ub_randstate* 
        return x & MAX_VALUE;
 }
 
+#elif defined(HAVE_NETTLE)
+
+/**
+ * libnettle implements a Yarrow-256 generator (SHA256 + AES),
+ * and we have to ensure it is seeded before use.
+ */
+struct ub_randstate {
+       struct yarrow256_ctx ctx;
+       int seeded;
+};
+
+void ub_systemseed(unsigned int ATTR_UNUSED(seed))
+{
+/**
+ * We seed on init and not here, as we need the ctx to re-seed.
+ * This also means that re-seeding is not supported.
+ */
+       log_err("Re-seeding not supported, generator untouched");
+}
+
+struct ub_randstate* ub_initstate(unsigned int seed,
+       struct ub_randstate* ATTR_UNUSED(from))
+{
+       struct ub_randstate* s = (struct ub_randstate*)calloc(1, sizeof(*s));
+       uint8_t buf[YARROW256_SEED_FILE_SIZE];
+       if(!s) {
+               log_err("malloc failure in random init");
+               return NULL;
+       }
+       /* Setup Yarrow context */
+       yarrow256_init(&s->ctx, 0, NULL);
+
+       if(getentropy(buf, sizeof(buf)) != -1) {
+               /* got entropy */
+               yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf);
+               s->seeded = yarrow256_is_seeded(&s->ctx);
+       } else {
+               /* Stretch the uint32 input seed and feed it to Yarrow */
+               uint32_t v = seed;
+               size_t i;
+               for(i=0; i < (YARROW256_SEED_FILE_SIZE/sizeof(seed)); i++) {
+                       memmove(buf+i*sizeof(seed), &v, sizeof(seed));
+                       v = v*seed + (uint32_t)i;
+               }
+               yarrow256_seed(&s->ctx, YARROW256_SEED_FILE_SIZE, buf);
+               s->seeded = yarrow256_is_seeded(&s->ctx);
+       }
+
+       return s;
+}
+
+long int ub_random(struct ub_randstate* s)
+{
+       /* random 31 bit value. */
+       long int x = 0;
+       if (!s || !s->seeded) {
+               log_err("Couldn't generate randomness, Yarrow-256 generator not 
yet seeded");
+       } else {
+               yarrow256_random(&s->ctx, sizeof(x), (uint8_t *)&x);
+       }
+       return x & MAX_VALUE;
+}
+#endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */
+
+
+#if defined(HAVE_NSS) || defined(HAVE_NETTLE)
 long int
 ub_random_max(struct ub_randstate* state, long int x)
 {
@@ -155,7 +223,7 @@ ub_random_max(struct ub_randstate* state
                v = ub_random(state);
        return (v % x);
 }
-#endif /* HAVE_NSS */
+#endif /* HAVE_NSS or HAVE_NETTLE */
 
 void 
 ub_randfree(struct ub_randstate* s)
Index: validator/autotrust.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/autotrust.c,v
retrieving revision 1.3
diff -u -p -r1.3 autotrust.c
--- validator/autotrust.c       9 Dec 2015 00:59:02 -0000       1.3
+++ validator/autotrust.c       10 Dec 2015 17:31:21 -0000
@@ -1195,6 +1195,14 @@ void autr_write_file(struct module_env* 
                fatal_exit("could not completely write: %s", fname);
                return;
        }
+       if(fflush(out) != 0)
+               log_err("could not fflush(%s): %s", fname, strerror(errno));
+#ifdef HAVE_FSYNC
+       if(fsync(fileno(out)) != 0)
+               log_err("could not fsync(%s): %s", fname, strerror(errno));
+#else
+       FlushFileBuffers((HANDLE)_fileno(out));
+#endif
        if(fclose(out) != 0) {
                fatal_exit("could not complete write: %s: %s",
                        fname, strerror(errno));
Index: validator/val_nsec.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_nsec.c,v
retrieving revision 1.2
diff -u -p -r1.2 val_nsec.c
--- validator/val_nsec.c        9 Dec 2015 00:59:02 -0000       1.2
+++ validator/val_nsec.c        10 Dec 2015 17:31:21 -0000
@@ -340,6 +340,28 @@ int nsec_proves_nodata(struct ub_packed_
                                *wc = ce;
                                return 1;
                        }
+               } else {
+                       /* See if the next owner name covers a wildcard
+                        * empty non-terminal. */
+                       while (dname_strict_subdomain_c(nm, nsec->rk.dname)) {
+                               /* wildcard does not apply if qname below
+                                * the name that exists under the '*' */
+                               if (dname_subdomain_c(qinfo->qname, nm))
+                                       break;
+                               /* but if it is a wildcard and qname is below
+                                * it, then the wildcard applies. The wildcard
+                                * is an empty nonterminal. nodata proven. */
+                               if (dname_is_wild(nm)) {
+                                       size_t ce_len = ln;
+                                       uint8_t* ce = nm;
+                                       dname_remove_label(&ce, &ce_len);
+                                       
if(dname_strict_subdomain_c(qinfo->qname, ce)) {
+                                               *wc = ce;
+                                               return 1;
+                                       }
+                               }
+                               dname_remove_label(&nm, &ln);
+                       }
                }
 
                /* Otherwise, this NSEC does not prove ENT and is not a 
Index: validator/val_nsec3.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_nsec3.c,v
retrieving revision 1.2
diff -u -p -r1.2 val_nsec3.c
--- validator/val_nsec3.c       9 Dec 2015 00:59:02 -0000       1.2
+++ validator/val_nsec3.c       10 Dec 2015 17:31:21 -0000
@@ -42,14 +42,8 @@
  */
 #include "config.h"
 #include <ctype.h>
-#ifdef HAVE_OPENSSL_SSL_H
-#include "openssl/ssl.h"
-#endif
-#ifdef HAVE_NSS
-/* nss3 */
-#include "sechash.h"
-#endif
 #include "validator/val_nsec3.h"
+#include "validator/val_secalgo.h"
 #include "validator/validator.h"
 #include "validator/val_kentry.h"
 #include "services/cache/rrset.h"
@@ -370,8 +364,8 @@ filter_next(struct nsec3_filter* filter,
 /**
  * Start iterating over NSEC3 records.
  * @param filter: the filter structure, must have been filter_init-ed.
- * @param rrsetnum: can be undefined on call, inited.
- * @param rrnum: can be undefined on call, inited.
+ * @param rrsetnum: can be undefined on call, initialised.
+ * @param rrnum: can be undefined on call, initialised.
  * @return first rrset of an NSEC3, together with rrnum this points to
  *     the first RR to examine. Is NULL on empty list.
  */
@@ -545,46 +539,24 @@ nsec3_get_hashed(sldns_buffer* buf, uint
        query_dname_tolower(sldns_buffer_begin(buf));
        sldns_buffer_write(buf, salt, saltlen);
        sldns_buffer_flip(buf);
-       switch(algo) {
-#if defined(HAVE_EVP_SHA1) || defined(HAVE_NSS)
-               case NSEC3_HASH_SHA1:
-#ifdef HAVE_SSL
-                       hash_len = SHA_DIGEST_LENGTH;
-#else
-                       hash_len = SHA1_LENGTH;
-#endif
-                       if(hash_len > max)
-                               return 0;
-#  ifdef HAVE_SSL
-                       (void)SHA1((unsigned char*)sldns_buffer_begin(buf),
-                               (unsigned long)sldns_buffer_limit(buf),
-                               (unsigned char*)res);
-#  else
-                       (void)HASH_HashBuf(HASH_AlgSHA1, (unsigned char*)res,
-                               (unsigned char*)sldns_buffer_begin(buf),
-                               (unsigned long)sldns_buffer_limit(buf));
-#  endif
-                       for(i=0; i<iter; i++) {
-                               sldns_buffer_clear(buf);
-                               sldns_buffer_write(buf, res, hash_len);
-                               sldns_buffer_write(buf, salt, saltlen);
-                               sldns_buffer_flip(buf);
-#  ifdef HAVE_SSL
-                               (void)SHA1(
-                                       (unsigned char*)sldns_buffer_begin(buf),
-                                       (unsigned long)sldns_buffer_limit(buf),
-                                       (unsigned char*)res);
-#  else
-                               (void)HASH_HashBuf(HASH_AlgSHA1,
-                                       (unsigned char*)res,
-                                       (unsigned char*)sldns_buffer_begin(buf),
-                                       (unsigned long)sldns_buffer_limit(buf));
-#  endif
-                       }
-                       break;
-#endif /* HAVE_EVP_SHA1 or NSS */
-               default:
-                       log_err("nsec3 hash of unknown algo %d", algo);
+       hash_len = nsec3_hash_algo_size_supported(algo);
+       if(hash_len == 0) {
+               log_err("nsec3 hash of unknown algo %d", algo);
+               return 0;
+       }
+       if(hash_len > max)
+               return 0;
+       if(!secalgo_nsec3_hash(algo, (unsigned char*)sldns_buffer_begin(buf),
+               sldns_buffer_limit(buf), (unsigned char*)res))
+               return 0;
+       for(i=0; i<iter; i++) {
+               sldns_buffer_clear(buf);
+               sldns_buffer_write(buf, res, hash_len);
+               sldns_buffer_write(buf, salt, saltlen);
+               sldns_buffer_flip(buf);
+               if(!secalgo_nsec3_hash(algo,
+                       (unsigned char*)sldns_buffer_begin(buf),
+                       sldns_buffer_limit(buf), (unsigned char*)res))
                        return 0;
        }
        return hash_len;
@@ -607,50 +579,24 @@ nsec3_calc_hash(struct regional* region,
        query_dname_tolower(sldns_buffer_begin(buf));
        sldns_buffer_write(buf, salt, saltlen);
        sldns_buffer_flip(buf);
-       switch(algo) {
-#if defined(HAVE_EVP_SHA1) || defined(HAVE_NSS)
-               case NSEC3_HASH_SHA1:
-#ifdef HAVE_SSL
-                       c->hash_len = SHA_DIGEST_LENGTH;
-#else
-                       c->hash_len = SHA1_LENGTH;
-#endif
-                       c->hash = (uint8_t*)regional_alloc(region, 
-                               c->hash_len);
-                       if(!c->hash)
-                               return 0;
-#  ifdef HAVE_SSL
-                       (void)SHA1((unsigned char*)sldns_buffer_begin(buf),
-                               (unsigned long)sldns_buffer_limit(buf),
-                               (unsigned char*)c->hash);
-#  else
-                       (void)HASH_HashBuf(HASH_AlgSHA1,
-                               (unsigned char*)c->hash,
-                               (unsigned char*)sldns_buffer_begin(buf),
-                               (unsigned long)sldns_buffer_limit(buf));
-#  endif
-                       for(i=0; i<iter; i++) {
-                               sldns_buffer_clear(buf);
-                               sldns_buffer_write(buf, c->hash, c->hash_len);
-                               sldns_buffer_write(buf, salt, saltlen);
-                               sldns_buffer_flip(buf);
-#  ifdef HAVE_SSL
-                               (void)SHA1(
-                                       (unsigned char*)sldns_buffer_begin(buf),
-                                       (unsigned long)sldns_buffer_limit(buf),
-                                       (unsigned char*)c->hash);
-#  else
-                               (void)HASH_HashBuf(HASH_AlgSHA1,
-                                       (unsigned char*)c->hash,
-                                       (unsigned char*)sldns_buffer_begin(buf),
-                                       (unsigned long)sldns_buffer_limit(buf));
-#  endif
-                       }
-                       break;
-#endif /* HAVE_EVP_SHA1 or NSS */
-               default:
-                       log_err("nsec3 hash of unknown algo %d", algo);
-                       return -1;
+       c->hash_len = nsec3_hash_algo_size_supported(algo);
+       if(c->hash_len == 0) {
+               log_err("nsec3 hash of unknown algo %d", algo);
+               return -1;
+       }
+       c->hash = (uint8_t*)regional_alloc(region, c->hash_len);
+       if(!c->hash)
+               return 0;
+       (void)secalgo_nsec3_hash(algo, (unsigned char*)sldns_buffer_begin(buf),
+               sldns_buffer_limit(buf), (unsigned char*)c->hash);
+       for(i=0; i<iter; i++) {
+               sldns_buffer_clear(buf);
+               sldns_buffer_write(buf, c->hash, c->hash_len);
+               sldns_buffer_write(buf, salt, saltlen);
+               sldns_buffer_flip(buf);
+               (void)secalgo_nsec3_hash(algo,
+                       (unsigned char*)sldns_buffer_begin(buf),
+                       sldns_buffer_limit(buf), (unsigned char*)c->hash);
        }
        return 1;
 }
Index: validator/val_secalgo.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_secalgo.c,v
retrieving revision 1.1.1.5
diff -u -p -r1.1.1.5 val_secalgo.c
--- validator/val_secalgo.c     16 Jul 2015 01:42:20 -0000      1.1.1.5
+++ validator/val_secalgo.c     10 Dec 2015 17:31:21 -0000
@@ -44,12 +44,13 @@
 /* packed_rrset on top to define enum types (forced by c99 standard) */
 #include "util/data/packed_rrset.h"
 #include "validator/val_secalgo.h"
+#include "validator/val_nsec3.h"
 #include "util/log.h"
 #include "sldns/rrdef.h"
 #include "sldns/keyraw.h"
 #include "sldns/sbuffer.h"
 
-#if !defined(HAVE_SSL) && !defined(HAVE_NSS)
+#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
 #error "Need crypto library to do digital signature cryptography"
 #endif
 
@@ -71,10 +72,36 @@
 #include <openssl/engine.h>
 #endif
 
+/* return size of digest if supported, or 0 otherwise */
+size_t
+nsec3_hash_algo_size_supported(int id)
+{
+       switch(id) {
+       case NSEC3_HASH_SHA1:
+               return SHA_DIGEST_LENGTH;
+       default:
+               return 0;
+       }
+}
+
+/* perform nsec3 hash. return false on failure */
+int
+secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
+        unsigned char* res)
+{
+       switch(algo) {
+       case NSEC3_HASH_SHA1:
+               (void)SHA1(buf, len, res);
+               return 1;
+       default:
+               return 0;
+       }
+}
+
 /**
  * Return size of DS digest according to its hash algorithm.
  * @param algo: DS digest algo.
- * @return size in bytes of digest, or 0 if not supported. 
+ * @return size in bytes of digest, or 0 if not supported.
  */
 size_t
 ds_digest_size_supported(int algo)
@@ -565,6 +592,32 @@ verify_canonrrset(sldns_buffer* buf, int
 /* nspr4 */
 #include "prerror.h"
 
+/* return size of digest if supported, or 0 otherwise */
+size_t
+nsec3_hash_algo_size_supported(int id)
+{
+       switch(id) {
+       case NSEC3_HASH_SHA1:
+               return SHA1_LENGTH;
+       default:
+               return 0;
+       }
+}
+
+/* perform nsec3 hash. return false on failure */
+int
+secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
+        unsigned char* res)
+{
+       switch(algo) {
+       case NSEC3_HASH_SHA1:
+               (void)HASH_HashBuf(HASH_AlgSHA1, res, buf, (unsigned long)len);
+               return 1;
+       default:
+               return 0;
+       }
+}
+
 size_t
 ds_digest_size_supported(int algo)
 {
@@ -1069,5 +1122,466 @@ verify_canonrrset(sldns_buffer* buf, int
        return sec_status_bogus;
 }
 
+#elif defined(HAVE_NETTLE)
+
+#include "sha.h"
+#include "bignum.h"
+#include "macros.h"
+#include "rsa.h"
+#include "dsa.h"
+#include "asn1.h"
+#ifdef USE_ECDSA
+#include "ecdsa.h"
+#include "ecc-curve.h"
+#endif
+
+static int
+_digest_nettle(int algo, uint8_t* buf, size_t len,
+       unsigned char* res)
+{
+       switch(algo) {
+               case SHA1_DIGEST_SIZE:
+               {
+                       struct sha1_ctx ctx;
+                       sha1_init(&ctx);
+                       sha1_update(&ctx, len, buf);
+                       sha1_digest(&ctx, SHA1_DIGEST_SIZE, res);
+                       return 1;
+               }
+               case SHA256_DIGEST_SIZE:
+               {
+                       struct sha256_ctx ctx;
+                       sha256_init(&ctx);
+                       sha256_update(&ctx, len, buf);
+                       sha256_digest(&ctx, SHA256_DIGEST_SIZE, res);
+                       return 1;
+               }
+               case SHA384_DIGEST_SIZE:
+               {
+                       struct sha384_ctx ctx;
+                       sha384_init(&ctx);
+                       sha384_update(&ctx, len, buf);
+                       sha384_digest(&ctx, SHA384_DIGEST_SIZE, res);
+                       return 1;
+               }
+               case SHA512_DIGEST_SIZE:
+               {
+                       struct sha512_ctx ctx;
+                       sha512_init(&ctx);
+                       sha512_update(&ctx, len, buf);
+                       sha512_digest(&ctx, SHA512_DIGEST_SIZE, res);
+                       return 1;
+               }
+               default:
+                       break;
+       }
+       return 0;
+}
+
+/* return size of digest if supported, or 0 otherwise */
+size_t
+nsec3_hash_algo_size_supported(int id)
+{
+       switch(id) {
+       case NSEC3_HASH_SHA1:
+               return SHA1_DIGEST_SIZE;
+       default:
+               return 0;
+       }
+}
+
+/* perform nsec3 hash. return false on failure */
+int
+secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
+        unsigned char* res)
+{
+       switch(algo) {
+       case NSEC3_HASH_SHA1:
+               return _digest_nettle(SHA1_DIGEST_SIZE, (uint8_t*)buf, len,
+                       res);
+       default:
+               return 0;
+       }
+}
+
+/**
+ * Return size of DS digest according to its hash algorithm.
+ * @param algo: DS digest algo.
+ * @return size in bytes of digest, or 0 if not supported.
+ */
+size_t
+ds_digest_size_supported(int algo)
+{
+       switch(algo) {
+               case LDNS_SHA1:
+                       return SHA1_DIGEST_SIZE;
+#ifdef USE_SHA2
+               case LDNS_SHA256:
+                       return SHA256_DIGEST_SIZE;
+#endif
+#ifdef USE_ECDSA
+               case LDNS_SHA384:
+                       return SHA384_DIGEST_SIZE;
+#endif
+               /* GOST not supported */
+               case LDNS_HASH_GOST:
+               default:
+                       break;
+       }
+       return 0;
+}
+
+int
+secalgo_ds_digest(int algo, unsigned char* buf, size_t len,
+       unsigned char* res)
+{
+       switch(algo) {
+               case LDNS_SHA1:
+                       return _digest_nettle(SHA1_DIGEST_SIZE, buf, len, res);
+#if defined(USE_SHA2)
+               case LDNS_SHA256:
+                       return _digest_nettle(SHA256_DIGEST_SIZE, buf, len, 
res);
+#endif
+#ifdef USE_ECDSA
+               case LDNS_SHA384:
+                       return _digest_nettle(SHA384_DIGEST_SIZE, buf, len, 
res);
+
+#endif
+               case LDNS_HASH_GOST:
+               default:
+                       verbose(VERB_QUERY, "unknown DS digest algorithm %d",
+                               algo);
+                       break;
+       }
+       return 0;
+}
+
+int
+dnskey_algo_id_is_supported(int id)
+{
+       /* uses libnettle */
+       switch(id) {
+       case LDNS_DSA:
+       case LDNS_DSA_NSEC3:
+       case LDNS_RSASHA1:
+       case LDNS_RSASHA1_NSEC3:
+#ifdef USE_SHA2
+       case LDNS_RSASHA256:
+       case LDNS_RSASHA512:
+#endif
+#ifdef USE_ECDSA
+       case LDNS_ECDSAP256SHA256:
+       case LDNS_ECDSAP384SHA384:
+#endif
+               return 1;
+       case LDNS_RSAMD5: /* RFC 6725 deprecates RSAMD5 */
+       case LDNS_ECC_GOST:
+       default:
+               return 0;
+       }
+}
+
+static char *
+_verify_nettle_dsa(sldns_buffer* buf, unsigned char* sigblock,
+       unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
+{
+       uint8_t digest[SHA1_DIGEST_SIZE];
+       uint8_t key_t;
+       int res = 0;
+       size_t offset;
+       struct dsa_public_key pubkey;
+       struct dsa_signature signature;
+       unsigned int expected_len;
+
+       /* Extract DSA signature from the record */
+       nettle_dsa_signature_init(&signature);
+       /* Signature length: 41 bytes - RFC 2536 sec. 3 */
+       if(sigblock_len == 41) {
+               if(key[0] != sigblock[0])
+                       return "invalid T value in DSA signature or pubkey";
+               nettle_mpz_set_str_256_u(signature.r, 20, sigblock+1);
+               nettle_mpz_set_str_256_u(signature.s, 20, sigblock+1+20);
+       } else {
+               /* DER encoded, decode the ASN1 notated R and S bignums */
+               /* SEQUENCE { r INTEGER, s INTEGER } */
+               struct asn1_der_iterator i, seq;
+               if(asn1_der_iterator_first(&i, sigblock_len,
+                       (uint8_t*)sigblock) != ASN1_ITERATOR_CONSTRUCTED
+                       || i.type != ASN1_SEQUENCE)
+                       return "malformed DER encoded DSA signature";
+               /* decode this element of i using the seq iterator */
+               if(asn1_der_decode_constructed(&i, &seq) !=
+                       ASN1_ITERATOR_PRIMITIVE || seq.type != ASN1_INTEGER)
+                       return "malformed DER encoded DSA signature";
+               if(!asn1_der_get_bignum(&seq, signature.r, 20*8))
+                       return "malformed DER encoded DSA signature";
+               if(asn1_der_iterator_next(&seq) != ASN1_ITERATOR_PRIMITIVE
+                       || seq.type != ASN1_INTEGER)
+                       return "malformed DER encoded DSA signature";
+               if(!asn1_der_get_bignum(&seq, signature.s, 20*8))
+                       return "malformed DER encoded DSA signature";
+               if(asn1_der_iterator_next(&i) != ASN1_ITERATOR_END)
+                       return "malformed DER encoded DSA signature";
+       }
+
+       /* Validate T values constraints - RFC 2536 sec. 2 & sec. 3 */
+       key_t = key[0];
+       if (key_t > 8) {
+               return "invalid T value in DSA pubkey";
+       }
+
+       /* Pubkey minimum length: 21 bytes - RFC 2536 sec. 2 */
+       if (keylen < 21) {
+               return "DSA pubkey too short";
+       }
+
+       expected_len =   1 +            /* T */
+                       20 +            /* Q */
+                      (64 + key_t*8) + /* P */
+                      (64 + key_t*8) + /* G */
+                      (64 + key_t*8);  /* Y */
+       if (keylen != expected_len ) {
+               return "invalid DSA pubkey length";
+       }
+
+       /* Extract DSA pubkey from the record */
+       nettle_dsa_public_key_init(&pubkey);
+       offset = 1;
+       nettle_mpz_set_str_256_u(pubkey.q, 20, key+offset);
+       offset += 20;
+       nettle_mpz_set_str_256_u(pubkey.p, (64 + key_t*8), key+offset);
+       offset += (64 + key_t*8);
+       nettle_mpz_set_str_256_u(pubkey.g, (64 + key_t*8), key+offset);
+       offset += (64 + key_t*8);
+       nettle_mpz_set_str_256_u(pubkey.y, (64 + key_t*8), key+offset);
+
+       /* Digest content of "buf" and verify its DSA signature in "sigblock"*/
+       res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned 
char*)sldns_buffer_begin(buf),
+                                               (unsigned 
int)sldns_buffer_limit(buf), (unsigned char*)digest);
+       res &= dsa_sha1_verify_digest(&pubkey, digest, &signature);
+
+       /* Clear and return */
+       nettle_dsa_signature_clear(&signature);
+       nettle_dsa_public_key_clear(&pubkey);
+       if (!res)
+               return "DSA signature verification failed";
+       else
+               return NULL;
+}
+
+static char *
+_verify_nettle_rsa(sldns_buffer* buf, unsigned int digest_size, char* sigblock,
+       unsigned int sigblock_len, uint8_t* key, unsigned int keylen)
+{
+       uint16_t exp_len = 0;
+       size_t exp_offset = 0, mod_offset = 0;
+       struct rsa_public_key pubkey;
+       mpz_t signature;
+       int res = 0;
+
+       /* RSA pubkey parsing as per RFC 3110 sec. 2 */
+       if( keylen <= 1) {
+               return "null RSA key";
+       }
+       if (key[0] != 0) {
+               /* 1-byte length */
+               exp_len = key[0];
+               exp_offset = 1;
+       } else {
+               /* 1-byte NUL + 2-bytes exponent length */
+               if (keylen < 3) {
+                       return "incorrect RSA key length";
+               }
+               exp_len = READ_UINT16(key+1);
+               if (exp_len == 0)
+                       return "null RSA exponent length";
+               exp_offset = 3;
+       }
+       /* Check that we are not over-running input length */
+       if (keylen < exp_offset + exp_len + 1) {
+               return "RSA key content shorter than expected";
+       }
+       mod_offset = exp_offset + exp_len;
+       nettle_rsa_public_key_init(&pubkey);
+       pubkey.size = keylen - mod_offset;
+       nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]);
+       nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]);
+
+       /* Digest content of "buf" and verify its RSA signature in "sigblock"*/
+       nettle_mpz_init_set_str_256_u(signature, sigblock_len, 
(uint8_t*)sigblock);
+       switch (digest_size) {
+               case SHA1_DIGEST_SIZE:
+               {
+                       uint8_t digest[SHA1_DIGEST_SIZE];
+                       res = _digest_nettle(SHA1_DIGEST_SIZE, (unsigned 
char*)sldns_buffer_begin(buf),
+                                               (unsigned 
int)sldns_buffer_limit(buf), (unsigned char*)digest);
+                       res &= rsa_sha1_verify_digest(&pubkey, digest, 
signature);
+                       break;
+               }
+               case SHA256_DIGEST_SIZE:
+               {
+                       uint8_t digest[SHA256_DIGEST_SIZE];
+                       res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned 
char*)sldns_buffer_begin(buf),
+                                               (unsigned 
int)sldns_buffer_limit(buf), (unsigned char*)digest);
+                       res &= rsa_sha256_verify_digest(&pubkey, digest, 
signature);
+                       break;
+               }
+               case SHA512_DIGEST_SIZE:
+               {
+                       uint8_t digest[SHA512_DIGEST_SIZE];
+                       res = _digest_nettle(SHA512_DIGEST_SIZE, (unsigned 
char*)sldns_buffer_begin(buf),
+                                               (unsigned 
int)sldns_buffer_limit(buf), (unsigned char*)digest);
+                       res &= rsa_sha512_verify_digest(&pubkey, digest, 
signature);
+                       break;
+               }
+               default:
+                       break;
+       }
+
+       /* Clear and return */
+       nettle_rsa_public_key_clear(&pubkey);
+       mpz_clear(signature);
+       if (!res) {
+               return "RSA signature verification failed";
+       } else {
+               return NULL;
+       }
+}
+
+#ifdef USE_ECDSA
+static char *
+_verify_nettle_ecdsa(sldns_buffer* buf, unsigned int digest_size, unsigned 
char* sigblock,
+       unsigned int sigblock_len, unsigned char* key, unsigned int keylen)
+{
+       int res = 0;
+       struct ecc_point pubkey;
+       struct dsa_signature signature;
+
+       /* Always matched strength, as per RFC 6605 sec. 1 */
+       if (sigblock_len != 2*digest_size || keylen != 2*digest_size) {
+               return "wrong ECDSA signature length";
+       }
+
+       /* Parse ECDSA signature as per RFC 6605 sec. 4 */
+       nettle_dsa_signature_init(&signature);
+       switch (digest_size) {
+               case SHA256_DIGEST_SIZE:
+               {
+                       uint8_t digest[SHA256_DIGEST_SIZE];
+                       mpz_t x, y;
+                       nettle_ecc_point_init(&pubkey, &nettle_secp_256r1);
+                       nettle_mpz_init_set_str_256_u(x, SHA256_DIGEST_SIZE, 
key);
+                       nettle_mpz_init_set_str_256_u(y, SHA256_DIGEST_SIZE, 
key+SHA256_DIGEST_SIZE);
+                       nettle_mpz_set_str_256_u(signature.r, 
SHA256_DIGEST_SIZE, sigblock);
+                       nettle_mpz_set_str_256_u(signature.s, 
SHA256_DIGEST_SIZE, sigblock+SHA256_DIGEST_SIZE);
+                       res = _digest_nettle(SHA256_DIGEST_SIZE, (unsigned 
char*)sldns_buffer_begin(buf),
+                                               (unsigned 
int)sldns_buffer_limit(buf), (unsigned char*)digest);
+                       res &= nettle_ecc_point_set(&pubkey, x, y);
+                       res &= nettle_ecdsa_verify (&pubkey, 
SHA256_DIGEST_SIZE, digest, &signature);
+                       mpz_clear(x);
+                       mpz_clear(y);
+                       break;
+               }
+               case SHA384_DIGEST_SIZE:
+               {
+                       uint8_t digest[SHA384_DIGEST_SIZE];
+                       mpz_t x, y;
+                       nettle_ecc_point_init(&pubkey, &nettle_secp_384r1);
+                       nettle_mpz_init_set_str_256_u(x, SHA384_DIGEST_SIZE, 
key);
+                       nettle_mpz_init_set_str_256_u(y, SHA384_DIGEST_SIZE, 
key+SHA384_DIGEST_SIZE);
+                       nettle_mpz_set_str_256_u(signature.r, 
SHA384_DIGEST_SIZE, sigblock);
+                       nettle_mpz_set_str_256_u(signature.s, 
SHA384_DIGEST_SIZE, sigblock+SHA384_DIGEST_SIZE);
+                       res = _digest_nettle(SHA384_DIGEST_SIZE, (unsigned 
char*)sldns_buffer_begin(buf),
+                                               (unsigned 
int)sldns_buffer_limit(buf), (unsigned char*)digest);
+                       res &= nettle_ecc_point_set(&pubkey, x, y);
+                       res &= nettle_ecdsa_verify (&pubkey, 
SHA384_DIGEST_SIZE, digest, &signature);
+                       mpz_clear(x);
+                       mpz_clear(y);
+                       nettle_ecc_point_clear(&pubkey);
+                       break;
+               }
+               default:
+                       return "unknown ECDSA algorithm";
+       }
+
+       /* Clear and return */
+       nettle_dsa_signature_clear(&signature);
+       if (!res)
+               return "ECDSA signature verification failed";
+       else
+               return NULL;
+}
+#endif
+
+/**
+ * Check a canonical sig+rrset and signature against a dnskey
+ * @param buf: buffer with data to verify, the first rrsig part and the
+ *     canonicalized rrset.
+ * @param algo: DNSKEY algorithm.
+ * @param sigblock: signature rdata field from RRSIG
+ * @param sigblock_len: length of sigblock data.
+ * @param key: public key data from DNSKEY RR.
+ * @param keylen: length of keydata.
+ * @param reason: bogus reason in more detail.
+ * @return secure if verification succeeded, bogus on crypto failure,
+ *     unchecked on format errors and alloc failures.
+ */
+enum sec_status
+verify_canonrrset(sldns_buffer* buf, int algo, unsigned char* sigblock,
+       unsigned int sigblock_len, unsigned char* key, unsigned int keylen,
+       char** reason)
+{
+       unsigned int digest_size = 0;
+
+       if (sigblock_len == 0 || keylen == 0) {
+               *reason = "null signature";
+               return sec_status_bogus;
+       }
+
+       switch(algo) {
+       case LDNS_DSA:
+       case LDNS_DSA_NSEC3:
+               *reason = _verify_nettle_dsa(buf, sigblock, sigblock_len, key, 
keylen);
+               if (*reason != NULL)
+                       return sec_status_bogus;
+               else
+                       return sec_status_secure;
+
+       case LDNS_RSASHA1:
+       case LDNS_RSASHA1_NSEC3:
+               digest_size = (digest_size ? digest_size : SHA1_DIGEST_SIZE);
+#ifdef USE_SHA2
+       case LDNS_RSASHA256:
+               digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
+       case LDNS_RSASHA512:
+               digest_size = (digest_size ? digest_size : SHA512_DIGEST_SIZE);
+
+#endif
+               *reason = _verify_nettle_rsa(buf, digest_size, (char*)sigblock,
+                                               sigblock_len, key, keylen);
+               if (*reason != NULL)
+                       return sec_status_bogus;
+               else
+                       return sec_status_secure;
+
+#ifdef USE_ECDSA
+       case LDNS_ECDSAP256SHA256:
+               digest_size = (digest_size ? digest_size : SHA256_DIGEST_SIZE);
+       case LDNS_ECDSAP384SHA384:
+               digest_size = (digest_size ? digest_size : SHA384_DIGEST_SIZE);
+               *reason = _verify_nettle_ecdsa(buf, digest_size, sigblock,
+                                               sigblock_len, key, keylen);
+               if (*reason != NULL)
+                       return sec_status_bogus;
+               else
+                       return sec_status_secure;
+#endif
+       case LDNS_RSAMD5:
+       case LDNS_ECC_GOST:
+       default:
+               *reason = "unable to verify signature, unknown algorithm";
+               return sec_status_bogus;
+       }
+}
 
-#endif /* HAVE_SSL or HAVE_NSS */
+#endif /* HAVE_SSL or HAVE_NSS or HAVE_NETTLE */
Index: validator/val_secalgo.h
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_secalgo.h,v
retrieving revision 1.1.1.2
diff -u -p -r1.1.1.2 val_secalgo.h
--- validator/val_secalgo.h     16 Mar 2014 11:38:28 -0000      1.1.1.2
+++ validator/val_secalgo.h     10 Dec 2015 17:31:21 -0000
@@ -44,6 +44,21 @@
 #define VALIDATOR_VAL_SECALGO_H
 struct sldns_buffer;
 
+/** Return size of nsec3 hash algorithm, 0 if not supported */
+size_t nsec3_hash_algo_size_supported(int id);
+
+/**
+ * Hash a single hash call of an NSEC3 hash algorithm.
+ * Iterations and salt are done by the caller.
+ * @param algo: nsec3 hash algorithm.
+ * @param buf: the buffer to digest
+ * @param len: length of buffer to digest.
+ * @param res: result stored here (must have sufficient space).
+ * @return false on failure.
+*/
+int secalgo_nsec3_hash(int algo, unsigned char* buf, size_t len,
+        unsigned char* res);
+
 /**
  * Return size of DS digest according to its hash algorithm.
  * @param algo: DS digest algo.
Index: validator/val_sigcrypt.c
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/validator/val_sigcrypt.c,v
retrieving revision 1.2
diff -u -p -r1.2 val_sigcrypt.c
--- validator/val_sigcrypt.c    5 Nov 2015 21:29:03 -0000       1.2
+++ validator/val_sigcrypt.c    10 Dec 2015 17:31:21 -0000
@@ -57,7 +57,7 @@
 #include "sldns/wire2str.h"
 
 #include <ctype.h>
-#if !defined(HAVE_SSL) && !defined(HAVE_NSS)
+#if !defined(HAVE_SSL) && !defined(HAVE_NSS) && !defined(HAVE_NETTLE)
 #error "Need crypto library to do digital signature cryptography"
 #endif
 
Index: Makefile.in  -----> only build infra changes below here <-----
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/Makefile.in,v
retrieving revision 1.16
diff -u -p -r1.16 Makefile.in
--- Makefile.in 5 Nov 2015 21:29:02 -0000       1.16
+++ Makefile.in 10 Dec 2015 17:31:18 -0000
@@ -38,6 +38,7 @@ UNBOUND_VERSION_MINOR=@UNBOUND_VERSION_M
 UNBOUND_VERSION_MICRO=@UNBOUND_VERSION_MICRO@
 ALLTARGET=@ALLTARGET@
 INSTALLTARGET=@INSTALLTARGET@
+SSLLIB=@SSLLIB@
 
 # _unbound.la if pyunbound enabled.
 PYUNBOUND_TARGET=@PYUNBOUND_TARGET@
@@ -132,7 +133,7 @@ compat/memcmp.c compat/memmove.c compat/
 compat/strlcpy.c compat/strptime.c compat/getentropy_linux.c \
 compat/getentropy_osx.c compat/getentropy_solaris.c compat/getentropy_win.c \
 compat/explicit_bzero.c compat/arc4random.c compat/arc4random_uniform.c \
-compat/arc4_lock.c compat/sha512.c compat/reallocarray.c
+compat/arc4_lock.c compat/sha512.c compat/reallocarray.c compat/isblank.c
 COMPAT_OBJ=$(LIBOBJS:.o=.lo)
 COMPAT_OBJ_WITHOUT_CTIME=$(LIBOBJ_WITHOUT_CTIME:.o=.lo)
 COMPAT_OBJ_WITHOUT_CTIMEARC4=$(LIBOBJ_WITHOUT_CTIMEARC4:.o=.lo)
@@ -295,22 +296,22 @@ longtest: tests
 lib:   libunbound.la unbound.h
 
 libunbound.la: $(LIBUNBOUND_OBJ_LINK)
-       $(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) 
-lssl $(LIBS)
+       $(LINK_LIB) $(UBSYMS) -o $@ $(LIBUNBOUND_OBJ_LINK) -rpath $(libdir) 
$(SSLLIB) $(LIBS)
 
 unbound$(EXEEXT):      $(DAEMON_OBJ_LINK) libunbound.la
-       $(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(DAEMON_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
 
 unbound-checkconf$(EXEEXT):    $(CHECKCONF_OBJ_LINK) libunbound.la
-       $(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(CHECKCONF_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
 
 unbound-control$(EXEEXT):      $(CONTROL_OBJ_LINK) libunbound.la
-       $(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(CONTROL_OBJ_LINK) $(EXTRALINK) $(SSLLIB) $(LIBS)
 
 unbound-host$(EXEEXT): $(HOST_OBJ_LINK) libunbound.la
        $(LINK) -o $@ $(HOST_OBJ_LINK) -L. -L.libs -lunbound $(LIBS)
 
 unbound-anchor$(EXEEXT):       $(UBANCHOR_OBJ_LINK) libunbound.la
-       $(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat -lssl 
$(LIBS)
+       $(LINK) -o $@ $(UBANCHOR_OBJ_LINK) -L. -L.libs -lunbound -lexpat 
$(SSLLIB) $(LIBS)
 
 unbound-service-install$(EXEEXT):      $(SVCINST_OBJ_LINK)
        $(LINK) -o $@ $(SVCINST_OBJ_LINK) $(LIBS)
@@ -322,37 +323,37 @@ anchor-update$(EXEEXT):  $(ANCHORUPD_OBJ
        $(LINK) -o $@ $(ANCHORUPD_OBJ_LINK) -L. -L.libs -lunbound $(LIBS)
 
 unittest$(EXEEXT):     $(UNITTEST_OBJ_LINK)
-       $(LINK) -o $@ $(UNITTEST_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(UNITTEST_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 testbound$(EXEEXT):    $(TESTBOUND_OBJ_LINK)
-       $(LINK) -o $@ $(TESTBOUND_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(TESTBOUND_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 lock-verify$(EXEEXT):  $(LOCKVERIFY_OBJ_LINK)
-       $(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(LOCKVERIFY_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 petal$(EXEEXT):        $(PETAL_OBJ_LINK)
-       $(LINK) -o $@ $(PETAL_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(PETAL_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 pktview$(EXEEXT):      $(PKTVIEW_OBJ_LINK)
-       $(LINK) -o $@ $(PKTVIEW_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(PKTVIEW_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 memstats$(EXEEXT):     $(MEMSTATS_OBJ_LINK)
-       $(LINK) -o $@ $(MEMSTATS_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(MEMSTATS_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 asynclook$(EXEEXT):    $(ASYNCLOOK_OBJ_LINK) libunbound.la
        $(LINK) -o $@ $(ASYNCLOOK_OBJ_LINK) $(LIBS) -L. -L.libs -lunbound
 
 streamtcp$(EXEEXT):    $(STREAMTCP_OBJ_LINK)
-       $(LINK) -o $@ $(STREAMTCP_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(STREAMTCP_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 perf$(EXEEXT): $(PERF_OBJ_LINK)
-       $(LINK) -o $@ $(PERF_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(PERF_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 delayer$(EXEEXT):      $(DELAYER_OBJ_LINK)
-       $(LINK) -o $@ $(DELAYER_OBJ_LINK) -lssl $(LIBS)
+       $(LINK) -o $@ $(DELAYER_OBJ_LINK) $(SSLLIB) $(LIBS)
 
 signit$(EXEEXT):       testcode/signit.c
-       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ testcode/signit.c $(LDFLAGS) -lldns 
-lssl $(LIBS)
+       $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ testcode/signit.c $(LDFLAGS) -lldns 
$(SSLLIB) $(LIBS)
 
 unbound.h:     $(srcdir)/libunbound/unbound.h
        sed -e 's/@''UNBOUND_VERSION_MAJOR@/$(UNBOUND_VERSION_MAJOR)/' -e 
's/@''UNBOUND_VERSION_MINOR@/$(UNBOUND_VERSION_MINOR)/' -e 
's/@''UNBOUND_VERSION_MICRO@/$(UNBOUND_VERSION_MICRO)/' < 
$(srcdir)/libunbound/unbound.h > $@
@@ -480,8 +481,6 @@ unbound-event-install:
 install:
        # avoid mistakes made by people who forget "make -f 
Makefile.bsd-wrapper"
 
-orig-install:  $(INSTALLTARGET)
-
 install-lib:   lib $(UNBOUND_EVENT_INSTALL)
        $(INSTALL) -m 755 -d $(DESTDIR)$(libdir)
        $(INSTALL) -m 755 -d $(DESTDIR)$(includedir)
@@ -647,7 +646,7 @@ iterator.lo iterator.o: $(srcdir)/iterat
  $(srcdir)/util/rtt.h $(srcdir)/util/netevent.h $(srcdir)/util/net_help.h 
$(srcdir)/util/regional.h \
  $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h 
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
  $(srcdir)/services/mesh.h $(srcdir)/services/modstack.h 
$(srcdir)/util/config_file.h $(srcdir)/util/random.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/parseutil.h 
$(srcdir)/sldns/sbuffer.h
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h 
$(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h
 iter_delegpt.lo iter_delegpt.o: $(srcdir)/iterator/iter_delegpt.c config.h 
$(srcdir)/iterator/iter_delegpt.h \
  $(srcdir)/util/log.h $(srcdir)/services/cache/dns.h 
$(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/regional.h \
@@ -730,8 +729,7 @@ outside_network.lo outside_network.o: $(
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/data/msgencode.h \
  $(srcdir)/util/data/dname.h $(srcdir)/util/net_help.h $(srcdir)/util/random.h 
$(srcdir)/util/fptr_wlist.h \
  $(srcdir)/util/module.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h 
$(srcdir)/services/modstack.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h \
- 
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/dnstap/dnstap.h
 alloc.lo alloc.o: $(srcdir)/util/alloc.c config.h $(srcdir)/util/alloc.h 
$(srcdir)/util/locks.h $(srcdir)/util/log.h \
  $(srcdir)/util/regional.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
  $(srcdir)/util/fptr_wlist.h $(srcdir)/util/netevent.h $(srcdir)/util/module.h 
$(srcdir)/util/data/msgreply.h \
@@ -779,14 +777,12 @@ netevent.lo netevent.o: $(srcdir)/util/n
  $(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/tube.h \
  $(srcdir)/services/mesh.h $(srcdir)/util/rbtree.h 
$(srcdir)/services/modstack.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/dnstap/dnstap.h  \
- $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
+ $(srcdir)/dnstap/dnstap.h  $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.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/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 \
  $(srcdir)/util/netevent.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/locks.h $(srcdir)/util/log.h \
@@ -821,8 +817,7 @@ autotrust.lo autotrust.o: $(srcdir)/vali
  $(srcdir)/util/net_help.h $(srcdir)/util/config_file.h 
$(srcdir)/util/regional.h $(srcdir)/util/random.h \
  $(srcdir)/services/mesh.h $(srcdir)/util/netevent.h 
$(srcdir)/services/modstack.h \
  $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h 
$(srcdir)/validator/val_kcache.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h 
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h \
- 
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h 
$(srcdir)/sldns/str2wire.h $(srcdir)/sldns/keyraw.h
 val_anchor.lo val_anchor.o: $(srcdir)/validator/val_anchor.c config.h 
$(srcdir)/validator/val_anchor.h \
  $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/validator/val_sigcrypt.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/validator/autotrust.h \
@@ -847,18 +842,16 @@ val_kcache.lo val_kcache.o: $(srcdir)/va
 val_kentry.lo val_kentry.o: $(srcdir)/validator/val_kentry.c config.h 
$(srcdir)/validator/val_kentry.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/util/data/packed_rrset.h \
  $(srcdir)/util/data/dname.h $(srcdir)/util/storage/lookup3.h 
$(srcdir)/util/regional.h $(srcdir)/util/net_help.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
- 
-val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h \
- $(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/util/rbtree.h \
- $(srcdir)/validator/val_nsec.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_utils.h 
$(srcdir)/util/data/dname.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/net_help.h 
$(srcdir)/util/config_file.h \
- $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h 
$(srcdir)/services/cache/dns.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h
-val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h \
- $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h 
$(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/validator/validator.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h
+val_neg.lo val_neg.o: $(srcdir)/validator/val_neg.c config.h 
$(srcdir)/validator/val_neg.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/rbtree.h $(srcdir)/validator/val_nsec.h 
$(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/validator/val_nsec3.h 
$(srcdir)/validator/val_utils.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/net_help.h \
+ $(srcdir)/util/config_file.h $(srcdir)/services/cache/rrset.h 
$(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/sldns/rrdef.h 
$(srcdir)/sldns/sbuffer.h
+val_nsec3.lo val_nsec3.o: $(srcdir)/validator/val_nsec3.c config.h 
$(srcdir)/validator/val_nsec3.h \
+ $(srcdir)/util/rbtree.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h 
$(srcdir)/validator/validator.h \
  $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h 
$(srcdir)/validator/val_kentry.h \
  $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h 
$(srcdir)/util/regional.h \
@@ -870,17 +863,15 @@ val_nsec.lo val_nsec.o: $(srcdir)/valida
  $(srcdir)/sldns/rrdef.h $(srcdir)/services/cache/rrset.h 
$(srcdir)/util/storage/slabhash.h
 val_secalgo.lo val_secalgo.o: $(srcdir)/validator/val_secalgo.c config.h 
$(srcdir)/util/data/packed_rrset.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/validator/val_secalgo.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/sbuffer.h \
- 
+ $(srcdir)/validator/val_nsec3.h $(srcdir)/util/rbtree.h 
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/sldns/sbuffer.h
 val_sigcrypt.lo val_sigcrypt.o: $(srcdir)/validator/val_sigcrypt.c config.h \
  $(srcdir)/validator/val_sigcrypt.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
  $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/validator/val_secalgo.h 
$(srcdir)/validator/validator.h \
  $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/validator/val_utils.h 
$(srcdir)/util/data/dname.h $(srcdir)/util/rbtree.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parseutil.h 
$(srcdir)/sldns/wire2str.h \
- 
+ $(srcdir)/util/net_help.h $(srcdir)/util/regional.h $(srcdir)/sldns/keyraw.h 
$(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/wire2str.h
 val_utils.lo val_utils.o: $(srcdir)/validator/val_utils.c config.h 
$(srcdir)/validator/val_utils.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/locks.h $(srcdir)/util/log.h \
  $(srcdir)/validator/validator.h $(srcdir)/util/module.h 
$(srcdir)/util/data/msgreply.h \
@@ -898,11 +889,6 @@ dns64.lo dns64.o: $(srcdir)/dns64/dns64.
  $(srcdir)/services/modstack.h $(srcdir)/util/net_help.h 
$(srcdir)/util/regional.h
 checklocks.lo checklocks.o: $(srcdir)/testcode/checklocks.c config.h 
$(srcdir)/util/locks.h $(srcdir)/util/log.h \
  $(srcdir)/testcode/checklocks.h
-dnstap.lo dnstap.o: $(srcdir)/dnstap/dnstap.c  config.h 
$(srcdir)/sldns/sbuffer.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h 
$(srcdir)/util/netevent.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
 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
@@ -911,8 +897,7 @@ unitdname.lo unitdname.o: $(srcdir)/test
  $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h
 unitlruhash.lo unitlruhash.o: $(srcdir)/testcode/unitlruhash.c config.h 
$(srcdir)/testcode/unitmain.h \
  $(srcdir)/util/log.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h 
$(srcdir)/util/storage/slabhash.h
-unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
+unitmain.lo unitmain.o: $(srcdir)/testcode/unitmain.c config.h 
$(srcdir)/sldns/rrdef.h $(srcdir)/sldns/keyraw.h \
  $(srcdir)/util/log.h $(srcdir)/testcode/unitmain.h $(srcdir)/util/alloc.h 
$(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/rtt.h 
$(srcdir)/services/cache/infra.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/util/rbtree.h \
@@ -950,38 +935,35 @@ unitldns.lo unitldns.o: $(srcdir)/testco
 acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h 
$(srcdir)/daemon/acl_list.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h 
$(srcdir)/util/regional.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h
-cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h \
- $(srcdir)/daemon/cachedump.h $(srcdir)/daemon/remote.h 
$(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/netevent.h 
$(srcdir)/util/alloc.h \
+cachedump.lo cachedump.o: $(srcdir)/daemon/cachedump.c config.h 
$(srcdir)/daemon/cachedump.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h 
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h 
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h 
$(srcdir)/util/timehist.h \
+ $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h 
$(srcdir)/services/cache/dns.h \
+ $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h \
+ $(srcdir)/util/regional.h $(srcdir)/util/net_help.h 
$(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/iterator/iter_delegpt.h 
$(srcdir)/iterator/iter_utils.h \
+ $(srcdir)/iterator/iter_resptype.h $(srcdir)/iterator/iter_fwd.h 
$(srcdir)/iterator/iter_hints.h \
+ $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
+daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h 
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h 
$(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/netevent.h \
  $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h 
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
  $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h 
$(srcdir)/dnstap/dnstap.h \
-  $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/infra.h 
$(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/regional.h 
$(srcdir)/util/net_help.h \
- $(srcdir)/util/data/dname.h $(srcdir)/iterator/iterator.h 
$(srcdir)/services/outbound_list.h \
- $(srcdir)/iterator/iter_delegpt.h $(srcdir)/iterator/iter_utils.h 
$(srcdir)/iterator/iter_resptype.h \
- $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h 
$(srcdir)/sldns/wire2str.h \
- $(srcdir)/sldns/str2wire.h
-daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
-  $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h 
$(srcdir)/util/module.h \
- $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/util/rbtree.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h 
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h 
$(srcdir)/util/storage/slabhash.h \
  $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h 
$(srcdir)/services/cache/infra.h \
  $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h 
$(srcdir)/util/tube.h \
  $(srcdir)/util/net_help.h $(srcdir)/sldns/keyraw.h
-remote.lo remote.o: $(srcdir)/daemon/remote.c config.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h 
$(srcdir)/sldns/sbuffer.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h 
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h 
$(srcdir)/util/timehist.h \
- $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
+remote.lo remote.o: $(srcdir)/daemon/remote.c config.h 
$(srcdir)/daemon/remote.h $(srcdir)/daemon/worker.h \
+ $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h 
$(srcdir)/util/data/packed_rrset.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/util/netevent.h \
+ $(srcdir)/util/alloc.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h 
$(srcdir)/util/module.h \
+ $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
  $(srcdir)/services/modstack.h $(srcdir)/daemon/cachedump.h 
$(srcdir)/util/config_file.h \
  $(srcdir)/util/net_help.h $(srcdir)/services/listen_dnsport.h 
$(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/storage/slabhash.h $(srcdir)/services/cache/infra.h 
$(srcdir)/util/storage/dnstree.h \
@@ -1005,35 +987,33 @@ stats.lo stats.o: $(srcdir)/daemon/stats
  $(srcdir)/util/rtt.h $(srcdir)/validator/val_kcache.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 \
- $(srcdir)/util/config_file.h $(srcdir)/util/storage/slabhash.h 
$(srcdir)/util/storage/lruhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/util/netevent.h 
$(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h 
$(srcdir)/util/storage/dnstree.h \
- $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h $(srcdir)/util/fptr_wlist.h 
$(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h 
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/tube.h $(srcdir)/services/mesh.h $(srcdir)/util/net_help.h 
$(srcdir)/util/mini_event.h \
- $(srcdir)/util/rbtree.h
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h 
$(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/services/listen_dnsport.h 
$(srcdir)/util/netevent.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/services/cache/infra.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/util/rtt.h 
$(srcdir)/util/fptr_wlist.h \
+ $(srcdir)/util/module.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/tube.h $(srcdir)/services/mesh.h 
$(srcdir)/util/net_help.h \
+ $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h
 worker.lo worker.o: $(srcdir)/daemon/worker.c config.h $(srcdir)/util/log.h 
$(srcdir)/util/net_help.h \
  $(srcdir)/util/random.h $(srcdir)/daemon/worker.h 
$(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/locks.h \
  $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h 
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
  $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h 
$(srcdir)/util/timehist.h \
  $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/util/rbtree.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h 
$(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h 
$(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h 
$(srcdir)/services/localzone.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h 
$(srcdir)/daemon/acl_list.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h 
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h 
$(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h 
$(srcdir)/services/localzone.h \
  $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h 
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
  $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h 
$(srcdir)/validator/autotrust.h \
  $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h 
$(srcdir)/libunbound/unbound.h \
  $(srcdir)/libunbound/libworker.h
 testbound.lo testbound.o: $(srcdir)/testcode/testbound.c config.h 
$(srcdir)/testcode/testpkts.h \
  $(srcdir)/testcode/replay.h $(srcdir)/util/netevent.h $(srcdir)/util/rbtree.h 
$(srcdir)/testcode/fake_event.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/keyraw.h 
$(srcdir)/daemon/unbound.c $(srcdir)/util/log.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/alloc.h 
$(srcdir)/services/modstack.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/util/config_file.h 
$(srcdir)/sldns/keyraw.h $(srcdir)/daemon/unbound.c \
+ $(srcdir)/util/log.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h 
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
   $(srcdir)/util/storage/slabhash.h $(srcdir)/util/storage/lruhash.h \
  $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/services/cache/infra.h 
$(srcdir)/util/storage/dnstree.h \
@@ -1049,12 +1029,12 @@ worker.lo worker.o: $(srcdir)/daemon/wor
  $(srcdir)/util/netevent.h $(srcdir)/util/alloc.h 
$(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
  $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h 
$(srcdir)/util/timehist.h \
  $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h  $(srcdir)/daemon/daemon.h \
- $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/util/rbtree.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/regional.h 
$(srcdir)/util/storage/slabhash.h \
- $(srcdir)/services/listen_dnsport.h $(srcdir)/services/outside_network.h \
- $(srcdir)/services/outbound_list.h $(srcdir)/services/cache/rrset.h 
$(srcdir)/services/cache/infra.h \
- $(srcdir)/util/rtt.h $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h 
$(srcdir)/services/localzone.h \
+ $(srcdir)/services/modstack.h $(srcdir)/daemon/remote.h 
$(srcdir)/daemon/acl_list.h \
+ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h 
$(srcdir)/util/config_file.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/services/listen_dnsport.h \
+ $(srcdir)/services/outside_network.h $(srcdir)/services/outbound_list.h \
+ $(srcdir)/services/cache/rrset.h $(srcdir)/services/cache/infra.h 
$(srcdir)/util/rtt.h \
+ $(srcdir)/services/cache/dns.h $(srcdir)/services/mesh.h 
$(srcdir)/services/localzone.h \
  $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/dname.h 
$(srcdir)/util/fptr_wlist.h $(srcdir)/util/tube.h \
  $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h 
$(srcdir)/validator/autotrust.h \
  $(srcdir)/validator/val_anchor.h $(srcdir)/libunbound/context.h 
$(srcdir)/libunbound/unbound.h \
@@ -1062,14 +1042,13 @@ worker.lo worker.o: $(srcdir)/daemon/wor
 acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h 
$(srcdir)/daemon/acl_list.h \
  $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h 
$(srcdir)/util/regional.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h
-daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h 
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
-  $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h 
$(srcdir)/util/module.h \
- $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
- $(srcdir)/daemon/acl_list.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/util/rbtree.h \
+daemon.lo daemon.o: $(srcdir)/daemon/daemon.c config.h 
$(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h  \
+ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h 
$(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/netevent.h \
+ $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h 
$(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/util/module.h 
$(srcdir)/dnstap/dnstap.h \
+ $(srcdir)/daemon/remote.h $(srcdir)/daemon/acl_list.h 
$(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h \
  $(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h 
$(srcdir)/util/storage/slabhash.h \
  $(srcdir)/services/listen_dnsport.h $(srcdir)/services/cache/rrset.h 
$(srcdir)/services/cache/infra.h \
  $(srcdir)/util/rtt.h $(srcdir)/services/localzone.h $(srcdir)/util/random.h 
$(srcdir)/util/tube.h \
@@ -1144,19 +1123,18 @@ libunbound.lo libunbound.o: $(srcdir)/li
  $(srcdir)/util/random.h $(srcdir)/util/net_help.h $(srcdir)/util/tube.h 
$(srcdir)/services/localzone.h \
  $(srcdir)/services/cache/infra.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/util/rtt.h \
  $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h 
$(srcdir)/sldns/sbuffer.h
-libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
- $(srcdir)/libunbound/libworker.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/libunbound/context.h 
$(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h \
- $(srcdir)/services/modstack.h $(srcdir)/libunbound/unbound.h 
$(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/libunbound/unbound-event.h 
$(srcdir)/services/outside_network.h \
- $(srcdir)/util/netevent.h  $(srcdir)/services/mesh.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h 
$(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/services/localzone.h 
$(srcdir)/services/cache/rrset.h \
- $(srcdir)/util/storage/slabhash.h $(srcdir)/services/outbound_list.h 
$(srcdir)/util/fptr_wlist.h \
- $(srcdir)/util/tube.h $(srcdir)/util/regional.h $(srcdir)/util/random.h 
$(srcdir)/util/config_file.h \
- $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h 
$(srcdir)/util/data/dname.h \
- $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h 
$(srcdir)/iterator/iter_hints.h \
- $(srcdir)/util/storage/dnstree.h $(srcdir)/sldns/str2wire.h
+libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h 
$(srcdir)/libunbound/libworker.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h 
$(srcdir)/util/locks.h $(srcdir)/util/log.h \
+ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h 
$(srcdir)/services/modstack.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/worker.h 
$(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/libunbound/unbound-event.h $(srcdir)/services/outside_network.h 
$(srcdir)/util/netevent.h \
+  $(srcdir)/services/mesh.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/module.h 
$(srcdir)/util/data/msgreply.h \
+ $(srcdir)/services/localzone.h $(srcdir)/services/cache/rrset.h 
$(srcdir)/util/storage/slabhash.h \
+ $(srcdir)/services/outbound_list.h $(srcdir)/util/fptr_wlist.h 
$(srcdir)/util/tube.h $(srcdir)/util/regional.h \
+ $(srcdir)/util/random.h $(srcdir)/util/config_file.h 
$(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h 
$(srcdir)/iterator/iter_fwd.h \
+ $(srcdir)/iterator/iter_hints.h $(srcdir)/util/storage/dnstree.h 
$(srcdir)/sldns/str2wire.h
 unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h 
$(srcdir)/libunbound/unbound.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
 asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h 
$(srcdir)/libunbound/unbound.h \
@@ -1167,21 +1145,18 @@ streamtcp.lo streamtcp.o: $(srcdir)/test
  $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h 
$(srcdir)/util/data/msgparse.h \
  $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h 
$(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h 
$(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
- 
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
 perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h 
$(srcdir)/util/locks.h $(srcdir)/util/net_help.h \
  $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/storage/lruhash.h \
  $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h 
$(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h 
$(srcdir)/sldns/str2wire.h
 delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h 
$(srcdir)/util/net_help.h $(srcdir)/util/log.h \
  $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
-unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c 
config.h \
- $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h 
$(srcdir)/util/net_help.h
+unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c 
config.h $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h
 unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c 
config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h \
- 
-petal.lo petal.o: $(srcdir)/testcode/petal.c config.h \
- 
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
+petal.lo petal.o: $(srcdir)/testcode/petal.c config.h
 pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c 
config.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 \
@@ -1194,8 +1169,7 @@ win_svc.lo win_svc.o: $(srcdir)/winrc/wi
  $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h 
$(srcdir)/util/storage/lruhash.h \
  $(srcdir)/util/netevent.h $(srcdir)/util/data/msgreply.h 
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h 
$(srcdir)/util/module.h \
- $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/winsock_event.h
+ $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h 
$(srcdir)/util/config_file.h $(srcdir)/util/winsock_event.h
 w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h 
$(srcdir)/winrc/win_svc.h
 unbound-service-install.lo unbound-service-install.o: 
$(srcdir)/winrc/unbound-service-install.c config.h \
  $(srcdir)/winrc/w_inst.h
@@ -1203,14 +1177,11 @@ unbound-service-remove.lo unbound-servic
  $(srcdir)/winrc/w_inst.h
 anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h 
$(srcdir)/libunbound/unbound.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h
-keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h 
\
- $(srcdir)/sldns/rrdef.h \
- 
+keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h 
$(srcdir)/sldns/rrdef.h
 sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h 
$(srcdir)/sldns/sbuffer.h
 wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h 
$(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
  $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h 
$(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/keyraw.h \
- 
+ $(srcdir)/sldns/keyraw.h
 parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h 
$(srcdir)/sldns/parseutil.h \
  $(srcdir)/sldns/sbuffer.h
 parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h 
$(srcdir)/sldns/parseutil.h
@@ -1230,8 +1201,7 @@ snprintf.lo snprintf.o: $(srcdir)/compat
 strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
 strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
 strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
-getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c 
config.h \
- 
+getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c 
config.h
 getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
 getentropy_solaris.lo getentropy_solaris.o: 
$(srcdir)/compat/getentropy_solaris.c config.h
 getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
@@ -1241,3 +1211,4 @@ arc4random_uniform.lo arc4random_uniform
 arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h 
$(srcdir)/util/locks.h
 sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h
 reallocarray.lo reallocarray.o: $(srcdir)/compat/reallocarray.c config.h
+isblank.lo isblank.o: $(srcdir)/compat/isblank.c config.h
Index: README
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/README,v
retrieving revision 1.2
diff -u -p -r1.2 README
--- README      5 Nov 2015 21:29:02 -0000       1.2
+++ README      10 Dec 2015 17:31:18 -0000
@@ -1,4 +1,4 @@
-README for Unbound 1.5.6
+Unbound README
 * ./configure && make && make install
 * You can use libevent if you want. libevent is useful when using 
   many (10000) outgoing ports. By default max 256 ports are opened at
Index: acx_nlnetlabs.m4
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/acx_nlnetlabs.m4,v
retrieving revision 1.2
diff -u -p -r1.2 acx_nlnetlabs.m4
--- acx_nlnetlabs.m4    5 Nov 2015 21:29:02 -0000       1.2
+++ acx_nlnetlabs.m4    10 Dec 2015 17:31:18 -0000
@@ -2,7 +2,9 @@
 # Copyright 2009, Wouter Wijngaards, NLnet Labs.   
 # BSD licensed.
 #
-# Version 28
+# Version 30
+# 2015-11-18 spelling check fix.
+# 2015-11-05 ACX_SSL_CHECKS no longer adds -ldl needlessly.
 # 2015-08-28 ACX_CHECK_PIE and ACX_CHECK_RELRO_NOW added.
 # 2015-03-17 AHX_CONFIG_REALLOCARRAY added
 # 2013-09-19 FLTO help text improved.
@@ -24,7 +26,7 @@
 # 2010-07-02 Add check for ss_family (for minix).
 # 2010-04-26 Fix to use CPPFLAGS for CHECK_COMPILER_FLAGS.
 # 2010-03-01 Fix RPATH using CONFIG_COMMANDS to run at the very end.
-# 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS seperate, -ldl
+# 2010-02-18 WITH_SSL outputs the LIBSSL_LDFLAGS, LIBS, CPPFLAGS separate, -ldl
 # 2010-02-01 added ACX_CHECK_MEMCMP_SIGNED, AHX_MEMCMP_BROKEN
 # 2010-01-20 added AHX_COONFIG_STRLCAT
 # 2009-07-14 U_CHAR detection improved for windows crosscompile.
@@ -715,12 +717,6 @@ AC_DEFUN([ACX_SSL_CHECKS], [
         fi
         AC_SUBST(HAVE_SSL)
         AC_SUBST(RUNTIME_PATH)
-       # openssl engine functionality needs dlopen().
-       BAKLIBS="$LIBS"
-       AC_SEARCH_LIBS([dlopen], [dl])
-       if test "$LIBS" != "$BAKLIBS"; then
-               LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
-       fi
     fi
 AC_CHECK_HEADERS([openssl/ssl.h],,, [AC_INCLUDES_DEFAULT])
 AC_CHECK_HEADERS([openssl/err.h],,, [AC_INCLUDES_DEFAULT])
Index: config.h.in
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/config.h.in,v
retrieving revision 1.2
diff -u -p -r1.2 config.h.in
--- config.h.in 5 Nov 2015 21:29:02 -0000       1.2
+++ config.h.in 10 Dec 2015 17:31:18 -0000
@@ -94,6 +94,10 @@
    don't. */
 #undef HAVE_DECL_STRLCPY
 
+/* Define to 1 if you have the declaration of `XML_StopParser', and to 0 if
+   you don't. */
+#undef HAVE_DECL_XML_STOPPARSER
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -151,6 +155,9 @@
 /* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
 #undef HAVE_FSEEKO
 
+/* Define to 1 if you have the `fsync' function. */
+#undef HAVE_FSYNC
+
 /* Whether getaddrinfo is available */
 #undef HAVE_GETADDRINFO
 
@@ -205,6 +212,9 @@
 /* Define to 1 if you have the <iphlpapi.h> header file. */
 #undef HAVE_IPHLPAPI_H
 
+/* Define to 1 if you have the `isblank' function. */
+#undef HAVE_ISBLANK
+
 /* Define to 1 if you have the `kill' function. */
 #undef HAVE_KILL
 
@@ -232,6 +242,9 @@
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H
 
+/* Use libnettle for crypto */
+#undef HAVE_NETTLE
+
 /* Use libnss for crypto */
 #undef HAVE_NSS
 
@@ -535,6 +548,9 @@
 /* The size of `time_t', as computed by sizeof. */
 #undef SIZEOF_TIME_T
 
+/* define if (v)snprintf does not return length needed, (but length used) */
+#undef SNPRINTF_RET_BROKEN
+
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
@@ -848,15 +864,13 @@
 #define MAXHOSTNAMELEN 256
 #endif
 
-
-#ifndef HAVE_SNPRINTF
+#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
 #define snprintf snprintf_unbound
 #define vsnprintf vsnprintf_unbound
 #include <stdarg.h>
 int snprintf (char *str, size_t count, const char *fmt, ...);
 int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
-#endif /* HAVE_SNPRINTF */
-
+#endif /* HAVE_SNPRINTF or SNPRINTF_RET_BROKEN */
 
 #ifndef HAVE_INET_PTON
 #define inet_pton inet_pton_unbound
@@ -950,6 +964,11 @@ int memcmp(const void *x, const void *y,
 #ifndef HAVE_CTIME_R
 #define ctime_r unbound_ctime_r
 char *ctime_r(const time_t *timep, char *buf);
+#endif
+
+#ifndef HAVE_ISBLANK
+#define isblank unbound_isblank
+int isblank(int c);
 #endif
 
 #if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)
Index: configure
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/configure,v
retrieving revision 1.15
diff -u -p -r1.15 configure
--- configure   5 Nov 2015 21:29:02 -0000       1.15
+++ configure   10 Dec 2015 17:31:19 -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.5.6.
+# Generated by GNU Autoconf 2.69 for unbound 1.5.7.
 #
 # Report bugs to <unbound-b...@nlnetlabs.nl>.
 #
@@ -590,8 +590,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='unbound'
 PACKAGE_TARNAME='unbound'
-PACKAGE_VERSION='1.5.6'
-PACKAGE_STRING='unbound 1.5.6'
+PACKAGE_VERSION='1.5.7'
+PACKAGE_STRING='unbound 1.5.7'
 PACKAGE_BUGREPORT='unbound-b...@nlnetlabs.nl'
 PACKAGE_URL=''
 
@@ -661,6 +661,7 @@ CHECKLOCK_OBJ
 staticexe
 UNBOUND_EVENT_UNINSTALL
 UNBOUND_EVENT_INSTALL
+SSLLIB
 HAVE_SSL
 CONFIG_DATE
 NETBSD_LINTFLAGS
@@ -823,6 +824,7 @@ with_solaris_threads
 with_pyunbound
 with_pythonmodule
 with_nss
+with_nettle
 with_ssl
 enable_sha2
 enable_gost
@@ -1391,7 +1393,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.5.6 to adapt to many kinds of systems.
+\`configure' configures unbound 1.5.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1456,7 +1458,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of unbound 1.5.6:";;
+     short | recursive ) echo "Configuration of unbound 1.5.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1534,6 +1536,7 @@ Optional Packages:
   --with-pythonmodule     build Python module, or --without-pythonmodule to
                           disable script engine. (default=no)
   --with-nss=path         use libnss instead of openssl, installed at path.
+  --with-nettle=path      use libnettle as crypto library, installed at path.
   --with-ssl=pathname     enable SSL (will check /usr/local/ssl /usr/lib/ssl
                           /usr/ssl /usr/pkg /usr/local /opt/local /usr/sfw
                           /usr)
@@ -1635,7 +1638,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-unbound configure 1.5.6
+unbound configure 1.5.7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2344,7 +2347,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.5.6, which was
+It was created by unbound $as_me 1.5.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2696,11 +2699,11 @@ UNBOUND_VERSION_MAJOR=1
 
 UNBOUND_VERSION_MINOR=5
 
-UNBOUND_VERSION_MICRO=6
+UNBOUND_VERSION_MICRO=7
 
 
 LIBUNBOUND_CURRENT=5
-LIBUNBOUND_REVISION=9
+LIBUNBOUND_REVISION=10
 LIBUNBOUND_AGE=3
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
@@ -2746,6 +2749,7 @@ LIBUNBOUND_AGE=3
 # 1.5.4 had 5:7:3
 # 1.5.5 had 5:8:3
 # 1.5.6 had 5:9:3
+# 1.5.7 had 5:10:3
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -16407,13 +16411,44 @@ $as_echo "#define HAVE_NSS 1" >>confdefs
                CPPFLAGS="-I/usr/include/nspr4 $CPPFLAGS"
        fi
         LIBS="$LIBS -lnss3 -lnspr4"
+       SSLLIB=""
+
+
+fi
+
+
+# libnettle
+USE_NETTLE="no"
+
+# Check whether --with-nettle was given.
+if test "${with_nettle+set}" = set; then :
+  withval=$with_nettle;
+       USE_NETTLE="yes"
+
+$as_echo "#define HAVE_NETTLE 1" >>confdefs.h
+
+       if test "$withval" != "" -a "$withval" != "yes"; then
+               CPPFLAGS="$CPPFLAGS -I$withval/include/nettle"
+               LDFLAGS="$LDFLAGS -L$withval/lib"
+
+       if test "x$enable_rpath" = xyes; then
+               if echo "$withval/lib" | grep "^/" >/dev/null; then
+                       RUNTIME_PATH="$RUNTIME_PATH -R$withval/lib"
+               fi
+       fi
+
+       else
+               CPPFLAGS="$CPPFLAGS -I/usr/include/nettle"
+       fi
+        LIBS="$LIBS -lhogweed -lnettle -lgmp"
+       SSLLIB=""
 
 
 fi
 
 
 # openssl
-if test $USE_NSS = "no"; then
+if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
 
 
 # Check whether --with-ssl was given.
@@ -16582,67 +16617,6 @@ rm -f core conftest.err conftest.$ac_obj
         fi
 
 
-       # openssl engine functionality needs dlopen().
-       BAKLIBS="$LIBS"
-       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library 
containing dlopen" >&5
-$as_echo_n "checking for library containing dlopen... " >&6; }
-if ${ac_cv_search_dlopen+:} false; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char dlopen ();
-int
-main ()
-{
-return dlopen ();
-  ;
-  return 0;
-}
-_ACEOF
-for ac_lib in '' dl; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_dlopen=$ac_res
-fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext
-  if ${ac_cv_search_dlopen+:} false; then :
-  break
-fi
-done
-if ${ac_cv_search_dlopen+:} false; then :
-
-else
-  ac_cv_search_dlopen=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5
-$as_echo "$ac_cv_search_dlopen" >&6; }
-ac_res=$ac_cv_search_dlopen
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-fi
-
-       if test "$LIBS" != "$BAKLIBS"; then
-               LIBSSL_LIBS="$LIBSSL_LIBS -ldl"
-       fi
     fi
 for ac_header in openssl/ssl.h
 do :
@@ -16780,6 +16754,7 @@ fi
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
+SSLLIB="-lssl"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for LibreSSL" >&5
 $as_echo_n "checking for LibreSSL... " >&6; }
 if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" 
>/dev/null; then
@@ -16977,6 +16952,7 @@ _ACEOF
 fi
 
 
+
 # Check whether --enable-sha2 was given.
 if test "${enable_sha2+set}" = set; then :
   enableval=$enable_sha2;
@@ -17000,7 +16976,7 @@ if test "${enable_gost+set}" = set; then
 fi
 
 use_gost="no"
-if test $USE_NSS = "no"; then
+if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
 case "$enable_gost" in
        no)
        ;;
@@ -17153,7 +17129,7 @@ case "$enable_ecdsa" in
     no)
       ;;
     *)
-      if test $USE_NSS = "no"; then
+      if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
              ac_fn_c_check_func "$LINENO" "ECDSA_sign" "ac_cv_func_ECDSA_sign"
 if test "x$ac_cv_func_ECDSA_sign" = xyes; then :
 
@@ -17644,6 +17620,20 @@ fi
 
 done
 
+ac_fn_c_check_decl "$LINENO" "XML_StopParser" "ac_cv_have_decl_XML_StopParser" 
"$ac_includes_default
+#include <expat.h>
+
+"
+if test "x$ac_cv_have_decl_XML_StopParser" = xyes; then :
+  ac_have_decl=1
+else
+  ac_have_decl=0
+fi
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_DECL_XML_STOPPARSER $ac_have_decl
+_ACEOF
+
 
 # set static linking if requested
 
@@ -18101,7 +18091,7 @@ if test "$ac_res" != no; then :
 
 fi
 
-for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid 
sbrk chroot kill chown sleep usleep random srandom recvmsg sendmsg writev 
socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex 
endservent endprotoent
+for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid 
sbrk chroot kill chown sleep usleep random srandom recvmsg sendmsg writev 
socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex 
endservent endprotoent fsync
 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"
@@ -18222,6 +18212,48 @@ esac
 fi
 
 
+# test if snprintf return the proper length
+if test "x$ac_cv_func_snprintf" = xyes; then
+    if test c${cross_compiling} = cno; then
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking for correct snprintf 
return value" >&5
+$as_echo_n "checking for correct snprintf return value... " >&6; }
+       if test "$cross_compiling" = yes; then :
+  { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run test program while cross compiling
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+
+int main(void) { return !(snprintf(NULL, 0, "test") == 4); }
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+
+               { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define SNPRINTF_RET_BROKEN /**/" >>confdefs.h
+
+               case " $LIBOBJS " in
+  *" snprintf.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS snprintf.$ac_objext"
+ ;;
+esac
+
+
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+    fi
+fi
 ac_fn_c_check_func "$LINENO" "strlcat" "ac_cv_func_strlcat"
 if test "x$ac_cv_func_strlcat" = xyes; then :
   $as_echo "#define HAVE_STRLCAT 1" >>confdefs.h
@@ -18278,6 +18310,20 @@ esac
 fi
 
 
+ac_fn_c_check_func "$LINENO" "isblank" "ac_cv_func_isblank"
+if test "x$ac_cv_func_isblank" = xyes; then :
+  $as_echo "#define HAVE_ISBLANK 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" isblank.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS isblank.$ac_objext"
+ ;;
+esac
+
+fi
+
+
 LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
 
 ac_fn_c_check_func "$LINENO" "reallocarray" "ac_cv_func_reallocarray"
@@ -19018,7 +19064,7 @@ _ACEOF
 
 
 
-version=1.5.6
+version=1.5.7
 
 date=`date +'%b %e, %Y'`
 
@@ -19533,7 +19579,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.5.6, which was
+This file was extended by unbound $as_me 1.5.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -19599,7 +19645,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.5.6
+unbound config.status 1.5.7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
Index: configure.ac
===================================================================
RCS file: /cvs/src/usr.sbin/unbound/configure.ac,v
retrieving revision 1.15
diff -u -p -r1.15 configure.ac
--- configure.ac        5 Nov 2015 21:29:02 -0000       1.15
+++ configure.ac        10 Dec 2015 17:31:19 -0000
@@ -10,14 +10,14 @@ sinclude(dnstap/dnstap.m4)
 # must be numbers. ac_defun because of later processing
 m4_define([VERSION_MAJOR],[1])
 m4_define([VERSION_MINOR],[5])
-m4_define([VERSION_MICRO],[6])
+m4_define([VERSION_MICRO],[7])
 AC_INIT(unbound, 
m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]), 
unbound-b...@nlnetlabs.nl, unbound)
 AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR])
 AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR])
 AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO])
 
 LIBUNBOUND_CURRENT=5
-LIBUNBOUND_REVISION=9
+LIBUNBOUND_REVISION=10
 LIBUNBOUND_AGE=3
 # 1.0.0 had 0:12:0
 # 1.0.1 had 0:13:0
@@ -63,6 +63,7 @@ LIBUNBOUND_AGE=3
 # 1.5.4 had 5:7:3
 # 1.5.5 had 5:8:3
 # 1.5.6 had 5:9:3
+# 1.5.7 had 5:10:3
 
 #   Current  -- the number of the binary API that we're implementing
 #   Revision -- which iteration of the implementation of the binary
@@ -562,13 +563,34 @@ AC_ARG_WITH([nss], AC_HELP_STRING([--wit
                CPPFLAGS="-I/usr/include/nspr4 $CPPFLAGS"
        fi
         LIBS="$LIBS -lnss3 -lnspr4"
+       SSLLIB=""
+       ]
+)
+
+# libnettle
+USE_NETTLE="no"
+AC_ARG_WITH([nettle], AC_HELP_STRING([--with-nettle=path],
+       [use libnettle as crypto library, installed at path.]),
+       [
+       USE_NETTLE="yes"
+       AC_DEFINE(HAVE_NETTLE, 1, [Use libnettle for crypto])
+       if test "$withval" != "" -a "$withval" != "yes"; then
+               CPPFLAGS="$CPPFLAGS -I$withval/include/nettle"
+               LDFLAGS="$LDFLAGS -L$withval/lib"
+               ACX_RUNTIME_PATH_ADD([$withval/lib])
+       else
+               CPPFLAGS="$CPPFLAGS -I/usr/include/nettle"
+       fi
+        LIBS="$LIBS -lhogweed -lnettle -lgmp"
+       SSLLIB=""
        ]
 )
 
 # openssl
-if test $USE_NSS = "no"; then
+if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
 ACX_WITH_SSL
 ACX_LIB_SSL
+SSLLIB="-lssl"
 AC_MSG_CHECKING([for LibreSSL])
 if grep VERSION_TEXT $ssldir/include/openssl/opensslv.h | grep "LibreSSL" 
>/dev/null; then
        AC_MSG_RESULT([yes])
@@ -603,6 +625,7 @@ AC_INCLUDES_DEFAULT
 #include <openssl/evp.h>
 ])
 fi
+AC_SUBST(SSLLIB)
 
 
 AC_ARG_ENABLE(sha2, AC_HELP_STRING([--disable-sha2], [Disable SHA256 and 
SHA512 RRSIG support]))
@@ -714,7 +737,7 @@ AC_MSG_RESULT($ac_cv_c_gost_works)
 
 AC_ARG_ENABLE(gost, AC_HELP_STRING([--disable-gost], [Disable GOST support]))
 use_gost="no"
-if test $USE_NSS = "no"; then
+if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
 case "$enable_gost" in
        no)
        ;;
@@ -728,7 +751,7 @@ case "$enable_gost" in
        fi
        ;;
 esac
-fi dnl !USE_NSS
+fi dnl !USE_NSS && !USE_NETTLE
 
 AC_ARG_ENABLE(ecdsa, AC_HELP_STRING([--disable-ecdsa], [Disable ECDSA 
support]))
 use_ecdsa="no"
@@ -736,7 +759,7 @@ case "$enable_ecdsa" in
     no)
       ;;
     *)
-      if test $USE_NSS = "no"; then
+      if test $USE_NSS = "no" -a $USE_NETTLE = "no"; then
              AC_CHECK_FUNC(ECDSA_sign, [], [AC_MSG_ERROR([OpenSSL does not 
support ECDSA: please upgrade or rerun with --disable-ecdsa])])
              AC_CHECK_FUNC(SHA384_Init, [], [AC_MSG_ERROR([OpenSSL does not 
support SHA384: please upgrade or rerun with --disable-ecdsa])])
              AC_CHECK_DECLS([NID_X9_62_prime256v1, NID_secp384r1], [], 
[AC_MSG_ERROR([OpenSSL does not support the ECDSA curves: please upgrade or 
rerun with --disable-ecdsa])], [AC_INCLUDES_DEFAULT
@@ -882,6 +905,9 @@ if test x_$found_libexpat != x_yes; then
        AC_ERROR([Could not find libexpat, expat.h])
 fi
 AC_CHECK_HEADERS([expat.h],,, [AC_INCLUDES_DEFAULT])
+AC_CHECK_DECLS([XML_StopParser], [], [], [AC_INCLUDES_DEFAULT
+#include <expat.h>
+])
 
 # set static linking if requested
 AC_SUBST(staticexe)
@@ -986,7 +1012,7 @@ AC_INCLUDES_DEFAULT
 #endif
 ])
 AC_SEARCH_LIBS([setusercontext], [util])
-AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid 
sbrk chroot kill chown sleep usleep random srandom recvmsg sendmsg writev 
socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex 
endservent endprotoent])
+AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setrlimit setsid 
sbrk chroot kill chown sleep usleep random srandom recvmsg sendmsg writev 
socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex 
endservent endprotoent fsync])
 AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])])
 AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])])
 
@@ -998,10 +1024,25 @@ AC_REPLACE_FUNCS(inet_aton)
 AC_REPLACE_FUNCS(inet_pton)
 AC_REPLACE_FUNCS(inet_ntop)
 AC_REPLACE_FUNCS(snprintf)
+# test if snprintf return the proper length
+if test "x$ac_cv_func_snprintf" = xyes; then
+    if test c${cross_compiling} = cno; then
+       AC_MSG_CHECKING([for correct snprintf return value])
+       AC_RUN_IFELSE([AC_LANG_SOURCE(AC_INCLUDES_DEFAULT
+[[
+int main(void) { return !(snprintf(NULL, 0, "test") == 4); }
+]])], [AC_MSG_RESULT(yes)], [
+               AC_MSG_RESULT(no)
+               AC_DEFINE([SNPRINTF_RET_BROKEN], [], [define if (v)snprintf 
does not return length needed, (but length used)])
+               AC_LIBOBJ(snprintf)
+         ])
+    fi
+fi
 AC_REPLACE_FUNCS(strlcat)
 AC_REPLACE_FUNCS(strlcpy)
 AC_REPLACE_FUNCS(memmove)
 AC_REPLACE_FUNCS(gmtime_r)
+AC_REPLACE_FUNCS(isblank)
 dnl without CTIME, ARC4-functions and without reallocarray.
 LIBOBJ_WITHOUT_CTIMEARC4="$LIBOBJS"
 AC_SUBST(LIBOBJ_WITHOUT_CTIMEARC4)
@@ -1236,7 +1277,13 @@ AHX_CONFIG_FORMAT_ATTRIBUTE
 AHX_CONFIG_UNUSED_ATTRIBUTE
 AHX_CONFIG_FSEEKO
 AHX_CONFIG_MAXHOSTNAMELEN
-AHX_CONFIG_SNPRINTF(unbound)
+#if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN)
+#define snprintf snprintf_unbound
+#define vsnprintf vsnprintf_unbound
+#include <stdarg.h>
+int snprintf (char *str, size_t count, const char *fmt, ...);
+int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);
+#endif /* HAVE_SNPRINTF or SNPRINTF_RET_BROKEN */
 AHX_CONFIG_INET_PTON(unbound)
 AHX_CONFIG_INET_NTOP(unbound)
 AHX_CONFIG_INET_ATON(unbound)
@@ -1257,6 +1304,11 @@ AHX_MEMCMP_BROKEN(unbound)
 #ifndef HAVE_CTIME_R
 #define ctime_r unbound_ctime_r
 char *ctime_r(const time_t *timep, char *buf);
+#endif
+
+#ifndef HAVE_ISBLANK
+#define isblank unbound_isblank
+int isblank(int c);
 #endif
 
 #if !defined(HAVE_STRPTIME) || !defined(STRPTIME_WORKS)

Reply via email to