aboutsummaryrefslogtreecommitdiff
path: root/lib/dns
diff options
context:
space:
mode:
authorXin LI <delphij@FreeBSD.org>2015-04-08 17:52:54 +0000
committerXin LI <delphij@FreeBSD.org>2015-04-08 17:52:54 +0000
commit7ba7a5de74780dee4ec54bace1ec36427be1d8b8 (patch)
treea5a1890b0b884a1d303e90c4130c3b731772abd5 /lib/dns
parenta2bc50f814b6966b412ba90221460066a8b31951 (diff)
Vendor import of BIND 9.9.7vendor/bind9/9.9.7
Diffstat (limited to 'lib/dns')
-rw-r--r--lib/dns/adb.c10
-rw-r--r--lib/dns/api2
-rw-r--r--lib/dns/diff.c5
-rw-r--r--lib/dns/dispatch.c28
-rw-r--r--lib/dns/gen.c4
-rw-r--r--lib/dns/include/dns/dispatch.h15
-rw-r--r--lib/dns/include/dns/log.h3
-rw-r--r--lib/dns/include/dns/rbt.h5
-rw-r--r--lib/dns/include/dns/request.h3
-rw-r--r--lib/dns/journal.c2
-rw-r--r--lib/dns/keytable.c11
-rw-r--r--lib/dns/log.c3
-rw-r--r--lib/dns/master.c47
-rw-r--r--lib/dns/masterdump.c3
-rw-r--r--lib/dns/message.c6
-rw-r--r--lib/dns/name.c1
-rw-r--r--lib/dns/nsec3.c4
-rw-r--r--lib/dns/openssldh_link.c4
-rw-r--r--lib/dns/opensslecdsa_link.c12
-rw-r--r--lib/dns/opensslgost_link.c2
-rw-r--r--lib/dns/private.c3
-rw-r--r--lib/dns/rbt.c4
-rw-r--r--lib/dns/rbtdb.c29
-rw-r--r--lib/dns/rdata.c10
-rw-r--r--lib/dns/rdata/generic/cdnskey_60.c4
-rw-r--r--lib/dns/rdata/generic/cds_59.c5
-rw-r--r--lib/dns/rdata/generic/keydata_65533.c66
-rw-r--r--lib/dns/rdata/generic/nsec3_50.c5
-rw-r--r--lib/dns/rdata/generic/openpgpkey_61.c240
-rw-r--r--lib/dns/rdata/generic/openpgpkey_61.h27
-rw-r--r--lib/dns/rdata/generic/opt_41.c59
-rw-r--r--lib/dns/rdata/generic/rrsig_46.c3
-rw-r--r--lib/dns/rdata/generic/sig_24.c3
-rw-r--r--lib/dns/rdata/generic/spf_99.h28
-rw-r--r--lib/dns/rdata/generic/txt_16.c55
-rw-r--r--lib/dns/rdataset.c4
-rw-r--r--lib/dns/request.c14
-rw-r--r--lib/dns/resolver.c78
-rw-r--r--lib/dns/rootns.c18
-rw-r--r--lib/dns/spnego_asn1.c50
-rw-r--r--lib/dns/tkey.c21
-rw-r--r--lib/dns/tsig.c5
-rw-r--r--lib/dns/validator.c5
-rw-r--r--lib/dns/zone.c515
-rw-r--r--lib/dns/zt.c8
45 files changed, 1077 insertions, 352 deletions
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index c75ea59f751f..da77bb6c92a5 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -1768,12 +1768,12 @@ new_adbentry(dns_adb_t *adb) {
ISC_LINK_INIT(e, plink);
LOCK(&adb->entriescntlock);
adb->entriescnt++;
- if (!adb->growentries_sent && adb->growentries_sent &&
+ if (!adb->growentries_sent && adb->excl != NULL &&
adb->entriescnt > (adb->nentries * 8))
{
isc_event_t *event = &adb->growentries;
inc_adb_irefcnt(adb);
- isc_task_send(adb->task, &event);
+ isc_task_send(adb->excl, &event);
adb->growentries_sent = ISC_TRUE;
}
UNLOCK(&adb->entriescntlock);
@@ -3805,11 +3805,11 @@ fetch_callback(isc_task_t *task, isc_event_t *ev) {
goto out;
/* XXXMLG Don't pound on bad servers. */
if (address_type == DNS_ADBFIND_INET) {
- name->expire_v4 = ISC_MIN(name->expire_v4, now + 300);
+ name->expire_v4 = ISC_MIN(name->expire_v4, now + 10);
name->fetch_err = FIND_ERR_FAILURE;
inc_stats(adb, dns_resstatscounter_gluefetchv4fail);
} else {
- name->expire_v6 = ISC_MIN(name->expire_v6, now + 300);
+ name->expire_v6 = ISC_MIN(name->expire_v6, now + 10);
name->fetch6_err = FIND_ERR_FAILURE;
inc_stats(adb, dns_resstatscounter_gluefetchv6fail);
}
diff --git a/lib/dns/api b/lib/dns/api
index b11beb8343db..83640ba56b2e 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -4,6 +4,6 @@
# 9.8: 80-89, 120-129
# 9.9: 90-109
# 9.9-sub: 130-139
-LIBINTERFACE = 105
+LIBINTERFACE = 107
LIBREVISION = 0
LIBAGE = 1
diff --git a/lib/dns/diff.c b/lib/dns/diff.c
index 4517dade38dc..b6d4152999f8 100644
--- a/lib/dns/diff.c
+++ b/lib/dns/diff.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011, 2013-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -390,9 +390,6 @@ diff_apply(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *ver,
* Issue a warning and continue.
*/
if (warn) {
- char classbuf[DNS_RDATATYPE_FORMATSIZE];
- char namebuf[DNS_NAME_FORMATSIZE];
-
dns_name_format(dns_db_origin(db),
namebuf,
sizeof(namebuf));
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index 129895431ddf..1c113eccb235 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -3038,6 +3038,8 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
if (result != ISC_R_SUCCESS)
return (result);
+ disp->socktype = isc_sockettype_udp;
+
if ((attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0) {
result = get_udpsocket(mgr, disp, sockmgr, localaddr, &sock,
dup_socket);
@@ -3087,7 +3089,6 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
isc_mempool_setname(disp->portpool, "disp_portpool");
isc_mempool_setfreemax(disp->portpool, 128);
}
- disp->socktype = isc_sockettype_udp;
disp->socket = sock;
disp->local = *localaddr;
@@ -3233,6 +3234,17 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
dns_messageid_t *idp, dns_dispentry_t **resp,
isc_socketmgr_t *sockmgr)
{
+ return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg,
+ idp, resp, sockmgr));
+}
+
+isc_result_t
+dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options,
+ isc_sockaddr_t *dest, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ dns_messageid_t *idp, dns_dispentry_t **resp,
+ isc_socketmgr_t *sockmgr)
+{
dns_dispentry_t *res;
unsigned int bucket;
in_port_t localport = 0;
@@ -3320,10 +3332,14 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
}
/*
- * Try somewhat hard to find an unique ID.
+ * Try somewhat hard to find an unique ID unless FIXEDID is set
+ * in which case we use the id passed in via *idp.
*/
LOCK(&qid->lock);
- id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
+ if ((options & DNS_DISPATCHOPT_FIXEDID) != 0)
+ id = *idp;
+ else
+ id = (dns_messageid_t)dispatch_random(DISP_ARC4CTX(disp));
ok = ISC_FALSE;
i = 0;
do {
@@ -3332,6 +3348,8 @@ dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
ok = ISC_TRUE;
break;
}
+ if ((disp->attributes & DNS_DISPATCHATTR_FIXEDID) != 0)
+ break;
id += qid->qid_increment;
id &= 0x0000ffff;
} while (i++ < 64);
@@ -3419,7 +3437,7 @@ dns_dispatch_addresponse(dns_dispatch_t *disp, isc_sockaddr_t *dest,
REQUIRE(VALID_DISPATCH(disp));
REQUIRE((disp->attributes & DNS_DISPATCHATTR_EXCLUSIVE) == 0);
- return (dns_dispatch_addresponse2(disp, dest, task, action, arg,
+ return (dns_dispatch_addresponse3(disp, 0, dest, task, action, arg,
idp, resp, NULL));
}
diff --git a/lib/dns/gen.c b/lib/dns/gen.c
index ff41de6d624a..7a7dafb46100 100644
--- a/lib/dns/gen.c
+++ b/lib/dns/gen.c
@@ -23,10 +23,12 @@
*/
#define _CRT_SECURE_NO_DEPRECATE 1
/*
- * We use snprintf.
+ * We use snprintf which was defined late in Windows even it is in C99.
*/
+#if _MSC_VER < 1900
#define snprintf _snprintf
#endif
+#endif
#include <sys/types.h>
diff --git a/lib/dns/include/dns/dispatch.h b/lib/dns/include/dns/dispatch.h
index 1235f7ca40f3..f9e45db3b179 100644
--- a/lib/dns/include/dns/dispatch.h
+++ b/lib/dns/include/dns/dispatch.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -143,10 +143,14 @@ struct dns_dispatchset {
#define DNS_DISPATCHATTR_NOLISTEN 0x00000020U
#define DNS_DISPATCHATTR_MAKEQUERY 0x00000040U
#define DNS_DISPATCHATTR_CONNECTED 0x00000080U
-/*#define DNS_DISPATCHATTR_RANDOMPORT 0x00000100U*/
+#define DNS_DISPATCHATTR_FIXEDID 0x00000100U
#define DNS_DISPATCHATTR_EXCLUSIVE 0x00000200U
/*@}*/
+/*
+ */
+#define DNS_DISPATCHOPT_FIXEDID 0x00000001U
+
isc_result_t
dns_dispatchmgr_create(isc_mem_t *mctx, isc_entropy_t *entropy,
dns_dispatchmgr_t **mgrp);
@@ -370,6 +374,13 @@ dns_dispatch_starttcp(dns_dispatch_t *disp);
*/
isc_result_t
+dns_dispatch_addresponse3(dns_dispatch_t *disp, unsigned int options,
+ isc_sockaddr_t *dest, isc_task_t *task,
+ isc_taskaction_t action, void *arg,
+ isc_uint16_t *idp, dns_dispentry_t **resp,
+ isc_socketmgr_t *sockmgr);
+
+isc_result_t
dns_dispatch_addresponse2(dns_dispatch_t *disp, isc_sockaddr_t *dest,
isc_task_t *task, isc_taskaction_t action, void *arg,
isc_uint16_t *idp, dns_dispentry_t **resp,
diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h
index e8c8c105473e..488b48e33de2 100644
--- a/lib/dns/include/dns/log.h
+++ b/lib/dns/include/dns/log.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -44,6 +44,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
#define DNS_LOGCATEGORY_EDNS_DISABLED (&dns_categories[11])
#define DNS_LOGCATEGORY_RPZ (&dns_categories[12])
#define DNS_LOGCATEGORY_RRL (&dns_categories[13])
+#define DNS_LOGCATEGORY_CNAME (&dns_categories[14])
/* Backwards compatibility. */
#define DNS_LOGCATEGORY_GENERAL ISC_LOGCATEGORY_GENERAL
diff --git a/lib/dns/include/dns/rbt.h b/lib/dns/include/dns/rbt.h
index 8b382b5ed6be..947e7c177a47 100644
--- a/lib/dns/include/dns/rbt.h
+++ b/lib/dns/include/dns/rbt.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -115,6 +115,9 @@ struct dns_rbtnode {
unsigned int oldnamelen : 8; /*%< range is 1..255 */
/*@}*/
+ /* node needs to be cleaned from rpz */
+ unsigned int rpz : 1;
+
#ifdef DNS_RBT_USEHASH
unsigned int hashval;
#endif
diff --git a/lib/dns/include/dns/request.h b/lib/dns/include/dns/request.h
index 8c792ddd5774..f5ec69614aec 100644
--- a/lib/dns/include/dns/request.h
+++ b/lib/dns/include/dns/request.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2010, 2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -48,6 +48,7 @@
#define DNS_REQUESTOPT_TCP 0x00000001U
#define DNS_REQUESTOPT_CASE 0x00000002U
+#define DNS_REQUESTOPT_FIXEDID 0x00000004U
typedef struct dns_requestevent {
ISC_EVENT_COMMON(struct dns_requestevent);
diff --git a/lib/dns/journal.c b/lib/dns/journal.c
index 2d0b3f5f7494..a21ec2e8a348 100644
--- a/lib/dns/journal.c
+++ b/lib/dns/journal.c
@@ -1391,6 +1391,8 @@ roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) {
dns_diff_clear(&diff);
+ INSIST(ver == NULL);
+
return (result);
}
diff --git a/lib/dns/keytable.c b/lib/dns/keytable.c
index 56fefcd2c122..29f129ffbf5f 100644
--- a/lib/dns/keytable.c
+++ b/lib/dns/keytable.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2010, 2013-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -275,16 +275,17 @@ dns_keytable_deletekeynode(dns_keytable_t *keytable, dst_key_t *dstkey) {
}
knode = node->data;
- if (knode->next == NULL &&
- (knode->key == NULL ||
- dst_key_compare(knode->key, dstkey) == ISC_TRUE)) {
+ if (knode->next == NULL && knode->key != NULL &&
+ dst_key_compare(knode->key, dstkey) == ISC_TRUE)
+ {
result = dns_rbt_deletenode(keytable->table, node, ISC_FALSE);
goto finish;
}
kprev = (dns_keynode_t **) &node->data;
while (knode != NULL) {
- if (dst_key_compare(knode->key, dstkey) == ISC_TRUE)
+ if (knode->key != NULL &&
+ dst_key_compare(knode->key, dstkey) == ISC_TRUE)
break;
kprev = &knode->next;
knode = knode->next;
diff --git a/lib/dns/log.c b/lib/dns/log.c
index 75e0d79ba34b..70055aaf887b 100644
--- a/lib/dns/log.c
+++ b/lib/dns/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -46,6 +46,7 @@ LIBDNS_EXTERNAL_DATA isc_logcategory_t dns_categories[] = {
{ "edns-disabled", 0 },
{ "rpz", 0 },
{ "rate-limit", 0 },
+ { "cname", 0 },
{ NULL, 0 }
};
diff --git a/lib/dns/master.c b/lib/dns/master.c
index dcea97a0bdd4..1fde70c3b6ec 100644
--- a/lib/dns/master.c
+++ b/lib/dns/master.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -209,7 +209,7 @@ task_send(dns_loadctx_t *lctx);
static void
loadctx_destroy(dns_loadctx_t *lctx);
-#define GETTOKEN(lexer, options, token, eol) \
+#define GETTOKENERR(lexer, options, token, eol, err) \
do { \
result = gettoken(lexer, options, token, eol, callbacks); \
switch (result) { \
@@ -222,6 +222,7 @@ loadctx_destroy(dns_loadctx_t *lctx);
SETRESULT(lctx, result); \
LOGIT(result); \
read_till_eol = ISC_TRUE; \
+ err \
goto next_line; \
} else \
goto log_and_cleanup; \
@@ -237,6 +238,8 @@ loadctx_destroy(dns_loadctx_t *lctx);
goto log_and_cleanup; \
} \
} while (0)
+#define GETTOKEN(lexer, options, token, eol) \
+ GETTOKENERR(lexer, options, token, eol, {} )
#define COMMITALL \
do { \
@@ -377,13 +380,19 @@ gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *token,
if (eol != ISC_TRUE)
if (token->type == isc_tokentype_eol ||
token->type == isc_tokentype_eof) {
+ unsigned long int line;
+ const char *what;
+ const char *file;
+ file = isc_lex_getsourcename(lex);
+ line = isc_lex_getsourceline(lex);
+ if (token->type == isc_tokentype_eol) {
+ line--;
+ what = "line";
+ } else
+ what = "file";
(*callbacks->error)(callbacks,
"dns_master_load: %s:%lu: unexpected end of %s",
- isc_lex_getsourcename(lex),
- isc_lex_getsourceline(lex),
- (token->type ==
- isc_tokentype_eol) ?
- "line" : "file");
+ file, line, what);
return (ISC_R_UNEXPECTEDEND);
}
return (ISC_R_SUCCESS);
@@ -505,6 +514,7 @@ incctx_create(isc_mem_t *mctx, dns_name_t *origin, dns_incctx_t **ictxp) {
ictx->drop = ISC_FALSE;
ictx->glue_line = 0;
ictx->current_line = 0;
+ ictx->origin_changed = ISC_TRUE;
*ictxp = ictx;
return (ISC_R_SUCCESS);
@@ -807,6 +817,7 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
isc_textregion_t r;
int i, n, start, stop, step = 0;
dns_incctx_t *ictx;
+ char dummy;
ictx = lctx->inc;
callbacks = lctx->callbacks;
@@ -823,9 +834,9 @@ generate(dns_loadctx_t *lctx, char *range, char *lhs, char *gtype, char *rhs,
}
isc_buffer_init(&target, target_mem, target_size);
- n = sscanf(range, "%d-%d/%d", &start, &stop, &step);
- if ((n < 2) || (start < 0) || (stop < 0) || (step < 0) ||
- (stop < start))
+ n = sscanf(range, "%d-%d%[/]%d", &start, &stop, &dummy, &step);
+ if ((n != 2 && n != 4) || (start < 0) || (stop < 0) ||
+ (n == 4 && step < 1) || (stop < start))
{
(*callbacks->error)(callbacks,
"%s: %s:%lu: invalid range '%s'",
@@ -1109,7 +1120,6 @@ load_text(dns_loadctx_t *lctx) {
line = isc_lex_getsourceline(lctx->lex);
source = isc_lex_getsourcename(lctx->lex);
ictx = lctx->inc;
- EXPECTEOL;
continue;
}
done = ISC_TRUE;
@@ -1145,7 +1155,9 @@ load_text(dns_loadctx_t *lctx) {
finish_origin = ISC_TRUE;
} else if (strcasecmp(DNS_AS_STR(token),
"$TTL") == 0) {
- GETTOKEN(lctx->lex, 0, &token, ISC_FALSE);
+ GETTOKENERR(lctx->lex, 0, &token, ISC_FALSE,
+ lctx->ttl = 0;
+ lctx->default_ttl_known = ISC_TRUE;);
result =
dns_ttl_fromtext(&token.value.as_textregion,
&lctx->ttl);
@@ -1197,7 +1209,6 @@ load_text(dns_loadctx_t *lctx) {
token.type == isc_tokentype_eof) {
if (token.type == isc_tokentype_eof)
WARNUNEXPECTEDEOF(lctx->lex);
- isc_lex_ungettoken(lctx->lex, &token);
/*
* No origin field.
*/
@@ -1416,6 +1427,7 @@ load_text(dns_loadctx_t *lctx) {
}
if (finish_include) {
finish_include = ISC_FALSE;
+ EXPECTEOL;
result = pushfile(include_file, new_name, lctx);
if (MANYERRS(lctx, result)) {
SETRESULT(lctx, result);
@@ -1426,6 +1438,7 @@ load_text(dns_loadctx_t *lctx) {
goto insist_and_cleanup;
}
ictx = lctx->inc;
+ ictx->origin_changed = ISC_TRUE;
source = isc_lex_getsourcename(lctx->lex);
line = isc_lex_getsourceline(lctx->lex);
POST(line);
@@ -2046,6 +2059,11 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) {
if (result != ISC_R_SUCCESS)
return (result);
+ /*
+ * Push origin_changed.
+ */
+ new->origin_changed = ictx->origin_changed;
+
/* Set current domain. */
if (ictx->glue != NULL || ictx->current != NULL) {
for (new_in_use = 0; new_in_use < NBUFS; new_in_use++)
@@ -2070,8 +2088,7 @@ pushfile(const char *master_file, dns_name_t *origin, dns_loadctx_t *lctx) {
return (ISC_R_SUCCESS);
cleanup:
- if (new != NULL)
- incctx_destroy(lctx->mctx, new);
+ incctx_destroy(lctx->mctx, new);
return (result);
}
diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c
index 01f797cb99ed..7e53a735c47e 100644
--- a/lib/dns/masterdump.c
+++ b/lib/dns/masterdump.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -994,7 +994,6 @@ dump_rdataset_raw(isc_mem_t *mctx, dns_name_t *name, dns_rdataset_t *rdataset,
do {
dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_region_t r;
dns_rdataset_current(rdataset, &rdata);
dns_rdata_toregion(&rdata, &r);
diff --git a/lib/dns/message.c b/lib/dns/message.c
index d76eb4fb26c6..b95e48ea2641 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id$ */
-
/*! \file */
/***
@@ -3268,7 +3266,7 @@ dns_message_pseudosectiontotext(dns_message_t *msg,
ADD_STRING(target, "; NSID");
} else {
ADD_STRING(target, "; OPT=");
- sprintf(buf, "%u", optcode);
+ snprintf(buf, sizeof(buf), "%u", optcode);
ADD_STRING(target, buf);
}
diff --git a/lib/dns/name.c b/lib/dns/name.c
index 5207f74b4240..3b7ff3f962bf 100644
--- a/lib/dns/name.c
+++ b/lib/dns/name.c
@@ -579,6 +579,7 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
if (name1 == name2) {
*orderp = 0;
+ *nlabelsp = name1->labels;
return (dns_namereln_equal);
}
diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c
index ef43c35d27bb..11ae837a54a8 100644
--- a/lib/dns/nsec3.c
+++ b/lib/dns/nsec3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2008-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2008-2015 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
@@ -2057,8 +2057,6 @@ dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
(scope >= 0 && (order > 0 ||
memcmp(hash, nsec3.next, length) < 0)))
{
- char namebuf[DNS_NAME_FORMATSIZE];
-
dns_name_format(qname, namebuf, sizeof(namebuf));
(*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
"name does not exist: '%s'", namebuf);
diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c
index cb9fb77d4219..953e8fd50e4a 100644
--- a/lib/dns/openssldh_link.c
+++ b/lib/dns/openssldh_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -93,7 +93,7 @@ openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
if (r.length < len)
return (ISC_R_NOSPACE);
ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv);
- if (ret == 0)
+ if (ret <= 0)
return (dst__openssl_toresult2("DH_compute_key",
DST_R_COMPUTESECRETFAILURE));
isc_buffer_add(secret, len);
diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c
index 40081c2df856..34f8ba03b092 100644
--- a/lib/dns/opensslecdsa_link.c
+++ b/lib/dns/opensslecdsa_link.c
@@ -295,10 +295,13 @@ opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
UNUSED(unused);
UNUSED(callback);
- if (key->key_alg == DST_ALG_ECDSA256)
+ if (key->key_alg == DST_ALG_ECDSA256) {
group_nid = NID_X9_62_prime256v1;
- else
+ key->key_size = DNS_KEY_ECDSA256SIZE * 4;
+ } else {
group_nid = NID_secp384r1;
+ key->key_size = DNS_KEY_ECDSA384SIZE * 4;
+ }
eckey = EC_KEY_new_by_curve_name(group_nid);
if (eckey == NULL)
@@ -433,6 +436,7 @@ opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
isc_buffer_forward(data, len);
key->keydata.pkey = pkey;
+ key->key_size = len * 4;
ret = ISC_R_SUCCESS;
err:
@@ -581,6 +585,10 @@ opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
}
key->keydata.pkey = pkey;
+ if (key->key_alg == DST_ALG_ECDSA256)
+ key->key_size = DNS_KEY_ECDSA256SIZE * 4;
+ else
+ key->key_size = DNS_KEY_ECDSA384SIZE * 4;
ret = ISC_R_SUCCESS;
err:
diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c
index b0578661f97f..a01e9f32bb25 100644
--- a/lib/dns/opensslgost_link.c
+++ b/lib/dns/opensslgost_link.c
@@ -196,6 +196,7 @@ opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) {
DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen",
DST_R_OPENSSLFAILURE));
key->keydata.pkey = pkey;
+ key->key_size = EVP_PKEY_bits(pkey);
EVP_PKEY_CTX_free(ctx);
return (ISC_R_SUCCESS);
@@ -281,6 +282,7 @@ opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) {
return (dst__openssl_toresult2("d2i_PUBKEY",
DST_R_OPENSSLFAILURE));
key->keydata.pkey = pkey;
+ key->key_size = EVP_PKEY_bits(pkey);
return (ISC_R_SUCCESS);
}
diff --git a/lib/dns/private.c b/lib/dns/private.c
index 6521279f2d9b..c29522c52990 100644
--- a/lib/dns/private.c
+++ b/lib/dns/private.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2011, 2012, 2015 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
@@ -162,7 +162,6 @@ dns_private_chains(dns_db_t *db, dns_dbversion_t *ver,
for (result = dns_rdataset_first(&privateset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&privateset)) {
- unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
dns_rdata_t private = DNS_RDATA_INIT;
dns_rdata_t rdata = DNS_RDATA_INIT;
diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c
index 0e9c5f950569..1b6121de7945 100644
--- a/lib/dns/rbt.c
+++ b/lib/dns/rbt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -1446,6 +1446,8 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
LEFT(node) = NULL;
DOWN(node) = NULL;
DATA(node) = NULL;
+ node->rpz = 0;
+
#ifdef DNS_RBT_USEHASH
HASHNEXT(node) = NULL;
HASHVAL(node) = 0;
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index a8ad8329c73b..a1398d3d1ab1 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -1636,7 +1636,7 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node)
switch (node->nsec) {
case DNS_RBT_NSEC_NORMAL:
#ifdef BIND9
- if (rbtdb->rpz_cidr != NULL) {
+ if (rbtdb->rpz_cidr != NULL && node->rpz) {
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
dns_rbt_fullnamefromnode(node, name);
@@ -1677,7 +1677,7 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node)
}
}
#ifdef BIND9
- if (rbtdb->rpz_cidr != NULL)
+ if (rbtdb->rpz_cidr != NULL && node->rpz)
dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name);
#endif
result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
@@ -2192,7 +2192,6 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version) {
unsigned int count, length;
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)db;
- RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
version->havensec3 = ISC_FALSE;
node = rbtdb->origin_node;
NODE_LOCK(&(rbtdb->node_locks[node->locknum].lock),
@@ -2269,7 +2268,6 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version) {
unlock:
NODE_UNLOCK(&(rbtdb->node_locks[node->locknum].lock),
isc_rwlocktype_read);
- RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
}
#endif
@@ -2313,7 +2311,6 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
dns_rbtnode_t *rbtnode;
unsigned int refs;
rdatasetheader_t *header;
- isc_boolean_t writer;
REQUIRE(VALID_RBTDB(rbtdb));
version = (rbtdb_version_t *)*versionp;
@@ -2335,7 +2332,6 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
serial = version->serial;
- writer = version->writer;
if (version->writer) {
if (commit) {
unsigned cur_ref;
@@ -2392,6 +2388,11 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
link);
}
/*
+ * Update the zone's secure status.
+ */
+ if (!IS_CACHE(rbtdb))
+ iszonesecure(db, version, rbtdb->origin_node);
+ /*
* Become the current version.
*/
version->writer = ISC_FALSE;
@@ -2469,12 +2470,6 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
least_serial = rbtdb->least_serial;
RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
- /*
- * Update the zone's secure status.
- */
- if (writer && commit && !IS_CACHE(rbtdb))
- iszonesecure(db, version, rbtdb->origin_node);
-
if (cleanup_version != NULL) {
INSIST(EMPTY(cleanup_version->changed_list));
isc_mem_put(rbtdb->common.mctx, cleanup_version,
@@ -2679,6 +2674,7 @@ findnodeintree(dns_rbtdb_t *rbtdb, dns_rbt_t *tree, dns_name_t *name,
fname = dns_fixedname_name(&fnamef);
dns_rbt_fullnamefromnode(node, fname);
dns_rpz_cidr_addip(rbtdb->rpz_cidr, fname);
+ node->rpz = 1;
}
#endif
dns_rbt_namefromnode(node, &nodename);
@@ -5882,8 +5878,6 @@ allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
currentversion(db,
(dns_dbversion_t **) (void *)(&rbtversion));
else {
- unsigned int refs;
-
INSIST(rbtversion->rbtdb == rbtdb);
isc_refcount_increment(&rbtversion->references,
@@ -7099,7 +7093,6 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
"dns_rbt_addnode(NSEC): %s",
isc_result_totext(tmpresult),
isc_result_totext(noderesult));
-
}
/*
@@ -7109,8 +7102,10 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
done:
#ifdef BIND9
- if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL)
+ if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL) {
dns_rpz_cidr_addip(rbtdb->rpz_cidr, name);
+ node->rpz = 1;
+ }
#endif
if (noderesult == ISC_R_SUCCESS || noderesult == ISC_R_EXISTS)
*nodep = node;
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c
index 08bfa34aa678..9e1eebe70d29 100644
--- a/lib/dns/rdata.c
+++ b/lib/dns/rdata.c
@@ -1168,12 +1168,12 @@ txt_totext(isc_region_t *source, isc_boolean_t quote, isc_buffer_t *target) {
continue;
}
/*
- * Escape double quote, semi-colon, backslash.
- * If we are not enclosing the string in double
- * quotes also escape at sign.
+ * Escape double quote and backslash. If we are not
+ * enclosing the string in double quotes also escape
+ * at sign and semicolon.
*/
- if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c ||
- (!quote && *sp == 0x40)) {
+ if (*sp == 0x22 || *sp == 0x5c ||
+ (!quote && (*sp == 0x40 || *sp == 0x3b))) {
if (tl < 2)
return (ISC_R_NOSPACE);
*tp++ = '\\';
diff --git a/lib/dns/rdata/generic/cdnskey_60.c b/lib/dns/rdata/generic/cdnskey_60.c
index a1e681403b75..624f581725e0 100644
--- a/lib/dns/rdata/generic/cdnskey_60.c
+++ b/lib/dns/rdata/generic/cdnskey_60.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2014, 2015 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
@@ -27,7 +27,7 @@
#include <dst/dst.h>
-#define RRTYPE_CDNSKEY_ATTRIBUTES (DNS_RDATATYPEATTR_DNSSEC)
+#define RRTYPE_CDNSKEY_ATTRIBUTES 0
static inline isc_result_t
fromtext_cdnskey(ARGS_FROMTEXT) {
diff --git a/lib/dns/rdata/generic/cds_59.c b/lib/dns/rdata/generic/cds_59.c
index fcf49662c46a..ff7ff6315790 100644
--- a/lib/dns/rdata/generic/cds_59.c
+++ b/lib/dns/rdata/generic/cds_59.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2014, 2015 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
@@ -21,8 +21,7 @@
#ifndef RDATA_GENERIC_CDS_59_C
#define RDATA_GENERIC_CDS_59_C
-#define RRTYPE_CDS_ATTRIBUTES \
- (DNS_RDATATYPEATTR_DNSSEC|DNS_RDATATYPEATTR_ATPARENT)
+#define RRTYPE_CDS_ATTRIBUTES 0
#include <isc/sha1.h>
#include <isc/sha2.h>
diff --git a/lib/dns/rdata/generic/keydata_65533.c b/lib/dns/rdata/generic/keydata_65533.c
index fae2bce8dbeb..00cf084eb62a 100644
--- a/lib/dns/rdata/generic/keydata_65533.c
+++ b/lib/dns/rdata/generic/keydata_65533.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2011-2013, 2015 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -14,11 +14,12 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id$ */
-
#ifndef GENERIC_KEYDATA_65533_C
#define GENERIC_KEYDATA_65533_C 1
+#include <isc/time.h>
+#include <isc/stdtime.h>
+
#include <dst/dst.h>
#define RRTYPE_KEYDATA_ATTRIBUTES (0)
@@ -97,7 +98,7 @@ totext_keydata(ARGS_TOTEXT) {
char buf[sizeof("64000")];
unsigned int flags;
unsigned char algorithm;
- unsigned long when;
+ unsigned long refresh, add, remove;
char algbuf[DNS_NAME_FORMATSIZE];
const char *keyinfo;
@@ -109,21 +110,21 @@ totext_keydata(ARGS_TOTEXT) {
dns_rdata_toregion(rdata, &sr);
/* refresh timer */
- when = uint32_fromregion(&sr);
+ refresh = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
- RETERR(dns_time32_totext(when, target));
+ RETERR(dns_time32_totext(refresh, target));
RETERR(str_totext(" ", target));
/* add hold-down */
- when = uint32_fromregion(&sr);
+ add = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
- RETERR(dns_time32_totext(when, target));
+ RETERR(dns_time32_totext(add, target));
RETERR(str_totext(" ", target));
/* remove hold-down */
- when = uint32_fromregion(&sr);
+ remove = uint32_fromregion(&sr);
isc_region_consume(&sr, 4);
- RETERR(dns_time32_totext(when, target));
+ RETERR(dns_time32_totext(remove, target));
RETERR(str_totext(" ", target));
/* flags */
@@ -176,6 +177,10 @@ totext_keydata(ARGS_TOTEXT) {
if ((tctx->flags & DNS_STYLEFLAG_RRCOMMENT) != 0) {
isc_region_t tmpr;
+ char rbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
+ char abuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
+ char dbuf[ISC_FORMATHTTPTIMESTAMP_SIZE];
+ isc_time_t t;
RETERR(str_totext(" ; ", target));
RETERR(str_totext(keyinfo, target));
@@ -189,6 +194,47 @@ totext_keydata(ARGS_TOTEXT) {
isc_region_consume(&tmpr, 12);
sprintf(buf, "%u", dst_region_computeid(&tmpr, algorithm));
RETERR(str_totext(buf, target));
+
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0) {
+ isc_stdtime_t now;
+
+ isc_stdtime_get(&now);
+
+ RETERR(str_totext(tctx->linebreak, target));
+ RETERR(str_totext("; next refresh: ", target));
+ isc_time_set(&t, refresh, 0);
+ isc_time_formathttptimestamp(&t, rbuf, sizeof(rbuf));
+ RETERR(str_totext(rbuf, target));
+
+ if (add == 0) {
+ RETERR(str_totext(tctx->linebreak, target));
+ RETERR(str_totext("; no trust", target));
+ } else {
+ RETERR(str_totext(tctx->linebreak, target));
+ if (add < now) {
+ RETERR(str_totext("; trusted since: ",
+ target));
+ } else {
+ RETERR(str_totext("; trust pending: ",
+ target));
+ }
+ isc_time_set(&t, add, 0);
+ isc_time_formathttptimestamp(&t, abuf,
+ sizeof(abuf));
+ RETERR(str_totext(abuf, target));
+ }
+
+ if (remove != 0) {
+ RETERR(str_totext(tctx->linebreak, target));
+ RETERR(str_totext("; removal pending: ",
+ target));
+ isc_time_set(&t, remove, 0);
+ isc_time_formathttptimestamp(&t, dbuf,
+ sizeof(dbuf));
+ RETERR(str_totext(dbuf, target));
+ }
+ }
+
}
return (ISC_R_SUCCESS);
}
diff --git a/lib/dns/rdata/generic/nsec3_50.c b/lib/dns/rdata/generic/nsec3_50.c
index 35fcf5d58229..eb4f68dca2a1 100644
--- a/lib/dns/rdata/generic/nsec3_50.c
+++ b/lib/dns/rdata/generic/nsec3_50.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2008, 2009, 2011, 2012, 2014, 2015 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
@@ -140,7 +140,7 @@ totext_nsec3(ARGS_TOTEXT) {
unsigned int window, len;
unsigned char hash;
unsigned char flags;
- char buf[sizeof("65535 ")];
+ char buf[sizeof("TYPE65535")];
isc_uint32_t iterations;
isc_boolean_t first;
@@ -224,7 +224,6 @@ totext_nsec3(ARGS_TOTEXT) {
if (dns_rdatatype_isknown(t)) {
RETERR(dns_rdatatype_totext(t, target));
} else {
- char buf[sizeof("TYPE65535")];
sprintf(buf, "TYPE%u", t);
RETERR(str_totext(buf, target));
}
diff --git a/lib/dns/rdata/generic/openpgpkey_61.c b/lib/dns/rdata/generic/openpgpkey_61.c
new file mode 100644
index 000000000000..7b2a88bbd312
--- /dev/null
+++ b/lib/dns/rdata/generic/openpgpkey_61.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef RDATA_GENERIC_OPENPGPKEY_61_C
+#define RDATA_GENERIC_OPENPGPKEY_61_C
+
+#define RRTYPE_OPENPGPKEY_ATTRIBUTES 0
+
+static inline isc_result_t
+fromtext_openpgpkey(ARGS_FROMTEXT) {
+
+ REQUIRE(type == 61);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(callbacks);
+ UNUSED(options);
+ UNUSED(origin);
+
+ /*
+ * Keyring.
+ */
+ return (isc_base64_tobuffer(lexer, target, -1));
+}
+
+static inline isc_result_t
+totext_openpgpkey(ARGS_TOTEXT) {
+ isc_region_t sr;
+
+ REQUIRE(rdata->type == 61);
+ REQUIRE(rdata->length != 0);
+
+ dns_rdata_toregion(rdata, &sr);
+
+ /*
+ * Keyring
+ */
+ if ((tctx->flags & DNS_STYLEFLAG_MULTILINE) != 0)
+ RETERR(str_totext("( ", target));
+ if (tctx->width == 0) /* No splitting */
+ RETERR(isc_base64_totext(&sr, 60, "", target));
+ else
+ RETERR(isc_base64_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_openpgpkey(ARGS_FROMWIRE) {
+ isc_region_t sr;
+
+ REQUIRE(type == 61);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+ UNUSED(options);
+
+ /*
+ * Keyring.
+ */
+ isc_buffer_activeregion(source, &sr);
+ isc_buffer_forward(source, sr.length);
+ return (mem_tobuffer(target, sr.base, sr.length));
+}
+
+static inline isc_result_t
+towire_openpgpkey(ARGS_TOWIRE) {
+ isc_region_t sr;
+
+ REQUIRE(rdata->type == 61);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(cctx);
+
+ dns_rdata_toregion(rdata, &sr);
+ return (mem_tobuffer(target, sr.base, sr.length));
+}
+
+static inline int
+compare_openpgpkey(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 61);
+ 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_openpgpkey(ARGS_FROMSTRUCT) {
+ dns_rdata_openpgpkey_t *sig = source;
+
+ REQUIRE(type == 61);
+ REQUIRE(source != NULL);
+ REQUIRE(sig->common.rdtype == type);
+ REQUIRE(sig->common.rdclass == rdclass);
+ REQUIRE(sig->keyring != NULL && sig->length != 0);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ /*
+ * Keyring.
+ */
+ return (mem_tobuffer(target, sig->keyring, sig->length));
+}
+
+static inline isc_result_t
+tostruct_openpgpkey(ARGS_TOSTRUCT) {
+ isc_region_t sr;
+ dns_rdata_openpgpkey_t *sig = target;
+
+ REQUIRE(rdata->type == 61);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length != 0);
+
+ sig->common.rdclass = rdata->rdclass;
+ sig->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&sig->common, link);
+
+ dns_rdata_toregion(rdata, &sr);
+
+ /*
+ * Keyring.
+ */
+ sig->length = sr.length;
+ sig->keyring = mem_maybedup(mctx, sr.base, sig->length);
+ if (sig->keyring == NULL)
+ goto cleanup;
+
+ sig->mctx = mctx;
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ return (ISC_R_NOMEMORY);
+}
+
+static inline void
+freestruct_openpgpkey(ARGS_FREESTRUCT) {
+ dns_rdata_openpgpkey_t *sig = (dns_rdata_openpgpkey_t *) source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(sig->common.rdtype == 61);
+
+ if (sig->mctx == NULL)
+ return;
+
+ if (sig->keyring != NULL)
+ isc_mem_free(sig->mctx, sig->keyring);
+ sig->mctx = NULL;
+}
+
+static inline isc_result_t
+additionaldata_openpgpkey(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == 61);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_openpgpkey(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 61);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_openpgpkey(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 61);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_openpgpkey(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 61);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_openpgpkey(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 61);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+
+ return (isc_region_compare(&r1, &r2));
+}
+
+#endif /* RDATA_GENERIC_OPENPGPKEY_61_C */
diff --git a/lib/dns/rdata/generic/openpgpkey_61.h b/lib/dns/rdata/generic/openpgpkey_61.h
new file mode 100644
index 000000000000..2219422230c2
--- /dev/null
+++ b/lib/dns/rdata/generic/openpgpkey_61.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2014 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.
+ */
+
+#ifndef GENERIC_OPENPGPKEY_61_H
+#define GENERIC_OPENPGPKEY_61_H 1
+
+typedef struct dns_rdata_openpgpkey {
+ dns_rdatacommon_t common;
+ isc_mem_t * mctx;
+ isc_uint16_t length;
+ unsigned char * keyring;
+} dns_rdata_openpgpkey_t;
+
+#endif /* GENERIC_OPENPGPKEY_61_H */
diff --git a/lib/dns/rdata/generic/opt_41.c b/lib/dns/rdata/generic/opt_41.c
index ae09abf71e91..ba3fef001a15 100644
--- a/lib/dns/rdata/generic/opt_41.c
+++ b/lib/dns/rdata/generic/opt_41.c
@@ -326,4 +326,63 @@ casecompare_opt(ARGS_COMPARE) {
return (compare_opt(rdata1, rdata2));
}
+isc_result_t
+dns_rdata_opt_first(dns_rdata_opt_t *opt) {
+
+ REQUIRE(opt != NULL);
+ REQUIRE(opt->common.rdtype == 41);
+ REQUIRE(opt->options != NULL || opt->length == 0);
+
+ if (opt->length == 0)
+ return (ISC_R_NOMORE);
+
+ opt->offset = 0;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_rdata_opt_next(dns_rdata_opt_t *opt) {
+ isc_region_t r;
+ isc_uint16_t length;
+
+ REQUIRE(opt != NULL);
+ REQUIRE(opt->common.rdtype == 41);
+ REQUIRE(opt->options != NULL && opt->length != 0);
+ REQUIRE(opt->offset < opt->length);
+
+ INSIST(opt->offset + 4 <= opt->length);
+ r.base = opt->options + opt->offset + 2;
+ r.length = opt->length - opt->offset - 2;
+ length = uint16_fromregion(&r);
+ INSIST(opt->offset + 4 + length <= opt->length);
+ opt->offset = opt->offset + 4 + length;
+ if (opt->offset == opt->length)
+ return (ISC_R_NOMORE);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_rdata_opt_current(dns_rdata_opt_t *opt, dns_rdata_opt_opcode_t *opcode) {
+ isc_region_t r;
+
+ REQUIRE(opt != NULL);
+ REQUIRE(opcode != NULL);
+ REQUIRE(opt->common.rdtype == 41);
+ REQUIRE(opt->options != NULL);
+ REQUIRE(opt->offset < opt->length);
+
+ INSIST(opt->offset + 4 <= opt->length);
+ r.base = opt->options + opt->offset;
+ r.length = opt->length - opt->offset;
+
+ opcode->opcode = uint16_fromregion(&r);
+ isc_region_consume(&r, 2);
+ opcode->length = uint16_fromregion(&r);
+ isc_region_consume(&r, 2);
+ opcode->data = r.base;
+ INSIST(opt->offset + 4 + opcode->length <= opt->length);
+
+ return (ISC_R_SUCCESS);
+}
+
#endif /* RDATA_GENERIC_OPT_41_C */
diff --git a/lib/dns/rdata/generic/rrsig_46.c b/lib/dns/rdata/generic/rrsig_46.c
index 5dd5a31a7ca8..d4e8767fed88 100644
--- a/lib/dns/rdata/generic/rrsig_46.c
+++ b/lib/dns/rdata/generic/rrsig_46.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -178,7 +178,6 @@ totext_rrsig(ARGS_TOTEXT) {
if (dns_rdatatype_isknown(covered) && covered != 0) {
RETERR(dns_rdatatype_totext(covered, target));
} else {
- char buf[sizeof("TYPE65535")];
sprintf(buf, "TYPE%u", covered);
RETERR(str_totext(buf, target));
}
diff --git a/lib/dns/rdata/generic/sig_24.c b/lib/dns/rdata/generic/sig_24.c
index 803a864067f0..86aa38a696b6 100644
--- a/lib/dns/rdata/generic/sig_24.c
+++ b/lib/dns/rdata/generic/sig_24.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -154,7 +154,6 @@ totext_sig(ARGS_TOTEXT) {
if (dns_rdatatype_isknown(covered) && covered != 0) {
RETERR(dns_rdatatype_totext(covered, target));
} else {
- char buf[sizeof("65535")];
sprintf(buf, "%u", covered);
RETERR(str_totext(buf, target));
}
diff --git a/lib/dns/rdata/generic/spf_99.h b/lib/dns/rdata/generic/spf_99.h
index be5e9789842a..35ec9bc9ff95 100644
--- a/lib/dns/rdata/generic/spf_99.h
+++ b/lib/dns/rdata/generic/spf_99.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -21,31 +21,21 @@
/* $Id: spf_99.h,v 1.4 2007/06/19 23:47:17 tbox Exp $ */
typedef struct dns_rdata_spf_string {
- isc_uint8_t length;
- unsigned char *data;
+ isc_uint8_t length;
+ unsigned char *data;
} dns_rdata_spf_string_t;
typedef struct dns_rdata_spf {
- dns_rdatacommon_t common;
- isc_mem_t *mctx;
- unsigned char *txt;
- isc_uint16_t txt_len;
- /* private */
- isc_uint16_t offset;
+ dns_rdatacommon_t common;
+ isc_mem_t *mctx;
+ unsigned char *txt;
+ isc_uint16_t txt_len;
+ /* private */
+ isc_uint16_t offset;
} dns_rdata_spf_t;
/*
* ISC_LANG_BEGINDECLS and ISC_LANG_ENDDECLS are already done
* via rdatastructpre.h and rdatastructsuf.h.
*/
-
-isc_result_t
-dns_rdata_spf_first(dns_rdata_spf_t *);
-
-isc_result_t
-dns_rdata_spf_next(dns_rdata_spf_t *);
-
-isc_result_t
-dns_rdata_spf_current(dns_rdata_spf_t *, dns_rdata_spf_string_t *);
-
#endif /* GENERIC_SPF_99_H */
diff --git a/lib/dns/rdata/generic/txt_16.c b/lib/dns/rdata/generic/txt_16.c
index 41e270279216..0cbe3ea6f15a 100644
--- a/lib/dns/rdata/generic/txt_16.c
+++ b/lib/dns/rdata/generic/txt_16.c
@@ -247,4 +247,59 @@ casecompare_txt(ARGS_COMPARE) {
return (compare_txt(rdata1, rdata2));
}
+isc_result_t
+dns_rdata_txt_first(dns_rdata_txt_t *txt) {
+
+ REQUIRE(txt != NULL);
+ REQUIRE(txt->common.rdtype == 16);
+ REQUIRE(txt->txt != NULL || txt->txt_len == 0);
+
+ if (txt->txt_len == 0)
+ return (ISC_R_NOMORE);
+
+ txt->offset = 0;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_rdata_txt_next(dns_rdata_txt_t *txt) {
+ isc_region_t r;
+ isc_uint8_t length;
+
+ REQUIRE(txt != NULL);
+ REQUIRE(txt->common.rdtype == 16);
+ REQUIRE(txt->txt != NULL && txt->txt_len != 0);
+
+ INSIST(txt->offset + 1 <= txt->txt_len);
+ r.base = txt->txt + txt->offset;
+ r.length = txt->txt_len - txt->offset;
+ length = uint8_fromregion(&r);
+ INSIST(txt->offset + 1 + length <= txt->txt_len);
+ txt->offset = txt->offset + 1 + length;
+ if (txt->offset == txt->txt_len)
+ return (ISC_R_NOMORE);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+dns_rdata_txt_current(dns_rdata_txt_t *txt, dns_rdata_txt_string_t *string) {
+ isc_region_t r;
+
+ REQUIRE(txt != NULL);
+ REQUIRE(string != NULL);
+ REQUIRE(txt->common.rdtype == 16);
+ REQUIRE(txt->txt != NULL);
+ REQUIRE(txt->offset < txt->txt_len);
+
+ INSIST(txt->offset + 1 <= txt->txt_len);
+ r.base = txt->txt + txt->offset;
+ r.length = txt->txt_len - txt->offset;
+
+ string->length = uint8_fromregion(&r);
+ isc_region_consume(&r, 1);
+ string->data = r.base;
+ INSIST(txt->offset + 1 + string->length <= txt->txt_len);
+
+ return (ISC_R_SUCCESS);
+}
#endif /* RDATA_GENERIC_TXT_16_C */
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c
index 026d771235cc..ab02d32e0998 100644
--- a/lib/dns/rdataset.c
+++ b/lib/dns/rdataset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2012, 2014, 2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -80,6 +80,7 @@ dns_rdataset_init(dns_rdataset_t *rdataset) {
rdataset->privateuint4 = 0;
rdataset->private5 = NULL;
rdataset->private6 = NULL;
+ rdataset->private7 = NULL;
rdataset->resign = 0;
}
@@ -415,7 +416,6 @@ towiresorted(dns_rdataset_t *rdataset, const dns_name_t *owner_name,
* 'Random' order.
*/
for (i = 0; i < count; i++) {
- dns_rdata_t rdata;
isc_uint32_t val;
isc_random_get(&val);
diff --git a/lib/dns/request.c b/lib/dns/request.c
index 1316e6994110..59e166eb0257 100644
--- a/lib/dns/request.c
+++ b/lib/dns/request.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -686,6 +686,7 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
dns_messageid_t id;
isc_boolean_t tcp = ISC_FALSE;
isc_region_t r;
+ unsigned int dispopt = 0;
REQUIRE(VALID_REQUESTMGR(requestmgr));
REQUIRE(msgbuf != NULL);
@@ -751,9 +752,14 @@ dns_request_createraw3(dns_requestmgr_t *requestmgr, isc_buffer_t *msgbuf,
if (result != ISC_R_SUCCESS)
goto cleanup;
- result = dns_dispatch_addresponse2(request->dispatch, destaddr, task,
- req_response, request, &id,
- &request->dispentry,
+ if ((options & DNS_REQUESTOPT_FIXEDID) != 0) {
+ id = (r.base[0] << 8) | r.base[1];
+ dispopt |= DNS_DISPATCHOPT_FIXEDID;
+ }
+
+ result = dns_dispatch_addresponse3(request->dispatch, dispopt,
+ destaddr, task, req_response,
+ request, &id, &request->dispentry,
requestmgr->socketmgr);
if (result != ISC_R_SUCCESS)
goto cleanup;
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index befe3cafe0f2..d33c43ed82af 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -1673,6 +1673,24 @@ add_triededns512(fetchctx_t *fctx, isc_sockaddr_t *address) {
ISC_LIST_INITANDAPPEND(fctx->edns512, sa, link);
}
+static isc_boolean_t
+wouldvalidate(fetchctx_t *fctx) {
+ isc_boolean_t secure_domain;
+ isc_result_t result;
+
+ if (!fctx->res->view->enablevalidation)
+ return (ISC_FALSE);
+
+ if (fctx->res->view->dlv != NULL)
+ return (ISC_TRUE);
+
+ result = dns_view_issecuredomain(fctx->res->view, &fctx->name,
+ &secure_domain);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+ return (secure_domain);
+}
+
static isc_result_t
resquery_send(resquery_t *query) {
fetchctx_t *fctx;
@@ -1842,11 +1860,12 @@ resquery_send(resquery_t *query) {
if ((triededns512(fctx, &query->addrinfo->sockaddr) ||
fctx->timeouts >= (MAX_EDNS0_TIMEOUTS * 2)) &&
(query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
- !EDNSOK(query->addrinfo)) {
+ (!EDNSOK(query->addrinfo) || !wouldvalidate(fctx))) {
+ query->options |= DNS_FETCHOPT_NOEDNS0;
+ fctx->reason = "disabling EDNS";
} else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
fctx->timeouts >= MAX_EDNS0_TIMEOUTS) &&
- (query->options & DNS_FETCHOPT_NOEDNS0) == 0 &&
- !EDNSOK(query->addrinfo)) {
+ (query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
query->options |= DNS_FETCHOPT_EDNS512;
fctx->reason = "reducing the advertised EDNS UDP "
"packet size to 512 octets";
@@ -2504,11 +2523,19 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
fctx->depth + 1, fctx->qc, &find);
if (result != ISC_R_SUCCESS) {
if (result == DNS_R_ALIAS) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+
/*
* XXXRTH Follow the CNAME/DNAME chain?
*/
dns_adb_destroyfind(&find);
fctx->adberr++;
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_CNAME,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
+ "skipping nameserver '%s' because it "
+ "is a CNAME, while resolving '%s'",
+ namebuf, fctx->info);
}
} else if (!ISC_LIST_EMPTY(find->list)) {
/*
@@ -2725,6 +2752,10 @@ fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
stdoptions |= DNS_ADBFIND_INET;
if (res->dispatches6 != NULL)
stdoptions |= DNS_ADBFIND_INET6;
+
+ if ((stdoptions & DNS_ADBFIND_ADDRESSMASK) == 0)
+ return (DNS_R_SERVFAIL);
+
isc_stdtime_get(&now);
INSIST(ISC_LIST_EMPTY(fctx->finds));
@@ -3055,6 +3086,16 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
REQUIRE(!ADDRWAIT(fctx));
+ /* We've already exceeded maximum query count */
+ if (isc_counter_used(fctx->qc) > fctx->res->maxqueries) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+ "exceeded max queries resolving '%s'",
+ fctx->info);
+ fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
+ return;
+ }
+
addrinfo = fctx_nextaddress(fctx);
if (addrinfo == NULL) {
/*
@@ -3092,14 +3133,16 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
}
}
- result = isc_counter_increment(fctx->qc);
- if (result != ISC_R_SUCCESS) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
- DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
- "exceeded max queries resolving '%s'",
- fctx->info);
- fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
- return;
+ if (dns_name_countlabels(&fctx->domain) > 2) {
+ result = isc_counter_increment(fctx->qc);
+ if (result != ISC_R_SUCCESS) {
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_DEBUG(3),
+ "exceeded max queries resolving '%s'",
+ fctx->info);
+ fctx_done(fctx, DNS_R_SERVFAIL, __LINE__);
+ return;
+ }
}
result = fctx_query(fctx, addrinfo, fctx->options);
@@ -4248,7 +4291,11 @@ validated(isc_task_t *task, isc_event_t *event) {
inc_stats(res, dns_resstatscounter_valnegsuccess);
- if (fctx->rmessage->rcode == dns_rcode_nxdomain)
+ /*
+ * Cache DS NXDOMAIN seperately to other types.
+ */
+ if (fctx->rmessage->rcode == dns_rcode_nxdomain &&
+ fctx->type != dns_rdatatype_ds)
covers = dns_rdatatype_any;
else
covers = fctx->type;
@@ -7481,7 +7528,12 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
*/
if (WANTNCACHE(fctx)) {
dns_rdatatype_t covers;
- if (message->rcode == dns_rcode_nxdomain)
+
+ /*
+ * Cache DS NXDOMAIN seperately to other types.
+ */
+ if (message->rcode == dns_rcode_nxdomain &&
+ fctx->type != dns_rdatatype_ds)
covers = dns_rdatatype_any;
else
covers = fctx->type;
diff --git a/lib/dns/rootns.c b/lib/dns/rootns.c
index a3d9bd8d6084..21c532c39696 100644
--- a/lib/dns/rootns.c
+++ b/lib/dns/rootns.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2010, 2012-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010, 2012-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -211,7 +211,7 @@ dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
result = dns_db_create(mctx, "rbt", dns_rootname, dns_dbtype_zone,
rdclass, 0, NULL, &db);
if (result != ISC_R_SUCCESS)
- return (result);
+ goto failure;
dns_rdatacallbacks_init(&callbacks);
@@ -222,7 +222,7 @@ dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
result = dns_db_beginload(db, &callbacks.add,
&callbacks.add_private);
if (result != ISC_R_SUCCESS)
- return (result);
+ goto failure;
if (filename != NULL) {
/*
* Load the hints from the specified filename.
@@ -245,7 +245,7 @@ dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
if (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE)
result = eresult;
if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE)
- goto db_detach;
+ goto failure;
if (check_hints(db) != ISC_R_SUCCESS)
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_HINTS, ISC_LOG_WARNING,
@@ -254,8 +254,14 @@ dns_rootns_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
*target = db;
return (ISC_R_SUCCESS);
- db_detach:
- dns_db_detach(&db);
+ failure:
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_HINTS,
+ ISC_LOG_ERROR, "could not configure root hints from "
+ "'%s': %s", (filename != NULL) ? filename : "<BUILT-IN>",
+ isc_result_totext(result));
+
+ if (db != NULL)
+ dns_db_detach(&db);
return (result);
}
diff --git a/lib/dns/spnego_asn1.c b/lib/dns/spnego_asn1.c
index a90f1be63c2c..8dc4ba803022 100644
--- a/lib/dns/spnego_asn1.c
+++ b/lib/dns/spnego_asn1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2007, 2012, 2013, 2015 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
@@ -486,13 +486,13 @@ decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
e = decode_MechTypeList(p, len, &(data)->mechTypes, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
@@ -513,16 +513,16 @@ decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->reqFlags = malloc(sizeof(*(data)->reqFlags));
if ((data)->reqFlags == NULL)
return ENOMEM;
e = decode_ContextFlags(p, len, (data)->reqFlags, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
@@ -543,16 +543,16 @@ decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->mechToken = malloc(sizeof(*(data)->mechToken));
if ((data)->mechToken == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->mechToken, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
@@ -573,16 +573,16 @@ decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
if ((data)->mechListMIC == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->mechListMIC, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
@@ -710,16 +710,16 @@ decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->negState = malloc(sizeof(*(data)->negState));
if ((data)->negState == NULL)
return ENOMEM;
e = decode_enumerated(p, len, (data)->negState, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
@@ -740,16 +740,16 @@ decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->supportedMech = malloc(sizeof(*(data)->supportedMech));
if ((data)->supportedMech == NULL)
return ENOMEM;
e = decode_MechType(p, len, (data)->supportedMech, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
@@ -770,16 +770,16 @@ decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->responseToken = malloc(sizeof(*(data)->responseToken));
if ((data)->responseToken == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->responseToken, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
@@ -800,16 +800,16 @@ decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, siz
e = der_get_length(p, len, &newlen, &l);
FORW;
{
- int dce_fix;
+ int mydce_fix;
oldlen = len;
- if ((dce_fix = fix_dce(newlen, &len)) < 0)
+ if ((mydce_fix = fix_dce(newlen, &len)) < 0)
return ASN1_BAD_FORMAT;
(data)->mechListMIC = malloc(sizeof(*(data)->mechListMIC));
if ((data)->mechListMIC == NULL)
return ENOMEM;
e = decode_octet_string(p, len, (data)->mechListMIC, &l);
FORW;
- if (dce_fix) {
+ if (mydce_fix) {
e = der_match_tag_and_length(p, len, (Der_class) 0, (Der_type) 0, 0, &reallen, &l);
FORW;
} else
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c
index 11b4f49eb04b..f46577f01d7b 100644
--- a/lib/dns/tkey.c
+++ b/lib/dns/tkey.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -859,7 +859,7 @@ buildquery(dns_message_t *msg, dns_name_t *name,
dns_rdataset_t *question = NULL, *tkeyset = NULL;
dns_rdatalist_t *tkeylist = NULL;
dns_rdata_t *rdata = NULL;
- isc_buffer_t *dynbuf = NULL;
+ isc_buffer_t *dynbuf = NULL, *anamebuf = NULL, *qnamebuf = NULL;
isc_result_t result;
REQUIRE(msg != NULL);
@@ -875,6 +875,8 @@ buildquery(dns_message_t *msg, dns_name_t *name,
dns_rdatatype_tkey);
RETERR(isc_buffer_allocate(msg->mctx, &dynbuf, 4096));
+ RETERR(isc_buffer_allocate(msg->mctx, &anamebuf, DNS_NAME_MAXWIRE));
+ RETERR(isc_buffer_allocate(msg->mctx, &qnamebuf, DNS_NAME_MAXWIRE));
RETERR(dns_message_gettemprdata(msg, &rdata));
RETERR(dns_rdata_fromstruct(rdata, dns_rdataclass_any,
@@ -894,15 +896,16 @@ buildquery(dns_message_t *msg, dns_name_t *name,
RETERR(dns_rdatalist_tordataset(tkeylist, tkeyset));
dns_name_init(qname, NULL);
- dns_name_clone(name, qname);
+ dns_name_copy(name, qname, qnamebuf);
dns_name_init(aname, NULL);
- dns_name_clone(name, aname);
+ dns_name_copy(name, aname, anamebuf);
ISC_LIST_APPEND(qname->list, question, link);
ISC_LIST_APPEND(aname->list, tkeyset, link);
dns_message_addname(msg, qname, DNS_SECTION_QUESTION);
+ dns_message_takebuffer(msg, &qnamebuf);
/*
* Windows 2000 needs this in the answer section, not the additional
@@ -912,6 +915,7 @@ buildquery(dns_message_t *msg, dns_name_t *name,
dns_message_addname(msg, aname, DNS_SECTION_ANSWER);
else
dns_message_addname(msg, aname, DNS_SECTION_ADDITIONAL);
+ dns_message_takebuffer(msg, &anamebuf);
return (ISC_R_SUCCESS);
@@ -926,6 +930,10 @@ buildquery(dns_message_t *msg, dns_name_t *name,
}
if (dynbuf != NULL)
isc_buffer_free(&dynbuf);
+ if (qnamebuf != NULL)
+ isc_buffer_free(&qnamebuf);
+ if (anamebuf != NULL)
+ isc_buffer_free(&anamebuf);
printf("buildquery error\n");
return (result);
}
@@ -1389,6 +1397,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
dst_key_t *dstkey = NULL;
isc_result_t result;
unsigned char array[1024];
+ isc_boolean_t freertkey = ISC_FALSE;
REQUIRE(qmsg != NULL);
REQUIRE(rmsg != NULL);
@@ -1401,6 +1410,7 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
RETERR(find_tkey(rmsg, &tkeyname, &rtkeyrdata, DNS_SECTION_ANSWER));
RETERR(dns_rdata_tostruct(&rtkeyrdata, &rtkey, NULL));
+ freertkey = ISC_TRUE;
if (win2k == ISC_TRUE)
RETERR(find_tkey(qmsg, &tkeyname, &qtkeyrdata,
@@ -1453,7 +1463,8 @@ dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
/*
* XXXSRA This probably leaks memory from qtkey.
*/
- dns_rdata_freestruct(&rtkey);
+ if (freertkey)
+ dns_rdata_freestruct(&rtkey);
if (dstkey != NULL)
dst_key_free(&dstkey);
return (result);
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c
index 1ddca181a4ab..307cb2577b41 100644
--- a/lib/dns/tsig.c
+++ b/lib/dns/tsig.c
@@ -275,12 +275,12 @@ keyring_add(dns_tsig_keyring_t *ring, dns_name_t *name,
}
result = dns_rbt_addname(ring->keys, name, tkey);
- if (tkey->generated) {
+ if (result == ISC_R_SUCCESS && tkey->generated) {
/*
* Add the new key to the LRU list and remove the least
* recently used key if there are too many keys on the list.
*/
- ISC_LIST_INITANDAPPEND(ring->lru, tkey, link);
+ ISC_LIST_APPEND(ring->lru, tkey, link);
if (ring->generated++ > ring->maxgenerated)
remove_fromring(ISC_LIST_HEAD(ring->lru));
}
@@ -419,6 +419,7 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
tkey->expire = expire;
tkey->mctx = NULL;
isc_mem_attach(mctx, &tkey->mctx);
+ ISC_LINK_INIT(tkey, link);
tkey->magic = TSIG_MAGIC;
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 0b203d882923..565e7e1d62ab 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -2062,9 +2062,6 @@ validatezonekey(dns_validator_t *val) {
"the DNSKEY RRset and also matches a "
"trusted key for '%s'",
namebuf);
- validator_log(val, ISC_LOG_NOTICE,
- "please check the 'trusted-keys' for "
- "'%s' in named.conf.", namebuf);
return (DNS_R_NOVALIDKEY);
}
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 5db28449b8f7..fbaeab14c699 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id$ */
-
/*! \file */
#include <config.h>
@@ -444,6 +442,10 @@ typedef struct {
#define DNS_ZONEFLG_LOADPENDING 0x10000000U /*%< Loading scheduled */
#define DNS_ZONEFLG_NODELAY 0x20000000U
#define DNS_ZONEFLG_SENDSECURE 0x40000000U
+#define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
+ * due to the zone just
+ * being loaded for the
+ * first time. */
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
@@ -482,6 +484,8 @@ struct dns_zonemgr {
isc_pool_t * mctxpool;
isc_ratelimiter_t * notifyrl;
isc_ratelimiter_t * refreshrl;
+ isc_ratelimiter_t * startupnotifyrl;
+ isc_ratelimiter_t * startuprefreshrl;
isc_rwlock_t rwlock;
isc_mutex_t iolock;
isc_rwlock_t urlock;
@@ -494,7 +498,10 @@ struct dns_zonemgr {
/* Configuration data. */
isc_uint32_t transfersin;
isc_uint32_t transfersperns;
+ unsigned int notifyrate;
+ unsigned int startupnotifyrate;
unsigned int serialqueryrate;
+ unsigned int startupserialqueryrate;
/* Locked by iolock */
isc_uint32_t iolimit;
@@ -521,9 +528,11 @@ struct dns_notify {
isc_sockaddr_t dst;
dns_tsigkey_t *key;
ISC_LINK(dns_notify_t) link;
+ isc_event_t *event;
};
#define DNS_NOTIFY_NOSOA 0x0001U
+#define DNS_NOTIFY_STARTUP 0x0002U
/*%
* dns_stub holds state while performing a 'stub' transfer.
@@ -564,6 +573,7 @@ struct dns_forward {
isc_sockaddr_t addr;
dns_updatecallback_t callback;
void *callback_arg;
+ unsigned int options;
ISC_LINK(dns_forward_t) link;
};
@@ -651,6 +661,16 @@ struct dns_asyncload {
#define DAY (24*HOUR)
#define MONTH (30*DAY)
+/*
+ * These can be overridden by the -T mkeytimers option on the command
+ * line, so that we can test with shorter periods than specified in
+ * RFC 5011.
+ */
+unsigned int dns_zone_mkey_hour = HOUR;
+unsigned int dns_zone_mkey_day = (24 * HOUR);
+unsigned int dns_zone_mkey_month = (30 * DAY);
+
+
#define SEND_BUFFER_SIZE 2048
static void zone_settimer(dns_zone_t *, isc_time_t *);
@@ -742,6 +762,8 @@ static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
dns_diff_t *diff);
static void zone_rekey(dns_zone_t *zone);
static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
+static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
+ unsigned int value);
#define ENTER zone_debuglog(zone, me, 1, "enter")
@@ -2328,6 +2350,8 @@ zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
DNS_DBFIND_GLUEOK, 0, NULL,
foundname, &aaaa, NULL);
if (tresult == ISC_R_SUCCESS) {
+ if (dns_rdataset_isassociated(&a))
+ dns_rdataset_disassociate(&a);
dns_rdataset_disassociate(&aaaa);
return (ISC_TRUE);
}
@@ -3175,7 +3199,7 @@ 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, isc_boolean_t force)
{
const char me[] = "set_refreshkeytimer";
isc_stdtime_t then;
@@ -3184,6 +3208,8 @@ set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
ENTER;
then = key->refresh;
+ if (force)
+ then = now;
if (key->addhd > now && key->addhd < then)
then = key->addhd;
if (key->removehd > now && key->removehd < then)
@@ -3263,8 +3289,9 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
dst_key_name(key), 0, &rdata));
*changed = ISC_TRUE;
+
/* Refresh new keys from the zone apex as soon as possible. */
- set_refreshkeytimer(zone, &keydata, now);
+ set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
skip:
result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
@@ -3420,8 +3447,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
continue;
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- /* Set the key refresh timer. */
- set_refreshkeytimer(zone, &keydata, now);
+ /* Set the key refresh timer to force a fast refresh. */
+ set_refreshkeytimer(zone, &keydata, now, ISC_TRUE);
/* If the removal timer is nonzero, this key was revoked. */
if (keydata.removehd != 0) {
@@ -3615,6 +3642,8 @@ failure:
if (ver != NULL)
dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
+ INSIST(ver == NULL);
+
return (result);
}
@@ -3687,7 +3716,8 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
result = dns_keytable_find(sr, rrname, &keynode);
if ((result != ISC_R_SUCCESS &&
result != DNS_R_PARTIALMATCH) ||
- dns_keynode_managed(keynode) == ISC_FALSE) {
+ dns_keynode_managed(keynode) == ISC_FALSE)
+ {
CHECK(delete_keydata(db, ver, &diff,
rrname, rdataset));
changed = ISC_TRUE;
@@ -3777,6 +3807,8 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
dns_db_closeversion(db, &ver, commit);
dns_diff_clear(&diff);
+ INSIST(ver == NULL);
+
return (result);
}
@@ -4210,7 +4242,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
zone_attachdb(zone, db);
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
DNS_ZONE_SETFLAG(zone,
- DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
+ DNS_ZONEFLG_LOADED|
+ DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
inline_raw(zone))
{
@@ -5383,8 +5416,8 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
dns_rdataset_t rdataset;
unsigned int i;
dns_rdata_rrsig_t rrsig;
- isc_boolean_t found, changed;
- isc_int64_t warn = 0, maybe = 0;
+ isc_boolean_t found;
+ isc_int64_t timewarn = 0, timemaybe = 0;
dns_rdataset_init(&rdataset);
@@ -5409,7 +5442,6 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
goto failure;
}
- changed = ISC_FALSE;
for (result = dns_rdataset_first(&rdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(&rdataset)) {
@@ -5425,8 +5457,6 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
result = update_one_rr(db, ver, zonediff->diff,
DNS_DIFFOP_DELRESIGN, name,
rdataset.ttl, &rdata);
- if (incremental)
- changed = ISC_TRUE;
if (result != ISC_R_SUCCESS)
break;
deleted = ISC_TRUE;
@@ -5445,7 +5475,6 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
result = offline(db, ver, zonediff,
name, rdataset.ttl,
&rdata);
- changed = ISC_TRUE;
if (result != ISC_R_SUCCESS)
break;
}
@@ -5494,22 +5523,23 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
{
isc_int64_t timeexpire =
dns_time64_from32(rrsig.timeexpire);
- if (warn != 0 && warn > timeexpire)
- warn = timeexpire;
+ if (timewarn != 0 &&
+ timewarn > timeexpire)
+ timewarn = timeexpire;
if (rdata.flags & DNS_RDATA_OFFLINE) {
- if (maybe == 0 ||
- maybe > timeexpire)
- maybe = timeexpire;
+ if (timemaybe == 0 ||
+ timemaybe > timeexpire)
+ timemaybe = timeexpire;
break;
}
- if (warn == 0)
- warn = maybe;
- if (warn == 0 || warn > timeexpire)
- warn = timeexpire;
+ if (timewarn == 0)
+ timewarn = timemaybe;
+ if (timewarn == 0 ||
+ timewarn > timeexpire)
+ timewarn = timeexpire;
result = offline(db, ver, zonediff,
name, rdataset.ttl,
&rdata);
- changed = ISC_TRUE;
break;
}
result = update_one_rr(db, ver, zonediff->diff,
@@ -5532,18 +5562,16 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
break;
}
- if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
- dns_db_resigned(db, &rdataset, ver);
-
dns_rdataset_disassociate(&rdataset);
if (result == ISC_R_NOMORE)
result = ISC_R_SUCCESS;
- if (warn > 0) {
+ if (timewarn > 0) {
#if defined(STDTIME_ON_32BITS)
- isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
- if (warn == stdwarn)
+ isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
+ if (timewarn == stdwarn)
#endif
- set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
+ set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
+ now);
#if defined(STDTIME_ON_32BITS)
else
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -5769,8 +5797,7 @@ zone_resigninc(dns_zone_t *zone) {
dns_result_totext(result));
break;
}
- result = dns_db_getsigningtime(db, &rdataset,
- dns_fixedname_name(&fixed));
+ result = dns_db_getsigningtime(db, &rdataset, name);
if (nkeys == 0 && result == ISC_R_NOTFOUND) {
result = ISC_R_SUCCESS;
break;
@@ -5857,6 +5884,8 @@ zone_resigninc(dns_zone_t *zone) {
isc_interval_set(&ival, 300, 0);
isc_time_nowplusinterval(&zone->resigntime, &ival);
}
+
+ INSIST(version == NULL);
}
static isc_result_t
@@ -7331,15 +7360,17 @@ zone_nsec3chain(dns_zone_t *zone) {
LOCK_ZONE(zone);
if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
- isc_interval_t i;
+ isc_interval_t interval;
if (zone->update_disabled || result != ISC_R_SUCCESS)
- isc_interval_set(&i, 60, 0); /* 1 minute */
+ isc_interval_set(&interval, 60, 0); /* 1 minute */
else
- isc_interval_set(&i, 0, 10000000); /* 10 ms */
- isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
+ isc_interval_set(&interval, 0, 10000000); /* 10 ms */
+ isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
} else
isc_time_settoepoch(&zone->nsec3chaintime);
UNLOCK_ZONE(zone);
+
+ INSIST(version == NULL);
}
static isc_result_t
@@ -7879,19 +7910,22 @@ zone_sign(dns_zone_t *zone) {
dns_db_detach(&db);
if (ISC_LIST_HEAD(zone->signing) != NULL) {
- isc_interval_t i;
+ isc_interval_t interval;
if (zone->update_disabled || result != ISC_R_SUCCESS)
- isc_interval_set(&i, 60, 0); /* 1 minute */
+ isc_interval_set(&interval, 60, 0); /* 1 minute */
else
- isc_interval_set(&i, 0, 10000000); /* 10 ms */
- isc_time_nowplusinterval(&zone->signingtime, &i);
+ isc_interval_set(&interval, 0, 10000000); /* 10 ms */
+ isc_time_nowplusinterval(&zone->signingtime, &interval);
} else
isc_time_settoepoch(&zone->signingtime);
+
+ INSIST(version == NULL);
}
static isc_result_t
normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
- unsigned char *data, int size) {
+ unsigned char *data, int size)
+{
dns_rdata_dnskey_t dnskey;
dns_rdata_keydata_t keydata;
isc_buffer_t buf;
@@ -7988,11 +8022,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
rdset = &kfetch->dnskeysigset;
else
- return (now + HOUR);
+ return (now + dns_zone_mkey_hour);
result = dns_rdataset_first(rdset);
if (result != ISC_R_SUCCESS)
- return (now + HOUR);
+ return (now + dns_zone_mkey_hour);
dns_rdataset_current(rdset, &sigrr);
result = dns_rdata_tostruct(&sigrr, &sig, NULL);
@@ -8007,11 +8041,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
t = exp;
}
- if (t > (15*DAY))
- t = (15*DAY);
+ if (t > (15 * dns_zone_mkey_day))
+ t = (15 * dns_zone_mkey_day);
- if (t < HOUR)
- t = HOUR;
+ if (t < dns_zone_mkey_hour)
+ t = dns_zone_mkey_hour;
} else {
t = sig.originalttl / 10;
@@ -8021,11 +8055,11 @@ refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
t = exp;
}
- if (t > DAY)
- t = DAY;
+ if (t > dns_zone_mkey_day)
+ t = dns_zone_mkey_day;
- if (t < HOUR)
- t = HOUR;
+ if (t < dns_zone_mkey_hour)
+ t = dns_zone_mkey_hour;
}
return (now + t);
@@ -8068,7 +8102,7 @@ minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
if (result != ISC_R_SUCCESS)
goto failure;
keydata.refresh = refresh_time(kfetch, ISC_TRUE);
- set_refreshkeytimer(zone, &keydata, now);
+ set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
dns_rdata_reset(&rdata);
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
@@ -8111,8 +8145,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
/* Generate a key from keydata */
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
dns_keydata_todnskey(keydata, &dnskey, NULL);
- dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
- &dnskey, &keyb);
+ dns_rdata_fromstruct(&rr, keydata->common.rdclass,
+ dns_rdatatype_dnskey, &dnskey, &keyb);
result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
if (result != ISC_R_SUCCESS)
return (ISC_FALSE);
@@ -8120,7 +8154,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
/* See if that key generated any of the signatures */
for (result = dns_rdataset_first(&kfetch->dnskeysigset);
result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&kfetch->dnskeysigset)) {
+ result = dns_rdataset_next(&kfetch->dnskeysigset))
+ {
dns_fixedname_t fixed;
dns_fixedname_init(&fixed);
@@ -8130,8 +8165,8 @@ revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (dst_key_alg(dstkey) == sig.algorithm &&
- (dst_key_id(dstkey) == sig.keyid ||
- dst_key_rid(dstkey) == sig.keyid)) {
+ dst_key_rid(dstkey) == sig.keyid)
+ {
result = dns_dnssec_verify2(keyname,
&kfetch->dnskeyset,
dstkey, ISC_FALSE, mctx, &sigrr,
@@ -8246,6 +8281,12 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
}
/*
+ * Clear any cached trust level, as we need to run validation
+ * over again; trusted keys might have changed.
+ */
+ kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
+
+ /*
* Validate the dnskeyset against the current trusted keys.
*/
for (result = dns_rdataset_first(&kfetch->dnskeysigset);
@@ -8278,7 +8319,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
dns_zone_log(zone, ISC_LOG_DEBUG(3),
"Verifying DNSKEY set for zone "
- "'%s': %s", namebuf,
+ "'%s' using key %d/%d: %s",
+ namebuf, sig.keyid, sig.algorithm,
dns_result_totext(result));
if (result == ISC_R_SUCCESS) {
@@ -8286,8 +8328,6 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
dns_trust_secure;
kfetch->dnskeysigset.trust =
dns_trust_secure;
- dns_keytable_detachkeynode(secroots,
- &keynode);
break;
}
}
@@ -8298,6 +8338,9 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
keynode = nextnode;
}
+ if (keynode != NULL)
+ dns_keytable_detachkeynode(secroots, &keynode);
+
if (kfetch->dnskeyset.trust == dns_trust_secure)
break;
}
@@ -8342,31 +8385,34 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
isc_boolean_t deletekey = ISC_FALSE;
if (!secure) {
- if (now > keydata.removehd)
+ if (keydata.removehd != 0 &&
+ keydata.removehd <= now)
deletekey = ISC_TRUE;
- } else if (now < keydata.addhd) {
+ } else if (keydata.addhd == 0) {
+ deletekey = ISC_TRUE;
+ } else if (keydata.addhd > now) {
dns_zone_log(zone, ISC_LOG_WARNING,
"Pending key unexpectedly missing "
"from %s; restarting acceptance "
"timer", namebuf);
- keydata.addhd = now + MONTH;
+ if (keydata.addhd < now + dns_zone_mkey_month)
+ keydata.addhd =
+ now + dns_zone_mkey_month;
keydata.refresh = refresh_time(kfetch,
ISC_FALSE);
- } else if (keydata.addhd == 0) {
- keydata.addhd = now;
} else if (keydata.removehd == 0) {
dns_zone_log(zone, ISC_LOG_WARNING,
"Active key unexpectedly missing "
"from %s", namebuf);
- keydata.refresh = now + HOUR;
- } else if (now > keydata.removehd) {
+ keydata.refresh = now + dns_zone_mkey_hour;
+ } else if (keydata.removehd <= now) {
deletekey = ISC_TRUE;
} else {
keydata.refresh = refresh_time(kfetch,
ISC_FALSE);
}
- if (secure || deletekey) {
+ if (secure || deletekey) {
/* Delete old version */
CHECK(update_one_rr(kfetch->db, ver, &diff,
DNS_DIFFOP_DEL, keyname, 0,
@@ -8387,7 +8433,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
DNS_DIFFOP_ADD, keyname, 0,
&keydatarr));
- set_refreshkeytimer(zone, &keydata, now);
+ set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
}
}
@@ -8409,7 +8455,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
*/
for (result = dns_rdataset_first(&kfetch->dnskeyset);
result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&kfetch->dnskeyset)) {
+ result = dns_rdataset_next(&kfetch->dnskeyset))
+ {
isc_boolean_t revoked = ISC_FALSE;
isc_boolean_t newkey = ISC_FALSE;
isc_boolean_t updatekey = ISC_FALSE;
@@ -8445,34 +8492,43 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
dns_view_untrust(zone->view, keyname,
&dnskey, mctx);
+ /* But ensure there's a null key */
+ fail_secure(zone, keyname);
+
/* If initializing, delete now */
if (keydata.addhd == 0)
deletekey = ISC_TRUE;
- else
- keydata.removehd = now + MONTH;
+ else {
+ keydata.removehd = now +
+ dns_zone_mkey_month;
+ keydata.flags |=
+ DNS_KEYFLAG_REVOKE;
+ }
} else if (keydata.removehd < now) {
/* Scheduled for removal */
deletekey = ISC_TRUE;
}
- } else if (revoked) {
- if (secure && keydata.removehd == 0) {
- dns_zone_log(zone, ISC_LOG_WARNING,
- "Active key for zone "
- "'%s' is revoked but "
- "did not self-sign; "
- "ignoring.", namebuf);
- continue;
- }
+ } else if (revoked && keydata.removehd == 0) {
+ dns_zone_log(zone, ISC_LOG_WARNING,
+ "Active key for zone "
+ "'%s' is revoked but "
+ "did not self-sign; "
+ "ignoring.", namebuf);
+ continue;
} else if (secure) {
if (keydata.removehd != 0) {
/*
* Key isn't revoked--but it
* seems it used to be.
* Remove it now and add it
- * back as if it were a fresh key.
+ * back as if it were a fresh key,
+ * with a 30 day acceptance timer.
*/
deletekey = ISC_TRUE;
newkey = ISC_TRUE;
+ keydata.removehd = 0;
+ keydata.addhd =
+ now + dns_zone_mkey_month;
} else if (keydata.addhd > now)
pending++;
else if (keydata.addhd == 0)
@@ -8480,6 +8536,13 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
if (keydata.addhd <= now)
trustkey = ISC_TRUE;
+ } else if (keydata.addhd > now) {
+ /*
+ * Not secure, and key is pending:
+ * reset the acceptance timer
+ */
+ pending++;
+ keydata.addhd = now + dns_zone_mkey_month;
}
if (!deletekey && !newkey)
@@ -8541,7 +8604,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
NULL);
- keydata.addhd = initializing ? now : now + MONTH;
+ keydata.addhd = initializing
+ ? now : now + dns_zone_mkey_month;
keydata.refresh = refresh_time(kfetch, ISC_FALSE);
dns_rdata_reset(&keydatarr);
isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
@@ -8564,7 +8628,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
if (secure && !deletekey) {
INSIST(newkey || updatekey);
- set_refreshkeytimer(zone, &keydata, now);
+ set_refreshkeytimer(zone, &keydata, now, ISC_FALSE);
}
}
@@ -8593,7 +8657,7 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
zone_needdump(zone, 30);
}
- failure:
+ failure:
dns_diff_clear(&diff);
if (ver != NULL)
@@ -8624,6 +8688,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
UNLOCK_ZONE(zone);
if (free_needed)
zone_free(zone);
+
+ INSIST(ver == NULL);
}
/*
@@ -8776,7 +8842,7 @@ zone_refreshkeys(dns_zone_t *zone) {
char timebuf[80];
TIME_NOW(&timenow);
- DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
+ DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
zone->refreshkeytime = timethen;
zone_settimer(zone, &timenow);
@@ -8796,6 +8862,8 @@ zone_refreshkeys(dns_zone_t *zone) {
dns_db_closeversion(db, &ver, commit);
}
dns_db_detach(&db);
+
+ INSIST(ver == NULL);
}
static void
@@ -8868,7 +8936,8 @@ zone_maintenance(dns_zone_t *zone) {
* Slaves send notifies before backing up to disk, masters after.
*/
if (zone->type == dns_zone_slave &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
+ (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
+ DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
isc_time_compare(&now, &zone->notifytime) >= 0)
zone_notify(zone, &now);
@@ -8908,7 +8977,8 @@ zone_maintenance(dns_zone_t *zone) {
switch (zone->type) {
case dns_zone_master:
case dns_zone_redirect:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
+ if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
+ DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
isc_time_compare(&now, &zone->notifytime) >= 0)
zone_notify(zone, &now);
default:
@@ -9537,21 +9607,51 @@ dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
}
static isc_boolean_t
-notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
+notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
+ isc_sockaddr_t *addr, dns_tsigkey_t *key)
+{
dns_notify_t *notify;
+ dns_zonemgr_t *zmgr;
+ isc_result_t result;
for (notify = ISC_LIST_HEAD(zone->notifies);
notify != NULL;
notify = ISC_LIST_NEXT(notify, link)) {
if (notify->request != NULL)
continue;
+ if ((flags & DNS_NOTIFY_STARTUP) == 0)
+ notify->flags &= ~DNS_NOTIFY_STARTUP;
if (name != NULL && dns_name_dynamic(&notify->ns) &&
dns_name_equal(name, &notify->ns))
- return (ISC_TRUE);
- if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst))
- return (ISC_TRUE);
+ goto requeue;
+ if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
+ notify->key == key)
+ goto requeue;
}
return (ISC_FALSE);
+
+requeue:
+ /*
+ * If we are enqueued on the startup ratelimiter and this is
+ * not a startup notify, re-enqueue on the normal notify
+ * ratelimiter.
+ */
+ if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0) {
+ zmgr = notify->zone->zmgr;
+ result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
+ notify->event);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_TRUE);
+ result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
+ notify->zone->task,
+ &notify->event);
+ if (result != ISC_R_SUCCESS) {
+ isc_event_free(&notify->event);
+ return (ISC_FALSE);
+ }
+ }
+
+ return (ISC_TRUE);
}
static isc_boolean_t
@@ -9649,6 +9749,7 @@ notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
notify->find = NULL;
notify->request = NULL;
notify->key = NULL;
+ notify->event = NULL;
isc_sockaddr_any(&notify->dst);
dns_name_init(&notify->ns, NULL);
ISC_LINK_INIT(notify, link);
@@ -9724,22 +9825,27 @@ notify_find_address(dns_notify_t *notify) {
static isc_result_t
-notify_send_queue(dns_notify_t *notify) {
+notify_send_queue(dns_notify_t *notify, isc_boolean_t startup) {
isc_event_t *e;
isc_result_t result;
- e = isc_event_allocate(notify->mctx, NULL,
- DNS_EVENT_NOTIFYSENDTOADDR,
- notify_send_toaddr,
- notify, sizeof(isc_event_t));
+ INSIST(notify->event == NULL);
+ e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
+ notify_send_toaddr, notify, sizeof(isc_event_t));
if (e == NULL)
return (ISC_R_NOMEMORY);
+ if (startup)
+ notify->event = e;
e->ev_arg = notify;
e->ev_sender = NULL;
- result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
+ result = isc_ratelimiter_enqueue(startup
+ ? notify->zone->zmgr->startupnotifyrl
+ : notify->zone->zmgr->notifyrl,
notify->zone->task, &e);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
isc_event_free(&e);
+ notify->event = NULL;
+ }
return (result);
}
@@ -9762,6 +9868,8 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
LOCK_ZONE(notify->zone);
+ notify->event = NULL;
+
if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
result = ISC_R_CANCELED;
goto cleanup;
@@ -9871,6 +9979,8 @@ notify_send(dns_notify_t *notify) {
isc_sockaddr_t dst;
isc_result_t result;
dns_notify_t *new = NULL;
+ unsigned int flags;
+ isc_boolean_t startup;
/*
* Zone lock held by caller.
@@ -9882,20 +9992,21 @@ notify_send(dns_notify_t *notify) {
ai != NULL;
ai = ISC_LIST_NEXT(ai, publink)) {
dst = ai->sockaddr;
- if (notify_isqueued(notify->zone, NULL, &dst))
+ if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
+ NULL))
continue;
if (notify_isself(notify->zone, &dst))
continue;
new = NULL;
- result = notify_create(notify->mctx,
- (notify->flags & DNS_NOTIFY_NOSOA),
- &new);
+ flags = notify->flags & DNS_NOTIFY_NOSOA;
+ result = notify_create(notify->mctx, flags, &new);
if (result != ISC_R_SUCCESS)
goto cleanup;
zone_iattach(notify->zone, &new->zone);
ISC_LIST_APPEND(new->zone->notifies, new, link);
new->dst = dst;
- result = notify_send_queue(new);
+ startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
+ result = notify_send_queue(new, startup);
if (result != ISC_R_SUCCESS)
goto cleanup;
new = NULL;
@@ -9934,18 +10045,20 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
dns_rdataset_t nsrdset;
dns_rdataset_t soardset;
isc_result_t result;
- dns_notify_t *notify = NULL;
unsigned int i;
isc_sockaddr_t dst;
isc_boolean_t isqueued;
dns_notifytype_t notifytype;
unsigned int flags = 0;
isc_boolean_t loggednotify = ISC_FALSE;
+ isc_boolean_t startup;
REQUIRE(DNS_ZONE_VALID(zone));
LOCK_ZONE(zone);
+ startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
+ DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
notifytype = zone->notifytype;
DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
UNLOCK_ZONE(zone);
@@ -9970,6 +10083,12 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
flags |= DNS_NOTIFY_NOSOA;
/*
+ * Record that this was a notify due to starting up.
+ */
+ if (startup)
+ flags |= DNS_NOTIFY_STARTUP;
+
+ /*
* Get SOA RRset.
*/
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
@@ -10012,31 +10131,41 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
LOCK_ZONE(zone);
for (i = 0; i < zone->notifycnt; i++) {
dns_tsigkey_t *key = NULL;
+ dns_notify_t *notify = NULL;
+
+ if ((zone->notifykeynames != NULL) &&
+ (zone->notifykeynames[i] != NULL)) {
+ dns_view_t *view = dns_zone_getview(zone);
+ dns_name_t *keyname = zone->notifykeynames[i];
+ (void)dns_view_gettsig(view, keyname, &key);
+ }
dst = zone->notify[i];
- if (notify_isqueued(zone, NULL, &dst))
+ if (notify_isqueued(zone, flags, NULL, &dst, key)) {
+ if (key != NULL)
+ dns_tsigkey_detach(&key);
continue;
+ }
result = notify_create(zone->mctx, flags, &notify);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ if (key != NULL)
+ dns_tsigkey_detach(&key);
continue;
+ }
zone_iattach(zone, &notify->zone);
notify->dst = dst;
- if ((zone->notifykeynames != NULL) &&
- (zone->notifykeynames[i] != NULL)) {
- dns_view_t *view = dns_zone_getview(zone);
- dns_name_t *keyname = zone->notifykeynames[i];
- result = dns_view_gettsig(view, keyname, &key);
- if (result == ISC_R_SUCCESS) {
- notify->key = key;
- key = NULL;
- }
+ INSIST(notify->key == NULL);
+
+ if (key != NULL) {
+ notify->key = key;
+ key = NULL;
}
ISC_LIST_APPEND(zone->notifies, notify, link);
- result = notify_send_queue(notify);
+ result = notify_send_queue(notify, startup);
if (result != ISC_R_SUCCESS)
notify_destroy(notify, ISC_TRUE);
if (!loggednotify) {
@@ -10045,7 +10174,6 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
serial);
loggednotify = ISC_TRUE;
}
- notify = NULL;
}
UNLOCK_ZONE(zone);
@@ -10064,6 +10192,8 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
result = dns_rdataset_first(&nsrdset);
while (result == ISC_R_SUCCESS) {
+ dns_notify_t *notify = NULL;
+
dns_rdataset_current(&nsrdset, &rdata);
result = dns_rdata_tostruct(&rdata, &ns, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@@ -10086,7 +10216,7 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
}
LOCK_ZONE(zone);
- isqueued = notify_isqueued(zone, &ns.name, NULL);
+ isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
UNLOCK_ZONE(zone);
if (isqueued) {
result = dns_rdataset_next(&nsrdset);
@@ -10107,7 +10237,6 @@ zone_notify(dns_zone_t *zone, isc_time_t *now) {
ISC_LIST_APPEND(zone->notifies, notify, link);
UNLOCK_ZONE(zone);
notify_find_address(notify);
- notify = NULL;
result = dns_rdataset_next(&nsrdset);
}
dns_rdataset_disassociate(&nsrdset);
@@ -10715,12 +10844,12 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
serial = soa.serial;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- unsigned int soacount;
- result = zone_get_from_db(zone, zone->db, NULL, &soacount,
+ unsigned int dbsoacount;
+ result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
&oldserial, NULL, NULL, NULL, NULL,
NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- RUNTIME_CHECK(soacount > 0U);
+ RUNTIME_CHECK(dbsoacount > 0U);
zone_debuglog(zone, me, 1, "serial: new %u, old %u",
serial, oldserial);
} else
@@ -11004,14 +11133,11 @@ soa_query(isc_task_t *task, isc_event_t *event) {
goto cleanup;
}
- /*
- * XXX Optimisation: Create message when zone is setup and reuse.
- */
+ again:
result = create_query(zone, dns_rdatatype_soa, &message);
if (result != ISC_R_SUCCESS)
goto cleanup;
- again:
INSIST(zone->masterscnt > 0);
INSIST(zone->curmaster < zone->masterscnt);
@@ -11116,9 +11242,9 @@ soa_query(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_SUCCESS) {
zone_idetach(&dummy);
zone_debuglog(zone, me, 1,
- "dns_request_createvia2() failed: %s",
+ "dns_request_createvia4() failed: %s",
dns_result_totext(result));
- goto cleanup;
+ goto skip_master;
} else {
if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
inc_stats(zone, dns_zonestatscounter_soaoutv4);
@@ -11144,6 +11270,7 @@ soa_query(isc_task_t *task, isc_event_t *event) {
skip_master:
if (key != NULL)
dns_tsigkey_detach(&key);
+ dns_message_destroy(&message);
/*
* Skip to next failed / untried master.
*/
@@ -11526,7 +11653,8 @@ zone_settimer(dns_zone_t *zone, isc_time_t *now) {
/* FALLTHROUGH */
case dns_zone_master:
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
+ DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
next = zone->notifytime;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
@@ -12586,9 +12714,12 @@ notify_done(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
if (message != NULL && message->rcode == dns_rcode_formerr &&
(notify->flags & DNS_NOTIFY_NOSOA) == 0) {
+ isc_boolean_t startup;
+
notify->flags |= DNS_NOTIFY_NOSOA;
dns_request_destroy(&notify->request);
- result = notify_send_queue(notify);
+ startup = ISC_TF((notify->flags & DNS_NOTIFY_STARTUP) != 0);
+ result = notify_send_queue(notify, startup);
if (result != ISC_R_SUCCESS)
notify_destroy(notify, ISC_FALSE);
} else {
@@ -12614,7 +12745,7 @@ update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
}
static isc_result_t
-sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal,
+sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
isc_uint32_t start, isc_uint32_t end,
dns_difftuple_t **soatuplep, dns_diff_t *diff)
{
@@ -12658,9 +12789,9 @@ sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal,
/* Sanity. */
if (n_soa == 0) {
- dns_zone_log(zone->raw, ISC_LOG_ERROR,
+ dns_zone_log(raw, ISC_LOG_ERROR,
"corrupt journal file: '%s'\n",
- zone->raw->journal);
+ raw->journal);
return (ISC_R_FAILURE);
}
@@ -12689,7 +12820,7 @@ sync_secure_journal(dns_zone_t *zone, dns_journal_t *journal,
}
static isc_result_t
-sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb,
+sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
dns_dbversion_t *secver, dns_difftuple_t **soatuple,
dns_diff_t *diff)
{
@@ -12701,13 +12832,12 @@ sync_secure_db(dns_zone_t *seczone, dns_db_t *secdb,
dns_rdata_soa_t oldsoa, newsoa;
REQUIRE(DNS_ZONE_VALID(seczone));
- REQUIRE(inline_secure(seczone));
REQUIRE(soatuple != NULL && *soatuple == NULL);
if (!seczone->sourceserialset)
return (DNS_R_UNCHANGED);
- dns_db_attach(seczone->raw->db, &rawdb);
+ dns_db_attach(raw->db, &rawdb);
dns_db_currentversion(rawdb, &rawver);
result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
dns_db_closeversion(rawdb, &rawver, ISC_FALSE);
@@ -12794,7 +12924,7 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
dns_journal_t *rjournal = NULL;
isc_uint32_t start, end;
- dns_zone_t *zone;
+ dns_zone_t *zone, *raw = NULL;
dns_db_t *db = NULL;
dns_dbversion_t *newver = NULL, *oldver = NULL;
dns_diff_t diff;
@@ -12819,10 +12949,14 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
dns_db_attach(zone->db, &db);
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
+ if (zone->raw != NULL)
+ dns_zone_attach(zone->raw, &raw);
+ UNLOCK_ZONE(zone);
+
/*
* zone->db may be NULL if the load from disk failed.
*/
- if (db == NULL || !inline_secure(zone)) {
+ if (db == NULL || raw == NULL) {
result = ISC_R_FAILURE;
goto failure;
}
@@ -12836,7 +12970,7 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
* If that fails, then we'll fall back to a direct comparison
* between raw and secure zones.
*/
- result = dns_journal_open(zone->raw->mctx, zone->raw->journal,
+ result = dns_journal_open(raw->mctx, raw->journal,
DNS_JOURNAL_WRITE, &rjournal);
if (result != ISC_R_SUCCESS)
goto failure;
@@ -12875,12 +13009,12 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
* zone. If that fails, we recover by syncing up the databases
* directly.
*/
- result = sync_secure_journal(zone, rjournal, start, end,
+ result = sync_secure_journal(zone, raw, rjournal, start, end,
&soatuple, &diff);
if (result == DNS_R_UNCHANGED)
goto failure;
else if (result != ISC_R_SUCCESS)
- CHECK(sync_secure_db(zone, db, oldver, &soatuple, &diff));
+ CHECK(sync_secure_db(zone, raw, db, oldver, &soatuple, &diff));
CHECK(dns_diff_apply(&diff, db, newver));
@@ -12913,6 +13047,7 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
dns_journal_set_sourceserial(rjournal, end);
dns_journal_commit(rjournal);
+ LOCK_ZONE(zone);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
zone->sourceserial = end;
@@ -12921,12 +13056,14 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
TIME_NOW(&timenow);
zone_settimer(zone, &timenow);
+ UNLOCK_ZONE(zone);
dns_db_closeversion(db, &oldver, ISC_FALSE);
dns_db_closeversion(db, &newver, ISC_TRUE);
failure:
- UNLOCK_ZONE(zone);
+ if (raw != NULL)
+ dns_zone_detach(&raw);
if (result != ISC_R_SUCCESS)
dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
dns_result_totext(result));
@@ -12945,6 +13082,9 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
dns_journal_destroy(&rjournal);
dns_diff_clear(&diff);
dns_zone_idetach(&zone);
+
+ INSIST(oldver == NULL);
+ INSIST(newver == NULL);
}
static isc_result_t
@@ -13380,6 +13520,8 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
if (db != NULL) {
if (node != NULL)
dns_db_detachnode(db, &node);
+ if (version != NULL)
+ dns_db_closeversion(db, &version, ISC_FALSE);
dns_db_detach(&db);
}
if (rawnode != NULL)
@@ -13388,6 +13530,8 @@ receive_secure_db(isc_task_t *task, isc_event_t *event) {
if (dbiterator != NULL)
dns_dbiterator_destroy(&dbiterator);
dns_zone_idetach(&zone);
+
+ INSIST(version == NULL);
}
static isc_result_t
@@ -14288,7 +14432,7 @@ sendtomaster(dns_forward_t *forward) {
result = dns_request_createraw(forward->zone->view->requestmgr,
forward->msgbuf,
&src, &forward->addr,
- DNS_REQUESTOPT_TCP, 15 /* XXX */,
+ forward->options, 15 /* XXX */,
forward->zone->task,
forward_callback, forward,
&forward->request);
@@ -14435,6 +14579,13 @@ dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
forward->callback_arg = callback_arg;
ISC_LINK_INIT(forward, link);
forward->magic = FORWARD_MAGIC;
+ forward->options = DNS_REQUESTOPT_TCP;
+ /*
+ * If we have a SIG(0) signed message we need to preserve the
+ * query id as that is included in the SIG(0) computation.
+ */
+ if (msg->sig0 != NULL)
+ forward->options |= DNS_REQUESTOPT_FIXEDID;
mr = dns_message_getrawmessage(msg);
if (mr == NULL) {
@@ -14495,7 +14646,6 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
{
dns_zonemgr_t *zmgr;
isc_result_t result;
- isc_interval_t interval;
zmgr = isc_mem_get(mctx, sizeof(*zmgr));
if (zmgr == NULL)
@@ -14512,6 +14662,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
zmgr->task = NULL;
zmgr->notifyrl = NULL;
zmgr->refreshrl = NULL;
+ zmgr->startupnotifyrl = NULL;
+ zmgr->startuprefreshrl = NULL;
ISC_LIST_INIT(zmgr->zones);
ISC_LIST_INIT(zmgr->waiting_for_xfrin);
ISC_LIST_INIT(zmgr->xfrin_in_progress);
@@ -14544,15 +14696,21 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
if (result != ISC_R_SUCCESS)
goto free_notifyrl;
- /* default to 20 refresh queries / notifies per second. */
- isc_interval_set(&interval, 0, 1000000000/2);
- result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_ratelimiter_setpertic(zmgr->notifyrl, 10);
+ result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
+ &zmgr->startupnotifyrl);
+ if (result != ISC_R_SUCCESS)
+ goto free_refreshrl;
- result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_ratelimiter_setpertic(zmgr->refreshrl, 10);
+ result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
+ &zmgr->startuprefreshrl);
+ if (result != ISC_R_SUCCESS)
+ goto free_startupnotifyrl;
+
+ /* default to 20 refresh queries / notifies per second. */
+ setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
+ setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
+ setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
+ setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
zmgr->iolimit = 1;
zmgr->ioactive = 0;
@@ -14561,7 +14719,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
result = isc_mutex_init(&zmgr->iolock);
if (result != ISC_R_SUCCESS)
- goto free_refreshrl;
+ goto free_startuprefreshrl;
zmgr->magic = ZONEMGR_MAGIC;
@@ -14572,6 +14730,10 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
free_iolock:
DESTROYLOCK(&zmgr->iolock);
#endif
+ free_startuprefreshrl:
+ isc_ratelimiter_detach(&zmgr->startuprefreshrl);
+ free_startupnotifyrl:
+ isc_ratelimiter_detach(&zmgr->startupnotifyrl);
free_refreshrl:
isc_ratelimiter_detach(&zmgr->refreshrl);
free_notifyrl:
@@ -14775,6 +14937,8 @@ dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
isc_ratelimiter_shutdown(zmgr->notifyrl);
isc_ratelimiter_shutdown(zmgr->refreshrl);
+ isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
+ isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
if (zmgr->task != NULL)
isc_task_destroy(&zmgr->task);
@@ -14908,6 +15072,8 @@ zonemgr_free(dns_zonemgr_t *zmgr) {
DESTROYLOCK(&zmgr->iolock);
isc_ratelimiter_detach(&zmgr->notifyrl);
isc_ratelimiter_detach(&zmgr->refreshrl);
+ isc_ratelimiter_detach(&zmgr->startupnotifyrl);
+ isc_ratelimiter_detach(&zmgr->startuprefreshrl);
isc_rwlock_destroy(&zmgr->urlock);
isc_rwlock_destroy(&zmgr->rwlock);
@@ -15270,15 +15436,13 @@ dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
}
#endif
-void
-dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
+static void
+setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
isc_interval_t interval;
isc_uint32_t s, ns;
isc_uint32_t pertic;
isc_result_t result;
- REQUIRE(DNS_ZONEMGR_VALID(zmgr));
-
if (value == 0)
value = 1;
@@ -15298,15 +15462,26 @@ dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
isc_interval_set(&interval, s, ns);
- result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
+ result = isc_ratelimiter_setinterval(rl, &interval);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_ratelimiter_setpertic(zmgr->notifyrl, pertic);
+ isc_ratelimiter_setpertic(rl, pertic);
- result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
- RUNTIME_CHECK(result == ISC_R_SUCCESS);
- isc_ratelimiter_setpertic(zmgr->refreshrl, pertic);
+ *rate = value;
+}
- zmgr->serialqueryrate = value;
+void
+dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
+
+ REQUIRE(DNS_ZONEMGR_VALID(zmgr));
+
+ setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
+
+ /* Seperately controlled in BIND 9.11.x */
+ setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
+ setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
+
+ /* XXXMPA seperate out once we have the code to support this. */
+ setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
}
unsigned int
@@ -16627,6 +16802,8 @@ zone_rekey(dns_zone_t *zone) {
dns_db_detachnode(db, &node);
if (db != NULL)
dns_db_detach(&db);
+
+ INSIST(ver == NULL);
return;
failure:
@@ -16964,6 +17141,9 @@ keydone(isc_task_t *task, isc_event_t *event) {
dns_diff_clear(&diff);
isc_event_free(&event);
dns_zone_idetach(&zone);
+
+ INSIST(oldver == NULL);
+ INSIST(newver == NULL);
}
isc_result_t
@@ -17199,6 +17379,9 @@ setnsec3param(isc_task_t *task, isc_event_t *event) {
dns_diff_clear(&diff);
isc_event_free(&event);
dns_zone_idetach(&zone);
+
+ INSIST(oldver == NULL);
+ INSIST(newver == NULL);
}
isc_result_t
diff --git a/lib/dns/zt.c b/lib/dns/zt.c
index eb1e42472475..33c974b1d972 100644
--- a/lib/dns/zt.c
+++ b/lib/dns/zt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2011, 2012, 2014 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -396,16 +396,16 @@ freezezones(dns_zone_t *zone, void *uap) {
result = DNS_R_FROZEN;
if (result == ISC_R_SUCCESS)
result = dns_zone_flush(zone);
+ if (result == ISC_R_SUCCESS)
+ dns_zone_setupdatedisabled(zone, freeze);
} else {
if (frozen) {
- result = dns_zone_load(zone);
+ result = dns_zone_loadandthaw(zone);
if (result == DNS_R_CONTINUE ||
result == DNS_R_UPTODATE)
result = ISC_R_SUCCESS;
}
}
- if (result == ISC_R_SUCCESS)
- dns_zone_setupdatedisabled(zone, freeze);
view = dns_zone_getview(zone);
if (strcmp(view->name, "_bind") == 0 ||
strcmp(view->name, "_default") == 0)