diff --git a/unbound-1.1-checkconf.patch b/unbound-1.1-checkconf.patch deleted file mode 100644 index dc0ab86..0000000 --- a/unbound-1.1-checkconf.patch +++ /dev/null @@ -1,15 +0,0 @@ -Index: smallapp/unbound-checkconf.c -=================================================================== ---- smallapp/unbound-checkconf.c (revision 1404) -+++ smallapp/unbound-checkconf.c (working copy) -@@ -258,7 +258,9 @@ - { - struct config_strlist* p; - for(p=list; p; p=p->next) { -- check_chroot_string(desc, &p->str, chrootdir, cfg); -+ /* skip wildcard checks, may fail */ -+ if(strstr(p->str,"*") == NULL) -+ check_chroot_string(desc, &p->str, chrootdir, cfg); - } - } - diff --git a/unbound-1.1-scandir.patch b/unbound-1.1-scandir.patch deleted file mode 100644 index b07d91f..0000000 --- a/unbound-1.1-scandir.patch +++ /dev/null @@ -1,73 +0,0 @@ -Index: validator/val_anchor.c -=================================================================== ---- validator/val_anchor.c (revision 1404) -+++ validator/val_anchor.c (working copy) -@@ -47,6 +47,11 @@ - #include "util/regional.h" - #include "util/config_file.h" - -+#include -+#include -+#include -+ -+ - int - anchor_cmp(const void* k1, const void* k2) - { -@@ -627,9 +633,53 @@ - FILE* in = fopen(fname, "r"); - int rdlen = 0; - if(!in) { -- log_err("error opening file %s: %s", fname, strerror(errno)); -- return 0; -- } -+ if(strstr(fname,"*")!=NULL) { -+ struct dirent **namelist; -+ char *fnameb = strdup(fname); -+ char *fnamef = strdup(fname); -+ char *dbase, *globmatch; -+ dbase = dirname(fnameb); -+ globmatch = basename(fnamef); -+ int n; -+ verbose(VERB_QUERY, "wildcard found, processing directory"); -+ n = scandir(dbase,&namelist, 0, 0); -+ if (n<0) { -+ log_err("error opening wildcard in dir: %s:", dbase); -+ free(namelist); -+ free(dbase); -+ free(fnameb); -+ free(fnamef); -+ free(globmatch); -+ return 1; -+ } -+ else { -+ while(n--) { -+ if (namelist[n]->d_type != DT_DIR) { -+ if(!fnmatch(globmatch,namelist[n]->d_name,0)) { -+ // log_err( "file %s matched pattern %s - loading", namelist[n]->d_name, globmatch); -+ char *newname = malloc(strlen(namelist[n]->d_name) + strlen(dbase) + strlen("/") + 1); -+ strcpy(newname, dbase); -+ strcat(newname,"/"); -+ strcat(newname, namelist[n]->d_name); -+ if(!anchor_read_bind_file(anchors, buffer,newname)) { -+ log_err("error reading wildcard trusted-keys-file: %s", newname); -+ } -+ free(newname); -+ } else { -+ // log_err("file %s did not match pattern %s", namelist[n]->d_name, globmatch); -+ } -+ } -+ free(namelist[n]); -+ } -+ free(namelist); -+ free(dbase); -+ // causes segfault free(fnameb); -+ free(fnamef); -+ // causes segfault free(globmatch); -+ } -+ return 1; -+ } -+ } - verbose(VERB_QUERY, "reading in bind-compat-mode: '%s'", fname); - /* scan for trusted-keys keyword, ignore everything else */ - ldns_buffer_clear(buffer); diff --git a/unbound-1.2-glob.patch b/unbound-1.2-glob.patch deleted file mode 100644 index 996ceac..0000000 --- a/unbound-1.2-glob.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff -Naur unbound-1.2.0/validator/val_anchor.c unbound-1.2.0.new/validator/val_anchor.c ---- unbound-1.2.0/validator/val_anchor.c 2009-01-07 07:24:34.000000000 -0500 -+++ unbound-1.2.0.new/validator/val_anchor.c 2009-01-20 17:31:43.000000000 -0500 -@@ -718,7 +718,8 @@ - log_err("wildcard trusted-keys-file %s: expansion " - "failed (%s)", pat, strerror(errno)); - } -- return 0; -+ /* ignore globs that yield no files */ -+ return 1; - } - /* process files found, if any */ - for(i=0; i<(size_t)g.gl_pathc; i++) { diff --git a/unbound-1.4.12-pythonmod.patch b/unbound-1.4.12-pythonmod.patch deleted file mode 100644 index 7bc9927..0000000 --- a/unbound-1.4.12-pythonmod.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- pythonmod/pythonmod.c.orig 2011-08-08 20:45:48.344987246 +0200 -+++ pythonmod/pythonmod.c 2011-08-08 21:31:41.429025557 +0200 -@@ -153,6 +153,8 @@ - } - PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n"); - PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n"); -+ PyRun_SimpleString("import sysconfig \n"); -+ PyRun_SimpleString("sys.path.append(sysconfig.get_path('purelib')) \n"); - if (PyRun_SimpleString("from unboundmodule import *\n") < 0) - { - log_err("pythonmod: cannot initialize core module: unboundmodule.py"); diff --git a/unbound-1.4.13-edns1480.patch b/unbound-1.4.13-edns1480.patch deleted file mode 100644 index 038b3ca..0000000 --- a/unbound-1.4.13-edns1480.patch +++ /dev/null @@ -1,109 +0,0 @@ -Index: services/outside_network.c -=================================================================== ---- services/outside_network.c (revision 2491) -+++ services/outside_network.c (revision 2493) -@@ -1199,6 +1199,7 @@ - if(sq->status == serviced_query_UDP_EDNS || - sq->status == serviced_query_UDP || - sq->status == serviced_query_PROBE_EDNS || -+ sq->status == serviced_query_UDP_EDNS_FRAG || - sq->status == serviced_query_UDP_EDNS_fallback) { - struct pending* p = (struct pending*)sq->pending; - if(p->pc) -@@ -1280,7 +1281,19 @@ - edns.edns_present = 1; - edns.ext_rcode = 0; - edns.edns_version = EDNS_ADVERTISED_VERSION; -- edns.udp_size = EDNS_ADVERTISED_SIZE; -+ if(sq->status == serviced_query_UDP_EDNS_FRAG) { -+ if(addr_is_ip6(&sq->addr, sq->addrlen)) { -+ if(EDNS_FRAG_SIZE_IP6 < EDNS_ADVERTISED_SIZE) -+ edns.udp_size = EDNS_FRAG_SIZE_IP6; -+ else edns.udp_size = EDNS_ADVERTISED_SIZE; -+ } else { -+ if(EDNS_FRAG_SIZE_IP4 < EDNS_ADVERTISED_SIZE) -+ edns.udp_size = EDNS_FRAG_SIZE_IP4; -+ else edns.udp_size = EDNS_ADVERTISED_SIZE; -+ } -+ } else { -+ edns.udp_size = EDNS_ADVERTISED_SIZE; -+ } - edns.bits = 0; - if(sq->dnssec & EDNS_DO) - edns.bits = EDNS_DO; -@@ -1324,7 +1337,8 @@ - sq->status = serviced_query_UDP; - } - } -- serviced_encode(sq, buff, sq->status == serviced_query_UDP_EDNS); -+ serviced_encode(sq, buff, (sq->status == serviced_query_UDP_EDNS) || -+ (sq->status == serviced_query_UDP_EDNS_FRAG)); - sq->last_sent_time = *sq->outnet->now_tv; - sq->edns_lame_known = (int)edns_lame_known; - verbose(VERB_ALGO, "serviced query UDP timeout=%d msec", rtt); -@@ -1564,6 +1578,20 @@ - * by EDNS. */ - sq->status = serviced_query_UDP_EDNS; - } -+ if(sq->status == serviced_query_UDP_EDNS) { -+ /* fallback to 1480/1280 */ -+ sq->status = serviced_query_UDP_EDNS_FRAG; -+ log_name_addr(VERB_ALGO, "try edns1xx0", sq->qbuf+10, -+ &sq->addr, sq->addrlen); -+ if(!serviced_udp_send(sq, c->buffer)) { -+ serviced_callbacks(sq, NETEVENT_CLOSED, c, rep); -+ } -+ return 0; -+ } -+ if(sq->status == serviced_query_UDP_EDNS_FRAG) { -+ /* fragmentation size did not fix it */ -+ sq->status = serviced_query_UDP_EDNS; -+ } - sq->retry++; - if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, - -1, sq->last_rtt, (uint32_t)now.tv_sec))) -@@ -1589,7 +1617,8 @@ - return 0; - } - if(!fallback_tcp) { -- if(sq->status == serviced_query_UDP_EDNS -+ if( (sq->status == serviced_query_UDP_EDNS -+ ||sq->status == serviced_query_UDP_EDNS_FRAG) - && (LDNS_RCODE_WIRE(ldns_buffer_begin(c->buffer)) - == LDNS_RCODE_FORMERR || LDNS_RCODE_WIRE( - ldns_buffer_begin(c->buffer)) == LDNS_RCODE_NOTIMPL)) { -@@ -1866,6 +1895,7 @@ - if(sq->status == serviced_query_UDP_EDNS || - sq->status == serviced_query_UDP || - sq->status == serviced_query_PROBE_EDNS || -+ sq->status == serviced_query_UDP_EDNS_FRAG || - sq->status == serviced_query_UDP_EDNS_fallback) { - s += sizeof(struct pending); - s += comm_timer_get_mem(NULL); -Index: services/outside_network.h -=================================================================== ---- services/outside_network.h (revision 2491) -+++ services/outside_network.h (revision 2493) -@@ -274,6 +274,11 @@ - void* cb_arg; - }; - -+/** fallback size for fragmentation for EDNS in IPv4 */ -+#define EDNS_FRAG_SIZE_IP4 1480 -+/** fallback size for EDNS in IPv6, fits one fragment with ip6-tunnel-ids */ -+#define EDNS_FRAG_SIZE_IP6 1260 -+ - /** - * Query service record. - * Contains query and destination. UDP, TCP, EDNS are all tried. -@@ -314,7 +319,9 @@ - /** probe to test noEDNS0 (EDNS gives FORMERRorNOTIMP) */ - serviced_query_UDP_EDNS_fallback, - /** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */ -- serviced_query_TCP_EDNS_fallback -+ serviced_query_TCP_EDNS_fallback, -+ /** send UDP query with EDNS1480 (or 1280) */ -+ serviced_query_UDP_EDNS_FRAG - } - /** variable with current status */ - status; diff --git a/unbound-1.4.15-version.patch b/unbound-1.4.15-version.patch deleted file mode 100644 index 59ded33..0000000 --- a/unbound-1.4.15-version.patch +++ /dev/null @@ -1,49 +0,0 @@ ->From fe05ea0802ff3f2fd2f49ed0bb3f1f0f4542f196 Mon Sep 17 00:00:00 2001 -From: "Robert S. Edmonds" -Date: Sat, 28 Jan 2012 20:05:43 -0500 -Subject: [PATCH] Makefile.in: use -version-info, not -version-number - -from the libtool manual: - - -version-info current[:revision[:age]] - If output-file is a libtool library, use interface version - information current, revision, and age to build it (see - Versioning). Do not use this flag to specify package release - information, rather see the -release flag. - - -version-number major[:minor[:revision]] - If output-file is a libtool library, compute interface version - information so that the resulting library uses the specified - major, minor and revision numbers. This is designed to permit - libtool to be used with existing projects where identical - version numbers are already used across operating systems. New - projects should use the -version-info flag instead. ---- - Makefile.in | 4 ++-- - 1 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/Makefile.in b/Makefile.in -index bdd8dba..4c26f52 100644 ---- a/Makefile.in -+++ b/Makefile.in -@@ -224,7 +224,7 @@ ALL_OBJ=$(COMMON_OBJ) $(UNITTEST_OBJ) $(DAEMON_OBJ) \ - - COMPILE=$(LIBTOOL) --tag=CC --mode=compile $(CC) $(CPPFLAGS) $(CFLAGS) - LINK=$(LIBTOOL) --tag=CC --mode=link $(CC) $(staticexe) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) --LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-number @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined -+LINK_LIB=$(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) $(staticexe) -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined - - .PHONY: clean realclean doc lint all install uninstall tests test strip lib longtest longcheck check - -@@ -369,7 +369,7 @@ libunbound/python/libunbound_wrap.c: $(srcdir)/libunbound/python/libunbound.i $( - - # Pyunbound python unbound wrapper - _unbound.la: libunbound_wrap.lo libunbound.la -- $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -version-number @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound $(LIBS) -+ $(LIBTOOL) --tag=CC --mode=link $(CC) $(RUNTIME_PATH) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -module -version-info @LIBUNBOUND_CURRENT@:@LIBUNBOUND_REVISION@:@LIBUNBOUND_AGE@ -no-undefined -o $@ libunbound_wrap.lo -rpath $(PYTHON_SITE_PKG) L. -L.libs -lunbound $(LIBS) - - util/config_file.c: util/configparser.h - util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h --- -1.7.8.3 - diff --git a/unbound-1.4.17-bug452.patch b/unbound-1.4.17-bug452.patch deleted file mode 100644 index 01545e0..0000000 --- a/unbound-1.4.17-bug452.patch +++ /dev/null @@ -1,100 +0,0 @@ -diff -aur unbound-1.4.17-orig/iterator/iterator.c unbound-1.4.17/iterator/iterator.c ---- unbound-1.4.17-orig/iterator/iterator.c 2012-03-21 11:01:01.000000000 -0400 -+++ unbound-1.4.17/iterator/iterator.c 2012-07-23 13:29:05.755093317 -0400 -@@ -1541,8 +1541,7 @@ - * the final state (i.e., on answer). - */ - static int --processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, -- int id) -+processDSNSFind(struct module_qstate* qstate, struct iter_qstate* iq, int id) - { - struct module_qstate* subq = NULL; - verbose(VERB_ALGO, "processDSNSFind"); -@@ -1906,8 +1905,16 @@ - if(iq->qchase.qtype == LDNS_RR_TYPE_DS && !iq->dsns_point - && !(iq->chase_flags&BIT_RD) - && iter_ds_toolow(iq->response, iq->dp) -- && iter_dp_cangodown(&iq->qchase, iq->dp)) -+ && iter_dp_cangodown(&iq->qchase, iq->dp)) { -+ /* close down outstanding requests to be discarded */ -+ outbound_list_clear(&iq->outlist); -+ iq->num_current_queries = 0; -+ fptr_ok(fptr_whitelist_modenv_detach_subs( -+ qstate->env->detach_subs)); -+ (*qstate->env->detach_subs)(qstate); -+ iq->num_target_queries = 0; - return processDSNSFind(qstate, iq, id); -+ } - if(!iter_dns_store(qstate->env, &iq->response->qinfo, - iq->response->rep, 0, qstate->prefetch_leeway, - iq->dp&&iq->dp->has_parent_side_NS, -@@ -2032,8 +2039,15 @@ - if(iq->qchase.qtype == LDNS_RR_TYPE_DS && !iq->dsns_point - && !(iq->chase_flags&BIT_RD) - && iter_ds_toolow(iq->response, iq->dp) -- && iter_dp_cangodown(&iq->qchase, iq->dp)) -+ && iter_dp_cangodown(&iq->qchase, iq->dp)) { -+ outbound_list_clear(&iq->outlist); -+ iq->num_current_queries = 0; -+ fptr_ok(fptr_whitelist_modenv_detach_subs( -+ qstate->env->detach_subs)); -+ (*qstate->env->detach_subs)(qstate); -+ iq->num_target_queries = 0; - return processDSNSFind(qstate, iq, id); -+ } - /* Process the CNAME response. */ - if(!handle_cname_response(qstate, iq, iq->response, - &sname, &snamelen)) -diff -aur unbound-1.4.17-orig/services/mesh.c unbound-1.4.17/services/mesh.c ---- unbound-1.4.17-orig/services/mesh.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-1.4.17/services/mesh.c 2012-07-23 13:27:08.163096837 -0400 -@@ -676,6 +676,7 @@ - /* find it, if not, create it */ - struct mesh_area* mesh = qstate->env->mesh; - struct mesh_state* sub = mesh_area_find(mesh, qinfo, qflags, prime); -+ int was_detached; - if(mesh_detect_cycle_found(qstate, sub)) { - verbose(VERB_ALGO, "attach failed, cycle detected"); - return 0; -@@ -706,9 +707,12 @@ - *newq = &sub->s; - } else - *newq = NULL; -+ was_detached = (sub->super_set.count == 0); - if(!mesh_state_attachment(qstate->mesh_info, sub)) - return 0; -- if(!sub->reply_list && !sub->cb_list && sub->super_set.count == 1) { -+ /* if it was a duplicate attachment, the count was not zero before */ -+ if(!sub->reply_list && !sub->cb_list && was_detached && -+ sub->super_set.count == 1) { - /* it used to be detached, before this one got added */ - log_assert(mesh->num_detached_states > 0); - mesh->num_detached_states--; -@@ -735,16 +739,20 @@ - superref->s = super; - subref->node.key = subref; - subref->s = sub; --#ifdef UNBOUND_DEBUG -- n = --#endif -- rbtree_insert(&sub->super_set, &superref->node); -- log_assert(n != NULL); -+ if(!rbtree_insert(&sub->super_set, &superref->node)) { -+ /* this should not happen, iterator and validator do not -+ * attach subqueries that are identical. */ -+ /* already attached, we are done, nothing todo. -+ * since superref and subref already allocated in region, -+ * we cannot free them */ -+ return 1; -+ } - #ifdef UNBOUND_DEBUG - n = - #endif - rbtree_insert(&super->sub_set, &subref->node); -- log_assert(n != NULL); -+ log_assert(n != NULL); /* we checked above if statement, the reverse -+ administration should not fail now, unless they are out of sync */ - return 1; - } - diff --git a/unbound-1.4.17-fips.patch b/unbound-1.4.17-fips.patch deleted file mode 100644 index c35cfd4..0000000 --- a/unbound-1.4.17-fips.patch +++ /dev/null @@ -1,109 +0,0 @@ -diff -Naur unbound-1.4.17-orig/config.h.in unbound-1.4.17/config.h.in ---- unbound-1.4.17-orig/config.h.in 2012-02-13 05:42:22.000000000 -0500 -+++ unbound-1.4.17/config.h.in 2012-07-03 11:08:53.440318529 -0400 -@@ -106,6 +106,9 @@ - /* Define to 1 if you have the `fcntl' function. */ - #undef HAVE_FCNTL - -+/* Define to 1 if you have the `FIPS_mode' function. */ -+#undef HAVE_FIPS_MODE -+ - /* Define to 1 if you have the `fork' function. */ - #undef HAVE_FORK - -diff -Naur unbound-1.4.17-orig/configure unbound-1.4.17/configure ---- unbound-1.4.17-orig/configure 2012-05-24 04:37:55.000000000 -0400 -+++ unbound-1.4.17/configure 2012-07-03 11:08:53.445318575 -0400 -@@ -16376,7 +16376,7 @@ - - done - --for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 -+for ac_func in OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode - 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" -diff -Naur unbound-1.4.17-orig/configure.ac unbound-1.4.17/configure.ac ---- unbound-1.4.17-orig/configure.ac 2012-05-15 10:50:21.000000000 -0400 -+++ unbound-1.4.17/configure.ac 2012-07-03 11:08:53.447318592 -0400 -@@ -515,7 +515,7 @@ - ACX_LIB_SSL - AC_CHECK_HEADERS([openssl/conf.h],,, [AC_INCLUDES_DEFAULT]) - AC_CHECK_HEADERS([openssl/engine.h],,, [AC_INCLUDES_DEFAULT]) --AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512]) -+AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode]) - AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free], [], [], [ - AC_INCLUDES_DEFAULT - #ifdef HAVE_OPENSSL_ERR_H -diff -Naur unbound-1.4.17-orig/util/random.c unbound-1.4.17/util/random.c ---- unbound-1.4.17-orig/util/random.c 2012-05-09 05:13:57.000000000 -0400 -+++ unbound-1.4.17/util/random.c 2012-07-03 11:08:53.440318529 -0400 -@@ -140,6 +140,16 @@ - return; - } - } -+#ifdef HAVE_FIPS_MODE -+ if(FIPS_mode()) { -+ /* RC4 is not allowed, get some trustworthy randomness */ -+ /* double certainty here, this routine should not be -+ * called in FIPS_mode */ -+ memset(rand_buf, 0, sizeof(rand_buf)); -+ s->rc4_ready = REKEY_BYTES; -+ return; -+ } -+#endif /* FIPS_MODE */ - RC4_set_key(&s->rc4, SEED_SIZE, (unsigned char*)rand_buf); - - /* -@@ -164,6 +174,9 @@ - return NULL; - } - ub_systemseed(seed); -+#ifdef HAVE_FIPS_MODE -+ if(!FIPS_mode()) -+#endif - ub_arc4random_stir(s, from); - return s; - } -@@ -172,6 +185,20 @@ - ub_random(struct ub_randstate* s) - { - unsigned int r = 0; -+#ifdef HAVE_FIPS_MODE -+ if(FIPS_mode()) { -+ /* RC4 is not allowed, get some trustworthy randomness */ -+ /* we use pseudo bytes: it tries to return secure randomness -+ * but returns 'something' if that fails. We need something -+ * else if it fails, because we cannot block here */ -+ if(RAND_pseudo_bytes((unsigned char*)&r, (int)sizeof(r)) -+ == -1) { -+ log_err("FIPSmode, no arc4random but RAND failed " -+ "(error %ld)", ERR_get_error()); -+ } -+ return (long int)((r) % (((unsigned)MAX_VALUE + 1))); -+ } -+#endif /* FIPS_MODE */ - if (s->rc4_ready <= 0) { - ub_arc4random_stir(s, NULL); - } -diff -Naur unbound-1.4.17-orig/validator/val_sigcrypt.c unbound-1.4.17/validator/val_sigcrypt.c ---- unbound-1.4.17-orig/validator/val_sigcrypt.c 2012-02-16 05:08:07.000000000 -0500 -+++ unbound-1.4.17/validator/val_sigcrypt.c 2012-07-03 11:15:31.724850996 -0400 -@@ -417,11 +417,16 @@ - dnskey_algo_id_is_supported(int id) - { - switch(id) { -+ case LDNS_RSAMD5: -+#ifdef HAVE_FIPS_MODE -+ return !FIPS_mode(); -+#else -+ return 1; -+#endif - case LDNS_DSA: - case LDNS_DSA_NSEC3: - case LDNS_RSASHA1: - case LDNS_RSASHA1_NSEC3: -- case LDNS_RSAMD5: - #if defined(HAVE_EVP_SHA256) && defined(USE_SHA2) - case LDNS_RSASHA256: - #endif diff --git a/unbound-1.4.18-includeglob.patch b/unbound-1.4.18-includeglob.patch deleted file mode 100644 index 7811754..0000000 --- a/unbound-1.4.18-includeglob.patch +++ /dev/null @@ -1,265 +0,0 @@ -diff -Naur unbound-1.4.18-orig/util/config_file.c unbound-1.4.18/util/config_file.c ---- unbound-1.4.18-orig/util/config_file.c 2012-06-18 10:22:29.000000000 -0400 -+++ unbound-1.4.18/util/config_file.c 2012-09-26 00:45:37.509190970 -0400 -@@ -53,6 +53,10 @@ - #include "util/regional.h" - #include "util/fptr_wlist.h" - #include "util/data/dname.h" -+#ifdef HAVE_GLOB_H -+# include -+#endif -+ - /** global config during parsing */ - struct config_parser_state* cfg_parser = 0; - /** lex in file */ -@@ -689,6 +693,65 @@ - char *fname = (char*)filename; - if(!fname) - return 1; -+ -+ /* check for wildcards */ -+#ifdef HAVE_GLOB -+ glob_t g; -+ size_t i; -+ int r, flags; -+ if(!(!strchr(fname, '*') && !strchr(fname, '?') && !strchr(fname, '[') && -+ !strchr(fname, '{') && !strchr(fname, '~'))) { -+ verbose(VERB_QUERY, "wildcard found, processing %s", fname); -+ flags = 0 -+#ifdef GLOB_ERR -+ | GLOB_ERR -+#endif -+#ifdef GLOB_NOSORT -+ | GLOB_NOSORT -+#endif -+#ifdef GLOB_BRACE -+ | GLOB_BRACE -+#endif -+#ifdef GLOB_TILDE -+ | GLOB_TILDE -+#endif -+ ; -+ memset(&g, 0, sizeof(g)); -+ r = glob(fname, flags, NULL, &g); -+ if(r) { -+ /* some error */ -+ if(r == GLOB_NOMATCH) { -+ verbose(VERB_QUERY, "include: " -+ "no matches for %s", fname); -+ return 1; -+ } else if(r == GLOB_NOSPACE) { -+ log_err("include: %s: " -+ "fnametern out of memory", fname); -+ } else if(r == GLOB_ABORTED) { -+ log_err("wildcard include: %s: expansion " -+ "aborted (%s)", fname, strerror(errno)); -+ } else { -+ log_err("wildcard include: %s: expansion " -+ "failed (%s)", fname, strerror(errno)); -+ } -+ /* ignore globs that yield no files */ -+ return 1; -+ } -+ /* process files found, if any */ -+ for(i=0; i<(size_t)g.gl_pathc; i++) { -+ if(!config_read(cfg, g.gl_pathv[i], chroot)) { -+ log_err("error reading wildcard " -+ "include: %s", g.gl_pathv[i]); -+ globfree(&g); -+ return 0; -+ } -+ } -+ globfree(&g); -+ return 1; -+ } -+#endif -+ -+ - in = fopen(fname, "r"); - if(!in) { - log_err("Could not open %s: %s", fname, strerror(errno)); -diff -Naur unbound-1.4.18-orig/util/configlexer.c unbound-1.4.18/util/configlexer.c ---- unbound-1.4.18-orig/util/configlexer.c 2012-08-02 03:26:14.000000000 -0400 -+++ unbound-1.4.18/util/configlexer.c 2012-09-26 00:47:40.856511450 -0400 -@@ -22,6 +22,10 @@ - #include - #include - #include -+#ifdef HAVE_GLOB_H -+# include -+#endif -+ - - /* end standard C headers. */ - -@@ -1827,7 +1831,7 @@ - } - input = fopen(filename, "r"); - if(!input) { -- ub_c_error_msg("cannot open include file '%s': %s", -+ ub_c_error_msg("(c)cannot open include file '%s': %s", - filename, strerror(errno)); - return; - } -@@ -1841,6 +1845,46 @@ - ++config_include_stack_ptr; - } - -+static void config_start_include_glob(const char* filename) -+{ -+#ifdef HAVE_GLOB -+ glob_t g; -+ size_t i; -+ int r, flags; -+ if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') && -+ !strchr(filename, '{') && !strchr(filename, '~'))) { -+ /* verbose(VERB_QUERY, "wildcard found, processing %s", filename); */ -+ flags = 0 -+#ifdef GLOB_ERR -+ | GLOB_ERR -+#endif -+#ifdef GLOB_NOSORT -+ | GLOB_NOSORT -+#endif -+#ifdef GLOB_BRACE -+ | GLOB_BRACE -+#endif -+#ifdef GLOB_TILDE -+ | GLOB_TILDE -+#endif -+ ; -+ memset(&g, 0, sizeof(g)); -+ r = glob(filename, flags, NULL, &g); -+ if(r) { -+ /* some error */ -+ return; -+ } -+ /* process files found, if any */ -+ for(i=0; i<(size_t)g.gl_pathc; i++) { -+ config_start_include(g.gl_pathv[i]); -+ } -+ globfree(&g); -+ return; -+ } -+#endif -+ config_start_include(filename); -+} -+ - static void config_end_include(void) - { - --config_include_stack_ptr; -@@ -2875,7 +2919,7 @@ - #line 300 "util/configlexer.lex" - { - LEXOUT(("Iunquotedstr(%s) ", yytext)); -- config_start_include(yytext); -+ config_start_include_glob(yytext); - BEGIN(inc_prev); - } - YY_BREAK -@@ -2904,7 +2948,7 @@ - { - LEXOUT(("IQE ")); - yytext[yyleng - 1] = '\0'; -- config_start_include(yytext); -+ config_start_include_glob(yytext); - BEGIN(inc_prev); - } - YY_BREAK -diff -Naur unbound-1.4.18-orig/util/configlexer.lex unbound-1.4.18/util/configlexer.lex ---- unbound-1.4.18-orig/util/configlexer.lex 2012-04-10 05:16:39.000000000 -0400 -+++ unbound-1.4.18/util/configlexer.lex 2012-09-26 00:46:59.135064805 -0400 -@@ -11,6 +11,9 @@ - #include - #include - #include -+#ifdef HAVE_GLOB_H -+# include -+#endif - - #include "util/config_file.h" - #include "util/configparser.h" -@@ -43,6 +46,7 @@ - static int inc_prev = 0; - static int num_args = 0; - -+ - static void config_start_include(const char* filename) - { - FILE *input; -@@ -60,7 +64,7 @@ - } - input = fopen(filename, "r"); - if(!input) { -- ub_c_error_msg("cannot open include file '%s': %s", -+ ub_c_error_msg("(lex)cannot open include file '%s': %s", - filename, strerror(errno)); - return; - } -@@ -74,6 +78,48 @@ - ++config_include_stack_ptr; - } - -+static void config_start_include_glob(const char* filename) -+{ -+ -+ /* check for wildcards */ -+#ifdef HAVE_GLOB -+ glob_t g; -+ size_t i; -+ int r, flags; -+ if(!(!strchr(filename, '*') && !strchr(filename, '?') && !strchr(filename, '[') && -+ !strchr(filename, '{') && !strchr(filename, '~'))) { -+ /* verbose(VERB_QUERY, "wildcard found, processing %s", filename); */ -+ flags = 0 -+#ifdef GLOB_ERR -+ | GLOB_ERR -+#endif -+#ifdef GLOB_NOSORT -+ | GLOB_NOSORT -+#endif -+#ifdef GLOB_BRACE -+ | GLOB_BRACE -+#endif -+#ifdef GLOB_TILDE -+ | GLOB_TILDE -+#endif -+ ; -+ memset(&g, 0, sizeof(g)); -+ r = glob(filename, flags, NULL, &g); -+ if(r) { -+ /* some error */ -+ return config_start_include(filename); /* let original deal with it */ -+ } -+ /* process files found, if any */ -+ for(i=0; i<(size_t)g.gl_pathc; i++) { -+ config_start_include(g.gl_pathv[i]); -+ } -+ globfree(&g); -+ return 1; -+ } -+#endif -+ -+ config_start_include(filename); -+} - static void config_end_include(void) - { - --config_include_stack_ptr; -@@ -299,7 +345,7 @@ - \" { LEXOUT(("IQS ")); BEGIN(include_quoted); } - {UNQUOTEDLETTER}* { - LEXOUT(("Iunquotedstr(%s) ", yytext)); -- config_start_include(yytext); -+ config_start_include_glob(yytext); - BEGIN(inc_prev); - } - <> { -@@ -312,7 +358,7 @@ - \" { - LEXOUT(("IQE ")); - yytext[yyleng - 1] = '\0'; -- config_start_include(yytext); -+ config_start_include_glob(yytext); - BEGIN(inc_prev); - } - <> { diff --git a/unbound-1.4.18-openssl_threads.patch b/unbound-1.4.18-openssl_threads.patch deleted file mode 100644 index 45b05ea..0000000 --- a/unbound-1.4.18-openssl_threads.patch +++ /dev/null @@ -1,104 +0,0 @@ -Index: daemon/daemon.c -=================================================================== ---- daemon/daemon.c (revision 2732) -+++ daemon/daemon.c (revision 2733) -@@ -209,6 +209,10 @@ - comp_meth = (void*)SSL_COMP_get_compression_methods(); - # endif - (void)SSL_library_init(); -+# if defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) -+ if(!ub_openssl_lock_init()) -+ fatal_exit("could not init openssl locks"); -+# endif - #elif defined(HAVE_NSS) - if(NSS_NoDB_Init(NULL) != SECSuccess) - fatal_exit("could not init NSS"); -@@ -568,6 +572,9 @@ - ERR_remove_state(0); - ERR_free_strings(); - RAND_cleanup(); -+# if defined(OPENSSL_THREADS) && !defined(THREADS_DISABLED) -+ ub_openssl_lock_delete(); -+# endif - #elif defined(HAVE_NSS) - NSS_Shutdown(); - #endif /* HAVE_SSL or HAVE_NSS */ -Index: util/net_help.c -=================================================================== ---- util/net_help.c (revision 2732) -+++ util/net_help.c (revision 2733) -@@ -725,3 +725,54 @@ - return NULL; - #endif - } -+ -+/** global lock list for openssl locks */ -+static lock_basic_t *ub_openssl_locks = NULL; -+ -+/** callback that gets thread id for openssl */ -+static unsigned long -+ub_crypto_id_cb(void) -+{ -+ return (unsigned long)ub_thread_self(); -+} -+ -+static void -+ub_crypto_lock_cb(int mode, int type, const char *ATTR_UNUSED(file), -+ int ATTR_UNUSED(line)) -+{ -+ if((mode&CRYPTO_LOCK)) { -+ lock_basic_lock(&ub_openssl_locks[type]); -+ } else { -+ lock_basic_unlock(&ub_openssl_locks[type]); -+ } -+} -+ -+int ub_openssl_lock_init(void) -+{ -+#ifdef OPENSSL_THREADS -+ size_t i; -+ ub_openssl_locks = (lock_basic_t*)malloc( -+ sizeof(lock_basic_t)*CRYPTO_num_locks()); -+ if(!ub_openssl_locks) -+ return 0; -+ for(i=0; i 1); -- return 0; /* no forwards above, no holes needed */ --} -- - /** insert a stub hole (if necessary) for stub name */ - static int - fwd_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm) -@@ -298,11 +279,8 @@ - key.dclass = c; - key.name = nm; - key.namelabs = dname_count_size_labels(key.name, &key.namelen); -- if(need_hole_insert(fwd->tree, &key)) { -- return forwards_insert_data(fwd, key.dclass, key.name, -- key.namelen, key.namelabs, NULL); -- } -- return 1; -+ return forwards_insert_data(fwd, key.dclass, key.name, -+ key.namelen, key.namelabs, NULL); - } - - /** make NULL entries for stubs */ diff --git a/unbound-1.4.19-888759.patch b/unbound-1.4.19-888759.patch deleted file mode 100644 index bc86810..0000000 --- a/unbound-1.4.19-888759.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff -Naur unbound-1.4.19-orig/smallapp/unbound-anchor.c unbound-1.4.19/smallapp/unbound-anchor.c ---- unbound-1.4.19-orig/smallapp/unbound-anchor.c 2012-10-30 11:13:53.000000000 -0400 -+++ unbound-1.4.19/smallapp/unbound-anchor.c 2012-12-20 13:18:11.048256192 -0500 -@@ -1503,6 +1503,20 @@ - } - } - -+/* Stop the parser when an entity declaration is encountered. For safety. */ -+static void -+xml_entitydeclhandler(void *userData, -+ const XML_Char *ATTR_UNUSED(entityName), -+ int ATTR_UNUSED(is_parameter_entity), -+ const XML_Char *ATTR_UNUSED(value), int ATTR_UNUSED(value_length), -+ const XML_Char *ATTR_UNUSED(base), -+ const XML_Char *ATTR_UNUSED(systemId), -+ const XML_Char *ATTR_UNUSED(publicId), -+ const XML_Char *ATTR_UNUSED(notationName)) -+{ -+ XML_StopParser((XML_Parser)userData, XML_FALSE); -+} -+ - /** - * XML parser setup of the callbacks for the tags - */ -@@ -1531,6 +1545,7 @@ - if(verb) printf("out of memory\n"); - exit(0); - } -+ XML_SetEntityDeclHandler(parser, xml_entitydeclhandler); - XML_SetElementHandler(parser, xml_startelem, xml_endelem); - XML_SetCharacterDataHandler(parser, xml_charhandle); - } diff --git a/unbound-1.4.4-00f12c.patch b/unbound-1.4.4-00f12c.patch deleted file mode 100644 index 4f14045..0000000 --- a/unbound-1.4.4-00f12c.patch +++ /dev/null @@ -1,52 +0,0 @@ -commit 00f12c3365fbb1f8a185a9972734c6bf225e7c0d -Author: wouter -Date: Tue Apr 27 14:15:19 2010 +0000 - - Fix harden-referral-path so it does not generate lookup failures. - -diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in -index fbe3748..16a607c 100644 ---- a/doc/unbound.conf.5.in -+++ b/doc/unbound.conf.5.in -@@ -456,6 +456,8 @@ path to the answer. - Default off, because it burdens the authority servers, and it is - not RFC standard, and could lead to performance problems because of the - extra query load that is generated. Experimental option. -+If you enable it consider adding more numbers after the target\-fetch\-policy -+to increase the max depth that is checked to. - .TP - .B use\-caps\-for\-id: \fI - Use 0x20\-encoded random bits in the query to foil spoof attempts. -diff --git a/iterator/iterator.c b/iterator/iterator.c -index 08354e8..19b9a26 100644 ---- a/iterator/iterator.c -+++ b/iterator/iterator.c -@@ -695,12 +695,15 @@ static void - generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq, - int id) - { -+ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; - struct module_qstate* subq; - size_t i; - struct reply_info* rep = iq->response->rep; - struct ub_packed_rrset_key* s; - log_assert(iq->dp); - -+ if(iq->depth == ie->max_dependency_depth) -+ return; - /* walk through additional, and check if in-zone, - * only relevant A, AAAA are left after scrub anyway */ - for(i=rep->an_numrrsets+rep->ns_numrrsets; irrset_count; i++) { -@@ -746,9 +749,12 @@ generate_a_aaaa_check(struct module_qstate* qstate, struct iter_qstate* iq, - static void - generate_ns_check(struct module_qstate* qstate, struct iter_qstate* iq, int id) - { -+ struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; - struct module_qstate* subq; - log_assert(iq->dp); - -+ if(iq->depth == ie->max_dependency_depth) -+ return; - /* is this query the same as the nscheck? */ - if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS && - query_dname_compare(iq->dp->name, qstate->qinfo.qname)==0 && diff --git a/unbound-1.4.4-28093c.patch b/unbound-1.4.4-28093c.patch deleted file mode 100644 index 64d4319..0000000 --- a/unbound-1.4.4-28093c.patch +++ /dev/null @@ -1,196 +0,0 @@ -commit 28093c6d7d9bafbb9763fc6d9b7f222642e8a835 -Author: wouter -Date: Thu Apr 22 15:01:02 2010 +0000 - - - Fix validation failure for qtype ANY caused by a RRSIG parse failure. - The validator error message was 'no signatures from ...'. - -diff --git a/testcode/unitmsgparse.c b/testcode/unitmsgparse.c -index 43e4377..d1ef854 100644 ---- a/testcode/unitmsgparse.c -+++ b/testcode/unitmsgparse.c -@@ -45,6 +45,7 @@ - #include "util/data/msgparse.h" - #include "util/data/msgreply.h" - #include "util/data/msgencode.h" -+#include "util/data/dname.h" - #include "util/alloc.h" - #include "util/regional.h" - #include "util/net_help.h" -@@ -54,6 +55,8 @@ - static int vbmp = 0; - /** if matching within a section should disregard the order of RRs. */ - static int matches_nolocation = 0; -+/** see if RRSIGs are properly matched to RRsets. */ -+static int check_rrsigs = 0; - - /** match two rr lists */ - static int -@@ -318,6 +321,76 @@ perftestpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, - regional_destroy(region); - } - -+/** debug print a packet that failed */ -+static void -+print_packet_rrsets(struct query_info* qinfo, struct reply_info* rep) -+{ -+ size_t i; -+ ldns_rr_list* l; -+ ldns_buffer* buf = ldns_buffer_new(65536); -+ log_query_info(0, "failed query", qinfo); -+ printf(";; ANSWER SECTION (%d rrsets)\n", (int)rep->an_numrrsets); -+ for(i=0; ian_numrrsets; i++) { -+ l = packed_rrset_to_rr_list(rep->rrsets[i], buf); -+ printf("; rrset %d\n", (int)i); -+ ldns_rr_list_print(stdout, l); -+ ldns_rr_list_deep_free(l); -+ } -+ printf(";; AUTHORITY SECTION (%d rrsets)\n", (int)rep->ns_numrrsets); -+ for(i=rep->an_numrrsets; ian_numrrsets+rep->ns_numrrsets; i++) { -+ l = packed_rrset_to_rr_list(rep->rrsets[i], buf); -+ printf("; rrset %d\n", (int)i); -+ ldns_rr_list_print(stdout, l); -+ ldns_rr_list_deep_free(l); -+ } -+ printf(";; ADDITIONAL SECTION (%d rrsets)\n", (int)rep->ar_numrrsets); -+ for(i=rep->an_numrrsets+rep->ns_numrrsets; irrset_count; i++) { -+ l = packed_rrset_to_rr_list(rep->rrsets[i], buf); -+ printf("; rrset %d\n", (int)i); -+ ldns_rr_list_print(stdout, l); -+ ldns_rr_list_deep_free(l); -+ } -+ printf(";; packet end\n"); -+ ldns_buffer_free(buf); -+} -+ -+/** check that there is no data element that matches the RRSIG */ -+static int -+no_data_for_rrsig(struct reply_info* rep, struct ub_packed_rrset_key* rrsig) -+{ -+ size_t i; -+ for(i=0; irrset_count; i++) { -+ if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_RRSIG) -+ continue; -+ if(query_dname_compare(rep->rrsets[i]->rk.dname, -+ rrsig->rk.dname) == 0) -+ /* only name is compared right now */ -+ return 0; -+ } -+ return 1; -+} -+ -+/** check RRSIGs in packet */ -+static void -+check_the_rrsigs(struct query_info* qinfo, struct reply_info* rep) -+{ -+ /* every RRSIG must be matched to an RRset */ -+ size_t i; -+ for(i=0; irrset_count; i++) { -+ struct ub_packed_rrset_key* s = rep->rrsets[i]; -+ if(ntohs(s->rk.type) == LDNS_RR_TYPE_RRSIG) { -+ /* see if really a problem, i.e. is there a data -+ * element. */ -+ if(no_data_for_rrsig(rep, rep->rrsets[i])) -+ continue; -+ log_dns_msg("rrsig failed for packet", qinfo, rep); -+ print_packet_rrsets(qinfo, rep); -+ printf("failed rrset is nr %d\n", (int)i); -+ unit_assert(0); -+ } -+ } -+} -+ - /** test a packet */ - static void - testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, -@@ -355,6 +428,8 @@ testpkt(ldns_buffer* pkt, struct alloc_cache* alloc, ldns_buffer* out, - (unsigned)ldns_buffer_limit(pkt), - (unsigned)ldns_buffer_limit(out)); - test_buffers(pkt, out); -+ if(check_rrsigs) -+ check_the_rrsigs(&qi, rep); - - if(ldns_buffer_limit(out) > lim) { - ret = reply_info_encode(&qi, rep, id, flags, out, -@@ -519,7 +594,9 @@ void msgparse_test() - - matches_nolocation = 1; /* RR order not important for the next test */ - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.6"); -+ check_rrsigs = 1; - testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.7"); -+ check_rrsigs = 0; - matches_nolocation = 0; - - /* cleanup */ -diff --git a/testdata/test_packets.7 b/testdata/test_packets.7 -index 4f71c2c..357fa40 100644 ---- a/testdata/test_packets.7 -+++ b/testdata/test_packets.7 -@@ -17,3 +17,21 @@ A608C7155005EBEDCA2176A559EFAF28D5DA1E91F540874BAA1C46BB08B1BAAE1812699A18139CF0 - 13BBDA2EC641FB23993A72ED6606C8C85E0D1660CC1770769697CEE7EB8E6474714984D7FF41FBBE48FF4A70669101BF00320340B82DC590B2C19D0006841121DC6AC933002E00010000012C007D000105030000012C4B11ADE94AEA20E9FC600673776974636802636800561C052414445D427CE00A40ACE2DA2EC168523823830CA724B087B8116F46B3CD051C5EC5874F6FC75CF6BA846279E469C474A75F9334242BB66FDD367C73B8BBC3F8748736BC5E6AED8B9B7C5FB5FE2DEDFBF46B403BC173DE958C038CFCCAC933002E00010000012C007D001C05030000012C4B11ADE94AEA20E9FC600673776974636802636800A6F44063C12A5A8BF5BCFADD - 745C5B3915E463DA478131E636347EED414675023BBCA5BA2AABEC2FA3DF976A2343B4AA3403D1AFA3D470D25812BD1A319FBB5B833244D0FA18A59BB69ABB77BBDB3D7F62740D3871A69A5B9D43331D78AB8AE8C91B002E00010000012C007D000105030000012C4B11ADE94AEA20E9FC6006737769746368026368008906D2CFEFC3AA652125DD021CAB6392EBC4A9B4B3CFE3B07E4AFE7DA3263C7B8CE5DC3B66DA45D120E75B3D49ADC1F7D2E9A04A31760698FCFDEAB4AC82915D8E0AD2494DB4F11C02E115C3BD47DC8E57EDA7805BF0E7820A445F93A07698DF0000291000000080000000 - -+;-- es.net IN ANY about RRSIG ordering. -+687D8410000100150000000E026573036E65740000FF0001C00C00060001000151800027036E7331C00C0A686F73746D6173746572C00C77CECF4300001C2000000E100012750000000258C00C002E000100015180011A00300502000151804BE2932A4BD0101A2522026573036E657400AF2107A80A9D98A0712FF20826B95D8E686FFF023BEEAD1019045569D94D1493C84C819446ECB5489EBC6B556F4BE4B51A8E9CAC8BAA69F2B74948B78CBB197044E3D3A9E0E5EA958254637984D34BAE34167E1437D275E01C4B7C04C34053333514E1FE7EAC7C4777B02F24356F1F775526E19F54A21D3A134DC74DE153F9267008F5605D3BE38E61352BA9495D77 -+97A76735BD68350CD648F40F95ADA4B25464A615E7CD4870E23C21D681F5C68C3DE9477D2EC7216FDF3269F5993428D0F1A4B7E203A04AB6807836263FDD7D6796BE6D84478B906B802DEBDCB1E0870481388503F0396CAD24147BC819A855E6CBCE98526ECAF8423450E30CB4F59C7062C069002E000100015180009A00300502000151804BE2932A4BD0101A4BA3026573036E657400602356C2D379E94F97D2900473D118288D46CFBCAAFF73D8A6FDF0B4305E8B338DD53A90106CDD78BF82A1AEC20B7C02067FDE1BEEC912E5581687BB32DD8BDC7E84B3F844F01E198E75C179194447C13B568886B33933FF35370060440D64E2DB7446962CA348C199 -+DDFE4AA252AFFDEB3A818D1BF45CD795EA0907332B4508C18F002E000100015180009A00060502000151804BE2932A4BD0101A4BA3026573036E6574004FFB07563C6F88028C0E09CF163BAC777065BDCC826C583A3B3ABD525D6AF5101A6D5533888E5BAAA33DE28B52330815E14034506C4C69EDE8AD1A1F00B486C670FE0DC2F3B5F7210EBAC66695CC8679F2CA2353666A143A2E3E87377DCD8D3E6E450934BBD4CC6F9EE033E11D05CA3F44B1A64A2666E3AF2A8710F16FF8CC33C235002E000100000258009A002F0502000002584BE2932A4BD0101A4BA3026573036E6574003D2DDC713285C7338263BD338AFEEAB77571054B1F483A7BADC87BAF32 -+0740A8D1B8B28CB23E04A80F90979704B44FE379103F4D91482D0EBC1D7005E326668F30B2A434F9DE76BB90DFEF2BFEDEE8CAD62164CA089651AB31498F18ED9A1E5694B4D460FFA4E667950322B2A75E8FD408B6A54EDB00257CE44AC865D1567346C2DB002E000100000258009A00100502000002584BE2932A4BD0101A4BA3026573036E6574004367180234A327C0AF72B3963518FC6E53A43E92CE6F5560E383FE8E7EF258FEA28BA666C026A90DAB67F46FBA4FF82F2704FEB3A27E25F3A8E6874B78938D70C5A20D94BEC90596B55C594F94A1438B14C8F890CE61D9630EFD897DEA9B3995D2C668469F62DB9346BB6AAF2EB6F3EE20EC31EAC80BCB -+962105A64CCD5783EFC381002E000100000258009A000F0502000002584BE2932A4BD0101A4BA3026573036E657400D36D367D4D95060CB2952870BE9E826E6F7835CF6517FF83957F5097B6FC401FE5815B8895D02C68E23A47D7015A3DCE9FDE63AF9D9E1D697016444355633D0BE03177B35BE54980B241C12978A7F3EBF2420861EBFAA028CAF9FCBBF54C069869BFB7F9AB9E60D4791ACCA276AE698EB6EF7582235977E158DA8530EC84327EC427002E000100000258009A00010502000002584BE2932A4BD0101A4BA3026573036E65740068E7176D8561B49621F80DB36DC12A3C5DCD2DE5FE3973F5D7DE15769F099F2A1A9BB088042E794747E3AB -+BB4AE48651F815D5D38BE7F4FB94F08F51FC209246296BE108111E90A7A5E2A5A79D305F81DBE313569B72598F36F3CFAA02FD9F321FBC2BDA10861F1D537D48DDF80BBF4B228724636FD79C06C4487365F602E6F5C4CD002E000100000258009A00020502000002584BE2932A4BD0101A4BA3026573036E657400BAA98093DDB57F38CA58C599EEED47F16AA20C1CCF668FF0A022AFAAC97059A28C50FE63034E58FBE361059B43FCBAE3876AC6AE8450987B8A00BEC29093267B9B655E645B7478294FF5E149984459A39D191585463BD80F635C21DBCF30462E60E4EACF8EECC25E4D02C181954CCBB8BDF5D19882CF6F9E982B1BEBEF14797DC573003000 -+0100015180008801000305030100017D08356710D7E8A11F9B4C29E5E0F6B65F18CE64B4AAFAD7EA0E08DB85013CD777436CB8BC4EE33C0B4E6EEDFBE4227B25354F2EA2F978EE3222F3F32C1D4D3AF0F6014A527981FC5A0D2B65BF78B86A1D37965A98CAE3746CBB250655C2200FB9B8EBCC8C0AFD3182738F246AD0DAACA3199C54F08CF5F666477281872710E7C573003000010001518000880100030503010001DF43A43270EA741D5E79034C5E46A8310C9CFC7BD65C532D815D6B8C245EFF8F0C365DE400B6CDAC0124B00E08017DFB98D91133D5C18251EE0868852AD9E7FED091B393DAD1CD57381A5A1E7EA74E8FB4B708DB0F93B9EA4296EA4A71 -+6E3572F168779CB5288880699413B3FFD4B7432EBE2AA2767B8EA6CB576A65C5163A3DC5730030000100015180010801010305030100017DA2FA058940109205AA36338EB8AA8B5B0D9788C4229368D371DBDE4BD24F0805C60EDD8DF223D250F23D189CDC434F388A91D6CEC1A9D6F305817409ACA784F381DFFD7EC3EC688FFE16D2AC57BD7F0B625EFC3099B3A9A5EDA1742460229669DD67D81F12069877F6AFA497F81EB12D179B183F5C8185B2786B790BEAFB6D02E0F94C780065511CF46AF80D40055022867DF712869CC262C0D315B92DFA96D58BC2336DAB5D1258DD60406913D116DC2EC1135D89C6D2092C35A19C67959743B407A3C30F3C6B8B -+C4763504FE12541EDD947A5FBE8E402D31816D1824867E2CD89AEE5FF6ED7A2D683B8C5E6B7B5972BDFF355BFD9128F0D0EDB59A60F321C573003000010001518001080101030503010001DD8EC709089B6D74BAF2D294E4C626CF789B89A74B7E320D7002A03D0F94EA62DF1F19717FE8C4BFD732DA495E481353C78167255CC6256A98ACBFF5977B81A48C5E2A5AF23E8377423C4034D5D84E9E3548B9D0A07955586F67324B6B5720CC4456D86AEE3A21A4EBED9BA13358C8127D182A5083739B042D7E06307E417D020DD68EC0628E9C8279AF0F7E608A3C5D51AB33BF7C32EBD27B45D72B1AD5752BB485D52488FBA9A1B5BF3B2B50F074F481171E4B65 -+3AF846E58FE46DEB3491FA683959B38B893BF55721CED8FC4A64DBEDB6BF1C7FADE650EE219A01E81DD0212B89259319CA5DC81F26821A5CC29B4CC1059AE28227B89B8816039E43C35E33C57300300001000151800108018103050301000188F31BEFA3466D6FCAF11E0D1954D2011D6EAECF922D9E1B8D620095A0D15E7CFF8EA33F8E2A8C3B3F45A1ADACFED62E3E4EDC884AEF8A7CADBCFF8EDF2158730136D01BDB6D057BEBF3D35A92ADB5E8ACB1152FE1244B2D36DCB500E952CFB6D744BF7DBAB24A901B984F869FF47113C9515D53FE1A57293B01C24195A1D40580566CDAE5B04348CB60507267BB38F34839EE959D43FB9605652157014059FDBD -+39EB0836D4043A63F8660D241006F757DB92B35B39B5ABCA32A16A81C65C9F53DA79A99F1134CF3ED5304F189434AF787A3A10D63862E6C2E5FBA08B6EF6701783DB00CB41851DF13070947EEC090FCED3539F3F494170BD90E68F99453DF9C573002F00010000025800220B726573657276652D3132380231340131026573036E657400000762018000000380CA7C0010000100000258009C9B763D73706631206D7820613A6D61696C312E65732E6E657420613A6D61696C322E65732E6E657420613A6D61696C332E65732E6E657420613A6D61696C342E65732E6E657420613A6D61696C2E65732E6E657420613A6D61696C67772E65732E6E657420613A -+706F7374616C312E65732E6E657420613A706F7374616C322E65732E6E657420613A706F7374616C332E65732E6E6574207E616C6CCA7C000F00010000025800090032046D61696CCA7CCA7C00010001000002580004C6800370CA7C00020001000002580009066E732D616F61CA7CCA7C00020001000002580002C024CA7C00020001000002580009066E732D6C766BCA7CCB4300010001000002580004C0BC1609CB43001C000100000258001020010400FFFFFFFFFFFFFFFFFFFFFF81C02400010001000151800004C680020AC024001C000100000258001020010400001400020000000000000010CB6600010001000002580004C67CFC16CB66001C0001 -+00000258001020010400600000000000000000000022CB8900010001000002580004C681FC22CB89001C000100000258001020010400091000010000000000000002CB43002E000100000258009A00010503000002584BE2932A4BD0101A4BA3026573036E657400B425467E45E411066B99B85420FB7E844D734F414FFAF6B9528867B3DF808733BF479A0F125C84179401306579994AB8D84DF0173E2824527CEDA45C75ED4D818722EEB2D5A37641108B112D9A6D832D29A507C35DBBEBD46D50DE9915E924F53F55B5A2A263A48B48209FB50A13A7DF40AE697B1BCCE71A2B95C1BB9E47ACCACB43002E000100000258009A001C0503000002584BE2932A -+4BD0101A4BA3026573036E6574002588E73F85BE8FAFD09628232906913DB78592B59F9C3C95A4AD1334D383C1326EE0C6FCF38892D8BB74631D680A6E4DB2D603D32394BC7B4EC798A1511667D246A0C30B33D03AB144C3704AA80AFCA27F197B2F83F20A9F0D2835C7C0A9B49E47E7CF2E192DC7DBF4635C39ECCCB291DB4B2832E0B8FF430A75726500194D9EC024002E000100015180009A00010503000151804BE2932A4BD0101A4BA3026573036E6574000E9F4098B1EF4F429B802007E3A9EA8E267A1F78EA7241AADD120A74CEBF70DC1DF76065A2CE0CDAA51AAB2F68411D9DEDC1F9DBEB3AB114A1FCBE122610756DE205EEC576CA5E62BD02497F -+84D5DDB7110AC7F2BF02485B3E7B28FC1EB2999724B64D811270B085D1D10E184295D423F0141D652BD7E97633AC2E98C2819EDAC024002E000100000258009A001C0503000002584BE2932A4BD0101A4BA3026573036E657400936ADA283A90836E92BD42E2B6C8A0299147BCB8E47D9D4464C4151FCC99DC4F2D1C39FB691F6E322715B22F61E7BB8D5507982A3119674B350C569BDC2CD95C708EC73B4E5DEA516D053A4FD725326FFC5B0D0562B542BA96124D9FFBBF787CA0BBE6960951CC2FDD074376A1D184287C2C56A93FBBC1C7FFAA6977B30AE808CB66002E000100000258009A00010503000002584BE2932A4BD0101A4BA3026573036E657400 -+0CE145578E56BB359606C9B85538450D2BCA3E9AD0DEFC8FF865DA646F900B9CBC7325B7F04706B60E2770107E62894FE9CF3B1A432F0FB53C5C7A8F37D0F60354C7D52F4DF88BDD4C46774AA728DFC1C807EF5276641CA28774F323C7326B7C1D99DFCB9498C6E096392009AA972B83F0583A5D1002CA26B59B5C97F6A8309C0000291000000080000000 -+ -diff --git a/util/data/msgparse.c b/util/data/msgparse.c -index 2db8832..ae6dfc1 100644 ---- a/util/data/msgparse.c -+++ b/util/data/msgparse.c -@@ -335,16 +335,20 @@ moveover_rrsigs(ldns_buffer* pkt, struct regional* region, - struct rr_parse* sig = sigset->rr_first; - struct rr_parse* prev = NULL; - struct rr_parse* insert; -+ struct rr_parse* nextsig; - while(sig) { -+ nextsig = sig->next; - if(pkt_rrsig_covered_equals(pkt, sig->ttl_data, - dataset->type)) { - if(duplicate) { - /* new */ - insert = (struct rr_parse*)regional_alloc( - region, sizeof(struct rr_parse)); -+ if(!insert) return 0; - insert->outside_packet = 0; - insert->ttl_data = sig->ttl_data; - insert->size = sig->size; -+ /* prev not used */ - } else { - /* remove from sigset */ - if(prev) prev->next = sig->next; -@@ -354,6 +358,7 @@ moveover_rrsigs(ldns_buffer* pkt, struct regional* region, - sigset->rr_count--; - sigset->size -= sig->size; - insert = sig; -+ /* prev not changed */ - } - /* add to dataset */ - dataset->rrsig_count++; -@@ -363,9 +368,9 @@ moveover_rrsigs(ldns_buffer* pkt, struct regional* region, - else dataset->rrsig_first = insert; - dataset->rrsig_last = insert; - dataset->size += insert->size; -- } -- prev = sig; -- sig = sig->next; -+ } else -+ prev = sig; -+ sig = nextsig; - } - return 1; - } diff --git a/unbound-1.4.4-374822.patch b/unbound-1.4.4-374822.patch deleted file mode 100644 index f99b55a..0000000 --- a/unbound-1.4.4-374822.patch +++ /dev/null @@ -1,38 +0,0 @@ -commit 374822322e33503d3576c85b3e43fef158a80e42 -Author: wouter -Date: Thu Apr 29 12:36:12 2010 +0000 - - dnssec lameness detection looks in key cache if dnssec is expected. - -diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c -index 6124650..f63b6fe 100644 ---- a/iterator/iter_utils.c -+++ b/iterator/iter_utils.c -@@ -60,6 +60,8 @@ - #include "util/random.h" - #include "util/fptr_wlist.h" - #include "validator/val_anchor.h" -+#include "validator/val_kcache.h" -+#include "validator/val_kentry.h" - - /** time when nameserver glue is said to be 'recent' */ - #define SUSPICION_RECENT_EXPIRY 86400 -@@ -570,6 +572,18 @@ iter_indicates_dnssec(struct module_env* env, struct delegpt* dp, - reply_find_rrset_section_ns(msg->rep, dp->name, dp->namelen, - LDNS_RR_TYPE_DS, dclass)) - return 1; -+ /* look in key cache */ -+ if(env->key_cache) { -+ struct key_entry_key* kk = key_cache_obtain(env->key_cache, -+ dp->name, dp->namelen, dclass, env->scratch, *env->now); -+ if(kk) { -+ if(key_entry_isgood(kk) || key_entry_isbad(kk)) { -+ regional_free_all(env->scratch); -+ return 1; -+ } -+ regional_free_all(env->scratch); -+ } -+ } - return 0; - } - diff --git a/unbound-1.4.4-40d18f.patch b/unbound-1.4.4-40d18f.patch deleted file mode 100644 index 23e73ae..0000000 --- a/unbound-1.4.4-40d18f.patch +++ /dev/null @@ -1,153 +0,0 @@ -commit 40d18f7cfb64a806699545410858b655e76660e1 -Author: wouter -Date: Tue May 4 08:39:04 2010 +0000 - - - Fix dnssec-missing detection that was turned off by server selection. - -diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c -index b3a31fa..3a75d03 100644 ---- a/iterator/iter_utils.c -+++ b/iterator/iter_utils.c -@@ -310,7 +310,7 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env, - struct delegpt_addr* - iter_server_selection(struct iter_env* iter_env, - struct module_env* env, struct delegpt* dp, -- uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_expected, -+ uint8_t* name, size_t namelen, uint16_t qtype, int* dnssec_lame, - int* chase_to_rd, int open_target, struct sock_list* blacklist) - { - int sel; -@@ -331,7 +331,7 @@ iter_server_selection(struct iter_env* iter_env, - if(selrtt-BLACKLIST_PENALTY > USEFUL_SERVER_TOP_TIMEOUT) { - verbose(VERB_ALGO, "chase to " - "blacklisted dnssec lame server"); -- *dnssec_expected = 0; -+ *dnssec_lame = 1; - } - } else { - if(selrtt > USEFUL_SERVER_TOP_TIMEOUT*2) { -@@ -340,7 +340,7 @@ iter_server_selection(struct iter_env* iter_env, - } - if(selrtt > USEFUL_SERVER_TOP_TIMEOUT) { - verbose(VERB_ALGO, "chase to dnssec lame server"); -- *dnssec_expected = 0; -+ *dnssec_lame = 1; - } - if(selrtt == USEFUL_SERVER_TOP_TIMEOUT) { - verbose(VERB_ALGO, "chase to blacklisted lame server"); -diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h -index a9f4247..d3870ec 100644 ---- a/iterator/iter_utils.h -+++ b/iterator/iter_utils.h -@@ -80,7 +80,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg); - * @param name: zone name (for lameness check). - * @param namelen: length of name. - * @param qtype: query type that we want to send. -- * @param dnssec_expected: set to 0, if a known dnssec-lame server is selected -+ * @param dnssec_lame: set to 1, if a known dnssec-lame server is selected - * these are not preferred, but are used as a last resort. - * @param chase_to_rd: set to 1 if a known recursion lame server is selected - * these are not preferred, but are used as a last resort. -@@ -92,7 +92,7 @@ int iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg); - */ - struct delegpt_addr* iter_server_selection(struct iter_env* iter_env, - struct module_env* env, struct delegpt* dp, uint8_t* name, -- size_t namelen, uint16_t qtype, int* dnssec_expected, -+ size_t namelen, uint16_t qtype, int* dnssec_lame, - int* chase_to_rd, int open_target, struct sock_list* blacklist); - - /** -diff --git a/iterator/iterator.c b/iterator/iterator.c -index 19b9a26..6f486bf 100644 ---- a/iterator/iterator.c -+++ b/iterator/iterator.c -@@ -120,6 +120,7 @@ iter_new(struct module_qstate* qstate, int id) - iq->wait_priming_stub = 0; - iq->refetch_glue = 0; - iq->dnssec_expected = 0; -+ iq->dnssec_lame_query = 0; - iq->chase_flags = qstate->query_flags; - /* Start with the (current) qname. */ - iq->qchase = qstate->qinfo; -@@ -1451,8 +1452,8 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - /* Select the next usable target, filtering out unsuitable targets. */ - target = iter_server_selection(ie, qstate->env, iq->dp, - iq->dp->name, iq->dp->namelen, iq->qchase.qtype, -- &iq->dnssec_expected, &iq->chase_to_rd, iq->num_target_queries, -- qstate->blacklist); -+ &iq->dnssec_lame_query, &iq->chase_to_rd, -+ iq->num_target_queries, qstate->blacklist); - - /* If no usable target was selected... */ - if(!target) { -@@ -1530,10 +1531,14 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - } - - /* We have a valid target. */ -- if(iq->dnssec_expected) verbose(VERB_ALGO, "dnssec is expected"); -- log_query_info(VERB_QUERY, "sending query:", &iq->qchase); -- log_name_addr(VERB_QUERY, "sending to target:", iq->dp->name, -- &target->addr, target->addrlen); -+ if(verbosity >= VERB_QUERY) { -+ log_query_info(VERB_QUERY, "sending query:", &iq->qchase); -+ log_name_addr(VERB_QUERY, "sending to target:", iq->dp->name, -+ &target->addr, target->addrlen); -+ verbose(VERB_ALGO, "dnssec status: %s%s", -+ iq->dnssec_expected?"expected": "not expected", -+ iq->dnssec_lame_query?" but lame_query anyway": ""); -+ } - fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query)); - outq = (*qstate->env->send_query)( - iq->qchase.qname, iq->qchase.qname_len, -@@ -1587,6 +1592,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - iq->num_current_queries--; - if(iq->response == NULL) { - iq->chase_to_rd = 0; -+ iq->dnssec_lame_query = 0; - verbose(VERB_ALGO, "query response was timeout"); - return next_state(iq, QUERYTARGETS_STATE); - } -@@ -1599,7 +1605,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - * differently. No queries should be sent elsewhere */ - type = RESPONSE_TYPE_ANSWER; - } -- if(iq->dnssec_expected && !(iq->chase_flags&BIT_RD) -+ if(iq->dnssec_expected && !iq->dnssec_lame_query && -+ !(iq->chase_flags&BIT_RD) - && type != RESPONSE_TYPE_LAME - && type != RESPONSE_TYPE_REC_LAME - && type != RESPONSE_TYPE_THROWAWAY -@@ -1615,7 +1622,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - type = RESPONSE_TYPE_LAME; - dnsseclame = 1; - } -- } -+ } else iq->dnssec_lame_query = 0; - /* see if referral brings us close to the target */ - if(type == RESPONSE_TYPE_REFERRAL) { - struct ub_packed_rrset_key* ns = find_NS( -@@ -1764,7 +1771,6 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, - /* Clear the query state, since this is a query restart. */ - iq->deleg_msg = NULL; - iq->dp = NULL; -- iq->dnssec_expected = 0; - /* Note the query restart. */ - iq->query_restart_count++; - -diff --git a/iterator/iterator.h b/iterator/iterator.h -index 736af51..350fb1d 100644 ---- a/iterator/iterator.h -+++ b/iterator/iterator.h -@@ -255,6 +255,12 @@ struct iter_qstate { - int dnssec_expected; - - /** -+ * We are expecting dnssec information, but we also know the server -+ * is DNSSEC lame. The response need not be marked dnssec-lame again. -+ */ -+ int dnssec_lame_query; -+ -+ /** - * This is flag that, if true, means that this event is - * waiting for a stub priming query. - */ diff --git a/unbound-1.4.4-41b631.patch b/unbound-1.4.4-41b631.patch deleted file mode 100644 index 29cff37..0000000 --- a/unbound-1.4.4-41b631.patch +++ /dev/null @@ -1,159 +0,0 @@ -commit 41b631ca4182e68b09eecdaec7d67ac576f3800d -Author: wouter -Date: Tue Apr 27 11:10:35 2010 +0000 - - - fix retry sequence if prime hints are recursion-lame. - -diff --git a/iterator/iterator.c b/iterator/iterator.c -index b1a948d..08354e8 100644 ---- a/iterator/iterator.c -+++ b/iterator/iterator.c -@@ -1897,8 +1897,11 @@ static int - processPrimeResponse(struct module_qstate* qstate, int id) - { - struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; -- enum response_type type = response_type_from_server(0, iq->response, -- &iq->qchase, iq->dp); -+ enum response_type type; -+ iq->response->rep->flags &= ~(BIT_RD|BIT_RA); /* ignore rec-lame */ -+ type = response_type_from_server( -+ (int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd), -+ iq->response, &iq->qchase, iq->dp); - if(type == RESPONSE_TYPE_ANSWER) { - qstate->return_rcode = LDNS_RCODE_NOERROR; - qstate->return_msg = iq->response; -@@ -2230,7 +2233,7 @@ void - iter_inform_super(struct module_qstate* qstate, int id, - struct module_qstate* super) - { -- if(super->qinfo.qclass == LDNS_RR_CLASS_ANY) -+ if(!qstate->is_priming && super->qinfo.qclass == LDNS_RR_CLASS_ANY) - processClassResponse(qstate, id, super); - else if(qstate->return_rcode != LDNS_RCODE_NOERROR) - error_supers(qstate, id, super); -diff --git a/testdata/iter_hint_lame.rpl b/testdata/iter_hint_lame.rpl -new file mode 100644 -index 0000000..8cbede1 ---- /dev/null -+++ b/testdata/iter_hint_lame.rpl -@@ -0,0 +1,120 @@ -+; config options -+server: -+ target-fetch-policy: "0 0 0 0 0" -+ -+stub-zone: -+ name: "." -+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. -+CONFIG_END -+ -+SCENARIO_BEGIN Test iterative resolve with lame hints. -+ -+; K.ROOT-SERVERS.NET. -+RANGE_BEGIN 0 100 -+ ADDRESS 193.0.14.129 -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR RA NOERROR -+SECTION QUESTION -+. IN NS -+SECTION ANSWER -+. IN NS K.ROOT-SERVERS.NET. -+SECTION ADDITIONAL -+K.ROOT-SERVERS.NET. IN A 193.0.14.129 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR RA NOERROR -+SECTION QUESTION -+www.example.com. IN A -+SECTION AUTHORITY -+com. IN NS a.gtld-servers.net. -+SECTION ADDITIONAL -+a.gtld-servers.net. IN A 192.5.6.30 -+ENTRY_END -+RANGE_END -+ -+; a.gtld-servers.net. -+RANGE_BEGIN 0 100 -+ ADDRESS 192.5.6.30 -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR NOERROR -+SECTION QUESTION -+com. IN NS -+SECTION ANSWER -+com. IN NS a.gtld-servers.net. -+SECTION ADDITIONAL -+a.gtld-servers.net. IN A 192.5.6.30 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR NOERROR -+SECTION QUESTION -+www.example.com. IN A -+SECTION AUTHORITY -+example.com. IN NS ns.example.com. -+SECTION ADDITIONAL -+ns.example.com. IN A 1.2.3.4 -+ENTRY_END -+RANGE_END -+ -+; ns.example.com. -+RANGE_BEGIN 0 100 -+ ADDRESS 1.2.3.4 -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR NOERROR -+SECTION QUESTION -+example.com. IN NS -+SECTION ANSWER -+example.com. IN NS ns.example.com. -+SECTION ADDITIONAL -+ns.example.com. IN A 1.2.3.4 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR NOERROR -+SECTION QUESTION -+www.example.com. IN A -+SECTION ANSWER -+www.example.com. IN A 10.20.30.40 -+SECTION AUTHORITY -+example.com. IN NS ns.example.com. -+SECTION ADDITIONAL -+ns.example.com. IN A 1.2.3.4 -+ENTRY_END -+RANGE_END -+ -+STEP 1 QUERY -+ENTRY_BEGIN -+REPLY RD -+SECTION QUESTION -+www.example.com. IN A -+ENTRY_END -+ -+; recursion happens here. -+STEP 10 CHECK_ANSWER -+ENTRY_BEGIN -+MATCH all -+REPLY QR RD RA NOERROR -+SECTION QUESTION -+www.example.com. IN A -+SECTION ANSWER -+www.example.com. IN A 10.20.30.40 -+SECTION AUTHORITY -+example.com. IN NS ns.example.com. -+SECTION ADDITIONAL -+ns.example.com. IN A 1.2.3.4 -+ENTRY_END -+ -+SCENARIO_END diff --git a/unbound-1.4.4-5e989a.patch b/unbound-1.4.4-5e989a.patch deleted file mode 100644 index 2c66bb4..0000000 --- a/unbound-1.4.4-5e989a.patch +++ /dev/null @@ -1,51 +0,0 @@ -commit 5e989a15b927094a83d0f3a08be0cd559e29d3ff -Author: wouter -Date: Fri Apr 23 09:07:05 2010 +0000 - - - Fix to fetch data as last resort more tenaciously. When cycle - targets cause the server selection to believe there are more options - when they really are not there, the server selection is reinitiated. - - Fix fetch from blacklisted dnssec lame servers as last resort. The - servers IP address is then given in validator errors as well. - -diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c -index a706e6b..9082055 100644 ---- a/iterator/iter_utils.c -+++ b/iterator/iter_utils.c -@@ -322,9 +322,15 @@ iter_server_selection(struct iter_env* iter_env, - verbose(VERB_ALGO, "selrtt %d", selrtt); - if(selrtt > BLACKLIST_PENALTY) { - if(selrtt-BLACKLIST_PENALTY > USEFUL_SERVER_TOP_TIMEOUT*2) { -- verbose(VERB_ALGO, "chase to recursion lame server"); -+ verbose(VERB_ALGO, "chase to " -+ "blacklisted recursion lame server"); - *chase_to_rd = 1; - } -+ if(selrtt-BLACKLIST_PENALTY > USEFUL_SERVER_TOP_TIMEOUT) { -+ verbose(VERB_ALGO, "chase to " -+ "blacklisted dnssec lame server"); -+ *dnssec_expected = 0; -+ } - } else { - if(selrtt > USEFUL_SERVER_TOP_TIMEOUT*2) { - verbose(VERB_ALGO, "chase to recursion lame server"); -diff --git a/iterator/iterator.c b/iterator/iterator.c -index e8345c8..c7cdbc8 100644 ---- a/iterator/iterator.c -+++ b/iterator/iterator.c -@@ -1469,6 +1469,15 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - return error_response(qstate, id, - LDNS_RCODE_SERVFAIL); - } -+ if(qs == 0 && -+ delegpt_count_missing_targets(iq->dp) == 0){ -+ /* it looked like there were missing -+ * targets, but they did not turn up. -+ * Try the bad choices again (if any), -+ * when we get back here missing==0, -+ * so this is not a loop. */ -+ return 1; -+ } - iq->num_target_queries += qs; - } - /* Since a target query might have been made, we diff --git a/unbound-1.4.4-5f58ed.patch b/unbound-1.4.4-5f58ed.patch deleted file mode 100644 index 5664e1b..0000000 --- a/unbound-1.4.4-5f58ed.patch +++ /dev/null @@ -1,18 +0,0 @@ -commit 5f58ed252d7bcd500ebedfb351e3ce7c84c44211 -Author: wouter -Date: Tue Apr 27 09:16:23 2010 +0000 - - unbound-control get_option domain-insecure works. - -diff --git a/util/config_file.c b/util/config_file.c -index aca82e1..ec0866c 100644 ---- a/util/config_file.c -+++ b/util/config_file.c -@@ -609,6 +609,7 @@ config_get_option(struct config_file* cfg, const char* opt, - else O_LST(opt, "trusted-keys-file", trusted_keys_file_list) - else O_LST(opt, "dlv-anchor", dlv_anchor_list) - else O_LST(opt, "control-interface", control_ifs) -+ else O_LST(opt, "domain-insecure", domain_insecure) - else O_UNS(opt, "val-override-date", val_date_override) - /* not here: - * outgoing-permit, outgoing-avoid - have list of ports diff --git a/unbound-1.4.4-74d75e.patch b/unbound-1.4.4-74d75e.patch deleted file mode 100644 index 95a88ad..0000000 --- a/unbound-1.4.4-74d75e.patch +++ /dev/null @@ -1,26 +0,0 @@ -commit 74d75e591a6f5343109922f2bf1f83eba59f0a4f -Author: wouter -Date: Thu Apr 29 12:52:44 2010 +0000 - - fix for key cache lookup - -diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c -index f63b6fe..b3a31fa 100644 ---- a/iterator/iter_utils.c -+++ b/iterator/iter_utils.c -@@ -577,9 +577,14 @@ iter_indicates_dnssec(struct module_env* env, struct delegpt* dp, - struct key_entry_key* kk = key_cache_obtain(env->key_cache, - dp->name, dp->namelen, dclass, env->scratch, *env->now); - if(kk) { -- if(key_entry_isgood(kk) || key_entry_isbad(kk)) { -+ if(query_dname_compare(kk->name, dp->name) == 0) { -+ if(key_entry_isgood(kk) || key_entry_isbad(kk)) { - regional_free_all(env->scratch); - return 1; -+ } else if(key_entry_isnull(kk)) { -+ regional_free_all(env->scratch); -+ return 0; -+ } - } - regional_free_all(env->scratch); - } diff --git a/unbound-1.4.4-778d4a.patch b/unbound-1.4.4-778d4a.patch deleted file mode 100644 index de05c0e..0000000 --- a/unbound-1.4.4-778d4a.patch +++ /dev/null @@ -1,77 +0,0 @@ -commit 778d4ab54a4e9efb41b042607b9a685853c5483c -Author: wouter -Date: Fri Apr 23 14:03:09 2010 +0000 - - - Fix local-zone type redirect that did not use the query name for - the answer rrset. - -diff --git a/services/localzone.c b/services/localzone.c -index dba7f3b..b8da77a 100644 ---- a/services/localzone.c -+++ b/services/localzone.c -@@ -1040,10 +1040,10 @@ local_data_answer(struct local_zone* z, struct query_info* qinfo, - if(!lr) - return 0; - if(z->type == local_zone_redirect) { -- /* convert rrset name to zone name; like a wildcard */ -+ /* convert rrset name to query name; like a wildcard */ - struct ub_packed_rrset_key r = *lr->rrset; -- r.rk.dname = z->name; -- r.rk.dname_len = z->namelen; -+ r.rk.dname = qinfo->qname; -+ r.rk.dname_len = qinfo->qname_len; - return local_encode(qinfo, edns, buf, temp, &r, 1, - LDNS_RCODE_NOERROR); - } -diff --git a/testdata/localdata.rpl b/testdata/localdata.rpl -index 5bb259e..08aec6d 100644 ---- a/testdata/localdata.rpl -+++ b/testdata/localdata.rpl -@@ -30,6 +30,10 @@ server: - ; refuse zone (error) - local-zone: "refuse.top." refuse - -+ ; redirect zone -+ local-zone: "redirect.top." redirect -+ local-data: "redirect.top. A 20.30.40.54" -+ - ; create implicit data in the IN domain as well - local-data: "a.a.implicit. A 20.30.41.50" - local-data: "b.a.implicit. A 20.30.42.50" -@@ -318,4 +322,36 @@ www.deny.top. IN A - ENTRY_END - ; no answer is checked at exit of testbound. - -+; redirect zone apex -+STEP 50 QUERY -+ENTRY_BEGIN -+SECTION QUESTION -+redirect.top. IN A -+ENTRY_END -+STEP 51 CHECK_ANSWER -+ENTRY_BEGIN -+MATCH all -+REPLY QR RA AA NOERROR -+SECTION QUESTION -+redirect.top. IN A -+SECTION ANSWER -+redirect.top. IN A 20.30.40.54 -+ENTRY_END -+ -+; redirect zone -+STEP 52 QUERY -+ENTRY_BEGIN -+SECTION QUESTION -+www.redirect.top. IN A -+ENTRY_END -+STEP 53 CHECK_ANSWER -+ENTRY_BEGIN -+MATCH all -+REPLY QR RA AA NOERROR -+SECTION QUESTION -+www.redirect.top. IN A -+SECTION ANSWER -+www.redirect.top. IN A 20.30.40.54 -+ENTRY_END -+ - SCENARIO_END diff --git a/unbound-1.4.4-7f27d6.patch b/unbound-1.4.4-7f27d6.patch deleted file mode 100644 index 76b8d77..0000000 --- a/unbound-1.4.4-7f27d6.patch +++ /dev/null @@ -1,88 +0,0 @@ -commit 7f27d6c9992fec6847ae914f38db6a3d1b28e81a -Author: wouter -Date: Thu Apr 29 14:12:54 2010 +0000 - - - infra cache entries that are expired are wiped clean. Previously - it was possible to not expire host data (if accessed often). - -diff --git a/services/cache/infra.c b/services/cache/infra.c -index 9c32c81..6066f98 100644 ---- a/services/cache/infra.c -+++ b/services/cache/infra.c -@@ -187,6 +187,19 @@ infra_lookup_host(struct infra_cache* infra, - return data; - } - -+/** init the host elements (not lame elems) */ -+static void -+host_entry_init(struct infra_cache* infra, struct lruhash_entry* e, -+ uint32_t timenow) -+{ -+ struct infra_host_data* data = (struct infra_host_data*)e->data; -+ data->ttl = timenow + infra->host_ttl; -+ rtt_init(&data->rtt); -+ data->edns_version = 0; -+ data->edns_lame_known = 0; -+ data->num_timeouts = 0; -+} -+ - /** - * Create and init a new entry for a host - * @param infra: infra structure with config parameters. -@@ -216,12 +229,8 @@ new_host_entry(struct infra_cache* infra, struct sockaddr_storage* addr, - key->entry.data = (void*)data; - key->addrlen = addrlen; - memcpy(&key->addr, addr, addrlen); -- data->ttl = tm + infra->host_ttl; - data->lameness = NULL; -- data->edns_version = 0; -- data->edns_lame_known = 0; -- data->num_timeouts = 0; -- rtt_init(&data->rtt); -+ host_entry_init(infra, &key->entry, tm); - return &key->entry; - } - -@@ -240,12 +249,8 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr, - if(e) { - /* if its still there we have a writelock, init */ - /* re-initialise */ -- data = (struct infra_host_data*)e->data; -- data->ttl = timenow + infra->host_ttl; -- rtt_init(&data->rtt); - /* do not touch lameness, it may be valid still */ -- data->edns_version = 0; -- data->edns_lame_known = 0; -+ host_entry_init(infra, e, timenow); - } - } - if(!e) { -@@ -469,10 +474,11 @@ infra_rtt_update(struct infra_cache* infra, - if(!(e = new_host_entry(infra, addr, addrlen, timenow))) - return 0; - needtoinsert = 1; -- } -- /* have an entry, update the rtt, and the ttl */ -+ } else if(((struct infra_host_data*)e->data)->ttl < timenow) { -+ host_entry_init(infra, e, timenow); -+ } -+ /* have an entry, update the rtt */ - data = (struct infra_host_data*)e->data; -- data->ttl = timenow + infra->host_ttl; - if(roundtrip == -1) { - rtt_lost(&data->rtt, orig_rtt); - if(data->num_timeouts<255) -@@ -503,10 +509,11 @@ infra_edns_update(struct infra_cache* infra, - if(!(e = new_host_entry(infra, addr, addrlen, timenow))) - return 0; - needtoinsert = 1; -- } -+ } else if(((struct infra_host_data*)e->data)->ttl < timenow) { -+ host_entry_init(infra, e, timenow); -+ } - /* have an entry, update the rtt, and the ttl */ - data = (struct infra_host_data*)e->data; -- data->ttl = timenow + infra->host_ttl; - data->edns_version = edns_version; - data->edns_lame_known = 1; - diff --git a/unbound-1.4.4-a6f07b.patch b/unbound-1.4.4-a6f07b.patch deleted file mode 100644 index 7285f03..0000000 --- a/unbound-1.4.4-a6f07b.patch +++ /dev/null @@ -1,62 +0,0 @@ -commit a6f07ba49319bbb62772a99cc3267fe8409a39d4 -Author: wouter -Date: Fri Apr 23 06:48:49 2010 +0000 - - - Squelch log message: sendto failed permission denied for - 255.255.255.255, it is visible in VERB_DETAIL (verbosity 2). - -diff --git a/util/net_help.c b/util/net_help.c -index 182f39d..7b2a3f4 100644 ---- a/util/net_help.c -+++ b/util/net_help.c -@@ -494,6 +494,14 @@ addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen) - return (memcmp(s, map_prefix, 12) == 0); - } - -+int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen) -+{ -+ int af = (int)((struct sockaddr_in*)addr)->sin_family; -+ void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; -+ return af == AF_INET && addrlen>=(socklen_t)sizeof(struct sockaddr_in) -+ && memcmp(sinaddr, "\377\377\377\377", 4) == 0; -+} -+ - void sock_list_insert(struct sock_list** list, struct sockaddr_storage* addr, - socklen_t len, struct regional* region) - { -diff --git a/util/net_help.h b/util/net_help.h -index 9ac96eb..8afa84b 100644 ---- a/util/net_help.h -+++ b/util/net_help.h -@@ -280,6 +280,14 @@ void addr_to_str(struct sockaddr_storage* addr, socklen_t addrlen, - int addr_is_ip4mapped(struct sockaddr_storage* addr, socklen_t addrlen); - - /** -+ * See if sockaddr is 255.255.255.255. -+ * @param addr: address -+ * @param addrlen: length of address -+ * @return true if so -+ */ -+int addr_is_broadcast(struct sockaddr_storage* addr, socklen_t addrlen); -+ -+/** - * Insert new socket list item. If fails logs error. - * @param list: pointer to pointer to first item. - * @param addr: address or NULL if 'cache'. -diff --git a/util/netevent.c b/util/netevent.c -index 4b6a0a3..3f3c6ce 100644 ---- a/util/netevent.c -+++ b/util/netevent.c -@@ -301,6 +301,12 @@ comm_point_send_udp_msg(struct comm_point *c, ldns_buffer* packet, - (struct sockaddr_storage*)addr, addrlen) && - verbosity < VERB_DETAIL) - return 0; -+ /* SO_BROADCAST sockopt can give access to 255.255.255.255, -+ * but a dns cache does not need it. */ -+ if(errno == EACCES && addr_is_broadcast( -+ (struct sockaddr_storage*)addr, addrlen) && -+ verbosity < VERB_DETAIL) -+ return 0; - #ifndef USE_WINSOCK - verbose(VERB_OPS, "sendto failed: %s", strerror(errno)); - #else diff --git a/unbound-1.4.4-c2baa7.patch b/unbound-1.4.4-c2baa7.patch deleted file mode 100644 index bf54a54..0000000 --- a/unbound-1.4.4-c2baa7.patch +++ /dev/null @@ -1,61 +0,0 @@ -commit c2baa73db1a2a0b0c0c8bba3d203a28ca86c5f31 -Author: wouter -Date: Tue May 4 10:50:27 2010 +0000 - - - Conforms to draft-ietf-dnsop-default-local-zones-13. Added default - reverse lookup blocks for IPv4 test nets 100.51.198.in-addr.arpa, - 113.0.203.in-addr.arpa and Orchid prefix 0.1.1.0.0.2.ip6.arpa. - -diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in -index 16a607c..40b4bad 100644 ---- a/doc/unbound.conf.5.in -+++ b/doc/unbound.conf.5.in -@@ -778,7 +778,8 @@ records are provided. - .TP 10 - \h'5'\fIreverse RFC3330 IP4 this, link\-local, testnet and broadcast\fR - Reverse data for zones 0.in\-addr.arpa, 254.169.in\-addr.arpa, --2.0.192.in\-addr.arpa, 255.255.255.255.in\-addr.arpa. -+2.0.192.in\-addr.arpa (TEST NET 1), 100.51.198.in\-addr.arpa (TEST NET 2), -+113.0.203.in\-addr.arpa (TEST NET 3), 255.255.255.255.in\-addr.arpa. - .TP 10 - \h'5'\fIreverse RFC4291 IP6 unspecified\fR - Reverse data for zone -@@ -793,12 +794,17 @@ Reverse data for zone D.F.ip6.arpa. - \h'5'\fIreverse RFC4291 IPv6 Link Local Addresses\fR - Reverse data for zones 8.E.F.ip6.arpa to B.E.F.ip6.arpa. - .TP 10 -+\h'5'\fIreverse RFC4843 Orchid Prefix\fR -+Reverse data for zone 0.1.1.0.0.2.ip6.arpa. -+.TP 10 - \h'5'\fIreverse IPv6 Example Prefix\fR - Reverse data for zone 8.B.D.0.1.0.0.2.ip6.arpa. This zone is used for - tutorials and examples. You can remove the block on this zone with: - .nf - local\-zone: 8.B.D.0.1.0.0.2.ip6.arpa. nodefault - .fi -+You can also selectively unblock a part of the zone by making that part -+transparent with a local\-zone statement. - This also works with the other default zones. - .\" End of local-zone listing. - .TP 5 -diff --git a/services/localzone.c b/services/localzone.c -index b8da77a..248d45f 100644 ---- a/services/localzone.c -+++ b/services/localzone.c -@@ -689,6 +689,8 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg, - !add_as112_default(zones, cfg, buf, "0.in-addr.arpa.") || - !add_as112_default(zones, cfg, buf, "254.169.in-addr.arpa.") || - !add_as112_default(zones, cfg, buf, "2.0.192.in-addr.arpa.") || -+ !add_as112_default(zones, cfg, buf, "100.51.198.in-addr.arpa.") || -+ !add_as112_default(zones, cfg, buf, "113.0.203.in-addr.arpa.") || - !add_as112_default(zones, cfg, buf, "255.255.255.255.in-addr.arpa.") || - !add_as112_default(zones, cfg, buf, "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.") || - !add_as112_default(zones, cfg, buf, "d.f.ip6.arpa.") || -@@ -696,6 +698,7 @@ lz_enter_defaults(struct local_zones* zones, struct config_file* cfg, - !add_as112_default(zones, cfg, buf, "9.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, buf, "a.e.f.ip6.arpa.") || - !add_as112_default(zones, cfg, buf, "b.e.f.ip6.arpa.") || -+ !add_as112_default(zones, cfg, buf, "0.1.1.0.0.2.ip6.arpa.") || - !add_as112_default(zones, cfg, buf, "8.b.d.0.1.0.0.2.ip6.arpa.")) { - log_err("out of memory adding default zone"); - return 0; diff --git a/unbound-1.4.4-d7ef7b.patch b/unbound-1.4.4-d7ef7b.patch deleted file mode 100644 index 868f826..0000000 --- a/unbound-1.4.4-d7ef7b.patch +++ /dev/null @@ -1,123 +0,0 @@ -commit d7ef7b31e0dbb0a73b201649c3729508b270f43f -Author: wouter -Date: Mon Apr 26 14:59:44 2010 +0000 - - Fix bug#307: 0x20 fallback outstanding query count, together with rec_lame, - and canonical rrset comparison. - -diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c -index 9082055..6124650 100644 ---- a/iterator/iter_utils.c -+++ b/iterator/iter_utils.c -@@ -674,7 +674,7 @@ rrset_equal(struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2) - } - - int --reply_equal(struct reply_info* p, struct reply_info* q) -+reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* scratch) - { - size_t i; - if(p->flags != q->flags || -@@ -688,8 +688,29 @@ reply_equal(struct reply_info* p, struct reply_info* q) - p->rrset_count != q->rrset_count) - return 0; - for(i=0; irrset_count; i++) { -- if(!rrset_equal(p->rrsets[i], q->rrsets[i])) -- return 0; -+ if(!rrset_equal(p->rrsets[i], q->rrsets[i])) { -+ /* fallback procedure: try to sort and canonicalize */ -+ ldns_rr_list* pl, *ql; -+ pl = packed_rrset_to_rr_list(p->rrsets[i], scratch); -+ ql = packed_rrset_to_rr_list(q->rrsets[i], scratch); -+ if(!pl || !ql) { -+ ldns_rr_list_deep_free(pl); -+ ldns_rr_list_deep_free(ql); -+ return 0; -+ } -+ ldns_rr_list2canonical(pl); -+ ldns_rr_list2canonical(ql); -+ ldns_rr_list_sort(pl); -+ ldns_rr_list_sort(ql); -+ if(ldns_rr_list_compare(pl, ql) != 0) { -+ ldns_rr_list_deep_free(pl); -+ ldns_rr_list_deep_free(ql); -+ return 0; -+ } -+ ldns_rr_list_deep_free(pl); -+ ldns_rr_list_deep_free(ql); -+ continue; -+ } - } - return 1; - } -@@ -792,3 +813,18 @@ iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, uint8_t* z) - i++; - } - } -+ -+void iter_dec_attempts(struct delegpt* dp, int d) -+{ -+ struct delegpt_addr* a; -+ for(a=dp->target_list; a; a = a->next_target) { -+ if(a->attempts >= OUTBOUND_MSG_RETRY) { -+ /* add back to result list */ -+ a->next_result = dp->result_list; -+ dp->result_list = a; -+ } -+ if(a->attempts > d) -+ a->attempts -= d; -+ else a->attempts = 0; -+ } -+} -diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h -index 9a1db5f..a9f4247 100644 ---- a/iterator/iter_utils.h -+++ b/iterator/iter_utils.h -@@ -211,9 +211,10 @@ int iter_msg_from_zone(struct dns_msg* msg, struct delegpt* dp, - * @param p: reply one. The reply has rrset data pointers in region. - * Does not check rrset-IDs - * @param q: reply two -+ * @param buf: scratch buffer. - * @return if one and two are equal. - */ --int reply_equal(struct reply_info* p, struct reply_info* q); -+int reply_equal(struct reply_info* p, struct reply_info* q, ldns_buffer* buf); - - /** - * Store in-zone glue in seperate rrset cache entries for later last-resort -@@ -257,4 +258,11 @@ int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd, - void iter_scrub_ds(struct dns_msg* msg, struct ub_packed_rrset_key* ns, - uint8_t* z); - -+/** -+ * Remove query attempts from all available ips. For 0x20. -+ * @param dp: delegpt. -+ * @param d: decrease. -+ */ -+void iter_dec_attempts(struct delegpt* dp, int d); -+ - #endif /* ITERATOR_ITER_UTILS_H */ -diff --git a/iterator/iterator.c b/iterator/iterator.c -index c7cdbc8..b1a948d 100644 ---- a/iterator/iterator.c -+++ b/iterator/iterator.c -@@ -1416,6 +1416,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, - "match for %d wanted, done.", - (int)iq->caps_server+1, (int)naddr*3); - iq->caps_fallback = 0; -+ iter_dec_attempts(iq->dp, 3); /* space for fallback */ -+ iq->num_current_queries++; /* RespState decrements it*/ -+ iq->referral_count++; /* make sure we don't loop */ - iq->state = QUERY_RESP_STATE; - return 1; - } -@@ -2384,7 +2387,8 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, - goto handle_it; - } else { - /* check if reply is the same, otherwise, fail */ -- if(!reply_equal(iq->response->rep, iq->caps_reply)) { -+ if(!reply_equal(iq->response->rep, iq->caps_reply, -+ qstate->env->scratch_buffer)) { - verbose(VERB_DETAIL, "Capsforid fallback: " - "getting different replies, failed"); - outbound_list_remove(&iq->outlist, outbound); diff --git a/unbound-CVE-2011-1922.patch b/unbound-CVE-2011-1922.patch deleted file mode 100644 index bdcacad..0000000 --- a/unbound-CVE-2011-1922.patch +++ /dev/null @@ -1,11 +0,0 @@ -diff -Naur unbound-1.4.9/daemon/worker.c unbound-1.4.9-CVE-2011-1922/daemon/worker.c ---- unbound-1.4.9/daemon/worker.c 2010-11-04 08:35:39.000000000 -0400 -+++ unbound-1.4.9-CVE-2011-1922/daemon/worker.c 2011-05-25 15:14:04.888288236 -0400 -@@ -777,6 +777,7 @@ - qinfo.qtype == LDNS_RR_TYPE_IXFR) { - verbose(VERB_ALGO, "worker request: refused zone transfer."); - log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen); -+ ldns_buffer_rewind(c->buffer); - LDNS_QR_SET(ldns_buffer_begin(c->buffer)); - LDNS_RCODE_SET(ldns_buffer_begin(c->buffer), - LDNS_RCODE_REFUSED); diff --git a/unbound-initgroups-r1453.patch b/unbound-initgroups-r1453.patch deleted file mode 100644 index 061c1f8..0000000 --- a/unbound-initgroups-r1453.patch +++ /dev/null @@ -1,105 +0,0 @@ -commit b1a2731277dd0939572901bf018afa7a0debdb54 -Author: wouter -Date: Thu Feb 5 11:12:01 2009 +0000 - - call initgroups. - - - git-svn-id: http://unbound.nlnetlabs.nl/svn/trunk@1453 be551aaa-1e26-0410-a405-d3ace91eadb9 - -diff --git a/config.h.in b/config.h.in -index 956224d..aa7ce2d 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -85,6 +85,9 @@ - /* Define to 1 if you have the `gmtime_r' function. */ - #undef HAVE_GMTIME_R - -+/* Define to 1 if you have the header file. */ -+#undef HAVE_GRP_H -+ - /* If you have HMAC_CTX_init */ - #undef HAVE_HMAC_CTX_INIT - -@@ -97,6 +100,9 @@ - /* Define to 1 if you have the `inet_pton' function. */ - #undef HAVE_INET_PTON - -+/* Define to 1 if you have the `initgroups' function. */ -+#undef HAVE_INITGROUPS -+ - /* Define to 1 if you have the header file. */ - #undef HAVE_INTTYPES_H - -diff --git a/configure b/configure -index a823b0b..0b1f96a 100755 ---- a/configure -+++ b/configure -@@ -19961,7 +19961,8 @@ fi - - - --for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h -+ -+for ac_header in stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h - do - as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -@@ -25282,7 +25283,8 @@ fi - - - --for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev setresuid setreuid setresgid setregid glob -+ -+for ac_func in tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev setresuid setreuid setresgid setregid glob initgroups - do - as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` - { echo "$as_me:$LINENO: checking for $ac_func" >&5 -diff --git a/configure.ac b/configure.ac -index bd000bc..48a4385 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -480,7 +480,7 @@ AC_PROG_LIBTOOL - - # Checks for header files. - AC_HEADER_STDC --AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h],,, [AC_INCLUDES_DEFAULT]) -+AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h],,, [AC_INCLUDES_DEFAULT]) - - # check for types - AC_CHECK_TYPE(int8_t, char) -@@ -854,7 +854,7 @@ AC_CHECK_GETADDRINFO_WITH_INCLUDES - if test $ac_cv_func_getaddrinfo = no; then - AC_LIBOBJ([fake-rfc2553]) - fi --AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev setresuid setreuid setresgid setregid glob]) -+AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam getrlimit setsid sbrk chroot kill sleep usleep random srandom recvmsg sendmsg writev setresuid setreuid setresgid setregid glob initgroups]) - - # check if setreuid en setregid fail, on MacOSX10.4(darwin8). - if echo $build_os | grep darwin8 > /dev/null; then -diff --git a/daemon/unbound.c b/daemon/unbound.c -index 09767a4..6c5fb6f 100644 ---- a/daemon/unbound.c -+++ b/daemon/unbound.c -@@ -56,6 +56,9 @@ - #ifdef HAVE_PWD_H - #include - #endif -+#ifdef HAVE_GRP_H -+#include -+#endif - - #ifdef HAVE_SYS_RESOURCE_H - #include -@@ -451,6 +454,11 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, - /* drop permissions after chroot, getpwnam, pidfile, syslog done*/ - #ifdef HAVE_GETPWNAM - if(cfg->username && cfg->username[0]) { -+#ifdef HAVE_INITGROUPS -+ if(initgroups(cfg->username, gid) != 0) -+ log_warn("unable to initgroups %s: %s", -+ cfg->username, strerror(errno)); -+#endif - #ifdef HAVE_SETRESGID - if(setresgid(gid,gid,gid) != 0) - #elif defined(HAVE_SETREGID) && !defined(DARWIN_BROKEN_SETREUID) diff --git a/unbound-iterator.patch b/unbound-iterator.patch deleted file mode 100644 index f5dd002..0000000 --- a/unbound-iterator.patch +++ /dev/null @@ -1,23 +0,0 @@ -Index: iterator/iterator.c -=================================================================== ---- iterator/iterator.c (revision 1527) -+++ iterator/iterator.c (working copy) -@@ -1288,14 +1288,14 @@ - /* if there is a policy to fetch missing targets - * opportunistically, do it. we rely on the fact that once a - * query (or queries) for a missing name have been issued, -- * they will not be show up again. */ -+ * they will not show up again. */ - } else if(tf_policy != 0) { - int extra = 0; - verbose(VERB_ALGO, "attempt to get extra %d targets", - tf_policy); -- if(!query_for_targets(qstate, iq, ie, id, tf_policy, &extra)) { -- return error_response(qstate, id, LDNS_RCODE_SERVFAIL); -- } -+ (void)query_for_targets(qstate, iq, ie, id, tf_policy, &extra); -+ /* errors ignored, these targets are not strictly necessary for -+ * this result, we do not have to reply with SERVFAIL */ - iq->num_target_queries += extra; - } - diff --git a/unbound-lame-r1953.patch b/unbound-lame-r1953.patch deleted file mode 100644 index 7f7d99e..0000000 --- a/unbound-lame-r1953.patch +++ /dev/null @@ -1,348 +0,0 @@ -Index: iterator/iter_delegpt.c -=================================================================== ---- iterator/iter_delegpt.c (revision 1952) -+++ iterator/iter_delegpt.c (revision 1953) -@@ -154,11 +154,13 @@ - /* ignore it */ - return 1; - } -- if(addr_is_ip6(addr, addrlen)) -- ns->got6 = 1; -- else ns->got4 = 1; -- if(ns->got4 && ns->got6) -- ns->resolved = 1; -+ if(!lame) { -+ if(addr_is_ip6(addr, addrlen)) -+ ns->got6 = 1; -+ else ns->got4 = 1; -+ if(ns->got4 && ns->got6) -+ ns->resolved = 1; -+ } - return delegpt_add_addr(dp, region, addr, addrlen, bogus, lame, nodup); - } - -@@ -254,10 +256,11 @@ - (dp->bogus?" BOGUS":"") ); - } - for(a = dp->target_list; a; a = a->next_target) { -- if(a->bogus) -- log_addr(VERB_ALGO, " BOGUS ", -- &a->addr, a->addrlen); -- else log_addr(VERB_ALGO, " ", &a->addr, a->addrlen); -+ const char* str = " "; -+ if(a->bogus && a->lame) str = " BOGUS ADDR_LAME "; -+ else if(a->bogus) str = " BOGUS "; -+ else if(a->lame) str = " ADDR_LAME "; -+ log_addr(VERB_ALGO, str, &a->addr, a->addrlen); - } - } - } -@@ -448,3 +451,13 @@ - } - } - } -+ -+void delegpt_no_ipv6(struct delegpt* dp) -+{ -+ struct delegpt_ns* ns; -+ for(ns = dp->nslist; ns; ns = ns->next) { -+ /* no ipv6, so only ipv4 is enough to resolve a nameserver */ -+ if(ns->got4) -+ ns->resolved = 1; -+ } -+} -Index: iterator/iter_delegpt.h -=================================================================== ---- iterator/iter_delegpt.h (revision 1952) -+++ iterator/iter_delegpt.h (revision 1953) -@@ -314,4 +314,11 @@ - */ - void delegpt_add_neg_msg(struct delegpt* dp, struct msgreply_entry* msg); - -+/** -+ * Register the fact that there is no ipv6 and thus AAAAs are not going -+ * to be queried for or be useful. -+ * @param dp: the delegation point. Updated to reflect no ipv6. -+ */ -+void delegpt_no_ipv6(struct delegpt* dp); -+ - #endif /* ITERATOR_ITER_DELEGPT_H */ -Index: iterator/iterator.c -=================================================================== ---- iterator/iterator.c (revision 1952) -+++ iterator/iterator.c (revision 1953) -@@ -1305,6 +1305,8 @@ - verbose(VERB_QUERY, "Failed to get a delegation, giving up"); - return error_response(qstate, id, LDNS_RCODE_SERVFAIL); - } -+ if(!ie->supports_ipv6) -+ delegpt_no_ipv6(iq->dp); - delegpt_log(VERB_ALGO, iq->dp); - - if(iq->num_current_queries>0) { -Index: doc/Changelog -=================================================================== ---- doc/Changelog (revision 1952) -+++ doc/Changelog (revision 1953) -@@ -1,3 +1,11 @@ -+8 January 2010: Wouter -+ - Fix for parent-child disagreement code which could have trouble -+ when (a) ipv6 was disabled and (b) the TTL for parent and child -+ were different. There were two bugs, the parent-side information -+ is fixed to no longer block lookup of child side information and -+ the iterator is fixed to no longer attempt to get ipv6 when it is -+ not enabled and then give up in failure. -+ - 7 January 2010: Wouter - - Fixup python documentation (thanks Leo Vandewoestijne). - - Work on cache prefetch feature. -Index: testdata/iter_pcttl.rpl -=================================================================== ---- testdata/iter_pcttl.rpl (revision 0) -+++ testdata/iter_pcttl.rpl (revision 1953) -@@ -0,0 +1,245 @@ -+; config options -+server: -+ target-fetch-policy: "0 0 0 0 0" -+ do-ip6: no -+ -+stub-zone: -+ name: "." -+ stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET. -+CONFIG_END -+ -+SCENARIO_BEGIN Test cache ttls where parent child differ in ttl -+; and the lameness for parent suddenly becomes the only information point. -+ -+; K.ROOT-SERVERS.NET. -+RANGE_BEGIN 0 100 -+ ADDRESS 193.0.14.129 -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR NOERROR -+SECTION QUESTION -+. IN NS -+SECTION ANSWER -+. IN NS K.ROOT-SERVERS.NET. -+SECTION ADDITIONAL -+K.ROOT-SERVERS.NET. IN A 193.0.14.129 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode subdomain -+ADJUST copy_id copy_query -+REPLY QR NOERROR -+SECTION QUESTION -+com. IN NS -+SECTION AUTHORITY -+com. IN NS a.gtld-servers.net. -+SECTION ADDITIONAL -+a.gtld-servers.net. IN A 192.5.6.30 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode subdomain -+ADJUST copy_id copy_query -+REPLY QR NOERROR -+SECTION QUESTION -+net. IN NS -+SECTION AUTHORITY -+net. IN NS e.gtld-servers.net. -+SECTION ADDITIONAL -+e.gtld-servers.net. IN A 192.12.94.30 -+ENTRY_END -+ -+RANGE_END -+ -+; a.gtld-servers.net. -+RANGE_BEGIN 0 100 -+ ADDRESS 192.5.6.30 -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR NOERROR -+SECTION QUESTION -+com. IN NS -+SECTION ANSWER -+com. IN NS a.gtld-servers.net. -+SECTION ADDITIONAL -+a.gtld-servers.net. IN A 192.5.6.30 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode subdomain -+ADJUST copy_id copy_query -+REPLY QR NOERROR -+SECTION QUESTION -+example.com. IN NS -+SECTION AUTHORITY -+example.com. IN NS ns.foo.com. -+SECTION ADDITIONAL -+;ns.foo.com. 200 IN A 1.2.3.44 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode subdomain -+ADJUST copy_id copy_query -+REPLY QR NOERROR -+SECTION QUESTION -+foo.com. IN NS -+SECTION AUTHORITY -+foo.com. 200 IN NS ns.foo.com. -+SECTION ADDITIONAL -+ns.foo.com. 200 IN A 1.2.3.44 -+ENTRY_END -+ -+RANGE_END -+ -+; e.gtld-servers.net. -+RANGE_BEGIN 0 100 -+ ADDRESS 192.12.94.30 -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY QR NOERROR -+SECTION QUESTION -+net. IN NS -+SECTION ANSWER -+net. IN NS e.gtld-servers.net. -+SECTION ADDITIONAL -+e.gtld-servers.net. IN A 192.12.94.30 -+ENTRY_END -+ -+RANGE_END -+ -+; ns.foo.com. -+; The parent-IP version -+RANGE_BEGIN 0 100 -+ ADDRESS 1.2.3.44 -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY AA QR NOERROR -+SECTION QUESTION -+foo.com. IN NS -+SECTION ANSWER -+foo.com. 200 IN NS ns.foo.com. -+SECTION ADDITIONAL -+ns.foo.com. 100 IN A 1.2.3.44 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY AA QR NOERROR -+SECTION QUESTION -+ns.foo.com. IN A -+SECTION ANSWER -+ns.foo.com. 100 IN A 1.2.3.44 -+SECTION AUTHORITY -+foo.com. 200 IN NS ns.foo.com. -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY AA QR NOERROR -+SECTION QUESTION -+ns.foo.com. IN AAAA -+SECTION AUTHORITY -+foo.com. 100 IN SOA . . 1 2 3 4 5 -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY AA QR NOERROR -+SECTION QUESTION -+example.com. IN NS -+SECTION ANSWER -+example.com. 200 IN NS ns.foo.com. -+ENTRY_END -+ -+ENTRY_BEGIN -+MATCH opcode qtype qname -+ADJUST copy_id -+REPLY AA QR NOERROR -+SECTION QUESTION -+www.example.com. IN A -+SECTION ANSWER -+www.example.com. 100 IN A 10.20.30.40 -+SECTION AUTHORITY -+example.com. 200 IN NS ns.foo.com. -+SECTION ADDITIONAL -+ns.foo.com 100 IN A 1.2.3.44 -+ENTRY_END -+RANGE_END -+ -+; NOT USED. The parent side equals child side but not in the cache. -+; and they have different TTLs only. -+; ns.foo.com -+; The child IP version. Does not respond to anything (servfail instead -+; of timeouts since this is easier to encode in .rpl file format). -+RANGE_BEGIN 0 100 -+ ADDRESS 1.2.3.55 -+ENTRY_BEGIN -+MATCH opcode -+ADJUST copy_id copy_query -+REPLY QR SERVFAIL -+SECTION QUESTION -+foo.com. IN NS -+SECTION ANSWER -+ENTRY_END -+ -+RANGE_END -+ -+STEP 1 QUERY -+ENTRY_BEGIN -+REPLY RD -+SECTION QUESTION -+www.example.com. IN A -+ENTRY_END -+ -+; recursion happens here. -+STEP 20 CHECK_ANSWER -+ENTRY_BEGIN -+MATCH all -+REPLY QR RD RA NOERROR -+SECTION QUESTION -+www.example.com. IN A -+SECTION ANSWER -+www.example.com. 100 IN A 10.20.30.40 -+SECTION AUTHORITY -+example.com. 100 IN NS ns.foo.com. -+; scrubbed off -+;SECTION ADDITIONAL -+;ns.foo.com IN A 1.2.3.44 -+ENTRY_END -+ -+; Now we wait 101 seconds, and the child data is gone, -+; but the parent-side was cached for 200 and it still there. -+ -+STEP 30 TIME_PASSES ELAPSE 101 -+ -+STEP 40 QUERY -+ENTRY_BEGIN -+REPLY RD -+SECTION QUESTION -+www.example.com. IN A -+ENTRY_END -+ -+; recursion happens here. -+STEP 50 CHECK_ANSWER -+ENTRY_BEGIN -+MATCH all -+REPLY QR RD RA NOERROR -+SECTION QUESTION -+www.example.com. IN A -+SECTION ANSWER -+www.example.com. 100 IN A 10.20.30.40 -+SECTION AUTHORITY -+example.com. 100 IN NS ns.foo.com. -+; scrubbed off -+;SECTION ADDITIONAL -+;ns.foo.com IN A 1.2.3.44 -+ENTRY_END -+ -+SCENARIO_END diff --git a/unbound-r1657.patch b/unbound-r1657.patch deleted file mode 100644 index b4e6482..0000000 --- a/unbound-r1657.patch +++ /dev/null @@ -1,66 +0,0 @@ -Index: validator/validator.c -=================================================================== ---- validator/validator.c (revision 1656) -+++ validator/validator.c (revision 1657) -@@ -251,9 +251,8 @@ - /** - * Check to see if a given response needs to go through the validation - * process. Typical reasons for this routine to return false are: CD bit was -- * on in the original request, the response was already validated, or the -- * response is a kind of message that is unvalidatable (i.e., SERVFAIL, -- * REFUSED, etc.) -+ * on in the original request, or the response is a kind of message that -+ * is unvalidatable (i.e., SERVFAIL, REFUSED, etc.) - * - * @param qstate: query state. - * @param ret_rc: rcode for this message (if noerror - examine ret_msg). -@@ -292,14 +291,25 @@ - verbose(VERB_ALGO, "cannot validate RRSIG, no sigs on sigs."); - return 0; - } -+ return 1; -+} - -+/** -+ * Check to see if the response has already been validated. -+ * @param ret_msg: return msg, can be NULL -+ * @return true if the response has already been validated -+ */ -+static int -+already_validated(struct dns_msg* ret_msg) -+{ - /* validate unchecked, and re-validate bogus messages */ - if (ret_msg && ret_msg->rep->security > sec_status_bogus) - { -- verbose(VERB_ALGO, "response has already been validated"); -- return 0; -+ verbose(VERB_ALGO, "response has already been validated: %s", -+ sec_status_to_string(ret_msg->rep->security)); -+ return 1; - } -- return 1; -+ return 0; - } - - /** -@@ -1937,6 +1947,10 @@ - qstate->ext_state[id] = module_finished; - return; - } -+ if(already_validated(qstate->return_msg)) { -+ qstate->ext_state[id] = module_finished; -+ return; -+ } - /* create state to start validation */ - qstate->ext_state[id] = module_error; /* override this */ - if(!vq) { -@@ -2397,7 +2411,8 @@ - } - if(msg->rep->security != sec_status_secure) { - vq->dlv_status = dlv_error; -- verbose(VERB_ALGO, "response is not secure"); -+ verbose(VERB_ALGO, "response is not secure, %s", -+ sec_status_to_string(msg->rep->security)); - return; - } - /* was the lookup a success? validated DLV? */ diff --git a/unbound-r1670.patch b/unbound-r1670.patch deleted file mode 100644 index 6ad2bd8..0000000 --- a/unbound-r1670.patch +++ /dev/null @@ -1,77 +0,0 @@ -Index: validator/validator.c -=================================================================== ---- validator/validator.c (revision 1669) -+++ validator/validator.c (revision 1670) -@@ -479,6 +479,36 @@ - } - - /** -+ * Detect wrong truncated response, by a bad recursor out there. -+ * The positive response has a mangled authority section. -+ * Remove that authority section. -+ * @param rep: reply -+ * @return true if a wrongly truncated response. -+ */ -+static int -+detect_wrongly_truncated(struct reply_info* rep) -+{ -+ size_t i; -+ /* no additional, only NS in authority, and it is bogus */ -+ if(rep->ar_numrrsets != 0 || rep->ns_numrrsets != 1 || -+ rep->an_numrrsets == 0) -+ return 0; -+ if(ntohs(rep->rrsets[ rep->an_numrrsets ]->rk.type) != LDNS_RR_TYPE_NS) -+ return 0; -+ if(((struct packed_rrset_data*)rep->rrsets[ rep->an_numrrsets ] -+ ->entry.data)->security != sec_status_bogus) -+ return 0; -+ /* answer section is present and secure */ -+ for(i=0; ian_numrrsets; i++) { -+ if(((struct packed_rrset_data*)rep->rrsets[ i ] -+ ->entry.data)->security != sec_status_secure) -+ return 0; -+ } -+ return 1; -+} -+ -+ -+/** - * Given a "positive" response -- a response that contains an answer to the - * question, and no CNAME chain, validate this response. - * -@@ -1449,17 +1479,31 @@ - vq->chase_reply->security = sec_status_bogus; - return 1; - } -+ subtype = val_classify_response(qstate->query_flags, &qstate->qinfo, -+ &vq->qchase, vq->orig_msg->rep, vq->rrset_skip); - - /* check signatures in the message; - * answer and authority must be valid, additional is only checked. */ - if(!validate_msg_signatures(qstate->env, ve, &vq->qchase, - vq->chase_reply, vq->key_entry)) { -- verbose(VERB_DETAIL, "Validate: message contains bad rrsets"); -- return 1; -+ /* workaround bad recursor out there that truncates (even -+ * with EDNS4k) to 512 by removing RRSIG from auth section -+ * for positive replies*/ -+ if(subtype == VAL_CLASS_POSITIVE && -+ detect_wrongly_truncated(vq->orig_msg->rep)) { -+ /* truncate the message some more */ -+ vq->orig_msg->rep->ns_numrrsets = 0; -+ vq->orig_msg->rep->rrset_count--; -+ vq->chase_reply->ns_numrrsets = 0; -+ vq->chase_reply->rrset_count--; -+ } -+ else { -+ verbose(VERB_DETAIL, "Validate: message contains " -+ "bad rrsets"); -+ return 1; -+ } - } - -- subtype = val_classify_response(qstate->query_flags, &qstate->qinfo, -- &vq->qchase, vq->orig_msg->rep, vq->rrset_skip); - switch(subtype) { - case VAL_CLASS_POSITIVE: - verbose(VERB_ALGO, "Validating a positive response"); diff --git a/unbound-r1677.patch b/unbound-r1677.patch deleted file mode 100644 index 3707085..0000000 --- a/unbound-r1677.patch +++ /dev/null @@ -1,33 +0,0 @@ -Index: validator/validator.c -=================================================================== ---- validator/validator.c (revision 1677) -+++ validator/validator.c (working copy) -@@ -479,7 +479,7 @@ - } - - /** -- * Detect wrong truncated response, by a bad recursor out there. -+ * Detect wrong truncated response (from BIND 9.6.1 with minimal-responses). - * The positive response has a mangled authority section. - * Remove that authority section. - * @param rep: reply -Index: iterator/iterator.c -=================================================================== ---- iterator/iterator.c (revision 1677) -+++ iterator/iterator.c (working copy) -@@ -1513,9 +1513,14 @@ - /* we know that all other NS rrsets are scrubbed - * away, thus on referral only one is left. - * see if that equals the query name... */ -- && reply_find_rrset_section_ns(iq->response->rep, -+ && ( /* auth section, but sometimes in answer section*/ -+ reply_find_rrset_section_ns(iq->response->rep, - qstate->qinfo.qname, qstate->qinfo.qname_len, - LDNS_RR_TYPE_NS, qstate->qinfo.qclass) -+ || reply_find_rrset_section_an(iq->response->rep, -+ qstate->qinfo.qname, qstate->qinfo.qname_len, -+ LDNS_RR_TYPE_NS, qstate->qinfo.qclass) -+ ) - )) { - /* Store the referral under the current query */ - if(!iter_dns_store(qstate->env, &iq->response->qinfo, diff --git a/unbound-trunk.patch b/unbound-trunk.patch deleted file mode 100644 index ae66b6b..0000000 --- a/unbound-trunk.patch +++ /dev/null @@ -1,3316 +0,0 @@ -diff -Naur unbound-1.4.16/compat/memcmp.h unbound-trunk/compat/memcmp.h ---- unbound-1.4.16/compat/memcmp.h 1969-12-31 19:00:00.000000000 -0500 -+++ unbound-trunk/compat/memcmp.h 2012-02-22 20:37:14.182368184 -0500 -@@ -0,0 +1,16 @@ -+/* -+ * memcmp.h: undef memcmp for compat. -+ * -+ * Copyright (c) 2012, NLnet Labs. All rights reserved. -+ * -+ * See LICENSE for the license. -+*/ -+#ifndef COMPAT_MEMCMP_H -+#define COMPAT_MEMCMP_H -+ -+#ifdef memcmp -+/* undef here otherwise autoheader messes it up in config.h */ -+# undef memcmp -+#endif -+ -+#endif /* COMPAT_MEMCMP_H */ -diff -Naur unbound-1.4.16/daemon/cachedump.c unbound-trunk/daemon/cachedump.c ---- unbound-1.4.16/daemon/cachedump.c 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/daemon/cachedump.c 2012-02-22 20:37:15.803368186 -0500 -@@ -765,7 +765,7 @@ - if(!go_on) - return 1; /* skip this one, not all references satisfied */ - -- if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, NULL)) { -+ if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL)) { - log_warn("error out of memory"); - return 0; - } -@@ -802,7 +802,8 @@ - { - char buf[257]; - struct delegpt_addr* a; -- int lame, dlame, rlame, rto, edns_vs, to, delay, entry_ttl; -+ int lame, dlame, rlame, rto, edns_vs, to, delay, entry_ttl, -+ tA = 0, tAAAA = 0, tother = 0; - struct rtt_info ri; - uint8_t edns_lame_known; - for(a = dp->target_list; a; a = a->next_target) { -@@ -817,9 +818,11 @@ - delay=0; - entry_ttl = infra_get_host_rto(worker->env.infra_cache, - &a->addr, a->addrlen, dp->name, dp->namelen, -- &ri, &delay, *worker->env.now); -+ &ri, &delay, *worker->env.now, &tA, &tAAAA, &tother); - if(entry_ttl == -2 && ri.rto >= USEFUL_SERVER_TOP_TIMEOUT) { -- if(!ssl_printf(ssl, "expired, rto %d msec.\n", ri.rto)) -+ if(!ssl_printf(ssl, "expired, rto %d msec, tA %d " -+ "tAAAA %d tother %d.\n", ri.rto, tA, tAAAA, -+ tother)) - return; - continue; - } -@@ -840,11 +843,12 @@ - continue; /* skip stuff not in infra cache */ - } - if(!ssl_printf(ssl, "%s%s%s%srto %d msec, ttl %d, ping %d " -- "var %d rtt %d", -+ "var %d rtt %d, tA %d, tAAAA %d, tother %d", - lame?"LAME ":"", dlame?"NoDNSSEC ":"", - a->lame?"AddrWasParentSide ":"", - rlame?"NoAuthButRecursive ":"", rto, entry_ttl, -- ri.srtt, ri.rttvar, rtt_notimeout(&ri))) -+ ri.srtt, ri.rttvar, rtt_notimeout(&ri), -+ tA, tAAAA, tother)) - return; - if(delay) - if(!ssl_printf(ssl, ", probedelay %d", delay)) -@@ -907,19 +911,12 @@ - char b[260]; - struct query_info qinfo; - struct iter_hints_stub* stub; -- struct iter_env* ie; - regional_free_all(region); - qinfo.qname = nm; - qinfo.qname_len = nmlen; - qinfo.qtype = LDNS_RR_TYPE_A; - qinfo.qclass = LDNS_RR_CLASS_IN; - -- if(modstack_find(&worker->daemon->mods, "iterator") == -1) { -- return ssl_printf(ssl, "error: no iterator module\n"); -- } -- ie = (struct iter_env*)worker->env.modinfo[modstack_find(&worker-> -- daemon->mods, "iterator")]; -- - dname_str(nm, b); - if(!ssl_printf(ssl, "The following name servers are used for lookup " - "of %s\n", b)) -@@ -964,7 +961,8 @@ - continue; - } - } -- stub = hints_lookup_stub(ie->hints, nm, qinfo.qclass, dp); -+ stub = hints_lookup_stub(worker->env.hints, nm, qinfo.qclass, -+ dp); - if(stub) { - if(stub->noprime) { - if(!ssl_printf(ssl, "The noprime stub servers " -diff -Naur unbound-1.4.16/daemon/remote.c unbound-trunk/daemon/remote.c ---- unbound-1.4.16/daemon/remote.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-trunk/daemon/remote.c 2012-02-22 20:37:15.804368186 -0500 -@@ -68,6 +68,7 @@ - #include "validator/validator.h" - #include "validator/val_kcache.h" - #include "validator/val_kentry.h" -+#include "validator/val_anchor.h" - #include "iterator/iterator.h" - #include "iterator/iter_fwd.h" - #include "iterator/iter_hints.h" -@@ -1337,15 +1338,15 @@ - - /** parse args into delegpt */ - static struct delegpt* --parse_delegpt(SSL* ssl, struct regional* region, char* args, uint8_t* root) -+parse_delegpt(SSL* ssl, char* args, uint8_t* nm, int allow_names) - { - /* parse args and add in */ - char* p = args; - char* todo; -- struct delegpt* dp = delegpt_create(region); -+ struct delegpt* dp = delegpt_create_mlc(nm); - struct sockaddr_storage addr; - socklen_t addrlen; -- if(!dp || !delegpt_set_name(dp, region, root)) { -+ if(!dp) { - (void)ssl_printf(ssl, "error out of memory\n"); - return NULL; - } -@@ -1358,14 +1359,37 @@ - } - /* parse address */ - if(!extstrtoaddr(todo, &addr, &addrlen)) { -- (void)ssl_printf(ssl, "error cannot parse" -- " IP address '%s'\n", todo); -- return NULL; -- } -- /* add address */ -- if(!delegpt_add_addr(dp, region, &addr, addrlen, 0, 0)) { -- (void)ssl_printf(ssl, "error out of memory\n"); -- return NULL; -+ if(allow_names) { -+ uint8_t* n = NULL; -+ size_t ln; -+ int lb; -+ if(!parse_arg_name(ssl, todo, &n, &ln, &lb)) { -+ (void)ssl_printf(ssl, "error cannot " -+ "parse IP address or name " -+ "'%s'\n", todo); -+ delegpt_free_mlc(dp); -+ return NULL; -+ } -+ if(!delegpt_add_ns_mlc(dp, n, 0)) { -+ (void)ssl_printf(ssl, "error out of memory\n"); -+ delegpt_free_mlc(dp); -+ return NULL; -+ } -+ free(n); -+ -+ } else { -+ (void)ssl_printf(ssl, "error cannot parse" -+ " IP address '%s'\n", todo); -+ delegpt_free_mlc(dp); -+ return NULL; -+ } -+ } else { -+ /* add address */ -+ if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) { -+ (void)ssl_printf(ssl, "error out of memory\n"); -+ delegpt_free_mlc(dp); -+ return NULL; -+ } - } - } - return dp; -@@ -1389,20 +1413,166 @@ - * the actual mesh is not running, so we can freely edit it. */ - /* delete all the existing queries first */ - mesh_delete_all(worker->env.mesh); -- /* reset the fwd structure ; the cfg is unchanged (shared by threads)*/ -- /* this reset frees up memory */ -- forwards_apply_cfg(fwd, worker->env.cfg); - if(strcmp(args, "off") == 0) { - forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, root); - } else { - struct delegpt* dp; -- if(!(dp = parse_delegpt(ssl, fwd->region, args, root))) -+ if(!(dp = parse_delegpt(ssl, args, root, 0))) - return; - if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) { - (void)ssl_printf(ssl, "error out of memory\n"); -+ delegpt_free_mlc(dp); -+ return; -+ } -+ } -+ send_ok(ssl); -+} -+ -+static int -+parse_fs_args(SSL* ssl, char* args, uint8_t** nm, struct delegpt** dp, -+ int* insecure, int* prime) -+{ -+ char* zonename; -+ char* rest; -+ size_t nmlen; -+ int nmlabs; -+ /* parse all -x args */ -+ while(args[0] == '+') { -+ if(!find_arg2(ssl, args, &rest)) -+ return 0; -+ while(*(++args) != 0) { -+ if(*args == 'i' && insecure) -+ *insecure = 1; -+ else if(*args == 'p' && prime) -+ *prime = 1; -+ else { -+ (void)ssl_printf(ssl, "error: unknown option %s\n", args); -+ return 0; -+ } -+ } -+ args = rest; -+ } -+ /* parse name */ -+ if(dp) { -+ if(!find_arg2(ssl, args, &rest)) -+ return 0; -+ zonename = args; -+ args = rest; -+ } else zonename = args; -+ if(!parse_arg_name(ssl, zonename, nm, &nmlen, &nmlabs)) -+ return 0; -+ -+ /* parse dp */ -+ if(dp) { -+ if(!(*dp = parse_delegpt(ssl, args, *nm, 1))) { -+ free(*nm); -+ return 0; -+ } -+ } -+ return 1; -+} -+ -+/** do the forward_add command */ -+static void -+do_forward_add(SSL* ssl, struct worker* worker, char* args) -+{ -+ struct iter_forwards* fwd = worker->env.fwds; -+ int insecure = 0; -+ uint8_t* nm = NULL; -+ struct delegpt* dp = NULL; -+ if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, NULL)) -+ return; -+ if(insecure) { -+ if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, -+ nm)) { -+ (void)ssl_printf(ssl, "error out of memory\n"); -+ delegpt_free_mlc(dp); -+ free(nm); -+ return; -+ } -+ } -+ if(!forwards_add_zone(fwd, LDNS_RR_CLASS_IN, dp)) { -+ (void)ssl_printf(ssl, "error out of memory\n"); -+ delegpt_free_mlc(dp); -+ free(nm); -+ return; -+ } -+ free(nm); -+ send_ok(ssl); -+} -+ -+/** do the forward_remove command */ -+static void -+do_forward_remove(SSL* ssl, struct worker* worker, char* args) -+{ -+ struct iter_forwards* fwd = worker->env.fwds; -+ int insecure = 0; -+ uint8_t* nm = NULL; -+ if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) -+ return; -+ if(insecure) -+ anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, -+ nm); -+ forwards_delete_zone(fwd, LDNS_RR_CLASS_IN, nm); -+ free(nm); -+ send_ok(ssl); -+} -+ -+/** do the stub_add command */ -+static void -+do_stub_add(SSL* ssl, struct worker* worker, char* args) -+{ -+ struct iter_forwards* fwd = worker->env.fwds; -+ int insecure = 0, prime = 0; -+ uint8_t* nm = NULL; -+ struct delegpt* dp = NULL; -+ if(!parse_fs_args(ssl, args, &nm, &dp, &insecure, &prime)) -+ return; -+ if(insecure) { -+ if(!anchors_add_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, -+ nm)) { -+ (void)ssl_printf(ssl, "error out of memory\n"); -+ delegpt_free_mlc(dp); -+ free(nm); - return; - } - } -+ if(!forwards_add_stub_hole(fwd, LDNS_RR_CLASS_IN, nm)) { -+ if(insecure) anchors_delete_insecure(worker->env.anchors, -+ LDNS_RR_CLASS_IN, nm); -+ (void)ssl_printf(ssl, "error out of memory\n"); -+ delegpt_free_mlc(dp); -+ free(nm); -+ return; -+ } -+ if(!hints_add_stub(worker->env.hints, LDNS_RR_CLASS_IN, dp, !prime)) { -+ (void)ssl_printf(ssl, "error out of memory\n"); -+ forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm); -+ if(insecure) anchors_delete_insecure(worker->env.anchors, -+ LDNS_RR_CLASS_IN, nm); -+ delegpt_free_mlc(dp); -+ free(nm); -+ return; -+ } -+ free(nm); -+ send_ok(ssl); -+} -+ -+/** do the stub_remove command */ -+static void -+do_stub_remove(SSL* ssl, struct worker* worker, char* args) -+{ -+ struct iter_forwards* fwd = worker->env.fwds; -+ int insecure = 0; -+ uint8_t* nm = NULL; -+ if(!parse_fs_args(ssl, args, &nm, NULL, &insecure, NULL)) -+ return; -+ if(insecure) -+ anchors_delete_insecure(worker->env.anchors, LDNS_RR_CLASS_IN, -+ nm); -+ forwards_delete_stub_hole(fwd, LDNS_RR_CLASS_IN, nm); -+ hints_delete_stub(worker->env.hints, LDNS_RR_CLASS_IN, nm); -+ free(nm); - send_ok(ssl); - } - -@@ -1570,9 +1740,11 @@ - return; - } - if(!ssl_printf(a->ssl, "%s %s ttl %d ping %d var %d rtt %d rto %d " -+ "tA %d tAAAA %d tother %d " - "ednsknown %d edns %d delay %d lame dnssec %d rec %d A %d " - "other %d\n", ip_str, name, (int)(d->ttl - a->now), - d->rtt.srtt, d->rtt.rttvar, rtt_notimeout(&d->rtt), d->rtt.rto, -+ d->timeout_A, d->timeout_AAAA, d->timeout_other, - (int)d->edns_lame_known, (int)d->edns_version, - (int)(a->nowprobedelay?d->probedelay-a->now:0), - (int)d->isdnsseclame, (int)d->rec_lame, (int)d->lame_type_A, -@@ -1652,17 +1824,8 @@ - static void - do_list_stubs(SSL* ssl, struct worker* worker) - { -- /* readonly structure */ -- int m; - struct iter_hints_stub* z; -- struct iter_env* ie; -- m = modstack_find(&worker->env.mesh->mods, "iterator"); -- if(m == -1) { -- (void)ssl_printf(ssl, "error no iterator module\n"); -- return; -- } -- ie = (struct iter_env*)worker->env.modinfo[m]; -- RBTREE_FOR(z, struct iter_hints_stub*, &ie->hints->tree) { -+ RBTREE_FOR(z, struct iter_hints_stub*, &worker->env.hints->tree) { - if(!ssl_print_name_dp(ssl, - z->noprime?"stub noprime":"stub prime", z->node.name, - z->node.dclass, z->dp)) -@@ -1780,6 +1943,26 @@ - } else if(cmdcmp(p, "list_local_data", 15)) { - do_list_local_data(ssl, worker); - return; -+ } else if(cmdcmp(p, "stub_add", 8)) { -+ /* must always distribute this cmd */ -+ if(rc) distribute_cmd(rc, ssl, cmd); -+ do_stub_add(ssl, worker, skipwhite(p+8)); -+ return; -+ } else if(cmdcmp(p, "stub_remove", 11)) { -+ /* must always distribute this cmd */ -+ if(rc) distribute_cmd(rc, ssl, cmd); -+ do_stub_remove(ssl, worker, skipwhite(p+11)); -+ return; -+ } else if(cmdcmp(p, "forward_add", 11)) { -+ /* must always distribute this cmd */ -+ if(rc) distribute_cmd(rc, ssl, cmd); -+ do_forward_add(ssl, worker, skipwhite(p+11)); -+ return; -+ } else if(cmdcmp(p, "forward_remove", 14)) { -+ /* must always distribute this cmd */ -+ if(rc) distribute_cmd(rc, ssl, cmd); -+ do_forward_remove(ssl, worker, skipwhite(p+14)); -+ return; - } else if(cmdcmp(p, "forward", 7)) { - /* must always distribute this cmd */ - if(rc) distribute_cmd(rc, ssl, cmd); -diff -Naur unbound-1.4.16/daemon/worker.c unbound-trunk/daemon/worker.c ---- unbound-1.4.16/daemon/worker.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-trunk/daemon/worker.c 2012-02-22 20:37:15.803368186 -0500 -@@ -67,7 +67,9 @@ - #include "util/fptr_wlist.h" - #include "util/tube.h" - #include "iterator/iter_fwd.h" -+#include "iterator/iter_hints.h" - #include "validator/autotrust.h" -+#include "validator/val_anchor.h" - - #ifdef HAVE_SYS_TYPES_H - # include -@@ -148,7 +150,7 @@ - #ifdef UNBOUND_ALLOC_STATS - /* debug func in validator module */ - size_t total, front, back, mesh, msg, rrset, infra, ac, superac; -- size_t me, iter, val; -+ size_t me, iter, val, anch; - int i; - if(verbosity < VERB_ALGO) - return; -@@ -160,6 +162,7 @@ - mesh = mesh_get_mem(worker->env.mesh); - ac = alloc_get_mem(&worker->alloc); - superac = alloc_get_mem(&worker->daemon->superalloc); -+ anch = anchors_get_mem(worker->env.anchors); - iter = 0; - val = 0; - for(i=0; ienv.mesh->mods.num; i++) { -@@ -177,7 +180,8 @@ - + regional_get_mem(worker->scratchpad) - + sizeof(*worker->env.scratch_buffer) - + ldns_buffer_capacity(worker->env.scratch_buffer) -- + forwards_get_mem(worker->env.fwds); -+ + forwards_get_mem(worker->env.fwds) -+ + hints_get_mem(worker->env.hints; - if(worker->thread_num == 0) - me += acl_list_get_mem(worker->daemon->acl); - if(cur_serv) { -@@ -185,12 +189,12 @@ - } - total = front+back+mesh+msg+rrset+infra+iter+val+ac+superac+me; - log_info("Memory conditions: %u front=%u back=%u mesh=%u msg=%u " -- "rrset=%u infra=%u iter=%u val=%u " -+ "rrset=%u infra=%u iter=%u val=%u anchors=%u " - "alloccache=%u globalalloccache=%u me=%u", - (unsigned)total, (unsigned)front, (unsigned)back, - (unsigned)mesh, (unsigned)msg, (unsigned)rrset, -- (unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)ac, -- (unsigned)superac, (unsigned)me); -+ (unsigned)infra, (unsigned)iter, (unsigned)val, (unsigned)anch, -+ (unsigned)ac, (unsigned)superac, (unsigned)me); - debug_total_mem(total); - #else /* no UNBOUND_ALLOC_STATS */ - size_t val = 0; -@@ -1158,6 +1162,12 @@ - worker_delete(worker); - return 0; - } -+ if(!(worker->env.hints = hints_create()) || -+ !hints_apply_cfg(worker->env.hints, cfg)) { -+ log_err("Could not set root or stub hints"); -+ worker_delete(worker); -+ return 0; -+ } - /* one probe timer per process -- if we have 5011 anchors */ - if(autr_get_num_anchors(worker->env.anchors) > 0 - #ifndef THREADS_DISABLED -@@ -1210,6 +1220,7 @@ - mesh_delete(worker->env.mesh); - ldns_buffer_free(worker->env.scratch_buffer); - forwards_delete(worker->env.fwds); -+ hints_delete(worker->env.hints); - listen_delete(worker->front); - outside_network_delete(worker->back); - comm_signal_delete(worker->comsig); -diff -Naur unbound-1.4.16/iterator/iterator.c unbound-trunk/iterator/iterator.c ---- unbound-1.4.16/iterator/iterator.c 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/iterator/iterator.c 2012-02-22 20:37:15.042368186 -0500 -@@ -89,7 +89,6 @@ - iter_env = (struct iter_env*)env->modinfo[id]; - free(iter_env->target_fetch_policy); - priv_delete(iter_env->priv); -- hints_delete(iter_env->hints); - donotq_delete(iter_env->donotq); - free(iter_env); - env->modinfo[id] = NULL; -@@ -260,7 +259,7 @@ - /* do not waste time trying to validate this servfail */ - err.security = sec_status_indeterminate; - verbose(VERB_ALGO, "store error response in message cache"); -- if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, NULL)) { -+ if(!iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL)) { - log_err("error_response_cache: could not store error (nomem)"); - } - return error_response(qstate, id, rcode); -@@ -532,21 +531,20 @@ - * Generate and send a root priming request. - * @param qstate: the qtstate that triggered the need to prime. - * @param iq: iterator query state. -- * @param ie: iterator global state. - * @param id: module id. - * @param qclass: the class to prime. - * @return 0 on failure - */ - static int --prime_root(struct module_qstate* qstate, struct iter_qstate* iq, -- struct iter_env* ie, int id, uint16_t qclass) -+prime_root(struct module_qstate* qstate, struct iter_qstate* iq, int id, -+ uint16_t qclass) - { - struct delegpt* dp; - struct module_qstate* subq; - verbose(VERB_DETAIL, "priming . %s NS", - ldns_lookup_by_id(ldns_rr_classes, (int)qclass)? - ldns_lookup_by_id(ldns_rr_classes, (int)qclass)->name:"??"); -- dp = hints_lookup_root(ie->hints, qclass); -+ dp = hints_lookup_root(qstate->env->hints, qclass); - if(!dp) { - verbose(VERB_ALGO, "Cannot prime due to lack of hints"); - return 0; -@@ -590,7 +588,6 @@ - * - * @param qstate: the qtstate that triggered the need to prime. - * @param iq: iterator query state. -- * @param ie: iterator global state. - * @param id: module id. - * @param q: request name. - * @return true if a priming subrequest was made, false if not. The will only -@@ -599,8 +596,8 @@ - * that a noprime-stub is available and resolution can continue. - */ - static int --prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, -- struct iter_env* ie, int id, struct query_info* q) -+prime_stub(struct module_qstate* qstate, struct iter_qstate* iq, int id, -+ struct query_info* q) - { - /* Lookup the stub hint. This will return null if the stub doesn't - * need to be re-primed. */ -@@ -614,7 +611,8 @@ - /* remove first label, but not for root */ - dname_remove_label(&delname, &delnamelen); - -- stub = hints_lookup_stub(ie->hints, delname, q->qclass, iq->dp); -+ stub = hints_lookup_stub(qstate->env->hints, delname, q->qclass, -+ iq->dp); - /* The stub (if there is one) does not need priming. */ - if(!stub) - return 0; -@@ -1042,14 +1040,15 @@ - if(delname) - iq->dp = dns_cache_find_delegation(qstate->env, delname, - delnamelen, iq->qchase.qtype, iq->qchase.qclass, -- qstate->region, &iq->deleg_msg, *qstate->env->now); -+ qstate->region, &iq->deleg_msg, -+ *qstate->env->now+qstate->prefetch_leeway); - else iq->dp = NULL; - - /* If the cache has returned nothing, then we have a - * root priming situation. */ - if(iq->dp == NULL) { - /* if there is a stub, then no root prime needed */ -- int r = prime_stub(qstate, iq, ie, id, &iq->qchase); -+ int r = prime_stub(qstate, iq, id, &iq->qchase); - if(r == 2) - break; /* got noprime-stub-zone, continue */ - else if(r) -@@ -1058,7 +1057,7 @@ - iq->qchase.qclass)) { - /* forward zone root, no root prime needed */ - /* fill in some dp - safety belt */ -- iq->dp = hints_lookup_root(ie->hints, -+ iq->dp = hints_lookup_root(qstate->env->hints, - iq->qchase.qclass); - if(!iq->dp) { - log_err("internal error: no hints dp"); -@@ -1075,7 +1074,7 @@ - } - /* Note that the result of this will set a new - * DelegationPoint based on the result of priming. */ -- if(!prime_root(qstate, iq, ie, id, iq->qchase.qclass)) -+ if(!prime_root(qstate, iq, id, iq->qchase.qclass)) - return error_response(qstate, id, - LDNS_RCODE_REFUSED); - -@@ -1104,7 +1103,7 @@ - /* use safety belt */ - verbose(VERB_QUERY, "Cache has root NS but " - "no addresses. Fallback to the safety belt."); -- iq->dp = hints_lookup_root(ie->hints, -+ iq->dp = hints_lookup_root(qstate->env->hints, - iq->qchase.qclass); - /* note deleg_msg is from previous lookup, - * but RD is on, so it is not used */ -@@ -1151,20 +1150,19 @@ - * - * @param qstate: query state. - * @param iq: iterator query state. -- * @param ie: iterator shared global environment. - * @param id: module id. - * @return true if the event needs more request processing immediately, - * false if not. - */ - static int - processInitRequest2(struct module_qstate* qstate, struct iter_qstate* iq, -- struct iter_env* ie, int id) -+ int id) - { - log_query_info(VERB_QUERY, "resolving (init part 2): ", - &qstate->qinfo); - - /* Check to see if we need to prime a stub zone. */ -- if(prime_stub(qstate, iq, ie, id, &iq->qchase)) { -+ if(prime_stub(qstate, iq, id, &iq->qchase)) { - /* A priming sub request was made */ - return 0; - } -@@ -1261,7 +1259,8 @@ - } else { - subiq->dp = dns_cache_find_delegation(qstate->env, - name, namelen, qtype, qclass, subq->region, -- &subiq->deleg_msg, *qstate->env->now); -+ &subiq->deleg_msg, -+ *qstate->env->now+subq->prefetch_leeway); - /* if no dp, then it's from root, refetch unneeded */ - if(subiq->dp) { - subiq->dnssec_expected = iter_indicates_dnssec( -@@ -1833,6 +1832,7 @@ - } - if(!iter_dns_store(qstate->env, &iq->response->qinfo, - iq->response->rep, 0, qstate->prefetch_leeway, -+ iq->dp&&iq->dp->has_parent_side_NS, - qstate->region)) - return error_response(qstate, id, LDNS_RCODE_SERVFAIL); - /* close down outstanding requests to be discarded */ -@@ -1872,7 +1872,7 @@ - /* Store the referral under the current query */ - /* no prefetch-leeway, since its not the answer */ - if(!iter_dns_store(qstate->env, &iq->response->qinfo, -- iq->response->rep, 1, 0, NULL)) -+ iq->response->rep, 1, 0, 0, NULL)) - return error_response(qstate, id, - LDNS_RCODE_SERVFAIL); - if(iq->store_parent_NS) -@@ -1958,7 +1958,9 @@ - * the partial query answer (CNAME only). */ - /* prefetchleeway applied because this updates answer parts */ - if(!iter_dns_store(qstate->env, &iq->response->qinfo, -- iq->response->rep, 1, qstate->prefetch_leeway, NULL)) -+ iq->response->rep, 1, qstate->prefetch_leeway, -+ iq->dp&&iq->dp->has_parent_side_NS, -+ NULL)) - return error_response(qstate, id, LDNS_RCODE_SERVFAIL); - /* set the current request's qname to the new value. */ - iq->qchase.qname = sname; -@@ -2336,7 +2338,6 @@ - processCollectClass(struct module_qstate* qstate, int id) - { - struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; -- struct iter_env* ie = (struct iter_env*)qstate->env->modinfo[id]; - struct module_qstate* subq; - /* If qchase.qclass == 0 then send out queries for all classes. - * Otherwise, do nothing (wait for all answers to arrive and the -@@ -2345,7 +2346,8 @@ - if(iq->qchase.qclass == 0) { - uint16_t c = 0; - iq->qchase.qclass = LDNS_RR_CLASS_ANY; -- while(iter_get_next_root(ie->hints, qstate->env->fwds, &c)) { -+ while(iter_get_next_root(qstate->env->hints, -+ qstate->env->fwds, &c)) { - /* generate query for this class */ - log_nametypeclass(VERB_ALGO, "spawn collect query", - qstate->qinfo.qname, qstate->qinfo.qtype, c); -@@ -2435,6 +2437,7 @@ - if(qstate->query_flags&BIT_RD) { - if(!iter_dns_store(qstate->env, &qstate->qinfo, - iq->response->rep, 0, qstate->prefetch_leeway, -+ iq->dp&&iq->dp->has_parent_side_NS, - qstate->region)) - return error_response(qstate, id, - LDNS_RCODE_SERVFAIL); -@@ -2493,7 +2496,7 @@ - cont = processInitRequest(qstate, iq, ie, id); - break; - case INIT_REQUEST_2_STATE: -- cont = processInitRequest2(qstate, iq, ie, id); -+ cont = processInitRequest2(qstate, iq, id); - break; - case INIT_REQUEST_3_STATE: - cont = processInitRequest3(qstate, iq, id); -@@ -2705,8 +2708,7 @@ - if(!ie) - return 0; - return sizeof(*ie) + sizeof(int)*((size_t)ie->max_dependency_depth+1) -- + hints_get_mem(ie->hints) + donotq_get_mem(ie->donotq) -- + priv_get_mem(ie->priv); -+ + donotq_get_mem(ie->donotq) + priv_get_mem(ie->priv); - } - - /** -diff -Naur unbound-1.4.16/iterator/iterator.h unbound-trunk/iterator/iterator.h ---- unbound-1.4.16/iterator/iterator.h 2011-09-16 10:11:12.000000000 -0400 -+++ unbound-trunk/iterator/iterator.h 2012-02-22 20:37:15.038368186 -0500 -@@ -86,14 +86,6 @@ - * Global state for the iterator. - */ - struct iter_env { -- /** -- * The hints -- these aren't stored in the cache because they don't -- * expire. The hints are always used to "prime" the cache. Note -- * that both root hints and stub zone "hints" are stored in this -- * data structure. -- */ -- struct iter_hints* hints; -- - /** A flag to indicate whether or not we have an IPv6 route */ - int supports_ipv6; - -diff -Naur unbound-1.4.16/iterator/iter_delegpt.c unbound-trunk/iterator/iter_delegpt.c ---- unbound-1.4.16/iterator/iter_delegpt.c 2011-09-07 10:34:10.000000000 -0400 -+++ unbound-trunk/iterator/iter_delegpt.c 2012-02-22 20:37:15.040368186 -0500 -@@ -90,6 +90,7 @@ - int - delegpt_set_name(struct delegpt* dp, struct regional* region, uint8_t* name) - { -+ log_assert(!dp->dp_type_mlc); - dp->namelabs = dname_count_size_labels(name, &dp->namelen); - dp->name = regional_alloc_init(region, name, dp->namelen); - return dp->name != 0; -@@ -102,6 +103,7 @@ - struct delegpt_ns* ns; - size_t len; - (void)dname_count_size_labels(name, &len); -+ log_assert(!dp->dp_type_mlc); - /* slow check for duplicates to avoid counting failures when - * adding the same server as a dependency twice */ - if(delegpt_find_ns(dp, name, len)) -@@ -120,7 +122,7 @@ - ns->lame = (uint8_t)lame; - ns->done_pside4 = 0; - ns->done_pside6 = 0; -- return 1; -+ return ns->name != 0; - } - - struct delegpt_ns* -@@ -157,6 +159,7 @@ - socklen_t addrlen, int bogus, int lame) - { - struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); -+ log_assert(!dp->dp_type_mlc); - if(!ns) { - /* ignore it */ - return 1; -@@ -177,6 +180,7 @@ - int lame) - { - struct delegpt_addr* a; -+ log_assert(!dp->dp_type_mlc); - /* check for duplicates */ - if((a = delegpt_find_addr(dp, addr, addrlen))) { - if(bogus) -@@ -377,6 +381,7 @@ - struct packed_rrset_data* nsdata = (struct packed_rrset_data*) - ns_rrset->entry.data; - size_t i; -+ log_assert(!dp->dp_type_mlc); - if(nsdata->security == sec_status_bogus) - dp->bogus = 1; - for(i=0; icount; i++) { -@@ -399,6 +404,7 @@ - size_t i; - struct sockaddr_in sa; - socklen_t len = (socklen_t)sizeof(sa); -+ log_assert(!dp->dp_type_mlc); - memset(&sa, 0, len); - sa.sin_family = AF_INET; - sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT); -@@ -422,6 +428,7 @@ - size_t i; - struct sockaddr_in6 sa; - socklen_t len = (socklen_t)sizeof(sa); -+ log_assert(!dp->dp_type_mlc); - memset(&sa, 0, len); - sa.sin6_family = AF_INET6; - sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT); -@@ -492,3 +499,141 @@ - ns->resolved = 1; - } - } -+ -+struct delegpt* delegpt_create_mlc(uint8_t* name) -+{ -+ struct delegpt* dp=(struct delegpt*)calloc(1, sizeof(*dp)); -+ if(!dp) -+ return NULL; -+ memset(dp, 0, sizeof(*dp)); -+ dp->dp_type_mlc = 1; -+ if(name) { -+ dp->namelabs = dname_count_size_labels(name, &dp->namelen); -+ dp->name = memdup(name, dp->namelen); -+ if(!dp->name) { -+ free(dp); -+ return NULL; -+ } -+ } -+ return dp; -+} -+ -+void delegpt_free_mlc(struct delegpt* dp) -+{ -+ struct delegpt_ns* n, *nn; -+ struct delegpt_addr* a, *na; -+ if(!dp) return; -+ log_assert(dp->dp_type_mlc); -+ n = dp->nslist; -+ while(n) { -+ nn = n->next; -+ free(n->name); -+ free(n); -+ n = nn; -+ } -+ a = dp->target_list; -+ while(a) { -+ na = a->next_target; -+ free(a); -+ a = na; -+ } -+ free(dp->name); -+ free(dp); -+} -+ -+int delegpt_set_name_mlc(struct delegpt* dp, uint8_t* name) -+{ -+ log_assert(dp->dp_type_mlc); -+ dp->namelabs = dname_count_size_labels(name, &dp->namelen); -+ dp->name = memdup(name, dp->namelen); -+ return (dp->name != NULL); -+} -+ -+int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, int lame) -+{ -+ struct delegpt_ns* ns; -+ size_t len; -+ (void)dname_count_size_labels(name, &len); -+ log_assert(dp->dp_type_mlc); -+ /* slow check for duplicates to avoid counting failures when -+ * adding the same server as a dependency twice */ -+ if(delegpt_find_ns(dp, name, len)) -+ return 1; -+ ns = (struct delegpt_ns*)malloc(sizeof(struct delegpt_ns)); -+ if(!ns) -+ return 0; -+ ns->namelen = len; -+ ns->name = memdup(name, ns->namelen); -+ if(!ns->name) { -+ free(ns); -+ return 0; -+ } -+ ns->next = dp->nslist; -+ dp->nslist = ns; -+ ns->resolved = 0; -+ ns->got4 = 0; -+ ns->got6 = 0; -+ ns->lame = (uint8_t)lame; -+ ns->done_pside4 = 0; -+ ns->done_pside6 = 0; -+ return 1; -+} -+ -+int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr, -+ socklen_t addrlen, int bogus, int lame) -+{ -+ struct delegpt_addr* a; -+ log_assert(dp->dp_type_mlc); -+ /* check for duplicates */ -+ if((a = delegpt_find_addr(dp, addr, addrlen))) { -+ if(bogus) -+ a->bogus = bogus; -+ if(!lame) -+ a->lame = 0; -+ return 1; -+ } -+ -+ a = (struct delegpt_addr*)malloc(sizeof(struct delegpt_addr)); -+ if(!a) -+ return 0; -+ a->next_target = dp->target_list; -+ dp->target_list = a; -+ a->next_result = 0; -+ a->next_usable = dp->usable_list; -+ dp->usable_list = a; -+ memcpy(&a->addr, addr, addrlen); -+ a->addrlen = addrlen; -+ a->attempts = 0; -+ a->bogus = bogus; -+ a->lame = lame; -+ return 1; -+} -+ -+int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen, -+ struct sockaddr_storage* addr, socklen_t addrlen, int bogus, int lame) -+{ -+ struct delegpt_ns* ns = delegpt_find_ns(dp, name, namelen); -+ log_assert(dp->dp_type_mlc); -+ if(!ns) { -+ /* ignore it */ -+ return 1; -+ } -+ if(!lame) { -+ if(addr_is_ip6(addr, addrlen)) -+ ns->got6 = 1; -+ else ns->got4 = 1; -+ if(ns->got4 && ns->got6) -+ ns->resolved = 1; -+ } -+ return delegpt_add_addr_mlc(dp, addr, addrlen, bogus, lame); -+} -+ -+size_t delegpt_get_mem(struct delegpt* dp) -+{ -+ struct delegpt_ns* ns; -+ size_t s = sizeof(*dp) + dp->namelen + -+ delegpt_count_targets(dp)*sizeof(struct delegpt_addr); -+ for(ns=dp->nslist; ns; ns=ns->next) -+ s += sizeof(*ns)+ns->namelen; -+ return s; -+} -diff -Naur unbound-1.4.16/iterator/iter_delegpt.h unbound-trunk/iterator/iter_delegpt.h ---- unbound-1.4.16/iterator/iter_delegpt.h 2011-09-07 10:34:10.000000000 -0400 -+++ unbound-trunk/iterator/iter_delegpt.h 2012-02-22 20:37:15.041368186 -0500 -@@ -79,6 +79,8 @@ - * Also true if the delegationpoint was created from a delegation - * message and thus contains the parent-side-info already. */ - uint8_t has_parent_side_NS; -+ /** for assertions on type of delegpt */ -+ uint8_t dp_type_mlc; - }; - - /** -@@ -346,4 +348,64 @@ - */ - void delegpt_no_ipv4(struct delegpt* dp); - -+/** -+ * create malloced delegation point, with the given name -+ * @param name: uncompressed wireformat of degegpt name. -+ * @return NULL on alloc failure -+ */ -+struct delegpt* delegpt_create_mlc(uint8_t* name); -+ -+/** -+ * free malloced delegation point. -+ * @param dp: must have been created with delegpt_create_mlc, free'd. -+ */ -+void delegpt_free_mlc(struct delegpt* dp); -+ -+/** -+ * Set name of delegation point. -+ * @param dp: delegation point. malloced. -+ * @param name: name to use. -+ * @return false on error. -+ */ -+int delegpt_set_name_mlc(struct delegpt* dp, uint8_t* name); -+ -+/** -+ * add a name to malloced delegation point. -+ * @param dp: must have been created with delegpt_create_mlc. -+ * @param name: the name to add. -+ * @param lame: the name is lame, disprefer. -+ * @return false on error. -+ */ -+int delegpt_add_ns_mlc(struct delegpt* dp, uint8_t* name, int lame); -+ -+/** -+ * add an address to a malloced delegation point. -+ * @param dp: must have been created with delegpt_create_mlc. -+ * @param addr: the address. -+ * @param addrlen: the length of addr. -+ * @param bogus: if address is bogus. -+ * @param lame: if address is lame. -+ * @return false on error. -+ */ -+int delegpt_add_addr_mlc(struct delegpt* dp, struct sockaddr_storage* addr, -+ socklen_t addrlen, int bogus, int lame); -+ -+/** -+ * Add target address to the delegation point. -+ * @param dp: must have been created with delegpt_create_mlc. -+ * @param name: name for which target was found (must be in nslist). -+ * This name is marked resolved. -+ * @param namelen: length of name. -+ * @param addr: the address. -+ * @param addrlen: the length of addr. -+ * @param bogus: security status for the address, pass true if bogus. -+ * @param lame: address is lame. -+ * @return false on error. -+ */ -+int delegpt_add_target_mlc(struct delegpt* dp, uint8_t* name, size_t namelen, -+ struct sockaddr_storage* addr, socklen_t addrlen, int bogus, int lame); -+ -+/** get memory in use by dp */ -+size_t delegpt_get_mem(struct delegpt* dp); -+ - #endif /* ITERATOR_ITER_DELEGPT_H */ -diff -Naur unbound-1.4.16/iterator/iter_fwd.c unbound-trunk/iterator/iter_fwd.c ---- unbound-1.4.16/iterator/iter_fwd.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-trunk/iterator/iter_fwd.c 2012-02-22 20:37:15.039368186 -0500 -@@ -45,7 +45,6 @@ - #include - #include "iterator/iter_fwd.h" - #include "iterator/iter_delegpt.h" --#include "util/regional.h" - #include "util/log.h" - #include "util/config_file.h" - #include "util/net_help.h" -@@ -73,21 +72,36 @@ - sizeof(struct iter_forwards)); - if(!fwd) - return NULL; -- fwd->region = regional_create(); -- if(!fwd->region) { -- forwards_delete(fwd); -- return NULL; -- } - return fwd; - } - -+static void fwd_zone_free(struct iter_forward_zone* n) -+{ -+ if(!n) return; -+ delegpt_free_mlc(n->dp); -+ free(n->name); -+ free(n); -+} -+ -+static void delfwdnode(rbnode_t* n, void* ATTR_UNUSED(arg)) -+{ -+ struct iter_forward_zone* node = (struct iter_forward_zone*)n; -+ fwd_zone_free(node); -+} -+ -+static void fwd_del_tree(struct iter_forwards* fwd) -+{ -+ if(fwd->tree) -+ traverse_postorder(fwd->tree, &delfwdnode, NULL); -+ free(fwd->tree); -+} -+ - void - forwards_delete(struct iter_forwards* fwd) - { - if(!fwd) - return; -- regional_destroy(fwd->region); -- free(fwd->tree); -+ fwd_del_tree(fwd); - free(fwd); - } - -@@ -96,20 +110,28 @@ - forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm, - size_t nmlen, int nmlabs, struct delegpt* dp) - { -- struct iter_forward_zone* node = regional_alloc(fwd->region, -+ struct iter_forward_zone* node = (struct iter_forward_zone*)malloc( - sizeof(struct iter_forward_zone)); -- if(!node) -+ if(!node) { -+ delegpt_free_mlc(dp); - return 0; -+ } - node->node.key = node; - node->dclass = c; -- node->name = regional_alloc_init(fwd->region, nm, nmlen); -- if(!node->name) -+ node->name = memdup(nm, nmlen); -+ if(!node->name) { -+ delegpt_free_mlc(dp); -+ free(node); - return 0; -+ } - node->namelen = nmlen; - node->namelabs = nmlabs; - node->dp = dp; - if(!rbtree_insert(fwd->tree, &node->node)) { - log_err("duplicate forward zone ignored."); -+ delegpt_free_mlc(dp); -+ free(node->name); -+ free(node); - } - return 1; - } -@@ -152,33 +174,32 @@ - } - - /** set zone name */ --static int --read_fwds_name(struct iter_forwards* fwd, struct config_stub* s, -- struct delegpt* dp) -+static struct delegpt* -+read_fwds_name(struct config_stub* s) - { -+ struct delegpt* dp; - ldns_rdf* rdf; - if(!s->name) { - log_err("forward zone without a name (use name \".\" to forward everything)"); -- return 0; -+ return NULL; - } - rdf = ldns_dname_new_frm_str(s->name); - if(!rdf) { - log_err("cannot parse forward zone name %s", s->name); -- return 0; -+ return NULL; - } -- if(!delegpt_set_name(dp, fwd->region, ldns_rdf_data(rdf))) { -+ if(!(dp=delegpt_create_mlc(ldns_rdf_data(rdf)))) { - ldns_rdf_deep_free(rdf); - log_err("out of memory"); -- return 0; -+ return NULL; - } - ldns_rdf_deep_free(rdf); -- return 1; -+ return dp; - } - - /** set fwd host names */ - static int --read_fwds_host(struct iter_forwards* fwd, struct config_stub* s, -- struct delegpt* dp) -+read_fwds_host(struct config_stub* s, struct delegpt* dp) - { - struct config_strlist* p; - ldns_rdf* rdf; -@@ -190,7 +211,7 @@ - s->name, p->str); - return 0; - } -- if(!delegpt_add_ns(dp, fwd->region, ldns_rdf_data(rdf), 0)) { -+ if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0)) { - ldns_rdf_deep_free(rdf); - log_err("out of memory"); - return 0; -@@ -202,8 +223,7 @@ - - /** set fwd server addresses */ - static int --read_fwds_addr(struct iter_forwards* fwd, struct config_stub* s, -- struct delegpt* dp) -+read_fwds_addr(struct config_stub* s, struct delegpt* dp) - { - struct config_strlist* p; - struct sockaddr_storage addr; -@@ -215,7 +235,7 @@ - s->name, p->str); - return 0; - } -- if(!delegpt_add_addr(dp, fwd->region, &addr, addrlen, 0, 0)) { -+ if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) { - log_err("out of memory"); - return 0; - } -@@ -229,18 +249,14 @@ - { - struct config_stub* s; - for(s = cfg->forwards; s; s = s->next) { -- struct delegpt* dp = delegpt_create(fwd->region); -- if(!dp) { -- log_err("out of memory"); -+ struct delegpt* dp; -+ if(!(dp=read_fwds_name(s)) || -+ !read_fwds_host(s, dp) || -+ !read_fwds_addr(s, dp)) - return 0; -- } - /* set flag that parent side NS information is included. - * Asking a (higher up) server on the internet is not useful */ - dp->has_parent_side_NS = 1; -- if(!read_fwds_name(fwd, s, dp) || -- !read_fwds_host(fwd, s, dp) || -- !read_fwds_addr(fwd, s, dp)) -- return 0; - if(!forwards_insert(fwd, LDNS_RR_CLASS_IN, dp)) - return 0; - verbose(VERB_QUERY, "Forward zone server list:"); -@@ -268,28 +284,35 @@ - return 0; /* no forwards above, no holes needed */ - } - -+/** insert a stub hole (if necessary) for stub name */ -+static int -+fwd_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm) -+{ -+ struct iter_forward_zone key; -+ key.node.key = &key; -+ key.dclass = c; -+ key.name = nm; -+ key.namelabs = dname_count_size_labels(key.name, &key.namelen); -+ if(need_hole_insert(fwd->tree, &key)) { -+ return forwards_insert_data(fwd, key.dclass, key.name, -+ key.namelen, key.namelabs, NULL); -+ } -+ return 1; -+} -+ - /** make NULL entries for stubs */ - static int - make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg) - { - struct config_stub* s; -- struct iter_forward_zone key; -- key.node.key = &key; -- key.dclass = LDNS_RR_CLASS_IN; - for(s = cfg->stubs; s; s = s->next) { - ldns_rdf* rdf = ldns_dname_new_frm_str(s->name); - if(!rdf) { - log_err("cannot parse stub name '%s'", s->name); - return 0; - } -- key.name = ldns_rdf_data(rdf); -- key.namelabs = dname_count_size_labels(key.name, &key.namelen); -- if(!need_hole_insert(fwd->tree, &key)) { -- ldns_rdf_deep_free(rdf); -- continue; -- } -- if(!forwards_insert_data(fwd, key.dclass, key.name, -- key.namelen, key.namelabs, NULL)) { -+ if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, -+ ldns_rdf_data(rdf))) { - ldns_rdf_deep_free(rdf); - log_err("out of memory"); - return 0; -@@ -302,8 +325,7 @@ - int - forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg) - { -- free(fwd->tree); -- regional_free_all(fwd->region); -+ fwd_del_tree(fwd); - fwd->tree = rbtree_create(fwd_cmp); - if(!fwd->tree) - return 0; -@@ -411,15 +433,36 @@ - size_t - forwards_get_mem(struct iter_forwards* fwd) - { -+ struct iter_forward_zone* p; -+ size_t s; - if(!fwd) - return 0; -- return sizeof(*fwd) + sizeof(*fwd->tree) + -- regional_get_mem(fwd->region); -+ s = sizeof(*fwd) + sizeof(*fwd->tree); -+ RBTREE_FOR(p, struct iter_forward_zone*, fwd->tree) { -+ s += sizeof(*p) + p->namelen + delegpt_get_mem(p->dp); -+ } -+ return s; -+} -+ -+static struct iter_forward_zone* -+fwd_zone_find(struct iter_forwards* fwd, uint16_t c, uint8_t* nm) -+{ -+ struct iter_forward_zone key; -+ key.node.key = &key; -+ key.dclass = c; -+ key.name = nm; -+ key.namelabs = dname_count_size_labels(nm, &key.namelen); -+ return (struct iter_forward_zone*)rbtree_search(fwd->tree, &key); - } - - int - forwards_add_zone(struct iter_forwards* fwd, uint16_t c, struct delegpt* dp) - { -+ struct iter_forward_zone *z; -+ if((z=fwd_zone_find(fwd, c, dp->name)) != NULL) { -+ (void)rbtree_delete(fwd->tree, &z->node); -+ fwd_zone_free(z); -+ } - if(!forwards_insert(fwd, c, dp)) - return 0; - fwd_init_parents(fwd); -@@ -429,14 +472,34 @@ - void - forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm) - { -- struct iter_forward_zone key; -- key.node.key = &key; -- key.dclass = c; -- key.name = nm; -- key.namelabs = dname_count_size_labels(nm, &key.namelen); -- if(!rbtree_search(fwd->tree, &key)) -+ struct iter_forward_zone *z; -+ if(!(z=fwd_zone_find(fwd, c, nm))) -+ return; /* nothing to do */ -+ (void)rbtree_delete(fwd->tree, &z->node); -+ fwd_zone_free(z); -+ fwd_init_parents(fwd); -+} -+ -+int -+forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm) -+{ -+ if(!fwd_add_stub_hole(fwd, c, nm)) { -+ return 0; -+ } -+ fwd_init_parents(fwd); -+ return 1; -+} -+ -+void -+forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm) -+{ -+ struct iter_forward_zone *z; -+ if(!(z=fwd_zone_find(fwd, c, nm))) - return; /* nothing to do */ -- (void)rbtree_delete(fwd->tree, &key); -+ if(z->dp != NULL) -+ return; /* not a stub hole */ -+ (void)rbtree_delete(fwd->tree, &z->node); -+ fwd_zone_free(z); - fwd_init_parents(fwd); - } - -diff -Naur unbound-1.4.16/iterator/iter_fwd.h unbound-trunk/iterator/iter_fwd.h ---- unbound-1.4.16/iterator/iter_fwd.h 2010-07-07 09:13:36.000000000 -0400 -+++ unbound-trunk/iterator/iter_fwd.h 2012-02-22 20:37:15.041368186 -0500 -@@ -45,14 +45,11 @@ - #include "util/rbtree.h" - struct config_file; - struct delegpt; --struct regional; - - /** - * Iterator forward zones structure - */ - struct iter_forwards { -- /** regional where forward zone server addresses are allocated */ -- struct regional* region; - /** - * Zones are stored in this tree. Sort order is specially chosen. - * first sorted on qclass. Then on dname in nsec-like order, so that -@@ -77,7 +74,9 @@ - int namelabs; - /** delegation point with forward server information for this zone. - * If NULL then this forward entry is used to indicate that a -- * stub-zone with the same name exists, and should be used. */ -+ * stub-zone with the same name exists, and should be used. -+ * This delegation point is malloced. -+ */ - struct delegpt* dp; - /** pointer to parent in tree (or NULL if none) */ - struct iter_forward_zone* parent; -@@ -152,9 +151,7 @@ - * @param fwd: the forward data structure - * @param c: class of zone - * @param dp: delegation point with name and target nameservers for new -- * forward zone. This delegation point and all its data must be -- * malloced in the fwd->region. (then it is freed when the fwd is -- * deleted). -+ * forward zone. malloced. - * @return false on failure (out of memory); - */ - int forwards_add_zone(struct iter_forwards* fwd, uint16_t c, -@@ -162,12 +159,31 @@ - - /** - * Remove zone from forward structure. For external use since it -- * recalcs the tree parents. Does not actually release any memory, the region -- * is unchanged. -+ * recalcs the tree parents. - * @param fwd: the forward data structure - * @param c: class of zone - * @param nm: name of zone (in uncompressed wireformat). - */ - void forwards_delete_zone(struct iter_forwards* fwd, uint16_t c, uint8_t* nm); - -+/** -+ * Add stub hole (empty entry in forward table, that makes resolution skip -+ * a forward-zone because the stub zone should override the forward zone). -+ * Does not add one if not necessary. -+ * @param fwd: the forward data structure -+ * @param c: class of zone -+ * @param nm: name of zone (in uncompressed wireformat). -+ * @return false on failure (out of memory); -+ */ -+int forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm); -+ -+/** -+ * Remove stub hole, if one exists. -+ * @param fwd: the forward data structure -+ * @param c: class of zone -+ * @param nm: name of zone (in uncompressed wireformat). -+ */ -+void forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c, -+ uint8_t* nm); -+ - #endif /* ITERATOR_ITER_FWD_H */ -diff -Naur unbound-1.4.16/iterator/iter_hints.c unbound-trunk/iterator/iter_hints.c ---- unbound-1.4.16/iterator/iter_hints.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-trunk/iterator/iter_hints.c 2012-02-22 20:37:15.041368186 -0500 -@@ -44,7 +44,6 @@ - #include - #include "iterator/iter_hints.h" - #include "iterator/iter_delegpt.h" --#include "util/regional.h" - #include "util/log.h" - #include "util/config_file.h" - #include "util/net_help.h" -@@ -57,26 +56,39 @@ - sizeof(struct iter_hints)); - if(!hints) - return NULL; -- hints->region = regional_create(); -- if(!hints->region) { -- hints_delete(hints); -- return NULL; -- } - return hints; - } - -+static void hints_stub_free(struct iter_hints_stub* s) -+{ -+ if(!s) return; -+ delegpt_free_mlc(s->dp); -+ free(s); -+} -+ -+static void delhintnode(rbnode_t* n, void* ATTR_UNUSED(arg)) -+{ -+ struct iter_hints_stub* node = (struct iter_hints_stub*)n; -+ hints_stub_free(node); -+} -+ -+static void hints_del_tree(struct iter_hints* hints) -+{ -+ traverse_postorder(&hints->tree, &delhintnode, NULL); -+} -+ - void - hints_delete(struct iter_hints* hints) - { - if(!hints) - return; -- regional_destroy(hints->region); -+ hints_del_tree(hints); - free(hints); - } - - /** add hint to delegation hints */ - static int --ah(struct delegpt* dp, struct regional* r, const char* sv, const char* ip) -+ah(struct delegpt* dp, const char* sv, const char* ip) - { - struct sockaddr_storage addr; - socklen_t addrlen; -@@ -85,9 +97,9 @@ - log_err("could not parse %s", sv); - return 0; - } -- if(!delegpt_add_ns(dp, r, ldns_rdf_data(rdf), 0) || -+ if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0) || - !extstrtoaddr(ip, &addr, &addrlen) || -- !delegpt_add_target(dp, r, ldns_rdf_data(rdf), ldns_rdf_size(rdf), -+ !delegpt_add_target_mlc(dp, ldns_rdf_data(rdf), ldns_rdf_size(rdf), - &addr, addrlen, 0, 0)) { - ldns_rdf_deep_free(rdf); - return 0; -@@ -98,7 +110,7 @@ - - /** obtain compiletime provided root hints */ - static struct delegpt* --compile_time_root_prime(struct regional* r, int do_ip4, int do_ip6) -+compile_time_root_prime(int do_ip4, int do_ip6) - { - /* from: - ; This file is made available by InterNIC -@@ -109,37 +121,35 @@ - ; - ; related version of root zone: 2010061700 - */ -- struct delegpt* dp = delegpt_create(r); -+ struct delegpt* dp = delegpt_create_mlc((uint8_t*)"\000"); - if(!dp) - return NULL; - dp->has_parent_side_NS = 1; -- if(!delegpt_set_name(dp, r, (uint8_t*)"\000")) -- return NULL; - if(do_ip4) { -- if(!ah(dp, r, "A.ROOT-SERVERS.NET.", "198.41.0.4")) return 0; -- if(!ah(dp, r, "B.ROOT-SERVERS.NET.", "192.228.79.201")) return 0; -- if(!ah(dp, r, "C.ROOT-SERVERS.NET.", "192.33.4.12")) return 0; -- if(!ah(dp, r, "D.ROOT-SERVERS.NET.", "128.8.10.90")) return 0; -- if(!ah(dp, r, "E.ROOT-SERVERS.NET.", "192.203.230.10")) return 0; -- if(!ah(dp, r, "F.ROOT-SERVERS.NET.", "192.5.5.241")) return 0; -- if(!ah(dp, r, "G.ROOT-SERVERS.NET.", "192.112.36.4")) return 0; -- if(!ah(dp, r, "H.ROOT-SERVERS.NET.", "128.63.2.53")) return 0; -- if(!ah(dp, r, "I.ROOT-SERVERS.NET.", "192.36.148.17")) return 0; -- if(!ah(dp, r, "J.ROOT-SERVERS.NET.", "192.58.128.30")) return 0; -- if(!ah(dp, r, "K.ROOT-SERVERS.NET.", "193.0.14.129")) return 0; -- if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "199.7.83.42")) return 0; -- if(!ah(dp, r, "M.ROOT-SERVERS.NET.", "202.12.27.33")) return 0; -+ if(!ah(dp, "A.ROOT-SERVERS.NET.", "198.41.0.4")) return 0; -+ if(!ah(dp, "B.ROOT-SERVERS.NET.", "192.228.79.201")) return 0; -+ if(!ah(dp, "C.ROOT-SERVERS.NET.", "192.33.4.12")) return 0; -+ if(!ah(dp, "D.ROOT-SERVERS.NET.", "128.8.10.90")) return 0; -+ if(!ah(dp, "E.ROOT-SERVERS.NET.", "192.203.230.10")) return 0; -+ if(!ah(dp, "F.ROOT-SERVERS.NET.", "192.5.5.241")) return 0; -+ if(!ah(dp, "G.ROOT-SERVERS.NET.", "192.112.36.4")) return 0; -+ if(!ah(dp, "H.ROOT-SERVERS.NET.", "128.63.2.53")) return 0; -+ if(!ah(dp, "I.ROOT-SERVERS.NET.", "192.36.148.17")) return 0; -+ if(!ah(dp, "J.ROOT-SERVERS.NET.", "192.58.128.30")) return 0; -+ if(!ah(dp, "K.ROOT-SERVERS.NET.", "193.0.14.129")) return 0; -+ if(!ah(dp, "L.ROOT-SERVERS.NET.", "199.7.83.42")) return 0; -+ if(!ah(dp, "M.ROOT-SERVERS.NET.", "202.12.27.33")) return 0; - } - if(do_ip6) { -- if(!ah(dp, r, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) return 0; -- if(!ah(dp, r, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) return 0; -- if(!ah(dp, r, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) return 0; -- if(!ah(dp, r, "H.ROOT-SERVERS.NET.", "2001:500:1::803f:235")) return 0; -- if(!ah(dp, r, "I.ROOT-SERVERS.NET.", "2001:7fe::53")) return 0; -- if(!ah(dp, r, "J.ROOT-SERVERS.NET.", "2001:503:c27::2:30")) return 0; -- if(!ah(dp, r, "K.ROOT-SERVERS.NET.", "2001:7fd::1")) return 0; -- if(!ah(dp, r, "L.ROOT-SERVERS.NET.", "2001:500:3::42")) return 0; -- if(!ah(dp, r, "M.ROOT-SERVERS.NET.", "2001:dc3::35")) return 0; -+ if(!ah(dp, "A.ROOT-SERVERS.NET.", "2001:503:ba3e::2:30")) return 0; -+ if(!ah(dp, "D.ROOT-SERVERS.NET.", "2001:500:2d::d")) return 0; -+ if(!ah(dp, "F.ROOT-SERVERS.NET.", "2001:500:2f::f")) return 0; -+ if(!ah(dp, "H.ROOT-SERVERS.NET.", "2001:500:1::803f:235")) return 0; -+ if(!ah(dp, "I.ROOT-SERVERS.NET.", "2001:7fe::53")) return 0; -+ if(!ah(dp, "J.ROOT-SERVERS.NET.", "2001:503:c27::2:30")) return 0; -+ if(!ah(dp, "K.ROOT-SERVERS.NET.", "2001:7fd::1")) return 0; -+ if(!ah(dp, "L.ROOT-SERVERS.NET.", "2001:500:3::42")) return 0; -+ if(!ah(dp, "M.ROOT-SERVERS.NET.", "2001:dc3::35")) return 0; - } - return dp; - } -@@ -149,51 +159,50 @@ - hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp, - int noprime) - { -- struct iter_hints_stub* node = regional_alloc(hints->region, -+ struct iter_hints_stub* node = (struct iter_hints_stub*)malloc( - sizeof(struct iter_hints_stub)); -- uint8_t* nm; -- if(!node) -- return 0; -- nm = regional_alloc_init(hints->region, dp->name, dp->namelen); -- if(!nm) -+ if(!node) { -+ delegpt_free_mlc(dp); - return 0; -+ } - node->dp = dp; - node->noprime = (uint8_t)noprime; -- if(!name_tree_insert(&hints->tree, &node->node, nm, dp->namelen, -+ if(!name_tree_insert(&hints->tree, &node->node, dp->name, dp->namelen, - dp->namelabs, c)) { - log_err("second hints ignored."); -+ delegpt_free_mlc(dp); -+ free(node); - } - return 1; - } - - /** set stub name */ --static int --read_stubs_name(struct iter_hints* hints, struct config_stub* s, -- struct delegpt* dp) -+static struct delegpt* -+read_stubs_name(struct config_stub* s) - { -+ struct delegpt* dp; - ldns_rdf* rdf; - if(!s->name) { - log_err("stub zone without a name"); -- return 0; -+ return NULL; - } - rdf = ldns_dname_new_frm_str(s->name); - if(!rdf) { - log_err("cannot parse stub zone name %s", s->name); -- return 0; -+ return NULL; - } -- if(!delegpt_set_name(dp, hints->region, ldns_rdf_data(rdf))) { -+ if(!(dp=delegpt_create_mlc(ldns_rdf_data(rdf)))) { - ldns_rdf_deep_free(rdf); - log_err("out of memory"); -- return 0; -+ return NULL; - } - ldns_rdf_deep_free(rdf); -- return 1; -+ return dp; - } - - /** set stub host names */ - static int --read_stubs_host(struct iter_hints* hints, struct config_stub* s, -- struct delegpt* dp) -+read_stubs_host(struct config_stub* s, struct delegpt* dp) - { - struct config_strlist* p; - ldns_rdf* rdf; -@@ -205,7 +214,7 @@ - s->name, p->str); - return 0; - } -- if(!delegpt_add_ns(dp, hints->region, ldns_rdf_data(rdf), 0)) { -+ if(!delegpt_add_ns_mlc(dp, ldns_rdf_data(rdf), 0)) { - ldns_rdf_deep_free(rdf); - log_err("out of memory"); - return 0; -@@ -217,8 +226,7 @@ - - /** set stub server addresses */ - static int --read_stubs_addr(struct iter_hints* hints, struct config_stub* s, -- struct delegpt* dp) -+read_stubs_addr(struct config_stub* s, struct delegpt* dp) - { - struct config_strlist* p; - struct sockaddr_storage addr; -@@ -230,7 +238,7 @@ - s->name, p->str); - return 0; - } -- if(!delegpt_add_addr(dp, hints->region, &addr, addrlen, 0, 0)) { -+ if(!delegpt_add_addr_mlc(dp, &addr, addrlen, 0, 0)) { - log_err("out of memory"); - return 0; - } -@@ -243,17 +251,13 @@ - read_stubs(struct iter_hints* hints, struct config_file* cfg) - { - struct config_stub* s; -+ struct delegpt* dp; - for(s = cfg->stubs; s; s = s->next) { -- struct delegpt* dp = delegpt_create(hints->region); -- if(!dp) { -- log_err("out of memory"); -+ if(!(dp=read_stubs_name(s)) || -+ !read_stubs_host(s, dp) || -+ !read_stubs_addr(s, dp)) - return 0; -- } - dp->has_parent_side_NS = 1; -- if(!read_stubs_name(hints, s, dp) || -- !read_stubs_host(hints, s, dp) || -- !read_stubs_addr(hints, s, dp)) -- return 0; - if(!hints_insert(hints, LDNS_RR_CLASS_IN, dp, !s->isprime)) - return 0; - delegpt_log(VERB_QUERY, dp); -@@ -279,7 +283,7 @@ - fname, strerror(errno)); - return 0; - } -- dp = delegpt_create(hints->region); -+ dp = delegpt_create_mlc(NULL); - if(!dp) { - log_err("out of memory reading root hints"); - fclose(f); -@@ -300,14 +304,14 @@ - goto stop_read; - } - if(ldns_rr_get_type(rr) == LDNS_RR_TYPE_NS) { -- if(!delegpt_add_ns(dp, hints->region, -+ if(!delegpt_add_ns_mlc(dp, - ldns_rdf_data(ldns_rr_rdf(rr, 0)), 0)) { - log_err("out of memory reading root hints"); - goto stop_read; - } - c = ldns_rr_get_class(rr); - if(!dp->name) { -- if(!delegpt_set_name(dp, hints->region, -+ if(!delegpt_set_name_mlc(dp, - ldns_rdf_data(ldns_rr_owner(rr)))){ - log_err("out of memory."); - goto stop_read; -@@ -321,7 +325,7 @@ - sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT); - memmove(&sa.sin_addr, - ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET_SIZE); -- if(!delegpt_add_target(dp, hints->region, -+ if(!delegpt_add_target_mlc(dp, - ldns_rdf_data(ldns_rr_owner(rr)), - ldns_rdf_size(ldns_rr_owner(rr)), - (struct sockaddr_storage*)&sa, len, -@@ -337,7 +341,7 @@ - sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT); - memmove(&sa.sin6_addr, - ldns_rdf_data(ldns_rr_rdf(rr, 0)), INET6_SIZE); -- if(!delegpt_add_target(dp, hints->region, -+ if(!delegpt_add_target_mlc(dp, - ldns_rdf_data(ldns_rr_owner(rr)), - ldns_rdf_size(ldns_rr_owner(rr)), - (struct sockaddr_storage*)&sa, len, -@@ -360,6 +364,7 @@ - fclose(f); - if(!dp->name) { - log_warn("root hints %s: no NS content", fname); -+ delegpt_free_mlc(dp); - return 1; - } - if(!hints_insert(hints, c, dp, 0)) { -@@ -373,6 +378,7 @@ - ldns_rdf_deep_free(origin); - if (prev_rr) - ldns_rdf_deep_free(prev_rr); -+ delegpt_free_mlc(dp); - fclose(f); - return 0; - } -@@ -400,7 +406,7 @@ - int - hints_apply_cfg(struct iter_hints* hints, struct config_file* cfg) - { -- regional_free_all(hints->region); -+ hints_del_tree(hints); - name_tree_init(&hints->tree); - - /* read root hints */ -@@ -413,8 +419,8 @@ - - /* use fallback compiletime root hints */ - if(!hints_lookup_root(hints, LDNS_RR_CLASS_IN)) { -- struct delegpt* dp = compile_time_root_prime(hints->region, -- cfg->do_ip4, cfg->do_ip6); -+ struct delegpt* dp = compile_time_root_prime(cfg->do_ip4, -+ cfg->do_ip6); - verbose(VERB_ALGO, "no config, using builtin root hints."); - if(!dp) - return 0; -@@ -483,6 +489,43 @@ - size_t - hints_get_mem(struct iter_hints* hints) - { -+ size_t s; -+ struct iter_hints_stub* p; - if(!hints) return 0; -- return sizeof(*hints) + regional_get_mem(hints->region); -+ s = sizeof(*hints); -+ RBTREE_FOR(p, struct iter_hints_stub*, &hints->tree) { -+ s += sizeof(*p) + delegpt_get_mem(p->dp); -+ } -+ return s; - } -+ -+int -+hints_add_stub(struct iter_hints* hints, uint16_t c, struct delegpt* dp, -+ int noprime) -+{ -+ struct iter_hints_stub *z; -+ if((z=(struct iter_hints_stub*)name_tree_find(&hints->tree, -+ dp->name, dp->namelen, dp->namelabs, c)) != NULL) { -+ (void)rbtree_delete(&hints->tree, &z->node); -+ hints_stub_free(z); -+ } -+ if(!hints_insert(hints, c, dp, noprime)) -+ return 0; -+ name_tree_init_parents(&hints->tree); -+ return 1; -+} -+ -+void -+hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm) -+{ -+ struct iter_hints_stub *z; -+ size_t len; -+ int labs = dname_count_size_labels(nm, &len); -+ if(!(z=(struct iter_hints_stub*)name_tree_find(&hints->tree, -+ nm, len, labs, c))) -+ return; /* nothing to do */ -+ (void)rbtree_delete(&hints->tree, &z->node); -+ hints_stub_free(z); -+ name_tree_init_parents(&hints->tree); -+} -+ -diff -Naur unbound-1.4.16/iterator/iter_hints.h unbound-trunk/iterator/iter_hints.h ---- unbound-1.4.16/iterator/iter_hints.h 2010-07-07 09:13:36.000000000 -0400 -+++ unbound-trunk/iterator/iter_hints.h 2012-02-22 20:37:15.042368186 -0500 -@@ -46,14 +46,11 @@ - struct iter_env; - struct config_file; - struct delegpt; --struct regional; - - /** - * Iterator hints structure - */ - struct iter_hints { -- /** regional where hints are allocated */ -- struct regional* region; - /** - * Hints are stored in this tree. Sort order is specially chosen. - * first sorted on qclass. Then on dname in nsec-like order, so that -@@ -71,7 +68,7 @@ - struct iter_hints_stub { - /** tree sorted by name, class */ - struct name_tree_node node; -- /** delegation point with hint information for this stub. */ -+ /** delegation point with hint information for this stub. malloced. */ - struct delegpt* dp; - /** does the stub need to forego priming (like on other ports) */ - uint8_t noprime; -@@ -139,4 +136,26 @@ - */ - size_t hints_get_mem(struct iter_hints* hints); - -+/** -+ * Add stub to hints structure. For external use since it recalcs -+ * the tree parents. -+ * @param hints: the hints data structure -+ * @param c: class of zone -+ * @param dp: delegation point with name and target nameservers for new -+ * hints stub. malloced. -+ * @param noprime: set noprime option to true or false on new hint stub. -+ * @return false on failure (out of memory); -+ */ -+int hints_add_stub(struct iter_hints* hints, uint16_t c, struct delegpt* dp, -+ int noprime); -+ -+/** -+ * Remove stub from hints structure. For external use since it -+ * recalcs the tree parents. -+ * @param hints: the hints data structure -+ * @param c: class of stub zone -+ * @param nm: name of stub zone (in uncompressed wireformat). -+ */ -+void hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm); -+ - #endif /* ITERATOR_ITER_HINTS_H */ -diff -Naur unbound-1.4.16/iterator/iter_utils.c unbound-trunk/iterator/iter_utils.c ---- unbound-1.4.16/iterator/iter_utils.c 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/iterator/iter_utils.c 2012-02-22 20:37:15.042368186 -0500 -@@ -113,12 +113,6 @@ - verbose(VERB_QUERY, "target fetch policy for level %d is %d", - i, iter_env->target_fetch_policy[i]); - -- if(!iter_env->hints) -- iter_env->hints = hints_create(); -- if(!iter_env->hints || !hints_apply_cfg(iter_env->hints, cfg)) { -- log_err("Could not set root or stub hints"); -- return 0; -- } - if(!iter_env->donotq) - iter_env->donotq = donotq_create(); - if(!iter_env->donotq || !donotq_apply_cfg(iter_env->donotq, cfg)) { -@@ -425,11 +419,11 @@ - - int - iter_dns_store(struct module_env* env, struct query_info* msgqinf, -- struct reply_info* msgrep, int is_referral, uint32_t leeway, -+ struct reply_info* msgrep, int is_referral, uint32_t leeway, int pside, - struct regional* region) - { - return dns_cache_store(env, msgqinf, msgrep, is_referral, leeway, -- region); -+ pside, region); - } - - int -diff -Naur unbound-1.4.16/iterator/iter_utils.h unbound-trunk/iterator/iter_utils.h ---- unbound-1.4.16/iterator/iter_utils.h 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/iterator/iter_utils.h 2012-02-22 20:37:15.042368186 -0500 -@@ -121,11 +121,13 @@ - * @param is_referral: If true, then the given message to be stored is a - * referral. The cache implementation may use this as a hint. - * @param leeway: prefetch TTL leeway to expire old rrsets quicker. -+ * @param pside: true if dp is parentside, thus message is 'fresh' and NS -+ * can be prefetch-updates. - * @param region: to copy modified (cache is better) rrs back to. - * @return 0 on alloc error (out of memory). - */ - int iter_dns_store(struct module_env* env, struct query_info* qinf, -- struct reply_info* rep, int is_referral, uint32_t leeway, -+ struct reply_info* rep, int is_referral, uint32_t leeway, int pside, - struct regional* region); - - /** -diff -Naur unbound-1.4.16/libunbound/libworker.c unbound-trunk/libunbound/libworker.c ---- unbound-1.4.16/libunbound/libworker.c 2012-01-10 10:07:16.000000000 -0500 -+++ unbound-trunk/libunbound/libworker.c 2012-02-22 20:37:15.600368186 -0500 -@@ -66,6 +66,7 @@ - #include "util/data/msgencode.h" - #include "util/tube.h" - #include "iterator/iter_fwd.h" -+#include "iterator/iter_hints.h" - - /** handle new query command for bg worker */ - static void handle_newq(struct libworker* w, uint8_t* buf, uint32_t len); -@@ -83,6 +84,7 @@ - ldns_buffer_free(w->env->scratch_buffer); - regional_destroy(w->env->scratch); - forwards_delete(w->env->fwds); -+ hints_delete(w->env->hints); - ub_randfree(w->env->rnd); - free(w->env); - } -@@ -127,17 +129,24 @@ - forwards_delete(w->env->fwds); - w->env->fwds = NULL; - } -+ w->env->hints = hints_create(); -+ if(w->env->hints && !hints_apply_cfg(w->env->hints, cfg)) { -+ hints_delete(w->env->hints); -+ w->env->hints = NULL; -+ } - if(cfg->ssl_upstream) { - w->sslctx = connect_sslctx_create(NULL, NULL, NULL); - if(!w->sslctx) { -- libworker_delete(w); -- return NULL; -+ /* to make the setup fail after unlock */ -+ hints_delete(w->env->hints); -+ w->env->hints = NULL; - } - } - if(!w->is_bg || w->is_bg_thread) { - lock_basic_unlock(&ctx->cfglock); - } -- if(!w->env->scratch || !w->env->scratch_buffer || !w->env->fwds) { -+ if(!w->env->scratch || !w->env->scratch_buffer || !w->env->fwds || -+ !w->env->hints) { - libworker_delete(w); - return NULL; - } -diff -Naur unbound-1.4.16/pythonmod/pythonmod_utils.c unbound-trunk/pythonmod/pythonmod_utils.c ---- unbound-1.4.16/pythonmod/pythonmod_utils.c 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/pythonmod/pythonmod_utils.c 2012-02-22 20:37:12.805368182 -0500 -@@ -66,7 +66,7 @@ - } - - return dns_cache_store(qstate->env, qinfo, msgrep, is_referral, -- qstate->prefetch_leeway, NULL); -+ qstate->prefetch_leeway, 0, NULL); - } - - /* Invalidate the message associated with query_info stored in message cache */ -diff -Naur unbound-1.4.16/services/cache/dns.c unbound-trunk/services/cache/dns.c ---- unbound-1.4.16/services/cache/dns.c 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/services/cache/dns.c 2012-02-22 20:37:14.065368184 -0500 -@@ -55,12 +55,20 @@ - * @param env: module environment with caches. - * @param rep: contains list of rrsets to store. - * @param now: current time. -+ * @param leeway: during prefetch how much leeway to update TTLs. -+ * This makes rrsets (other than type NS) timeout sooner so they get -+ * updated with a new full TTL. -+ * Type NS does not get this, because it must not be refreshed from the -+ * child domain, but keep counting down properly. -+ * @param pside: if from parentside discovered NS, so that its NS is okay -+ * in a prefetch situation to be updated (without becoming sticky). - * @param qrep: update rrsets here if cache is better - * @param region: for qrep allocs. - */ - static void - store_rrsets(struct module_env* env, struct reply_info* rep, uint32_t now, -- struct reply_info* qrep, struct regional* region) -+ uint32_t leeway, int pside, struct reply_info* qrep, -+ struct regional* region) - { - size_t i; - /* see if rrset already exists in cache, if not insert it. */ -@@ -69,7 +77,8 @@ - rep->ref[i].id = rep->rrsets[i]->id; - /* update ref if it was in the cache */ - switch(rrset_cache_update(env->rrset_cache, &rep->ref[i], -- env->alloc, now)) { -+ env->alloc, now + ((ntohs(rep->ref[i].key->rk.type)== -+ LDNS_RR_TYPE_NS && !pside)?0:leeway))) { - case 0: /* ref unchanged, item inserted */ - break; - case 2: /* ref updated, cache is superior */ -@@ -96,7 +105,7 @@ - - void - dns_cache_store_msg(struct module_env* env, struct query_info* qinfo, -- hashvalue_t hash, struct reply_info* rep, uint32_t leeway, -+ hashvalue_t hash, struct reply_info* rep, uint32_t leeway, int pside, - struct reply_info* qrep, struct regional* region) - { - struct msgreply_entry* e; -@@ -112,7 +121,7 @@ - /* there was a reply_info_sortref(rep) here but it seems to be - * unnecessary, because the cache gets locked per rrset. */ - reply_info_set_ttls(rep, *env->now); -- store_rrsets(env, rep, *env->now+leeway, qrep, region); -+ store_rrsets(env, rep, *env->now, leeway, pside, qrep, region); - if(ttl == 0) { - /* we do not store the message, but we did store the RRs, - * which could be useful for delegation information */ -@@ -730,7 +739,7 @@ - - int - dns_cache_store(struct module_env* env, struct query_info* msgqinf, -- struct reply_info* msgrep, int is_referral, uint32_t leeway, -+ struct reply_info* msgrep, int is_referral, uint32_t leeway, int pside, - struct regional* region) - { - struct reply_info* rep = NULL; -@@ -752,8 +761,11 @@ - ref.key = rep->rrsets[i]; - ref.id = rep->rrsets[i]->id; - /*ignore ret: it was in the cache, ref updated */ -+ /* no leeway for typeNS */ - (void)rrset_cache_update(env->rrset_cache, &ref, -- env->alloc, *env->now + leeway); -+ env->alloc, *env->now + -+ ((ntohs(ref.key->rk.type)==LDNS_RR_TYPE_NS -+ && !pside) ? 0:leeway)); - } - free(rep); - return 1; -@@ -774,7 +786,8 @@ - rep->flags |= (BIT_RA | BIT_QR); - rep->flags &= ~(BIT_AA | BIT_CD); - h = query_info_hash(&qinf); -- dns_cache_store_msg(env, &qinf, h, rep, leeway, msgrep, region); -+ dns_cache_store_msg(env, &qinf, h, rep, leeway, pside, msgrep, -+ region); - /* qname is used inside query_info_entrysetup, and set to - * NULL. If it has not been used, free it. free(0) is safe. */ - free(qinf.qname); -diff -Naur unbound-1.4.16/services/cache/dns.h unbound-trunk/services/cache/dns.h ---- unbound-1.4.16/services/cache/dns.h 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/services/cache/dns.h 2012-02-22 20:37:14.066368184 -0500 -@@ -74,12 +74,15 @@ - * It will store only the RRsets, not the message. - * @param leeway: TTL value, if not 0, other rrsets are considered expired - * that many seconds before actual TTL expiry. -+ * @param pside: if true, information came from a server which was fetched -+ * from the parentside of the zonecut. This means that the type NS -+ * can be updated to full TTL even in prefetch situations. - * @param region: region to allocate better entries from cache into. - * (used when is_referral is false). - * @return 0 on alloc error (out of memory). - */ - int dns_cache_store(struct module_env* env, struct query_info* qinf, -- struct reply_info* rep, int is_referral, uint32_t leeway, -+ struct reply_info* rep, int is_referral, uint32_t leeway, int pside, - struct regional* region); - - /** -@@ -95,11 +98,14 @@ - * Adjusts the reply info TTLs to absolute time. - * @param leeway: TTL value, if not 0, other rrsets are considered expired - * that many seconds before actual TTL expiry. -+ * @param pside: if true, information came from a server which was fetched -+ * from the parentside of the zonecut. This means that the type NS -+ * can be updated to full TTL even in prefetch situations. - * @param qrep: message that can be altered with better rrs from cache. - * @param region: to allocate into for qmsg. - */ - void dns_cache_store_msg(struct module_env* env, struct query_info* qinfo, -- hashvalue_t hash, struct reply_info* rep, uint32_t leeway, -+ hashvalue_t hash, struct reply_info* rep, uint32_t leeway, int pside, - struct reply_info* qrep, struct regional* region); - - /** -diff -Naur unbound-1.4.16/services/cache/infra.c unbound-trunk/services/cache/infra.c ---- unbound-1.4.16/services/cache/infra.c 2012-01-10 10:07:16.000000000 -0500 -+++ unbound-trunk/services/cache/infra.c 2012-02-22 20:37:14.063368184 -0500 -@@ -52,6 +52,11 @@ - /** Timeout when only a single probe query per IP is allowed. */ - #define PROBE_MAXRTO 12000 /* in msec */ - -+/** number of timeouts for a type when the domain can be blocked ; -+ * even if another type has completely rtt maxed it, the different type -+ * can do this number of packets (until those all timeout too) */ -+#define TIMEOUT_COUNT_MAX 3 -+ - size_t - infra_sizefunc(void* k, void* ATTR_UNUSED(d)) - { -@@ -196,6 +201,9 @@ - data->rec_lame = 0; - data->lame_type_A = 0; - data->lame_other = 0; -+ data->timeout_A = 0; -+ data->timeout_AAAA = 0; -+ data->timeout_other = 0; - } - - /** -@@ -250,6 +258,9 @@ - if(e && ((struct infra_data*)e->data)->ttl < timenow) { - /* it expired, try to reuse existing entry */ - int old = ((struct infra_data*)e->data)->rtt.rto; -+ uint8_t tA = ((struct infra_data*)e->data)->timeout_A; -+ uint8_t tAAAA = ((struct infra_data*)e->data)->timeout_AAAA; -+ uint8_t tother = ((struct infra_data*)e->data)->timeout_other; - lock_rw_unlock(&e->lock); - e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1); - if(e) { -@@ -259,9 +270,13 @@ - data_entry_init(infra, e, timenow); - wr = 1; - /* TOP_TIMEOUT remains on reuse */ -- if(old >= USEFUL_SERVER_TOP_TIMEOUT) -+ if(old >= USEFUL_SERVER_TOP_TIMEOUT) { - ((struct infra_data*)e->data)->rtt.rto - = USEFUL_SERVER_TOP_TIMEOUT; -+ ((struct infra_data*)e->data)->timeout_A = tA; -+ ((struct infra_data*)e->data)->timeout_AAAA = tAAAA; -+ ((struct infra_data*)e->data)->timeout_other = tother; -+ } - } - } - if(!e) { -@@ -358,8 +373,8 @@ - - int - infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, -- socklen_t addrlen, uint8_t* nm, size_t nmlen, int roundtrip, -- int orig_rtt, uint32_t timenow) -+ socklen_t addrlen, uint8_t* nm, size_t nmlen, int qtype, -+ int roundtrip, int orig_rtt, uint32_t timenow) - { - struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, - nm, nmlen, 1); -@@ -377,9 +392,24 @@ - data = (struct infra_data*)e->data; - if(roundtrip == -1) { - rtt_lost(&data->rtt, orig_rtt); -+ if(qtype == LDNS_RR_TYPE_A) { -+ if(data->timeout_A < TIMEOUT_COUNT_MAX) -+ data->timeout_A++; -+ } else if(qtype == LDNS_RR_TYPE_AAAA) { -+ if(data->timeout_AAAA < TIMEOUT_COUNT_MAX) -+ data->timeout_AAAA++; -+ } else { -+ if(data->timeout_other < TIMEOUT_COUNT_MAX) -+ data->timeout_other++; -+ } - } else { - rtt_update(&data->rtt, roundtrip); - data->probedelay = 0; -+ if(qtype == LDNS_RR_TYPE_A) -+ data->timeout_A = 0; -+ else if(qtype == LDNS_RR_TYPE_AAAA) -+ data->timeout_AAAA = 0; -+ else data->timeout_other = 0; - } - if(data->rtt.rto > 0) - rto = data->rtt.rto; -@@ -392,7 +422,8 @@ - - int infra_get_host_rto(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm, -- size_t nmlen, struct rtt_info* rtt, int* delay, uint32_t timenow) -+ size_t nmlen, struct rtt_info* rtt, int* delay, uint32_t timenow, -+ int* tA, int* tAAAA, int* tother) - { - struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, - nm, nmlen, 0); -@@ -407,6 +438,9 @@ - *delay = (int)(data->probedelay - timenow); - else *delay = 0; - } -+ *tA = (int)data->timeout_A; -+ *tAAAA = (int)data->timeout_AAAA; -+ *tother = (int)data->timeout_other; - lock_rw_unlock(&e->lock); - return ttl; - } -@@ -456,20 +490,34 @@ - host = (struct infra_data*)e->data; - *rtt = rtt_unclamped(&host->rtt); - if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay -- && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) -+ && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) { - /* single probe for this domain, and we are not probing */ -- *rtt = USEFUL_SERVER_TOP_TIMEOUT; -+ /* unless the query type allows a probe to happen */ -+ if(qtype == LDNS_RR_TYPE_A) { -+ if(host->timeout_A >= TIMEOUT_COUNT_MAX) -+ *rtt = USEFUL_SERVER_TOP_TIMEOUT; -+ else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; -+ } else if(qtype == LDNS_RR_TYPE_AAAA) { -+ if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX) -+ *rtt = USEFUL_SERVER_TOP_TIMEOUT; -+ else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; -+ } else { -+ if(host->timeout_other >= TIMEOUT_COUNT_MAX) -+ *rtt = USEFUL_SERVER_TOP_TIMEOUT; -+ else *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; -+ } -+ } - if(timenow > host->ttl) { - /* expired entry */ - /* see if this can be a re-probe of an unresponsive server */ - /* minus 1000 because that is outside of the RTTBAND, so - * blacklisted servers stay blacklisted if this is chosen */ - if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) { -+ lock_rw_unlock(&e->lock); - *rtt = USEFUL_SERVER_TOP_TIMEOUT-1000; - *lame = 0; - *dnsseclame = 0; - *reclame = 0; -- lock_rw_unlock(&e->lock); - return 1; - } - lock_rw_unlock(&e->lock); -diff -Naur unbound-1.4.16/services/cache/infra.h unbound-trunk/services/cache/infra.h ---- unbound-1.4.16/services/cache/infra.h 2011-10-26 11:46:23.000000000 -0400 -+++ unbound-trunk/services/cache/infra.h 2012-02-22 20:37:14.065368184 -0500 -@@ -91,6 +91,13 @@ - uint8_t lame_type_A; - /** the host is lame (not authoritative) for other query types */ - uint8_t lame_other; -+ -+ /** timeouts counter for type A */ -+ uint8_t timeout_A; -+ /** timeouts counter for type AAAA */ -+ uint8_t timeout_AAAA; -+ /** timeouts counter for others */ -+ uint8_t timeout_other; - }; - - /** -@@ -195,6 +202,7 @@ - * @param addrlen: length of addr. - * @param name: zone name - * @param namelen: zone name length -+ * @param qtype: query type. - * @param roundtrip: estimate of roundtrip time in milliseconds or -1 for - * timeout. - * @param orig_rtt: original rtt for the query that timed out (roundtrip==-1). -@@ -203,7 +211,7 @@ - * @return: 0 on error. new rto otherwise. - */ - int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, -- socklen_t addrlen, uint8_t* name, size_t namelen, -+ socklen_t addrlen, uint8_t* name, size_t namelen, int qtype, - int roundtrip, int orig_rtt, uint32_t timenow); - - /** -@@ -267,12 +275,16 @@ - * @param rtt: the rtt_info is copied into here (caller alloced return struct). - * @param delay: probe delay (if any). - * @param timenow: what time it is now. -+ * @param tA: timeout counter on type A. -+ * @param tAAAA: timeout counter on type AAAA. -+ * @param tother: timeout counter on type other. - * @return TTL the infra host element is valid for. If -1: not found in cache. - * TTL -2: found but expired. - */ - int infra_get_host_rto(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* name, -- size_t namelen, struct rtt_info* rtt, int* delay, uint32_t timenow); -+ size_t namelen, struct rtt_info* rtt, int* delay, uint32_t timenow, -+ int* tA, int* tAAAA, int* tother); - - /** - * Get memory used by the infra cache. -diff -Naur unbound-1.4.16/services/outside_network.c unbound-trunk/services/outside_network.c ---- unbound-1.4.16/services/outside_network.c 2011-12-24 06:27:53.000000000 -0500 -+++ unbound-trunk/services/outside_network.c 2012-02-22 20:37:14.106368184 -0500 -@@ -1166,7 +1166,7 @@ - serviced_create(struct outside_network* outnet, ldns_buffer* buff, int dnssec, - int want_dnssec, int tcp_upstream, int ssl_upstream, - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, -- size_t zonelen) -+ size_t zonelen, int qtype) - { - struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq)); - #ifdef UNBOUND_DEBUG -@@ -1188,6 +1188,7 @@ - return NULL; - } - sq->zonelen = zonelen; -+ sq->qtype = qtype; - sq->dnssec = dnssec; - sq->want_dnssec = want_dnssec; - sq->tcp_upstream = tcp_upstream; -@@ -1566,8 +1567,8 @@ - * huge due to system-hibernated and we woke up */ - if(roundtime < TCP_AUTH_QUERY_TIMEOUT*1000) { - if(!infra_rtt_update(sq->outnet->infra, &sq->addr, -- sq->addrlen, sq->zone, sq->zonelen, roundtime, -- sq->last_rtt, (uint32_t)now.tv_sec)) -+ sq->addrlen, sq->zone, sq->zonelen, sq->qtype, -+ roundtime, sq->last_rtt, (uint32_t)now.tv_sec)) - log_err("out of memory noting rtt."); - } - } -@@ -1658,7 +1659,7 @@ - } - sq->retry++; - if(!(rto=infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, -- sq->zone, sq->zonelen, -1, sq->last_rtt, -+ sq->zone, sq->zonelen, sq->qtype, -1, sq->last_rtt, - (uint32_t)now.tv_sec))) - log_err("out of memory in UDP exponential backoff"); - if(sq->retry < OUTBOUND_UDP_RETRY) { -@@ -1752,8 +1753,8 @@ - * above this value gives trouble with server selection */ - if(roundtime < 60000) { - if(!infra_rtt_update(outnet->infra, &sq->addr, sq->addrlen, -- sq->zone, sq->zonelen, roundtime, sq->last_rtt, -- (uint32_t)now.tv_sec)) -+ sq->zone, sq->zonelen, sq->qtype, roundtime, -+ sq->last_rtt, (uint32_t)now.tv_sec)) - log_err("out of memory noting rtt."); - } - } -@@ -1814,7 +1815,7 @@ - /* make new serviced query entry */ - sq = serviced_create(outnet, buff, dnssec, want_dnssec, - tcp_upstream, ssl_upstream, addr, addrlen, zone, -- zonelen); -+ zonelen, (int)qtype); - if(!sq) { - free(cb); - return NULL; -diff -Naur unbound-1.4.16/services/outside_network.h unbound-trunk/services/outside_network.h ---- unbound-1.4.16/services/outside_network.h 2011-11-01 06:18:56.000000000 -0400 -+++ unbound-trunk/services/outside_network.h 2012-02-22 20:37:14.107368184 -0500 -@@ -312,6 +312,8 @@ - uint8_t* zone; - /** length of zone name */ - size_t zonelen; -+ /** qtype */ -+ int qtype; - /** current status */ - enum serviced_query_status { - /** initial status */ -diff -Naur unbound-1.4.16/smallapp/unbound-checkconf.c unbound-trunk/smallapp/unbound-checkconf.c ---- unbound-1.4.16/smallapp/unbound-checkconf.c 2011-08-26 02:50:23.000000000 -0400 -+++ unbound-trunk/smallapp/unbound-checkconf.c 2012-02-22 20:37:16.189368186 -0500 -@@ -50,6 +50,7 @@ - #include "util/regional.h" - #include "iterator/iterator.h" - #include "iterator/iter_fwd.h" -+#include "iterator/iter_hints.h" - #include "validator/validator.h" - #include "services/localzone.h" - #ifdef HAVE_GETOPT_H -@@ -434,6 +435,17 @@ - forwards_delete(fwd); - } - -+/** check hints */ -+static void -+check_hints(struct config_file* cfg) -+{ -+ struct iter_hints* hints = hints_create(); -+ if(!hints || !hints_apply_cfg(hints, cfg)) { -+ fatal_exit("Could not set root or stub hints"); -+ } -+ hints_delete(hints); -+} -+ - /** check config file */ - static void - checkconf(const char* cfgfile, const char* opt) -@@ -454,6 +466,7 @@ - check_mod(cfg, pythonmod_get_funcblock()); - #endif - check_fwd(cfg); -+ check_hints(cfg); - if(opt) print_option(cfg, opt); - else printf("unbound-checkconf: no errors in %s\n", cfgfile); - config_delete(cfg); -diff -Naur unbound-1.4.16/smallapp/unbound-control.c unbound-trunk/smallapp/unbound-control.c ---- unbound-1.4.16/smallapp/unbound-control.c 2011-06-10 06:11:38.000000000 -0400 -+++ unbound-trunk/smallapp/unbound-control.c 2012-02-22 20:37:16.188368186 -0500 -@@ -104,6 +104,12 @@ - printf(" list_forwards list forward-zones in use\n"); - printf(" list_local_zones list local-zones in use\n"); - printf(" list_local_data list local-data RRs in use\n"); -+ printf(" forward_add [+i] zone addr.. add forward-zone with servers\n"); -+ printf(" forward_remove [+i] zone remove forward zone\n"); -+ printf(" stub_add [+ip] zone addr.. add stub-zone with servers\n"); -+ printf(" stub_remove [+i] zone remove stub zone\n"); -+ printf(" +i also do dnssec insecure point\n"); -+ printf(" +p set stub to use priming\n"); - printf(" forward [off | addr ...] without arg show forward setup\n"); - printf(" or off to turn off root forwarding\n"); - printf(" or give list of ip addresses\n"); -diff -Naur unbound-1.4.16/testcode/fake_event.c unbound-trunk/testcode/fake_event.c ---- unbound-1.4.16/testcode/fake_event.c 2011-11-01 06:18:56.000000000 -0400 -+++ unbound-trunk/testcode/fake_event.c 2012-02-22 20:37:22.995368196 -0500 -@@ -147,6 +147,7 @@ - { - if(!pend) - return; -+ free(pend->zone); - ldns_buffer_free(pend->buffer); - ldns_pkt_free(pend->pkt); - free(pend); -@@ -554,7 +555,7 @@ - if(!dp) fatal_exit("cannot parse %s", now->variable); - rto = infra_rtt_update(runtime->infra, &now->addr, - now->addrlen, ldns_rdf_data(dp), ldns_rdf_size(dp), -- atoi(now->string), -1, runtime->now_secs); -+ LDNS_RR_TYPE_A, atoi(now->string), -1, runtime->now_secs); - log_addr(0, "INFRA_RTT for", &now->addr, now->addrlen); - log_info("INFRA_RTT(%s roundtrip %d): rto of %d", now->variable, - atoi(now->string), rto); -@@ -562,6 +563,24 @@ - ldns_rdf_deep_free(dp); - } - -+/** perform exponential backoff on the timout */ -+static void -+expon_timeout_backoff(struct replay_runtime* runtime) -+{ -+ struct fake_pending* p = runtime->pending_list; -+ int rtt, vs; -+ uint8_t edns_lame_known; -+ int last_rtt, rto; -+ if(!p) return; /* no pending packet to backoff */ -+ if(!infra_host(runtime->infra, &p->addr, p->addrlen, p->zone, -+ p->zonelen, runtime->now_secs, &vs, &edns_lame_known, &rtt)) -+ return; -+ last_rtt = rtt; -+ rto = infra_rtt_update(runtime->infra, &p->addr, p->addrlen, p->zone, -+ p->zonelen, p->qtype, -1, last_rtt, runtime->now_secs); -+ log_info("infra_rtt_update returned rto %d", rto); -+} -+ - /** - * Advance to the next moment. - */ -@@ -608,6 +627,7 @@ - case repevt_timeout: - mom = runtime->now; - advance_moment(runtime); -+ expon_timeout_backoff(runtime); - fake_pending_callback(runtime, mom, NETEVENT_TIMEOUT); - break; - case repevt_back_reply: -@@ -929,6 +949,7 @@ - pend->timeout = timeout/1000; - pend->transport = transport_udp; - pend->pkt = NULL; -+ pend->zone = NULL; - pend->serviced = 0; - pend->runtime = runtime; - status = ldns_buffer2pkt_wire(&pend->pkt, packet); -@@ -982,6 +1003,7 @@ - pend->timeout = timeout; - pend->transport = transport_tcp; - pend->pkt = NULL; -+ pend->zone = NULL; - pend->runtime = runtime; - pend->serviced = 0; - status = ldns_buffer2pkt_wire(&pend->pkt, packet); -@@ -1017,9 +1039,8 @@ - uint16_t flags, int dnssec, int ATTR_UNUSED(want_dnssec), - int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, -- size_t ATTR_UNUSED(zonelen), comm_point_callback_t* callback, -- void* callback_arg, ldns_buffer* ATTR_UNUSED(buff), -- int (*arg_compare)(void*,void*)) -+ size_t zonelen, comm_point_callback_t* callback, void* callback_arg, -+ ldns_buffer* ATTR_UNUSED(buff), int (*arg_compare)(void*,void*)) - { - struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; - struct fake_pending* pend = (struct fake_pending*)calloc(1, -@@ -1062,6 +1083,10 @@ - } - memcpy(&pend->addr, addr, addrlen); - pend->addrlen = addrlen; -+ pend->zone = memdup(zone, zonelen); -+ pend->zonelen = zonelen; -+ pend->qtype = (int)qtype; -+ log_assert(pend->zone); - pend->callback = callback; - pend->cb_arg = callback_arg; - pend->timeout = UDP_AUTH_QUERY_TIMEOUT; -@@ -1112,6 +1137,7 @@ - else runtime->pending_list = p->next; - ldns_buffer_free(p->buffer); - ldns_pkt_free(p->pkt); -+ free(p->zone); - free(p); - return; - } -diff -Naur unbound-1.4.16/testcode/replay.h unbound-trunk/testcode/replay.h ---- unbound-1.4.16/testcode/replay.h 2011-10-26 11:46:23.000000000 -0400 -+++ unbound-trunk/testcode/replay.h 2012-02-22 20:37:22.950368196 -0500 -@@ -323,6 +323,12 @@ - struct sockaddr_storage addr; - /** len of addr */ - socklen_t addrlen; -+ /** zone name, uncompressed wire format (as used when sent) */ -+ uint8_t* zone; -+ /** length of zone name */ -+ size_t zonelen; -+ /** qtype */ -+ int qtype; - /** The callback function to call when answer arrives (or timeout) */ - comm_point_callback_t* callback; - /** callback user argument */ -diff -Naur unbound-1.4.16/testcode/testbound.c unbound-trunk/testcode/testbound.c ---- unbound-1.4.16/testcode/testbound.c 2010-09-15 03:15:30.000000000 -0400 -+++ unbound-trunk/testcode/testbound.c 2012-02-22 20:37:22.995368196 -0500 -@@ -70,6 +70,7 @@ - printf("-p file playback text file\n"); - printf("-2 detect SHA256 support (exit code 0 or 1)\n"); - printf("-g detect GOST support (exit code 0 or 1)\n"); -+ printf("-e detect ECDSA support (exit code 0 or 1)\n"); - printf("-s testbound self-test - unit test of testbound parts.\n"); - printf("-o str unbound commandline options separated by spaces.\n"); - printf("Version %s\n", PACKAGE_VERSION); -@@ -272,7 +273,7 @@ - pass_argc = 1; - pass_argv[0] = "unbound"; - add_opts("-d", &pass_argc, pass_argv); -- while( (c=getopt(argc, argv, "2gho:p:s")) != -1) { -+ while( (c=getopt(argc, argv, "2egho:p:s")) != -1) { - switch(c) { - case 's': - free(pass_argv[1]); -@@ -288,6 +289,15 @@ - exit(1); - #endif - break; -+ case 'e': -+#if defined(USE_ECDSA) -+ printf("ECDSA supported\n"); -+ exit(0); -+#else -+ printf("ECDSA not supported\n"); -+ exit(1); -+#endif -+ break; - case 'g': - #ifdef USE_GOST - if(ldns_key_EVP_load_gost_id()) { -diff -Naur unbound-1.4.16/testcode/unitmain.c unbound-trunk/testcode/unitmain.c ---- unbound-1.4.16/testcode/unitmain.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-trunk/testcode/unitmain.c 2012-02-22 20:37:22.996368196 -0500 -@@ -445,7 +445,7 @@ - &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init && edns_lame == 0 ); - -- unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, -1, init, now) ); -+ unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, LDNS_RR_TYPE_A, -1, init, now) ); - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, - now, &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init*2 && edns_lame == 0 ); -diff -Naur unbound-1.4.16/testcode/unitverify.c unbound-trunk/testcode/unitverify.c ---- unbound-1.4.16/testcode/unitverify.c 2010-12-20 11:08:52.000000000 -0500 -+++ unbound-trunk/testcode/unitverify.c 2012-02-22 20:37:22.994368196 -0500 -@@ -520,6 +520,11 @@ - verifytest_file("testdata/test_sigs.gost", "20090807060504"); - else printf("Warning: skipped GOST, openssl does not provide gost.\n"); - #endif -+#ifdef USE_ECDSA -+ verifytest_file("testdata/test_sigs.ecdsa_p256", "20100908100439"); -+ verifytest_file("testdata/test_sigs.ecdsa_p384", "20100908100439"); -+ dstest_file("testdata/test_ds.sha384"); -+#endif - dstest_file("testdata/test_ds.sha1"); - nsectest(); - nsec3_hash_test("testdata/test_nsec3_hash.1"); -diff -Naur unbound-1.4.16/util/iana_ports.inc unbound-trunk/util/iana_ports.inc ---- unbound-1.4.16/util/iana_ports.inc 2012-01-10 04:42:55.000000000 -0500 -+++ unbound-trunk/util/iana_ports.inc 2012-02-22 20:37:23.866368198 -0500 -@@ -5026,6 +5026,7 @@ - 12006, - 12007, - 12008, -+12009, - 12012, - 12013, - 12109, -@@ -5272,6 +5273,7 @@ - 32896, - 33123, - 33331, -+33334, - 33434, - 33656, - 34249, -@@ -5304,6 +5306,7 @@ - 43188, - 43189, - 43190, -+43439, - 43440, - 43441, - 44321, -diff -Naur unbound-1.4.16/util/module.h unbound-trunk/util/module.h ---- unbound-1.4.16/util/module.h 2011-10-26 11:46:23.000000000 -0400 -+++ unbound-trunk/util/module.h 2012-02-22 20:37:23.867368198 -0500 -@@ -60,6 +60,7 @@ - struct val_anchors; - struct val_neg_cache; - struct iter_forwards; -+struct iter_hints; - - /** Maximum number of modules in operation */ - #define MAX_MODULE 5 -@@ -204,6 +205,14 @@ - /** Mapping of forwarding zones to targets. - * iterator forwarder information. per-thread, created by worker */ - struct iter_forwards* fwds; -+ /** -+ * iterator forwarder information. per-thread, created by worker. -+ * The hints -- these aren't stored in the cache because they don't -+ * expire. The hints are always used to "prime" the cache. Note -+ * that both root hints and stub zone "hints" are stored in this -+ * data structure. -+ */ -+ struct iter_hints* hints; - /** module specific data. indexed by module id. */ - void* modinfo[MAX_MODULE]; - }; -diff -Naur unbound-1.4.16/util/netevent.c unbound-trunk/util/netevent.c ---- unbound-1.4.16/util/netevent.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-trunk/util/netevent.c 2012-02-22 20:37:23.867368198 -0500 -@@ -367,11 +367,15 @@ - strncpy(buf1, "(inet_ntop error)", sizeof(buf1)); - } - buf1[sizeof(buf1)-1]=0; -+#ifdef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST - if(inet_ntop(AF_INET, &r->pktinfo.v4info.ipi_spec_dst, - buf2, (socklen_t)sizeof(buf2)) == 0) { - strncpy(buf2, "(inet_ntop error)", sizeof(buf2)); - } - buf2[sizeof(buf2)-1]=0; -+#else -+ buf2[0]=0; -+#endif - log_info("%s: %d %s %s", str, r->pktinfo.v4info.ipi_ifindex, - buf1, buf2); - #elif defined(IP_RECVDSTADDR) -diff -Naur unbound-1.4.16/validator/autotrust.c unbound-trunk/validator/autotrust.c ---- unbound-1.4.16/validator/autotrust.c 2012-01-19 09:17:22.000000000 -0500 -+++ unbound-trunk/validator/autotrust.c 2012-02-22 20:37:14.741368184 -0500 -@@ -996,6 +996,9 @@ - /* success; overwrite actual file */ - fclose(out); - verbose(VERB_ALGO, "autotrust: replaced %s", fname); -+#ifdef UB_ON_WINDOWS -+ (void)unlink(fname); /* windows does not replace file with rename() */ -+#endif - if(rename(tempf, fname) < 0) { - log_err("rename(%s to %s): %s", tempf, fname, strerror(errno)); - } -diff -Naur unbound-1.4.16/validator/val_anchor.c unbound-trunk/validator/val_anchor.c ---- unbound-1.4.16/validator/val_anchor.c 2011-11-10 13:44:06.000000000 -0500 -+++ unbound-trunk/validator/val_anchor.c 2012-02-22 20:37:14.741368184 -0500 -@@ -49,7 +49,6 @@ - #include "util/data/dname.h" - #include "util/log.h" - #include "util/net_help.h" --#include "util/regional.h" - #include "util/config_file.h" - #ifdef HAVE_GLOB_H - #include -@@ -77,11 +76,6 @@ - struct val_anchors* a = (struct val_anchors*)calloc(1, sizeof(*a)); - if(!a) - return NULL; -- a->region = regional_create(); -- if(!a->region) { -- free(a); -- return NULL; -- } - a->tree = rbtree_create(anchor_cmp); - if(!a->tree) { - anchors_delete(a); -@@ -98,15 +92,45 @@ - return a; - } - -+/** delete assembled rrset */ -+static void -+assembled_rrset_delete(struct ub_packed_rrset_key* pkey) -+{ -+ if(!pkey) return; -+ if(pkey->entry.data) { -+ struct packed_rrset_data* pd = (struct packed_rrset_data*) -+ pkey->entry.data; -+ free(pd->rr_data); -+ free(pd->rr_ttl); -+ free(pd->rr_len); -+ free(pd); -+ } -+ free(pkey->rk.dname); -+ free(pkey); -+} -+ - /** destroy locks in tree and delete autotrust anchors */ - static void - anchors_delfunc(rbnode_t* elem, void* ATTR_UNUSED(arg)) - { - struct trust_anchor* ta = (struct trust_anchor*)elem; -+ if(!ta) return; - if(ta->autr) { - autr_point_delete(ta); - } else { -+ struct ta_key* p, *np; - lock_basic_destroy(&ta->lock); -+ free(ta->name); -+ p = ta->keylist; -+ while(p) { -+ np = p->next; -+ free(p->data); -+ free(p); -+ p = np; -+ } -+ assembled_rrset_delete(ta->ds_rrset); -+ assembled_rrset_delete(ta->dnskey_rrset); -+ free(ta); - } - } - -@@ -118,9 +142,9 @@ - lock_unprotect(&anchors->lock, anchors->autr); - lock_unprotect(&anchors->lock, anchors); - lock_basic_destroy(&anchors->lock); -- traverse_postorder(anchors->tree, anchors_delfunc, NULL); -+ if(anchors->tree) -+ traverse_postorder(anchors->tree, anchors_delfunc, NULL); - free(anchors->tree); -- regional_destroy(anchors->region); - autr_global_delete(anchors->autr); - free(anchors); - } -@@ -193,30 +217,34 @@ - /** create new trust anchor object */ - static struct trust_anchor* - anchor_new_ta(struct val_anchors* anchors, uint8_t* name, int namelabs, -- size_t namelen, uint16_t dclass) -+ size_t namelen, uint16_t dclass, int lockit) - { - #ifdef UNBOUND_DEBUG - rbnode_t* r; - #endif -- struct trust_anchor* ta = (struct trust_anchor*)regional_alloc( -- anchors->region, sizeof(struct trust_anchor)); -+ struct trust_anchor* ta = (struct trust_anchor*)malloc( -+ sizeof(struct trust_anchor)); - if(!ta) - return NULL; - memset(ta, 0, sizeof(*ta)); - ta->node.key = ta; -- ta->name = regional_alloc_init(anchors->region, name, namelen); -- if(!ta->name) -+ ta->name = memdup(name, namelen); -+ if(!ta->name) { -+ free(ta); - return NULL; -+ } - ta->namelabs = namelabs; - ta->namelen = namelen; - ta->dclass = dclass; - lock_basic_init(&ta->lock); -- lock_basic_lock(&anchors->lock); -+ if(lockit) -+ lock_basic_lock(&anchors->lock); - #ifdef UNBOUND_DEBUG - r = - #endif - rbtree_insert(anchors->tree, &ta->node); -- lock_basic_unlock(&anchors->lock); -+ if(lockit) -+ lock_basic_unlock(&anchors->lock); - log_assert(r != NULL); - return ta; - } -@@ -237,17 +265,17 @@ - - /** create new trustanchor key */ - static struct ta_key* --anchor_new_ta_key(struct val_anchors* anchors, uint8_t* rdata, size_t rdata_len, -- uint16_t type) -+anchor_new_ta_key(uint8_t* rdata, size_t rdata_len, uint16_t type) - { -- struct ta_key* k = (struct ta_key*)regional_alloc(anchors->region, -- sizeof(*k)); -+ struct ta_key* k = (struct ta_key*)malloc(sizeof(*k)); - if(!k) - return NULL; - memset(k, 0, sizeof(*k)); -- k->data = regional_alloc_init(anchors->region, rdata, rdata_len); -- if(!k->data) -+ k->data = memdup(rdata, rdata_len); -+ if(!k->data) { -+ free(k); - return NULL; -+ } - k->len = rdata_len; - k->type = type; - return k; -@@ -282,7 +310,7 @@ - /* lookup or create trustanchor */ - ta = anchor_find(anchors, name, namelabs, namelen, dclass); - if(!ta) { -- ta = anchor_new_ta(anchors, name, namelabs, namelen, dclass); -+ ta = anchor_new_ta(anchors, name, namelabs, namelen, dclass, 1); - if(!ta) - return NULL; - lock_basic_lock(&ta->lock); -@@ -296,7 +324,7 @@ - lock_basic_unlock(&ta->lock); - return ta; - } -- k = anchor_new_ta_key(anchors, rdata, rdata_len, type); -+ k = anchor_new_ta_key(rdata, rdata_len, type); - if(!k) { - lock_basic_unlock(&ta->lock); - return NULL; -@@ -826,55 +854,73 @@ - - /** - * Assemble an rrset structure for the type -- * @param region: allocated in this region. - * @param ta: trust anchor. - * @param num: number of items to fetch from list. - * @param type: fetch only items of this type. - * @return rrset or NULL on error. - */ - static struct ub_packed_rrset_key* --assemble_it(struct regional* region, struct trust_anchor* ta, size_t num, -- uint16_t type) -+assemble_it(struct trust_anchor* ta, size_t num, uint16_t type) - { - struct ub_packed_rrset_key* pkey = (struct ub_packed_rrset_key*) -- regional_alloc(region, sizeof(*pkey)); -+ malloc(sizeof(*pkey)); - struct packed_rrset_data* pd; - struct ta_key* tk; - size_t i; - if(!pkey) - return NULL; - memset(pkey, 0, sizeof(*pkey)); -- pkey->rk.dname = regional_alloc_init(region, ta->name, ta->namelen); -- if(!pkey->rk.dname) -+ pkey->rk.dname = memdup(ta->name, ta->namelen); -+ if(!pkey->rk.dname) { -+ free(pkey); - return NULL; -- -+ } -+ - pkey->rk.dname_len = ta->namelen; - pkey->rk.type = htons(type); - pkey->rk.rrset_class = htons(ta->dclass); - /* The rrset is build in an uncompressed way. This means it - * cannot be copied in the normal way. */ -- pd = (struct packed_rrset_data*)regional_alloc(region, sizeof(*pd)); -- if(!pd) -+ pd = (struct packed_rrset_data*)malloc(sizeof(*pd)); -+ if(!pd) { -+ free(pkey->rk.dname); -+ free(pkey); - return NULL; -+ } - memset(pd, 0, sizeof(*pd)); - pd->count = num; - pd->trust = rrset_trust_ultimate; -- pd->rr_len = (size_t*)regional_alloc(region, num*sizeof(size_t)); -- if(!pd->rr_len) -- return NULL; -- pd->rr_ttl = (uint32_t*)regional_alloc(region, num*sizeof(uint32_t)); -- if(!pd->rr_ttl) -- return NULL; -- pd->rr_data = (uint8_t**)regional_alloc(region, num*sizeof(uint8_t*)); -- if(!pd->rr_data) -+ pd->rr_len = (size_t*)malloc(num*sizeof(size_t)); -+ if(!pd->rr_len) { -+ free(pd); -+ free(pkey->rk.dname); -+ free(pkey); -+ return NULL; -+ } -+ pd->rr_ttl = (uint32_t*)malloc(num*sizeof(uint32_t)); -+ if(!pd->rr_ttl) { -+ free(pd->rr_len); -+ free(pd); -+ free(pkey->rk.dname); -+ free(pkey); -+ return NULL; -+ } -+ pd->rr_data = (uint8_t**)malloc(num*sizeof(uint8_t*)); -+ if(!pd->rr_data) { -+ free(pd->rr_ttl); -+ free(pd->rr_len); -+ free(pd); -+ free(pkey->rk.dname); -+ free(pkey); - return NULL; -+ } - /* fill in rrs */ - i=0; - for(tk = ta->keylist; tk; tk = tk->next) { - if(tk->type != type) - continue; - pd->rr_len[i] = tk->len; -- /* reuse data ptr to allocation in region */ -+ /* reuse data ptr to allocation in talist */ - pd->rr_data[i] = tk->data; - pd->rr_ttl[i] = 0; - i++; -@@ -885,22 +931,20 @@ - - /** - * Assemble structures for the trust DS and DNSKEY rrsets. -- * @param anchors: trust anchor storage. - * @param ta: trust anchor - * @return: false on error. - */ - static int --anchors_assemble(struct val_anchors* anchors, struct trust_anchor* ta) -+anchors_assemble(struct trust_anchor* ta) - { - if(ta->numDS > 0) { -- ta->ds_rrset = assemble_it(anchors->region, ta, -- ta->numDS, LDNS_RR_TYPE_DS); -+ ta->ds_rrset = assemble_it(ta, ta->numDS, LDNS_RR_TYPE_DS); - if(!ta->ds_rrset) - return 0; - } - if(ta->numDNSKEY > 0) { -- ta->dnskey_rrset = assemble_it(anchors->region, ta, -- ta->numDNSKEY, LDNS_RR_TYPE_DNSKEY); -+ ta->dnskey_rrset = assemble_it(ta, ta->numDNSKEY, -+ LDNS_RR_TYPE_DNSKEY); - if(!ta->dnskey_rrset) - return 0; - } -@@ -961,7 +1005,7 @@ - ta = next; /* skip */ - continue; - } -- if(!anchors_assemble(anchors, ta)) { -+ if(!anchors_assemble(ta)) { - log_err("out of memory"); - lock_basic_unlock(&ta->lock); - lock_basic_unlock(&anchors->lock); -@@ -987,7 +1031,7 @@ - " upgrade unbound and openssl)", b); - (void)rbtree_delete(anchors->tree, &ta->node); - lock_basic_unlock(&ta->lock); -- lock_basic_destroy(&ta->lock); -+ anchors_delfunc(&ta->node, NULL); - ta = next; - continue; - } -@@ -1146,5 +1190,72 @@ - size_t - anchors_get_mem(struct val_anchors* anchors) - { -- return sizeof(*anchors) + regional_get_mem(anchors->region); -+ struct trust_anchor *ta; -+ size_t s = sizeof(*anchors); -+ RBTREE_FOR(ta, struct trust_anchor*, anchors->tree) { -+ s += sizeof(*ta) + ta->namelen; -+ /* keys and so on */ -+ } -+ return s; -+} -+ -+int -+anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm) -+{ -+ struct trust_anchor key; -+ key.node.key = &key; -+ key.name = nm; -+ key.namelabs = dname_count_size_labels(nm, &key.namelen); -+ key.dclass = c; -+ lock_basic_lock(&anchors->lock); -+ if(rbtree_search(anchors->tree, &key)) { -+ lock_basic_unlock(&anchors->lock); -+ /* nothing to do, already an anchor or insecure point */ -+ return 1; -+ } -+ if(!anchor_new_ta(anchors, nm, key.namelabs, key.namelen, c, 0)) { -+ log_err("out of memory"); -+ lock_basic_unlock(&anchors->lock); -+ return 0; -+ } -+ /* no other contents in new ta, because it is insecure point */ -+ anchors_init_parents_locked(anchors); -+ lock_basic_unlock(&anchors->lock); -+ return 1; -+} -+ -+void -+anchors_delete_insecure(struct val_anchors* anchors, uint16_t c, -+ uint8_t* nm) -+{ -+ struct trust_anchor key; -+ struct trust_anchor* ta; -+ key.node.key = &key; -+ key.name = nm; -+ key.namelabs = dname_count_size_labels(nm, &key.namelen); -+ key.dclass = c; -+ lock_basic_lock(&anchors->lock); -+ if(!(ta=(struct trust_anchor*)rbtree_search(anchors->tree, &key))) { -+ lock_basic_unlock(&anchors->lock); -+ /* nothing there */ -+ return; -+ } -+ /* lock it to drive away other threads that use it */ -+ lock_basic_lock(&ta->lock); -+ /* see if its really an insecure point */ -+ if(ta->keylist || ta->autr || ta->numDS || ta->numDNSKEY) { -+ lock_basic_unlock(&ta->lock); -+ /* its not an insecure point, do not remove it */ -+ return; -+ } -+ -+ /* remove from tree */ -+ (void)rbtree_delete(anchors->tree, &ta->node); -+ anchors_init_parents_locked(anchors); -+ lock_basic_unlock(&anchors->lock); -+ -+ /* actual free of data */ -+ lock_basic_unlock(&ta->lock); -+ anchors_delfunc(&ta->node, NULL); - } -+ -diff -Naur unbound-1.4.16/validator/val_anchor.h unbound-trunk/validator/val_anchor.h ---- unbound-1.4.16/validator/val_anchor.h 2010-07-07 09:13:36.000000000 -0400 -+++ unbound-trunk/validator/val_anchor.h 2012-02-22 20:37:14.743368184 -0500 -@@ -43,7 +43,6 @@ - #define VALIDATOR_VAL_ANCHOR_H - #include "util/rbtree.h" - #include "util/locks.h" --struct regional; - struct trust_anchor; - struct config_file; - struct ub_packed_rrset_key; -@@ -60,11 +59,6 @@ - struct val_anchors { - /** lock on trees */ - lock_basic_t lock; -- /** -- * region where trust anchors are allocated. -- * Autotrust anchors are malloced so they can be updated. -- */ -- struct regional* region; - /** - * Anchors are store in this tree. Sort order is chosen, so that - * dnames are in nsec-like order. A lookup on class, name will return -@@ -111,7 +105,6 @@ - struct trust_anchor* parent; - /** - * List of DS or DNSKEY rrs that form the trust anchor. -- * It is allocated in the region. - */ - struct ta_key* keylist; - /** Autotrust anchor point data, or NULL */ -@@ -203,4 +196,23 @@ - /** compare two trust anchors */ - int anchor_cmp(const void* k1, const void* k2); - -+/** -+ * Add insecure point trust anchor. For external use (locks and init_parents) -+ * @param anchors: anchor storage. -+ * @param c: class. -+ * @param nm: name of insecure trust point. -+ * @return false on alloc failure. -+ */ -+int anchors_add_insecure(struct val_anchors* anchors, uint16_t c, uint8_t* nm); -+ -+/** -+ * Delete insecure point trust anchor. Does not remove if no such point. -+ * For external use (locks and init_parents) -+ * @param anchors: anchor storage. -+ * @param c: class. -+ * @param nm: name of insecure trust point. -+ */ -+void anchors_delete_insecure(struct val_anchors* anchors, uint16_t c, -+ uint8_t* nm); -+ - #endif /* VALIDATOR_VAL_ANCHOR_H */ -diff -Naur unbound-1.4.16/validator/validator.c unbound-trunk/validator/validator.c ---- unbound-1.4.16/validator/validator.c 2012-01-10 04:42:32.000000000 -0500 -+++ unbound-trunk/validator/validator.c 2012-02-22 20:37:14.743368184 -0500 -@@ -1977,15 +1977,17 @@ - - /* store results in cache */ - if(qstate->query_flags&BIT_RD) { -+ /* if secure, this will override cache anyway, no need -+ * to check if from parentNS */ - if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, -- vq->orig_msg->rep, 0, qstate->prefetch_leeway, NULL)) { -+ vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, NULL)) { - log_err("out of memory caching validator results"); - } - } else { - /* for a referral, store the verified RRsets */ - /* and this does not get prefetched, so no leeway */ - if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, -- vq->orig_msg->rep, 1, 0, NULL)) { -+ vq->orig_msg->rep, 1, 0, 0, NULL)) { - log_err("out of memory caching validator results"); - } - } -@@ -2923,7 +2925,6 @@ - return 0; - return sizeof(*ve) + key_cache_get_mem(ve->kcache) + - val_neg_get_mem(ve->neg_cache) + -- anchors_get_mem(env->anchors) + - sizeof(size_t)*2*ve->nsec3_keyiter_count; - } - -diff -Naur unbound-1.4.16/validator/val_sigcrypt.c unbound-trunk/validator/val_sigcrypt.c ---- unbound-1.4.16/validator/val_sigcrypt.c 2012-01-17 04:06:18.000000000 -0500 -+++ unbound-trunk/validator/val_sigcrypt.c 2012-02-22 20:37:14.739368184 -0500 -@@ -280,6 +280,10 @@ - return 32; - else return 0; - #endif -+#ifdef USE_ECDSA -+ case LDNS_SHA384: -+ return SHA384_DIGEST_LENGTH; -+#endif - default: break; - } - return 0; -@@ -348,6 +352,12 @@ - ldns_buffer_limit(b), (unsigned char*)digest)) - return 1; - #endif -+#ifdef USE_ECDSA -+ case LDNS_SHA384: -+ (void)SHA384((unsigned char*)ldns_buffer_begin(b), -+ ldns_buffer_limit(b), (unsigned char*)digest); -+ return 1; -+#endif - default: - verbose(VERB_QUERY, "unknown DS digest algorithm %d", - (int) ds_get_digest_algo(ds_rrset, ds_idx)); -@@ -418,6 +428,10 @@ - #if defined(HAVE_EVP_SHA512) && defined(USE_SHA2) - case LDNS_RSASHA512: - #endif -+#ifdef USE_ECDSA -+ case LDNS_ECDSAP256SHA256: -+ case LDNS_ECDSAP384SHA384: -+#endif - return 1; - #ifdef USE_GOST - case LDNS_ECC_GOST: -@@ -1321,7 +1335,7 @@ - * Setup DSA key digest in DER encoding ... - * @param sig: input is signature output alloced ptr (unless failure). - * caller must free alloced ptr if this routine returns true. -- * @param len: intput is initial siglen, output is output len. -+ * @param len: input is initial siglen, output is output len. - * @return false on failure. - */ - static int -@@ -1350,6 +1364,7 @@ - *sig = NULL; - newlen = i2d_DSA_SIG(dsasig, sig); - if(newlen < 0) { -+ DSA_SIG_free(dsasig); - free(*sig); - return 0; - } -@@ -1358,6 +1373,48 @@ - return 1; - } - -+#ifdef USE_ECDSA -+/** -+ * Setup the ECDSA signature in its encoding that the library wants. -+ * Converts from plain numbers to ASN formatted. -+ * @param sig: input is signature, output alloced ptr (unless failure). -+ * caller must free alloced ptr if this routine returns true. -+ * @param len: input is initial siglen, output is output len. -+ * @return false on failure. -+ */ -+static int -+setup_ecdsa_sig(unsigned char** sig, unsigned int* len) -+{ -+ ECDSA_SIG* ecdsa_sig; -+ int newlen; -+ int bnsize = (int)((*len)/2); -+ /* if too short or not even length, fails */ -+ if(*len < 16 || bnsize*2 != (int)*len) -+ return 0; -+ /* use the raw data to parse two evenly long BIGNUMs, "r | s". */ -+ ecdsa_sig = ECDSA_SIG_new(); -+ if(!ecdsa_sig) return 0; -+ ecdsa_sig->r = BN_bin2bn(*sig, bnsize, ecdsa_sig->r); -+ ecdsa_sig->s = BN_bin2bn(*sig+bnsize, bnsize, ecdsa_sig->s); -+ if(!ecdsa_sig->r || !ecdsa_sig->s) { -+ ECDSA_SIG_free(ecdsa_sig); -+ return 0; -+ } -+ -+ /* spool it into ASN format */ -+ *sig = NULL; -+ newlen = i2d_ECDSA_SIG(ecdsa_sig, sig); -+ if(newlen <= 0) { -+ ECDSA_SIG_free(ecdsa_sig); -+ free(*sig); -+ return 0; -+ } -+ *len = (unsigned int)newlen; -+ ECDSA_SIG_free(ecdsa_sig); -+ return 1; -+} -+#endif /* USE_ECDSA */ -+ - /** - * Setup key and digest for verification. Adjust sig if necessary. - * -@@ -1472,6 +1529,62 @@ - } - break; - #endif -+#ifdef USE_ECDSA -+ case LDNS_ECDSAP256SHA256: -+ *evp_key = ldns_ecdsa2pkey_raw(key, keylen, -+ LDNS_ECDSAP256SHA256); -+ if(!*evp_key) { -+ verbose(VERB_QUERY, "verify: " -+ "ldns_ecdsa2pkey_raw failed"); -+ return 0; -+ } -+#ifdef USE_ECDSA_EVP_WORKAROUND -+ /* openssl before 1.0.0 fixes RSA with the SHA256 -+ * hash in EVP. We create one for ecdsa_sha256 */ -+ { -+ static int md_ecdsa_256_done = 0; -+ static EVP_MD md; -+ if(!md_ecdsa_256_done) { -+ EVP_MD m = *EVP_sha256(); -+ md_ecdsa_256_done = 1; -+ m.required_pkey_type[0] = (*evp_key)->type; -+ m.verify = (void*)ECDSA_verify; -+ md = m; -+ } -+ *digest_type = &md; -+ } -+#else -+ *digest_type = EVP_sha256(); -+#endif -+ break; -+ case LDNS_ECDSAP384SHA384: -+ *evp_key = ldns_ecdsa2pkey_raw(key, keylen, -+ LDNS_ECDSAP384SHA384); -+ if(!*evp_key) { -+ verbose(VERB_QUERY, "verify: " -+ "ldns_ecdsa2pkey_raw failed"); -+ return 0; -+ } -+#ifdef USE_ECDSA_EVP_WORKAROUND -+ /* openssl before 1.0.0 fixes RSA with the SHA384 -+ * hash in EVP. We create one for ecdsa_sha384 */ -+ { -+ static int md_ecdsa_384_done = 0; -+ static EVP_MD md; -+ if(!md_ecdsa_384_done) { -+ EVP_MD m = *EVP_sha384(); -+ md_ecdsa_384_done = 1; -+ m.required_pkey_type[0] = (*evp_key)->type; -+ m.verify = (void*)ECDSA_verify; -+ md = m; -+ } -+ *digest_type = &md; -+ } -+#else -+ *digest_type = EVP_sha384(); -+#endif -+ break; -+#endif /* USE_ECDSA */ - default: - verbose(VERB_QUERY, "verify: unknown algorithm %d", - algo); -@@ -1519,7 +1632,19 @@ - return sec_status_bogus; - } - dofree = 1; -- } -+ } -+#ifdef USE_ECDSA -+ else if(algo == LDNS_ECDSAP256SHA256 || algo == LDNS_ECDSAP384SHA384) { -+ /* EVP uses ASN prefix on sig, which is not in the wire data */ -+ if(!setup_ecdsa_sig(&sigblock, &sigblock_len)) { -+ verbose(VERB_QUERY, "verify: failed to setup ECDSA sig"); -+ *reason = "use of signature for ECDSA crypto failed"; -+ EVP_PKEY_free(evp_key); -+ return sec_status_bogus; -+ } -+ dofree = 1; -+ } -+#endif /* USE_ECDSA */ - - /* do the signature cryptography work */ - EVP_MD_CTX_init(&ctx); -@@ -1536,7 +1661,7 @@ - if(dofree) free(sigblock); - return sec_status_unchecked; - } -- -+ - res = EVP_VerifyFinal(&ctx, sigblock, sigblock_len, evp_key); - if(EVP_MD_CTX_cleanup(&ctx) == 0) { - verbose(VERB_QUERY, "verify: EVP_MD_CTX_cleanup failed");