diff options
author | Doug Barton <dougb@FreeBSD.org> | 2012-05-28 10:21:54 +0000 |
---|---|---|
committer | Doug Barton <dougb@FreeBSD.org> | 2012-05-28 10:21:54 +0000 |
commit | 31ffd11de096ff42940ae937e8e5a955664514c9 (patch) | |
tree | 6dc3dc4c57d86d545b84f6bf88014bfc1dcf80fa | |
parent | 65880d08f9383b1b2f7d971891cc32f9ba70e051 (diff) |
Vendor import of BIND 9.6-ESV-R7vendor/bind9/9.6-ESV-R7
Notes
Notes:
svn path=/vendor/bind9/dist-9.6/; revision=236174
svn path=/vendor/bind9/9.6-ESV-R7/; revision=236175; tag=vendor/bind9/9.6-ESV-R7
-rw-r--r-- | CHANGES | 82 | ||||
-rw-r--r-- | README | 5 | ||||
-rw-r--r-- | bin/named/query.c | 5 | ||||
-rw-r--r-- | lib/dns/api | 2 | ||||
-rw-r--r-- | lib/dns/include/dns/stats.h | 2 | ||||
-rw-r--r-- | lib/dns/include/dns/view.h | 2 | ||||
-rw-r--r-- | lib/dns/rbtdb.c | 2 | ||||
-rw-r--r-- | lib/dns/rdata/generic/tlsa_52.c | 285 | ||||
-rw-r--r-- | lib/dns/rdata/generic/tlsa_52.h | 35 | ||||
-rw-r--r-- | lib/dns/resolver.c | 228 | ||||
-rw-r--r-- | lib/dns/sdb.c | 9 | ||||
-rw-r--r-- | lib/dns/tkey.c | 4 | ||||
-rw-r--r-- | lib/dns/zone.c | 121 | ||||
-rw-r--r-- | lib/isc/pthreads/mutex.c | 14 | ||||
-rw-r--r-- | lib/isccfg/api | 2 | ||||
-rw-r--r-- | lib/isccfg/parser.c | 24 | ||||
-rw-r--r-- | release-notes.css | 42 | ||||
-rw-r--r-- | version | 2 |
18 files changed, 621 insertions, 245 deletions
@@ -1,3 +1,43 @@ + --- 9.6-ESV-R7 released --- + +3318. [tuning] Reduce the amount of work performed while holding a + bucket lock when finshed with a fetch context. + [RT #29239] + +3314. [bug] The masters list could be updated while refesh_callback + and stub_callback were using it. [RT #26732] + +3313. [protocol] Add TLSA record type. [RT #28989] + +3311. [bug] Abort the zone dump if zone->db is NULL in + zone.c:zone_gotwritehandle. [RT #29028] + +3310. [test] Increase table size for mutex profiling. [RT #28809] + +3309. [bug] resolver.c:fctx_finddone() was not threadsafe. + [RT #27995] + +3307. [bug] Add missing ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS. + [RT #28956] + +3304. [bug] Use hmctx, not mctx when freeing rbtdb->heaps. + [RT #28571] + +3301. [contrib] Update queryperf to build on darwin. Add -R flag + for non-recursive queries. [RT #28565] + +3300. [bug] Named could die if gssapi was enabled in named.conf + but was not compiled in. [RT #28338] + +3299. [bug] Make SDB handle errors from database drivers better. + [RT #28534] + +3232. [bug] Zero zone->curmaster before return in + dns_zone_setmasterswithkeys(). [RT #26732] + +3197. [bug] Don't try to log the filename and line number when + the config parser can't open a file. [RT #22263] + --- 9.6-ESV-R6 released --- 3298. [bug] Named could dereference a NULL pointer in @@ -168,7 +208,7 @@ 3189. [test] Added a summary report after system tests. [RT #25517] -3187. [port] win32: support for Visual Studio 2008. [RT #26356] +3187. [port] win32: support for Visual Studio 2008. [RT #26356] 3179. [port] kfreebsd: build issues. [RT #26273] @@ -201,7 +241,7 @@ an assert. [RT #25452] 3151. [bug] Queries for type RRSIG or SIG could be handled - incorrectly. [RT #21050] + incorrectly. [RT #21050] 3149. [tuning] Improve scalability by allocating one zone task per 100 zones at startup time. (The @@ -213,7 +253,7 @@ 3148. [bug] Processing of normal queries could be stalled when forwarding a UPDATE message. [RT #24711] -3146. [test] Fixed gcc4.6.0 errors in ATF. [RT #25598] +3146. [test] Fixed gcc4.6.0 errors in ATF. [RT #25598] 3145. [test] Capture output of ATF unit tests in "./atf.out" if there were any errors while running them. [RT #25527] @@ -273,10 +313,10 @@ dns_rdataset_totext() that could cause named to crash with an assertion failure. [RT #24777] -3121. [security] An authoritative name server sending a negative - response containing a very large RRset could - trigger an off-by-one error in the ncache code - and crash named. [RT #24650] +3121. [security] An authoritative name server sending a negative + response containing a very large RRset could + trigger an off-by-one error in the ncache code + and crash named. [RT #24650] 3120. [bug] Named could fail to validate zones listed in a DLV that validated insecure without using DLV and had @@ -370,9 +410,9 @@ 3043. [test] Merged in the NetBSD ATF test framework (currently version 0.12) for development of future unit tests. - Use configure --with-atf to build ATF internally - or configure --with-atf=prefix to use an external - copy. [RT #23209] + Use configure --with-atf to build ATF internally + or configure --with-atf=prefix to use an external + copy. [RT #23209] 3042. [bug] dig +trace could fail attempting to use IPv6 addresses on systems with only IPv4 connectivity. @@ -562,7 +602,7 @@ 2929. [bug] Improved handling of GSS security contexts: - added LRU expiration for generated TSIGs - added the ability to use a non-default realm - - added new "realm" keyword in nsupdate + - added new "realm" keyword in nsupdate - limited lifetime of generated keys to 1 hour or the lifetime of the context (whichever is smaller) @@ -927,11 +967,11 @@ trigger an assert. [RT #20368] 2705. [bug] Reconcile the XML stats version number with a later - BIND9 release, by adding a "name" attribute to - "cache" elements and increasing the version number - to 2.2. (This is a minor version change, but may - affect XML parsers if they assume the cache element - doesn't take an attribute.) + BIND9 release, by adding a "name" attribute to + "cache" elements and increasing the version number + to 2.2. (This is a minor version change, but may + affect XML parsers if they assume the cache element + doesn't take an attribute.) 2704. [bug] Serial of dynamic and stub zones could be inconsistent with their SOA serial. [RT #19387] @@ -1590,10 +1630,10 @@ time. [RT #18277] 2423. [security] Randomize server selection on queries, so as to - make forgery a little more difficult. Instead of - always preferring the server with the lowest RTT, - pick a server with RTT within the same 128 - millisecond band. [RT #18441] + make forgery a little more difficult. Instead of + always preferring the server with the lowest RTT, + pick a server with RTT within the same 128 + millisecond band. [RT #18441] 2422. [bug] Handle the special return value of a empty node as if it was a NXRRSET in the validator. [RT #18447] @@ -1674,7 +1714,7 @@ 2399. [placeholder] -2398. [bug] Improve file descriptor management. New, +2398. [bug] Improve file descriptor management. New, temporary, named.conf option reserved-sockets, default 512. [RT #18344] @@ -48,6 +48,11 @@ BIND 9 For up-to-date release notes and errata, see http://www.isc.org/software/bind9/releasenotes +BIND 9.6-ESV-R7 (Extended Support Version) + + BIND 9.4-ESV-R7 is a maintenance release, fixing bugs in BIND + 9.6-ESV-R6. + BIND 9.6-ESV-R6 (Extended Support Version) BIND 9.6-ESV-R6 includes a number of bug fixes and prevents a diff --git a/bin/named/query.c b/bin/named/query.c index 429a9b6b0d21..2f37db586057 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -2912,6 +2912,11 @@ query_addwildcardproof(ns_client_t *client, dns_db_t *db, dns_name_copy(name, cname, NULL); while (result == DNS_R_NXDOMAIN) { labels = dns_name_countlabels(cname) - 1; + /* + * Sanity check. + */ + if (labels == 0U) + goto cleanup; dns_name_split(cname, labels, NULL, cname); result = dns_db_find(db, cname, version, dns_rdatatype_nsec, diff --git a/lib/dns/api b/lib/dns/api index 5a5cbc7fd18d..974ae84d538c 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 110 -LIBREVISION = 1 +LIBREVISION = 2 LIBAGE = 0 diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h index b8dc17eba5e9..bc77d1e9c5a3 100644 --- a/lib/dns/include/dns/stats.h +++ b/lib/dns/include/dns/stats.h @@ -147,6 +147,8 @@ typedef void (*dns_rdatatypestats_dumper_t)(dns_rdatastatstype_t, isc_uint64_t, void *); typedef void (*dns_opcodestats_dumper_t)(dns_opcode_t, isc_uint64_t, void *); +ISC_LANG_BEGINDECLS + isc_result_t dns_generalstats_create(isc_mem_t *mctx, dns_stats_t **statsp, int ncounters); /*%< diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 94823f46baf6..667b87522ec1 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -878,4 +878,6 @@ dns_view_getresquerystats(dns_view_t *view, dns_stats_t **statsp); *\li 'statsp' != NULL && '*statsp' != NULL */ +ISC_LANG_ENDDECLS + #endif /* DNS_VIEW_H */ diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index e62eb9590948..9478ef946d88 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -7277,7 +7277,7 @@ dns_rbtdb_create for (i = 0 ; i < (int)rbtdb->node_lock_count ; i++) if (rbtdb->heaps[i] != NULL) isc_heap_destroy(&rbtdb->heaps[i]); - isc_mem_put(mctx, rbtdb->heaps, + isc_mem_put(hmctx, rbtdb->heaps, rbtdb->node_lock_count * sizeof(isc_heap_t *)); } diff --git a/lib/dns/rdata/generic/tlsa_52.c b/lib/dns/rdata/generic/tlsa_52.c new file mode 100644 index 000000000000..194f846b1c62 --- /dev/null +++ b/lib/dns/rdata/generic/tlsa_52.c @@ -0,0 +1,285 @@ +/* + * Copyright (C) 2012 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 + * 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$ */ + +/* draft-ietf-dane-protocol-19.txt */ + +#ifndef RDATA_GENERIC_TLSA_52_C +#define RDATA_GENERIC_TLSA_52_C + +#define RRTYPE_TLSA_ATTRIBUTES 0 + +static inline isc_result_t +fromtext_tlsa(ARGS_FROMTEXT) { + isc_token_t token; + + REQUIRE(type == 52); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(origin); + UNUSED(options); + UNUSED(callbacks); + + /* + * Certificate Usage. + */ + 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)); + + /* + * Selector. + */ + 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)); + + /* + * Matching 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)); + + /* + * Certificate Association Data. + */ + return (isc_hex_tobuffer(lexer, target, -1)); +} + +static inline isc_result_t +totext_tlsa(ARGS_TOTEXT) { + isc_region_t sr; + char buf[sizeof("64000 ")]; + unsigned int n; + + REQUIRE(rdata->type == 52); + REQUIRE(rdata->length != 0); + + UNUSED(tctx); + + dns_rdata_toregion(rdata, &sr); + + /* + * Certificate Usage. + */ + n = uint8_fromregion(&sr); + isc_region_consume(&sr, 1); + sprintf(buf, "%u ", n); + RETERR(str_totext(buf, target)); + + /* + * Selector. + */ + n = uint8_fromregion(&sr); + isc_region_consume(&sr, 1); + sprintf(buf, "%u ", n); + RETERR(str_totext(buf, target)); + + /* + * Matching type. + */ + n = uint8_fromregion(&sr); + isc_region_consume(&sr, 1); + sprintf(buf, "%u", n); + RETERR(str_totext(buf, target)); + + /* + * Certificate Association Data. + */ + if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) + RETERR(str_totext(" (", target)); + RETERR(str_totext(tctx->linebreak, target)); + if (tctx->width == 0) /* No splitting */ + RETERR(isc_hex_totext(&sr, 0, "", target)); + else + 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_tlsa(ARGS_FROMWIRE) { + isc_region_t sr; + + REQUIRE(type == 52); + + UNUSED(type); + UNUSED(rdclass); + UNUSED(dctx); + UNUSED(options); + + isc_buffer_activeregion(source, &sr); + + if (sr.length < 3) + return (ISC_R_UNEXPECTEDEND); + + isc_buffer_forward(source, sr.length); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static inline isc_result_t +towire_tlsa(ARGS_TOWIRE) { + isc_region_t sr; + + REQUIRE(rdata->type == 52); + REQUIRE(rdata->length != 0); + + UNUSED(cctx); + + dns_rdata_toregion(rdata, &sr); + return (mem_tobuffer(target, sr.base, sr.length)); +} + +static inline int +compare_tlsa(ARGS_COMPARE) { + isc_region_t r1; + isc_region_t r2; + + REQUIRE(rdata1->type == rdata2->type); + REQUIRE(rdata1->rdclass == rdata2->rdclass); + REQUIRE(rdata1->type == 52); + 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_tlsa(ARGS_FROMSTRUCT) { + dns_rdata_tlsa_t *tlsa = source; + + REQUIRE(type == 52); + REQUIRE(source != NULL); + REQUIRE(tlsa->common.rdtype == type); + REQUIRE(tlsa->common.rdclass == rdclass); + + UNUSED(type); + UNUSED(rdclass); + + RETERR(uint8_tobuffer(tlsa->usage, target)); + RETERR(uint8_tobuffer(tlsa->selector, target)); + RETERR(uint8_tobuffer(tlsa->match, target)); + + return (mem_tobuffer(target, tlsa->data, tlsa->length)); +} + +static inline isc_result_t +tostruct_tlsa(ARGS_TOSTRUCT) { + dns_rdata_tlsa_t *tlsa = target; + isc_region_t region; + + REQUIRE(rdata->type == 52); + REQUIRE(target != NULL); + REQUIRE(rdata->length != 0); + + tlsa->common.rdclass = rdata->rdclass; + tlsa->common.rdtype = rdata->type; + ISC_LINK_INIT(&tlsa->common, link); + + dns_rdata_toregion(rdata, ®ion); + + tlsa->usage = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + tlsa->selector = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + tlsa->match = uint8_fromregion(®ion); + isc_region_consume(®ion, 1); + tlsa->length = region.length; + + tlsa->data = mem_maybedup(mctx, region.base, region.length); + if (tlsa->data == NULL) + return (ISC_R_NOMEMORY); + + tlsa->mctx = mctx; + return (ISC_R_SUCCESS); +} + +static inline void +freestruct_tlsa(ARGS_FREESTRUCT) { + dns_rdata_tlsa_t *tlsa = source; + + REQUIRE(tlsa != NULL); + REQUIRE(tlsa->common.rdtype == 52); + + if (tlsa->mctx == NULL) + return; + + if (tlsa->data != NULL) + isc_mem_free(tlsa->mctx, tlsa->data); + tlsa->mctx = NULL; +} + +static inline isc_result_t +additionaldata_tlsa(ARGS_ADDLDATA) { + REQUIRE(rdata->type == 52); + + UNUSED(rdata); + UNUSED(add); + UNUSED(arg); + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +digest_tlsa(ARGS_DIGEST) { + isc_region_t r; + + REQUIRE(rdata->type == 52); + + dns_rdata_toregion(rdata, &r); + + return ((digest)(arg, &r)); +} + +static inline isc_boolean_t +checkowner_tlsa(ARGS_CHECKOWNER) { + + REQUIRE(type == 52); + + UNUSED(name); + UNUSED(type); + UNUSED(rdclass); + UNUSED(wildcard); + + return (ISC_TRUE); +} + +static inline isc_boolean_t +checknames_tlsa(ARGS_CHECKNAMES) { + + REQUIRE(rdata->type == 52); + + UNUSED(rdata); + UNUSED(owner); + UNUSED(bad); + + return (ISC_TRUE); +} + +#endif /* RDATA_GENERIC_TLSA_52_C */ diff --git a/lib/dns/rdata/generic/tlsa_52.h b/lib/dns/rdata/generic/tlsa_52.h new file mode 100644 index 000000000000..83ce9529976d --- /dev/null +++ b/lib/dns/rdata/generic/tlsa_52.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2012 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 + * 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$ */ + +#ifndef GENERIC_TLSA_52_H +#define GENERIC_TLSA_52_H 1 + +/*! + * \brief per draft-ietf-dane-protocol-19.txt + */ +typedef struct dns_rdata_tlsa { + dns_rdatacommon_t common; + isc_mem_t *mctx; + isc_uint8_t usage; + isc_uint8_t selector; + isc_uint8_t match; + isc_uint16_t length; + unsigned char *data; +} dns_rdata_tlsa_t; + +#endif /* GENERIC_TLSA_52_H */ diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 105ed6130e40..632cfb4a7abf 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -172,7 +172,9 @@ struct fetchctx { dns_rdatatype_t type; unsigned int options; unsigned int bucketnum; - char * info; + char * info; + isc_mem_t * mctx; + /*% Locked by appropriate bucket lock. */ fetchstate state; isc_boolean_t want_shutdown; @@ -436,7 +438,8 @@ static void resquery_response(isc_task_t *task, isc_event_t *event); static void resquery_connected(isc_task_t *task, isc_event_t *event); static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache); -static isc_boolean_t fctx_destroy(fetchctx_t *fctx); +static void fctx_destroy(fetchctx_t *fctx); +static isc_boolean_t fctx_unlink(fetchctx_t *fctx); static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, dns_rdatatype_t covers, @@ -468,8 +471,7 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, dns_valarg_t *valarg; isc_result_t result; - valarg = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, - sizeof(*valarg)); + valarg = isc_mem_get(fctx->mctx, sizeof(*valarg)); if (valarg == NULL) return (ISC_R_NOMEMORY); @@ -491,8 +493,7 @@ valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name, } ISC_LIST_APPEND(fctx->validators, validator, link); } else - isc_mem_put(fctx->res->buckets[fctx->bucketnum].mctx, - valarg, sizeof(*valarg)); + isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); return (result); } @@ -1375,13 +1376,12 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_message_reset(fctx->rmessage, DNS_MESSAGE_INTENTPARSE); - query = isc_mem_get(res->buckets[fctx->bucketnum].mctx, - sizeof(*query)); + query = isc_mem_get(fctx->mctx, sizeof(*query)); if (query == NULL) { result = ISC_R_NOMEMORY; goto stop_idle_timer; } - query->mctx = res->buckets[fctx->bucketnum].mctx; + query->mctx = fctx->mctx; query->options = options; query->attributes = 0; query->sends = 0; @@ -1558,8 +1558,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, cleanup_query: if (query->connects == 0) { query->magic = 0; - isc_mem_put(res->buckets[fctx->bucketnum].mctx, - query, sizeof(*query)); + isc_mem_put(fctx->mctx, query, sizeof(*query)); } stop_idle_timer: @@ -1589,8 +1588,7 @@ add_bad_edns(fetchctx_t *fctx, isc_sockaddr_t *address) { if (bad_edns(fctx, address)) return; - sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, - sizeof(*sa)); + sa = isc_mem_get(fctx->mctx, sizeof(*sa)); if (sa == NULL) return; @@ -1619,8 +1617,7 @@ add_triededns(fetchctx_t *fctx, isc_sockaddr_t *address) { if (triededns(fctx, address)) return; - sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, - sizeof(*sa)); + sa = isc_mem_get(fctx->mctx, sizeof(*sa)); if (sa == NULL) return; @@ -1649,8 +1646,7 @@ add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) { if (triededns512(fctx, address)) return; - sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, - sizeof(*sa)); + sa = isc_mem_get(fctx->mctx, sizeof(*sa)); if (sa == NULL) return; @@ -2156,8 +2152,8 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) { isc_boolean_t want_try = ISC_FALSE; isc_boolean_t want_done = ISC_FALSE; isc_boolean_t bucket_empty = ISC_FALSE; - isc_boolean_t destroy = ISC_FALSE; unsigned int bucketnum; + isc_boolean_t destroy = ISC_FALSE; find = event->ev_sender; fctx = event->ev_arg; @@ -2195,17 +2191,14 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) { } } else if (SHUTTINGDOWN(fctx) && fctx->pending == 0 && fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { - /* - * Note that we had to wait until we had the lock before - * looking at fctx->references. - */ - if (fctx->references == 0) + + if (fctx->references == 0) { + bucket_empty = fctx_unlink(fctx); destroy = ISC_TRUE; + } } UNLOCK(&res->buckets[bucketnum].lock); - if (destroy) - bucket_empty = fctx_destroy(fctx); isc_event_free(&event); dns_adb_destroyfind(&find); @@ -2213,8 +2206,11 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) { fctx_try(fctx, ISC_TRUE, ISC_FALSE); else if (want_done) fctx_done(fctx, ISC_R_FAILURE, __LINE__); - else if (bucket_empty) - empty_bucket(res); + else if (destroy) { + fctx_destroy(fctx); + if (bucket_empty) + empty_bucket(res); + } } @@ -2337,8 +2333,7 @@ add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_result_t reason, FCTXTRACE("add_bad"); - sa = isc_mem_get(fctx->res->buckets[fctx->bucketnum].mctx, - sizeof(*sa)); + sa = isc_mem_get(fctx->mctx, sizeof(*sa)); if (sa == NULL) return; *sa = *address; @@ -2689,12 +2684,9 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { fctx->fwdpolicy = forwarders->fwdpolicy; if (fctx->fwdpolicy == dns_fwdpolicy_only && isstrictsubdomain(domain, &fctx->domain)) { - isc_mem_t *mctx; - - mctx = res->buckets[fctx->bucketnum].mctx; - dns_name_free(&fctx->domain, mctx); + dns_name_free(&fctx->domain, fctx->mctx); dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(domain, mctx, + result = dns_name_dup(domain, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) return (result); @@ -3133,10 +3125,9 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) { } static isc_boolean_t -fctx_destroy(fetchctx_t *fctx) { +fctx_unlink(fetchctx_t *fctx) { dns_resolver_t *res; unsigned int bucketnum; - isc_sockaddr_t *sa, *next_sa; /* * Caller must be holding the bucket lock. @@ -3153,13 +3144,42 @@ fctx_destroy(fetchctx_t *fctx) { REQUIRE(fctx->references == 0); REQUIRE(ISC_LIST_EMPTY(fctx->validators)); - FCTXTRACE("destroy"); + FCTXTRACE("unlink"); res = fctx->res; bucketnum = fctx->bucketnum; ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link); + LOCK(&res->nlock); + res->nfctx--; + UNLOCK(&res->nlock); + + if (res->buckets[bucketnum].exiting && + ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs)) + return (ISC_TRUE); + + return (ISC_FALSE); +} + +static void +fctx_destroy(fetchctx_t *fctx) { + isc_sockaddr_t *sa, *next_sa; + + REQUIRE(VALID_FCTX(fctx)); + REQUIRE(fctx->state == fetchstate_done || + fctx->state == fetchstate_init); + REQUIRE(ISC_LIST_EMPTY(fctx->events)); + REQUIRE(ISC_LIST_EMPTY(fctx->queries)); + REQUIRE(ISC_LIST_EMPTY(fctx->finds)); + REQUIRE(ISC_LIST_EMPTY(fctx->altfinds)); + REQUIRE(fctx->pending == 0); + REQUIRE(fctx->references == 0); + REQUIRE(ISC_LIST_EMPTY(fctx->validators)); + REQUIRE(!ISC_LINK_LINKED(fctx, link)); + + FCTXTRACE("destroy"); + /* * Free bad. */ @@ -3168,7 +3188,7 @@ fctx_destroy(fetchctx_t *fctx) { sa = next_sa) { next_sa = ISC_LIST_NEXT(sa, link); ISC_LIST_UNLINK(fctx->bad, sa, link); - isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa)); + isc_mem_put(fctx->mctx, sa, sizeof(*sa)); } for (sa = ISC_LIST_HEAD(fctx->edns); @@ -3176,7 +3196,7 @@ fctx_destroy(fetchctx_t *fctx) { sa = next_sa) { next_sa = ISC_LIST_NEXT(sa, link); ISC_LIST_UNLINK(fctx->edns, sa, link); - isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa)); + isc_mem_put(fctx->mctx, sa, sizeof(*sa)); } for (sa = ISC_LIST_HEAD(fctx->edns512); @@ -3184,7 +3204,7 @@ fctx_destroy(fetchctx_t *fctx) { sa = next_sa) { next_sa = ISC_LIST_NEXT(sa, link); ISC_LIST_UNLINK(fctx->edns512, sa, link); - isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa)); + isc_mem_put(fctx->mctx, sa, sizeof(*sa)); } for (sa = ISC_LIST_HEAD(fctx->bad_edns); @@ -3192,31 +3212,21 @@ fctx_destroy(fetchctx_t *fctx) { sa = next_sa) { next_sa = ISC_LIST_NEXT(sa, link); ISC_LIST_UNLINK(fctx->bad_edns, sa, link); - isc_mem_put(res->buckets[bucketnum].mctx, sa, sizeof(*sa)); + isc_mem_put(fctx->mctx, sa, sizeof(*sa)); } isc_timer_detach(&fctx->timer); dns_message_destroy(&fctx->rmessage); dns_message_destroy(&fctx->qmessage); if (dns_name_countlabels(&fctx->domain) > 0) - dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx); + dns_name_free(&fctx->domain, fctx->mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); - dns_name_free(&fctx->name, res->buckets[bucketnum].mctx); + dns_name_free(&fctx->name, fctx->mctx); dns_db_detach(&fctx->cache); dns_adb_detach(&fctx->adb); - isc_mem_free(res->buckets[bucketnum].mctx, fctx->info); - isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx)); - - LOCK(&res->nlock); - res->nfctx--; - UNLOCK(&res->nlock); - - if (res->buckets[bucketnum].exiting && - ISC_LIST_EMPTY(res->buckets[bucketnum].fctxs)) - return (ISC_TRUE); - - return (ISC_FALSE); + isc_mem_free(fctx->mctx, fctx->info); + isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx)); } /* @@ -3316,6 +3326,7 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) { dns_resolver_t *res; unsigned int bucketnum; dns_validator_t *validator; + isc_boolean_t destroy = ISC_FALSE; REQUIRE(VALID_FCTX(fctx)); @@ -3365,13 +3376,18 @@ fctx_doshutdown(isc_task_t *task, isc_event_t *event) { } if (fctx->references == 0 && fctx->pending == 0 && - fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) - bucket_empty = fctx_destroy(fctx); + fctx->nqueries == 0 && ISC_LIST_EMPTY(fctx->validators)) { + bucket_empty = fctx_unlink(fctx); + destroy = ISC_TRUE; + } UNLOCK(&res->buckets[bucketnum].lock); - if (bucket_empty) - empty_bucket(res); + if (destroy) { + fctx_destroy(fctx); + if (bucket_empty) + empty_bucket(res); + } } static void @@ -3380,6 +3396,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) { isc_boolean_t done = ISC_FALSE, bucket_empty = ISC_FALSE; dns_resolver_t *res; unsigned int bucketnum; + isc_boolean_t destroy = ISC_FALSE; REQUIRE(VALID_FCTX(fctx)); @@ -3412,7 +3429,8 @@ fctx_start(isc_task_t *task, isc_event_t *event) { /* * It's now safe to destroy this fctx. */ - bucket_empty = fctx_destroy(fctx); + bucket_empty = fctx_unlink(fctx); + destroy = ISC_TRUE; } done = ISC_TRUE; } else { @@ -3434,6 +3452,8 @@ fctx_start(isc_task_t *task, isc_event_t *event) { if (!done) { isc_result_t result; + INSIST(!destroy); + /* * All is well. Start working on the fetch. */ @@ -3442,8 +3462,11 @@ fctx_start(isc_task_t *task, isc_event_t *event) { fctx_done(fctx, result, __LINE__); else fctx_try(fctx, ISC_FALSE, ISC_FALSE); - } else if (bucket_empty) - empty_bucket(res); + } else if (destroy) { + fctx_destroy(fctx); + if (bucket_empty) + empty_bucket(res); + } } /* @@ -3530,27 +3553,29 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE]; char typebuf[DNS_RDATATYPE_FORMATSIZE]; dns_name_t suffix; + isc_mem_t *mctx; /* * Caller must be holding the lock for bucket number 'bucketnum'. */ REQUIRE(fctxp != NULL && *fctxp == NULL); - fctx = isc_mem_get(res->buckets[bucketnum].mctx, sizeof(*fctx)); + mctx = res->buckets[bucketnum].mctx; + fctx = isc_mem_get(mctx, sizeof(*fctx)); if (fctx == NULL) return (ISC_R_NOMEMORY); dns_name_format(name, buf, sizeof(buf)); dns_rdatatype_format(type, typebuf, sizeof(typebuf)); strcat(buf, "/"); /* checked */ strcat(buf, typebuf); /* checked */ - fctx->info = isc_mem_strdup(res->buckets[bucketnum].mctx, buf); + fctx->info = isc_mem_strdup(mctx, buf); if (fctx->info == NULL) { result = ISC_R_NOMEMORY; goto cleanup_fetch; } FCTXTRACE("create"); dns_name_init(&fctx->name, NULL); - result = dns_name_dup(name, res->buckets[bucketnum].mctx, &fctx->name); + result = dns_name_dup(name, mctx, &fctx->name); if (result != ISC_R_SUCCESS) goto cleanup_info; dns_name_init(&fctx->domain, NULL); @@ -3652,9 +3677,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, NULL); if (result != ISC_R_SUCCESS) goto cleanup_name; - result = dns_name_dup(domain, - res->buckets[bucketnum].mctx, - &fctx->domain); + result = dns_name_dup(domain, mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { dns_rdataset_disassociate(&fctx->nameservers); goto cleanup_name; @@ -3665,16 +3688,12 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, /* * We're in forward-only mode. Set the query domain. */ - result = dns_name_dup(domain, - res->buckets[bucketnum].mctx, - &fctx->domain); + result = dns_name_dup(domain, mctx, &fctx->domain); if (result != ISC_R_SUCCESS) goto cleanup_name; } } else { - result = dns_name_dup(domain, - res->buckets[bucketnum].mctx, - &fctx->domain); + result = dns_name_dup(domain, mctx, &fctx->domain); if (result != ISC_R_SUCCESS) goto cleanup_name; dns_rdataset_clone(nameservers, &fctx->nameservers); @@ -3687,16 +3706,14 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, INSIST(dns_name_issubdomain(&fctx->name, &fctx->domain)); fctx->qmessage = NULL; - result = dns_message_create(res->buckets[bucketnum].mctx, - DNS_MESSAGE_INTENTRENDER, + result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &fctx->qmessage); if (result != ISC_R_SUCCESS) goto cleanup_domain; fctx->rmessage = NULL; - result = dns_message_create(res->buckets[bucketnum].mctx, - DNS_MESSAGE_INTENTPARSE, + result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &fctx->rmessage); if (result != ISC_R_SUCCESS) @@ -3746,6 +3763,8 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, dns_db_attach(res->view->cachedb, &fctx->cache); fctx->adb = NULL; dns_adb_attach(res->view->adb, &fctx->adb); + fctx->mctx = NULL; + isc_mem_attach(mctx, &fctx->mctx); ISC_LIST_INIT(fctx->events); ISC_LINK_INIT(fctx, link); @@ -3769,18 +3788,18 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, cleanup_domain: if (dns_name_countlabels(&fctx->domain) > 0) - dns_name_free(&fctx->domain, res->buckets[bucketnum].mctx); + dns_name_free(&fctx->domain, mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); cleanup_name: - dns_name_free(&fctx->name, res->buckets[bucketnum].mctx); + dns_name_free(&fctx->name, mctx); cleanup_info: - isc_mem_free(res->buckets[bucketnum].mctx, fctx->info); + isc_mem_free(mctx, fctx->info); cleanup_fetch: - isc_mem_put(res->buckets[bucketnum].mctx, fctx, sizeof(*fctx)); + isc_mem_put(mctx, fctx, sizeof(*fctx)); return (result); } @@ -3950,6 +3969,7 @@ maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) { isc_boolean_t bucket_empty = ISC_FALSE; dns_resolver_t *res = fctx->res; dns_validator_t *validator, *next_validator; + isc_boolean_t destroy = ISC_FALSE; REQUIRE(SHUTTINGDOWN(fctx)); @@ -3965,11 +3985,15 @@ maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) { dns_validator_cancel(validator); } - if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) - bucket_empty = fctx_destroy(fctx); + if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators)) { + bucket_empty = fctx_unlink(fctx); + destroy = ISC_TRUE; + } unlock: if (!locked) UNLOCK(&res->buckets[bucketnum].lock); + if (destroy) + fctx_destroy(fctx); return (bucket_empty); } @@ -4023,8 +4047,7 @@ validated(isc_task_t *task, isc_event_t *event) { * destroy the fctx if necessary. */ dns_validator_destroy(&vevent->validator); - isc_mem_put(res->buckets[fctx->bucketnum].mctx, - valarg, sizeof(*valarg)); + isc_mem_put(fctx->mctx, valarg, sizeof(*valarg)); negative = ISC_TF(vevent->rdataset == NULL); @@ -5518,14 +5541,11 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname, * if so we should bail out. */ INSIST(dns_name_countlabels(&fctx->domain) > 0); - dns_name_free(&fctx->domain, - fctx->res->buckets[fctx->bucketnum].mctx); + dns_name_free(&fctx->domain, fctx->mctx); if (dns_rdataset_isassociated(&fctx->nameservers)) dns_rdataset_disassociate(&fctx->nameservers); dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(ns_name, - fctx->res->buckets[fctx->bucketnum].mctx, - &fctx->domain); + result = dns_name_dup(ns_name, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) return (result); fctx->attributes |= FCTX_ATTR_WANTCACHE; @@ -5977,7 +5997,8 @@ fctx_decreference(fetchctx_t *fctx) { * This fctx is already shutdown; we were just * waiting for the last reference to go away. */ - bucket_empty = fctx_destroy(fctx); + bucket_empty = fctx_unlink(fctx); + fctx_destroy(fctx); } else { /* * Initiate shutdown. @@ -6032,12 +6053,9 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { fctx->ns_ttl = fctx->nameservers.ttl; fctx->ns_ttl_ok = ISC_TRUE; log_ns_ttl(fctx, "resume_dslookup"); - dns_name_free(&fctx->domain, - fctx->res->buckets[bucketnum].mctx); + dns_name_free(&fctx->domain, fctx->mctx); dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(&fctx->nsname, - fctx->res->buckets[bucketnum].mctx, - &fctx->domain); + result = dns_name_dup(&fctx->nsname, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); goto cleanup; @@ -6887,12 +6905,9 @@ resquery_response(isc_task_t *task, isc_event_t *event) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; } - dns_name_free(&fctx->domain, - fctx->res->buckets[fctx->bucketnum].mctx); + dns_name_free(&fctx->domain, fctx->mctx); dns_name_init(&fctx->domain, NULL); - result = dns_name_dup(fname, - fctx->res->buckets[fctx->bucketnum].mctx, - &fctx->domain); + result = dns_name_dup(fname, fctx->mctx, &fctx->domain); if (result != ISC_R_SUCCESS) { fctx_done(fctx, DNS_R_SERVFAIL, __LINE__); return; @@ -7631,6 +7646,7 @@ dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, unsigned int count = 0; unsigned int spillat; unsigned int spillatmin; + isc_boolean_t destroy = ISC_FALSE; UNUSED(forwarders); @@ -7728,16 +7744,20 @@ dns_resolver_createfetch2(dns_resolver_t *res, dns_name_t *name, isc_task_send(res->buckets[bucketnum].task, &event); } else { /* - * We don't care about the result of fctx_destroy() + * We don't care about the result of fctx_unlink() * since we know we're not exiting. */ - (void)fctx_destroy(fctx); + (void)fctx_unlink(fctx); + destroy = ISC_TRUE; } } unlock: UNLOCK(&res->buckets[bucketnum].lock); + if (destroy) + fctx_destroy(fctx); + if (result == ISC_R_SUCCESS) { FTRACE("created"); *fetchp = fetch; diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 595ca256a4d2..447ecbd2e574 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -841,10 +841,17 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, */ dns_name_getlabelsequence(name, nlabels - i, i, xname); result = findnode(db, xname, ISC_FALSE, &node); - if (result != ISC_R_SUCCESS) { + if (result == ISC_R_NOTFOUND) { + /* + * No data at zone apex? + */ + if (i == olabels) + return (DNS_R_BADDB); result = DNS_R_NXDOMAIN; continue; } + if (result != ISC_R_SUCCESS) + return (result); /* * Look for a DNAME at the current label, unless this is diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c index c52544702858..0b38417e087f 100644 --- a/lib/dns/tkey.c +++ b/lib/dns/tkey.c @@ -468,9 +468,9 @@ process_gsstkey(dns_name_t *name, dns_rdata_tkey_t *tkeyin, tkeyout->error = dns_tsigerror_badkey; tkey_log("process_gsstkey(): dns_tsigerror_badkey"); /* XXXSRA */ return (ISC_R_SUCCESS); - } else if (result == ISC_R_FAILURE) + } + if (result != DNS_R_CONTINUE && result != ISC_R_SUCCESS) goto failure; - ENSURE(result == DNS_R_CONTINUE || result == ISC_R_SUCCESS); /* * XXXDCL Section 4.1.3: Limit GSS_S_CONTINUE_NEEDED to 10 times. */ diff --git a/lib/dns/zone.c b/lib/dns/zone.c index 11b7cc336ec6..329fbef31924 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -395,6 +395,7 @@ struct dns_zonemgr { isc_ratelimiter_t * rl; isc_rwlock_t rwlock; isc_mutex_t iolock; + isc_rwlock_t urlock; /* Locked by rwlock. */ dns_zonelist_t zones; @@ -412,7 +413,7 @@ struct dns_zonemgr { dns_iolist_t high; dns_iolist_t low; - /* Locked by rwlock. */ + /* Locked by urlock. */ /* LRU cache */ struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE]; }; @@ -1607,12 +1608,16 @@ zone_gotwritehandle(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read); - dns_db_currentversion(zone->db, &version); - result = dns_master_dumpinc2(zone->mctx, zone->db, version, - &dns_master_style_default, - zone->masterfile, zone->task, dump_done, - zone, &zone->dctx, zone->masterformat); - dns_db_closeversion(zone->db, &version, ISC_FALSE); + if (zone->db != NULL) { + dns_db_currentversion(zone->db, &version); + result = dns_master_dumpinc2(zone->mctx, zone->db, version, + &dns_master_style_default, + zone->masterfile, zone->task, + dump_done, zone, &zone->dctx, + zone->masterformat); + dns_db_closeversion(zone->db, &version, ISC_FALSE); + } else + result = ISC_R_CANCELED; ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read); UNLOCK_ZONE(zone); if (result != DNS_R_CONTINUE) @@ -3478,6 +3483,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, /* * Everything is ok so attach to the zone. */ + zone->curmaster = 0; zone->masters = new; zone->mastersok = newok; zone->masterkeynames = newname; @@ -6541,6 +6547,14 @@ zone_unload(dns_zone_t *zone) { REQUIRE(LOCKED_ZONE(zone)); + if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) || + !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) { + if (zone->writeio != NULL) + zonemgr_cancelio(zone->writeio); + + if (zone->dctx != NULL) + dns_dumpctx_cancel(zone->dctx); + } ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write); zone_detachdb(zone); ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); @@ -7255,6 +7269,8 @@ stub_callback(isc_task_t *task, isc_event_t *event) { TIME_NOW(&now); + LOCK_ZONE(zone); + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) { zone_debuglog(zone, me, 1, "exiting"); exiting = ISC_TRUE; @@ -7267,9 +7283,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { if (revent->result != ISC_R_SUCCESS) { if (revent->result == ISC_R_TIMEDOUT && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { - LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); - UNLOCK_ZONE(zone); dns_zone_log(zone, ISC_LOG_DEBUG(1), "refreshing stub: timeout retrying " " without EDNS master %s (source %s)", @@ -7311,9 +7325,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { "refreshing stub: rcode (%.*s) retrying " "without EDNS master %s (source %s)", (int)rb.used, rcode, master, source); - LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); - UNLOCK_ZONE(zone); goto same_master; } @@ -7335,9 +7347,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) { master, source); goto next_master; } - LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); - UNLOCK_ZONE(zone); goto same_master; } @@ -7392,21 +7402,17 @@ stub_callback(isc_task_t *task, isc_event_t *event) { ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write); dns_db_detach(&stub->db); - if (zone->masterfile != NULL) { - dns_zone_dump(zone); - TIME_NOW(&zone->loadtime); - } + if (zone->masterfile != NULL) + zone_needdump(zone, 0); dns_message_destroy(&msg); isc_event_free(&event); - LOCK_ZONE(zone); dns_request_destroy(&zone->request); DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime); isc_interval_set(&i, zone->expire, 0); DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime); zone_settimer(zone, &now); - UNLOCK_ZONE(zone); goto free_stub; next_master: @@ -7417,7 +7423,6 @@ stub_callback(isc_task_t *task, isc_event_t *event) { if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); - LOCK_ZONE(zone); dns_request_destroy(&zone->request); /* * Skip to next failed / untried master. @@ -7455,25 +7460,23 @@ stub_callback(isc_task_t *task, isc_event_t *event) { DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH); zone_settimer(zone, &now); - UNLOCK_ZONE(zone); goto free_stub; } } queue_soa_query(zone); - UNLOCK_ZONE(zone); goto free_stub; same_master: if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); - LOCK_ZONE(zone); dns_request_destroy(&zone->request); - UNLOCK_ZONE(zone); ns_query(zone, NULL, stub); + UNLOCK_ZONE(zone); goto done; free_stub: + UNLOCK_ZONE(zone); stub->magic = 0; dns_zone_idetach(&stub->zone); INSIST(stub->db == NULL); @@ -7504,6 +7507,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { isc_result_t result; isc_uint32_t serial, oldserial = 0; unsigned int j; + isc_boolean_t do_queue_xfrin = ISC_FALSE; zone = revent->ev_arg; INSIST(DNS_ZONE_VALID(zone)); @@ -7512,6 +7516,10 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { ENTER; + TIME_NOW(&now); + + LOCK_ZONE(zone); + /* * if timeout log and next master; */ @@ -7519,14 +7527,10 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { isc_sockaddr_format(&zone->masteraddr, master, sizeof(master)); isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source)); - TIME_NOW(&now); - if (revent->result != ISC_R_SUCCESS) { if (revent->result == ISC_R_TIMEDOUT && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) { - LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); - UNLOCK_ZONE(zone); dns_zone_log(zone, ISC_LOG_DEBUG(1), "refresh: timeout retrying without EDNS " "master %s (source %s)", master, source); @@ -7546,10 +7550,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { &zone->sourceaddr, &now)) { - LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR); - UNLOCK_ZONE(zone); goto tcp_transfer; } dns_zone_log(zone, ISC_LOG_DEBUG(1), @@ -7596,9 +7598,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { "refresh: rcode (%.*s) retrying without " "EDNS master %s (source %s)", (int)rb.used, rcode, master, source); - LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS); - UNLOCK_ZONE(zone); goto same_master; } dns_zone_log(zone, ISC_LOG_INFO, @@ -7624,9 +7624,7 @@ 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); @@ -7637,9 +7635,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { master, source); goto next_master; } - LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC); - UNLOCK_ZONE(zone); goto same_master; } } @@ -7700,6 +7696,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { soacnt, master, source); goto next_master; } + /* * Extract serial */ @@ -7727,7 +7724,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { serial = soa.serial; if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) { - result = dns_zone_getserial2(zone, &oldserial); + result = zone_get_from_db(zone, zone->db, NULL, NULL, + &oldserial, NULL, NULL, NULL, NULL, + NULL); RUNTIME_CHECK(result == ISC_R_SUCCESS); zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial, oldserial); @@ -7751,11 +7750,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { } tcp_transfer: isc_event_free(&event); - LOCK_ZONE(zone); dns_request_destroy(&zone->request); - UNLOCK_ZONE(zone); if (zone->type == dns_zone_slave) { - queue_xfrin(zone); + do_queue_xfrin = ISC_TRUE; } else { INSIST(zone->type == dns_zone_stub); ns_query(zone, rdataset, NULL); @@ -7777,9 +7774,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { &now); /* Someone removed the file from underneath us! */ if (result == ISC_R_FILENOTFOUND) { - LOCK_ZONE(zone); zone_needdump(zone, DNS_DUMP_DELAY); - UNLOCK_ZONE(zone); } else if (result != ISC_R_SUCCESS) dns_zone_log(zone, ISC_LOG_ERROR, "refresh: could not set file " @@ -7809,7 +7804,6 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); - LOCK_ZONE(zone); dns_request_destroy(&zone->request); /* * Skip to next failed / untried master. @@ -7851,25 +7845,24 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { } DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC); zone_settimer(zone, &now); - UNLOCK_ZONE(zone); goto detach; } requeue: queue_soa_query(zone); - UNLOCK_ZONE(zone); goto detach; same_master: if (msg != NULL) dns_message_destroy(&msg); isc_event_free(&event); - LOCK_ZONE(zone); dns_request_destroy(&zone->request); queue_soa_query(zone); - UNLOCK_ZONE(zone); detach: + UNLOCK_ZONE(zone); + if (do_queue_xfrin) + queue_xfrin(zone); dns_zone_idetach(&zone); return; } @@ -8227,13 +8220,13 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { isc_uint16_t udpsize = SEND_BUFFER_SIZE; REQUIRE(DNS_ZONE_VALID(zone)); + REQUIRE(LOCKED_ZONE(zone)); REQUIRE((soardataset != NULL && stub == NULL) || (soardataset == NULL && stub != NULL)); REQUIRE(stub == NULL || DNS_STUB_VALID(stub)); ENTER; - LOCK_ZONE(zone); if (stub == NULL) { stub = isc_mem_get(zone->mctx, sizeof(*stub)); if (stub == NULL) @@ -8419,10 +8412,9 @@ ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) { } if (message != NULL) dns_message_destroy(&message); - unlock: + unlock: if (key != NULL) dns_tsigkey_detach(&key); - UNLOCK_ZONE(zone); return; } @@ -10569,15 +10561,22 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, zmgr->transfersin = 10; zmgr->transfersperns = 2; + /* Unreachable lock. */ + result = isc_rwlock_init(&zmgr->urlock, 0, 0); + if (result != ISC_R_SUCCESS) + goto free_rwlock; + /* Create a single task for queueing of SOA queries. */ result = isc_task_create(taskmgr, 1, &zmgr->task); if (result != ISC_R_SUCCESS) - goto free_rwlock; + goto free_urlock; + isc_task_setname(zmgr->task, "zmgr", zmgr); result = isc_ratelimiter_create(mctx, timermgr, zmgr->task, &zmgr->rl); if (result != ISC_R_SUCCESS) goto free_task; + /* default to 20 refresh queries / notifies per second. */ isc_interval_set(&interval, 0, 1000000000/2); result = isc_ratelimiter_setinterval(zmgr->rl, &interval); @@ -10606,6 +10605,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, isc_ratelimiter_detach(&zmgr->rl); free_task: isc_task_detach(&zmgr->task); + free_urlock: + isc_rwlock_destroy(&zmgr->urlock); free_rwlock: isc_rwlock_destroy(&zmgr->rwlock); free_mem: @@ -10786,7 +10787,6 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { UNLOCK_ZONE(zone); } RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); - } isc_result_t @@ -10830,6 +10830,7 @@ zonemgr_free(dns_zonemgr_t *zmgr) { DESTROYLOCK(&zmgr->iolock); isc_ratelimiter_detach(&zmgr->rl); + isc_rwlock_destroy(&zmgr->urlock); isc_rwlock_destroy(&zmgr->rwlock); mctx = zmgr->mctx; isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr)); @@ -11242,12 +11243,12 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, REQUIRE(DNS_ZONEMGR_VALID(zmgr)); locktype = isc_rwlocktype_read; - RWLOCK(&zmgr->rwlock, locktype); + RWLOCK(&zmgr->urlock, locktype); for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { if (zmgr->unreachable[i].expire >= seconds && isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) { - result = isc_rwlock_tryupgrade(&zmgr->rwlock); + result = isc_rwlock_tryupgrade(&zmgr->urlock); if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; zmgr->unreachable[i].last = seconds; @@ -11255,7 +11256,7 @@ dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, break; } } - RWUNLOCK(&zmgr->rwlock, locktype); + RWUNLOCK(&zmgr->urlock, locktype); return (ISC_TF(i < UNREACH_CHACHE_SIZE)); } @@ -11276,11 +11277,11 @@ dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, REQUIRE(DNS_ZONEMGR_VALID(zmgr)); locktype = isc_rwlocktype_read; - RWLOCK(&zmgr->rwlock, locktype); + RWLOCK(&zmgr->urlock, 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); + result = isc_rwlock_tryupgrade(&zmgr->urlock); if (result == ISC_R_SUCCESS) { locktype = isc_rwlocktype_write; zmgr->unreachable[i].expire = 0; @@ -11293,7 +11294,7 @@ dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, break; } } - RWUNLOCK(&zmgr->rwlock, locktype); + RWUNLOCK(&zmgr->urlock, locktype); } void @@ -11306,7 +11307,7 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, REQUIRE(DNS_ZONEMGR_VALID(zmgr)); - RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); + RWLOCK(&zmgr->urlock, isc_rwlocktype_write); for (i = 0; i < UNREACH_CHACHE_SIZE; i++) { /* Existing entry? */ if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) && @@ -11345,7 +11346,7 @@ dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, zmgr->unreachable[oldest].remote = *remote; zmgr->unreachable[oldest].local = *local; } - RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); + RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write); } void diff --git a/lib/isc/pthreads/mutex.c b/lib/isc/pthreads/mutex.c index f8bc43481f65..7c9cc19e651e 100644 --- a/lib/isc/pthreads/mutex.c +++ b/lib/isc/pthreads/mutex.c @@ -78,7 +78,7 @@ struct isc_mutexstats { }; #ifndef ISC_MUTEX_PROFTABLESIZE -#define ISC_MUTEX_PROFTABLESIZE (16 * 1024) +#define ISC_MUTEX_PROFTABLESIZE (1024 * 1024) #endif static isc_mutexstats_t stats[ISC_MUTEX_PROFTABLESIZE]; static int stats_next = 0; @@ -200,24 +200,24 @@ isc_mutex_statsprofile(FILE *fp) { fprintf(fp, "Mutex stats (in us)\n"); for (i = 0; i < stats_next; i++) { - fprintf(fp, "%-12s %4d: %10u %lu.%06lu %lu.%06lu\n", + fprintf(fp, "%-12s %4d: %10u %lu.%06lu %lu.%06lu %5d\n", stats[i].file, stats[i].line, stats[i].count, stats[i].locked_total.tv_sec, stats[i].locked_total.tv_usec, stats[i].wait_total.tv_sec, - stats[i].wait_total.tv_usec - ); + stats[i].wait_total.tv_usec, + i); for (j = 0; j < ISC_MUTEX_MAX_LOCKERS; j++) { locker = &stats[i].lockers[j]; if (locker->file == NULL) continue; - fprintf(fp, " %-11s %4d: %10u %lu.%06lu %lu.%06lu\n", + fprintf(fp, " %-11s %4d: %10u %lu.%06lu %lu.%06lu %5d\n", locker->file, locker->line, locker->count, locker->locked_total.tv_sec, locker->locked_total.tv_usec, locker->wait_total.tv_sec, - locker->wait_total.tv_usec - ); + locker->wait_total.tv_usec, + i); } } } diff --git a/lib/isccfg/api b/lib/isccfg/api index ae9fbaedc545..d15c78ebe60d 100644 --- a/lib/isccfg/api +++ b/lib/isccfg/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 50 -LIBREVISION = 4 +LIBREVISION = 6 LIBAGE = 0 diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 8bb563a1b742..3d02379447e0 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -2203,16 +2203,30 @@ cfg_parser_warning(cfg_parser_t *pctx, unsigned int flags, const char *fmt, ...) #define MAX_LOG_TOKEN 30 /* How much of a token to quote in log messages. */ +static isc_boolean_t +have_current_file(cfg_parser_t *pctx) { + cfg_listelt_t *elt; + if (pctx->open_files == NULL) + return (ISC_FALSE); + + elt = ISC_LIST_TAIL(pctx->open_files->value.list); + if (elt == NULL) + return (ISC_FALSE); + + return (ISC_TRUE); +} + static char * current_file(cfg_parser_t *pctx) { static char none[] = "none"; cfg_listelt_t *elt; cfg_obj_t *fileobj; - if (pctx->open_files == NULL) + if (!have_current_file(pctx)) return (none); + elt = ISC_LIST_TAIL(pctx->open_files->value.list); - if (elt == NULL) + if (elt == NULL) /* shouldn't be possible, but... */ return (none); fileobj = elt->obj; @@ -2235,8 +2249,10 @@ parser_complain(cfg_parser_t *pctx, isc_boolean_t is_warning, if (is_warning) level = ISC_LOG_WARNING; - snprintf(where, sizeof(where), "%s:%u: ", - current_file(pctx), pctx->line); + where[0] = '\0'; + if (have_current_file(pctx)) + snprintf(where, sizeof(where), "%s:%u: ", + current_file(pctx), pctx->line); len = vsnprintf(message, sizeof(message), format, args); if (len >= sizeof(message)) diff --git a/release-notes.css b/release-notes.css deleted file mode 100644 index f01af5787b31..000000000000 --- a/release-notes.css +++ /dev/null @@ -1,42 +0,0 @@ -body { - background-color: #ffffff; - color: #333333; - font-family: "Helvetica Neue", "ArialMT", "Verdana", "Arial", "Helvetica", sans-serif; - font-size: 14px; - line-height: 18px; - margin: 2em auto; - width: 700px; -} - -.command { - font-family: "Courier New", "Courier", monospace; - font-weight: normal; -} - -.note { - background-color: #ddeedd; - border: 1px solid #aaccaa; - margin: 1em 0 1em 0; - padding: 0.5em 1em 0.5em 1em; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; -} - -.screen { - background-color: #ffffee; - border: 1px solid #ddddaa; - padding: 0.25em 1em 0.25em 1em; - margin: 1em 0 1em 0; - -moz-border-radius: 10px; - -webkit-border-radius: 10px; -} - -.section.title { - font-size: 150%; - font-weight: bold; -} - -.section.section.title { - font-size: 130%; - font-weight: bold; -} @@ -7,4 +7,4 @@ MAJORVER=9 MINORVER=6 PATCHVER= RELEASETYPE=-ESV -RELEASEVER=-R6 +RELEASEVER=-R7 |