diff options
author | Internet Software Consortium, Inc <@isc.org> | 2012-01-18 10:10:47 -0700 |
---|---|---|
committer | Internet Software Consortium, Inc <@isc.org> | 2012-01-18 10:10:47 -0700 |
commit | 8b08ed79737eaec2fd64fbecce719fc5d91c0f48 (patch) | |
tree | 095e2e7eb68fcd1d4401915a8b8e65fc69bbe917 /lib/dns | |
parent | 52a7f63e4e1a5cc6705c88c2090499b2caaa0805 (diff) | |
download | bind9-8b08ed79737eaec2fd64fbecce719fc5d91c0f48.tar.gz |
9.9.0b2
Diffstat (limited to 'lib/dns')
-rw-r--r-- | lib/dns/api | 4 | ||||
-rw-r--r-- | lib/dns/include/dns/Makefile.in | 6 | ||||
-rw-r--r-- | lib/dns/include/dns/dnssec.h | 5 | ||||
-rw-r--r-- | lib/dns/include/dns/resolver.h | 5 | ||||
-rw-r--r-- | lib/dns/include/dns/rriterator.h | 88 | ||||
-rw-r--r-- | lib/dns/include/dns/zone.h | 28 | ||||
-rw-r--r-- | lib/dns/masterdump.c | 55 | ||||
-rw-r--r-- | lib/dns/rbtdb.c | 113 | ||||
-rw-r--r-- | lib/dns/rdata.c | 80 | ||||
-rw-r--r-- | lib/dns/rdata/generic/null_10.c | 10 | ||||
-rw-r--r-- | lib/dns/resolver.c | 86 | ||||
-rw-r--r-- | lib/dns/rriterator.c | 10 | ||||
-rw-r--r-- | lib/dns/tests/zonemgr_test.c | 71 | ||||
-rw-r--r-- | lib/dns/tsig.c | 4 | ||||
-rw-r--r-- | lib/dns/update.c | 8 | ||||
-rw-r--r-- | lib/dns/validator.c | 10 | ||||
-rw-r--r-- | lib/dns/win32/libdns.def | 2 | ||||
-rw-r--r-- | lib/dns/zone.c | 162 |
18 files changed, 538 insertions, 209 deletions
diff --git a/lib/dns/api b/lib/dns/api index 3d2fa6ef..580ddcfd 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 90 +LIBINTERFACE = 91 LIBREVISION = 0 -LIBAGE = 0 +LIBAGE = 1 diff --git a/lib/dns/include/dns/Makefile.in b/lib/dns/include/dns/Makefile.in index 5161b0ef..db689092 100644 --- a/lib/dns/include/dns/Makefile.in +++ b/lib/dns/include/dns/Makefile.in @@ -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.59 2011-03-01 23:48:07 tbox Exp $ +# $Id: Makefile.in,v 1.60 2011-11-14 18:32:34 each Exp $ srcdir = @srcdir@ VPATH = @srcdir@ @@ -22,8 +22,8 @@ top_srcdir = @top_srcdir@ @BIND9_VERSION@ HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h cert.h compress.h \ - db.h dbiterator.h dbtable.h diff.h dispatch.h dlz.h \ - dnssec.h ds.h events.h fixedname.h iptable.h journal.h \ + clientinfo.h db.h dbiterator.h dbtable.h diff.h dispatch.h \ + dlz.h dnssec.h ds.h events.h fixedname.h iptable.h journal.h \ keyflags.h keytable.h keyvalues.h lib.h log.h \ master.h masterdump.h message.h name.h ncache.h nsec.h \ peer.h portlist.h private.h rbt.h rcode.h \ diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h index 696e9951..25169d1a 100644 --- a/lib/dns/include/dns/dnssec.h +++ b/lib/dns/include/dns/dnssec.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: dnssec.h,v 1.46 2011-05-06 23:47:29 tbox Exp $ */ +/* $Id: dnssec.h,v 1.47 2011-11-03 02:54:47 each Exp $ */ #ifndef DNS_DNSSEC_H #define DNS_DNSSEC_H 1 @@ -32,6 +32,9 @@ ISC_LANG_BEGINDECLS +/*%< Maximum number of keys supported in a zone. */ +#define DNS_MAXZONEKEYS 32 + /* * Indicates how the signer found this key: in the key repository, at the * zone apex, or specified by the user. diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index 460edc2a..f6cd6325 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.h,v 1.69 2011-02-03 12:18:11 tbox Exp $ */ +/* $Id: resolver.h,v 1.71 2011-11-16 22:18:52 marka Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -96,6 +96,9 @@ typedef struct dns_fetchevent { #define DNS_FETCHOPT_EDNS512 0x40 /*%< Advertise a 512 byte UDP buffer. */ #define DNS_FETCHOPT_WANTNSID 0x80 /*%< Request NSID */ +#define DNS_FETCHOPT_CACHENOEDNS 0x100 /*%< This is a candidate + for setting NOEDNS + in adb. */ #define DNS_FETCHOPT_EDNSVERSIONSET 0x00800000 #define DNS_FETCHOPT_EDNSVERSIONMASK 0xff000000 diff --git a/lib/dns/include/dns/rriterator.h b/lib/dns/include/dns/rriterator.h index 00873492..ca86c47e 100644 --- a/lib/dns/include/dns/rriterator.h +++ b/lib/dns/include/dns/rriterator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rriterator.h,v 1.2 2009-06-30 02:52:32 each Exp $ */ +/* $Id: rriterator.h,v 1.4 2011-11-01 23:47:00 tbox Exp $ */ #ifndef DNS_RRITERATOR_H #define DNS_RRITERATOR_H 1 @@ -77,26 +77,110 @@ typedef struct dns_rriterator { isc_result_t dns_rriterator_init(dns_rriterator_t *it, dns_db_t *db, dns_dbversion_t *ver, isc_stdtime_t now); +/*% + * Initialize an rriterator; sets the cursor to the origin node + * of the database. + * + * Requires: + * + * \li 'db' is a valid database. + * + * Returns: + * + * \li #ISC_R_SUCCESS + * \li #ISC_R_NOMEMORY + */ isc_result_t dns_rriterator_first(dns_rriterator_t *it); +/*%< + * Move the rriterator cursor to the first rdata in the database. + * + * Requires: + *\li 'it' is a valid, initialized rriterator + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE There are no rdata in the set. + */ isc_result_t dns_rriterator_nextrrset(dns_rriterator_t *it); +/*%< + * Move the rriterator cursor to the next rrset in the database, + * skipping over any remaining records that have the same rdatatype + * as the current one. + * + * Requires: + *\li 'it' is a valid, initialized rriterator + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE No more rrsets in the database + */ isc_result_t dns_rriterator_next(dns_rriterator_t *it); +/*%< + * Move the rriterator cursor to the next rrset in the database, + * skipping over any remaining records that have the same rdatatype + * as the current one. + * + * Requires: + *\li 'it' is a valid, initialized rriterator + * + * Returns: + *\li #ISC_R_SUCCESS + *\li #ISC_R_NOMORE No more records in the database + */ void dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name, isc_uint32_t *ttl, dns_rdataset_t **rdataset, dns_rdata_t **rdata); +/*%< + * Make '*name' refer to the current name. If 'rdataset' is not NULL, + * make '*rdataset' refer to the current * rdataset. If '*rdata' is not + * NULL, make '*rdata' refer to the current record. + * + * Requires: + *\li '*name' is a valid name object + *\li 'rdataset' is NULL or '*rdataset' is NULL + *\li 'rdata' is NULL or '*rdata' is NULL + * + * Ensures: + *\li 'rdata' refers to the rdata at the rdata cursor location of + *\li 'rdataset'. + */ void dns_rriterator_pause(dns_rriterator_t *it); +/*%< + * Pause rriterator. Frees any locks held by the database iterator. + * Callers should use this routine any time they are not going to + * execute another rriterator method in the immediate future. + * + * Requires: + *\li 'it' is a valid iterator. + * + * Ensures: + *\li Any database locks being held for efficiency of iterator access are + * released. + */ void dns_rriterator_destroy(dns_rriterator_t *it); +/*%< + * Shut down and free resources in rriterator 'it'. + * + * Requires: + * + *\li 'it' is a valid iterator. + * + * Ensures: + * + *\li All resources used by the rriterator are freed. + */ ISC_LANG_ENDDECLS diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h index 8725cb7d..f9e534b3 100644 --- a/lib/dns/include/dns/zone.h +++ b/lib/dns/include/dns/zone.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.h,v 1.196 2011-10-28 06:20:06 each Exp $ */ +/* $Id: zone.h,v 1.197 2011-11-04 05:51:01 each Exp $ */ #ifndef DNS_ZONE_H #define DNS_ZONE_H 1 @@ -1607,6 +1607,32 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, *\li 'local' to be a valid sockaddr. */ +isc_boolean_t +dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, + isc_sockaddr_t *local, isc_time_t *now); +/*%< + * Returns ISC_TRUE if the given local/remote address pair + * is found in the zone maanger's unreachable cache. + * + * Requires: + *\li 'zmgr' to be a valid zone manager. + *\li 'remote' to be a valid sockaddr. + *\li 'local' to be a valid sockaddr. + *\li 'now' != NULL + */ + +void +dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, + isc_sockaddr_t *local); +/*%< + * Remove the pair of addresses from the unreachable cache. + * + * Requires: + *\li 'zmgr' to be a valid zone manager. + *\li 'remote' to be a valid sockaddr. + *\li 'local' to be a valid sockaddr. + */ + void dns_zone_forcereload(dns_zone_t *zone); /*%< diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index 61a9cfc1..93e07054 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: masterdump.c,v 1.109 2011-09-07 19:11:13 each Exp $ */ +/* $Id: masterdump.c,v 1.110 2011-11-07 23:16:31 each Exp $ */ /*! \file */ @@ -1150,20 +1150,52 @@ dns_dumpctx_cancel(dns_dumpctx_t *dctx) { } static isc_result_t -closeandrename(FILE *f, isc_result_t result, const char *temp, const char *file) -{ - isc_result_t tresult; +flushandsync(FILE *f, isc_result_t result, const char *temp) { isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS); if (result == ISC_R_SUCCESS) - result = isc_stdio_sync(f); + result = isc_stdio_flush(f); if (result != ISC_R_SUCCESS && logit) { - isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, - DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, - "dumping master file: %s: fsync: %s", - temp, isc_result_totext(result)); + if (temp != NULL) + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to master file: %s: flush: %s", + temp, isc_result_totext(result)); + else + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to stream: flush: %s", + isc_result_totext(result)); logit = ISC_FALSE; } + + if (result == ISC_R_SUCCESS) + result = isc_stdio_sync(f); + if (result != ISC_R_SUCCESS && logit) { + if (temp != NULL) + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to master file: %s: fsync: %s", + temp, isc_result_totext(result)); + else + isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR, + "dumping to stream: fsync: %s", + isc_result_totext(result)); + } + return (result); +} + +static isc_result_t +closeandrename(FILE *f, isc_result_t result, const char *temp, const char *file) +{ + isc_result_t tresult; + isc_boolean_t logit = ISC_TF(result == ISC_R_SUCCESS); + + result = flushandsync(f, result, temp); + if (result != ISC_R_SUCCESS) + logit = ISC_FALSE; + tresult = isc_stdio_close(f); if (result == ISC_R_SUCCESS) result = tresult; @@ -1211,7 +1243,8 @@ dump_quantum(isc_task_t *task, isc_event_t *event) { dctx->tmpfile, dctx->file); if (tresult != ISC_R_SUCCESS && result == ISC_R_SUCCESS) result = tresult; - } + } else + result = flushandsync(dctx->f, result, NULL); (dctx->done)(dctx->done_arg, result); isc_event_free(&event); dns_dumpctx_detach(&dctx); @@ -1544,6 +1577,8 @@ dns_master_dumptostream2(isc_mem_t *mctx, dns_db_t *db, result = dumptostreaminc(dctx); INSIST(result != DNS_R_CONTINUE); dns_dumpctx_detach(&dctx); + + result = flushandsync(f, result, NULL); return (result); } diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 8fc81e1f..fbbdcb93 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.319 2011-10-13 01:32:33 vjs Exp $ */ +/* $Id: rbtdb.c,v 1.322 2011-11-18 18:40:31 each Exp $ */ /*! \file */ @@ -1616,6 +1616,7 @@ new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { unsigned int lockrefs, noderefs; isc_refcount_t *lockref; + INSIST(!ISC_LINK_LINKED(node, deadlink)); dns_rbtnode_refincrement0(node, &noderefs); if (noderefs == 1) { /* this is the first reference to the node */ lockref = &rbtdb->node_locks[node->locknum].references; @@ -1642,8 +1643,6 @@ reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, isc_boolean_t need_relock = ISC_FALSE; NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); - new_reference(rbtdb, node); - NODE_WEAKLOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_read); if (ISC_LINK_LINKED(node, deadlink)) @@ -1664,7 +1663,7 @@ reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, NODE_WEAKUNLOCK(&rbtdb->node_locks[node->locknum].lock, isc_rwlocktype_write); } - + new_reference(rbtdb, node); NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); } @@ -1830,6 +1829,7 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, ISC_LOG_INFO, "decrement_reference: failed to " "allocate pruning event"); + INSIST(node->data == NULL); INSIST(!ISC_LINK_LINKED(node, deadlink)); ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink); @@ -1853,6 +1853,7 @@ decrement_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node, delete_node(rbtdb, node); } } else if (dns_rbtnode_refcurrent(node) == 0) { + INSIST(node->data == NULL); INSIST(!ISC_LINK_LINKED(node, deadlink)); ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node, deadlink); } else @@ -1924,11 +1925,10 @@ prune_tree(isc_task_t *task, isc_event_t *event) { * from the list beforehand as we do in * reactivate_node(). */ - new_reference(rbtdb, parent); - if (ISC_LINK_LINKED(parent, deadlink)) { + if (ISC_LINK_LINKED(parent, deadlink)) ISC_LIST_UNLINK(rbtdb->deadnodes[locknum], parent, deadlink); - } + new_reference(rbtdb, parent); } else parent = NULL; @@ -2500,20 +2500,19 @@ add_empty_wildcards(dns_rbtdb_t *rbtdb, dns_name_t *name) { } static isc_result_t -findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) +findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree, dns_name_t *name, + isc_boolean_t create, dns_dbnode_t **nodep) { - dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; dns_rbtnode_t *node = NULL; dns_name_t nodename; isc_result_t result; isc_rwlocktype_t locktype = isc_rwlocktype_read; - REQUIRE(VALID_RBTDB(rbtdb)); + INSIST(tree == rbtdb->tree || tree == rbtdb->nsec3); dns_name_init(&nodename, NULL); RWLOCK(&rbtdb->tree_lock, locktype); - result = dns_rbt_findnode(rbtdb->tree, name, NULL, &node, NULL, + result = dns_rbt_findnode(tree, name, NULL, &node, NULL, DNS_RBTFIND_EMPTYDATA, NULL, NULL); if (result != ISC_R_SUCCESS) { RWUNLOCK(&rbtdb->tree_lock, locktype); @@ -2529,10 +2528,10 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, locktype = isc_rwlocktype_write; RWLOCK(&rbtdb->tree_lock, locktype); node = NULL; - result = dns_rbt_addnode(rbtdb->tree, name, &node); + result = dns_rbt_addnode(tree, name, &node); if (result == ISC_R_SUCCESS) { #ifdef BIND9 - if (rbtdb->rpz_cidr != NULL) { + if (tree == rbtdb->tree && rbtdb->rpz_cidr != NULL) { dns_fixedname_t fnamef; dns_name_t *fname; @@ -2549,20 +2548,28 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, node->locknum = dns_name_hash(&nodename, ISC_TRUE) % rbtdb->node_lock_count; #endif - add_empty_wildcards(rbtdb, name); - - if (dns_name_iswildcard(name)) { - result = add_wildcard_magic(rbtdb, name); - if (result != ISC_R_SUCCESS) { - RWUNLOCK(&rbtdb->tree_lock, locktype); - return (result); + if (tree == rbtdb->tree) { + add_empty_wildcards(rbtdb, name); + + if (dns_name_iswildcard(name)) { + result = add_wildcard_magic(rbtdb, name); + if (result != ISC_R_SUCCESS) { + RWUNLOCK(&rbtdb->tree_lock, locktype); + return (result); + } } } + if (tree == rbtdb->nsec3) + node->nsec = DNS_RBT_NSEC_NSEC3; } else if (result != ISC_R_EXISTS) { RWUNLOCK(&rbtdb->tree_lock, locktype); return (result); } } + + if (tree == rbtdb->nsec3) + INSIST(node->nsec == DNS_RBT_NSEC_NSEC3); + reactivate_node(rbtdb, node, locktype); RWUNLOCK(&rbtdb->tree_lock, locktype); @@ -2572,60 +2579,25 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, } static isc_result_t -findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create, - dns_dbnode_t **nodep) +findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_dbnode_t **nodep) { dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - dns_rbtnode_t *node = NULL; - dns_name_t nodename; - isc_result_t result; - isc_rwlocktype_t locktype = isc_rwlocktype_read; REQUIRE(VALID_RBTDB(rbtdb)); - dns_name_init(&nodename, NULL); - RWLOCK(&rbtdb->tree_lock, locktype); - result = dns_rbt_findnode(rbtdb->nsec3, name, NULL, &node, NULL, - DNS_RBTFIND_EMPTYDATA, NULL, NULL); - if (result != ISC_R_SUCCESS) { - RWUNLOCK(&rbtdb->tree_lock, locktype); - if (!create) { - if (result == DNS_R_PARTIALMATCH) - result = ISC_R_NOTFOUND; - return (result); - } - /* - * It would be nice to try to upgrade the lock instead of - * unlocking then relocking. - */ - locktype = isc_rwlocktype_write; - RWLOCK(&rbtdb->tree_lock, locktype); - node = NULL; - result = dns_rbt_addnode(rbtdb->nsec3, name, &node); - if (result == ISC_R_SUCCESS) { - dns_rbt_namefromnode(node, &nodename); -#ifdef DNS_RBT_USEHASH - node->locknum = node->hashval % rbtdb->node_lock_count; -#else - node->locknum = dns_name_hash(&nodename, ISC_TRUE) % - rbtdb->node_lock_count; -#endif - node->nsec = DNS_RBT_NSEC_NSEC3; - } else if (result != ISC_R_EXISTS) { - RWUNLOCK(&rbtdb->tree_lock, locktype); - return (result); - } - } else { - INSIST(node->nsec == DNS_RBT_NSEC_NSEC3); - } - NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock); - new_reference(rbtdb, node); - NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock); - RWUNLOCK(&rbtdb->tree_lock, locktype); + return (findnodeintree(rbtdb, rbtdb->tree, name, create, nodep)); +} - *nodep = (dns_dbnode_t *)node; +static isc_result_t +findnsec3node(dns_db_t *db, dns_name_t *name, isc_boolean_t create, + dns_dbnode_t **nodep) +{ + dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db; - return (ISC_R_SUCCESS); + REQUIRE(VALID_RBTDB(rbtdb)); + + return (findnodeintree(rbtdb, rbtdb->nsec3, name, create, nodep)); } static isc_result_t @@ -4772,6 +4744,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type, dns_db_attachnode(db, node, &st->m.node); } dns_db_attach(db, &st->m.db); + st->m.version = version; dns_zone_attach(zone, &st->m.zone); if (dns_rdataset_isassociated(&zrdataset)) dns_rdataset_disassociate(&zrdataset); @@ -5081,7 +5054,7 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, rdataset); if (need_headerupdate(found, search.now)) update = found; - if (foundsig != NULL) { + if (!NEGATIVE(found) && foundsig != NULL) { bind_rdataset(search.rbtdb, node, foundsig, search.now, sigrdataset); if (need_headerupdate(foundsig, search.now)) @@ -5714,7 +5687,7 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version, } if (found != NULL) { bind_rdataset(rbtdb, rbtnode, found, now, rdataset); - if (foundsig != NULL) + if (!NEGATIVE(found) && foundsig != NULL) bind_rdataset(rbtdb, rbtnode, foundsig, now, sigrdataset); } diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c index 6710a1cf..08a12619 100644 --- a/lib/dns/rdata.c +++ b/lib/dns/rdata.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdata.c,v 1.213 2011-03-11 06:11:24 marka Exp $ */ +/* $Id: rdata.c,v 1.214 2011-11-02 01:01:52 marka Exp $ */ /*! \file */ @@ -217,6 +217,10 @@ warn_badmx(isc_token_t *token, isc_lex_t *lexer, static isc_uint16_t uint16_consume_fromregion(isc_region_t *region); +static isc_result_t +unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, + isc_buffer_t *target); + static inline int getquad(const void *src, struct in_addr *dst, isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks) @@ -692,13 +696,53 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass, } static isc_result_t +unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, + isc_buffer_t *target) +{ + isc_result_t result; + char buf[sizeof("65535")]; + isc_region_t sr; + + strlcpy(buf, "\\# ", sizeof(buf)); + result = str_totext(buf, target); + if (result != ISC_R_SUCCESS) + return (result); + + dns_rdata_toregion(rdata, &sr); + INSIST(sr.length < 65536); + snprintf(buf, sizeof(buf), "%u", sr.length); + result = str_totext(buf, target); + if (result != ISC_R_SUCCESS) + return (result); + + if (sr.length != 0U) { + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + result = str_totext(" ( ", target); + else + result = str_totext(" ", target); + + if (result != ISC_R_SUCCESS) + return (result); + + if (tctx->width == 0) /* No splitting */ + result = isc_hex_totext(&sr, 0, "", target); + else + result = isc_hex_totext(&sr, tctx->width - 2, + tctx->linebreak, + target); + if (result == ISC_R_SUCCESS && + (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + result = str_totext(" )", target); + } + return (result); +} + +static isc_result_t rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, isc_buffer_t *target) { isc_result_t result = ISC_R_NOTIMPLEMENTED; isc_boolean_t use_default = ISC_FALSE; - char buf[sizeof("65535")]; - isc_region_t sr; REQUIRE(rdata != NULL); REQUIRE(tctx->origin == NULL || @@ -714,34 +758,8 @@ rdata_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx, TOTEXTSWITCH - if (use_default) { - strlcpy(buf, "\\# ", sizeof(buf)); - result = str_totext(buf, target); - INSIST(result == ISC_R_SUCCESS); - dns_rdata_toregion(rdata, &sr); - INSIST(sr.length < 65536); - snprintf(buf, sizeof(buf), "%u", sr.length); - result = str_totext(buf, target); - if (sr.length != 0 && result == ISC_R_SUCCESS) { - if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - result = str_totext(" ( ", target); - else - result = str_totext(" ", target); - - if (result != ISC_R_SUCCESS) - return (result); - - if (tctx->width == 0) /* No splitting */ - result = isc_hex_totext(&sr, 0, "", target); - else - result = isc_hex_totext(&sr, tctx->width - 2, - tctx->linebreak, - target); - if (result == ISC_R_SUCCESS && - (tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) - result = str_totext(" )", target); - } - } + if (use_default) + result = unknown_totext(rdata, tctx, target); return (result); } diff --git a/lib/dns/rdata/generic/null_10.c b/lib/dns/rdata/generic/null_10.c index e6d9b9ad..5e5bf0fd 100644 --- a/lib/dns/rdata/generic/null_10.c +++ b/lib/dns/rdata/generic/null_10.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: null_10.c,v 1.44 2009-12-04 22:06:37 tbox Exp $ */ +/* $Id: null_10.c,v 1.46 2011-11-02 23:46:24 tbox Exp $ */ /* Reviewed: Thu Mar 16 13:57:50 PST 2000 by explorer */ @@ -43,11 +43,7 @@ static inline isc_result_t totext_null(ARGS_TOTEXT) { REQUIRE(rdata->type == 10); - UNUSED(rdata); - UNUSED(tctx); - UNUSED(target); - - return (DNS_R_SYNTAX); + return (unknown_totext(rdata, tctx, target)); } static inline isc_result_t diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 49823d31..6b64461b 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.437 2011-10-27 23:46:31 tbox Exp $ */ +/* $Id: resolver.c,v 1.442 2011-11-16 22:18:52 marka Exp $ */ /*! \file */ @@ -453,7 +453,7 @@ static isc_result_t ncache_adderesult(dns_message_t *message, dns_rdataset_t *ardataset, isc_result_t *eresultp); static void validated(isc_task_t *task, isc_event_t *event); -static void maybe_destroy(fetchctx_t *fctx); +static void maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked); static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, badnstype_t badtype); @@ -747,7 +747,7 @@ resquery_destroy(resquery_t **queryp) { query->fctx->nqueries--; if (SHUTTINGDOWN(query->fctx)) - maybe_destroy(query->fctx); /* Locks bucket. */ + maybe_destroy(query->fctx, ISC_FALSE); /* Locks bucket. */ query->magic = 0; isc_mem_put(query->mctx, query, sizeof(*query)); *queryp = NULL; @@ -1564,9 +1564,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_dispatch_detach(&query->dispatch); cleanup_query: - query->magic = 0; - isc_mem_put(res->buckets[fctx->bucketnum].mctx, - query, sizeof(*query)); + if (query->connects == 0) { + query->magic = 0; + isc_mem_put(res->buckets[fctx->bucketnum].mctx, + query, sizeof(*query)); + } stop_idle_timer: RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS); @@ -1684,6 +1686,7 @@ resquery_send(resquery_t *query) { dns_compress_t cctx; isc_boolean_t cleanup_cctx = ISC_FALSE; isc_boolean_t secure_domain; + isc_boolean_t connecting = ISC_FALSE; unsigned int edns_fetchopt_flag; isc_stdtime_t now; @@ -1843,6 +1846,7 @@ resquery_send(resquery_t *query) { fctx->timeouts > MAX_EDNS0_TIMEOUTS) && (query->options & DNS_FETCHOPT_NOEDNS0) == 0) { query->options |= DNS_FETCHOPT_NOEDNS0; + query->options |= DNS_FETCHOPT_CACHENOEDNS; fctx->reason = "disabling EDNS"; } else if ((triededns(fctx, &query->addrinfo->sockaddr) || fctx->timeouts >= 1) && @@ -1914,21 +1918,18 @@ resquery_send(resquery_t *query) { goto cleanup_message; } - if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) + if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) { add_triededns(fctx, &query->addrinfo->sockaddr); - if ((query->options & DNS_FETCHOPT_EDNS512) != 0) - add_triededns512(fctx, &query->addrinfo->sockaddr); + if ((query->options & DNS_FETCHOPT_EDNS512) != 0) + add_triededns512(fctx, &query->addrinfo->sockaddr); + } /* - * Clear CD if EDNS is not in use and set NOEDNS0 in adb. + * Clear CD if EDNS is not in use. */ - if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) { + if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD; - dns_adb_changeflags(fctx->adb, query->addrinfo, - DNS_FETCHOPT_NOEDNS0, - DNS_FETCHOPT_NOEDNS0); - } /* * Add TSIG record tailored to the current recipient. @@ -1996,6 +1997,7 @@ resquery_send(resquery_t *query) { query); if (result != ISC_R_SUCCESS) goto cleanup_message; + connecting = ISC_TRUE; query->connects++; } } @@ -2007,8 +2009,19 @@ resquery_send(resquery_t *query) { */ result = isc_socket_sendto(socket, &r, task, resquery_senddone, query, address, NULL); - if (result != ISC_R_SUCCESS) + if (result != ISC_R_SUCCESS) { + if (connecting) { + /* + * This query is still connecting. + * Mark it as canceled so that it will just be + * cleaned up when the connected event is received. + * Keep fctx around until the event is processed. + */ + query->fctx->nqueries++; + query->attributes |= RESQUERY_ATTR_CANCELED; + } goto cleanup_message; + } query->sends++; @@ -3905,7 +3918,7 @@ clone_results(fetchctx_t *fctx) { * '*fctx' is shutting down. */ static void -maybe_destroy(fetchctx_t *fctx) { +maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) { unsigned int bucketnum; isc_boolean_t bucket_empty = ISC_FALSE; dns_resolver_t *res = fctx->res; @@ -3923,10 +3936,12 @@ maybe_destroy(fetchctx_t *fctx) { } bucketnum = fctx->bucketnum; - LOCK(&res->buckets[bucketnum].lock); + if (!locked) + LOCK(&res->buckets[bucketnum].lock); if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) bucket_empty = fctx_destroy(fctx); - UNLOCK(&res->buckets[bucketnum].lock); + if (!locked) + UNLOCK(&res->buckets[bucketnum].lock); if (bucket_empty) empty_bucket(res); @@ -3971,6 +3986,8 @@ validated(isc_task_t *task, isc_event_t *event) { FCTXTRACE("received validation completion event"); + LOCK(&fctx->res->buckets[fctx->bucketnum].lock); + ISC_LIST_UNLINK(fctx->validators, vevent->validator, link); fctx->validator = NULL; @@ -3992,12 +4009,11 @@ validated(isc_task_t *task, isc_event_t *event) { * so, destroy the fctx. */ if (SHUTTINGDOWN(fctx) && !sentresponse) { - maybe_destroy(fctx); /* Locks bucket. */ + maybe_destroy(fctx, ISC_TRUE); + UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); goto cleanup_event; } - LOCK(&fctx->res->buckets[fctx->bucketnum].lock); - isc_stdtime_get(&now); /* @@ -4210,7 +4226,7 @@ validated(isc_task_t *task, isc_event_t *event) { dns_db_detachnode(fctx->cache, &node); UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); if (SHUTTINGDOWN(fctx)) - maybe_destroy(fctx); /* Locks bucket. */ + maybe_destroy(fctx, ISC_FALSE); /* Locks bucket. */ goto cleanup_event; } @@ -4301,7 +4317,6 @@ validated(isc_task_t *task, isc_event_t *event) { dns_db_detachnode(fctx->cache, &node); UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); - fctx_done(fctx, result, __LINE__); /* Locks bucket. */ cleanup_event: @@ -6565,6 +6580,25 @@ resquery_response(isc_task_t *task, isc_event_t *event) { } } goto done; +#if 0 + } else if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0 && + (query->options & DNS_FETCHOPT_CACHENOEDNS) != 0 && + triededns512(fctx, &query->addrinfo->sockaddr)) { + char addrbuf[ISC_SOCKADDR_FORMATSIZE]; + isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, + sizeof(addrbuf)); + /* + * We had a successful response to a DNS_FETCHOPT_NOEDNS0 + * query. + */ + isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, + DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, + "%s: setting NOEDNS flag in adb cache for '%s'", + fctx->info, addrbuf); + dns_adb_changeflags(fctx->adb, query->addrinfo, + DNS_FETCHOPT_NOEDNS0, + DNS_FETCHOPT_NOEDNS0); +#endif } message = fctx->rmessage; @@ -6708,6 +6742,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) { char addrbuf[ISC_SOCKADDR_FORMATSIZE]; isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf, sizeof(addrbuf)); + isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED, + DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO, + "%s: changed rcode: setting NOEDNS flag in " + "adb cache for '%s'", fctx->info, addrbuf); dns_adb_changeflags(fctx->adb, query->addrinfo, DNS_FETCHOPT_NOEDNS0, DNS_FETCHOPT_NOEDNS0); diff --git a/lib/dns/rriterator.c b/lib/dns/rriterator.c index 31d67afd..2c683bce 100644 --- a/lib/dns/rriterator.c +++ b/lib/dns/rriterator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2011 Internet Systems Consortium, Inc. ("ISC") * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rriterator.c,v 1.2 2009-06-30 02:52:32 each Exp $ */ +/* $Id: rriterator.c,v 1.4 2011-11-01 23:47:00 tbox Exp $ */ /*! \file */ @@ -187,6 +187,8 @@ dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name, REQUIRE(name != NULL && *name == NULL); REQUIRE(VALID_RRITERATOR(it)); REQUIRE(it->result == ISC_R_SUCCESS); + REQUIRE(rdataset == NULL || *rdataset == NULL); + REQUIRE(rdata == NULL || *rdata == NULL); *name = dns_fixedname_name(&it->fixedname); *ttl = it->rdataset.ttl; @@ -194,9 +196,9 @@ dns_rriterator_current(dns_rriterator_t *it, dns_name_t **name, dns_rdata_reset(&it->rdata); dns_rdataset_current(&it->rdataset, &it->rdata); - if (rdataset) + if (rdataset != NULL) *rdataset = &it->rdataset; - if (rdata) + if (rdata != NULL) *rdata = &it->rdata; } diff --git a/lib/dns/tests/zonemgr_test.c b/lib/dns/tests/zonemgr_test.c index b00165cb..3400c6b4 100644 --- a/lib/dns/tests/zonemgr_test.c +++ b/lib/dns/tests/zonemgr_test.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zonemgr_test.c,v 1.3 2011-09-02 21:15:37 each Exp $ */ +/* $Id: zonemgr_test.c,v 1.4 2011-11-04 05:51:02 each Exp $ */ /*! \file */ @@ -110,12 +110,79 @@ ATF_TC_BODY(zonemgr_managezone, tc) { dns_test_end(); } +ATF_TC(zonemgr_unreachable); +ATF_TC_HEAD(zonemgr_unreachable, tc) { + atf_tc_set_md_var(tc, "descr", "manage and release a zone"); +} +ATF_TC_BODY(zonemgr_unreachable, tc) { + dns_zonemgr_t *zonemgr = NULL; + dns_zone_t *zone = NULL; + isc_sockaddr_t addr1, addr2; + struct in_addr in; + isc_result_t result; + isc_time_t now; + + UNUSED(tc); + + TIME_NOW(&now); + + result = dns_test_begin(NULL, ISC_TRUE); + + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = dns_zonemgr_create(mctx, taskmgr, timermgr, socketmgr, + &zonemgr); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = dns_test_makezone("foo", &zone, NULL, ISC_FALSE); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = dns_zonemgr_setsize(zonemgr, 1); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + result = dns_zonemgr_managezone(zonemgr, zone); + ATF_REQUIRE_EQ(result, ISC_R_SUCCESS); + + in.s_addr = inet_addr("10.53.0.1"); + isc_sockaddr_fromin(&addr1, &in, 2112); + in.s_addr = inet_addr("10.53.0.2"); + isc_sockaddr_fromin(&addr2, &in, 5150); + ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now); + ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + + in.s_addr = inet_addr("10.53.0.3"); + isc_sockaddr_fromin(&addr2, &in, 5150); + ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + dns_zonemgr_unreachableadd(zonemgr, &addr1, &addr2, &now); + ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + + dns_zonemgr_unreachabledel(zonemgr, &addr1, &addr2); + ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + + in.s_addr = inet_addr("10.53.0.2"); + isc_sockaddr_fromin(&addr2, &in, 5150); + ATF_CHECK(dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + dns_zonemgr_unreachabledel(zonemgr, &addr1, &addr2); + ATF_CHECK(! dns_zonemgr_unreachable(zonemgr, &addr1, &addr2, &now)); + + dns_zonemgr_releasezone(zonemgr, zone); + dns_zone_detach(&zone); + dns_zonemgr_shutdown(zonemgr); + dns_zonemgr_detach(&zonemgr); + ATF_REQUIRE_EQ(zonemgr, NULL); + + dns_test_end(); +} + + /* * Main */ ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, zonemgr_create); ATF_TP_ADD_TC(tp, zonemgr_managezone); + ATF_TP_ADD_TC(tp, zonemgr_unreachable); return (atf_no_error()); } @@ -137,6 +204,4 @@ ATF_TP_ADD_TCS(tp) { * - dns_zonemgr_dbdestroyed * - dns_zonemgr_setserialqueryrate * - dns_zonemgr_getserialqueryrate - * - dns_zonemgr_unreachable - * - dns_zonemgr_unreachableadd */ diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 498ca0e3..00bad70e 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -16,7 +16,7 @@ */ /* - * $Id: tsig.c,v 1.150 2011-08-29 04:02:54 marka Exp $ + * $Id: tsig.c,v 1.151 2011-11-02 19:41:02 each Exp $ */ /*! \file */ #include <config.h> @@ -1043,7 +1043,7 @@ dns_tsig_sign(dns_message_t *msg) { goto cleanup_context; /* - * Digest the error and other data. + * Digest other data. */ if (tsig.otherlen > 0) { r.length = tsig.otherlen; diff --git a/lib/dns/update.c b/lib/dns/update.c index 9099994d..e8b803fa 100644 --- a/lib/dns/update.c +++ b/lib/dns/update.c @@ -14,7 +14,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: update.c,v 1.5 2011-08-30 23:46:52 tbox Exp $ */ +/* $Id: update.c,v 1.6 2011-11-03 02:54:47 each Exp $ */ #include <config.h> @@ -713,8 +713,6 @@ delete_if(rr_predicate *predicate, dns_db_t *db, dns_dbversion_t *ver, * Incremental updating of NSECs and RRSIGs. */ -#define MAXZONEKEYS 32 /*%< Maximum number of zone keys supported. */ - /*% * We abuse the dns_diff_t type to represent a set of domain names * affected by the update. @@ -1338,7 +1336,7 @@ dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_diff_t nsec_diff; dns_diff_t nsec_mindiff; isc_boolean_t flag, build_nsec, build_nsec3; - dst_key_t *zone_keys[MAXZONEKEYS]; + dst_key_t *zone_keys[DNS_MAXZONEKEYS]; unsigned int nkeys = 0; unsigned int i; isc_stdtime_t now, inception, expire; @@ -1361,7 +1359,7 @@ dns_update_signatures(dns_update_log_t *log, dns_zone_t *zone, dns_db_t *db, dns_diff_init(diff->mctx, &nsec_mindiff); result = find_zone_keys(zone, db, newver, diff->mctx, - MAXZONEKEYS, zone_keys, &nkeys); + DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { update_log(log, zone, ISC_LOG_ERROR, "could not get zone keys for secure dynamic update"); diff --git a/lib/dns/validator.c b/lib/dns/validator.c index 4002181a..efb4ad2b 100644 --- a/lib/dns/validator.c +++ b/lib/dns/validator.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.207 2011-10-20 23:46:51 tbox Exp $ */ +/* $Id: validator.c,v 1.208 2011-11-04 05:36:28 each Exp $ */ #include <config.h> @@ -1930,7 +1930,9 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, again: result = dns_dnssec_verify2(val->event->name, val->event->rdataset, key, ignore, val->view->mctx, rdata, wild); - if (result == DNS_R_SIGEXPIRED && val->view->acceptexpired) { + if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) && + val->view->acceptexpired) + { ignore = ISC_TRUE; goto again; } @@ -1939,6 +1941,10 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata, "accepted expired %sRRSIG (keyid=%u)", (result == DNS_R_FROMWILDCARD) ? "wildcard " : "", keyid); + else if (result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) + validator_log(val, ISC_LOG_INFO, + "verify failed due to bad signature (keyid=%u): " + "%s", keyid, isc_result_totext(result)); else validator_log(val, ISC_LOG_DEBUG(3), "verify rdataset (keyid=%u): %s", diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def index 5eaaad72..7ddceb0b 100644 --- a/lib/dns/win32/libdns.def +++ b/lib/dns/win32/libdns.def @@ -932,6 +932,8 @@ dns_zonemgr_setsize dns_zonemgr_settransfersin dns_zonemgr_settransfersperns dns_zonemgr_shutdown +dns_zonemgr_unreachable +dns_zonemgr_unreachabledel dns_zt_apply dns_zt_attach dns_zt_create diff --git a/lib/dns/zone.c b/lib/dns/zone.c index ba9379d0..541d5e9e 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.643 2011-10-28 12:27:06 marka Exp $ */ +/* $Id: zone.c,v 1.647 2011-11-04 05:51:01 each Exp $ */ /*! \file */ @@ -701,10 +701,6 @@ static void zone_saveunique(dns_zone_t *zone, const char *path, static void zone_maintenance(dns_zone_t *zone); static void zone_notify(dns_zone_t *zone, isc_time_t *now); static void dump_done(void *arg, isc_result_t result); -static isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, - isc_sockaddr_t *remote, - isc_sockaddr_t *local, - isc_time_t *now); static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid, isc_boolean_t delete); static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver, @@ -3360,7 +3356,7 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) { for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS; result = dns_rriterator_nextrrset(&rrit)) { - dns_rdataset_t *rdataset; + dns_rdataset_t *rdataset = NULL; dns_name_t *rrname = NULL; isc_uint32_t ttl; @@ -3514,7 +3510,11 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, "no master file, requesting db"); maybe_send_securedb(zone); } else { - dns_zone_log(zone, ISC_LOG_ERROR, + int level = ISC_LOG_ERROR; + if (zone->type == dns_zone_key && + result == ISC_R_FILENOTFOUND) + level = ISC_LOG_DEBUG(1); + dns_zone_log(zone, level, "loading from master file %s failed: %s", zone->masterfile, dns_result_totext(result)); @@ -4803,8 +4803,6 @@ was_dumping(dns_zone_t *zone) { return (dumping); } -#define MAXZONEKEYS 10 - static isc_result_t find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, isc_mem_t *mctx, unsigned int maxkeys, @@ -5185,7 +5183,7 @@ zone_resigninc(dns_zone_t *zone) { dns_name_t *name; dns_rdataset_t rdataset; dns_rdatatype_t covers; - dst_key_t *zone_keys[MAXZONEKEYS]; + dst_key_t *zone_keys[DNS_MAXZONEKEYS]; isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE; isc_result_t result; isc_stdtime_t now, inception, soaexpire, expire, stop; @@ -5223,7 +5221,7 @@ zone_resigninc(dns_zone_t *zone) { goto failure; } - result = find_zone_keys(zone, db, version, zone->mctx, MAXZONEKEYS, + result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -6089,7 +6087,7 @@ zone_nsec3chain(dns_zone_t *zone) { dns_rdataset_t rdataset; dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain; dns_nsec3chainlist_t cleanup; - dst_key_t *zone_keys[MAXZONEKEYS]; + dst_key_t *zone_keys[DNS_MAXZONEKEYS]; isc_int32_t signatures; isc_boolean_t check_ksk, keyset_kskonly; isc_boolean_t delegation; @@ -6141,7 +6139,7 @@ zone_nsec3chain(dns_zone_t *zone) { } result = find_zone_keys(zone, db, version, zone->mctx, - MAXZONEKEYS, zone_keys, &nkeys); + DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:find_zone_keys -> %s\n", @@ -6922,7 +6920,7 @@ zone_sign(dns_zone_t *zone) { dns_rdataset_t rdataset; dns_signing_t *signing, *nextsigning; dns_signinglist_t cleanup; - dst_key_t *zone_keys[MAXZONEKEYS]; + dst_key_t *zone_keys[DNS_MAXZONEKEYS]; isc_int32_t signatures; isc_boolean_t check_ksk, keyset_kskonly, is_ksk; isc_boolean_t commit = ISC_FALSE; @@ -6968,7 +6966,7 @@ zone_sign(dns_zone_t *zone) { } result = find_zone_keys(zone, db, version, zone->mctx, - MAXZONEKEYS, zone_keys, &nkeys); + DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:find_zone_keys -> %s\n", @@ -8102,6 +8100,7 @@ zone_refreshkeys(dns_zone_t *zone) { dns_rdata_keydata_t kd; isc_stdtime_t now; isc_boolean_t commit = ISC_FALSE; + isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE; ENTER; REQUIRE(zone->db != NULL); @@ -8130,16 +8129,14 @@ zone_refreshkeys(dns_zone_t *zone) { result == ISC_R_SUCCESS; result = dns_rriterator_nextrrset(&rrit)) { isc_stdtime_t timer = 0xffffffff; + dns_name_t *name = NULL, *kname = NULL; + dns_rdataset_t *kdset = NULL; dns_keyfetch_t *kfetch; - dns_rdataset_t *kdset; - dns_name_t *name = NULL; isc_uint32_t ttl; dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL); - if (!dns_rdataset_isassociated(kdset)) - continue; - - if (kdset->type != dns_rdatatype_keydata) + if (kdset == NULL || kdset->type != dns_rdatatype_keydata || + !dns_rdataset_isassociated(kdset)) continue; /* @@ -8174,15 +8171,19 @@ zone_refreshkeys(dns_zone_t *zone) { if (timer > now) continue; - zone->refreshkeycount++; - kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t)); + if (kfetch == NULL) { + fetch_err = ISC_TRUE; + goto failure; + } + + zone->refreshkeycount++; kfetch->zone = zone; zone->irefs++; INSIST(zone->irefs != 0); dns_fixedname_init(&kfetch->name); - dns_name_dup(name, zone->mctx, - dns_fixedname_name(&kfetch->name)); + kname = dns_fixedname_name(&kfetch->name); + dns_name_dup(name, zone->mctx, kname); dns_rdataset_init(&kfetch->dnskeyset); dns_rdataset_init(&kfetch->dnskeysigset); dns_rdataset_init(&kfetch->keydataset); @@ -8191,15 +8192,29 @@ zone_refreshkeys(dns_zone_t *zone) { dns_db_attach(db, &kfetch->db); kfetch->fetch = NULL; - dns_resolver_createfetch(zone->view->resolver, - dns_fixedname_name(&kfetch->name), - dns_rdatatype_dnskey, - NULL, NULL, NULL, - DNS_FETCHOPT_NOVALIDATE, - zone->task, keyfetch_done, kfetch, - &kfetch->dnskeyset, - &kfetch->dnskeysigset, - &kfetch->fetch); + result = dns_resolver_createfetch(zone->view->resolver, + kname, dns_rdatatype_dnskey, + NULL, NULL, NULL, + DNS_FETCHOPT_NOVALIDATE, + zone->task, + keyfetch_done, kfetch, + &kfetch->dnskeyset, + &kfetch->dnskeysigset, + &kfetch->fetch); + if (result == ISC_R_SUCCESS) + fetching = ISC_TRUE; + else { + zone->refreshkeycount--; + zone->irefs--; + dns_db_detach(&kfetch->db); + dns_rdataset_disassociate(&kfetch->keydataset); + dns_name_free(kname, zone->mctx); + isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t)); + dns_zone_log(zone, ISC_LOG_WARNING, + "Failed to create fetch for " + "DNSKEY update"); + fetch_err = ISC_TRUE; + } } if (!ISC_LIST_EMPTY(diff.tuples)) { CHECK(update_soa_serial(db, ver, &diff, zone->mctx, @@ -8211,6 +8226,26 @@ zone_refreshkeys(dns_zone_t *zone) { } failure: + if (fetch_err) { + /* + * Error during a key fetch; retry in an hour. + */ + isc_time_t timenow, timethen; + char timebuf[80]; + + TIME_NOW(&timenow); + DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen); + zone->refreshkeytime = timethen; + zone_settimer(zone, &timenow); + + isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80); + dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s", + timebuf); + + if (!fetching) + DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING); + } + UNLOCK_ZONE(zone); dns_diff_clear(&diff); @@ -9870,7 +9905,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { if (!dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, &zone->sourceaddr, - &now)) { + &now)) + { LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); @@ -10066,7 +10102,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) || isc_serial_gt(serial, oldserial)) { if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, - &zone->sourceaddr, &now)) { + &zone->sourceaddr, &now)) + { dns_zone_log(zone, ISC_LOG_INFO, "refresh: skipping %s as master %s " "(source %s) is unreachable (cached)", @@ -11196,6 +11233,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, char fromtext[ISC_SOCKADDR_FORMATSIZE]; int match = 0; isc_netaddr_t netaddr; + isc_sockaddr_t local, remote; REQUIRE(DNS_ZONE_VALID(zone)); @@ -11354,7 +11392,10 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from, return (ISC_R_SUCCESS); } zone->notifyfrom = *from; + local = zone->masteraddr; + remote = zone->sourceaddr; UNLOCK_ZONE(zone); + dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote); dns_zone_refresh(zone); return (ISC_R_SUCCESS); } @@ -12891,7 +12932,8 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) { isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr, - &zone->sourceaddr, &now)) { + &zone->sourceaddr, &now)) + { isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); dns_zone_log(zone, ISC_LOG_INFO, "got_transfer_quota: skipping zone transfer as " @@ -13971,7 +14013,7 @@ dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) { return (zmgr->serialqueryrate); } -static isc_boolean_t +isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local, isc_time_t *now) { @@ -14001,6 +14043,43 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, } void +dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, + isc_sockaddr_t *local) +{ + unsigned int i; + isc_rwlocktype_t locktype; + isc_result_t result; + + char master[ISC_SOCKADDR_FORMATSIZE]; + char source[ISC_SOCKADDR_FORMATSIZE]; + + isc_sockaddr_format(remote, master, sizeof(master)); + isc_sockaddr_format(local, source, sizeof(source)); + + REQUIRE(DNS_ZONEMGR_VALID(zmgr)); + + locktype = isc_rwlocktype_read; + RWLOCK(&zmgr->rwlock, locktype); + for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { + if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && + isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { + result = isc_rwlock_tryupgrade(&zmgr->rwlock); + if (result == ISC_R_SUCCESS) { + locktype = isc_rwlocktype_write; + zmgr->unreachable[i].expire = 0; + isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, + DNS_LOGMODULE_ZONE, ISC_LOG_INFO, + "master %s (source %s) deleted " + "from unreachable cache", + master, source); + } + break; + } + } + RWUNLOCK(&zmgr->rwlock, locktype); +} + +void dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, isc_sockaddr_t *local, isc_time_t *now) { @@ -14661,11 +14740,11 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, isc_result_t result; isc_stdtime_t now, inception, soaexpire; isc_boolean_t check_ksk, keyset_kskonly; - dst_key_t *zone_keys[MAXZONEKEYS]; + dst_key_t *zone_keys[DNS_MAXZONEKEYS]; unsigned int nkeys = 0, i; dns_difftuple_t *tuple; - result = find_zone_keys(zone, db, ver, zone->mctx, MAXZONEKEYS, + result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS, zone_keys, &nkeys); if (result != ISC_R_SUCCESS) { dns_zone_log(zone, ISC_LOG_ERROR, @@ -14952,7 +15031,8 @@ zone_rekey(dns_zone_t *zone) { goto failure; } - /* See if any pre-existing keys have newly become active; + /* + * See if any pre-existing keys have newly become active; * also, see if any new key is for a new algorithm, as in that * event, we need to sign the zone fully. (If there's a new * key, but it's for an already-existing algorithm, then |