summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorInternet Software Consortium, Inc <@isc.org>2012-10-29 07:27:43 -0600
committerInternet Software Consortium, Inc <@isc.org>2012-10-29 07:27:43 -0600
commit56b61b7cd52fdce3fd477a28c8dd55db76eba042 (patch)
tree5619c48ff3e920b87bc1c1a2de09ba68426c38bf /lib
parentc450e7bf1c721a84ef09d825e79cf998159decc0 (diff)
downloadbind9-56b61b7cd52fdce3fd477a28c8dd55db76eba042.tar.gz
9.9.2
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.in2
-rw-r--r--lib/bind9/Makefile.in2
-rw-r--r--lib/bind9/api2
-rw-r--r--lib/bind9/check.c83
-rw-r--r--lib/bind9/include/Makefile.in2
-rw-r--r--lib/bind9/include/bind9/Makefile.in2
-rw-r--r--lib/dns/Makefile.in7
-rw-r--r--lib/dns/adb.c46
-rw-r--r--lib/dns/api2
-rw-r--r--lib/dns/db.c13
-rw-r--r--lib/dns/dnssec.c126
-rw-r--r--lib/dns/ds.c35
-rw-r--r--lib/dns/dst_api.c73
-rw-r--r--lib/dns/dst_internal.h7
-rw-r--r--lib/dns/dst_openssl.h5
-rw-r--r--lib/dns/dst_parse.c63
-rw-r--r--lib/dns/dst_parse.h5
-rw-r--r--lib/dns/dst_result.c4
-rw-r--r--lib/dns/gssapi_link.c3
-rw-r--r--lib/dns/hmac_link.c8
-rw-r--r--lib/dns/include/Makefile.in2
-rw-r--r--lib/dns/include/dns/Makefile.in2
-rw-r--r--lib/dns/include/dns/db.h16
-rw-r--r--lib/dns/include/dns/dnssec.h20
-rw-r--r--lib/dns/include/dns/ds.h7
-rw-r--r--lib/dns/include/dns/iptable.h4
-rw-r--r--lib/dns/include/dns/keyvalues.h10
-rw-r--r--lib/dns/include/dns/log.h3
-rw-r--r--lib/dns/include/dns/nsec.h24
-rw-r--r--lib/dns/include/dns/private.h8
-rw-r--r--lib/dns/include/dns/rdata.h2
-rw-r--r--lib/dns/include/dns/rdataset.h22
-rw-r--r--lib/dns/include/dns/rpz.h13
-rw-r--r--lib/dns/include/dns/stats.h10
-rw-r--r--lib/dns/include/dns/view.h3
-rw-r--r--lib/dns/include/dns/zone.h2
-rw-r--r--lib/dns/include/dst/Makefile.in2
-rw-r--r--lib/dns/include/dst/dst.h20
-rw-r--r--lib/dns/include/dst/result.h6
-rw-r--r--lib/dns/log.c3
-rw-r--r--lib/dns/master.c47
-rw-r--r--lib/dns/masterdump.c12
-rw-r--r--lib/dns/nsec.c93
-rw-r--r--lib/dns/nsec3.c61
-rw-r--r--lib/dns/openssl_link.c40
-rw-r--r--lib/dns/openssldh_link.c19
-rw-r--r--lib/dns/openssldsa_link.c35
-rw-r--r--lib/dns/opensslecdsa_link.c597
-rw-r--r--lib/dns/opensslgost_link.c76
-rw-r--r--lib/dns/opensslrsa_link.c90
-rw-r--r--lib/dns/rbtdb.c39
-rw-r--r--lib/dns/rcode.c2
-rw-r--r--lib/dns/rdata.c15
-rw-r--r--lib/dns/rdata/generic/dlv_32769.c12
-rw-r--r--lib/dns/rdata/generic/ds_43.c12
-rw-r--r--lib/dns/rdataset.c28
-rw-r--r--lib/dns/resolver.c50
-rw-r--r--lib/dns/rpz.c133
-rw-r--r--lib/dns/spnego_asn1.pl2
-rw-r--r--lib/dns/tests/Makefile.in9
-rw-r--r--lib/dns/tests/rdataset_test.c131
-rw-r--r--lib/dns/tests/zt_test.c39
-rw-r--r--lib/dns/validator.c21
-rw-r--r--lib/dns/view.c3
-rw-r--r--lib/dns/win32/libdns.def5
-rw-r--r--lib/dns/zone.c109
-rw-r--r--lib/dns/zt.c47
-rw-r--r--lib/export/Makefile.in2
-rw-r--r--lib/export/dns/Makefile.in4
-rw-r--r--lib/export/dns/include/Makefile.in2
-rw-r--r--lib/export/dns/include/dns/Makefile.in2
-rw-r--r--lib/export/dns/include/dst/Makefile.in2
-rw-r--r--lib/export/irs/include/irs/Makefile.in2
-rw-r--r--lib/export/isc/Makefile.in2
-rw-r--r--lib/export/isc/include/isc/Makefile.in2
-rw-r--r--lib/export/isc/nls/Makefile.in2
-rw-r--r--lib/export/isc/nothreads/Makefile.in2
-rw-r--r--lib/export/isc/nothreads/include/isc/Makefile.in2
-rw-r--r--lib/export/isc/pthreads/Makefile.in2
-rw-r--r--lib/export/isc/pthreads/include/isc/Makefile.in2
-rw-r--r--lib/export/isc/unix/Makefile.in2
-rw-r--r--lib/export/isc/unix/include/isc/Makefile.in2
-rw-r--r--lib/export/isccfg/include/isccfg/Makefile.in2
-rw-r--r--lib/export/samples/Makefile-postinstall.in2
-rw-r--r--lib/export/samples/Makefile.in2
-rw-r--r--lib/irs/Makefile.in2
-rw-r--r--lib/irs/include/Makefile.in2
-rw-r--r--lib/irs/include/irs/Makefile.in2
-rw-r--r--lib/isc/alpha/Makefile.in2
-rw-r--r--lib/isc/alpha/include/Makefile.in2
-rw-r--r--lib/isc/alpha/include/isc/Makefile.in2
-rw-r--r--lib/isc/api4
-rw-r--r--lib/isc/ia64/Makefile.in2
-rw-r--r--lib/isc/ia64/include/Makefile.in2
-rw-r--r--lib/isc/ia64/include/isc/Makefile.in2
-rw-r--r--lib/isc/ia64/include/isc/atomic.h6
-rw-r--r--lib/isc/include/Makefile.in2
-rw-r--r--lib/isc/include/isc/file.h13
-rw-r--r--lib/isc/include/isc/heap.h4
-rw-r--r--lib/isc/include/isc/namespace.h2
-rw-r--r--lib/isc/include/isc/queue.h20
-rw-r--r--lib/isc/include/isc/task.h27
-rw-r--r--lib/isc/mem.c10
-rw-r--r--lib/isc/mips/Makefile.in2
-rw-r--r--lib/isc/mips/include/Makefile.in2
-rw-r--r--lib/isc/mips/include/isc/Makefile.in2
-rw-r--r--lib/isc/nls/Makefile.in2
-rw-r--r--lib/isc/noatomic/Makefile.in2
-rw-r--r--lib/isc/noatomic/include/Makefile.in2
-rw-r--r--lib/isc/noatomic/include/isc/Makefile.in2
-rw-r--r--lib/isc/nothreads/Makefile.in2
-rw-r--r--lib/isc/nothreads/include/Makefile.in2
-rw-r--r--lib/isc/nothreads/include/isc/Makefile.in2
-rw-r--r--lib/isc/powerpc/Makefile.in2
-rw-r--r--lib/isc/powerpc/include/Makefile.in2
-rw-r--r--lib/isc/powerpc/include/isc/Makefile.in2
-rw-r--r--lib/isc/pthreads/Makefile.in2
-rw-r--r--lib/isc/pthreads/condition.c11
-rw-r--r--lib/isc/pthreads/include/Makefile.in2
-rw-r--r--lib/isc/pthreads/include/isc/Makefile.in2
-rw-r--r--lib/isc/sparc64/Makefile.in2
-rw-r--r--lib/isc/sparc64/include/Makefile.in2
-rw-r--r--lib/isc/sparc64/include/isc/Makefile.in2
-rw-r--r--lib/isc/task.c45
-rw-r--r--lib/isc/task_api.c11
-rw-r--r--lib/isc/tests/isctest.c8
-rw-r--r--lib/isc/tests/queue_test.c12
-rw-r--r--lib/isc/unix/Makefile.in2
-rw-r--r--lib/isc/unix/file.c31
-rw-r--r--lib/isc/unix/include/Makefile.in2
-rw-r--r--lib/isc/unix/include/isc/Makefile.in2
-rw-r--r--lib/isc/win32/Makefile.in2
-rw-r--r--lib/isc/win32/file.c84
-rw-r--r--lib/isc/win32/include/Makefile.in2
-rw-r--r--lib/isc/win32/include/isc/Makefile.in2
-rw-r--r--lib/isc/win32/include/isc/stat.h7
-rw-r--r--lib/isc/win32/libisc.def6
-rw-r--r--lib/isc/x86_32/Makefile.in2
-rw-r--r--lib/isc/x86_32/include/Makefile.in2
-rw-r--r--lib/isc/x86_32/include/isc/Makefile.in2
-rw-r--r--lib/isc/x86_64/Makefile.in2
-rw-r--r--lib/isc/x86_64/include/Makefile.in2
-rw-r--r--lib/isc/x86_64/include/isc/Makefile.in2
-rw-r--r--lib/isccc/api2
-rw-r--r--lib/isccc/cc.c6
-rw-r--r--lib/isccc/include/Makefile.in2
-rw-r--r--lib/isccc/include/isccc/Makefile.in2
-rw-r--r--lib/isccfg/api2
-rw-r--r--lib/isccfg/include/Makefile.in2
-rw-r--r--lib/isccfg/include/isccfg/Makefile.in2
-rw-r--r--lib/isccfg/namedconf.c225
-rw-r--r--lib/lwres/Makefile.in2
-rw-r--r--lib/lwres/api2
-rw-r--r--lib/lwres/getaddrinfo.c8
-rw-r--r--lib/lwres/include/Makefile.in2
-rw-r--r--lib/lwres/include/lwres/Makefile.in2
-rw-r--r--lib/lwres/man/Makefile.in2
-rw-r--r--lib/lwres/unix/Makefile.in2
-rw-r--r--lib/lwres/unix/include/Makefile.in2
-rw-r--r--lib/lwres/unix/include/lwres/Makefile.in2
-rw-r--r--lib/lwres/win32/Makefile.in2
-rw-r--r--lib/lwres/win32/include/Makefile.in2
-rw-r--r--lib/lwres/win32/include/lwres/Makefile.in2
-rw-r--r--lib/tests/Makefile.in2
-rw-r--r--lib/tests/include/Makefile.in2
-rw-r--r--lib/tests/include/tests/Makefile.in2
166 files changed, 2426 insertions, 670 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in
index e46aef26..e3f0bdb8 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001, 2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/bind9/Makefile.in b/lib/bind9/Makefile.in
index 35c40223..73285e1e 100644
--- a/lib/bind9/Makefile.in
+++ b/lib/bind9/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/bind9/api b/lib/bind9/api
index 6ed2ee97..787f54fc 100644
--- a/lib/bind9/api
+++ b/lib/bind9/api
@@ -4,5 +4,5 @@
# 9.8: 80-89
# 9.9: 90-109
LIBINTERFACE = 90
-LIBREVISION = 3
+LIBREVISION = 5
LIBAGE = 0
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index 08d393ec..9cbcf24f 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -287,10 +287,6 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) {
tresult = dns_secalg_fromtext(&alg, &r);
if (tresult != ISC_R_SUCCESS) {
- isc_uint8_t ui;
- result = isc_parse_uint8(&ui, r.base, 10);
- }
- if (tresult != ISC_R_SUCCESS) {
cfg_obj_log(cfg_listelt_value(element), logctx,
ISC_LOG_ERROR, "invalid algorithm '%s'",
r.base);
@@ -737,6 +733,20 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
}
obj = NULL;
+ cfg_map_get(options, "max-rsa-exponent-size", &obj);
+ if (obj != NULL) {
+ isc_uint32_t val;
+
+ val = cfg_obj_asuint32(obj);
+ if (val != 0 && (val < 35 || val > 4096)) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "max-rsa-exponent-size '%u' is out of "
+ "range (35..4096)", val);
+ result = ISC_R_RANGE;
+ }
+ }
+
+ obj = NULL;
cfg_map_get(options, "sig-validity-interval", &obj);
if (obj != NULL) {
isc_uint32_t validity, resign = 0;
@@ -1261,6 +1271,29 @@ typedef struct {
} optionstable;
static isc_result_t
+check_nonzero(const cfg_obj_t *options, isc_log_t *logctx) {
+ isc_result_t result = ISC_R_SUCCESS;
+ const cfg_obj_t *obj = NULL;
+ unsigned int i;
+
+ static const char *nonzero[] = { "max-retry-time", "min-retry-time",
+ "max-refresh-time", "min-refresh-time" };
+ /*
+ * Check if value is zero.
+ */
+ for (i = 0; i < sizeof(nonzero) / sizeof(nonzero[0]); i++) {
+ obj = NULL;
+ if (cfg_map_get(options, nonzero[i], &obj) == ISC_R_SUCCESS &&
+ cfg_obj_asuint32(obj) == 0) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "'%s' must not be zero", nonzero[i]);
+ result = ISC_R_FAILURE;
+ }
+ }
+ return (result);
+}
+
+static isc_result_t
check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
const cfg_obj_t *config, isc_symtab_t *symtab,
dns_rdataclass_t defclass, cfg_aclconfctx_t *actx,
@@ -1269,7 +1302,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
const char *znamestr;
const char *typestr;
unsigned int ztype;
- const cfg_obj_t *zoptions;
+ const cfg_obj_t *zoptions, *goptions = NULL;
const cfg_obj_t *obj = NULL;
isc_result_t result = ISC_R_SUCCESS;
isc_result_t tresult;
@@ -1290,8 +1323,10 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
{ "also-notify", MASTERZONE | SLAVEZONE },
{ "dialup", MASTERZONE | SLAVEZONE | STUBZONE | STREDIRECTZONE },
{ "delegation-only", HINTZONE | STUBZONE | DELEGATIONZONE },
- { "forward", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE },
- { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE | FORWARDZONE },
+ { "forward", MASTERZONE | SLAVEZONE | STUBZONE |
+ STATICSTUBZONE | FORWARDZONE },
+ { "forwarders", MASTERZONE | SLAVEZONE | STUBZONE |
+ STATICSTUBZONE | FORWARDZONE },
{ "maintain-ixfr-base", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
{ "max-ixfr-log-size", MASTERZONE | SLAVEZONE | STREDIRECTZONE },
{ "notify-source", MASTERZONE | SLAVEZONE },
@@ -1350,10 +1385,14 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
{ "passive", SLAVEZONE | STUBZONE | STREDIRECTZONE },
};
+
znamestr = cfg_obj_asstring(cfg_tuple_get(zconfig, "name"));
zoptions = cfg_tuple_get(zconfig, "options");
+ if (config != NULL)
+ cfg_map_get(config, "options", &goptions);
+
obj = NULL;
(void)cfg_map_get(zoptions, "type", &obj);
if (obj == NULL) {
@@ -1443,6 +1482,12 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
}
/*
+ * Check if value is zero.
+ */
+ if (check_nonzero(zoptions, logctx) != ISC_R_SUCCESS)
+ result = ISC_R_FAILURE;
+
+ /*
* Look for inappropriate options for the given zone type.
* Check that ACLs expand correctly.
*/
@@ -2190,6 +2235,14 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
}
/*
+ * Check non-zero options at the global and view levels.
+ */
+ if (options != NULL && check_nonzero(options, logctx) != ISC_R_SUCCESS)
+ result = ISC_R_FAILURE;
+ if (voptions != NULL &&check_nonzero(voptions, logctx) != ISC_R_SUCCESS)
+ result = ISC_R_FAILURE;
+
+ /*
* Check that dual-stack-servers is reasonable.
*/
if (voptions == NULL) {
@@ -2216,15 +2269,15 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
tresult = isc_symtab_create(mctx, 1000, freekey, mctx,
ISC_FALSE, &symtab);
if (tresult != ISC_R_SUCCESS)
- return (ISC_R_NOMEMORY);
+ goto cleanup;
(void)cfg_map_get(config, "key", &keys);
tresult = check_keylist(keys, symtab, mctx, logctx);
if (tresult == ISC_R_EXISTS)
result = ISC_R_FAILURE;
else if (tresult != ISC_R_SUCCESS) {
- isc_symtab_destroy(&symtab);
- return (tresult);
+ result = tresult;
+ goto cleanup;
}
if (voptions != NULL) {
@@ -2234,8 +2287,8 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
if (tresult == ISC_R_EXISTS)
result = ISC_R_FAILURE;
else if (tresult != ISC_R_SUCCESS) {
- isc_symtab_destroy(&symtab);
- return (tresult);
+ result = tresult;
+ goto cleanup;
}
}
@@ -2356,7 +2409,11 @@ check_viewconf(const cfg_obj_t *config, const cfg_obj_t *voptions,
if (tresult != ISC_R_SUCCESS)
result = tresult;
- cfg_aclconfctx_detach(&actx);
+ cleanup:
+ if (symtab != NULL)
+ isc_symtab_destroy(&symtab);
+ if (actx != NULL)
+ cfg_aclconfctx_detach(&actx);
return (result);
}
diff --git a/lib/bind9/include/Makefile.in b/lib/bind9/include/Makefile.in
index 65eecb05..0a7436c0 100644
--- a/lib/bind9/include/Makefile.in
+++ b/lib/bind9/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/bind9/include/bind9/Makefile.in b/lib/bind9/include/bind9/Makefile.in
index 8abfaf65..11ae5862 100644
--- a/lib/bind9/include/bind9/Makefile.in
+++ b/lib/bind9/include/bind9/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in
index b68a1b0b..a0063388 100644
--- a/lib/dns/Makefile.in
+++ b/lib/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -47,7 +47,8 @@ LIBS = @LIBS@
# Alphabetically
OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
- opensslgost_link.@O@ opensslrsa_link.@O@
+ opensslecdsa_link.@O@ opensslgost_link.@O@ \
+ opensslrsa_link.@O@
DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
@@ -76,7 +77,7 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS}
# Alphabetically
OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \
- opensslgost_link.c opensslrsa_link.c
+ opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c
DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
dst_api.c dst_lib.c dst_parse.c \
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index 8d17d829..5db442cf 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -111,6 +111,7 @@ struct dns_adb {
isc_taskmgr_t *taskmgr;
isc_task_t *task;
+ isc_task_t *excl;
isc_interval_t tick_interval;
int next_cleanbucket;
@@ -1627,10 +1628,12 @@ new_adbname(dns_adb_t *adb, dns_name_t *dnsname) {
LOCK(&adb->namescntlock);
adb->namescnt++;
- if (!adb->grownames_sent && adb->namescnt > (adb->nnames * 8)) {
+ if (!adb->grownames_sent && adb->excl != NULL &&
+ adb->namescnt > (adb->nnames * 8))
+ {
isc_event_t *event = &adb->grownames;
inc_adb_irefcnt(adb);
- isc_task_send(adb->task, &event);
+ isc_task_send(adb->excl, &event);
adb->grownames_sent = ISC_TRUE;
}
UNLOCK(&adb->namescntlock);
@@ -1751,8 +1754,9 @@ new_adbentry(dns_adb_t *adb) {
ISC_LINK_INIT(e, plink);
LOCK(&adb->entriescntlock);
adb->entriescnt++;
- if (!adb->growentries_sent &&
- adb->entriescnt > (adb->nentries * 8)) {
+ if (!adb->growentries_sent && adb->growentries_sent &&
+ adb->entriescnt > (adb->nentries * 8))
+ {
isc_event_t *event = &adb->growentries;
inc_adb_irefcnt(adb);
isc_task_send(adb->task, &event);
@@ -2327,6 +2331,7 @@ destroy(dns_adb_t *adb) {
adb->magic = 0;
isc_task_detach(&adb->task);
+ isc_task_detach(&adb->excl);
isc_mempool_destroy(&adb->nmp);
isc_mempool_destroy(&adb->nhmp);
@@ -2410,6 +2415,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
adb->aimp = NULL;
adb->afmp = NULL;
adb->task = NULL;
+ adb->excl = NULL;
adb->mctx = NULL;
adb->view = view;
adb->taskmgr = taskmgr;
@@ -2445,6 +2451,16 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
adb, NULL, NULL);
adb->grownames_sent = ISC_FALSE;
+ result = isc_taskmgr_excltask(adb->taskmgr, &adb->excl);
+ if (result != ISC_R_SUCCESS) {
+ DP(ISC_LOG_INFO, "adb: task-exclusive mode unavailable, "
+ "intializing table sizes to %u\n",
+ nbuckets[11]);
+ adb->nentries = nbuckets[11];
+ adb->nnames= nbuckets[11];
+
+ }
+
isc_mem_attach(mem, &adb->mctx);
result = isc_mutex_init(&adb->lock);
@@ -2557,6 +2573,7 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr,
result = isc_task_create(adb->taskmgr, 0, &adb->task);
if (result != ISC_R_SUCCESS)
goto fail3;
+
isc_task_setname(adb->task, "ADB", adb);
/*
@@ -3904,8 +3921,10 @@ dns_adb_adjustsrtt(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
addr->entry->srtt = new_srtt;
addr->srtt = new_srtt;
- isc_stdtime_get(&now);
- addr->entry->expires = now + ADB_ENTRY_WINDOW;
+ if (addr->entry->expires == 0) {
+ isc_stdtime_get(&now);
+ addr->entry->expires = now + ADB_ENTRY_WINDOW;
+ }
UNLOCK(&adb->entrylocks[bucket]);
}
@@ -3915,6 +3934,7 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
unsigned int bits, unsigned int mask)
{
int bucket;
+ isc_stdtime_t now;
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
@@ -3923,6 +3943,11 @@ dns_adb_changeflags(dns_adb_t *adb, dns_adbaddrinfo_t *addr,
LOCK(&adb->entrylocks[bucket]);
addr->entry->flags = (addr->entry->flags & ~mask) | (bits & mask);
+ if (addr->entry->expires == 0) {
+ isc_stdtime_get(&now);
+ addr->entry->expires = now + ADB_ENTRY_WINDOW;
+ }
+
/*
* Note that we do not update the other bits in addr->flags with
* the most recent values from addr->entry->flags.
@@ -4001,15 +4026,16 @@ dns_adb_freeaddrinfo(dns_adb_t *adb, dns_adbaddrinfo_t **addrp) {
entry = addr->entry;
REQUIRE(DNS_ADBENTRY_VALID(entry));
- isc_stdtime_get(&now);
-
*addrp = NULL;
overmem = isc_mem_isovermem(adb->mctx);
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
- entry->expires = now + ADB_ENTRY_WINDOW;
+ if (entry->expires == 0) {
+ isc_stdtime_get(&now);
+ entry->expires = now + ADB_ENTRY_WINDOW;
+ }
want_check_exit = dec_entry_refcnt(adb, overmem, entry, ISC_FALSE);
diff --git a/lib/dns/api b/lib/dns/api
index 9d37a0b8..5eded2c1 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -3,6 +3,6 @@
# 9.7: 60-79
# 9.8: 80-89
# 9.9: 90-109
-LIBINTERFACE = 94
+LIBINTERFACE = 96
LIBREVISION = 1
LIBAGE = 1
diff --git a/lib/dns/db.c b/lib/dns/db.c
index e7e4bf15..77547268 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 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.99 2011/10/13 01:32:33 vjs Exp $ */
+/* $Id: db.c,v 1.99.4.1 2011/10/23 20:12:07 vjs Exp $ */
/*! \file */
@@ -1014,14 +1014,13 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
(db->methods->rpz_enabled)(db, st);
}
-isc_result_t
+void
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
dns_name_t *query_qname)
{
- if (db->methods->rpz_findips == NULL)
- return (ISC_R_NOTIMPLEMENTED);
- return ((db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
- ardataset, st, query_qname));
+ if (db->methods->rpz_findips != NULL)
+ (db->methods->rpz_findips)(rpz, rpz_type, zone, db, version,
+ ardataset, st, query_qname);
}
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index ed945254..2995fdde 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -44,10 +44,13 @@
#include <dns/rdataset.h>
#include <dns/rdatastruct.h>
#include <dns/result.h>
+#include <dns/stats.h>
#include <dns/tsig.h> /* for DNS_TSIG_FUDGE */
#include <dst/result.h>
+LIBDNS_EXTERNAL_DATA isc_stats_t *dns_dnssec_stats;
+
#define is_response(msg) (msg->flags & DNS_MESSAGEFLAG_QR)
#define RETERR(x) do { \
@@ -77,6 +80,12 @@ digest_callback(void *arg, isc_region_t *data) {
return (dst_context_adddata(ctx, data));
}
+static inline void
+inc_stat(isc_statscounter_t counter) {
+ if (dns_dnssec_stats != NULL)
+ isc_stats_increment(dns_dnssec_stats, counter);
+}
+
/*
* Make qsort happy.
*/
@@ -153,7 +162,9 @@ dns_dnssec_keyfromrdata(dns_name_t *name, dns_rdata_t *rdata, isc_mem_t *mctx,
}
static isc_result_t
-digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) {
+digest_sig(dst_context_t *ctx, isc_boolean_t downcase, dns_rdata_t *sigrdata,
+ dns_rdata_rrsig_t *rrsig)
+{
isc_region_t r;
isc_result_t ret;
dns_fixedname_t fname;
@@ -165,11 +176,16 @@ digest_sig(dst_context_t *ctx, dns_rdata_t *sigrdata, dns_rdata_rrsig_t *sig) {
ret = dst_context_adddata(ctx, &r);
if (ret != ISC_R_SUCCESS)
return (ret);
- dns_fixedname_init(&fname);
- RUNTIME_CHECK(dns_name_downcase(&sig->signer,
- dns_fixedname_name(&fname), NULL)
- == ISC_R_SUCCESS);
- dns_name_toregion(dns_fixedname_name(&fname), &r);
+ if (downcase) {
+ dns_fixedname_init(&fname);
+
+ RUNTIME_CHECK(dns_name_downcase(&rrsig->signer,
+ dns_fixedname_name(&fname),
+ NULL) == ISC_R_SUCCESS);
+ dns_name_toregion(dns_fixedname_name(&fname), &r);
+ } else
+ dns_name_toregion(&rrsig->signer, &r);
+
return (dst_context_adddata(ctx, &r));
}
@@ -191,6 +207,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_uint32_t flags;
unsigned int sigsize;
dns_fixedname_t fnewname;
+ dns_fixedname_t fsigner;
REQUIRE(name != NULL);
REQUIRE(dns_name_countlabels(name) <= 255);
@@ -218,8 +235,14 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
sig.common.rdtype = dns_rdatatype_rrsig;
ISC_LINK_INIT(&sig.common, link);
+ /*
+ * Downcase signer.
+ */
dns_name_init(&sig.signer, NULL);
- dns_name_clone(dst_key_name(key), &sig.signer);
+ dns_fixedname_init(&fsigner);
+ RUNTIME_CHECK(dns_name_downcase(dst_key_name(key),
+ dns_fixedname_name(&fsigner), NULL) == ISC_R_SUCCESS);
+ dns_name_clone(dns_fixedname_name(&fsigner), &sig.signer);
sig.covered = set->type;
sig.algorithm = dst_key_alg(key);
@@ -259,7 +282,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
/*
* Digest the SIG rdata.
*/
- ret = digest_sig(ctx, &tmpsigrdata, &sig);
+ ret = digest_sig(ctx, ISC_FALSE, &tmpsigrdata, &sig);
if (ret != ISC_R_SUCCESS)
goto cleanup_context;
@@ -332,7 +355,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
memcpy(sig.signature, r.base, sig.siglen);
ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass,
- sig.common.rdtype, &sig, buffer);
+ sig.common.rdtype, &sig, buffer);
cleanup_array:
isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t));
@@ -351,6 +374,15 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_boolean_t ignoretime, isc_mem_t *mctx,
dns_rdata_t *sigrdata, dns_name_t *wild)
{
+ return (dns_dnssec_verify3(name, set, key, ignoretime, 0, mctx,
+ sigrdata, wild));
+}
+
+isc_result_t
+dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
+ isc_boolean_t ignoretime, unsigned int maxbits,
+ isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild)
+{
dns_rdata_rrsig_t sig;
dns_fixedname_t fnewname;
isc_region_t r;
@@ -363,6 +395,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
dst_context_t *ctx = NULL;
int labels = 0;
isc_uint32_t flags;
+ isc_boolean_t downcase = ISC_FALSE;
REQUIRE(name != NULL);
REQUIRE(set != NULL);
@@ -377,8 +410,10 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
if (set->type != sig.covered)
return (DNS_R_SIGINVALID);
- if (isc_serial_lt(sig.timeexpire, sig.timesigned))
+ if (isc_serial_lt(sig.timeexpire, sig.timesigned)) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_SIGINVALID);
+ }
if (!ignoretime) {
isc_stdtime_get(&now);
@@ -386,10 +421,13 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
/*
* Is SIG temporally valid?
*/
- if (isc_serial_lt((isc_uint32_t)now, sig.timesigned))
+ if (isc_serial_lt((isc_uint32_t)now, sig.timesigned)) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_SIGFUTURE);
- else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now))
+ } else if (isc_serial_lt(sig.timeexpire, (isc_uint32_t)now)) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_SIGEXPIRED);
+ }
}
/*
@@ -400,16 +438,22 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
case dns_rdatatype_ns:
case dns_rdatatype_soa:
case dns_rdatatype_dnskey:
- if (!dns_name_equal(name, &sig.signer))
+ if (!dns_name_equal(name, &sig.signer)) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_SIGINVALID);
+ }
break;
case dns_rdatatype_ds:
- if (dns_name_equal(name, &sig.signer))
+ if (dns_name_equal(name, &sig.signer)) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_SIGINVALID);
+ }
/* FALLTHROUGH */
default:
- if (!dns_name_issubdomain(name, &sig.signer))
+ if (!dns_name_issubdomain(name, &sig.signer)) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_SIGINVALID);
+ }
break;
}
@@ -417,11 +461,16 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
* Is the key allowed to sign data?
*/
flags = dst_key_flags(key);
- if (flags & DNS_KEYTYPE_NOAUTH)
+ if (flags & DNS_KEYTYPE_NOAUTH) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_KEYUNAUTHORIZED);
- if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE)
+ }
+ if ((flags & DNS_KEYFLAG_OWNERMASK) != DNS_KEYOWNER_ZONE) {
+ inc_stat(dns_dnssecstats_fail);
return (DNS_R_KEYUNAUTHORIZED);
+ }
+ again:
ret = dst_context_create(key, mctx, &ctx);
if (ret != ISC_R_SUCCESS)
goto cleanup_struct;
@@ -429,7 +478,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
/*
* Digest the SIG rdata (not including the signature).
*/
- ret = digest_sig(ctx, sigrdata, &sig);
+ ret = digest_sig(ctx, downcase, sigrdata, &sig);
if (ret != ISC_R_SUCCESS)
goto cleanup_context;
@@ -507,22 +556,41 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
r.base = sig.signature;
r.length = sig.siglen;
- ret = dst_context_verify(ctx, &r);
- if (ret == DST_R_VERIFYFAILURE)
- ret = DNS_R_SIGINVALID;
+ ret = dst_context_verify2(ctx, maxbits, &r);
+ if (ret == ISC_R_SUCCESS && downcase) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ dns_name_format(&sig.signer, namebuf, sizeof(namebuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_DNSSEC, ISC_LOG_INFO,
+ "sucessfully validated after lower casing "
+ "signer '%s'", namebuf);
+ inc_stat(dns_dnssecstats_downcase);
+ } else if (ret == ISC_R_SUCCESS)
+ inc_stat(dns_dnssecstats_asis);
cleanup_array:
isc_mem_put(mctx, rdatas, nrdatas * sizeof(dns_rdata_t));
cleanup_context:
dst_context_destroy(&ctx);
+ if (ret == DST_R_VERIFYFAILURE && !downcase) {
+ downcase = ISC_TRUE;
+ goto again;
+ }
cleanup_struct:
dns_rdata_freestruct(&sig);
+ if (ret == DST_R_VERIFYFAILURE)
+ ret = DNS_R_SIGINVALID;
+
+ if (ret != ISC_R_SUCCESS)
+ inc_stat(dns_dnssecstats_fail);
+
if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
if (wild != NULL)
RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname,
dns_fixedname_name(&fnewname),
wild, NULL) == ISC_R_SUCCESS);
+ inc_stat(dns_dnssecstats_wildcard);
ret = DNS_R_FROMWILDCARD;
}
return (ret);
@@ -1333,11 +1401,12 @@ dns_dnssec_findmatchingkeys(dns_name_t *origin, const char *directory,
* the keys in the keyset, regardless of whether they have
* metadata indicating they should be deactivated or removed.
*/
-static void
+static isc_result_t
addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
isc_boolean_t savekeys, isc_mem_t *mctx)
{
dns_dnsseckey_t *key;
+ isc_result_t result;
/* Skip duplicates */
for (key = ISC_LIST_HEAD(*keylist);
@@ -1365,10 +1434,12 @@ addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
}
key->source = dns_keysource_zoneapex;
- return;
+ return (ISC_R_SUCCESS);
}
- dns_dnsseckey_create(mctx, newkey, &key);
+ result = dns_dnsseckey_create(mctx, newkey, &key);
+ if (result != ISC_R_SUCCESS)
+ return (result);
if (key->legacy || savekeys) {
key->force_publish = ISC_TRUE;
key->force_sign = dst_key_isprivate(key->key);
@@ -1376,6 +1447,7 @@ addkey(dns_dnsseckeylist_t *keylist, dst_key_t **newkey,
key->source = dns_keysource_zoneapex;
ISC_LIST_APPEND(*keylist, key, link);
*newkey = NULL;
+ return (ISC_R_SUCCESS);
}
@@ -1466,7 +1538,7 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin,
goto skip;
if (public) {
- addkey(keylist, &pubkey, savekeys, mctx);
+ RETERR(addkey(keylist, &pubkey, savekeys, mctx));
goto skip;
}
@@ -1519,7 +1591,7 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin,
}
if (result == ISC_R_FILENOTFOUND || result == ISC_R_NOPERM) {
- addkey(keylist, &pubkey, savekeys, mctx);
+ RETERR(addkey(keylist, &pubkey, savekeys, mctx));
goto skip;
}
RETERR(result);
@@ -1534,7 +1606,7 @@ dns_dnssec_keylistfromrdataset(dns_name_t *origin,
*/
dst_key_setttl(privkey, dst_key_getttl(pubkey));
- addkey(keylist, &privkey, savekeys, mctx);
+ RETERR(addkey(keylist, &privkey, savekeys, mctx));
skip:
if (pubkey != NULL)
dst_key_free(&pubkey);
diff --git a/lib/dns/ds.c b/lib/dns/ds.c
index 3c74d1da..e72ecbb6 100644
--- a/lib/dns/ds.c
+++ b/lib/dns/ds.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -52,12 +52,13 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
{
dns_fixedname_t fname;
dns_name_t *name;
- unsigned char digest[ISC_SHA256_DIGESTLENGTH];
+ unsigned char digest[ISC_SHA384_DIGESTLENGTH];
isc_region_t r;
isc_buffer_t b;
dns_rdata_ds_t ds;
isc_sha1_t sha1;
isc_sha256_t sha256;
+ isc_sha384_t sha384;
#ifdef HAVE_OPENSSL_GOST
EVP_MD_CTX ctx;
const EVP_MD *md;
@@ -86,17 +87,18 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
isc_sha1_update(&sha1, r.base, r.length);
isc_sha1_final(&sha1, digest);
break;
+
#ifdef HAVE_OPENSSL_GOST
#define CHECK(x) \
if ((x) != 1) { \
EVP_MD_CTX_cleanup(&ctx); \
- return (DST_R_OPENSSLFAILURE); \
+ return (DST_R_CRYPTOFAILURE); \
}
case DNS_DSDIGEST_GOST:
md = EVP_gost();
if (md == NULL)
- return (DST_R_OPENSSLFAILURE);
+ return (DST_R_CRYPTOFAILURE);
EVP_MD_CTX_init(&ctx);
CHECK(EVP_DigestInit(&ctx, md));
dns_name_toregion(name, &r);
@@ -111,6 +113,18 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
CHECK(EVP_DigestFinal(&ctx, digest, NULL));
break;
#endif
+
+ case DNS_DSDIGEST_SHA384:
+ isc_sha384_init(&sha384);
+ dns_name_toregion(name, &r);
+ isc_sha384_update(&sha384, r.base, r.length);
+ dns_rdata_toregion(key, &r);
+ INSIST(r.length >= 4);
+ isc_sha384_update(&sha384, r.base, r.length);
+ isc_sha384_final(digest, &sha384);
+ break;
+
+ case DNS_DSDIGEST_SHA256:
default:
isc_sha256_init(&sha256);
dns_name_toregion(name, &r);
@@ -132,11 +146,18 @@ dns_ds_buildrdata(dns_name_t *owner, dns_rdata_t *key,
case DNS_DSDIGEST_SHA1:
ds.length = ISC_SHA1_DIGESTLENGTH;
break;
+
#ifdef HAVE_OPENSSL_GOST
case DNS_DSDIGEST_GOST:
ds.length = ISC_GOST_DIGESTLENGTH;
break;
#endif
+
+ case DNS_DSDIGEST_SHA384:
+ ds.length = ISC_SHA384_DIGESTLENGTH;
+ break;
+
+ case DNS_DSDIGEST_SHA256:
default:
ds.length = ISC_SHA256_DIGESTLENGTH;
break;
@@ -152,9 +173,11 @@ dns_ds_digest_supported(unsigned int digest_type) {
#ifdef HAVE_OPENSSL_GOST
return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
digest_type == DNS_DSDIGEST_SHA256 ||
- digest_type == DNS_DSDIGEST_GOST));
+ digest_type == DNS_DSDIGEST_GOST ||
+ digest_type == DNS_DSDIGEST_SHA384));
#else
return (ISC_TF(digest_type == DNS_DSDIGEST_SHA1 ||
- digest_type == DNS_DSDIGEST_SHA256));
+ digest_type == DNS_DSDIGEST_SHA256 ||
+ digest_type == DNS_DSDIGEST_SHA384));
#endif
}
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
index a94abff0..12822bed 100644
--- a/lib/dns/dst_api.c
+++ b/lib/dns/dst_api.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2012 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
@@ -56,6 +56,9 @@
#include <isc/string.h>
#include <isc/time.h>
#include <isc/util.h>
+#include <isc/file.h>
+
+#define DST_KEY_INTERNAL
#include <dns/fixedname.h>
#include <dns/keyvalues.h>
@@ -227,6 +230,10 @@ dst_lib_init2(isc_mem_t *mctx, isc_entropy_t *ectx,
#ifdef HAVE_OPENSSL_GOST
RETERR(dst__opensslgost_init(&dst_t_func[DST_ALG_ECCGOST]));
#endif
+#ifdef HAVE_OPENSSL_ECDSA
+ RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA256]));
+ RETERR(dst__opensslecdsa_init(&dst_t_func[DST_ALG_ECDSA384]));
+#endif
#endif /* OPENSSL */
#ifdef GSSAPI
RETERR(dst__gssapi_init(&dst_t_func[DST_ALG_GSSAPI]));
@@ -359,6 +366,25 @@ dst_context_verify(dst_context_t *dctx, isc_region_t *sig) {
}
isc_result_t
+dst_context_verify2(dst_context_t *dctx, unsigned int maxbits,
+ isc_region_t *sig)
+{
+ REQUIRE(VALID_CTX(dctx));
+ REQUIRE(sig != NULL);
+
+ CHECKALG(dctx->key->key_alg);
+ if (dctx->key->keydata.generic == NULL)
+ return (DST_R_NULLKEY);
+ if (dctx->key->func->verify == NULL &&
+ dctx->key->func->verify2 == NULL)
+ return (DST_R_NOTPUBLICKEY);
+
+ return (dctx->key->func->verify2 != NULL ?
+ dctx->key->func->verify2(dctx, maxbits, sig) :
+ dctx->key->func->verify(dctx, sig));
+}
+
+isc_result_t
dst_key_computesecret(const dst_key_t *pub, const dst_key_t *priv,
isc_buffer_t *secret)
{
@@ -736,6 +762,40 @@ out:
}
isc_result_t
+dst_key_buildinternal(dns_name_t *name, unsigned int alg,
+ unsigned int bits, unsigned int flags,
+ unsigned int protocol, dns_rdataclass_t rdclass,
+ void *data, isc_mem_t *mctx, dst_key_t **keyp)
+{
+ dst_key_t *key;
+ isc_result_t result;
+
+ REQUIRE(dst_initialized == ISC_TRUE);
+ REQUIRE(dns_name_isabsolute(name));
+ REQUIRE(mctx != NULL);
+ REQUIRE(keyp != NULL && *keyp == NULL);
+ REQUIRE(data != NULL);
+
+ CHECKALG(alg);
+
+ key = get_key_struct(name, alg, flags, protocol, bits, rdclass,
+ 0, mctx);
+ if (key == NULL)
+ return (ISC_R_NOMEMORY);
+
+ key->keydata.generic = data;
+
+ result = computeid(key);
+ if (result != ISC_R_SUCCESS) {
+ dst_key_free(&key);
+ return (result);
+ }
+
+ *keyp = key;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags,
unsigned int protocol, dns_rdataclass_t rdclass,
const char *engine, const char *label, const char *pin,
@@ -1112,6 +1172,12 @@ dst_key_sigsize(const dst_key_t *key, unsigned int *n) {
case DST_ALG_ECCGOST:
*n = DNS_SIG_GOSTSIGSIZE;
break;
+ case DST_ALG_ECDSA256:
+ *n = DNS_SIG_ECDSA256SIZE;
+ break;
+ case DST_ALG_ECDSA384:
+ *n = DNS_SIG_ECDSA384SIZE;
+ break;
case DST_ALG_HMACMD5:
*n = 16;
break;
@@ -1420,6 +1486,8 @@ issymmetric(const dst_key_t *key) {
case DST_ALG_NSEC3DSA:
case DST_ALG_DH:
case DST_ALG_ECCGOST:
+ case DST_ALG_ECDSA256:
+ case DST_ALG_ECDSA384:
return (ISC_FALSE);
case DST_ALG_HMACMD5:
case DST_ALG_GSSAPI:
@@ -1698,7 +1766,8 @@ algorithm_status(unsigned int alg) {
alg == DST_ALG_HMACMD5 || alg == DST_ALG_NSEC3DSA ||
alg == DST_ALG_NSEC3RSASHA1 ||
alg == DST_ALG_RSASHA256 || alg == DST_ALG_RSASHA512 ||
- alg == DST_ALG_ECCGOST)
+ alg == DST_ALG_ECCGOST ||
+ alg == DST_ALG_ECDSA256 || alg == DST_ALG_ECDSA384)
return (DST_R_NOCRYPTO);
#endif
return (DST_R_UNSUPPORTEDALG);
diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h
index f2906d75..d9d75672 100644
--- a/lib/dns/dst_internal.h
+++ b/lib/dns/dst_internal.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2012 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
@@ -170,6 +170,8 @@ struct dst_func {
*/
isc_result_t (*sign)(dst_context_t *dctx, isc_buffer_t *sig);
isc_result_t (*verify)(dst_context_t *dctx, const isc_region_t *sig);
+ isc_result_t (*verify2)(dst_context_t *dctx, int maxbits,
+ const isc_region_t *sig);
isc_result_t (*computesecret)(const dst_key_t *pub,
const dst_key_t *priv,
isc_buffer_t *secret);
@@ -218,6 +220,9 @@ isc_result_t dst__gssapi_init(struct dst_func **funcp);
#ifdef HAVE_OPENSSL_GOST
isc_result_t dst__opensslgost_init(struct dst_func **funcp);
#endif
+#ifdef HAVE_OPENSSL_ECDSA
+isc_result_t dst__opensslecdsa_init(struct dst_func **funcp);
+#endif
/*%
* Destructors
diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h
index cc9929fc..22071c08 100644
--- a/lib/dns/dst_openssl.h
+++ b/lib/dns/dst_openssl.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -39,6 +39,9 @@ ISC_LANG_BEGINDECLS
isc_result_t
dst__openssl_toresult(isc_result_t fallback);
+isc_result_t
+dst__openssl_toresult2(const char *funcname, isc_result_t fallback);
+
#ifdef USE_ENGINE
ENGINE *
dst__openssl_getengine(const char *engine);
diff --git a/lib/dns/dst_parse.c b/lib/dns/dst_parse.c
index ee513d55..ca43cb3d 100644
--- a/lib/dns/dst_parse.c
+++ b/lib/dns/dst_parse.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2012 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
@@ -44,8 +44,10 @@
#include <isc/stdtime.h>
#include <isc/string.h>
#include <isc/util.h>
+#include <isc/file.h>
#include <dns/time.h>
+#include <dns/log.h>
#include "dst_internal.h"
#include "dst_parse.h"
@@ -106,6 +108,8 @@ static struct parse_map map[] = {
{TAG_GOST_PRIVASN1, "GostAsn1:"},
+ {TAG_ECDSA_PRIVATEKEY, "PrivateKey:"},
+
{TAG_HMACMD5_KEY, "Key:"},
{TAG_HMACMD5_BITS, "Bits:"},
@@ -251,6 +255,15 @@ check_gost(const dst_private_t *priv) {
}
static int
+check_ecdsa(const dst_private_t *priv) {
+ if (priv->nelements != ECDSA_NTAGS)
+ return (-1);
+ if (priv->elements[0].tag != TAG(DST_ALG_ECDSA256, 0))
+ return (-1);
+ return (0);
+}
+
+static int
check_hmac_md5(const dst_private_t *priv, isc_boolean_t old) {
int i, j;
@@ -302,13 +315,20 @@ check_data(const dst_private_t *priv, const unsigned int alg,
switch (alg) {
case DST_ALG_RSAMD5:
case DST_ALG_RSASHA1:
+ case DST_ALG_NSEC3RSASHA1:
+ case DST_ALG_RSASHA256:
+ case DST_ALG_RSASHA512:
return (check_rsa(priv));
case DST_ALG_DH:
return (check_dh(priv));
case DST_ALG_DSA:
+ case DST_ALG_NSEC3DSA:
return (check_dsa(priv));
case DST_ALG_ECCGOST:
return (check_gost(priv));
+ case DST_ALG_ECDSA256:
+ case DST_ALG_ECDSA384:
+ return (check_ecdsa(priv));
case DST_ALG_HMACMD5:
return (check_hmac_md5(priv, old));
case DST_ALG_HMACSHA1:
@@ -345,7 +365,7 @@ isc_result_t
dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
isc_mem_t *mctx, dst_private_t *priv)
{
- int n = 0, major, minor;
+ int n = 0, major, minor, check;
isc_buffer_t b;
isc_token_t token;
unsigned char *data = NULL;
@@ -515,8 +535,14 @@ dst__privstruct_parse(dst_key_t *key, unsigned int alg, isc_lex_t *lex,
data = NULL;
}
done:
- if (check_data(priv, alg, ISC_TRUE) < 0)
+ check = check_data(priv, alg, ISC_TRUE);
+ if (check < 0) {
+ ret = DST_R_INVALIDPRIVATEKEY;
+ goto fail;
+ } else if (check != ISC_R_SUCCESS) {
+ ret = check;
goto fail;
+ }
return (ISC_R_SUCCESS);
@@ -533,7 +559,6 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
const char *directory)
{
FILE *fp;
- int ret, i;
isc_result_t result;
char filename[ISC_DIR_NAMEMAX];
char buffer[MAXFIELDSIZE * 2];
@@ -543,16 +568,32 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
isc_buffer_t b;
isc_region_t r;
int major, minor;
+ mode_t mode;
+ int i, ret;
REQUIRE(priv != NULL);
- if (check_data(priv, dst_key_alg(key), ISC_FALSE) < 0)
+ ret = check_data(priv, dst_key_alg(key), ISC_FALSE);
+ if (ret < 0)
return (DST_R_INVALIDPRIVATEKEY);
+ else if (ret != ISC_R_SUCCESS)
+ return (ret);
isc_buffer_init(&b, filename, sizeof(filename));
- ret = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b);
- if (ret != ISC_R_SUCCESS)
- return (ret);
+ result = dst_key_buildfilename(key, DST_TYPE_PRIVATE, directory, &b);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = isc_file_mode(filename, &mode);
+ if (result == ISC_R_SUCCESS && mode != 0600) {
+ /* File exists; warn that we are changing its permissions */
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_DNSSEC, ISC_LOG_WARNING,
+ "Permissions on the file %s "
+ "have changed from 0%o to 0600 as "
+ "a result of this operation.",
+ filename, (unsigned int)mode);
+ }
if ((fp = fopen(filename, "w")) == NULL)
return (DST_R_WRITEERROR);
@@ -603,6 +644,12 @@ dst__privstruct_writefile(const dst_key_t *key, const dst_private_t *priv,
case DST_ALG_ECCGOST:
fprintf(fp, "(ECC-GOST)\n");
break;
+ case DST_ALG_ECDSA256:
+ fprintf(fp, "(ECDSAP256SHA256)\n");
+ break;
+ case DST_ALG_ECDSA384:
+ fprintf(fp, "(ECDSAP384SHA384)\n");
+ break;
case DST_ALG_HMACMD5:
fprintf(fp, "(HMAC_MD5)\n");
break;
diff --git a/lib/dns/dst_parse.h b/lib/dns/dst_parse.h
index 91b072fb..f048bf0c 100644
--- a/lib/dns/dst_parse.h
+++ b/lib/dns/dst_parse.h
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2010, 2012 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
@@ -81,6 +81,9 @@
#define GOST_NTAGS 1
#define TAG_GOST_PRIVASN1 ((DST_ALG_ECCGOST << TAG_SHIFT) + 0)
+#define ECDSA_NTAGS 1
+#define TAG_ECDSA_PRIVATEKEY ((DST_ALG_ECDSA256 << TAG_SHIFT) + 0)
+
#define OLD_HMACMD5_NTAGS 1
#define HMACMD5_NTAGS 2
#define TAG_HMACMD5_KEY ((DST_ALG_HMACMD5 << TAG_SHIFT) + 0)
diff --git a/lib/dns/dst_result.c b/lib/dns/dst_result.c
index 429dbb2f..297e809c 100644
--- a/lib/dns/dst_result.c
+++ b/lib/dns/dst_result.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -30,7 +30,7 @@
static const char *text[DST_R_NRESULTS] = {
"algorithm is unsupported", /*%< 0 */
- "openssl failure", /*%< 1 */
+ "crypto failure", /*%< 1 */
"built with no crypto support", /*%< 2 */
"illegal operation for a null key", /*%< 3 */
"public key is invalid", /*%< 4 */
diff --git a/lib/dns/gssapi_link.c b/lib/dns/gssapi_link.c
index 381ba102..5ad81cd8 100644
--- a/lib/dns/gssapi_link.c
+++ b/lib/dns/gssapi_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -362,6 +362,7 @@ static dst_func_t gssapi_functions = {
gssapi_adddata,
gssapi_sign,
gssapi_verify,
+ NULL, /*%< verify2 */
NULL, /*%< computesecret */
gssapi_compare,
NULL, /*%< paramcompare */
diff --git a/lib/dns/hmac_link.c b/lib/dns/hmac_link.c
index bc0e9a04..256abb6e 100644
--- a/lib/dns/hmac_link.c
+++ b/lib/dns/hmac_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2012 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
@@ -313,6 +313,7 @@ static dst_func_t hmacmd5_functions = {
hmacmd5_adddata,
hmacmd5_sign,
hmacmd5_verify,
+ NULL, /*%< verify2 */
NULL, /*%< computesecret */
hmacmd5_compare,
NULL, /*%< paramcompare */
@@ -589,6 +590,7 @@ static dst_func_t hmacsha1_functions = {
hmacsha1_adddata,
hmacsha1_sign,
hmacsha1_verify,
+ NULL, /* verify2 */
NULL, /* computesecret */
hmacsha1_compare,
NULL, /* paramcompare */
@@ -867,6 +869,7 @@ static dst_func_t hmacsha224_functions = {
hmacsha224_adddata,
hmacsha224_sign,
hmacsha224_verify,
+ NULL, /* verify2 */
NULL, /* computesecret */
hmacsha224_compare,
NULL, /* paramcompare */
@@ -1145,6 +1148,7 @@ static dst_func_t hmacsha256_functions = {
hmacsha256_adddata,
hmacsha256_sign,
hmacsha256_verify,
+ NULL, /* verify2 */
NULL, /* computesecret */
hmacsha256_compare,
NULL, /* paramcompare */
@@ -1423,6 +1427,7 @@ static dst_func_t hmacsha384_functions = {
hmacsha384_adddata,
hmacsha384_sign,
hmacsha384_verify,
+ NULL, /* verify2 */
NULL, /* computesecret */
hmacsha384_compare,
NULL, /* paramcompare */
@@ -1701,6 +1706,7 @@ static dst_func_t hmacsha512_functions = {
hmacsha512_adddata,
hmacsha512_sign,
hmacsha512_verify,
+ NULL, /* verify2 */
NULL, /* computesecret */
hmacsha512_compare,
NULL, /* paramcompare */
diff --git a/lib/dns/include/Makefile.in b/lib/dns/include/Makefile.in
index b52cb980..10d798d9 100644
--- a/lib/dns/include/Makefile.in
+++ b/lib/dns/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/dns/include/dns/Makefile.in b/lib/dns/include/dns/Makefile.in
index 5b2e78d0..1a69f2c8 100644
--- a/lib/dns/include/dns/Makefile.in
+++ b/lib/dns/include/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index 48b5a26e..a5edbce2 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011, 2012 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: db.h,v 1.107 2011/10/13 01:32:34 vjs Exp $ */
+/* $Id: db.h,v 1.107.4.1 2011/10/23 20:12:08 vjs Exp $ */
#ifndef DNS_DB_H
#define DNS_DB_H 1
@@ -173,7 +173,7 @@ typedef struct dns_dbmethods {
isc_boolean_t (*isdnssec)(dns_db_t *db);
dns_stats_t *(*getrrsetstats)(dns_db_t *db);
void (*rpz_enabled)(dns_db_t *db, dns_rpz_st_t *st);
- isc_result_t (*rpz_findips)(dns_rpz_zone_t *rpz,
+ void (*rpz_findips)(dns_rpz_zone_t *rpz,
dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db,
dns_dbversion_t *version,
@@ -770,6 +770,10 @@ dns_db_findext(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* that it is correct. This only affects answers returned from the
* cache.
*
+ * \li In the #DNS_DBFIND_FORCENSEC3 option is set, then we are looking
+ * in the NSEC3 tree and not the main tree. Without this option being
+ * set NSEC3 records will not be found.
+ *
* \li To respond to a query for SIG records, the caller should create a
* rdataset iterator and extract the signatures from each rdataset.
*
@@ -1545,7 +1549,7 @@ dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
* DNS_RPZ_TYPE_NSDNAME records.
*/
-isc_result_t
+void
dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
@@ -1562,10 +1566,6 @@ dns_db_rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
* \li 'ardataset' is an A or AAAA rdataset of addresses to check
* \li 'found' specifies the previous best match if any or
* or NULL, an empty name, 0, DNS_RPZ_POLICY_MISS, and 0
- *
- * Returns:
- * \li #ISC_R_SUCCESS
- * \li #ISC_R_UNEXPECTED
*/
ISC_LANG_ENDDECLS
diff --git a/lib/dns/include/dns/dnssec.h b/lib/dns/include/dns/dnssec.h
index 68df540a..e443f91b 100644
--- a/lib/dns/include/dns/dnssec.h
+++ b/lib/dns/include/dns/dnssec.h
@@ -24,6 +24,7 @@
#include <isc/lang.h>
#include <isc/stdtime.h>
+#include <isc/stats.h>
#include <dns/diff.h>
#include <dns/types.h>
@@ -32,6 +33,8 @@
ISC_LANG_BEGINDECLS
+LIBDNS_EXTERNAL_DATA extern isc_stats_t *dns_dnssec_stats;
+
/*%< Maximum number of keys supported in a zone. */
#define DNS_MAXZONEKEYS 32
@@ -96,8 +99,8 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_stdtime_t *inception, isc_stdtime_t *expire,
isc_mem_t *mctx, isc_buffer_t *buffer, dns_rdata_t *sigrdata);
/*%<
- * Generates a SIG record covering this rdataset. This has no effect
- * on existing SIG records.
+ * Generates a RRSIG record covering this rdataset. This has no effect
+ * on existing RRSIG records.
*
* Requires:
*\li 'name' (the owner name of the record) is a valid name
@@ -129,12 +132,19 @@ isc_result_t
dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
isc_boolean_t ignoretime, isc_mem_t *mctx,
dns_rdata_t *sigrdata, dns_name_t *wild);
+
+isc_result_t
+dns_dnssec_verify3(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
+ isc_boolean_t ignoretime, unsigned int maxbits,
+ isc_mem_t *mctx, dns_rdata_t *sigrdata, dns_name_t *wild);
/*%<
- * Verifies the SIG record covering this rdataset signed by a specific
- * key. This does not determine if the key's owner is authorized to
- * sign this record, as this requires a resolver or database.
+ * Verifies the RRSIG record covering this rdataset signed by a specific
+ * key. This does not determine if the key's owner is authorized to sign
+ * this record, as this requires a resolver or database.
* If 'ignoretime' is ISC_TRUE, temporal validity will not be checked.
*
+ * 'maxbits' specifies the maximum number of rsa exponent bits accepted.
+ *
* Requires:
*\li 'name' (the owner name of the record) is a valid name
*\li 'set' is a valid rdataset
diff --git a/lib/dns/include/dns/ds.h b/lib/dns/include/dns/ds.h
index b20b4086..03ab0ed0 100644
--- a/lib/dns/include/dns/ds.h
+++ b/lib/dns/include/dns/ds.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -27,15 +27,16 @@
#define DNS_DSDIGEST_SHA1 (1)
#define DNS_DSDIGEST_SHA256 (2)
#define DNS_DSDIGEST_GOST (3)
+#define DNS_DSDIGEST_SHA384 (4)
/* should not be here... */
#define ISC_GOST_DIGESTLENGTH 32U
/*
- * Assuming SHA-256 digest type.
+ * Assuming SHA-384 digest type.
*/
-#define DNS_DS_BUFFERSIZE (36)
+#define DNS_DS_BUFFERSIZE (52)
ISC_LANG_BEGINDECLS
diff --git a/lib/dns/include/dns/iptable.h b/lib/dns/include/dns/iptable.h
index d7eb140d..2ce8e181 100644
--- a/lib/dns/include/dns/iptable.h
+++ b/lib/dns/include/dns/iptable.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -23,6 +23,8 @@
#include <isc/magic.h>
#include <isc/radix.h>
+#include <dns/types.h>
+
struct dns_iptable {
unsigned int magic;
isc_mem_t *mctx;
diff --git a/lib/dns/include/dns/keyvalues.h b/lib/dns/include/dns/keyvalues.h
index 55c0b8fc..0c392ca1 100644
--- a/lib/dns/include/dns/keyvalues.h
+++ b/lib/dns/include/dns/keyvalues.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010, 2012 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
@@ -71,6 +71,8 @@
#define DNS_KEYALG_RSASHA256 8
#define DNS_KEYALG_RSASHA512 10
#define DNS_KEYALG_ECCGOST 12
+#define DNS_KEYALG_ECDSA256 13
+#define DNS_KEYALG_ECDSA384 14
#define DNS_KEYALG_INDIRECT 252
#define DNS_KEYALG_PRIVATEDNS 253
#define DNS_KEYALG_PRIVATEOID 254 /*%< Key begins with OID giving alg */
@@ -101,4 +103,10 @@
#define DNS_SIG_GOSTSIGSIZE 64
+#define DNS_SIG_ECDSA256SIZE 64
+#define DNS_SIG_ECDSA384SIZE 96
+
+#define DNS_KEY_ECDSA256SIZE 64
+#define DNS_KEY_ECDSA384SIZE 96
+
#endif /* DNS_KEYVALUES_H */
diff --git a/lib/dns/include/dns/log.h b/lib/dns/include/dns/log.h
index 2060a33c..3c4df8a4 100644
--- a/lib/dns/include/dns/log.h
+++ b/lib/dns/include/dns/log.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011, 2012 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
@@ -75,6 +75,7 @@ LIBDNS_EXTERNAL_DATA extern isc_logmodule_t dns_modules[];
#define DNS_LOGMODULE_ACACHE (&dns_modules[25])
#define DNS_LOGMODULE_DLZ (&dns_modules[26])
#define DNS_LOGMODULE_DNSSEC (&dns_modules[27])
+#define DNS_LOGMODULE_CRYPTO (&dns_modules[28])
ISC_LANG_BEGINDECLS
diff --git a/lib/dns/include/dns/nsec.h b/lib/dns/include/dns/nsec.h
index fca843a1..bdcd2eec 100644
--- a/lib/dns/include/dns/nsec.h
+++ b/lib/dns/include/dns/nsec.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2011, 2012 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
@@ -76,6 +76,28 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
* 'answer' to be non NULL.
*/
+unsigned int
+dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw,
+ unsigned int max_type);
+/*%<
+ * Convert a raw bitmap into a compressed windowed bit map. 'map' and 'raw'
+ * may overlap.
+ *
+ * Returns the length of the compressed windowed bit map.
+ */
+
+void
+dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit);
+/*%<
+ * Set type bit in raw 'array' to 'bit'.
+ */
+
+isc_boolean_t
+dns_nsec_isset(const unsigned char *array, unsigned int type);
+/*%<
+ * Test if the corresponding 'type' bit is set in 'array'.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_NSEC_H */
diff --git a/lib/dns/include/dns/private.h b/lib/dns/include/dns/private.h
index 91fff5f7..c4a2ae64 100644
--- a/lib/dns/include/dns/private.h
+++ b/lib/dns/include/dns/private.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -51,15 +51,15 @@ dns_private_chains(dns_db_t *db, dns_dbversion_t *ver,
*/
isc_result_t
-dns_private_totext(dns_rdata_t *private, isc_buffer_t *buffer);
+dns_private_totext(dns_rdata_t *privaterdata, isc_buffer_t *buffer);
/*%<
- * Convert a private-type RR 'private' to human-readable form,
+ * Convert a private-type RR 'privaterdata' to human-readable form,
* and place the result in 'buffer'. The text should indicate
* which action the private-type record specifies and whether the
* action has been completed.
*
* Requires:
- * \li 'private' is a valid rdata containing at least five bytes
+ * \li 'privaterdata' is a valid rdata containing at least five bytes
* \li 'buffer' is a valid buffer
*
* Returns:
diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h
index a82b03b1..2c7b2730 100644
--- a/lib/dns/include/dns/rdata.h
+++ b/lib/dns/include/dns/rdata.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/dns/include/dns/rdataset.h b/lib/dns/include/dns/rdataset.h
index f6a55e3b..31bcd15f 100644
--- a/lib/dns/include/dns/rdataset.h
+++ b/lib/dns/include/dns/rdataset.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -56,6 +56,7 @@
#include <isc/stdtime.h>
#include <dns/types.h>
+#include <dns/rdatastruct.h>
ISC_LANG_BEGINDECLS
@@ -651,6 +652,25 @@ dns_rdataset_expire(dns_rdataset_t *rdataset);
* Mark the rdataset to be expired in the backing database.
*/
+void
+dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+ dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
+ isc_boolean_t acceptexpired);
+/*%<
+ * Trim the ttl of 'rdataset' and 'sigrdataset' so that they will expire
+ * at or before 'rrsig->expiretime'. If 'acceptexpired' is true and the
+ * signature has expired or will expire in the next 120 seconds, limit
+ * the ttl to be no more than 120 seconds.
+ *
+ * The ttl is further limited by the original ttl as stored in 'rrsig'
+ * and the original ttl values of 'rdataset' and 'sigrdataset'.
+ *
+ * Requires:
+ * \li 'rdataset' is a valid rdataset.
+ * \li 'sigrdataset' is a valid rdataset.
+ * \li 'rrsig' is non NULL.
+ */
+
const char *
dns_trust_totext(dns_trust_t trust);
/*
diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h
index accec2ab..03db8d33 100644
--- a/lib/dns/include/dns/rpz.h
+++ b/lib/dns/include/dns/rpz.h
@@ -30,6 +30,7 @@ ISC_LANG_BEGINDECLS
#define DNS_RPZ_IP_ZONE "rpz-ip"
#define DNS_RPZ_NSIP_ZONE "rpz-nsip"
#define DNS_RPZ_NSDNAME_ZONE "rpz-nsdname"
+#define DNS_RPZ_PASSTHRU_ZONE "rpz-passthru"
typedef isc_uint8_t dns_rpz_cidr_bits_t;
@@ -66,11 +67,14 @@ typedef struct dns_rpz_zone dns_rpz_zone_t;
struct dns_rpz_zone {
ISC_LINK(dns_rpz_zone_t) link;
- int num;
+ int num; /* ordinal in list of policy zones */
dns_name_t origin; /* Policy zone name */
dns_name_t nsdname; /* DNS_RPZ_NSDNAME_ZONE.origin */
- dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
+ dns_name_t passthru;/* DNS_RPZ_PASSTHRU_ZONE. */
dns_name_t cname; /* override value for ..._CNAME */
+ dns_ttl_t max_policy_ttl;
+ dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
+ isc_boolean_t recursive_only;
};
/*
@@ -143,6 +147,7 @@ typedef struct {
} dns_rpz_st_t;
#define DNS_RPZ_TTL_DEFAULT 5
+#define DNS_RPZ_MAX_TTL_DEFAULT DNS_RPZ_TTL_DEFAULT
/*
* So various response policy zone messages can be turned up or down.
@@ -152,6 +157,7 @@ typedef struct {
#define DNS_RPZ_DEBUG_LEVEL1 ISC_LOG_DEBUG(1)
#define DNS_RPZ_DEBUG_LEVEL2 ISC_LOG_DEBUG(2)
#define DNS_RPZ_DEBUG_LEVEL3 ISC_LOG_DEBUG(3)
+#define DNS_RPZ_DEBUG_QUIET (DNS_RPZ_DEBUG_LEVEL3+1)
const char *
dns_rpz_type2str(dns_rpz_type_t type);
@@ -192,7 +198,8 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
dns_name_t *search_name, dns_rpz_cidr_bits_t *prefix);
dns_rpz_policy_t
-dns_rpz_decode_cname(dns_rdataset_t *, dns_name_t *selfname);
+dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
+ dns_name_t *selfname);
ISC_LANG_ENDDECLS
diff --git a/lib/dns/include/dns/stats.h b/lib/dns/include/dns/stats.h
index bc77d1e9..53642672 100644
--- a/lib/dns/include/dns/stats.h
+++ b/lib/dns/include/dns/stats.h
@@ -64,6 +64,16 @@ enum {
dns_resstatscounter_max = 30,
+ /*
+ * DNSSEC stats.
+ */
+ dns_dnssecstats_asis = 0,
+ dns_dnssecstats_downcase = 1,
+ dns_dnssecstats_wildcard = 2,
+ dns_dnssecstats_fail = 3,
+
+ dns_dnssecstats_max = 4,
+
/*%
* Zone statistics counters.
*/
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
index 3d652436..16f8d7a1 100644
--- a/lib/dns/include/dns/view.h
+++ b/lib/dns/include/dns/view.h
@@ -157,11 +157,14 @@ struct dns_view {
dns_name_t * dlv;
dns_fixedname_t dlv_fixed;
isc_uint16_t maxudp;
+ unsigned int maxbits;
dns_v4_aaaa_t v4_aaaa;
dns_acl_t * v4_aaaa_acl;
dns_dns64list_t dns64;
unsigned int dns64cnt;
ISC_LIST(dns_rpz_zone_t) rpz_zones;
+ isc_boolean_t rpz_recursive_only;
+ isc_boolean_t rpz_break_dnssec;
/*
* Configurable data for server use only,
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index e7c754f2..8f32bae4 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -1861,7 +1861,7 @@ dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures);
isc_result_t
dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
- isc_uint16_t keyid, isc_boolean_t delete);
+ isc_uint16_t keyid, isc_boolean_t deleteit);
/*%<
* Initiate/resume signing of the entire zone with the zone DNSKEY(s)
* that match the given algorithm and keyid.
diff --git a/lib/dns/include/dst/Makefile.in b/lib/dns/include/dst/Makefile.in
index 4ed4ec04..cece67dd 100644
--- a/lib/dns/include/dst/Makefile.in
+++ b/lib/dns/include/dst/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
index 7a1d938d..66501df4 100644
--- a/lib/dns/include/dst/dst.h
+++ b/lib/dns/include/dst/dst.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -59,6 +59,8 @@ typedef struct dst_context dst_context_t;
#define DST_ALG_RSASHA256 8
#define DST_ALG_RSASHA512 10
#define DST_ALG_ECCGOST 12
+#define DST_ALG_ECDSA256 13
+#define DST_ALG_ECDSA384 14
#define DST_ALG_HMACMD5 157
#define DST_ALG_GSSAPI 160
#define DST_ALG_HMACSHA1 161 /* XXXMPA */
@@ -231,9 +233,16 @@ dst_context_sign(dst_context_t *dctx, isc_buffer_t *sig);
isc_result_t
dst_context_verify(dst_context_t *dctx, isc_region_t *sig);
+
+isc_result_t
+dst_context_verify2(dst_context_t *dctx, unsigned int maxbits,
+ isc_region_t *sig);
/*%<
* Verifies the signature using the data and key stored in the context.
*
+ * 'maxbits' specifies the maximum number of bits permitted in the RSA
+ * exponent.
+ *
* Requires:
* \li "dctx" is a valid context.
* \li "sig" is a valid region.
@@ -490,6 +499,14 @@ dst_key_fromgssapi(dns_name_t *name, gss_ctx_id_t gssctx, isc_mem_t *mctx,
* the context id.
*/
+#ifdef DST_KEY_INTERNAL
+isc_result_t
+dst_key_buildinternal(dns_name_t *name, unsigned int alg,
+ unsigned int bits, unsigned int flags,
+ unsigned int protocol, dns_rdataclass_t rdclass,
+ void *data, isc_mem_t *mctx, dst_key_t **keyp);
+#endif
+
isc_result_t
dst_key_fromlabel(dns_name_t *name, int alg, unsigned int flags,
unsigned int protocol, dns_rdataclass_t rdclass,
@@ -510,6 +527,7 @@ dst_key_generate2(dns_name_t *name, unsigned int alg,
dns_rdataclass_t rdclass,
isc_mem_t *mctx, dst_key_t **keyp,
void (*callback)(int));
+
/*%<
* Generate a DST key (or keypair) with the supplied parameters. The
* interpretation of the "param" field depends on the algorithm:
diff --git a/lib/dns/include/dst/result.h b/lib/dns/include/dst/result.h
index d77b72e7..00640a1b 100644
--- a/lib/dns/include/dst/result.h
+++ b/lib/dns/include/dst/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -34,7 +34,9 @@
#include <isc/result.h> /* Contractual promise. */
#define DST_R_UNSUPPORTEDALG (ISC_RESULTCLASS_DST + 0)
-#define DST_R_OPENSSLFAILURE (ISC_RESULTCLASS_DST + 1)
+#define DST_R_CRYPTOFAILURE (ISC_RESULTCLASS_DST + 1)
+/* compat */
+#define DST_R_OPENSSLFAILURE DST_R_CRYPTOFAILURE
#define DST_R_NOCRYPTO (ISC_RESULTCLASS_DST + 2)
#define DST_R_NULLKEY (ISC_RESULTCLASS_DST + 3)
#define DST_R_INVALIDPUBLICKEY (ISC_RESULTCLASS_DST + 4)
diff --git a/lib/dns/log.c b/lib/dns/log.c
index e6fbb53a..c4d644e3 100644
--- a/lib/dns/log.c
+++ b/lib/dns/log.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2011, 2012 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
@@ -81,6 +81,7 @@ LIBDNS_EXTERNAL_DATA isc_logmodule_t dns_modules[] = {
{ "dns/acache", 0 },
{ "dns/dlz", 0 },
{ "dns/dnssec", 0 },
+ { "dns/crypto", 0 },
{ NULL, 0 }
};
diff --git a/lib/dns/master.c b/lib/dns/master.c
index 7b1ccdf8..a8a456d7 100644
--- a/lib/dns/master.c
+++ b/lib/dns/master.c
@@ -2078,20 +2078,22 @@ load_raw(dns_loadctx_t *lctx) {
unsigned int loop_cnt = 0;
dns_rdatacallbacks_t *callbacks;
unsigned char namebuf[DNS_NAME_MAXWIRE];
- isc_region_t r;
- dns_name_t name;
+ dns_fixedname_t fixed;
+ dns_name_t *name;
rdatalist_head_t head, dummy;
dns_rdatalist_t rdatalist;
isc_mem_t *mctx = lctx->mctx;
dns_rdata_t *rdata = NULL;
unsigned int rdata_size = 0;
int target_size = TSIZ;
- isc_buffer_t target;
+ isc_buffer_t target, buf;
unsigned char *target_mem = NULL;
dns_masterrawheader_t header;
+ dns_decompress_t dctx;
REQUIRE(DNS_LCTX_VALID(lctx));
callbacks = lctx->callbacks;
+ dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
dns_master_initrawheader(&header);
@@ -2171,6 +2173,9 @@ load_raw(dns_loadctx_t *lctx) {
}
isc_buffer_init(&target, target_mem, target_size);
+ dns_fixedname_init(&fixed);
+ name = dns_fixedname_name(&fixed);
+
/*
* In the following loop, we regard any error fatal regardless of
* whether "MANYERRORS" is set in the context option. This is because
@@ -2182,7 +2187,7 @@ load_raw(dns_loadctx_t *lctx) {
for (loop_cnt = 0;
(lctx->loop_cnt == 0 || loop_cnt < lctx->loop_cnt);
loop_cnt++) {
- unsigned int i, rdcount, consumed_name;
+ unsigned int i, rdcount;
isc_uint16_t namelen;
isc_uint32_t totallen;
size_t minlen, readlen;
@@ -2272,12 +2277,11 @@ load_raw(dns_loadctx_t *lctx) {
lctx->f);
if (result != ISC_R_SUCCESS)
goto cleanup;
+
isc_buffer_setactive(&target, (unsigned int)namelen);
- isc_buffer_activeregion(&target, &r);
- dns_name_init(&name, NULL);
- dns_name_fromregion(&name, &r);
- isc_buffer_forward(&target, (unsigned int)namelen);
- consumed_name = isc_buffer_consumedlength(&target);
+ result = dns_name_fromwire(name, &target, &dctx, 0, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
/* Rdata contents. */
if (rdcount > rdata_size) {
@@ -2308,7 +2312,7 @@ load_raw(dns_loadctx_t *lctx) {
/* Partial Commit. */
ISC_LIST_APPEND(head, &rdatalist, link);
- result = commit(callbacks, lctx, &head, &name,
+ result = commit(callbacks, lctx, &head, name,
NULL, 0);
for (j = 0; j < i; j++) {
ISC_LIST_UNLINK(rdatalist.rdata,
@@ -2320,8 +2324,6 @@ load_raw(dns_loadctx_t *lctx) {
/* Rewind the buffer and continue */
isc_buffer_clear(&target);
- isc_buffer_add(&target, consumed_name);
- isc_buffer_forward(&target, consumed_name);
rdcount -= i;
@@ -2341,11 +2343,20 @@ load_raw(dns_loadctx_t *lctx) {
if (result != ISC_R_SUCCESS)
goto cleanup;
isc_buffer_setactive(&target, (unsigned int)rdlen);
- isc_buffer_activeregion(&target, &r);
- isc_buffer_forward(&target, (unsigned int)rdlen);
- dns_rdata_fromregion(&rdata[i], rdatalist.rdclass,
- rdatalist.type, &r);
-
+ /*
+ * It is safe to have the source active region and
+ * the target available region be the same if
+ * decompression is disabled (see dctx above) and we
+ * are not downcasing names (options == 0).
+ */
+ isc_buffer_init(&buf, isc_buffer_current(&target),
+ (unsigned int)rdlen);
+ result = dns_rdata_fromwire(&rdata[i],
+ rdatalist.rdclass,
+ rdatalist.type, &target,
+ &dctx, 0, &buf);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
ISC_LIST_APPEND(rdatalist.rdata, &rdata[i], link);
}
@@ -2362,7 +2373,7 @@ load_raw(dns_loadctx_t *lctx) {
ISC_LIST_APPEND(head, &rdatalist, link);
/* Commit this RRset. rdatalist will be unlinked. */
- result = commit(callbacks, lctx, &head, &name, NULL, 0);
+ result = commit(callbacks, lctx, &head, name, NULL, 0);
for (i = 0; i < rdcount; i++) {
ISC_LIST_UNLINK(rdatalist.rdata, &rdata[i], link);
diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c
index e800715e..2717658e 100644
--- a/lib/dns/masterdump.c
+++ b/lib/dns/masterdump.c
@@ -1614,7 +1614,8 @@ dns_master_dumptostream3(isc_mem_t *mctx, dns_db_t *db,
}
static isc_result_t
-opentmp(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) {
+opentmp(isc_mem_t *mctx, dns_masterformat_t format, const char *file,
+ char **tempp, FILE **fp) {
FILE *f = NULL;
isc_result_t result;
char *tempname = NULL;
@@ -1629,7 +1630,10 @@ opentmp(isc_mem_t *mctx, const char *file, char **tempp, FILE **fp) {
if (result != ISC_R_SUCCESS)
goto cleanup;
- result = isc_file_openunique(tempname, &f);
+ if (format == dns_masterformat_text)
+ result = isc_file_openunique(tempname, &f);
+ else
+ result = isc_file_bopenunique(tempname, &f);
if (result != ISC_R_SUCCESS) {
isc_log_write(dns_lctx, ISC_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_MASTERDUMP, ISC_LOG_ERROR,
@@ -1684,7 +1688,7 @@ dns_master_dumpinc3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
if (file == NULL)
return (ISC_R_NOMEMORY);
- result = opentmp(mctx, filename, &tempname, &f);
+ result = opentmp(mctx, format, filename, &tempname, &f);
if (result != ISC_R_SUCCESS)
goto cleanup;
@@ -1748,7 +1752,7 @@ dns_master_dump3(isc_mem_t *mctx, dns_db_t *db, dns_dbversion_t *version,
char *tempname;
dns_dumpctx_t *dctx = NULL;
- result = opentmp(mctx, filename, &tempname, &f);
+ result = opentmp(mctx, format, filename, &tempname, &f);
if (result != ISC_R_SUCCESS)
return (result);
diff --git a/lib/dns/nsec.c b/lib/dns/nsec.c
index 6e3a69ab..69207d09 100644
--- a/lib/dns/nsec.c
+++ b/lib/dns/nsec.c
@@ -41,28 +41,61 @@
goto failure; \
} while (0)
-static void
-set_bit(unsigned char *array, unsigned int index, unsigned int bit) {
+void
+dns_nsec_setbit(unsigned char *array, unsigned int type, unsigned int bit) {
unsigned int shift, mask;
- shift = 7 - (index % 8);
+ shift = 7 - (type % 8);
mask = 1 << shift;
if (bit != 0)
- array[index / 8] |= mask;
+ array[type / 8] |= mask;
else
- array[index / 8] &= (~mask & 0xFF);
+ array[type / 8] &= (~mask & 0xFF);
}
-static unsigned int
-bit_isset(unsigned char *array, unsigned int index) {
+isc_boolean_t
+dns_nsec_isset(const unsigned char *array, unsigned int type) {
unsigned int byte, shift, mask;
- byte = array[index / 8];
- shift = 7 - (index % 8);
+ byte = array[type / 8];
+ shift = 7 - (type % 8);
mask = 1 << shift;
- return ((byte & mask) != 0);
+ return (ISC_TF(byte & mask));
+}
+
+unsigned int
+dns_nsec_compressbitmap(unsigned char *map, const unsigned char *raw,
+ unsigned int max_type)
+{
+ unsigned char *start = map;
+ unsigned int window;
+ int octet;
+
+ if (raw == NULL)
+ return (0);
+
+ for (window = 0; window < 256; window++) {
+ if (window * 256 > max_type)
+ break;
+ for (octet = 31; octet >= 0; octet--)
+ if (*(raw + octet) != 0)
+ break;
+ if (octet < 0) {
+ raw += 32;
+ continue;
+ }
+ *map++ = window;
+ *map++ = octet + 1;
+ /*
+ * Note: potential overlapping move.
+ */
+ memmove(map, raw, octet + 1);
+ map += octet + 1;
+ raw += 32;
+ }
+ return (map - start);
}
isc_result_t
@@ -73,8 +106,7 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
isc_result_t result;
dns_rdataset_t rdataset;
isc_region_t r;
- unsigned int i, window;
- int octet;
+ unsigned int i;
unsigned char *nsec_bits, *bm;
unsigned int max_type;
@@ -90,8 +122,8 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
*/
bm = r.base + r.length + 512;
nsec_bits = r.base + r.length;
- set_bit(bm, dns_rdatatype_rrsig, 1);
- set_bit(bm, dns_rdatatype_nsec, 1);
+ dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
+ dns_nsec_setbit(bm, dns_rdatatype_nsec, 1);
max_type = dns_rdatatype_nsec;
dns_rdataset_init(&rdataset);
rdsiter = NULL;
@@ -108,7 +140,7 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
rdataset.type != dns_rdatatype_rrsig) {
if (rdataset.type > max_type)
max_type = rdataset.type;
- set_bit(bm, rdataset.type, 1);
+ dns_nsec_setbit(bm, rdataset.type, 1);
}
dns_rdataset_disassociate(&rdataset);
}
@@ -116,12 +148,12 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
/*
* At zone cuts, deny the existence of glue in the parent zone.
*/
- if (bit_isset(bm, dns_rdatatype_ns) &&
- ! bit_isset(bm, dns_rdatatype_soa)) {
+ if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
+ ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
for (i = 0; i <= max_type; i++) {
- if (bit_isset(bm, i) &&
+ if (dns_nsec_isset(bm, i) &&
! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
- set_bit(bm, i, 0);
+ dns_nsec_setbit(bm, i, 0);
}
}
@@ -129,22 +161,8 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
if (result != ISC_R_NOMORE)
return (result);
- for (window = 0; window < 256; window++) {
- if (window * 256 > max_type)
- break;
- for (octet = 31; octet >= 0; octet--)
- if (bm[window * 32 + octet] != 0)
- break;
- if (octet < 0)
- continue;
- nsec_bits[0] = window;
- nsec_bits[1] = octet + 1;
- /*
- * Note: potential overlapping move.
- */
- memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
- nsec_bits += 3 + octet;
- }
+ nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
+
r.length = nsec_bits - r.base;
INSIST(r.length <= DNS_NSEC_BUFFERSIZE);
dns_rdata_fromregion(rdata,
@@ -155,7 +173,6 @@ dns_nsec_buildrdata(dns_db_t *db, dns_dbversion_t *version,
return (ISC_R_SUCCESS);
}
-
isc_result_t
dns_nsec_build(dns_db_t *db, dns_dbversion_t *version, dns_dbnode_t *node,
dns_name_t *target, dns_ttl_t ttl)
@@ -216,8 +233,8 @@ dns_nsec_typepresent(dns_rdata_t *nsec, dns_rdatatype_t type) {
if ((window + 1) * 256 <= type)
continue;
if (type < (window * 256) + len * 8)
- present = ISC_TF(bit_isset(&nsecstruct.typebits[i],
- type % 256));
+ present = ISC_TF(dns_nsec_isset(&nsecstruct.typebits[i],
+ type % 256));
break;
}
dns_rdata_freestruct(&nsecstruct);
diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c
index 44cc6527..4975bf31 100644
--- a/lib/dns/nsec3.c
+++ b/lib/dns/nsec3.c
@@ -33,6 +33,7 @@
#include <dns/dbiterator.h>
#include <dns/diff.h>
#include <dns/fixedname.h>
+#include <dns/nsec.h>
#include <dns/nsec3.h>
#include <dns/rdata.h>
#include <dns/rdatalist.h>
@@ -52,30 +53,6 @@
#define INITIAL(x) (((x) & DNS_NSEC3FLAG_INITIAL) != 0)
#define REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
-static void
-set_bit(unsigned char *array, unsigned int index, unsigned int bit) {
- unsigned int shift, mask;
-
- shift = 7 - (index % 8);
- mask = 1 << shift;
-
- if (bit != 0)
- array[index / 8] |= mask;
- else
- array[index / 8] &= (~mask & 0xFF);
-}
-
-static unsigned int
-bit_isset(unsigned char *array, unsigned int index) {
- unsigned int byte, shift, mask;
-
- byte = array[index / 8];
- shift = 7 - (index % 8);
- mask = 1 << shift;
-
- return ((byte & mask) != 0);
-}
-
isc_result_t
dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
dns_dbnode_t *node, unsigned int hashalg,
@@ -87,8 +64,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
isc_result_t result;
dns_rdataset_t rdataset;
isc_region_t r;
- unsigned int i, window;
- int octet;
+ unsigned int i;
isc_boolean_t found;
isc_boolean_t found_ns;
isc_boolean_t need_rrsig;
@@ -156,7 +132,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
rdataset.type != dns_rdatatype_rrsig) {
if (rdataset.type > max_type)
max_type = rdataset.type;
- set_bit(bm, rdataset.type, 1);
+ dns_nsec_setbit(bm, rdataset.type, 1);
/*
* Work out if we need to set the RRSIG bit for
* this node. We set the RRSIG bit if either of
@@ -179,18 +155,18 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
if ((found && !found_ns) || need_rrsig) {
if (dns_rdatatype_rrsig > max_type)
max_type = dns_rdatatype_rrsig;
- set_bit(bm, dns_rdatatype_rrsig, 1);
+ dns_nsec_setbit(bm, dns_rdatatype_rrsig, 1);
}
/*
* At zone cuts, deny the existence of glue in the parent zone.
*/
- if (bit_isset(bm, dns_rdatatype_ns) &&
- ! bit_isset(bm, dns_rdatatype_soa)) {
+ if (dns_nsec_isset(bm, dns_rdatatype_ns) &&
+ ! dns_nsec_isset(bm, dns_rdatatype_soa)) {
for (i = 0; i <= max_type; i++) {
- if (bit_isset(bm, i) &&
+ if (dns_nsec_isset(bm, i) &&
! dns_rdatatype_iszonecutauth((dns_rdatatype_t)i))
- set_bit(bm, i, 0);
+ dns_nsec_setbit(bm, i, 0);
}
}
@@ -199,22 +175,7 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
return (result);
collapse_bitmap:
- for (window = 0; window < 256; window++) {
- if (window * 256 > max_type)
- break;
- for (octet = 31; octet >= 0; octet--)
- if (bm[window * 32 + octet] != 0)
- break;
- if (octet < 0)
- continue;
- nsec_bits[0] = window;
- nsec_bits[1] = octet + 1;
- /*
- * Note: potentially overlapping move.
- */
- memmove(&nsec_bits[2], &bm[window * 32], octet + 1);
- nsec_bits += 3 + octet;
- }
+ nsec_bits += dns_nsec_compressbitmap(nsec_bits, bm, max_type);
r.length = nsec_bits - r.base;
INSIST(r.length <= DNS_NSEC3_BUFFERSIZE);
dns_rdata_fromregion(rdata, dns_db_class(db), dns_rdatatype_nsec3, &r);
@@ -249,8 +210,8 @@ dns_nsec3_typepresent(dns_rdata_t *rdata, dns_rdatatype_t type) {
if ((window + 1) * 256 <= type)
continue;
if (type < (window * 256) + len * 8)
- present = ISC_TF(bit_isset(&nsec3.typebits[i],
- type % 256));
+ present = ISC_TF(dns_nsec_isset(&nsec3.typebits[i],
+ type % 256));
break;
}
dns_rdata_freestruct(&nsec3);
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
index 59626f20..d186761c 100644
--- a/lib/dns/openssl_link.c
+++ b/lib/dns/openssl_link.c
@@ -45,6 +45,8 @@
#include <isc/thread.h>
#include <isc/util.h>
+#include <dns/log.h>
+
#include <dst/result.h>
#include "dst_internal.h"
@@ -172,6 +174,8 @@ dst__openssl_init(const char *engine) {
CRYPTO_set_locking_callback(lock_callback);
CRYPTO_set_id_callback(id_callback);
+ ERR_load_crypto_strings();
+
rm = mem_alloc(sizeof(RAND_METHOD));
if (rm == NULL) {
result = ISC_R_NOMEMORY;
@@ -285,7 +289,7 @@ dst__openssl_destroy() {
isc_result_t
dst__openssl_toresult(isc_result_t fallback) {
isc_result_t result = fallback;
- int err = ERR_get_error();
+ unsigned long err = ERR_get_error();
switch (ERR_GET_REASON(err)) {
case ERR_R_MALLOC_FAILURE:
@@ -298,6 +302,40 @@ dst__openssl_toresult(isc_result_t fallback) {
return (result);
}
+isc_result_t
+dst__openssl_toresult2(const char *funcname, isc_result_t fallback) {
+ isc_result_t result = fallback;
+ unsigned long err = ERR_peek_error();
+ const char *file, *data;
+ int line, flags;
+ char buf[256];
+
+ switch (ERR_GET_REASON(err)) {
+ case ERR_R_MALLOC_FAILURE:
+ result = ISC_R_NOMEMORY;
+ goto done;
+ default:
+ break;
+ }
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING,
+ "%s failed", funcname);
+ for (;;) {
+ err = ERR_get_error_line_data(&file, &line, &data, &flags);
+ if (err == 0U)
+ goto done;
+ ERR_error_string_n(err, buf, sizeof(buf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
+ DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO,
+ "%s:%s:%d:%s", buf, file, line,
+ (flags & ERR_TXT_STRING) ? data : "");
+ }
+
+ done:
+ ERR_clear_error();
+ return (result);
+}
+
#if defined(USE_ENGINE)
ENGINE *
dst__openssl_getengine(const char *engine) {
diff --git a/lib/dns/openssldh_link.c b/lib/dns/openssldh_link.c
index 71b4b122..36b8a412 100644
--- a/lib/dns/openssldh_link.c
+++ b/lib/dns/openssldh_link.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2009, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2009, 2011, 2012 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
@@ -94,7 +94,8 @@ openssldh_computesecret(const dst_key_t *pub, const dst_key_t *priv,
return (ISC_R_NOSPACE);
ret = DH_compute_key(r.base, dhpub->pub_key, dhpriv);
if (ret == 0)
- return (dst__openssl_toresult(DST_R_COMPUTESECRETFAILURE));
+ return (dst__openssl_toresult2("DH_compute_key",
+ DST_R_COMPUTESECRETFAILURE));
isc_buffer_add(secret, len);
return (ISC_R_SUCCESS);
}
@@ -204,7 +205,7 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
#if OPENSSL_VERSION_NUMBER > 0x00908000L
dh = DH_new();
if (dh == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult(ISC_R_NOMEMORY));
if (callback == NULL) {
BN_GENCB_set_old(&cb, NULL, NULL);
@@ -216,7 +217,9 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
if (!DH_generate_parameters_ex(dh, key->key_size, generator,
&cb)) {
DH_free(dh);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2(
+ "DH_generate_parameters_ex",
+ DST_R_OPENSSLFAILURE));
}
#else
dh = DH_generate_parameters(key->key_size, generator,
@@ -225,11 +228,13 @@ openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
}
if (dh == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2("DH_generate_parameters",
+ DST_R_OPENSSLFAILURE));
if (DH_generate_key(dh) == 0) {
DH_free(dh);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2("DH_generate_key",
+ DST_R_OPENSSLFAILURE));
}
dh->flags &= ~DH_FLAG_CACHE_MONT_P;
@@ -460,6 +465,7 @@ openssldh_tofile(const dst_key_t *key, const char *directory) {
dh = key->keydata.dh;
+ memset(bufs, 0, sizeof(bufs));
for (i = 0; i < 4; i++) {
bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(dh->p));
if (bufs[i] == NULL) {
@@ -628,6 +634,7 @@ static dst_func_t openssldh_functions = {
NULL, /*%< adddata */
NULL, /*%< openssldh_sign */
NULL, /*%< openssldh_verify */
+ NULL, /*%< openssldh_verify2 */
openssldh_computesecret,
openssldh_compare,
openssldh_paramcompare,
diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c
index 39c06159..715fa73a 100644
--- a/lib/dns/openssldsa_link.c
+++ b/lib/dns/openssldsa_link.c
@@ -168,7 +168,8 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
if (!EVP_SignFinal(evp_md_ctx, sigbuf, &siglen, pkey)) {
EVP_PKEY_free(pkey);
free(sigbuf);
- return (ISC_R_FAILURE);
+ return (dst__openssl_toresult2("EVP_SignFinal",
+ ISC_R_FAILURE));
}
INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
EVP_PKEY_free(pkey);
@@ -181,23 +182,26 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
sb = sigbuf;
if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
free(sigbuf);
- return (ISC_R_FAILURE);
+ return (dst__openssl_toresult2("d2i_DSA_SIG", ISC_R_FAILURE));
}
free(sigbuf);
#elif 0
/* Only use EVP for the Digest */
if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &siglen)) {
- return (ISC_R_FAILURE);
+ return (dst__openssl_toresult2("EVP_DigestFinal_ex",
+ ISC_R_FAILURE));
}
dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
if (dsasig == NULL)
- return (dst__openssl_toresult(DST_R_SIGNFAILURE));
+ return (dst__openssl_toresult2("DSA_do_sign",
+ DST_R_SIGNFAILURE));
#else
isc_sha1_final(sha1ctx, digest);
dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
if (dsasig == NULL)
- return (dst__openssl_toresult(DST_R_SIGNFAILURE));
+ return (dst__openssl_toresult2("DSA_do_sign",
+ DST_R_SIGNFAILURE));
#endif
*r.base++ = (key->key_size - 512)/64;
BN_bn2bin_fixed(dsasig->r, r.base, ISC_SHA1_DIGESTLENGTH);
@@ -276,10 +280,15 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
status = DSA_do_verify(digest, ISC_SHA1_DIGESTLENGTH, dsasig, dsa);
#endif
DSA_SIG_free(dsasig);
- if (status != 1)
+ switch (status) {
+ case 1:
+ return (ISC_R_SUCCESS);
+ case 0:
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
-
- return (ISC_R_SUCCESS);
+ default:
+ return (dst__openssl_toresult2("DSA_do_verify",
+ DST_R_VERIFYFAILURE));
+ }
}
static isc_boolean_t
@@ -370,19 +379,22 @@ openssldsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
&cb))
{
DSA_free(dsa);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2("DSA_generate_parameters_ex",
+ DST_R_OPENSSLFAILURE));
}
#else
dsa = DSA_generate_parameters(key->key_size, rand_array,
ISC_SHA1_DIGESTLENGTH, NULL, NULL,
NULL, NULL);
if (dsa == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2("DSA_generate_parameters",
+ DST_R_OPENSSLFAILURE));
#endif
if (DSA_generate_key(dsa) == 0) {
DSA_free(dsa);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2("DSA_generate_key",
+ DST_R_OPENSSLFAILURE));
}
dsa->flags &= ~DSA_FLAG_CACHE_MONT_P;
@@ -605,6 +617,7 @@ static dst_func_t openssldsa_functions = {
openssldsa_adddata,
openssldsa_sign,
openssldsa_verify,
+ NULL, /*%< verify2 */
NULL, /*%< computesecret */
openssldsa_compare,
NULL, /*%< paramcompare */
diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c
new file mode 100644
index 00000000..ad628650
--- /dev/null
+++ b/lib/dns/opensslecdsa_link.c
@@ -0,0 +1,597 @@
+/*
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+
+#ifdef HAVE_OPENSSL_ECDSA
+
+#if !defined(HAVE_EVP_SHA256) || !defined(HAVE_EVP_SHA384)
+#error "ECDSA without EVP for SHA2?"
+#endif
+
+#include <isc/entropy.h>
+#include <isc/mem.h>
+#include <isc/sha2.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include <dns/keyvalues.h>
+#include <dst/result.h>
+
+#include "dst_internal.h"
+#include "dst_openssl.h"
+#include "dst_parse.h"
+
+#include <openssl/err.h>
+#include <openssl/objects.h>
+#include <openssl/ecdsa.h>
+#include <openssl/bn.h>
+
+#ifndef NID_X9_62_prime256v1
+#error "P-256 group is not known (NID_X9_62_prime256v1)"
+#endif
+#ifndef NID_secp384r1
+#error "P-384 group is not known (NID_secp384r1)"
+#endif
+
+#define DST_RET(a) {ret = a; goto err;}
+
+static isc_result_t opensslecdsa_todns(const dst_key_t *key,
+ isc_buffer_t *data);
+
+static isc_result_t
+opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
+ EVP_MD_CTX *evp_md_ctx;
+ const EVP_MD *type = NULL;
+
+ UNUSED(key);
+ REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
+ dctx->key->key_alg == DST_ALG_ECDSA384);
+
+ evp_md_ctx = EVP_MD_CTX_create();
+ if (evp_md_ctx == NULL)
+ return (ISC_R_NOMEMORY);
+ if (dctx->key->key_alg == DST_ALG_ECDSA256)
+ type = EVP_sha256();
+ else
+ type = EVP_sha384();
+
+ if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
+ EVP_MD_CTX_destroy(evp_md_ctx);
+ return (dst__openssl_toresult2("EVP_DigestInit_ex",
+ ISC_R_FAILURE));
+ }
+
+ dctx->ctxdata.evp_md_ctx = evp_md_ctx;
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+opensslecdsa_destroyctx(dst_context_t *dctx) {
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+
+ REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
+ dctx->key->key_alg == DST_ALG_ECDSA384);
+
+ if (evp_md_ctx != NULL) {
+ EVP_MD_CTX_destroy(evp_md_ctx);
+ dctx->ctxdata.evp_md_ctx = NULL;
+ }
+}
+
+static isc_result_t
+opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+
+ REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
+ dctx->key->key_alg == DST_ALG_ECDSA384);
+
+ if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
+ return (dst__openssl_toresult2("EVP_DigestUpdate",
+ ISC_R_FAILURE));
+
+ return (ISC_R_SUCCESS);
+}
+
+static int
+BN_bn2bin_fixed(BIGNUM *bn, unsigned char *buf, int size) {
+ int bytes = size - BN_num_bytes(bn);
+
+ while (bytes-- > 0)
+ *buf++ = 0;
+ BN_bn2bin(bn, buf);
+ return (size);
+}
+
+static isc_result_t
+opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
+ isc_result_t ret;
+ dst_key_t *key = dctx->key;
+ isc_region_t r;
+ ECDSA_SIG *ecdsasig;
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+ EVP_PKEY *pkey = key->keydata.pkey;
+ EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
+ unsigned int dgstlen, siglen;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
+ key->key_alg == DST_ALG_ECDSA384);
+
+ if (eckey == NULL)
+ return (ISC_R_FAILURE);
+
+ if (key->key_alg == DST_ALG_ECDSA256)
+ siglen = DNS_SIG_ECDSA256SIZE;
+ else
+ siglen = DNS_SIG_ECDSA384SIZE;
+
+ isc_buffer_availableregion(sig, &r);
+ if (r.length < siglen)
+ DST_RET(ISC_R_NOSPACE);
+
+ if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen))
+ DST_RET(dst__openssl_toresult2("EVP_DigestFinal",
+ ISC_R_FAILURE));
+
+ ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
+ if (ecdsasig == NULL)
+ DST_RET(dst__openssl_toresult2("ECDSA_do_sign",
+ DST_R_SIGNFAILURE));
+ BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
+ r.base += siglen / 2;
+ BN_bn2bin_fixed(ecdsasig->s, r.base, siglen / 2);
+ r.base += siglen / 2;
+ ECDSA_SIG_free(ecdsasig);
+ isc_buffer_add(sig, siglen);
+ ret = ISC_R_SUCCESS;
+
+ err:
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ return (ret);
+}
+
+static isc_result_t
+opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
+ isc_result_t ret;
+ dst_key_t *key = dctx->key;
+ int status;
+ unsigned char *cp = sig->base;
+ ECDSA_SIG *ecdsasig = NULL;
+ EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
+ EVP_PKEY *pkey = key->keydata.pkey;
+ EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
+ unsigned int dgstlen, siglen;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
+ key->key_alg == DST_ALG_ECDSA384);
+
+ if (eckey == NULL)
+ return (ISC_R_FAILURE);
+
+ if (key->key_alg == DST_ALG_ECDSA256)
+ siglen = DNS_SIG_ECDSA256SIZE;
+ else
+ siglen = DNS_SIG_ECDSA384SIZE;
+
+ if (sig->length != siglen)
+ return (DST_R_VERIFYFAILURE);
+
+ if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
+ DST_RET (dst__openssl_toresult2("EVP_DigestFinal_ex",
+ ISC_R_FAILURE));
+
+ ecdsasig = ECDSA_SIG_new();
+ if (ecdsasig == NULL)
+ DST_RET (ISC_R_NOMEMORY);
+ ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
+ cp += siglen / 2;
+ ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
+ /* cp += siglen / 2; */
+
+ status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
+ switch (status) {
+ case 1:
+ ret = ISC_R_SUCCESS;
+ break;
+ case 0:
+ ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
+ break;
+ default:
+ ret = dst__openssl_toresult2("ECDSA_do_verify",
+ DST_R_VERIFYFAILURE);
+ break;
+ }
+
+ err:
+ if (ecdsasig != NULL)
+ ECDSA_SIG_free(ecdsasig);
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ return (ret);
+}
+
+static isc_boolean_t
+opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
+ isc_boolean_t ret;
+ int status;
+ EVP_PKEY *pkey1 = key1->keydata.pkey;
+ EVP_PKEY *pkey2 = key2->keydata.pkey;
+ EC_KEY *eckey1 = NULL;
+ EC_KEY *eckey2 = NULL;
+ const BIGNUM *priv1, *priv2;
+
+ if (pkey1 == NULL && pkey2 == NULL)
+ return (ISC_TRUE);
+ else if (pkey1 == NULL || pkey2 == NULL)
+ return (ISC_FALSE);
+
+ eckey1 = EVP_PKEY_get1_EC_KEY(pkey1);
+ eckey2 = EVP_PKEY_get1_EC_KEY(pkey2);
+ if (eckey1 == NULL && eckey2 == NULL) {
+ DST_RET (ISC_TRUE);
+ } else if (eckey1 == NULL || eckey2 == NULL)
+ DST_RET (ISC_FALSE);
+
+ status = EVP_PKEY_cmp(pkey1, pkey2);
+ if (status != 1)
+ DST_RET (ISC_FALSE);
+
+ priv1 = EC_KEY_get0_private_key(eckey1);
+ priv2 = EC_KEY_get0_private_key(eckey2);
+ if (priv1 != NULL || priv2 != NULL) {
+ if (priv1 == NULL || priv2 == NULL)
+ DST_RET (ISC_FALSE);
+ if (BN_cmp(priv1, priv2) != 0)
+ DST_RET (ISC_FALSE);
+ }
+ ret = ISC_TRUE;
+
+ err:
+ if (eckey1 != NULL)
+ EC_KEY_free(eckey1);
+ if (eckey2 != NULL)
+ EC_KEY_free(eckey2);
+ return (ret);
+}
+
+static isc_result_t
+opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
+ isc_result_t ret;
+ EVP_PKEY *pkey;
+ EC_KEY *eckey = NULL;
+ int group_nid;
+
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
+ key->key_alg == DST_ALG_ECDSA384);
+ UNUSED(unused);
+ UNUSED(callback);
+
+ if (key->key_alg == DST_ALG_ECDSA256)
+ group_nid = NID_X9_62_prime256v1;
+ else
+ group_nid = NID_secp384r1;
+
+ eckey = EC_KEY_new_by_curve_name(group_nid);
+ if (eckey == NULL)
+ return (dst__openssl_toresult2("EC_KEY_new_by_curve_name",
+ DST_R_OPENSSLFAILURE));
+
+ if (EC_KEY_generate_key(eckey) != 1)
+ DST_RET (dst__openssl_toresult2("EC_KEY_generate_key",
+ DST_R_OPENSSLFAILURE));
+
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL)
+ DST_RET (ISC_R_NOMEMORY);
+ if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
+ EVP_PKEY_free(pkey);
+ DST_RET (ISC_R_FAILURE);
+ }
+ key->keydata.pkey = pkey;
+ ret = ISC_R_SUCCESS;
+
+ err:
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ return (ret);
+}
+
+static isc_boolean_t
+opensslecdsa_isprivate(const dst_key_t *key) {
+ isc_boolean_t ret;
+ EVP_PKEY *pkey = key->keydata.pkey;
+ EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
+
+ ret = ISC_TF(eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL);
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ return (ret);
+}
+
+static void
+opensslecdsa_destroy(dst_key_t *key) {
+ EVP_PKEY *pkey = key->keydata.pkey;
+
+ EVP_PKEY_free(pkey);
+ key->keydata.pkey = NULL;
+}
+
+static isc_result_t
+opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) {
+ isc_result_t ret;
+ EVP_PKEY *pkey;
+ EC_KEY *eckey = NULL;
+ isc_region_t r;
+ int len;
+ unsigned char *cp;
+ unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
+
+ REQUIRE(key->keydata.pkey != NULL);
+
+ pkey = key->keydata.pkey;
+ eckey = EVP_PKEY_get1_EC_KEY(pkey);
+ if (eckey == NULL)
+ return (dst__openssl_toresult(ISC_R_FAILURE));
+ len = i2o_ECPublicKey(eckey, NULL);
+ /* skip form */
+ len--;
+
+ isc_buffer_availableregion(data, &r);
+ if (r.length < (unsigned int) len)
+ DST_RET (ISC_R_NOSPACE);
+ cp = buf;
+ if (!i2o_ECPublicKey(eckey, &cp))
+ DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
+ memcpy(r.base, buf + 1, len);
+ isc_buffer_add(data, len);
+ ret = ISC_R_SUCCESS;
+
+ err:
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ return (ret);
+}
+
+static isc_result_t
+opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
+ isc_result_t ret;
+ EVP_PKEY *pkey;
+ EC_KEY *eckey = NULL;
+ isc_region_t r;
+ int group_nid;
+ unsigned int len;
+ const unsigned char *cp;
+ unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
+
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
+ key->key_alg == DST_ALG_ECDSA384);
+
+ if (key->key_alg == DST_ALG_ECDSA256) {
+ len = DNS_KEY_ECDSA256SIZE;
+ group_nid = NID_X9_62_prime256v1;
+ } else {
+ len = DNS_KEY_ECDSA384SIZE;
+ group_nid = NID_secp384r1;
+ }
+
+ isc_buffer_remainingregion(data, &r);
+ if (r.length == 0)
+ return (ISC_R_SUCCESS);
+ if (r.length < len)
+ return (DST_R_INVALIDPUBLICKEY);
+
+ eckey = EC_KEY_new_by_curve_name(group_nid);
+ if (eckey == NULL)
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+
+ buf[0] = POINT_CONVERSION_UNCOMPRESSED;
+ memcpy(buf + 1, r.base, len);
+ cp = buf;
+ if (o2i_ECPublicKey(&eckey,
+ (const unsigned char **) &cp,
+ (long) len + 1) == NULL)
+ DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
+ if (EC_KEY_check_key(eckey) != 1)
+ DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
+
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL)
+ DST_RET (ISC_R_NOMEMORY);
+ if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
+ EVP_PKEY_free(pkey);
+ DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
+ }
+
+ isc_buffer_forward(data, len);
+ key->keydata.pkey = pkey;
+ ret = ISC_R_SUCCESS;
+
+ err:
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ return (ret);
+}
+
+static isc_result_t
+opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
+ isc_result_t ret;
+ EVP_PKEY *pkey;
+ EC_KEY *eckey = NULL;
+ const BIGNUM *privkey;
+ dst_private_t priv;
+ unsigned char *buf = NULL;
+
+ if (key->keydata.pkey == NULL)
+ return (DST_R_NULLKEY);
+
+ pkey = key->keydata.pkey;
+ eckey = EVP_PKEY_get1_EC_KEY(pkey);
+ if (eckey == NULL)
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ privkey = EC_KEY_get0_private_key(eckey);
+ if (privkey == NULL)
+ DST_RET (ISC_R_FAILURE);
+
+ buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
+ if (buf == NULL)
+ DST_RET (ISC_R_NOMEMORY);
+
+ priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY;
+ priv.elements[0].length = BN_num_bytes(privkey);
+ BN_bn2bin(privkey, buf);
+ priv.elements[0].data = buf;
+ priv.nelements = ECDSA_NTAGS;
+ ret = dst__privstruct_writefile(key, &priv, directory);
+
+ err:
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ if (buf != NULL)
+ isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
+ return (ret);
+}
+
+static isc_result_t
+ecdsa_check(EC_KEY *eckey, dst_key_t *pub)
+{
+ isc_result_t ret = ISC_R_FAILURE;
+ EVP_PKEY *pkey;
+ EC_KEY *pubeckey = NULL;
+ const EC_POINT *pubkey;
+
+ if (pub == NULL)
+ return (ISC_R_SUCCESS);
+ pkey = pub->keydata.pkey;
+ if (pkey == NULL)
+ return (ISC_R_SUCCESS);
+ pubeckey = EVP_PKEY_get1_EC_KEY(pkey);
+ if (pubeckey == NULL)
+ return (ISC_R_SUCCESS);
+ pubkey = EC_KEY_get0_public_key(pubeckey);
+ if (pubkey == NULL)
+ DST_RET (ISC_R_SUCCESS);
+ if (EC_KEY_set_public_key(eckey, pubkey) != 1)
+ DST_RET (ISC_R_SUCCESS);
+ if (EC_KEY_check_key(eckey) == 1)
+ DST_RET (ISC_R_SUCCESS);
+
+ err:
+ if (pubeckey != NULL)
+ EC_KEY_free(pubeckey);
+ return (ret);
+}
+
+static isc_result_t
+opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
+ dst_private_t priv;
+ isc_result_t ret;
+ EVP_PKEY *pkey;
+ EC_KEY *eckey = NULL;
+ BIGNUM *privkey;
+ int group_nid;
+ isc_mem_t *mctx = key->mctx;
+
+ REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
+ key->key_alg == DST_ALG_ECDSA384);
+
+ if (key->key_alg == DST_ALG_ECDSA256)
+ group_nid = NID_X9_62_prime256v1;
+ else
+ group_nid = NID_secp384r1;
+
+ eckey = EC_KEY_new_by_curve_name(group_nid);
+ if (eckey == NULL)
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+
+ /* read private key file */
+ ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
+ if (ret != ISC_R_SUCCESS)
+ goto err;
+
+ privkey = BN_bin2bn(priv.elements[0].data,
+ priv.elements[0].length, NULL);
+ if (privkey == NULL)
+ DST_RET(ISC_R_NOMEMORY);
+ if (!EC_KEY_set_private_key(eckey, privkey))
+ DST_RET(ISC_R_NOMEMORY);
+ if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
+ DST_RET(DST_R_INVALIDPRIVATEKEY);
+ dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+
+ pkey = EVP_PKEY_new();
+ if (pkey == NULL)
+ DST_RET (ISC_R_NOMEMORY);
+ if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
+ EVP_PKEY_free(pkey);
+ DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ }
+ key->keydata.pkey = pkey;
+ ret = ISC_R_SUCCESS;
+
+ err:
+ if (eckey != NULL)
+ EC_KEY_free(eckey);
+ dst__privstruct_free(&priv, mctx);
+ memset(&priv, 0, sizeof(priv));
+ return (ret);
+}
+
+static dst_func_t opensslecdsa_functions = {
+ opensslecdsa_createctx,
+ opensslecdsa_destroyctx,
+ opensslecdsa_adddata,
+ opensslecdsa_sign,
+ opensslecdsa_verify,
+ NULL, /*%< verify2 */
+ NULL, /*%< computesecret */
+ opensslecdsa_compare,
+ NULL, /*%< paramcompare */
+ opensslecdsa_generate,
+ opensslecdsa_isprivate,
+ opensslecdsa_destroy,
+ opensslecdsa_todns,
+ opensslecdsa_fromdns,
+ opensslecdsa_tofile,
+ opensslecdsa_parse,
+ NULL, /*%< cleanup */
+ NULL, /*%< fromlabel */
+ NULL, /*%< dump */
+ NULL, /*%< restore */
+};
+
+isc_result_t
+dst__opensslecdsa_init(dst_func_t **funcp) {
+ REQUIRE(funcp != NULL);
+ if (*funcp == NULL)
+ *funcp = &opensslecdsa_functions;
+ return (ISC_R_SUCCESS);
+}
+
+#else /* HAVE_OPENSSL_ECDSA */
+
+#include <isc/util.h>
+
+EMPTY_TRANSLATION_UNIT
+
+#endif /* HAVE_OPENSSL_ECDSA */
+/*! \file */
diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c
index e92d50f9..1ca89808 100644
--- a/lib/dns/opensslgost_link.c
+++ b/lib/dns/opensslgost_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2010-2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -121,10 +121,15 @@ opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) {
EVP_PKEY *pkey = key->keydata.pkey;
status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
- if (status != 1)
+ switch (status) {
+ case 1:
+ return (ISC_R_SUCCESS);
+ case 0:
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
-
- return (ISC_R_SUCCESS);
+ default:
+ return (dst__openssl_toresult2("EVP_VerifyFinal",
+ DST_R_VERIFYFAILURE));
+ }
}
static isc_boolean_t
@@ -168,22 +173,27 @@ opensslgost_generate(dst_key_t *key, int unused, void (*callback)(int)) {
void (*fptr)(int);
} u;
EVP_PKEY *pkey = NULL;
+ isc_result_t ret;
UNUSED(unused);
ctx = EVP_PKEY_CTX_new_id(NID_id_GostR3410_2001, NULL);
if (ctx == NULL)
- goto err;
+ DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_new_id",
+ DST_R_OPENSSLFAILURE));
if (callback != NULL) {
u.fptr = callback;
EVP_PKEY_CTX_set_app_data(ctx, u.dptr);
EVP_PKEY_CTX_set_cb(ctx, &progress_cb);
}
if (EVP_PKEY_keygen_init(ctx) <= 0)
- goto err;
+ DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen_init",
+ DST_R_OPENSSLFAILURE));
if (EVP_PKEY_CTX_ctrl_str(ctx, "paramset", "A") <= 0)
- goto err;
+ DST_RET(dst__openssl_toresult2("EVP_PKEY_CTX_ctrl_str",
+ DST_R_OPENSSLFAILURE));
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
- goto err;
+ DST_RET(dst__openssl_toresult2("EVP_PKEY_keygen",
+ DST_R_OPENSSLFAILURE));
key->keydata.pkey = pkey;
EVP_PKEY_CTX_free(ctx);
return (ISC_R_SUCCESS);
@@ -193,7 +203,7 @@ err:
EVP_PKEY_free(pkey);
if (ctx != NULL)
EVP_PKEY_CTX_free(ctx);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (ret);
}
static isc_boolean_t
@@ -267,7 +277,8 @@ opensslgost_fromdns(dst_key_t *key, isc_buffer_t *data) {
p = der;
if (d2i_PUBKEY(&pkey, &p, (long) sizeof(der)) == NULL)
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2("d2i_PUBKEY",
+ DST_R_OPENSSLFAILURE));
key->keydata.pkey = pkey;
return (ISC_R_SUCCESS);
@@ -293,7 +304,8 @@ opensslgost_tofile(const dst_key_t *key, const char *directory) {
p = der;
if (i2d_PrivateKey(pkey, &p) != len) {
- result = dst__openssl_toresult(DST_R_OPENSSLFAILURE);
+ result = dst__openssl_toresult2("i2d_PrivateKey",
+ DST_R_OPENSSLFAILURE);
goto fail;
}
@@ -328,7 +340,8 @@ opensslgost_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
p = priv.elements[0].data;
if (d2i_PrivateKey(NID_id_GostR3410_2001, &pkey, &p,
(long) priv.elements[0].length) == NULL)
- DST_RET(DST_R_INVALIDPRIVATEKEY);
+ DST_RET(dst__openssl_toresult2("d2i_PrivateKey",
+ DST_R_INVALIDPRIVATEKEY));
key->keydata.pkey = pkey;
key->key_size = EVP_PKEY_bits(pkey);
dst__privstruct_free(&priv, mctx);
@@ -359,6 +372,7 @@ static dst_func_t opensslgost_functions = {
opensslgost_adddata,
opensslgost_sign,
opensslgost_verify,
+ NULL, /*%< verify2 */
NULL, /*%< computesecret */
opensslgost_compare,
NULL, /*%< paramcompare */
@@ -377,35 +391,47 @@ static dst_func_t opensslgost_functions = {
isc_result_t
dst__opensslgost_init(dst_func_t **funcp) {
+ isc_result_t ret;
+
REQUIRE(funcp != NULL);
/* check if the gost engine works properly */
e = ENGINE_by_id("gost");
if (e == NULL)
- return (DST_R_OPENSSLFAILURE);
+ return (dst__openssl_toresult2("ENGINE_by_id",
+ DST_R_OPENSSLFAILURE));
if (ENGINE_init(e) <= 0) {
ENGINE_free(e);
e = NULL;
- return (DST_R_OPENSSLFAILURE);
+ return (dst__openssl_toresult2("ENGINE_init",
+ DST_R_OPENSSLFAILURE));
}
/* better than to rely on digest_gost symbol */
opensslgost_digest = ENGINE_get_digest(e, NID_id_GostR3411_94);
+ if (opensslgost_digest == NULL)
+ DST_RET(dst__openssl_toresult2("ENGINE_get_digest",
+ DST_R_OPENSSLFAILURE));
/* from openssl.cnf */
- if ((opensslgost_digest == NULL) ||
- (ENGINE_register_pkey_asn1_meths(e) <= 0) ||
- (ENGINE_ctrl_cmd_string(e,
- "CRYPT_PARAMS",
- "id-Gost28147-89-CryptoPro-A-ParamSet",
- 0) <= 0)) {
- ENGINE_finish(e);
- ENGINE_free(e);
- e = NULL;
- return (DST_R_OPENSSLFAILURE);
- }
+ if (ENGINE_register_pkey_asn1_meths(e) <= 0)
+ DST_RET(dst__openssl_toresult2(
+ "ENGINE_register_pkey_asn1_meths",
+ DST_R_OPENSSLFAILURE));
+ if (ENGINE_ctrl_cmd_string(e,
+ "CRYPT_PARAMS",
+ "id-Gost28147-89-CryptoPro-A-ParamSet",
+ 0) <= 0)
+ DST_RET(dst__openssl_toresult2("ENGINE_ctrl_cmd_string",
+ DST_R_OPENSSLFAILURE));
if (*funcp == NULL)
*funcp = &opensslgost_functions;
return (ISC_R_SUCCESS);
+
+ err:
+ ENGINE_finish(e);
+ ENGINE_free(e);
+ e = NULL;
+ return (ret);
}
#else /* HAVE_OPENSSL_GOST */
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c
index a2456188..a6db4545 100644
--- a/lib/dns/opensslrsa_link.c
+++ b/lib/dns/opensslrsa_link.c
@@ -56,6 +56,13 @@
#endif
/*
+ * Limit the size of public exponents.
+ */
+#ifndef RSA_MAX_PUBEXP_BITS
+#define RSA_MAX_PUBEXP_BITS 35
+#endif
+
+/*
* We don't use configure for windows so enforce the OpenSSL version
* here. Unlike with configure we don't support overriding this test.
*/
@@ -156,7 +163,8 @@ opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
EVP_MD_CTX_destroy(evp_md_ctx);
- return (ISC_R_FAILURE);
+ return (dst__openssl_toresult2("EVP_DigestInit_ex",
+ ISC_R_FAILURE));
}
dctx->ctxdata.evp_md_ctx = evp_md_ctx;
#else
@@ -304,7 +312,8 @@ opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
#if USE_EVP
if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
- return (ISC_R_FAILURE);
+ return (dst__openssl_toresult2("EVP_DigestUpdate",
+ ISC_R_FAILURE));
}
#else
switch (dctx->key->key_alg) {
@@ -374,10 +383,6 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
int status;
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;
@@ -397,7 +402,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
return (ISC_R_NOSPACE);
if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) {
- return (ISC_R_FAILURE);
+ return (dst__openssl_toresult2("EVP_SignFinal",
+ ISC_R_FAILURE));
}
#else
if (r.length < (unsigned int) RSA_size(rsa))
@@ -489,13 +495,9 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
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) {
- message = ERR_error_string(err, NULL);
- }
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
- }
+ if (status == 0)
+ return (dst__openssl_toresult2("RSA_sign",
+ DST_R_OPENSSLFAILURE));
#endif
isc_buffer_add(sig, siglen);
@@ -504,12 +506,14 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
}
static isc_result_t
-opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
+opensslrsa_verify2(dst_context_t *dctx, int maxbits, const isc_region_t *sig) {
dst_key_t *key = dctx->key;
int status = 0;
#if USE_EVP
EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
EVP_PKEY *pkey = key->keydata.pkey;
+ RSA *rsa;
+ int bits;
#else
/* note: ISC_SHA512_DIGESTLENGTH >= ISC_*_DIGESTLENGTH */
unsigned char digest[ISC_SHA512_DIGESTLENGTH];
@@ -529,8 +533,19 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
dctx->key->key_alg == DST_ALG_RSASHA512);
#if USE_EVP
+ rsa = EVP_PKEY_get1_RSA(pkey);
+ if (rsa == NULL)
+ return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ bits = BN_num_bits(rsa->e);
+ RSA_free(rsa);
+ if (bits > maxbits && maxbits != 0)
+ return (DST_R_VERIFYFAILURE);
+
status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
#else
+ if (BN_num_bits(rsa->e) > maxbits && maxbits != 0)
+ return (DST_R_VERIFYFAILURE);
+
switch (dctx->key->key_alg) {
case DST_ALG_RSAMD5:
{
@@ -615,7 +630,9 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
original, rsa,
RSA_PKCS1_PADDING);
if (status <= 0)
- return (DST_R_VERIFYFAILURE);
+ return (dst__openssl_toresult2(
+ "RSA_public_decrypt",
+ DST_R_VERIFYFAILURE));
if (status != (int)(prefixlen + digestlen))
return (DST_R_VERIFYFAILURE);
if (memcmp(original, prefix, prefixlen))
@@ -636,11 +653,17 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
#endif
#endif
if (status != 1)
- return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
+ return (dst__openssl_toresult2("RSA_verify",
+ DST_R_VERIFYFAILURE));
return (ISC_R_SUCCESS);
}
+static isc_result_t
+opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
+ return (opensslrsa_verify2(dctx, 0, sig));
+}
+
static isc_boolean_t
opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
int status;
@@ -727,6 +750,7 @@ progress_cb(int p, int n, BN_GENCB *cb)
static isc_result_t
opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
#if OPENSSL_VERSION_NUMBER > 0x00908000L
+ isc_result_t ret = DST_R_OPENSSLFAILURE;
BN_GENCB cb;
union {
void *dptr;
@@ -752,7 +776,7 @@ opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
BN_set_bit(e, 0);
BN_set_bit(e, 16);
} else {
- /* F5 0x100000001 */
+ /* (phased-out) F5 0x100000001 */
BN_set_bit(e, 0);
BN_set_bit(e, 32);
}
@@ -776,6 +800,8 @@ opensslrsa_generate(dst_key_t *key, int exp, void (*callback)(int)) {
#endif
return (ISC_R_SUCCESS);
}
+ ret = dst__openssl_toresult2("RSA_generate_key_ex",
+ DST_R_OPENSSLFAILURE);
err:
#if USE_EVP
@@ -786,7 +812,7 @@ err:
BN_free(e);
if (rsa != NULL)
RSA_free(rsa);
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult(ret));
#else
RSA *rsa;
unsigned long e;
@@ -810,7 +836,8 @@ err:
#if USE_EVP
EVP_PKEY_free(pkey);
#endif
- return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
+ return (dst__openssl_toresult2("RSA_generate_key",
+ DST_R_OPENSSLFAILURE));
}
SET_FLAGS(rsa);
#if USE_EVP
@@ -1009,6 +1036,7 @@ opensslrsa_tofile(const dst_key_t *key, const char *directory) {
rsa = key->keydata.rsa;
#endif
+ memset(bufs, 0, sizeof(bufs));
for (i = 0; i < 8; i++) {
bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
if (bufs[i] == NULL) {
@@ -1162,7 +1190,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
/* read private key file */
ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
if (ret != ISC_R_SUCCESS)
- return (ret);
+ goto err;
for (i = 0; i < priv.nelements; i++) {
switch (priv.elements[i].tag) {
@@ -1188,10 +1216,10 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
if (e == NULL)
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_NOTFOUND);
- }
+ if (pkey == NULL)
+ DST_RET(dst__openssl_toresult2(
+ "ENGINE_load_private_key",
+ ISC_R_NOTFOUND));
key->engine = isc_mem_strdup(key->mctx, engine);
if (key->engine == NULL)
DST_RET(ISC_R_NOMEMORY);
@@ -1203,6 +1231,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
DST_RET(DST_R_INVALIDPRIVATEKEY);
+ if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
+ DST_RET(ISC_R_RANGE);
if (pubrsa != NULL)
RSA_free(pubrsa);
key->key_size = EVP_PKEY_bits(pkey);
@@ -1285,6 +1315,8 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
DST_RET(DST_R_INVALIDPRIVATEKEY);
+ if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
+ DST_RET(ISC_R_RANGE);
key->key_size = BN_num_bits(rsa->n);
if (pubrsa != NULL)
RSA_free(pubrsa);
@@ -1303,7 +1335,7 @@ opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
RSA_free(rsa);
if (pubrsa != NULL)
RSA_free(pubrsa);
- opensslrsa_destroy(key);
+ key->keydata.generic = NULL;
dst__privstruct_free(&priv, mctx);
memset(&priv, 0, sizeof(priv));
return (ret);
@@ -1336,7 +1368,8 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
}
pkey = ENGINE_load_private_key(e, label, NULL, NULL);
if (pkey == NULL)
- DST_RET(ISC_R_NOTFOUND);
+ DST_RET(dst__openssl_toresult2("ENGINE_load_private_key",
+ ISC_R_NOTFOUND));
if (engine != NULL) {
key->engine = isc_mem_strdup(key->mctx, engine);
if (key->engine == NULL)
@@ -1357,6 +1390,8 @@ opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
if (rsa_check(rsa, pubrsa) != ISC_R_SUCCESS)
DST_RET(DST_R_INVALIDPRIVATEKEY);
+ if (BN_num_bits(rsa->e) > RSA_MAX_PUBEXP_BITS)
+ DST_RET(ISC_R_RANGE);
if (pubrsa != NULL)
RSA_free(pubrsa);
key->key_size = EVP_PKEY_bits(pkey);
@@ -1392,6 +1427,7 @@ static dst_func_t opensslrsa_functions = {
opensslrsa_adddata,
opensslrsa_sign,
opensslrsa_verify,
+ opensslrsa_verify2,
NULL, /*%< computesecret */
opensslrsa_compare,
NULL, /*%< paramcompare */
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 5bae6c48..b80a0c7e 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -113,6 +113,8 @@ typedef isc_uint32_t rbtdb_rdatatype_t;
RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_cname)
#define RBTDB_RDATATYPE_SIGDNAME \
RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_dname)
+#define RBTDB_RDATATYPE_SIGDDS \
+ RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, dns_rdatatype_ds)
#define RBTDB_RDATATYPE_NCACHEANY \
RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any)
@@ -4572,7 +4574,7 @@ get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
* configured earlier than this policy zone and does not have a higher
* precedence type.
*/
-static isc_result_t
+static void
rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_t *ardataset, dns_rpz_st_t *st,
@@ -4597,7 +4599,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
if (rbtdb->rpz_cidr == NULL) {
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- return (ISC_R_UNEXPECTED);
+ return;
}
dns_fixedname_init(&selfnamef);
@@ -4659,7 +4661,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
dns_name_format(qname, namebuf, sizeof(namebuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
- "rpz_findips findnode(%s): %s",
+ "rpz_findips findnode(%s) failed: %s",
namebuf, isc_result_totext(result));
continue;
}
@@ -4680,7 +4682,8 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
if (zrdataset.type != dns_rdatatype_cname) {
rpz_policy = DNS_RPZ_POLICY_RECORD;
} else {
- rpz_policy = dns_rpz_decode_cname(&zrdataset,
+ rpz_policy = dns_rpz_decode_cname(rpz,
+ &zrdataset,
selfname);
if (rpz_policy == DNS_RPZ_POLICY_RECORD ||
rpz_policy == DNS_RPZ_POLICY_WILDCNAME)
@@ -4738,7 +4741,7 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
st->m.type = rpz_type;
st->m.prefix = prefix;
st->m.policy = rpz_policy;
- st->m.ttl = ttl;
+ st->m.ttl = ISC_MIN(ttl, rpz->max_policy_ttl);
st->m.result = result;
dns_name_copy(qname, st->qname, NULL);
if ((rpz_policy == DNS_RPZ_POLICY_RECORD ||
@@ -4755,7 +4758,6 @@ rpz_findips(dns_rpz_zone_t *rpz, dns_rpz_type_t rpz_type,
}
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- return (ISC_R_SUCCESS);
}
#endif
@@ -5914,13 +5916,12 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
negtype = 0;
if (rbtversion == NULL && !newheader_nx) {
rdtype = RBTDB_RDATATYPE_BASE(newheader->type);
+ covers = RBTDB_RDATATYPE_EXT(newheader->type);
+ sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig, covers);
if (NEGATIVE(newheader)) {
/*
* We're adding a negative cache entry.
*/
- covers = RBTDB_RDATATYPE_EXT(newheader->type);
- sigtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
- covers);
for (topheader = rbtnode->data;
topheader != NULL;
topheader = topheader->next) {
@@ -5953,14 +5954,20 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* We're adding something that isn't a
* negative cache entry. Look for an extant
* non-stale NXDOMAIN/NODATA(QTYPE=ANY) negative
- * cache entry.
+ * cache entry. If we're adding an RRSIG, also
+ * check for an extant non-stale NODATA ncache
+ * entry which covers the same type as the RRSIG.
*/
for (topheader = rbtnode->data;
topheader != NULL;
topheader = topheader->next) {
- if (topheader->type ==
- RBTDB_RDATATYPE_NCACHEANY)
- break;
+ if ((topheader->type ==
+ RBTDB_RDATATYPE_NCACHEANY) ||
+ (newheader->type == sigtype &&
+ topheader->type ==
+ RBTDB_RDATATYPE_VALUE(0, covers))) {
+ break;
+ }
}
if (topheader != NULL && EXISTS(topheader) &&
topheader->rdh_ttl > now) {
@@ -5983,7 +5990,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
}
/*
* The new rdataset is better. Expire the
- * NXDOMAIN/NODATA(QTYPE=ANY).
+ * ncache entry.
*/
set_ttl(rbtdb, topheader, 0);
topheader->attributes |= RDATASET_ATTR_STALE;
@@ -6145,7 +6152,9 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
}
if (IS_CACHE(rbtdb) && header->rdh_ttl > now &&
(header->type == dns_rdatatype_a ||
- header->type == dns_rdatatype_aaaa) &&
+ header->type == dns_rdatatype_aaaa ||
+ header->type == dns_rdatatype_ds ||
+ header->type == RBTDB_RDATATYPE_SIGDDS) &&
!header_nx && !newheader_nx &&
header->trust >= newheader->trust &&
dns_rdataslab_equal((unsigned char *)header,
diff --git a/lib/dns/rcode.c b/lib/dns/rcode.c
index 09f6d83d..0b7fe8c2 100644
--- a/lib/dns/rcode.c
+++ b/lib/dns/rcode.c
@@ -108,6 +108,8 @@
{ DNS_KEYALG_RSASHA256, "RSASHA256", 0 }, \
{ DNS_KEYALG_RSASHA512, "RSASHA512", 0 }, \
{ DNS_KEYALG_ECCGOST, "ECCGOST", 0 }, \
+ { DNS_KEYALG_ECDSA256, "ECDSAP256SHA256", 0 }, \
+ { DNS_KEYALG_ECDSA384, "ECDSAP384SHA384", 0 }, \
{ DNS_KEYALG_INDIRECT, "INDIRECT", 0 }, \
{ DNS_KEYALG_PRIVATEDNS, "PRIVATEDNS", 0 }, \
{ DNS_KEYALG_PRIVATEOID, "PRIVATEOID", 0 }, \
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c
index 683130ac..b6e715ef 100644
--- a/lib/dns/rdata.c
+++ b/lib/dns/rdata.c
@@ -445,6 +445,8 @@ dns_rdata_fromwire(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
REQUIRE(DNS_RDATA_INITIALIZED(rdata));
REQUIRE(DNS_RDATA_VALIDFLAGS(rdata));
}
+ REQUIRE(source != NULL);
+ REQUIRE(target != NULL);
if (type == 0)
return (DNS_R_FORMERR);
@@ -545,13 +547,11 @@ rdata_validate(isc_buffer_t *src, isc_buffer_t *dest, dns_rdataclass_t rdclass,
dns_rdatatype_t type)
{
dns_decompress_t dctx;
- dns_rdata_t rdata = DNS_RDATA_INIT;
isc_result_t result;
dns_decompress_init(&dctx, -1, DNS_DECOMPRESS_NONE);
isc_buffer_setactive(src, isc_buffer_usedlength(src));
- result = dns_rdata_fromwire(&rdata, rdclass, type, src,
- &dctx, 0, dest);
+ result = dns_rdata_fromwire(NULL, rdclass, type, src, &dctx, 0, dest);
dns_decompress_invalidate(&dctx);
return (result);
@@ -1182,7 +1182,8 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
if (n > tregion.length)
return (ISC_R_NOSPACE);
- memcpy(tregion.base, sregion.base, n);
+ if (tregion.base != sregion.base)
+ memcpy(tregion.base, sregion.base, n);
isc_buffer_forward(source, n);
isc_buffer_add(target, n);
return (ISC_R_SUCCESS);
@@ -1331,7 +1332,8 @@ multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
if (n > tregion.length)
return (ISC_R_NOSPACE);
- memcpy(tregion.base, sregion.base, n);
+ if (tregion.base != sregion.base)
+ memcpy(tregion.base, sregion.base, n);
isc_buffer_forward(source, n);
isc_buffer_add(target, n);
isc_buffer_activeregion(source, &sregion);
@@ -1507,7 +1509,8 @@ mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
isc_buffer_availableregion(target, &tr);
if (length > tr.length)
return (ISC_R_NOSPACE);
- memcpy(tr.base, base, length);
+ if (tr.base != base)
+ memcpy(tr.base, base, length);
isc_buffer_add(target, length);
return (ISC_R_SUCCESS);
}
diff --git a/lib/dns/rdata/generic/dlv_32769.c b/lib/dns/rdata/generic/dlv_32769.c
index 51ed11d1..474e9cb3 100644
--- a/lib/dns/rdata/generic/dlv_32769.c
+++ b/lib/dns/rdata/generic/dlv_32769.c
@@ -84,6 +84,9 @@ fromtext_dlv(ARGS_FROMTEXT) {
case DNS_DSDIGEST_GOST:
length = ISC_GOST_DIGESTLENGTH;
break;
+ case DNS_DSDIGEST_SHA384:
+ length = ISC_SHA384_DIGESTLENGTH;
+ break;
default:
length = -1;
break;
@@ -166,7 +169,9 @@ fromwire_dlv(ARGS_FROMWIRE) {
(sr.base[3] == DNS_DSDIGEST_SHA256 &&
sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
(sr.base[3] == DNS_DSDIGEST_GOST &&
- sr.length < 4 + ISC_GOST_DIGESTLENGTH))
+ sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
+ (sr.base[3] == DNS_DSDIGEST_SHA384 &&
+ sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
return (ISC_R_UNEXPECTEDEND);
/*
@@ -180,6 +185,8 @@ fromwire_dlv(ARGS_FROMWIRE) {
sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
else if (sr.base[3] == DNS_DSDIGEST_GOST)
sr.length = 4 + ISC_GOST_DIGESTLENGTH;
+ else if (sr.base[3] == DNS_DSDIGEST_SHA384)
+ sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
isc_buffer_forward(source, sr.length);
return (mem_tobuffer(target, sr.base, sr.length));
@@ -232,6 +239,9 @@ fromstruct_dlv(ARGS_FROMSTRUCT) {
case DNS_DSDIGEST_GOST:
REQUIRE(dlv->length == ISC_GOST_DIGESTLENGTH);
break;
+ case DNS_DSDIGEST_SHA384:
+ REQUIRE(dlv->length == ISC_SHA384_DIGESTLENGTH);
+ break;
}
UNUSED(type);
diff --git a/lib/dns/rdata/generic/ds_43.c b/lib/dns/rdata/generic/ds_43.c
index fc35b72e..dd47c8d5 100644
--- a/lib/dns/rdata/generic/ds_43.c
+++ b/lib/dns/rdata/generic/ds_43.c
@@ -84,6 +84,9 @@ fromtext_ds(ARGS_FROMTEXT) {
case DNS_DSDIGEST_GOST:
length = ISC_GOST_DIGESTLENGTH;
break;
+ case DNS_DSDIGEST_SHA384:
+ length = ISC_SHA384_DIGESTLENGTH;
+ break;
default:
length = -1;
break;
@@ -166,7 +169,9 @@ fromwire_ds(ARGS_FROMWIRE) {
(sr.base[3] == DNS_DSDIGEST_SHA256 &&
sr.length < 4 + ISC_SHA256_DIGESTLENGTH) ||
(sr.base[3] == DNS_DSDIGEST_GOST &&
- sr.length < 4 + ISC_GOST_DIGESTLENGTH))
+ sr.length < 4 + ISC_GOST_DIGESTLENGTH) ||
+ (sr.base[3] == DNS_DSDIGEST_SHA384 &&
+ sr.length < 4 + ISC_SHA384_DIGESTLENGTH))
return (ISC_R_UNEXPECTEDEND);
/*
@@ -180,6 +185,8 @@ fromwire_ds(ARGS_FROMWIRE) {
sr.length = 4 + ISC_SHA256_DIGESTLENGTH;
else if (sr.base[3] == DNS_DSDIGEST_GOST)
sr.length = 4 + ISC_GOST_DIGESTLENGTH;
+ else if (sr.base[3] == DNS_DSDIGEST_SHA384)
+ sr.length = 4 + ISC_SHA384_DIGESTLENGTH;
isc_buffer_forward(source, sr.length);
return (mem_tobuffer(target, sr.base, sr.length));
@@ -232,6 +239,9 @@ fromstruct_ds(ARGS_FROMSTRUCT) {
case DNS_DSDIGEST_GOST:
REQUIRE(ds->length == ISC_GOST_DIGESTLENGTH);
break;
+ case DNS_DSDIGEST_SHA384:
+ REQUIRE(ds->length == ISC_SHA384_DIGESTLENGTH);
+ break;
}
UNUSED(type);
diff --git a/lib/dns/rdataset.c b/lib/dns/rdataset.c
index 8c865498..026d7712 100644
--- a/lib/dns/rdataset.c
+++ b/lib/dns/rdataset.c
@@ -26,6 +26,7 @@
#include <isc/buffer.h>
#include <isc/mem.h>
#include <isc/random.h>
+#include <isc/serial.h>
#include <isc/util.h>
#include <dns/name.h>
@@ -772,3 +773,30 @@ dns_rdataset_expire(dns_rdataset_t *rdataset) {
if (rdataset->methods->expire != NULL)
(rdataset->methods->expire)(rdataset);
}
+
+void
+dns_rdataset_trimttl(dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset,
+ dns_rdata_rrsig_t *rrsig, isc_stdtime_t now,
+ isc_boolean_t acceptexpired)
+{
+ isc_uint32_t ttl = 0;
+
+ REQUIRE(DNS_RDATASET_VALID(rdataset));
+ REQUIRE(DNS_RDATASET_VALID(sigrdataset));
+ REQUIRE(rrsig != NULL);
+
+ /*
+ * If we accept expired RRsets keep them for no more than 120 seconds.
+ */
+ if (acceptexpired &&
+ (isc_serial_le(rrsig->timeexpire, ((now + 120) & 0xffffffff)) ||
+ isc_serial_le(rrsig->timeexpire, now)))
+ ttl = 120;
+ else if (isc_serial_ge(rrsig->timeexpire, now))
+ ttl = rrsig->timeexpire - now;
+
+ ttl = ISC_MIN(ISC_MIN(rdataset->ttl, sigrdataset->ttl),
+ ISC_MIN(rrsig->originalttl, ttl));
+ rdataset->ttl = ttl;
+ sigrdataset->ttl = ttl;
+}
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 20b8de47..503f1d23 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -105,8 +105,21 @@
#define QTRACE(m)
#endif
+#define US_PER_SEC 1000000U
+/*
+ * The maximum time we will wait for a single query.
+ */
+#define MAX_SINGLE_QUERY_TIMEOUT 9U
+#define MAX_SINGLE_QUERY_TIMEOUT_US (MAX_SINGLE_QUERY_TIMEOUT*US_PER_SEC)
+
+/*
+ * We need to allow a individual query time to complete / timeout.
+ */
+#define MINIMUM_QUERY_TIMEOUT (MAX_SINGLE_QUERY_TIMEOUT + 1U)
+
+/* The default time in seconds for the whole query to live. */
#ifndef DEFAULT_QUERY_TIMEOUT
-#define DEFAULT_QUERY_TIMEOUT 10 /* The default time in seconds for the whole query to live. */
+#define DEFAULT_QUERY_TIMEOUT MINIMUM_QUERY_TIMEOUT
#endif
#ifndef MAXIMUM_QUERY_TIMEOUT
@@ -821,8 +834,8 @@ fctx_cancelquery(resquery_t **queryp, dns_dispatchevent_t **deventp,
*/
INSIST(no_response);
rtt = query->addrinfo->srtt + 200000;
- if (rtt > 10000000)
- rtt = 10000000;
+ if (rtt > MAX_SINGLE_QUERY_TIMEOUT_US)
+ rtt = MAX_SINGLE_QUERY_TIMEOUT_US;
/*
* Replace the current RTT with our value.
*/
@@ -1336,12 +1349,18 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
us = (800000 << (fctx->restarts - 2));
/*
- * Double the round-trip time.
+ * Add a fudge factor to the expected rtt based on the current
+ * estimate.
*/
- rtt *= 2;
+ if (rtt < 50000)
+ rtt += 50000;
+ else if (rtt < 100000)
+ rtt += 100000;
+ else
+ rtt += 200000;
/*
- * Always wait for at least the doubled round-trip time.
+ * Always wait for at least the expected rtt.
*/
if (us < rtt)
us = rtt;
@@ -1349,11 +1368,11 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
/*
* But don't ever wait for more than 10 seconds.
*/
- if (us > 10000000)
- us = 10000000;
+ if (us > MAX_SINGLE_QUERY_TIMEOUT_US)
+ us = MAX_SINGLE_QUERY_TIMEOUT_US;
- seconds = us / 1000000;
- us -= seconds * 1000000;
+ seconds = us / US_PER_SEC;
+ us -= seconds * US_PER_SEC;
isc_interval_set(&fctx->interval, seconds, us * 1000);
}
@@ -1375,6 +1394,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
task = res->buckets[fctx->bucketnum].task;
srtt = addrinfo->srtt;
+
+ /*
+ * A forwarder needs to make multiple queries. Give it at least
+ * a second to do these in.
+ */
if (ISFORWARDER(addrinfo) && srtt < 1000000)
srtt = 1000000;
@@ -8211,8 +8235,8 @@ dns_resolver_logfetch(dns_fetch_t *fetch, isc_log_t *lctx,
"timeout:%u,lame:%u,neterr:%u,badresp:%u,"
"adberr:%u,findfail:%u,valfail:%u]",
__FILE__, fctx->exitline, fctx->info,
- fctx->duration / 1000000,
- fctx->duration % 1000000,
+ fctx->duration / US_PER_SEC,
+ fctx->duration % US_PER_SEC,
isc_result_totext(fctx->result),
isc_result_totext(fctx->vresult), domainbuf,
fctx->referrals, fctx->restarts,
@@ -8818,6 +8842,8 @@ dns_resolver_settimeout(dns_resolver_t *resolver, unsigned int seconds) {
seconds = DEFAULT_QUERY_TIMEOUT;
if (seconds > MAXIMUM_QUERY_TIMEOUT)
seconds = MAXIMUM_QUERY_TIMEOUT;
+ if (seconds < MINIMUM_QUERY_TIMEOUT)
+ seconds = MINIMUM_QUERY_TIMEOUT;
resolver->query_timeout = seconds;
}
diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c
index e3f49897..78658590 100644
--- a/lib/dns/rpz.c
+++ b/lib/dns/rpz.c
@@ -118,9 +118,9 @@ struct dns_rpz_cidr {
isc_mem_t *mctx;
isc_boolean_t have_nsdname; /* zone has NSDNAME record */
dns_rpz_cidr_node_t *root;
- dns_name_t ip_name; /* RPZ_IP_ZONE.LOCALHOST. */
- dns_name_t nsip_name; /* RPZ_NSIP_ZONE.LOCALHOST. */
- dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.LOCALHOST */
+ dns_name_t ip_name; /* RPZ_IP_ZONE.origin. */
+ dns_name_t nsip_name; /* RPZ_NSIP_ZONE.origin. */
+ dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */
};
static isc_boolean_t have_rpz_zones = ISC_FALSE;
@@ -183,7 +183,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) {
str = "NODATA";
break;
case DNS_RPZ_POLICY_RECORD:
- str = "records";
+ str = "Local-Data";
break;
case DNS_RPZ_POLICY_CNAME:
case DNS_RPZ_POLICY_WILDCNAME:
@@ -255,6 +255,8 @@ dns_rpz_view_destroy(dns_view_t *view) {
ISC_LIST_UNLINK(view->rpz_zones, zone, link);
if (dns_name_dynamic(&zone->origin))
dns_name_free(&zone->origin, view->mctx);
+ if (dns_name_dynamic(&zone->passthru))
+ dns_name_free(&zone->passthru, view->mctx);
if (dns_name_dynamic(&zone->nsdname))
dns_name_free(&zone->nsdname, view->mctx);
if (dns_name_dynamic(&zone->cname))
@@ -427,14 +429,16 @@ new_node(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *ip,
}
static void
-badname(int level, dns_name_t *name, const char *comment) {
+badname(int level, dns_name_t *name, const char *str1, const char *str2) {
char printname[DNS_NAME_FORMATSIZE];
- if (isc_log_wouldlog(dns_lctx, level)) {
+ if (level < DNS_RPZ_DEBUG_QUIET
+ && isc_log_wouldlog(dns_lctx, level)) {
dns_name_format(name, printname, sizeof(printname));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, level,
- "invalid rpz \"%s\"%s", printname, comment);
+ "invalid rpz IP address \"%s\"%s%s",
+ printname, str1, str2);
}
}
@@ -566,11 +570,11 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
dns_rpz_type_t type, dns_rpz_cidr_key_t *tgt_ip,
dns_rpz_cidr_bits_t *tgt_prefix)
{
- isc_buffer_t buffer;
- unsigned char data[DNS_NAME_MAXWIRE+1];
+ isc_result_t result;
dns_fixedname_t fname;
- dns_name_t *name;
- const char *cp, *end;
+ dns_name_t *ipname;
+ char ipstr[DNS_NAME_FORMATSIZE];
+ const char *prefix_str, *cp, *end;
char *cp2;
int ip_labels;
dns_rpz_cidr_bits_t bits;
@@ -585,37 +589,43 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
ip_labels -= dns_name_countlabels(&cidr->ip_name);
ip_labels--;
if (ip_labels < 1) {
- badname(level, src_name, ", too short");
+ badname(level, src_name, "; too short", "");
return (ISC_R_FAILURE);
}
/*
- * Get text for the IP address without RPZ_x_ZONE.rpz.LOCALHOST.
+ * Get text for the IP address
*/
dns_fixedname_init(&fname);
- name = dns_fixedname_name(&fname);
+ ipname = dns_fixedname_name(&fname);
dns_name_split(src_name, dns_name_countlabels(&cidr->ip_name),
- name, NULL);
- isc_buffer_init(&buffer, data, sizeof(data));
- dns_name_totext(name, ISC_TRUE, &buffer);
- isc_buffer_putuint8(&buffer, '\0');
- cp = isc_buffer_base(&buffer);
-
- prefix = strtoul(cp, &cp2, 10);
- if (prefix < 1U || prefix > 128U || *cp2 != '.') {
- badname(level, src_name, ", bad prefix length");
+ ipname, NULL);
+ dns_name_format(ipname, ipstr, sizeof(ipstr));
+ end = &ipstr[strlen(ipstr)+1];
+ prefix_str = ipstr;
+
+ prefix = strtoul(prefix_str, &cp2, 10);
+ if (*cp2 != '.') {
+ badname(level, src_name,
+ "; invalid leading prefix length", "");
+ return (ISC_R_FAILURE);
+ }
+ *cp2 = '\0';
+ if (prefix < 1U || prefix > 128U) {
+ badname(level, src_name,
+ "; invalid prefix length of ", prefix_str);
return (ISC_R_FAILURE);
}
cp = cp2+1;
- end = isc_buffer_used(&buffer);
if (ip_labels == 4 && !strchr(cp, 'z')) {
/*
* Convert an IPv4 address
* from the form "prefix.w.z.y.x"
*/
if (prefix > 32U) {
- badname(level, src_name, "; bad IPv4 prefix length");
+ badname(level, src_name,
+ "; invalid IPv4 prefix length of ", prefix_str);
return (ISC_R_FAILURE);
}
prefix += 96;
@@ -627,7 +637,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
for (i = 0; i < 32; i += 8) {
l = strtoul(cp, &cp2, 10);
if (l > 255U || (*cp2 != '.' && *cp2 != '\0')) {
- badname(level, src_name, "; bad IPv4 address");
+ if (*cp2 == '.')
+ *cp2 = '\0';
+ badname(level, src_name,
+ "; invalid IPv4 octet ", cp);
return (ISC_R_FAILURE);
}
tgt_ip->w[3] |= l << i;
@@ -654,7 +667,10 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
l = strtoul(cp, &cp2, 16);
if (l > 0xffffu ||
(*cp2 != '.' && *cp2 != '\0')) {
- badname(level, src_name, "");
+ if (*cp2 == '.')
+ *cp2 = '\0';
+ badname(level, src_name,
+ "; invalid IPv6 word ", cp);
return (ISC_R_FAILURE);
}
if ((i & 1) == 0)
@@ -667,7 +683,7 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
}
}
if (cp != end) {
- badname(level, src_name, "");
+ badname(level, src_name, "", "");
return (ISC_R_FAILURE);
}
@@ -681,7 +697,8 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
i = bits % DNS_RPZ_CIDR_WORD_BITS;
aword = tgt_ip->w[bits / DNS_RPZ_CIDR_WORD_BITS];
if ((aword & ~DNS_RPZ_WORD_MASK(i)) != 0) {
- badname(level, src_name, "; wrong prefix length");
+ badname(level, src_name,
+ "; too small prefix length of ", prefix_str);
return (ISC_R_FAILURE);
}
bits -= i;
@@ -689,13 +706,13 @@ name2ipkey(dns_rpz_cidr_t *cidr, int level, dns_name_t *src_name,
}
/*
- * Convert the IPv6 address back to a canonical policy domain name
+ * Convert the address back to a canonical policy domain name
* to ensure that it is in canonical form.
*/
- if (ISC_R_SUCCESS != ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t)prefix,
- type, NULL, name) ||
- !dns_name_equal(src_name, name)) {
- badname(level, src_name, "; not canonical");
+ result = ip2name(cidr, tgt_ip, (dns_rpz_cidr_bits_t) prefix,
+ type, NULL, ipname);
+ if (result != ISC_R_SUCCESS || !dns_name_equal(src_name, ipname)) {
+ badname(level, src_name, "; not canonical", "");
return (ISC_R_FAILURE);
}
@@ -934,6 +951,7 @@ search(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
*/
void
dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
+ isc_result_t result;
dns_rpz_cidr_key_t tgt_ip;
dns_rpz_cidr_bits_t tgt_prefix;
dns_rpz_type_t type;
@@ -956,19 +974,22 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
case DNS_RPZ_TYPE_BAD:
return;
}
- if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
- type, &tgt_ip, &tgt_prefix))
+ result = name2ipkey(cidr, DNS_RPZ_ERROR_LEVEL, name,
+ type, &tgt_ip, &tgt_prefix);
+ if (result != ISC_R_SUCCESS)
return;
- if (ISC_R_EXISTS == search(cidr, &tgt_ip, tgt_prefix, type,
- ISC_TRUE, NULL) &&
- isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
+ result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_TRUE, NULL);
+ if (result == ISC_R_EXISTS &&
+ isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL))
+ {
char printname[DNS_NAME_FORMATSIZE];
dns_name_format(name, printname, sizeof(printname));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
- "duplicate rpz name \"%s\"", printname);
+ "rpz add failed; \"%s\" is a duplicate name",
+ printname);
}
}
@@ -978,6 +999,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
*/
void
dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
+ isc_result_t result;
dns_rpz_cidr_key_t tgt_ip;
dns_rpz_cidr_bits_t tgt_prefix;
dns_rpz_type_t type;
@@ -1010,19 +1032,14 @@ dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
/*
* Do not get excited about the deletion of interior rbt nodes.
*/
- if (ISC_R_SUCCESS != name2ipkey(cidr, DNS_RPZ_DEBUG_LEVEL3, name,
- type, &tgt_ip, &tgt_prefix))
+ result = name2ipkey(cidr, DNS_RPZ_DEBUG_QUIET, name,
+ type, &tgt_ip, &tgt_prefix);
+ if (result != ISC_R_SUCCESS)
return;
- if (ISC_R_SUCCESS != search(cidr, &tgt_ip, tgt_prefix, type,
- ISC_FALSE, &tgt)) {
- if (isc_log_wouldlog(dns_lctx, DNS_RPZ_ERROR_LEVEL)) {
- char printname[DNS_NAME_FORMATSIZE];
-
- dns_name_format(name, printname, sizeof(printname));
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
- DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
- "missing rpz node \"%s\"", printname);
- }
+
+ result = search(cidr, &tgt_ip, tgt_prefix, type, ISC_FALSE, &tgt);
+ if (result != ISC_R_SUCCESS) {
+ badname(DNS_RPZ_ERROR_LEVEL, name, "; missing rpz node", "");
return;
}
@@ -1135,7 +1152,9 @@ dns_rpz_cidr_find(dns_rpz_cidr_t *cidr, const isc_netaddr_t *netaddr,
* Translate CNAME rdata to a QNAME response policy action.
*/
dns_rpz_policy_t
-dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
+dns_rpz_decode_cname(dns_rpz_zone_t *rpz, dns_rdataset_t *rdataset,
+ dns_name_t *selfname)
+{
dns_rdata_t rdata = DNS_RDATA_INIT;
dns_rdata_cname_t cname;
isc_result_t result;
@@ -1171,7 +1190,13 @@ dns_rpz_decode_cname(dns_rdataset_t *rdataset, dns_name_t *selfname) {
}
/*
- * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. means "do not rewrite"
+ * CNAME PASSTHRU.origin means "do not rewrite.
+ */
+ if (dns_name_equal(&cname.cname, &rpz->passthru))
+ return (DNS_RPZ_POLICY_PASSTHRU);
+
+ /*
+ * 128.1.0.127.rpz-ip CNAME 128.1.0.0.127. is obsolete PASSTHRU
*/
if (selfname != NULL && dns_name_equal(&cname.cname, selfname))
return (DNS_RPZ_POLICY_PASSTHRU);
diff --git a/lib/dns/spnego_asn1.pl b/lib/dns/spnego_asn1.pl
index 93dd6767..0aaa57fa 100644
--- a/lib/dns/spnego_asn1.pl
+++ b/lib/dns/spnego_asn1.pl
@@ -1,6 +1,6 @@
#!/bin/bin/perl -w
#
-# Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/dns/tests/Makefile.in b/lib/dns/tests/Makefile.in
index 5f68af0a..409ee8dc 100644
--- a/lib/dns/tests/Makefile.in
+++ b/lib/dns/tests/Makefile.in
@@ -39,13 +39,13 @@ LIBS = @LIBS@ @ATFLIBS@
OBJS = dnstest.@O@
SRCS = dnstest.c master_test.c dbiterator_test.c time_test.c \
private_test.c update_test.c zonemgr_test.c zt_test.c \
- dbdiff_test.c nsec3_test.c rdata_test.c
+ dbdiff_test.c nsec3_test.c rdataset_test.c rdata_test.c
SUBDIRS =
TARGETS = master_test@EXEEXT@ dbiterator_test@EXEEXT@ time_test@EXEEXT@ \
private_test@EXEEXT@ update_test@EXEEXT@ zonemgr_test@EXEEXT@ \
zt_test@EXEEXT@ dbversion_test@EXEEXT@ dbdiff_test@EXEEXT@ \
- nsec3_test@EXEEXT@ rdata_test@EXEEXT@
+ nsec3_test@EXEEXT@ rdataset_test@EXEEXT@ rdata_test@EXEEXT@
@BIND9_MAKE_RULES@
@@ -104,6 +104,11 @@ nsec3_test@EXEEXT@: nsec3_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
nsec3_test.@O@ dnstest.@O@ ${DNSLIBS} \
${ISCLIBS} ${LIBS}
+
+rdataset_test@EXEEXT@: rdataset_test.@O@ dnstest.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
+ ${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
+ rdataset_test.@O@ dnstest.@O@ ${DNSLIBS} \
+ ${ISCLIBS} ${LIBS}
rdata_test@EXEEXT@: rdata_test.@O@ ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} ${PURIFY} ${CC} ${CFLAGS} ${LDFLAGS} -o $@ \
diff --git a/lib/dns/tests/rdataset_test.c b/lib/dns/tests/rdataset_test.c
new file mode 100644
index 00000000..7cbaa195
--- /dev/null
+++ b/lib/dns/tests/rdataset_test.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <atf-c.h>
+
+#include <unistd.h>
+
+#include <dns/rdataset.h>
+#include <dns/rdatastruct.h>
+
+#include "dnstest.h"
+
+
+/*
+ * Individual unit tests
+ */
+
+/* Successful load test */
+ATF_TC(trimttl);
+ATF_TC_HEAD(trimttl, tc) {
+ atf_tc_set_md_var(tc, "descr", "dns_master_loadfile() loads a "
+ "valid master file and returns success");
+}
+ATF_TC_BODY(trimttl, tc) {
+ isc_result_t result;
+ dns_rdataset_t rdataset, sigrdataset;
+ dns_rdata_rrsig_t rrsig;
+ isc_stdtime_t ttltimenow, ttltimeexpire;
+
+ ttltimenow = 10000000;
+ ttltimeexpire = ttltimenow + 800;
+
+ UNUSED(tc);
+
+ dns_rdataset_init(&rdataset);
+ dns_rdataset_init(&sigrdataset);
+
+ result = dns_test_begin(NULL, ISC_FALSE);
+ ATF_REQUIRE_EQ(result, ISC_R_SUCCESS);
+
+ rdataset.ttl = 900;
+ sigrdataset.ttl = 1000;
+ rrsig.timeexpire = ttltimeexpire;
+ rrsig.originalttl = 1000;
+
+ dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow,
+ ISC_TRUE);
+ ATF_REQUIRE_EQ(rdataset.ttl, 800);
+ ATF_REQUIRE_EQ(sigrdataset.ttl, 800);
+
+ rdataset.ttl = 900;
+ sigrdataset.ttl = 1000;
+ rrsig.timeexpire = ttltimenow - 200;
+ rrsig.originalttl = 1000;
+
+ dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow,
+ ISC_TRUE);
+ ATF_REQUIRE_EQ(rdataset.ttl, 120);
+ ATF_REQUIRE_EQ(sigrdataset.ttl, 120);
+
+ rdataset.ttl = 900;
+ sigrdataset.ttl = 1000;
+ rrsig.timeexpire = ttltimenow - 200;
+ rrsig.originalttl = 1000;
+
+ dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow,
+ ISC_FALSE);
+ ATF_REQUIRE_EQ(rdataset.ttl, 0);
+ ATF_REQUIRE_EQ(sigrdataset.ttl, 0);
+
+ sigrdataset.ttl = 900;
+ rdataset.ttl = 1000;
+ rrsig.timeexpire = ttltimeexpire;
+ rrsig.originalttl = 1000;
+
+ dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow,
+ ISC_TRUE);
+ ATF_REQUIRE_EQ(rdataset.ttl, 800);
+ ATF_REQUIRE_EQ(sigrdataset.ttl, 800);
+
+ sigrdataset.ttl = 900;
+ rdataset.ttl = 1000;
+ rrsig.timeexpire = ttltimenow - 200;
+ rrsig.originalttl = 1000;
+
+ dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow,
+ ISC_TRUE);
+ ATF_REQUIRE_EQ(rdataset.ttl, 120);
+ ATF_REQUIRE_EQ(sigrdataset.ttl, 120);
+
+ sigrdataset.ttl = 900;
+ rdataset.ttl = 1000;
+ rrsig.timeexpire = ttltimenow - 200;
+ rrsig.originalttl = 1000;
+
+ dns_rdataset_trimttl(&rdataset, &sigrdataset, &rrsig, ttltimenow,
+ ISC_FALSE);
+ ATF_REQUIRE_EQ(rdataset.ttl, 0);
+ ATF_REQUIRE_EQ(sigrdataset.ttl, 0);
+
+ dns_test_end();
+}
+
+/*
+ * Main
+ */
+ATF_TP_ADD_TCS(tp) {
+ ATF_TP_ADD_TC(tp, trimttl);
+
+ return (atf_no_error());
+}
+
diff --git a/lib/dns/tests/zt_test.c b/lib/dns/tests/zt_test.c
index 80d11cd6..176d4779 100644
--- a/lib/dns/tests/zt_test.c
+++ b/lib/dns/tests/zt_test.c
@@ -37,6 +37,11 @@
#include "dnstest.h"
+struct args {
+ void *arg1;
+ void *arg2;
+};
+
/*
* Helper functions
*/
@@ -72,6 +77,27 @@ all_done(void *arg) {
return (ISC_R_SUCCESS);
}
+static void
+start_zt_asyncload(isc_task_t *task, isc_event_t *event) {
+ struct args *args = (struct args *)(event->ev_arg);
+
+ UNUSED(task);
+
+ dns_zt_asyncload(args->arg1, all_done, args->arg2);
+
+ isc_event_free(&event);
+}
+
+static void
+start_zone_asyncload(isc_task_t *task, isc_event_t *event) {
+ struct args *args = (struct args *)(event->ev_arg);
+
+ UNUSED(task);
+
+ dns_zone_asyncload(args->arg1, load_done, args->arg2);
+ isc_event_free(&event);
+}
+
/*
* Individual unit tests
*/
@@ -127,6 +153,7 @@ ATF_TC_BODY(asyncload_zone, tc) {
dns_db_t *db = NULL;
isc_boolean_t done = ISC_FALSE;
int i = 0;
+ struct args args;
UNUSED(tc);
@@ -147,8 +174,10 @@ ATF_TC_BODY(asyncload_zone, tc) {
ATF_CHECK(!dns__zone_loadpending(zone));
ATF_CHECK(!done);
dns_zone_setfile(zone, "testdata/zt/zone1.db");
- dns_zone_asyncload(zone, load_done, (void *) &done);
- ATF_CHECK(dns__zone_loadpending(zone));
+
+ args.arg1 = zone;
+ args.arg2 = &done;
+ isc_app_onrun(mctx, maintask, start_zone_asyncload, &args);
isc_app_run();
while (dns__zone_loadpending(zone) && i++ < 5000)
@@ -183,6 +212,7 @@ ATF_TC_BODY(asyncload_zt, tc) {
dns_db_t *db = NULL;
isc_boolean_t done = ISC_FALSE;
int i = 0;
+ struct args args;
UNUSED(tc);
@@ -218,7 +248,10 @@ ATF_TC_BODY(asyncload_zt, tc) {
ATF_CHECK(!dns__zone_loadpending(zone1));
ATF_CHECK(!dns__zone_loadpending(zone2));
ATF_CHECK(!done);
- dns_zt_asyncload(zt, all_done, (void *) &done);
+
+ args.arg1 = zt;
+ args.arg2 = &done;
+ isc_app_onrun(mctx, maintask, start_zt_asyncload, &args);
isc_app_run();
while (!done && i++ < 5000)
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 3f9aae7f..56639241 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -1890,8 +1890,10 @@ isselfsigned(dns_validator_t *val) {
if (result != ISC_R_SUCCESS)
continue;
- result = dns_dnssec_verify2(name, rdataset, dstkey,
- ISC_TRUE, mctx, &sigrdata,
+ result = dns_dnssec_verify3(name, rdataset, dstkey,
+ ISC_TRUE,
+ val->view->maxbits,
+ mctx, &sigrdata,
dns_fixedname_name(&fixed));
dst_key_free(&dstkey);
if (result != ISC_R_SUCCESS)
@@ -1928,8 +1930,9 @@ verify(dns_validator_t *val, dst_key_t *key, dns_rdata_t *rdata,
dns_fixedname_init(&fixed);
wild = dns_fixedname_name(&fixed);
again:
- result = dns_dnssec_verify2(val->event->name, val->event->rdataset,
- key, ignore, val->view->mctx, rdata, wild);
+ result = dns_dnssec_verify3(val->event->name, val->event->rdataset,
+ key, ignore, val->view->maxbits,
+ val->view->mctx, rdata, wild);
if ((result == DNS_R_SIGEXPIRED || result == DNS_R_SIGFUTURE) &&
val->view->acceptexpired)
{
@@ -2075,15 +2078,13 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
validator_log(val, ISC_LOG_DEBUG(3),
"failed to verify rdataset");
else {
- isc_uint32_t ttl;
isc_stdtime_t now;
isc_stdtime_get(&now);
- ttl = ISC_MIN(event->rdataset->ttl,
- ISC_MIN(val->siginfo->originalttl,
- val->siginfo->timeexpire - now));
- event->rdataset->ttl = ttl;
- event->sigrdataset->ttl = ttl;
+ dns_rdataset_trimttl(event->rdataset,
+ event->sigrdataset,
+ val->siginfo, now,
+ val->view->acceptexpired);
}
if (val->keynode != NULL)
diff --git a/lib/dns/view.c b/lib/dns/view.c
index 0f82b1ae..0a9727c2 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -189,9 +189,12 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->flush = ISC_FALSE;
view->dlv = NULL;
view->maxudp = 0;
+ view->maxbits = 0;
view->v4_aaaa = dns_v4_aaaa_ok;
view->v4_aaaa_acl = NULL;
ISC_LIST_INIT(view->rpz_zones);
+ view->rpz_recursive_only = ISC_TRUE;
+ view->rpz_break_dnssec = ISC_FALSE;
dns_fixedname_init(&view->dlv_fixed);
view->managed_keys = NULL;
view->redirect = NULL;
diff --git a/lib/dns/win32/libdns.def b/lib/dns/win32/libdns.def
index e91ce4d4..878318fa 100644
--- a/lib/dns/win32/libdns.def
+++ b/lib/dns/win32/libdns.def
@@ -219,6 +219,7 @@ dns_dnssec_signs
dns_dnssec_updatekeys
dns_dnssec_verify
dns_dnssec_verify2
+dns_dnssec_verify3
dns_dnssec_verifymessage
dns_dnsseckey_create
dns_dnsseckey_destroy
@@ -431,7 +432,10 @@ dns_nsec3param_fromprivate
dns_nsec3param_toprivate
dns_nsec_build
dns_nsec_buildrdata
+dns_nsec_compressbitmap
+dns_nsec_isset
dns_nsec_nseconly
+dns_nsec_setbit
dns_nsec_typepresent
dns_opcode_totext
dns_opcodestats_create
@@ -550,6 +554,7 @@ dns_rdataset_settrust
dns_rdataset_totext
dns_rdataset_towire
dns_rdataset_towiresorted
+dns_rdataset_trimttl
dns_rdatasetiter_current
dns_rdatasetiter_destroy
dns_rdatasetiter_first
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 99b540be..5dd0b76a 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -3346,7 +3346,7 @@ zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
&journal);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "%s:dns_journal_open -> %s\n",
+ "%s:dns_journal_open -> %s",
caller, dns_result_totext(result));
return (result);
}
@@ -3357,7 +3357,7 @@ zone_journal(dns_zone_t *zone, dns_diff_t *diff, isc_uint32_t *sourceserial,
result = dns_journal_write_transaction(journal, diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "%s:dns_journal_write_transaction -> %s\n",
+ "%s:dns_journal_write_transaction -> %s",
caller, dns_result_totext(result));
}
dns_journal_destroy(&journal);
@@ -3383,7 +3383,7 @@ add_soa(dns_zone_t *zone, dns_db_t *db) {
result = dns_db_newversion(db, &ver);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "add_soa:dns_db_newversion -> %s\n",
+ "add_soa:dns_db_newversion -> %s",
dns_result_totext(result));
goto failure;
}
@@ -3393,7 +3393,7 @@ add_soa(dns_zone_t *zone, dns_db_t *db) {
0, 0, 0, 0, 0, buf, &rdata);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "add_soa:dns_soa_buildrdata -> %s\n",
+ "add_soa:dns_soa_buildrdata -> %s",
dns_result_totext(result));
goto failure;
}
@@ -3445,7 +3445,7 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
result = dns_db_newversion(db, &ver);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "sync_keyzone:dns_db_newversion -> %s\n",
+ "sync_keyzone:dns_db_newversion -> %s",
dns_result_totext(result));
goto failure;
}
@@ -5411,7 +5411,7 @@ zone_resigninc(dns_zone_t *zone) {
result = dns_db_newversion(db, &version);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_db_newversion -> %s\n",
+ "zone_resigninc:dns_db_newversion -> %s",
dns_result_totext(result));
goto failure;
}
@@ -5420,7 +5420,7 @@ zone_resigninc(dns_zone_t *zone) {
zone_keys, &nkeys);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:find_zone_keys -> %s\n",
+ "zone_resigninc:find_zone_keys -> %s",
dns_result_totext(result));
goto failure;
}
@@ -5444,7 +5444,7 @@ zone_resigninc(dns_zone_t *zone) {
result = dns_db_getsigningtime(db, &rdataset, name);
if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_db_getsigningtime -> %s\n",
+ "zone_resigninc:dns_db_getsigningtime -> %s",
dns_result_totext(result));
}
@@ -5468,7 +5468,7 @@ zone_resigninc(dns_zone_t *zone) {
zone_keys, nkeys, now, ISC_TRUE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:del_sigs -> %s\n",
+ "zone_resigninc:del_sigs -> %s",
dns_result_totext(result));
break;
}
@@ -5478,7 +5478,7 @@ zone_resigninc(dns_zone_t *zone) {
expire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:add_sigs -> %s\n",
+ "zone_resigninc:add_sigs -> %s",
dns_result_totext(result));
break;
}
@@ -5490,7 +5490,7 @@ zone_resigninc(dns_zone_t *zone) {
}
if (result != ISC_R_SUCCESS)
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:dns_db_getsigningtime -> %s\n",
+ "zone_resigninc:dns_db_getsigningtime -> %s",
dns_result_totext(result));
}
@@ -5501,7 +5501,7 @@ zone_resigninc(dns_zone_t *zone) {
&sig_diff, zone_keys, nkeys, now, ISC_TRUE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:del_sigs -> %s\n",
+ "zone_resigninc:del_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -5517,7 +5517,7 @@ zone_resigninc(dns_zone_t *zone) {
zone->updatemethod);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:update_soa_serial -> %s\n",
+ "zone_resigninc:update_soa_serial -> %s",
dns_result_totext(result));
goto failure;
}
@@ -5531,7 +5531,7 @@ zone_resigninc(dns_zone_t *zone) {
soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_resigninc:add_sigs -> %s\n",
+ "zone_resigninc:add_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6233,7 +6233,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "update_sigs:del_sigs -> %s\n",
+ "update_sigs:del_sigs -> %s",
dns_result_totext(result));
return (result);
}
@@ -6243,7 +6243,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
expire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "update_sigs:add_sigs -> %s\n",
+ "update_sigs:add_sigs -> %s",
dns_result_totext(result));
return (result);
}
@@ -6328,7 +6328,7 @@ zone_nsec3chain(dns_zone_t *zone) {
result = dns_db_newversion(db, &version);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:dns_db_newversion -> %s\n",
+ "zone_nsec3chain:dns_db_newversion -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6337,7 +6337,7 @@ zone_nsec3chain(dns_zone_t *zone) {
DNS_MAXZONEKEYS, zone_keys, &nkeys);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_nsec3chain:find_zone_keys -> %s\n",
+ "zone_nsec3chain:find_zone_keys -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6483,7 +6483,7 @@ zone_nsec3chain(dns_zone_t *zone) {
&nsec3_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "dns_nsec3_addnsec3 -> %s\n",
+ "dns_nsec3_addnsec3 -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6541,7 +6541,7 @@ zone_nsec3chain(dns_zone_t *zone) {
} else if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "dns_dbiterator_next -> %s\n",
+ "dns_dbiterator_next -> %s",
dns_result_totext(result));
goto failure;
} else if (delegation) {
@@ -6600,7 +6600,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "need_nsec_chain -> %s\n",
+ "need_nsec_chain -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6625,7 +6625,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "fixup_nsec3param -> %s\n",
+ "fixup_nsec3param -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6640,7 +6640,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "deletematchingnsec3 -> %s\n",
+ "deletematchingnsec3 -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6741,7 +6741,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "fixup_nsec3param -> %s\n",
+ "fixup_nsec3param -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6749,7 +6749,7 @@ zone_nsec3chain(dns_zone_t *zone) {
} else if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "dns_dbiterator_next -> %s\n",
+ "dns_dbiterator_next -> %s",
dns_result_totext(result));
goto failure;
} else if (delegation) {
@@ -6786,7 +6786,7 @@ zone_nsec3chain(dns_zone_t *zone) {
result = dns_db_allrdatasets(db, node, version, 0, &iterator);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "dns_db_allrdatasets -> %s\n",
+ "dns_db_allrdatasets -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6812,7 +6812,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "updatesecure -> %s\n",
+ "updatesecure -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6825,7 +6825,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_nsec3chain:"
- "dns_nsec3_addnsec3s -> %s\n",
+ "dns_nsec3_addnsec3s -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6840,7 +6840,7 @@ zone_nsec3chain(dns_zone_t *zone) {
check_ksk, keyset_kskonly, &sig_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_sigs -> %s\n", dns_result_totext(result));
+ "update_sigs -> %s", dns_result_totext(result));
goto failure;
}
@@ -6853,7 +6853,7 @@ zone_nsec3chain(dns_zone_t *zone) {
check_ksk, keyset_kskonly, &sig_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_sigs -> %s\n", dns_result_totext(result));
+ "update_sigs -> %s", dns_result_totext(result));
goto failure;
}
@@ -6864,7 +6864,7 @@ zone_nsec3chain(dns_zone_t *zone) {
zone->minimum, ISC_FALSE, &nsec_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "updatesecure -> %s\n",
+ "updatesecure -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6875,7 +6875,7 @@ zone_nsec3chain(dns_zone_t *zone) {
check_ksk, keyset_kskonly, &sig_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_sigs -> %s\n", dns_result_totext(result));
+ "update_sigs -> %s", dns_result_totext(result));
goto failure;
}
@@ -6890,7 +6890,7 @@ zone_nsec3chain(dns_zone_t *zone) {
&sig_diff, zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "del_sigs -> %s\n", dns_result_totext(result));
+ "del_sigs -> %s", dns_result_totext(result));
goto failure;
}
@@ -6898,7 +6898,7 @@ zone_nsec3chain(dns_zone_t *zone) {
zone->updatemethod);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "update_soa_serial -> %s\n",
+ "update_soa_serial -> %s",
dns_result_totext(result));
goto failure;
}
@@ -6908,7 +6908,7 @@ zone_nsec3chain(dns_zone_t *zone) {
soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
- "add_sigs -> %s\n", dns_result_totext(result));
+ "add_sigs -> %s", dns_result_totext(result));
goto failure;
}
@@ -6952,7 +6952,7 @@ zone_nsec3chain(dns_zone_t *zone) {
failure:
if (result != ISC_R_SUCCESS)
- dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s\n",
+ dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
dns_result_totext(result));
/*
* On error roll back the current nsec3chain.
@@ -7155,7 +7155,7 @@ zone_sign(dns_zone_t *zone) {
result = dns_db_newversion(db, &version);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:dns_db_newversion -> %s\n",
+ "zone_sign:dns_db_newversion -> %s",
dns_result_totext(result));
goto failure;
}
@@ -7164,7 +7164,7 @@ zone_sign(dns_zone_t *zone) {
DNS_MAXZONEKEYS, zone_keys, &nkeys);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:find_zone_keys -> %s\n",
+ "zone_sign:find_zone_keys -> %s",
dns_result_totext(result));
goto failure;
}
@@ -7385,7 +7385,7 @@ zone_sign(dns_zone_t *zone) {
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone,
ISC_LOG_ERROR,
- "updatesecure -> %s\n",
+ "updatesecure -> %s",
dns_result_totext(result));
goto failure;
}
@@ -7397,8 +7397,7 @@ zone_sign(dns_zone_t *zone) {
&post_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "updatesignwithkey "
- "-> %s\n",
+ "updatesignwithkey -> %s",
dns_result_totext(result));
goto failure;
}
@@ -7406,7 +7405,7 @@ zone_sign(dns_zone_t *zone) {
goto next_signing;
} else if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:dns_dbiterator_next -> %s\n",
+ "zone_sign:dns_dbiterator_next -> %s",
dns_result_totext(result));
goto failure;
} else if (delegation) {
@@ -7432,7 +7431,7 @@ zone_sign(dns_zone_t *zone) {
check_ksk, keyset_kskonly, &sig_diff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
- "update_sigs -> %s\n",
+ "update_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -7452,7 +7451,7 @@ zone_sign(dns_zone_t *zone) {
&sig_diff, zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:del_sigs -> %s\n",
+ "zone_sign:del_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -7461,7 +7460,7 @@ zone_sign(dns_zone_t *zone) {
zone->updatemethod);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:update_soa_serial -> %s\n",
+ "zone_sign:update_soa_serial -> %s",
dns_result_totext(result));
goto failure;
}
@@ -7475,7 +7474,7 @@ zone_sign(dns_zone_t *zone) {
soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "zone_sign:add_sigs -> %s\n",
+ "zone_sign:add_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -8532,7 +8531,7 @@ zone_maintenance(dns_zone_t *zone) {
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
dumping = was_dumping(zone);
- } else
+ } else
dumping = ISC_TRUE;
UNLOCK_ZONE(zone);
if (!dumping) {
@@ -15190,7 +15189,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
zone_keys, &nkeys);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "sign_apex:find_zone_keys -> %s\n",
+ "sign_apex:find_zone_keys -> %s",
dns_result_totext(result));
return (result);
}
@@ -15221,7 +15220,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "sign_apex:del_sigs -> %s\n",
+ "sign_apex:del_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -15231,7 +15230,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "sign_apex:add_sigs -> %s\n",
+ "sign_apex:add_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -15243,7 +15242,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "sign_apex:update_sigs -> %s\n",
+ "sign_apex:update_sigs -> %s",
dns_result_totext(result));
goto failure;
}
@@ -15943,7 +15942,7 @@ keydone(isc_task_t *task, isc_event_t *event) {
result = dns_db_newversion(db, &newver);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "keydone:dns_db_newversion -> %s\n",
+ "keydone:dns_db_newversion -> %s",
dns_result_totext(result));
goto failure;
}
@@ -16063,7 +16062,7 @@ dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
kd->all = ISC_FALSE;
n = sscanf(keystr, "%hd/", &keyid);
- if (n == 0)
+ if (n == 0U)
CHECK(ISC_R_FAILURE);
algstr = strchr(keystr, '/');
@@ -16073,7 +16072,7 @@ dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
CHECK(ISC_R_FAILURE);
n = sscanf(algstr, "%hhd", &alg);
- if (n == 0) {
+ if (n == 0U) {
DE_CONST(algstr, r.base);
r.length = strlen(algstr);
CHECK(dns_secalg_fromtext(&alg, &r));
@@ -16141,7 +16140,7 @@ setnsec3param(isc_task_t *task, isc_event_t *event) {
result = dns_db_newversion(db, &newver);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
- "setnsec3param:dns_db_newversion -> %s\n",
+ "setnsec3param:dns_db_newversion -> %s",
dns_result_totext(result));
goto failure;
}
diff --git a/lib/dns/zt.c b/lib/dns/zt.c
index 5bb4cb8b..eb1e4247 100644
--- a/lib/dns/zt.c
+++ b/lib/dns/zt.c
@@ -46,6 +46,7 @@ struct dns_zt {
dns_zt_allloaded_t loaddone;
void * loaddone_arg;
/* Locked by lock. */
+ isc_boolean_t flush;
isc_uint32_t references;
unsigned int loads_pending;
dns_rbt_t *table;
@@ -93,8 +94,10 @@ dns_zt_create(isc_mem_t *mctx, dns_rdataclass_t rdclass, dns_zt_t **ztp)
if (result != ISC_R_SUCCESS)
goto cleanup_rbt;
- zt->mctx = mctx;
+ zt->mctx = NULL;
+ isc_mem_attach(mctx, &zt->mctx);
zt->references = 1;
+ zt->flush = ISC_FALSE;
zt->rdclass = rdclass;
zt->magic = ZTMAGIC;
zt->loaddone = NULL;
@@ -201,6 +204,16 @@ flush(dns_zone_t *zone, void *uap) {
}
static void
+zt_destroy(dns_zt_t *zt) {
+ if (zt->flush)
+ (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL);
+ dns_rbt_destroy(&zt->table);
+ isc_rwlock_destroy(&zt->rwlock);
+ zt->magic = 0;
+ isc_mem_putanddetach(&zt->mctx, zt, sizeof(*zt));
+}
+
+static void
zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) {
isc_boolean_t destroy = ISC_FALSE;
dns_zt_t *zt;
@@ -215,17 +228,13 @@ zt_flushanddetach(dns_zt_t **ztp, isc_boolean_t need_flush) {
zt->references--;
if (zt->references == 0)
destroy = ISC_TRUE;
+ if (need_flush)
+ zt->flush = ISC_TRUE;
RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
- if (destroy) {
- if (need_flush)
- (void)dns_zt_apply(zt, ISC_FALSE, flush, NULL);
- dns_rbt_destroy(&zt->table);
- isc_rwlock_destroy(&zt->rwlock);
- zt->magic = 0;
- isc_mem_put(zt->mctx, zt, sizeof(*zt));
- }
+ if (destroy)
+ zt_destroy(zt);
*ztp = NULL;
}
@@ -272,10 +281,9 @@ dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) {
REQUIRE(VALID_ZT(zt));
- RWLOCK(&zt->rwlock, isc_rwlocktype_read);
+ RWLOCK(&zt->rwlock, isc_rwlocktype_write);
INSIST(zt->loads_pending == 0);
-
result = dns_zt_apply2(zt, ISC_FALSE, NULL, asyncload, &dl);
pending = zt->loads_pending;
@@ -284,7 +292,7 @@ dns_zt_asyncload(dns_zt_t *zt, dns_zt_allloaded_t alldone, void *arg) {
zt->loaddone_arg = arg;
}
- RWUNLOCK(&zt->rwlock, isc_rwlocktype_read);
+ RWUNLOCK(&zt->rwlock, isc_rwlocktype_write);
if (pending == 0)
alldone(arg);
@@ -305,10 +313,15 @@ asyncload(dns_zone_t *zone, void *callback) {
REQUIRE(zone != NULL);
zt = dns_zone_getview(zone)->zonetable;
+ INSIST(VALID_ZT(zt));
result = dns_zone_asyncload(zone, *loaded, zt);
- if (result == ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS) {
+ INSIST(zt->references > 0);
+ zt->references++;
+ INSIST(zt->references != 0);
zt->loads_pending++;
+ }
return (ISC_R_SUCCESS);
}
@@ -479,6 +492,7 @@ dns_zt_apply2(dns_zt_t *zt, isc_boolean_t stop, isc_result_t *sub,
*/
static isc_result_t
doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
+ isc_boolean_t destroy = ISC_FALSE;
dns_zt_allloaded_t alldone = NULL;
void *arg = NULL;
@@ -489,6 +503,10 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
RWLOCK(&zt->rwlock, isc_rwlocktype_write);
INSIST(zt->loads_pending != 0);
+ INSIST(zt->references != 0);
+ zt->references--;
+ if (zt->references == 0)
+ destroy = ISC_TRUE;
zt->loads_pending--;
if (zt->loads_pending == 0) {
alldone = zt->loaddone;
@@ -501,6 +519,9 @@ doneloading(dns_zt_t *zt, dns_zone_t *zone, isc_task_t *task) {
if (alldone != NULL)
alldone(arg);
+ if (destroy)
+ zt_destroy(zt);
+
return (ISC_R_SUCCESS);
}
diff --git a/lib/export/Makefile.in b/lib/export/Makefile.in
index fc9d4ad4..1fd72168 100644
--- a/lib/export/Makefile.in
+++ b/lib/export/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in
index cd72988d..6df36fe8 100644
--- a/lib/export/dns/Makefile.in
+++ b/lib/export/dns/Makefile.in
@@ -44,7 +44,7 @@ LIBS = @LIBS@
# Alphabetically
OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
- opensslgost_link.@O@ opensslrsa_link.@O@
+ opensslecdsa_link.@O@ opensslgost_link.@O@ opensslrsa_link.@O@
DSTOBJS = @OPENSSLLINKOBJS@ \
dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
@@ -72,7 +72,7 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS}
# Alphabetically
OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \
- opensslgost_link.c opensslrsa_link.c
+ opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c
DSTSRCS = @OPENSSLLINKSRCS@ \
dst_api.c dst_lib.c dst_parse.c \
diff --git a/lib/export/dns/include/Makefile.in b/lib/export/dns/include/Makefile.in
index 9fc0b66b..6bf12053 100644
--- a/lib/export/dns/include/Makefile.in
+++ b/lib/export/dns/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/dns/include/dns/Makefile.in b/lib/export/dns/include/dns/Makefile.in
index 2d7f2c78..b7f51b4a 100644
--- a/lib/export/dns/include/dns/Makefile.in
+++ b/lib/export/dns/include/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/dns/include/dst/Makefile.in b/lib/export/dns/include/dst/Makefile.in
index 259e62ed..f6f540a2 100644
--- a/lib/export/dns/include/dst/Makefile.in
+++ b/lib/export/dns/include/dst/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/irs/include/irs/Makefile.in b/lib/export/irs/include/irs/Makefile.in
index c8507571..530e67c8 100644
--- a/lib/export/irs/include/irs/Makefile.in
+++ b/lib/export/irs/include/irs/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in
index a55a1f44..86726ab3 100644
--- a/lib/export/isc/Makefile.in
+++ b/lib/export/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/include/isc/Makefile.in b/lib/export/isc/include/isc/Makefile.in
index 24991853..91f538c4 100644
--- a/lib/export/isc/include/isc/Makefile.in
+++ b/lib/export/isc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/nls/Makefile.in b/lib/export/isc/nls/Makefile.in
index a9e779f9..25156854 100644
--- a/lib/export/isc/nls/Makefile.in
+++ b/lib/export/isc/nls/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/nothreads/Makefile.in b/lib/export/isc/nothreads/Makefile.in
index 93b21093..994da636 100644
--- a/lib/export/isc/nothreads/Makefile.in
+++ b/lib/export/isc/nothreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/nothreads/include/isc/Makefile.in b/lib/export/isc/nothreads/include/isc/Makefile.in
index eb25c885..9bda987d 100644
--- a/lib/export/isc/nothreads/include/isc/Makefile.in
+++ b/lib/export/isc/nothreads/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/pthreads/Makefile.in b/lib/export/isc/pthreads/Makefile.in
index 92788ec1..f08e5c63 100644
--- a/lib/export/isc/pthreads/Makefile.in
+++ b/lib/export/isc/pthreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/pthreads/include/isc/Makefile.in b/lib/export/isc/pthreads/include/isc/Makefile.in
index 77d5c077..43197685 100644
--- a/lib/export/isc/pthreads/include/isc/Makefile.in
+++ b/lib/export/isc/pthreads/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/unix/Makefile.in b/lib/export/isc/unix/Makefile.in
index 5a8eed88..f5cf7e86 100644
--- a/lib/export/isc/unix/Makefile.in
+++ b/lib/export/isc/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isc/unix/include/isc/Makefile.in b/lib/export/isc/unix/include/isc/Makefile.in
index f19b8c65..7159c768 100644
--- a/lib/export/isc/unix/include/isc/Makefile.in
+++ b/lib/export/isc/unix/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/isccfg/include/isccfg/Makefile.in b/lib/export/isccfg/include/isccfg/Makefile.in
index 5e9ea78d..57a344cc 100644
--- a/lib/export/isccfg/include/isccfg/Makefile.in
+++ b/lib/export/isccfg/include/isccfg/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/samples/Makefile-postinstall.in b/lib/export/samples/Makefile-postinstall.in
index 174aed60..5b1aafba 100644
--- a/lib/export/samples/Makefile-postinstall.in
+++ b/lib/export/samples/Makefile-postinstall.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/export/samples/Makefile.in b/lib/export/samples/Makefile.in
index c60baac5..cdc66b16 100644
--- a/lib/export/samples/Makefile.in
+++ b/lib/export/samples/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/irs/Makefile.in b/lib/irs/Makefile.in
index ed869679..d3c47b01 100644
--- a/lib/irs/Makefile.in
+++ b/lib/irs/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/irs/include/Makefile.in b/lib/irs/include/Makefile.in
index eca19452..91099f1e 100644
--- a/lib/irs/include/Makefile.in
+++ b/lib/irs/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/irs/include/irs/Makefile.in b/lib/irs/include/irs/Makefile.in
index 3c3b6127..63e7fd6b 100644
--- a/lib/irs/include/irs/Makefile.in
+++ b/lib/irs/include/irs/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/alpha/Makefile.in b/lib/isc/alpha/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/alpha/Makefile.in
+++ b/lib/isc/alpha/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/alpha/include/Makefile.in b/lib/isc/alpha/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/alpha/include/Makefile.in
+++ b/lib/isc/alpha/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/alpha/include/isc/Makefile.in b/lib/isc/alpha/include/isc/Makefile.in
index 5f116cac..4927e210 100644
--- a/lib/isc/alpha/include/isc/Makefile.in
+++ b/lib/isc/alpha/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/api b/lib/isc/api
index ed4b69f8..178430ae 100644
--- a/lib/isc/api
+++ b/lib/isc/api
@@ -3,6 +3,6 @@
# 9.7: 60-79
# 9.8: 80-89
# 9.9: 90-109
-LIBINTERFACE = 91
-LIBREVISION = 1
+LIBINTERFACE = 93
+LIBREVISION = 0
LIBAGE = 1
diff --git a/lib/isc/ia64/Makefile.in b/lib/isc/ia64/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/ia64/Makefile.in
+++ b/lib/isc/ia64/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/ia64/include/Makefile.in b/lib/isc/ia64/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/ia64/include/Makefile.in
+++ b/lib/isc/ia64/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/ia64/include/isc/Makefile.in b/lib/isc/ia64/include/isc/Makefile.in
index 5f116cac..4927e210 100644
--- a/lib/isc/ia64/include/isc/Makefile.in
+++ b/lib/isc/ia64/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/ia64/include/isc/atomic.h b/lib/isc/ia64/include/isc/atomic.h
index 6c22f2a5..557941d0 100644
--- a/lib/isc/ia64/include/isc/atomic.h
+++ b/lib/isc/ia64/include/isc/atomic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -41,7 +41,7 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val)
for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
swapped = prev + val;
__asm__ volatile(
- "mov ar.ccv=%2;"
+ "mov ar.ccv=%2;;"
"cmpxchg4.acq %0=%4,%3,ar.ccv"
: "=r" (swapped), "=m" (*p)
: "r" (prev), "r" (swapped), "m" (*p)
@@ -84,7 +84,7 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val)
isc_int32_t ret;
__asm__ volatile(
- "mov ar.ccv=%2;"
+ "mov ar.ccv=%2;;"
"cmpxchg4.acq %0=%4,%3,ar.ccv"
: "=r" (ret), "=m" (*p)
: "r" (cmpval), "r" (val), "m" (*p)
diff --git a/lib/isc/include/Makefile.in b/lib/isc/include/Makefile.in
index 04778d78..70c165ef 100644
--- a/lib/isc/include/Makefile.in
+++ b/lib/isc/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h
index 8794065b..38f78b74 100644
--- a/lib/isc/include/isc/file.h
+++ b/lib/isc/include/isc/file.h
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <isc/lang.h>
+#include <isc/stat.h>
#include <isc/types.h>
ISC_LANG_BEGINDECLS
@@ -33,6 +34,9 @@ isc_result_t
isc_file_settime(const char *file, isc_time_t *time);
isc_result_t
+isc_file_mode(const char *file, mode_t *modep);
+
+isc_result_t
isc_file_getmodtime(const char *file, isc_time_t *time);
/*!<
* \brief Get the time of last modification of a file.
@@ -97,15 +101,22 @@ isc_file_mktemplate(const char *path, char *buf, size_t buflen);
* of the path with the internal template string.
*/
-
isc_result_t
isc_file_openunique(char *templet, FILE **fp);
isc_result_t
isc_file_openuniqueprivate(char *templet, FILE **fp);
isc_result_t
isc_file_openuniquemode(char *templet, int mode, FILE **fp);
+isc_result_t
+isc_file_bopenunique(char *templet, FILE **fp);
+isc_result_t
+isc_file_bopenuniqueprivate(char *templet, FILE **fp);
+isc_result_t
+isc_file_bopenuniquemode(char *templet, int mode, FILE **fp);
/*!<
* \brief Create and open a file with a unique name based on 'templet'.
+ * isc_file_bopen*() open the file in binary mode in Windows.
+ * isc_file_open*() open the file in text mode in Windows.
*
* Notes:
*\li 'template' is a reserved work in C++. If you want to complain
diff --git a/lib/isc/include/isc/heap.h b/lib/isc/include/isc/heap.h
index 77bf07c3..0b3a53b0 100644
--- a/lib/isc/include/isc/heap.h
+++ b/lib/isc/include/isc/heap.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -60,6 +60,8 @@ isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
* storage method. When the heap elements are deleted space is not freed
* but will be reused when new elements are inserted.
*
+ * Heap elements are indexed from 1.
+ *
* Requires:
*\li "mctx" is valid.
*\li "compare" is a function which takes two void * arguments and
diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h
index cd4ec9ad..05b7daa7 100644
--- a/lib/isc/include/isc/namespace.h
+++ b/lib/isc/include/isc/namespace.h
@@ -151,6 +151,8 @@
#define isc_taskmgr_setmode isc__taskmgr_setmode
#define isc_taskmgr_mode isc__taskmgr_mode
#define isc_taskmgr_destroy isc__taskmgr_destroy
+#define isc_taskmgr_setexcltask isc__taskmgr_setexcltask
+#define isc_taskmgr_excltask isc__taskmgr_excltask
#define isc_task_beginexclusive isc__task_beginexclusive
#define isc_task_endexclusive isc__task_endexclusive
#define isc_task_setprivilege isc__task_setprivilege
diff --git a/lib/isc/include/isc/queue.h b/lib/isc/include/isc/queue.h
index 1bc9d5b4..22e2a01e 100644
--- a/lib/isc/include/isc/queue.h
+++ b/lib/isc/include/isc/queue.h
@@ -35,7 +35,7 @@
#define ISC_QLINK_INSIST(x) (void)0
#endif
-#define ISC_QLINK(type) struct { void *prev, *next; }
+#define ISC_QLINK(type) struct { type *prev, *next; }
#define ISC_QLINK_INIT(elt, link) \
do { \
@@ -142,4 +142,22 @@
(ret)->link.next = (ret)->link.prev = (void *)(-1); \
} while(0)
+#define ISC_QUEUE_UNLINK(queue, elt, link) \
+ do { \
+ ISC_QLINK_INSIST(ISC_QLINK_LINKED(elt, link)); \
+ LOCK(&(queue).headlock); \
+ LOCK(&(queue).taillock); \
+ if ((elt)->link.prev == NULL) \
+ (queue).head = (elt)->link.next; \
+ else \
+ (elt)->link.prev->link.next = (elt)->link.next; \
+ if ((elt)->link.next == NULL) \
+ (queue).tail = (elt)->link.prev; \
+ else \
+ (elt)->link.next->link.prev = (elt)->link.prev; \
+ UNLOCK(&(queue).taillock); \
+ UNLOCK(&(queue).headlock); \
+ (elt)->link.next = (elt)->link.prev = (void *)(-1); \
+ } while(0)
+
#endif /* ISC_QUEUE_H */
diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h
index 594d80f3..c63c3e66 100644
--- a/lib/isc/include/isc/task.h
+++ b/lib/isc/include/isc/task.h
@@ -115,6 +115,8 @@ typedef struct isc_taskmgrmethods {
isc_result_t (*taskcreate)(isc_taskmgr_t *manager,
unsigned int quantum,
isc_task_t **taskp);
+ void (*setexcltask)(isc_taskmgr_t *mgr, isc_task_t *task);
+ isc_result_t (*excltask)(isc_taskmgr_t *mgr, isc_task_t **taskp);
} isc_taskmgrmethods_t;
typedef struct isc_taskmethods {
@@ -759,6 +761,31 @@ isc_taskmgr_destroy(isc_taskmgr_t **managerp);
* have been freed.
*/
+void
+isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task);
+/*%<
+ * Set a task which will be used for all task-exclusive operations.
+ *
+ * Requires:
+ *\li 'manager' is a valid task manager.
+ *
+ *\li 'task' is a valid task.
+ */
+
+isc_result_t
+isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp);
+/*%<
+ * Attach '*taskp' to the task set by isc_taskmgr_getexcltask().
+ * This task should be used whenever running in task-exclusive mode,
+ * so as to prevent deadlock between two exclusive tasks.
+ *
+ * Requires:
+ *\li 'manager' is a valid task manager.
+
+ *\li taskp != NULL && *taskp == NULL
+ */
+
+
#ifdef HAVE_LIBXML2
void
diff --git a/lib/isc/mem.c b/lib/isc/mem.c
index 5b4b16c5..1964b7a0 100644
--- a/lib/isc/mem.c
+++ b/lib/isc/mem.c
@@ -1191,7 +1191,7 @@ isc___mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) {
oldsize -= ALIGNMENT_SIZE;
INSIST(oldsize == size);
}
- isc_mem_free((isc_mem_t *)ctx, ptr);
+ isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS);
MCTXLOCK(ctx, &ctx->lock);
ctx->references--;
@@ -1327,7 +1327,7 @@ isc___mem_put(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
oldsize -= ALIGNMENT_SIZE;
INSIST(oldsize == size);
}
- isc_mem_free((isc_mem_t *)ctx, ptr);
+ isc__mem_free((isc_mem_t *)ctx, ptr FLARG_PASS);
return;
}
@@ -1592,7 +1592,11 @@ isc___mem_reallocate(isc_mem_t *ctx0, void *ptr, size_t size FLARG) {
oldsize = (((size_info *)ptr)[-1]).u.size;
INSIST(oldsize >= ALIGNMENT_SIZE);
oldsize -= ALIGNMENT_SIZE;
- copysize = oldsize > size ? size : oldsize;
+ if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {
+ INSIST(oldsize >= ALIGNMENT_SIZE);
+ oldsize -= ALIGNMENT_SIZE;
+ }
+ copysize = (oldsize > size) ? size : oldsize;
memcpy(new_ptr, ptr, copysize);
isc__mem_free(ctx0, ptr FLARG_PASS);
}
diff --git a/lib/isc/mips/Makefile.in b/lib/isc/mips/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/mips/Makefile.in
+++ b/lib/isc/mips/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/mips/include/Makefile.in b/lib/isc/mips/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/mips/include/Makefile.in
+++ b/lib/isc/mips/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/mips/include/isc/Makefile.in b/lib/isc/mips/include/isc/Makefile.in
index 5f116cac..4927e210 100644
--- a/lib/isc/mips/include/isc/Makefile.in
+++ b/lib/isc/mips/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/nls/Makefile.in b/lib/isc/nls/Makefile.in
index aca4a273..7bacf1c8 100644
--- a/lib/isc/nls/Makefile.in
+++ b/lib/isc/nls/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/noatomic/Makefile.in b/lib/isc/noatomic/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/noatomic/Makefile.in
+++ b/lib/isc/noatomic/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/noatomic/include/Makefile.in b/lib/isc/noatomic/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/noatomic/include/Makefile.in
+++ b/lib/isc/noatomic/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/noatomic/include/isc/Makefile.in b/lib/isc/noatomic/include/isc/Makefile.in
index 5f116cac..4927e210 100644
--- a/lib/isc/noatomic/include/isc/Makefile.in
+++ b/lib/isc/noatomic/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/nothreads/Makefile.in b/lib/isc/nothreads/Makefile.in
index 7e7abd6b..540b2434 100644
--- a/lib/isc/nothreads/Makefile.in
+++ b/lib/isc/nothreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/nothreads/include/Makefile.in b/lib/isc/nothreads/include/Makefile.in
index a52310a6..662a72df 100644
--- a/lib/isc/nothreads/include/Makefile.in
+++ b/lib/isc/nothreads/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/nothreads/include/isc/Makefile.in b/lib/isc/nothreads/include/isc/Makefile.in
index 3c9eab0e..a2c347ea 100644
--- a/lib/isc/nothreads/include/isc/Makefile.in
+++ b/lib/isc/nothreads/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/powerpc/Makefile.in b/lib/isc/powerpc/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/powerpc/Makefile.in
+++ b/lib/isc/powerpc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/powerpc/include/Makefile.in b/lib/isc/powerpc/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/powerpc/include/Makefile.in
+++ b/lib/isc/powerpc/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/powerpc/include/isc/Makefile.in b/lib/isc/powerpc/include/isc/Makefile.in
index 5f116cac..4927e210 100644
--- a/lib/isc/powerpc/include/isc/Makefile.in
+++ b/lib/isc/powerpc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/pthreads/Makefile.in b/lib/isc/pthreads/Makefile.in
index d6e7c760..9f66ef33 100644
--- a/lib/isc/pthreads/Makefile.in
+++ b/lib/isc/pthreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/pthreads/condition.c b/lib/isc/pthreads/condition.c
index 50281a2b..9053cf0f 100644
--- a/lib/isc/pthreads/condition.c
+++ b/lib/isc/pthreads/condition.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -43,7 +43,14 @@ isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
* POSIX defines a timespec's tv_sec as time_t.
*/
result = isc_time_secondsastimet(t, &ts.tv_sec);
- if (result != ISC_R_SUCCESS)
+
+ /*
+ * If we have a range error ts.tv_sec is most probably a signed
+ * 32 bit value. Set ts.tv_sec to INT_MAX. This is a kludge.
+ */
+ if (result == ISC_R_RANGE)
+ ts.tv_sec = INT_MAX;
+ else if (result != ISC_R_SUCCESS)
return (result);
/*!
diff --git a/lib/isc/pthreads/include/Makefile.in b/lib/isc/pthreads/include/Makefile.in
index 0303ab13..46c243e1 100644
--- a/lib/isc/pthreads/include/Makefile.in
+++ b/lib/isc/pthreads/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/pthreads/include/isc/Makefile.in b/lib/isc/pthreads/include/isc/Makefile.in
index 11675ec2..7cadcf4b 100644
--- a/lib/isc/pthreads/include/isc/Makefile.in
+++ b/lib/isc/pthreads/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/sparc64/Makefile.in b/lib/isc/sparc64/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/sparc64/Makefile.in
+++ b/lib/isc/sparc64/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/sparc64/include/Makefile.in b/lib/isc/sparc64/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/sparc64/include/Makefile.in
+++ b/lib/isc/sparc64/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/sparc64/include/isc/Makefile.in b/lib/isc/sparc64/include/isc/Makefile.in
index 5f116cac..4927e210 100644
--- a/lib/isc/sparc64/include/isc/Makefile.in
+++ b/lib/isc/sparc64/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/task.c b/lib/isc/task.c
index 227b2959..9c8badd4 100644
--- a/lib/isc/task.c
+++ b/lib/isc/task.c
@@ -156,6 +156,7 @@ struct isc__taskmgr {
isc_boolean_t pause_requested;
isc_boolean_t exclusive_requested;
isc_boolean_t exiting;
+ isc__task_t *excl;
#ifdef USE_SHARED_MANAGER
unsigned int refs;
#endif /* ISC_PLATFORM_USETHREADS */
@@ -225,6 +226,10 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
unsigned int default_quantum, isc_taskmgr_t **managerp);
ISC_TASKFUNC_SCOPE void
isc__taskmgr_destroy(isc_taskmgr_t **managerp);
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp);
ISC_TASKFUNC_SCOPE isc_result_t
isc__task_beginexclusive(isc_task_t *task);
ISC_TASKFUNC_SCOPE void
@@ -286,7 +291,9 @@ static isc_taskmgrmethods_t taskmgrmethods = {
isc__taskmgr_destroy,
isc__taskmgr_setmode,
isc__taskmgr_mode,
- isc__task_create
+ isc__task_create,
+ isc__taskmgr_setexcltask,
+ isc__taskmgr_excltask
};
/***
@@ -1396,6 +1403,7 @@ isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
manager->exclusive_requested = ISC_FALSE;
manager->pause_requested = ISC_FALSE;
manager->exiting = ISC_FALSE;
+ manager->excl = NULL;
isc_mem_attach(mctx, &manager->mctx);
@@ -1480,6 +1488,12 @@ isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
*/
/*
+ * Detach the exclusive task before acquiring the manager lock
+ */
+ if (manager->excl != NULL)
+ isc__task_detach((isc_task_t **) &manager->excl);
+
+ /*
* Unlike elsewhere, we're going to hold this lock a long time.
* We need to do so, because otherwise the list of tasks could
* change while we were traversing it.
@@ -1629,12 +1643,41 @@ isc__taskmgr_resume(isc_taskmgr_t *manager0) {
}
#endif /* USE_WORKER_THREADS */
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_setexcltask(isc_taskmgr_t *mgr0, isc_task_t *task0) {
+ isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0;
+ isc__task_t *task = (isc__task_t *) task0;
+
+ REQUIRE(VALID_MANAGER(mgr));
+ REQUIRE(VALID_TASK(task));
+ if (mgr->excl != NULL)
+ isc__task_detach((isc_task_t **) &mgr->excl);
+ isc__task_attach(task0, (isc_task_t **) &mgr->excl);
+}
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_excltask(isc_taskmgr_t *mgr0, isc_task_t **taskp) {
+ isc__taskmgr_t *mgr = (isc__taskmgr_t *) mgr0;
+
+ REQUIRE(VALID_MANAGER(mgr));
+ REQUIRE(taskp != NULL && *taskp == NULL);
+
+ if (mgr->excl == NULL)
+ return (ISC_R_NOTFOUND);
+
+ isc__task_attach((isc_task_t *) mgr->excl, taskp);
+ return (ISC_R_SUCCESS);
+}
+
ISC_TASKFUNC_SCOPE isc_result_t
isc__task_beginexclusive(isc_task_t *task0) {
#ifdef USE_WORKER_THREADS
isc__task_t *task = (isc__task_t *)task0;
isc__taskmgr_t *manager = task->manager;
+
REQUIRE(task->state == task_state_running);
+ /* XXX: Require task == manager->excl? */
+
LOCK(&manager->lock);
if (manager->exclusive_requested) {
UNLOCK(&manager->lock);
diff --git a/lib/isc/task_api.c b/lib/isc/task_api.c
index 34510ff6..f49ab321 100644
--- a/lib/isc/task_api.c
+++ b/lib/isc/task_api.c
@@ -201,6 +201,17 @@ isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type, void *tag)
return (task->methods->purgeevents(task, sender, type, tag));
}
+void
+isc_taskmgr_setexcltask(isc_taskmgr_t *mgr, isc_task_t *task) {
+ REQUIRE(ISCAPI_TASK_VALID(task));
+ return (mgr->methods->setexcltask(mgr, task));
+}
+
+isc_result_t
+isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp) {
+ return (mgr->methods->excltask(mgr, taskp));
+}
+
isc_result_t
isc_task_beginexclusive(isc_task_t *task) {
REQUIRE(ISCAPI_TASK_VALID(task));
diff --git a/lib/isc/tests/isctest.c b/lib/isc/tests/isctest.c
index e118bbf2..41b09fce 100644
--- a/lib/isc/tests/isctest.c
+++ b/lib/isc/tests/isctest.c
@@ -42,6 +42,7 @@ isc_log_t *lctx = NULL;
isc_taskmgr_t *taskmgr = NULL;
isc_timermgr_t *timermgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
+isc_task_t *maintask = NULL;
int ncpus;
static isc_boolean_t hash_active = ISC_FALSE;
@@ -63,6 +64,8 @@ static isc_logcategory_t categories[] = {
static void
cleanup_managers() {
+ if (maintask != NULL)
+ isc_task_destroy(&maintask);
if (socketmgr != NULL)
isc_socketmgr_destroy(&socketmgr);
if (taskmgr != NULL)
@@ -81,6 +84,9 @@ create_managers() {
#endif
CHECK(isc_taskmgr_create(mctx, ncpus, 0, &taskmgr));
+ CHECK(isc_task_create(taskmgr, 0, &maintask));
+ isc_taskmgr_setexcltask(taskmgr, maintask);
+
CHECK(isc_timermgr_create(mctx, &timermgr));
CHECK(isc_socketmgr_create(mctx, &socketmgr));
return (ISC_R_SUCCESS);
@@ -138,6 +144,8 @@ isc_test_begin(FILE *logfile, isc_boolean_t start_managers) {
void
isc_test_end() {
+ if (maintask != NULL)
+ isc_task_detach(&maintask);
if (taskmgr != NULL)
isc_taskmgr_destroy(&taskmgr);
if (lctx != NULL)
diff --git a/lib/isc/tests/queue_test.c b/lib/isc/tests/queue_test.c
index 74620fef..c4a80c4c 100644
--- a/lib/isc/tests/queue_test.c
+++ b/lib/isc/tests/queue_test.c
@@ -29,10 +29,11 @@
#include "isctest.h"
-typedef struct item {
+typedef struct item item_t;
+struct item {
int value;
ISC_QLINK(item_t) qlink;
-} item_t;
+};
typedef ISC_QUEUE(item_t) item_queue_t;
@@ -107,6 +108,9 @@ ATF_TC_BODY(queue_valid, tc) {
ISC_QUEUE_PUSH(queue, &five, qlink);
ATF_CHECK(ISC_QLINK_LINKED(&five, qlink));
+ /* Test unlink by removing one item from the middle */
+ ISC_QUEUE_UNLINK(queue, &three, qlink);
+
ISC_QUEUE_POP(queue, qlink, p);
ATF_REQUIRE(p != NULL);
ATF_CHECK_EQ(p->value, 1);
@@ -117,10 +121,6 @@ ATF_TC_BODY(queue_valid, tc) {
ISC_QUEUE_POP(queue, qlink, p);
ATF_REQUIRE(p != NULL);
- ATF_CHECK_EQ(p->value, 3);
-
- ISC_QUEUE_POP(queue, qlink, p);
- ATF_REQUIRE(p != NULL);
ATF_CHECK_EQ(p->value, 4);
ISC_QUEUE_POP(queue, qlink, p);
diff --git a/lib/isc/unix/Makefile.in b/lib/isc/unix/Makefile.in
index 9884ca90..c1411cb3 100644
--- a/lib/isc/unix/Makefile.in
+++ b/lib/isc/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c
index 0538761a..99c02ec7 100644
--- a/lib/isc/unix/file.c
+++ b/lib/isc/unix/file.c
@@ -98,6 +98,20 @@ file_stats(const char *file, struct stat *stats) {
}
isc_result_t
+isc_file_mode(const char *file, mode_t *modep) {
+ isc_result_t result;
+ struct stat stats;
+
+ REQUIRE(modep != NULL);
+
+ result = file_stats(file, &stats);
+ if (result == ISC_R_SUCCESS)
+ *modep = (stats.st_mode & 07777);
+
+ return (result);
+}
+
+isc_result_t
isc_file_getmodtime(const char *file, isc_time_t *time) {
isc_result_t result;
struct stat stats;
@@ -313,6 +327,23 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
}
isc_result_t
+isc_file_bopenunique(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_bopenuniqueprivate(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_bopenuniquemode(char *templet, int mode, FILE **fp) {
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
isc_file_remove(const char *filename) {
int r;
diff --git a/lib/isc/unix/include/Makefile.in b/lib/isc/unix/include/Makefile.in
index 0303ab13..46c243e1 100644
--- a/lib/isc/unix/include/Makefile.in
+++ b/lib/isc/unix/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/unix/include/isc/Makefile.in b/lib/isc/unix/include/isc/Makefile.in
index 2f4d2164..d3b50842 100644
--- a/lib/isc/unix/include/isc/Makefile.in
+++ b/lib/isc/unix/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/win32/Makefile.in b/lib/isc/win32/Makefile.in
index 3396db1e..c129e31c 100644
--- a/lib/isc/win32/Makefile.in
+++ b/lib/isc/win32/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/win32/file.c b/lib/isc/win32/file.c
index c6b9e4f5..146fd35e 100644
--- a/lib/isc/win32/file.c
+++ b/lib/isc/win32/file.c
@@ -45,10 +45,14 @@
*
*/
static int
-gettemp(char *path, int *doopen) {
+gettemp(char *path, isc_boolean_t binary, int *doopen) {
char *start, *trv;
struct stat sbuf;
int pid;
+ int flags = O_CREAT|O_EXCL|O_RDWR;
+
+ if (binary)
+ flags |= _O_BINARY;
trv = strrchr(path, 'X');
trv++;
@@ -81,8 +85,7 @@ gettemp(char *path, int *doopen) {
for (;;) {
if (doopen) {
if ((*doopen =
- open(path, O_CREAT|O_EXCL|O_RDWR,
- _S_IREAD | _S_IWRITE)) >= 0)
+ open(path, flags, _S_IREAD | _S_IWRITE)) >= 0)
return (1);
if (errno != EEXIST)
return (0);
@@ -108,10 +111,10 @@ gettemp(char *path, int *doopen) {
}
static int
-mkstemp(char *path) {
+mkstemp(char *path, isc_boolean_t binary) {
int fd;
- return (gettemp(path, &fd) ? fd : -1);
+ return (gettemp(path, binary, &fd) ? fd : -1);
}
/*
@@ -165,7 +168,7 @@ isc_file_safemovefile(const char *oldname, const char *newname) {
exists = TRUE;
strcpy(buf, newname);
strcat(buf, ".XXXXX");
- tmpfd = mkstemp(buf);
+ tmpfd = mkstemp(buf, ISC_TRUE);
if (tmpfd > 0)
_close(tmpfd);
DeleteFile(buf);
@@ -300,7 +303,7 @@ isc_file_renameunique(const char *file, char *templet) {
REQUIRE(file != NULL);
REQUIRE(templet != NULL);
- fd = mkstemp(templet);
+ fd = mkstemp(templet, ISC_TRUE);
if (fd == -1)
result = isc__errno2result(errno);
else
@@ -316,20 +319,8 @@ isc_file_renameunique(const char *file, char *templet) {
return (result);
}
-isc_result_t
-isc_file_openuniqueprivate(char *templet, FILE **fp) {
- int mode = _S_IREAD | _S_IWRITE;
- return (isc_file_openuniquemode(templet, mode, fp));
-}
-
-isc_result_t
-isc_file_openunique(char *templet, FILE **fp) {
- int mode = _S_IREAD | _S_IWRITE;
- return (isc_file_openuniquemode(templet, mode, fp));
-}
-
-isc_result_t
-isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
+static isc_result_t
+openuniquemode(char *templet, int mode, isc_boolean_t binary, FILE **fp) {
int fd;
FILE *f;
isc_result_t result = ISC_R_SUCCESS;
@@ -340,7 +331,7 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
/*
* Win32 does not have mkstemp. Using emulation above.
*/
- fd = mkstemp(templet);
+ fd = mkstemp(templet, binary);
if (fd == -1)
result = isc__errno2result(errno);
@@ -350,7 +341,7 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
#else
(void)fchmod(fd, mode);
#endif
- f = fdopen(fd, "w+");
+ f = fdopen(fd, binary ? "wb+" : "w+");
if (f == NULL) {
result = isc__errno2result(errno);
(void)remove(templet);
@@ -363,6 +354,40 @@ isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
}
isc_result_t
+isc_file_openuniqueprivate(char *templet, FILE **fp) {
+ int mode = _S_IREAD | _S_IWRITE;
+ return (openuniquemode(templet, mode, ISC_FALSE, fp));
+}
+
+isc_result_t
+isc_file_openunique(char *templet, FILE **fp) {
+ int mode = _S_IREAD | _S_IWRITE;
+ return (openuniquemode(templet, mode, ISC_FALSE, fp));
+}
+
+isc_result_t
+isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
+ return (openuniquemode(templet, mode, ISC_FALSE, fp));
+}
+
+isc_result_t
+isc_file_bopenuniqueprivate(char *templet, FILE **fp) {
+ int mode = _S_IREAD | _S_IWRITE;
+ return (openuniquemode(templet, mode, ISC_TRUE, fp));
+}
+
+isc_result_t
+isc_file_bopenunique(char *templet, FILE **fp) {
+ int mode = _S_IREAD | _S_IWRITE;
+ return (openuniquemode(templet, mode, ISC_TRUE, fp));
+}
+
+isc_result_t
+isc_file_bopenuniquemode(char *templet, int mode, FILE **fp) {
+ return (openuniquemode(templet, mode, ISC_TRUE, fp));
+}
+
+isc_result_t
isc_file_remove(const char *filename) {
int r;
@@ -617,3 +642,16 @@ isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename)
return (ISC_R_SUCCESS);
}
+
+isc_result_t
+isc_file_mode(const char *file, mode_t *modep) {
+ isc_result_t result;
+ struct stat stats;
+
+ REQUIRE(modep != NULL);
+
+ result = file_stats(file, &stats);
+ if (result == ISC_R_SUCCESS)
+ *modep = (stats.st_mode & 07777);
+ return (result);
+}
diff --git a/lib/isc/win32/include/Makefile.in b/lib/isc/win32/include/Makefile.in
index c74b52d2..60435f9e 100644
--- a/lib/isc/win32/include/Makefile.in
+++ b/lib/isc/win32/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/win32/include/isc/Makefile.in b/lib/isc/win32/include/isc/Makefile.in
index dcd85190..6b5bcea2 100644
--- a/lib/isc/win32/include/isc/Makefile.in
+++ b/lib/isc/win32/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isc/win32/include/isc/stat.h b/lib/isc/win32/include/isc/stat.h
index 2c822b9e..6703e329 100644
--- a/lib/isc/win32/include/isc/stat.h
+++ b/lib/isc/win32/include/isc/stat.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2009, 2012 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
@@ -22,6 +22,11 @@
#include <sys/stat.h>
+/*
+ * Windows doesn't typedef this.
+ */
+typedef unsigned short mode_t;
+
/* open() under unix allows setting of read/write permissions
* at the owner, group and other levels. These don't exist in NT
* We'll just map them all to the NT equivalent
diff --git a/lib/isc/win32/libisc.def b/lib/isc/win32/libisc.def
index fb084103..fe3f739b 100644
--- a/lib/isc/win32/libisc.def
+++ b/lib/isc/win32/libisc.def
@@ -140,7 +140,9 @@ isc__task_unsend
isc__task_unsendrange
isc__taskmgr_create
isc__taskmgr_destroy
+isc__taskmgr_excltask
isc__taskmgr_mode
+isc__taskmgr_setexcltask
isc__taskmgr_setmode
isc__timer_attach
isc__timer_create
@@ -218,6 +220,9 @@ isc_event_allocate
isc_event_free
isc_file_absolutepath
isc_file_basename
+isc_file_bopenunique
+isc_file_bopenuniquemode
+isc_file_bopenuniqueprivate
isc_file_exists
isc_file_getmodtime
isc_file_isabsolute
@@ -225,6 +230,7 @@ isc_file_ischdiridempotent
isc_file_iscurrentdir
isc_file_isplainfile
isc_file_mktemplate
+isc_file_mode
isc_file_openunique
isc_file_openuniquemode
isc_file_openuniqueprivate
diff --git a/lib/isc/x86_32/Makefile.in b/lib/isc/x86_32/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/x86_32/Makefile.in
+++ b/lib/isc/x86_32/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/x86_32/include/Makefile.in b/lib/isc/x86_32/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/x86_32/include/Makefile.in
+++ b/lib/isc/x86_32/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/x86_32/include/isc/Makefile.in b/lib/isc/x86_32/include/isc/Makefile.in
index 5f116cac..4927e210 100644
--- a/lib/isc/x86_32/include/isc/Makefile.in
+++ b/lib/isc/x86_32/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/x86_64/Makefile.in b/lib/isc/x86_64/Makefile.in
index 324db070..9c24cdf9 100644
--- a/lib/isc/x86_64/Makefile.in
+++ b/lib/isc/x86_64/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/x86_64/include/Makefile.in b/lib/isc/x86_64/include/Makefile.in
index f1d8bdd3..e3995599 100644
--- a/lib/isc/x86_64/include/Makefile.in
+++ b/lib/isc/x86_64/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isc/x86_64/include/isc/Makefile.in b/lib/isc/x86_64/include/isc/Makefile.in
index f33ae994..9a988bb7 100644
--- a/lib/isc/x86_64/include/isc/Makefile.in
+++ b/lib/isc/x86_64/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
diff --git a/lib/isccc/api b/lib/isccc/api
index 59e4f66c..e34aa945 100644
--- a/lib/isccc/api
+++ b/lib/isccc/api
@@ -4,5 +4,5 @@
# 9.8: 80-89
# 9.9: 90-109
LIBINTERFACE = 90
-LIBREVISION = 1
+LIBREVISION = 2
LIBAGE = 0
diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c
index b549d6cb..1ab94798 100644
--- a/lib/isccc/cc.c
+++ b/lib/isccc/cc.c
@@ -399,8 +399,6 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret,
first_tag = ISC_FALSE;
}
- *alistp = alist;
-
if (secret != NULL) {
if (checksum_rstart != NULL)
result = verify(alist, checksum_rstart,
@@ -412,7 +410,9 @@ table_fromwire(isccc_region_t *source, isccc_region_t *secret,
result = ISC_R_SUCCESS;
bad:
- if (result != ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS)
+ *alistp = alist;
+ else
isccc_sexpr_free(&alist);
return (result);
diff --git a/lib/isccc/include/Makefile.in b/lib/isccc/include/Makefile.in
index 9f727c30..6b222a52 100644
--- a/lib/isccc/include/Makefile.in
+++ b/lib/isccc/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isccc/include/isccc/Makefile.in b/lib/isccc/include/isccc/Makefile.in
index ae5bec75..c4af19a7 100644
--- a/lib/isccc/include/isccc/Makefile.in
+++ b/lib/isccc/include/isccc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isccfg/api b/lib/isccfg/api
index 59e4f66c..e34aa945 100644
--- a/lib/isccfg/api
+++ b/lib/isccfg/api
@@ -4,5 +4,5 @@
# 9.8: 80-89
# 9.9: 90-109
LIBINTERFACE = 90
-LIBREVISION = 1
+LIBREVISION = 2
LIBAGE = 0
diff --git a/lib/isccfg/include/Makefile.in b/lib/isccfg/include/Makefile.in
index 1f240030..5c6976a8 100644
--- a/lib/isccfg/include/Makefile.in
+++ b/lib/isccfg/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isccfg/include/isccfg/Makefile.in b/lib/isccfg/include/isccfg/Makefile.in
index a6fd4125..211583a5 100644
--- a/lib/isccfg/include/isccfg/Makefile.in
+++ b/lib/isccfg/include/isccfg/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001, 2002 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index 58b5ca4c..541f078b 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -917,6 +917,7 @@ options_clauses[] = {
{ "listen-on-v6", &cfg_type_listenon, CFG_CLAUSEFLAG_MULTI },
{ "managed-keys-directory", &cfg_type_qstring, 0 },
{ "match-mapped-addresses", &cfg_type_boolean, 0 },
+ { "max-rsa-exponent-size", &cfg_type_uint32, 0 },
{ "memstatistics-file", &cfg_type_qstring, 0 },
{ "memstatistics", &cfg_type_boolean, 0 },
{ "multiple-cnames", &cfg_type_boolean, CFG_CLAUSEFLAG_OBSOLETE },
@@ -1025,66 +1026,60 @@ static cfg_type_t cfg_type_masterformat = {
-/*
+/*%
* response-policy {
* zone <string> [ policy (given|disabled|passthru|
- * nxdomain|nodata|cname <domain> ) ];
- * };
- *
- * this is a chimera of doc_optional_keyvalue() and cfg_doc_enum()
+ * nxdomain|nodata|cname <domain> ) ]
+ * [ recursive-only yes|no ]
+ * [ max-policy-ttl number ] ;
+ * } [ recursive-only yes|no ] [ break-dnssec yes|no ]
+ * [ max-policy-ttl number ] ;
*/
+
static void
-doc_rpz_policies(cfg_printer_t *pctx, const cfg_type_t *type) {
- const keyword_type_t *kw;
+doc_rpz_policy(cfg_printer_t *pctx, const cfg_type_t *type) {
const char * const *p;
-
- kw = type->of;
- cfg_print_chars(pctx, "[ ", 2);
- cfg_print_cstr(pctx, kw->name);
- cfg_print_chars(pctx, " ", 1);
-
+ /*
+ * This is cfg_doc_enum() without the trailing " )".
+ */
cfg_print_chars(pctx, "( ", 2);
- for (p = kw->type->of; *p != NULL; p++) {
+ for (p = type->of; *p != NULL; p++) {
cfg_print_cstr(pctx, *p);
if (p[1] != NULL)
cfg_print_chars(pctx, " | ", 3);
}
}
-/*
- * print_qstring() from parser.c
- */
-static void
-print_rpz_cname(cfg_printer_t *pctx, const cfg_obj_t *obj)
-{
- cfg_print_chars(pctx, "\"", 1);
- cfg_print_ustring(pctx, obj);
- cfg_print_chars(pctx, "\"", 1);
-}
-
static void
doc_rpz_cname(cfg_printer_t *pctx, const cfg_type_t *type) {
cfg_doc_terminal(pctx, type);
- cfg_print_chars(pctx, " ) ]", 4);
+ cfg_print_chars(pctx, " )", 2);
}
+/*
+ * Parse
+ * given|disabled|passthru|nxdomain|nodata|cname <domain>
+ */
static isc_result_t
-parse_rpz(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+cfg_parse_rpz_policy(cfg_parser_t *pctx, const cfg_type_t *type,
+ cfg_obj_t **ret)
+{
isc_result_t result;
- cfg_obj_t *obj = NULL;
- const cfg_tuplefielddef_t *fields = type->of;
+ cfg_obj_t *obj;
+ const cfg_tuplefielddef_t *fields;
CHECK(cfg_create_tuple(pctx, type, &obj));
+
+ fields = type->of;
CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
- CHECK(cfg_parse_obj(pctx, fields[1].type, &obj->value.tuple[1]));
/*
* parse cname domain only after "policy cname"
*/
- if (cfg_obj_isvoid(obj->value.tuple[1]) ||
- strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[1]))) {
- CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[2]));
+ if (strcasecmp("cname", cfg_obj_asstring(obj->value.tuple[0])) != 0) {
+ CHECK(cfg_parse_void(pctx, NULL, &obj->value.tuple[1]));
} else {
- CHECK(cfg_parse_obj(pctx, fields[2].type, &obj->value.tuple[2]));
+ CHECK(cfg_parse_obj(pctx, fields[1].type,
+ &obj->value.tuple[1]));
}
*ret = obj;
@@ -1095,50 +1090,160 @@ cleanup:
return (result);
}
+/*
+ * Parse a tuple consisting of any kind of required field followed
+ * by 2 or more optional keyvalues that can be in any order.
+ */
+static isc_result_t
+cfg_parse_kv_tuple(cfg_parser_t *pctx, const cfg_type_t *type, cfg_obj_t **ret) {
+ const cfg_tuplefielddef_t *fields, *f;
+ cfg_obj_t *obj;
+ int fn;
+ isc_result_t result;
+
+ obj = NULL;
+ CHECK(cfg_create_tuple(pctx, type, &obj));
+
+ /*
+ * The zone first field is required and always first.
+ */
+ fields = type->of;
+ CHECK(cfg_parse_obj(pctx, fields[0].type, &obj->value.tuple[0]));
+
+ for (;;) {
+ CHECK(cfg_peektoken(pctx, CFG_LEXOPT_QSTRING));
+ if (pctx->token.type != isc_tokentype_string)
+ break;
+
+ for (fn = 1, f = &fields[1]; ; ++fn, ++f) {
+ if (f->name == NULL) {
+ cfg_parser_error(pctx, 0, "unexpected '%s'",
+ TOKEN_STRING(pctx));
+ result = ISC_R_UNEXPECTEDTOKEN;
+ goto cleanup;
+ }
+ if (obj->value.tuple[fn] == NULL &&
+ strcasecmp(f->name, TOKEN_STRING(pctx)) == 0)
+ break;
+ }
+
+ CHECK(cfg_gettoken(pctx, 0));
+ CHECK(cfg_parse_obj(pctx, f->type, &obj->value.tuple[fn]));
+ }
+
+ for (fn = 1, f = &fields[1]; f->name != NULL; ++fn, ++f) {
+ if (obj->value.tuple[fn] == NULL)
+ CHECK(cfg_parse_void(pctx, NULL,
+ &obj->value.tuple[fn]));
+ }
+
+ *ret = obj;
+ return (ISC_R_SUCCESS);
+
+cleanup:
+ CLEANUP_OBJ(obj);
+ return (result);
+}
+
+static void
+cfg_print_kv_tuple(cfg_printer_t *pctx, const cfg_obj_t *obj) {
+ unsigned int i;
+ const cfg_tuplefielddef_t *fields, *f;
+ const cfg_obj_t *fieldobj;
+
+ fields = obj->type->of;
+ for (f = fields, i = 0; f->name != NULL; f++, i++) {
+ fieldobj = obj->value.tuple[i];
+ if (fieldobj->type->print == cfg_print_void)
+ continue;
+ if (i != 0) {
+ cfg_print_chars(pctx, " ", 1);
+ cfg_print_cstr(pctx, f->name);
+ cfg_print_chars(pctx, " ", 1);
+ }
+ cfg_print_obj(pctx, fieldobj);
+ }
+}
+
+static void
+cfg_doc_kv_tuple(cfg_printer_t *pctx, const cfg_type_t *type) {
+ const cfg_tuplefielddef_t *fields, *f;
+
+ fields = type->of;
+ for (f = fields; f->name != NULL; f++) {
+ if (f != fields) {
+ cfg_print_chars(pctx, " [ ", 3);
+ cfg_print_cstr(pctx, f->name);
+ if (f->type->doc != cfg_doc_void)
+ cfg_print_chars(pctx, " ", 1);
+ }
+ cfg_doc_obj(pctx, f->type);
+ if (f != fields)
+ cfg_print_chars(pctx, " ]", 2);
+ }
+}
+
+static keyword_type_t zone_kw = {"zone", &cfg_type_qstring};
+static cfg_type_t cfg_type_rpz_zone = {
+ "zone", parse_keyvalue, print_keyvalue,
+ doc_keyvalue, &cfg_rep_string,
+ &zone_kw
+};
static const char *rpz_policies[] = {
"given", "disabled", "passthru", "no-op", "nxdomain", "nodata",
"cname", NULL
};
-static cfg_type_t cfg_type_rpz_policylist = {
- "policies", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
- &cfg_rep_string, &rpz_policies
+static cfg_type_t cfg_type_rpz_policy_name = {
+ "policy name", cfg_parse_enum, cfg_print_ustring,
+ doc_rpz_policy, &cfg_rep_string,
+ &rpz_policies
};
-static keyword_type_t rpz_policies_kw = {
- "policy", &cfg_type_rpz_policylist
+static cfg_type_t cfg_type_rpz_cname = {
+ "quoted_string", cfg_parse_astring, NULL,
+ doc_rpz_cname, &cfg_rep_string,
+ NULL
};
-static cfg_type_t cfg_type_rpz_policy = {
- "optional_policy", parse_optional_keyvalue, print_keyvalue,
- doc_rpz_policies, &cfg_rep_string, &rpz_policies_kw
+static cfg_tuplefielddef_t rpz_policy_fields[] = {
+ { "policy name", &cfg_type_rpz_policy_name, 0 },
+ { "cname", &cfg_type_rpz_cname, 0 },
+ { NULL, NULL, 0 }
};
-static cfg_type_t cfg_type_cname = {
- "domain", cfg_parse_astring, print_rpz_cname, doc_rpz_cname,
- &cfg_rep_string, NULL
+static cfg_type_t cfg_type_rpz_policy = {
+ "policy tuple", cfg_parse_rpz_policy,
+ cfg_print_tuple, cfg_doc_tuple, &cfg_rep_tuple,
+ rpz_policy_fields
};
-static cfg_tuplefielddef_t rpzone_fields[] = {
- { "name", &cfg_type_astring, 0 },
+static cfg_tuplefielddef_t rpz_zone_fields[] = {
+ { "zone name", &cfg_type_rpz_zone, 0 },
{ "policy", &cfg_type_rpz_policy, 0 },
- { "cname", &cfg_type_cname, 0 },
+ { "recursive-only", &cfg_type_boolean, 0 },
+ { "max-policy-ttl", &cfg_type_uint32, 0 },
{ NULL, NULL, 0 }
};
-static cfg_type_t cfg_type_rpzone = {
- "rpzone", parse_rpz, cfg_print_tuple, cfg_doc_tuple,
- &cfg_rep_tuple, rpzone_fields
+static cfg_type_t cfg_type_rpz_tuple = {
+ "rpz tuple", cfg_parse_kv_tuple,
+ cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
+ rpz_zone_fields
};
-static cfg_clausedef_t rpz_clauses[] = {
- { "zone", &cfg_type_rpzone, CFG_CLAUSEFLAG_MULTI },
- { NULL, NULL, 0 }
+static cfg_type_t cfg_type_rpz_list = {
+ "zone list", cfg_parse_bracketed_list, cfg_print_bracketed_list,
+ cfg_doc_bracketed_list, &cfg_rep_list,
+ &cfg_type_rpz_tuple
};
-static cfg_clausedef_t *rpz_clausesets[] = {
- rpz_clauses,
- NULL
+static cfg_tuplefielddef_t rpz_fields[] = {
+ { "zone list", &cfg_type_rpz_list, 0 },
+ { "recursive-only", &cfg_type_boolean, 0 },
+ { "break-dnssec", &cfg_type_boolean, 0 },
+ { "max-policy-ttl", &cfg_type_uint32, 0 },
+ { NULL, NULL, 0 }
};
static cfg_type_t cfg_type_rpz = {
- "rpz", cfg_parse_map, cfg_print_map, cfg_doc_map,
- &cfg_rep_map, rpz_clausesets
+ "rpz", cfg_parse_kv_tuple,
+ cfg_print_kv_tuple, cfg_doc_kv_tuple, &cfg_rep_tuple,
+ rpz_fields
};
-
/*%
* dnssec-lookaside
*/
diff --git a/lib/lwres/Makefile.in b/lib/lwres/Makefile.in
index 858b325d..0cf873b5 100644
--- a/lib/lwres/Makefile.in
+++ b/lib/lwres/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/api b/lib/lwres/api
index a45a6bff..59e4f66c 100644
--- a/lib/lwres/api
+++ b/lib/lwres/api
@@ -4,5 +4,5 @@
# 9.8: 80-89
# 9.9: 90-109
LIBINTERFACE = 90
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 0
diff --git a/lib/lwres/getaddrinfo.c b/lib/lwres/getaddrinfo.c
index 8e916f34..811a2fee 100644
--- a/lib/lwres/getaddrinfo.c
+++ b/lib/lwres/getaddrinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* This code is derived from software contributed to ISC by
@@ -398,7 +398,7 @@ lwres_getaddrinfo(const char *hostname, const char *servname,
goto inet6_addr;
}
addrsize = sizeof(struct in_addr);
- addroff = (char *)(&SIN(0)->sin_addr) - (char *)0;
+ addroff = offsetof(struct sockaddr_in, sin_addr);
family = AF_INET;
goto common;
#ifdef LWRES_HAVE_SIN6_SCOPE_ID
@@ -408,7 +408,7 @@ lwres_getaddrinfo(const char *hostname, const char *servname,
if (family && family != AF_INET6)
return (EAI_NONAME);
addrsize = sizeof(struct in6_addr);
- addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ addroff = offsetof(struct sockaddr_in6, sin6_addr);
family = AF_INET6;
goto common;
#endif
@@ -417,7 +417,7 @@ lwres_getaddrinfo(const char *hostname, const char *servname,
return (EAI_NONAME);
inet6_addr:
addrsize = sizeof(struct in6_addr);
- addroff = (char *)(&SIN6(0)->sin6_addr) - (char *)0;
+ addroff = offsetof(struct sockaddr_in6, sin6_addr);
family = AF_INET6;
common:
diff --git a/lib/lwres/include/Makefile.in b/lib/lwres/include/Makefile.in
index 4750a5e9..6c3d07fd 100644
--- a/lib/lwres/include/Makefile.in
+++ b/lib/lwres/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/include/lwres/Makefile.in b/lib/lwres/include/lwres/Makefile.in
index fc3126f8..36b8b03d 100644
--- a/lib/lwres/include/lwres/Makefile.in
+++ b/lib/lwres/include/lwres/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/man/Makefile.in b/lib/lwres/man/Makefile.in
index cb723c27..80db9f2f 100644
--- a/lib/lwres/man/Makefile.in
+++ b/lib/lwres/man/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/unix/Makefile.in b/lib/lwres/unix/Makefile.in
index 5d77208a..26ca4fb8 100644
--- a/lib/lwres/unix/Makefile.in
+++ b/lib/lwres/unix/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/unix/include/Makefile.in b/lib/lwres/unix/include/Makefile.in
index 61906330..5372543c 100644
--- a/lib/lwres/unix/include/Makefile.in
+++ b/lib/lwres/unix/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/unix/include/lwres/Makefile.in b/lib/lwres/unix/include/lwres/Makefile.in
index c943e015..4f60ce82 100644
--- a/lib/lwres/unix/include/lwres/Makefile.in
+++ b/lib/lwres/unix/include/lwres/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/win32/Makefile.in b/lib/lwres/win32/Makefile.in
index 5d77208a..26ca4fb8 100644
--- a/lib/lwres/win32/Makefile.in
+++ b/lib/lwres/win32/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/win32/include/Makefile.in b/lib/lwres/win32/include/Makefile.in
index 61906330..5372543c 100644
--- a/lib/lwres/win32/include/Makefile.in
+++ b/lib/lwres/win32/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/lwres/win32/include/lwres/Makefile.in b/lib/lwres/win32/include/lwres/Makefile.in
index c943e015..4f60ce82 100644
--- a/lib/lwres/win32/include/lwres/Makefile.in
+++ b/lib/lwres/win32/include/lwres/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/tests/Makefile.in b/lib/tests/Makefile.in
index 105d567d..02802656 100644
--- a/lib/tests/Makefile.in
+++ b/lib/tests/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001, 2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/tests/include/Makefile.in b/lib/tests/include/Makefile.in
index 10eedede..b529c75d 100644
--- a/lib/tests/include/Makefile.in
+++ b/lib/tests/include/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
diff --git a/lib/tests/include/tests/Makefile.in b/lib/tests/include/tests/Makefile.in
index 5d6ad0f6..cfadac78 100644
--- a/lib/tests/include/tests/Makefile.in
+++ b/lib/tests/include/tests/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1999-2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any