Vendor import of BIND 9.8.3

This commit is contained in:
Doug Barton 2012-05-28 09:49:28 +00:00
parent ef021ab32c
commit 084de27e02
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/bind9/dist/; revision=236171
svn path=/vendor/bind9/9.8.3/; revision=236172; tag=vendor/bind9/9.8.3
27 changed files with 870 additions and 327 deletions

59
CHANGES
View File

@ -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

4
README
View File

@ -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

View File

@ -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 */
/*
* If the total length is not 71 then this is a empty node
* so return success.
*/
if (nlen + zlen != 71U)
return (ISC_R_SUCCESS);
snprintf(reverse, sizeof(reverse), "%u.%u.%u.%u.in-addr.arpa.",
v[8], v[9], v[10], v[11]);
break;
case 28: /* prefix len 40 */
case ZLEN(32): /* prefix len 32 */
/*
* 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 > 16U && v[(nlen-1)/4 - 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[6], v[8], v[9], v[10]);
len = dns64_rdata(v, 8, rdata);
break;
case 32: /* prefix len 48 */
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 > 7U && v[nlen/4 - 2] != 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[5], v[6], v[8], v[9]);
len = dns64_rdata(v, 6, rdata);
break;
case 36: /* prefix len 56 */
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 > 3U && v[nlen/4 - 1] != 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[4], v[5], v[6], v[8]);
len = dns64_rdata(v, 5, rdata);
break;
case 40: /* prefix len 64 */
case ZLEN(56): /* prefix len 56 */
/*
* The nibbles that map to this byte must be zero for 'name'
* to exist in the zone.
*/
if (v[nlen/4] != 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[3], v[4], v[5], v[6]);
len = dns64_rdata(v, 4, rdata);
break;
case 56: /* prefix len 96 */
case ZLEN(64): /* prefix len 64 */
/*
* 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 (v[(nlen-1)/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[0], v[1], v[2], v[3]);
len = dns64_rdata(v, 3, rdata);
break;
case ZLEN(96): /* prefix len 96 */
/*
* If the total length is not 74 then this is a empty node
* so return success.
*/
if (nlen + zlen != 74U)
return (ISC_R_SUCCESS);
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,12 +289,22 @@ 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];
@ -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);
}

View File

@ -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,

View File

@ -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;

View File

@ -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
/*

View File

@ -4,5 +4,5 @@
# 9.8: 80-89
# 9.9: 90-109
LIBINTERFACE = 80
LIBREVISION = 4
LIBREVISION = 5
LIBAGE = 0

View File

@ -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);

View File

@ -4,5 +4,5 @@
# 9.8: 80-89
# 9.9: 90-109
LIBINTERFACE = 87
LIBREVISION = 0
LIBREVISION = 1
LIBAGE = 6

View File

@ -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';

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -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);
/*%<

View File

@ -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 */

View File

@ -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 */

View File

@ -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 *));
}

View File

@ -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, &region);
tlsa->usage = uint8_fromregion(&region);
isc_region_consume(&region, 1);
tlsa->selector = uint8_fromregion(&region);
isc_region_consume(&region, 1);
tlsa->match = uint8_fromregion(&region);
isc_region_consume(&region, 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 */

View File

@ -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 */

View File

@ -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,61 +3086,13 @@ 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);
/*
* Free bad.
*/
for (sa = ISC_LIST_HEAD(fctx->bad);
sa != NULL;
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));
}
for (sa = ISC_LIST_HEAD(fctx->edns);
sa != NULL;
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));
}
for (sa = ISC_LIST_HEAD(fctx->edns512);
sa != NULL;
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));
}
for (sa = ISC_LIST_HEAD(fctx->bad_edns);
sa != NULL;
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_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);
if (dns_rdataset_isassociated(&fctx->nameservers))
dns_rdataset_disassociate(&fctx->nameservers);
dns_name_free(&fctx->name, res->buckets[bucketnum].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);
@ -3161,6 +3104,73 @@ fctx_destroy(fetchctx_t *fctx) {
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.
*/
for (sa = ISC_LIST_HEAD(fctx->bad);
sa != NULL;
sa = next_sa) {
next_sa = ISC_LIST_NEXT(sa, link);
ISC_LIST_UNLINK(fctx->bad, sa, link);
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
}
for (sa = ISC_LIST_HEAD(fctx->edns);
sa != NULL;
sa = next_sa) {
next_sa = ISC_LIST_NEXT(sa, link);
ISC_LIST_UNLINK(fctx->edns, sa, link);
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
}
for (sa = ISC_LIST_HEAD(fctx->edns512);
sa != NULL;
sa = next_sa) {
next_sa = ISC_LIST_NEXT(sa, link);
ISC_LIST_UNLINK(fctx->edns512, sa, link);
isc_mem_put(fctx->mctx, sa, sizeof(*sa));
}
for (sa = ISC_LIST_HEAD(fctx->bad_edns);
sa != NULL;
sa = next_sa) {
next_sa = ISC_LIST_NEXT(sa, link);
ISC_LIST_UNLINK(fctx->bad_edns, sa, link);
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, fctx->mctx);
if (dns_rdataset_isassociated(&fctx->nameservers))
dns_rdataset_disassociate(&fctx->nameservers);
dns_name_free(&fctx->name, fctx->mctx);
dns_db_detach(&fctx->cache);
dns_adb_detach(&fctx->adb);
isc_mem_free(fctx->mctx, fctx->info);
isc_mem_putanddetach(&fctx->mctx, fctx, sizeof(*fctx));
}
/*
* Fetch event handlers.
*/
@ -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;

View File

@ -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.
*/

View File

@ -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.
*/

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -4,5 +4,5 @@
# 9.8: 80-89
# 9.9: 90-109
LIBINTERFACE = 82
LIBREVISION = 1
LIBREVISION = 2
LIBAGE = 0

View File

@ -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))

View File

@ -5,6 +5,6 @@
#
MAJORVER=9
MINORVER=8
PATCHVER=2
PATCHVER=3
RELEASETYPE=
RELEASEVER=