diff options
| author | Doug Barton <dougb@FreeBSD.org> | 2006-12-10 07:09:56 +0000 |
|---|---|---|
| committer | Doug Barton <dougb@FreeBSD.org> | 2006-12-10 07:09:56 +0000 |
| commit | e99fbbb680307fe016c8db7d6611f1a3249761fb (patch) | |
| tree | d7fa0e61cadfdb3b3752a55401049f2294a7cfaf /contrib/bind9/lib/dns | |
| parent | a02f92e875d0d48c46103eef0fbea835048a278b (diff) | |
Notes
Diffstat (limited to 'contrib/bind9/lib/dns')
47 files changed, 1550 insertions, 506 deletions
diff --git a/contrib/bind9/lib/dns/Makefile.in b/contrib/bind9/lib/dns/Makefile.in index fbbec2eba8e7..9c368d19e662 100644 --- a/contrib/bind9/lib/dns/Makefile.in +++ b/contrib/bind9/lib/dns/Makefile.in @@ -1,4 +1,4 @@ -# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") # Copyright (C) 1998-2003 Internet Software Consortium. # # Permission to use, copy, modify, and distribute this software for any @@ -13,7 +13,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: Makefile.in,v 1.126.2.3.2.17 2004/12/09 04:07:15 marka Exp $ +# $Id: Makefile.in,v 1.126.2.3.2.19 2006/01/06 00:01:42 marka Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -156,7 +156,8 @@ code.h: gen ./gen -s ${srcdir} > code.h gen: gen.c - ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o $@ ${srcdir}/gen.c ${LIBS} + ${BUILD_CC} ${BUILD_CFLAGS} -I${top_srcdir}/lib/isc/include \ + ${BUILD_CPPFLAGS} ${BUILD_LDFLAGS} -o $@ ${srcdir}/gen.c ${BUILD_LIBS} rbtdb64.@O@: rbtdb.c diff --git a/contrib/bind9/lib/dns/acl.c b/contrib/bind9/lib/dns/acl.c index d2814405a720..e81d5ef33812 100644 --- a/contrib/bind9/lib/dns/acl.c +++ b/contrib/bind9/lib/dns/acl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: acl.c,v 1.23.52.4 2004/03/09 05:21:08 marka Exp $ */ +/* $Id: acl.c,v 1.23.52.6 2006/03/02 00:37:20 marka Exp $ */ #include <config.h> @@ -68,7 +68,7 @@ dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target) { } isc_result_t -dns_acl_appendelement(dns_acl_t *acl, dns_aclelement_t *elt) { +dns_acl_appendelement(dns_acl_t *acl, const dns_aclelement_t *elt) { if (acl->length + 1 > acl->alloc) { /* * Resize the ACL. @@ -123,12 +123,12 @@ dns_acl_none(isc_mem_t *mctx, dns_acl_t **target) { } isc_result_t -dns_acl_match(isc_netaddr_t *reqaddr, - dns_name_t *reqsigner, - dns_acl_t *acl, - dns_aclenv_t *env, +dns_acl_match(const isc_netaddr_t *reqaddr, + const dns_name_t *reqsigner, + const dns_acl_t *acl, + const dns_aclenv_t *env, int *match, - dns_aclelement_t **matchelt) + dns_aclelement_t const**matchelt) { unsigned int i; @@ -150,9 +150,9 @@ dns_acl_match(isc_netaddr_t *reqaddr, } isc_result_t -dns_acl_elementmatch(dns_acl_t *acl, - dns_aclelement_t *elt, - dns_aclelement_t **matchelt) +dns_acl_elementmatch(const dns_acl_t *acl, + const dns_aclelement_t *elt, + const dns_aclelement_t **matchelt) { unsigned int i; @@ -173,14 +173,14 @@ dns_acl_elementmatch(dns_acl_t *acl, } isc_boolean_t -dns_aclelement_match(isc_netaddr_t *reqaddr, - dns_name_t *reqsigner, - dns_aclelement_t *e, - dns_aclenv_t *env, - dns_aclelement_t **matchelt) +dns_aclelement_match(const isc_netaddr_t *reqaddr, + const dns_name_t *reqsigner, + const dns_aclelement_t *e, + const dns_aclenv_t *env, + const dns_aclelement_t **matchelt) { dns_acl_t *inner = NULL; - isc_netaddr_t *addr; + const isc_netaddr_t *addr; isc_netaddr_t v4addr; int indirectmatch; isc_result_t result; @@ -312,7 +312,7 @@ dns_acl_detach(dns_acl_t **aclp) { } isc_boolean_t -dns_aclelement_equal(dns_aclelement_t *ea, dns_aclelement_t *eb) { +dns_aclelement_equal(const dns_aclelement_t *ea, const dns_aclelement_t *eb) { if (ea->type != eb->type) return (ISC_FALSE); switch (ea->type) { @@ -338,7 +338,7 @@ dns_aclelement_equal(dns_aclelement_t *ea, dns_aclelement_t *eb) { } isc_boolean_t -dns_acl_equal(dns_acl_t *a, dns_acl_t *b) { +dns_acl_equal(const dns_acl_t *a, const dns_acl_t *b) { unsigned int i; if (a == b) return (ISC_TRUE); @@ -353,7 +353,7 @@ dns_acl_equal(dns_acl_t *a, dns_acl_t *b) { } static isc_boolean_t -is_loopback(dns_aclipprefix_t *p) { +is_loopback(const dns_aclipprefix_t *p) { switch (p->address.family) { case AF_INET: if (p->prefixlen == 32 && @@ -372,7 +372,7 @@ is_loopback(dns_aclipprefix_t *p) { } isc_boolean_t -dns_acl_isinsecure(dns_acl_t *a) { +dns_acl_isinsecure(const dns_acl_t *a) { unsigned int i; for (i = 0; i < a->length; i++) { dns_aclelement_t *e = &a->elements[i]; diff --git a/contrib/bind9/lib/dns/adb.c b/contrib/bind9/lib/dns/adb.c index c0b31db1129d..3fe436a2bbb4 100644 --- a/contrib/bind9/lib/dns/adb.c +++ b/contrib/bind9/lib/dns/adb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: adb.c,v 1.181.2.11.2.24 2005/10/14 05:19:00 marka Exp $ */ +/* $Id: adb.c,v 1.181.2.11.2.26 2006/01/04 23:50:20 marka Exp $ */ /* * Implementation notes @@ -2587,8 +2587,7 @@ dns_adb_createfind(dns_adb_t *adb, isc_task_t *task, isc_taskaction_t action, } } - if (bucket != DNS_ADB_INVALIDBUCKET) - UNLOCK(&adb->namelocks[bucket]); + UNLOCK(&adb->namelocks[bucket]); return (result); } diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api index 7df81573fd7f..1bc2b11a91bd 100644 --- a/contrib/bind9/lib/dns/api +++ b/contrib/bind9/lib/dns/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 21 -LIBREVISION = 1 +LIBINTERFACE = 22 +LIBREVISION = 7 LIBAGE = 0 diff --git a/contrib/bind9/lib/dns/cache.c b/contrib/bind9/lib/dns/cache.c index 0e17a957d17a..f45af90d08d3 100644 --- a/contrib/bind9/lib/dns/cache.c +++ b/contrib/bind9/lib/dns/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cache.c,v 1.45.2.4.8.9 2005/03/17 03:58:30 marka Exp $ */ +/* $Id: cache.c,v 1.45.2.4.8.15 2006/08/01 01:07:05 marka Exp $ */ #include <config.h> @@ -68,7 +68,6 @@ typedef enum { * Convenience macros for comprehensive assertion checking. */ #define CLEANER_IDLE(c) ((c)->state == cleaner_s_idle && \ - (c)->iterator == NULL && \ (c)->resched_event != NULL) #define CLEANER_BUSY(c) ((c)->state == cleaner_s_busy && \ (c)->iterator != NULL && \ @@ -101,6 +100,7 @@ struct cache_cleaner { clean in one increment */ cleaner_state_t state; /* Idle/Busy. */ isc_boolean_t overmem; /* The cache is in an overmem state. */ + isc_boolean_t replaceiterator; }; /* @@ -387,7 +387,7 @@ dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp) { } isc_result_t -dns_cache_setfilename(dns_cache_t *cache, char *filename) { +dns_cache_setfilename(dns_cache_t *cache, const char *filename) { char *newname; REQUIRE(VALID_CACHE(cache)); @@ -501,12 +501,18 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, cleaner->cache = cache; cleaner->iterator = NULL; cleaner->overmem = ISC_FALSE; + cleaner->replaceiterator = ISC_FALSE; cleaner->task = NULL; cleaner->cleaning_timer = NULL; cleaner->resched_event = NULL; cleaner->overmem_event = NULL; + result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE, + &cleaner->iterator); + if (result != ISC_R_SUCCESS) + goto cleanup; + if (taskmgr != NULL && timermgr != NULL) { result = isc_task_create(taskmgr, 1, &cleaner->task); if (result != ISC_R_SUCCESS) { @@ -575,6 +581,8 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, isc_timer_detach(&cleaner->cleaning_timer); if (cleaner->task != NULL) isc_task_detach(&cleaner->task); + if (cleaner->iterator != NULL) + dns_dbiterator_destroy(&cleaner->iterator); DESTROYLOCK(&cleaner->lock); fail: return (result); @@ -582,15 +590,17 @@ cache_cleaner_init(dns_cache_t *cache, isc_taskmgr_t *taskmgr, static void begin_cleaning(cache_cleaner_t *cleaner) { - isc_result_t result; + isc_result_t result = ISC_R_SUCCESS; REQUIRE(CLEANER_IDLE(cleaner)); /* - * Create an iterator and position it at the beginning of the cache. + * Create an iterator, if it does not already exist, and + * position it at the beginning of the cache. */ - result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE, - &cleaner->iterator); + if (cleaner->iterator == NULL) + result = dns_db_createiterator(cleaner->cache->db, ISC_FALSE, + &cleaner->iterator); if (result != ISC_R_SUCCESS) isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_CACHE, ISC_LOG_WARNING, @@ -600,20 +610,21 @@ begin_cleaning(cache_cleaner_t *cleaner) { dns_dbiterator_setcleanmode(cleaner->iterator, ISC_TRUE); result = dns_dbiterator_first(cleaner->iterator); } - if (result != ISC_R_SUCCESS) { /* * If the result is ISC_R_NOMORE, the database is empty, * so there is nothing to be cleaned. */ - if (result != ISC_R_NOMORE) + if (result != ISC_R_NOMORE && cleaner->iterator != NULL) { UNEXPECTED_ERROR(__FILE__, __LINE__, "cache cleaner: " "dns_dbiterator_first() failed: %s", dns_result_totext(result)); - - if (cleaner->iterator != NULL) dns_dbiterator_destroy(&cleaner->iterator); + } else if (cleaner->iterator != NULL) { + result = dns_dbiterator_pause(cleaner->iterator); + RUNTIME_CHECK(result == ISC_R_SUCCESS); + } } else { /* * Pause the iterator to free its lock. @@ -634,10 +645,14 @@ begin_cleaning(cache_cleaner_t *cleaner) { static void end_cleaning(cache_cleaner_t *cleaner, isc_event_t *event) { + isc_result_t result; + REQUIRE(CLEANER_BUSY(cleaner)); REQUIRE(event != NULL); - dns_dbiterator_destroy(&cleaner->iterator); + result = dns_dbiterator_pause(cleaner->iterator); + if (result != ISC_R_SUCCESS) + dns_dbiterator_destroy(&cleaner->iterator); dns_cache_setcleaninginterval(cleaner->cache, cleaner->cleaning_interval); @@ -735,6 +750,17 @@ incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { if (cleaner->state == cleaner_s_done) { cleaner->state = cleaner_s_busy; end_cleaning(cleaner, event); + LOCK(&cleaner->cache->lock); + LOCK(&cleaner->lock); + if (cleaner->replaceiterator) { + dns_dbiterator_destroy(&cleaner->iterator); + (void) dns_db_createiterator(cleaner->cache->db, + ISC_FALSE, + &cleaner->iterator); + cleaner->replaceiterator = ISC_FALSE; + } + UNLOCK(&cleaner->lock); + UNLOCK(&cleaner->cache->lock); return; } @@ -774,7 +800,7 @@ incremental_cleaning_action(isc_task_t *task, isc_event_t *event) { * Either the end was reached (ISC_R_NOMORE) or * some error was signaled. If the cache is still * overmem and no error was encountered, - * keep trying to clean it, otherwise stop cleanng. + * keep trying to clean it, otherwise stop cleaning. */ if (result != ISC_R_NOMORE) UNEXPECTED_ERROR(__FILE__, __LINE__, @@ -982,8 +1008,23 @@ dns_cache_flush(dns_cache_t *cache) { if (result != ISC_R_SUCCESS) return (result); + LOCK(&cache->lock); + LOCK(&cache->cleaner.lock); + if (cache->cleaner.state == cleaner_s_idle) { + if (cache->cleaner.iterator != NULL) + dns_dbiterator_destroy(&cache->cleaner.iterator); + (void) dns_db_createiterator(db, ISC_FALSE, + &cache->cleaner.iterator); + } else { + if (cache->cleaner.state == cleaner_s_busy) + cache->cleaner.state = cleaner_s_done; + cache->cleaner.replaceiterator = ISC_TRUE; + } dns_db_detach(&cache->db); cache->db = db; + UNLOCK(&cache->cleaner.lock); + UNLOCK(&cache->lock); + return (ISC_R_SUCCESS); } diff --git a/contrib/bind9/lib/dns/compress.c b/contrib/bind9/lib/dns/compress.c index e0fe8c276a13..212243686535 100644 --- a/contrib/bind9/lib/dns/compress.c +++ b/contrib/bind9/lib/dns/compress.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.c,v 1.50.206.2 2004/03/06 08:13:37 marka Exp $ */ +/* $Id: compress.c,v 1.50.206.4 2006/03/02 00:37:20 marka Exp $ */ #define DNS_NAME_USEINLINE 1 @@ -111,7 +111,7 @@ do { \ * If no match is found return ISC_FALSE. */ isc_boolean_t -dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, +dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, dns_name_t *prefix, isc_uint16_t *offset) { dns_name_t tname, nname; @@ -161,15 +161,15 @@ dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, } static inline unsigned int -name_length(dns_name_t *name) { +name_length(const dns_name_t *name) { isc_region_t r; dns_name_toregion(name, &r); return (r.length); } void -dns_compress_add(dns_compress_t *cctx, dns_name_t *name, dns_name_t *prefix, - isc_uint16_t offset) +dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, + const dns_name_t *prefix, isc_uint16_t offset) { dns_name_t tname; unsigned int start; diff --git a/contrib/bind9/lib/dns/dispatch.c b/contrib/bind9/lib/dns/dispatch.c index 8534fe15ad10..91ef2c5ee0aa 100644 --- a/contrib/bind9/lib/dns/dispatch.c +++ b/contrib/bind9/lib/dns/dispatch.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dispatch.c,v 1.101.2.6.2.10 2004/09/01 04:27:41 marka Exp $ */ +/* $Id: dispatch.c,v 1.101.2.6.2.13 2006/07/19 00:44:04 marka Exp $ */ #include <config.h> @@ -641,6 +641,50 @@ udp_recv(isc_task_t *task, isc_event_t *ev_in) { free_buffer(disp, ev->region.base, ev->region.length); goto unlock; } + + /* + * Now that we have the original dispatch the query was sent + * from check that the address and port the response was + * sent to make sense. + */ + if (disp != resp->disp) { + isc_sockaddr_t a1; + isc_sockaddr_t a2; + + /* + * Check that the socket types and ports match. + */ + if (disp->socktype != resp->disp->socktype || + isc_sockaddr_getport(&disp->local) != + isc_sockaddr_getport(&resp->disp->local)) { + free_buffer(disp, ev->region.base, ev->region.length); + goto unlock; + } + + /* + * If both dispatches are bound to an address then fail as + * the addresses can't be equal (enforced by the IP stack). + * + * Note under Linux a packet can be sent out via IPv4 socket + * and the response be received via a IPv6 socket. + * + * Requests sent out via IPv6 should always come back in + * via IPv6. + */ + if (isc_sockaddr_pf(&resp->disp->local) == PF_INET6 && + isc_sockaddr_pf(&disp->local) != PF_INET6) { + free_buffer(disp, ev->region.base, ev->region.length); + goto unlock; + } + isc_sockaddr_anyofpf(&a1, isc_sockaddr_pf(&resp->disp->local)); + isc_sockaddr_anyofpf(&a2, isc_sockaddr_pf(&disp->local)); + if (!isc_sockaddr_eqaddr(&a1, &resp->disp->local) && + !isc_sockaddr_eqaddr(&a2, &disp->local)) { + free_buffer(disp, ev->region.base, ev->region.length); + goto unlock; + } + } + queue_response = resp->item_out; rev = allocate_event(resp->disp); if (rev == NULL) { @@ -1687,6 +1731,11 @@ dns_dispatch_getudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, /* * mgr should be locked. */ + +#ifndef DNS_DISPATCH_HELD +#define DNS_DISPATCH_HELD 20U +#endif + static isc_result_t dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_taskmgr_t *taskmgr, @@ -1697,7 +1746,9 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, { isc_result_t result; dns_dispatch_t *disp; - isc_socket_t *sock; + isc_socket_t *sock = NULL; + isc_socket_t *held[DNS_DISPATCH_HELD]; + unsigned int i = 0, j = 0; /* * dispatch_allocate() checks mgr for us. @@ -1708,17 +1759,30 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, return (result); /* - * This assumes that the IP stack will *not* quickly reallocate - * the same port. If it does continually reallocate the same port - * then we need a mechanism to hold all the blacklisted sockets - * until we find a usable socket. + * Try to allocate a socket that is not on the blacklist. + * Hold up to DNS_DISPATCH_HELD sockets to prevent the OS + * from returning the same port to us too quickly. */ + memset(held, 0, sizeof(held)); getsocket: result = create_socket(sockmgr, localaddr, &sock); if (result != ISC_R_SUCCESS) goto deallocate_dispatch; if (isc_sockaddr_getport(localaddr) == 0 && blacklisted(mgr, sock)) { - isc_socket_detach(&sock); + if (held[i] != NULL) + isc_socket_detach(&held[i]); + held[i++] = sock; + sock = NULL; + if (i == DNS_DISPATCH_HELD) + i = 0; + if (j++ == 0xffffU) { + mgr_log(mgr, ISC_LOG_ERROR, "avoid-v%s-udp-ports: " + "unable to allocate a non-blacklisted port", + isc_sockaddr_pf(localaddr) == AF_INET ? + "4" : "6"); + result = ISC_R_FAILURE; + goto deallocate_dispatch; + } goto getsocket; } @@ -1755,7 +1819,7 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, *dispp = disp; - return (ISC_R_SUCCESS); + goto cleanheld; /* * Error returns. @@ -1766,7 +1830,10 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr, isc_socket_detach(&disp->socket); deallocate_dispatch: dispatch_free(&disp); - + cleanheld: + for (i = 0; i < DNS_DISPATCH_HELD; i++) + if (held[i] != NULL) + isc_socket_detach(&held[i]); return (result); } diff --git a/contrib/bind9/lib/dns/dnssec.c b/contrib/bind9/lib/dns/dnssec.c index 34ff3d3aceb6..91f7a99fe983 100644 --- a/contrib/bind9/lib/dns/dnssec.c +++ b/contrib/bind9/lib/dns/dnssec.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -16,7 +16,7 @@ */ /* - * $Id: dnssec.c,v 1.69.2.5.2.7 2004/06/11 00:30:54 marka Exp $ + * $Id: dnssec.c,v 1.69.2.5.2.9 2006/01/04 23:50:20 marka Exp $ */ @@ -330,8 +330,7 @@ cleanup_array: cleanup_context: dst_context_destroy(&ctx); cleanup_databuf: - if (databuf != NULL) - isc_buffer_free(&databuf); + isc_buffer_free(&databuf); cleanup_signature: isc_mem_put(mctx, sig.signature, sig.siglen); diff --git a/contrib/bind9/lib/dns/dst_api.c b/contrib/bind9/lib/dns/dst_api.c index 19f60a27e805..b7b03e6ef2de 100644 --- a/contrib/bind9/lib/dns/dst_api.c +++ b/contrib/bind9/lib/dns/dst_api.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -18,7 +18,7 @@ /* * Principal Author: Brian Wellington - * $Id: dst_api.c,v 1.1.4.1 2004/12/09 04:07:16 marka Exp $ + * $Id: dst_api.c,v 1.1.4.3 2006/01/04 23:50:20 marka Exp $ */ #include <config.h> @@ -1027,8 +1027,10 @@ write_public_key(const dst_key_t *key, int type, const char *directory) { } ret = dns_name_print(key->key_name, fp); - if (ret != ISC_R_SUCCESS) + if (ret != ISC_R_SUCCESS) { + fclose(fp); return (ret); + } fprintf(fp, " "); diff --git a/contrib/bind9/lib/dns/gen.c b/contrib/bind9/lib/dns/gen.c index 4a6cc0d796d5..1d83023259b6 100644 --- a/contrib/bind9/lib/dns/gen.c +++ b/contrib/bind9/lib/dns/gen.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,9 +15,14 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: gen.c,v 1.65.2.5.2.6 2004/03/15 01:02:54 marka Exp $ */ +/* $Id: gen.c,v 1.65.2.5.2.9 2006/10/02 06:31:26 marka Exp $ */ -#include <config.h> +#ifdef WIN32 +/* + * Silence compiler warnings about using strcpy and friends. + */ +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif #include <sys/types.h> diff --git a/contrib/bind9/lib/dns/include/dns/acl.h b/contrib/bind9/lib/dns/include/dns/acl.h index bc723f43bf99..ce4c8b6a8679 100644 --- a/contrib/bind9/lib/dns/include/dns/acl.h +++ b/contrib/bind9/lib/dns/include/dns/acl.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: acl.h,v 1.20.52.3 2004/03/08 09:04:34 marka Exp $ */ +/* $Id: acl.h,v 1.20.52.5 2006/03/02 00:37:20 marka Exp $ */ #ifndef DNS_ACL_H #define DNS_ACL_H 1 @@ -104,7 +104,7 @@ dns_acl_create(isc_mem_t *mctx, int n, dns_acl_t **target); */ isc_result_t -dns_acl_appendelement(dns_acl_t *acl, dns_aclelement_t *elt); +dns_acl_appendelement(dns_acl_t *acl, const dns_aclelement_t *elt); /* * Append an element to an existing ACL. */ @@ -128,13 +128,13 @@ void dns_acl_detach(dns_acl_t **aclp); isc_boolean_t -dns_aclelement_equal(dns_aclelement_t *ea, dns_aclelement_t *eb); +dns_aclelement_equal(const dns_aclelement_t *ea, const dns_aclelement_t *eb); isc_boolean_t -dns_acl_equal(dns_acl_t *a, dns_acl_t *b); +dns_acl_equal(const dns_acl_t *a, const dns_acl_t *b); isc_boolean_t -dns_acl_isinsecure(dns_acl_t *a); +dns_acl_isinsecure(const dns_acl_t *a); /* * Return ISC_TRUE iff the acl 'a' is considered insecure, that is, * if it contains IP addresses other than those of the local host. @@ -154,12 +154,12 @@ void dns_aclenv_destroy(dns_aclenv_t *env); isc_result_t -dns_acl_match(isc_netaddr_t *reqaddr, - dns_name_t *reqsigner, - dns_acl_t *acl, - dns_aclenv_t *env, +dns_acl_match(const isc_netaddr_t *reqaddr, + const dns_name_t *reqsigner, + const dns_acl_t *acl, + const dns_aclenv_t *env, int *match, - dns_aclelement_t **matchelt); + const dns_aclelement_t **matchelt); /* * General, low-level ACL matching. This is expected to * be useful even for weird stuff like the topology and sortlist statements. @@ -185,11 +185,11 @@ dns_acl_match(isc_netaddr_t *reqaddr, */ isc_boolean_t -dns_aclelement_match(isc_netaddr_t *reqaddr, - dns_name_t *reqsigner, - dns_aclelement_t *e, - dns_aclenv_t *env, - dns_aclelement_t **matchelt); +dns_aclelement_match(const isc_netaddr_t *reqaddr, + const dns_name_t *reqsigner, + const dns_aclelement_t *e, + const dns_aclenv_t *env, + const dns_aclelement_t **matchelt); /* * Like dns_acl_match, but matches against the single ACL element 'e' * rather than a complete list and returns ISC_TRUE iff it matched. @@ -200,9 +200,9 @@ dns_aclelement_match(isc_netaddr_t *reqaddr, */ isc_result_t -dns_acl_elementmatch(dns_acl_t *acl, - dns_aclelement_t *elt, - dns_aclelement_t **matchelt); +dns_acl_elementmatch(const dns_acl_t *acl, + const dns_aclelement_t *elt, + const dns_aclelement_t **matchelt); /* * Search for an ACL element in 'acl' which is exactly the same as 'elt'. * If there is one, and 'matchelt' is non NULL, then '*matchelt' will point diff --git a/contrib/bind9/lib/dns/include/dns/cache.h b/contrib/bind9/lib/dns/include/dns/cache.h index 79c53de8f010..4b775c9c14cb 100644 --- a/contrib/bind9/lib/dns/include/dns/cache.h +++ b/contrib/bind9/lib/dns/include/dns/cache.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: cache.h,v 1.17.12.3 2004/03/08 09:04:34 marka Exp $ */ +/* $Id: cache.h,v 1.17.12.5 2006/03/02 00:37:20 marka Exp $ */ #ifndef DNS_CACHE_H #define DNS_CACHE_H 1 @@ -151,7 +151,7 @@ dns_cache_attachdb(dns_cache_t *cache, dns_db_t **dbp); isc_result_t -dns_cache_setfilename(dns_cache_t *cahce, char *filename); +dns_cache_setfilename(dns_cache_t *cahce, const char *filename); /* * If 'filename' is non-NULL, make the cache persistent. * The cache's data will be stored in the given file. diff --git a/contrib/bind9/lib/dns/include/dns/compress.h b/contrib/bind9/lib/dns/include/dns/compress.h index 0f6451cc6bf9..042a4ea51a96 100644 --- a/contrib/bind9/lib/dns/include/dns/compress.h +++ b/contrib/bind9/lib/dns/include/dns/compress.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.h,v 1.29.2.2.8.1 2004/03/06 08:13:51 marka Exp $ */ +/* $Id: compress.h,v 1.29.2.2.8.3 2006/03/02 00:37:20 marka Exp $ */ #ifndef DNS_COMPRESS_H #define DNS_COMPRESS_H 1 @@ -136,7 +136,7 @@ dns_compress_getedns(dns_compress_t *cctx); */ isc_boolean_t -dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, +dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name, dns_name_t *prefix, isc_uint16_t *offset); /* * Finds longest possible match of 'name' in the global compression table. @@ -155,8 +155,8 @@ dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, */ void -dns_compress_add(dns_compress_t *cctx, dns_name_t *name, dns_name_t *prefix, - isc_uint16_t offset); +dns_compress_add(dns_compress_t *cctx, const dns_name_t *name, + const dns_name_t *prefix, isc_uint16_t offset); /* * Add compression pointers for 'name' to the compression table, * not replacing existing pointers. diff --git a/contrib/bind9/lib/dns/include/dns/keytable.h b/contrib/bind9/lib/dns/include/dns/keytable.h index a07c05201e34..f3a21a68b385 100644 --- a/contrib/bind9/lib/dns/include/dns/keytable.h +++ b/contrib/bind9/lib/dns/include/dns/keytable.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keytable.h,v 1.10.206.1 2004/03/06 08:13:56 marka Exp $ */ +/* $Id: keytable.h,v 1.10.206.3 2006/01/06 00:01:42 marka Exp $ */ #ifndef DNS_KEYTABLE_H #define DNS_KEYTABLE_H 1 @@ -137,7 +137,8 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, dns_keynode_t **keynodep); /* * Search for a key named 'name', matching 'algorithm' and 'tag' in - * 'keytable'. + * 'keytable'. This finds the first instance which matches. Use + * dns_keytable_findnextkeynode() to find other instances. * * Requires: * @@ -150,6 +151,7 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, * Returns: * * ISC_R_SUCCESS + * DNS_R_PARTIALMATCH the name existed in the keytable. * ISC_R_NOTFOUND * * Any other result indicates an error. @@ -160,7 +162,7 @@ dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, dns_keynode_t **nextnodep); /* * Search for the next key with the same properties as 'keynode' in - * 'keytable'. + * 'keytable' as found by dns_keytable_findkeynode(). * * Requires: * diff --git a/contrib/bind9/lib/dns/include/dns/message.h b/contrib/bind9/lib/dns/include/dns/message.h index c8273221460e..960c11aa12b3 100644 --- a/contrib/bind9/lib/dns/include/dns/message.h +++ b/contrib/bind9/lib/dns/include/dns/message.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.h,v 1.100.2.3.8.7 2004/03/08 02:08:00 marka Exp $ */ +/* $Id: message.h,v 1.100.2.3.8.10 2006/02/28 06:32:54 marka Exp $ */ #ifndef DNS_MESSAGE_H #define DNS_MESSAGE_H 1 @@ -236,7 +236,7 @@ struct dns_message { isc_region_t saved; dns_rdatasetorderfunc_t order; - void * order_arg; + const void * order_arg; }; /*** @@ -710,6 +710,27 @@ dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, * ISC_R_NOTFOUND -- the desired type does not exist. */ +isc_result_t +dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, + dns_rdatatype_t type, dns_rdatatype_t covers, + dns_rdataset_t **rdataset); +/*%< + * Search the name for the specified rdclass and type. If it is found, + * *rdataset is filled in with a pointer to that rdataset. + * + * Requires: + *\li if '**rdataset' is non-NULL, *rdataset needs to be NULL. + * + *\li 'type' be a valid type, and NOT dns_rdatatype_any. + * + *\li If 'type' is dns_rdatatype_rrsig, 'covers' must be a valid type. + * Otherwise it should be 0. + * + * Returns: + *\li #ISC_R_SUCCESS -- all is well. + *\li #ISC_R_NOTFOUND -- the desired type does not exist. + */ + void dns_message_movename(dns_message_t *msg, dns_name_t *name, dns_section_t fromsection, @@ -1260,7 +1281,7 @@ dns_message_getrawmessage(dns_message_t *msg); void dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, - void *order_arg); + const void *order_arg); /* * Define the order in which RR sets get rendered by * dns_message_rendersection() to be the ascending order diff --git a/contrib/bind9/lib/dns/include/dns/name.h b/contrib/bind9/lib/dns/include/dns/name.h index 5f6a3db9c191..ce9e1f153164 100644 --- a/contrib/bind9/lib/dns/include/dns/name.h +++ b/contrib/bind9/lib/dns/include/dns/name.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.h,v 1.95.2.3.2.12 2004/09/08 00:29:34 marka Exp $ */ +/* $Id: name.h,v 1.95.2.3.2.14 2006/03/02 00:37:20 marka Exp $ */ #ifndef DNS_NAME_H #define DNS_NAME_H 1 @@ -589,7 +589,7 @@ dns_name_getlabelsequence(const dns_name_t *source, unsigned int first, void -dns_name_clone(dns_name_t *source, dns_name_t *target); +dns_name_clone(const dns_name_t *source, dns_name_t *target); /* * Make 'target' refer to the same name as 'source'. * @@ -703,7 +703,8 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, */ isc_result_t -dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target); +dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, + isc_buffer_t *target); /* * Convert 'name' into wire format, compressing it as specified by the * compression context 'cctx', and storing the result in 'target'. @@ -983,7 +984,7 @@ dns_name_split(dns_name_t *name, unsigned int suffixlabels, */ isc_result_t -dns_name_dup(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target); +dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, dns_name_t *target); /* * Make 'target' a dynamically allocated copy of 'source'. * diff --git a/contrib/bind9/lib/dns/include/dns/peer.h b/contrib/bind9/lib/dns/include/dns/peer.h index 03f720af3548..90329646c7aa 100644 --- a/contrib/bind9/lib/dns/include/dns/peer.h +++ b/contrib/bind9/lib/dns/include/dns/peer.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: peer.h,v 1.16.2.1.10.3 2004/03/06 08:13:58 marka Exp $ */ +/* $Id: peer.h,v 1.16.2.1.10.5 2006/03/02 00:37:20 marka Exp $ */ #ifndef DNS_PEER_H #define DNS_PEER_H 1 @@ -167,7 +167,8 @@ isc_result_t dns_peer_setkey(dns_peer_t *peer, dns_name_t **keyval); isc_result_t -dns_peer_settransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source); +dns_peer_settransfersource(dns_peer_t *peer, + const isc_sockaddr_t *transfer_source); isc_result_t dns_peer_gettransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source); diff --git a/contrib/bind9/lib/dns/include/dns/rdataset.h b/contrib/bind9/lib/dns/include/dns/rdataset.h index d856784c3e88..12cfbdeacc7c 100644 --- a/contrib/bind9/lib/dns/include/dns/rdataset.h +++ b/contrib/bind9/lib/dns/include/dns/rdataset.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.h,v 1.41.2.5.2.8 2005/03/17 03:58:31 marka Exp $ */ +/* $Id: rdataset.h,v 1.41.2.5.2.10 2006/03/02 00:37:20 marka Exp $ */ #ifndef DNS_RDATASET_H #define DNS_RDATASET_H 1 @@ -365,11 +365,11 @@ dns_rdataset_towire(dns_rdataset_t *rdataset, isc_result_t dns_rdataset_towiresorted(dns_rdataset_t *rdataset, - dns_name_t *owner_name, + const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, - void *order_arg, + const void *order_arg, unsigned int options, unsigned int *countp); /* @@ -384,11 +384,11 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset, isc_result_t dns_rdataset_towirepartial(dns_rdataset_t *rdataset, - dns_name_t *owner_name, + const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, - void *order_arg, + const void *order_arg, unsigned int options, unsigned int *countp, void **state); diff --git a/contrib/bind9/lib/dns/include/dns/resolver.h b/contrib/bind9/lib/dns/include/dns/resolver.h index 0a6080d27a5e..8e3e63232bfe 100644 --- a/contrib/bind9/lib/dns/include/dns/resolver.h +++ b/contrib/bind9/lib/dns/include/dns/resolver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.h,v 1.34.12.7 2004/04/15 23:56:31 marka Exp $ */ +/* $Id: resolver.h,v 1.34.12.9 2006/02/01 23:48:51 marka Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -136,7 +136,7 @@ dns_resolver_create(dns_view_t *view, * * 'dispatchv6' is a valid dispatcher with an IPv6 UDP socket, or is NULL. * - * *resp != NULL && *resp == NULL. + * resp != NULL && *resp == NULL. * * Returns: * diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h index 2bad7ea02cca..27995deb279d 100644 --- a/contrib/bind9/lib/dns/include/dns/types.h +++ b/contrib/bind9/lib/dns/include/dns/types.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: types.h,v 1.103.12.7 2004/03/08 09:04:39 marka Exp $ */ +/* $Id: types.h,v 1.103.12.9 2006/03/02 00:37:20 marka Exp $ */ #ifndef DNS_TYPES_H #define DNS_TYPES_H 1 @@ -294,6 +294,6 @@ typedef void (*dns_updatecallback_t)(void *, isc_result_t, dns_message_t *); typedef int -(*dns_rdatasetorderfunc_t)(dns_rdata_t *rdata, void *arg); +(*dns_rdatasetorderfunc_t)(const dns_rdata_t *rdata, const void *arg); #endif /* DNS_TYPES_H */ diff --git a/contrib/bind9/lib/dns/include/dns/validator.h b/contrib/bind9/lib/dns/include/dns/validator.h index 24769f3c88a5..00e9ee32b75a 100644 --- a/contrib/bind9/lib/dns/include/dns/validator.h +++ b/contrib/bind9/lib/dns/include/dns/validator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.h,v 1.18.12.9 2005/09/06 02:12:41 marka Exp $ */ +/* $Id: validator.h,v 1.18.12.11 2006/01/06 00:01:42 marka Exp $ */ #ifndef DNS_VALIDATOR_H #define DNS_VALIDATOR_H 1 @@ -24,27 +24,35 @@ ***** Module Info *****/ -/* +/*! \file + * + * \brief * DNS Validator + * This is the BIND 9 validator, the module responsible for validating the + * rdatasets and negative responses (messages). It makes use of zones in + * the view and may fetch RRset to complete trust chains. It implements + * DNSSEC as specified in RFC 4033, 4034 and 4035. * - * XXX <TBS> XXX + * It can also optionally implement ISC's DNSSEC look-aside validation. + * + * Correct operation is critical to preventing spoofed answers from secure + * zones being accepted. * * MP: - * The module ensures appropriate synchronization of data structures it + *\li The module ensures appropriate synchronization of data structures it * creates and manipulates. * * Reliability: - * No anticipated impact. + *\li No anticipated impact. * * Resources: - * <TBS> + *\li TBS * * Security: - * No anticipated impact. + *\li No anticipated impact. * * Standards: - * RFCs: 1034, 1035, 2181, 2535, <TBS> - * Drafts: <TBS> + *\li RFCs: 1034, 1035, 2181, 4033, 4034, 4035. */ #include <isc/lang.h> @@ -58,12 +66,16 @@ #include <dst/dst.h> -/* +/*% * A dns_validatorevent_t is sent when a 'validation' completes. - * + * \brief * 'name', 'rdataset', 'sigrdataset', and 'message' are the values that were * supplied when dns_validator_create() was called. They are returned to the * caller so that they may be freed. + * + * If the RESULT is ISC_R_SUCCESS and the answer is secure then + * proofs[] will contain the the names of the NSEC records that hold the + * various proofs. Note the same name may appear multiple times. */ typedef struct dns_validatorevent { ISC_EVENT_COMMON(struct dns_validatorevent); @@ -81,9 +93,9 @@ typedef struct dns_validatorevent { #define DNS_VALIDATOR_NODATAPROOF 1 #define DNS_VALIDATOR_NOWILDCARDPROOF 2 -/* - * A validator object represents a validation in procgress. - * +/*% + * A validator object represents a validation in progress. + * \brief * Clients are strongly discouraged from using this type directly, with * the exception of the 'link' field, which may be used directly for * whatever purpose the client desires. @@ -128,7 +140,10 @@ struct dns_validator { unsigned int depth; }; -#define DNS_VALIDATOR_DLV 1 +/*% + * dns_validator_create() options. + */ +#define DNS_VALIDATOR_DLV 1U ISC_LANG_BEGINDECLS @@ -138,7 +153,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, dns_message_t *message, unsigned int options, isc_task_t *task, isc_taskaction_t action, void *arg, dns_validator_t **validatorp); -/* +/*%< * Start a DNSSEC validation. * * This validates a response to the question given by @@ -163,41 +178,45 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, * arguments must be provided. * * The validation is performed in the context of 'view'. - * 'options' must be zero. * * When the validation finishes, a dns_validatorevent_t with * the given 'action' and 'arg' are sent to 'task'. * Its 'result' field will be ISC_R_SUCCESS iff the * response was successfully proven to be either secure or * part of a known insecure domain. + * + * options: + * If DNS_VALIDATOR_DLV is set the caller knows there is not a + * trusted key and the validator should immediately attempt to validate + * the answer by looking for a appopriate DLV RRset. */ void dns_validator_cancel(dns_validator_t *validator); -/* +/*%< * Cancel a DNSSEC validation in progress. * * Requires: - * 'validator' points to a valid DNSSEC validator, which + *\li 'validator' points to a valid DNSSEC validator, which * may or may not already have completed. * * Ensures: - * It the validator has not already sent its completion + *\li It the validator has not already sent its completion * event, it will send it with result code ISC_R_CANCELED. */ void dns_validator_destroy(dns_validator_t **validatorp); -/* +/*%< * Destroy a DNSSEC validator. * * Requires: - * '*validatorp' points to a valid DNSSEC validator. - * The validator must have completed and sent its completion + *\li '*validatorp' points to a valid DNSSEC validator. + * \li The validator must have completed and sent its completion * event. * * Ensures: - * All resources used by the validator are freed. + *\li All resources used by the validator are freed. */ ISC_LANG_ENDDECLS diff --git a/contrib/bind9/lib/dns/include/dns/xfrin.h b/contrib/bind9/lib/dns/include/dns/xfrin.h index 0050238f94a1..0f5e086b2105 100644 --- a/contrib/bind9/lib/dns/include/dns/xfrin.h +++ b/contrib/bind9/lib/dns/include/dns/xfrin.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.h,v 1.18.136.2 2004/03/06 08:14:01 marka Exp $ */ +/* $Id: xfrin.h,v 1.18.136.4 2006/07/20 01:10:29 marka Exp $ */ #ifndef DNS_XFRIN_H #define DNS_XFRIN_H 1 @@ -75,10 +75,12 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, * code as arguments when the transfer finishes. * * Requires: - * 'xfrtype' is dns_rdatatype_axfr or dns_rdatatype_ixfr. + * 'xfrtype' is dns_rdatatype_axfr, dns_rdatatype_ixfr + * or dns_rdatatype_soa (soa query followed by axfr if + * serial is greater than current serial). * - * If 'xfrtype' is dns_rdatatype_ixfr, the zone has a - * database. + * If 'xfrtype' is dns_rdatatype_ixfr or dns_rdatatype_soa, + * the zone has a database. */ void diff --git a/contrib/bind9/lib/dns/include/dns/zone.h b/contrib/bind9/lib/dns/include/dns/zone.h index b7680fa27741..4baf36ab360a 100644 --- a/contrib/bind9/lib/dns/include/dns/zone.h +++ b/contrib/bind9/lib/dns/include/dns/zone.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.106.2.7.4.15 2004/10/26 02:08:43 marka Exp $ */ +/* $Id: zone.h,v 1.106.2.7.4.18 2006/08/01 03:44:00 marka Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -163,7 +163,7 @@ dns_zone_getview(dns_zone_t *zone); */ isc_result_t -dns_zone_setorigin(dns_zone_t *zone, dns_name_t *origin); +dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin); /* * Sets the zones origin to 'origin'. * @@ -414,11 +414,13 @@ dns_zone_maintenance(dns_zone_t *zone); */ isc_result_t -dns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, +dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, isc_uint32_t count); isc_result_t -dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, - dns_name_t **keynames, isc_uint32_t count); +dns_zone_setmasterswithkeys(dns_zone_t *zone, + const isc_sockaddr_t *masters, + dns_name_t **keynames, + isc_uint32_t count); /* * Set the list of master servers for the zone. * @@ -440,7 +442,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, */ isc_result_t -dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *notify, +dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, isc_uint32_t count); /* * Set the list of additional servers to be notified when @@ -525,9 +527,10 @@ dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val); */ isc_result_t -dns_zone_setxfrsource4(dns_zone_t *zone, isc_sockaddr_t *xfrsource); +dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); isc_result_t -dns_zone_setaltxfrsource4(dns_zone_t *zone, isc_sockaddr_t *xfrsource); +dns_zone_setaltxfrsource4(dns_zone_t *zone, + const isc_sockaddr_t *xfrsource); /* * Set the source address to be used in IPv4 zone transfers. * @@ -552,9 +555,10 @@ dns_zone_getaltxfrsource4(dns_zone_t *zone); */ isc_result_t -dns_zone_setxfrsource6(dns_zone_t *zone, isc_sockaddr_t *xfrsource); +dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource); isc_result_t -dns_zone_setaltxfrsource6(dns_zone_t *zone, isc_sockaddr_t *xfrsource); +dns_zone_setaltxfrsource6(dns_zone_t *zone, + const isc_sockaddr_t *xfrsource); /* * Set the source address to be used in IPv6 zone transfers. * @@ -579,7 +583,7 @@ dns_zone_getaltxfrsource6(dns_zone_t *zone); */ isc_result_t -dns_zone_setnotifysrc4(dns_zone_t *zone, isc_sockaddr_t *notifysrc); +dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); /* * Set the source address to be used with IPv4 NOTIFY messages. * @@ -602,7 +606,7 @@ dns_zone_getnotifysrc4(dns_zone_t *zone); */ isc_result_t -dns_zone_setnotifysrc6(dns_zone_t *zone, isc_sockaddr_t *notifysrc); +dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc); /* * Set the source address to be used with IPv6 NOTIFY messages. * @@ -1252,7 +1256,7 @@ dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone); void dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value); /* - * Set the maximum number of simultanious transfers in allowed by + * Set the maximum number of simultaneous transfers in allowed by * the zone manager. * * Requires: @@ -1262,7 +1266,7 @@ dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value); isc_uint32_t dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr); /* - * Return the the maximum number of simultanious transfers in allowed. + * Return the the maximum number of simultaneous transfers in allowed. * * Requires: * 'zmgr' to be a valid zone manager. diff --git a/contrib/bind9/lib/dns/keytable.c b/contrib/bind9/lib/dns/keytable.c index 922c09af118a..7f3e3cff2bc6 100644 --- a/contrib/bind9/lib/dns/keytable.c +++ b/contrib/bind9/lib/dns/keytable.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: keytable.c,v 1.26.12.3 2004/03/08 09:04:30 marka Exp $ */ +/* $Id: keytable.c,v 1.26.12.5 2006/01/06 00:01:42 marka Exp $ */ #include <config.h> @@ -244,6 +244,13 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, RWLOCK(&keytable->rwlock, isc_rwlocktype_read); + /* + * Note we don't want the DNS_R_PARTIALMATCH from dns_rbt_findname() + * as that indicates that 'name' was not found. + * + * DNS_R_PARTIALMATCH indicates that the name was found but we + * didn't get a match on algorithm and key id arguments. + */ knode = NULL; data = NULL; result = dns_rbt_findname(keytable->table, name, 0, NULL, &data); @@ -261,7 +268,7 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, dns_name_t *name, UNLOCK(&keytable->lock); *keynodep = knode; } else - result = ISC_R_NOTFOUND; + result = DNS_R_PARTIALMATCH; } else if (result == DNS_R_PARTIALMATCH) result = ISC_R_NOTFOUND; diff --git a/contrib/bind9/lib/dns/lookup.c b/contrib/bind9/lib/dns/lookup.c index e593c7be7fe4..1cf572145dbb 100644 --- a/contrib/bind9/lib/dns/lookup.c +++ b/contrib/bind9/lib/dns/lookup.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: lookup.c,v 1.9.12.5 2004/04/15 02:10:40 marka Exp $ */ +/* $Id: lookup.c,v 1.9.12.7 2006/01/04 23:50:20 marka Exp $ */ #include <config.h> @@ -154,11 +154,6 @@ build_event(dns_lookup_t *lookup) { dns_rdataset_disassociate(rdataset); isc_mem_put(lookup->mctx, rdataset, sizeof(dns_rdataset_t)); } - if (sigrdataset != NULL) { - if (dns_rdataset_isassociated(sigrdataset)) - dns_rdataset_disassociate(sigrdataset); - isc_mem_put(lookup->mctx, sigrdataset, sizeof(dns_rdataset_t)); - } return (result); } @@ -229,13 +224,14 @@ lookup_find(dns_lookup_t *lookup, dns_fetchevent_t *event) { send_event = ISC_TRUE; goto done; } - } else { + } else if (event != NULL) { result = event->result; fname = dns_fixedname_name(&event->foundname); dns_resolver_destroyfetch(&lookup->fetch); INSIST(event->rdataset == &lookup->rdataset); INSIST(event->sigrdataset == &lookup->sigrdataset); - } + } else + fname = NULL; /* Silence compiler warning. */ /* * If we've been canceled, forget about the result. diff --git a/contrib/bind9/lib/dns/masterdump.c b/contrib/bind9/lib/dns/masterdump.c index 0225d7243f88..0f4716d583d9 100644 --- a/contrib/bind9/lib/dns/masterdump.c +++ b/contrib/bind9/lib/dns/masterdump.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.c,v 1.56.2.5.2.12 2004/08/28 06:25:19 marka Exp $ */ +/* $Id: masterdump.c,v 1.56.2.5.2.15 2006/03/10 00:17:21 marka Exp $ */ #include <config.h> @@ -1160,7 +1160,8 @@ dumptostreaminc(dns_dumpctx_t *dctx) { } if (dctx->nodes != 0 && result == ISC_R_SUCCESS) { - dns_dbiterator_pause(dctx->dbiter); + result = dns_dbiterator_pause(dctx->dbiter); + RUNTIME_CHECK(result == ISC_R_SUCCESS); result = DNS_R_CONTINUE; } else if (result == ISC_R_NOMORE) result = ISC_R_SUCCESS; @@ -1197,9 +1198,8 @@ dns_master_dumptostreaminc(isc_mem_t *mctx, dns_db_t *db, dns_dumpctx_attach(dctx, dctxp); return (DNS_R_CONTINUE); } - if (dctx != NULL) - dns_dumpctx_detach(&dctx); + dns_dumpctx_detach(&dctx); return (result); } diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c index d4b2e1962f99..33875433f6aa 100644 --- a/contrib/bind9/lib/dns/message.c +++ b/contrib/bind9/lib/dns/message.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.c,v 1.194.2.10.2.20 2005/06/07 01:42:23 marka Exp $ */ +/* $Id: message.c,v 1.194.2.10.2.24 2006/02/28 06:32:54 marka Exp $ */ /*** *** Imports @@ -801,11 +801,37 @@ findname(dns_name_t **foundname, dns_name_t *target, } isc_result_t +dns_message_find(dns_name_t *name, dns_rdataclass_t rdclass, + dns_rdatatype_t type, dns_rdatatype_t covers, + dns_rdataset_t **rdataset) +{ + dns_rdataset_t *curr; + + if (rdataset != NULL) { + REQUIRE(*rdataset == NULL); + } + + for (curr = ISC_LIST_TAIL(name->list); + curr != NULL; + curr = ISC_LIST_PREV(curr, link)) { + if (curr->rdclass == rdclass && + curr->type == type && curr->covers == covers) { + if (rdataset != NULL) + *rdataset = curr; + return (ISC_R_SUCCESS); + } + } + + return (ISC_R_NOTFOUND); +} + +isc_result_t dns_message_findtype(dns_name_t *name, dns_rdatatype_t type, dns_rdatatype_t covers, dns_rdataset_t **rdataset) { dns_rdataset_t *curr; + REQUIRE(name != NULL); if (rdataset != NULL) { REQUIRE(*rdataset == NULL); } @@ -1030,7 +1056,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, /* * Can't ask the same question twice. */ - result = dns_message_findtype(name, rdtype, 0, NULL); + result = dns_message_find(name, rdclass, rdtype, 0, NULL); if (result == ISC_R_SUCCESS) DO_FORMERR; @@ -1190,6 +1216,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, && rdtype != dns_rdatatype_dnskey /* in a TKEY query */ && rdtype != dns_rdatatype_sig /* SIG(0) */ && rdtype != dns_rdatatype_tkey /* Win2000 TKEY */ + && msg->rdclass != dns_rdataclass_any && msg->rdclass != rdclass) DO_FORMERR; @@ -1279,12 +1306,9 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, rdata->type = rdtype; rdata->flags = DNS_RDATA_UPDATE; result = ISC_R_SUCCESS; - } else if (rdtype == dns_rdatatype_tsig) + } else result = getrdata(source, msg, dctx, rdclass, rdtype, rdatalen, rdata); - else - result = getrdata(source, msg, dctx, msg->rdclass, - rdtype, rdatalen, rdata); if (result != ISC_R_SUCCESS) goto cleanup; rdata->rdclass = rdclass; @@ -1360,8 +1384,8 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx, DO_FORMERR; rdataset = NULL; - result = dns_message_findtype(name, rdtype, covers, - &rdataset); + result = dns_message_find(name, rdclass, rdtype, + covers, &rdataset); } /* @@ -1799,7 +1823,7 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, if (rdataset != NULL && (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 && (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) { - void *order_arg = msg->order_arg; + const void *order_arg = msg->order_arg; st = *(msg->buffer); count = 0; if (partial) @@ -3187,7 +3211,7 @@ dns_message_getrawmessage(dns_message_t *msg) { void dns_message_setsortorder(dns_message_t *msg, dns_rdatasetorderfunc_t order, - void *order_arg) + const void *order_arg) { REQUIRE(DNS_MESSAGE_VALID(msg)); msg->order = order; diff --git a/contrib/bind9/lib/dns/name.c b/contrib/bind9/lib/dns/name.c index 116a56a81867..1a257de8e133 100644 --- a/contrib/bind9/lib/dns/name.c +++ b/contrib/bind9/lib/dns/name.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.127.2.7.2.14 2005/10/14 01:38:48 marka Exp $ */ +/* $Id: name.c,v 1.127.2.7.2.16 2006/03/02 00:37:20 marka Exp $ */ #include <config.h> @@ -856,7 +856,7 @@ dns_name_getlabelsequence(const dns_name_t *source, } void -dns_name_clone(dns_name_t *source, dns_name_t *target) { +dns_name_clone(const dns_name_t *source, dns_name_t *target) { /* * Make 'target' refer to the same name as 'source'. @@ -1748,7 +1748,9 @@ dns_name_fromwire(dns_name_t *name, isc_buffer_t *source, } isc_result_t -dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) { +dns_name_towire(const dns_name_t *name, dns_compress_t *cctx, + isc_buffer_t *target) +{ unsigned int methods; isc_uint16_t offset; dns_name_t gp; /* Global compression prefix */ @@ -1962,7 +1964,9 @@ dns_name_split(dns_name_t *name, unsigned int suffixlabels, } isc_result_t -dns_name_dup(dns_name_t *source, isc_mem_t *mctx, dns_name_t *target) { +dns_name_dup(const dns_name_t *source, isc_mem_t *mctx, + dns_name_t *target) +{ /* * Make 'target' a dynamically allocated copy of 'source'. */ diff --git a/contrib/bind9/lib/dns/openssl_link.c b/contrib/bind9/lib/dns/openssl_link.c index 62eac05f30a0..525905c18828 100644 --- a/contrib/bind9/lib/dns/openssl_link.c +++ b/contrib/bind9/lib/dns/openssl_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2003 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -18,7 +18,7 @@ /* * Principal Author: Brian Wellington - * $Id: openssl_link.c,v 1.1.4.1 2004/12/09 04:07:18 marka Exp $ + * $Id: openssl_link.c,v 1.1.4.3 2006/05/23 23:51:03 marka Exp $ */ #ifdef OPENSSL @@ -39,7 +39,7 @@ #include <openssl/rand.h> #include <openssl/crypto.h> -#if defined(CRYPTO_LOCK_ENGINE) && (OPENSSL_VERSION_NUMBER < 0x00907000L) +#if defined(CRYPTO_LOCK_ENGINE) && (OPENSSL_VERSION_NUMBER != 0x00907000L) #define USE_ENGINE 1 #endif @@ -160,7 +160,7 @@ dst__openssl_init() { goto cleanup_rm; } ENGINE_set_RAND(e, rm); - RAND_set_rand_method(e); + RAND_set_rand_method(rm); #else RAND_set_rand_method(rm); #endif diff --git a/contrib/bind9/lib/dns/openssldh_link.c b/contrib/bind9/lib/dns/openssldh_link.c index 24255834d780..74ba39af3612 100644 --- a/contrib/bind9/lib/dns/openssldh_link.c +++ b/contrib/bind9/lib/dns/openssldh_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -18,7 +18,7 @@ /* * Principal Author: Brian Wellington - * $Id: openssldh_link.c,v 1.1.4.1 2004/12/09 04:07:18 marka Exp $ + * $Id: openssldh_link.c,v 1.1.4.3 2006/03/02 00:37:20 marka Exp $ */ #ifdef OPENSSL @@ -138,6 +138,79 @@ openssldh_paramcompare(const dst_key_t *key1, const dst_key_t *key2) { return (ISC_TRUE); } +#ifndef HAVE_DH_GENERATE_PARAMETERS +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +static DH * +DH_generate_parameters(int prime_len, int generator, + void (*callback)(int,int,void *), void *cb_arg) +{ + BN_GENCB cb; + DH *dh = NULL; + + dh = DH_new(); + if (dh != NULL) { + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DH_generate_parameters_ex(dh, prime_len, generator, &cb)) + return (dh); + DH_free(dh); + } + return (NULL); +} +#endif + static isc_result_t openssldh_generate(dst_key_t *key, int generator) { DH *dh = NULL; diff --git a/contrib/bind9/lib/dns/openssldsa_link.c b/contrib/bind9/lib/dns/openssldsa_link.c index ac84a6565be4..267bfe8d1398 100644 --- a/contrib/bind9/lib/dns/openssldsa_link.c +++ b/contrib/bind9/lib/dns/openssldsa_link.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2002 Internet Software Consortium. * Portions Copyright (C) 1995-2000 by Network Associates, Inc. * @@ -16,7 +16,7 @@ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: openssldsa_link.c,v 1.1.4.1 2004/12/09 04:07:18 marka Exp $ */ +/* $Id: openssldsa_link.c,v 1.1.4.3 2006/03/02 00:37:20 marka Exp $ */ #ifdef OPENSSL @@ -169,6 +169,83 @@ openssldsa_compare(const dst_key_t *key1, const dst_key_t *key2) { return (ISC_TRUE); } +#ifndef HAVE_DSA_GENERATE_PARAMETERS +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +static DSA * +DSA_generate_parameters(int bits, unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, + void (*callback)(int, int, void *), + void *cb_arg) +{ + BN_GENCB cb; + DSA *dsa; + + dsa = DSA_new(); + if (dsa != NULL) { + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DSA_generate_parameters_ex(dsa, bits, seed_in, seed_len, + counter_ret, h_ret, &cb)) + return (dsa); + DSA_free(dsa); + } + return (NULL); +} +#endif + static isc_result_t openssldsa_generate(dst_key_t *key, int unused) { DSA *dsa; diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c index f5530971dff1..c33913ce3d07 100644 --- a/contrib/bind9/lib/dns/opensslrsa_link.c +++ b/contrib/bind9/lib/dns/opensslrsa_link.c @@ -17,7 +17,7 @@ /* * Principal Author: Brian Wellington - * $Id: opensslrsa_link.c,v 1.1.4.1.10.5 2006/10/11 03:58:50 marka Exp $ + * $Id: opensslrsa_link.c,v 1.1.4.9 2006/11/07 21:28:40 marka Exp $ */ #ifdef OPENSSL @@ -49,7 +49,7 @@ */ #ifdef WIN32 #if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \ - OPENSSL_VERSION_NUMBER < 0x009080000L) || \ + OPENSSL_VERSION_NUMBER < 0x00908000L) || \ OPENSSL_VERSION_NUMBER >= 0x0090804fL) #error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater. #endif @@ -84,6 +84,12 @@ (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \ (rsa)->flags &= ~RSA_FLAG_BLINDING; \ } while (0) +#elif defined(RSA_FLAG_NO_BLINDING) +#define SET_FLAGS(rsa) \ + do { \ + (rsa)->flags &= ~RSA_FLAG_BLINDING; \ + (rsa)->flags |= RSA_FLAG_NO_BLINDING; \ + } while (0) #else #define SET_FLAGS(rsa) \ do { \ @@ -103,12 +109,16 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) { isc_md5_t *md5ctx; md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t)); + if (md5ctx == NULL) + return (ISC_R_NOMEMORY); isc_md5_init(md5ctx); dctx->opaque = md5ctx; } else { isc_sha1_t *sha1ctx; sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t)); + if (sha1ctx == NULL) + return (ISC_R_NOMEMORY); isc_sha1_init(sha1ctx); dctx->opaque = sha1ctx; } @@ -288,7 +298,7 @@ opensslrsa_generate(dst_key_t *key, int exp) { /* RSA_F4 0x10001 */ BN_set_bit(e, 0); BN_set_bit(e, 16); - } else { + } else { /* F5 0x100000001 */ BN_set_bit(e, 0); BN_set_bit(e, 32); @@ -303,7 +313,7 @@ opensslrsa_generate(dst_key_t *key, int exp) { return (ISC_R_SUCCESS); } - err: +err: if (e != NULL) BN_free(e); if (rsa != NULL) @@ -314,12 +324,12 @@ opensslrsa_generate(dst_key_t *key, int exp) { unsigned long e; if (exp == 0) - e = RSA_F4; + e = RSA_F4; else - e = 0x40000003; + e = 0x40000003; rsa = RSA_generate_key(key->key_size, e, NULL, NULL); if (rsa == NULL) - return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); + return (dst__openssl_toresult(DST_R_OPENSSLFAILURE)); SET_FLAGS(rsa); key->opaque = rsa; diff --git a/contrib/bind9/lib/dns/peer.c b/contrib/bind9/lib/dns/peer.c index a50ff0c9abe5..8b6ccdb2bebe 100644 --- a/contrib/bind9/lib/dns/peer.c +++ b/contrib/bind9/lib/dns/peer.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: peer.c,v 1.14.2.1.10.4 2004/03/06 08:13:41 marka Exp $ */ +/* $Id: peer.c,v 1.14.2.1.10.6 2006/03/02 00:37:20 marka Exp $ */ #include <config.h> @@ -491,7 +491,9 @@ dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) { } isc_result_t -dns_peer_settransfersource(dns_peer_t *peer, isc_sockaddr_t *transfer_source) { +dns_peer_settransfersource(dns_peer_t *peer, + const isc_sockaddr_t *transfer_source) +{ REQUIRE(DNS_PEER_VALID(peer)); if (peer->transfer_source != NULL) { diff --git a/contrib/bind9/lib/dns/portlist.c b/contrib/bind9/lib/dns/portlist.c index 64546e374b17..f65910bbea67 100644 --- a/contrib/bind9/lib/dns/portlist.c +++ b/contrib/bind9/lib/dns/portlist.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,9 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: portlist.c,v 1.3.72.4 2004/03/16 05:50:21 marka Exp $ */ +/* $Id: portlist.c,v 1.3.72.6 2006/08/25 05:25:50 marka Exp $ */ + +#include <config.h> #include <stdlib.h> diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c index f399dd17bcea..8930d355fd0a 100644 --- a/contrib/bind9/lib/dns/rbtdb.c +++ b/contrib/bind9/lib/dns/rbtdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.168.2.11.2.22 2005/10/14 01:38:48 marka Exp $ */ +/* $Id: rbtdb.c,v 1.168.2.11.2.26 2006/03/02 23:18:20 marka Exp $ */ /* * Principal Author: Bob Halley @@ -1011,6 +1011,47 @@ cleanup_nondirty(rbtdb_version_t *version, rbtdb_changedlist_t *cleanup_list) { } } +static isc_boolean_t +iszonesecure(dns_db_t *db, dns_dbnode_t *origin) { + dns_rdataset_t keyset; + dns_rdataset_t nsecset, signsecset; + isc_boolean_t haszonekey = ISC_FALSE; + isc_boolean_t hasnsec = ISC_FALSE; + isc_result_t result; + + dns_rdataset_init(&keyset); + result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_dnskey, 0, + 0, &keyset, NULL); + if (result == ISC_R_SUCCESS) { + dns_rdata_t keyrdata = DNS_RDATA_INIT; + result = dns_rdataset_first(&keyset); + while (result == ISC_R_SUCCESS) { + dns_rdataset_current(&keyset, &keyrdata); + if (dns_zonekey_iszonekey(&keyrdata)) { + haszonekey = ISC_TRUE; + break; + } + result = dns_rdataset_next(&keyset); + } + dns_rdataset_disassociate(&keyset); + } + if (!haszonekey) + return (ISC_FALSE); + + dns_rdataset_init(&nsecset); + dns_rdataset_init(&signsecset); + result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_nsec, 0, + 0, &nsecset, &signsecset); + if (result == ISC_R_SUCCESS) { + if (dns_rdataset_isassociated(&signsecset)) { + hasnsec = ISC_TRUE; + dns_rdataset_disassociate(&signsecset); + } + dns_rdataset_disassociate(&nsecset); + } + return (hasnsec); +} + static void closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; @@ -1136,6 +1177,12 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) { least_serial = rbtdb->least_serial; UNLOCK(&rbtdb->lock); + /* + * Update the zone's secure status. + */ + if (version->writer && commit && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + if (cleanup_version != NULL) { INSIST(EMPTY(cleanup_version->changed_list)); isc_mem_put(rbtdb->common.mctx, cleanup_version, @@ -2184,12 +2231,12 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, /* * Certain DNSSEC types are not subject to CNAME matching - * (RFC 2535, section 2.3.5). + * (RFC4035, section 2.5 and RFC3007). * * We don't check for RRSIG, because we don't store RRSIG records * directly. */ - if (type == dns_rdatatype_dnskey || type == dns_rdatatype_nsec) + if (type == dns_rdatatype_key || type == dns_rdatatype_nsec) cname_ok = ISC_FALSE; /* @@ -2247,9 +2294,15 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, search.need_cleanup = ISC_TRUE; maybe_zonecut = ISC_FALSE; at_zonecut = ISC_TRUE; + /* + * It is not clear if KEY should still be + * allowed at the parent side of the zone + * cut or not. It is needed for RFC3007 + * validated updates. + */ if ((search.options & DNS_DBFIND_GLUEOK) == 0 && type != dns_rdatatype_nsec - && type != dns_rdatatype_dnskey) { + && type != dns_rdatatype_key) { /* * Glue is not OK, but any answer we * could return would be glue. Return @@ -2430,8 +2483,14 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, * and the type is NSEC or KEY. */ if (search.zonecut == node) { + /* + * It is not clear if KEY should still be + * allowed at the parent side of the zone + * cut or not. It is needed for RFC3007 + * validated updates. + */ if (type == dns_rdatatype_nsec || - type == dns_rdatatype_dnskey) + type == dns_rdatatype_key) result = ISC_R_SUCCESS; else if (type == dns_rdatatype_any) result = DNS_R_ZONECUT; @@ -2860,7 +2919,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, rdatasetheader_t *header, *header_prev, *header_next; rdatasetheader_t *found, *nsheader; rdatasetheader_t *foundsig, *nssig, *cnamesig; - rbtdb_rdatatype_t sigtype, nsectype; + rbtdb_rdatatype_t sigtype, negtype; UNUSED(version); @@ -2918,12 +2977,12 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, /* * Certain DNSSEC types are not subject to CNAME matching - * (RFC 2535, section 2.3.5). + * (RFC4035, section 2.5 and RFC3007). * * We don't check for RRSIG, because we don't store RRSIG records * directly. */ - if (type == dns_rdatatype_dnskey || type == dns_rdatatype_nsec) + if (type == dns_rdatatype_key || type == dns_rdatatype_nsec) cname_ok = ISC_FALSE; /* @@ -2935,7 +2994,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, found = NULL; foundsig = NULL; sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); - nsectype = RBTDB_RDATATYPE_VALUE(0, type); + negtype = RBTDB_RDATATYPE_VALUE(0, type); nsheader = NULL; nssig = NULL; cnamesig = NULL; @@ -3007,7 +3066,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, */ foundsig = header; } else if (header->type == RBTDB_RDATATYPE_NCACHEANY || - header->type == nsectype) { + header->type == negtype) { /* * We've found a negative cache entry. */ @@ -3618,7 +3677,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *rbtnode = (dns_rbtnode_t *)node; rdatasetheader_t *header, *header_next, *found, *foundsig; - rbtdb_rdatatype_t matchtype, sigmatchtype, nsectype; + rbtdb_rdatatype_t matchtype, sigmatchtype, negtype; isc_result_t result; REQUIRE(VALID_RBTDB(rbtdb)); @@ -3636,7 +3695,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, found = NULL; foundsig = NULL; matchtype = RBTDB_RDATATYPE_VALUE(type, covers); - nsectype = RBTDB_RDATATYPE_VALUE(0, type); + negtype = RBTDB_RDATATYPE_VALUE(0, type); if (covers == 0) sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, type); else @@ -3659,7 +3718,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, if (header->type == matchtype) found = header; else if (header->type == RBTDB_RDATATYPE_NCACHEANY || - header->type == nsectype) + header->type == negtype) found = header; else if (header->type == sigmatchtype) foundsig = header; @@ -3785,16 +3844,13 @@ cname_and_other_data(dns_rbtnode_t *node, rbtdb_serial_t serial) { * Look for active extant "other data". * * "Other data" is any rdataset whose type is not - * DNSKEY, RRSIG DNSKEY, NSEC, RRSIG NSEC, - * or RRSIG CNAME. + * KEY, RRSIG KEY, NSEC, RRSIG NSEC or RRSIG CNAME. */ rdtype = RBTDB_RDATATYPE_BASE(header->type); if (rdtype == dns_rdatatype_rrsig || rdtype == dns_rdatatype_sig) rdtype = RBTDB_RDATATYPE_EXT(header->type); if (rdtype != dns_rdatatype_nsec && - rdtype != dns_rdatatype_dnskey && - rdtype != dns_rdatatype_nxt && rdtype != dns_rdatatype_key && rdtype != dns_rdatatype_cname) { /* @@ -3839,7 +3895,8 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, isc_boolean_t header_nx; isc_boolean_t newheader_nx; isc_boolean_t merge; - dns_rdatatype_t nsectype, rdtype, covers; + dns_rdatatype_t rdtype, covers; + rbtdb_rdatatype_t negtype; dns_trust_t trust; /* @@ -3877,7 +3934,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, newheader_nx = NONEXISTENT(newheader) ? ISC_TRUE : ISC_FALSE; topheader_prev = NULL; - nsectype = 0; + negtype = 0; if (rbtversion == NULL && !newheader_nx) { rdtype = RBTDB_RDATATYPE_BASE(newheader->type); if (rdtype == 0) { @@ -3887,12 +3944,13 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, covers = RBTDB_RDATATYPE_EXT(newheader->type); if (covers == dns_rdatatype_any) { /* - * We're adding an NXDOMAIN negative cache - * entry. + * We're adding an negative cache entry + * which covers all types (NXDOMAIN, + * NODATA(QTYPE=ANY)). * * We make all other data stale so that the * only rdataset that can be found at this - * node is the NXDOMAIN negative cache entry. + * node is the negative cache entry. */ for (topheader = rbtnode->data; topheader != NULL; @@ -3904,17 +3962,19 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, rbtnode->dirty = 1; goto find_header; } - nsectype = RBTDB_RDATATYPE_VALUE(covers, 0); + negtype = RBTDB_RDATATYPE_VALUE(covers, 0); } else { /* * We're adding something that isn't a * negative cache entry. Look for an extant - * non-stale NXDOMAIN negative cache entry. + * non-stale NXDOMAIN/NODATA(QTYPE=ANY) negative + * cache entry. */ for (topheader = rbtnode->data; topheader != NULL; topheader = topheader->next) { - if (NXDOMAIN(topheader)) + if (topheader->type == + RBTDB_RDATATYPE_NCACHEANY) break; } if (topheader != NULL && EXISTS(topheader) && @@ -3924,7 +3984,8 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, */ if (trust < topheader->trust) { /* - * The NXDOMAIN is more trusted. + * The NXDOMAIN/NODATA(QTYPE=ANY) + * is more trusted. */ free_rdataset(rbtdb->common.mctx, newheader); @@ -3936,7 +3997,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, } /* * The new rdataset is better. Expire the - * NXDOMAIN. + * NXDOMAIN/NODATA(QTYPE=ANY). */ topheader->ttl = 0; topheader->attributes |= RDATASET_ATTR_STALE; @@ -3944,7 +4005,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, topheader = NULL; goto find_header; } - nsectype = RBTDB_RDATATYPE_VALUE(0, rdtype); + negtype = RBTDB_RDATATYPE_VALUE(0, rdtype); } } @@ -3952,7 +4013,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, topheader != NULL; topheader = topheader->next) { if (topheader->type == newheader->type || - topheader->type == nsectype) + topheader->type == negtype) break; topheader_prev = topheader; } @@ -4118,6 +4179,10 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion, rbtnode->dirty = 1; if (changed != NULL) changed->dirty = ISC_TRUE; + if (rbtversion == NULL) { + header->ttl = 0; + header->attributes |= RDATASET_ATTR_STALE; + } } } else { /* @@ -4318,6 +4383,13 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, if (delegating) RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write); + /* + * Update the zone's secure status. If version is non-NULL + * this is defered until closeversion() is called. + */ + if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + return (result); } @@ -4460,6 +4532,13 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, unlock: UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + /* + * Update the zone's secure status. If version is non-NULL + * this is defered until closeversion() is called. + */ + if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + return (result); } @@ -4501,6 +4580,13 @@ deleterdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock); + /* + * Update the zone's secure status. If version is non-NULL + * this is defered until closeversion() is called. + */ + if (result == ISC_R_SUCCESS && version == NULL && !IS_CACHE(rbtdb)) + rbtdb->secure = iszonesecure(db, rbtdb->origin_node); + return (result); } @@ -4615,48 +4701,6 @@ beginload(dns_db_t *db, dns_addrdatasetfunc_t *addp, dns_dbload_t **dbloadp) { return (ISC_R_SUCCESS); } -static isc_boolean_t -iszonesecure(dns_db_t *db, dns_dbnode_t *origin) { - dns_rdataset_t keyset; - dns_rdataset_t nsecset, signsecset; - isc_boolean_t haszonekey = ISC_FALSE; - isc_boolean_t hasnsec = ISC_FALSE; - isc_result_t result; - - dns_rdataset_init(&keyset); - result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_dnskey, 0, - 0, &keyset, NULL); - if (result == ISC_R_SUCCESS) { - dns_rdata_t keyrdata = DNS_RDATA_INIT; - result = dns_rdataset_first(&keyset); - while (result == ISC_R_SUCCESS) { - dns_rdataset_current(&keyset, &keyrdata); - if (dns_zonekey_iszonekey(&keyrdata)) { - haszonekey = ISC_TRUE; - break; - } - result = dns_rdataset_next(&keyset); - } - dns_rdataset_disassociate(&keyset); - } - if (!haszonekey) - return (ISC_FALSE); - - dns_rdataset_init(&nsecset); - dns_rdataset_init(&signsecset); - result = dns_db_findrdataset(db, origin, NULL, dns_rdatatype_nsec, 0, - 0, &nsecset, &signsecset); - if (result == ISC_R_SUCCESS) { - if (dns_rdataset_isassociated(&signsecset)) { - hasnsec = ISC_TRUE; - dns_rdataset_disassociate(&signsecset); - } - dns_rdataset_disassociate(&nsecset); - } - return (hasnsec); - -} - static isc_result_t endload(dns_db_t *db, dns_dbload_t **dbloadp) { rbtdb_load_t *loadctx; @@ -5235,7 +5279,8 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { rdatasetheader_t *header, *top_next; rbtdb_serial_t serial; isc_stdtime_t now; - rbtdb_rdatatype_t type; + rbtdb_rdatatype_t type, negtype; + dns_rdatatype_t rdtype, covers; header = rbtiterator->current; if (header == NULL) @@ -5252,9 +5297,18 @@ rdatasetiter_next(dns_rdatasetiter_t *iterator) { LOCK(&rbtdb->node_locks[rbtnode->locknum].lock); type = header->type; + rdtype = RBTDB_RDATATYPE_BASE(header->type); + if (rdtype == 0) { + covers = RBTDB_RDATATYPE_EXT(header->type); + negtype = RBTDB_RDATATYPE_VALUE(covers, 0); + } else + negtype = RBTDB_RDATATYPE_VALUE(0, rdtype); for (header = header->next; header != NULL; header = top_next) { top_next = header->next; - if (header->type != type) { + /* + * If not walking back up the down list. + */ + if (header->type != type && header->type != negtype) { do { if (header->serial <= serial && !IGNORE(header)) { diff --git a/contrib/bind9/lib/dns/rdata.c b/contrib/bind9/lib/dns/rdata.c index 1b3f2a51c13a..bcd0e1500529 100644 --- a/contrib/bind9/lib/dns/rdata.c +++ b/contrib/bind9/lib/dns/rdata.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdata.c,v 1.147.2.11.2.20 2005/07/22 05:27:52 marka Exp $ */ +/* $Id: rdata.c,v 1.147.2.11.2.22 2006/07/21 02:05:56 marka Exp $ */ #include <config.h> #include <ctype.h> @@ -1266,7 +1266,7 @@ hexvalue(char value) { return (-1); if (isupper(c)) c = tolower(c); - if ((s = strchr(hexdigits, value)) == NULL) + if ((s = strchr(hexdigits, c)) == NULL) return (-1); return (s - hexdigits); } diff --git a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c new file mode 100644 index 000000000000..b28435c8bd54 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.c @@ -0,0 +1,281 @@ +/* + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: dlv_32769.c,v 1.2.4.2 2006/02/19 06:50:46 marka Exp $ */ + +/* draft-ietf-dnsext-delegation-signer-05.txt */ + +#ifndef RDATA_GENERIC_DLV_32769_C +#define RDATA_GENERIC_DLV_32769_C + +#define RRTYPE_DLV_ATTRIBUTES 0 + +static inline isc_result_t +fromtext_dlv(ARGS_FROMTEXT) { + isc_token_t token; + + REQUIRE(type == 32769); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + /* + * Key tag. + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffffU) + RETTOK(ISC_R_RANGE); + RETERR(uint16_tobuffer(token.value.as_ulong, target)); + + /* + * Algorithm. + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffU) + RETTOK(ISC_R_RANGE); + RETERR(uint8_tobuffer(token.value.as_ulong, target)); + + /* + * Digest type. + */ + RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number, + ISC_FALSE)); + if (token.value.as_ulong > 0xffU) + RETTOK(ISC_R_RANGE); + RETERR(uint8_tobuffer(token.value.as_ulong, target)); + type = (isc_uint16_t) token.value.as_ulong; + + /* + * Digest. + */ + return (isc_hex_tobuffer(lexer, target, -1)); +} + +static inline isc_result_t +totext_dlv(ARGS_TOTEXT) { + isc_region_t sr; + char buf[sizeof("64000 ")]; + unsigned int n; + + REQUIRE(rdata->type == 32769); + REQUIRE(rdata->length != 0); + + UNUSED(tctx); + + dns_rdata_toregion(rdata, &sr); + + /* + * Key tag. + */ + n = uint16_fromregion(&sr); + isc_region_consume(&sr, 2); + sprintf(buf, "%u ", n); + RETERR(str_totext(buf, target)); + + /* + * Algorithm. + */ + n = uint8_fromregion(&sr); + isc_region_consume(&sr, 1); + sprintf(buf, "%u ", n); + RETERR(str_totext(buf, target)); + + /* + * Digest type. + */ + n = uint8_fromregion(&sr); + isc_region_consume(&sr, 1); + sprintf(buf, "%u", n); + RETERR(str_totext(buf, target)); + + /* + * Digest. + */ + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext(" (", target)); + RETERR(str_totext(tctx->linebreak, target)); + RETERR(isc_hex_totext(&sr, tctx->width - 2, tctx->linebreak, target)); + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext(" )", target)); + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +fromwire_dlv(ARGS_FROMWIRE) { + isc_region_t sr; + + REQUIRE(type == 32769); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(dctx); + UNUSED(options); + + isc_buffer_activeregion(source, &sr); + if (sr.length < 4) + return (ISC_R_UNEXPECTEDEND); + + isc_buffer_forward(source, sr.length); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static inline isc_result_t +towire_dlv(ARGS_TOWIRE) { + isc_region_t sr; + + REQUIRE(rdata->type == 32769); + REQUIRE(rdata->length != 0); + + UNUSED(cctx); + + dns_rdata_toregion(rdata, &sr); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static inline int +compare_dlv(ARGS_COMPARE) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 32769); + REQUIRE(rdata1->length != 0); + REQUIRE(rdata2->length != 0); + + dns_rdata_toregion(rdata1, &r1); + dns_rdata_toregion(rdata2, &r2); + return (isc_region_compare(&r1, &r2)); +} + +static inline isc_result_t +fromstruct_dlv(ARGS_FROMSTRUCT) { + dns_rdata_dlv_t *dlv = source; + + REQUIRE(type == 32769); + REQUIRE(source != NULL); + REQUIRE(dlv->common.rdtype == type); + REQUIRE(dlv->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + RETERR(uint16_tobuffer(dlv->key_tag, target)); + RETERR(uint8_tobuffer(dlv->algorithm, target)); + RETERR(uint8_tobuffer(dlv->digest_type, target)); + + return (mem_tobuffer(target, dlv->digest, dlv->length)); +} + +static inline isc_result_t +tostruct_dlv(ARGS_TOSTRUCT) { + dns_rdata_dlv_t *dlv = target; + isc_region_t region; + + REQUIRE(rdata->type == 32769); + REQUIRE(target != NULL); + REQUIRE(rdata->length != 0); + + dlv->common.rdclass = rdata->rdclass; + dlv->common.rdtype = rdata->type; + ISC_LINK_INIT(&dlv->common, link); + + dns_rdata_toregion(rdata, ®ion); + + dlv->key_tag = uint16_fromregion(®ion); + isc_region_consume(®ion, 2); + dlv->algorithm = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + dlv->digest_type = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + dlv->length = region.length; + + dlv->digest = mem_maybedup(mctx, region.base, region.length); + if (dlv->digest == NULL) + return (ISC_R_NOMEMORY); + + dlv->mctx = mctx; + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_dlv(ARGS_FREESTRUCT) { + dns_rdata_dlv_t *dlv = source; + + REQUIRE(dlv != NULL); + REQUIRE(dlv->common.rdtype == 32769); + + if (dlv->mctx == NULL) + return; + + if (dlv->digest != NULL) + isc_mem_free(dlv->mctx, dlv->digest); + dlv->mctx = NULL; +} + +static inline isc_result_t +additionaldata_dlv(ARGS_ADDLDATA) { + REQUIRE(rdata->type == 32769); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_dlv(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 32769); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_dlv(ARGS_CHECKOWNER) { + + REQUIRE(type == 32769); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_dlv(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 32769); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +#endif /* RDATA_GENERIC_DLV_32769_C */ diff --git a/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h new file mode 100644 index 000000000000..08a9b1d4aab9 --- /dev/null +++ b/contrib/bind9/lib/dns/rdata/generic/dlv_32769.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM + * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE + * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +/* $Id: dlv_32769.h,v 1.2.4.2 2006/02/19 06:50:46 marka Exp $ */ + +/* draft-ietf-dnsext-delegation-signer-05.txt */ +#ifndef GENERIC_DLV_32769_H +#define GENERIC_DLV_32769_H 1 + +typedef struct dns_rdata_dlv { + dns_rdatacommon_t common; + isc_mem_t *mctx; + isc_uint16_t key_tag; + isc_uint8_t algorithm; + isc_uint8_t digest_type; + isc_uint16_t length; + unsigned char *digest; +} dns_rdata_dlv_t; + +#endif /* GENERIC_DLV_32769_H */ diff --git a/contrib/bind9/lib/dns/rdataset.c b/contrib/bind9/lib/dns/rdataset.c index 672777b02f50..8af71c3f8dd0 100644 --- a/contrib/bind9/lib/dns/rdataset.c +++ b/contrib/bind9/lib/dns/rdataset.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.c,v 1.58.2.2.2.10 2004/03/08 09:04:31 marka Exp $ */ +/* $Id: rdataset.c,v 1.58.2.2.2.12 2006/03/02 00:37:20 marka Exp $ */ #include <config.h> @@ -280,9 +280,9 @@ towire_compare(const void *av, const void *bv) { } static isc_result_t -towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, +towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, - dns_rdatasetorderfunc_t order, void *order_arg, + dns_rdatasetorderfunc_t order, const void *order_arg, isc_boolean_t partial, unsigned int options, unsigned int *countp, void **state) { @@ -528,11 +528,11 @@ towiresorted(dns_rdataset_t *rdataset, dns_name_t *owner_name, isc_result_t dns_rdataset_towiresorted(dns_rdataset_t *rdataset, - dns_name_t *owner_name, + const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, - void *order_arg, + const void *order_arg, unsigned int options, unsigned int *countp) { @@ -543,11 +543,11 @@ dns_rdataset_towiresorted(dns_rdataset_t *rdataset, isc_result_t dns_rdataset_towirepartial(dns_rdataset_t *rdataset, - dns_name_t *owner_name, + const dns_name_t *owner_name, dns_compress_t *cctx, isc_buffer_t *target, dns_rdatasetorderfunc_t order, - void *order_arg, + const void *order_arg, unsigned int options, unsigned int *countp, void **state) diff --git a/contrib/bind9/lib/dns/request.c b/contrib/bind9/lib/dns/request.c index 3ec845f80d8c..c325fd4c2800 100644 --- a/contrib/bind9/lib/dns/request.c +++ b/contrib/bind9/lib/dns/request.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: request.c,v 1.64.2.1.10.6 2004/03/08 09:04:31 marka Exp $ */ +/* $Id: request.c,v 1.64.2.1.10.9 2006/08/21 00:50:48 marka Exp $ */ #include <config.h> @@ -512,6 +512,7 @@ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr, isc_sockettype_tcp, &socket); if (result != ISC_R_SUCCESS) return (result); +#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT if (srcaddr == NULL) { isc_sockaddr_anyofpf(&bind_any, isc_sockaddr_pf(destaddr)); @@ -523,6 +524,7 @@ create_tcp_dispatch(dns_requestmgr_t *requestmgr, isc_sockaddr_t *srcaddr, } if (result != ISC_R_SUCCESS) goto cleanup; +#endif attrs = 0; attrs |= DNS_DISPATCHATTR_TCP; attrs |= DNS_DISPATCHATTR_PRIVATE; @@ -701,6 +703,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf, if (udptimeout == 0) udptimeout = 1; } + request->udpcount = udpretries; /* * Create timer now. We will set it below once. @@ -898,6 +901,7 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message, if (udptimeout == 0) udptimeout = 1; } + request->udpcount = udpretries; /* * Create timer now. We will set it below once. diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c index a5474f1ae020..b9e69c8c8730 100644 --- a/contrib/bind9/lib/dns/resolver.c +++ b/contrib/bind9/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.218.2.18.4.56.4.2 2006/10/04 07:06:02 marka Exp $ */ +/* $Id: resolver.c,v 1.218.2.18.4.64 2006/08/31 03:57:11 marka Exp $ */ #include <config.h> @@ -27,8 +27,10 @@ #include <dns/acl.h> #include <dns/adb.h> +#include <dns/cache.h> #include <dns/db.h> #include <dns/dispatch.h> +#include <dns/ds.h> #include <dns/events.h> #include <dns/forward.h> #include <dns/keytable.h> @@ -47,6 +49,7 @@ #include <dns/rdatatype.h> #include <dns/resolver.h> #include <dns/result.h> +#include <dns/rootns.h> #include <dns/tsig.h> #include <dns/validator.h> @@ -461,8 +464,7 @@ fctx_starttimer(fetchctx_t *fctx) { * no further idle events are delivered. */ return (isc_timer_reset(fctx->timer, isc_timertype_once, - &fctx->expires, NULL, - ISC_TRUE)); + &fctx->expires, NULL, ISC_TRUE)); } static inline void @@ -1028,9 +1030,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, if (result != ISC_R_SUCCESS) goto cleanup_query; +#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT result = isc_socket_bind(query->tcpsocket, &addr); if (result != ISC_R_SUCCESS) goto cleanup_socket; +#endif /* * A dispatch will be created once the connect succeeds. @@ -1288,6 +1292,12 @@ resquery_send(resquery_t *query) { } /* + * Clear CD if EDNS is not in use. + */ + if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) + fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD; + + /* * Add TSIG record tailored to the current recipient. */ result = dns_view_getpeertsig(fctx->res->view, &ipaddr, &tsigkey); @@ -3156,10 +3166,12 @@ validated(isc_task_t *task, isc_event_t *event) { * so, destroy the fctx. */ if (SHUTTINGDOWN(fctx) && !sentresponse) { - maybe_destroy(fctx); + maybe_destroy(fctx); /* Locks bucket. */ goto cleanup_event; } + LOCK(&fctx->res->buckets[fctx->bucketnum].lock); + /* * If chaining, we need to make sure that the right result code is * returned, and that the rdatasets are bound. @@ -3219,10 +3231,11 @@ validated(isc_task_t *task, isc_event_t *event) { result = vevent->result; add_bad(fctx, &addrinfo->sockaddr, result); isc_event_free(&event); + UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); if (sentresponse) - fctx_done(fctx, result); + fctx_done(fctx, result); /* Locks bucket. */ else - fctx_try(fctx); + fctx_try(fctx); /* Locks bucket. */ return; } @@ -3267,6 +3280,7 @@ validated(isc_task_t *task, isc_event_t *event) { result = dns_rdataset_addnoqname(vevent->rdataset, vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]); RUNTIME_CHECK(result == ISC_R_SUCCESS); + INSIST(vevent->sigrdataset != NULL); vevent->sigrdataset->ttl = vevent->rdataset->ttl; } @@ -3299,9 +3313,9 @@ validated(isc_task_t *task, isc_event_t *event) { * If we only deferred the destroy because we wanted to cache * the data, destroy now. */ + UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); if (SHUTTINGDOWN(fctx)) - maybe_destroy(fctx); - + maybe_destroy(fctx); /* Locks bucket. */ goto cleanup_event; } @@ -3315,6 +3329,7 @@ validated(isc_task_t *task, isc_event_t *event) { * more rdatasets that still need to * be validated. */ + UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); goto cleanup_event; } @@ -3387,7 +3402,9 @@ validated(isc_task_t *task, isc_event_t *event) { if (node != NULL) dns_db_detachnode(fctx->cache, &node); - fctx_done(fctx, result); + UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); + + fctx_done(fctx, result); /* Locks bucket. */ cleanup_event: isc_event_free(&event); @@ -4921,6 +4938,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { fctx_try(fctx); } else { unsigned int n; + dns_rdataset_t *nsrdataset = NULL; /* * Retrieve state from fctx->nsfetch before we destroy it. @@ -4928,13 +4946,20 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { dns_fixedname_init(&fixed); domain = dns_fixedname_name(&fixed); dns_name_copy(&fctx->nsfetch->private->domain, domain, NULL); - dns_rdataset_clone(&fctx->nsfetch->private->nameservers, - &nameservers); - dns_resolver_destroyfetch(&fctx->nsfetch); if (dns_name_equal(&fctx->nsname, domain)) { fctx_done(fctx, DNS_R_SERVFAIL); + dns_resolver_destroyfetch(&fctx->nsfetch); goto cleanup; } + if (dns_rdataset_isassociated( + &fctx->nsfetch->private->nameservers)) { + dns_rdataset_clone( + &fctx->nsfetch->private->nameservers, + &nameservers); + nsrdataset = &nameservers; + } else + domain = NULL; + dns_resolver_destroyfetch(&fctx->nsfetch); n = dns_name_countlabels(&fctx->nsname); dns_name_getlabelsequence(&fctx->nsname, 1, n - 1, &fctx->nsname); @@ -4944,7 +4969,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { FCTXTRACE("continuing to look for parent's NS records"); result = dns_resolver_createfetch(fctx->res, &fctx->nsname, dns_rdatatype_ns, domain, - &nameservers, NULL, 0, task, + nsrdataset, NULL, 0, task, resume_dslookup, fctx, &fctx->nsrrset, NULL, &fctx->nsfetch); diff --git a/contrib/bind9/lib/dns/tcpmsg.c b/contrib/bind9/lib/dns/tcpmsg.c index 4400a3a58f7f..a0fddcde12a2 100644 --- a/contrib/bind9/lib/dns/tcpmsg.c +++ b/contrib/bind9/lib/dns/tcpmsg.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: tcpmsg.c,v 1.24.206.1 2004/03/06 08:13:46 marka Exp $ */ +/* $Id: tcpmsg.c,v 1.24.206.3 2006/08/10 23:59:28 marka Exp $ */ #include <config.h> @@ -52,6 +52,7 @@ recv_length(isc_task_t *task, isc_event_t *ev_in) { INSIST(VALID_TCPMSG(tcpmsg)); dev = &tcpmsg->event; + tcpmsg->address = ev->address; if (ev->result != ISC_R_SUCCESS) { tcpmsg->result = ev->result; @@ -108,6 +109,7 @@ recv_message(isc_task_t *task, isc_event_t *ev_in) { INSIST(VALID_TCPMSG(tcpmsg)); dev = &tcpmsg->event; + tcpmsg->address = ev->address; if (ev->result != ISC_R_SUCCESS) { tcpmsg->result = ev->result; @@ -116,7 +118,6 @@ recv_message(isc_task_t *task, isc_event_t *ev_in) { tcpmsg->result = ISC_R_SUCCESS; isc_buffer_add(&tcpmsg->buffer, ev->n); - tcpmsg->address = ev->address; XDEBUG(("Received %d bytes (of %d)\n", ev->n, tcpmsg->size)); diff --git a/contrib/bind9/lib/dns/tkey.c b/contrib/bind9/lib/dns/tkey.c index 43c8db0e57c8..ca793d2b9423 100644 --- a/contrib/bind9/lib/dns/tkey.c +++ b/contrib/bind9/lib/dns/tkey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -16,7 +16,7 @@ */ /* - * $Id: tkey.c,v 1.71.2.1.10.7 2005/06/12 00:02:26 marka Exp $ + * $Id: tkey.c,v 1.71.2.1.10.9 2006/01/04 23:50:20 marka Exp $ */ #include <config.h> @@ -441,15 +441,17 @@ process_gsstkey(dns_message_t *msg, dns_name_t *signer, dns_name_t *name, dstkey, ISC_TRUE, signer, tkeyin->inception, tkeyin->expire, msg->mctx, ring, NULL); +#if 1 if (result != ISC_R_SUCCESS) goto failure; - +#else if (result == ISC_R_NOTFOUND) { tkeyout->error = dns_tsigerror_badalg; return (ISC_R_SUCCESS); } if (result != ISC_R_SUCCESS) goto failure; +#endif /* This key is good for a long time */ isc_stdtime_get(&now); diff --git a/contrib/bind9/lib/dns/tsig.c b/contrib/bind9/lib/dns/tsig.c index 6a8d774a2702..9bdde06eb151 100644 --- a/contrib/bind9/lib/dns/tsig.c +++ b/contrib/bind9/lib/dns/tsig.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2002 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -16,7 +16,7 @@ */ /* - * $Id: tsig.c,v 1.112.2.3.8.6 2005/03/17 03:58:31 marka Exp $ + * $Id: tsig.c,v 1.112.2.3.8.10 2006/05/02 04:21:42 marka Exp $ */ #include <config.h> @@ -363,7 +363,7 @@ dns_tsig_sign(dns_message_t *msg) { isc_buffer_t databuf, sigbuf; isc_buffer_t *dynbuf; dns_name_t *owner; - dns_rdata_t *rdata; + dns_rdata_t *rdata = NULL; dns_rdatalist_t *datalist; dns_rdataset_t *dataset; isc_region_t r; @@ -555,13 +555,12 @@ dns_tsig_sign(dns_message_t *msg) { tsig.signature = NULL; } - rdata = NULL; ret = dns_message_gettemprdata(msg, &rdata); if (ret != ISC_R_SUCCESS) goto cleanup_signature; ret = isc_buffer_allocate(msg->mctx, &dynbuf, 512); if (ret != ISC_R_SUCCESS) - goto cleanup_signature; + goto cleanup_rdata; ret = dns_rdata_fromstruct(rdata, dns_rdataclass_any, dns_rdatatype_tsig, &tsig, dynbuf); if (ret != ISC_R_SUCCESS) @@ -577,7 +576,7 @@ dns_tsig_sign(dns_message_t *msg) { owner = NULL; ret = dns_message_gettempname(msg, &owner); if (ret != ISC_R_SUCCESS) - goto cleanup_dynbuf; + goto cleanup_rdata; dns_name_init(owner, NULL); ret = dns_name_dup(&key->name, msg->mctx, owner); if (ret != ISC_R_SUCCESS) @@ -587,16 +586,16 @@ dns_tsig_sign(dns_message_t *msg) { ret = dns_message_gettemprdatalist(msg, &datalist); if (ret != ISC_R_SUCCESS) goto cleanup_owner; + dataset = NULL; + ret = dns_message_gettemprdataset(msg, &dataset); + if (ret != ISC_R_SUCCESS) + goto cleanup_rdatalist; datalist->rdclass = dns_rdataclass_any; datalist->type = dns_rdatatype_tsig; datalist->covers = 0; datalist->ttl = 0; ISC_LIST_INIT(datalist->rdata); ISC_LIST_APPEND(datalist->rdata, rdata, link); - dataset = NULL; - ret = dns_message_gettemprdataset(msg, &dataset); - if (ret != ISC_R_SUCCESS) - goto cleanup_owner; dns_rdataset_init(dataset); RUNTIME_CHECK(dns_rdatalist_tordataset(datalist, dataset) == ISC_R_SUCCESS); @@ -605,16 +604,19 @@ dns_tsig_sign(dns_message_t *msg) { return (ISC_R_SUCCESS); -cleanup_owner: - if (owner != NULL) - dns_message_puttempname(msg, &owner); -cleanup_dynbuf: - if (dynbuf != NULL) - isc_buffer_free(&dynbuf); -cleanup_signature: + cleanup_rdatalist: + dns_message_puttemprdatalist(msg, &datalist); + cleanup_owner: + dns_message_puttempname(msg, &owner); + goto cleanup_rdata; + cleanup_dynbuf: + isc_buffer_free(&dynbuf); + cleanup_rdata: + dns_message_puttemprdata(msg, &rdata); + cleanup_signature: if (tsig.signature != NULL) isc_mem_put(mctx, tsig.signature, sigsize); -cleanup_context: + cleanup_context: if (ctx != NULL) dst_context_destroy(&ctx); return (ret); @@ -646,8 +648,11 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg, msg->verify_attempted = 1; - if (msg->tcp_continuation) + if (msg->tcp_continuation) { + if (tsigkey == NULL || msg->querytsig == NULL) + return (DNS_R_UNEXPECTEDTSIG); return (tsig_verify_tcp(source, msg)); + } /* * There should be a TSIG record... diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c index a62db3413768..ec727b71255a 100644 --- a/contrib/bind9/lib/dns/validator.c +++ b/contrib/bind9/lib/dns/validator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.91.2.5.8.21 2005/11/02 02:07:47 marka Exp $ */ +/* $Id: validator.c,v 1.91.2.5.8.27 2006/02/26 23:03:52 marka Exp $ */ #include <config.h> @@ -43,20 +43,65 @@ #include <dns/validator.h> #include <dns/view.h> +/*! \file + * \brief + * Basic processing sequences. + * + * \li When called with rdataset and sigrdataset: + * validator_start -> validate -> proveunsecure -> startfinddlvsep -> + * dlv_validator_start -> validator_start -> validate -> proveunsecure + * + * validator_start -> validate -> nsecvalidate (secure wildcard answer) + * + * \li When called with rdataset, sigrdataset and with DNS_VALIDATOR_DLV: + * validator_start -> startfinddlvsep -> dlv_validator_start -> + * validator_start -> validate -> proveunsecure + * + * \li When called with rdataset: + * validator_start -> proveunsecure -> startfinddlvsep -> + * dlv_validator_start -> validator_start -> proveunsecure + * + * \li When called with rdataset and with DNS_VALIDATOR_DLV: + * validator_start -> startfinddlvsep -> dlv_validator_start -> + * validator_start -> proveunsecure + * + * \li When called without a rdataset: + * validator_start -> nsecvalidate -> proveunsecure -> startfinddlvsep -> + * dlv_validator_start -> validator_start -> nsecvalidate -> proveunsecure + * + * \li When called without a rdataset and with DNS_VALIDATOR_DLV: + * validator_start -> startfinddlvsep -> dlv_validator_start -> + * validator_start -> nsecvalidate -> proveunsecure + * + * validator_start: determines what type of validation to do. + * validate: attempts to perform a positive validation. + * proveunsecure: attempts to prove the answer comes from a unsecure zone. + * nsecvalidate: attempts to prove a negative response. + * startfinddlvsep: starts the DLV record lookup. + * dlv_validator_start: resets state and restarts the lookup using the + * DLV RRset found by startfinddlvsep. + */ + #define VALIDATOR_MAGIC ISC_MAGIC('V', 'a', 'l', '?') #define VALID_VALIDATOR(v) ISC_MAGIC_VALID(v, VALIDATOR_MAGIC) -#define VALATTR_SHUTDOWN 0x0001 -#define VALATTR_FOUNDNONEXISTENCE 0x0002 -#define VALATTR_TRIEDVERIFY 0x0004 -#define VALATTR_NEGATIVE 0x0008 -#define VALATTR_INSECURITY 0x0010 -#define VALATTR_DLVTRIED 0x0020 +#define VALATTR_SHUTDOWN 0x0001 /*%< Shutting down. */ +#define VALATTR_TRIEDVERIFY 0x0004 /*%< We have found a key and + * have attempted a verify. */ +#define VALATTR_INSECURITY 0x0010 /*%< Attempting proveunsecure. */ +#define VALATTR_DLVTRIED 0x0020 /*%< Looked for a DLV record. */ +#define VALATTR_AUTHNONPENDING 0x0040 /*%< Tidy up pending auth. */ +/*! + * NSEC proofs to be looked for. + */ #define VALATTR_NEEDNOQNAME 0x0100 #define VALATTR_NEEDNOWILDCARD 0x0200 #define VALATTR_NEEDNODATA 0x0400 +/*! + * NSEC proofs that have been found. + */ #define VALATTR_FOUNDNOQNAME 0x1000 #define VALATTR_FOUNDNOWILDCARD 0x2000 #define VALATTR_FOUNDNODATA 0x4000 @@ -104,19 +149,35 @@ validator_logcreate(dns_validator_t *val, static isc_result_t dlv_validatezonekey(dns_validator_t *val); -static isc_result_t +static void dlv_validator_start(dns_validator_t *val); static isc_result_t finddlvsep(dns_validator_t *val, isc_boolean_t resume); +static void +auth_nonpending(dns_message_t *message); + +static isc_result_t +startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure); + +/*% + * Mark the RRsets as a answer. + * + * If VALATTR_AUTHNONPENDING is set then this is a negative answer + * in a insecure zone. We need to mark any pending RRsets as + * dns_trust_authauthority answers (this is deferred from resolver.c). + */ static inline void markanswer(dns_validator_t *val) { validator_log(val, ISC_LOG_DEBUG(3), "marking as answer"); - if (val->event->rdataset) + if (val->event->rdataset != NULL) val->event->rdataset->trust = dns_trust_answer; - if (val->event->sigrdataset) + if (val->event->sigrdataset != NULL) val->event->sigrdataset->trust = dns_trust_answer; + if (val->event->message != NULL && + (val->attributes & VALATTR_AUTHNONPENDING) != 0) + auth_nonpending(val->event->message); } static void @@ -155,6 +216,9 @@ exit_check(dns_validator_t *val) { return (ISC_TRUE); } +/*% + * Mark pending answers in the authority section as dns_trust_authauthority. + */ static void auth_nonpending(dns_message_t *message) { isc_result_t result; @@ -177,6 +241,10 @@ auth_nonpending(dns_message_t *message) { } } +/*% + * Look in the NSEC record returned from a DS query to see if there is + * a NS RRset at this name. If it is found we are at a delegation point. + */ static isc_boolean_t isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, isc_result_t dbresult) @@ -210,6 +278,11 @@ isdelegation(dns_name_t *name, dns_rdataset_t *rdataset, return (found); } +/*% + * We have been asked to to look for a key. + * If found resume the validation process. + * If not found fail the validation process. + */ static void fetch_callback_validator(isc_task_t *task, isc_event_t *event) { dns_fetchevent_t *devent; @@ -269,6 +342,11 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { destroy(val); } +/*% + * We were asked to look for a DS record as part of following a key chain + * upwards. If found resume the validation process. If not found fail the + * validation process. + */ static void dsfetched(isc_task_t *task, isc_event_t *event) { dns_fetchevent_t *devent; @@ -330,8 +408,16 @@ dsfetched(isc_task_t *task, isc_event_t *event) { destroy(val); } -/* - * XXX there's too much duplicated code here. +/*% + * We were asked to look for the DS record as part of proving that a + * name is unsecure. + * + * If the DS record doesn't exist and the query name corresponds to + * a delegation point we are transitioning from a secure zone to a + * unsecure zone. + * + * If the DS record exists it will be secure. We can continue looking + * for the break point in the chain of trust. */ static void dsfetched2(isc_task_t *task, isc_event_t *event) { @@ -359,7 +445,8 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { INSIST(val->event != NULL); - validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2"); + validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s", + dns_result_totext(eresult)); LOCK(&val->lock); if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NCACHENXRRSET) { /* @@ -371,9 +458,13 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { validator_log(val, ISC_LOG_WARNING, "must be secure failure"); validator_done(val, DNS_R_MUSTBESECURE); - } else { + } else if (val->view->dlv == NULL || DLVTRIED(val)) { markanswer(val); validator_done(val, ISC_R_SUCCESS); + } else { + result = startfinddlvsep(val, tname); + if (result != DNS_R_WAIT) + validator_done(val, result); } } else { result = proveunsecure(val, ISC_TRUE); @@ -385,7 +476,9 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { eresult == DNS_R_NCACHENXDOMAIN) { /* - * Either there is a DS or this is not a zone cut. Continue. + * There is a DS which may or may not be a zone cut. + * In either case we are still in a secure zone resume + * validation. */ result = proveunsecure(val, ISC_TRUE); if (result != DNS_R_WAIT) @@ -403,6 +496,11 @@ dsfetched2(isc_task_t *task, isc_event_t *event) { destroy(val); } +/*% + * Callback from when a DNSKEY RRset has been validated. + * + * Resumes the stalled validation process. + */ static void keyvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; @@ -448,6 +546,11 @@ keyvalidated(isc_task_t *task, isc_event_t *event) { destroy(val); } +/*% + * Callback when the DS record has been validated. + * + * Resumes validation of the zone key or the unsecure zone proof. + */ static void dsvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; @@ -491,10 +594,12 @@ dsvalidated(isc_task_t *task, isc_event_t *event) { destroy(val); } -/* +/*% * Return ISC_R_SUCCESS if we can determine that the name doesn't exist * or we can determine whether there is data or not at the name. * If the name does not exist return the wildcard name. + * + * Return ISC_R_IGNORE when the NSEC is not the appropriate one. */ static isc_result_t nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, @@ -627,7 +732,7 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, wild, NULL); if (result != ISC_R_SUCCESS) { validator_log(val, ISC_LOG_DEBUG(3), - "failure generating wilcard name"); + "failure generating wildcard name"); return (result); } } @@ -637,6 +742,13 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname, return (ISC_R_SUCCESS); } +/*% + * Callback for when NSEC records have been validated. + * + * Looks for NOQNAME and NODATA proofs. + * + * Resumes nsecvalidate. + */ static void authvalidated(isc_task_t *task, isc_event_t *event) { dns_validatorevent_t *devent; @@ -715,44 +827,20 @@ authvalidated(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); } -static void -negauthvalidated(isc_task_t *task, isc_event_t *event) { - dns_validatorevent_t *devent; - dns_validator_t *val; - isc_boolean_t want_destroy; - isc_result_t eresult; - - UNUSED(task); - INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE); - - devent = (dns_validatorevent_t *)event; - val = devent->ev_arg; - eresult = devent->result; - isc_event_free(&event); - dns_validator_destroy(&val->subvalidator); - - INSIST(val->event != NULL); - - validator_log(val, ISC_LOG_DEBUG(3), "in negauthvalidated"); - LOCK(&val->lock); - if (eresult == ISC_R_SUCCESS) { - val->attributes |= VALATTR_FOUNDNONEXISTENCE; - validator_log(val, ISC_LOG_DEBUG(3), - "nonexistence proof found"); - auth_nonpending(val->event->message); - validator_done(val, ISC_R_SUCCESS); - } else { - validator_log(val, ISC_LOG_DEBUG(3), - "negauthvalidated: got %s", - isc_result_totext(eresult)); - validator_done(val, eresult); - } - want_destroy = exit_check(val); - UNLOCK(&val->lock); - if (want_destroy) - destroy(val); -} - +/*% + * Looks for the requested name and type in the view (zones and cache). + * + * When looking for a DLV record also checks to make sure the NSEC record + * returns covers the query name as part of aggressive negative caching. + * + * Returns: + * \li ISC_R_SUCCESS + * \li ISC_R_NOTFOUND + * \li DNS_R_NCACHENXDOMAIN + * \li DNS_R_NCACHENXRRSET + * \li DNS_R_NXRRSET + * \li DNS_R_NXDOMAIN + */ static inline isc_result_t view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { dns_fixedname_t fixedname; @@ -855,12 +943,9 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { dns_rdata_freestruct(&nsec); result = DNS_R_NCACHENXDOMAIN; } else if (result != ISC_R_SUCCESS && - result != DNS_R_GLUE && - result != DNS_R_HINT && result != DNS_R_NCACHENXDOMAIN && result != DNS_R_NCACHENXRRSET && result != DNS_R_NXRRSET && - result != DNS_R_HINTNXRRSET && result != ISC_R_NOTFOUND) { goto notfound; } @@ -874,11 +959,15 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { return (ISC_R_NOTFOUND); } +/*% + * Checks to make sure we are not going to loop. As we use a SHARED fetch + * the validation process will stall if looping was to occur. + */ static inline isc_boolean_t check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { dns_validator_t *parent; - for (parent = val->parent; parent != NULL; parent = parent->parent) { + for (parent = val; parent != NULL; parent = parent->parent) { if (parent->event != NULL && parent->event->type == type && dns_name_equal(parent->event->name, name)) @@ -892,6 +981,9 @@ check_deadlock(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { return (ISC_FALSE); } +/*% + * Start a fetch for the requested name and type. + */ static inline isc_result_t create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, isc_taskaction_t callback, const char *caller) @@ -914,6 +1006,9 @@ create_fetch(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, &val->fetch)); } +/*% + * Start a subvalidation process. + */ static inline isc_result_t create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset, @@ -936,7 +1031,7 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type, return (result); } -/* +/*% * Try to find a key that could have signed 'siginfo' among those * in 'rdataset'. If found, build a dst_key_t for it and point * val->key at it. @@ -1004,6 +1099,9 @@ get_dst_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo, return (result); } +/*% + * Get the key that genertated this signature. + */ static isc_result_t get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { isc_result_t result; @@ -1130,7 +1228,7 @@ compute_keytag(dns_rdata_t *rdata, dns_rdata_dnskey_t *key) { return (dst_region_computeid(&r, key->algorithm)); } -/* +/*% * Is this keyset self-signed? */ static isc_boolean_t @@ -1172,8 +1270,19 @@ isselfsigned(dns_validator_t *val) { return (ISC_FALSE); } +/*% + * Attempt to verify the rdataset using the given key and rdata (RRSIG). + * The signature was good and from a wildcard record and the QNAME does + * not match the wildcard we need to look for a NOQNAME proof. + * + * Returns: + * \li ISC_R_SUCCESS if the verification succeeds. + * \li Others if the verification fails. + */ static isc_result_t -verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) { +verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, + isc_uint16_t keyid) +{ isc_result_t result; dns_fixedname_t fixed; @@ -1183,8 +1292,8 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) { key, ISC_FALSE, val->view->mctx, rdata, dns_fixedname_name(&fixed)); validator_log(val, ISC_LOG_DEBUG(3), - "verify rdataset: %s", - isc_result_totext(result)); + "verify rdataset (keyid=%u): %s", + keyid, isc_result_totext(result)); if (result == DNS_R_FROMWILDCARD) { if (!dns_name_equal(val->event->name, dns_fixedname_name(&fixed))) @@ -1194,14 +1303,14 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata) { return (result); } -/* +/*% * Attempts positive response validation of a normal RRset. * * Returns: - * ISC_R_SUCCESS Validation completed successfully - * DNS_R_WAIT Validation has started but is waiting + * \li ISC_R_SUCCESS Validation completed successfully + * \li DNS_R_WAIT Validation has started but is waiting * for an event. - * Other return codes are possible and all indicate failure. + * \li Other return codes are possible and all indicate failure. */ static isc_result_t validate(dns_validator_t *val, isc_boolean_t resume) { @@ -1272,7 +1381,8 @@ validate(dns_validator_t *val, isc_boolean_t resume) { } do { - result = verify(val, val->key, &rdata); + result = verify(val, val->key, &rdata, + val->siginfo->keyid); if (result == ISC_R_SUCCESS) break; if (val->keynode != NULL) { @@ -1356,6 +1466,10 @@ validate(dns_validator_t *val, isc_boolean_t resume) { return (DNS_R_NOVALIDSIG); } +/*% + * Validate the DNSKEY RRset by looking for a DNSKEY that matches a + * DLV record and that also verifies the DNSKEY RRset. + */ static isc_result_t dlv_validatezonekey(dns_validator_t *val) { dns_keytag_t keytag; @@ -1373,12 +1487,12 @@ dlv_validatezonekey(dns_validator_t *val) { unsigned char dsbuf[DNS_DS_BUFFERSIZE]; validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey"); + /* * Look through the DLV record and find the keys that can sign the * key set and the matching signature. For each such key, attempt * verification. */ - supported_algorithm = ISC_FALSE; for (result = dns_rdataset_first(&val->dlv); @@ -1456,7 +1570,7 @@ dlv_validatezonekey(dns_validator_t *val) { */ continue; - result = verify(val, dstkey, &sigrdata); + result = verify(val, dstkey, &sigrdata, sig.keyid); dst_key_free(&dstkey); if (result == ISC_R_SUCCESS) break; @@ -1486,14 +1600,14 @@ dlv_validatezonekey(dns_validator_t *val) { return (DNS_R_NOVALIDSIG); } -/* +/*% * Attempts positive response validation of an RRset containing zone keys. * * Returns: - * ISC_R_SUCCESS Validation completed successfully - * DNS_R_WAIT Validation has started but is waiting + * \li ISC_R_SUCCESS Validation completed successfully + * \li DNS_R_WAIT Validation has started but is waiting * for an event. - * Other return codes are possible and all indicate failure. + * \li Other return codes are possible and all indicate failure. */ static isc_result_t validatezonekey(dns_validator_t *val) { @@ -1505,12 +1619,14 @@ validatezonekey(dns_validator_t *val) { dns_rdata_t keyrdata = DNS_RDATA_INIT; dns_rdata_t sigrdata = DNS_RDATA_INIT; unsigned char dsbuf[DNS_DS_BUFFERSIZE]; + char namebuf[DNS_NAME_FORMATSIZE]; dns_keytag_t keytag; dns_rdata_ds_t ds; dns_rdata_dnskey_t key; dns_rdata_rrsig_t sig; dst_key_t *dstkey; isc_boolean_t supported_algorithm; + isc_boolean_t atsep = ISC_FALSE; /* * Caller must be holding the validator lock. @@ -1541,9 +1657,13 @@ validatezonekey(dns_validator_t *val) { sig.algorithm, sig.keyid, &keynode); + if (result == DNS_R_PARTIALMATCH || + result == ISC_R_SUCCESS) + atsep = ISC_TRUE; while (result == ISC_R_SUCCESS) { dstkey = dns_keynode_key(keynode); - result = verify(val, dstkey, &sigrdata); + result = verify(val, dstkey, &sigrdata, + sig.keyid); if (result == ISC_R_SUCCESS) { dns_keytable_detachkeynode(val->keytable, &keynode); @@ -1578,6 +1698,22 @@ validatezonekey(dns_validator_t *val) { return (DNS_R_NOVALIDDS); } + if (atsep) { + /* + * We have not found a key to verify this DNSKEY + * RRset. As this is a SEP we have to assume that + * the RRset is invalid. + */ + dns_name_format(val->event->name, namebuf, + sizeof(namebuf)); + validator_log(val, ISC_LOG_DEBUG(2), + "unable to find a DNSKEY which verifies " + "the DNSKEY RRset and also matches one " + "of specified trusted-keys for '%s'", + namebuf); + return (DNS_R_NOVALIDKEY); + } + /* * Otherwise, try to find the DS record. */ @@ -1680,6 +1816,9 @@ validatezonekey(dns_validator_t *val) { dns_rdataset_init(&trdataset); dns_rdataset_clone(val->event->rdataset, &trdataset); + /* + * Look for the KEY that matches the DS record. + */ for (result = dns_rdataset_first(&trdataset); result == ISC_R_SUCCESS; result = dns_rdataset_next(&trdataset)) @@ -1714,7 +1853,7 @@ validatezonekey(dns_validator_t *val) { dns_rdataset_current(val->event->sigrdataset, &sigrdata); (void)dns_rdata_tostruct(&sigrdata, &sig, NULL); - if (ds.key_tag != sig.keyid && + if (ds.key_tag != sig.keyid || ds.algorithm != sig.algorithm) continue; @@ -1728,8 +1867,7 @@ validatezonekey(dns_validator_t *val) { * This really shouldn't happen, but... */ continue; - - result = verify(val, dstkey, &sigrdata); + result = verify(val, dstkey, &sigrdata, sig.keyid); dst_key_free(&dstkey); if (result == ISC_R_SUCCESS) break; @@ -1759,14 +1897,14 @@ validatezonekey(dns_validator_t *val) { return (DNS_R_NOVALIDSIG); } -/* +/*% * Starts a positive response validation. * * Returns: - * ISC_R_SUCCESS Validation completed successfully - * DNS_R_WAIT Validation has started but is waiting + * \li ISC_R_SUCCESS Validation completed successfully + * \li DNS_R_WAIT Validation has started but is waiting * for an event. - * Other return codes are possible and all indicate failure. + * \li Other return codes are possible and all indicate failure. */ static isc_result_t start_positive_validation(dns_validator_t *val) { @@ -1779,6 +1917,14 @@ start_positive_validation(dns_validator_t *val) { return (validatezonekey(val)); } +/*% + * Look for NODATA at the wildcard and NOWILDCARD proofs in the + * previously validated NSEC records. As these proofs are mutually + * exclusive we stop when one is found. + * + * Returns + * \li ISC_R_SUCCESS + */ static isc_result_t checkwildcard(dns_validator_t *val) { dns_name_t *name, *wild; @@ -1851,6 +1997,18 @@ checkwildcard(dns_validator_t *val) { return (result); } +/*% + * Prove a negative answer is good or that there is a NOQNAME when the + * answer is from a wildcard. + * + * Loop through the authority section looking for NODATA, NOWILDCARD + * and NOQNAME proofs in the NSEC records by calling authvalidated(). + * + * If the required proofs are found we are done. + * + * If the proofs are not found attempt to prove this is a unsecure + * response. + */ static isc_result_t nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { dns_name_t *name; @@ -1946,7 +2104,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { return (result); /* - * Do we only need to check for NOQNAME? + * Do we only need to check for NOQNAME? To get here we must have + * had a secure wildcard answer. */ if ((val->attributes & VALATTR_NEEDNODATA) == 0 && (val->attributes & VALATTR_NEEDNOWILDCARD) == 0 && @@ -1982,28 +2141,17 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { ((val->attributes & VALATTR_NEEDNOQNAME) != 0 && (val->attributes & VALATTR_FOUNDNOQNAME) != 0 && (val->attributes & VALATTR_NEEDNOWILDCARD) != 0 && - (val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)) - val->attributes |= VALATTR_FOUNDNONEXISTENCE; - - if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) { - if (!val->seensig && val->soaset != NULL) { - result = create_validator(val, val->soaname, - dns_rdatatype_soa, - val->soaset, NULL, - negauthvalidated, - "nsecvalidate"); - if (result != ISC_R_SUCCESS) - return (result); - return (DNS_R_WAIT); - } + (val->attributes & VALATTR_FOUNDNOWILDCARD) != 0)) { validator_log(val, ISC_LOG_DEBUG(3), - "nonexistence proof not found"); - return (DNS_R_NOVALIDNSEC); - } else { - validator_log(val, ISC_LOG_DEBUG(3), - "nonexistence proof found"); + "nonexistence proof(s) found"); return (ISC_R_SUCCESS); } + + validator_log(val, ISC_LOG_DEBUG(3), + "nonexistence proof(s) not found"); + val->attributes |= VALATTR_AUTHNONPENDING; + val->attributes |= VALATTR_INSECURITY; + return (proveunsecure(val, ISC_FALSE)); } static isc_boolean_t @@ -2029,6 +2177,11 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { return (ISC_FALSE); } +/*% + * Callback from fetching a DLV record. + * + * Resumes the DLV lookup process. + */ static void dlvfetched(isc_task_t *task, isc_event_t *event) { char namebuf[DNS_NAME_FORMATSIZE]; @@ -2065,9 +2218,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { dns_rdataset_clone(&val->frdataset, &val->dlv); val->havedlvsep = ISC_TRUE; validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); - result = dlv_validator_start(val); - if (result != DNS_R_WAIT) - validator_done(val, result); + dlv_validator_start(val); } else if (eresult == DNS_R_NXRRSET || eresult == DNS_R_NXDOMAIN || eresult == DNS_R_NCACHENXRRSET || @@ -2078,9 +2229,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); - result = dlv_validator_start(val); - if (result != DNS_R_WAIT) - validator_done(val, result); + dlv_validator_start(val); } else if (result == ISC_R_NOTFOUND) { validator_log(val, ISC_LOG_DEBUG(3), "DLV not found"); markanswer(val); @@ -2094,6 +2243,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { } else { validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s", dns_result_totext(eresult)); + validator_done(val, eresult); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -2101,6 +2251,14 @@ dlvfetched(isc_task_t *task, isc_event_t *event) { destroy(val); } +/*% + * Start the DLV lookup proccess. + * + * Returns + * \li ISC_R_SUCCESS + * \li DNS_R_WAIT + * \li Others on validation failures. + */ static isc_result_t startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) { char namebuf[DNS_NAME_FORMATSIZE]; @@ -2135,9 +2293,19 @@ startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) { dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf, sizeof(namebuf)); validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf); - return (dlv_validator_start(val)); + dlv_validator_start(val); + return (DNS_R_WAIT); } +/*% + * Continue the DLV lookup process. + * + * Returns + * \li ISC_R_SUCCESS + * \li ISC_R_NOTFOUND + * \li DNS_R_WAIT + * \li Others on validation failure. + */ static isc_result_t finddlvsep(dns_validator_t *val, isc_boolean_t resume) { char namebuf[DNS_NAME_FORMATSIZE]; @@ -2147,7 +2315,7 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { dns_name_t noroot; isc_result_t result; unsigned int labels; - + INSIST(val->view->dlv != NULL); if (!resume) { @@ -2231,11 +2399,24 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { return (ISC_R_NOTFOUND); } -/* +/*% * proveunsecure walks down from the SEP looking for a break in the - * chain of trust. That occurs when we can prove the DS record does + * chain of trust. That occurs when we can prove the DS record does * not exist at a delegation point or the DS exists at a delegation * but we don't support the algorithm/digest. + * + * If DLV is active and we look for a DLV record at or below the + * point we go insecure. If found we restart the validation process. + * If not found or DLV isn't active we mark the response as a answer. + * + * Returns: + * \li ISC_R_SUCCESS val->event->name is in a unsecure zone + * \li DNS_R_WAIT validation is in progress. + * \li DNS_R_MUSTBESECURE val->event->name is supposed to be secure + * (policy) but we proved that it is unsecure. + * \li DNS_R_NOVALIDSIG + * \li DNS_R_NOVALIDNSEC + * \li DNS_R_NOTINSECURE */ static isc_result_t proveunsecure(dns_validator_t *val, isc_boolean_t resume) { @@ -2253,7 +2434,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { result = dns_keytable_finddeepestmatch(val->keytable, val->event->name, secroot); - + if (result == ISC_R_NOTFOUND) { validator_log(val, ISC_LOG_DEBUG(3), "not beneath secure root"); @@ -2395,8 +2576,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { goto out; return (DNS_R_WAIT); } else if (result == DNS_R_NXDOMAIN || - result == DNS_R_NCACHENXDOMAIN) - { + result == DNS_R_NCACHENXDOMAIN) { /* * This is not a zone cut. Assuming things are * as expected, continue. @@ -2441,7 +2621,10 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) { return (result); } -static isc_result_t +/*% + * Reset state and revalidate the answer using DLV. + */ +static void dlv_validator_start(dns_validator_t *val) { isc_event_t *event; @@ -2455,9 +2638,20 @@ dlv_validator_start(dns_validator_t *val) { event = (isc_event_t *)val->event; isc_task_send(val->task, &event); - return (DNS_R_WAIT); } +/*% + * Start the validation process. + * + * Attempt to valididate the answer based on the category it appears to + * fall in. + * \li 1. secure positive answer. + * \li 2. unsecure positive answer. + * \li 3. a negative answer (secure or unsecure). + * + * Note a answer that appears to be a secure positive answer may actually + * be a unsecure positive answer. + */ static void validator_start(isc_task_t *task, isc_event_t *event) { dns_validator_t *val; @@ -2529,7 +2723,6 @@ validator_start(isc_task_t *task, isc_event_t *event) { validator_log(val, ISC_LOG_DEBUG(3), "attempting negative response validation"); - val->attributes |= VALATTR_NEGATIVE; if (val->event->message->rcode == dns_rcode_nxdomain) { val->attributes |= VALATTR_NEEDNOQNAME; val->attributes |= VALATTR_NEEDNOWILDCARD; @@ -2640,7 +2833,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, cleanup_event: isc_task_detach(&tclone); - isc_event_free((isc_event_t **)&val->event); + isc_event_free(ISC_EVENT_PTR(&event)); cleanup_val: dns_view_weakdetach(&val->view); diff --git a/contrib/bind9/lib/dns/xfrin.c b/contrib/bind9/lib/dns/xfrin.c index 8a824a73ef5e..fdeed14bd6e6 100644 --- a/contrib/bind9/lib/dns/xfrin.c +++ b/contrib/bind9/lib/dns/xfrin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: xfrin.c,v 1.124.2.4.2.12 2005/11/03 23:08:41 marka Exp $ */ +/* $Id: xfrin.c,v 1.124.2.4.2.16 2006/07/19 01:04:24 marka Exp $ */ #include <config.h> @@ -73,6 +73,8 @@ * when the first two (2) response RRs have already been received. */ typedef enum { + XFRST_SOAQUERY, + XFRST_GOTSOA, XFRST_INITIALSOA, XFRST_FIRSTDATA, XFRST_IXFR_DELSOA, @@ -424,6 +426,30 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl, redo: switch (xfr->state) { + case XFRST_SOAQUERY: + if (rdata->type != dns_rdatatype_soa) { + xfrin_log(xfr, ISC_LOG_ERROR, + "non-SOA response to SOA query"); + FAIL(DNS_R_FORMERR); + } + xfr->end_serial = dns_soa_getserial(rdata); + if (!DNS_SERIAL_GT(xfr->end_serial, xfr->ixfr.request_serial) && + !dns_zone_isforced(xfr->zone)) { + xfrin_log(xfr, ISC_LOG_DEBUG(3), + "requested serial %u, " + "master has %u, not updating", + xfr->ixfr.request_serial, xfr->end_serial); + FAIL(DNS_R_UPTODATE); + } + xfr->state = XFRST_GOTSOA; + break; + + case XFRST_GOTSOA: + /* + * Skip other records in the answer section. + */ + break; + case XFRST_INITIALSOA: if (rdata->type != dns_rdatatype_soa) { xfrin_log(xfr, ISC_LOG_ERROR, @@ -589,6 +615,9 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype, (void)dns_zone_getdb(zone, &db); + if (xfrtype == dns_rdatatype_soa || xfrtype == dns_rdatatype_ixfr) + REQUIRE(db != NULL); + CHECK(xfrin_create(mctx, zone, db, task, timermgr, socketmgr, zonename, dns_zone_getclass(zone), xfrtype, masteraddr, sourceaddr, tsigkey, &xfr)); @@ -754,7 +783,10 @@ xfrin_create(isc_mem_t *mctx, dns_diff_init(xfr->mctx, &xfr->diff); xfr->difflen = 0; - xfr->state = XFRST_INITIALSOA; + if (reqtype == dns_rdatatype_soa) + xfr->state = XFRST_SOAQUERY; + else + xfr->state = XFRST_INITIALSOA; /* end_serial */ xfr->nmsg = 0; @@ -797,7 +829,18 @@ xfrin_create(isc_mem_t *mctx, return (ISC_R_SUCCESS); failure: - xfrin_fail(xfr, result, "failed creating transfer context"); + if (xfr->timer != NULL) + isc_timer_detach(&xfr->timer); + if (dns_name_dynamic(&xfr->name)) + dns_name_free(&xfr->name, xfr->mctx); + if (xfr->tsigkey != NULL) + dns_tsigkey_detach(&xfr->tsigkey); + if (xfr->db != NULL) + dns_db_detach(&xfr->db); + isc_task_detach(&xfr->task); + dns_zone_idetach(&xfr->zone); + isc_mem_put(mctx, xfr, sizeof(*xfr)); + return (result); } @@ -808,7 +851,9 @@ xfrin_start(dns_xfrin_ctx_t *xfr) { isc_sockaddr_pf(&xfr->sourceaddr), isc_sockettype_tcp, &xfr->socket)); +#ifndef BROKEN_TCP_BIND_BEFORE_CONNECT CHECK(isc_socket_bind(xfr->socket, &xfr->sourceaddr)); +#endif CHECK(isc_socket_connect(xfr->socket, &xfr->masteraddr, xfr->task, xfrin_connect_done, xfr)); xfr->connects++; @@ -987,7 +1032,9 @@ xfrin_send_request(dns_xfrin_ctx_t *xfr) { CHECK(tuple2msgname(soatuple, msg, &msgsoaname)); dns_message_addname(msg, msgsoaname, DNS_SECTION_AUTHORITY); - } + } else if (xfr->reqtype == dns_rdatatype_soa) + CHECK(dns_db_getsoaserial(xfr->db, NULL, + &xfr->ixfr.request_serial)); xfr->checkid = ISC_TRUE; xfr->id++; @@ -1148,8 +1195,8 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) { try_axfr: dns_message_destroy(&msg); xfrin_reset(xfr); - xfr->reqtype = dns_rdatatype_axfr; - xfr->state = XFRST_INITIALSOA; + xfr->reqtype = dns_rdatatype_soa; + xfr->state = XFRST_SOAQUERY; (void)xfrin_start(xfr); return; } @@ -1246,7 +1293,11 @@ xfrin_recv_done(isc_task_t *task, isc_event_t *ev) { dns_message_destroy(&msg); - if (xfr->state == XFRST_END) { + if (xfr->state == XFRST_GOTSOA) { + xfr->reqtype = dns_rdatatype_axfr; + xfr->state = XFRST_INITIALSOA; + CHECK(xfrin_send_request(xfr)); + } else if (xfr->state == XFRST_END) { /* * Inform the caller we succeeded. */ diff --git a/contrib/bind9/lib/dns/zone.c b/contrib/bind9/lib/dns/zone.c index a993877e91ae..d2a47b072b2f 100644 --- a/contrib/bind9/lib/dns/zone.c +++ b/contrib/bind9/lib/dns/zone.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.333.2.23.2.59 2005/07/29 00:38:33 marka Exp $ */ +/* $Id: zone.c,v 1.333.2.23.2.65 2006/07/19 01:04:24 marka Exp $ */ #include <config.h> @@ -264,6 +264,7 @@ struct dns_zone { #define DNS_ZONEFLG_FLUSH 0x00200000U #define DNS_ZONEFLG_NOEDNS 0x00400000U #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U +#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) @@ -772,12 +773,10 @@ dns_zone_setdbtype(dns_zone_t *zone, nomem: if (new != NULL) { - for (i = 0; i < dbargc; i++) { - if (zone->db_argv[i] != NULL) + for (i = 0; i < dbargc; i++) + if (new[i] != NULL) isc_mem_free(zone->mctx, new[i]); - isc_mem_put(zone->mctx, new, - dbargc * sizeof(*new)); - } + isc_mem_put(zone->mctx, new, dbargc * sizeof(*new)); } result = ISC_R_NOMEMORY; @@ -807,7 +806,7 @@ dns_zone_getview(dns_zone_t *zone) { isc_result_t -dns_zone_setorigin(dns_zone_t *zone, dns_name_t *origin) { +dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) { isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); @@ -998,7 +997,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) { result = isc_file_getmodtime(zone->masterfile, &filetime); if (result == ISC_R_SUCCESS && - isc_time_compare(&filetime, &zone->loadtime) < 0) { + isc_time_compare(&filetime, &zone->loadtime) <= 0) { dns_zone_log(zone, ISC_LOG_DEBUG(1), "skipping load: master file older " "than last load"); @@ -1010,6 +1009,16 @@ zone_load(dns_zone_t *zone, unsigned int flags) { INSIST(zone->db_argc >= 1); + /* + * Built in zones don't need to be reloaded. + */ + if (zone->type == dns_zone_master && + strcmp(zone->db_argv[0], "_builtin") == 0 && + DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { + result = ISC_R_SUCCESS; + goto cleanup; + } + if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) && (strcmp(zone->db_argv[0], "rbt") == 0 || strcmp(zone->db_argv[0], "rbt64") == 0)) { @@ -1210,10 +1219,12 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) { zone_gotreadhandle, load, &zone->readio); if (result != ISC_R_SUCCESS) { - tresult = dns_db_endload(load->db, - &load->callbacks.add_private); - if (result == ISC_R_SUCCESS) - result = tresult; + /* + * We can't report multiple errors so ignore + * the result of dns_db_endload(). + */ + (void)dns_db_endload(load->db, + &load->callbacks.add_private); goto cleanup; } else result = DNS_R_CONTINUE; @@ -1284,14 +1295,12 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, dns_zone_log(zone, ISC_LOG_DEBUG(2), "number of nodes in database: %u", dns_db_nodecount(db)); - zone->loadtime = loadtime; - - dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded"); if (result == DNS_R_SEENINCLUDE) DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE); else DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE); + /* * Apply update log, if any, on initial load. */ @@ -1323,6 +1332,10 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, needdump = ISC_TRUE; } + zone->loadtime = loadtime; + + dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded"); + /* * Obtain ns and soa counts for top of zone. */ @@ -1821,7 +1834,7 @@ dns_zone_getoptions(dns_zone_t *zone) { } isc_result_t -dns_zone_setxfrsource4(dns_zone_t *zone, isc_sockaddr_t *xfrsource) { +dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -1838,7 +1851,7 @@ dns_zone_getxfrsource4(dns_zone_t *zone) { } isc_result_t -dns_zone_setxfrsource6(dns_zone_t *zone, isc_sockaddr_t *xfrsource) { +dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -1855,7 +1868,9 @@ dns_zone_getxfrsource6(dns_zone_t *zone) { } isc_result_t -dns_zone_setaltxfrsource4(dns_zone_t *zone, isc_sockaddr_t *altxfrsource) { +dns_zone_setaltxfrsource4(dns_zone_t *zone, + const isc_sockaddr_t *altxfrsource) +{ REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -1872,7 +1887,9 @@ dns_zone_getaltxfrsource4(dns_zone_t *zone) { } isc_result_t -dns_zone_setaltxfrsource6(dns_zone_t *zone, isc_sockaddr_t *altxfrsource) { +dns_zone_setaltxfrsource6(dns_zone_t *zone, + const isc_sockaddr_t *altxfrsource) +{ REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -1889,7 +1906,7 @@ dns_zone_getaltxfrsource6(dns_zone_t *zone) { } isc_result_t -dns_zone_setnotifysrc4(dns_zone_t *zone, isc_sockaddr_t *notifysrc) { +dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -1906,7 +1923,7 @@ dns_zone_getnotifysrc4(dns_zone_t *zone) { } isc_result_t -dns_zone_setnotifysrc6(dns_zone_t *zone, isc_sockaddr_t *notifysrc) { +dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) { REQUIRE(DNS_ZONE_VALID(zone)); LOCK_ZONE(zone); @@ -1923,7 +1940,7 @@ dns_zone_getnotifysrc6(dns_zone_t *zone) { } isc_result_t -dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *notify, +dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify, isc_uint32_t count) { isc_sockaddr_t *new; @@ -1953,7 +1970,7 @@ dns_zone_setalsonotify(dns_zone_t *zone, isc_sockaddr_t *notify, } isc_result_t -dns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, +dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters, isc_uint32_t count) { isc_result_t result; @@ -1963,8 +1980,10 @@ dns_zone_setmasters(dns_zone_t *zone, isc_sockaddr_t *masters, } isc_result_t -dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters, - dns_name_t **keynames, isc_uint32_t count) +dns_zone_setmasterswithkeys(dns_zone_t *zone, + const isc_sockaddr_t *masters, + dns_name_t **keynames, + isc_uint32_t count) { isc_sockaddr_t *new; isc_result_t result = ISC_R_SUCCESS; @@ -2274,6 +2293,7 @@ dns_zone_refresh(dns_zone_t *zone) { isc_interval_t i; isc_uint32_t oldflags; unsigned int j; + isc_result_t result; REQUIRE(DNS_ZONE_VALID(zone)); @@ -2307,7 +2327,11 @@ dns_zone_refresh(dns_zone_t *zone) { */ isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4), 0); - isc_time_nowplusinterval(&zone->refreshtime, &i); + result = isc_time_nowplusinterval(&zone->refreshtime, &i); + if (result |= ISC_R_SUCCESS) + dns_zone_log(zone, ISC_LOG_WARNING, + "isc_time_nowplusinterval() failed: %s", + dns_result_totext(result)); /* * When lacking user-specified timer values from the SOA, @@ -3535,8 +3559,13 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { "master %s exceeded (source %s)", master, source); /* Try with slave with TCP. */ - if (zone->type == dns_zone_slave) + if (zone->type == dns_zone_slave) { + LOCK_ZONE(zone); + DNS_ZONE_SETFLAG(zone, + DNS_ZONEFLG_SOABEFOREAXFR); + UNLOCK_ZONE(zone); goto tcp_transfer; + } } else dns_zone_log(zone, ISC_LOG_INFO, "refresh: failure trying master " @@ -3603,6 +3632,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { "initiating TCP zone xfer " "for master %s (source %s)", master, source); + LOCK_ZONE(zone); + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); + UNLOCK_ZONE(zone); goto tcp_transfer; } else { INSIST(zone->type == dns_zone_stub); @@ -5515,6 +5547,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { LOCK_ZONE(zone); INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); TIME_NOW(&now); switch (result) { @@ -5868,7 +5901,10 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) { "IXFR disabled, " "requesting AXFR from %s", mastertext); - xfrtype = dns_rdatatype_axfr; + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) + xfrtype = dns_rdatatype_soa; + else + xfrtype = dns_rdatatype_axfr; } else { dns_zone_log(zone, ISC_LOG_DEBUG(1), "requesting IXFR from %s", |
