diff options
-rw-r--r-- | CHANGES | 59 | ||||
-rw-r--r-- | README | 4 | ||||
-rw-r--r-- | bin/named/builtin.c | 210 | ||||
-rw-r--r-- | bin/named/query.c | 5 | ||||
-rw-r--r-- | bin/named/server.c | 2 | ||||
-rw-r--r-- | bin/named/unix/dlz_dlopen_driver.c | 2 | ||||
-rw-r--r-- | lib/bind9/api | 2 | ||||
-rw-r--r-- | lib/bind9/check.c | 2 | ||||
-rw-r--r-- | lib/dns/api | 2 | ||||
-rw-r--r-- | lib/dns/dnssec.c | 2 | ||||
-rw-r--r-- | lib/dns/include/dns/ecdb.h | 4 | ||||
-rw-r--r-- | lib/dns/include/dns/rpz.h | 2 | ||||
-rw-r--r-- | lib/dns/include/dns/sdb.h | 5 | ||||
-rw-r--r-- | lib/dns/include/dns/stats.h | 2 | ||||
-rw-r--r-- | lib/dns/include/dns/tsec.h | 4 | ||||
-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 | 290 | ||||
-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 | 91 | ||||
-rw-r--r-- | lib/dns/tkey.c | 4 | ||||
-rw-r--r-- | lib/dns/zone.c | 124 | ||||
-rw-r--r-- | lib/isc/pthreads/mutex.c | 16 | ||||
-rw-r--r-- | lib/isccfg/api | 2 | ||||
-rw-r--r-- | lib/isccfg/parser.c | 24 | ||||
-rw-r--r-- | version | 2 |
27 files changed, 835 insertions, 292 deletions
@@ -1,3 +1,56 @@ + --- 9.8.3 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] + +3312. [bug] named-checkconf didn't detect a bad dns64 clients acl. + [RT #27631] + +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] + +3306. [bug] Improve DNS64 reverse zone performance. [RT #28563] + +3305. [func] Add wire format lookup method to sdb. [RT #28563] + +3304. [bug] Use hmctx, not mctx when freeing rbtdb->heaps. + [RT #28571] + +3302. [bug] dns_dnssec_findmatchingkeys could fail to find + keys if the zone name contained character that + required special mappings. [RT #28600] + +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] + +3183. [bug] Added RTLD_GLOBAL flag to dlopen call. [RT #26301] + +3197. [bug] Don't try to log the filename and line number when + the config parser can't open a file. [RT #22263] + --- 9.8.2 released --- 3298. [bug] Named could dereference a NULL pointer in @@ -58,9 +111,9 @@ 3274. [bug] Log when a zone is not reusable. Only set loadtime on successful loads. [RT #27650] -3273. [bug] AAAA responses could be returned in the additional - section even when filter-aaaa-on-v4 was in use. - [RT #27292] +3273. [bug] AAAA responses could be returned in the additional + section even when filter-aaaa-on-v4 was in use. + [RT #27292] 3271. [port] darwin: mksymtbl is not always stable, loop several times before giving up. mksymtbl was using non @@ -51,6 +51,10 @@ BIND 9 For up-to-date release notes and errata, see http://www.isc.org/software/bind9/releasenotes +BIND 9.8.3 + + BIND 9.8.3 is a maintenance release. + BIND 9.8.2 BIND 9.8.2 includes a number of bug fixes and prevents a security diff --git a/bin/named/builtin.c b/bin/named/builtin.c index 86afa5a..754e73d 100644 --- a/bin/named/builtin.c +++ b/bin/named/builtin.c @@ -69,35 +69,79 @@ static builtin_t empty_builtin = { do_empty_lookup, NULL, NULL }; static builtin_t dns64_builtin = { do_dns64_lookup, NULL, NULL }; static dns_sdbimplementation_t *builtin_impl; +static dns_sdbimplementation_t *dns64_impl; -static const char hex[] = "0123456789abcdef"; -static const char HEX[] = "0123456789ABCDEF"; +/* + * Pre computed HEX * 16 or 1 table. + */ +static const unsigned char hex16[256] = { + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*00*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*10*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*20*/ + 0, 16, 32, 48, 64, 80, 96,112,128,144, 1, 1, 1, 1, 1, 1, /*30*/ + 1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*40*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*50*/ + 1,160,176,192,208,224,240, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*60*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*70*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*80*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*90*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*A0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*B0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*C0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*D0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /*E0*/ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 /*F0*/ +}; + +const unsigned char decimal[] = "0123456789"; + +static size_t +dns64_rdata(unsigned char *v, size_t start, unsigned char *rdata) { + size_t i, j = 0; + + for (i = 0; i < 4; i++) { + unsigned char c = v[start++]; + if (start == 7) + start++; + if (c > 99) { + rdata[j++] = 3; + rdata[j++] = decimal[c/100]; c = c % 100; + rdata[j++] = decimal[c/10]; c = c % 10; + rdata[j++] = decimal[c]; + } else if (c > 9) { + rdata[j++] = 2; + rdata[j++] = decimal[c/10]; c = c % 10; + rdata[j++] = decimal[c]; + } else { + rdata[j++] = 1; + rdata[j++] = decimal[c]; + } + } + memcpy(&rdata[j], "\07in-addr\04arpa", 14); + return (j + 14); +} static isc_result_t -dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) { - size_t zlen, nlen, j; - const char *s; - unsigned char v[16]; +dns64_cname(const dns_name_t *zone, const dns_name_t *name, + dns_sdblookup_t *lookup) +{ + size_t zlen, nlen, j, len; + unsigned char v[16], n; unsigned int i; - char reverse[sizeof("123.123.123.123.in-addr.arpa.")]; + unsigned char rdata[sizeof("123.123.123.123.in-addr.arpa.")]; + unsigned char *ndata; /* - * The sum the length of the relative name and the length of the zone - * name for a IPv6 reverse lookup comes to 71. + * The combined length of the zone and name is 74. * - * The reverse of 2001::10.0.0.1 (dns64 2001::/96) has a zone of - * "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.2.ip6.arpa" - * and a name of "1.0.0.0.0.0.a.0". The sum of the lengths of these - * two strings is 71. + * The minimum zone length is 10 ((3)ip6(4)arpa(0)). * - * The minimum length for a ip6.arpa zone name is 8. - * - * The length of name should always be odd as we are expecting + * The length of name should always be even as we are expecting * a series of nibbles. */ - zlen = strlen(zone); - nlen = strlen(name); - if ((zlen + nlen) > 71U || zlen < 8U || (nlen % 2) != 1U) + zlen = zone->length; + nlen = name->length; + if ((zlen + nlen) > 74U || zlen < 10U || (nlen % 2) != 0U) return (ISC_R_NOTFOUND); /* @@ -116,25 +160,20 @@ dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) { * are byte aligned and we correctly return ISC_R_NOTFOUND or * ISC_R_SUCCESS. We will not generate a CNAME in this case. */ - i = (nlen % 4) == 1U ? 1 : 0; + ndata = name->ndata; + i = (nlen % 4) == 2U ? 1 : 0; j = nlen; memset(v, 0, sizeof(v)); - while (j >= 1U) { + while (j != 0) { INSIST((i/2) < sizeof(v)); - if (j > 1U && name[1] != '.') + if (ndata[0] != 1) return (ISC_R_NOTFOUND); - v[i/2] >>= 4; - if ((s = strchr(hex, name[0])) != NULL) - v[i/2] |= (s - hex) << 4; - else if ((s = strchr(HEX, name[0])) != NULL) - v[i/2] |= (s - HEX) << 4; - else + n = hex16[ndata[1]&0xff]; + if (n == 1) return (ISC_R_NOTFOUND); - if (j > 1U) - j -= 2; - else - j -= 1; - name += 2; + v[i/2] = n | (v[i/2]>>4); + j -= 2; + ndata += 2; i++; } @@ -144,90 +183,91 @@ dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) { * it corresponds to a empty node in the zone or there should be * a CNAME. */ +#define ZLEN(x) (10 + (x)/2) switch (zlen) { - case 24: /* prefix len 32 */ + case ZLEN(32): /* prefix len 32 */ /* - * If the total length is not 71 then this is a empty node + * The nibbles that map to this byte must be zero for 'name' + * to exist in the zone. + */ + if (nlen > 16U && v[(nlen-1)/4 - 4] != 0) + return (ISC_R_NOTFOUND); + /* + * If the total length is not 74 then this is a empty node * so return success. */ - if (nlen + zlen != 71U) + if (nlen + zlen != 74U) return (ISC_R_SUCCESS); - snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", - v[8], v[9], v[10], v[11]); + len = dns64_rdata(v, 8, rdata); break; - case 28: /* prefix len 40 */ + case ZLEN(40): /* prefix len 40 */ /* * The nibbles that map to this byte must be zero for 'name' * to exist in the zone. */ - if (nlen > 11U && v[nlen/4 - 3] != 0) + if (nlen > 12U && v[(nlen-1)/4 - 3] != 0) return (ISC_R_NOTFOUND); /* - * If the total length is not 71 then this is a empty node + * If the total length is not 74 then this is a empty node * so return success. */ - if (nlen + zlen != 71U) + if (nlen + zlen != 74U) return (ISC_R_SUCCESS); - snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", - v[6], v[8], v[9], v[10]); + len = dns64_rdata(v, 6, rdata); break; - case 32: /* prefix len 48 */ + case ZLEN(48): /* prefix len 48 */ /* * The nibbles that map to this byte must be zero for 'name' * to exist in the zone. */ - if (nlen > 7U && v[nlen/4 - 2] != 0) + if (nlen > 8U && v[(nlen-1)/4 - 2] != 0) return (ISC_R_NOTFOUND); /* - * If the total length is not 71 then this is a empty node + * If the total length is not 74 then this is a empty node * so return success. */ - if (nlen + zlen != 71U) + if (nlen + zlen != 74U) return (ISC_R_SUCCESS); - snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", - v[5], v[6], v[8], v[9]); + len = dns64_rdata(v, 5, rdata); break; - case 36: /* prefix len 56 */ + case ZLEN(56): /* prefix len 56 */ /* * The nibbles that map to this byte must be zero for 'name' * to exist in the zone. */ - if (nlen > 3U && v[nlen/4 - 1] != 0) + if (nlen > 4U && v[(nlen-1)/4 - 1] != 0) return (ISC_R_NOTFOUND); /* - * If the total length is not 71 then this is a empty node + * If the total length is not 74 then this is a empty node * so return success. */ - if (nlen + zlen != 71U) + if (nlen + zlen != 74U) return (ISC_R_SUCCESS); - snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", - v[4], v[5], v[6], v[8]); + len = dns64_rdata(v, 4, rdata); break; - case 40: /* prefix len 64 */ + case ZLEN(64): /* prefix len 64 */ /* * The nibbles that map to this byte must be zero for 'name' * to exist in the zone. */ - if (v[nlen/4] != 0) + if (v[(nlen-1)/4] != 0) return (ISC_R_NOTFOUND); /* - * If the total length is not 71 then this is a empty node + * If the total length is not 74 then this is a empty node * so return success. */ - if (nlen + zlen != 71U) + if (nlen + zlen != 74U) return (ISC_R_SUCCESS); - snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", - v[3], v[4], v[5], v[6]); + len = dns64_rdata(v, 3, rdata); break; - case 56: /* prefix len 96 */ + case ZLEN(96): /* prefix len 96 */ /* - * If the total length is not 71 then this is a empty node + * If the total length is not 74 then this is a empty node * so return success. */ - if (nlen + zlen != 71U) + if (nlen + zlen != 74U) return (ISC_R_SUCCESS); - snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.", - v[0], v[1], v[2], v[3]); + len = dns64_rdata(v, 0, rdata); break; default: /* @@ -236,7 +276,7 @@ dns64_cname(const char *zone, const char *name, dns_sdblookup_t *lookup) { */ return (ISC_R_NOTFOUND); } - return (dns_sdb_putrr(lookup, "CNAME", 600, reverse)); + return (dns_sdb_putrdata(lookup, dns_rdatatype_cname, 600, rdata, len)); } static isc_result_t @@ -249,13 +289,23 @@ builtin_lookup(const char *zone, const char *name, void *dbdata, if (strcmp(name, "@") == 0) return (b->do_lookup(lookup)); - else if (b->do_lookup == do_dns64_lookup) - return (dns64_cname(zone, name, lookup)); else return (ISC_R_NOTFOUND); } static isc_result_t +dns64_lookup(const dns_name_t *zone, const dns_name_t *name, void *dbdata, + dns_sdblookup_t *lookup) +{ + builtin_t *b = (builtin_t *) dbdata; + + if (name->labels == 0 && name->length == 0) + return (b->do_lookup(lookup)); + else + return (dns64_cname(zone, name, lookup)); +} + +static isc_result_t put_txt(dns_sdblookup_t *lookup, const char *text) { unsigned char buf[256]; unsigned int len = strlen(text); @@ -481,7 +531,17 @@ static dns_sdbmethods_t builtin_methods = { builtin_authority, NULL, /* allnodes */ builtin_create, - builtin_destroy + builtin_destroy, + NULL +}; + +static dns_sdbmethods_t dns64_methods = { + NULL, + builtin_authority, + NULL, /* allnodes */ + builtin_create, + builtin_destroy, + dns64_lookup, }; isc_result_t @@ -491,11 +551,17 @@ ns_builtin_init(void) { DNS_SDBFLAG_RELATIVERDATA, ns_g_mctx, &builtin_impl) == ISC_R_SUCCESS); + RUNTIME_CHECK(dns_sdb_register("_dns64", &dns64_methods, NULL, + DNS_SDBFLAG_RELATIVEOWNER | + DNS_SDBFLAG_RELATIVERDATA | + DNS_SDBFLAG_DNS64, + ns_g_mctx, &dns64_impl) + == ISC_R_SUCCESS); return (ISC_R_SUCCESS); } void ns_builtin_deinit(void) { dns_sdb_unregister(&builtin_impl); + dns_sdb_unregister(&dns64_impl); } - diff --git a/bin/named/query.c b/bin/named/query.c index 6d2ee44..9464a82 100644 --- a/bin/named/query.c +++ b/bin/named/query.c @@ -3354,6 +3354,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/bin/named/server.c b/bin/named/server.c index 46f26c4..666d854 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -1358,7 +1358,7 @@ dns64_reverse(dns_view_t *view, isc_mem_t *mctx, isc_netaddr_t *na, { char *cp; char reverse[48+sizeof("ip6.arpa.")]; - const char *dns64_dbtype[4] = { "_builtin", "dns64", ".", "." }; + const char *dns64_dbtype[4] = { "_dns64", "dns64", ".", "." }; const char *sep = ": view "; const char *viewname = view->name; const unsigned char *s6; diff --git a/bin/named/unix/dlz_dlopen_driver.c b/bin/named/unix/dlz_dlopen_driver.c index ca4b1fd..edd3946 100644 --- a/bin/named/unix/dlz_dlopen_driver.c +++ b/bin/named/unix/dlz_dlopen_driver.c @@ -250,7 +250,7 @@ dlopen_dlz_create(const char *dlzname, unsigned int argc, char *argv[], isc_mutex_init(&cd->lock); /* Open the library */ - dlopen_flags = RTLD_NOW; + dlopen_flags = RTLD_NOW|RTLD_GLOBAL; #ifdef RTLD_DEEPBIND /* diff --git a/lib/bind9/api b/lib/bind9/api index 74bc338..089e782 100644 --- a/lib/bind9/api +++ b/lib/bind9/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 80 -LIBREVISION = 4 +LIBREVISION = 5 LIBAGE = 0 diff --git a/lib/bind9/check.c b/lib/bind9/check.c index 695a230..26eaa1a 100644 --- a/lib/bind9/check.c +++ b/lib/bind9/check.c @@ -434,7 +434,7 @@ check_dns64(cfg_aclconfctx_t *actx, const cfg_obj_t *voptions, int nbytes; int i; - static const char *acls[] = { "client", "exclude", "mapped", NULL}; + static const char *acls[] = { "clients", "exclude", "mapped", NULL}; if (voptions != NULL) cfg_map_get(voptions, "dns64", &dns64); diff --git a/lib/dns/api b/lib/dns/api index 69ec5c4..9e783a5 100644 --- a/lib/dns/api +++ b/lib/dns/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 87 -LIBREVISION = 0 +LIBREVISION = 1 LIBAGE = 6 diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c index 34dd464..b72e82d 100644 --- a/lib/dns/dnssec.c +++ b/lib/dns/dnssec.c @@ -1246,7 +1246,7 @@ dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory, isc_dir_init(&dir); isc_buffer_init(&b, namebuf, sizeof(namebuf) - 1); - RETERR(dns_name_totext(origin, ISC_FALSE, &b)); + RETERR(dns_name_tofilenametext(origin, ISC_FALSE, &b)); len = isc_buffer_usedlength(&b); namebuf[len] = '\0'; diff --git a/lib/dns/include/dns/ecdb.h b/lib/dns/include/dns/ecdb.h index 5c735b5..246cc30 100644 --- a/lib/dns/include/dns/ecdb.h +++ b/lib/dns/include/dns/ecdb.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 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 @@ -39,6 +39,8 @@ *** Functions ***/ +ISC_LANG_BEGINDECLS + /* TBD: describe those */ isc_result_t diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h index fbbe539..59d4f87 100644 --- a/lib/dns/include/dns/rpz.h +++ b/lib/dns/include/dns/rpz.h @@ -194,5 +194,7 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr, dns_rpz_policy_t dns_rpz_decode_cname(dns_rdataset_t *, dns_name_t *selfname); +ISC_LANG_ENDDECLS + #endif /* DNS_RPZ_H */ diff --git a/lib/dns/include/dns/sdb.h b/lib/dns/include/dns/sdb.h index 4b3ab48..c57c4a1 100644 --- a/lib/dns/include/dns/sdb.h +++ b/lib/dns/include/dns/sdb.h @@ -59,6 +59,9 @@ typedef struct dns_sdballnodes dns_sdballnodes_t; typedef isc_result_t (*dns_sdblookupfunc_t)(const char *zone, const char *name, void *dbdata, dns_sdblookup_t *); +typedef isc_result_t +(*dns_sdblookup2func_t)(const dns_name_t *zone, const dns_name_t *name, + void *dbdata, dns_sdblookup_t *lookup); typedef isc_result_t (*dns_sdbauthorityfunc_t)(const char *zone, void *dbdata, dns_sdblookup_t *); @@ -81,6 +84,7 @@ typedef struct dns_sdbmethods { dns_sdballnodesfunc_t allnodes; dns_sdbcreatefunc_t create; dns_sdbdestroyfunc_t destroy; + dns_sdblookup2func_t lookup2; } dns_sdbmethods_t; /*** @@ -92,6 +96,7 @@ ISC_LANG_BEGINDECLS #define DNS_SDBFLAG_RELATIVEOWNER 0x00000001U #define DNS_SDBFLAG_RELATIVERDATA 0x00000002U #define DNS_SDBFLAG_THREADSAFE 0x00000004U +#define DNS_SDBFLAG_DNS64 0x00000008U isc_result_t dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h index b8dc17e..bc77d1e 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/tsec.h b/lib/dns/include/dns/tsec.h index a9d60c2..4f31c3e 100644 --- a/lib/dns/include/dns/tsec.h +++ b/lib/dns/include/dns/tsec.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2009, 2010, 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 @@ -132,4 +132,6 @@ dns_tsec_getkey(dns_tsec_t *tsec, void *keyp); *\li *tsecp points to a valid key structure depending on the TSEC type. */ +ISC_LANG_ENDDECLS + #endif /* DNS_TSEC_H */ diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h index 6f7140c..7db600b 100644 --- a/lib/dns/include/dns/view.h +++ b/lib/dns/include/dns/view.h @@ -1075,4 +1075,6 @@ dns_view_setnewzones(dns_view_t *view, isc_boolean_t allow, void *cfgctx, void dns_view_restorekeyring(dns_view_t *view); +ISC_LANG_ENDDECLS + #endif /* DNS_VIEW_H */ diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 1550221..a2523ba 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -7814,7 +7814,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 0000000..11c6d75 --- /dev/null +++ b/lib/dns/rdata/generic/tlsa_52.c @@ -0,0 +1,290 @@ +/* + * 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); +} + +static inline int +casecompare_tlsa(ARGS_COMPARE) { + return (compare_tlsa(rdata1, rdata2)); +} + +#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 0000000..83ce952 --- /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 3084dd8..1ae2f16 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -180,7 +180,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; @@ -446,7 +448,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, @@ -478,8 +481,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); @@ -501,8 +503,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); } @@ -1386,13 +1387,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; @@ -1569,8 +1569,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: @@ -1600,8 +1599,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; @@ -1630,8 +1628,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; @@ -1660,8 +1657,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; @@ -2166,8 +2162,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; @@ -2205,17 +2201,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); @@ -2223,8 +2216,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); + } } @@ -2347,8 +2343,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; @@ -2631,12 +2626,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); @@ -3075,10 +3067,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. @@ -3095,13 +3086,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. */ @@ -3110,7 +3130,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); @@ -3118,7 +3138,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); @@ -3126,7 +3146,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); @@ -3134,31 +3154,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)); } /* @@ -3258,6 +3268,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)); @@ -3307,13 +3318,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 @@ -3322,6 +3338,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)); @@ -3354,7 +3371,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 { @@ -3376,6 +3394,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. */ @@ -3384,8 +3404,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); + } } /* @@ -3473,27 +3496,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); @@ -3596,9 +3621,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; @@ -3609,16 +3632,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); @@ -3631,16 +3650,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) @@ -3690,6 +3707,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); @@ -3713,18 +3732,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); } @@ -3934,6 +3953,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)); @@ -3949,11 +3969,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); } @@ -4008,8 +4032,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); @@ -5723,14 +5746,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; @@ -6232,7 +6252,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. @@ -6287,12 +6308,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; @@ -7210,12 +7228,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; @@ -7955,6 +7970,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); @@ -8052,16 +8068,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 01ab17c..8092c5a 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -216,12 +216,13 @@ dns_sdb_register(const char *drivername, const dns_sdbmethods_t *methods, REQUIRE(drivername != NULL); REQUIRE(methods != NULL); - REQUIRE(methods->lookup != NULL); + REQUIRE(methods->lookup != NULL || methods->lookup2 != NULL); REQUIRE(mctx != NULL); REQUIRE(sdbimp != NULL && *sdbimp == NULL); REQUIRE((flags & ~(DNS_SDBFLAG_RELATIVEOWNER | DNS_SDBFLAG_RELATIVERDATA | - DNS_SDBFLAG_THREADSAFE)) == 0); + DNS_SDBFLAG_THREADSAFE| + DNS_SDBFLAG_DNS64)) == 0); imp = isc_mem_get(mctx, sizeof(dns_sdbimplementation_t)); if (imp == NULL) @@ -280,8 +281,9 @@ initial_size(unsigned int len) { } isc_result_t -dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, dns_ttl_t ttl, - const unsigned char *rdatap, unsigned int rdlen) +dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, + dns_ttl_t ttl, const unsigned char *rdatap, + unsigned int rdlen) { dns_rdatalist_t *rdatalist; dns_rdata_t *rdata; @@ -338,7 +340,6 @@ dns_sdb_putrdata(dns_sdblookup_t *lookup, dns_rdatatype_t typeval, dns_ttl_t ttl return (result); } - isc_result_t dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl, const char *data) @@ -737,6 +738,8 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, char namestr[DNS_NAME_MAXTEXT + 1]; isc_boolean_t isorigin; dns_sdbimplementation_t *imp; + dns_name_t relname; + unsigned int labels; REQUIRE(VALID_SDB(sdb)); REQUIRE(create == ISC_FALSE); @@ -747,33 +750,46 @@ findnode(dns_db_t *db, dns_name_t *name, isc_boolean_t create, imp = sdb->implementation; - isc_buffer_init(&b, namestr, sizeof(namestr)); - if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { - dns_name_t relname; - unsigned int labels; + isorigin = dns_name_equal(name, &sdb->common.origin); - labels = dns_name_countlabels(name) - - dns_name_countlabels(&db->origin); - dns_name_init(&relname, NULL); - dns_name_getlabelsequence(name, 0, labels, &relname); - result = dns_name_totext(&relname, ISC_TRUE, &b); - if (result != ISC_R_SUCCESS) - return (result); + if (imp->methods->lookup2 != NULL) { + if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { + labels = dns_name_countlabels(name) - + dns_name_countlabels(&db->origin); + dns_name_init(&relname, NULL); + dns_name_getlabelsequence(name, 0, labels, &relname); + name = &relname; + } } else { - result = dns_name_totext(name, ISC_TRUE, &b); - if (result != ISC_R_SUCCESS) - return (result); + isc_buffer_init(&b, namestr, sizeof(namestr)); + if ((imp->flags & DNS_SDBFLAG_RELATIVEOWNER) != 0) { + + labels = dns_name_countlabels(name) - + dns_name_countlabels(&db->origin); + dns_name_init(&relname, NULL); + dns_name_getlabelsequence(name, 0, labels, &relname); + result = dns_name_totext(&relname, ISC_TRUE, &b); + if (result != ISC_R_SUCCESS) + return (result); + } else { + result = dns_name_totext(name, ISC_TRUE, &b); + if (result != ISC_R_SUCCESS) + return (result); + } + isc_buffer_putuint8(&b, 0); } - isc_buffer_putuint8(&b, 0); result = createnode(sdb, &node); if (result != ISC_R_SUCCESS) return (result); - isorigin = dns_name_equal(name, &sdb->common.origin); - MAYBE_LOCK(sdb); - result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, node); + if (imp->methods->lookup2 != NULL) + result = imp->methods->lookup2(&sdb->common.origin, name, + sdb->dbdata, node); + else + result = imp->methods->lookup(sdb->zone, namestr, sdb->dbdata, + node); MAYBE_UNLOCK(sdb); if (result != ISC_R_SUCCESS && !(result == ISC_R_NOTFOUND && @@ -811,13 +827,13 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, unsigned int nlabels, olabels; isc_result_t result; unsigned int i; + unsigned int flags; REQUIRE(VALID_SDB(sdb)); REQUIRE(nodep == NULL || *nodep == NULL); REQUIRE(version == NULL || version == (void *) &dummy); UNUSED(options); - UNUSED(sdb); if (!dns_name_issubdomain(name, &db->origin)) return (DNS_R_NXDOMAIN); @@ -834,17 +850,37 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, } result = DNS_R_NXDOMAIN; - - for (i = olabels; i <= nlabels; i++) { + flags = sdb->implementation->flags; + i = (flags & DNS_SDBFLAG_DNS64) != 0 ? nlabels : olabels; + for (; i <= nlabels; i++) { /* * Look up the next label. */ 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); + + /* + * DNS64 zone's don't have DNAME or NS records. + */ + if ((flags & DNS_SDBFLAG_DNS64) != 0) + goto skip; + + /* + * DNS64 zone's don't have DNAME or NS records. + */ + if ((flags & DNS_SDBFLAG_DNS64) != 0) + goto skip; /* * Look for a DNAME at the current label, unless this is @@ -895,6 +931,7 @@ find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version, continue; } + skip: /* * If we're looking for ANY, we're done. */ diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c index bfc8e8b..0112f7e 100644 --- a/lib/dns/tkey.c +++ b/lib/dns/tkey.c @@ -485,9 +485,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 61a8170..22870dc 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -429,6 +429,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; @@ -446,7 +447,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]; }; @@ -1676,12 +1677,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) @@ -2695,7 +2700,8 @@ check_nsec3param(dns_zone_t *zone, dns_db_t *db) { */ static void set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key, - isc_stdtime_t now) { + isc_stdtime_t now) +{ const char me[] = "set_refreshkeytimer"; isc_stdtime_t then; isc_time_t timenow, timethen; @@ -4443,6 +4449,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; @@ -8531,6 +8538,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); @@ -9245,6 +9260,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; @@ -9257,9 +9274,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)", @@ -9301,9 +9316,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; } @@ -9325,9 +9338,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; } @@ -9382,21 +9393,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: @@ -9407,7 +9414,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. @@ -9445,25 +9451,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); @@ -9494,6 +9498,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)); @@ -9502,6 +9507,10 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { ENTER; + TIME_NOW(&now); + + LOCK_ZONE(zone); + /* * if timeout log and next master; */ @@ -9509,14 +9518,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); @@ -9536,10 +9541,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), @@ -9586,9 +9589,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, @@ -9614,9 +9615,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); @@ -9627,9 +9626,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; } } @@ -9690,6 +9687,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) { soacnt, master, source); goto next_master; } + /* * Extract serial */ @@ -9717,7 +9715,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); @@ -9741,11 +9741,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); @@ -9767,9 +9765,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 " @@ -9799,7 +9795,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. @@ -9841,25 +9836,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; } @@ -10217,13 +10211,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) @@ -10414,10 +10408,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; } @@ -12597,15 +12590,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); @@ -12634,6 +12634,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: @@ -12814,7 +12816,6 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) { UNLOCK_ZONE(zone); } RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read); - } isc_result_t @@ -12858,6 +12859,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)); @@ -13270,12 +13272,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; @@ -13283,7 +13285,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)); } @@ -13304,11 +13306,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; @@ -13321,7 +13323,7 @@ dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote, break; } } - RWUNLOCK(&zmgr->rwlock, locktype); + RWUNLOCK(&zmgr->urlock, locktype); } void @@ -13334,7 +13336,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) && @@ -13373,7 +13375,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 ba04f16..c7e5795 100644 --- a/lib/isc/pthreads/mutex.c +++ b/lib/isc/pthreads/mutex.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008, 2011 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2002 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -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 2b2a12d..9f3d38c 100644 --- a/lib/isccfg/api +++ b/lib/isccfg/api @@ -4,5 +4,5 @@ # 9.8: 80-89 # 9.9: 90-109 LIBINTERFACE = 82 -LIBREVISION = 1 +LIBREVISION = 2 LIBAGE = 0 diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c index 1d1f08e..ef20184 100644 --- a/lib/isccfg/parser.c +++ b/lib/isccfg/parser.c @@ -2232,16 +2232,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; @@ -2264,8 +2278,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)) @@ -5,6 +5,6 @@ # MAJORVER=9 MINORVER=8 -PATCHVER=2 +PATCHVER=3 RELEASETYPE= RELEASEVER= |