summaryrefslogtreecommitdiff
path: root/contrib/bind9/lib/dns
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/lib/dns')
-rw-r--r--contrib/bind9/lib/dns/api4
-rw-r--r--contrib/bind9/lib/dns/db.c6
-rw-r--r--contrib/bind9/lib/dns/dispatch.c28
-rw-r--r--contrib/bind9/lib/dns/dnssec.c69
-rw-r--r--contrib/bind9/lib/dns/dst_api.c53
-rw-r--r--contrib/bind9/lib/dns/dst_internal.h12
-rw-r--r--contrib/bind9/lib/dns/dst_parse.c18
-rw-r--r--contrib/bind9/lib/dns/include/dns/db.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/dnssec.h8
-rw-r--r--contrib/bind9/lib/dns/include/dns/journal.h11
-rw-r--r--contrib/bind9/lib/dns/include/dns/keyvalues.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/name.h8
-rw-r--r--contrib/bind9/lib/dns/include/dns/ncache.h4
-rw-r--r--contrib/bind9/lib/dns/include/dns/nsec3.h4
-rw-r--r--contrib/bind9/lib/dns/include/dns/rbt.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/rdataset.h20
-rw-r--r--contrib/bind9/lib/dns/include/dns/resolver.h46
-rw-r--r--contrib/bind9/lib/dns/include/dns/result.h8
-rw-r--r--contrib/bind9/lib/dns/include/dns/types.h2
-rw-r--r--contrib/bind9/lib/dns/include/dns/validator.h6
-rw-r--r--contrib/bind9/lib/dns/include/dns/zone.h20
-rw-r--r--contrib/bind9/lib/dns/include/dst/dst.h6
-rw-r--r--contrib/bind9/lib/dns/journal.c99
-rw-r--r--contrib/bind9/lib/dns/masterdump.c2
-rw-r--r--contrib/bind9/lib/dns/message.c4
-rw-r--r--contrib/bind9/lib/dns/ncache.c6
-rw-r--r--contrib/bind9/lib/dns/nsec3.c25
-rw-r--r--contrib/bind9/lib/dns/opensslrsa_link.c496
-rw-r--r--contrib/bind9/lib/dns/rbt.c35
-rw-r--r--contrib/bind9/lib/dns/rbtdb.c163
-rw-r--r--contrib/bind9/lib/dns/rcode.c6
-rw-r--r--contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c3
-rw-r--r--contrib/bind9/lib/dns/rdatalist.c6
-rw-r--r--contrib/bind9/lib/dns/rdataset.c25
-rw-r--r--contrib/bind9/lib/dns/rdataslab.c6
-rw-r--r--contrib/bind9/lib/dns/resolver.c461
-rw-r--r--contrib/bind9/lib/dns/result.c7
-rw-r--r--contrib/bind9/lib/dns/sdb.c10
-rw-r--r--contrib/bind9/lib/dns/sdlz.c10
-rw-r--r--contrib/bind9/lib/dns/spnego.c18
-rw-r--r--contrib/bind9/lib/dns/validator.c160
-rw-r--r--contrib/bind9/lib/dns/view.c14
-rw-r--r--contrib/bind9/lib/dns/zone.c211
43 files changed, 1705 insertions, 413 deletions
diff --git a/contrib/bind9/lib/dns/api b/contrib/bind9/lib/dns/api
index 4bcf883246ce..4fc7eca838cb 100644
--- a/contrib/bind9/lib/dns/api
+++ b/contrib/bind9/lib/dns/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 53
+LIBINTERFACE = 56
LIBREVISION = 0
-LIBAGE = 0
+LIBAGE = 1
diff --git a/contrib/bind9/lib/dns/db.c b/contrib/bind9/lib/dns/db.c
index a4c28641701f..02ea6b596ec8 100644
--- a/contrib/bind9/lib/dns/db.c
+++ b/contrib/bind9/lib/dns/db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009 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
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.c,v 1.88 2008/09/24 02:46:22 marka Exp $ */
+/* $Id: db.c,v 1.88.50.2 2009/06/23 00:19:34 tbox Exp $ */
/*! \file */
@@ -854,12 +854,14 @@ dns_db_unregister(dns_dbimplementation_t **dbimp) {
RUNTIME_CHECK(isc_once_do(&once, initialize) == ISC_R_SUCCESS);
imp = *dbimp;
+ *dbimp = NULL;
RWLOCK(&implock, isc_rwlocktype_write);
ISC_LIST_UNLINK(implementations, imp, link);
mctx = imp->mctx;
isc_mem_put(mctx, imp, sizeof(dns_dbimplementation_t));
isc_mem_detach(&mctx);
RWUNLOCK(&implock, isc_rwlocktype_write);
+ ENSURE(*dbimp == NULL);
}
isc_result_t
diff --git a/contrib/bind9/lib/dns/dispatch.c b/contrib/bind9/lib/dns/dispatch.c
index 9b4e9685f408..1d04961277be 100644
--- a/contrib/bind9/lib/dns/dispatch.c
+++ b/contrib/bind9/lib/dns/dispatch.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.155.12.7 2009/04/28 21:39:45 jinmei Exp $ */
+/* $Id: dispatch.c,v 1.155.12.11 2009/12/02 23:26:28 marka Exp $ */
/*! \file */
@@ -746,13 +746,19 @@ new_portentry(dns_dispatch_t *disp, in_port_t port) {
return (portentry);
}
+/*%
+ * The caller must not hold the qid->lock.
+ */
static void
deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
dispportentry_t *portentry = *portentryp;
+ dns_qid_t *qid;
REQUIRE(disp->port_table != NULL);
REQUIRE(portentry != NULL && portentry->refs > 0);
+ qid = DNS_QID(disp);
+ LOCK(&qid->lock);
portentry->refs--;
if (portentry->refs == 0) {
ISC_LIST_UNLINK(disp->port_table[portentry->port %
@@ -762,6 +768,7 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
}
*portentryp = NULL;
+ UNLOCK(&qid->lock);
}
/*%
@@ -779,8 +786,9 @@ socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port,
dispsock = ISC_LIST_HEAD(qid->sock_table[bucket]);
while (dispsock != NULL) {
- if (isc_sockaddr_equal(dest, &dispsock->host) &&
- dispsock->portentry->port == port)
+ if (dispsock->portentry != NULL &&
+ dispsock->portentry->port == port &&
+ isc_sockaddr_equal(dest, &dispsock->host))
return (dispsock);
dispsock = ISC_LIST_NEXT(dispsock, blink);
}
@@ -2048,8 +2056,18 @@ dns_dispatchmgr_setudp(dns_dispatchmgr_t *mgr,
/* Create or adjust buffer pool */
if (mgr->bpool != NULL) {
- isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
- mgr->maxbuffers = maxbuffers;
+ /*
+ * We only increase the maxbuffers to avoid accidental buffer
+ * shortage. Ideally we'd separate the manager-wide maximum
+ * from per-dispatch limits and respect the latter within the
+ * global limit. But at this moment that's deemed to be
+ * overkilling and isn't worth additional implementation
+ * complexity.
+ */
+ if (maxbuffers > mgr->maxbuffers) {
+ isc_mempool_setmaxalloc(mgr->bpool, maxbuffers);
+ mgr->maxbuffers = maxbuffers;
+ }
} else {
result = isc_mempool_create(mgr->mctx, buffersize, &mgr->bpool);
if (result != ISC_R_SUCCESS) {
diff --git a/contrib/bind9/lib/dns/dnssec.c b/contrib/bind9/lib/dns/dnssec.c
index baf3ec5b12ec..8ae29bceee92 100644
--- a/contrib/bind9/lib/dns/dnssec.c
+++ b/contrib/bind9/lib/dns/dnssec.c
@@ -16,7 +16,7 @@
*/
/*
- * $Id: dnssec.c,v 1.93.12.4 2009/06/08 23:47:00 tbox Exp $
+ * $Id: dnssec.c,v 1.93.12.6 2009/06/22 23:47:18 tbox Exp $
*/
/*! \file */
@@ -93,6 +93,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
isc_result_t ret;
int i = 0, n;
dns_rdata_t *data;
+ dns_rdataset_t rdataset;
n = dns_rdataset_count(set);
@@ -100,8 +101,11 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
if (data == NULL)
return (ISC_R_NOMEMORY);
- ret = dns_rdataset_first(set);
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_clone(set, &rdataset);
+ ret = dns_rdataset_first(&rdataset);
if (ret != ISC_R_SUCCESS) {
+ dns_rdataset_disassociate(&rdataset);
isc_mem_put(mctx, data, n * sizeof(dns_rdata_t));
return (ret);
}
@@ -111,8 +115,8 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
*/
do {
dns_rdata_init(&data[i]);
- dns_rdataset_current(set, &data[i++]);
- } while (dns_rdataset_next(set) == ISC_R_SUCCESS);
+ dns_rdataset_current(&rdataset, &data[i++]);
+ } while (dns_rdataset_next(&rdataset) == ISC_R_SUCCESS);
/*
* Sort the array.
@@ -120,6 +124,7 @@ rdataset_to_sortedarray(dns_rdataset_t *set, isc_mem_t *mctx,
qsort(data, n, sizeof(dns_rdata_t), rdata_compare_wrapper);
*rdata = data;
*nrdata = n;
+ dns_rdataset_disassociate(&rdataset);
return (ISC_R_SUCCESS);
}
@@ -890,3 +895,59 @@ failure:
return (result);
}
+
+/*%
+ * Does this key ('rdata') self sign the rrset ('rdataset')?
+ */
+isc_boolean_t
+dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+ isc_boolean_t ignoretime, isc_mem_t *mctx)
+{
+ dst_key_t *dstkey = NULL;
+ dns_keytag_t keytag;
+ dns_rdata_dnskey_t key;
+ dns_rdata_rrsig_t sig;
+ dns_rdata_t sigrdata = DNS_RDATA_INIT;
+ isc_result_t result;
+
+ INSIST(rdataset->type == dns_rdatatype_key ||
+ rdataset->type == dns_rdatatype_dnskey);
+ if (rdataset->type == dns_rdatatype_key) {
+ INSIST(sigrdataset->type == dns_rdatatype_sig);
+ INSIST(sigrdataset->covers == dns_rdatatype_key);
+ } else {
+ INSIST(sigrdataset->type == dns_rdatatype_rrsig);
+ INSIST(sigrdataset->covers == dns_rdatatype_dnskey);
+ }
+
+ result = dns_dnssec_keyfromrdata(name, rdata, mctx, &dstkey);
+ if (result != ISC_R_SUCCESS)
+ return (ISC_FALSE);
+ result = dns_rdata_tostruct(rdata, &key, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ keytag = dst_key_id(dstkey);
+ for (result = dns_rdataset_first(sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(sigrdataset))
+ {
+ dns_rdata_reset(&sigrdata);
+ dns_rdataset_current(sigrdataset, &sigrdata);
+ result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ if (sig.algorithm == key.algorithm &&
+ sig.keyid == keytag) {
+ result = dns_dnssec_verify2(name, rdataset, dstkey,
+ ignoretime, mctx,
+ &sigrdata, NULL);
+ if (result == ISC_R_SUCCESS) {
+ dst_key_free(&dstkey);
+ return (ISC_TRUE);
+ }
+ }
+ }
+ dst_key_free(&dstkey);
+ return (ISC_FALSE);
+}
diff --git a/contrib/bind9/lib/dns/dst_api.c b/contrib/bind9/lib/dns/dst_api.c
index 144c685e1089..bbb0a09cc3a3 100644
--- a/contrib/bind9/lib/dns/dst_api.c
+++ b/contrib/bind9/lib/dns/dst_api.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.16.12.3 2009/03/02 02:00:34 marka Exp $
+ * $Id: dst_api.c,v 1.16.12.10 2010/01/15 19:38:53 each Exp $
*/
/*! \file */
@@ -183,9 +183,16 @@ dst_lib_init(isc_mem_t *mctx, isc_entropy_t *ectx, unsigned int eflags) {
RETERR(dst__hmacsha512_init(&dst_t_func[DST_ALG_HMACSHA512]));
#ifdef OPENSSL
RETERR(dst__openssl_init());
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5]));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1]));
- RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1]));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSAMD5],
+ DST_ALG_RSAMD5));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA1],
+ DST_ALG_RSASHA1));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_NSEC3RSASHA1],
+ DST_ALG_NSEC3RSASHA1));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA256],
+ DST_ALG_RSASHA256));
+ RETERR(dst__opensslrsa_init(&dst_t_func[DST_ALG_RSASHA512],
+ DST_ALG_RSASHA512));
#ifdef HAVE_OPENSSL_DSA
RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_DSA]));
RETERR(dst__openssldsa_init(&dst_t_func[DST_ALG_NSEC3DSA]));
@@ -848,6 +855,8 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
*n = (key->key_size + 7) / 8;
break;
case DST_ALG_DSA:
@@ -1017,6 +1026,9 @@ dst_key_read_public(const char *filename, int type,
/* Read the next word: either TTL, class, or 'KEY' */
NEXTTOKEN(lex, opt, &token);
+ if (token.type != isc_tokentype_string)
+ BADTOKEN();
+
/* If it's a TTL, read the next one */
result = dns_ttl_fromtext(&token.value.as_textregion, &ttl);
if (result == ISC_R_SUCCESS)
@@ -1072,6 +1084,8 @@ issymmetric(const dst_key_t *key) {
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
case DST_ALG_NSEC3RSASHA1:
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
case DST_ALG_DSA:
case DST_ALG_NSEC3DSA:
case DST_ALG_DH:
@@ -1152,7 +1166,7 @@ write_public_key(const dst_key_t *key, int type, const char *directory) {
fprintf(fp, " ");
isc_buffer_usedregion(&classb, &r);
- fwrite(r.base, 1, r.length, fp);
+ isc_util_fwrite(r.base, 1, r.length, fp);
if ((type & DST_TYPE_KEY) != 0)
fprintf(fp, " KEY ");
@@ -1160,7 +1174,7 @@ write_public_key(const dst_key_t *key, int type, const char *directory) {
fprintf(fp, " DNSKEY ");
isc_buffer_usedregion(&textb, &r);
- fwrite(r.base, 1, r.length, fp);
+ isc_util_fwrite(r.base, 1, r.length, fp);
fputc('\n', fp);
fflush(fp);
@@ -1275,7 +1289,8 @@ algorithm_status(unsigned int alg) {
if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
alg == DST_ALG_DSA || alg == DST_ALG_DH ||
alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA ||
- alg == DST_ALG_NSEC3RSASHA1)
+ alg == DST_ALG_NSEC3RSASHA1 ||
+ alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512)
return (DST_R_NOCRYPTO);
#endif
return (DST_R_UNSUPPORTEDALG);
@@ -1297,6 +1312,8 @@ addsuffix(char *filename, unsigned int len, const char *ofilename,
n = snprintf(filename, len, "%.*s%s", olen, ofilename, suffix);
if (n < 0)
+ return (ISC_R_FAILURE);
+ if ((unsigned int)n >= len)
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
}
@@ -1304,6 +1321,9 @@ addsuffix(char *filename, unsigned int len, const char *ofilename,
isc_result_t
dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
unsigned int flags = dst_entropy_flags;
+
+ if (len == 0)
+ return (ISC_R_SUCCESS);
if (pseudo)
flags &= ~ISC_ENTROPY_GOODONLY;
return (isc_entropy_getdata(dst_entropy_pool, buf, len, NULL, flags));
@@ -1311,5 +1331,22 @@ dst__entropy_getdata(void *buf, unsigned int len, isc_boolean_t pseudo) {
unsigned int
dst__entropy_status(void) {
+#ifdef GSSAPI
+ unsigned int flags = dst_entropy_flags;
+ isc_result_t ret;
+ unsigned char buf[32];
+ static isc_boolean_t first = ISC_TRUE;
+
+ if (first) {
+ /* Someone believes RAND_status() initializes the PRNG */
+ flags &= ~ISC_ENTROPY_GOODONLY;
+ ret = isc_entropy_getdata(dst_entropy_pool, buf,
+ sizeof(buf), NULL, flags);
+ INSIST(ret == ISC_R_SUCCESS);
+ isc_entropy_putdata(dst_entropy_pool, buf,
+ sizeof(buf), 2 * sizeof(buf));
+ first = ISC_FALSE;
+ }
+#endif
return (isc_entropy_status(dst_entropy_pool));
}
diff --git a/contrib/bind9/lib/dns/dst_internal.h b/contrib/bind9/lib/dns/dst_internal.h
index 0c1a71c22560..16696487bc47 100644
--- a/contrib/bind9/lib/dns/dst_internal.h
+++ b/contrib/bind9/lib/dns/dst_internal.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -29,7 +29,7 @@
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst_internal.h,v 1.11 2008/04/01 23:47:10 tbox Exp $ */
+/* $Id: dst_internal.h,v 1.11.120.2 2010/01/15 23:47:33 tbox Exp $ */
#ifndef DST_DST_INTERNAL_H
#define DST_DST_INTERNAL_H 1
@@ -42,6 +42,7 @@
#include <isc/types.h>
#include <isc/md5.h>
#include <isc/sha1.h>
+#include <isc/sha2.h>
#include <isc/hmacmd5.h>
#include <isc/hmacsha.h>
@@ -97,7 +98,7 @@ struct dst_key {
void *generic;
gss_ctx_id_t gssctx;
#ifdef OPENSSL
-#if USE_EVP_RSA
+#if !defined(USE_EVP) || !USE_EVP
RSA *rsa;
#endif
DSA *dsa;
@@ -124,6 +125,8 @@ struct dst_context {
dst_gssapi_signverifyctx_t *gssctx;
isc_md5_t *md5ctx;
isc_sha1_t *sha1ctx;
+ isc_sha256_t *sha256ctx;
+ isc_sha512_t *sha512ctx;
isc_hmacmd5_t *hmacmd5ctx;
isc_hmacsha1_t *hmacsha1ctx;
isc_hmacsha224_t *hmacsha224ctx;
@@ -183,7 +186,8 @@ isc_result_t dst__hmacsha224_init(struct dst_func **funcp);
isc_result_t dst__hmacsha256_init(struct dst_func **funcp);
isc_result_t dst__hmacsha384_init(struct dst_func **funcp);
isc_result_t dst__hmacsha512_init(struct dst_func **funcp);
-isc_result_t dst__opensslrsa_init(struct dst_func **funcp);
+isc_result_t dst__opensslrsa_init(struct dst_func **funcp,
+ unsigned char algorithm);
isc_result_t dst__openssldsa_init(struct dst_func **funcp);
isc_result_t dst__openssldh_init(struct dst_func **funcp);
isc_result_t dst__gssapi_init(struct dst_func **funcp);
diff --git a/contrib/bind9/lib/dns/dst_parse.c b/contrib/bind9/lib/dns/dst_parse.c
index 2da72ae6415a..e8ab34ff7573 100644
--- a/contrib/bind9/lib/dns/dst_parse.c
+++ b/contrib/bind9/lib/dns/dst_parse.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010 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
@@ -31,7 +31,7 @@
/*%
* Principal Author: Brian Wellington
- * $Id: dst_parse.c,v 1.14.120.2 2009/03/02 23:47:11 tbox Exp $
+ * $Id: dst_parse.c,v 1.14.120.6 2010/01/15 19:38:53 each Exp $
*/
#include <config.h>
@@ -480,6 +480,18 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
case DST_ALG_RSASHA1:
fprintf(fp, "(RSASHA1)\n");
break;
+ case DST_ALG_NSEC3DSA:
+ fprintf(fp, "(NSEC3DSA)\n");
+ break;
+ case DST_ALG_NSEC3RSASHA1:
+ fprintf(fp, "(NSEC3RSASHA1)\n");
+ break;
+ case DST_ALG_RSASHA256:
+ fprintf(fp, "(RSASHA256)\n");
+ break;
+ case DST_ALG_RSASHA512:
+ fprintf(fp, "(RSASHA512)\n");
+ break;
case DST_ALG_HMACMD5:
fprintf(fp, "(HMAC_MD5)\n");
break;
@@ -521,7 +533,7 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
isc_buffer_usedregion(&b, &r);
fprintf(fp, "%s ", s);
- fwrite(r.base, 1, r.length, fp);
+ isc_util_fwrite(r.base, 1, r.length, fp);
fprintf(fp, "\n");
}
diff --git a/contrib/bind9/lib/dns/include/dns/db.h b/contrib/bind9/lib/dns/include/dns/db.h
index c75c774143f0..9a1126d7084f 100644
--- a/contrib/bind9/lib/dns/include/dns/db.h
+++ b/contrib/bind9/lib/dns/include/dns/db.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: db.h,v 1.93.50.3.12.1 2009/12/31 21:44:37 each Exp $ */
+/* $Id: db.h,v 1.93.50.5 2009/11/25 23:48:42 tbox Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -695,6 +695,10 @@ dns_db_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* For cache databases, glue is any rdataset with a trust of
* dns_trust_glue.
*
+ * \li If 'options' does not have #DNS_DBFIND_ADDITIONALOK set, then no
+ * additional records will be returned. Only caches can have
+ * rdataset with trust dns_trust_additional.
+ *
* \li If 'options' does not have #DNS_DBFIND_PENDINGOK set, then no
* pending data will be returned. This option is only meaningful for
* cache databases.
diff --git a/contrib/bind9/lib/dns/include/dns/dnssec.h b/contrib/bind9/lib/dns/include/dns/dnssec.h
index c5206be63bb3..14462664a1eb 100644
--- a/contrib/bind9/lib/dns/include/dns/dnssec.h
+++ b/contrib/bind9/lib/dns/include/dns/dnssec.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dnssec.h,v 1.32.332.4 2009/06/08 23:47:00 tbox Exp $ */
+/* $Id: dnssec.h,v 1.32.332.6 2009/06/22 23:47:18 tbox Exp $ */
#ifndef DNS_DNSSEC_H
#define DNS_DNSSEC_H 1
@@ -178,6 +178,12 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
*\li DST_R_*
*/
+isc_boolean_t
+dns_dnssec_selfsigns(dns_rdata_t *rdata, dns_name_t *name,
+ dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+ isc_boolean_t ignoretime, isc_mem_t *mctx);
+
+
ISC_LANG_ENDDECLS
#endif /* DNS_DNSSEC_H */
diff --git a/contrib/bind9/lib/dns/include/dns/journal.h b/contrib/bind9/lib/dns/include/dns/journal.h
index 3917d8db9a0a..a1e16e448785 100644
--- a/contrib/bind9/lib/dns/include/dns/journal.h
+++ b/contrib/bind9/lib/dns/include/dns/journal.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.h,v 1.33.120.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: journal.h,v 1.33.120.4 2009/11/04 23:47:25 tbox Exp $ */
#ifndef DNS_JOURNAL_H
#define DNS_JOURNAL_H 1
@@ -232,12 +232,19 @@ dns_journal_current_rr(dns_journal_t *j, dns_name_t **name, isc_uint32_t *ttl,
isc_result_t
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
const char *filename);
+
+isc_result_t
+dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
+ isc_uint32_t resign, const char *filename);
/*%<
* Roll forward (play back) the journal file "filename" into the
* database "db". This should be called when the server starts
- * after a shutdown or crash.
+ * after a shutdown or crash. 'resign' is how many seconds before
+ * a RRSIG is due to expire it should be scheduled to be regenerated.
*
* Requires:
+ *\li dns_journal_rollforward() requires that DNS_JOURNALOPT_RESIGN
+ * is not set.
*\li 'mctx' is a valid memory context.
*\li 'db' is a valid database which does not have a version
* open for writing.
diff --git a/contrib/bind9/lib/dns/include/dns/keyvalues.h b/contrib/bind9/lib/dns/include/dns/keyvalues.h
index 7f509e6ef13a..f4a50fa606f1 100644
--- a/contrib/bind9/lib/dns/include/dns/keyvalues.h
+++ b/contrib/bind9/lib/dns/include/dns/keyvalues.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: keyvalues.h,v 1.23.48.2 2009/06/04 02:56:14 tbox Exp $ */
+/* $Id: keyvalues.h,v 1.23.48.4 2010/01/15 23:47:33 tbox Exp $ */
#ifndef DNS_KEYVALUES_H
#define DNS_KEYVALUES_H 1
@@ -69,6 +69,8 @@
#define DNS_KEYALG_ECC 4
#define DNS_KEYALG_RSASHA1 5
#define DNS_KEYALG_NSEC3RSASHA1 7
+#define DNS_KEYALG_RSASHA256 8
+#define DNS_KEYALG_RSASHA512 10
#define DNS_KEYALG_INDIRECT 252
#define DNS_KEYALG_PRIVATEDNS 253
#define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */
diff --git a/contrib/bind9/lib/dns/include/dns/name.h b/contrib/bind9/lib/dns/include/dns/name.h
index 0149301dcfbd..dc6e525c1c84 100644
--- a/contrib/bind9/lib/dns/include/dns/name.h
+++ b/contrib/bind9/lib/dns/include/dns/name.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: name.h,v 1.126.332.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: name.h,v 1.126.332.3 2009/12/24 00:34:59 each Exp $ */
#ifndef DNS_NAME_H
#define DNS_NAME_H 1
@@ -99,12 +99,6 @@ ISC_LANG_BEGINDECLS
*****/
/***
- *** Compression pointer chaining limit
- ***/
-
-#define DNS_POINTER_MAXHOPS 16
-
-/***
*** Types
***/
diff --git a/contrib/bind9/lib/dns/include/dns/ncache.h b/contrib/bind9/lib/dns/include/dns/ncache.h
index d61684df88c4..0677211719ec 100644
--- a/contrib/bind9/lib/dns/include/dns/ncache.h
+++ b/contrib/bind9/lib/dns/include/dns/ncache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ncache.h,v 1.25.142.1 2009/12/31 20:29:21 each Exp $ */
+/* $Id: ncache.h,v 1.25.48.2 2009/12/30 23:47:31 tbox Exp $ */
#ifndef DNS_NCACHE_H
#define DNS_NCACHE_H 1
diff --git a/contrib/bind9/lib/dns/include/dns/nsec3.h b/contrib/bind9/lib/dns/include/dns/nsec3.h
index 2d6a8dde8a72..6243fdb10f2b 100644
--- a/contrib/bind9/lib/dns/include/dns/nsec3.h
+++ b/contrib/bind9/lib/dns/include/dns/nsec3.h
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.h,v 1.5.48.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: nsec3.h,v 1.5.48.3 2009/10/06 21:20:18 each Exp $ */
#ifndef DNS_NSEC3_H
#define DNS_NSEC3_H 1
@@ -28,6 +28,8 @@
#include <dns/rdatastruct.h>
#include <dns/types.h>
+#define DNS_NSEC3_SALTSIZE 255
+
/*
* hash = 1, flags =1, iterations = 2, salt length = 1, salt = 255 (max)
* hash length = 1, hash = 255 (max), bitmap = 8192 + 512 (max)
diff --git a/contrib/bind9/lib/dns/include/dns/rbt.h b/contrib/bind9/lib/dns/include/dns/rbt.h
index 6eea787af888..26155965c838 100644
--- a/contrib/bind9/lib/dns/include/dns/rbt.h
+++ b/contrib/bind9/lib/dns/include/dns/rbt.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbt.h,v 1.71.48.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: rbt.h,v 1.71.48.3 2009/10/20 05:06:04 marka Exp $ */
#ifndef DNS_RBT_H
#define DNS_RBT_H 1
@@ -105,11 +105,11 @@ struct dns_rbtnode {
unsigned int is_root : 1; /*%< range is 0..1 */
unsigned int color : 1; /*%< range is 0..1 */
unsigned int find_callback : 1; /*%< range is 0..1 */
- unsigned int attributes : 3; /*%< range is 0..2 */
+ unsigned int attributes : 4; /*%< range is 0..2 */
unsigned int nsec3 : 1; /*%< range is 0..1 */
unsigned int namelen : 8; /*%< range is 1..255 */
unsigned int offsetlen : 8; /*%< range is 1..128 */
- unsigned int padbytes : 9; /*%< range is 0..380 */
+ unsigned int oldnamelen : 8; /*%< range is 1..255 */
/*@}*/
#ifdef DNS_RBT_USEHASH
diff --git a/contrib/bind9/lib/dns/include/dns/rdataset.h b/contrib/bind9/lib/dns/include/dns/rdataset.h
index baff146fcade..d435ed009d4f 100644
--- a/contrib/bind9/lib/dns/include/dns/rdataset.h
+++ b/contrib/bind9/lib/dns/include/dns/rdataset.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.h,v 1.65.50.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: rdataset.h,v 1.65.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
@@ -110,6 +110,9 @@ typedef struct dns_rdatasetmethods {
dns_rdataset_t *rdataset,
dns_rdatasetadditional_t type,
dns_rdatatype_t qtype);
+ void (*settrust)(dns_rdataset_t *rdataset,
+ dns_trust_t trust);
+ void (*expire)(dns_rdataset_t *rdataset);
} dns_rdatasetmethods_t;
#define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R')
@@ -634,6 +637,19 @@ dns_rdataset_putadditional(dns_acache_t *acache,
* information for 'rdataset.'
*/
+void
+dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
+/*%<
+ * Set the trust of the 'rdataset' to trust in any in the backing database.
+ * The local trust level of 'rdataset' is also set.
+ */
+
+void
+dns_rdataset_expire(dns_rdataset_t *rdataset);
+/*%<
+ * Mark the rdataset to be expired in the backing database.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_RDATASET_H */
diff --git a/contrib/bind9/lib/dns/include/dns/resolver.h b/contrib/bind9/lib/dns/include/dns/resolver.h
index fa837c1de4d7..8c7ad7254b0a 100644
--- a/contrib/bind9/lib/dns/include/dns/resolver.h
+++ b/contrib/bind9/lib/dns/include/dns/resolver.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.h,v 1.60.56.3 2009/01/29 22:40:35 jinmei Exp $ */
+/* $Id: resolver.h,v 1.60.56.3.22.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
@@ -508,6 +508,48 @@ dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state);
unsigned int
dns_resolver_getoptions(dns_resolver_t *resolver);
+void
+dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *expire);
+/*%<
+ * Add a entry to the bad cache for <name,type> that will expire at 'expire'.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ * \li name to be valid.
+ */
+
+isc_boolean_t
+dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *now);
+/*%<
+ * Check to see if there is a unexpired entry in the bad cache for
+ * <name,type>.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ * \li name to be valid.
+ */
+
+void
+dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name);
+/*%<
+ * Flush the bad cache of all entries at 'name' if 'name' is non NULL.
+ * Flush the entire bad cache if 'name' is NULL.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ */
+
+void
+dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp);
+/*%
+ * Print out the contents of the bad cache to 'fp'.
+ *
+ * Requires:
+ * \li resolver to be valid.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_RESOLVER_H */
diff --git a/contrib/bind9/lib/dns/include/dns/result.h b/contrib/bind9/lib/dns/include/dns/result.h
index ed29bcd5d3f6..a1e7f535dee8 100644
--- a/contrib/bind9/lib/dns/include/dns/result.h
+++ b/contrib/bind9/lib/dns/include/dns/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.h,v 1.116 2008/09/25 04:02:39 tbox Exp $ */
+/* $Id: result.h,v 1.116.226.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_RESULT_H
#define DNS_RESULT_H 1
@@ -148,8 +148,10 @@
#define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102)
#define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103)
#define DNS_R_INVALIDNSEC3 (ISC_RESULTCLASS_DNS + 104)
+#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105)
+#define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106)
-#define DNS_R_NRESULTS 105 /*%< Number of results */
+#define DNS_R_NRESULTS 107 /*%< Number of results */
/*
* DNS wire format rcodes.
diff --git a/contrib/bind9/lib/dns/include/dns/types.h b/contrib/bind9/lib/dns/include/dns/types.h
index 525dd8d48921..10ce229ac970 100644
--- a/contrib/bind9/lib/dns/include/dns/types.h
+++ b/contrib/bind9/lib/dns/include/dns/types.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: types.h,v 1.130.50.3.12.2 2009/12/31 20:29:21 each Exp $ */
+/* $Id: types.h,v 1.130.50.5 2009/12/30 08:34:30 jinmei Exp $ */
#ifndef DNS_TYPES_H
#define DNS_TYPES_H 1
diff --git a/contrib/bind9/lib/dns/include/dns/validator.h b/contrib/bind9/lib/dns/include/dns/validator.h
index 2555214b14cf..1da4e0c4c390 100644
--- a/contrib/bind9/lib/dns/include/dns/validator.h
+++ b/contrib/bind9/lib/dns/include/dns/validator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.h,v 1.41.48.3 2009/01/18 23:25:17 marka Exp $ */
+/* $Id: validator.h,v 1.41.48.3.22.2 2010/02/25 10:57:12 tbox Exp $ */
#ifndef DNS_VALIDATOR_H
#define DNS_VALIDATOR_H 1
@@ -159,6 +159,8 @@ struct dns_validator {
isc_boolean_t mustbesecure;
unsigned int dlvlabels;
unsigned int depth;
+ unsigned int authcount;
+ unsigned int authfail;
};
/*%
diff --git a/contrib/bind9/lib/dns/include/dns/zone.h b/contrib/bind9/lib/dns/include/dns/zone.h
index e2859ae5bbb5..746b43cdd6f6 100644
--- a/contrib/bind9/lib/dns/include/dns/zone.h
+++ b/contrib/bind9/lib/dns/include/dns/zone.h
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.h,v 1.160.50.4 2009/01/29 22:40:35 jinmei Exp $ */
+/* $Id: zone.h,v 1.160.50.6 2009/10/05 21:57:00 each Exp $ */
#ifndef DNS_ZONE_H
#define DNS_ZONE_H 1
@@ -149,13 +149,24 @@ dns_zone_getclass(dns_zone_t *zone);
*\li 'zone' to be a valid zone.
*/
+isc_result_t
+dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp);
+
isc_uint32_t
dns_zone_getserial(dns_zone_t *zone);
/*%<
- * Returns the current serial number of the zone.
+ * Returns the current serial number of the zone. On success, the SOA
+ * serial of the zone will be copied into '*serialp'.
+ * dns_zone_getserial() cannot catch failure cases and is deprecated by
+ * dns_zone_getserial2().
*
* Requires:
*\li 'zone' to be a valid zone.
+ *\li 'serialp' to be non NULL
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #DNS_R_NOTLOADED zone DB is not loaded
*/
void
@@ -256,6 +267,9 @@ dns_zone_load(dns_zone_t *zone);
isc_result_t
dns_zone_loadnew(dns_zone_t *zone);
+
+isc_result_t
+dns_zone_loadandthaw(dns_zone_t *zone);
/*%<
* Cause the database to be loaded from its backing store.
* Confirm that the minimum requirements for the zone type are
@@ -264,6 +278,8 @@ dns_zone_loadnew(dns_zone_t *zone);
* dns_zone_loadnew() only loads zones that are not yet loaded.
* dns_zone_load() also loads zones that are already loaded and
* and whose master file has changed since the last load.
+ * dns_zone_loadandthaw() is similar to dns_zone_load() but will
+ * also re-enable DNS UPDATEs when the load completes.
*
* Require:
*\li 'zone' to be a valid zone.
diff --git a/contrib/bind9/lib/dns/include/dst/dst.h b/contrib/bind9/lib/dns/include/dst/dst.h
index 702ad719d21b..de262bdafb1a 100644
--- a/contrib/bind9/lib/dns/include/dst/dst.h
+++ b/contrib/bind9/lib/dns/include/dst/dst.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dst.h,v 1.12 2008/09/24 02:46:23 marka Exp $ */
+/* $Id: dst.h,v 1.12.50.2 2010/01/15 23:47:34 tbox Exp $ */
#ifndef DST_DST_H
#define DST_DST_H 1
@@ -53,6 +53,8 @@ typedef struct dst_context dst_context_t;
#define DST_ALG_RSASHA1 5
#define DST_ALG_NSEC3DSA 6
#define DST_ALG_NSEC3RSASHA1 7
+#define DST_ALG_RSASHA256 8
+#define DST_ALG_RSASHA512 10
#define DST_ALG_HMACMD5 157
#define DST_ALG_GSSAPI 160
#define DST_ALG_HMACSHA1 161 /* XXXMPA */
diff --git a/contrib/bind9/lib/dns/journal.c b/contrib/bind9/lib/dns/journal.c
index 8c21f1ece34b..638e64755b54 100644
--- a/contrib/bind9/lib/dns/journal.c
+++ b/contrib/bind9/lib/dns/journal.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: journal.c,v 1.103.48.2 2009/01/18 23:47:37 tbox Exp $ */
+/* $Id: journal.c,v 1.103.48.6 2009/11/04 23:47:25 tbox Exp $ */
#include <config.h>
@@ -1218,7 +1218,9 @@ dns_journal_destroy(dns_journal_t **journalp) {
/* XXX Share code with incoming IXFR? */
static isc_result_t
-roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) {
+roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options,
+ isc_uint32_t resign)
+{
isc_buffer_t source; /* Transaction data from disk */
isc_buffer_t target; /* Ditto after _fromwire check */
isc_uint32_t db_serial; /* Database SOA serial */
@@ -1235,6 +1237,7 @@ roll_forward(dns_journal_t *j, dns_db_t *db, unsigned int options) {
REQUIRE(DNS_DB_VALID(db));
dns_diff_init(j->mctx, &diff);
+ diff.resign = resign;
/*
* Set up empty initial buffers for unchecked and checked
@@ -1353,6 +1356,14 @@ isc_result_t
dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db,
unsigned int options, const char *filename)
{
+ REQUIRE((options & DNS_JOURNALOPT_RESIGN) == 0);
+ return (dns_journal_rollforward2(mctx, db, options, 0, filename));
+}
+
+isc_result_t
+dns_journal_rollforward2(isc_mem_t *mctx, dns_db_t *db, unsigned int options,
+ isc_uint32_t resign, const char *filename)
+{
dns_journal_t *j;
isc_result_t result;
@@ -1371,7 +1382,7 @@ dns_journal_rollforward(isc_mem_t *mctx, dns_db_t *db,
if (JOURNAL_EMPTY(&j->header))
result = DNS_R_UPTODATE;
else
- result = roll_forward(j, db, options);
+ result = roll_forward(j, db, options, resign);
dns_journal_destroy(&j);
@@ -1850,18 +1861,11 @@ dns_diff_subtract(dns_diff_t diff[2], dns_diff_t *r) {
return (result);
}
-/*
- * Compare the databases 'dba' and 'dbb' and generate a journal
- * entry containing the changes to make 'dba' from 'dbb' (note
- * the order). This journal entry will consist of a single,
- * possibly very large transaction.
- */
-
-isc_result_t
-dns_db_diff(isc_mem_t *mctx,
- dns_db_t *dba, dns_dbversion_t *dbvera,
- dns_db_t *dbb, dns_dbversion_t *dbverb,
- const char *journal_filename)
+static isc_result_t
+diff_namespace(isc_mem_t *mctx,
+ dns_db_t *dba, dns_dbversion_t *dbvera,
+ dns_db_t *dbb, dns_dbversion_t *dbverb,
+ unsigned int options, dns_diff_t *resultdiff)
{
dns_db_t *db[2];
dns_dbversion_t *ver[2];
@@ -1869,30 +1873,24 @@ dns_db_diff(isc_mem_t *mctx,
isc_boolean_t have[2] = { ISC_FALSE, ISC_FALSE };
dns_fixedname_t fixname[2];
isc_result_t result, itresult[2];
- dns_diff_t diff[2], resultdiff;
+ dns_diff_t diff[2];
int i, t;
- dns_journal_t *journal = NULL;
db[0] = dba, db[1] = dbb;
ver[0] = dbvera, ver[1] = dbverb;
dns_diff_init(mctx, &diff[0]);
dns_diff_init(mctx, &diff[1]);
- dns_diff_init(mctx, &resultdiff);
dns_fixedname_init(&fixname[0]);
dns_fixedname_init(&fixname[1]);
- result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal);
+ result = dns_db_createiterator(db[0], options, &dbit[0]);
if (result != ISC_R_SUCCESS)
return (result);
-
- result = dns_db_createiterator(db[0], 0, &dbit[0]);
- if (result != ISC_R_SUCCESS)
- goto cleanup_journal;
- result = dns_db_createiterator(db[1], 0, &dbit[1]);
+ result = dns_db_createiterator(db[1], options, &dbit[1]);
if (result != ISC_R_SUCCESS)
- goto cleanup_interator0;
+ goto cleanup_iterator;
itresult[0] = dns_dbiterator_first(dbit[0]);
itresult[1] = dns_dbiterator_first(dbit[1]);
@@ -1919,7 +1917,7 @@ dns_db_diff(isc_mem_t *mctx,
for (i = 0; i < 2; i++) {
if (! have[!i]) {
- ISC_LIST_APPENDLIST(resultdiff.tuples,
+ ISC_LIST_APPENDLIST(resultdiff->tuples,
diff[i].tuples, link);
INSIST(ISC_LIST_EMPTY(diff[i].tuples));
have[i] = ISC_FALSE;
@@ -1930,21 +1928,21 @@ dns_db_diff(isc_mem_t *mctx,
t = dns_name_compare(dns_fixedname_name(&fixname[0]),
dns_fixedname_name(&fixname[1]));
if (t < 0) {
- ISC_LIST_APPENDLIST(resultdiff.tuples,
+ ISC_LIST_APPENDLIST(resultdiff->tuples,
diff[0].tuples, link);
INSIST(ISC_LIST_EMPTY(diff[0].tuples));
have[0] = ISC_FALSE;
continue;
}
if (t > 0) {
- ISC_LIST_APPENDLIST(resultdiff.tuples,
+ ISC_LIST_APPENDLIST(resultdiff->tuples,
diff[1].tuples, link);
INSIST(ISC_LIST_EMPTY(diff[1].tuples));
have[1] = ISC_FALSE;
continue;
}
INSIST(t == 0);
- CHECK(dns_diff_subtract(diff, &resultdiff));
+ CHECK(dns_diff_subtract(diff, resultdiff));
INSIST(ISC_LIST_EMPTY(diff[0].tuples));
INSIST(ISC_LIST_EMPTY(diff[1].tuples));
have[0] = have[1] = ISC_FALSE;
@@ -1955,20 +1953,49 @@ dns_db_diff(isc_mem_t *mctx,
if (itresult[1] != ISC_R_NOMORE)
FAIL(itresult[1]);
+ INSIST(ISC_LIST_EMPTY(diff[0].tuples));
+ INSIST(ISC_LIST_EMPTY(diff[1].tuples));
+
+ failure:
+ dns_dbiterator_destroy(&dbit[1]);
+ cleanup_iterator:
+ dns_dbiterator_destroy(&dbit[0]);
+ return (result);
+}
+
+/*
+ * Compare the databases 'dba' and 'dbb' and generate a journal
+ * entry containing the changes to make 'dba' from 'dbb' (note
+ * the order). This journal entry will consist of a single,
+ * possibly very large transaction.
+ */
+isc_result_t
+dns_db_diff(isc_mem_t *mctx,
+ dns_db_t *dba, dns_dbversion_t *dbvera,
+ dns_db_t *dbb, dns_dbversion_t *dbverb,
+ const char *journal_filename)
+{
+ isc_result_t result;
+ dns_journal_t *journal = NULL;
+ dns_diff_t resultdiff;
+
+ result = dns_journal_open(mctx, journal_filename, ISC_TRUE, &journal);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_diff_init(mctx, &resultdiff);
+
+ CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb,
+ DNS_DB_NONSEC3, &resultdiff));
+ CHECK(diff_namespace(mctx, dba, dbvera, dbb, dbverb,
+ DNS_DB_NSEC3ONLY, &resultdiff));
if (ISC_LIST_EMPTY(resultdiff.tuples)) {
isc_log_write(JOURNAL_DEBUG_LOGARGS(3), "no changes");
} else {
CHECK(dns_journal_write_transaction(journal, &resultdiff));
}
- INSIST(ISC_LIST_EMPTY(diff[0].tuples));
- INSIST(ISC_LIST_EMPTY(diff[1].tuples));
-
failure:
dns_diff_clear(&resultdiff);
- dns_dbiterator_destroy(&dbit[1]);
- cleanup_interator0:
- dns_dbiterator_destroy(&dbit[0]);
- cleanup_journal:
dns_journal_destroy(&journal);
return (result);
}
diff --git a/contrib/bind9/lib/dns/masterdump.c b/contrib/bind9/lib/dns/masterdump.c
index 1dbb1e615e8b..314112ce5f1b 100644
--- a/contrib/bind9/lib/dns/masterdump.c
+++ b/contrib/bind9/lib/dns/masterdump.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: masterdump.c,v 1.94.50.2.12.1 2009/11/18 23:58:04 marka Exp $ */
+/* $Id: masterdump.c,v 1.94.50.3 2009/11/18 00:15:37 marka Exp $ */
/*! \file */
diff --git a/contrib/bind9/lib/dns/message.c b/contrib/bind9/lib/dns/message.c
index b541635abf03..2e34120f3b9b 100644
--- a/contrib/bind9/lib/dns/message.c
+++ b/contrib/bind9/lib/dns/message.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: message.c,v 1.245.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: message.c,v 1.245.50.3 2009/11/24 03:25:53 marka Exp $ */
/*! \file */
@@ -1888,6 +1888,8 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
msg->counts[sectionid] += total;
return (result);
}
+ if (result == ISC_R_NOSPACE)
+ msg->flags |= DNS_MESSAGEFLAG_TC;
if (result != ISC_R_SUCCESS) {
INSIST(st.used < 65536);
dns_compress_rollback(msg->cctx,
diff --git a/contrib/bind9/lib/dns/ncache.c b/contrib/bind9/lib/dns/ncache.c
index af0450b525dc..733d138dda24 100644
--- a/contrib/bind9/lib/dns/ncache.c
+++ b/contrib/bind9/lib/dns/ncache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010 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,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ncache.c,v 1.43 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: ncache.c,v 1.43.334.2 2010/02/25 10:57:11 tbox Exp $ */
/*! \file */
@@ -519,6 +519,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/nsec3.c b/contrib/bind9/lib/dns/nsec3.c
index f9b8cad21a70..ea6546d9e60f 100644
--- a/contrib/bind9/lib/dns/nsec3.c
+++ b/contrib/bind9/lib/dns/nsec3.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.c,v 1.6.12.2 2009/06/04 02:56:14 tbox Exp $ */
+/* $Id: nsec3.c,v 1.6.12.4 2009/11/03 23:47:46 tbox Exp $ */
#include <config.h>
@@ -87,6 +87,8 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
unsigned int i, window;
int octet;
isc_boolean_t found;
+ isc_boolean_t found_ns;
+ isc_boolean_t need_rrsig;
unsigned char *nsec_bits, *bm;
unsigned int max_type;
@@ -140,7 +142,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
result = dns_db_allrdatasets(db, node, version, 0, &rdsiter);
if (result != ISC_R_SUCCESS)
return (result);
- found = ISC_FALSE;
+ found = found_ns = need_rrsig = ISC_FALSE;
for (result = dns_rdatasetiter_first(rdsiter);
result == ISC_R_SUCCESS;
result = dns_rdatasetiter_next(rdsiter))
@@ -152,13 +154,26 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
if (rdataset.type > max_type)
max_type = rdataset.type;
set_bit(bm, rdataset.type, 1);
- /* Don't set RRSIG for insecure delegation. */
- if (rdataset.type != dns_rdatatype_ns)
+ /*
+ * Work out if we need to set the RRSIG bit for
+ * this node. We set the RRSIG bit if either of
+ * the following conditions are met:
+ * 1) We have a SOA or DS then we need to set
+ * the RRSIG bit as both always will be signed.
+ * 2) We set the RRSIG bit if we don't have
+ * a NS record but do have other data.
+ */
+ if (rdataset.type == dns_rdatatype_soa ||
+ rdataset.type == dns_rdatatype_ds)
+ need_rrsig = ISC_TRUE;
+ else if (rdataset.type == dns_rdatatype_ns)
+ found_ns = ISC_TRUE;
+ else
found = ISC_TRUE;
}
dns_rdataset_disassociate(&rdataset);
}
- if (found) {
+ if ((found && !found_ns) || need_rrsig) {
if (dns_rdatatype_rrsig > max_type)
max_type = dns_rdatatype_rrsig;
set_bit(bm, dns_rdatatype_rrsig, 1);
diff --git a/contrib/bind9/lib/dns/opensslrsa_link.c b/contrib/bind9/lib/dns/opensslrsa_link.c
index d557c43db258..95095d1186b7 100644
--- a/contrib/bind9/lib/dns/opensslrsa_link.c
+++ b/contrib/bind9/lib/dns/opensslrsa_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -17,21 +17,23 @@
/*
* Principal Author: Brian Wellington
- * $Id: opensslrsa_link.c,v 1.20.50.3 2009/01/18 23:25:16 marka Exp $
+ * $Id: opensslrsa_link.c,v 1.20.50.8 2010/01/22 02:36:49 marka Exp $
*/
#ifdef OPENSSL
+#include <config.h>
+
#ifndef USE_EVP
+#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA512)
+#define USE_EVP 0
+#else
#define USE_EVP 1
#endif
-#if USE_EVP
-#define USE_EVP_RSA 1
#endif
-#include <config.h>
-
#include <isc/entropy.h>
#include <isc/md5.h>
#include <isc/sha1.h>
+#include <isc/sha2.h>
#include <isc/mem.h>
#include <isc/string.h>
#include <isc/util.h>
@@ -112,23 +114,42 @@ static isc_result_t
opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
#if USE_EVP
EVP_MD_CTX *evp_md_ctx;
- const EVP_MD *type;
+ const EVP_MD *type = NULL;
#endif
UNUSED(key);
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
evp_md_ctx = EVP_MD_CTX_create();
if (evp_md_ctx == NULL)
return (ISC_R_NOMEMORY);
- if (dctx->key->key_alg == DST_ALG_RSAMD5)
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
type = EVP_md5(); /* MD5 + RSA */
- else
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
type = EVP_sha1(); /* SHA1 + RSA */
+ break;
+#ifdef HAVE_EVP_SHA256
+ case DST_ALG_RSASHA256:
+ type = EVP_sha256(); /* SHA256 + RSA */
+ break;
+#endif
+#ifdef HAVE_EVP_SHA512
+ case DST_ALG_RSASHA512:
+ type = EVP_sha512();
+ break;
+#endif
+ default:
+ INSIST(0);
+ }
if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
EVP_MD_CTX_destroy(evp_md_ctx);
@@ -136,22 +157,56 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
}
dctx->ctxdata.evp_md_ctx = evp_md_ctx;
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx;
- md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
- if (md5ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_md5_init(md5ctx);
- dctx->ctxdata.md5ctx = md5ctx;
- } else {
- isc_sha1_t *sha1ctx;
+ md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
+ if (md5ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_md5_init(md5ctx);
+ dctx->ctxdata.md5ctx = md5ctx;
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx;
- sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
- if (sha1ctx == NULL)
- return (ISC_R_NOMEMORY);
- isc_sha1_init(sha1ctx);
- dctx->ctxdata.sha1ctx = sha1ctx;
+ sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
+ if (sha1ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_sha1_init(sha1ctx);
+ dctx->ctxdata.sha1ctx = sha1ctx;
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx;
+
+ sha256ctx = isc_mem_get(dctx->mctx,
+ sizeof(isc_sha256_t));
+ if (sha256ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_sha256_init(sha256ctx);
+ dctx->ctxdata.sha256ctx = sha256ctx;
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx;
+
+ sha512ctx = isc_mem_get(dctx->mctx,
+ sizeof(isc_sha512_t));
+ if (sha512ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ isc_sha512_init(sha512ctx);
+ dctx->ctxdata.sha512ctx = sha512ctx;
+ }
+ break;
+ default:
+ INSIST(0);
}
#endif
@@ -166,7 +221,9 @@ opensslrsa_destroyctx(dst_context_t *dctx) {
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
if (evp_md_ctx != NULL) {
@@ -174,22 +231,58 @@ opensslrsa_destroyctx(dst_context_t *dctx) {
dctx->ctxdata.evp_md_ctx = NULL;
}
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
- if (md5ctx != NULL) {
- isc_md5_invalidate(md5ctx);
- isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
- dctx->ctxdata.md5ctx = NULL;
+ if (md5ctx != NULL) {
+ isc_md5_invalidate(md5ctx);
+ isc_mem_put(dctx->mctx, md5ctx,
+ sizeof(isc_md5_t));
+ dctx->ctxdata.md5ctx = NULL;
+ }
}
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- if (sha1ctx != NULL) {
- isc_sha1_invalidate(sha1ctx);
- isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
- dctx->ctxdata.sha1ctx = NULL;
+ if (sha1ctx != NULL) {
+ isc_sha1_invalidate(sha1ctx);
+ isc_mem_put(dctx->mctx, sha1ctx,
+ sizeof(isc_sha1_t));
+ dctx->ctxdata.sha1ctx = NULL;
+ }
}
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ if (sha256ctx != NULL) {
+ isc_sha256_invalidate(sha256ctx);
+ isc_mem_put(dctx->mctx, sha256ctx,
+ sizeof(isc_sha256_t));
+ dctx->ctxdata.sha256ctx = NULL;
+ }
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ if (sha512ctx != NULL) {
+ isc_sha512_invalidate(sha512ctx);
+ isc_mem_put(dctx->mctx, sha512ctx,
+ sizeof(isc_sha512_t));
+ dctx->ctxdata.sha512ctx = NULL;
+ }
+ }
+ break;
+ default:
+ INSIST(0);
}
#endif
}
@@ -202,24 +295,67 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
return (ISC_R_FAILURE);
}
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
- isc_md5_update(md5ctx, data->base, data->length);
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- isc_sha1_update(sha1ctx, data->base, data->length);
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+
+ isc_md5_update(md5ctx, data->base, data->length);
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+
+ isc_sha1_update(sha1ctx, data->base, data->length);
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ isc_sha256_update(sha256ctx, data->base, data->length);
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ isc_sha512_update(sha512ctx, data->base, data->length);
+ }
+ break;
+ default:
+ INSIST(0);
}
#endif
return (ISC_R_SUCCESS);
}
+#if ! USE_EVP && OPENSSL_VERSION_NUMBER < 0x00908000L
+/*
+ * Digest prefixes from RFC 5702.
+ */
+static unsigned char sha256_prefix[] =
+ { 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20};
+static unsigned char sha512_prefix[] =
+ { 0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48,
+ 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40};
+#define PREFIXLEN sizeof(sha512_prefix)
+#else
+#define PREFIXLEN 0
+#endif
+
static isc_result_t
opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
dst_key_t *key = dctx->key;
@@ -230,20 +366,26 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
EVP_PKEY *pkey = key->keydata.pkey;
#else
RSA *rsa = key->keydata.rsa;
- /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
- unsigned char digest[ISC_SHA1_DIGESTLENGTH];
- int status;
- int type;
- unsigned int digestlen;
+ /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
+ unsigned char digest[PREFIXLEN + ISC_SHA512_DIGESTLENGTH];
+ int status = 0;
+ int type = 0;
+ unsigned int digestlen = 0;
char *message;
unsigned long err;
const char* file;
int line;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ unsigned int prefixlen = 0;
+ const unsigned char *prefix = NULL;
+#endif
#endif
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
isc_buffer_availableregion(sig, &r);
@@ -258,19 +400,92 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
if (r.length < (unsigned int) RSA_size(rsa))
return (ISC_R_NOSPACE);
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
- isc_md5_final(md5ctx, digest);
- type = NID_md5;
- digestlen = ISC_MD5_DIGESTLENGTH;
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- isc_sha1_final(sha1ctx, digest);
- type = NID_sha1;
- digestlen = ISC_SHA1_DIGESTLENGTH;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+
+ isc_md5_final(md5ctx, digest);
+ type = NID_md5;
+ digestlen = ISC_MD5_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+
+ isc_sha1_final(sha1ctx, digest);
+ type = NID_sha1;
+ digestlen = ISC_SHA1_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ isc_sha256_final(digest, sha256ctx);
+ digestlen = ISC_SHA256_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha256_prefix;
+ prefixlen = sizeof(sha256_prefix);
+#else
+ type = NID_sha256;
+#endif
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ isc_sha512_final(digest, sha512ctx);
+ digestlen = ISC_SHA512_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha512_prefix;
+ prefixlen = sizeof(sha512_prefix);
+#else
+ type = NID_sha512;
+#endif
+ }
+ break;
+ default:
+ INSIST(0);
}
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ INSIST(type != 0);
+ status = RSA_sign(type, digest, digestlen, r.base,
+ &siglen, rsa);
+ break;
+
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
+ INSIST(prefix != NULL);
+ INSIST(prefixlen != 0);
+ INSIST(prefixlen + digestlen <= sizeof(digest));
+
+ memmove(digest + prefixlen, digest, digestlen);
+ memcpy(digest, prefix, prefixlen);
+ status = RSA_private_encrypt(digestlen + prefixlen,
+ digest, r.base, rsa,
+ RSA_PKCS1_PADDING);
+ if (status < 0)
+ status = 0;
+ else
+ siglen = status;
+ break;
+
+ default:
+ INSIST(0);
+ }
+#else
+ INSIST(type != 0);
status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
+#endif
if (status == 0) {
err = ERR_peek_error_line(&file, &line);
if (err != 0U) {
@@ -293,37 +508,129 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
EVP_PKEY *pkey = key->keydata.pkey;
#else
- /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
- unsigned char digest[ISC_SHA1_DIGESTLENGTH];
- int type;
- unsigned int digestlen;
+ /* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
+ unsigned char digest[ISC_SHA512_DIGESTLENGTH];
+ int type = 0;
+ unsigned int digestlen = 0;
RSA *rsa = key->keydata.rsa;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ unsigned int prefixlen = 0;
+ const unsigned char *prefix = NULL;
+#endif
#endif
REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
dctx->key->key_alg == DST_ALG_RSASHA1 ||
- dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
+ dctx->key->key_alg == DST_ALG_NSEC3RSASHA1 ||
+ dctx->key->key_alg == DST_ALG_RSASHA256 ||
+ dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
#else
- if (dctx->key->key_alg == DST_ALG_RSAMD5) {
- isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
- isc_md5_final(md5ctx, digest);
- type = NID_md5;
- digestlen = ISC_MD5_DIGESTLENGTH;
- } else {
- isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
- isc_sha1_final(sha1ctx, digest);
- type = NID_sha1;
- digestlen = ISC_SHA1_DIGESTLENGTH;
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ {
+ isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
+
+ isc_md5_final(md5ctx, digest);
+ type = NID_md5;
+ digestlen = ISC_MD5_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ {
+ isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
+
+ isc_sha1_final(sha1ctx, digest);
+ type = NID_sha1;
+ digestlen = ISC_SHA1_DIGESTLENGTH;
+ }
+ break;
+ case DST_ALG_RSASHA256:
+ {
+ isc_sha256_t *sha256ctx = dctx->ctxdata.sha256ctx;
+
+ isc_sha256_final(digest, sha256ctx);
+ digestlen = ISC_SHA256_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha256_prefix;
+ prefixlen = sizeof(sha256_prefix);
+#else
+ type = NID_sha256;
+#endif
+ }
+ break;
+ case DST_ALG_RSASHA512:
+ {
+ isc_sha512_t *sha512ctx = dctx->ctxdata.sha512ctx;
+
+ isc_sha512_final(digest, sha512ctx);
+ digestlen = ISC_SHA512_DIGESTLENGTH;
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ prefix = sha512_prefix;
+ prefixlen = sizeof(sha512_prefix);
+#else
+ type = NID_sha512;
+#endif
+ }
+ break;
+ default:
+ INSIST(0);
}
- if (sig->length < (unsigned int) RSA_size(rsa))
+ if (sig->length != (unsigned int) RSA_size(rsa))
return (DST_R_VERIFYFAILURE);
+#if OPENSSL_VERSION_NUMBER < 0x00908000L
+ switch (dctx->key->key_alg) {
+ case DST_ALG_RSAMD5:
+ case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ INSIST(type != 0);
+ status = RSA_verify(type, digest, digestlen, sig->base,
+ RSA_size(rsa), rsa);
+ break;
+
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
+ {
+ /*
+ * 1024 is big enough for all valid RSA bit sizes
+ * for use with DNSSEC.
+ */
+ unsigned char original[PREFIXLEN + 1024];
+
+ INSIST(prefix != NULL);
+ INSIST(prefixlen != 0U);
+
+ if (RSA_size(rsa) > (int)sizeof(original))
+ return (DST_R_VERIFYFAILURE);
+
+ status = RSA_public_decrypt(sig->length, sig->base,
+ original, rsa,
+ RSA_PKCS1_PADDING);
+ if (status <= 0)
+ return (DST_R_VERIFYFAILURE);
+ if (status != (int)(prefixlen + digestlen))
+ return (DST_R_VERIFYFAILURE);
+ if (memcmp(original, prefix, prefixlen))
+ return (DST_R_VERIFYFAILURE);
+ if (memcmp(original + prefixlen, digest, digestlen))
+ return (DST_R_VERIFYFAILURE);
+ status = 1;
+ }
+ break;
+
+ default:
+ INSIST(0);
+ }
+#else
+ INSIST(type != 0);
status = RSA_verify(type, digest, digestlen, sig->base,
- RSA_size(rsa), rsa);
+ RSA_size(rsa), rsa);
+#endif
#endif
if (status != 1)
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
@@ -552,19 +859,20 @@ opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
if (r.length < 1)
DST_RET(ISC_R_NOSPACE);
isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
+ isc_region_consume(&r, 1);
} else {
if (r.length < 3)
DST_RET(ISC_R_NOSPACE);
isc_buffer_putuint8(data, 0);
isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
+ isc_region_consume(&r, 3);
}
if (r.length < e_bytes + mod_bytes)
- return (ISC_R_NOSPACE);
- isc_buffer_availableregion(data, &r);
+ DST_RET(ISC_R_NOSPACE);
BN_bn2bin(rsa->e, r.base);
- r.base += e_bytes;
+ isc_region_consume(&r, e_bytes);
BN_bn2bin(rsa->n, r.base);
isc_buffer_add(data, e_bytes + mod_bytes);
@@ -805,8 +1113,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
DST_RET(DST_R_NOENGINE);
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL) {
- ERR_print_errors_fp(stderr);
- DST_RET(ISC_R_FAILURE);
+ /* ERR_print_errors_fp(stderr); */
+ DST_RET(ISC_R_NOTFOUND);
}
key->engine = isc_mem_strdup(key->mctx, name);
if (key->engine == NULL)
@@ -924,7 +1232,7 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
DST_RET(DST_R_NOENGINE);
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL)
- DST_RET(ISC_R_NOMEMORY);
+ DST_RET(ISC_R_NOTFOUND);
key->engine = isc_mem_strdup(key->mctx, label);
if (key->engine == NULL)
DST_RET(ISC_R_NOMEMORY);
@@ -969,10 +1277,26 @@ static dst_func_t opensslrsa_functions = {
};
isc_result_t
-dst__opensslrsa_init(dst_func_t **funcp) {
+dst__opensslrsa_init(dst_func_t **funcp, unsigned char algorithm) {
REQUIRE(funcp != NULL);
- if (*funcp == NULL)
- *funcp = &opensslrsa_functions;
+
+ if (*funcp == NULL) {
+ switch (algorithm) {
+ case DST_ALG_RSASHA256:
+#if defined(HAVE_EVP_SHA256) || !USE_EVP
+ *funcp = &opensslrsa_functions;
+#endif
+ break;
+ case DST_ALG_RSASHA512:
+#if defined(HAVE_EVP_SHA512) || !USE_EVP
+ *funcp = &opensslrsa_functions;
+#endif
+ break;
+ default:
+ *funcp = &opensslrsa_functions;
+ break;
+ }
+ }
return (ISC_R_SUCCESS);
}
diff --git a/contrib/bind9/lib/dns/rbt.c b/contrib/bind9/lib/dns/rbt.c
index ff8b3a36e379..62a9e2b03bb7 100644
--- a/contrib/bind9/lib/dns/rbt.c
+++ b/contrib/bind9/lib/dns/rbt.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbt.c,v 1.142.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: rbt.c,v 1.142.50.3 2009/10/20 05:06:04 marka Exp $ */
/*! \file */
@@ -85,9 +85,9 @@ struct dns_rbt {
#define HASHVAL(node) ((node)->hashval)
#define COLOR(node) ((node)->color)
#define NAMELEN(node) ((node)->namelen)
+#define OLDNAMELEN(node) ((node)->oldnamelen)
#define OFFSETLEN(node) ((node)->offsetlen)
#define ATTRS(node) ((node)->attributes)
-#define PADBYTES(node) ((node)->padbytes)
#define IS_ROOT(node) ISC_TF((node)->is_root == 1)
#define FINDCALLBACK(node) ISC_TF((node)->find_callback == 1)
@@ -100,13 +100,23 @@ struct dns_rbt {
#define LOCKNUM(node) ((node)->locknum)
/*%
- * The variable length stuff stored after the node.
+ * The variable length stuff stored after the node has the following
+ * structure.
+ *
+ * <name_data>{1..255}<oldoffsetlen>{1}<offsets>{1..128}
+ *
+ * <name_data> contains the name of the node when it was created.
+ * <oldoffsetlen> contains the length of <offsets> when the node was created.
+ * <offsets> contains the offets into name for each label when the node was
+ * created.
*/
+
#define NAME(node) ((unsigned char *)((node) + 1))
-#define OFFSETS(node) (NAME(node) + NAMELEN(node))
+#define OFFSETS(node) (NAME(node) + OLDNAMELEN(node) + 1)
+#define OLDOFFSETLEN(node) (OFFSETS(node)[-1])
#define NODE_SIZE(node) (sizeof(*node) + \
- NAMELEN(node) + OFFSETLEN(node) + PADBYTES(node))
+ OLDNAMELEN(node) + OLDOFFSETLEN(node) + 1)
/*%
* Color management.
@@ -553,11 +563,6 @@ dns_rbt_addnode(dns_rbt_t *rbt, dns_name_t *name, dns_rbtnode_t **nodep) {
NAMELEN(current) = prefix->length;
OFFSETLEN(current) = prefix->labels;
- memcpy(OFFSETS(current), prefix->offsets,
- prefix->labels);
- PADBYTES(current) +=
- (current_name.length - prefix->length) +
- (current_name.labels - prefix->labels);
/*
* Set up the new root of the next level.
@@ -1423,7 +1428,7 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
* Allocate space for the node structure, the name, and the offsets.
*/
node = (dns_rbtnode_t *)isc_mem_get(mctx, sizeof(*node) +
- region.length + labels);
+ region.length + labels + 1);
if (node == NULL)
return (ISC_R_NOMEMORY);
@@ -1460,10 +1465,12 @@ create_node(isc_mem_t *mctx, dns_name_t *name, dns_rbtnode_t **nodep) {
* The offsets table could be made smaller by eliminating the
* first offset, which is always 0. This requires changes to
* lib/dns/name.c.
+ *
+ * Note: OLDOFFSETLEN *must* be assigned *after* OLDNAMELEN is assigned
+ * as it uses OLDNAMELEN.
*/
- NAMELEN(node) = region.length;
- PADBYTES(node) = 0;
- OFFSETLEN(node) = labels;
+ OLDNAMELEN(node) = NAMELEN(node) = region.length;
+ OLDOFFSETLEN(node) = OFFSETLEN(node) = labels;
ATTRS(node) = name->attributes;
memcpy(NAME(node), region.base, region.length);
diff --git a/contrib/bind9/lib/dns/rbtdb.c b/contrib/bind9/lib/dns/rbtdb.c
index d5b5b5c8194f..df3a5f47e206 100644
--- a/contrib/bind9/lib/dns/rbtdb.c
+++ b/contrib/bind9/lib/dns/rbtdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.270.12.6.10.2 2009/12/31 21:44:36 each Exp $ */
+/* $Id: rbtdb.c,v 1.270.12.16.8.3 2010/02/26 00:24:39 marka Exp $ */
/*! \file */
@@ -258,21 +258,8 @@ typedef struct rdatasetheader {
dns_rbtnode_t *node;
isc_stdtime_t last_used;
- ISC_LINK(struct rdatasetheader) lru_link;
- /*%<
- * Used for LRU-based cache management. We should probably make
- * these cache-DB specific. We might also make it a pointer and
- * ensure only the top header has a valid link to save memory.
- * The linked-list is locked by the rbtdb->lrulock.
- */
+ ISC_LINK(struct rdatasetheader) link;
- /*
- * It's possible this should not be here anymore, but instead
- * referenced from the bucket's heap directly.
- */
-#if 0
- isc_heap_t *heap;
-#endif
unsigned int heap_index;
/*%<
* Used for TTL-based cache cleaning.
@@ -396,7 +383,7 @@ typedef struct rbtdb_version {
isc_uint8_t flags;
isc_uint16_t iterations;
isc_uint8_t salt_length;
- unsigned char salt[NSEC3_MAX_HASH_LENGTH];
+ unsigned char salt[DNS_NSEC3_SALTSIZE];
} rbtdb_version_t;
typedef ISC_LIST(rbtdb_version_t) rbtdb_versionlist_t;
@@ -534,6 +521,8 @@ static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
rdatasetheader_t *newheader);
static void prune_tree(isc_task_t *task, isc_event_t *event);
+static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
+static void rdataset_expire(dns_rdataset_t *rdataset);
static dns_rdatasetmethods_t rdataset_methods = {
rdataset_disassociate,
@@ -548,7 +537,9 @@ static dns_rdatasetmethods_t rdataset_methods = {
rdataset_getclosest,
rdataset_getadditional,
rdataset_setadditional,
- rdataset_putadditional
+ rdataset_putadditional,
+ rdataset_settrust,
+ rdataset_expire
};
static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
@@ -1227,7 +1218,7 @@ free_noqname(isc_mem_t *mctx, struct noqname **noqname) {
static inline void
init_rdataset(dns_rbtdb_t *rbtdb, rdatasetheader_t *h)
{
- ISC_LINK_INIT(h, lru_link);
+ ISC_LINK_INIT(h, link);
h->heap_index = 0;
#if TRACE_HEADER
@@ -1267,8 +1258,10 @@ free_rdataset(dns_rbtdb_t *rbtdb, isc_mem_t *mctx, rdatasetheader_t *rdataset)
}
idx = rdataset->node->locknum;
- if (ISC_LINK_LINKED(rdataset, lru_link))
- ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, lru_link);
+ if (ISC_LINK_LINKED(rdataset, link)) {
+ INSIST(IS_CACHE(rbtdb));
+ ISC_LIST_UNLINK(rbtdb->rdatasets[idx], rdataset, link);
+ }
if (rdataset->heap_index != 0)
isc_heap_delete(rbtdb->heaps[idx], rdataset->heap_index);
rdataset->heap_index = 0;
@@ -2075,8 +2068,6 @@ setnsec3parameters(dns_db_t *db, rbtdb_version_t *version,
continue;
#endif
- INSIST(nsec3param.salt_length <=
- sizeof(version->salt));
memcpy(version->salt, nsec3param.salt,
nsec3param.salt_length);
version->hash = nsec3param.hash;
@@ -2284,17 +2275,18 @@ closeversion(dns_db_t *db, dns_dbversion_t **versionp, isc_boolean_t commit) {
for (header = HEAD(resigned_list);
header != NULL;
header = HEAD(resigned_list)) {
- ISC_LIST_UNLINK(resigned_list, header, lru_link);
- if (rollback) {
- nodelock_t *lock;
- lock = &rbtdb->node_locks[header->node->locknum].lock;
- NODE_LOCK(lock, isc_rwlocktype_write);
+ nodelock_t *lock;
+
+ ISC_LIST_UNLINK(resigned_list, header, link);
+
+ lock = &rbtdb->node_locks[header->node->locknum].lock;
+ NODE_LOCK(lock, isc_rwlocktype_write);
+ if (rollback)
resign_insert(rbtdb, header->node->locknum, header);
- NODE_UNLOCK(lock, isc_rwlocktype_write);
- }
decrement_reference(rbtdb, header->node, least_serial,
isc_rwlocktype_write, isc_rwlocktype_none,
ISC_FALSE);
+ NODE_UNLOCK(lock, isc_rwlocktype_write);
}
if (!EMPTY(cleanup_list)) {
@@ -3524,11 +3516,17 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
/*
* The node may be a zone cut itself. If it might be one,
* make sure we check for it later.
+ *
+ * DS records live above the zone cut in ordinary zone so
+ * we want to ignore any referral.
+ *
+ * Stub zones don't have anything "above" the delgation so
+ * we always return a referral.
*/
if (node->find_callback &&
- (node != search.rbtdb->origin_node ||
- IS_STUB(search.rbtdb)) &&
- !dns_rdatatype_atparent(type))
+ ((node != search.rbtdb->origin_node &&
+ !dns_rdatatype_atparent(type)) ||
+ IS_STUB(search.rbtdb)))
maybe_zonecut = ISC_TRUE;
}
@@ -3546,8 +3544,8 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* We now go looking for rdata...
*/
- NODE_LOCK(&(search.rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ lock = &search.rbtdb->node_locks[node->locknum].lock;
+ NODE_LOCK(lock, isc_rwlocktype_read);
found = NULL;
foundsig = NULL;
@@ -3625,8 +3623,10 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* we are using behave as if it isn't here.
*/
if (header->type == dns_rdatatype_nsec3 &&
- !matchparams(header, &search))
+ !matchparams(header, &search)) {
+ NODE_UNLOCK(lock, isc_rwlocktype_read);
goto partial_match;
+ }
/*
* If we found a type we were looking for,
* remember it.
@@ -3705,7 +3705,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* we really have a partial match.
*/
if (!wild) {
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
goto partial_match;
}
@@ -3722,7 +3721,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
*
* Return the delegation.
*/
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
result = setup_delegation(&search, nodep, foundname,
rdataset, sigrdataset);
@@ -3744,7 +3742,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
goto node_exit;
}
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
result = find_closest_nsec(&search, nodep, foundname,
rdataset, sigrdataset,
@@ -3829,7 +3826,6 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
if (result == DNS_R_GLUE &&
(search.options & DNS_DBFIND_VALIDATEGLUE) != 0 &&
!valid_glue(&search, foundname, type, node)) {
- lock = &search.rbtdb->node_locks[node->locknum].lock;
NODE_UNLOCK(lock, isc_rwlocktype_read);
result = setup_delegation(&search, nodep, foundname,
rdataset, sigrdataset);
@@ -3861,8 +3857,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
foundname->attributes |= DNS_NAMEATTR_WILDCARD;
node_exit:
- NODE_UNLOCK(&(search.rbtdb->node_locks[node->locknum].lock),
- isc_rwlocktype_read);
+ NODE_UNLOCK(lock, isc_rwlocktype_read);
tree_exit:
RWUNLOCK(&search.rbtdb->tree_lock, isc_rwlocktype_read);
@@ -5408,8 +5403,10 @@ static isc_result_t
resign_insert(dns_rbtdb_t *rbtdb, int idx, rdatasetheader_t *newheader) {
isc_result_t result;
+ INSIST(!IS_CACHE(rbtdb));
INSIST(newheader->heap_index == 0);
- INSIST(!ISC_LINK_LINKED(newheader, lru_link));
+ INSIST(!ISC_LINK_LINKED(newheader, link));
+
result = isc_heap_insert(rbtdb->heaps[idx], newheader);
return (result);
}
@@ -5735,7 +5732,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) {
ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
- newheader, lru_link);
+ newheader, link);
/*
* XXXMLG We don't check the return value
* here. If it fails, we will not do TTL
@@ -5794,7 +5791,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
idx = newheader->node->locknum;
if (IS_CACHE(rbtdb)) {
ISC_LIST_PREPEND(rbtdb->rdatasets[idx],
- newheader, lru_link);
+ newheader, link);
isc_heap_insert(rbtdb->heaps[idx], newheader);
} else if (RESIGN(newheader)) {
resign_insert(rbtdb, idx, newheader);
@@ -6519,11 +6516,17 @@ static void
delete_callback(void *data, void *arg) {
dns_rbtdb_t *rbtdb = arg;
rdatasetheader_t *current, *next;
+ unsigned int locknum;
- for (current = data; current != NULL; current = next) {
+ current = data;
+ locknum = current->node->locknum;
+ NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
+ while (current != NULL) {
next = current->next;
free_rdataset(rbtdb, rbtdb->common.mctx, current);
+ current = next;
}
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
}
static isc_boolean_t
@@ -6642,8 +6645,8 @@ getnsec3parameters(dns_db_t *db, dns_dbversion_t *version, dns_hash_t *hash,
if (rbtversion->havensec3) {
if (hash != NULL)
*hash = rbtversion->hash;
- if (salt != NULL && salt_length != 0) {
- REQUIRE(*salt_length > rbtversion->salt_length);
+ if (salt != NULL && salt_length != NULL) {
+ REQUIRE(*salt_length >= rbtversion->salt_length);
memcpy(salt, rbtversion->salt, rbtversion->salt_length);
}
if (salt_length != NULL)
@@ -6707,27 +6710,35 @@ getsigningtime(dns_db_t *db, dns_rdataset_t *rdataset,
rdatasetheader_t *header = NULL, *this;
unsigned int i;
isc_result_t result = ISC_R_NOTFOUND;
+ unsigned int locknum;
REQUIRE(VALID_RBTDB(rbtdb));
RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
for (i = 0; i < rbtdb->node_lock_count; i++) {
+ NODE_LOCK(&rbtdb->node_locks[i].lock, isc_rwlocktype_read);
this = isc_heap_element(rbtdb->heaps[i], 1);
- if (this == NULL)
+ if (this == NULL) {
+ NODE_UNLOCK(&rbtdb->node_locks[i].lock,
+ isc_rwlocktype_read);
continue;
+ }
if (header == NULL)
header = this;
- else if (isc_serial_lt(this->resign, header->resign))
+ else if (isc_serial_lt(this->resign, header->resign)) {
+ locknum = header->node->locknum;
+ NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
+ isc_rwlocktype_read);
header = this;
+ } else
+ NODE_UNLOCK(&rbtdb->node_locks[i].lock,
+ isc_rwlocktype_read);
}
if (header == NULL)
goto unlock;
- NODE_LOCK(&rbtdb->node_locks[header->node->locknum].lock,
- isc_rwlocktype_read);
-
bind_rdataset(rbtdb, header->node, header, 0, rdataset);
if (foundname != NULL)
@@ -6761,7 +6772,7 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
header = rdataset->private3;
header--;
- RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_read);
+ RBTDB_LOCK(&rbtdb->lock, isc_rwlocktype_write);
NODE_LOCK(&rbtdb->node_locks[node->locknum].lock,
isc_rwlocktype_write);
/*
@@ -6771,11 +6782,11 @@ resigned(dns_db_t *db, dns_rdataset_t *rdataset, dns_dbversion_t *version)
new_reference(rbtdb, node);
isc_heap_delete(rbtdb->heaps[node->locknum], header->heap_index);
header->heap_index = 0;
- ISC_LIST_APPEND(rbtversion->resigned_list, header, lru_link);
+ ISC_LIST_APPEND(rbtversion->resigned_list, header, link);
NODE_UNLOCK(&rbtdb->node_locks[node->locknum].lock,
isc_rwlocktype_write);
- RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_read);
+ RBTDB_UNLOCK(&rbtdb->lock, isc_rwlocktype_write);
}
static dns_stats_t *
@@ -7400,6 +7411,34 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
return (ISC_R_SUCCESS);
}
+static void
+rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
+ dns_rbtdb_t *rbtdb = rdataset->private1;
+ dns_rbtnode_t *rbtnode = rdataset->private2;
+ rdatasetheader_t *header = rdataset->private3;
+
+ header--;
+ NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+ header->trust = rdataset->trust = trust;
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+}
+
+static void
+rdataset_expire(dns_rdataset_t *rdataset) {
+ dns_rbtdb_t *rbtdb = rdataset->private1;
+ dns_rbtnode_t *rbtnode = rdataset->private2;
+ rdatasetheader_t *header = rdataset->private3;
+
+ header--;
+ NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+ expire_header(rbtdb, header, ISC_FALSE);
+ NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock,
+ isc_rwlocktype_write);
+}
+
/*
* Rdataset Iterator Methods
*/
@@ -8497,13 +8536,11 @@ update_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header,
INSIST(IS_CACHE(rbtdb));
/* To be checked: can we really assume this? XXXMLG */
- INSIST(ISC_LINK_LINKED(header, lru_link));
+ INSIST(ISC_LINK_LINKED(header, link));
- ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum],
- header, lru_link);
+ ISC_LIST_UNLINK(rbtdb->rdatasets[header->node->locknum], header, link);
header->last_used = now;
- ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum],
- header, lru_link);
+ ISC_LIST_PREPEND(rbtdb->rdatasets[header->node->locknum], header, link);
}
/*%
@@ -8539,7 +8576,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
for (header = ISC_LIST_TAIL(rbtdb->rdatasets[locknum]);
header != NULL && purgecount > 0;
header = header_prev) {
- header_prev = ISC_LIST_PREV(header, lru_link);
+ header_prev = ISC_LIST_PREV(header, link);
/*
* Unlink the entry at this point to avoid checking it
* again even if it's currently used someone else and
@@ -8548,7 +8585,7 @@ overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
* TTL was reset to 0.
*/
ISC_LIST_UNLINK(rbtdb->rdatasets[locknum], header,
- lru_link);
+ link);
expire_header(rbtdb, header, tree_locked);
purgecount--;
}
diff --git a/contrib/bind9/lib/dns/rcode.c b/contrib/bind9/lib/dns/rcode.c
index 58ade8587e8c..9feaeb07d9c0 100644
--- a/contrib/bind9/lib/dns/rcode.c
+++ b/contrib/bind9/lib/dns/rcode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rcode.c,v 1.8 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: rcode.c,v 1.8.48.2 2010/01/15 23:47:33 tbox Exp $ */
#include <config.h>
#include <ctype.h>
@@ -100,6 +100,8 @@
{ DNS_KEYALG_ECC, "ECC", 0 }, \
{ DNS_KEYALG_RSASHA1, "RSASHA1", 0 }, \
{ DNS_KEYALG_NSEC3RSASHA1, "NSEC3RSASHA1", 0 }, \
+ { DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \
+ { DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \
{ DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \
{ DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \
{ DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \
diff --git a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
index bc2b4e889d4b..6a58bc9bb4e8 100644
--- a/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
+++ b/contrib/bind9/lib/dns/rdata/generic/ipseckey_45.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: ipseckey_45.c,v 1.4.332.2 2009/01/18 23:47:41 tbox Exp $ */
+/* $Id: ipseckey_45.c,v 1.4.332.3 2009/09/18 21:55:48 jinmei Exp $ */
#ifndef RDATA_GENERIC_IPSECKEY_45_C
#define RDATA_GENERIC_IPSECKEY_45_C
@@ -243,6 +243,7 @@ fromwire_ipseckey(ARGS_FROMWIRE) {
isc_buffer_forward(source, 3);
RETERR(dns_name_fromwire(&name, source, dctx, options, target));
isc_buffer_activeregion(source, &region);
+ isc_buffer_forward(source, region.length);
return(mem_tobuffer(target, region.base, region.length));
default:
diff --git a/contrib/bind9/lib/dns/rdatalist.c b/contrib/bind9/lib/dns/rdatalist.c
index d6f11ae64d30..d07261989640 100644
--- a/contrib/bind9/lib/dns/rdatalist.c
+++ b/contrib/bind9/lib/dns/rdatalist.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010 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
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdatalist.c,v 1.36 2008/09/24 02:46:22 marka Exp $ */
+/* $Id: rdatalist.c,v 1.36.336.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -46,6 +46,8 @@ static dns_rdatasetmethods_t methods = {
isc__rdatalist_getclosest,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/rdataset.c b/contrib/bind9/lib/dns/rdataset.c
index 6088a068ad2f..946ec9ae9aab 100644
--- a/contrib/bind9/lib/dns/rdataset.c
+++ b/contrib/bind9/lib/dns/rdataset.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataset.c,v 1.82.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: rdataset.c,v 1.82.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -182,6 +182,8 @@ static dns_rdatasetmethods_t question_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -732,3 +734,22 @@ dns_rdataset_putadditional(dns_acache_t *acache,
return (ISC_R_FAILURE);
}
+void
+dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
+ REQUIRE(DNS_RDATASET_VALID(rdataset));
+ REQUIRE(rdataset->methods != NULL);
+
+ if (rdataset->methods->settrust != NULL)
+ (rdataset->methods->settrust)(rdataset, trust);
+ else
+ rdataset->trust = trust;
+}
+
+void
+dns_rdataset_expire(dns_rdataset_t *rdataset) {
+ REQUIRE(DNS_RDATASET_VALID(rdataset));
+ REQUIRE(rdataset->methods != NULL);
+
+ if (rdataset->methods->expire != NULL)
+ (rdataset->methods->expire)(rdataset);
+}
diff --git a/contrib/bind9/lib/dns/rdataslab.c b/contrib/bind9/lib/dns/rdataslab.c
index b22868d6f212..4eadff9881e7 100644
--- a/contrib/bind9/lib/dns/rdataslab.c
+++ b/contrib/bind9/lib/dns/rdataslab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rdataslab.c,v 1.48.50.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: rdataslab.c,v 1.48.50.2.22.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -436,6 +436,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c
index 1b4f407c87fe..244718fb5db0 100644
--- a/contrib/bind9/lib/dns/resolver.c
+++ b/contrib/bind9/lib/dns/resolver.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.384.14.14.8.2 2010/01/07 17:17:19 each Exp $ */
+/* $Id: resolver.c,v 1.384.14.20.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -334,6 +334,18 @@ typedef struct alternate {
ISC_LINK(struct alternate) link;
} alternate_t;
+typedef struct dns_badcache dns_badcache_t;
+struct dns_badcache {
+ dns_badcache_t * next;
+ dns_rdatatype_t type;
+ isc_time_t expire;
+ unsigned int hashval;
+ dns_name_t name;
+};
+#define DNS_BADCACHE_SIZE 1021
+#define DNS_BADCACHE_TTL(fctx) \
+ (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30)
+
struct dns_resolver {
/* Unlocked. */
unsigned int magic;
@@ -380,6 +392,13 @@ struct dns_resolver {
isc_boolean_t priming;
unsigned int spillat; /* clients-per-query */
unsigned int nextdisp;
+
+ /* Bad cache. */
+ dns_badcache_t ** badcache;
+ unsigned int badcount;
+ unsigned int badhash;
+ unsigned int badsweep;
+
/* Locked by primelock. */
dns_fetch_t * primefetch;
/* Locked by nlock. */
@@ -410,7 +429,8 @@ static void empty_bucket(dns_resolver_t *res);
static isc_result_t resquery_send(resquery_t *query);
static void resquery_response(isc_task_t *task, isc_event_t *event);
static void resquery_connected(isc_task_t *task, isc_event_t *event);
-static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying);
+static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying,
+ isc_boolean_t badcache);
static isc_boolean_t fctx_destroy(fetchctx_t *fctx);
static isc_result_t ncache_adderesult(dns_message_t *message,
dns_db_t *cache, dns_dbnode_t *node,
@@ -1169,7 +1189,7 @@ process_sendevent(resquery_t *query, isc_event_t *event) {
if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
else
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
}
}
@@ -2071,7 +2091,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
else
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
}
}
@@ -2133,7 +2153,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) {
dns_adb_destroyfind(&find);
if (want_try)
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
else if (want_done)
fctx_done(fctx, ISC_R_FAILURE, __LINE__);
else if (bucket_empty)
@@ -2534,8 +2554,18 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
}
}
+static isc_boolean_t
+isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) {
+ int order;
+ unsigned int nlabels;
+ dns_namereln_t namereln;
+
+ namereln = dns_name_fullcompare(name1, name2, &order, &nlabels);
+ return (ISC_TF(namereln == dns_namereln_subdomain));
+}
+
static isc_result_t
-fctx_getaddresses(fetchctx_t *fctx) {
+fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) {
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
dns_resolver_t *res;
@@ -2579,23 +2609,40 @@ fctx_getaddresses(fetchctx_t *fctx) {
dns_name_t *name = &fctx->name;
dns_name_t suffix;
unsigned int labels;
+ dns_fixedname_t fixed;
+ dns_name_t *domain;
/*
* DS records are found in the parent server.
* Strip label to get the correct forwarder (if any).
*/
- if (fctx->type == dns_rdatatype_ds &&
+ if (dns_rdatatype_atparent(fctx->type) &&
dns_name_countlabels(name) > 1) {
dns_name_init(&suffix, NULL);
labels = dns_name_countlabels(name);
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
name = &suffix;
}
- result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
- &forwarders);
+
+ dns_fixedname_init(&fixed);
+ domain = dns_fixedname_name(&fixed);
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
+ domain, &forwarders);
if (result == ISC_R_SUCCESS) {
sa = ISC_LIST_HEAD(forwarders->addrs);
fctx->fwdpolicy = forwarders->fwdpolicy;
+ if (fctx->fwdpolicy == dns_fwdpolicy_only &&
+ isstrictsubdomain(domain, &fctx->domain)) {
+ isc_mem_t *mctx;
+
+ mctx = res->buckets[fctx->bucketnum].mctx;
+ dns_name_free(&fctx->domain, mctx);
+ dns_name_init(&fctx->domain, NULL);
+ result = dns_name_dup(domain, mctx,
+ &fctx->domain);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
}
}
@@ -2737,12 +2784,24 @@ fctx_getaddresses(fetchctx_t *fctx) {
*/
result = DNS_R_WAIT;
} else {
+ isc_time_t expire;
+ isc_interval_t i;
/*
* We've lost completely. We don't know any
* addresses, and the ADB has told us it can't get
* them.
*/
FCTXTRACE("no addresses");
+ isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
+ result = isc_time_nowplusinterval(&expire, &i);
+ if (badcache &&
+ (fctx->type == dns_rdatatype_dnskey ||
+ fctx->type == dns_rdatatype_dlv ||
+ fctx->type == dns_rdatatype_ds) &&
+ result == ISC_R_SUCCESS)
+ dns_resolver_addbadcache(fctx->res,
+ &fctx->name,
+ fctx->type, &expire);
result = ISC_R_FAILURE;
}
} else {
@@ -2965,7 +3024,7 @@ fctx_nextaddress(fetchctx_t *fctx) {
}
static void
-fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) {
+fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) {
isc_result_t result;
dns_adbaddrinfo_t *addrinfo;
@@ -2983,7 +3042,7 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) {
fctx_cleanupaltfinds(fctx);
fctx_cleanupforwaddrs(fctx);
fctx_cleanupaltaddrs(fctx);
- result = fctx_getaddresses(fctx);
+ result = fctx_getaddresses(fctx, badcache);
if (result == DNS_R_WAIT) {
/*
* Sleep waiting for addresses.
@@ -3148,7 +3207,7 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) {
/*
* Keep trying.
*/
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
}
isc_event_free(&event);
@@ -3318,7 +3377,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) {
if (result != ISC_R_SUCCESS)
fctx_done(fctx, result, __LINE__);
else
- fctx_try(fctx, ISC_FALSE);
+ fctx_try(fctx, ISC_FALSE, ISC_FALSE);
} else if (bucket_empty)
empty_bucket(res);
}
@@ -3477,21 +3536,22 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
if (domain == NULL) {
dns_forwarders_t *forwarders = NULL;
unsigned int labels;
+ dns_name_t *fwdname = name;
/*
* DS records are found in the parent server.
* Strip label to get the correct forwarder (if any).
*/
- if (fctx->type == dns_rdatatype_ds &&
+ if (dns_rdatatype_atparent(fctx->type) &&
dns_name_countlabels(name) > 1) {
dns_name_init(&suffix, NULL);
labels = dns_name_countlabels(name);
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
- name = &suffix;
+ fwdname = &suffix;
}
dns_fixedname_init(&fixed);
domain = dns_fixedname_name(&fixed);
- result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, fwdname,
domain, &forwarders);
if (result == ISC_R_SUCCESS)
fctx->fwdpolicy = forwarders->fwdpolicy;
@@ -3502,7 +3562,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
* nameservers, and we're not in forward-only mode,
* so find the best nameservers to use.
*/
- if (dns_rdatatype_atparent(type))
+ if (dns_rdatatype_atparent(fctx->type))
findoptions |= DNS_DBFIND_NOEXACT;
result = dns_view_findzonecut(res->view, name, domain,
0, findoptions, ISC_TRUE,
@@ -3895,6 +3955,8 @@ validated(isc_task_t *task, isc_event_t *event) {
LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+ isc_stdtime_get(&now);
+
/*
* If chaining, we need to make sure that the right result code is
* returned, and that the rdatasets are bound.
@@ -3941,35 +4003,80 @@ validated(isc_task_t *task, isc_event_t *event) {
inc_stats(fctx->res, dns_resstatscounter_valfail);
fctx->valfail++;
fctx->vresult = vevent->result;
- result = ISC_R_NOTFOUND;
- if (vevent->rdataset != NULL)
- result = dns_db_findnode(fctx->cache, vevent->name,
- ISC_TRUE, &node);
- if (result == ISC_R_SUCCESS)
- (void)dns_db_deleterdataset(fctx->cache, node, NULL,
- vevent->type, 0);
- if (result == ISC_R_SUCCESS && vevent->sigrdataset != NULL)
- (void)dns_db_deleterdataset(fctx->cache, node, NULL,
- dns_rdatatype_rrsig,
- vevent->type);
- if (result == ISC_R_SUCCESS)
- dns_db_detachnode(fctx->cache, &node);
- result = vevent->result;
+ if (fctx->vresult != DNS_R_BROKENCHAIN) {
+ result = ISC_R_NOTFOUND;
+ if (vevent->rdataset != NULL)
+ result = dns_db_findnode(fctx->cache,
+ vevent->name,
+ ISC_TRUE, &node);
+ if (result == ISC_R_SUCCESS)
+ (void)dns_db_deleterdataset(fctx->cache, node,
+ NULL,
+ vevent->type, 0);
+ if (result == ISC_R_SUCCESS &&
+ vevent->sigrdataset != NULL)
+ (void)dns_db_deleterdataset(fctx->cache, node,
+ NULL,
+ dns_rdatatype_rrsig,
+ vevent->type);
+ if (result == ISC_R_SUCCESS)
+ dns_db_detachnode(fctx->cache, &node);
+ }
+ if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) {
+ /*
+ * Cache the data as pending for later validation.
+ */
+ result = ISC_R_NOTFOUND;
+ if (vevent->rdataset != NULL)
+ result = dns_db_findnode(fctx->cache,
+ vevent->name,
+ ISC_TRUE, &node);
+ if (result == ISC_R_SUCCESS) {
+ (void)dns_db_addrdataset(fctx->cache, node,
+ NULL, now,
+ vevent->rdataset, 0,
+ NULL);
+ }
+ if (result == ISC_R_SUCCESS &&
+ vevent->sigrdataset != NULL)
+ (void)dns_db_addrdataset(fctx->cache, node,
+ NULL, now,
+ vevent->sigrdataset,
+ 0, NULL);
+ if (result == ISC_R_SUCCESS)
+ dns_db_detachnode(fctx->cache, &node);
+ }
+ result = fctx->vresult;
add_bad(fctx, addrinfo, result, badns_validation);
isc_event_free(&event);
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
INSIST(fctx->validator == NULL);
fctx->validator = ISC_LIST_HEAD(fctx->validators);
- if (fctx->validator != NULL) {
+ if (fctx->validator != NULL)
dns_validator_send(fctx->validator);
- } else if (sentresponse)
+ else if (sentresponse)
fctx_done(fctx, result, __LINE__); /* Locks bucket. */
- else
- fctx_try(fctx, ISC_TRUE); /* Locks bucket. */
+ else if (result == DNS_R_BROKENCHAIN) {
+ isc_result_t tresult;
+ isc_time_t expire;
+ isc_interval_t i;
+
+ isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0);
+ tresult = isc_time_nowplusinterval(&expire, &i);
+ if (negative &&
+ (fctx->type == dns_rdatatype_dnskey ||
+ fctx->type == dns_rdatatype_dlv ||
+ fctx->type == dns_rdatatype_ds) &&
+ tresult == ISC_R_SUCCESS)
+ dns_resolver_addbadcache(fctx->res,
+ &fctx->name,
+ fctx->type, &expire);
+ fctx_done(fctx, result, __LINE__); /* Locks bucket. */
+ } else
+ fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */
return;
}
- isc_stdtime_get(&now);
if (negative) {
dns_rdatatype_t covers;
@@ -5762,7 +5869,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) {
/*
* Try again.
*/
- fctx_try(fctx, ISC_TRUE);
+ fctx_try(fctx, ISC_TRUE, ISC_FALSE);
} else {
unsigned int n;
dns_rdataset_t *nsrdataset = NULL;
@@ -6601,7 +6708,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/*
* Try again.
*/
- fctx_try(fctx, !get_nameservers);
+ fctx_try(fctx, !get_nameservers, ISC_FALSE);
} else if (resend) {
/*
* Resend (probably with changed options).
@@ -6663,6 +6770,27 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/***
*** Resolver Methods
***/
+static void
+destroy_badcache(dns_resolver_t *res) {
+ dns_badcache_t *bad, *next;
+ unsigned int i;
+
+ if (res->badcache != NULL) {
+ for (i = 0; i < res->badhash; i++)
+ for (bad = res->badcache[i]; bad != NULL;
+ bad = next) {
+ next = bad->next;
+ isc_mem_put(res->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ res->badcount--;
+ }
+ isc_mem_put(res->mctx, res->badcache,
+ sizeof(*res->badcache) * res->badhash);
+ res->badcache = NULL;
+ res->badhash = 0;
+ INSIST(res->badcount == 0);
+ }
+}
static void
destroy(dns_resolver_t *res) {
@@ -6700,6 +6828,7 @@ destroy(dns_resolver_t *res) {
isc_mem_put(res->mctx, a, sizeof(*a));
}
dns_resolver_reset_algorithms(res);
+ destroy_badcache(res);
dns_resolver_resetmustbesecure(res);
#if USE_ALGLOCK
isc_rwlock_destroy(&res->alglock);
@@ -6823,6 +6952,10 @@ dns_resolver_create(dns_view_t *view,
ISC_LIST_INIT(res->alternates);
res->udpsize = RECV_BUFFER_SIZE;
res->algorithms = NULL;
+ res->badcache = NULL;
+ res->badcount = 0;
+ res->badhash = 0;
+ res->badsweep = 0;
res->mustbesecure = NULL;
res->spillatmin = res->spillat = 10;
res->spillatmax = 100;
@@ -7664,6 +7797,256 @@ dns_resolver_getudpsize(dns_resolver_t *resolver) {
return (resolver->udpsize);
}
+void
+dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) {
+ unsigned int i;
+ dns_badcache_t *bad, *prev, *next;
+
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ LOCK(&resolver->lock);
+ if (resolver->badcache == NULL)
+ goto unlock;
+
+ if (name != NULL) {
+ isc_time_t now;
+ isc_result_t result;
+ result = isc_time_now(&now);
+ if (result != ISC_R_SUCCESS)
+ isc_time_settoepoch(&now);
+ i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ int n;
+ next = bad->next;
+ n = isc_time_compare(&bad->expire, &now);
+ if (n < 0 || dns_name_equal(name, &bad->name)) {
+ if (prev == NULL)
+ resolver->badcache[i] = bad->next;
+ else
+ prev->next = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ } else
+ prev = bad;
+ }
+ } else
+ destroy_badcache(resolver);
+
+ unlock:
+ UNLOCK(&resolver->lock);
+
+}
+
+static void
+resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) {
+ unsigned int newsize;
+ dns_badcache_t **new, *bad, *next;
+ unsigned int i;
+
+ if (grow)
+ newsize = resolver->badhash * 2 + 1;
+ else
+ newsize = (resolver->badhash - 1) / 2;
+
+ new = isc_mem_get(resolver->mctx,
+ sizeof(*resolver->badcache) * newsize);
+ if (new == NULL)
+ return;
+ memset(new, 0, sizeof(*resolver->badcache) * newsize);
+ for (i = 0; i < resolver->badhash; i++) {
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ if (isc_time_compare(&bad->expire, now) < 0) {
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ } else {
+ bad->next = new[bad->hashval % newsize];
+ new[bad->hashval % newsize] = bad;
+ }
+ }
+ }
+ isc_mem_put(resolver->mctx, resolver->badcache,
+ sizeof(*resolver->badcache) * resolver->badhash);
+ resolver->badhash = newsize;
+ resolver->badcache = new;
+}
+
+void
+dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *expire)
+{
+ isc_time_t now;
+ isc_result_t result = ISC_R_SUCCESS;
+ unsigned int i, hashval;
+ dns_badcache_t *bad, *prev, *next;
+
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ LOCK(&resolver->lock);
+ if (resolver->badcache == NULL) {
+ resolver->badcache = isc_mem_get(resolver->mctx,
+ sizeof(*resolver->badcache) *
+ DNS_BADCACHE_SIZE);
+ if (resolver->badcache == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ resolver->badhash = DNS_BADCACHE_SIZE;
+ memset(resolver->badcache, 0, sizeof(*resolver->badcache) *
+ resolver->badhash);
+ }
+
+ result = isc_time_now(&now);
+ if (result != ISC_R_SUCCESS)
+ isc_time_settoepoch(&now);
+ hashval = dns_name_hash(name, ISC_FALSE);
+ i = hashval % resolver->badhash;
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ if (bad->type == type && dns_name_equal(name, &bad->name))
+ break;
+ if (isc_time_compare(&bad->expire, &now) < 0) {
+ if (prev == NULL)
+ resolver->badcache[i] = bad->next;
+ else
+ prev->next = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ } else
+ prev = bad;
+ }
+ if (bad == NULL) {
+ isc_buffer_t buffer;
+ bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length);
+ if (bad == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup;
+ }
+ bad->type = type;
+ bad->hashval = hashval;
+ isc_buffer_init(&buffer, bad + 1, name->length);
+ dns_name_init(&bad->name, NULL);
+ dns_name_copy(name, &bad->name, &buffer);
+ bad->next = resolver->badcache[i];
+ resolver->badcache[i] = bad;
+ resolver->badcount++;
+ if (resolver->badcount > resolver->badhash * 8)
+ resizehash(resolver, &now, ISC_TRUE);
+ if (resolver->badcount < resolver->badhash * 2 &&
+ resolver->badhash > DNS_BADCACHE_SIZE)
+ resizehash(resolver, &now, ISC_FALSE);
+ }
+ bad->expire = *expire;
+ cleanup:
+ UNLOCK(&resolver->lock);
+}
+
+isc_boolean_t
+dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name,
+ dns_rdatatype_t type, isc_time_t *now)
+{
+ dns_badcache_t *bad, *prev, *next;
+ isc_boolean_t answer = ISC_FALSE;
+ unsigned int i;
+
+ REQUIRE(VALID_RESOLVER(resolver));
+
+ LOCK(&resolver->lock);
+ if (resolver->badcache == NULL)
+ goto unlock;
+
+ i = dns_name_hash(name, ISC_FALSE) % resolver->badhash;
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ /*
+ * Search the hash list. Clean out expired records as we go.
+ */
+ if (isc_time_compare(&bad->expire, now) < 0) {
+ if (prev != NULL)
+ prev->next = bad->next;
+ else
+ resolver->badcache[i] = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ continue;
+ }
+ if (bad->type == type && dns_name_equal(name, &bad->name)) {
+ answer = ISC_TRUE;
+ break;
+ }
+ prev = bad;
+ }
+
+ /*
+ * Slow sweep to clean out stale records.
+ */
+ i = resolver->badsweep++ % resolver->badhash;
+ bad = resolver->badcache[i];
+ if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) {
+ resolver->badcache[i] = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ }
+
+ unlock:
+ UNLOCK(&resolver->lock);
+ return (answer);
+}
+
+void
+dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
+ dns_badcache_t *bad, *next, *prev;
+ isc_time_t now;
+ unsigned int i;
+ isc_uint64_t t;
+
+ LOCK(&resolver->lock);
+ fprintf(fp, ";\n; Bad cache\n;\n");
+
+ if (resolver->badcache == NULL)
+ goto unlock;
+
+ TIME_NOW(&now);
+ for (i = 0; i < resolver->badhash; i++) {
+ prev = NULL;
+ for (bad = resolver->badcache[i]; bad != NULL; bad = next) {
+ next = bad->next;
+ if (isc_time_compare(&bad->expire, &now) < 0) {
+ if (prev != NULL)
+ prev->next = bad->next;
+ else
+ resolver->badcache[i] = bad->next;
+ isc_mem_put(resolver->mctx, bad, sizeof(*bad) +
+ bad->name.length);
+ resolver->badcount--;
+ continue;
+ }
+ prev = bad;
+ dns_name_format(&bad->name, namebuf, sizeof(namebuf));
+ dns_rdatatype_format(bad->type, typebuf,
+ sizeof(typebuf));
+ t = isc_time_microdiff(&bad->expire, &now);
+ t /= 1000;
+ fprintf(fp, "; %s/%s [ttl "
+ "%" ISC_PLATFORM_QUADFORMAT "u]\n",
+ namebuf, typebuf, t);
+ }
+ }
+
+ unlock:
+ UNLOCK(&resolver->lock);
+}
+
static void
free_algorithm(void *node, void *arg) {
unsigned char *algorithms = node;
diff --git a/contrib/bind9/lib/dns/result.c b/contrib/bind9/lib/dns/result.c
index 54c70e0e9088..e3361975823b 100644
--- a/contrib/bind9/lib/dns/result.c
+++ b/contrib/bind9/lib/dns/result.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: result.c,v 1.125 2008/09/25 04:02:38 tbox Exp $ */
+/* $Id: result.c,v 1.125.122.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -157,6 +157,9 @@ static const char *text[DNS_R_NRESULTS] = {
"MX is an address", /*%< 102 DNS_R_MXISADDRESS */
"duplicate query", /*%< 103 DNS_R_DUPLICATE */
"invalid NSEC3 owner name (wildcard)", /*%< 104 DNS_R_INVALIDNSEC3 */
+
+ "not master", /*%< 105 DNS_R_NOTMASTER */
+ "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
diff --git a/contrib/bind9/lib/dns/sdb.c b/contrib/bind9/lib/dns/sdb.c
index 03fca9ed63e6..e0c8786b2130 100644
--- a/contrib/bind9/lib/dns/sdb.c
+++ b/contrib/bind9/lib/dns/sdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdb.c,v 1.66.48.2 2009/04/21 23:47:18 tbox Exp $ */
+/* $Id: sdb.c,v 1.66.48.3.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -1387,6 +1387,8 @@ static dns_rdatasetmethods_t methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
@@ -1458,9 +1460,11 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
sdb_dbiterator_t *sdbiter = (sdb_dbiterator_t *)iterator;
sdbiter->current = ISC_LIST_HEAD(sdbiter->nodelist);
- while (sdbiter->current != NULL)
+ while (sdbiter->current != NULL) {
if (dns_name_equal(sdbiter->current->name, name))
return (ISC_R_SUCCESS);
+ sdbiter->current = ISC_LIST_NEXT(sdbiter->current, link);
+ }
return (ISC_R_NOTFOUND);
}
diff --git a/contrib/bind9/lib/dns/sdlz.c b/contrib/bind9/lib/dns/sdlz.c
index 89cd0eea2a70..caf71b5af7cf 100644
--- a/contrib/bind9/lib/dns/sdlz.c
+++ b/contrib/bind9/lib/dns/sdlz.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2005-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2005-2010 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: sdlz.c,v 1.18.50.2 2009/04/21 23:47:18 tbox Exp $ */
+/* $Id: sdlz.c,v 1.18.50.3.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -1117,9 +1117,11 @@ dbiterator_seek(dns_dbiterator_t *iterator, dns_name_t *name) {
sdlz_dbiterator_t *sdlziter = (sdlz_dbiterator_t *)iterator;
sdlziter->current = ISC_LIST_HEAD(sdlziter->nodelist);
- while (sdlziter->current != NULL)
+ while (sdlziter->current != NULL) {
if (dns_name_equal(sdlziter->current->name, name))
return (ISC_R_SUCCESS);
+ sdlziter->current = ISC_LIST_NEXT(sdlziter->current, link);
+ }
return (ISC_R_NOTFOUND);
}
@@ -1209,6 +1211,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
+ NULL,
+ NULL,
NULL
};
diff --git a/contrib/bind9/lib/dns/spnego.c b/contrib/bind9/lib/dns/spnego.c
index 0ae6ea233c0a..6c94e51baeea 100644
--- a/contrib/bind9/lib/dns/spnego.c
+++ b/contrib/bind9/lib/dns/spnego.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: spnego.c,v 1.8.118.2 2009/01/18 23:47:40 tbox Exp $ */
+/* $Id: spnego.c,v 1.8.118.4 2009/07/21 07:27:13 marka Exp $ */
/*! \file
* \brief
@@ -265,8 +265,7 @@ decode_oid(const unsigned char *p, size_t len,
oid * k, size_t * size);
static int
-decode_enumerated(const unsigned char *p, size_t len,
- unsigned *num, size_t *size);
+decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size);
static int
decode_octet_string(const unsigned char *, size_t, octet_string *, size_t *);
@@ -291,8 +290,7 @@ der_put_length_and_tag(unsigned char *, size_t, size_t,
Der_class, Der_type, int, size_t *);
static int
-encode_enumerated(unsigned char *p, size_t len,
- const unsigned *data, size_t *);
+encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *);
static int
encode_octet_string(unsigned char *p, size_t len,
@@ -622,7 +620,7 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status,
}
for (i = 0; !found && i < init_token.mechTypes.len; ++i) {
- char mechbuf[17];
+ unsigned char mechbuf[17];
size_t mech_len;
ret = der_put_oid(mechbuf + sizeof(mechbuf) - 1,
@@ -956,8 +954,7 @@ der_match_tag_and_length(const unsigned char *p, size_t len,
}
static int
-decode_enumerated(const unsigned char *p, size_t len,
- unsigned *num, size_t *size)
+decode_enumerated(const unsigned char *p, size_t len, void *num, size_t *size)
{
size_t ret = 0;
size_t l, reallen;
@@ -1269,10 +1266,9 @@ der_put_length_and_tag(unsigned char *p, size_t len, size_t len_val,
}
static int
-encode_enumerated(unsigned char *p, size_t len, const unsigned *data,
- size_t *size)
+encode_enumerated(unsigned char *p, size_t len, const void *data, size_t *size)
{
- unsigned num = *data;
+ unsigned num = *(const unsigned *)data;
size_t ret = 0;
size_t l;
int e;
diff --git a/contrib/bind9/lib/dns/validator.c b/contrib/bind9/lib/dns/validator.c
index ce49daf2eb10..0ccdc41980ce 100644
--- a/contrib/bind9/lib/dns/validator.c
+++ b/contrib/bind9/lib/dns/validator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.164.12.9.8.2 2009/12/31 20:29:21 each Exp $ */
+/* $Id: validator.c,v 1.164.12.11.8.2 2010/02/25 10:57:12 tbox Exp $ */
#include <config.h>
@@ -177,9 +177,16 @@ static inline void
markanswer(dns_validator_t *val) {
validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");
if (val->event->rdataset != NULL)
- val->event->rdataset->trust = dns_trust_answer;
+ dns_rdataset_settrust(val->event->rdataset, dns_trust_answer);
if (val->event->sigrdataset != NULL)
- val->event->sigrdataset->trust = dns_trust_answer;
+ dns_rdataset_settrust(val->event->sigrdataset,
+ dns_trust_answer);
+}
+
+static inline void
+marksecure(dns_validatorevent_t *event) {
+ dns_rdataset_settrust(event->rdataset, dns_trust_secure);
+ dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
}
static void
@@ -425,7 +432,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
if (eresult == ISC_R_CANCELED)
validator_done(val, eresult);
else
- validator_done(val, DNS_R_NOVALIDKEY);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -495,7 +502,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
if (eresult == ISC_R_CANCELED)
validator_done(val, eresult);
else
- validator_done(val, DNS_R_NOVALIDDS);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -635,10 +642,16 @@ keyvalidated(isc_task_t *task, isc_event_t *event) {
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
+ if (eresult != DNS_R_BROKENCHAIN) {
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_expire(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_expire(&val->fsigrdataset);
+ }
validator_log(val, ISC_LOG_DEBUG(3),
"keyvalidated: got %s",
isc_result_totext(eresult));
- validator_done(val, eresult);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -685,10 +698,16 @@ dsvalidated(isc_task_t *task, isc_event_t *event) {
if (result != DNS_R_WAIT)
validator_done(val, result);
} else {
+ if (eresult != DNS_R_BROKENCHAIN) {
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_expire(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_expire(&val->fsigrdataset);
+ }
validator_log(val, ISC_LOG_DEBUG(3),
"dsvalidated: got %s",
isc_result_totext(eresult));
- validator_done(val, eresult);
+ validator_done(val, DNS_R_BROKENCHAIN);
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -1199,6 +1218,8 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
validator_log(val, ISC_LOG_DEBUG(3),
"authvalidated: got %s",
isc_result_totext(result));
+ if (result == DNS_R_BROKENCHAIN)
+ val->authfail++;
if (result == ISC_R_CANCELED)
validator_done(val, result);
else {
@@ -1271,6 +1292,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
* \li DNS_R_NCACHENXRRSET
* \li DNS_R_NXRRSET
* \li DNS_R_NXDOMAIN
+ * \li DNS_R_BROKENCHAIN
*/
static inline isc_result_t
view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
@@ -1280,9 +1302,12 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
unsigned int options;
+ isc_time_t now;
char buf1[DNS_NAME_FORMATSIZE];
char buf2[DNS_NAME_FORMATSIZE];
char buf3[DNS_NAME_FORMATSIZE];
+ char namebuf[DNS_NAME_FORMATSIZE];
+ char typebuf[DNS_RDATATYPE_FORMATSIZE];
if (dns_rdataset_isassociated(&val->frdataset))
dns_rdataset_disassociate(&val->frdataset);
@@ -1292,6 +1317,16 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
if (val->view->zonetable == NULL)
return (ISC_R_CANCELED);
+ if (isc_time_now(&now) == ISC_R_SUCCESS &&
+ dns_resolver_getbadcache(val->view->resolver, name, type, &now)) {
+
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ dns_rdatatype_format(type, typebuf, sizeof(typebuf));
+ validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)",
+ namebuf, typebuf);
+ return (DNS_R_BROKENCHAIN);
+ }
+
options = DNS_DBFIND_PENDINGOK;
if (type == dns_rdatatype_dlv)
options |= DNS_DBFIND_COVERINGNSEC;
@@ -1300,6 +1335,7 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
result = dns_view_find(val->view, name, type, 0, options,
ISC_FALSE, NULL, NULL, foundname,
&val->frdataset, &val->fsigrdataset);
+
if (result == DNS_R_NXDOMAIN) {
if (dns_rdataset_isassociated(&val->frdataset))
dns_rdataset_disassociate(&val->frdataset);
@@ -1656,7 +1692,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
/*
* We don't know anything about this key.
*/
- result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey,
+ result = create_fetch(val, &siginfo->signer,
+ dns_rdatatype_dnskey,
fetch_callback_validator, "get_key");
if (result != ISC_R_SUCCESS)
return (result);
@@ -1671,7 +1708,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
* This key doesn't exist.
*/
result = DNS_R_CONTINUE;
- }
+ } else if (result == DNS_R_BROKENCHAIN)
+ return (result);
if (dns_rdataset_isassociated(&val->frdataset) &&
val->keyset != &val->frdataset)
@@ -1919,8 +1957,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
"looking for noqname proof");
return (nsecvalidate(val, ISC_FALSE));
} else if (result == ISC_R_SUCCESS) {
- event->rdataset->trust = dns_trust_secure;
- event->sigrdataset->trust = dns_trust_secure;
+ marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3),
"marking as secure");
return (result);
@@ -2096,8 +2133,7 @@ dlv_validatezonekey(dns_validator_t *val) {
"no RRSIG matching DLV key");
}
if (result == ISC_R_SUCCESS) {
- val->event->rdataset->trust = dns_trust_secure;
- val->event->sigrdataset->trust = dns_trust_secure;
+ marksecure(val->event);
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
@@ -2198,8 +2234,7 @@ validatezonekey(dns_validator_t *val) {
keynode = nextnode;
}
if (result == ISC_R_SUCCESS) {
- event->rdataset->trust = dns_trust_secure;
- event->sigrdataset->trust = dns_trust_secure;
+ marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3),
"signed by trusted key; "
"marking as secure");
@@ -2226,11 +2261,14 @@ validatezonekey(dns_validator_t *val) {
*/
dns_name_format(val->event->name, namebuf,
sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(2),
+ validator_log(val, ISC_LOG_NOTICE,
"unable to find a DNSKEY which verifies "
"the DNSKEY RRset and also matches one "
"of specified trusted-keys for '%s'",
namebuf);
+ validator_log(val, ISC_LOG_NOTICE,
+ "please check the 'trusted-keys' for "
+ "'%s' in named.conf.", namebuf);
return (DNS_R_NOVALIDKEY);
}
@@ -2291,7 +2329,8 @@ validatezonekey(dns_validator_t *val) {
dns_rdataset_disassociate(&val->fsigrdataset);
validator_log(val, ISC_LOG_DEBUG(2), "no DS record");
return (DNS_R_NOVALIDSIG);
- }
+ } else if (result == DNS_R_BROKENCHAIN)
+ return (result);
}
/*
@@ -2440,8 +2479,7 @@ validatezonekey(dns_validator_t *val) {
"no RRSIG matching DS key");
}
if (result == ISC_R_SUCCESS) {
- event->rdataset->trust = dns_trust_secure;
- event->sigrdataset->trust = dns_trust_secure;
+ marksecure(event);
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
@@ -2844,6 +2882,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
"nsecvalidate");
if (result != ISC_R_SUCCESS)
return (result);
+ val->authcount++;
return (DNS_R_WAIT);
}
@@ -2868,8 +2907,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
"noqname proof found");
validator_log(val, ISC_LOG_DEBUG(3),
"marking as secure");
- val->event->rdataset->trust = dns_trust_secure;
- val->event->sigrdataset->trust = dns_trust_secure;
+ marksecure(val->event);
return (ISC_R_SUCCESS);
} else if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0 &&
dns_name_countlabels(dns_fixedname_name(&val->wild))
@@ -2923,6 +2961,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
}
findnsec3proofs(val);
+ if (val->authcount == val->authfail)
+ return (DNS_R_BROKENCHAIN);
validator_log(val, ISC_LOG_DEBUG(3),
"nonexistence proof(s) not found");
val->attributes |= VALATTR_INSECURITY;
@@ -2954,6 +2994,58 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
return (ISC_FALSE);
}
+static void
+dlvvalidated(isc_task_t *task, isc_event_t *event) {
+ dns_validatorevent_t *devent;
+ dns_validator_t *val;
+ isc_result_t eresult;
+ isc_boolean_t want_destroy;
+
+ UNUSED(task);
+ INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
+
+ devent = (dns_validatorevent_t *)event;
+ val = devent->ev_arg;
+ eresult = devent->result;
+
+ isc_event_free(&event);
+ dns_validator_destroy(&val->subvalidator);
+
+ INSIST(val->event != NULL);
+
+ validator_log(val, ISC_LOG_DEBUG(3), "in dlvvalidated");
+ LOCK(&val->lock);
+ if (CANCELED(val)) {
+ validator_done(val, ISC_R_CANCELED);
+ } else if (eresult == ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dlvset with trust %d", val->frdataset.trust);
+ dns_rdataset_clone(&val->frdataset, &val->dlv);
+ val->havedlvsep = ISC_TRUE;
+ if (dlv_algorithm_supported(val))
+ dlv_validator_start(val);
+ else {
+ markanswer(val);
+ validator_done(val, ISC_R_SUCCESS);
+ }
+ } else {
+ if (eresult != DNS_R_BROKENCHAIN) {
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_expire(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_expire(&val->fsigrdataset);
+ }
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dlvvalidated: got %s",
+ isc_result_totext(eresult));
+ validator_done(val, DNS_R_BROKENCHAIN);
+ }
+ want_destroy = exit_check(val);
+ UNLOCK(&val->lock);
+ if (want_destroy)
+ destroy(val);
+}
+
/*%
* Callback from fetching a DLV record.
*
@@ -3173,6 +3265,24 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
namebuf);
result = view_find(val, dlvname, dns_rdatatype_dlv);
if (result == ISC_R_SUCCESS) {
+ if (DNS_TRUST_PENDING(val->frdataset.trust) &&
+ dns_rdataset_isassociated(&val->fsigrdataset))
+ {
+ dns_fixedname_init(&val->fname);
+ dns_name_copy(dlvname,
+ dns_fixedname_name(&val->fname),
+ NULL);
+ result = create_validator(val,
+ dns_fixedname_name(&val->fname),
+ dns_rdatatype_dlv,
+ &val->frdataset,
+ &val->fsigrdataset,
+ dlvvalidated,
+ "finddlvsep");
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ return (DNS_R_WAIT);
+ }
if (val->frdataset.trust < dns_trust_secure)
return (DNS_R_NOVALIDSIG);
val->havedlvsep = ISC_TRUE;
@@ -3223,6 +3333,7 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
* \li DNS_R_NOVALIDSIG
* \li DNS_R_NOVALIDNSEC
* \li DNS_R_NOTINSECURE
+ * \li DNS_R_BROKENCHAIN
*/
static isc_result_t
proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
@@ -3465,7 +3576,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume)
if (result != ISC_R_SUCCESS)
goto out;
return (DNS_R_WAIT);
- }
+ } else if (result == DNS_R_BROKENCHAIN)
+ return (result);
}
/*
@@ -3682,6 +3794,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
val->seensig = ISC_FALSE;
val->havedlvsep = ISC_FALSE;
val->depth = 0;
+ val->authcount = 0;
+ val->authfail = 0;
val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
dns_rdataset_init(&val->frdataset);
dns_rdataset_init(&val->fsigrdataset);
diff --git a/contrib/bind9/lib/dns/view.c b/contrib/bind9/lib/dns/view.c
index 5f1447ae06ed..72163b4ab896 100644
--- a/contrib/bind9/lib/dns/view.c
+++ b/contrib/bind9/lib/dns/view.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010 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,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: view.c,v 1.150.84.2 2009/01/29 23:47:44 tbox Exp $ */
+/* $Id: view.c,v 1.150.84.3.8.2 2010/02/25 10:57:12 tbox Exp $ */
/*! \file */
@@ -1250,7 +1250,8 @@ dns_view_getpeertsig(dns_view_t *view, isc_netaddr_t *peeraddr,
if (result != ISC_R_SUCCESS)
return (result);
- return (dns_view_gettsig(view, keyname, keyp));
+ result = dns_view_gettsig(view, keyname, keyp);
+ return ((result == ISC_R_NOTFOUND) ? ISC_R_FAILURE : result);
}
isc_result_t
@@ -1270,10 +1271,11 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) {
(void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name);
result = dns_master_dumptostream(view->mctx, view->cachedb, NULL,
- &dns_master_style_cache, fp);
+ &dns_master_style_cache, fp);
if (result != ISC_R_SUCCESS)
return (result);
dns_adb_dump(view->adb, fp);
+ dns_resolver_printbadcache(view->resolver, fp);
return (ISC_R_SUCCESS);
}
@@ -1294,6 +1296,8 @@ dns_view_flushcache(dns_view_t *view) {
dns_cache_attachdb(view->cache, &view->cachedb);
if (view->acache != NULL)
dns_acache_setdb(view->acache, view->cachedb);
+ if (view->resolver != NULL)
+ dns_resolver_flushbadcache(view->resolver, NULL);
dns_adb_flush(view->adb);
return (ISC_R_SUCCESS);
@@ -1308,6 +1312,8 @@ dns_view_flushname(dns_view_t *view, dns_name_t *name) {
dns_adb_flushname(view->adb, name);
if (view->cache == NULL)
return (ISC_R_SUCCESS);
+ if (view->resolver != NULL)
+ dns_resolver_flushbadcache(view->resolver, name);
return (dns_cache_flushname(view->cache, name));
}
diff --git a/contrib/bind9/lib/dns/zone.c b/contrib/bind9/lib/dns/zone.c
index 423b00578720..c21b1f05b118 100644
--- a/contrib/bind9/lib/dns/zone.c
+++ b/contrib/bind9/lib/dns/zone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: zone.c,v 1.483.36.6 2009/03/26 22:57:07 marka Exp $ */
+/* $Id: zone.c,v 1.483.36.17 2009/12/21 04:32:42 marka Exp $ */
/*! \file */
@@ -200,7 +200,6 @@ struct dns_zone {
isc_time_t keywarntime;
isc_time_t signingtime;
isc_time_t nsec3chaintime;
- isc_uint32_t serial;
isc_uint32_t refresh;
isc_uint32_t retry;
isc_uint32_t expire;
@@ -351,11 +350,15 @@ struct dns_zone {
#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
+#define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
+#define DNS_ZONEFLG_THAW 0x08000000U
#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
/* Flags for zone_load() */
#define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
+#define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
+ load. */
#define UNREACH_CHACHE_SIZE 10U
#define UNREACH_HOLD_TIME 600 /* 10 minutes */
@@ -718,7 +721,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
isc_time_settoepoch(&zone->keywarntime);
isc_time_settoepoch(&zone->signingtime);
isc_time_settoepoch(&zone->nsec3chaintime);
- zone->serial = 0;
zone->refresh = DNS_ZONE_DEFAULTREFRESH;
zone->retry = DNS_ZONE_DEFAULTRETRY;
zone->expire = 0;
@@ -967,16 +969,35 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
UNLOCK_ZONE(zone);
}
-isc_uint32_t
-dns_zone_getserial(dns_zone_t *zone) {
- isc_uint32_t serial;
+isc_result_t
+dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
+ isc_result_t result;
REQUIRE(DNS_ZONE_VALID(zone));
+ REQUIRE(serialp != NULL);
LOCK_ZONE(zone);
- serial = zone->serial;
+ ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
+ if (zone->db != NULL) {
+ result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
+ NULL, NULL, NULL, NULL, NULL);
+ } else
+ result = DNS_R_NOTLOADED;
+ ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
UNLOCK_ZONE(zone);
+ return (result);
+}
+
+isc_uint32_t
+dns_zone_getserial(dns_zone_t *zone) {
+ isc_result_t result;
+ isc_uint32_t serial;
+
+ result = dns_zone_getserial2(zone, &serial);
+ if (result != ISC_R_SUCCESS)
+ serial = 0; /* XXX: not really correct, but no other choice */
+
return (serial);
}
@@ -1314,7 +1335,9 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
INSIST(zone->type != dns_zone_none);
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
- result = ISC_R_SUCCESS;
+ if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
+ result = DNS_R_CONTINUE;
goto cleanup;
}
@@ -1448,6 +1471,8 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
if (result == DNS_R_CONTINUE) {
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
+ if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
+ DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
goto cleanup;
}
@@ -1470,6 +1495,30 @@ dns_zone_loadnew(dns_zone_t *zone) {
return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
}
+isc_result_t
+dns_zone_loadandthaw(dns_zone_t *zone) {
+ isc_result_t result;
+
+ result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
+ switch (result) {
+ case DNS_R_CONTINUE:
+ /* Deferred thaw. */
+ break;
+ case ISC_R_SUCCESS:
+ case DNS_R_UPTODATE:
+ case DNS_R_SEENINCLUDE:
+ zone->update_disabled = ISC_FALSE;
+ break;
+ case DNS_R_NOMASTERFILE:
+ zone->update_disabled = ISC_FALSE;
+ break;
+ default:
+ /* Error, remain in disabled state. */
+ break;
+ }
+ return (result);
+}
+
static unsigned int
get_master_options(dns_zone_t *zone) {
unsigned int options;
@@ -2148,7 +2197,8 @@ resume_signingwithkey(dns_zone_t *zone) {
}
result = zone_signwithkey(zone, rdata.data[0],
- (rdata.data[1] << 8) | rdata.data[2], ISC_TF(rdata.data[3]));
+ (rdata.data[1] << 8) | rdata.data[2],
+ ISC_TF(rdata.data[3]));
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_signwithkey failed: %s",
@@ -2291,7 +2341,6 @@ static void
set_resigntime(dns_zone_t *zone) {
dns_rdataset_t rdataset;
dns_fixedname_t fixed;
- char namebuf[DNS_NAME_FORMATSIZE];
unsigned int resign;
isc_result_t result;
isc_uint32_t nanosecs;
@@ -2305,7 +2354,6 @@ set_resigntime(dns_zone_t *zone) {
return;
}
resign = rdataset.resign;
- dns_name_format(dns_fixedname_name(&fixed), namebuf, sizeof(namebuf));
dns_rdataset_disassociate(&rdataset);
isc_random_get(&nanosecs);
nanosecs %= 1000000000;
@@ -2409,7 +2457,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
unsigned int soacount = 0;
unsigned int nscount = 0;
unsigned int errors = 0;
- isc_uint32_t serial, refresh, retry, expire, minimum;
+ isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
isc_time_t now;
isc_boolean_t needdump = ISC_FALSE;
isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
@@ -2463,8 +2511,9 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
options = DNS_JOURNALOPT_RESIGN;
else
options = 0;
- result = dns_journal_rollforward(zone->mctx, db, options,
- zone->journal);
+ result = dns_journal_rollforward2(zone->mctx, db, options,
+ zone->sigresigninginterval,
+ zone->journal);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
result != ISC_R_RANGE) {
@@ -2544,14 +2593,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
* This is checked in zone_replacedb() for slave zones
* as they don't reload from disk.
*/
+ result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ &oldserial, NULL, NULL, NULL,
+ NULL, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
- !isc_serial_gt(serial, zone->serial)) {
+ !isc_serial_gt(serial, oldserial)) {
isc_uint32_t serialmin, serialmax;
INSIST(zone->type == dns_zone_master);
- serialmin = (zone->serial + 1) & 0xffffffffU;
- serialmax = (zone->serial + 0x7fffffffU) &
+ serialmin = (oldserial + 1) & 0xffffffffU;
+ serialmax = (oldserial + 0x7fffffffU) &
0xffffffffU;
dns_zone_log(zone, ISC_LOG_ERROR,
"ixfr-from-differences: "
@@ -2560,10 +2613,10 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
serialmax);
result = DNS_R_BADZONE;
goto cleanup;
- } else if (!isc_serial_ge(serial, zone->serial))
+ } else if (!isc_serial_ge(serial, oldserial))
dns_zone_log(zone, ISC_LOG_ERROR,
"zone serial has gone backwards");
- else if (serial == zone->serial && !hasinclude)
+ else if (serial == oldserial && !hasinclude)
dns_zone_log(zone, ISC_LOG_ERROR,
"zone serial unchanged. "
"zone may fail to transfer "
@@ -2580,7 +2633,6 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
"3 * refresh.");
}
- zone->serial = serial;
zone->refresh = RANGE(refresh,
zone->minrefresh, zone->maxrefresh);
zone->retry = RANGE(retry,
@@ -2664,8 +2716,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
}
if (! dns_db_ispersistent(db))
- dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s",
- zone->serial,
+ dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
dns_db_issecure(db) ? " (signed)" : "");
return (result);
@@ -2683,7 +2734,8 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
if (zone->task != NULL)
zone_settimer(zone, &now);
result = ISC_R_SUCCESS;
- }
+ } else if (zone->type == dns_zone_master)
+ dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
return (result);
}
@@ -4374,7 +4426,8 @@ updatesignwithkey(dns_signing_t *signing, dns_dbversion_t *version,
seen_done = ISC_TRUE;
else
CHECK(update_one_rr(signing->db, version, diff,
- DNS_DIFFOP_DEL, name, rdataset.ttl, &rdata));
+ DNS_DIFFOP_DEL, name,
+ rdataset.ttl, &rdata));
dns_rdata_reset(&rdata);
}
if (result == ISC_R_NOMORE)
@@ -5458,6 +5511,7 @@ zone_sign(dns_zone_t *zone) {
dst_key_t *zone_keys[MAXZONEKEYS];
isc_int32_t signatures;
isc_boolean_t check_ksk, is_ksk;
+ isc_boolean_t commit = ISC_FALSE;
isc_boolean_t delegation;
isc_boolean_t finishedakey = ISC_FALSE;
isc_boolean_t secureupdated = ISC_FALSE;
@@ -5745,6 +5799,7 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
}
+
if (finishedakey) {
/*
* We have changed the RRset above so we need to update
@@ -5770,6 +5825,15 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
}
+
+ /*
+ * Have we changed anything?
+ */
+ if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
+ goto pauseall;
+
+ commit = ISC_TRUE;
+
result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
&sig_diff, zone_keys, nkeys, now);
if (result != ISC_R_SUCCESS) {
@@ -5801,6 +5865,9 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
+ /*
+ * Write changes to journal file.
+ */
journalfile = dns_zone_getjournal(zone);
if (journalfile != NULL) {
dns_journal_t *journal = NULL;
@@ -5823,7 +5890,7 @@ zone_sign(dns_zone_t *zone) {
}
}
-
+ pauseall:
/*
* Pause all iterators so that dns_db_closeversion() can succeed.
*/
@@ -5840,7 +5907,7 @@ zone_sign(dns_zone_t *zone) {
/*
* Everything has succeeded. Commit the changes.
*/
- dns_db_closeversion(db, &version, ISC_TRUE);
+ dns_db_closeversion(db, &version, commit);
/*
* Everything succeeded so we can clean these up now.
@@ -5856,9 +5923,11 @@ zone_sign(dns_zone_t *zone) {
set_resigntime(zone);
- LOCK_ZONE(zone);
- zone_needdump(zone, DNS_DUMP_DELAY);
- UNLOCK_ZONE(zone);
+ if (commit) {
+ LOCK_ZONE(zone);
+ zone_needdump(zone, DNS_DUMP_DELAY);
+ UNLOCK_ZONE(zone);
+ }
failure:
/*
@@ -6498,6 +6567,7 @@ notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
isc_sockaddr_t any;
isc_boolean_t isself;
isc_netaddr_t dstaddr;
+ isc_result_t result;
if (zone->view == NULL || zone->isself == NULL)
return (ISC_FALSE);
@@ -6523,7 +6593,9 @@ notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
src = *dst;
isc_netaddr_fromsockaddr(&dstaddr, dst);
- (void)dns_view_getpeertsig(zone->view, &dstaddr, &key);
+ result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
+ return (ISC_FALSE);
isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
zone->isselfarg);
if (key != NULL)
@@ -6725,9 +6797,14 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
goto cleanup;
isc_netaddr_fromsockaddr(&dstip, &notify->dst);
- (void)dns_view_getpeertsig(notify->zone->view, &dstip, &key);
-
isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
+ result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
+ notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
+ "sent. Peer TSIG key lookup failure.", addrbuf);
+ goto cleanup_message;
+ }
+
notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
addrbuf);
if (notify->zone->view->peers != NULL) {
@@ -6774,6 +6851,7 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
cleanup_key:
if (key != NULL)
dns_tsigkey_detach(&key);
+ cleanup_message:
dns_message_destroy(&message);
cleanup:
UNLOCK_ZONE(notify->zone);
@@ -7386,7 +7464,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_soa_t soa;
isc_result_t result;
- isc_uint32_t serial;
+ isc_uint32_t serial, oldserial;
unsigned int j;
zone = revent->ev_arg;
@@ -7609,12 +7687,17 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
RUNTIME_CHECK(result == ISC_R_SUCCESS);
serial = soa.serial;
-
- zone_debuglog(zone, me, 1, "serial: new %u, old %u",
- serial, zone->serial);
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
+ result = dns_zone_getserial2(zone, &oldserial);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ zone_debuglog(zone, me, 1, "serial: new %u, old %u",
+ serial, oldserial);
+ } else
+ zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
+ serial);
if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
- isc_serial_gt(serial, zone->serial)) {
+ isc_serial_gt(serial, oldserial)) {
if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
&zone->sourceaddr, &now)) {
dns_zone_log(zone, ISC_LOG_INFO,
@@ -7638,7 +7721,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
}
if (msg != NULL)
dns_message_destroy(&msg);
- } else if (isc_serial_eq(soa.serial, zone->serial)) {
+ } else if (isc_serial_eq(soa.serial, oldserial)) {
if (zone->masterfile != NULL) {
result = ISC_R_FAILURE;
if (zone->journal != NULL)
@@ -7671,7 +7754,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
"received from master %s < ours (%u)",
- soa.serial, master, zone->serial);
+ soa.serial, master, oldserial);
else
zone_debuglog(zone, me, 1, "ahead");
zone->mastersok[zone->curmaster] = ISC_TRUE;
@@ -7965,10 +8048,19 @@ soa_query(isc_task_t *task, isc_event_t *event) {
dns_name_format(keyname, namebuf, sizeof(namebuf));
dns_zone_log(zone, ISC_LOG_ERROR,
"unable to find key: %s", namebuf);
+ goto skip_master;
+ }
+ }
+ if (key == NULL) {
+ result = dns_view_getpeertsig(zone->view, &masterip, &key);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
+ char addrbuf[ISC_NETADDR_FORMATSIZE];
+ isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "unable to find TSIG key for %s", addrbuf);
+ goto skip_master;
}
}
- if (key == NULL)
- (void)dns_view_getpeertsig(zone->view, &masterip, &key);
have_xfrsource = ISC_FALSE;
reqnsid = zone->view->requestnsid;
@@ -8789,13 +8881,21 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
if (result == ISC_R_SUCCESS)
result = dns_rdataset_first(rdataset);
if (result == ISC_R_SUCCESS) {
- isc_uint32_t serial = 0;
+ isc_uint32_t serial = 0, oldserial;
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &soa, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
serial = soa.serial;
- if (isc_serial_le(serial, zone->serial)) {
+ /*
+ * The following should safely be performed without DB
+ * lock and succeed in this context.
+ */
+ result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ &oldserial, NULL, NULL, NULL,
+ NULL, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ if (isc_serial_le(serial, oldserial)) {
dns_zone_log(zone, ISC_LOG_INFO,
"notify from %s: "
"zone is up to date",
@@ -9473,7 +9573,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
if (zone->db != NULL && zone->journal != NULL &&
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
- isc_uint32_t serial;
+ isc_uint32_t serial, oldserial;
dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
@@ -9488,11 +9588,15 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
/*
* This is checked in zone_postload() for master zones.
*/
+ result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ &oldserial, NULL, NULL, NULL, NULL,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (zone->type == dns_zone_slave &&
- !isc_serial_gt(serial, zone->serial)) {
+ !isc_serial_gt(serial, oldserial)) {
isc_uint32_t serialmin, serialmax;
- serialmin = (zone->serial + 1) & 0xffffffffU;
- serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
+ serialmin = (oldserial + 1) & 0xffffffffU;
+ serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
dns_zone_log(zone, ISC_LOG_ERROR,
"ixfr-from-differences: failed: "
"new serial (%u) out of range [%u - %u]",
@@ -9685,7 +9789,6 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
zone_unload(zone);
goto next_master;
}
- zone->serial = serial;
zone->refresh = RANGE(refresh, zone->minrefresh,
zone->maxrefresh);
zone->retry = RANGE(retry, zone->minretry,
@@ -9723,7 +9826,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
buf[0] = '\0';
dns_zone_log(zone, ISC_LOG_INFO,
"transferred serial %u%s",
- zone->serial, buf);
+ serial, buf);
}
/*
@@ -9873,6 +9976,13 @@ zone_loaddone(void *arg, isc_result_t result) {
(void)zone_postload(load->zone, load->db, load->loadtime, result);
zonemgr_putio(&load->zone->readio);
DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
+ /*
+ * Leave the zone frozen if the reload fails.
+ */
+ if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
+ DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
+ zone->update_disabled = ISC_FALSE;
+ DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
UNLOCK_ZONE(load->zone);
load->magic = 0;
@@ -11508,7 +11618,8 @@ zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
cleanup:
if (signing != NULL) {
- dns_db_detach(&signing->db);
+ if (signing->db != NULL)
+ dns_db_detach(&signing->db);
if (signing->dbiterator != NULL)
dns_dbiterator_destroy(&signing->dbiterator);
isc_mem_put(zone->mctx, signing, sizeof *signing);