summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile.in7
-rw-r--r--lib/bind9/Makefile.in3
-rw-r--r--lib/bind9/api5
-rw-r--r--lib/bind9/check.c32
-rw-r--r--lib/dns/Makefile.in8
-rw-r--r--lib/dns/acache.c49
-rw-r--r--lib/dns/adb.c24
-rw-r--r--lib/dns/api7
-rw-r--r--lib/dns/cache.c8
-rw-r--r--lib/dns/client.c32
-rw-r--r--lib/dns/db.c7
-rw-r--r--lib/dns/dispatch.c22
-rw-r--r--lib/dns/dlz.c22
-rw-r--r--lib/dns/dnssec.c15
-rw-r--r--lib/dns/dst_api.c37
-rw-r--r--lib/dns/dst_internal.h1
-rw-r--r--lib/dns/dst_openssl.h5
-rw-r--r--lib/dns/ecdb.c9
-rw-r--r--lib/dns/gen.c184
-rw-r--r--lib/dns/gssapictx.c10
-rw-r--r--lib/dns/include/dns/acache.h15
-rw-r--r--lib/dns/include/dns/db.h10
-rw-r--r--lib/dns/include/dns/message.h26
-rw-r--r--lib/dns/include/dns/name.h22
-rw-r--r--lib/dns/include/dns/ncache.h7
-rw-r--r--lib/dns/include/dns/nsec.h13
-rw-r--r--lib/dns/include/dns/nsec3.h8
-rw-r--r--lib/dns/include/dns/rdata.h1
-rw-r--r--lib/dns/include/dns/result.h6
-rw-r--r--lib/dns/include/dns/rpz.h20
-rw-r--r--lib/dns/include/dns/types.h6
-rw-r--r--lib/dns/include/dns/validator.h6
-rw-r--r--lib/dns/include/dns/view.h3
-rw-r--r--lib/dns/include/dns/zone.h13
-rw-r--r--lib/dns/include/dst/dst.h6
-rw-r--r--lib/dns/master.c23
-rw-r--r--lib/dns/message.c155
-rw-r--r--lib/dns/name.c24
-rw-r--r--lib/dns/ncache.c24
-rw-r--r--lib/dns/nsec.c161
-rw-r--r--lib/dns/nsec3.c289
-rw-r--r--lib/dns/openssl_link.c62
-rw-r--r--lib/dns/openssldsa_link.c19
-rw-r--r--lib/dns/opensslecdsa_link.c24
-rw-r--r--lib/dns/opensslgost_link.c3
-rw-r--r--lib/dns/opensslrsa_link.c31
-rw-r--r--lib/dns/peer.c4
-rw-r--r--lib/dns/rbt.c4
-rw-r--r--lib/dns/rbtdb.c77
-rw-r--r--lib/dns/rdata.c263
-rw-r--r--lib/dns/rdata/any_255/tsig_250.c11
-rw-r--r--lib/dns/rdata/generic/dlv_32769.c4
-rw-r--r--lib/dns/rdata/generic/eui48_108.c215
-rw-r--r--lib/dns/rdata/generic/eui48_108.h26
-rw-r--r--lib/dns/rdata/generic/eui64_109.c220
-rw-r--r--lib/dns/rdata/generic/eui64_109.h26
-rw-r--r--lib/dns/rdata/generic/l32_105.c233
-rw-r--r--lib/dns/rdata/generic/l32_105.h27
-rw-r--r--lib/dns/rdata/generic/l64_106.c228
-rw-r--r--lib/dns/rdata/generic/l64_106.h27
-rw-r--r--lib/dns/rdata/generic/lp_107.c275
-rw-r--r--lib/dns/rdata/generic/lp_107.h28
-rw-r--r--lib/dns/rdata/generic/mx_15.c3
-rw-r--r--lib/dns/rdata/generic/nid_104.c228
-rw-r--r--lib/dns/rdata/generic/nid_104.h27
-rw-r--r--lib/dns/rdata/generic/sshfp_44.c3
-rw-r--r--lib/dns/rdata/generic/txt_16.c9
-rw-r--r--lib/dns/rdata/generic/uri_256.c331
-rw-r--r--lib/dns/rdata/generic/uri_256.h31
-rw-r--r--lib/dns/rdata/in_1/naptr_35.c39
-rw-r--r--lib/dns/rdata/in_1/nsap_22.c3
-rw-r--r--lib/dns/request.c8
-rw-r--r--lib/dns/resolver.c460
-rw-r--r--lib/dns/result.c7
-rw-r--r--lib/dns/rootns.c5
-rw-r--r--lib/dns/rpz.c40
-rw-r--r--lib/dns/sdb.c4
-rw-r--r--lib/dns/sdlz.c4
-rw-r--r--lib/dns/spnego.c34
-rw-r--r--lib/dns/spnego_asn1.c52
-rw-r--r--lib/dns/ssu.c7
-rw-r--r--lib/dns/ssu_external.c2
-rw-r--r--lib/dns/tkey.c11
-rw-r--r--lib/dns/tsig.c44
-rw-r--r--lib/dns/validator.c544
-rw-r--r--lib/dns/view.c48
-rw-r--r--lib/dns/xfrin.c10
-rw-r--r--lib/dns/zone.c468
-rw-r--r--lib/export/dns/Makefile.in8
-rw-r--r--lib/export/irs/Makefile.in5
-rw-r--r--lib/export/isc/Makefile.in15
-rw-r--r--lib/export/isc/include/isc/Makefile.in4
-rw-r--r--lib/export/isc/nls/Makefile.in2
-rw-r--r--lib/export/isc/nothreads/Makefile.in2
-rw-r--r--lib/export/isc/pthreads/Makefile.in2
-rw-r--r--lib/export/isc/unix/Makefile.in2
-rw-r--r--lib/export/isccfg/Makefile.in4
-rw-r--r--lib/export/samples/Makefile.in5
-rw-r--r--lib/export/samples/nsprobe.c28
-rw-r--r--lib/export/samples/sample-async.c4
-rw-r--r--lib/export/samples/sample-gai.c6
-rw-r--r--lib/export/samples/sample-request.c12
-rw-r--r--lib/export/samples/sample-update.c6
-rw-r--r--lib/export/samples/sample.c24
-rw-r--r--lib/irs/api5
-rw-r--r--lib/irs/dnsconf.c6
-rw-r--r--lib/irs/getaddrinfo.c28
-rw-r--r--lib/irs/getnameinfo.c5
-rw-r--r--lib/irs/resconf.c2
-rw-r--r--lib/isc/Makefile.in7
-rw-r--r--lib/isc/api9
-rw-r--r--lib/isc/buffer.c4
-rw-r--r--lib/isc/include/isc/Makefile.in4
-rw-r--r--lib/isc/include/isc/buffer.h18
-rw-r--r--lib/isc/include/isc/file.h20
-rw-r--r--lib/isc/include/isc/list.h4
-rw-r--r--lib/isc/include/isc/mem.h19
-rw-r--r--lib/isc/include/isc/namespace.h1
-rw-r--r--lib/isc/include/isc/regex.h39
-rw-r--r--lib/isc/include/isc/region.h11
-rw-r--r--lib/isc/include/isc/sockaddr.h3
-rw-r--r--lib/isc/include/isc/socket.h2
-rw-r--r--lib/isc/include/isc/task.h2
-rw-r--r--lib/isc/include/isc/timer.h17
-rw-r--r--lib/isc/inet_aton.c4
-rw-r--r--lib/isc/mem.c199
-rw-r--r--lib/isc/nothreads/Makefile.in6
-rw-r--r--lib/isc/parseint.c13
-rw-r--r--lib/isc/pthreads/thread.c4
-rw-r--r--lib/isc/ratelimiter.c17
-rw-r--r--lib/isc/regex.c370
-rw-r--r--lib/isc/sockaddr.c7
-rw-r--r--lib/isc/sparc64/include/isc/atomic.h21
-rw-r--r--lib/isc/symtab.c10
-rw-r--r--lib/isc/task.c98
-rw-r--r--lib/isc/taskpool.c10
-rw-r--r--lib/isc/timer.c10
-rw-r--r--lib/isc/timer_api.c6
-rw-r--r--lib/isc/unix/entropy.c5
-rw-r--r--lib/isc/unix/file.c21
-rw-r--r--lib/isc/unix/include/isc/time.h6
-rw-r--r--lib/isc/unix/net.c3
-rw-r--r--lib/isc/unix/socket.c206
-rw-r--r--lib/isc/unix/time.c8
-rw-r--r--lib/isccc/api5
-rw-r--r--lib/isccc/cc.c47
-rw-r--r--lib/isccfg/Makefile.in3
-rw-r--r--lib/isccfg/aclconf.c2
-rw-r--r--lib/isccfg/api5
-rw-r--r--lib/isccfg/include/isccfg/cfg.h6
-rw-r--r--lib/isccfg/namedconf.c17
-rw-r--r--lib/isccfg/parser.c19
-rw-r--r--lib/lwres/api5
-rw-r--r--lib/lwres/context.c3
-rw-r--r--lib/lwres/getaddrinfo.c16
-rw-r--r--lib/lwres/getipnode.c14
-rw-r--r--lib/lwres/getnameinfo.c4
-rw-r--r--lib/lwres/getrrset.c54
-rw-r--r--lib/lwres/lwinetaton.c6
-rw-r--r--lib/lwres/print.c4
160 files changed, 5376 insertions, 1747 deletions
diff --git a/lib/Makefile.in b/lib/Makefile.in
index e3f0bdb..8dc1d38 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2012, 2013 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
@@ -27,3 +27,8 @@ SUBDIRS = isc isccc dns isccfg bind9 lwres tests
TARGETS =
@BIND9_MAKE_RULES@
+
+distclean::
+ @echo "making $@ in `pwd`/irs"; \
+ (cd irs; ${MAKE} ${MAKEDEFS} DESTDIR="${DESTDIR}" $@) || exit 1;
+
diff --git a/lib/bind9/Makefile.in b/lib/bind9/Makefile.in
index 73285e1..b6633e5 100644
--- a/lib/bind9/Makefile.in
+++ b/lib/bind9/Makefile.in
@@ -69,7 +69,8 @@ libbind9.la: ${OBJS} ${ISCCFGDEPLIBS} ${ISCDEPLIBS} ${DNSDEPLIBS}
${LIBTOOL_MODE_LINK} \
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libbind9.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
- ${OBJS} ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} ${LIBS}
+ ${OBJS} ${DNSLIBS} ${ISCCFGLIBS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ \
+ ${LIBS}
timestamp: libbind9.@A@
touch timestamp
diff --git a/lib/bind9/api b/lib/bind9/api
index 7e9b115..99f8d31 100644
--- a/lib/bind9/api
+++ b/lib/bind9/api
@@ -1,8 +1,9 @@
# LIBINTERFACE ranges
# 9.6: 50-59, 110-119
# 9.7: 60-79
-# 9.8: 80-89
+# 9.8: 80-89, 120-129
# 9.9: 90-109
+# 9.9-sub: 130-139
LIBINTERFACE = 80
-LIBREVISION = 7
+LIBREVISION = 8
LIBAGE = 0
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index f765604..7c975c9 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -100,7 +100,7 @@ check_orderent(const cfg_obj_t *ent, isc_log_t *logctx) {
obj = cfg_tuple_get(ent, "name");
if (cfg_obj_isstring(obj)) {
str = cfg_obj_asstring(obj);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
dns_rootname, 0, NULL);
@@ -197,7 +197,7 @@ check_dual_stack(const cfg_obj_t *options, isc_log_t *logctx) {
continue;
obj = cfg_tuple_get(value, "name");
str = cfg_obj_asstring(obj);
- isc_buffer_init(&buffer, str, strlen(str));
+ isc_buffer_constinit(&buffer, str, strlen(str));
isc_buffer_add(&buffer, strlen(str));
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
@@ -263,7 +263,7 @@ disabled_algorithms(const cfg_obj_t *disabled, isc_log_t *logctx) {
name = dns_fixedname_name(&fixed);
obj = cfg_tuple_get(disabled, "name");
str = cfg_obj_asstring(obj);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (tresult != ISC_R_SUCCESS) {
@@ -346,7 +346,7 @@ mustbesecure(const cfg_obj_t *secure, isc_symtab_t *symtab, isc_log_t *logctx,
name = dns_fixedname_name(&fixed);
obj = cfg_tuple_get(secure, "name");
str = cfg_obj_asstring(obj);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
result = dns_name_fromtext(name, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
@@ -799,7 +799,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
element = cfg_list_next(element)) {
exclude = cfg_listelt_value(element);
str = cfg_obj_asstring(exclude);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(name, &b,
dns_rootname,
@@ -867,7 +867,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
continue;
}
- isc_buffer_init(&b, dlv, strlen(dlv));
+ isc_buffer_constinit(&b, dlv, strlen(dlv));
isc_buffer_add(&b, strlen(dlv));
tresult = dns_name_fromtext(name, &b, dns_rootname,
0, NULL);
@@ -901,7 +901,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
if (!cfg_obj_isvoid(anchor)) {
dlv = cfg_obj_asstring(anchor);
- isc_buffer_init(&b, dlv, strlen(dlv));
+ isc_buffer_constinit(&b, dlv, strlen(dlv));
isc_buffer_add(&b, strlen(dlv));
tresult = dns_name_fromtext(name, &b,
dns_rootname,
@@ -975,7 +975,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
(void)cfg_map_get(options, server_contact[i], &obj);
if (obj != NULL) {
str = cfg_obj_asstring(obj);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed),
&b, dns_rootname, 0, NULL);
@@ -999,7 +999,7 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
{
obj = cfg_listelt_value(element);
str = cfg_obj_asstring(obj);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
dns_rootname, 0, NULL);
@@ -1184,7 +1184,7 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
dns_fixedname_init(&fixed);
str = cfg_obj_asstring(identity);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed), &b,
dns_rootname, 0, NULL);
@@ -1198,7 +1198,7 @@ check_update_policy(const cfg_obj_t *policy, isc_log_t *logctx) {
strcasecmp(cfg_obj_asstring(matchtype), "zonesub") != 0) {
dns_fixedname_init(&fixed);
str = cfg_obj_asstring(dname);
- isc_buffer_init(&b, str, strlen(str));
+ isc_buffer_constinit(&b, str, strlen(str));
isc_buffer_add(&b, strlen(str));
tresult = dns_name_fromtext(dns_fixedname_name(&fixed),
&b, dns_rootname, 0, NULL);
@@ -1432,7 +1432,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
* deals with strings.
*/
dns_fixedname_init(&fixedname);
- isc_buffer_init(&b, znamestr, strlen(znamestr));
+ isc_buffer_constinit(&b, znamestr, strlen(znamestr));
isc_buffer_add(&b, strlen(znamestr));
tresult = dns_name_fromtext(dns_fixedname_name(&fixedname), &b,
dns_rootname, DNS_NAME_DOWNCASE, NULL);
@@ -1680,7 +1680,7 @@ check_zoneconf(const cfg_obj_t *zconfig, const cfg_obj_t *voptions,
snamestr = cfg_obj_asstring(obj);
dns_fixedname_init(&fixed_sname);
- isc_buffer_init(&b2, snamestr, strlen(snamestr));
+ isc_buffer_constinit(&b2, snamestr, strlen(snamestr));
isc_buffer_add(&b2, strlen(snamestr));
sname = dns_fixedname_name(&fixed_sname);
tresult = dns_name_fromtext(sname, &b2, dns_rootname,
@@ -1859,7 +1859,7 @@ check_keylist(const cfg_obj_t *keys, isc_symtab_t *symtab,
isc_buffer_t b;
char *keyname;
- isc_buffer_init(&b, keyid, strlen(keyid));
+ isc_buffer_constinit(&b, keyid, strlen(keyid));
isc_buffer_add(&b, strlen(keyid));
tresult = dns_name_fromtext(name, &b, dns_rootname,
0, NULL);
@@ -2028,7 +2028,7 @@ check_servers(const cfg_obj_t *config, const cfg_obj_t *voptions,
*/
keyval = cfg_obj_asstring(keys);
dns_fixedname_init(&fname);
- isc_buffer_init(&b, keyval, strlen(keyval));
+ isc_buffer_constinit(&b, keyval, strlen(keyval));
isc_buffer_add(&b, strlen(keyval));
keyname = dns_fixedname_name(&fname);
tresult = dns_name_fromtext(keyname, &b, dns_rootname,
@@ -2073,7 +2073,7 @@ check_trusted_key(const cfg_obj_t *key, isc_boolean_t managed,
keyname = dns_fixedname_name(&fkeyname);
keynamestr = cfg_obj_asstring(cfg_tuple_get(key, "name"));
- isc_buffer_init(&b, keynamestr, strlen(keynamestr));
+ isc_buffer_constinit(&b, keynamestr, strlen(keynamestr));
isc_buffer_add(&b, strlen(keynamestr));
result = dns_name_fromtext(keyname, &b, dns_rootname, 0, NULL);
if (result != ISC_R_SUCCESS) {
diff --git a/lib/dns/Makefile.in b/lib/dns/Makefile.in
index a01bb41..51d6066 100644
--- a/lib/dns/Makefile.in
+++ b/lib/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -46,8 +46,9 @@ LIBS = @LIBS@
# Alphabetically
+OPENSSLGOSTLINKOBJS = opensslgost_link.@O@
OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
- opensslecdsa_link.@O@ opensslgost_link.@O@ \
+ opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ \
opensslrsa_link.@O@
DSTOBJS = @DST_EXTRA_OBJS@ @OPENSSLLINKOBJS@ \
@@ -76,8 +77,9 @@ DNSOBJS = acache.@O@ acl.@O@ adb.@O@ byaddr.@O@ \
OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS}
# Alphabetically
+OPENSSLGOSTLINKSRCS = opensslgost_link.c
OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \
- opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c
+ opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c
DSTSRCS = @DST_EXTRA_SRCS@ @OPENSSLLINKSRCS@ \
dst_api.c dst_lib.c dst_parse.c \
diff --git a/lib/dns/acache.c b/lib/dns/acache.c
index 2ad4981..863df35 100644
--- a/lib/dns/acache.c
+++ b/lib/dns/acache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,6 +27,7 @@
#include <isc/random.h>
#include <isc/refcount.h>
#include <isc/rwlock.h>
+#include <isc/serial.h>
#include <isc/task.h>
#include <isc/time.h>
#include <isc/timer.h>
@@ -72,10 +73,10 @@
* (XXX simply derived from definitions in cache.c There may be better
* constants here.)
*/
-#define DNS_ACACHE_MINSIZE 2097152 /* Bytes. 2097152 = 2 MB */
-#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */
+#define DNS_ACACHE_MINSIZE 2097152U /* Bytes. 2097152 = 2 MB */
+#define DNS_ACACHE_CLEANERINCREMENT 1000 /* Number of entries. */
-#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */
+#define DEFAULT_ACACHE_ENTRY_LOCK_COUNT 1009 /*%< Should be prime. */
#if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEATOMICSTORE)
#define ACACHE_USE_RWLOCK 1
@@ -776,10 +777,14 @@ entry_stale(acache_cleaner_t *cleaner, dns_acacheentry_t *entry,
* use and the cleaning interval.
*/
if (cleaner->overmem) {
- unsigned int passed =
- now32 - entry->lastused; /* <= interval */
+ unsigned int passed;
isc_uint32_t val;
+ if (isc_serial_ge(now32, entry->lastused))
+ passed = now32 - entry->lastused; /* <= interval */
+ else
+ passed = 0;
+
if (passed > interval / 2)
return (ISC_TRUE);
isc_random_get(&val);
@@ -825,8 +830,10 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
entry = cleaner->current_entry;
isc_stdtime_convert32(cleaner->last_cleanup_time, &last32);
- INSIST(now32 > last32);
- interval = now32 - last32;
+ if (isc_serial_ge(now32, last32))
+ interval = now32 - last32;
+ else
+ interval = 0;
while (n_entries-- > 0) {
isc_boolean_t is_stale = ISC_FALSE;
@@ -861,7 +868,11 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
if (entry != NULL) {
/*
* If we are still in the overmem
- * state, keep cleaning.
+ * state, keep cleaning. In case we
+ * exit from the loop immediately after
+ * this, reset next to the head entry
+ * as we'll expect it will be never
+ * NULL.
*/
isc_log_write(dns_lctx,
DNS_LOGCATEGORY_DATABASE,
@@ -870,6 +881,7 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
"acache cleaner: "
"still overmem, "
"reset and try again");
+ next = entry;
continue;
}
}
@@ -888,7 +900,7 @@ acache_incremental_cleaning_action(isc_task_t *task, isc_event_t *event) {
* be the starting point in the next clean-up, and reschedule another
* batch. If it fails, just try to continue anyway.
*/
- INSIST(next != NULL && next != cleaner->current_entry);
+ INSIST(next != NULL);
dns_acache_detachentry(&cleaner->current_entry);
dns_acache_attachentry(next, &cleaner->current_entry);
@@ -1649,12 +1661,17 @@ dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
return (result);
}
-void
+isc_boolean_t
dns_acache_cancelentry(dns_acacheentry_t *entry) {
- dns_acache_t *acache = entry->acache;
+ dns_acache_t *acache;
+ isc_boolean_t callback_active;
REQUIRE(DNS_ACACHEENTRY_VALID(entry));
- INSIST(DNS_ACACHE_VALID(acache));
+
+ acache = entry->acache;
+ callback_active = ISC_TF(entry->cbarg != NULL);
+
+ INSIST(DNS_ACACHE_VALID(entry->acache));
LOCK(&acache->lock);
ACACHE_LOCK(&acache->entrylocks[entry->locknum], isc_rwlocktype_write);
@@ -1674,6 +1691,8 @@ dns_acache_cancelentry(dns_acacheentry_t *entry) {
ACACHE_UNLOCK(&acache->entrylocks[entry->locknum],
isc_rwlocktype_write);
UNLOCK(&acache->lock);
+
+ return (callback_active);
}
void
@@ -1768,13 +1787,13 @@ dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size) {
REQUIRE(DNS_ACACHE_VALID(acache));
- if (size != 0 && size < DNS_ACACHE_MINSIZE)
+ if (size != 0U && size < DNS_ACACHE_MINSIZE)
size = DNS_ACACHE_MINSIZE;
hiwater = size - (size >> 3);
lowater = size - (size >> 2);
- if (size == 0 || hiwater == 0 || lowater == 0)
+ if (size == 0U || hiwater == 0U || lowater == 0U)
isc_mem_setwater(acache->mctx, water, acache, 0, 0);
else
isc_mem_setwater(acache->mctx, water, acache,
diff --git a/lib/dns/adb.c b/lib/dns/adb.c
index 531d112..6aa5e5a 100644
--- a/lib/dns/adb.c
+++ b/lib/dns/adb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -89,7 +89,7 @@
#define DNS_ADB_INVALIDBUCKET (-1) /*%< invalid bucket address */
-#define DNS_ADB_MINADBSIZE (1024*1024) /*%< 1 Megabyte */
+#define DNS_ADB_MINADBSIZE (1024U*1024U) /*%< 1 Megabyte */
typedef ISC_LIST(dns_adbname_t) dns_adbnamelist_t;
typedef struct dns_adbnamehook dns_adbnamehook_t;
@@ -518,7 +518,9 @@ grow_entries(isc_task_t *task, isc_event_t *ev) {
isc_event_free(&ev);
- isc_task_beginexclusive(task);
+ result = isc_task_beginexclusive(task);
+ if (result != ISC_R_SUCCESS)
+ goto check_exit;
i = 0;
while (nbuckets[i] != 0 && adb->nentries >= nbuckets[i])
@@ -646,6 +648,7 @@ grow_entries(isc_task_t *task, isc_event_t *ev) {
done:
isc_task_endexclusive(task);
+ check_exit:
LOCK(&adb->lock);
if (dec_adb_irefcnt(adb))
check_exit(adb);
@@ -670,7 +673,9 @@ grow_names(isc_task_t *task, isc_event_t *ev) {
isc_event_free(&ev);
- isc_task_beginexclusive(task);
+ result = isc_task_beginexclusive(task);
+ if (result != ISC_R_SUCCESS)
+ goto check_exit;
i = 0;
while (nbuckets[i] != 0 && adb->nnames >= nbuckets[i])
@@ -794,6 +799,7 @@ grow_names(isc_task_t *task, isc_event_t *ev) {
done:
isc_task_endexclusive(task);
+ check_exit:
LOCK(&adb->lock);
if (dec_adb_irefcnt(adb))
check_exit(adb);
@@ -1280,6 +1286,7 @@ clean_namehooks(dns_adb_t *adb, dns_adbnamehooklist_t *namehooks) {
if (addr_bucket != DNS_ADB_INVALIDBUCKET)
UNLOCK(&adb->entrylocks[addr_bucket]);
addr_bucket = entry->lock_bucket;
+ INSIST(addr_bucket != DNS_ADB_INVALIDBUCKET);
LOCK(&adb->entrylocks[addr_bucket]);
}
@@ -2075,6 +2082,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname,
while (namehook != NULL) {
entry = namehook->entry;
bucket = entry->lock_bucket;
+ INSIST(bucket != DNS_ADB_INVALIDBUCKET);
LOCK(&adb->entrylocks[bucket]);
if (!FIND_RETURNLAME(find)
@@ -2105,6 +2113,7 @@ copy_namehook_lists(dns_adb_t *adb, dns_adbfind_t *find, dns_name_t *qname,
while (namehook != NULL) {
entry = namehook->entry;
bucket = entry->lock_bucket;
+ INSIST(bucket != DNS_ADB_INVALIDBUCKET);
LOCK(&adb->entrylocks[bucket]);
if (!FIND_RETURNLAME(find)
@@ -2331,7 +2340,8 @@ destroy(dns_adb_t *adb) {
adb->magic = 0;
isc_task_detach(&adb->task);
- isc_task_detach(&adb->excl);
+ if (adb->excl != NULL)
+ isc_task_detach(&adb->excl);
isc_mempool_destroy(&adb->nmp);
isc_mempool_destroy(&adb->nhmp);
@@ -4126,13 +4136,13 @@ dns_adb_setadbsize(dns_adb_t *adb, isc_uint32_t size) {
INSIST(DNS_ADB_VALID(adb));
- if (size != 0 && size < DNS_ADB_MINADBSIZE)
+ if (size != 0U && size < DNS_ADB_MINADBSIZE)
size = DNS_ADB_MINADBSIZE;
hiwater = size - (size >> 3); /* Approximately 7/8ths. */
lowater = size - (size >> 2); /* Approximately 3/4ths. */
- if (size == 0 || hiwater == 0 || lowater == 0)
+ if (size == 0U || hiwater == 0U || lowater == 0U)
isc_mem_setwater(adb->mctx, water, adb, 0, 0);
else
isc_mem_setwater(adb->mctx, water, adb, hiwater, lowater);
diff --git a/lib/dns/api b/lib/dns/api
index 325781a..5241a88 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -1,8 +1,9 @@
# LIBINTERFACE ranges
# 9.6: 50-59, 110-119
# 9.7: 60-79
-# 9.8: 80-89
+# 9.8: 80-89, 120-129
# 9.9: 90-109
-LIBINTERFACE = 89
+# 9.9-sub: 130-139
+LIBINTERFACE = 122
LIBREVISION = 1
-LIBAGE = 1
+LIBAGE = 0
diff --git a/lib/dns/cache.c b/lib/dns/cache.c
index 56bff8d..bced80e 100644
--- a/lib/dns/cache.c
+++ b/lib/dns/cache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -50,7 +50,7 @@
* DNS_CACHE_MINSIZE is how many bytes is the floor for dns_cache_setcachesize().
* See also DNS_CACHE_CLEANERINCREMENT
*/
-#define DNS_CACHE_MINSIZE 2097152 /*%< Bytes. 2097152 = 2 MB */
+#define DNS_CACHE_MINSIZE 2097152U /*%< Bytes. 2097152 = 2 MB */
/*!
* Control incremental cleaning.
* CLEANERINCREMENT is how many nodes are examined in one pass.
@@ -1038,7 +1038,7 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) {
* Impose a minimum cache size; pathological things happen if there
* is too little room.
*/
- if (size != 0 && size < DNS_CACHE_MINSIZE)
+ if (size != 0U && size < DNS_CACHE_MINSIZE)
size = DNS_CACHE_MINSIZE;
LOCK(&cache->lock);
@@ -1055,7 +1055,7 @@ dns_cache_setcachesize(dns_cache_t *cache, isc_uint32_t size) {
* water().
*/
- if (size == 0 || hiwater == 0 || lowater == 0)
+ if (size == 0U || hiwater == 0U || lowater == 0U)
/*
* Disable cache memory limiting.
*/
diff --git a/lib/dns/client.c b/lib/dns/client.c
index 7b6d1640..c4780f7 100644
--- a/lib/dns/client.c
+++ b/lib/dns/client.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009-2013 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
@@ -354,6 +354,12 @@ dns_client_create(dns_client_t **clientp, unsigned int options) {
isc_taskmgr_t *taskmgr = NULL;
isc_socketmgr_t *socketmgr = NULL;
isc_timermgr_t *timermgr = NULL;
+#if 0
+ /* XXXMPA add debug logging support */
+ isc_log_t *lctx = NULL;
+ isc_logconfig_t *logconfig = NULL;
+ unsigned int logdebuglevel = 0;
+#endif
result = isc_mem_create(0, 0, &mctx);
if (result != ISC_R_SUCCESS)
@@ -373,7 +379,18 @@ dns_client_create(dns_client_t **clientp, unsigned int options) {
result = isc_timermgr_createinctx(mctx, actx, &timermgr);
if (result != ISC_R_SUCCESS)
goto cleanup;
-
+#if 0
+ result = isc_log_create(mctx, &lctx, &logconfig);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ isc_log_setcontext(lctx);
+ dns_log_init(lctx);
+ dns_log_setcontext(lctx);
+ result = isc_log_usechannel(logconfig, "default_debug", NULL, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ isc_log_setdebuglevel(lctx, logdebuglevel);
+#endif
result = dns_client_createx(mctx, actx, taskmgr, socketmgr, timermgr,
options, clientp);
if (result != ISC_R_SUCCESS)
@@ -485,6 +502,7 @@ dns_client_createx(isc_mem_t *mctx, isc_appctx_t *actx, isc_taskmgr_t *taskmgr,
client->update_udpretries = DEF_UPDATE_UDPRETRIES;
client->find_timeout = DEF_FIND_TIMEOUT;
client->find_udpretries = DEF_FIND_UDPRETRIES;
+ client->attributes = 0;
client->references = 1;
client->magic = DNS_CLIENT_MAGIC;
@@ -2000,8 +2018,9 @@ resolveaddr_done(isc_task_t *task, isc_event_t *event) {
switch (family) {
case AF_INET:
dns_rdataset_current(rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &rdata_a,
- NULL);
+ result = dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_sockaddr_fromin(sa,
&rdata_a.in_addr,
53);
@@ -2009,8 +2028,9 @@ resolveaddr_done(isc_task_t *task, isc_event_t *event) {
break;
case AF_INET6:
dns_rdataset_current(rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &rdata_aaaa,
- NULL);
+ result = dns_rdata_tostruct(&rdata, &rdata_aaaa,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_sockaddr_fromin6(sa,
&rdata_aaaa.in6_addr,
53);
diff --git a/lib/dns/db.c b/lib/dns/db.c
index 0cf2c27..77f82f1 100644
--- a/lib/dns/db.c
+++ b/lib/dns/db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 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
@@ -945,11 +945,12 @@ dns_db_resigned(dns_db_t *db, dns_rdataset_t *rdataset,
(db->methods->resigned)(db, rdataset, version);
}
-void
+isc_result_t
dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
{
if (db->methods->rpz_enabled != NULL)
- (db->methods->rpz_enabled)(db, st);
+ return ((db->methods->rpz_enabled)(db, st));
+ return (ISC_R_SUCCESS);
}
void
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index 775d4f4..9848ac2 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -2756,7 +2756,7 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
* If no port is specified, we first try to pick up a random
* port by ourselves.
*/
- if (isc_sockaddr_pf(&disp->local) == AF_INET) {
+ if (isc_sockaddr_pf(localaddr) == AF_INET) {
nports = disp->mgr->nv4ports;
ports = disp->mgr->v4ports;
} else {
@@ -2775,12 +2775,16 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
isc_sockaddr_setport(&localaddr_bound, prt);
result = open_socket(sockmgr, &localaddr_bound,
0, &sock);
- if (result == ISC_R_SUCCESS ||
- result != ISC_R_ADDRINUSE) {
- disp->localport = prt;
- *sockp = sock;
- return (result);
- }
+ /*
+ * Continue if the port choosen is already in use
+ * or the OS has reserved it.
+ */
+ if (result == ISC_R_NOPERM ||
+ result == ISC_R_ADDRINUSE)
+ continue;
+ disp->localport = prt;
+ *sockp = sock;
+ return (result);
}
/*
@@ -2805,8 +2809,6 @@ get_udpsocket(dns_dispatchmgr_t *mgr, dns_dispatch_t *disp,
result = open_socket(sockmgr, localaddr, 0, &sock);
if (result != ISC_R_SUCCESS)
goto end;
- else if (!anyport)
- break;
else if (portavailable(mgr, sock, NULL))
break;
if (held[i] != NULL)
diff --git a/lib/dns/dlz.c b/lib/dns/dlz.c
index 8d1625a..19c600c 100644
--- a/lib/dns/dlz.c
+++ b/lib/dns/dlz.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2005, 2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2005, 2007, 2009-2013 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -142,6 +142,7 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
{
dns_dlzimplementation_t *impinfo;
isc_result_t result;
+ dns_dlzdb_t *db = NULL;
/*
* initialize the dlz_implementations list, this is guaranteed
@@ -180,30 +181,31 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
}
/* Allocate memory to hold the DLZ database driver */
- (*dbp) = isc_mem_get(mctx, sizeof(dns_dlzdb_t));
- if ((*dbp) == NULL) {
+ db = isc_mem_get(mctx, sizeof(dns_dlzdb_t));
+ if (db == NULL) {
RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
return (ISC_R_NOMEMORY);
}
/* Make sure memory region is set to all 0's */
- memset((*dbp), 0, sizeof(dns_dlzdb_t));
+ memset(db, 0, sizeof(dns_dlzdb_t));
- (*dbp)->implementation = impinfo;
+ db->implementation = impinfo;
/* Create a new database using implementation 'drivername'. */
result = ((impinfo->methods->create)(mctx, dlzname, argc, argv,
impinfo->driverarg,
- &(*dbp)->dbdata));
+ &db->dbdata));
/* mark the DLZ driver as valid */
if (result == ISC_R_SUCCESS) {
RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
- (*dbp)->magic = DNS_DLZ_MAGIC;
- isc_mem_attach(mctx, &(*dbp)->mctx);
+ db->magic = DNS_DLZ_MAGIC;
+ isc_mem_attach(mctx, &db->mctx);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_DLZ, ISC_LOG_DEBUG(2),
"DLZ driver loaded successfully.");
+ *dbp = db;
return (ISC_R_SUCCESS);
} else {
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE,
@@ -213,7 +215,7 @@ dns_dlzcreate(isc_mem_t *mctx, const char *dlzname, const char *drivername,
/* impinfo->methods->create failed. */
RWUNLOCK(&dlz_implock, isc_rwlocktype_read);
- isc_mem_put(mctx, (*dbp), sizeof(dns_dlzdb_t));
+ isc_mem_put(mctx, db, sizeof(dns_dlzdb_t));
return (result);
}
@@ -543,7 +545,7 @@ dns_dlz_writeablezone(dns_view_t *view, const char *zone_name) {
REQUIRE(dlzdatabase->configure_callback != NULL);
- isc_buffer_init(&buffer, zone_name, strlen(zone_name));
+ isc_buffer_constinit(&buffer, zone_name, strlen(zone_name));
isc_buffer_add(&buffer, strlen(zone_name));
dns_fixedname_init(&fixorigin);
result = dns_name_fromtext(dns_fixedname_name(&fixorigin),
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index 3569ad7..587bd1c 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -275,7 +275,7 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
if (ret != ISC_R_SUCCESS)
goto cleanup_databuf;
- ret = dst_context_create(key, mctx, &ctx);
+ ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx);
if (ret != ISC_R_SUCCESS)
goto cleanup_databuf;
@@ -352,7 +352,6 @@ dns_dnssec_sign(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
ret = ISC_R_NOSPACE;
goto cleanup_array;
}
- memcpy(sig.signature, r.base, sig.siglen);
ret = dns_rdata_fromstruct(sigrdata, sig.common.rdclass,
sig.common.rdtype, &sig, buffer);
@@ -462,7 +461,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
}
again:
- ret = dst_context_create(key, mctx, &ctx);
+ ret = dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx);
if (ret != ISC_R_SUCCESS)
goto cleanup_struct;
@@ -551,9 +550,9 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
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 "
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_DNSSEC,
+ DNS_LOGMODULE_DNSSEC, ISC_LOG_DEBUG(1),
+ "successfully validated after lower casing "
"signer '%s'", namebuf);
inc_stat(dns_dnssecstats_downcase);
} else if (ret == ISC_R_SUCCESS)
@@ -854,7 +853,7 @@ dns_dnssec_signmessage(dns_message_t *msg, dst_key_t *key) {
isc_buffer_init(&databuf, data, sizeof(data));
- RETERR(dst_context_create(key, mctx, &ctx));
+ RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx));
/*
* Digest the fields of the SIG - we can cheat and use
@@ -1004,7 +1003,7 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
goto failure;
}
- RETERR(dst_context_create(key, mctx, &ctx));
+ RETERR(dst_context_create2(key, mctx, DNS_LOGCATEGORY_DNSSEC, &ctx));
/*
* Digest the SIG(0) record, except for the signature.
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
index f5dd89a..53978bc 100644
--- a/lib/dns/dst_api.c
+++ b/lib/dns/dst_api.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004-2013 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
@@ -276,6 +276,13 @@ dst_algorithm_supported(unsigned int alg) {
isc_result_t
dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
+ return (dst_context_create2(key, mctx,
+ DNS_LOGCATEGORY_GENERAL, dctxp));
+}
+
+isc_result_t
+dst_context_create2(dst_key_t *key, isc_mem_t *mctx,
+ isc_logcategory_t *category, dst_context_t **dctxp) {
dst_context_t *dctx;
isc_result_t result;
@@ -294,6 +301,7 @@ dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp) {
return (ISC_R_NOMEMORY);
dctx->key = key;
dctx->mctx = mctx;
+ dctx->category = category;
result = key->func->createctx(key, dctx);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, dctx, sizeof(dst_context_t));
@@ -495,8 +503,7 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
result = dst_key_read_public(newfilename, type, mctx, &pubkey);
isc_mem_put(mctx, newfilename, newfilenamelen);
newfilename = NULL;
- if (result != ISC_R_SUCCESS)
- return (result);
+ RETERR(result);
if ((type & (DST_TYPE_PRIVATE | DST_TYPE_PUBLIC)) == DST_TYPE_PUBLIC ||
(pubkey->key_flags & DNS_KEYFLAG_TYPEMASK) == DNS_KEYTYPE_NOKEY) {
@@ -560,7 +567,8 @@ dst_key_fromnamedfile(const char *filename, const char *dirname,
isc_mem_put(mctx, newfilename, newfilenamelen);
if (lex != NULL)
isc_lex_destroy(&lex);
- dst_key_free(&key);
+ if (key != NULL)
+ dst_key_free(&key);
return (result);
}
@@ -1190,7 +1198,7 @@ dst_key_dump(dst_key_t *key, isc_mem_t *mctx, char **buffer, int *length) {
REQUIRE(length != NULL && *length == 0);
REQUIRE(VALID_KEY(key));
- if (key->func->isprivate == NULL)
+ if (key->func->dump == NULL)
return (ISC_R_NOTIMPLEMENTED);
return (key->func->dump(key, mctx, buffer, length));
}
@@ -1247,24 +1255,24 @@ get_key_struct(dns_name_t *name, unsigned int alg,
return (NULL);
memset(key, 0, sizeof(dst_key_t));
- key->magic = KEY_MAGIC;
-
- result = isc_refcount_init(&key->refs, 1);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, key, sizeof(dst_key_t));
- return (NULL);
- }
key->key_name = isc_mem_get(mctx, sizeof(dns_name_t));
if (key->key_name == NULL) {
- isc_refcount_destroy(&key->refs);
isc_mem_put(mctx, key, sizeof(dst_key_t));
return (NULL);
}
+
dns_name_init(key->key_name, NULL);
result = dns_name_dup(name, mctx, key->key_name);
if (result != ISC_R_SUCCESS) {
- isc_refcount_destroy(&key->refs);
+ isc_mem_put(mctx, key->key_name, sizeof(dns_name_t));
+ isc_mem_put(mctx, key, sizeof(dst_key_t));
+ return (NULL);
+ }
+
+ result = isc_refcount_init(&key->refs, 1);
+ if (result != ISC_R_SUCCESS) {
+ dns_name_free(key->key_name, mctx);
isc_mem_put(mctx, key->key_name, sizeof(dns_name_t));
isc_mem_put(mctx, key, sizeof(dst_key_t));
return (NULL);
@@ -1283,6 +1291,7 @@ get_key_struct(dns_name_t *name, unsigned int alg,
key->times[i] = 0;
key->timeset[i] = ISC_FALSE;
}
+ key->magic = KEY_MAGIC;
return (key);
}
diff --git a/lib/dns/dst_internal.h b/lib/dns/dst_internal.h
index 2f4f946..ee824f4 100644
--- a/lib/dns/dst_internal.h
+++ b/lib/dns/dst_internal.h
@@ -137,6 +137,7 @@ struct dst_context {
unsigned int magic;
dst_key_t *key;
isc_mem_t *mctx;
+ isc_logcategory_t *category;
union {
void *generic;
dst_gssapi_signverifyctx_t *gssctx;
diff --git a/lib/dns/dst_openssl.h b/lib/dns/dst_openssl.h
index a30fd6a..e4d636e 100644
--- a/lib/dns/dst_openssl.h
+++ b/lib/dns/dst_openssl.h
@@ -21,6 +21,7 @@
#define DST_OPENSSL_H 1
#include <isc/lang.h>
+#include <isc/log.h>
#include <isc/result.h>
#include <openssl/err.h>
@@ -42,6 +43,10 @@ dst__openssl_toresult(isc_result_t fallback);
isc_result_t
dst__openssl_toresult2(const char *funcname, isc_result_t fallback);
+isc_result_t
+dst__openssl_toresult3(isc_logcategory_t *category,
+ const char *funcname, isc_result_t fallback);
+
#ifdef USE_ENGINE
ENGINE *
dst__openssl_getengine(const char *engine);
diff --git a/lib/dns/ecdb.c b/lib/dns/ecdb.c
index f1a833f..20da5b0 100644
--- a/lib/dns/ecdb.c
+++ b/lib/dns/ecdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009-2013 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
@@ -80,8 +80,11 @@ typedef struct rdatasetheader {
/* Copied from rbtdb.c */
#define RDATASET_ATTR_NXDOMAIN 0x0010
+#define RDATASET_ATTR_NEGATIVE 0x0100
#define NXDOMAIN(header) \
(((header)->attributes & RDATASET_ATTR_NXDOMAIN) != 0)
+#define NEGATIVE(header) \
+ (((header)->attributes & RDATASET_ATTR_NEGATIVE) != 0)
static isc_result_t dns_ecdb_create(isc_mem_t *mctx, dns_name_t *origin,
dns_dbtype_t type,
@@ -406,6 +409,8 @@ bind_rdataset(dns_ecdb_t *ecdb, dns_ecdbnode_t *node,
rdataset->trust = header->trust;
if (NXDOMAIN(header))
rdataset->attributes |= DNS_RDATASETATTR_NXDOMAIN;
+ if (NEGATIVE(header))
+ rdataset->attributes |= DNS_RDATASETATTR_NEGATIVE;
rdataset->private1 = ecdb;
rdataset->private2 = node;
@@ -469,6 +474,8 @@ addrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
header->attributes = 0;
if ((rdataset->attributes & DNS_RDATASETATTR_NXDOMAIN) != 0)
header->attributes |= RDATASET_ATTR_NXDOMAIN;
+ if ((rdataset->attributes & DNS_RDATASETATTR_NEGATIVE) != 0)
+ header->attributes |= RDATASET_ATTR_NEGATIVE;
ISC_LINK_INIT(header, link);
ISC_LIST_APPEND(ecdbnode->rdatasets, header, link);
diff --git a/lib/dns/gen.c b/lib/dns/gen.c
index a0b4df3..6b533dd 100644
--- a/lib/dns/gen.c
+++ b/lib/dns/gen.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: gen.c,v 1.85 2009/12/04 22:06:37 tbox Exp $ */
-
/*! \file */
#ifdef WIN32
@@ -24,6 +22,10 @@
* Silence compiler warnings about using strcpy and friends.
*/
#define _CRT_SECURE_NO_DEPRECATE 1
+/*
+ * We use snprintf.
+ */
+#define snprintf _snprintf
#endif
#include <sys/types.h>
@@ -41,7 +43,12 @@
#include "gen-unix.h"
#endif
-#define TYPECLASSLEN 21
+#define INSIST(cond) \
+ if (!(cond)) { \
+ fprintf(stderr, "%s:%d: INSIST(%s)\n", \
+ __FILE__, __LINE__, #cond); \
+ abort(); \
+ }
#define FROMTEXTARGS "rdclass, type, lexer, origin, options, target, callbacks"
#define FROMTEXTCLASS "rdclass"
@@ -103,7 +110,7 @@
#define CHECKNAMESTYPE "rdata->type"
#define CHECKNAMESDEF "result = ISC_TRUE"
-const char copyright[] =
+static const char copyright[] =
"/*\n"
" * Copyright (C) 2004%s Internet Systems Consortium, Inc. (\"ISC\")\n"
" * Copyright (C) 1998-2003 Internet Software Consortium.\n"
@@ -131,53 +138,59 @@ const char copyright[] =
"/*! \\file */\n"
"\n";
+#define STR_EXPAND(tok) #tok
+#define STR(tok) STR_EXPAND(tok)
+
#define TYPENAMES 256
+#define TYPECLASSLEN 20 /* DNS mnemonic size. Must be less than 100. */
+#define TYPECLASSBUF (TYPECLASSLEN + 1)
+#define TYPECLASSFMT "%" STR(TYPECLASSLEN) "[-0-9a-z]_%d"
+#define ATTRIBUTESIZE 256
+#define DIRNAMESIZE 256
-struct cc {
+static struct cc {
struct cc *next;
int rdclass;
- char classname[TYPECLASSLEN];
+ char classname[TYPECLASSBUF];
} *classes;
-struct tt {
+static struct tt {
struct tt *next;
int rdclass;
int type;
- char classname[TYPECLASSLEN];
- char typename[TYPECLASSLEN];
- char dirname[256]; /* XXX Should be max path length */
+ char classname[TYPECLASSBUF];
+ char typename[TYPECLASSBUF];
+ char dirname[DIRNAMESIZE]; /* XXX Should be max path length */
} *types;
-struct ttnam {
- char typename[TYPECLASSLEN];
- char macroname[TYPECLASSLEN];
- char attr[256];
+static struct ttnam {
+ char typename[TYPECLASSBUF];
+ char macroname[TYPECLASSBUF];
+ char attr[ATTRIBUTESIZE];
unsigned int sorted;
int type;
} typenames[TYPENAMES];
-int maxtype = -1;
+static int maxtype = -1;
-char *
+static char *
upper(char *);
-char *
+static char *
funname(const char *, char *);
-void
+static void
doswitch(const char *, const char *, const char *, const char *,
const char *, const char *);
-void
-dodecl(char *, char *, char *);
-void
+static void
add(int, const char *, int, const char *, const char *);
-void
+static void
sd(int, const char *, const char *, char);
-void
+static void
insert_into_typenames(int, const char *, const char *);
/*%
* If you use more than 10 of these in, say, a printf(), you'll have problems.
*/
-char *
+static char *
upper(char *s) {
static int buf_to_use = 0;
static char buf[10][256];
@@ -197,11 +210,12 @@ upper(char *s) {
return (buf[buf_to_use]);
}
-char *
+static char *
funname(const char *s, char *buf) {
char *b = buf;
char c;
+ INSIST(strlen(s) < TYPECLASSBUF);
while ((c = *s++)) {
*b++ = (c == '-') ? '_' : c;
}
@@ -209,7 +223,7 @@ funname(const char *s, char *buf) {
return (buf);
}
-void
+static void
doswitch(const char *name, const char *function, const char *args,
const char *tsw, const char *csw, const char *res)
{
@@ -217,7 +231,7 @@ doswitch(const char *name, const char *function, const char *args,
int first = 1;
int lasttype = 0;
int subswitch = 0;
- char buf1[TYPECLASSLEN], buf2[TYPECLASSLEN];
+ char buf1[TYPECLASSBUF], buf2[TYPECLASSBUF];
const char *result = " result =";
if (res == NULL)
@@ -280,26 +294,6 @@ doswitch(const char *name, const char *function, const char *args,
}
}
-void
-dodecl(char *type, char *function, char *args) {
- struct tt *tt;
- char buf1[TYPECLASSLEN], buf2[TYPECLASSLEN];
-
- fputs("\n", stdout);
- for (tt = types; tt; tt = tt->next)
- if (tt->rdclass)
- fprintf(stdout,
- "static inline %s %s_%s_%s(%s);\n",
- type, function,
- funname(tt->classname, buf1),
- funname(tt->typename, buf2), args);
- else
- fprintf(stdout,
- "static inline %s %s_%s(%s);\n",
- type, function,
- funname(tt->typename, buf1), args);
-}
-
static struct ttnam *
find_typename(int type) {
int i;
@@ -312,12 +306,13 @@ find_typename(int type) {
return (NULL);
}
-void
+static void
insert_into_typenames(int type, const char *typename, const char *attr) {
struct ttnam *ttn = NULL;
- int c, i;
+ int c, i, n;
char tmp[256];
+ INSIST(strlen(typename) < TYPECLASSBUF);
for (i = 0; i < TYPENAMES; i++) {
if (typenames[i].typename[0] != 0 &&
typenames[i].type == type &&
@@ -340,10 +335,10 @@ insert_into_typenames(int type, const char *typename, const char *attr) {
typename);
exit(1);
}
- strcpy(ttn->typename, typename);
+ strncpy(ttn->typename, typename, sizeof(ttn->typename));
ttn->type = type;
- strcpy(ttn->macroname, ttn->typename);
+ strncpy(ttn->macroname, ttn->typename, sizeof(ttn->macroname));
c = strlen(ttn->macroname);
while (c > 0) {
if (ttn->macroname[c - 1] == '-')
@@ -352,7 +347,9 @@ insert_into_typenames(int type, const char *typename, const char *attr) {
}
if (attr == NULL) {
- sprintf(tmp, "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname));
+ n = snprintf(tmp, sizeof(tmp),
+ "RRTYPE_%s_ATTRIBUTES", upper(ttn->macroname));
+ INSIST(n > 0 && (unsigned)n < sizeof(tmp));
attr = tmp;
}
@@ -367,13 +364,13 @@ insert_into_typenames(int type, const char *typename, const char *attr) {
attr, typename);
exit(1);
}
- strcpy(ttn->attr, attr);
+ strncpy(ttn->attr, attr, sizeof(ttn->attr));
ttn->sorted = 0;
if (maxtype < type)
maxtype = type;
}
-void
+static void
add(int rdclass, const char *classname, int type, const char *typename,
const char *dirname)
{
@@ -382,6 +379,10 @@ add(int rdclass, const char *classname, int type, const char *typename,
struct cc *newcc;
struct cc *cc, *oldcc;
+ INSIST(strlen(typename) < TYPECLASSBUF);
+ INSIST(strlen(classname) < TYPECLASSBUF);
+ INSIST(strlen(dirname) < DIRNAMESIZE);
+
insert_into_typenames(type, typename, NULL);
if (newtt == NULL) {
@@ -392,11 +393,11 @@ add(int rdclass, const char *classname, int type, const char *typename,
newtt->next = NULL;
newtt->rdclass = rdclass;
newtt->type = type;
- strcpy(newtt->classname, classname);
- strcpy(newtt->typename, typename);
+ strncpy(newtt->classname, classname, sizeof(newtt->classname));
+ strncpy(newtt->typename, typename, sizeof(newtt->typename));
if (strncmp(dirname, "./", 2) == 0)
dirname += 2;
- strcpy(newtt->dirname, dirname);
+ strncpy(newtt->dirname, dirname, sizeof(newtt->dirname));
tt = types;
oldtt = NULL;
@@ -429,8 +430,12 @@ add(int rdclass, const char *classname, int type, const char *typename,
return;
newcc = (struct cc *)malloc(sizeof(*newcc));
+ if (newcc == NULL) {
+ fprintf(stderr, "malloc() failed\n");
+ exit(1);
+ }
newcc->rdclass = rdclass;
- strcpy(newcc->classname, classname);
+ strncpy(newcc->classname, classname, sizeof(newcc->classname));
cc = classes;
oldcc = NULL;
@@ -451,25 +456,25 @@ add(int rdclass, const char *classname, int type, const char *typename,
classes = newcc;
}
-void
+static void
sd(int rdclass, const char *classname, const char *dirname, char filetype) {
- char buf[sizeof("01234567890123456789_65535.h")];
- char fmt[sizeof("%20[-0-9a-z]_%d.h")];
- int type;
- char typename[TYPECLASSLEN];
+ char buf[TYPECLASSLEN + sizeof("_65535.h")];
+ char typename[TYPECLASSBUF];
+ int type, n;
isc_dir_t dir;
if (!start_directory(dirname, &dir))
return;
- sprintf(fmt,"%s%c", "%20[-0-9a-z]_%d.", filetype);
while (next_file(&dir)) {
- if (sscanf(dir.filename, fmt, typename, &type) != 2)
+ if (sscanf(dir.filename, TYPECLASSFMT, typename, &type) != 2)
continue;
if ((type > 65535) || (type < 0))
continue;
- sprintf(buf, "%s_%d.%c", typename, type, filetype);
+ n = snprintf(buf, sizeof(buf), "%s_%d.%c", typename,
+ type, filetype);
+ INSIST(n > 0 && (unsigned)n < sizeof(buf));
if (strcmp(buf, dir.filename) != 0)
continue;
add(rdclass, classname, type, typename, dirname);
@@ -496,10 +501,10 @@ HASH(char *string) {
int
main(int argc, char **argv) {
- char buf[256]; /* XXX Should be max path length */
- char srcdir[256]; /* XXX Should be max path length */
+ char buf[DIRNAMESIZE]; /* XXX Should be max path length */
+ char srcdir[DIRNAMESIZE]; /* XXX Should be max path length */
int rdclass;
- char classname[TYPECLASSLEN];
+ char classname[TYPECLASSBUF];
struct tt *tt;
struct cc *cc;
struct ttnam *ttn, *ttn2;
@@ -513,8 +518,8 @@ main(int argc, char **argv) {
int type_enum = 0;
int structs = 0;
int depend = 0;
- int c, i, j;
- char buf1[TYPECLASSLEN];
+ int c, i, j, n;
+ char buf1[TYPECLASSBUF];
char filetype = 'c';
FILE *fd;
char *prefix = NULL;
@@ -561,7 +566,16 @@ main(int argc, char **argv) {
filetype = 'h';
break;
case 's':
- sprintf(srcdir, "%s/", isc_commandline_argument);
+ if (strlen(isc_commandline_argument) >
+ DIRNAMESIZE - 2 * TYPECLASSLEN -
+ sizeof("/rdata/_65535_65535")) {
+ fprintf(stderr, "\"%s\" too long\n",
+ isc_commandline_argument);
+ exit(1);
+ }
+ n = snprintf(srcdir, sizeof(srcdir), "%s/",
+ isc_commandline_argument);
+ INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
break;
case 'F':
file = isc_commandline_argument;
@@ -576,31 +590,37 @@ main(int argc, char **argv) {
exit(1);
}
- sprintf(buf, "%srdata", srcdir);
+ n = snprintf(buf, sizeof(buf), "%srdata", srcdir);
+ INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
if (!start_directory(buf, &dir))
exit(1);
while (next_file(&dir)) {
- if (sscanf(dir.filename, "%10[0-9a-z]_%d",
- classname, &rdclass) != 2)
+ if (sscanf(dir.filename, TYPECLASSFMT, classname,
+ &rdclass) != 2)
continue;
if ((rdclass > 65535) || (rdclass < 0))
continue;
- sprintf(buf, "%srdata/%s_%d", srcdir, classname, rdclass);
+ n = snprintf(buf, sizeof(buf), "%srdata/%s_%d",
+ srcdir, classname, rdclass);
+ INSIST(n > 0 && (unsigned)n < sizeof(buf));
if (strcmp(buf + 6 + strlen(srcdir), dir.filename) != 0)
continue;
sd(rdclass, classname, buf, filetype);
}
end_directory(&dir);
- sprintf(buf, "%srdata/generic", srcdir);
+ n = snprintf(buf, sizeof(buf), "%srdata/generic", srcdir);
+ INSIST(n > 0 && (unsigned)n < sizeof(srcdir));
sd(0, "", buf, filetype);
if (time(&now) != -1) {
- if ((tm = localtime(&now)) != NULL && tm->tm_year > 104)
- sprintf(year, "-%d", tm->tm_year + 1900);
- else
+ if ((tm = localtime(&now)) != NULL && tm->tm_year > 104) {
+ n = snprintf(year, sizeof(year), "-%d",
+ tm->tm_year + 1900);
+ INSIST(n > 0 && (unsigned)n < sizeof(year));
+ } else
year[0] = 0;
} else
year[0] = 0;
@@ -862,7 +882,7 @@ main(int argc, char **argv) {
}
}
for (tt = types; tt != NULL; tt = tt->next) {
- sprintf(buf, "%s/%s_%d.h",
+ snprintf(buf, sizeof(buf), "%s/%s_%d.h",
tt->dirname, tt->typename, tt->type);
if ((fd = fopen(buf,"r")) != NULL) {
while (fgets(buf, sizeof(buf), fd) != NULL)
diff --git a/lib/dns/gssapictx.c b/lib/dns/gssapictx.c
index ee5be56..e4047d2 100644
--- a/lib/dns/gssapictx.c
+++ b/lib/dns/gssapictx.c
@@ -541,7 +541,7 @@ gss_err_message(isc_mem_t *mctx, isc_uint32_t major, isc_uint32_t minor,
}
estr = gss_error_tostring(major, minor, buf, sizeof(buf));
- if (estr)
+ if (estr != NULL)
(*err_message) = isc_mem_strdup(mctx, estr);
}
#endif
@@ -597,8 +597,12 @@ dst_gssapi_initctx(dns_name_t *name, isc_buffer_t *intoken,
if (gret != GSS_S_COMPLETE && gret != GSS_S_CONTINUE_NEEDED) {
gss_err_message(mctx, gret, minor, err_message);
- gss_log(3, "Failure initiating security context: %s",
- *err_message);
+ if (err_message != NULL && *err_message != NULL)
+ gss_log(3, "Failure initiating security context: %s",
+ *err_message);
+ else
+ gss_log(3, "Failure initiating security context");
+
result = ISC_R_FAILURE;
goto out;
}
diff --git a/lib/dns/include/dns/acache.h b/lib/dns/include/dns/acache.h
index 28990c2..c372ed9 100644
--- a/lib/dns/include/dns/acache.h
+++ b/lib/dns/include/dns/acache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2006, 2007, 2013 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
@@ -25,7 +25,7 @@
/*
* Acache
- *
+ *
* The Additional Cache Object
*
* This module manages internal caching entries that correspond to
@@ -131,7 +131,7 @@
* - 76 bytes for each additional cache entry
* - if the entry has a DNS name and associated RRset,
* * 44 bytes + size of the name (1-255 bytes)
- * * 52 bytes x number_of_RRs
+ * * 52 bytes x number_of_RRs
* - 28 bytes for each DB related to this module
*
* Using the additional cache also requires extra memory consumption in
@@ -387,7 +387,7 @@ dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
* ISC_R_NOTFOUND
*/
-void
+isc_boolean_t
dns_acache_cancelentry(dns_acacheentry_t *entry);
/*
* Cancel the use of the cache entry 'entry'. This function is supposed to
@@ -398,6 +398,9 @@ dns_acache_cancelentry(dns_acacheentry_t *entry);
*
* Requires:
* 'entry' is a valid additional cache entry.
+ *
+ * Returns:
+ * ISC_TRUE if the entry was active when canceled
*/
void
@@ -415,7 +418,7 @@ dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp);
*
* *targetp is attached to 'source'.
*/
-
+
void
dns_acache_detachentry(dns_acacheentry_t **entryp);
/*
@@ -429,7 +432,7 @@ dns_acache_detachentry(dns_acacheentry_t **entryp);
*
* *entryp is NULL.
*
- * If '*entryp' is the last reference to the entry,
+ * If '*entryp' is the last reference to the entry,
* cache does not have an outstanding task, all resources used by the
* entry (including the entry object itself) will be freed.
*/
diff --git a/lib/dns/include/dns/db.h b/lib/dns/include/dns/db.h
index fe268f4..ef090a2 100644
--- a/lib/dns/include/dns/db.h
+++ b/lib/dns/include/dns/db.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -171,7 +171,7 @@ typedef struct dns_dbmethods {
dns_dbversion_t *version);
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_enabled)(dns_db_t *db, dns_rpz_st_t *st);
void (*rpz_findips)(dns_rpz_zone_t *rpz,
dns_rpz_type_t rpz_type,
dns_zone_t *zone, dns_db_t *db,
@@ -1500,11 +1500,11 @@ dns_db_getrrsetstats(dns_db_t *db);
* dns_rdatasetstats_create(); otherwise NULL.
*/
-void
+isc_result_t
dns_db_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st);
/*%<
- * See if a policy database has DNS_RPZ_TYPE_IP, DNS_RPZ_TYPE_NSIP, or
- * DNS_RPZ_TYPE_NSDNAME records.
+ * Mark a database for response policy rewriting
+ * or find which RPZ data is available.
*/
void
diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index 3bc734d..a6862fa 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -251,6 +251,12 @@ struct dns_message {
const void * order_arg;
};
+struct dns_ednsopt {
+ isc_uint16_t code;
+ isc_uint16_t length;
+ unsigned char *value;
+};
+
/***
*** Functions
***/
@@ -1350,6 +1356,24 @@ dns_message_gettimeadjust(dns_message_t *msg);
*\li msg be a valid message.
*/
+isc_result_t
+dns_message_buildopt(dns_message_t *msg, dns_rdataset_t **opt,
+ unsigned int version, isc_uint16_t udpsize,
+ unsigned int flags, dns_ednsopt_t *ednsopts, size_t count);
+/*%<
+ * Built a opt record.
+ *
+ * Requires:
+ * \li msg be a valid message.
+ * \li opt to be a non NULL and *opt to be NULL.
+ *
+ * Returns:
+ * \li ISC_R_SUCCESS on success.
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_NOSPACE
+ * \li other.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_MESSAGE_H */
diff --git a/lib/dns/include/dns/name.h b/lib/dns/include/dns/name.h
index bef8693..1a88e53 100644
--- a/lib/dns/include/dns/name.h
+++ b/lib/dns/include/dns/name.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2009-2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2009-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
@@ -1299,15 +1299,17 @@ ISC_LANG_ENDDECLS
#define DNS_NAME_INIT(n, o) \
do { \
- (n)->magic = DNS_NAME_MAGIC; \
- (n)->ndata = NULL; \
- (n)->length = 0; \
- (n)->labels = 0; \
- (n)->attributes = 0; \
- (n)->offsets = (o); \
- (n)->buffer = NULL; \
- ISC_LINK_INIT((n), link); \
- ISC_LIST_INIT((n)->list); \
+ dns_name_t *_n = (n); \
+ /* memset(_n, 0, sizeof(*_n)); */ \
+ _n->magic = DNS_NAME_MAGIC; \
+ _n->ndata = NULL; \
+ _n->length = 0; \
+ _n->labels = 0; \
+ _n->attributes = 0; \
+ _n->offsets = (o); \
+ _n->buffer = NULL; \
+ ISC_LINK_INIT(_n, link); \
+ ISC_LIST_INIT(_n->list); \
} while (0)
#define DNS_NAME_RESET(n) \
diff --git a/lib/dns/include/dns/ncache.h b/lib/dns/include/dns/ncache.h
index 8d89879..337e834 100644
--- a/lib/dns/include/dns/ncache.h
+++ b/lib/dns/include/dns/ncache.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -73,6 +73,11 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
* rdataset, and store it in 'cache' at 'node' with a TTL limited to
* 'maxttl'.
*
+ * \li dns_ncache_add produces a negative cache entry with a trust of no
+ * more than answer
+ * \li dns_ncache_addoptout produces a negative cache entry which will have
+ * a trust of secure if all the records that make up the entry are secure.
+ *
* The 'covers' argument is the RR type whose nonexistence we are caching,
* or dns_rdatatype_any when caching a NXDOMAIN response.
*
diff --git a/lib/dns/include/dns/nsec.h b/lib/dns/include/dns/nsec.h
index a18e138..510d96b 100644
--- a/lib/dns/include/dns/nsec.h
+++ b/lib/dns/include/dns/nsec.h
@@ -75,6 +75,19 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
* 'answer' to be non NULL.
*/
+isc_result_t
+dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name,
+ dns_name_t *nsecname, dns_rdataset_t *nsecset,
+ isc_boolean_t *exists, isc_boolean_t *data,
+ dns_name_t *wild, dns_nseclog_t log, void *arg);
+/*%
+ * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
+ * or we can determine whether there is data or not at the name.
+ * If the name does not exist return the wildcard name.
+ *
+ * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
+ */
+
ISC_LANG_ENDDECLS
#endif /* DNS_NSEC_H */
diff --git a/lib/dns/include/dns/nsec3.h b/lib/dns/include/dns/nsec3.h
index beb44f3..588dd05 100644
--- a/lib/dns/include/dns/nsec3.h
+++ b/lib/dns/include/dns/nsec3.h
@@ -247,6 +247,14 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
* Mark NSEC3PARAM for deletion.
*/
+isc_result_t
+dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
+ dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
+ dns_name_t *zonename, isc_boolean_t *exists,
+ isc_boolean_t *data, isc_boolean_t *optout,
+ isc_boolean_t *unknown, isc_boolean_t *setclosest,
+ isc_boolean_t *setnearest, dns_name_t *closest,
+ dns_name_t *nearest, dns_nseclog_t logit, void *arg);
ISC_LANG_ENDDECLS
diff --git a/lib/dns/include/dns/rdata.h b/lib/dns/include/dns/rdata.h
index c3e7db6..2a67dc9 100644
--- a/lib/dns/include/dns/rdata.h
+++ b/lib/dns/include/dns/rdata.h
@@ -176,6 +176,7 @@ struct dns_rdata {
#define DNS_RDATA_CHECKREVERSE DNS_NAME_CHECKREVERSE
#define DNS_RDATA_CHECKMX DNS_NAME_CHECKMX
#define DNS_RDATA_CHECKMXFAIL DNS_NAME_CHECKMXFAIL
+#define DNS_RDATA_UNKNOWNESCAPE 0x80000000
/***
*** Initialization
diff --git a/lib/dns/include/dns/result.h b/lib/dns/include/dns/result.h
index 21388b2..9a7d2c2 100644
--- a/lib/dns/include/dns/result.h
+++ b/lib/dns/include/dns/result.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -151,8 +151,10 @@
#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105)
#define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106)
#define DNS_R_EXPIRED (ISC_RESULTCLASS_DNS + 107)
+#define DNS_R_NOTDYNAMIC (ISC_RESULTCLASS_DNS + 108)
+#define DNS_R_BADEUI (ISC_RESULTCLASS_DNS + 109)
-#define DNS_R_NRESULTS 108 /*%< Number of results */
+#define DNS_R_NRESULTS 110 /*%< Number of results */
/*
* DNS wire format rcodes.
diff --git a/lib/dns/include/dns/rpz.h b/lib/dns/include/dns/rpz.h
index 4227dd4..ceea26d 100644
--- a/lib/dns/include/dns/rpz.h
+++ b/lib/dns/include/dns/rpz.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -27,10 +27,11 @@
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"
+#define DNS_RPZ_PREFIX "rpz-"
+#define DNS_RPZ_IP_ZONE DNS_RPZ_PREFIX"ip"
+#define DNS_RPZ_NSIP_ZONE DNS_RPZ_PREFIX"nsip"
+#define DNS_RPZ_NSDNAME_ZONE DNS_RPZ_PREFIX"nsdname"
+#define DNS_RPZ_PASSTHRU_ZONE DNS_RPZ_PREFIX"passthru"
typedef isc_uint8_t dns_rpz_cidr_bits_t;
@@ -75,6 +76,7 @@ struct dns_rpz_zone {
dns_ttl_t max_policy_ttl;
dns_rpz_policy_t policy; /* DNS_RPZ_POLICY_GIVEN or override */
isc_boolean_t recursive_only;
+ isc_boolean_t defined;
};
/*
@@ -169,12 +171,6 @@ const char *
dns_rpz_policy2str(dns_rpz_policy_t policy);
void
-dns_rpz_set_need(isc_boolean_t need);
-
-isc_boolean_t
-dns_rpz_needed(void);
-
-void
dns_rpz_cidr_free(dns_rpz_cidr_t **cidr);
void
@@ -184,7 +180,7 @@ isc_result_t
dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin,
dns_rpz_cidr_t **rbtdb_cidr);
void
-dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st);
+dns_rpz_enabled_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st);
void
dns_rpz_cidr_deleteip(dns_rpz_cidr_t *cidr, dns_name_t *name);
diff --git a/lib/dns/include/dns/types.h b/lib/dns/include/dns/types.h
index 921c76aa..a031825 100644
--- a/lib/dns/include/dns/types.h
+++ b/lib/dns/include/dns/types.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -72,6 +72,7 @@ typedef ISC_LIST(dns_dns64_t) dns_dns64list_t;
typedef struct dns_dnsseckey dns_dnsseckey_t;
typedef ISC_LIST(dns_dnsseckey_t) dns_dnsseckeylist_t;
typedef struct dns_dumpctx dns_dumpctx_t;
+typedef struct dns_ednsopt dns_ednsopt_t;
typedef struct dns_fetch dns_fetch_t;
typedef struct dns_fixedname dns_fixedname_t;
typedef struct dns_forwarders dns_forwarders_t;
@@ -373,4 +374,7 @@ typedef isc_boolean_t
(*dns_isselffunc_t)(dns_view_t *, dns_tsigkey_t *, isc_sockaddr_t *,
isc_sockaddr_t *, dns_rdataclass_t, void *);
+typedef void
+(*dns_nseclog_t)(void *val, int , const char *, ...);
+
#endif /* DNS_TYPES_H */
diff --git a/lib/dns/include/dns/validator.h b/lib/dns/include/dns/validator.h
index 7d6ea7a..b3cfe99 100644
--- a/lib/dns/include/dns/validator.h
+++ b/lib/dns/include/dns/validator.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2010, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -104,6 +104,10 @@ typedef struct dns_validatorevent {
* Optout proof seen.
*/
isc_boolean_t optout;
+ /*
+ * Answer is secure.
+ */
+ isc_boolean_t secure;
} dns_validatorevent_t;
#define DNS_VALIDATOR_NOQNAMEPROOF 0
diff --git a/lib/dns/include/dns/view.h b/lib/dns/include/dns/view.h
index 4a04867..d999fa1 100644
--- a/lib/dns/include/dns/view.h
+++ b/lib/dns/include/dns/view.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -164,6 +164,7 @@ struct dns_view {
ISC_LIST(dns_rpz_zone_t) rpz_zones;
isc_boolean_t rpz_recursive_only;
isc_boolean_t rpz_break_dnssec;
+ unsigned int rpz_min_ns_labels;
/*
* Configurable data for server use only,
diff --git a/lib/dns/include/dns/zone.h b/lib/dns/include/dns/zone.h
index 9db825c..6b9911d 100644
--- a/lib/dns/include/dns/zone.h
+++ b/lib/dns/include/dns/zone.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -34,6 +34,7 @@
#include <dns/masterdump.h>
#include <dns/rdatastruct.h>
+#include <dns/rpz.h>
#include <dns/types.h>
typedef enum {
@@ -77,6 +78,7 @@ typedef enum {
#define DNS_ZONEOPT_DNSKEYKSKONLY 0x10000000U /*%< dnssec-dnskey-kskonly */
#define DNS_ZONEOPT_CHECKDUPRR 0x20000000U /*%< check-dup-records */
#define DNS_ZONEOPT_CHECKDUPRRFAIL 0x40000000U /*%< fatal check-dup-records failures */
+#define DNS_ZONEOPT_CHECKSPF 0x80000000U /*%< check SPF records */
#ifndef NOMINUM_PUBLIC
/*
@@ -1898,6 +1900,15 @@ dns_zone_synckeyzone(dns_zone_t *zone);
* maintenance timer.
*/
+isc_result_t
+dns_zone_rpz_enable(dns_zone_t *zone);
+/*%
+ * Set the response policy associated with a zone.
+ */
+
+isc_boolean_t
+dns_zone_get_rpz(dns_zone_t *zone);
+
ISC_LANG_ENDDECLS
#endif /* DNS_ZONE_H */
diff --git a/lib/dns/include/dst/dst.h b/lib/dns/include/dst/dst.h
index b0fa690..87d844b 100644
--- a/lib/dns/include/dst/dst.h
+++ b/lib/dns/include/dst/dst.h
@@ -26,6 +26,7 @@
#include <isc/stdtime.h>
#include <dns/types.h>
+#include <dns/log.h>
#include <dns/name.h>
#include <dns/secalg.h>
@@ -169,6 +170,11 @@ dst_algorithm_supported(unsigned int alg);
isc_result_t
dst_context_create(dst_key_t *key, isc_mem_t *mctx, dst_context_t **dctxp);
+
+isc_result_t
+dst_context_create2(dst_key_t *key, isc_mem_t *mctx,
+ isc_logcategory_t *category, dst_context_t **dctxp);
+
/*%<
* Creates a context to be used for a sign or verify operation.
*
diff --git a/lib/dns/master.c b/lib/dns/master.c
index 8304507..1b7460c 100644
--- a/lib/dns/master.c
+++ b/lib/dns/master.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -156,6 +156,7 @@ struct dns_incctx {
int glue_in_use;
int current_in_use;
int origin_in_use;
+ isc_boolean_t origin_changed;
isc_boolean_t drop;
unsigned int glue_line;
unsigned int current_line;
@@ -568,6 +569,7 @@ loadctx_create(dns_masterformat_t format, isc_mem_t *mctx,
goto cleanup_inc;
lctx->keep_lex = ISC_FALSE;
memset(specials, 0, sizeof(specials));
+ specials[0] = 1;
specials['('] = 1;
specials[')'] = 1;
specials['"'] = 1;
@@ -770,7 +772,7 @@ static isc_result_t
openfile_raw(dns_loadctx_t *lctx, const char *master_file) {
isc_result_t result;
- result = isc_stdio_open(master_file, "r", &lctx->f);
+ result = isc_stdio_open(master_file, "rb", &lctx->f);
if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_stdio_open() failed: %s",
@@ -1402,6 +1404,7 @@ load_text(dns_loadctx_t *lctx) {
ictx->origin_in_use = new_in_use;
ictx->in_use[ictx->origin_in_use] = ISC_TRUE;
ictx->origin = new_name;
+ ictx->origin_changed = ISC_TRUE;
finish_origin = ISC_FALSE;
EXPECTEOL;
continue;
@@ -1574,8 +1577,24 @@ load_text(dns_loadctx_t *lctx) {
} else if (result != ISC_R_SUCCESS)
goto insist_and_cleanup;
}
+
+ if (ictx->origin_changed) {
+ char cbuf[DNS_NAME_FORMATSIZE];
+ char obuf[DNS_NAME_FORMATSIZE];
+ dns_name_format(ictx->current, cbuf,
+ sizeof(cbuf));
+ dns_name_format(ictx->origin, obuf,
+ sizeof(obuf));
+ (*callbacks->warn)(callbacks,
+ "%s:%lu: record with inherited "
+ "owner (%s) immediately after "
+ "$ORIGIN (%s)", source, line,
+ cbuf, obuf);
+ }
}
+ ictx->origin_changed = ISC_FALSE;
+
if (dns_rdataclass_fromtext(&rdclass,
&token.value.as_textregion)
== ISC_R_SUCCESS)
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 2b65f0e..d36edba 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -1441,8 +1441,15 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* the opcode is an update, or the type search is skipped.
*/
if (result == ISC_R_SUCCESS) {
- if (dns_rdatatype_issingleton(rdtype))
- DO_FORMERR;
+ if (dns_rdatatype_issingleton(rdtype)) {
+ dns_rdata_t *first;
+ dns_rdatalist_fromrdataset(rdataset,
+ &rdatalist);
+ first = ISC_LIST_HEAD(rdatalist->rdata);
+ INSIST(first != NULL);
+ if (dns_rdata_compare(rdata, first) != 0)
+ DO_FORMERR;
+ }
}
if (result == ISC_R_NOTFOUND) {
@@ -2112,6 +2119,30 @@ dns_message_renderend(dns_message_t *msg) {
}
/*
+ * If we're adding a OPT, TSIG or SIG(0) to a truncated message,
+ * clear all rdatasets from the message except for the question
+ * before adding the OPT, TSIG or SIG(0). If the question doesn't
+ * fit, don't include it.
+ */
+ if ((msg->tsigkey != NULL || msg->sig0key != NULL || msg->opt) &&
+ (msg->flags & DNS_MESSAGEFLAG_TC) != 0)
+ {
+ isc_buffer_t *buf;
+
+ msgresetnames(msg, DNS_SECTION_ANSWER);
+ buf = msg->buffer;
+ dns_message_renderreset(msg);
+ msg->buffer = buf;
+ isc_buffer_clear(msg->buffer);
+ isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
+ dns_compress_rollback(msg->cctx, 0);
+ result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
+ 0);
+ if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
+ return (result);
+ }
+
+ /*
* If we've got an OPT record, render it.
*/
if (msg->opt != NULL) {
@@ -2136,30 +2167,6 @@ dns_message_renderend(dns_message_t *msg) {
}
/*
- * If we're adding a TSIG or SIG(0) to a truncated message,
- * clear all rdatasets from the message except for the question
- * before adding the TSIG or SIG(0). If the question doesn't fit,
- * don't include it.
- */
- if ((msg->tsigkey != NULL || msg->sig0key != NULL) &&
- (msg->flags & DNS_MESSAGEFLAG_TC) != 0)
- {
- isc_buffer_t *buf;
-
- msgresetnames(msg, DNS_SECTION_ANSWER);
- buf = msg->buffer;
- dns_message_renderreset(msg);
- msg->buffer = buf;
- isc_buffer_clear(msg->buffer);
- isc_buffer_add(msg->buffer, DNS_MESSAGE_HEADERLEN);
- dns_compress_rollback(msg->cctx, 0);
- result = dns_message_rendersection(msg, DNS_SECTION_QUESTION,
- 0);
- if (result != ISC_R_SUCCESS && result != ISC_R_NOSPACE)
- return (result);
- }
-
- /*
* If we're adding a TSIG record, generate and render it.
*/
if (msg->tsigkey != NULL) {
@@ -2633,9 +2640,9 @@ dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
return (ISC_R_SUCCESS);
cleanup:
+ dns_rdataset_disassociate(opt);
dns_message_puttemprdataset(msg, &opt);
return (result);
-
}
dns_rdataset_t *
@@ -3449,3 +3456,95 @@ dns_opcode_totext(dns_opcode_t opcode, isc_buffer_t *target) {
isc_buffer_putstr(target, opcodetext[opcode]);
return (ISC_R_SUCCESS);
}
+
+isc_result_t
+dns_message_buildopt(dns_message_t *message, dns_rdataset_t **rdatasetp,
+ unsigned int version, isc_uint16_t udpsize,
+ unsigned int flags, dns_ednsopt_t *ednsopts, size_t count)
+{
+ dns_rdataset_t *rdataset = NULL;
+ dns_rdatalist_t *rdatalist = NULL;
+ dns_rdata_t *rdata = NULL;
+ isc_result_t result;
+ size_t len = 0, i;
+
+ REQUIRE(DNS_MESSAGE_VALID(message));
+ REQUIRE(rdatasetp != NULL && *rdatasetp == NULL);
+
+ result = dns_message_gettemprdatalist(message, &rdatalist);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ result = dns_message_gettemprdata(message, &rdata);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ result = dns_message_gettemprdataset(message, &rdataset);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+ dns_rdataset_init(rdataset);
+
+ rdatalist->type = dns_rdatatype_opt;
+ rdatalist->covers = 0;
+
+ /*
+ * Set Maximum UDP buffer size.
+ */
+ rdatalist->rdclass = udpsize;
+
+ /*
+ * Set EXTENDED-RCODE and Z to 0.
+ */
+ rdatalist->ttl = (version << 16);
+ rdatalist->ttl |= (flags & 0xffff);
+
+ /*
+ * Set EDNS options if applicable
+ */
+ if (count != 0U) {
+ isc_buffer_t *buf = NULL;
+ for (i = 0; i < count; i++)
+ len += ednsopts[i].length + 4;
+
+ if (len > 0xffffU) {
+ result = ISC_R_NOSPACE;
+ goto cleanup;
+ }
+
+ result = isc_buffer_allocate(message->mctx, &buf, len);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup;
+
+ for (i = 0; i < count; i++) {
+ isc_buffer_putuint16(buf, ednsopts[i].code);
+ isc_buffer_putuint16(buf, ednsopts[i].length);
+ isc_buffer_putmem(buf, ednsopts[i].value,
+ ednsopts[i].length);
+ }
+ rdata->data = isc_buffer_base(buf);
+ rdata->length = len;
+ dns_message_takebuffer(message, &buf);
+ } else {
+ rdata->data = NULL;
+ rdata->length = 0;
+ }
+
+ rdata->rdclass = rdatalist->rdclass;
+ rdata->type = rdatalist->type;
+ rdata->flags = 0;
+
+ ISC_LIST_INIT(rdatalist->rdata);
+ ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
+ result = dns_rdatalist_tordataset(rdatalist, rdataset);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ *rdatasetp = rdataset;
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ if (rdata != NULL)
+ dns_message_puttemprdata(message, &rdata);
+ if (rdataset != NULL)
+ dns_message_puttemprdataset(message, &rdataset);
+ if (rdatalist != NULL)
+ dns_message_puttemprdatalist(message, &rdatalist);
+ return (result);
+}
diff --git a/lib/dns/name.c b/lib/dns/name.c
index fab1f33..7fb21e1 100644
--- a/lib/dns/name.c
+++ b/lib/dns/name.c
@@ -584,11 +584,13 @@ dns_name_fullcompare(const dns_name_t *name1, const dns_name_t *name2,
nlabels = 0;
l1 = name1->labels;
l2 = name2->labels;
- ldiff = (int)l1 - (int)l2;
- if (ldiff < 0)
+ if (l2 > l1) {
l = l1;
- else
+ ldiff = 0 - (l2 - l1);
+ } else {
l = l2;
+ ldiff = l1 - l2;
+ }
while (l > 0) {
l--;
@@ -841,6 +843,10 @@ dns_name_matcheswildcard(const dns_name_t *name, const dns_name_t *wname) {
REQUIRE(labels > 0);
REQUIRE(dns_name_iswildcard(wname));
+#if defined(__clang__) && \
+ ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
+ memset(&tname, 0, sizeof(tname));
+#endif
DNS_NAME_INIT(&tname, NULL);
dns_name_getlabelsequence(wname, 1, labels - 1, &tname);
if (dns_name_fullcompare(name, &tname, &order, &nlabels) ==
@@ -1427,6 +1433,7 @@ dns_name_totext2(dns_name_t *name, unsigned int options, isc_buffer_t *target)
case 0x24: /* '$' */
if ((options & DNS_NAME_MASTERFILE) == 0)
goto no_escape;
+ /* FALLTHROUGH */
case 0x22: /* '"' */
case 0x28: /* '(' */
case 0x29: /* ')' */
@@ -1934,6 +1941,10 @@ dns_name_towire(const dns_name_t *name, dns_compress_t *cctx,
* has one.
*/
if (name->offsets == NULL) {
+#if defined(__clang__) && \
+ ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
+ memset(&clname, 0, sizeof(clname));
+#endif
DNS_NAME_INIT(&clname, clo);
dns_name_clone(name, &clname);
name = &clname;
@@ -2239,7 +2250,12 @@ dns_name_digest(dns_name_t *name, dns_digestfunc_t digest, void *arg) {
REQUIRE(VALID_NAME(name));
REQUIRE(digest != NULL);
+#if defined(__clang__) && \
+ ( __clang_major__ < 3 || (__clang_major__ == 3 && __clang_minor__ < 2))
+ memset(&downname, 0, sizeof(downname));
+#endif
DNS_NAME_INIT(&downname, NULL);
+
isc_buffer_init(&buffer, data, sizeof(data));
result = dns_name_downcase(name, &downname, &buffer);
@@ -2404,7 +2420,7 @@ dns_name_fromstring2(dns_name_t *target, const char *src,
REQUIRE(src != NULL);
- isc_buffer_init(&buf, src, strlen(src));
+ isc_buffer_constinit(&buf, src, strlen(src));
isc_buffer_add(&buf, strlen(src));
if (BINDABLE(target) && target->buffer != NULL)
name = target;
diff --git a/lib/dns/ncache.c b/lib/dns/ncache.c
index c0e99d4..bcb3d05 100644
--- a/lib/dns/ncache.c
+++ b/lib/dns/ncache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -47,6 +47,12 @@
*
*/
+static isc_result_t
+addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
+ dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
+ isc_boolean_t optout, isc_boolean_t secure,
+ dns_rdataset_t *addedrdataset);
+
static inline isc_result_t
copy_rdataset(dns_rdataset_t *rdataset, isc_buffer_t *buffer) {
isc_result_t result;
@@ -96,8 +102,8 @@ dns_ncache_add(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
dns_rdataset_t *addedrdataset)
{
- return (dns_ncache_addoptout(message, cache, node, covers, now, maxttl,
- ISC_FALSE, addedrdataset));
+ return (addoptout(message, cache, node, covers, now, maxttl,
+ ISC_FALSE, ISC_FALSE, addedrdataset));
}
isc_result_t
@@ -106,6 +112,16 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
isc_stdtime_t now, dns_ttl_t maxttl,
isc_boolean_t optout, dns_rdataset_t *addedrdataset)
{
+ return (addoptout(message, cache, node, covers, now, maxttl,
+ optout, ISC_TRUE, addedrdataset));
+}
+
+static isc_result_t
+addoptout(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
+ dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
+ isc_boolean_t optout, isc_boolean_t secure,
+ dns_rdataset_t *addedrdataset)
+{
isc_result_t result;
isc_buffer_t buffer;
isc_region_t r;
@@ -242,6 +258,8 @@ dns_ncache_addoptout(dns_message_t *message, dns_db_t *cache,
dns_rdataset_init(&ncrdataset);
RUNTIME_CHECK(dns_rdatalist_tordataset(&ncrdatalist, &ncrdataset)
== ISC_R_SUCCESS);
+ if (!secure && trust > dns_trust_answer)
+ trust = dns_trust_answer;
ncrdataset.trust = trust;
ncrdataset.attributes |= DNS_RDATASETATTR_NEGATIVE;
if (message->rcode == dns_rcode_nxdomain)
diff --git a/lib/dns/nsec.c b/lib/dns/nsec.c
index 72d1751..41b5dc3 100644
--- a/lib/dns/nsec.c
+++ b/lib/dns/nsec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2011-2013 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
@@ -21,6 +21,7 @@
#include <config.h>
+#include <isc/log.h>
#include <isc/string.h>
#include <isc/util.h>
@@ -275,3 +276,161 @@ dns_nsec_nseconly(dns_db_t *db, dns_dbversion_t *version,
}
return (result);
}
+
+/*%
+ * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
+ * or we can determine whether there is data or not at the name.
+ * If the name does not exist return the wildcard name.
+ *
+ * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
+ */
+isc_result_t
+dns_nsec_noexistnodata(dns_rdatatype_t type, dns_name_t *name,
+ dns_name_t *nsecname, dns_rdataset_t *nsecset,
+ isc_boolean_t *exists, isc_boolean_t *data,
+ dns_name_t *wild, dns_nseclog_t logit, void *arg)
+{
+ int order;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ isc_result_t result;
+ dns_namereln_t relation;
+ unsigned int olabels, nlabels, labels;
+ dns_rdata_nsec_t nsec;
+ isc_boolean_t atparent;
+ isc_boolean_t ns;
+ isc_boolean_t soa;
+
+ REQUIRE(exists != NULL);
+ REQUIRE(data != NULL);
+ REQUIRE(nsecset != NULL &&
+ nsecset->type == dns_rdatatype_nsec);
+
+ result = dns_rdataset_first(nsecset);
+ if (result != ISC_R_SUCCESS) {
+ (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC set");
+ return (result);
+ }
+ dns_rdataset_current(nsecset, &rdata);
+
+ (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC");
+ relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
+
+ if (order < 0) {
+ /*
+ * The name is not within the NSEC range.
+ */
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "NSEC does not cover name, before NSEC");
+ return (ISC_R_IGNORE);
+ }
+
+ if (order == 0) {
+ /*
+ * The names are the same. If we are validating "."
+ * then atparent should not be set as there is no parent.
+ */
+ atparent = (olabels != 1) && dns_rdatatype_atparent(type);
+ ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
+ soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa);
+ if (ns && !soa) {
+ if (!atparent) {
+ /*
+ * This NSEC record is from somewhere higher in
+ * the DNS, and at the parent of a delegation.
+ * It can not be legitimately used here.
+ */
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring parent nsec");
+ return (ISC_R_IGNORE);
+ }
+ } else if (atparent && ns && soa) {
+ /*
+ * This NSEC record is from the child.
+ * It can not be legitimately used here.
+ */
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring child nsec");
+ return (ISC_R_IGNORE);
+ }
+ if (type == dns_rdatatype_cname || type == dns_rdatatype_nxt ||
+ type == dns_rdatatype_nsec || type == dns_rdatatype_key ||
+ !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) {
+ *exists = ISC_TRUE;
+ *data = dns_nsec_typepresent(&rdata, type);
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "nsec proves name exists (owner) data=%d",
+ *data);
+ return (ISC_R_SUCCESS);
+ }
+ (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists");
+ return (ISC_R_IGNORE);
+ }
+
+ if (relation == dns_namereln_subdomain &&
+ dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
+ !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
+ {
+ /*
+ * This NSEC record is from somewhere higher in
+ * the DNS, and at the parent of a delegation.
+ * It can not be legitimately used here.
+ */
+ (*logit)(arg, ISC_LOG_DEBUG(3), "ignoring parent nsec");
+ return (ISC_R_IGNORE);
+ }
+
+ result = dns_rdata_tostruct(&rdata, &nsec, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
+ if (order == 0) {
+ dns_rdata_freestruct(&nsec);
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring nsec matches next name");
+ return (ISC_R_IGNORE);
+ }
+
+ if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {
+ /*
+ * The name is not within the NSEC range.
+ */
+ dns_rdata_freestruct(&nsec);
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring nsec because name is past end of range");
+ return (ISC_R_IGNORE);
+ }
+
+ if (order > 0 && relation == dns_namereln_subdomain) {
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "nsec proves name exist (empty)");
+ dns_rdata_freestruct(&nsec);
+ *exists = ISC_TRUE;
+ *data = ISC_FALSE;
+ return (ISC_R_SUCCESS);
+ }
+ if (wild != NULL) {
+ dns_name_t common;
+ dns_name_init(&common, NULL);
+ if (olabels > nlabels) {
+ labels = dns_name_countlabels(nsecname);
+ dns_name_getlabelsequence(nsecname, labels - olabels,
+ olabels, &common);
+ } else {
+ labels = dns_name_countlabels(&nsec.next);
+ dns_name_getlabelsequence(&nsec.next, labels - nlabels,
+ nlabels, &common);
+ }
+ result = dns_name_concatenate(dns_wildcardname, &common,
+ wild, NULL);
+ if (result != ISC_R_SUCCESS) {
+ dns_rdata_freestruct(&nsec);
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "failure generating wildcard name");
+ return (result);
+ }
+ }
+ dns_rdata_freestruct(&nsec);
+ (*logit)(arg, ISC_LOG_DEBUG(3), "nsec range ok");
+ *exists = ISC_FALSE;
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c
index 123126d..7ec6b4c 100644
--- a/lib/dns/nsec3.c
+++ b/lib/dns/nsec3.c
@@ -22,6 +22,7 @@
#include <isc/buffer.h>
#include <isc/hex.h>
#include <isc/iterated_hash.h>
+#include <isc/log.h>
#include <isc/string.h>
#include <isc/util.h>
@@ -1132,7 +1133,11 @@ dns_nsec3param_deletechains(dns_db_t *db, dns_dbversion_t *ver,
INSIST(rdata.length <= sizeof(buf));
memcpy(buf, rdata.data, rdata.length);
- if (buf[0] != 0 ||
+ /*
+ * Private NSEC3 record length >= 6.
+ * <0(1), hash(1), flags(1), iterations(2), saltlen(1)>
+ */
+ if (rdata.length < 6 || buf[0] != 0 ||
buf[2] == (DNS_NSEC3FLAG_REMOVE | DNS_NSEC3FLAG_NONSEC)) {
dns_rdata_reset(&rdata);
continue;
@@ -1832,3 +1837,285 @@ dns_nsec3_maxiterations(dns_db_t *db, dns_dbversion_t *version,
dns_rdataset_disassociate(&rdataset);
return (result);
}
+
+isc_result_t
+dns_nsec3_noexistnodata(dns_rdatatype_t type, dns_name_t* name,
+ dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
+ dns_name_t *zonename, isc_boolean_t *exists,
+ isc_boolean_t *data, isc_boolean_t *optout,
+ isc_boolean_t *unknown, isc_boolean_t *setclosest,
+ isc_boolean_t *setnearest, dns_name_t *closest,
+ dns_name_t *nearest, dns_nseclog_t logit, void *arg)
+{
+ char namebuf[DNS_NAME_FORMATSIZE];
+ dns_fixedname_t fzone;
+ dns_fixedname_t qfixed;
+ dns_label_t hashlabel;
+ dns_name_t *qname;
+ dns_name_t *zone;
+ dns_rdata_nsec3_t nsec3;
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ int order;
+ int scope;
+ isc_boolean_t atparent;
+ isc_boolean_t first;
+ isc_boolean_t ns;
+ isc_boolean_t soa;
+ isc_buffer_t buffer;
+ isc_result_t answer = ISC_R_IGNORE;
+ isc_result_t result;
+ unsigned char hash[NSEC3_MAX_HASH_LENGTH];
+ unsigned char owner[NSEC3_MAX_HASH_LENGTH];
+ unsigned int length;
+ unsigned int qlabels;
+ unsigned int zlabels;
+
+ REQUIRE((exists == NULL && data == NULL) ||
+ (exists != NULL && data != NULL));
+ REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
+ REQUIRE((setclosest == NULL && closest == NULL) ||
+ (setclosest != NULL && closest != NULL));
+ REQUIRE((setnearest == NULL && nearest == NULL) ||
+ (setnearest != NULL && nearest != NULL));
+
+ result = dns_rdataset_first(nsec3set);
+ if (result != ISC_R_SUCCESS) {
+ (*logit)(arg, ISC_LOG_DEBUG(3), "failure processing NSEC3 set");
+ return (result);
+ }
+
+ dns_rdataset_current(nsec3set, &rdata);
+
+ result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ (*logit)(arg, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
+
+ dns_fixedname_init(&fzone);
+ zone = dns_fixedname_name(&fzone);
+ zlabels = dns_name_countlabels(nsec3name);
+
+ /*
+ * NSEC3 records must have two or more labels to be valid.
+ */
+ if (zlabels < 2)
+ return (ISC_R_IGNORE);
+
+ /*
+ * Strip off the NSEC3 hash to get the zone.
+ */
+ zlabels--;
+ dns_name_split(nsec3name, zlabels, NULL, zone);
+
+ /*
+ * If not below the zone name we can ignore this record.
+ */
+ if (!dns_name_issubdomain(name, zone))
+ return (ISC_R_IGNORE);
+
+ /*
+ * Is this zone the same or deeper than the current zone?
+ */
+ if (dns_name_countlabels(zonename) == 0 ||
+ dns_name_issubdomain(zone, zonename))
+ dns_name_copy(zone, zonename, NULL);
+
+ if (!dns_name_equal(zone, zonename))
+ return (ISC_R_IGNORE);
+
+ /*
+ * Are we only looking for the most enclosing zone?
+ */
+ if (exists == NULL || data == NULL)
+ return (ISC_R_SUCCESS);
+
+ /*
+ * Only set unknown once we are sure that this NSEC3 is from
+ * the deepest covering zone.
+ */
+ if (!dns_nsec3_supportedhash(nsec3.hash)) {
+ if (unknown != NULL)
+ *unknown = ISC_TRUE;
+ return (ISC_R_IGNORE);
+ }
+
+ /*
+ * Recover the hash from the first label.
+ */
+ dns_name_getlabel(nsec3name, 0, &hashlabel);
+ isc_region_consume(&hashlabel, 1);
+ isc_buffer_init(&buffer, owner, sizeof(owner));
+ result = isc_base32hex_decoderegion(&hashlabel, &buffer);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * The hash lengths should match. If not ignore the record.
+ */
+ if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
+ return (ISC_R_IGNORE);
+
+ /*
+ * Work out what this NSEC3 covers.
+ * Inside (<0) or outside (>=0).
+ */
+ scope = memcmp(owner, nsec3.next, nsec3.next_length);
+
+ /*
+ * Prepare to compute all the hashes.
+ */
+ dns_fixedname_init(&qfixed);
+ qname = dns_fixedname_name(&qfixed);
+ dns_name_downcase(name, qname, NULL);
+ qlabels = dns_name_countlabels(qname);
+ first = ISC_TRUE;
+
+ while (qlabels >= zlabels) {
+ length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
+ nsec3.salt, nsec3.salt_length,
+ qname->ndata, qname->length);
+ /*
+ * The computed hash length should match.
+ */
+ if (length != nsec3.next_length) {
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring NSEC bad length %u vs %u",
+ length, nsec3.next_length);
+ return (ISC_R_IGNORE);
+ }
+
+ order = memcmp(hash, owner, length);
+ if (first && order == 0) {
+ /*
+ * The hashes are the same.
+ */
+ atparent = dns_rdatatype_atparent(type);
+ ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
+ soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
+ if (ns && !soa) {
+ if (!atparent) {
+ /*
+ * This NSEC3 record is from somewhere
+ * higher in the DNS, and at the
+ * parent of a delegation. It can not
+ * be legitimately used here.
+ */
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring parent NSEC3");
+ return (ISC_R_IGNORE);
+ }
+ } else if (atparent && ns && soa) {
+ /*
+ * This NSEC3 record is from the child.
+ * It can not be legitimately used here.
+ */
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring child NSEC3");
+ return (ISC_R_IGNORE);
+ }
+ if (type == dns_rdatatype_cname ||
+ type == dns_rdatatype_nxt ||
+ type == dns_rdatatype_nsec ||
+ type == dns_rdatatype_key ||
+ !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
+ *exists = ISC_TRUE;
+ *data = dns_nsec3_typepresent(&rdata, type);
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "NSEC3 proves name exists (owner) "
+ "data=%d", *data);
+ return (ISC_R_SUCCESS);
+ }
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "NSEC3 proves CNAME exists");
+ return (ISC_R_IGNORE);
+ }
+
+ if (order == 0 &&
+ dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
+ !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
+ {
+ /*
+ * This NSEC3 record is from somewhere higher in
+ * the DNS, and at the parent of a delegation.
+ * It can not be legitimately used here.
+ */
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "ignoring parent NSEC3");
+ return (ISC_R_IGNORE);
+ }
+
+ /*
+ * Potential closest encloser.
+ */
+ if (order == 0) {
+ if (closest != NULL &&
+ (dns_name_countlabels(closest) == 0 ||
+ dns_name_issubdomain(qname, closest)) &&
+ !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
+ !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
+ (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
+ !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
+ {
+
+ dns_name_format(qname, namebuf,
+ sizeof(namebuf));
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "NSEC3 indicates potential closest "
+ "encloser: '%s'", namebuf);
+ dns_name_copy(qname, closest, NULL);
+ *setclosest = ISC_TRUE;
+ }
+ dns_name_format(qname, namebuf, sizeof(namebuf));
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "NSEC3 at super-domain %s", namebuf);
+ return (answer);
+ }
+
+ /*
+ * Find if the name does not exist.
+ *
+ * We continue as we need to find the name closest to the
+ * closest encloser that doesn't exist.
+ *
+ * We also need to continue to ensure that we are not
+ * proving the non-existence of a record in a sub-zone.
+ * If that would be the case we will return ISC_R_IGNORE
+ * above.
+ */
+ if ((scope < 0 && order > 0 &&
+ memcmp(hash, nsec3.next, length) < 0) ||
+ (scope >= 0 && (order > 0 ||
+ memcmp(hash, nsec3.next, length) < 0)))
+ {
+ char namebuf[DNS_NAME_FORMATSIZE];
+
+ dns_name_format(qname, namebuf, sizeof(namebuf));
+ (*logit)(arg, ISC_LOG_DEBUG(3), "NSEC3 proves "
+ "name does not exist: '%s'", namebuf);
+ if (nearest != NULL &&
+ (dns_name_countlabels(nearest) == 0 ||
+ dns_name_issubdomain(nearest, qname))) {
+ dns_name_copy(qname, nearest, NULL);
+ *setnearest = ISC_TRUE;
+ }
+
+ *exists = ISC_FALSE;
+ *data = ISC_FALSE;
+ if (optout != NULL) {
+ if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
+ (*logit)(arg, ISC_LOG_DEBUG(3),
+ "NSEC3 indicates optout");
+ *optout =
+ ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
+ }
+ answer = ISC_R_SUCCESS;
+ }
+
+ qlabels--;
+ if (qlabels > 0)
+ dns_name_split(qname, qlabels, NULL, qname);
+ first = ISC_FALSE;
+ }
+ return (answer);
+}
diff --git a/lib/dns/openssl_link.c b/lib/dns/openssl_link.c
index d186761..56465aa 100644
--- a/lib/dns/openssl_link.c
+++ b/lib/dns/openssl_link.c
@@ -286,46 +286,78 @@ dst__openssl_destroy() {
}
}
-isc_result_t
-dst__openssl_toresult(isc_result_t fallback) {
+static isc_result_t
+toresult(isc_result_t fallback) {
isc_result_t result = fallback;
unsigned long err = ERR_get_error();
+#ifdef HAVE_OPENSSL_ECDSA
+ int lib = ERR_GET_LIB(err);
+#endif
+ int reason = ERR_GET_REASON(err);
- switch (ERR_GET_REASON(err)) {
+ switch (reason) {
+ /*
+ * ERR_* errors are globally unique; others
+ * are unique per sublibrary
+ */
case ERR_R_MALLOC_FAILURE:
result = ISC_R_NOMEMORY;
break;
default:
+#ifdef HAVE_OPENSSL_ECDSA
+ if (lib == ERR_R_ECDSA_LIB &&
+ reason == ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED) {
+ result = ISC_R_NOENTROPY;
+ break;
+ }
+#endif
break;
}
+
+ return (result);
+}
+
+isc_result_t
+dst__openssl_toresult(isc_result_t fallback) {
+ isc_result_t result;
+
+ result = toresult(fallback);
+
ERR_clear_error();
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();
+ return (dst__openssl_toresult3(DNS_LOGCATEGORY_GENERAL,
+ funcname, fallback));
+}
+
+isc_result_t
+dst__openssl_toresult3(isc_logcategory_t *category,
+ const char *funcname, isc_result_t fallback) {
+ isc_result_t result;
+ unsigned long err;
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,
+ result = toresult(fallback);
+
+ isc_log_write(dns_lctx, category,
DNS_LOGMODULE_CRYPTO, ISC_LOG_WARNING,
- "%s failed", funcname);
+ "%s failed (%s)", funcname,
+ isc_result_totext(result));
+
+ if (result == ISC_R_NOMEMORY)
+ goto done;
+
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,
+ isc_log_write(dns_lctx, category,
DNS_LOGMODULE_CRYPTO, ISC_LOG_INFO,
"%s:%s:%d:%s", buf, file, line,
(flags & ERR_TXT_STRING) ? data : "");
diff --git a/lib/dns/openssldsa_link.c b/lib/dns/openssldsa_link.c
index e2cf8cd..66d47bb 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 (dst__openssl_toresult2("EVP_SignFinal",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_SignFinal",
ISC_R_FAILURE));
}
INSIST(EVP_PKEY_size(pkey) >= (int) siglen);
@@ -182,25 +183,30 @@ openssldsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
sb = sigbuf;
if (d2i_DSA_SIG(&dsasig, &sb, (long) siglen) == NULL) {
free(sigbuf);
- return (dst__openssl_toresult2("d2i_DSA_SIG", ISC_R_FAILURE));
+ return (dst__openssl_toresult3(dctx->category,
+ "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 (dst__openssl_toresult2("EVP_DigestFinal_ex",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_DigestFinal_ex",
ISC_R_FAILURE));
}
dsasig = DSA_do_sign(digest, ISC_SHA1_DIGESTLENGTH, dsa);
if (dsasig == NULL)
- return (dst__openssl_toresult2("DSA_do_sign",
+ return (dst__openssl_toresult3(dctx->category,
+ "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_toresult2("DSA_do_sign",
+ return (dst__openssl_toresult3(dctx->category,
+ "DSA_do_sign",
DST_R_SIGNFAILURE));
#endif
*r.base++ = (key->key_size - 512)/64;
@@ -286,7 +292,8 @@ openssldsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
case 0:
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
default:
- return (dst__openssl_toresult2("DSA_do_verify",
+ return (dst__openssl_toresult3(dctx->category,
+ "DSA_do_verify",
DST_R_VERIFYFAILURE));
}
}
diff --git a/lib/dns/opensslecdsa_link.c b/lib/dns/opensslecdsa_link.c
index e6c9b67..1cf30f8 100644
--- a/lib/dns/opensslecdsa_link.c
+++ b/lib/dns/opensslecdsa_link.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2012, 2013 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
@@ -73,7 +73,8 @@ opensslecdsa_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 (dst__openssl_toresult2("EVP_DigestInit_ex",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_DigestInit_ex",
ISC_R_FAILURE));
}
@@ -103,7 +104,8 @@ opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
dctx->key->key_alg == DST_ALG_ECDSA384);
if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
- return (dst__openssl_toresult2("EVP_DigestUpdate",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_DigestUpdate",
ISC_R_FAILURE));
return (ISC_R_SUCCESS);
@@ -147,12 +149,14 @@ opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
DST_RET(ISC_R_NOSPACE);
if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen))
- DST_RET(dst__openssl_toresult2("EVP_DigestFinal",
+ DST_RET(dst__openssl_toresult3(dctx->category,
+ "EVP_DigestFinal",
ISC_R_FAILURE));
ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
if (ecdsasig == NULL)
- DST_RET(dst__openssl_toresult2("ECDSA_do_sign",
+ DST_RET(dst__openssl_toresult3(dctx->category,
+ "ECDSA_do_sign",
DST_R_SIGNFAILURE));
BN_bn2bin_fixed(ecdsasig->r, r.base, siglen / 2);
r.base += siglen / 2;
@@ -196,14 +200,19 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
return (DST_R_VERIFYFAILURE);
if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
- DST_RET (dst__openssl_toresult2("EVP_DigestFinal_ex",
+ DST_RET (dst__openssl_toresult3(dctx->category,
+ "EVP_DigestFinal_ex",
ISC_R_FAILURE));
ecdsasig = ECDSA_SIG_new();
if (ecdsasig == NULL)
DST_RET (ISC_R_NOMEMORY);
+ if (ecdsasig->r != NULL)
+ BN_free(ecdsasig->r);
ecdsasig->r = BN_bin2bn(cp, siglen / 2, NULL);
cp += siglen / 2;
+ if (ecdsasig->s != NULL)
+ BN_free(ecdsasig->s);
ecdsasig->s = BN_bin2bn(cp, siglen / 2, NULL);
/* cp += siglen / 2; */
@@ -216,7 +225,8 @@ opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
break;
default:
- ret = dst__openssl_toresult2("ECDSA_do_verify",
+ ret = dst__openssl_toresult3(dctx->category,
+ "ECDSA_do_verify",
DST_R_VERIFYFAILURE);
break;
}
diff --git a/lib/dns/opensslgost_link.c b/lib/dns/opensslgost_link.c
index 8a55a6b..098e312 100644
--- a/lib/dns/opensslgost_link.c
+++ b/lib/dns/opensslgost_link.c
@@ -127,7 +127,8 @@ opensslgost_verify(dst_context_t *dctx, const isc_region_t *sig) {
case 0:
return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
default:
- return (dst__openssl_toresult2("EVP_VerifyFinal",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_VerifyFinal",
DST_R_VERIFYFAILURE));
}
}
diff --git a/lib/dns/opensslrsa_link.c b/lib/dns/opensslrsa_link.c
index 80c3f57..2430f24 100644
--- a/lib/dns/opensslrsa_link.c
+++ b/lib/dns/opensslrsa_link.c
@@ -156,7 +156,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 (dst__openssl_toresult2("EVP_DigestInit_ex",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_DigestInit_ex",
ISC_R_FAILURE));
}
dctx->ctxdata.evp_md_ctx = evp_md_ctx;
@@ -305,7 +306,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 (dst__openssl_toresult2("EVP_DigestUpdate",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_DigestUpdate",
ISC_R_FAILURE));
}
#else
@@ -395,7 +397,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 (dst__openssl_toresult2("EVP_SignFinal",
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_SignFinal",
ISC_R_FAILURE));
}
#else
@@ -489,7 +492,8 @@ opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
#endif
if (status == 0)
- return (dst__openssl_toresult2("RSA_sign",
+ return (dst__openssl_toresult3(dctx->category,
+ "RSA_sign",
DST_R_OPENSSLFAILURE));
#endif
@@ -525,6 +529,16 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
#if USE_EVP
status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
+ switch (status) {
+ case 1:
+ return (ISC_R_SUCCESS);
+ case 0:
+ return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
+ default:
+ return (dst__openssl_toresult3(dctx->category,
+ "EVP_VerifyFinal",
+ DST_R_VERIFYFAILURE));
+ }
#else
switch (dctx->key->key_alg) {
case DST_ALG_RSAMD5:
@@ -610,7 +624,8 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
original, rsa,
RSA_PKCS1_PADDING);
if (status <= 0)
- return (dst__openssl_toresult2(
+ return (dst__openssl_toresult3(
+ dctx->category,
"RSA_public_decrypt",
DST_R_VERIFYFAILURE));
if (status != (int)(prefixlen + digestlen))
@@ -631,12 +646,10 @@ opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
status = RSA_verify(type, digest, digestlen, sig->base,
RSA_size(rsa), rsa);
#endif
-#endif
if (status != 1)
- return (dst__openssl_toresult2("RSA_verify",
- DST_R_VERIFYFAILURE));
-
+ return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
return (ISC_R_SUCCESS);
+#endif
}
static isc_boolean_t
diff --git a/lib/dns/peer.c b/lib/dns/peer.c
index c55d73d..ec9e08c 100644
--- a/lib/dns/peer.c
+++ b/lib/dns/peer.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-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
@@ -533,7 +533,7 @@ dns_peer_setkeybycharp(dns_peer_t *peer, const char *keyval) {
isc_result_t result;
dns_fixedname_init(&fname);
- isc_buffer_init(&b, keyval, strlen(keyval));
+ isc_buffer_constinit(&b, keyval, strlen(keyval));
isc_buffer_add(&b, strlen(keyval));
result = dns_name_fromtext(dns_fixedname_name(&fname), &b,
dns_rootname, 0, NULL);
diff --git a/lib/dns/rbt.c b/lib/dns/rbt.c
index 4e033d6..eb95d14 100644
--- a/lib/dns/rbt.c
+++ b/lib/dns/rbt.c
@@ -1537,6 +1537,8 @@ rehash(dns_rbt_t *rbt) {
return;
}
+ INSIST(rbt->hashsize > 0);
+
for (i = 0; i < rbt->hashsize; i++)
rbt->hashtable[i] = NULL;
@@ -1947,6 +1949,7 @@ dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) {
COLOR(sibling) = COLOR(parent);
MAKE_BLACK(parent);
+ INSIST(RIGHT(sibling) != NULL);
MAKE_BLACK(RIGHT(sibling));
rotate_left(parent, rootp);
child = *rootp;
@@ -1984,6 +1987,7 @@ dns_rbt_deletefromlevel(dns_rbtnode_t *delete, dns_rbtnode_t **rootp) {
COLOR(sibling) = COLOR(parent);
MAKE_BLACK(parent);
+ INSIST(LEFT(sibling) != NULL);
MAKE_BLACK(LEFT(sibling));
rotate_right(parent, rootp);
child = *rootp;
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index ef721b8..f6f96ab 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -1550,15 +1550,16 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node)
DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_CACHE,
ISC_LOG_WARNING,
- "delete_nsecnode(): "
+ "delete_node(): "
"dns_rbt_deletenode(nsecnode): %s",
isc_result_totext(result));
}
}
- result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
#ifdef BIND9
- dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name);
+ if (rbtdb->rpz_cidr != NULL)
+ dns_rpz_cidr_deleteip(rbtdb->rpz_cidr, name);
#endif
+ result = dns_rbt_deletenode(rbtdb->tree, node, ISC_FALSE);
break;
case DNS_RBT_NSEC_NSEC:
result = dns_rbt_deletenode(rbtdb->nsec, node, ISC_FALSE);
@@ -1572,7 +1573,7 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node)
DNS_LOGCATEGORY_DATABASE,
DNS_LOGMODULE_CACHE,
ISC_LOG_WARNING,
- "delete_nsecnode(): "
+ "delete_cnode(): "
"dns_rbt_deletenode: %s",
isc_result_totext(result));
}
@@ -4547,19 +4548,28 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
}
/*
- * Mark a database for response policy rewriting.
+ * Mark a database for response policy rewriting
+ * or find which RPZ data is available.
*/
#ifdef BIND9
-static void
-get_rpz_enabled(dns_db_t *db, dns_rpz_st_t *st)
-{
+static isc_result_t
+rpz_enabled(dns_db_t *db, dns_rpz_st_t *st) {
dns_rbtdb_t *rbtdb;
+ isc_result_t result;
+ result = ISC_R_SUCCESS;
rbtdb = (dns_rbtdb_t *)db;
REQUIRE(VALID_RBTDB(rbtdb));
RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
- dns_rpz_enabled(rbtdb->rpz_cidr, st);
+ if (st != NULL) {
+ dns_rpz_enabled_get(rbtdb->rpz_cidr, st);
+ } else {
+ result = dns_rpz_new_cidr(rbtdb->common.mctx,
+ &rbtdb->common.origin,
+ &rbtdb->rpz_cidr);
+ }
RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_read);
+ return (result);
}
/*
@@ -6224,6 +6234,7 @@ add(dns_rbtdb_t *rbtdb, dns_rbtnode_t *rbtnode, rbtdb_version_t *rbtversion,
* will do it on the LRU side, so memory
* will not leak... for long.
*/
+ INSIST(rbtdb->heaps != NULL);
isc_heap_insert(rbtdb->heaps[idx], newheader);
} else if (RESIGN(newheader))
resign_insert(rbtdb, idx, newheader);
@@ -6357,7 +6368,8 @@ addnoqname(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
cleanup:
dns_rdataset_disassociate(&neg);
dns_rdataset_disassociate(&negsig);
- free_noqname(mctx, &noqname);
+ if (noqname != NULL)
+ free_noqname(mctx, &noqname);
return(result);
}
@@ -6407,7 +6419,8 @@ addclosest(dns_rbtdb_t *rbtdb, rdatasetheader_t *newheader,
cleanup:
dns_rdataset_disassociate(&neg);
dns_rdataset_disassociate(&negsig);
- free_noqname(mctx, &closest);
+ if (closest != NULL)
+ free_noqname(mctx, &closest);
return(result);
}
@@ -6860,7 +6873,7 @@ loadnode(dns_rbtdb_t *rbtdb, dns_name_t *name, dns_rbtnode_t **nodep,
noderesult = dns_rbt_addnode(rbtdb->tree, name, nodep);
#ifdef BIND9
- if (noderesult == ISC_R_SUCCESS)
+ if (noderesult == ISC_R_SUCCESS && rbtdb->rpz_cidr != NULL)
dns_rpz_cidr_addip(rbtdb->rpz_cidr, name);
#endif
@@ -7447,8 +7460,8 @@ static dns_dbmethods_t zone_methods = {
isdnssec,
NULL,
#ifdef BIND9
- get_rpz_enabled,
- rpz_findips
+ rpz_enabled,
+ rpz_findips,
#else
NULL,
NULL
@@ -7681,24 +7694,6 @@ dns_rbtdb_create
return (result);
}
-#ifdef BIND9
- /*
- * Get ready for response policy IP address searching if at least one
- * zone has been configured as a response policy zone and this
- * is not a cache zone.
- * It would be better to know that this database is for a policy
- * zone named for a view, but that would require knowledge from
- * above such as an argv[] set from data in the zone.
- */
- if (type == dns_dbtype_zone && !dns_name_equal(origin, dns_rootname)) {
- result = dns_rpz_new_cidr(mctx, origin, &rbtdb->rpz_cidr);
- if (result != ISC_R_SUCCESS) {
- free_rbtdb(rbtdb, ISC_FALSE, NULL);
- return (result);
- }
- }
-#endif
-
/*
* In order to set the node callback bit correctly in zone databases,
* we need to know if the node has the origin name of the zone.
@@ -7977,7 +7972,9 @@ rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
dns_dbnode_t *cloned_node = NULL;
attachnode(db, node, &cloned_node);
+ INSIST(!ISC_LINK_LINKED(target, link));
*target = *source;
+ ISC_LINK_INIT(target, link);
/*
* Reset iterator state.
@@ -8929,12 +8926,10 @@ acache_callback(dns_acacheentry_t *entry, void **arg) {
if (acarray != NULL && acarray[count].entry == entry) {
acarray[count].entry = NULL;
INSIST(acarray[count].cbarg == cbarg);
- isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t));
acarray[count].cbarg = NULL;
- } else
isc_mem_put(rbtdb->common.mctx, cbarg, sizeof(acache_cbarg_t));
-
- dns_acache_detachentry(&entry);
+ dns_acache_detachentry(&entry);
+ }
NODE_UNLOCK(nodelock, isc_rwlocktype_write);
@@ -8958,9 +8953,10 @@ acache_cancelentry(isc_mem_t *mctx, dns_acacheentry_t *entry,
cbarg = *cbargp;
- dns_acache_cancelentry(entry);
- dns_db_detachnode(cbarg->db, &cbarg->node);
- dns_db_detach(&cbarg->db);
+ if (dns_acache_cancelentry(entry)) {
+ dns_db_detachnode(cbarg->db, &cbarg->node);
+ dns_db_detach(&cbarg->db);
+ }
isc_mem_put(mctx, cbarg, sizeof(acache_cbarg_t));
@@ -9027,6 +9023,7 @@ rdataset_setadditional(dns_rdataset_t *rdataset, dns_rdatasetadditional_t type,
acache_callback, newcbarg, &newentry);
if (result != ISC_R_SUCCESS)
goto fail;
+
/* Set cache data in the new entry. */
result = dns_acache_setentry(acache, newentry, zone, db,
version, node, fname);
diff --git a/lib/dns/rdata.c b/lib/dns/rdata.c
index 60890e0..3865f42 100644
--- a/lib/dns/rdata.c
+++ b/lib/dns/rdata.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,8 +15,6 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id$ */
-
/*! \file */
#include <config.h>
@@ -124,6 +122,15 @@ txt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
static isc_result_t
txt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
+static isc_result_t
+multitxt_totext(isc_region_t *source, isc_buffer_t *target);
+
+static isc_result_t
+multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target);
+
+static isc_result_t
+multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target);
+
static isc_boolean_t
name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target);
@@ -212,6 +219,70 @@ static isc_result_t
unknown_totext(dns_rdata_t *rdata, dns_rdata_textctx_t *tctx,
isc_buffer_t *target);
+/*% INT16 Size */
+#define NS_INT16SZ 2
+/*% IPv6 Address Size */
+#define NS_LOCATORSZ 8
+
+/*%
+ * convert presentation level address to network order binary form.
+ * \return
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * \note
+ * (1) does not touch `dst' unless it's returning 1.
+ */
+static inline int
+locator_pton(const char *src, unsigned char *dst) {
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[NS_LOCATORSZ];
+ unsigned char *tp = tmp, *endp;
+ const char *xdigits;
+ int ch, seen_xdigits;
+ unsigned int val;
+
+ memset(tp, '\0', NS_LOCATORSZ);
+ endp = tp + NS_LOCATORSZ;
+ seen_xdigits = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ pch = strchr((xdigits = xdigits_l), ch);
+ if (pch == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (++seen_xdigits > 4)
+ return (0);
+ continue;
+ }
+ if (ch == ':') {
+ if (!seen_xdigits)
+ return (0);
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ seen_xdigits = 0;
+ val = 0;
+ continue;
+ }
+ return (0);
+ }
+ if (seen_xdigits) {
+ if (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_LOCATORSZ);
+ return (1);
+}
+
static inline int
getquad(const void *src, struct in_addr *dst,
isc_lex_t *lexer, dns_rdatacallbacks_t *callbacks)
@@ -559,9 +630,9 @@ unknown_fromtext(dns_rdataclass_t rdclass, dns_rdatatype_t type,
if (type == 0 || dns_rdatatype_ismeta(type))
return (DNS_R_METATYPE);
- result = isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
- ISC_FALSE);
- if (result == ISC_R_SUCCESS && token.value.as_ulong > 65535U)
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 65535U)
return (ISC_R_RANGE);
result = isc_buffer_allocate(mctx, &buf, token.value.as_ulong);
if (result != ISC_R_SUCCESS)
@@ -611,6 +682,7 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
void (*callback)(dns_rdatacallbacks_t *, const char *, ...);
isc_result_t tresult;
size_t length;
+ isc_boolean_t unknown;
REQUIRE(origin == NULL || dns_name_isabsolute(origin) == ISC_TRUE);
if (rdata != NULL) {
@@ -638,13 +710,33 @@ dns_rdata_fromtext(dns_rdata_t *rdata, dns_rdataclass_t rdclass,
return (result);
}
- if (strcmp(DNS_AS_STR(token), "\\#") == 0)
- result = unknown_fromtext(rdclass, type, lexer, mctx, target);
- else {
+ unknown = ISC_FALSE;
+ if (token.type == isc_tokentype_string &&
+ strcmp(DNS_AS_STR(token), "\\#") == 0) {
+ /*
+ * If this is a TXT record '\#' could be a escaped '#'.
+ * Look to see if the next token is a number and if so
+ * treat it as a unknown record format.
+ */
+ if (type == dns_rdatatype_txt) {
+ result = isc_lex_getmastertoken(lexer, &token,
+ isc_tokentype_number,
+ ISC_FALSE);
+ if (result == ISC_R_SUCCESS)
+ isc_lex_ungettoken(lexer, &token);
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ unknown = ISC_TRUE;
+ result = unknown_fromtext(rdclass, type, lexer,
+ mctx, target);
+ } else
+ options |= DNS_RDATA_UNKNOWNESCAPE;
+ } else
isc_lex_ungettoken(lexer, &token);
+ if (!unknown)
FROMTEXTSWITCH
- }
/*
* Consume to end of line / file.
@@ -1174,6 +1266,157 @@ txt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
return (ISC_R_SUCCESS);
}
+static isc_result_t
+multitxt_totext(isc_region_t *source, isc_buffer_t *target) {
+ unsigned int tl;
+ unsigned int n0, n;
+ unsigned char *sp;
+ char *tp;
+ isc_region_t region;
+
+ isc_buffer_availableregion(target, &region);
+ sp = source->base;
+ tp = (char *)region.base;
+ tl = region.length;
+
+ if (tl < 1)
+ return (ISC_R_NOSPACE);
+ *tp++ = '"';
+ tl--;
+ do {
+ n0 = n = *sp++;
+
+ REQUIRE(n0 + 1 <= source->length);
+
+ while (n--) {
+ if (*sp < 0x20 || *sp >= 0x7f) {
+ if (tl < 4)
+ return (ISC_R_NOSPACE);
+ *tp++ = 0x5c;
+ *tp++ = 0x30 + ((*sp / 100) % 10);
+ *tp++ = 0x30 + ((*sp / 10) % 10);
+ *tp++ = 0x30 + (*sp % 10);
+ sp++;
+ tl -= 4;
+ continue;
+ }
+ /* double quote, semi-colon, backslash */
+ if (*sp == 0x22 || *sp == 0x3b || *sp == 0x5c) {
+ if (tl < 2)
+ return (ISC_R_NOSPACE);
+ *tp++ = '\\';
+ tl--;
+ }
+ if (tl < 1)
+ return (ISC_R_NOSPACE);
+ *tp++ = *sp++;
+ tl--;
+ }
+ isc_region_consume(source, n0 + 1);
+ } while (source->length != 0);
+ if (tl < 1)
+ return (ISC_R_NOSPACE);
+ *tp++ = '"';
+ tl--;
+ isc_buffer_add(target, tp - (char *)region.base);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+multitxt_fromtext(isc_textregion_t *source, isc_buffer_t *target) {
+ isc_region_t tregion;
+ isc_boolean_t escape;
+ unsigned int n, nrem;
+ char *s;
+ unsigned char *t0, *t;
+ int d;
+ int c;
+
+ s = source->base;
+ n = source->length;
+ escape = ISC_FALSE;
+
+ do {
+ isc_buffer_availableregion(target, &tregion);
+ t0 = tregion.base;
+ nrem = tregion.length;
+ if (nrem < 1)
+ return (ISC_R_NOSPACE);
+ /* length byte */
+ t = t0;
+ nrem--;
+ t++;
+ /* 255 byte character-string slice */
+ if (nrem > 255)
+ nrem = 255;
+ while (n != 0) {
+ --n;
+ c = (*s++) & 0xff;
+ if (escape && (d = decvalue((char)c)) != -1) {
+ c = d;
+ if (n == 0)
+ return (DNS_R_SYNTAX);
+ n--;
+ if ((d = decvalue(*s++)) != -1)
+ c = c * 10 + d;
+ else
+ return (DNS_R_SYNTAX);
+ if (n == 0)
+ return (DNS_R_SYNTAX);
+ n--;
+ if ((d = decvalue(*s++)) != -1)
+ c = c * 10 + d;
+ else
+ return (DNS_R_SYNTAX);
+ if (c > 255)
+ return (DNS_R_SYNTAX);
+ } else if (!escape && c == '\\') {
+ escape = ISC_TRUE;
+ continue;
+ }
+ escape = ISC_FALSE;
+ *t++ = c;
+ nrem--;
+ if (nrem == 0)
+ break;
+ }
+ if (escape)
+ return (DNS_R_SYNTAX);
+ *t0 = t - t0 - 1;
+ isc_buffer_add(target, *t0 + 1);
+ } while (n != 0);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+multitxt_fromwire(isc_buffer_t *source, isc_buffer_t *target) {
+ unsigned int n;
+ isc_region_t sregion;
+ isc_region_t tregion;
+
+ isc_buffer_activeregion(source, &sregion);
+ if (sregion.length == 0)
+ return(ISC_R_UNEXPECTEDEND);
+ n = 256U;
+ do {
+ if (n != 256U)
+ return (DNS_R_SYNTAX);
+ n = *sregion.base + 1;
+ if (n > sregion.length)
+ return (ISC_R_UNEXPECTEDEND);
+
+ isc_buffer_availableregion(target, &tregion);
+ if (n > tregion.length)
+ return (ISC_R_NOSPACE);
+
+ memcpy(tregion.base, sregion.base, n);
+ isc_buffer_forward(source, n);
+ isc_buffer_add(target, n);
+ isc_buffer_activeregion(source, &sregion);
+ } while (sregion.length != 0);
+ return (ISC_R_SUCCESS);
+}
+
static isc_boolean_t
name_prefix(dns_name_t *name, dns_name_t *origin, dns_name_t *target) {
int l1, l2;
diff --git a/lib/dns/rdata/any_255/tsig_250.c b/lib/dns/rdata/any_255/tsig_250.c
index 338c5dd..0046ed0 100644
--- a/lib/dns/rdata/any_255/tsig_250.c
+++ b/lib/dns/rdata/any_255/tsig_250.c
@@ -133,7 +133,7 @@ static inline isc_result_t
totext_any_tsig(ARGS_TOTEXT) {
isc_region_t sr;
isc_region_t sigr;
- char buf[sizeof("281474976710655 ")];
+ char buf[sizeof(" 281474976710655 ")];
char *bufp;
dns_name_t name;
dns_name_t prefix;
@@ -223,19 +223,14 @@ totext_any_tsig(ARGS_TOTEXT) {
*/
n = uint16_fromregion(&sr);
isc_region_consume(&sr, 2);
- if (dns_tsigrcode_totext((dns_rcode_t)n, target) == ISC_R_SUCCESS)
- RETERR(str_totext(" ", target));
- else {
- sprintf(buf, "%u ", n);
- RETERR(str_totext(buf, target));
- }
+ RETERR(dns_tsigrcode_totext((dns_rcode_t)n, target));
/*
* Other Size.
*/
n = uint16_fromregion(&sr);
isc_region_consume(&sr, 2);
- sprintf(buf, "%u ", n);
+ sprintf(buf, " %u ", n);
RETERR(str_totext(buf, target));
/*
diff --git a/lib/dns/rdata/generic/dlv_32769.c b/lib/dns/rdata/generic/dlv_32769.c
index 4dbcb1e..97f37f7 100644
--- a/lib/dns/rdata/generic/dlv_32769.c
+++ b/lib/dns/rdata/generic/dlv_32769.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2006, 2007, 2009, 2010, 2012, 2013 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
@@ -91,7 +91,7 @@ fromtext_dlv(ARGS_FROMTEXT) {
length = -1;
break;
}
- return (isc_hex_tobuffer(lexer, target, -1));
+ return (isc_hex_tobuffer(lexer, target, length));
}
static inline isc_result_t
diff --git a/lib/dns/rdata/generic/eui48_108.c b/lib/dns/rdata/generic/eui48_108.c
new file mode 100644
index 0000000..3e52fec
--- /dev/null
+++ b/lib/dns/rdata/generic/eui48_108.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef RDATA_GENERIC_EUI48_108_C
+#define RDATA_GENERIC_EUI48_108_C
+
+#include <string.h>
+
+#define RRTYPE_EUI48_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_eui48(ARGS_FROMTEXT) {
+ isc_token_t token;
+ unsigned char eui48[6];
+ unsigned int l0, l1, l2, l3, l4, l5;
+ int n;
+
+ REQUIRE(type == 108);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(options);
+ UNUSED(callbacks);
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x",
+ &l0, &l1, &l2, &l3, &l4, &l5);
+ if (n != 6 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U ||
+ l4 > 255U || l5 > 255U)
+ return (DNS_R_BADEUI);
+
+ eui48[0] = l0;
+ eui48[1] = l1;
+ eui48[2] = l2;
+ eui48[3] = l3;
+ eui48[4] = l4;
+ eui48[5] = l5;
+ return (mem_tobuffer(target, eui48, sizeof(eui48)));
+}
+
+static inline isc_result_t
+totext_eui48(ARGS_TOTEXT) {
+ char buf[sizeof("xx-xx-xx-xx-xx-xx")];
+
+ REQUIRE(rdata->type == 108);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(tctx);
+
+ (void)snprintf(buf, sizeof(buf), "%02x-%02x-%02x-%02x-%02x-%02x",
+ rdata->data[0], rdata->data[1], rdata->data[2],
+ rdata->data[3], rdata->data[4], rdata->data[5]);
+ return (str_totext(buf, target));
+}
+
+static inline isc_result_t
+fromwire_eui48(ARGS_FROMWIRE) {
+ isc_region_t sregion;
+
+ REQUIRE(type == 108);
+
+ UNUSED(type);
+ UNUSED(options);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+
+ isc_buffer_activeregion(source, &sregion);
+ if (sregion.length != 6)
+ return (DNS_R_FORMERR);
+ isc_buffer_forward(source, sregion.length);
+ return (mem_tobuffer(target, sregion.base, sregion.length));
+}
+
+static inline isc_result_t
+towire_eui48(ARGS_TOWIRE) {
+
+ REQUIRE(rdata->type == 108);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(cctx);
+
+ return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_eui48(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 108);
+ REQUIRE(rdata1->length == 6);
+ REQUIRE(rdata2->length == 6);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+ return (isc_region_compare(&region1, &region2));
+}
+
+static inline isc_result_t
+fromstruct_eui48(ARGS_FROMSTRUCT) {
+ dns_rdata_eui48_t *eui48 = source;
+
+ REQUIRE(type == 108);
+ REQUIRE(source != NULL);
+ REQUIRE(eui48->common.rdtype == type);
+ REQUIRE(eui48->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ return (mem_tobuffer(target, eui48->eui48, sizeof(eui48->eui48)));
+}
+
+static inline isc_result_t
+tostruct_eui48(ARGS_TOSTRUCT) {
+ dns_rdata_eui48_t *eui48 = target;
+
+ REQUIRE(rdata->type == 108);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(mctx);
+
+ eui48->common.rdclass = rdata->rdclass;
+ eui48->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&eui48->common, link);
+
+ memcpy(eui48->eui48, rdata->data, rdata->length);
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_eui48(ARGS_FREESTRUCT) {
+ dns_rdata_eui48_t *eui48 = source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(eui48->common.rdtype == 108);
+
+ return;
+}
+
+static inline isc_result_t
+additionaldata_eui48(ARGS_ADDLDATA) {
+
+ REQUIRE(rdata->type == 108);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_eui48(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 108);
+ REQUIRE(rdata->length == 6);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_eui48(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 108);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_eui48(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 108);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_eui48(ARGS_COMPARE) {
+ return (compare_eui48(rdata1, rdata2));
+}
+
+#endif /* RDATA_GENERIC_EUI48_108_C */
diff --git a/lib/dns/rdata/generic/eui48_108.h b/lib/dns/rdata/generic/eui48_108.h
new file mode 100644
index 0000000..508c61f
--- /dev/null
+++ b/lib/dns/rdata/generic/eui48_108.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* */
+#ifndef GENERIC_EUI48_108_H
+#define GENERIC_EUI48_108_H 1
+
+typedef struct dns_rdata_eui48 {
+ dns_rdatacommon_t common;
+ unsigned char eui48[6];
+} dns_rdata_eui48_t;
+
+#endif /* GENERIC_EUI48_10k_H */
diff --git a/lib/dns/rdata/generic/eui64_109.c b/lib/dns/rdata/generic/eui64_109.c
new file mode 100644
index 0000000..245994f
--- /dev/null
+++ b/lib/dns/rdata/generic/eui64_109.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef RDATA_GENERIC_EUI64_109_C
+#define RDATA_GENERIC_EUI64_109_C
+
+#include <string.h>
+
+#define RRTYPE_EUI64_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_eui64(ARGS_FROMTEXT) {
+ isc_token_t token;
+ unsigned char eui64[8];
+ unsigned int l0, l1, l2, l3, l4, l5, l6, l7;
+ int n;
+
+ REQUIRE(type == 109);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(options);
+ UNUSED(callbacks);
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+ n = sscanf(DNS_AS_STR(token), "%2x-%2x-%2x-%2x-%2x-%2x-%2x-%2x",
+ &l0, &l1, &l2, &l3, &l4, &l5, &l6, &l7);
+ if (n != 8 || l0 > 255U || l1 > 255U || l2 > 255U || l3 > 255U ||
+ l4 > 255U || l5 > 255U || l6 > 255U || l7 > 255U)
+ return (DNS_R_BADEUI);
+
+ eui64[0] = l0;
+ eui64[1] = l1;
+ eui64[2] = l2;
+ eui64[3] = l3;
+ eui64[4] = l4;
+ eui64[5] = l5;
+ eui64[6] = l6;
+ eui64[7] = l7;
+ return (mem_tobuffer(target, eui64, sizeof(eui64)));
+}
+
+static inline isc_result_t
+totext_eui64(ARGS_TOTEXT) {
+ char buf[sizeof("xx-xx-xx-xx-xx-xx-xx-xx")];
+
+ REQUIRE(rdata->type == 109);
+ REQUIRE(rdata->length == 8);
+
+ UNUSED(tctx);
+
+ (void)snprintf(buf, sizeof(buf),
+ "%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
+ rdata->data[0], rdata->data[1],
+ rdata->data[2], rdata->data[3],
+ rdata->data[4], rdata->data[5],
+ rdata->data[6], rdata->data[7]);
+ return (str_totext(buf, target));
+}
+
+static inline isc_result_t
+fromwire_eui64(ARGS_FROMWIRE) {
+ isc_region_t sregion;
+
+ REQUIRE(type == 109);
+
+ UNUSED(type);
+ UNUSED(options);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+
+ isc_buffer_activeregion(source, &sregion);
+ if (sregion.length != 8)
+ return (DNS_R_FORMERR);
+ isc_buffer_forward(source, sregion.length);
+ return (mem_tobuffer(target, sregion.base, sregion.length));
+}
+
+static inline isc_result_t
+towire_eui64(ARGS_TOWIRE) {
+
+ REQUIRE(rdata->type == 109);
+ REQUIRE(rdata->length == 8);
+
+ UNUSED(cctx);
+
+ return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_eui64(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 109);
+ REQUIRE(rdata1->length == 8);
+ REQUIRE(rdata2->length == 8);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+ return (isc_region_compare(&region1, &region2));
+}
+
+static inline isc_result_t
+fromstruct_eui64(ARGS_FROMSTRUCT) {
+ dns_rdata_eui64_t *eui64 = source;
+
+ REQUIRE(type == 109);
+ REQUIRE(source != NULL);
+ REQUIRE(eui64->common.rdtype == type);
+ REQUIRE(eui64->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ return (mem_tobuffer(target, eui64->eui64, sizeof(eui64->eui64)));
+}
+
+static inline isc_result_t
+tostruct_eui64(ARGS_TOSTRUCT) {
+ dns_rdata_eui64_t *eui64 = target;
+
+ REQUIRE(rdata->type == 109);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length == 8);
+
+ UNUSED(mctx);
+
+ eui64->common.rdclass = rdata->rdclass;
+ eui64->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&eui64->common, link);
+
+ memcpy(eui64->eui64, rdata->data, rdata->length);
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_eui64(ARGS_FREESTRUCT) {
+ dns_rdata_eui64_t *eui64 = source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(eui64->common.rdtype == 109);
+
+ return;
+}
+
+static inline isc_result_t
+additionaldata_eui64(ARGS_ADDLDATA) {
+
+ REQUIRE(rdata->type == 109);
+ REQUIRE(rdata->length == 8);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_eui64(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 109);
+ REQUIRE(rdata->length == 8);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_eui64(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 109);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_eui64(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 109);
+ REQUIRE(rdata->length == 8);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_eui64(ARGS_COMPARE) {
+ return (compare_eui64(rdata1, rdata2));
+}
+
+#endif /* RDATA_GENERIC_EUI64_109_C */
diff --git a/lib/dns/rdata/generic/eui64_109.h b/lib/dns/rdata/generic/eui64_109.h
new file mode 100644
index 0000000..56996f8
--- /dev/null
+++ b/lib/dns/rdata/generic/eui64_109.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* */
+#ifndef GENERIC_EUI64_109_H
+#define GENERIC_EUI64_109_H 1
+
+typedef struct dns_rdata_eui64 {
+ dns_rdatacommon_t common;
+ unsigned char eui64[8];
+} dns_rdata_eui64_t;
+
+#endif /* GENERIC_EUI64_10k_H */
diff --git a/lib/dns/rdata/generic/l32_105.c b/lib/dns/rdata/generic/l32_105.c
new file mode 100644
index 0000000..763ddb9
--- /dev/null
+++ b/lib/dns/rdata/generic/l32_105.c
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef RDATA_GENERIC_L32_105_C
+#define RDATA_GENERIC_L32_105_C
+
+#include <string.h>
+
+#include <isc/net.h>
+
+#define RRTYPE_L32_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_l32(ARGS_FROMTEXT) {
+ isc_token_t token;
+ struct in_addr addr;
+ isc_region_t region;
+
+ REQUIRE(type == 105);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(options);
+ UNUSED(callbacks);
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(token.value.as_ulong, target));
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+
+ if (getquad(DNS_AS_STR(token), &addr, lexer, callbacks) != 1)
+ RETTOK(DNS_R_BADDOTTEDQUAD);
+ isc_buffer_availableregion(target, &region);
+ if (region.length < 4)
+ return (ISC_R_NOSPACE);
+ memcpy(region.base, &addr, 4);
+ isc_buffer_add(target, 4);
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+totext_l32(ARGS_TOTEXT) {
+ isc_region_t region;
+ char buf[sizeof("65000")];
+ unsigned short num;
+
+ REQUIRE(rdata->type == 105);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(tctx);
+
+ dns_rdata_toregion(rdata, &region);
+ num = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+ sprintf(buf, "%u", num);
+ RETERR(str_totext(buf, target));
+
+ RETERR(str_totext(" ", target));
+
+ return (inet_totext(AF_INET, &region, target));
+}
+
+static inline isc_result_t
+fromwire_l32(ARGS_FROMWIRE) {
+ isc_region_t sregion;
+
+ REQUIRE(type == 105);
+
+ UNUSED(type);
+ UNUSED(options);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+
+ isc_buffer_activeregion(source, &sregion);
+ if (sregion.length != 6)
+ return (DNS_R_FORMERR);
+ isc_buffer_forward(source, sregion.length);
+ return (mem_tobuffer(target, sregion.base, sregion.length));
+}
+
+static inline isc_result_t
+towire_l32(ARGS_TOWIRE) {
+
+ REQUIRE(rdata->type == 105);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(cctx);
+
+ return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_l32(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 105);
+ REQUIRE(rdata1->length == 6);
+ REQUIRE(rdata2->length == 6);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+ return (isc_region_compare(&region1, &region2));
+}
+
+static inline isc_result_t
+fromstruct_l32(ARGS_FROMSTRUCT) {
+ dns_rdata_l32_t *l32 = source;
+ isc_uint32_t n;
+
+ REQUIRE(type == 105);
+ REQUIRE(source != NULL);
+ REQUIRE(l32->common.rdtype == type);
+ REQUIRE(l32->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ RETERR(uint16_tobuffer(l32->pref, target));
+ n = ntohl(l32->l32.s_addr);
+ return (uint32_tobuffer(n, target));
+}
+
+static inline isc_result_t
+tostruct_l32(ARGS_TOSTRUCT) {
+ isc_region_t region;
+ dns_rdata_l32_t *l32 = target;
+ isc_uint32_t n;
+
+ REQUIRE(rdata->type == 105);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(mctx);
+
+ l32->common.rdclass = rdata->rdclass;
+ l32->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&l32->common, link);
+
+ dns_rdata_toregion(rdata, &region);
+ l32->pref = uint16_fromregion(&region);
+ n = uint32_fromregion(&region);
+ l32->l32.s_addr = htonl(n);
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_l32(ARGS_FREESTRUCT) {
+ dns_rdata_l32_t *l32 = source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(l32->common.rdtype == 105);
+
+ return;
+}
+
+static inline isc_result_t
+additionaldata_l32(ARGS_ADDLDATA) {
+
+ REQUIRE(rdata->type == 105);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_l32(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 105);
+ REQUIRE(rdata->length == 6);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_l32(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 105);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_l32(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 105);
+ REQUIRE(rdata->length == 6);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_l32(ARGS_COMPARE) {
+ return (compare_l32(rdata1, rdata2));
+}
+
+#endif /* RDATA_GENERIC_L32_105_C */
diff --git a/lib/dns/rdata/generic/l32_105.h b/lib/dns/rdata/generic/l32_105.h
new file mode 100644
index 0000000..f95db22
--- /dev/null
+++ b/lib/dns/rdata/generic/l32_105.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* */
+#ifndef GENERIC_L32_105_H
+#define GENERIC_L32_105_H 1
+
+typedef struct dns_rdata_l32 {
+ dns_rdatacommon_t common;
+ isc_uint16_t pref;
+ struct in_addr l32;
+} dns_rdata_l32_t;
+
+#endif /* GENERIC_L32_105_H */
diff --git a/lib/dns/rdata/generic/l64_106.c b/lib/dns/rdata/generic/l64_106.c
new file mode 100644
index 0000000..ff20663
--- /dev/null
+++ b/lib/dns/rdata/generic/l64_106.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef RDATA_GENERIC_L64_106_C
+#define RDATA_GENERIC_L64_106_C
+
+#include <string.h>
+
+#include <isc/net.h>
+
+#define RRTYPE_L64_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_l64(ARGS_FROMTEXT) {
+ isc_token_t token;
+ unsigned char locator[NS_LOCATORSZ];
+
+ REQUIRE(type == 106);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(options);
+ UNUSED(callbacks);
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(token.value.as_ulong, target));
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+
+ if (locator_pton(DNS_AS_STR(token), locator) != 1)
+ RETTOK(DNS_R_SYNTAX);
+ return (mem_tobuffer(target, locator, NS_LOCATORSZ));
+}
+
+static inline isc_result_t
+totext_l64(ARGS_TOTEXT) {
+ isc_region_t region;
+ char buf[sizeof("xxxx:xxxx:xxxx:xxxx")];
+ unsigned short num;
+
+ REQUIRE(rdata->type == 106);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(tctx);
+
+ dns_rdata_toregion(rdata, &region);
+ num = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+ sprintf(buf, "%u", num);
+ RETERR(str_totext(buf, target));
+
+ RETERR(str_totext(" ", target));
+
+ sprintf(buf, "%x:%x:%x:%x",
+ region.base[0]<<8 | region.base[1],
+ region.base[2]<<8 | region.base[3],
+ region.base[4]<<8 | region.base[5],
+ region.base[6]<<8 | region.base[7]);
+ return (str_totext(buf, target));
+}
+
+static inline isc_result_t
+fromwire_l64(ARGS_FROMWIRE) {
+ isc_region_t sregion;
+
+ REQUIRE(type == 106);
+
+ UNUSED(type);
+ UNUSED(options);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+
+ isc_buffer_activeregion(source, &sregion);
+ if (sregion.length != 10)
+ return (DNS_R_FORMERR);
+ isc_buffer_forward(source, sregion.length);
+ return (mem_tobuffer(target, sregion.base, sregion.length));
+}
+
+static inline isc_result_t
+towire_l64(ARGS_TOWIRE) {
+
+ REQUIRE(rdata->type == 106);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(cctx);
+
+ return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_l64(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 106);
+ REQUIRE(rdata1->length == 10);
+ REQUIRE(rdata2->length == 10);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+ return (isc_region_compare(&region1, &region2));
+}
+
+static inline isc_result_t
+fromstruct_l64(ARGS_FROMSTRUCT) {
+ dns_rdata_l64_t *l64 = source;
+
+ REQUIRE(type == 106);
+ REQUIRE(source != NULL);
+ REQUIRE(l64->common.rdtype == type);
+ REQUIRE(l64->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ RETERR(uint16_tobuffer(l64->pref, target));
+ return (mem_tobuffer(target, l64->l64, sizeof(l64->l64)));
+}
+
+static inline isc_result_t
+tostruct_l64(ARGS_TOSTRUCT) {
+ isc_region_t region;
+ dns_rdata_l64_t *l64 = target;
+
+ REQUIRE(rdata->type == 106);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(mctx);
+
+ l64->common.rdclass = rdata->rdclass;
+ l64->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&l64->common, link);
+
+ dns_rdata_toregion(rdata, &region);
+ l64->pref = uint16_fromregion(&region);
+ memcpy(l64->l64, region.base, region.length);
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_l64(ARGS_FREESTRUCT) {
+ dns_rdata_l64_t *l64 = source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(l64->common.rdtype == 106);
+
+ return;
+}
+
+static inline isc_result_t
+additionaldata_l64(ARGS_ADDLDATA) {
+
+ REQUIRE(rdata->type == 106);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_l64(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 106);
+ REQUIRE(rdata->length == 10);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_l64(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 106);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_l64(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 106);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_l64(ARGS_COMPARE) {
+ return (compare_l64(rdata1, rdata2));
+}
+
+#endif /* RDATA_GENERIC_L64_106_C */
diff --git a/lib/dns/rdata/generic/l64_106.h b/lib/dns/rdata/generic/l64_106.h
new file mode 100644
index 0000000..8f93fc5
--- /dev/null
+++ b/lib/dns/rdata/generic/l64_106.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* */
+#ifndef GENERIC_L64_106_H
+#define GENERIC_L64_106_H 1
+
+typedef struct dns_rdata_l64 {
+ dns_rdatacommon_t common;
+ isc_uint16_t pref;
+ unsigned char l64[8];
+} dns_rdata_l64_t;
+
+#endif /* GENERIC_L64_106_H */
diff --git a/lib/dns/rdata/generic/lp_107.c b/lib/dns/rdata/generic/lp_107.c
new file mode 100644
index 0000000..732ef7f
--- /dev/null
+++ b/lib/dns/rdata/generic/lp_107.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef RDATA_GENERIC_LP_107_C
+#define RDATA_GENERIC_LP_107_C
+
+#include <string.h>
+
+#include <isc/net.h>
+
+#define RRTYPE_LP_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_lp(ARGS_FROMTEXT) {
+ isc_token_t token;
+ dns_name_t name;
+ isc_buffer_t buffer;
+
+ REQUIRE(type == 107);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(callbacks);
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(token.value.as_ulong, target));
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+
+ dns_name_init(&name, NULL);
+ buffer_fromregion(&buffer, &token.value.as_region);
+ origin = (origin != NULL) ? origin : dns_rootname;
+ return (dns_name_fromtext(&name, &buffer, origin, options, target));
+}
+
+static inline isc_result_t
+totext_lp(ARGS_TOTEXT) {
+ isc_region_t region;
+ dns_name_t name;
+ dns_name_t prefix;
+ isc_boolean_t sub;
+ char buf[sizeof("64000")];
+ unsigned short num;
+
+ REQUIRE(rdata->type == 107);
+ REQUIRE(rdata->length != 0);
+
+ dns_name_init(&name, NULL);
+ dns_name_init(&prefix, NULL);
+
+ dns_rdata_toregion(rdata, &region);
+ num = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+ sprintf(buf, "%u", num);
+ RETERR(str_totext(buf, target));
+
+ RETERR(str_totext(" ", target));
+
+ dns_name_fromregion(&name, &region);
+ sub = name_prefix(&name, tctx->origin, &prefix);
+ return (dns_name_totext(&prefix, sub, target));
+}
+
+static inline isc_result_t
+fromwire_lp(ARGS_FROMWIRE) {
+ dns_name_t name;
+ isc_region_t sregion;
+
+ REQUIRE(type == 107);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ dns_decompress_setmethods(dctx, DNS_COMPRESS_GLOBAL14);
+
+ dns_name_init(&name, NULL);
+
+ isc_buffer_activeregion(source, &sregion);
+ if (sregion.length < 2)
+ return (ISC_R_UNEXPECTEDEND);
+ RETERR(mem_tobuffer(target, sregion.base, 2));
+ isc_buffer_forward(source, 2);
+ return (dns_name_fromwire(&name, source, dctx, options, target));
+}
+
+static inline isc_result_t
+towire_lp(ARGS_TOWIRE) {
+
+ REQUIRE(rdata->type == 107);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(cctx);
+
+ return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_lp(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 107);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+
+ return (isc_region_compare(&region1, &region2));
+}
+
+static inline isc_result_t
+fromstruct_lp(ARGS_FROMSTRUCT) {
+ dns_rdata_lp_t *lp = source;
+ isc_region_t region;
+
+ REQUIRE(type == 107);
+ REQUIRE(source != NULL);
+ REQUIRE(lp->common.rdtype == type);
+ REQUIRE(lp->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ RETERR(uint16_tobuffer(lp->pref, target));
+ dns_name_toregion(&lp->lp, &region);
+ return (isc_buffer_copyregion(target, &region));
+}
+
+static inline isc_result_t
+tostruct_lp(ARGS_TOSTRUCT) {
+ isc_region_t region;
+ dns_rdata_lp_t *lp = target;
+ dns_name_t name;
+
+ REQUIRE(rdata->type == 107);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length != 0);
+
+ lp->common.rdclass = rdata->rdclass;
+ lp->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&lp->common, link);
+
+ dns_name_init(&name, NULL);
+ dns_rdata_toregion(rdata, &region);
+ lp->pref = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+ dns_name_fromregion(&name, &region);
+ dns_name_init(&lp->lp, NULL);
+ RETERR(name_duporclone(&name, mctx, &lp->lp));
+ lp->mctx = mctx;
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_lp(ARGS_FREESTRUCT) {
+ dns_rdata_lp_t *lp = source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(lp->common.rdtype == 107);
+
+ if (lp->mctx == NULL)
+ return;
+
+ dns_name_free(&lp->lp, lp->mctx);
+ lp->mctx = NULL;
+}
+
+static inline isc_result_t
+additionaldata_lp(ARGS_ADDLDATA) {
+ dns_name_t name;
+ dns_offsets_t offsets;
+ isc_region_t region;
+ isc_result_t result;
+
+ REQUIRE(rdata->type == 107);
+
+ dns_name_init(&name, offsets);
+ dns_rdata_toregion(rdata, &region);
+ isc_region_consume(&region, 2);
+ dns_name_fromregion(&name, &region);
+
+ result = (add)(arg, &name, dns_rdatatype_l32);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ return ((add)(arg, &name, dns_rdatatype_l64));
+}
+
+static inline isc_result_t
+digest_lp(ARGS_DIGEST) {
+ isc_region_t region;
+
+ REQUIRE(rdata->type == 107);
+
+ dns_rdata_toregion(rdata, &region);
+ return ((digest)(arg, &region));
+}
+
+static inline isc_boolean_t
+checkowner_lp(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 107);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(name);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_lp(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 107);
+
+ UNUSED(bad);
+ UNUSED(owner);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_lp(ARGS_COMPARE) {
+ dns_name_t name1;
+ dns_name_t name2;
+ isc_region_t region1;
+ isc_region_t region2;
+ int order;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 107);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ order = memcmp(rdata1->data, rdata2->data, 2);
+ if (order != 0)
+ return (order < 0 ? -1 : 1);
+
+ dns_name_init(&name1, NULL);
+ dns_name_init(&name2, NULL);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+
+ isc_region_consume(&region1, 2);
+ isc_region_consume(&region2, 2);
+
+ dns_name_fromregion(&name1, &region1);
+ dns_name_fromregion(&name2, &region2);
+
+ return (dns_name_rdatacompare(&name1, &name2));
+}
+
+#endif /* RDATA_GENERIC_LP_107_C */
diff --git a/lib/dns/rdata/generic/lp_107.h b/lib/dns/rdata/generic/lp_107.h
new file mode 100644
index 0000000..cbfee8a
--- /dev/null
+++ b/lib/dns/rdata/generic/lp_107.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* */
+#ifndef GENERIC_LP_107_H
+#define GENERIC_LP_107_H 1
+
+typedef struct dns_rdata_lp {
+ dns_rdatacommon_t common;
+ isc_mem_t *mctx;
+ isc_uint16_t pref;
+ dns_name_t lp;
+} dns_rdata_lp_t;
+
+#endif /* GENERIC_LP_107_H */
diff --git a/lib/dns/rdata/generic/mx_15.c b/lib/dns/rdata/generic/mx_15.c
index fd09e92..77eee15 100644
--- a/lib/dns/rdata/generic/mx_15.c
+++ b/lib/dns/rdata/generic/mx_15.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 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
@@ -57,7 +57,6 @@ fromtext_mx(ARGS_FROMTEXT) {
UNUSED(type);
UNUSED(rdclass);
- UNUSED(callbacks);
RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
ISC_FALSE));
diff --git a/lib/dns/rdata/generic/nid_104.c b/lib/dns/rdata/generic/nid_104.c
new file mode 100644
index 0000000..c96b0bf
--- /dev/null
+++ b/lib/dns/rdata/generic/nid_104.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef RDATA_GENERIC_NID_104_C
+#define RDATA_GENERIC_NID_104_C
+
+#include <string.h>
+
+#include <isc/net.h>
+
+#define RRTYPE_NID_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_nid(ARGS_FROMTEXT) {
+ isc_token_t token;
+ unsigned char locator[NS_LOCATORSZ];
+
+ REQUIRE(type == 104);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(options);
+ UNUSED(callbacks);
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(token.value.as_ulong, target));
+
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
+ ISC_FALSE));
+
+ if (locator_pton(DNS_AS_STR(token), locator) != 1)
+ RETTOK(DNS_R_SYNTAX);
+ return (mem_tobuffer(target, locator, NS_LOCATORSZ));
+}
+
+static inline isc_result_t
+totext_nid(ARGS_TOTEXT) {
+ isc_region_t region;
+ char buf[sizeof("xxxx:xxxx:xxxx:xxxx")];
+ unsigned short num;
+
+ REQUIRE(rdata->type == 104);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(tctx);
+
+ dns_rdata_toregion(rdata, &region);
+ num = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+ sprintf(buf, "%u", num);
+ RETERR(str_totext(buf, target));
+
+ RETERR(str_totext(" ", target));
+
+ sprintf(buf, "%x:%x:%x:%x",
+ region.base[0]<<8 | region.base[1],
+ region.base[2]<<8 | region.base[3],
+ region.base[4]<<8 | region.base[5],
+ region.base[6]<<8 | region.base[7]);
+ return (str_totext(buf, target));
+}
+
+static inline isc_result_t
+fromwire_nid(ARGS_FROMWIRE) {
+ isc_region_t sregion;
+
+ REQUIRE(type == 104);
+
+ UNUSED(type);
+ UNUSED(options);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+
+ isc_buffer_activeregion(source, &sregion);
+ if (sregion.length != 10)
+ return (DNS_R_FORMERR);
+ isc_buffer_forward(source, sregion.length);
+ return (mem_tobuffer(target, sregion.base, sregion.length));
+}
+
+static inline isc_result_t
+towire_nid(ARGS_TOWIRE) {
+
+ REQUIRE(rdata->type == 104);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(cctx);
+
+ return (mem_tobuffer(target, rdata->data, rdata->length));
+}
+
+static inline int
+compare_nid(ARGS_COMPARE) {
+ isc_region_t region1;
+ isc_region_t region2;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 104);
+ REQUIRE(rdata1->length == 10);
+ REQUIRE(rdata2->length == 10);
+
+ dns_rdata_toregion(rdata1, &region1);
+ dns_rdata_toregion(rdata2, &region2);
+ return (isc_region_compare(&region1, &region2));
+}
+
+static inline isc_result_t
+fromstruct_nid(ARGS_FROMSTRUCT) {
+ dns_rdata_nid_t *nid = source;
+
+ REQUIRE(type == 104);
+ REQUIRE(source != NULL);
+ REQUIRE(nid->common.rdtype == type);
+ REQUIRE(nid->common.rdclass == rdclass);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ RETERR(uint16_tobuffer(nid->pref, target));
+ return (mem_tobuffer(target, nid->nid, sizeof(nid->nid)));
+}
+
+static inline isc_result_t
+tostruct_nid(ARGS_TOSTRUCT) {
+ isc_region_t region;
+ dns_rdata_nid_t *nid = target;
+
+ REQUIRE(rdata->type == 104);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(mctx);
+
+ nid->common.rdclass = rdata->rdclass;
+ nid->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&nid->common, link);
+
+ dns_rdata_toregion(rdata, &region);
+ nid->pref = uint16_fromregion(&region);
+ memcpy(nid->nid, region.base, region.length);
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_nid(ARGS_FREESTRUCT) {
+ dns_rdata_nid_t *nid = source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(nid->common.rdtype == 104);
+
+ return;
+}
+
+static inline isc_result_t
+additionaldata_nid(ARGS_ADDLDATA) {
+
+ REQUIRE(rdata->type == 104);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_nid(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 104);
+ REQUIRE(rdata->length == 10);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_nid(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 104);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_nid(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 104);
+ REQUIRE(rdata->length == 10);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_nid(ARGS_COMPARE) {
+ return (compare_nid(rdata1, rdata2));
+}
+
+#endif /* RDATA_GENERIC_NID_104_C */
diff --git a/lib/dns/rdata/generic/nid_104.h b/lib/dns/rdata/generic/nid_104.h
new file mode 100644
index 0000000..64a3ba4
--- /dev/null
+++ b/lib/dns/rdata/generic/nid_104.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* */
+#ifndef GENERIC_NID_104_H
+#define GENERIC_NID_104_H 1
+
+typedef struct dns_rdata_nid {
+ dns_rdatacommon_t common;
+ isc_uint16_t pref;
+ unsigned char nid[8];
+} dns_rdata_nid_t;
+
+#endif /* GENERIC_NID_104_H */
diff --git a/lib/dns/rdata/generic/sshfp_44.c b/lib/dns/rdata/generic/sshfp_44.c
index c94c75c..03d5127 100644
--- a/lib/dns/rdata/generic/sshfp_44.c
+++ b/lib/dns/rdata/generic/sshfp_44.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007, 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2006, 2007, 2009, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -53,7 +53,6 @@ fromtext_sshfp(ARGS_FROMTEXT) {
if (token.value.as_ulong > 0xffU)
RETTOK(ISC_R_RANGE);
RETERR(uint8_tobuffer(token.value.as_ulong, target));
- type = (isc_uint16_t) token.value.as_ulong;
/*
* Digest.
diff --git a/lib/dns/rdata/generic/txt_16.c b/lib/dns/rdata/generic/txt_16.c
index c49864e..e1bce6a 100644
--- a/lib/dns/rdata/generic/txt_16.c
+++ b/lib/dns/rdata/generic/txt_16.c
@@ -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) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -38,6 +38,13 @@ fromtext_txt(ARGS_FROMTEXT) {
UNUSED(callbacks);
strings = 0;
+ if ((options & DNS_RDATA_UNKNOWNESCAPE) != 0) {
+ isc_textregion_t r;
+ DE_CONST("#", r.base);
+ r.length = 1;
+ RETERR(txt_fromtext(&r, target));
+ strings++;
+ }
for (;;) {
RETERR(isc_lex_getmastertoken(lexer, &token,
isc_tokentype_qstring,
diff --git a/lib/dns/rdata/generic/uri_256.c b/lib/dns/rdata/generic/uri_256.c
new file mode 100644
index 0000000..aa5b194
--- /dev/null
+++ b/lib/dns/rdata/generic/uri_256.c
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2011-2013 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: uri_256.c,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */
+
+#ifndef GENERIC_URI_256_C
+#define GENERIC_URI_256_C 1
+
+#define RRTYPE_URI_ATTRIBUTES (0)
+
+static inline isc_result_t
+fromtext_uri(ARGS_FROMTEXT) {
+ isc_token_t token;
+
+ REQUIRE(type == 256);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(origin);
+ UNUSED(options);
+ UNUSED(callbacks);
+
+ /*
+ * Priority
+ */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(token.value.as_ulong, target));
+
+ /*
+ * Weight
+ */
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ ISC_FALSE));
+ if (token.value.as_ulong > 0xffffU)
+ RETTOK(ISC_R_RANGE);
+ RETERR(uint16_tobuffer(token.value.as_ulong, target));
+
+ /*
+ * Target URI
+ */
+ RETERR(isc_lex_getmastertoken(lexer, &token,
+ isc_tokentype_qstring, ISC_FALSE));
+ if (token.type != isc_tokentype_qstring)
+ RETTOK(DNS_R_SYNTAX);
+ RETTOK(multitxt_fromtext(&token.value.as_textregion, target));
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+totext_uri(ARGS_TOTEXT) {
+ isc_region_t region;
+ unsigned short priority, weight;
+ char buf[sizeof("65000 ")];
+
+ UNUSED(tctx);
+
+ REQUIRE(rdata->type == 256);
+ REQUIRE(rdata->length != 0);
+
+ dns_rdata_toregion(rdata, &region);
+
+ /*
+ * Priority
+ */
+ priority = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+ sprintf(buf, "%u ", priority);
+ RETERR(str_totext(buf, target));
+
+ /*
+ * Weight
+ */
+ weight = uint16_fromregion(&region);
+ isc_region_consume(&region, 2);
+ sprintf(buf, "%u ", weight);
+ RETERR(str_totext(buf, target));
+
+ /*
+ * Target URI
+ */
+ RETERR(multitxt_totext(&region, target));
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+fromwire_uri(ARGS_FROMWIRE) {
+ isc_region_t region;
+
+ REQUIRE(type == 256);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(dctx);
+ UNUSED(options);
+
+ /*
+ * Priority, weight
+ */
+ isc_buffer_activeregion(source, &region);
+ if (region.length < 4)
+ return (ISC_R_UNEXPECTEDEND);
+ RETERR(mem_tobuffer(target, region.base, 4));
+ isc_buffer_forward(source, 4);
+
+ /*
+ * Target URI
+ */
+ RETERR(multitxt_fromwire(source, target));
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+towire_uri(ARGS_TOWIRE) {
+ isc_region_t region;
+
+ REQUIRE(rdata->type == 256);
+ REQUIRE(rdata->length != 0);
+
+ UNUSED(cctx);
+
+ dns_rdata_toregion(rdata, &region);
+ return (mem_tobuffer(target, region.base, region.length));
+}
+
+static inline int
+compare_uri(ARGS_COMPARE) {
+ isc_region_t r1;
+ isc_region_t r2;
+ int order;
+
+ REQUIRE(rdata1->type == rdata2->type);
+ REQUIRE(rdata1->rdclass == rdata2->rdclass);
+ REQUIRE(rdata1->type == 256);
+ REQUIRE(rdata1->length != 0);
+ REQUIRE(rdata2->length != 0);
+
+ dns_rdata_toregion(rdata1, &r1);
+ dns_rdata_toregion(rdata2, &r2);
+
+ /*
+ * Priority
+ */
+ order = memcmp(r1.base, r2.base, 2);
+ if (order != 0)
+ return (order < 0 ? -1 : 1);
+ isc_region_consume(&r1, 2);
+ isc_region_consume(&r2, 2);
+
+ /*
+ * Weight
+ */
+ order = memcmp(r1.base, r2.base, 2);
+ if (order != 0)
+ return (order < 0 ? -1 : 1);
+ isc_region_consume(&r1, 2);
+ isc_region_consume(&r2, 2);
+
+ return (isc_region_compare(&r1, &r2));
+}
+
+static inline isc_result_t
+fromstruct_uri(ARGS_FROMSTRUCT) {
+ dns_rdata_uri_t *uri = source;
+ isc_region_t region;
+ isc_uint8_t len;
+
+ REQUIRE(type == 256);
+ REQUIRE(source != NULL);
+ REQUIRE(uri->common.rdtype == type);
+ REQUIRE(uri->common.rdclass == rdclass);
+ REQUIRE(uri->target != NULL && uri->tgt_len != 0);
+
+ UNUSED(type);
+ UNUSED(rdclass);
+
+ /*
+ * Priority
+ */
+ RETERR(uint16_tobuffer(uri->priority, target));
+
+ /*
+ * Weight
+ */
+ RETERR(uint16_tobuffer(uri->weight, target));
+
+ /*
+ * Target URI
+ */
+ len = 255U;
+ region.base = uri->target;
+ region.length = uri->tgt_len;
+ while (region.length > 0) {
+ REQUIRE(len == 255U);
+ len = uint8_fromregion(&region);
+ isc_region_consume(&region, 1);
+ if (region.length < len)
+ return (ISC_R_UNEXPECTEDEND);
+ isc_region_consume(&region, len);
+ }
+
+ return (mem_tobuffer(target, uri->target, uri->tgt_len));
+}
+
+static inline isc_result_t
+tostruct_uri(ARGS_TOSTRUCT) {
+ dns_rdata_uri_t *uri = target;
+ isc_region_t sr;
+
+ REQUIRE(rdata->type == 256);
+ REQUIRE(target != NULL);
+ REQUIRE(rdata->length != 0);
+
+ uri->common.rdclass = rdata->rdclass;
+ uri->common.rdtype = rdata->type;
+ ISC_LINK_INIT(&uri->common, link);
+
+ dns_rdata_toregion(rdata, &sr);
+
+ /*
+ * Priority
+ */
+ if (sr.length < 2)
+ return (ISC_R_UNEXPECTEDEND);
+ uri->priority = uint16_fromregion(&sr);
+ isc_region_consume(&sr, 2);
+
+ /*
+ * Weight
+ */
+ if (sr.length < 2)
+ return (ISC_R_UNEXPECTEDEND);
+ uri->weight = uint16_fromregion(&sr);
+ isc_region_consume(&sr, 2);
+
+ /*
+ * Target URI
+ */
+ uri->tgt_len = sr.length;
+ uri->target = mem_maybedup(mctx, sr.base, sr.length);
+ if (uri->target == NULL)
+ return (ISC_R_NOMEMORY);
+
+ uri->mctx = mctx;
+ return (ISC_R_SUCCESS);
+}
+
+static inline void
+freestruct_uri(ARGS_FREESTRUCT) {
+ dns_rdata_uri_t *uri = (dns_rdata_uri_t *) source;
+
+ REQUIRE(source != NULL);
+ REQUIRE(uri->common.rdtype == 256);
+
+ if (uri->mctx == NULL)
+ return;
+
+ if (uri->target != NULL)
+ isc_mem_free(uri->mctx, uri->target);
+ uri->mctx = NULL;
+}
+
+static inline isc_result_t
+additionaldata_uri(ARGS_ADDLDATA) {
+ REQUIRE(rdata->type == 256);
+
+ UNUSED(rdata);
+ UNUSED(add);
+ UNUSED(arg);
+
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+digest_uri(ARGS_DIGEST) {
+ isc_region_t r;
+
+ REQUIRE(rdata->type == 256);
+
+ dns_rdata_toregion(rdata, &r);
+
+ return ((digest)(arg, &r));
+}
+
+static inline isc_boolean_t
+checkowner_uri(ARGS_CHECKOWNER) {
+
+ REQUIRE(type == 256);
+
+ UNUSED(name);
+ UNUSED(type);
+ UNUSED(rdclass);
+ UNUSED(wildcard);
+
+ return (ISC_TRUE);
+}
+
+static inline isc_boolean_t
+checknames_uri(ARGS_CHECKNAMES) {
+
+ REQUIRE(rdata->type == 256);
+
+ UNUSED(rdata);
+ UNUSED(owner);
+ UNUSED(bad);
+
+ return (ISC_TRUE);
+}
+
+static inline int
+casecompare_uri(ARGS_COMPARE) {
+ return (compare_uri(rdata1, rdata2));
+}
+
+#endif /* GENERIC_URI_256_C */
diff --git a/lib/dns/rdata/generic/uri_256.h b/lib/dns/rdata/generic/uri_256.h
new file mode 100644
index 0000000..5061c03
--- /dev/null
+++ b/lib/dns/rdata/generic/uri_256.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011-2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef GENERIC_URI_256_H
+#define GENERIC_URI_256_H 1
+
+/* $Id: uri_256.h,v 1.2 2011/03/03 14:10:27 fdupont Exp $ */
+
+typedef struct dns_rdata_uri {
+ dns_rdatacommon_t common;
+ isc_mem_t * mctx;
+ isc_uint16_t priority;
+ isc_uint16_t weight;
+ unsigned char * target;
+ isc_uint16_t tgt_len;
+} dns_rdata_uri_t;
+
+#endif /* GENERIC_URI_256_H */
diff --git a/lib/dns/rdata/in_1/naptr_35.c b/lib/dns/rdata/in_1/naptr_35.c
index 71ba31e..e5df80b 100644
--- a/lib/dns/rdata/in_1/naptr_35.c
+++ b/lib/dns/rdata/in_1/naptr_35.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2009, 2012, 2013 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
@@ -25,9 +25,8 @@
#define RDATA_IN_1_NAPTR_35_C
#define RRTYPE_NAPTR_ATTRIBUTES (0)
-#ifdef HAVE_REGEX_H
-#include <regex.h>
-#endif
+
+#include <isc/regex.h>
/*
* Check the wire format of the Regexp field.
@@ -35,18 +34,15 @@
*/
static inline isc_result_t
txt_valid_regex(const unsigned char *txt) {
-#ifdef HAVE_REGEX_H
- regex_t preg;
- unsigned int regflags = REG_EXTENDED;
unsigned int nsub = 0;
char regex[256];
char *cp;
-#endif
isc_boolean_t flags = ISC_FALSE;
isc_boolean_t replace = ISC_FALSE;
unsigned char c;
unsigned char delim;
unsigned int len;
+ int n;
len = *txt++;
if (len == 0U)
@@ -65,11 +61,7 @@ txt_valid_regex(const unsigned char *txt) {
return (DNS_R_SYNTAX);
}
-#ifdef HAVE_REGEX_H
- memset(&preg, 0, sizeof(preg));
cp = regex;
-#endif
-
while (len-- > 0) {
c = *txt++;
if (c == 0)
@@ -88,18 +80,13 @@ txt_valid_regex(const unsigned char *txt) {
if (flags) {
switch (c) {
case 'i':
-#ifdef HAVE_REGEX_H
- regflags |= REG_ICASE;
-#endif
continue;
default:
return (DNS_R_SYNTAX);
}
}
-#ifdef HAVE_REGEX_H
if (!replace)
*cp++ = c;
-#endif
if (c == '\\') {
if (len == 0)
return (DNS_R_SYNTAX);
@@ -110,7 +97,6 @@ txt_valid_regex(const unsigned char *txt) {
if (replace)
switch (c) {
case '0': return (DNS_R_SYNTAX);
-#ifdef HAVE_REGEX_H
case '1': if (nsub < 1) nsub = 1; break;
case '2': if (nsub < 2) nsub = 2; break;
case '3': if (nsub < 3) nsub = 3; break;
@@ -120,30 +106,17 @@ txt_valid_regex(const unsigned char *txt) {
case '7': if (nsub < 7) nsub = 7; break;
case '8': if (nsub < 8) nsub = 8; break;
case '9': if (nsub < 9) nsub = 9; break;
-#endif
}
-#ifdef HAVE_REGEX_H
if (!replace)
*cp++ = c;
-#endif
}
}
if (!flags)
return (DNS_R_SYNTAX);
-#ifdef HAVE_REGEX_H
*cp = '\0';
- if (regcomp(&preg, regex, regflags))
- return (DNS_R_SYNTAX);
- /*
- * Check that substitutions in the replacement string are consistant
- * with the regular expression.
- */
- if (preg.re_nsub < nsub) {
- regfree(&preg);
+ n = isc_regex_validate(regex);
+ if (n < 0 || nsub > (unsigned int)n)
return (DNS_R_SYNTAX);
- }
- regfree(&preg);
-#endif
return (ISC_R_SUCCESS);
}
diff --git a/lib/dns/rdata/in_1/nsap_22.c b/lib/dns/rdata/in_1/nsap_22.c
index d762fe1..66129fe 100644
--- a/lib/dns/rdata/in_1/nsap_22.c
+++ b/lib/dns/rdata/in_1/nsap_22.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -53,7 +53,6 @@ fromtext_in_nsap(ARGS_FROMTEXT) {
RETTOK(DNS_R_SYNTAX);
isc_textregion_consume(sr, 2);
digits = 0;
- n = 0;
while (sr->length > 0) {
if (sr->base[0] == '.') {
isc_textregion_consume(sr, 1);
diff --git a/lib/dns/request.c b/lib/dns/request.c
index 58c0103..1316e69 100644
--- a/lib/dns/request.c
+++ b/lib/dns/request.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -894,13 +894,15 @@ dns_request_createvia3(dns_requestmgr_t *requestmgr, dns_message_t *message,
REQUIRE(action != NULL);
REQUIRE(requestp != NULL && *requestp == NULL);
REQUIRE(timeout > 0);
- if (srcaddr != NULL)
- REQUIRE(isc_sockaddr_pf(srcaddr) == isc_sockaddr_pf(destaddr));
mctx = requestmgr->mctx;
req_log(ISC_LOG_DEBUG(3), "dns_request_createvia");
+ if (srcaddr != NULL &&
+ isc_sockaddr_pf(srcaddr) != isc_sockaddr_pf(destaddr))
+ return (ISC_R_FAMILYMISMATCH);
+
if (isblackholed(requestmgr->dispatchmgr, destaddr))
return (DNS_R_BLACKHOLED);
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 503f1d2..e21d97e 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -21,6 +21,7 @@
#include <config.h>
+#include <isc/log.h>
#include <isc/platform.h>
#include <isc/print.h>
#include <isc/string.h>
@@ -42,6 +43,8 @@
#include <dns/log.h>
#include <dns/message.h>
#include <dns/ncache.h>
+#include <dns/nsec.h>
+#include <dns/nsec3.h>
#include <dns/opcode.h>
#include <dns/peer.h>
#include <dns/rbt.h>
@@ -75,7 +78,7 @@
DNS_LOGCATEGORY_RESOLVER, \
DNS_LOGMODULE_RESOLVER, \
ISC_LOG_DEBUG(3), \
- "fctx %p(%s'): %s", fctx, fctx->info, (m))
+ "fctx %p(%s): %s", fctx, fctx->info, (m))
#define FCTXTRACE2(m1, m2) \
isc_log_write(dns_lctx, \
DNS_LOGCATEGORY_RESOLVER, \
@@ -130,6 +133,7 @@
* Maximum EDNS0 input packet size.
*/
#define RECV_BUFFER_SIZE 4096 /* XXXRTH Constant. */
+#define EDNSOPTS 2
/*%
* This defines the maximum number of timeouts we will permit before we
@@ -468,12 +472,16 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
dns_rdatatype_t covers,
isc_stdtime_t now, dns_ttl_t maxttl,
isc_boolean_t optout,
+ isc_boolean_t secure,
dns_rdataset_t *ardataset,
isc_result_t *eresultp);
static void validated(isc_task_t *task, isc_event_t *event);
static isc_boolean_t maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
isc_result_t reason, badnstype_t badtype);
+static inline isc_result_t findnoqname(fetchctx_t *fctx, dns_name_t *name,
+ dns_rdatatype_t type,
+ dns_name_t **noqname);
/*%
* Increment resolver-related statistics counters.
@@ -1270,67 +1278,15 @@ resquery_senddone(isc_task_t *task, isc_event_t *event) {
static inline isc_result_t
fctx_addopt(dns_message_t *message, unsigned int version,
- isc_uint16_t udpsize, isc_boolean_t request_nsid)
+ isc_uint16_t udpsize, dns_ednsopt_t *ednsopts, size_t count)
{
- dns_rdataset_t *rdataset;
- dns_rdatalist_t *rdatalist;
- dns_rdata_t *rdata;
+ dns_rdataset_t *rdataset = NULL;
isc_result_t result;
- rdatalist = NULL;
- result = dns_message_gettemprdatalist(message, &rdatalist);
- if (result != ISC_R_SUCCESS)
- return (result);
- rdata = NULL;
- result = dns_message_gettemprdata(message, &rdata);
- if (result != ISC_R_SUCCESS)
- return (result);
- rdataset = NULL;
- result = dns_message_gettemprdataset(message, &rdataset);
+ result = dns_message_buildopt(message, &rdataset, version, udpsize,
+ DNS_MESSAGEEXTFLAG_DO, ednsopts, count);
if (result != ISC_R_SUCCESS)
return (result);
- dns_rdataset_init(rdataset);
-
- rdatalist->type = dns_rdatatype_opt;
- rdatalist->covers = 0;
-
- /*
- * Set Maximum UDP buffer size.
- */
- rdatalist->rdclass = udpsize;
-
- /*
- * Set EXTENDED-RCODE and Z to 0, DO to 1.
- */
- rdatalist->ttl = (version << 16);
- rdatalist->ttl |= DNS_MESSAGEEXTFLAG_DO;
-
- /*
- * Set EDNS options if applicable
- */
- if (request_nsid) {
- /* Send empty NSID option (RFC5001) */
- unsigned char data[4];
- isc_buffer_t buf;
-
- isc_buffer_init(&buf, data, sizeof(data));
- isc_buffer_putuint16(&buf, DNS_OPT_NSID);
- isc_buffer_putuint16(&buf, 0);
- rdata->data = data;
- rdata->length = sizeof(data);
- } else {
- rdata->data = NULL;
- rdata->length = 0;
- }
-
- rdata->rdclass = rdatalist->rdclass;
- rdata->type = rdatalist->type;
- rdata->flags = 0;
-
- ISC_LIST_INIT(rdatalist->rdata);
- ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
- RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset) == ISC_R_SUCCESS);
-
return (dns_message_setopt(message, rdataset));
}
@@ -1710,6 +1666,8 @@ resquery_send(resquery_t *query) {
isc_boolean_t cleanup_cctx = ISC_FALSE;
isc_boolean_t secure_domain;
isc_boolean_t connecting = ISC_FALSE;
+ dns_ednsopt_t ednsopts[EDNSOPTS];
+ unsigned ednsopt = 0;
fctx = query->fctx;
QTRACE("send");
@@ -1892,8 +1850,15 @@ resquery_send(resquery_t *query) {
/* request NSID for current view or peer? */
if (peer != NULL)
(void) dns_peer_getrequestnsid(peer, &reqnsid);
+ if (reqnsid) {
+ INSIST(ednsopt < EDNSOPTS);
+ ednsopts[ednsopt].code = DNS_OPT_NSID;
+ ednsopts[ednsopt].length = 0;
+ ednsopts[ednsopt].value = NULL;
+ ednsopt++;
+ }
result = fctx_addopt(fctx->qmessage, version,
- udpsize, reqnsid);
+ udpsize, ednsopts, ednsopt);
if (reqnsid && result == ISC_R_SUCCESS) {
query->options |= DNS_FETCHOPT_WANTNSID;
} else if (result != ISC_R_SUCCESS) {
@@ -2478,7 +2443,7 @@ findname(fetchctx_t *fctx, dns_name_t *name, in_port_t port,
isc_result_t result;
res = fctx->res;
- unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);
+ unshared = ISC_TF((fctx->options & DNS_FETCHOPT_UNSHARED) != 0);
/*
* If this name is a subdomain of the query domain, tell
* the ADB to start looking using zone/hint data. This keeps us
@@ -4227,7 +4192,7 @@ validated(isc_task_t *task, isc_event_t *event) {
result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
covers, now, ttl, vevent->optout,
- ardataset, &eresult);
+ vevent->secure, ardataset, &eresult);
if (result != ISC_R_SUCCESS)
goto noanswer_response;
goto answer_response;
@@ -4237,7 +4202,6 @@ validated(isc_task_t *task, isc_event_t *event) {
FCTXTRACE("validation OK");
if (vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF] != NULL) {
-
result = dns_rdataset_addnoqname(vevent->rdataset,
vevent->proofs[DNS_VALIDATOR_NOQNAMEPROOF]);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
@@ -4248,6 +4212,18 @@ validated(isc_task_t *task, isc_event_t *event) {
vevent->proofs[DNS_VALIDATOR_CLOSESTENCLOSER]);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
+ } else if (vevent->rdataset->trust == dns_trust_answer &&
+ vevent->rdataset->type != dns_rdatatype_rrsig)
+ {
+ isc_result_t tresult;
+ dns_name_t *noqname = NULL;
+ tresult = findnoqname(fctx, vevent->name,
+ vevent->rdataset->type, &noqname);
+ if (tresult == ISC_R_SUCCESS && noqname != NULL) {
+ tresult = dns_rdataset_addnoqname(vevent->rdataset,
+ noqname);
+ RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
+ }
}
/*
@@ -4367,6 +4343,14 @@ validated(isc_task_t *task, isc_event_t *event) {
fctx->attributes |= FCTX_ATTR_HAVEANSWER;
if (hevent != NULL) {
+ /*
+ * Negative results must be indicated in event->result.
+ */
+ if (dns_rdataset_isassociated(hevent->rdataset) &&
+ NEGATIVE(hevent->rdataset)) {
+ INSIST(eresult == DNS_R_NCACHENXDOMAIN ||
+ eresult == DNS_R_NCACHENXRRSET);
+ }
hevent->result = eresult;
RUNTIME_CHECK(dns_name_copy(vevent->name,
dns_fixedname_name(&hevent->foundname), NULL)
@@ -4388,6 +4372,149 @@ validated(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
}
+static void
+fctx_log(void *arg, int level, const char *fmt, ...) {
+ char msgbuf[2048];
+ va_list args;
+ fetchctx_t *fctx = arg;
+
+ va_start(args, fmt);
+ vsnprintf(msgbuf, sizeof(msgbuf), fmt, args);
+ va_end(args);
+
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, level,
+ "fctx %p(%s): %s", fctx, fctx->info, msgbuf);
+}
+
+static inline isc_result_t
+findnoqname(fetchctx_t *fctx, dns_name_t *name, dns_rdatatype_t type,
+ dns_name_t **noqnamep)
+{
+ dns_rdataset_t *nrdataset, *next, *sigrdataset;
+ dns_rdata_rrsig_t rrsig;
+ isc_result_t result;
+ unsigned int labels;
+ dns_section_t section;
+ dns_name_t *zonename;
+ dns_fixedname_t fzonename;
+ dns_name_t *closest;
+ dns_fixedname_t fclosest;
+ dns_name_t *nearest;
+ dns_fixedname_t fnearest;
+ dns_rdatatype_t found = dns_rdatatype_none;
+ dns_name_t *noqname = NULL;
+
+ FCTXTRACE("findnoqname");
+
+ REQUIRE(noqnamep != NULL && *noqnamep == NULL);
+
+ /*
+ * Find the SIG for this rdataset, if we have it.
+ */
+ for (sigrdataset = ISC_LIST_HEAD(name->list);
+ sigrdataset != NULL;
+ sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
+ if (sigrdataset->type == dns_rdatatype_rrsig &&
+ sigrdataset->covers == type)
+ break;
+ }
+
+ if (sigrdataset == NULL)
+ return (ISC_R_NOTFOUND);
+
+ labels = dns_name_countlabels(name);
+
+ for (result = dns_rdataset_first(sigrdataset);
+ result == ISC_R_SUCCESS;
+ result = dns_rdataset_next(sigrdataset)) {
+ dns_rdata_t rdata = DNS_RDATA_INIT;
+ dns_rdataset_current(sigrdataset, &rdata);
+ result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ /* Wildcard has rrsig.labels < labels - 1. */
+ if (rrsig.labels + 1U >= labels)
+ continue;
+ break;
+ }
+
+ if (result == ISC_R_NOMORE)
+ return (ISC_R_NOTFOUND);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ dns_fixedname_init(&fzonename);
+ zonename = dns_fixedname_name(&fzonename);
+ dns_fixedname_init(&fclosest);
+ closest = dns_fixedname_name(&fclosest);
+ dns_fixedname_init(&fnearest);
+ nearest = dns_fixedname_name(&fnearest);
+
+#define NXND(x) ((x) == ISC_R_SUCCESS)
+
+ section = DNS_SECTION_AUTHORITY;
+ for (result = dns_message_firstname(fctx->rmessage, section);
+ result == ISC_R_SUCCESS;
+ result = dns_message_nextname(fctx->rmessage, section)) {
+ dns_name_t *nsec = NULL;
+ dns_message_currentname(fctx->rmessage, section, &nsec);
+ for (nrdataset = ISC_LIST_HEAD(nsec->list);
+ nrdataset != NULL; nrdataset = next) {
+ isc_boolean_t data = ISC_FALSE, exists = ISC_FALSE;
+ isc_boolean_t optout = ISC_FALSE, unknown = ISC_FALSE;
+ isc_boolean_t setclosest = ISC_FALSE;
+ isc_boolean_t setnearest = ISC_FALSE;
+
+ next = ISC_LIST_NEXT(nrdataset, link);
+ if (nrdataset->type != dns_rdatatype_nsec &&
+ nrdataset->type != dns_rdatatype_nsec3)
+ continue;
+
+ if (nrdataset->type == dns_rdatatype_nsec &&
+ NXND(dns_nsec_noexistnodata(type, name, nsec,
+ nrdataset, &exists,
+ &data, NULL, fctx_log,
+ fctx)))
+ {
+ if (!exists) {
+ noqname = nsec;
+ found = dns_rdatatype_nsec;
+ }
+ }
+
+ if (nrdataset->type == dns_rdatatype_nsec3 &&
+ NXND(dns_nsec3_noexistnodata(type, name, nsec,
+ nrdataset, zonename,
+ &exists, &data,
+ &optout, &unknown,
+ &setclosest,
+ &setnearest,
+ closest, nearest,
+ fctx_log, fctx)))
+ {
+ if (!exists && setnearest) {
+ noqname = nsec;
+ found = dns_rdatatype_nsec3;
+ }
+ }
+ }
+ }
+ if (result == ISC_R_NOMORE)
+ result = ISC_R_SUCCESS;
+ if (noqname != NULL) {
+ for (sigrdataset = ISC_LIST_HEAD(noqname->list);
+ sigrdataset != NULL;
+ sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
+ if (sigrdataset->type == dns_rdatatype_rrsig &&
+ sigrdataset->covers == found)
+ break;
+ }
+ if (sigrdataset != NULL)
+ *noqnamep = noqname;
+ }
+ return (result);
+}
+
static inline isc_result_t
cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
isc_stdtime_t now)
@@ -4521,6 +4648,17 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
rdataset->ttl = res->view->maxcachettl;
/*
+ * Find the SIG for this rdataset, if we have it.
+ */
+ for (sigrdataset = ISC_LIST_HEAD(name->list);
+ sigrdataset != NULL;
+ sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
+ if (sigrdataset->type == dns_rdatatype_rrsig &&
+ sigrdataset->covers == rdataset->type)
+ break;
+ }
+
+ /*
* If this RRset is in a secure domain, is in bailiwick,
* and is not glue, attempt DNSSEC validation. (We do not
* attempt to validate glue or out-of-bailiwick data--even
@@ -4540,16 +4678,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
*/
if (rdataset->type == dns_rdatatype_rrsig)
continue;
- /*
- * Find the SIG for this rdataset, if we have it.
- */
- for (sigrdataset = ISC_LIST_HEAD(name->list);
- sigrdataset != NULL;
- sigrdataset = ISC_LIST_NEXT(sigrdataset, link)) {
- if (sigrdataset->type == dns_rdatatype_rrsig &&
- sigrdataset->covers == rdataset->type)
- break;
- }
+
if (sigrdataset == NULL) {
if (!ANSWER(rdataset) && need_validation) {
/*
@@ -4583,6 +4712,22 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
if (sigrdataset != NULL)
sigrdataset->trust = trust;
if (!need_validation || !ANSWER(rdataset)) {
+ if (ANSWER(rdataset) &&
+ rdataset->type != dns_rdatatype_rrsig) {
+ isc_result_t tresult;
+ dns_name_t *noqname = NULL;
+ tresult = findnoqname(fctx, name,
+ rdataset->type,
+ &noqname);
+ if (tresult == ISC_R_SUCCESS &&
+ noqname != NULL) {
+ tresult =
+ dns_rdataset_addnoqname(
+ rdataset, noqname);
+ RUNTIME_CHECK(tresult ==
+ ISC_R_SUCCESS);
+ }
+ }
addedrdataset = ardataset;
result = dns_db_addrdataset(fctx->cache, node,
NULL, now, rdataset,
@@ -4710,6 +4855,21 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
options = DNS_DBADD_FORCE;
} else
options = 0;
+
+ if (ANSWER(rdataset) &&
+ rdataset->type != dns_rdatatype_rrsig) {
+ isc_result_t tresult;
+ dns_name_t *noqname = NULL;
+ tresult = findnoqname(fctx, name,
+ rdataset->type, &noqname);
+ if (tresult == ISC_R_SUCCESS &&
+ noqname != NULL) {
+ tresult = dns_rdataset_addnoqname(
+ rdataset, noqname);
+ RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
+ }
+ }
+
/*
* Now we can add the rdataset.
*/
@@ -4718,6 +4878,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
rdataset,
options,
addedrdataset);
+
if (result == DNS_R_UNCHANGED) {
if (ANSWER(rdataset) &&
ardataset != NULL &&
@@ -4813,8 +4974,8 @@ cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
static isc_result_t
ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdatatype_t covers, isc_stdtime_t now, dns_ttl_t maxttl,
- isc_boolean_t optout, dns_rdataset_t *ardataset,
- isc_result_t *eresultp)
+ isc_boolean_t optout, isc_boolean_t secure,
+ dns_rdataset_t *ardataset, isc_result_t *eresultp)
{
isc_result_t result;
dns_rdataset_t rdataset;
@@ -4823,8 +4984,12 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
dns_rdataset_init(&rdataset);
ardataset = &rdataset;
}
- result = dns_ncache_addoptout(message, cache, node, covers, now,
- maxttl, optout, ardataset);
+ if (secure)
+ result = dns_ncache_addoptout(message, cache, node, covers,
+ now, maxttl, optout, ardataset);
+ else
+ result = dns_ncache_add(message, cache, node, covers, now,
+ maxttl, ardataset);
if (result == DNS_R_UNCHANGED || result == ISC_R_SUCCESS) {
/*
* If the cache now contains a negative entry and we
@@ -4991,7 +5156,7 @@ ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
result = ncache_adderesult(fctx->rmessage, fctx->cache, node,
covers, now, ttl, ISC_FALSE,
- ardataset, &eresult);
+ ISC_FALSE, ardataset, &eresult);
if (result != ISC_R_SUCCESS)
goto unlock;
@@ -5387,10 +5552,10 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
{
isc_result_t result;
dns_message_t *message;
- dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name;
+ dns_name_t *name, *qname, *ns_name, *soa_name, *ds_name, *save_name;
dns_rdataset_t *rdataset, *ns_rdataset;
isc_boolean_t aa, negative_response;
- dns_rdatatype_t type;
+ dns_rdatatype_t type, save_type;
dns_section_t section;
FCTXTRACE("noanswer_response");
@@ -5457,6 +5622,8 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
ns_rdataset = NULL;
soa_name = NULL;
ds_name = NULL;
+ save_name = NULL;
+ save_type = dns_rdatatype_none;
result = dns_message_firstname(message, section);
while (result == ISC_R_SUCCESS) {
name = NULL;
@@ -5655,6 +5822,9 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
dns_trust_additional;
}
}
+ } else {
+ save_name = name;
+ save_type = ISC_LIST_HEAD(name->list)->type;
}
result = dns_message_nextname(message, section);
if (result == ISC_R_NOMORE)
@@ -5690,7 +5860,27 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
/*
* The responder is insane.
*/
- log_formerr(fctx, "invalid response");
+ if (save_name == NULL) {
+ log_formerr(fctx, "invalid response");
+ return (DNS_R_FORMERR);
+ }
+ if (!dns_name_issubdomain(save_name, &fctx->domain)) {
+ char nbuf[DNS_NAME_FORMATSIZE];
+ char dbuf[DNS_NAME_FORMATSIZE];
+ char tbuf[DNS_RDATATYPE_FORMATSIZE];
+
+ dns_rdatatype_format(save_type, tbuf,
+ sizeof(tbuf));
+ dns_name_format(save_name, nbuf, sizeof(nbuf));
+ dns_name_format(&fctx->domain, dbuf,
+ sizeof(dbuf));
+
+ log_formerr(fctx, "Name %s (%s) not subdomain"
+ " of zone %s -- invalid response",
+ nbuf, tbuf, dbuf);
+ } else {
+ log_formerr(fctx, "invalid response");
+ }
return (DNS_R_FORMERR);
}
}
@@ -5899,12 +6089,12 @@ answer_response(fetchctx_t *fctx) {
* but we found a CNAME.
*
* Getting a CNAME response for some
- * query types is an error.
+ * query types is an error, see
+ * RFC 4035, Section 2.5.
*/
if (type == dns_rdatatype_rrsig ||
- type == dns_rdatatype_dnskey ||
- type == dns_rdatatype_nsec ||
- type == dns_rdatatype_nsec3) {
+ type == dns_rdatatype_key ||
+ type == dns_rdatatype_nsec) {
char buf[DNS_RDATATYPE_FORMATSIZE];
dns_rdatatype_format(fctx->type,
buf, sizeof(buf));
@@ -6449,44 +6639,24 @@ checknames(dns_message_t *message) {
/*
* Log server NSID at log level 'level'
*/
-static isc_result_t
-log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx)
+static void
+log_nsid(isc_buffer_t *opt, size_t nsid_len, resquery_t *query,
+ int level, isc_mem_t *mctx)
{
static const char hex[17] = "0123456789abcdef";
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
- isc_uint16_t optcode, nsid_len, buflen, i;
- isc_result_t result;
- isc_buffer_t nsidbuf;
- dns_rdata_t rdata;
+ isc_uint16_t buflen, i;
unsigned char *p, *buf, *nsid;
- /* Extract rdata from OPT rdataset */
- result = dns_rdataset_first(opt);
- if (result != ISC_R_SUCCESS)
- return (ISC_R_FAILURE);
-
- dns_rdata_init(&rdata);
- dns_rdataset_current(opt, &rdata);
- if (rdata.length < 4)
- return (ISC_R_FAILURE);
-
- /* Check for NSID */
- isc_buffer_init(&nsidbuf, rdata.data, rdata.length);
- isc_buffer_add(&nsidbuf, rdata.length);
- optcode = isc_buffer_getuint16(&nsidbuf);
- nsid_len = isc_buffer_getuint16(&nsidbuf);
- if (optcode != DNS_OPT_NSID || nsid_len == 0)
- return (ISC_R_FAILURE);
-
/* Allocate buffer for storing hex version of the NSID */
buflen = nsid_len * 2 + 1;
buf = isc_mem_get(mctx, buflen);
if (buf == NULL)
- return (ISC_R_NOSPACE);
+ return;
/* Convert to hex */
p = buf;
- nsid = rdata.data + 4;
+ nsid = isc_buffer_current(opt);
for (i = 0; i < nsid_len; i++) {
*p++ = hex[(nsid[0] >> 4) & 0xf];
*p++ = hex[nsid[0] & 0xf];
@@ -6502,7 +6672,7 @@ log_nsid(dns_rdataset_t *opt, resquery_t *query, int level, isc_mem_t *mctx)
/* Clean up */
isc_mem_put(mctx, buf, buflen);
- return (ISC_R_SUCCESS);
+ return;
}
static void
@@ -6576,6 +6746,41 @@ betterreferral(fetchctx_t *fctx) {
}
static void
+process_opt(resquery_t *query, dns_rdataset_t *opt) {
+ dns_rdata_t rdata;
+ isc_buffer_t optbuf;
+ isc_result_t result;
+ isc_uint16_t optcode;
+ isc_uint16_t optlen;
+
+ result = dns_rdataset_first(opt);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdata_init(&rdata);
+ dns_rdataset_current(opt, &rdata);
+ isc_buffer_init(&optbuf, rdata.data, rdata.length);
+ isc_buffer_add(&optbuf, rdata.length);
+ while (isc_buffer_remaininglength(&optbuf) >= 4) {
+ optcode = isc_buffer_getuint16(&optbuf);
+ optlen = isc_buffer_getuint16(&optbuf);
+ INSIST(optlen <= isc_buffer_remaininglength(&optbuf));
+ switch (optcode) {
+ case DNS_OPT_NSID:
+ if (query->options & DNS_FETCHOPT_WANTNSID)
+ log_nsid(&optbuf, optlen, query,
+ ISC_LOG_INFO,
+ query->fctx->res->mctx);
+ isc_buffer_forward(&optbuf, optlen);
+ break;
+ default:
+ isc_buffer_forward(&optbuf, optlen);
+ break;
+ }
+ }
+ INSIST(isc_buffer_remaininglength(&optbuf) == 0U);
+ }
+}
+
+static void
resquery_response(isc_task_t *task, isc_event_t *event) {
isc_result_t result = ISC_R_SUCCESS;
resquery_t *query = event->ev_arg;
@@ -6650,13 +6855,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
*/
options |= DNS_FETCHOPT_NOEDNS0;
resend = ISC_TRUE;
- /*
- * Remember that they don't like EDNS0.
- */
- dns_adb_changeflags(fctx->adb,
- query->addrinfo,
- DNS_FETCHOPT_NOEDNS0,
- DNS_FETCHOPT_NOEDNS0);
+ add_bad_edns(fctx, &query->addrinfo->sockaddr);
} else {
/*
* There's no hope for this query.
@@ -6723,14 +6922,8 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
*/
options |= DNS_FETCHOPT_NOEDNS0;
resend = ISC_TRUE;
- /*
- * Remember that they don't like EDNS0.
- */
- dns_adb_changeflags(
- fctx->adb,
- query->addrinfo,
- DNS_FETCHOPT_NOEDNS0,
- DNS_FETCHOPT_NOEDNS0);
+ add_bad_edns(fctx,
+ &query->addrinfo->sockaddr);
inc_stats(fctx->res,
dns_resstatscounter_edns0fail);
} else {
@@ -6754,13 +6947,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
*/
options |= DNS_FETCHOPT_NOEDNS0;
resend = ISC_TRUE;
- /*
- * Remember that they don't like EDNS0.
- */
- dns_adb_changeflags(fctx->adb,
- query->addrinfo,
- DNS_FETCHOPT_NOEDNS0,
- DNS_FETCHOPT_NOEDNS0);
+ add_bad_edns(fctx, &query->addrinfo->sockaddr);
inc_stats(fctx->res,
dns_resstatscounter_edns0fail);
} else {
@@ -6783,12 +6970,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
/*
- * Did we request NSID? If so, and if the response contains
- * NSID data, log it at INFO level.
+ * Process receive opt record.
*/
opt = dns_message_getopt(message);
- if (opt != NULL && (query->options & DNS_FETCHOPT_WANTNSID) != 0)
- log_nsid(opt, query, ISC_LOG_INFO, fctx->res->mctx);
+ if (opt != NULL)
+ process_opt(query, opt);
/*
* If the message is signed, check the signature. If not, this
diff --git a/lib/dns/result.c b/lib/dns/result.c
index 0546d0f..3987953 100644
--- a/lib/dns/result.c
+++ b/lib/dns/result.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -160,7 +160,9 @@ static const char *text[DNS_R_NRESULTS] = {
"not master", /*%< 105 DNS_R_NOTMASTER */
"broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */
- "expired", /*%< 106 DNS_R_EXPIRED */
+ "expired", /*%< 107 DNS_R_EXPIRED */
+ "not dynamic", /*%< 108 DNS_R_NOTDYNAMIC */
+ "bad EUI" /*%< 109 DNS_R_BADEUI */
};
static const char *rcode_text[DNS_R_NRCODERESULTS] = {
@@ -264,6 +266,7 @@ dns_result_torcode(isc_result_t result) {
case DNS_R_TOOMANYHOPS:
case DNS_R_TSIGERRORSET:
case DNS_R_UNKNOWN:
+ case DNS_R_NAMETOOLONG:
rcode = dns_rcode_formerr;
break;
case DNS_R_DISALLOWED:
diff --git a/lib/dns/rootns.c b/lib/dns/rootns.c
index 9b25369..3502022 100644
--- a/lib/dns/rootns.c
+++ b/lib/dns/rootns.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2008, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -63,7 +63,8 @@ static char root_ns[] =
"A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:BA3E::2:30\n"
"B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201\n"
"C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12\n"
-"D.ROOT-SERVERS.NET. 3600000 IN A 128.8.10.90\n"
+"D.ROOT-SERVERS.NET. 3600000 IN A 199.7.91.13\n"
+"D.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2d::d\n"
"E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10\n"
"F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241\n"
"F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2F::F\n"
diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c
index 7865859..2d689e7 100644
--- a/lib/dns/rpz.c
+++ b/lib/dns/rpz.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2011-2013 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
@@ -16,6 +16,7 @@
/* $Id$ */
+
/*! \file */
#include <config.h>
@@ -123,8 +124,6 @@ struct dns_rpz_cidr {
dns_name_t nsdname_name; /* RPZ_NSDNAME_ZONE.origin */
};
-static isc_boolean_t have_rpz_zones = ISC_FALSE;
-
const char *
dns_rpz_type2str(dns_rpz_type_t type) {
switch (type) {
@@ -191,6 +190,7 @@ dns_rpz_policy2str(dns_rpz_policy_t policy) {
break;
default:
str = "";
+ POST(str);
INSIST(0);
}
return (str);
@@ -266,21 +266,6 @@ dns_rpz_view_destroy(dns_view_t *view) {
}
/*
- * Note that we have at least one response policy zone.
- * It would be better for something to tell the rbtdb code that the
- * zone is in at least one view's list of policy zones.
- */
-void
-dns_rpz_set_need(isc_boolean_t need) {
- have_rpz_zones = need;
-}
-
-isc_boolean_t
-dns_rpz_needed(void) {
- return (have_rpz_zones);
-}
-
-/*
* Start a new radix tree for a response policy zone.
*/
isc_result_t
@@ -292,12 +277,6 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin,
REQUIRE(rbtdb_cidr != NULL && *rbtdb_cidr == NULL);
- /*
- * Only if there is at least one response policy zone.
- */
- if (!have_rpz_zones)
- return (ISC_R_SUCCESS);
-
cidr = isc_mem_get(mctx, sizeof(*cidr));
if (cidr == NULL)
return (ISC_R_NOMEMORY);
@@ -339,7 +318,7 @@ dns_rpz_new_cidr(isc_mem_t *mctx, dns_name_t *origin,
* See if a policy zone has IP, NSIP, or NSDNAME rules or records.
*/
void
-dns_rpz_enabled(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
+dns_rpz_enabled_get(dns_rpz_cidr_t *cidr, dns_rpz_st_t *st) {
if (cidr == NULL)
return;
if (cidr->root != NULL &&
@@ -432,6 +411,9 @@ static void
badname(int level, dns_name_t *name, const char *str1, const char *str2) {
char printname[DNS_NAME_FORMATSIZE];
+ /*
+ * bin/tests/system/rpz/tests.sh looks for "invalid rpz".
+ */
if (level < DNS_RPZ_DEBUG_QUIET
&& isc_log_wouldlog(dns_lctx, level)) {
dns_name_format(name, printname, sizeof(printname));
@@ -508,7 +490,7 @@ ip2name(dns_rpz_cidr_t *cidr, const dns_rpz_cidr_key_t *tgt_ip,
while (i < DNS_RPZ_CIDR_WORDS * 2 && w[i] == 0)
++i;
}
- if (len > (int)sizeof(str))
+ if (len >= (int)sizeof(str))
return (ISC_R_FAILURE);
}
}
@@ -956,8 +938,7 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
dns_rpz_cidr_bits_t tgt_prefix;
dns_rpz_type_t type;
- if (cidr == NULL)
- return;
+ REQUIRE(cidr != NULL);
/*
* No worries if the new name is not an IP address.
@@ -985,6 +966,9 @@ dns_rpz_cidr_addip(dns_rpz_cidr_t *cidr, dns_name_t *name) {
{
char printname[DNS_NAME_FORMATSIZE];
+ /*
+ * bin/tests/system/rpz/tests.sh looks for "rpz.*failed".
+ */
dns_name_format(name, printname, sizeof(printname));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_RPZ,
DNS_LOGMODULE_RBTDB, DNS_RPZ_ERROR_LEVEL,
diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c
index 8092c5a..526ce87 100644
--- a/lib/dns/sdb.c
+++ b/lib/dns/sdb.c
@@ -382,7 +382,7 @@ dns_sdb_putrr(dns_sdblookup_t *lookup, const char *type, dns_ttl_t ttl,
datalen = strlen(data);
size = initial_size(datalen);
do {
- isc_buffer_init(&b, data, datalen);
+ isc_buffer_constinit(&b, data, datalen);
isc_buffer_add(&b, datalen);
result = isc_lex_openbuffer(lex, &b);
if (result != ISC_R_SUCCESS)
@@ -448,7 +448,7 @@ getnode(dns_sdballnodes_t *allnodes, const char *name, dns_sdbnode_t **nodep) {
origin = &sdb->common.origin;
else
origin = dns_rootname;
- isc_buffer_init(&b, name, strlen(name));
+ isc_buffer_constinit(&b, name, strlen(name));
isc_buffer_add(&b, strlen(name));
result = dns_name_fromtext(newname, &b, origin, 0, NULL);
diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c
index 870e981..6e518d1 100644
--- a/lib/dns/sdlz.c
+++ b/lib/dns/sdlz.c
@@ -1817,7 +1817,7 @@ dns_sdlz_putrr(dns_sdlzlookup_t *lookup, const char *type, dns_ttl_t ttl,
size = initial_size(data);
do {
- isc_buffer_init(&b, data, strlen(data));
+ isc_buffer_constinit(&b, data, strlen(data));
isc_buffer_add(&b, strlen(data));
result = isc_lex_openbuffer(lex, &b);
@@ -1883,7 +1883,7 @@ dns_sdlz_putnamedrr(dns_sdlzallnodes_t *allnodes, const char *name,
origin = &sdlz->common.origin;
else
origin = dns_rootname;
- isc_buffer_init(&b, name, strlen(name));
+ isc_buffer_constinit(&b, name, strlen(name));
isc_buffer_add(&b, strlen(name));
result = dns_name_fromtext(newname, &b, origin, 0, NULL);
diff --git a/lib/dns/spnego.c b/lib/dns/spnego.c
index 0486a72..0c1c858 100644
--- a/lib/dns/spnego.c
+++ b/lib/dns/spnego.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006-2013 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
@@ -630,8 +630,10 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status,
sizeof(mechbuf),
&init_token.mechTypes.val[i],
&mech_len);
- if (ret)
+ if (ret) {
+ free_NegTokenInit(&init_token);
return (GSS_S_DEFECTIVE_TOKEN);
+ }
if (mech_len == GSS_KRB5_MECH->length &&
memcmp(GSS_KRB5_MECH->elements,
mechbuf + sizeof(mechbuf) - mech_len,
@@ -650,8 +652,10 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status,
}
}
- if (!found)
+ if (!found) {
+ free_NegTokenInit(&init_token);
return (send_reject(minor_status, output_token));
+ }
if (i == 0 && init_token.mechToken != NULL) {
ibuf.length = init_token.mechToken->length;
@@ -669,12 +673,14 @@ gss_accept_sec_context_spnego(OM_uint32 *minor_status,
time_rec,
delegated_cred_handle);
if (GSS_ERROR(major_status)) {
+ free_NegTokenInit(&init_token);
send_reject(&minor_status2, output_token);
return (major_status);
}
ot = &obuf;
}
ret = send_accept(&minor_status2, output_token, ot, pref);
+ free_NegTokenInit(&init_token);
if (ot != NULL && ot->length != 0U)
gss_release_buffer(&minor_status2, ot);
@@ -846,10 +852,13 @@ der_get_octet_string(const unsigned char *p, size_t len,
octet_string *data, size_t *size)
{
data->length = len;
- data->data = malloc(len);
- if (data->data == NULL && data->length != 0U)
- return (ENOMEM);
- memcpy(data->data, p, len);
+ if (len != 0U) {
+ data->data = malloc(len);
+ if (data->data == NULL)
+ return (ENOMEM);
+ memcpy(data->data, p, len);
+ } else
+ data->data = NULL;
if (size)
*size = len;
return (0);
@@ -862,6 +871,8 @@ der_get_oid(const unsigned char *p, size_t len,
int n;
size_t oldlen = len;
+ data->components = NULL;
+ data->length = 0;
if (len < 1U)
return (ASN1_OVERRUN);
@@ -997,6 +1008,9 @@ decode_octet_string(const unsigned char *p, size_t len,
int e;
size_t slen;
+ k->data = NULL;
+ k->length = 0;
+
e = der_match_tag(p, len, ASN1_C_UNIV, PRIM, UT_OctetString, &l);
if (e)
return (e);
@@ -1547,6 +1561,11 @@ spnego_initial(OM_uint32 *minor_status,
buf_size = 1024;
buf = malloc(buf_size);
+ if (buf == NULL) {
+ *minor_status = ENOMEM;
+ ret = GSS_S_FAILURE;
+ goto end;
+ }
do {
ret = encode_NegTokenInit(buf + buf_size - 1,
@@ -1685,6 +1704,7 @@ spnego_reply(OM_uint32 *minor_status,
ret = decode_NegTokenResp(buf + taglen, len, &resp, NULL);
if (ret) {
+ free_NegTokenResp(&resp);
*minor_status = ENOMEM;
return (GSS_S_FAILURE);
}
diff --git a/lib/dns/spnego_asn1.c b/lib/dns/spnego_asn1.c
index 75c2304..b506054 100644
--- a/lib/dns/spnego_asn1.c
+++ b/lib/dns/spnego_asn1.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006, 2007, 2012, 2013 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
@@ -53,10 +53,10 @@ typedef struct oid {
(R) = ENOMEM; \
} else { \
(R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
- (S), (L)); \
+ (S), (L)); \
if((R) != 0) { \
- free((B)); \
- (B) = NULL; \
+ free((B)); \
+ (B) = NULL; \
} \
} \
} while (0)
@@ -171,33 +171,31 @@ static void free_NegTokenResp(NegTokenResp *);
/* Do not edit */
-#define BACK if (e) return e; p -= l; len -= l; ret += l
+#define BACK if (e) return e; p -= l; len -= l; ret += l; POST(p); POST(len); POST(ret)
static int
encode_MechType(unsigned char *p, size_t len, const MechType * data, size_t * size)
{
size_t ret = 0;
size_t l;
- int i, e;
+ int e;
- i = 0;
e = encode_oid(p, len, data, &l);
BACK;
*size = ret;
return 0;
}
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
+#define FORW if(e) goto fail; p += l; len -= l; ret += l; POST(p); POST(len); POST(ret)
static int
decode_MechType(const unsigned char *p, size_t len, MechType * data, size_t * size)
{
- size_t ret = 0, reallen;
+ size_t ret = 0;
size_t l;
int e;
memset(data, 0, sizeof(*data));
- reallen = 0;
e = decode_oid(p, len, data, &l);
FORW;
if (size)
@@ -223,8 +221,6 @@ free_MechType(MechType * data)
/* Do not edit */
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
static int
encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, size_t * size)
{
@@ -232,7 +228,6 @@ encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, siz
size_t l;
int i, e;
- i = 0;
for (i = (data)->len - 1; i >= 0; --i) {
int oldret = ret;
ret = 0;
@@ -246,8 +241,6 @@ encode_MechTypeList(unsigned char *p, size_t len, const MechTypeList * data, siz
return 0;
}
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
static int
decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, size_t * size)
{
@@ -269,8 +262,14 @@ decode_MechTypeList(const unsigned char *p, size_t len, MechTypeList * data, siz
(data)->len = 0;
(data)->val = NULL;
while (ret < origlen) {
+ void *old = (data)->val;
(data)->len++;
(data)->val = realloc((data)->val, sizeof(*((data)->val)) * (data)->len);
+ if ((data)->val == NULL) {
+ (data)->val = old;
+ (data)->len--;
+ return ENOMEM;
+ }
e = decode_MechType(p, len, &(data)->val[(data)->len - 1], &l);
FORW;
len = origlen - ret;
@@ -305,16 +304,13 @@ free_MechTypeList(MechTypeList * data)
/* Do not edit */
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
static int
encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, size_t * size)
{
size_t ret = 0;
size_t l;
- int i, e;
+ int e;
- i = 0;
{
unsigned char c = 0;
*p-- = c;
@@ -355,8 +351,6 @@ encode_ContextFlags(unsigned char *p, size_t len, const ContextFlags * data, siz
return 0;
}
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
static int
decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, size_t * size)
{
@@ -381,8 +375,6 @@ decode_ContextFlags(const unsigned char *p, size_t len, ContextFlags * data, siz
data->anonFlag = (*p >> 3) & 1;
data->confFlag = (*p >> 2) & 1;
data->integFlag = (*p >> 1) & 1;
- p += reallen;
- len -= reallen;
ret += reallen;
if (size)
*size = ret;
@@ -418,16 +410,13 @@ free_ContextFlags(ContextFlags * data)
/* Do not edit */
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
static int
encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, size_t * size)
{
size_t ret = 0;
size_t l;
- int i, e;
+ int e;
- i = 0;
if ((data)->mechListMIC) {
int oldret = ret;
ret = 0;
@@ -469,8 +458,6 @@ encode_NegTokenInit(unsigned char *p, size_t len, const NegTokenInit * data, siz
return 0;
}
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
static int
decode_NegTokenInit(const unsigned char *p, size_t len, NegTokenInit * data, size_t * size)
{
@@ -646,16 +633,13 @@ free_NegTokenInit(NegTokenInit * data)
/* Do not edit */
-#define BACK if (e) return e; p -= l; len -= l; ret += l
-
static int
encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, size_t * size)
{
size_t ret = 0;
size_t l;
- int i, e;
+ int e;
- i = 0;
if ((data)->mechListMIC) {
int oldret = ret;
ret = 0;
@@ -698,8 +682,6 @@ encode_NegTokenResp(unsigned char *p, size_t len, const NegTokenResp * data, siz
return 0;
}
-#define FORW if(e) goto fail; p += l; len -= l; ret += l
-
static int
decode_NegTokenResp(const unsigned char *p, size_t len, NegTokenResp * data, size_t * size)
{
diff --git a/lib/dns/ssu.c b/lib/dns/ssu.c
index 83aa679..49a777a 100644
--- a/lib/dns/ssu.c
+++ b/lib/dns/ssu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010, 2011 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010, 2011, 2013 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
@@ -82,7 +82,8 @@ dns_ssutable_create(isc_mem_t *mctx, dns_ssutable_t **tablep) {
return (result);
}
table->references = 1;
- table->mctx = mctx;
+ table->mctx = NULL;
+ isc_mem_attach(mctx, &table->mctx);
ISC_LIST_INIT(table->rules);
table->magic = SSUTABLEMAGIC;
*tablep = table;
@@ -115,7 +116,7 @@ destroy(dns_ssutable_t *table) {
}
DESTROYLOCK(&table->lock);
table->magic = 0;
- isc_mem_put(mctx, table, sizeof(dns_ssutable_t));
+ isc_mem_putanddetach(&table->mctx, table, sizeof(dns_ssutable_t));
}
void
diff --git a/lib/dns/ssu_external.c b/lib/dns/ssu_external.c
index 65ba1b5..43d231d 100644
--- a/lib/dns/ssu_external.c
+++ b/lib/dns/ssu_external.c
@@ -79,7 +79,7 @@ ux_socket_connect(const char *path) {
memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
- strncpy(addr.sun_path, path, sizeof(addr.sun_path));
+ strlcpy(addr.sun_path, path, sizeof(addr.sun_path));
fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (fd == -1) {
diff --git a/lib/dns/tkey.c b/lib/dns/tkey.c
index 0112f7e..161c188 100644
--- a/lib/dns/tkey.c
+++ b/lib/dns/tkey.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 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
@@ -991,8 +991,13 @@ dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key, dns_name_t *name,
ISC_LIST_INIT(namelist);
RETERR(add_rdata_to_list(msg, &keyname, rdata, 0, &namelist));
- dns_message_addname(msg, ISC_LIST_HEAD(namelist),
- DNS_SECTION_ADDITIONAL);
+ name = ISC_LIST_HEAD(namelist);
+ while (name != NULL) {
+ dns_name_t *next = ISC_LIST_NEXT(name, link);
+ ISC_LIST_UNLINK(namelist, name, link);
+ dns_message_addname(msg, name, DNS_SECTION_ADDITIONAL);
+ name = next;
+ }
return (ISC_R_SUCCESS);
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c
index 76c239b..c7768f4 100644
--- a/lib/dns/tsig.c
+++ b/lib/dns/tsig.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -239,7 +239,9 @@ adjust_lru(dns_tsigkey_t *tkey) {
* We may have been removed from the LRU list between
* removing the read lock and aquiring the write lock.
*/
- if (ISC_LINK_LINKED(tkey, link)) {
+ if (ISC_LINK_LINKED(tkey, link) &&
+ tkey->ring->lru.tail != tkey)
+ {
ISC_LIST_UNLINK(tkey->ring->lru, tkey, link);
ISC_LIST_APPEND(tkey->ring->lru, tkey, link);
}
@@ -625,8 +627,7 @@ restore_key(dns_tsig_keyring_t *ring, isc_stdtime_t now, FILE *fp) {
}
static void
-dump_key(dns_tsigkey_t *tkey, FILE *fp)
-{
+dump_key(dns_tsigkey_t *tkey, FILE *fp) {
char *buffer = NULL;
int length = 0;
char namestr[DNS_NAME_FORMATSIZE];
@@ -634,6 +635,9 @@ dump_key(dns_tsigkey_t *tkey, FILE *fp)
char algorithmstr[DNS_NAME_FORMATSIZE];
isc_result_t result;
+ REQUIRE(tkey != NULL);
+ REQUIRE(fp != NULL);
+
dns_name_format(&tkey->name, namestr, sizeof(namestr));
dns_name_format(tkey->creator, creatorstr, sizeof(creatorstr));
dns_name_format(tkey->algorithm, algorithmstr, sizeof(algorithmstr));
@@ -942,7 +946,8 @@ dns_tsig_sign(dns_message_t *msg) {
isc_buffer_t headerbuf;
isc_uint16_t digestbits;
- ret = dst_context_create(key->key, mctx, &ctx);
+ ret = dst_context_create2(key->key, mctx,
+ DNS_LOGCATEGORY_DNSSEC, &ctx);
if (ret != ISC_R_SUCCESS)
return (ret);
@@ -973,6 +978,13 @@ dns_tsig_sign(dns_message_t *msg) {
if (ret != ISC_R_SUCCESS)
goto cleanup_context;
}
+#if defined(__clang__) && \
+ ( __clang_major__ < 3 || \
+ (__clang_major__ == 3 && __clang_minor__ < 2) || \
+ (__clang_major__ == 4 && __clang_minor__ < 2))
+ /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */
+ else memset(&querytsig, 0, sizeof(querytsig));
+#endif
/*
* Digest the header.
@@ -1228,6 +1240,13 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
if (ret != ISC_R_SUCCESS)
return (ret);
}
+#if defined(__clang__) && \
+ ( __clang_major__ < 3 || \
+ (__clang_major__ == 3 && __clang_minor__ < 2) || \
+ (__clang_major__ == 4 && __clang_minor__ < 2))
+ /* false positive: http://llvm.org/bugs/show_bug.cgi?id=14461 */
+ else memset(&querytsig, 0, sizeof(querytsig));
+#endif
/*
* Do the key name and algorithm match that of the query?
@@ -1326,7 +1345,8 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
sig_r.base = tsig.signature;
sig_r.length = tsig.siglen;
- ret = dst_context_create(key, mctx, &ctx);
+ ret = dst_context_create2(key, mctx,
+ DNS_LOGCATEGORY_DNSSEC, &ctx);
if (ret != ISC_R_SUCCESS)
return (ret);
@@ -1557,7 +1577,9 @@ tsig_verify_tcp(isc_buffer_t *source, dns_message_t *msg) {
key = tsigkey->key;
if (msg->tsigctx == NULL) {
- ret = dst_context_create(key, mctx, &msg->tsigctx);
+ ret = dst_context_create2(key, mctx,
+ DNS_LOGCATEGORY_DNSSEC,
+ &msg->tsigctx);
if (ret != ISC_R_SUCCESS)
goto cleanup_querystruct;
@@ -1746,11 +1768,15 @@ static void
free_tsignode(void *node, void *_unused) {
dns_tsigkey_t *key;
- UNUSED(_unused);
-
REQUIRE(node != NULL);
+ UNUSED(_unused);
+
key = node;
+ if (key->generated) {
+ if (ISC_LINK_LINKED(key, link))
+ ISC_LIST_UNLINK(key->ring->lru, key, link);
+ }
dns_tsigkey_detach(&key);
}
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index 674675f..3d7518a 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -157,7 +157,7 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category,
ISC_FORMAT_PRINTF(5, 0);
static void
-validator_log(dns_validator_t *val, int level, const char *fmt, ...)
+validator_log(void *val, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
static void
@@ -195,6 +195,7 @@ marksecure(dns_validatorevent_t *event) {
dns_rdataset_settrust(event->rdataset, dns_trust_secure);
if (event->sigrdataset != NULL)
dns_rdataset_settrust(event->sigrdataset, dns_trust_secure);
+ event->secure = ISC_TRUE;
}
static void
@@ -403,6 +404,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
isc_result_t result;
isc_result_t eresult;
isc_result_t saved_result;
+ dns_fetch_t *fetch;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -419,12 +421,13 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
isc_event_free(&event);
- dns_resolver_destroyfetch(&val->fetch);
INSIST(val->event != NULL);
validator_log(val, ISC_LOG_DEBUG(3), "in fetch_callback_validator");
LOCK(&val->lock);
+ fetch = val->fetch;
+ val->fetch = NULL;
if (CANCELED(val)) {
validator_done(val, ISC_R_CANCELED);
} else if (eresult == ISC_R_SUCCESS) {
@@ -464,6 +467,8 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
+ if (fetch != NULL)
+ dns_resolver_destroyfetch(&fetch);
if (want_destroy)
destroy(val);
}
@@ -481,6 +486,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
+ dns_fetch_t *fetch;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -497,12 +503,13 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
isc_event_free(&event);
- dns_resolver_destroyfetch(&val->fetch);
INSIST(val->event != NULL);
validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched");
LOCK(&val->lock);
+ fetch = val->fetch;
+ val->fetch = NULL;
if (CANCELED(val)) {
validator_done(val, ISC_R_CANCELED);
} else if (eresult == ISC_R_SUCCESS) {
@@ -536,6 +543,8 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
+ if (fetch != NULL)
+ dns_resolver_destroyfetch(&fetch);
if (want_destroy)
destroy(val);
}
@@ -559,6 +568,7 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t result;
isc_result_t eresult;
+ dns_fetch_t *fetch;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -573,13 +583,14 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
dns_db_detach(&devent->db);
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
- dns_resolver_destroyfetch(&val->fetch);
INSIST(val->event != NULL);
validator_log(val, ISC_LOG_DEBUG(3), "in dsfetched2: %s",
dns_result_totext(eresult));
LOCK(&val->lock);
+ fetch = val->fetch;
+ val->fetch = NULL;
if (CANCELED(val)) {
validator_done(val, ISC_R_CANCELED);
} else if (eresult == DNS_R_CNAME ||
@@ -632,6 +643,8 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
want_destroy = exit_check(val);
UNLOCK(&val->lock);
+ if (fetch != NULL)
+ dns_resolver_destroyfetch(&fetch);
if (want_destroy)
destroy(val);
}
@@ -839,452 +852,6 @@ cnamevalidated(isc_task_t *task, isc_event_t *event) {
}
/*%
- * Return ISC_R_SUCCESS if we can determine that the name doesn't exist
- * or we can determine whether there is data or not at the name.
- * If the name does not exist return the wildcard name.
- *
- * Return ISC_R_IGNORE when the NSEC is not the appropriate one.
- */
-static isc_result_t
-nsecnoexistnodata(dns_validator_t *val, dns_name_t *name, dns_name_t *nsecname,
- dns_rdataset_t *nsecset, isc_boolean_t *exists,
- isc_boolean_t *data, dns_name_t *wild)
-{
- int order;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- isc_result_t result;
- dns_namereln_t relation;
- unsigned int olabels, nlabels, labels;
- dns_rdata_nsec_t nsec;
- isc_boolean_t atparent;
- isc_boolean_t ns;
- isc_boolean_t soa;
-
- REQUIRE(exists != NULL);
- REQUIRE(data != NULL);
- REQUIRE(nsecset != NULL &&
- nsecset->type == dns_rdatatype_nsec);
-
- result = dns_rdataset_first(nsecset);
- if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "failure processing NSEC set");
- return (result);
- }
- dns_rdataset_current(nsecset, &rdata);
-
- validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant nsec");
- relation = dns_name_fullcompare(name, nsecname, &order, &olabels);
-
- if (order < 0) {
- /*
- * The name is not within the NSEC range.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "NSEC does not cover name, before NSEC");
- return (ISC_R_IGNORE);
- }
-
- if (order == 0) {
- /*
- * The names are the same. If we are validating "."
- * then atparent should not be set as there is no parent.
- */
- atparent = (olabels != 1) &&
- dns_rdatatype_atparent(val->event->type);
- ns = dns_nsec_typepresent(&rdata, dns_rdatatype_ns);
- soa = dns_nsec_typepresent(&rdata, dns_rdatatype_soa);
- if (ns && !soa) {
- if (!atparent) {
- /*
- * This NSEC record is from somewhere higher in
- * the DNS, and at the parent of a delegation.
- * It can not be legitimately used here.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring parent nsec");
- return (ISC_R_IGNORE);
- }
- } else if (atparent && ns && soa) {
- /*
- * This NSEC record is from the child.
- * It can not be legitimately used here.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring child nsec");
- return (ISC_R_IGNORE);
- }
- if (val->event->type == dns_rdatatype_cname ||
- val->event->type == dns_rdatatype_nxt ||
- val->event->type == dns_rdatatype_nsec ||
- val->event->type == dns_rdatatype_key ||
- !dns_nsec_typepresent(&rdata, dns_rdatatype_cname)) {
- *exists = ISC_TRUE;
- *data = dns_nsec_typepresent(&rdata, val->event->type);
- validator_log(val, ISC_LOG_DEBUG(3),
- "nsec proves name exists (owner) data=%d",
- *data);
- return (ISC_R_SUCCESS);
- }
- validator_log(val, ISC_LOG_DEBUG(3), "NSEC proves CNAME exists");
- return (ISC_R_IGNORE);
- }
-
- if (relation == dns_namereln_subdomain &&
- dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
- !dns_nsec_typepresent(&rdata, dns_rdatatype_soa))
- {
- /*
- * This NSEC record is from somewhere higher in
- * the DNS, and at the parent of a delegation.
- * It can not be legitimately used here.
- */
- validator_log(val, ISC_LOG_DEBUG(3), "ignoring parent nsec");
- return (ISC_R_IGNORE);
- }
-
- result = dns_rdata_tostruct(&rdata, &nsec, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
- relation = dns_name_fullcompare(&nsec.next, name, &order, &nlabels);
- if (order == 0) {
- dns_rdata_freestruct(&nsec);
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring nsec matches next name");
- return (ISC_R_IGNORE);
- }
-
- if (order < 0 && !dns_name_issubdomain(nsecname, &nsec.next)) {
- /*
- * The name is not within the NSEC range.
- */
- dns_rdata_freestruct(&nsec);
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring nsec because name is past end of range");
- return (ISC_R_IGNORE);
- }
-
- if (order > 0 && relation == dns_namereln_subdomain) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "nsec proves name exist (empty)");
- dns_rdata_freestruct(&nsec);
- *exists = ISC_TRUE;
- *data = ISC_FALSE;
- return (ISC_R_SUCCESS);
- }
- if (wild != NULL) {
- dns_name_t common;
- dns_name_init(&common, NULL);
- if (olabels > nlabels) {
- labels = dns_name_countlabels(nsecname);
- dns_name_getlabelsequence(nsecname, labels - olabels,
- olabels, &common);
- } else {
- labels = dns_name_countlabels(&nsec.next);
- dns_name_getlabelsequence(&nsec.next, labels - nlabels,
- nlabels, &common);
- }
- result = dns_name_concatenate(dns_wildcardname, &common,
- wild, NULL);
- if (result != ISC_R_SUCCESS) {
- dns_rdata_freestruct(&nsec);
- validator_log(val, ISC_LOG_DEBUG(3),
- "failure generating wildcard name");
- return (result);
- }
- }
- dns_rdata_freestruct(&nsec);
- validator_log(val, ISC_LOG_DEBUG(3), "nsec range ok");
- *exists = ISC_FALSE;
- return (ISC_R_SUCCESS);
-}
-
-static isc_result_t
-nsec3noexistnodata(dns_validator_t *val, dns_name_t* name,
- dns_name_t *nsec3name, dns_rdataset_t *nsec3set,
- dns_name_t *zonename, isc_boolean_t *exists,
- isc_boolean_t *data, isc_boolean_t *optout,
- isc_boolean_t *unknown, isc_boolean_t *setclosest,
- isc_boolean_t *setnearest, dns_name_t *closest,
- dns_name_t *nearest)
-{
- char namebuf[DNS_NAME_FORMATSIZE];
- dns_fixedname_t fzone;
- dns_fixedname_t qfixed;
- dns_label_t hashlabel;
- dns_name_t *qname;
- dns_name_t *zone;
- dns_rdata_nsec3_t nsec3;
- dns_rdata_t rdata = DNS_RDATA_INIT;
- int order;
- int scope;
- isc_boolean_t atparent;
- isc_boolean_t first;
- isc_boolean_t ns;
- isc_boolean_t soa;
- isc_buffer_t buffer;
- isc_result_t answer = ISC_R_IGNORE;
- isc_result_t result;
- unsigned char hash[NSEC3_MAX_HASH_LENGTH];
- unsigned char owner[NSEC3_MAX_HASH_LENGTH];
- unsigned int length;
- unsigned int qlabels;
- unsigned int zlabels;
-
- REQUIRE((exists == NULL && data == NULL) ||
- (exists != NULL && data != NULL));
- REQUIRE(nsec3set != NULL && nsec3set->type == dns_rdatatype_nsec3);
- REQUIRE((setclosest == NULL && closest == NULL) ||
- (setclosest != NULL && closest != NULL));
- REQUIRE((setnearest == NULL && nearest == NULL) ||
- (setnearest != NULL && nearest != NULL));
-
- result = dns_rdataset_first(nsec3set);
- if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "failure processing NSEC3 set");
- return (result);
- }
-
- dns_rdataset_current(nsec3set, &rdata);
-
- result = dns_rdata_tostruct(&rdata, &nsec3, NULL);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- validator_log(val, ISC_LOG_DEBUG(3), "looking for relevant NSEC3");
-
- dns_fixedname_init(&fzone);
- zone = dns_fixedname_name(&fzone);
- zlabels = dns_name_countlabels(nsec3name);
-
- /*
- * NSEC3 records must have two or more labels to be valid.
- */
- if (zlabels < 2)
- return (ISC_R_IGNORE);
-
- /*
- * Strip off the NSEC3 hash to get the zone.
- */
- zlabels--;
- dns_name_split(nsec3name, zlabels, NULL, zone);
-
- /*
- * If not below the zone name we can ignore this record.
- */
- if (!dns_name_issubdomain(name, zone))
- return (ISC_R_IGNORE);
-
- /*
- * Is this zone the same or deeper than the current zone?
- */
- if (dns_name_countlabels(zonename) == 0 ||
- dns_name_issubdomain(zone, zonename))
- dns_name_copy(zone, zonename, NULL);
-
- if (!dns_name_equal(zone, zonename))
- return (ISC_R_IGNORE);
-
- /*
- * Are we only looking for the most enclosing zone?
- */
- if (exists == NULL || data == NULL)
- return (ISC_R_SUCCESS);
-
- /*
- * Only set unknown once we are sure that this NSEC3 is from
- * the deepest covering zone.
- */
- if (!dns_nsec3_supportedhash(nsec3.hash)) {
- if (unknown != NULL)
- *unknown = ISC_TRUE;
- return (ISC_R_IGNORE);
- }
-
- /*
- * Recover the hash from the first label.
- */
- dns_name_getlabel(nsec3name, 0, &hashlabel);
- isc_region_consume(&hashlabel, 1);
- isc_buffer_init(&buffer, owner, sizeof(owner));
- result = isc_base32hex_decoderegion(&hashlabel, &buffer);
- if (result != ISC_R_SUCCESS)
- return (result);
-
- /*
- * The hash lengths should match. If not ignore the record.
- */
- if (isc_buffer_usedlength(&buffer) != nsec3.next_length)
- return (ISC_R_IGNORE);
-
- /*
- * Work out what this NSEC3 covers.
- * Inside (<0) or outside (>=0).
- */
- scope = memcmp(owner, nsec3.next, nsec3.next_length);
-
- /*
- * Prepare to compute all the hashes.
- */
- dns_fixedname_init(&qfixed);
- qname = dns_fixedname_name(&qfixed);
- dns_name_downcase(name, qname, NULL);
- qlabels = dns_name_countlabels(qname);
- first = ISC_TRUE;
-
- while (qlabels >= zlabels) {
- length = isc_iterated_hash(hash, nsec3.hash, nsec3.iterations,
- nsec3.salt, nsec3.salt_length,
- qname->ndata, qname->length);
- /*
- * The computed hash length should match.
- */
- if (length != nsec3.next_length) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring NSEC bad length %u vs %u",
- length, nsec3.next_length);
- return (ISC_R_IGNORE);
- }
-
- order = memcmp(hash, owner, length);
- if (first && order == 0) {
- /*
- * The hashes are the same.
- */
- atparent = dns_rdatatype_atparent(val->event->type);
- ns = dns_nsec3_typepresent(&rdata, dns_rdatatype_ns);
- soa = dns_nsec3_typepresent(&rdata, dns_rdatatype_soa);
- if (ns && !soa) {
- if (!atparent) {
- /*
- * This NSEC3 record is from somewhere
- * higher in the DNS, and at the
- * parent of a delegation. It can not
- * be legitimately used here.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring parent NSEC3");
- return (ISC_R_IGNORE);
- }
- } else if (atparent && ns && soa) {
- /*
- * This NSEC3 record is from the child.
- * It can not be legitimately used here.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring child NSEC3");
- return (ISC_R_IGNORE);
- }
- if (val->event->type == dns_rdatatype_cname ||
- val->event->type == dns_rdatatype_nxt ||
- val->event->type == dns_rdatatype_nsec ||
- val->event->type == dns_rdatatype_key ||
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_cname)) {
- *exists = ISC_TRUE;
- *data = dns_nsec3_typepresent(&rdata,
- val->event->type);
- validator_log(val, ISC_LOG_DEBUG(3),
- "NSEC3 proves name exists (owner) "
- "data=%d", *data);
- return (ISC_R_SUCCESS);
- }
- validator_log(val, ISC_LOG_DEBUG(3),
- "NSEC3 proves CNAME exists");
- return (ISC_R_IGNORE);
- }
-
- if (order == 0 &&
- dns_nsec3_typepresent(&rdata, dns_rdatatype_ns) &&
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_soa))
- {
- /*
- * This NSEC3 record is from somewhere higher in
- * the DNS, and at the parent of a delegation.
- * It can not be legitimately used here.
- */
- validator_log(val, ISC_LOG_DEBUG(3),
- "ignoring parent NSEC3");
- return (ISC_R_IGNORE);
- }
-
- /*
- * Potential closest encloser.
- */
- if (order == 0) {
- if (closest != NULL &&
- (dns_name_countlabels(closest) == 0 ||
- dns_name_issubdomain(qname, closest)) &&
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_ds) &&
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_dname) &&
- (dns_nsec3_typepresent(&rdata, dns_rdatatype_soa) ||
- !dns_nsec3_typepresent(&rdata, dns_rdatatype_ns)))
- {
-
- dns_name_format(qname, namebuf,
- sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3),
- "NSEC3 indicates potential "
- "closest encloser: '%s'",
- namebuf);
- dns_name_copy(qname, closest, NULL);
- *setclosest = ISC_TRUE;
- }
- dns_name_format(qname, namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3),
- "NSEC3 at super-domain %s", namebuf);
- return (answer);
- }
-
- /*
- * Find if the name does not exist.
- *
- * We continue as we need to find the name closest to the
- * closest encloser that doesn't exist.
- *
- * We also need to continue to ensure that we are not
- * proving the non-existence of a record in a sub-zone.
- * If that would be the case we will return ISC_R_IGNORE
- * above.
- */
- if ((scope < 0 && order > 0 &&
- memcmp(hash, nsec3.next, length) < 0) ||
- (scope >= 0 && (order > 0 ||
- memcmp(hash, nsec3.next, length) < 0)))
- {
- char namebuf[DNS_NAME_FORMATSIZE];
-
- dns_name_format(qname, namebuf, sizeof(namebuf));
- validator_log(val, ISC_LOG_DEBUG(3), "NSEC3 proves "
- "name does not exist: '%s'", namebuf);
- if (nearest != NULL &&
- (dns_name_countlabels(nearest) == 0 ||
- dns_name_issubdomain(nearest, qname))) {
- dns_name_copy(qname, nearest, NULL);
- *setnearest = ISC_TRUE;
- }
-
- *exists = ISC_FALSE;
- *data = ISC_FALSE;
- if (optout != NULL) {
- if ((nsec3.flags & DNS_NSEC3FLAG_OPTOUT) != 0)
- validator_log(val, ISC_LOG_DEBUG(3),
- "NSEC3 indicates optout");
- *optout =
- ISC_TF(nsec3.flags & DNS_NSEC3FLAG_OPTOUT);
- }
- answer = ISC_R_SUCCESS;
- }
-
- qlabels--;
- if (qlabels > 0)
- dns_name_split(qname, qlabels, NULL, qname);
- first = ISC_FALSE;
- }
- return (answer);
-}
-
-/*%
* Callback for when NSEC records have been validated.
*
* Looks for NOQNAME, NODATA and OPTOUT proofs.
@@ -1339,8 +906,9 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
rdataset->trust == dns_trust_secure &&
(NEEDNODATA(val) || NEEDNOQNAME(val)) &&
!FOUNDNODATA(val) && !FOUNDNOQNAME(val) &&
- nsecnoexistnodata(val, val->event->name, devent->name,
- rdataset, &exists, &data, wild)
+ dns_nsec_noexistnodata(val->event->type, val->event->name,
+ devent->name, rdataset, &exists,
+ &data, wild, validator_log, val)
== ISC_R_SUCCESS)
{
if (exists && !data) {
@@ -1413,9 +981,6 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) {
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
- if (val->view->zonetable == NULL)
- return (ISC_R_CANCELED);
-
if (isc_time_now(&now) == ISC_R_SUCCESS &&
dns_resolver_getbadcache(val->view->resolver, name, type, &now)) {
@@ -1859,6 +1424,10 @@ isselfsigned(dns_validator_t *val) {
name = val->event->name;
mctx = val->view->mctx;
+ if (rdataset->type == dns_rdatatype_cname ||
+ rdataset->type == dns_rdatatype_dname)
+ return (answer);
+
INSIST(rdataset->type == dns_rdatatype_dnskey);
for (result = dns_rdataset_first(rdataset);
@@ -2831,8 +2400,9 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
if (rdataset->type == dns_rdatatype_nsec &&
(NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
!FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
- nsecnoexistnodata(val, wild, name, rdataset,
- &exists, &data, NULL)
+ dns_nsec_noexistnodata(val->event->type, wild, name,
+ rdataset, &exists, &data, NULL,
+ validator_log, val)
== ISC_R_SUCCESS)
{
dns_name_t **proofs = val->event->proofs;
@@ -2855,10 +2425,11 @@ checkwildcard(dns_validator_t *val, dns_rdatatype_t type, dns_name_t *zonename)
if (rdataset->type == dns_rdatatype_nsec3 &&
(NEEDNODATA(val) || NEEDNOWILDCARD(val)) &&
!FOUNDNODATA(val) && !FOUNDNOWILDCARD(val) &&
- nsec3noexistnodata(val, wild, name, rdataset,
- zonename, &exists, &data,
- NULL, NULL, NULL, NULL, NULL,
- NULL) == ISC_R_SUCCESS)
+ dns_nsec3_noexistnodata(val->event->type, wild, name,
+ rdataset, zonename, &exists, &data,
+ NULL, NULL, NULL, NULL, NULL, NULL,
+ validator_log, val)
+ == ISC_R_SUCCESS)
{
dns_name_t **proofs = val->event->proofs;
if (exists && !data)
@@ -2920,11 +2491,12 @@ findnsec3proofs(dns_validator_t *val) {
rdataset->trust != dns_trust_secure)
continue;
- result = nsec3noexistnodata(val, val->event->name,
- name, rdataset,
- zonename, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL,
- NULL);
+ result = dns_nsec3_noexistnodata(val->event->type,
+ val->event->name, name,
+ rdataset, zonename, NULL,
+ NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, validator_log,
+ val);
if (result != ISC_R_IGNORE && result != ISC_R_SUCCESS) {
if (dns_rdataset_isassociated(&trdataset))
dns_rdataset_disassociate(&trdataset);
@@ -2972,16 +2544,19 @@ findnsec3proofs(dns_validator_t *val) {
setclosest = setnearest = ISC_FALSE;
optout = ISC_FALSE;
unknown = ISC_FALSE;
- (void)nsec3noexistnodata(val, val->event->name, name, rdataset,
- zonename, &exists, &data, &optout,
- &unknown, setclosestp, &setnearest,
- closestp, nearest);
- if (setclosest)
- proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
+ result = dns_nsec3_noexistnodata(val->event->type,
+ val->event->name,
+ name, rdataset, zonename,
+ &exists, &data, &optout,
+ &unknown, setclosestp,
+ &setnearest, closestp,
+ nearest, validator_log, val);
if (unknown)
val->attributes |= VALATTR_FOUNDUNKNOWN;
if (result != ISC_R_SUCCESS)
continue;
+ if (setclosest)
+ proofs[DNS_VALIDATOR_CLOSESTENCLOSER] = name;
if (exists && !data && NEEDNODATA(val)) {
val->attributes |= VALATTR_FOUNDNODATA;
proofs[DNS_VALIDATOR_NODATAPROOF] = name;
@@ -3272,6 +2847,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
"nonexistence proof(s) found");
if (val->event->message == NULL)
marksecure(val->event);
+ else
+ val->event->secure = ISC_TRUE;
return (ISC_R_SUCCESS);
}
@@ -3374,6 +2951,7 @@ dlvfetched(isc_task_t *task, isc_event_t *event) {
isc_boolean_t want_destroy;
isc_result_t eresult;
isc_result_t result;
+ dns_fetch_t *fetch;
UNUSED(task);
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
@@ -3389,13 +2967,14 @@ dlvfetched(isc_task_t *task, isc_event_t *event) {
if (dns_rdataset_isassociated(&val->fsigrdataset))
dns_rdataset_disassociate(&val->fsigrdataset);
isc_event_free(&event);
- dns_resolver_destroyfetch(&val->fetch);
INSIST(val->event != NULL);
validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
dns_result_totext(eresult));
LOCK(&val->lock);
+ fetch = val->fetch;
+ val->fetch = NULL;
if (eresult == ISC_R_SUCCESS) {
dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
sizeof(namebuf));
@@ -3448,6 +3027,8 @@ dlvfetched(isc_task_t *task, isc_event_t *event) {
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
+ if (fetch != NULL)
+ dns_resolver_destroyfetch(&fetch);
if (want_destroy)
destroy(val);
}
@@ -4155,6 +3736,7 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
event->message = message;
memset(event->proofs, 0, sizeof(event->proofs));
event->optout = ISC_FALSE;
+ event->secure = ISC_FALSE;
result = isc_mutex_init(&val->lock);
if (result != ISC_R_SUCCESS)
goto cleanup_event;
@@ -4230,6 +3812,8 @@ dns_validator_send(dns_validator_t *validator) {
void
dns_validator_cancel(dns_validator_t *validator) {
+ dns_fetch_t *fetch = NULL;
+
REQUIRE(VALID_VALIDATOR(validator));
LOCK(&validator->lock);
@@ -4239,8 +3823,8 @@ dns_validator_cancel(dns_validator_t *validator) {
if ((validator->attributes & VALATTR_CANCELED) == 0) {
validator->attributes |= VALATTR_CANCELED;
if (validator->event != NULL) {
- if (validator->fetch != NULL)
- dns_resolver_cancelfetch(validator->fetch);
+ fetch = validator->fetch;
+ validator->fetch = NULL;
if (validator->subvalidator != NULL)
dns_validator_cancel(validator->subvalidator);
@@ -4251,6 +3835,12 @@ dns_validator_cancel(dns_validator_t *validator) {
}
}
UNLOCK(&validator->lock);
+
+ /* Need to cancel and destroy the fetch outside validator lock */
+ if (fetch != NULL) {
+ dns_resolver_cancelfetch(fetch);
+ dns_resolver_destroyfetch(&fetch);
+ }
}
static void
@@ -4339,7 +3929,7 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category,
}
static void
-validator_log(dns_validator_t *val, int level, const char *fmt, ...) {
+validator_log(void *val, int level, const char *fmt, ...) {
va_list ap;
if (! isc_log_wouldlog(dns_lctx, level))
diff --git a/lib/dns/view.c b/lib/dns/view.c
index 6750058..5b6ad65 100644
--- a/lib/dns/view.c
+++ b/lib/dns/view.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -86,6 +86,9 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view = isc_mem_get(mctx, sizeof(*view));
if (view == NULL)
return (ISC_R_NOMEMORY);
+
+ view->mctx = NULL;
+ isc_mem_attach(mctx, &view->mctx);
view->name = isc_mem_strdup(mctx, name);
if (view->name == NULL) {
result = ISC_R_NOMEMORY;
@@ -95,8 +98,8 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
if (result != ISC_R_SUCCESS)
goto cleanup_name;
-#ifdef BIND9
view->zonetable = NULL;
+#ifdef BIND9
result = dns_zt_create(mctx, rdclass, &view->zonetable);
if (result != ISC_R_SUCCESS) {
UNEXPECTED_ERROR(__FILE__, __LINE__,
@@ -125,7 +128,6 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
view->resolver = NULL;
view->adb = NULL;
view->requestmgr = NULL;
- view->mctx = mctx;
view->rdclass = rdclass;
view->frozen = ISC_FALSE;
view->task = NULL;
@@ -225,6 +227,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
ISC_EVENT_INIT(&view->reqevent, sizeof(view->reqevent), 0, NULL,
DNS_EVENT_VIEWREQSHUTDOWN, req_shutdown,
view, NULL, NULL, NULL);
+ view->viewlist = NULL;
view->magic = DNS_VIEW_MAGIC;
*viewp = view;
@@ -260,7 +263,7 @@ dns_view_create(isc_mem_t *mctx, dns_rdataclass_t rdclass,
isc_mem_free(mctx, view->name);
cleanup_view:
- isc_mem_put(mctx, view, sizeof(*view));
+ isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
return (result);
}
@@ -439,7 +442,7 @@ destroy(dns_view_t *view) {
DESTROYLOCK(&view->lock);
isc_refcount_destroy(&view->references);
isc_mem_free(view->mctx, view->name);
- isc_mem_put(view->mctx, view, sizeof(*view));
+ isc_mem_putanddetach(&view->mctx, view, sizeof(*view));
}
/*
@@ -482,6 +485,10 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
view->flush = ISC_TRUE;
isc_refcount_decrement(&view->references, &refs);
if (refs == 0) {
+#ifdef BIND9
+ dns_zone_t *mkzone = NULL;
+#endif
+
LOCK(&view->lock);
if (!RESSHUTDOWN(view))
dns_resolver_shutdown(view->resolver);
@@ -497,13 +504,20 @@ view_flushanddetach(dns_view_t **viewp, isc_boolean_t flush) {
else
dns_zt_detach(&view->zonetable);
if (view->managed_keys != NULL) {
+ mkzone = view->managed_keys;
+ view->managed_keys = NULL;
if (view->flush)
- dns_zone_flush(view->managed_keys);
- dns_zone_detach(&view->managed_keys);
+ dns_zone_flush(mkzone);
}
#endif
done = all_done(view);
UNLOCK(&view->lock);
+
+#ifdef BIND9
+ /* Need to detach zones outside view lock */
+ if (mkzone != NULL)
+ dns_zone_detach(&mkzone);
+#endif
}
*viewp = NULL;
@@ -855,11 +869,14 @@ dns_view_findzone(dns_view_t *view, dns_name_t *name, dns_zone_t **zonep) {
REQUIRE(DNS_VIEW_VALID(view));
- result = dns_zt_find(view->zonetable, name, 0, NULL, zonep);
- if (result == DNS_R_PARTIALMATCH) {
- dns_zone_detach(zonep);
+ if (view->zonetable != NULL) {
+ result = dns_zt_find(view->zonetable, name, 0, NULL, zonep);
+ if (result == DNS_R_PARTIALMATCH) {
+ dns_zone_detach(zonep);
+ result = ISC_R_NOTFOUND;
+ }
+ } else
result = ISC_R_NOTFOUND;
- }
return (result);
}
@@ -892,6 +909,7 @@ dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
#ifndef BIND9
UNUSED(use_hints);
UNUSED(use_static_stub);
+ UNUSED(zone);
#endif
/*
@@ -916,11 +934,11 @@ dns_view_find2(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
/*
* Find a database to answer the query.
*/
- zone = NULL;
db = NULL;
node = NULL;
is_staticstub_zone = ISC_FALSE;
#ifdef BIND9
+ zone = NULL;
result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
if (zone != NULL && dns_zone_gettype(zone) == dns_zone_staticstub &&
!use_static_stub) {
@@ -1168,11 +1186,14 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
dns_rdataset_t zrdataset, zsigrdataset;
dns_fixedname_t zfixedname;
+#ifndef BIND9
+ UNUSED(zone);
+#endif
+
REQUIRE(DNS_VIEW_VALID(view));
REQUIRE(view->frozen);
db = NULL;
- zone = NULL;
use_zone = ISC_FALSE;
try_hints = ISC_FALSE;
zfname = NULL;
@@ -1188,6 +1209,7 @@ dns_view_findzonecut2(dns_view_t *view, dns_name_t *name, dns_name_t *fname,
* Find the right database.
*/
#ifdef BIND9
+ zone = NULL;
result = dns_zt_find(view->zonetable, name, 0, NULL, &zone);
if (result == ISC_R_SUCCESS || result == DNS_R_PARTIALMATCH)
result = dns_zone_getdb(zone, &db);
diff --git a/lib/dns/xfrin.c b/lib/dns/xfrin.c
index eae39d9..3026af9 100644
--- a/lib/dns/xfrin.c
+++ b/lib/dns/xfrin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -591,6 +591,7 @@ xfr_rr(dns_xfrin_ctx_t *xfr, dns_name_t *name, isc_uint32_t ttl,
case XFRST_AXFR_END:
case XFRST_IXFR_END:
FAIL(DNS_R_EXTRADATA);
+ /* NOTREACHED */
default:
INSIST(0);
break;
@@ -781,7 +782,8 @@ xfrin_create(isc_mem_t *mctx,
xfr = isc_mem_get(mctx, sizeof(*xfr));
if (xfr == NULL)
return (ISC_R_NOMEMORY);
- xfr->mctx = mctx;
+ xfr->mctx = NULL;
+ isc_mem_attach(mctx, &xfr->mctx);
xfr->refcount = 0;
xfr->zone = NULL;
dns_zone_iattach(zone, &xfr->zone);
@@ -876,7 +878,7 @@ xfrin_create(isc_mem_t *mctx,
dns_db_detach(&xfr->db);
isc_task_detach(&xfr->task);
dns_zone_idetach(&xfr->zone);
- isc_mem_put(mctx, xfr, sizeof(*xfr));
+ isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
return (result);
}
@@ -1491,7 +1493,7 @@ maybe_free(dns_xfrin_ctx_t *xfr) {
if (xfr->zone != NULL)
dns_zone_idetach(&xfr->zone);
- isc_mem_put(xfr->mctx, xfr, sizeof(*xfr));
+ isc_mem_putanddetach(&xfr->mctx, xfr, sizeof(*xfr));
}
/*
diff --git a/lib/dns/zone.c b/lib/dns/zone.c
index 22db239..c212bf6 100644
--- a/lib/dns/zone.c
+++ b/lib/dns/zone.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -335,9 +335,9 @@ struct dns_zone {
isc_boolean_t added;
/*%
- * whether a rpz radix was needed when last loaded
+ * whether this is a response policy zone
*/
- isc_boolean_t rpz_zone;
+ isc_boolean_t is_rpz;
/*%
* Outstanding forwarded UPDATE requests.
@@ -345,6 +345,18 @@ struct dns_zone {
dns_forwardlist_t forwards;
};
+typedef struct {
+ dns_diff_t *diff;
+ isc_boolean_t offline;
+} zonediff_t;
+
+#define zonediff_init(z, d) \
+ do { \
+ zonediff_t *_z = (z); \
+ (_z)->diff = (d); \
+ (_z)->offline = ISC_FALSE; \
+ } while (0)
+
#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
#define DNS_ZONE_SETFLAG(z,f) do { \
INSIST(LOCKED_ZONE(z)); \
@@ -855,7 +867,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->nodes = 100;
zone->privatetype = (dns_rdatatype_t)0xffffU;
zone->added = ISC_FALSE;
- zone->rpz_zone = ISC_FALSE;
+ zone->is_rpz = ISC_FALSE;
ISC_LIST_INIT(zone->forwards);
zone->magic = ZONE_MAGIC;
@@ -1042,6 +1054,7 @@ dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
isc_result_t
dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
isc_result_t result;
+ unsigned int soacount;
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(serialp != NULL);
@@ -1049,8 +1062,11 @@ dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
LOCK_ZONE(zone);
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
if (zone->db != NULL) {
- result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
- NULL, NULL, NULL, NULL, NULL);
+ result = zone_get_from_db(zone, zone->db, NULL, &soacount,
+ serialp, NULL, NULL, NULL, NULL,
+ NULL);
+ if (result == ISC_R_SUCCESS && soacount == 0)
+ result = ISC_R_FAILURE;
} else
result = DNS_R_NOTLOADED;
ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
@@ -1390,6 +1406,30 @@ zone_isdynamic(dns_zone_t *zone) {
!dns_acl_isnone(zone->update_acl))));
}
+/*
+ * Set the response policy index and information for a zone.
+ */
+isc_result_t
+dns_zone_rpz_enable(dns_zone_t *zone) {
+ /*
+ * Only RBTDB zones can be used for response policy zones,
+ * because only they have the code to load the create the summary data.
+ * Only zones that are loaded instead of mmap()ed create the
+ * summary data and so can be policy zones.
+ */
+ if (strcmp(zone->db_argv[0], "rbt") != 0 &&
+ strcmp(zone->db_argv[0], "rbt64") != 0)
+ return (ISC_R_NOTIMPLEMENTED);
+
+ zone->is_rpz = ISC_TRUE;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_boolean_t
+dns_zone_get_rpz(dns_zone_t *zone) {
+ return (zone->is_rpz);
+}
static isc_result_t
zone_load(dns_zone_t *zone, unsigned int flags) {
@@ -1459,8 +1499,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
* "rndc reconfig", we are done.
*/
if (!isc_time_isepoch(&zone->loadtime) &&
- (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 &&
- zone->rpz_zone == dns_rpz_needed()) {
+ (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
result = ISC_R_SUCCESS;
goto cleanup;
}
@@ -1469,8 +1508,7 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
if (result == ISC_R_SUCCESS) {
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
- isc_time_compare(&filetime, &zone->loadtime) <= 0 &&
- zone->rpz_zone == dns_rpz_needed()) {
+ isc_time_compare(&filetime, &zone->loadtime) <= 0) {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"skipping load: master file "
"older than last load");
@@ -1478,7 +1516,6 @@ zone_load(dns_zone_t *zone, unsigned int flags) {
goto cleanup;
}
loadtime = filetime;
- zone->rpz_zone = dns_rpz_needed();
}
}
@@ -1704,8 +1741,15 @@ zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
isc_result_t tresult;
unsigned int options;
- options = get_master_options(zone);
+#ifdef BIND9
+ if (zone->is_rpz) {
+ result = dns_db_rpz_enabled(db, NULL);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ }
+#endif
+ options = get_master_options(zone);
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
options |= DNS_MASTER_MANYERRORS;
@@ -2174,6 +2218,34 @@ zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
}
static isc_boolean_t
+isspf(const dns_rdata_t *rdata) {
+ char buf[1024];
+ const unsigned char *data = rdata->data;
+ unsigned int rdl = rdata->length, i = 0, tl, len;
+
+ while (rdl > 0U) {
+ len = tl = *data;
+ ++data;
+ --rdl;
+ INSIST(tl <= rdl);
+ if (len > sizeof(buf) - i - 1)
+ len = sizeof(buf) - i - 1;
+ memcpy(buf + i, data, len);
+ i += len;
+ data += tl;
+ rdl -= tl;
+ }
+
+ if (i < 6U)
+ return(ISC_FALSE);
+
+ buf[i] = 0;
+ if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}
+
+static isc_boolean_t
integrity_checks(dns_zone_t *zone, dns_db_t *db) {
dns_dbiterator_t *dbiterator = NULL;
dns_dbnode_t *node = NULL;
@@ -2187,7 +2259,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) {
dns_name_t *name;
dns_name_t *bottom;
isc_result_t result;
- isc_boolean_t ok = ISC_TRUE;
+ isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
@@ -2265,7 +2337,7 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) {
result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
0, 0, &rdataset, NULL);
if (result != ISC_R_SUCCESS)
- goto next;
+ goto checkspf;
result = dns_rdataset_first(&rdataset);
while (result == ISC_R_SUCCESS) {
dns_rdataset_current(&rdataset, &rdata);
@@ -2278,6 +2350,50 @@ integrity_checks(dns_zone_t *zone, dns_db_t *db) {
}
dns_rdataset_disassociate(&rdataset);
+ checkspf:
+ /*
+ * Check if there is a type TXT spf record without a type SPF
+ * RRset being present.
+ */
+ if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
+ goto next;
+ if (zone->rdclass != dns_rdataclass_in)
+ goto next;
+ have_spf = have_txt = ISC_FALSE;
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
+ 0, 0, &rdataset, NULL);
+ if (result == ISC_R_SUCCESS) {
+ dns_rdataset_disassociate(&rdataset);
+ have_spf = ISC_TRUE;
+ }
+ result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
+ 0, 0, &rdataset, NULL);
+ if (result != ISC_R_SUCCESS)
+ goto notxt;
+ result = dns_rdataset_first(&rdataset);
+ while (result == ISC_R_SUCCESS) {
+ dns_rdataset_current(&rdataset, &rdata);
+ have_txt = isspf(&rdata);
+ dns_rdata_reset(&rdata);
+ if (have_txt)
+ break;
+ result = dns_rdataset_next(&rdataset);
+ }
+ dns_rdataset_disassociate(&rdataset);
+
+ notxt:
+ if (have_spf != have_txt) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ const char *found = have_txt ? "TXT" : "SPF";
+ const char *need = have_txt ? "SPF" : "TXT";
+
+ dns_name_format(name, namebuf, sizeof(namebuf));
+ dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s "
+ "record but no SPF/%s record found, add "
+ "matching type %s record", namebuf, found,
+ need, need);
+ }
+
next:
dns_db_detachnode(db, &node);
result = dns_dbiterator_next(dbiterator);
@@ -2788,6 +2904,8 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
dst_key_name(key), 0, &rdata));
*changed = ISC_TRUE;
+ /* Refresh new keys from the zone apex as soon as possible. */
+ set_refreshkeytimer(zone, &keydata, now);
skip:
result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
@@ -2797,10 +2915,6 @@ create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
}
}
- /* Refresh new keys from the zone apex as soon as possible. */
- if (*changed)
- set_refreshkeytimer(zone, &keydata, now);
-
if (keynode != NULL)
dns_keytable_detachkeynode(keytable, &keynode);
*keynodep = NULL;
@@ -2942,7 +3056,8 @@ load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
dns_rdataset_current(rdataset, &rdata);
/* Convert rdata to keydata. */
- dns_rdata_tostruct(&rdata, &keydata, NULL);
+ result = dns_rdata_tostruct(&rdata, &keydata, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
/* Set the key refresh timer. */
set_refreshkeytimer(zone, &keydata, now);
@@ -3285,6 +3400,13 @@ sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
}
failure:
+ if (result != ISC_R_SUCCESS &&
+ !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "unable to synchronize managed keys: %s",
+ dns_result_totext(result));
+ isc_time_settoepoch(&zone->refreshkeytime);
+ }
if (keynode != NULL)
dns_keytable_detachkeynode(sr, &keynode);
if (sr != NULL)
@@ -3462,14 +3584,18 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
}
if (zone->db != NULL) {
+ unsigned int oldsoacount;
+
/*
* This is checked in zone_replacedb() for slave zones
* as they don't reload from disk.
*/
- result = zone_get_from_db(zone, zone->db, NULL, NULL,
- &oldserial, NULL, NULL, NULL,
- NULL, NULL);
+ result = zone_get_from_db(zone, zone->db, NULL,
+ &oldsoacount, &oldserial,
+ NULL, NULL, NULL, NULL,
+ NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ RUNTIME_CHECK(soacount > 0U);
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
!isc_serial_gt(serial, oldserial)) {
isc_uint32_t serialmin, serialmax;
@@ -3877,6 +4003,19 @@ zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
*expire = soa.expire;
if (minimum != NULL)
*minimum = soa.minimum;
+ } else {
+ if (soacount != NULL)
+ *soacount = 0;
+ if (serial != NULL)
+ *serial = 0;
+ if (refresh != NULL)
+ *refresh = 0;
+ if (retry != NULL)
+ *retry = 0;
+ if (expire != NULL)
+ *expire = 0;
+ if (minimum != NULL)
+ *minimum = 0;
}
result = ISC_R_SUCCESS;
@@ -4543,20 +4682,21 @@ find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
}
static isc_result_t
-offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
- dns_ttl_t ttl, dns_rdata_t *rdata)
+offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
+ dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
{
isc_result_t result;
if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
return (ISC_R_SUCCESS);
- result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
+ result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
name, ttl, rdata);
if (result != ISC_R_SUCCESS)
return (result);
rdata->flags |= DNS_RDATA_OFFLINE;
- result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
+ result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
name, ttl, rdata);
+ zonediff->offline = ISC_TRUE;
return (result);
}
@@ -4631,7 +4771,7 @@ delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) {
*/
static isc_result_t
del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
- dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
+ dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
{
isc_result_t result;
@@ -4677,7 +4817,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
if (type != dns_rdatatype_dnskey) {
if (delsig_ok(&rrsig, keys, nkeys)) {
- result = update_one_rr(db, ver, diff,
+ result = update_one_rr(db, ver, zonediff->diff,
DNS_DIFFOP_DELRESIGN, name,
rdataset.ttl, &rdata);
if (incremental)
@@ -4695,8 +4835,9 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
* for the private part.
*/
if (incremental) {
- result = offline(db, ver, diff, name,
- rdataset.ttl, &rdata);
+ result = offline(db, ver, zonediff,
+ name, rdataset.ttl,
+ &rdata);
changed = ISC_TRUE;
if (result != ISC_R_SUCCESS)
break;
@@ -4756,11 +4897,12 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
warn = maybe;
if (warn == 0 || warn > timeexpire)
warn = timeexpire;
- result = offline(db, ver, diff, name,
- rdataset.ttl, &rdata);
+ result = offline(db, ver, zonediff,
+ name, rdataset.ttl,
+ &rdata);
break;
}
- result = update_one_rr(db, ver, diff,
+ result = update_one_rr(db, ver, zonediff->diff,
DNS_DIFFOP_DELRESIGN,
name, rdataset.ttl,
&rdata);
@@ -4773,7 +4915,7 @@ del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
* delete the RRSIG.
*/
if (!found)
- result = update_one_rr(db, ver, diff,
+ result = update_one_rr(db, ver, zonediff->diff,
DNS_DIFFOP_DELRESIGN, name,
rdataset.ttl, &rdata);
if (result != ISC_R_SUCCESS)
@@ -4903,9 +5045,11 @@ add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
static void
zone_resigninc(dns_zone_t *zone) {
+ const char *me = "zone_resigninc";
dns_db_t *db = NULL;
dns_dbversion_t *version = NULL;
- dns_diff_t sig_diff;
+ dns_diff_t _sig_diff;
+ zonediff_t zonediff;
dns_fixedname_t fixed;
dns_name_t *name;
dns_rdataset_t rdataset;
@@ -4919,10 +5063,13 @@ zone_resigninc(dns_zone_t *zone) {
unsigned int nkeys = 0;
unsigned int resign;
+ ENTER;
+
dns_rdataset_init(&rdataset);
dns_fixedname_init(&fixed);
- dns_diff_init(zone->mctx, &sig_diff);
- sig_diff.resign = zone->sigresigninginterval;
+ dns_diff_init(zone->mctx, &_sig_diff);
+ _sig_diff.resign = zone->sigresigninginterval;
+ zonediff_init(&zonediff, &_sig_diff);
/*
* Updates are disabled. Pause for 5 minutes.
@@ -4992,7 +5139,7 @@ zone_resigninc(dns_zone_t *zone) {
resign > stop)
break;
- result = del_sigs(zone, db, version, name, covers, &sig_diff,
+ result = del_sigs(zone, db, version, name, covers, &zonediff,
zone_keys, nkeys, now, ISC_TRUE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -5001,7 +5148,7 @@ zone_resigninc(dns_zone_t *zone) {
break;
}
- result = add_sigs(db, version, name, covers, &sig_diff,
+ result = add_sigs(db, version, name, covers, zonediff.diff,
zone_keys, nkeys, zone->mctx, inception,
expire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
@@ -5026,7 +5173,7 @@ zone_resigninc(dns_zone_t *zone) {
goto failure;
result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
- &sig_diff, zone_keys, nkeys, now, ISC_TRUE);
+ &zonediff, zone_keys, nkeys, now, ISC_TRUE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_resigninc:del_sigs -> %s",
@@ -5037,11 +5184,17 @@ zone_resigninc(dns_zone_t *zone) {
/*
* Did we change anything in the zone?
*/
- if (ISC_LIST_EMPTY(sig_diff.tuples))
+ if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
+ /*
+ * Commit the changes if any key has been marked as offline.
+ */
+ if (zonediff.offline)
+ dns_db_closeversion(db, &version, ISC_TRUE);
goto failure;
+ }
/* Increment SOA serial if we have made changes */
- result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
+ result = increment_soa_serial(db, version, zonediff.diff, zone->mctx);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_resigninc:increment_soa_serial -> %s",
@@ -5054,8 +5207,8 @@ zone_resigninc(dns_zone_t *zone) {
* termination is sensible.
*/
result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
- &sig_diff, zone_keys, nkeys, zone->mctx, inception,
- soaexpire, check_ksk, keyset_kskonly);
+ zonediff.diff, zone_keys, nkeys, zone->mctx,
+ inception, soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_resigninc:add_sigs -> %s",
@@ -5064,13 +5217,13 @@ zone_resigninc(dns_zone_t *zone) {
}
/* Write changes to journal file. */
- CHECK(zone_journal(zone, &sig_diff, "zone_resigninc"));
+ CHECK(zone_journal(zone, zonediff.diff, "zone_resigninc"));
/* Everything has succeeded. Commit the changes. */
dns_db_closeversion(db, &version, ISC_TRUE);
failure:
- dns_diff_clear(&sig_diff);
+ dns_diff_clear(&_sig_diff);
for (i = 0; i < nkeys; i++)
dst_key_free(&zone_keys[i]);
if (version != NULL) {
@@ -5740,7 +5893,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
- dns_diff_t *sig_diff)
+ zonediff_t *zonediff)
{
dns_difftuple_t *tuple;
isc_result_t result;
@@ -5749,7 +5902,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
tuple != NULL;
tuple = ISC_LIST_HEAD(diff->tuples)) {
result = del_sigs(zone, db, version, &tuple->name,
- tuple->rdata.type, sig_diff,
+ tuple->rdata.type, zonediff,
zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -5758,7 +5911,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
return (result);
}
result = add_sigs(db, version, &tuple->name,
- tuple->rdata.type, sig_diff,
+ tuple->rdata.type, zonediff->diff,
zone_keys, nkeys, zone->mctx, inception,
expire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
@@ -5775,7 +5928,7 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
!dns_name_equal(&tuple->name, &next->name)))
next = ISC_LIST_NEXT(next, link);
ISC_LIST_UNLINK(diff->tuples, tuple, link);
- dns_diff_appendminimal(sig_diff, &tuple);
+ dns_diff_appendminimal(zonediff->diff, &tuple);
INSIST(tuple == NULL);
tuple = next;
} while (tuple != NULL);
@@ -5789,13 +5942,15 @@ update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
*/
static void
zone_nsec3chain(dns_zone_t *zone) {
+ const char *me = "zone_nsec3chain";
dns_db_t *db = NULL;
dns_dbnode_t *node = NULL;
dns_dbversion_t *version = NULL;
- dns_diff_t sig_diff;
+ dns_diff_t _sig_diff;
dns_diff_t nsec_diff;
dns_diff_t nsec3_diff;
dns_diff_t param_diff;
+ zonediff_t zonediff;
dns_fixedname_t fixed;
dns_fixedname_t nextfixed;
dns_name_t *name, *nextname;
@@ -5821,6 +5976,8 @@ zone_nsec3chain(dns_zone_t *zone) {
isc_boolean_t updatensec = ISC_FALSE;
dns_rdatatype_t privatetype = zone->privatetype;
+ ENTER;
+
dns_rdataset_init(&rdataset);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
@@ -5829,8 +5986,9 @@ zone_nsec3chain(dns_zone_t *zone) {
dns_diff_init(zone->mctx, &param_diff);
dns_diff_init(zone->mctx, &nsec3_diff);
dns_diff_init(zone->mctx, &nsec_diff);
- dns_diff_init(zone->mctx, &sig_diff);
- sig_diff.resign = zone->sigresigninginterval;
+ dns_diff_init(zone->mctx, &_sig_diff);
+ _sig_diff.resign = zone->sigresigninginterval;
+ zonediff_init(&zonediff, &_sig_diff);
ISC_LIST_INIT(cleanup);
/*
@@ -6028,6 +6186,7 @@ zone_nsec3chain(dns_zone_t *zone) {
result = dns_dbiterator_next(nsec3chain->dbiterator);
if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
+ dns_dbiterator_pause(nsec3chain->dbiterator);
CHECK(fixup_nsec3param(db, version, nsec3chain,
ISC_FALSE, privatetype,
&param_diff));
@@ -6325,6 +6484,7 @@ zone_nsec3chain(dns_zone_t *zone) {
if (rebuild_nsec) {
if (nsec3chain != NULL)
dns_dbiterator_pause(nsec3chain->dbiterator);
+
result = updatesecure(db, version, &zone->origin,
zone->minimum, ISC_TRUE,
&nsec_diff);
@@ -6336,7 +6496,11 @@ zone_nsec3chain(dns_zone_t *zone) {
goto failure;
}
}
+
if (rebuild_nsec3) {
+ if (nsec3chain != NULL)
+ dns_dbiterator_pause(nsec3chain->dbiterator);
+
result = dns_nsec3_addnsec3s(db, version,
dns_db_origin(db),
zone->minimum, ISC_FALSE,
@@ -6351,12 +6515,17 @@ zone_nsec3chain(dns_zone_t *zone) {
}
}
+ if (nsec3chain != NULL)
+ dns_dbiterator_pause(nsec3chain->dbiterator);
+
/*
* Add / update signatures for the NSEC3 records.
*/
+ if (nsec3chain != NULL)
+ dns_dbiterator_pause(nsec3chain->dbiterator);
result = update_sigs(&nsec3_diff, db, version, zone_keys,
nkeys, zone, inception, expire, now,
- check_ksk, keyset_kskonly, &sig_diff);
+ check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
"update_sigs -> %s", dns_result_totext(result));
@@ -6369,7 +6538,7 @@ zone_nsec3chain(dns_zone_t *zone) {
*/
result = update_sigs(&param_diff, db, version, zone_keys,
nkeys, zone, inception, expire, now,
- check_ksk, keyset_kskonly, &sig_diff);
+ check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
"update_sigs -> %s", dns_result_totext(result));
@@ -6377,8 +6546,6 @@ zone_nsec3chain(dns_zone_t *zone) {
}
if (updatensec) {
- if (nsec3chain != NULL)
- dns_dbiterator_pause(nsec3chain->dbiterator);
result = updatesecure(db, version, &zone->origin,
zone->minimum, ISC_FALSE, &nsec_diff);
if (result != ISC_R_SUCCESS) {
@@ -6391,7 +6558,7 @@ zone_nsec3chain(dns_zone_t *zone) {
result = update_sigs(&nsec_diff, db, version, zone_keys,
nkeys, zone, inception, expire, now,
- check_ksk, keyset_kskonly, &sig_diff);
+ check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
"update_sigs -> %s", dns_result_totext(result));
@@ -6402,18 +6569,23 @@ zone_nsec3chain(dns_zone_t *zone) {
* If we made no effective changes to the zone then we can just
* cleanup otherwise we need to increment the serial.
*/
- if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
+ if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
+ /*
+ * No need to call dns_db_closeversion() here as it is
+ * called with commit = ISC_TRUE below.
+ */
goto done;
+ }
result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
- &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
+ &zonediff, zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
"del_sigs -> %s", dns_result_totext(result));
goto failure;
}
- result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
+ result = increment_soa_serial(db, version, zonediff.diff, zone->mctx);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
"increment_soa_serial -> %s",
@@ -6422,8 +6594,8 @@ zone_nsec3chain(dns_zone_t *zone) {
}
result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
- &sig_diff, zone_keys, nkeys, zone->mctx, inception,
- soaexpire, check_ksk, keyset_kskonly);
+ zonediff.diff, zone_keys, nkeys, zone->mctx,
+ inception, soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
"add_sigs -> %s", dns_result_totext(result));
@@ -6431,7 +6603,7 @@ zone_nsec3chain(dns_zone_t *zone) {
}
/* Write changes to journal file. */
- CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain"));
+ CHECK(zone_journal(zone, zonediff.diff, "zone_nsec3chain"));
LOCK_ZONE(zone);
zone_needdump(zone, DNS_DUMP_DELAY);
@@ -6451,6 +6623,7 @@ zone_nsec3chain(dns_zone_t *zone) {
/*
* Everything has succeeded. Commit the changes.
+ * Unconditionally commit as zonediff.offline not checked above.
*/
dns_db_closeversion(db, &version, ISC_TRUE);
@@ -6520,7 +6693,7 @@ zone_nsec3chain(dns_zone_t *zone) {
dns_diff_clear(&param_diff);
dns_diff_clear(&nsec3_diff);
dns_diff_clear(&nsec_diff);
- dns_diff_clear(&sig_diff);
+ dns_diff_clear(&_sig_diff);
if (iterator != NULL)
dns_rdatasetiter_destroy(&iterator);
@@ -6622,11 +6795,13 @@ del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
*/
static void
zone_sign(dns_zone_t *zone) {
+ const char *me = "zone_sign";
dns_db_t *db = NULL;
dns_dbnode_t *node = NULL;
dns_dbversion_t *version = NULL;
- dns_diff_t sig_diff;
+ dns_diff_t _sig_diff;
dns_diff_t post_diff;
+ zonediff_t zonediff;
dns_fixedname_t fixed;
dns_fixedname_t nextfixed;
dns_name_t *name, *nextname;
@@ -6648,14 +6823,17 @@ zone_sign(dns_zone_t *zone) {
unsigned int nkeys = 0;
isc_uint32_t nodes;
+ ENTER;
+
dns_rdataset_init(&rdataset);
dns_fixedname_init(&fixed);
name = dns_fixedname_name(&fixed);
dns_fixedname_init(&nextfixed);
nextname = dns_fixedname_name(&nextfixed);
- dns_diff_init(zone->mctx, &sig_diff);
- sig_diff.resign = zone->sigresigninginterval;
+ dns_diff_init(zone->mctx, &_sig_diff);
+ _sig_diff.resign = zone->sigresigninginterval;
dns_diff_init(zone->mctx, &post_diff);
+ zonediff_init(&zonediff, &_sig_diff);
ISC_LIST_INIT(cleanup);
/*
@@ -6769,7 +6947,7 @@ zone_sign(dns_zone_t *zone) {
dns_dbiterator_pause(signing->dbiterator);
CHECK(del_sig(db, version, name, node, nkeys,
signing->algorithm, signing->keyid,
- &sig_diff));
+ zonediff.diff));
}
/*
@@ -6864,7 +7042,7 @@ zone_sign(dns_zone_t *zone) {
build_nsec, zone_keys[i], inception,
expire, zone->minimum, is_ksk,
ISC_TF(both && keyset_kskonly),
- &delegation, &sig_diff,
+ &delegation, zonediff.diff,
&signatures, zone->mctx));
/*
* If we are adding we are done. Look for other keys
@@ -6946,7 +7124,7 @@ zone_sign(dns_zone_t *zone) {
if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
result = update_sigs(&post_diff, db, version, zone_keys,
nkeys, zone, inception, expire, now,
- check_ksk, keyset_kskonly, &sig_diff);
+ check_ksk, keyset_kskonly, &zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
"update_sigs -> %s",
@@ -6958,7 +7136,9 @@ zone_sign(dns_zone_t *zone) {
/*
* Have we changed anything?
*/
- if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) {
+ if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
+ if (zonediff.offline)
+ commit = ISC_TRUE;
result = ISC_R_SUCCESS;
goto pauseall;
}
@@ -6966,7 +7146,7 @@ zone_sign(dns_zone_t *zone) {
commit = ISC_TRUE;
result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
- &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
+ &zonediff, zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_sign:del_sigs -> %s",
@@ -6974,7 +7154,7 @@ zone_sign(dns_zone_t *zone) {
goto failure;
}
- result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
+ result = increment_soa_serial(db, version, zonediff.diff, zone->mctx);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_sign:increment_soa_serial -> %s",
@@ -6987,8 +7167,8 @@ zone_sign(dns_zone_t *zone) {
* termination is sensible.
*/
result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
- &sig_diff, zone_keys, nkeys, zone->mctx, inception,
- soaexpire, check_ksk, keyset_kskonly);
+ zonediff.diff, zone_keys, nkeys, zone->mctx,
+ inception, soaexpire, check_ksk, keyset_kskonly);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
"zone_sign:add_sigs -> %s",
@@ -6999,7 +7179,7 @@ zone_sign(dns_zone_t *zone) {
/*
* Write changes to journal file.
*/
- CHECK(zone_journal(zone, &sig_diff, "zone_sign"));
+ CHECK(zone_journal(zone, zonediff.diff, "zone_sign"));
pauseall:
/*
@@ -7059,7 +7239,7 @@ zone_sign(dns_zone_t *zone) {
signing = ISC_LIST_NEXT(signing, link))
dns_dbiterator_pause(signing->dbiterator);
- dns_diff_clear(&sig_diff);
+ dns_diff_clear(&_sig_diff);
for (i = 0; i < nkeys; i++)
dst_key_free(&zone_keys[i]);
@@ -7090,19 +7270,22 @@ normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
dns_rdata_dnskey_t dnskey;
dns_rdata_keydata_t keydata;
isc_buffer_t buf;
+ isc_result_t result;
dns_rdata_reset(target);
isc_buffer_init(&buf, data, size);
switch (rr->type) {
case dns_rdatatype_dnskey:
- dns_rdata_tostruct(rr, &dnskey, NULL);
+ result = dns_rdata_tostruct(rr, &dnskey, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
&dnskey, &buf);
break;
case dns_rdatatype_keydata:
- dns_rdata_tostruct(rr, &keydata, NULL);
+ result = dns_rdata_tostruct(rr, &keydata, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_keydata_todnskey(&keydata, &dnskey, NULL);
dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
&dnskey, &buf);
@@ -7509,7 +7692,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
result = dns_rdataset_next(&kfetch->keydataset)) {
dns_rdata_reset(&keydatarr);
dns_rdataset_current(&kfetch->keydataset, &keydatarr);
- dns_rdata_tostruct(&keydatarr, &keydata, NULL);
+ result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
/*
* If any keydata record has a nonzero add holddown, then
@@ -7599,7 +7783,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
dns_rdata_reset(&dnskeyrr);
dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
- dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
/* Skip ZSK's */
if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
@@ -7610,7 +7795,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
dns_rdata_reset(&keydatarr);
dns_rdataset_current(&kfetch->keydataset, &keydatarr);
- dns_rdata_tostruct(&keydatarr, &keydata, NULL);
+ result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
if (revoked && revocable(kfetch, &keydata)) {
if (keydata.addhd > now) {
@@ -7710,7 +7896,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
&keydatarr));
} else if (newkey) {
/* Convert DNSKEY to KEYDATA */
- dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
NULL);
keydata.addhd = initializing ? now : now + MONTH;
@@ -7729,7 +7916,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
if (trustkey) {
/* Trust this key. */
- dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
trust_key(zone, keyname, &dnskey, mctx);
}
@@ -8020,6 +8208,14 @@ zone_maintenance(dns_zone_t *zone) {
}
/*
+ * Slaves send notifies before backing up to disk, masters after.
+ */
+ if (zone->type == dns_zone_slave &&
+ DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
+ isc_time_compare(&now, &zone->notifytime) >= 0)
+ zone_notify(zone, &now);
+
+ /*
* Do we need to consolidate the backing store?
*/
switch (zone->type) {
@@ -8049,14 +8245,28 @@ zone_maintenance(dns_zone_t *zone) {
}
/*
+ * Master/redirect zones send notifies now, if needed
+ */
+ switch (zone->type) {
+ case dns_zone_master:
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
+ isc_time_compare(&now, &zone->notifytime) >= 0)
+ zone_notify(zone, &now);
+ default:
+ break;
+ }
+
+ /*
* Do we need to refresh keys?
*/
switch (zone->type) {
case dns_zone_key:
- if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
- DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
- !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
- zone_refreshkeys(zone);
+ if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
+ if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
+ !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
+ zone_refreshkeys(zone);
+ }
+ }
break;
case dns_zone_master:
if (!isc_time_isepoch(&zone->refreshkeytime) &&
@@ -8070,12 +8280,6 @@ zone_maintenance(dns_zone_t *zone) {
case dns_zone_master:
case dns_zone_slave:
/*
- * Do we need to send out notify messages?
- */
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
- isc_time_compare(&now, &zone->notifytime) >= 0)
- zone_notify(zone, &now);
- /*
* Do we need to sign/resign some RRsets?
*/
if (!isc_time_isepoch(&zone->signingtime) &&
@@ -8088,7 +8292,7 @@ zone_maintenance(dns_zone_t *zone) {
isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
zone_nsec3chain(zone);
/*
- * Do we need to issue a key expiry warning.
+ * Do we need to issue a key expiry warning?
*/
if (!isc_time_isepoch(&zone->keywarntime) &&
isc_time_compare(&now, &zone->keywarntime) >= 0)
@@ -8237,6 +8441,7 @@ dns_zone_dump(dns_zone_t *zone) {
static void
zone_needdump(dns_zone_t *zone, unsigned int delay) {
+ const char me[] = "zone_needdump";
isc_time_t dumptime;
isc_time_t now;
@@ -8246,6 +8451,7 @@ zone_needdump(dns_zone_t *zone, unsigned int delay) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(LOCKED_ZONE(zone));
+ ENTER;
/*
* Do we have a place to dump to and are we loaded?
@@ -8898,9 +9104,9 @@ notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
dns_message_destroy(&message);
cleanup:
UNLOCK_ZONE(notify->zone);
+ isc_event_free(&event);
if (result != ISC_R_SUCCESS)
notify_destroy(notify, ISC_FALSE);
- isc_event_free(&event);
}
static void
@@ -9247,7 +9453,7 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
isc_time_t now;
isc_boolean_t exiting = ISC_FALSE;
isc_interval_t i;
- unsigned int j;
+ unsigned int j, soacount;
stub = revent->ev_arg;
INSIST(DNS_STUB_VALID(stub));
@@ -9390,9 +9596,9 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
if (zone->db == NULL)
zone_attachdb(zone, stub->db);
- result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh,
- &retry, &expire, NULL, NULL);
- if (result == ISC_R_SUCCESS) {
+ result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
+ &refresh, &retry, &expire, NULL, NULL);
+ if (result == ISC_R_SUCCESS && soacount > 0U) {
zone->refresh = RANGE(refresh, zone->minrefresh,
zone->maxrefresh);
zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
@@ -9728,10 +9934,12 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
serial = soa.serial;
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
- result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ unsigned int soacount;
+ result = zone_get_from_db(zone, zone->db, NULL, &soacount,
&oldserial, NULL, NULL, NULL, NULL,
NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ RUNTIME_CHECK(soacount > 0U);
zone_debuglog(zone, me, 1, "serial: new %u, old %u",
serial, oldserial);
} else
@@ -10953,6 +11161,7 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
result = dns_rdataset_first(rdataset);
if (result == ISC_R_SUCCESS) {
isc_uint32_t serial = 0, oldserial;
+ unsigned int soacount;
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &soa, NULL);
@@ -10962,10 +11171,11 @@ dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
* The following should safely be performed without DB
* lock and succeed in this context.
*/
- result = zone_get_from_db(zone, zone->db, NULL, NULL,
- &oldserial, NULL, NULL, NULL,
- NULL, NULL);
+ result = zone_get_from_db(zone, zone->db, NULL,
+ &soacount, &oldserial, NULL,
+ NULL, NULL, NULL, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ RUNTIME_CHECK(soacount > 0U);
if (isc_serial_le(serial, oldserial)) {
dns_zone_log(zone,
ISC_LOG_INFO,
@@ -11652,6 +11862,7 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
isc_uint32_t serial, oldserial;
+ unsigned int soacount;
dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
@@ -11666,10 +11877,11 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
/*
* This is checked in zone_postload() for master zones.
*/
- result = zone_get_from_db(zone, zone->db, NULL, NULL,
+ result = zone_get_from_db(zone, zone->db, NULL, &soacount,
&oldserial, NULL, NULL, NULL, NULL,
NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ RUNTIME_CHECK(soacount > 0U);
if (zone->type == dns_zone_slave &&
!isc_serial_gt(serial, oldserial)) {
isc_uint32_t serialmin, serialmax;
@@ -11916,6 +12128,8 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
* won't hurt with an AXFR.
*/
if (zone->masterfile != NULL || zone->journal != NULL) {
+ unsigned int delay = DNS_DUMP_DELAY;
+
result = ISC_R_FAILURE;
if (zone->journal != NULL)
result = isc_file_settime(zone->journal, &now);
@@ -11923,14 +12137,16 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
zone->masterfile != NULL)
result = isc_file_settime(zone->masterfile,
&now);
- /* Someone removed the file from underneath us! */
- if (result == ISC_R_FILENOTFOUND &&
- zone->masterfile != NULL) {
- unsigned int delay = DNS_DUMP_DELAY;
- if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY))
- delay = 0;
+
+ if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
+ result == ISC_R_FILENOTFOUND)
+ delay = 0;
+
+ if ((result == ISC_R_SUCCESS ||
+ result == ISC_R_FILENOTFOUND) &&
+ zone->masterfile != NULL)
zone_needdump(zone, delay);
- } else if (result != ISC_R_SUCCESS)
+ else if (result != ISC_R_SUCCESS)
dns_zone_log(zone, ISC_LOG_ERROR,
"transfer: could not set file "
"modification time of '%s': %s",
@@ -13323,6 +13539,8 @@ dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
+ if (zmgr->unreachable[i].expire == 0)
+ break;
result = isc_rwlock_tryupgrade(&zmgr->urlock);
if (result == ISC_R_SUCCESS) {
locktype = isc_rwlocktype_write;
@@ -13994,7 +14212,7 @@ add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
static isc_result_t
sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
- dns_diff_t *diff, dns_diff_t *sig_diff)
+ dns_diff_t *diff, zonediff_t *zonediff)
{
isc_result_t result;
isc_stdtime_t now, inception, soaexpire;
@@ -14034,7 +14252,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
if (tuple == NULL) {
result = del_sigs(zone, db, ver, &zone->origin,
- dns_rdatatype_dnskey, sig_diff,
+ dns_rdatatype_dnskey, zonediff,
zone_keys, nkeys, now, ISC_FALSE);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -14043,7 +14261,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
goto failure;
}
result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
- sig_diff, zone_keys, nkeys, zone->mctx,
+ zonediff->diff, zone_keys, nkeys, zone->mctx,
inception, soaexpire, check_ksk,
keyset_kskonly);
if (result != ISC_R_SUCCESS) {
@@ -14056,7 +14274,7 @@ sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
inception, soaexpire, now, check_ksk,
- keyset_kskonly, sig_diff);
+ keyset_kskonly, zonediff);
if (result != ISC_R_SUCCESS) {
dns_zone_log(zone, ISC_LOG_ERROR,
@@ -14209,7 +14427,8 @@ zone_rekey(dns_zone_t *zone) {
dns_rdataset_t soaset, soasigs, keyset, keysigs;
dns_dnsseckeylist_t dnskeys, keys, rmkeys;
dns_dnsseckey_t *key;
- dns_diff_t diff, sig_diff;
+ dns_diff_t diff, _sig_diff;
+ zonediff_t zonediff;
isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
isc_boolean_t newalg = ISC_FALSE;
isc_boolean_t fullsign;
@@ -14233,8 +14452,9 @@ zone_rekey(dns_zone_t *zone) {
dir = dns_zone_getkeydirectory(zone);
mctx = zone->mctx;
dns_diff_init(mctx, &diff);
- dns_diff_init(mctx, &sig_diff);
- sig_diff.resign = zone->sigresigninginterval;
+ dns_diff_init(mctx, &_sig_diff);
+ _sig_diff.resign = zone->sigresigninginterval;
+ zonediff_init(&zonediff, &_sig_diff);
CHECK(dns_zone_getdb(zone, &db));
CHECK(dns_db_newversion(db, &ver));
@@ -14334,8 +14554,8 @@ zone_rekey(dns_zone_t *zone) {
ISC_TF(newalg || fullsign)));
CHECK(increment_soa_serial(db, ver, &diff, mctx));
CHECK(add_chains(zone, db, ver, &diff));
- CHECK(sign_apex(zone, db, ver, &diff, &sig_diff));
- CHECK(zone_journal(zone, &sig_diff, "zone_rekey"));
+ CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
+ CHECK(zone_journal(zone, zonediff.diff, "zone_rekey"));
commit = ISC_TRUE;
}
}
@@ -14425,7 +14645,7 @@ zone_rekey(dns_zone_t *zone) {
* Cause the zone to add/delete NSEC3 chains for the
* deferred NSEC3PARAM changes.
*/
- for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
+ for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
tuple != NULL;
tuple = ISC_LIST_NEXT(tuple, link)) {
unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
@@ -14500,7 +14720,7 @@ zone_rekey(dns_zone_t *zone) {
failure:
dns_diff_clear(&diff);
- dns_diff_clear(&sig_diff);
+ dns_diff_clear(&_sig_diff);
clear_keylist(&dnskeys, mctx);
clear_keylist(&keys, mctx);
diff --git a/lib/export/dns/Makefile.in b/lib/export/dns/Makefile.in
index 6df36fe..f575f86 100644
--- a/lib/export/dns/Makefile.in
+++ b/lib/export/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009-2013 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
@@ -43,8 +43,9 @@ LIBS = @LIBS@
# Alphabetically
+OPENSSLGOSTLINKOBJS = opensslgost_link.@O@
OPENSSLLINKOBJS = openssl_link.@O@ openssldh_link.@O@ openssldsa_link.@O@ \
- opensslecdsa_link.@O@ opensslgost_link.@O@ opensslrsa_link.@O@
+ opensslecdsa_link.@O@ @OPENSSLGOSTLINKOBJS@ opensslrsa_link.@O@
DSTOBJS = @OPENSSLLINKOBJS@ \
dst_api.@O@ dst_lib.@O@ dst_parse.@O@ dst_result.@O@ \
@@ -71,8 +72,9 @@ OBJS= ${DNSOBJS} ${OTHEROBJS} ${DSTOBJS} ${PORTDNSOBJS}
# Alphabetically
+OPENSSLGOSTLINKSRCS = opensslgost_link.c
OPENSSLLINKSRCS = openssl_link.c openssldh_link.c openssldsa_link.c \
- opensslecdsa_link.c opensslgost_link.c opensslrsa_link.c
+ opensslecdsa_link.c @OPENSSLGOSTLINKSRCS@ opensslrsa_link.c
DSTSRCS = @OPENSSLLINKSRCS@ \
dst_api.c dst_lib.c dst_parse.c \
diff --git a/lib/export/irs/Makefile.in b/lib/export/irs/Makefile.in
index 2cbc0bb..b2520f9 100644
--- a/lib/export/irs/Makefile.in
+++ b/lib/export/irs/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2011-2013 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
@@ -24,8 +24,9 @@ export_srcdir = @top_srcdir@/lib/export
@BIND9_MAKE_INCLUDES@
-CINCLUDES = -I. -I./include -I${srcdir}/include \
+CINCLUDES = -I. -I./include -I${srcdir}/include -I ../../irs/include \
${ISCCFG_INCLUDES} -I../dns/include ${DNS_INCLUDES} \
+ -I../dns/include ${DNS_INCLUDES} \
-I${export_srcdir}/isc/include ${ISC_INCLUDES}
CDEFINES =
CWARNINGS =
diff --git a/lib/export/isc/Makefile.in b/lib/export/isc/Makefile.in
index 86726ab..c04a907 100644
--- a/lib/export/isc/Makefile.in
+++ b/lib/export/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2010, 2012, 2013 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
@@ -67,12 +67,11 @@ OBJS = @ISC_EXTRA_OBJS@ \
error.@O@ event.@O@ \
hash.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@ \
inet_aton.@O@ iterated_hash.@O@ lex.@O@ lfsr.@O@ log.@O@ \
- md5.@O@ mutexblock.@O@ \
- netaddr.@O@ netscope.@O@ \
- ondestroy.@O@ \
- parseint.@O@ portset.@O@ radix.@O@ \
- random.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \
- serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ string.@O@ \
+ md5.@O@ mutexblock.@O@ netaddr.@O@ netscope.@O@ \
+ ondestroy.@O@ parseint.@O@ portset.@O@ radix.@O@ \
+ random.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \
+ rwlock.@O@ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ \
+ stats.@O@ string.@O@ \
symtab.@O@ \
version.@O@ \
${APIOBJS} ${ISCDRIVEROBJS} \
@@ -94,7 +93,7 @@ SRCS = @ISC_EXTRA_SRCS@ \
netaddr.c netscope.c \
ondestroy.c \
parseint.c portset.c radix.c \
- random.c refcount.c region.c result.c rwlock.c \
+ random.c refcount.c region.c regex.c result.c rwlock.c \
serial.c sha1.c sha2.c sockaddr.c stats.c string.c symtab.c \
version.c \
${APISRCS} ${ISCDRIVERSRCS}
diff --git a/lib/export/isc/include/isc/Makefile.in b/lib/export/isc/include/isc/Makefile.in
index 91f538c..8c7eff8 100644
--- a/lib/export/isc/include/isc/Makefile.in
+++ b/lib/export/isc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012, 2013 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
@@ -35,7 +35,7 @@ HEADERS = app.h assertions.h base64.h bitstring.h boolean.h \
magic.h md5.h mem.h msgcat.h msgs.h \
mutexblock.h namespace.h netaddr.h ondestroy.h os.h parseint.h \
print.h quota.h radix.h random.h ratelimiter.h \
- refcount.h region.h resource.h \
+ refcount.h regex.h region.h resource.h \
result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
sockaddr.h socket.h stdio.h stdlib.h string.h \
symtab.h \
diff --git a/lib/export/isc/nls/Makefile.in b/lib/export/isc/nls/Makefile.in
index 2515685..16a6a86 100644
--- a/lib/export/isc/nls/Makefile.in
+++ b/lib/export/isc/nls/Makefile.in
@@ -16,10 +16,12 @@
top_srcdir = @top_srcdir@
srcdir = @top_srcdir@/lib/isc/nls
+export_srcdir = @top_srcdir@/lib/export
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I${srcdir}/unix/include \
+ -I${export_srcdir}/isc/include \
${ISC_INCLUDES}
CDEFINES =
diff --git a/lib/export/isc/nothreads/Makefile.in b/lib/export/isc/nothreads/Makefile.in
index 994da63..4640993 100644
--- a/lib/export/isc/nothreads/Makefile.in
+++ b/lib/export/isc/nothreads/Makefile.in
@@ -16,11 +16,13 @@
top_srcdir = @top_srcdir@
srcdir = @top_srcdir@/lib/isc/nothreads
+export_srcdir = @top_srcdir@/lib/export
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../unix/include \
+ -I${export_srcdir}/isc/include \
-I../include \
-I${srcdir}/../include \
-I${srcdir}/..
diff --git a/lib/export/isc/pthreads/Makefile.in b/lib/export/isc/pthreads/Makefile.in
index f08e5c6..80c5e3b 100644
--- a/lib/export/isc/pthreads/Makefile.in
+++ b/lib/export/isc/pthreads/Makefile.in
@@ -16,11 +16,13 @@
top_srcdir = @top_srcdir@
srcdir = @top_srcdir@/lib/isc/pthreads
+export_srcdir = @top_srcdir@/lib/export
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../unix/include \
+ -I${export_srcdir}/isc/include \
-I../include \
-I${srcdir}/../include \
-I${srcdir}/..
diff --git a/lib/export/isc/unix/Makefile.in b/lib/export/isc/unix/Makefile.in
index f5cf7e8..1873202 100644
--- a/lib/export/isc/unix/Makefile.in
+++ b/lib/export/isc/unix/Makefile.in
@@ -16,11 +16,13 @@
top_srcdir = @top_srcdir@
srcdir = @top_srcdir@/lib/isc/unix
+export_srcdir = @top_srcdir@/lib/export
@BIND9_MAKE_INCLUDES@
CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../@ISC_THREAD_DIR@/include \
+ -I${export_srcdir}/isc/include \
-I../include \
-I${srcdir}/../include \
-I${srcdir}/..
diff --git a/lib/export/isccfg/Makefile.in b/lib/export/isccfg/Makefile.in
index 907af50..2a791a4 100644
--- a/lib/export/isccfg/Makefile.in
+++ b/lib/export/isccfg/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2011-2013 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
@@ -31,7 +31,7 @@ CDEFINES =
CWARNINGS =
ISCLIBS = ../isc/libisc.@A@
-DNSLIBS = ../dns/libdns.@A@
+DNSLIBS = ../dns/libdns.@A@ @DNS_CRYPTO_LIBS@
ISCDEPLIBS = ../../lib/isc/libisc.@A@
ISCCFGDEPLIBS = libisccfg.@A@
diff --git a/lib/export/samples/Makefile.in b/lib/export/samples/Makefile.in
index cdc66b1..194aaeb 100644
--- a/lib/export/samples/Makefile.in
+++ b/lib/export/samples/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2009, 2012, 2013 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
@@ -25,7 +25,8 @@ export_srcdir = @top_srcdir@/lib/export
CINCLUDES = -I${srcdir}/include -I../dns/include \
-I${export_srcdir}/isc/include \
${DNS_INCLUDES} ${ISC_INCLUDES} \
- -I${top_srcdir}/lib/irs/include
+ -I${top_srcdir}/lib/irs/include \
+ -I../../irs/include
CDEFINES =
CWARNINGS =
diff --git a/lib/export/samples/nsprobe.c b/lib/export/samples/nsprobe.c
index 869b194..1d7ed3b 100644
--- a/lib/export/samples/nsprobe.c
+++ b/lib/export/samples/nsprobe.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009-2013 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
@@ -282,8 +282,6 @@ make_querymessage(dns_message_t *message, dns_name_t *qname0,
dns_message_puttempname(message, &qname);
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
- if (message != NULL)
- dns_message_destroy(&message);
return (result);
}
@@ -293,7 +291,7 @@ make_querymessage(dns_message_t *message, dns_name_t *qname0,
static inline void
increment_entry(unsigned long *entryp) {
(*entryp)++;
- INSIST(*entryp != 0); /* check overflow */
+ INSIST(*entryp != 0U); /* check overflow */
}
static void
@@ -392,57 +390,57 @@ update_stat(struct probe_trans *trans) {
}
/* Update per domain statistics */
- if (local_stat.ignore > 0) {
+ if (local_stat.ignore > 0U) {
if (verbose_level > 0)
printf("%s:ignore\n", trans->domain);
increment_entry(&domain_stat.ignore);
err_count++;
}
- if (local_stat.nxdomain > 0) {
+ if (local_stat.nxdomain > 0U) {
if (verbose_level > 0)
printf("%s:nxdomain\n", trans->domain);
increment_entry(&domain_stat.nxdomain);
err_count++;
}
- if (local_stat.othererr > 0) {
+ if (local_stat.othererr > 0U) {
if (verbose_level > 0)
printf("%s:othererr\n", trans->domain);
increment_entry(&domain_stat.othererr);
err_count++;
}
- if (local_stat.multiplesoa > 0) {
+ if (local_stat.multiplesoa > 0U) {
if (verbose_level > 0)
printf("%s:multiplesoa\n", trans->domain);
increment_entry(&domain_stat.multiplesoa);
err_count++;
}
- if (local_stat.multiplecname > 0) {
+ if (local_stat.multiplecname > 0U) {
if (verbose_level > 0)
printf("%s:multiplecname\n", trans->domain);
increment_entry(&domain_stat.multiplecname);
err_count++;
}
- if (local_stat.brokenanswer > 0) {
+ if (local_stat.brokenanswer > 0U) {
if (verbose_level > 0)
printf("%s:brokenanswer\n", trans->domain);
increment_entry(&domain_stat.brokenanswer);
err_count++;
}
- if (local_stat.lame > 0) {
+ if (local_stat.lame > 0U) {
if (verbose_level > 0)
printf("%s:lame\n", trans->domain);
increment_entry(&domain_stat.lame);
err_count++;
}
- if (err_count > 1)
+ if (err_count > 1U)
increment_entry(&multiple_error_domains);
/*
* We regard the domain as valid if and only if no authoritative server
* has a problem and at least one server is known to be valid.
*/
- if (local_stat.valid > 0 && err_count == 0) {
+ if (local_stat.valid > 0U && err_count == 0U) {
if (verbose_level > 1)
printf("%s:valid\n", trans->domain);
increment_entry(&domain_stat.valid);
@@ -452,7 +450,7 @@ update_stat(struct probe_trans *trans) {
* If the domain has no available server or all servers have the
* 'unknown' result, the domain's result is also regarded as unknown.
*/
- if (local_stat.valid == 0 && err_count == 0) {
+ if (local_stat.valid == 0U && err_count == 0U) {
if (verbose_level > 1)
printf("%s:unknown\n", trans->domain);
increment_entry(&domain_stat.unknown);
@@ -1218,5 +1216,5 @@ main(int argc, char *argv[]) {
isc_app_ctxfinish(actx);
ctxs_destroy(&mctx, &actx, &taskmgr, &socketmgr, &timermgr);
- exit(0);
+ return (0);
}
diff --git a/lib/export/samples/sample-async.c b/lib/export/samples/sample-async.c
index e646e79..a70dd47 100644
--- a/lib/export/samples/sample-async.c
+++ b/lib/export/samples/sample-async.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2013 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
@@ -398,5 +398,5 @@ main(int argc, char *argv[]) {
isc_app_ctxfinish(query_actx);
ctxs_destroy(&mctx, &query_actx, &taskmgr, &socketmgr, &timermgr);
- exit(0);
+ return (0);
}
diff --git a/lib/export/samples/sample-gai.c b/lib/export/samples/sample-gai.c
index 6dc4014..243d07a 100644
--- a/lib/export/samples/sample-gai.c
+++ b/lib/export/samples/sample-gai.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2012, 2013 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
@@ -61,7 +61,7 @@ do_gai(int family, char *hostname) {
}
}
- freeaddrinfo(res);
+ freeaddrinfo(res0);
}
int
@@ -73,5 +73,5 @@ main(int argc, char *argv[]) {
do_gai(AF_INET6, argv[1]);
do_gai(AF_UNSPEC, argv[1]);
- exit(0);
+ return (0);
}
diff --git a/lib/export/samples/sample-request.c b/lib/export/samples/sample-request.c
index d5d2312..07baf39 100644
--- a/lib/export/samples/sample-request.c
+++ b/lib/export/samples/sample-request.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2012, 2013 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
@@ -77,9 +77,12 @@ make_querymessage(dns_message_t *message, const char *namestr,
isc_buffer_t b;
size_t namelen;
+ REQUIRE(message != NULL);
+ REQUIRE(namestr != NULL);
+
/* Construct qname */
namelen = strlen(namestr);
- isc_buffer_init(&b, namestr, namelen);
+ isc_buffer_constinit(&b, namestr, namelen);
isc_buffer_add(&b, namelen);
dns_fixedname_init(&fixedqname);
qname0 = dns_fixedname_name(&fixedqname);
@@ -115,8 +118,7 @@ make_querymessage(dns_message_t *message, const char *namestr,
dns_message_puttempname(message, &qname);
if (qrdataset != NULL)
dns_message_puttemprdataset(message, &qrdataset);
- if (message != NULL)
- dns_message_destroy(&message);
+ dns_message_destroy(&message);
return (result);
}
@@ -259,5 +261,5 @@ main(int argc, char *argv[]) {
dns_client_destroy(&client);
dns_lib_shutdown();
- exit(0);
+ return (0);
}
diff --git a/lib/export/samples/sample-update.c b/lib/export/samples/sample-update.c
index e54d154..2c35baa 100644
--- a/lib/export/samples/sample-update.c
+++ b/lib/export/samples/sample-update.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2010, 2012, 2013 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
@@ -305,7 +305,7 @@ main(int argc, char *argv[]) {
dns_client_destroy(&client);
dns_lib_shutdown();
- exit(0);
+ return (0);
}
/*
@@ -372,7 +372,7 @@ parse_name(char **cmdlinep, dns_name_t *name) {
isc_buffer_t source;
word = nsu_strsep(cmdlinep, " \t\r\n");
- if (*word == 0) {
+ if (word == NULL || *word == 0) {
fprintf(stderr, "could not read owner name\n");
exit(1);
}
diff --git a/lib/export/samples/sample.c b/lib/export/samples/sample.c
index 7fc6a30..b121a0d 100644
--- a/lib/export/samples/sample.c
+++ b/lib/export/samples/sample.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2012, 2013 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
@@ -172,7 +172,9 @@ set_key(dns_client_t *client, char *keynamestr, char *keystr,
}
static void
-addserver(dns_client_t *client, const char *addrstr, const char *namespace) {
+addserver(dns_client_t *client, const char *addrstr, const char *port,
+ const char *namespace)
+{
struct addrinfo hints, *res;
int gai_error;
isc_sockaddr_t sa;
@@ -188,7 +190,7 @@ addserver(dns_client_t *client, const char *addrstr, const char *namespace) {
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
hints.ai_flags = AI_NUMERICHOST;
- gai_error = getaddrinfo(addrstr, "53", &hints, &res);
+ gai_error = getaddrinfo(addrstr, port, &hints, &res);
if (gai_error != 0) {
fprintf(stderr, "getaddrinfo failed: %s\n",
gai_strerror(gai_error));
@@ -196,15 +198,15 @@ addserver(dns_client_t *client, const char *addrstr, const char *namespace) {
}
INSIST(res->ai_addrlen <= sizeof(sa.type));
memcpy(&sa.type, res->ai_addr, res->ai_addrlen);
- freeaddrinfo(res);
sa.length = res->ai_addrlen;
+ freeaddrinfo(res);
ISC_LINK_INIT(&sa, link);
ISC_LIST_INIT(servers);
ISC_LIST_APPEND(servers, &sa, link);
if (namespace != NULL) {
namelen = strlen(namespace);
- isc_buffer_init(&b, namespace, namelen);
+ isc_buffer_constinit(&b, namespace, namelen);
isc_buffer_add(&b, namelen);
dns_fixedname_init(&fname);
name = dns_fixedname_name(&fname);
@@ -245,8 +247,9 @@ main(int argc, char *argv[]) {
isc_mem_t *keymctx = NULL;
unsigned int clientopt, resopt;
isc_boolean_t is_sep = ISC_FALSE;
+ const char *port = "53";
- while ((ch = getopt(argc, argv, "a:es:t:k:K:")) != -1) {
+ while ((ch = getopt(argc, argv, "a:es:t:k:K:p:")) != -1) {
switch (ch) {
case 't':
tr.base = optarg;
@@ -279,6 +282,9 @@ main(int argc, char *argv[]) {
case 'K':
keystr = optarg;
break;
+ case 'p':
+ port = optarg;
+ break;
default:
usage();
}
@@ -318,11 +324,11 @@ main(int argc, char *argv[]) {
}
/* Set the nameserver */
- addserver(client, argv[0], NULL);
+ addserver(client, argv[0], port, NULL);
/* Set the alternate nameserver (when specified) */
if (altserver != NULL)
- addserver(client, altserveraddr, altservername);
+ addserver(client, altserveraddr, port, altservername);
/* Install DNSSEC key (if given) */
if (keynamestr != NULL) {
@@ -374,5 +380,5 @@ main(int argc, char *argv[]) {
isc_mem_destroy(&keymctx);
dns_lib_shutdown();
- exit(0);
+ return (0);
}
diff --git a/lib/irs/api b/lib/irs/api
index ba19dd9..5c8dd5e 100644
--- a/lib/irs/api
+++ b/lib/irs/api
@@ -1,8 +1,9 @@
# LIBINTERFACE ranges
# 9.6: 50-59, 110-119
# 9.7: 60-79
-# 9.8: 80-89
+# 9.8: 80-89, 120-129
# 9.9: 90-109
+# 9.9-sub: 130-139
LIBINTERFACE = 80
-LIBREVISION = 2
+LIBREVISION = 4
LIBAGE = 0
diff --git a/lib/irs/dnsconf.c b/lib/irs/dnsconf.c
index 4a7d58b..529cebd 100644
--- a/lib/irs/dnsconf.c
+++ b/lib/irs/dnsconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -144,8 +144,8 @@ configure_dnsseckeys(irs_dnsconf_t *conf, cfg_obj_t *cfgobj,
/* Configure key name */
dns_fixedname_init(&fkeyname);
keyname_base = dns_fixedname_name(&fkeyname);
- isc_buffer_init(&namebuf, keynamestr,
- strlen(keynamestr));
+ isc_buffer_constinit(&namebuf, keynamestr,
+ strlen(keynamestr));
isc_buffer_add(&namebuf, strlen(keynamestr));
result = dns_name_fromtext(keyname_base, &namebuf,
dns_rootname, 0, NULL);
diff --git a/lib/irs/getaddrinfo.c b/lib/irs/getaddrinfo.c
index 4b1f4a9..1de540f 100644
--- a/lib/irs/getaddrinfo.c
+++ b/lib/irs/getaddrinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2012, 2013 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
@@ -136,6 +136,7 @@
#include <isc/lib.h>
#include <isc/mem.h>
#include <isc/sockaddr.h>
+#include <isc/string.h>
#include <isc/util.h>
#include <dns/client.h>
@@ -479,8 +480,10 @@ getaddrinfo(const char *hostname, const char *servname,
err = (net_order[i])(hostname, flags, &ai_list,
socktype, port);
if (err != 0) {
- if (ai_list != NULL)
+ if (ai_list != NULL) {
freeaddrinfo(ai_list);
+ ai_list = NULL;
+ }
break;
}
}
@@ -549,7 +552,7 @@ make_resstate(isc_mem_t *mctx, gai_statehead_t *head, const char *hostname,
/* Construct base domain name */
namelen = strlen(domain);
- isc_buffer_init(&b, domain, namelen);
+ isc_buffer_constinit(&b, domain, namelen);
isc_buffer_add(&b, namelen);
dns_fixedname_init(&fixeddomain);
qdomain = dns_fixedname_name(&fixeddomain);
@@ -561,7 +564,7 @@ make_resstate(isc_mem_t *mctx, gai_statehead_t *head, const char *hostname,
/* Construct query name */
namelen = strlen(hostname);
- isc_buffer_init(&b, hostname, namelen);
+ isc_buffer_constinit(&b, hostname, namelen);
isc_buffer_add(&b, namelen);
dns_fixedname_init(&state->fixedname);
state->qname = dns_fixedname_name(&state->fixedname);
@@ -781,9 +784,9 @@ process_answer(isc_task_t *task, isc_event_t *event) {
switch (family) {
case AF_INET:
dns_rdataset_current(rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &rdata_a,
- NULL);
-
+ result = dns_rdata_tostruct(&rdata, &rdata_a,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
SIN(ai->ai_addr)->sin_port =
resstate->head->ai_port;
memcpy(&SIN(ai->ai_addr)->sin_addr,
@@ -792,8 +795,9 @@ process_answer(isc_task_t *task, isc_event_t *event) {
break;
case AF_INET6:
dns_rdataset_current(rdataset, &rdata);
- dns_rdata_tostruct(&rdata, &rdata_aaaa,
- NULL);
+ result = dns_rdata_tostruct(&rdata, &rdata_aaaa,
+ NULL);
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
SIN6(ai->ai_addr)->sin6_port =
resstate->head->ai_port;
memcpy(&SIN6(ai->ai_addr)->sin6_addr,
@@ -1143,10 +1147,8 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
UNUSED(flags);
ai = ai_clone(*aip, AF_INET6); /* don't use ai_clone() */
- if (ai == NULL) {
- freeaddrinfo(*aip);
+ if (ai == NULL)
return (EAI_MEMORY);
- }
*aip = ai;
ai->ai_socktype = socktype;
@@ -1186,7 +1188,7 @@ get_local(const char *name, int socktype, struct addrinfo **res) {
return (EAI_MEMORY);
slocal = SLOCAL(ai->ai_addr);
- strncpy(slocal->sun_path, name, sizeof(slocal->sun_path));
+ strlcpy(slocal->sun_path, name, sizeof(slocal->sun_path));
ai->ai_socktype = socktype;
/*
diff --git a/lib/irs/getnameinfo.c b/lib/irs/getnameinfo.c
index 80e3677..526ad09 100644
--- a/lib/irs/getnameinfo.c
+++ b/lib/irs/getnameinfo.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2011-2013 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
@@ -147,7 +147,7 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
IRS_GETNAMEINFO_BUFLEN_T hostlen, char *serv,
IRS_GETNAMEINFO_BUFLEN_T servlen, IRS_GETNAMEINFO_FLAGS_T flags)
{
- struct afd *afd;
+ struct afd *afd = NULL;
struct servent *sp;
unsigned short port = 0;
#ifdef IRS_PLATFORM_HAVESALEN
@@ -328,6 +328,7 @@ getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host,
case DNS_R_NOVALIDDS:
case DNS_R_NOVALIDSIG:
ERR(EAI_INSECUREDATA);
+ break;
default:
ERR(EAI_FAIL);
}
diff --git a/lib/irs/resconf.c b/lib/irs/resconf.c
index 18525e8..88bdac1 100644
--- a/lib/irs/resconf.c
+++ b/lib/irs/resconf.c
@@ -238,7 +238,7 @@ add_server(isc_mem_t *mctx, const char *address_str,
goto cleanup;
}
address->length = res->ai_addrlen;
- memcpy(&address->type.sa, res->ai_addr, res->ai_addrlen);
+ memcpy(&address->type.ss, res->ai_addr, res->ai_addrlen);
ISC_LINK_INIT(address, link);
ISC_LIST_APPEND(*nameservers, address, link);
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in
index ff500ff..2fa5633 100644
--- a/lib/isc/Makefile.in
+++ b/lib/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -60,7 +60,8 @@ OBJS = @ISC_EXTRA_OBJS@ \
md5.@O@ mem.@O@ mutexblock.@O@ \
netaddr.@O@ netscope.@O@ ondestroy.@O@ \
parseint.@O@ portset.@O@ quota.@O@ radix.@O@ random.@O@ \
- ratelimiter.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \
+ ratelimiter.@O@ refcount.@O@ region.@O@ regex.@O@ result.@O@ \
+ rwlock.@O@ \
serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ stats.@O@ \
string.@O@ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ \
timer.@O@ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
@@ -76,7 +77,7 @@ SRCS = @ISC_EXTRA_SRCS@ \
md5.c mem.c mutexblock.c \
netaddr.c netscope.c ondestroy.c \
parseint.c portset.c quota.c radix.c random.c \
- ratelimiter.c refcount.c region.c result.c rwlock.c \
+ ratelimiter.c refcount.c region.c regex.c result.c rwlock.c \
serial.c sha1.c sha2.c sockaddr.c stats.c string.c strtoul.c \
symtab.c symtbl-empty.c task.c taskpool.c timer.c version.c
diff --git a/lib/isc/api b/lib/isc/api
index 18de29c..c7d2813 100644
--- a/lib/isc/api
+++ b/lib/isc/api
@@ -1,8 +1,9 @@
# LIBINTERFACE ranges
# 9.6: 50-59, 110-119
# 9.7: 60-79
-# 9.8: 80-89
+# 9.8: 80-89, 120-129
# 9.9: 90-109
-LIBINTERFACE = 85
-LIBREVISION = 0
-LIBAGE = 1
+# 9.9-sub: 130-139
+LIBINTERFACE = 87
+LIBREVISION = 1
+LIBAGE = 3
diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c
index 1b59e65..e37af15 100644
--- a/lib/isc/buffer.c
+++ b/lib/isc/buffer.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) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -28,7 +28,7 @@
#include <isc/util.h>
void
-isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length) {
+isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length) {
/*
* Make 'b' refer to the 'length'-byte region starting at 'base'.
* XXXDCL see the comment in buffer.h about base being const.
diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in
index b8acdb5..8afcfa7 100644
--- a/lib/isc/include/isc/Makefile.in
+++ b/lib/isc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2009, 2012, 2013 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
@@ -36,7 +36,7 @@ HEADERS = app.h assertions.h base64.h bind9.h bitstring.h boolean.h \
magic.h md5.h mem.h msgcat.h msgs.h mutexblock.h \
namespace.h netaddr.h ondestroy.h os.h parseint.h \
print.h quota.h radix.h random.h ratelimiter.h \
- refcount.h region.h resource.h \
+ refcount.h regex.h region.h resource.h \
result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
sockaddr.h socket.h stdio.h stdlib.h string.h \
symtab.h \
diff --git a/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h
index ae7e4c3..72b8560 100644
--- a/lib/isc/include/isc/buffer.h
+++ b/lib/isc/include/isc/buffer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -222,7 +222,7 @@ isc_buffer_free(isc_buffer_t **dynbuffer);
*/
void
-isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length);
+isc__buffer_init(isc_buffer_t *b, void *base, unsigned int length);
/*!<
* \brief Make 'b' refer to the 'length'-byte region starting at base.
*
@@ -681,12 +681,7 @@ ISC_LANG_ENDDECLS
*/
#define ISC__BUFFER_INIT(_b, _base, _length) \
do { \
- union { \
- const void * konst; \
- void * var; \
- } _u; \
- _u.konst = (_base); \
- (_b)->base = _u.var; \
+ (_b)->base = _base; \
(_b)->length = (_length); \
(_b)->used = 0; \
(_b)->current = 0; \
@@ -896,6 +891,13 @@ ISC_LANG_ENDDECLS
#define isc_buffer_putuint32 isc__buffer_putuint32
#endif
+#define isc_buffer_constinit(_b, _d, _l) \
+ do { \
+ union { void *_var; const void *_const; } _deconst; \
+ _deconst._const = (_d); \
+ isc_buffer_init((_b), _deconst._var, (_l)); \
+ } while (0)
+
/*
* No inline method for this one (yet).
*/
diff --git a/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h
index 38f78b7..92ea96e 100644
--- a/lib/isc/include/isc/file.h
+++ b/lib/isc/include/isc/file.h
@@ -115,8 +115,8 @@ 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.
+ * 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
@@ -217,6 +217,22 @@ isc_file_isplainfile(const char *name);
* These occur when stat returns -1 and an errno.
*/
+isc_result_t
+isc_file_isdirectory(const char *name);
+/*!<
+ * \brief Check that 'name' exists and is a directory.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * Success, file is a directory.
+ *\li #ISC_R_INVALIDFILE
+ * File is not a directory.
+ *\li #ISC_R_FILENOTFOUND
+ * File does not exist.
+ *\li #other ISC_R_* errors translated from errno
+ * These occur when stat returns -1 and an errno.
+ */
+
isc_boolean_t
isc_file_iscurrentdir(const char *filename);
/*!<
diff --git a/lib/isc/include/isc/list.h b/lib/isc/include/isc/list.h
index 4056be2..2b174ec 100644
--- a/lib/isc/include/isc/list.h
+++ b/lib/isc/include/isc/list.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2006, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2006, 2007, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1997-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -102,6 +102,8 @@
} \
(elt)->link.prev = (type *)(-1); \
(elt)->link.next = (type *)(-1); \
+ ISC_INSIST((list).head != (elt)); \
+ ISC_INSIST((list).tail != (elt)); \
} while (0)
#define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \
diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h
index c47ae55..317417f 100644
--- a/lib/isc/include/isc/mem.h
+++ b/lib/isc/include/isc/mem.h
@@ -40,15 +40,6 @@ typedef void * (*isc_memalloc_t)(void *, size_t);
typedef void (*isc_memfree_t)(void *, void *);
/*%
- * Define ISC_MEM_DEBUG=1 to make all functions that free memory
- * set the pointer being freed to NULL after being freed.
- * This is the default; set ISC_MEM_DEBUG=0 to disable it.
- */
-#ifndef ISC_MEM_DEBUG
-#define ISC_MEM_DEBUG 1
-#endif
-
-/*%
* Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory
* allocation and freeing by file and line number.
*/
@@ -274,7 +265,6 @@ struct isc_mempool {
#define ISCAPI_MPOOL_VALID(mp) ((mp) != NULL && \
(mp)->magic == ISCAPI_MPOOL_MAGIC)
-#if ISC_MEM_DEBUG
#define isc_mem_put(c, p, s) \
do { \
ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE); \
@@ -295,13 +285,6 @@ struct isc_mempool {
ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE); \
(p) = NULL; \
} while (0)
-#else
-#define isc_mem_put(c, p, s) ISCMEMFUNC(put)((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_putanddetach(c, p, s) \
- ISCMEMFUNC(putanddetach)((c), (p), (s) _ISC_MEM_FILELINE)
-#define isc_mem_free(c, p) ISCMEMFUNC(free)((c), (p) _ISC_MEM_FILELINE)
-#define isc_mempool_put(c, p) ISCMEMPOOLFUNC(put)((c), (p) _ISC_MEM_FILELINE)
-#endif
/*@{*/
isc_result_t
@@ -548,7 +531,7 @@ isc_mem_gettag(isc_mem_t *ctx);
*/
#ifdef HAVE_LIBXML2
-void
+int
isc_mem_renderxml(xmlTextWriterPtr writer);
/*%<
* Render all contexts' statistics and status in XML for writer.
diff --git a/lib/isc/include/isc/namespace.h b/lib/isc/include/isc/namespace.h
index ae1801d..45b769c 100644
--- a/lib/isc/include/isc/namespace.h
+++ b/lib/isc/include/isc/namespace.h
@@ -70,6 +70,7 @@
#define isc_mem_isovermem isc__mem_isovermem
#define isc_mem_setname isc__mem_setname
#define isc_mem_setwater isc__mem_setwater
+#define isc_mem_printactive isc__mem_printactive
#define isc_mem_printallactive isc__mem_printallactive
#define isc_mem_waterack isc__mem_waterack
#define isc_mempool_create isc__mempool_create
diff --git a/lib/isc/include/isc/regex.h b/lib/isc/include/isc/regex.h
new file mode 100644
index 0000000..3cf6aa4
--- /dev/null
+++ b/lib/isc/include/isc/regex.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2013 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ISC_REGEX_H
+#define ISC_REGEX_H 1
+
+/*! \file isc/regex.h */
+
+#include <isc/types.h>
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+int
+isc_regex_validate(const char *expression);
+/*%<
+ * Check a regular expression for syntactic correctness.
+ *
+ * Returns:
+ *\li -1 on error.
+ *\li the number of groups in the expression.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_REGEX_H */
diff --git a/lib/isc/include/isc/region.h b/lib/isc/include/isc/region.h
index 43d8f8f..ccca272 100644
--- a/lib/isc/include/isc/region.h
+++ b/lib/isc/include/isc/region.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -23,6 +23,7 @@
/*! \file isc/region.h */
#include <isc/types.h>
+#include <isc/lang.h>
struct isc_region {
unsigned char * base;
@@ -81,12 +82,14 @@ struct isc_consttextregion {
} while (0)
/*@}*/
+ISC_LANG_BEGINDECLS
+
int
isc_region_compare(isc_region_t *r1, isc_region_t *r2);
/*%<
- * Compares the contents of two regions
+ * Compares the contents of two regions
*
- * Requires:
+ * Requires:
*\li 'r1' is a valid region
*\li 'r2' is a valid region
*
@@ -96,4 +99,6 @@ isc_region_compare(isc_region_t *r1, isc_region_t *r2);
*\li > 0 if r1 is lexicographically greater than r2
*/
+ISC_LANG_ENDDECLS
+
#endif /* ISC_REGION_H */
diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h
index 1e69142..4d811dd 100644
--- a/lib/isc/include/isc/sockaddr.h
+++ b/lib/isc/include/isc/sockaddr.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) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -34,6 +34,7 @@ struct isc_sockaddr {
struct sockaddr sa;
struct sockaddr_in sin;
struct sockaddr_in6 sin6;
+ struct sockaddr_storage ss;
#ifdef ISC_PLATFORM_HAVESYSUNH
struct sockaddr_un sunix;
#endif
diff --git a/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h
index 0df7d27..4111ec2 100644
--- a/lib/isc/include/isc/socket.h
+++ b/lib/isc/include/isc/socket.h
@@ -1116,7 +1116,7 @@ isc__socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp);
#ifdef HAVE_LIBXML2
-void
+int
isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer);
/*%<
* Render internal statistics and other state into the XML document.
diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h
index 19d4783..ced7059 100644
--- a/lib/isc/include/isc/task.h
+++ b/lib/isc/include/isc/task.h
@@ -726,7 +726,7 @@ isc_taskmgr_excltask(isc_taskmgr_t *mgr, isc_task_t **taskp);
#ifdef HAVE_LIBXML2
-void
+int
isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer);
#endif
diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h
index fa9abb1..0598f79 100644
--- a/lib/isc/include/isc/timer.h
+++ b/lib/isc/include/isc/timer.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -108,8 +108,8 @@ typedef struct {
void (*destroy)(isc_timermgr_t **managerp);
isc_result_t (*timercreate)(isc_timermgr_t *manager,
isc_timertype_t type,
- isc_time_t *expires,
- isc_interval_t *interval,
+ const isc_time_t *expires,
+ const isc_interval_t *interval,
isc_task_t *task,
isc_taskaction_t action,
const void *arg,
@@ -120,7 +120,8 @@ typedef struct {
void (*attach)(isc_timer_t *timer, isc_timer_t **timerp);
void (*detach)(isc_timer_t **timerp);
isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
+ const isc_time_t *expires,
+ const isc_interval_t *interval,
isc_boolean_t purge);
isc_result_t (*touch)(isc_timer_t *timer);
} isc_timermethods_t;
@@ -168,8 +169,8 @@ struct isc_timer {
isc_result_t
isc_timer_create(isc_timermgr_t *manager,
isc_timertype_t type,
- isc_time_t *expires,
- isc_interval_t *interval,
+ const isc_time_t *expires,
+ const isc_interval_t *interval,
isc_task_t *task,
isc_taskaction_t action,
const void *arg,
@@ -232,8 +233,8 @@ isc_timer_create(isc_timermgr_t *manager,
isc_result_t
isc_timer_reset(isc_timer_t *timer,
isc_timertype_t type,
- isc_time_t *expires,
- isc_interval_t *interval,
+ const isc_time_t *expires,
+ const isc_interval_t *interval,
isc_boolean_t purge);
/*%<
* Change the timer's type, expires, and interval values to the given
diff --git a/lib/isc/inet_aton.c b/lib/isc/inet_aton.c
index 14b4887..66a108d 100644
--- a/lib/isc/inet_aton.c
+++ b/lib/isc/inet_aton.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -91,7 +91,7 @@ static char rcsid[] = "$Id: inet_aton.c,v 1.23 2008/12/01 23:47:45 tbox Exp $";
*/
int
isc_net_aton(const char *cp, struct in_addr *addr) {
- unsigned long val;
+ isc_uint32_t val;
int base, n;
unsigned char c;
isc_uint8_t parts[4];
diff --git a/lib/isc/mem.c b/lib/isc/mem.c
index 1964b7a..20fec46 100644
--- a/lib/isc/mem.c
+++ b/lib/isc/mem.c
@@ -202,6 +202,7 @@ struct isc__mempool {
#if ! ISC_MEM_TRACKLINES
#define ADD_TRACE(a, b, c, d, e)
#define DELETE_TRACE(a, b, c, d, e)
+#define ISC_MEMFUNC_SCOPE
#else
#define ADD_TRACE(a, b, c, d, e) \
do { \
@@ -321,6 +322,7 @@ isc__mem_checkdestroyed(FILE *file);
ISC_MEMFUNC_SCOPE unsigned int
isc__mem_references(isc_mem_t *ctx0);
#endif
+#endif /* ISC_MEM_TRACKLINES */
static struct isc__memmethods {
isc_memmethods_t methods;
@@ -389,6 +391,7 @@ static struct isc__mempoolmethods {
#endif
};
+#if ISC_MEM_TRACKLINES
/*!
* mctx must be locked.
*/
@@ -1478,7 +1481,12 @@ isc__mem_stats(isc_mem_t *ctx0, FILE *out) {
}
while (pool != NULL) {
fprintf(out, "%15s %10lu %10u %10u %10u %10u %10u %10u %s\n",
- pool->name, (unsigned long) pool->size, pool->maxalloc,
+#if ISC_MEMPOOL_NAMES
+ pool->name,
+#else
+ "(not tracked)",
+#endif
+ (unsigned long) pool->size, pool->maxalloc,
pool->allocated, pool->freecount, pool->freemax,
pool->fillcount, pool->gets,
(pool->lock == NULL ? "N" : "Y"));
@@ -2260,16 +2268,16 @@ isc__mem_register() {
#ifdef BIND9
ISC_MEMFUNC_SCOPE void
isc__mem_printactive(isc_mem_t *ctx0, FILE *file) {
+#if ISC_MEM_TRACKLINES
isc__mem_t *ctx = (isc__mem_t *)ctx0;
REQUIRE(VALID_CONTEXT(ctx));
REQUIRE(file != NULL);
-#if !ISC_MEM_TRACKLINES
- UNUSED(ctx);
- UNUSED(file);
-#else
print_active(ctx, file);
+#else
+ UNUSED(ctx0);
+ UNUSED(file);
#endif
}
@@ -2295,6 +2303,9 @@ isc__mem_printallactive(FILE *file) {
ISC_MEMFUNC_SCOPE void
isc__mem_checkdestroyed(FILE *file) {
+#if !ISC_MEM_TRACKLINES
+ UNUSED(file);
+#endif
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
@@ -2339,25 +2350,27 @@ typedef struct summarystat {
isc_uint64_t contextsize;
} summarystat_t;
-static void
+#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
+static int
renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
+ int xmlrc;
+
REQUIRE(VALID_CONTEXT(ctx));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "context");
+ MCTXLOCK(ctx, &ctx->lock);
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "context"));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "id");
- xmlTextWriterWriteFormatString(writer, "%p", ctx);
- xmlTextWriterEndElement(writer); /* id */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%p", ctx));
+ TRY0(xmlTextWriterEndElement(writer)); /* id */
if (ctx->name[0] != 0) {
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteFormatString(writer, "%s", ctx->name);
- xmlTextWriterEndElement(writer); /* name */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%s", ctx->name));
+ TRY0(xmlTextWriterEndElement(writer)); /* name */
}
- REQUIRE(VALID_CONTEXT(ctx));
- MCTXLOCK(ctx, &ctx->lock);
-
summary->contextsize += sizeof(*ctx) +
(ctx->max_size + 1) * sizeof(struct stats) +
ctx->max_size * sizeof(element *) +
@@ -2369,70 +2382,79 @@ renderctx(isc__mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
ctx->debuglistcnt * sizeof(debuglink_t);
}
#endif
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
- xmlTextWriterWriteFormatString(writer, "%d", ctx->references);
- xmlTextWriterEndElement(writer); /* references */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d", ctx->references));
+ TRY0(xmlTextWriterEndElement(writer)); /* references */
summary->total += ctx->total;
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "total");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- (isc_uint64_t)ctx->total);
- xmlTextWriterEndElement(writer); /* total */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "total"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ (isc_uint64_t)ctx->total));
+ TRY0(xmlTextWriterEndElement(writer)); /* total */
summary->inuse += ctx->inuse;
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- (isc_uint64_t)ctx->inuse);
- xmlTextWriterEndElement(writer); /* inuse */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- (isc_uint64_t)ctx->maxinuse);
- xmlTextWriterEndElement(writer); /* maxinuse */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ (isc_uint64_t)ctx->inuse));
+ TRY0(xmlTextWriterEndElement(writer)); /* inuse */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ (isc_uint64_t)ctx->maxinuse));
+ TRY0(xmlTextWriterEndElement(writer)); /* maxinuse */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize"));
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
summary->blocksize += ctx->basic_table_count *
NUM_BASIC_BLOCKS * ctx->mem_target;
- xmlTextWriterWriteFormatString(writer,
+ TRY0(xmlTextWriterWriteFormatString(writer,
"%" ISC_PRINT_QUADFORMAT "u",
(isc_uint64_t)
ctx->basic_table_count *
NUM_BASIC_BLOCKS *
- ctx->mem_target);
+ ctx->mem_target));
} else
- xmlTextWriterWriteFormatString(writer, "%s", "-");
- xmlTextWriterEndElement(writer); /* blocksize */
+ TRY0(xmlTextWriterWriteFormatString(writer, "%s", "-"));
+ TRY0(xmlTextWriterEndElement(writer)); /* blocksize */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools");
- xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt);
- xmlTextWriterEndElement(writer); /* pools */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt));
+ TRY0(xmlTextWriterEndElement(writer)); /* pools */
summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t);
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- (isc_uint64_t)ctx->hi_water);
- xmlTextWriterEndElement(writer); /* hiwater */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ (isc_uint64_t)ctx->hi_water));
+ TRY0(xmlTextWriterEndElement(writer)); /* hiwater */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- (isc_uint64_t)ctx->lo_water);
- xmlTextWriterEndElement(writer); /* lowater */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ (isc_uint64_t)ctx->lo_water));
+ TRY0(xmlTextWriterEndElement(writer)); /* lowater */
+ TRY0(xmlTextWriterEndElement(writer)); /* context */
+
+ error:
MCTXUNLOCK(ctx, &ctx->lock);
- xmlTextWriterEndElement(writer); /* context */
+ return (xmlrc);
}
-void
+int
isc_mem_renderxml(xmlTextWriterPtr writer) {
isc__mem_t *ctx;
summarystat_t summary;
isc_uint64_t lost;
+ int xmlrc;
memset(&summary, 0, sizeof(summary));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts"));
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
@@ -2441,40 +2463,51 @@ isc_mem_renderxml(xmlTextWriterPtr writer) {
for (ctx = ISC_LIST_HEAD(contexts);
ctx != NULL;
ctx = ISC_LIST_NEXT(ctx, link)) {
- renderctx(ctx, &summary, writer);
+ xmlrc = renderctx(ctx, &summary, writer);
+ if (xmlrc < 0) {
+ UNLOCK(&lock);
+ goto error;
+ }
}
UNLOCK(&lock);
- xmlTextWriterEndElement(writer); /* contexts */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary");
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- summary.total);
- xmlTextWriterEndElement(writer); /* TotalUse */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- summary.inuse);
- xmlTextWriterEndElement(writer); /* InUse */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- summary.blocksize);
- xmlTextWriterEndElement(writer); /* BlockSize */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- summary.contextsize);
- xmlTextWriterEndElement(writer); /* ContextSize */
-
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost");
- xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
- lost);
- xmlTextWriterEndElement(writer); /* Lost */
-
- xmlTextWriterEndElement(writer); /* summary */
+ TRY0(xmlTextWriterEndElement(writer)); /* contexts */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary"));
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ summary.total));
+ TRY0(xmlTextWriterEndElement(writer)); /* TotalUse */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ summary.inuse));
+ TRY0(xmlTextWriterEndElement(writer)); /* InUse */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ summary.blocksize));
+ TRY0(xmlTextWriterEndElement(writer)); /* BlockSize */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ summary.contextsize));
+ TRY0(xmlTextWriterEndElement(writer)); /* ContextSize */
+
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost"));
+ TRY0(xmlTextWriterWriteFormatString(writer,
+ "%" ISC_PRINT_QUADFORMAT "u",
+ lost));
+ TRY0(xmlTextWriterEndElement(writer)); /* Lost */
+
+ TRY0(xmlTextWriterEndElement(writer)); /* summary */
+ error:
+ return (xmlrc);
}
#endif /* HAVE_LIBXML2 */
diff --git a/lib/isc/nothreads/Makefile.in b/lib/isc/nothreads/Makefile.in
index 540b243..b8b5f98 100644
--- a/lib/isc/nothreads/Makefile.in
+++ b/lib/isc/nothreads/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007, 2009, 2010, 2012 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2009, 2010, 2012, 2013 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 2000, 2001 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -16,8 +16,8 @@
# $Id: Makefile.in,v 1.12 2010/06/09 23:50:58 tbox Exp $
top_srcdir = @top_srcdir@
-srcdir = @top_srcdir@/lib/isc/nothreads
-VPATH = @top_srcdir@/lib/isc/nothreads
+srcdir = @srcdir@
+VPATH = @srcdir@
CINCLUDES = -I${srcdir}/include \
-I${srcdir}/../unix/include \
diff --git a/lib/isc/parseint.c b/lib/isc/parseint.c
index 266d44c..f8ec389 100644
--- a/lib/isc/parseint.c
+++ b/lib/isc/parseint.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) 2001-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -32,6 +32,7 @@
isc_result_t
isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) {
unsigned long n;
+ isc_uint32_t r;
char *e;
if (! isalnum((unsigned char)(string[0])))
return (ISC_R_BADNUMBER);
@@ -39,9 +40,15 @@ isc_parse_uint32(isc_uint32_t *uip, const char *string, int base) {
n = strtoul(string, &e, base);
if (*e != '\0')
return (ISC_R_BADNUMBER);
- if (n == ULONG_MAX && errno == ERANGE)
+ /*
+ * Where long is 64 bits we need to convert to 32 bits then test for
+ * equality. This is a no-op on 32 bit machines and a good compiler
+ * will optimise it away.
+ */
+ r = (isc_uint32_t)n;
+ if ((n == ULONG_MAX && errno == ERANGE) || (n != (unsigned long)r))
return (ISC_R_RANGE);
- *uip = n;
+ *uip = r;
return (ISC_R_SUCCESS);
}
diff --git a/lib/isc/pthreads/thread.c b/lib/isc/pthreads/thread.c
index 4b5b491..1b250fa 100644
--- a/lib/isc/pthreads/thread.c
+++ b/lib/isc/pthreads/thread.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2013 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
@@ -25,7 +25,7 @@
#include <isc/util.h>
#ifndef THREAD_MINSTACKSIZE
-#define THREAD_MINSTACKSIZE (64U * 1024)
+#define THREAD_MINSTACKSIZE (1024U * 1024)
#endif
isc_result_t
diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c
index 07bcc7c..fc66e9f 100644
--- a/lib/isc/ratelimiter.c
+++ b/lib/isc/ratelimiter.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) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -114,7 +114,7 @@ isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval) {
/*
* If the timer is currently running, change its rate.
*/
- if (rl->state == isc_ratelimiter_ratelimited) {
+ if (rl->state == isc_ratelimiter_ratelimited) {
result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL,
&rl->interval, ISC_FALSE);
}
@@ -142,13 +142,13 @@ isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
REQUIRE(ev->ev_sender == NULL);
LOCK(&rl->lock);
- if (rl->state == isc_ratelimiter_ratelimited ||
+ if (rl->state == isc_ratelimiter_ratelimited ||
rl->state == isc_ratelimiter_stalled) {
isc_event_t *ev = *eventp;
ev->ev_sender = task;
- ISC_LIST_APPEND(rl->pending, ev, ev_link);
+ ISC_LIST_APPEND(rl->pending, ev, ev_link);
*eventp = NULL;
- } else if (rl->state == isc_ratelimiter_idle) {
+ } else if (rl->state == isc_ratelimiter_idle) {
result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL,
&rl->interval, ISC_FALSE);
if (result == ISC_R_SUCCESS) {
@@ -177,7 +177,7 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
pertic = rl->pertic;
- while (pertic != 0) {
+ while (pertic != 0) {
pertic--;
LOCK(&rl->lock);
p = ISC_LIST_HEAD(rl->pending);
@@ -289,8 +289,9 @@ isc_ratelimiter_stall(isc_ratelimiter_t *rl) {
break;
case isc_ratelimiter_ratelimited:
result = isc_timer_reset(rl->timer, isc_timertype_inactive,
- NULL, NULL, ISC_FALSE);
+ NULL, NULL, ISC_FALSE);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+ /* FALLTHROUGH */
case isc_ratelimiter_idle:
case isc_ratelimiter_stalled:
rl->state = isc_ratelimiter_stalled;
@@ -316,7 +317,7 @@ isc_ratelimiter_release(isc_ratelimiter_t *rl) {
&rl->interval, ISC_FALSE);
if (result == ISC_R_SUCCESS)
rl->state = isc_ratelimiter_ratelimited;
- } else
+ } else
rl->state = isc_ratelimiter_idle;
break;
case isc_ratelimiter_ratelimited:
diff --git a/lib/isc/regex.c b/lib/isc/regex.c
new file mode 100644
index 0000000..279bcdc
--- /dev/null
+++ b/lib/isc/regex.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+#include <config.h>
+
+#include <isc/file.h>
+#include <isc/regex.h>
+#include <isc/string.h>
+
+#if VALREGEX_REPORT_REASON
+#define FAIL(x) do { reason = (x); goto error; } while(0)
+#else
+#define FAIL(x) goto error
+#endif
+
+/*
+ * Validate the regular expression 'C' locale.
+ */
+int
+isc_regex_validate(const char *c) {
+ enum {
+ none, parse_bracket, parse_bound,
+ parse_ce, parse_ec, parse_cc
+ } state = none;
+ /* Well known character classes. */
+ const char *cc[] = {
+ ":alnum:", ":digit:", ":punct:", ":alpha:", ":graph:",
+ ":space:", ":blank:", ":lower:", ":upper:", ":cntrl:",
+ ":print:", ":xdigit:"
+ };
+ isc_boolean_t seen_comma = ISC_FALSE;
+ isc_boolean_t seen_high = ISC_FALSE;
+ isc_boolean_t seen_char = ISC_FALSE;
+ isc_boolean_t seen_ec = ISC_FALSE;
+ isc_boolean_t seen_ce = ISC_FALSE;
+ isc_boolean_t have_atom = ISC_FALSE;
+ int group = 0;
+ int range = 0;
+ int sub = 0;
+ isc_boolean_t empty_ok = ISC_FALSE;
+ isc_boolean_t neg = ISC_FALSE;
+ isc_boolean_t was_multiple = ISC_FALSE;
+ unsigned int low = 0;
+ unsigned int high = 0;
+ const char *ccname = NULL;
+ int range_start = 0;
+#if VALREGEX_REPORT_REASON
+ const char *reason = "";
+#endif
+
+ if (c == NULL || *c == 0)
+ FAIL("empty string");
+
+ while (c != NULL && *c != 0) {
+ switch (state) {
+ case none:
+ switch (*c) {
+ case '\\': /* make literal */
+ ++c;
+ switch (*c) {
+ case '1': case '2': case '3':
+ case '4': case '5': case '6':
+ case '7': case '8': case '9':
+ if ((*c - '0') > sub)
+ FAIL("bad back reference");
+ have_atom = ISC_TRUE;
+ was_multiple = ISC_FALSE;
+ break;
+ case 0:
+ FAIL("escaped end-of-string");
+ default:
+ goto literal;
+ }
+ ++c;
+ break;
+ case '[': /* bracket start */
+ ++c;
+ neg = ISC_FALSE;
+ was_multiple = ISC_FALSE;
+ seen_char = ISC_FALSE;
+ state = parse_bracket;
+ break;
+ case '{': /* bound start */
+ switch (c[1]) {
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9':
+ if (!have_atom)
+ FAIL("no atom");
+ if (was_multiple)
+ FAIL("was multiple");
+ seen_comma = ISC_FALSE;
+ seen_high = ISC_FALSE;
+ low = high = 0;
+ state = parse_bound;
+ break;
+ default:
+ goto literal;
+ }
+ ++c;
+ have_atom = ISC_TRUE;
+ was_multiple = ISC_TRUE;
+ break;
+ case '}':
+ goto literal;
+ case '(': /* group start */
+ have_atom = ISC_FALSE;
+ was_multiple = ISC_FALSE;
+ empty_ok = ISC_TRUE;
+ ++group;
+ ++sub;
+ ++c;
+ break;
+ case ')': /* group end */
+ if (group && !have_atom && !empty_ok)
+ FAIL("empty alternative");
+ have_atom = ISC_TRUE;
+ was_multiple = ISC_FALSE;
+ if (group != 0)
+ --group;
+ ++c;
+ break;
+ case '|': /* alternative seperator */
+ if (!have_atom)
+ FAIL("no atom");
+ have_atom = ISC_FALSE;
+ empty_ok = ISC_FALSE;
+ was_multiple = ISC_FALSE;
+ ++c;
+ break;
+ case '^':
+ case '$':
+ have_atom = ISC_TRUE;
+ was_multiple = ISC_TRUE;
+ ++c;
+ break;
+ case '+':
+ case '*':
+ case '?':
+ if (was_multiple)
+ FAIL("was multiple");
+ if (!have_atom)
+ FAIL("no atom");
+ have_atom = ISC_TRUE;
+ was_multiple = ISC_TRUE;
+ ++c;
+ break;
+ case '.':
+ default:
+ literal:
+ have_atom = ISC_TRUE;
+ was_multiple = ISC_FALSE;
+ ++c;
+ break;
+ }
+ break;
+ case parse_bound:
+ switch (*c) {
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ if (!seen_comma) {
+ low = low * 10 + *c - '0';
+ if (low > 255)
+ FAIL("lower bound too big");
+ } else {
+ seen_high = ISC_TRUE;
+ high = high * 10 + *c - '0';
+ if (high > 255)
+ FAIL("upper bound too big");
+ }
+ ++c;
+ break;
+ case ',':
+ if (seen_comma)
+ FAIL("multiple commas");
+ seen_comma = ISC_TRUE;
+ ++c;
+ break;
+ default:
+ case '{':
+ FAIL("non digit/comma");
+ case '}':
+ if (seen_high && low > high)
+ FAIL("bad parse bound");
+ seen_comma = ISC_FALSE;
+ state = none;
+ ++c;
+ break;
+ }
+ break;
+ case parse_bracket:
+ switch (*c) {
+ case '^':
+ if (seen_char || neg) goto inside;
+ neg = ISC_TRUE;
+ ++c;
+ break;
+ case '-':
+ if (range == 2) goto inside;
+ if (!seen_char) goto inside;
+ if (range == 1)
+ FAIL("bad range");
+ range = 2;
+ ++c;
+ break;
+ case '[':
+ ++c;
+ switch (*c) {
+ case '.': /* collating element */
+ if (range) --range;
+ ++c;
+ state = parse_ce;
+ seen_ce = ISC_FALSE;
+ break;
+ case '=': /* equivalence class */
+ if (range == 2)
+ FAIL("equivalence class in range");
+ ++c;
+ state = parse_ec;
+ seen_ec = ISC_FALSE;
+ break;
+ case ':': /* character class */
+ if (range == 2)
+ FAIL("character class in range");
+ ccname = c;
+ ++c;
+ state = parse_cc;
+ break;
+ }
+ seen_char = ISC_TRUE;
+ break;
+ case ']':
+ if (!c[1] && !seen_char)
+ FAIL("unfinished brace");
+ if (!seen_char)
+ goto inside;
+ ++c;
+ range = 0;
+ have_atom = ISC_TRUE;
+ state = none;
+ break;
+ default:
+ inside:
+ seen_char = ISC_TRUE;
+ if (range == 2 && *c < range_start)
+ FAIL("out of order range");
+ if (range != 0)
+ --range;
+ range_start = *c;
+ ++c;
+ break;
+ };
+ break;
+ case parse_ce:
+ switch (*c) {
+ case '.':
+ ++c;
+ switch (*c) {
+ case ']':
+ if (!seen_ce)
+ FAIL("empty ce");
+ ++c;
+ state = parse_bracket;
+ break;
+ default:
+ if (seen_ce)
+ range_start = 256;
+ else
+ range_start = '.';
+ seen_ce = ISC_TRUE;
+ break;
+ }
+ break;
+ default:
+ if (seen_ce)
+ range_start = 256;
+ else
+ range_start = *c;
+ seen_ce = ISC_TRUE;
+ ++c;
+ break;
+ }
+ break;
+ case parse_ec:
+ switch (*c) {
+ case '=':
+ ++c;
+ switch (*c) {
+ case ']':
+ if (!seen_ec)
+ FAIL("no ec");
+ ++c;
+ state = parse_bracket;
+ break;
+ default:
+ seen_ec = ISC_TRUE;
+ break;
+ }
+ break;
+ default:
+ seen_ec = ISC_TRUE;
+ ++c;
+ break;
+ }
+ break;
+ case parse_cc:
+ switch (*c) {
+ case ':':
+ ++c;
+ switch (*c) {
+ case ']': {
+ unsigned int i;
+ isc_boolean_t found = ISC_FALSE;
+ for (i = 0;
+ i < sizeof(cc)/sizeof(*cc);
+ i++)
+ {
+ unsigned int len;
+ len = strlen(cc[i]);
+ if (len !=
+ (unsigned int)(c - ccname))
+ continue;
+ if (strncmp(cc[i], ccname, len))
+ continue;
+ found = ISC_TRUE;
+ }
+ if (!found)
+ FAIL("unknown cc");
+ ++c;
+ state = parse_bracket;
+ break;
+ }
+ default:
+ break;
+ }
+ break;
+ default:
+ ++c;
+ break;
+ }
+ break;
+ }
+ }
+ if (group != 0)
+ FAIL("group open");
+ if (state != none)
+ FAIL("incomplete");
+ if (!have_atom)
+ FAIL("no atom");
+ return (sub);
+
+ error:
+#if VALREGEX_REPORT_REASON
+ fprintf(stderr, "%s\n", reason);
+#endif
+ return (-1);
+}
diff --git a/lib/isc/sockaddr.c b/lib/isc/sockaddr.c
index 7b43b8f..91a949b 100644
--- a/lib/isc/sockaddr.c
+++ b/lib/isc/sockaddr.c
@@ -219,13 +219,12 @@ isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
break;
case AF_INET6:
in6 = &sockaddr->type.sin6.sin6_addr;
+ s = (const unsigned char *)in6;
if (IN6_IS_ADDR_V4MAPPED(in6)) {
- s = (const unsigned char *)&in6[12];
+ s += 12;
length = sizeof(sockaddr->type.sin.sin_addr.s_addr);
- } else {
- s = (const unsigned char *)in6;
+ } else
length = sizeof(sockaddr->type.sin6.sin6_addr);
- }
p = ntohs(sockaddr->type.sin6.sin6_port);
break;
default:
diff --git a/lib/isc/sparc64/include/isc/atomic.h b/lib/isc/sparc64/include/isc/atomic.h
index b920095..4b36661 100644
--- a/lib/isc/sparc64/include/isc/atomic.h
+++ b/lib/isc/sparc64/include/isc/atomic.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2005, 2007, 2013 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
@@ -72,9 +72,9 @@ 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(
- "casa [%1] %2, %3, %0"
- : "+r"(swapped)
- : "r"(p), "n"(ASI_P), "r"(prev));
+ "casa [%2] %3, %4, %0"
+ : "+r"(swapped), "=m"(*p)
+ : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p));
if (swapped == prev)
break;
}
@@ -92,10 +92,9 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
swapped = val;
__asm__ volatile(
- "casa [%1] %2, %3, %0"
- : "+r"(swapped)
- : "r"(p), "n"(ASI_P), "r"(prev)
- : "memory");
+ "casa [%2] %3, %4, %0"
+ : "+r"(swapped), "=m"(*p)
+ : "r"(p), "n"(ASI_P), "r"(prev), "m"(*p));
if (swapped == prev)
break;
}
@@ -111,9 +110,9 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
isc_int32_t temp = val;
__asm__ volatile(
- "casa [%1] %2, %3, %0"
- : "+r"(temp)
- : "r"(p), "n"(ASI_P), "r"(cmpval));
+ "casa [%2] %3, %4, %0"
+ : "+r"(temp), "=m"(*p)
+ : "r"(p), "n"(ASI_P), "r"(cmpval), "m"(*p));
return (temp);
}
diff --git a/lib/isc/symtab.c b/lib/isc/symtab.c
index d4c1dcc..1f294fb 100644
--- a/lib/isc/symtab.c
+++ b/lib/isc/symtab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -71,15 +71,17 @@ isc_symtab_create(isc_mem_t *mctx, unsigned int size,
symtab = (isc_symtab_t *)isc_mem_get(mctx, sizeof(*symtab));
if (symtab == NULL)
return (ISC_R_NOMEMORY);
+
+ symtab->mctx = NULL;
+ isc_mem_attach(mctx, &symtab->mctx);
symtab->table = (eltlist_t *)isc_mem_get(mctx,
size * sizeof(eltlist_t));
if (symtab->table == NULL) {
- isc_mem_put(mctx, symtab, sizeof(*symtab));
+ isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab));
return (ISC_R_NOMEMORY);
}
for (i = 0; i < size; i++)
INIT_LIST(symtab->table[i]);
- symtab->mctx = mctx;
symtab->size = size;
symtab->count = 0;
symtab->maxload = size * 3 / 4;
@@ -117,7 +119,7 @@ isc_symtab_destroy(isc_symtab_t **symtabp) {
isc_mem_put(symtab->mctx, symtab->table,
symtab->size * sizeof(eltlist_t));
symtab->magic = 0;
- isc_mem_put(symtab->mctx, symtab, sizeof(*symtab));
+ isc_mem_putanddetach(&symtab->mctx, symtab, sizeof(*symtab));
*symtabp = NULL;
}
diff --git a/lib/isc/task.c b/lib/isc/task.c
index a5f6ef9..94f1c6d 100644
--- a/lib/isc/task.c
+++ b/lib/isc/task.c
@@ -1539,10 +1539,12 @@ isc_task_exiting(isc_task_t *t) {
#if defined(HAVE_LIBXML2) && defined(BIND9)
-void
+#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
+int
isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0;
- isc__task_t *task;
+ isc__task_t *task = NULL;
+ int xmlrc;
LOCK(&mgr->lock);
@@ -1550,72 +1552,82 @@ isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
* Write out the thread-model, and some details about each depending
* on which type is enabled.
*/
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model"));
#ifdef ISC_PLATFORM_USETHREADS
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "type");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded");
- xmlTextWriterEndElement(writer); /* type */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded"));
+ TRY0(xmlTextWriterEndElement(writer)); /* type */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads");
- xmlTextWriterWriteFormatString(writer, "%d", mgr->workers);
- xmlTextWriterEndElement(writer); /* worker-threads */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->workers));
+ TRY0(xmlTextWriterEndElement(writer)); /* worker-threads */
#else /* ISC_PLATFORM_USETHREADS */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "type");
- xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded");
- xmlTextWriterEndElement(writer); /* type */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "type"));
+ TRY0(xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded"));
+ TRY0(xmlTextWriterEndElement(writer)); /* type */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
- xmlTextWriterWriteFormatString(writer, "%d", mgr->refs);
- xmlTextWriterEndElement(writer); /* references */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs));
+ TRY0(xmlTextWriterEndElement(writer)); /* references */
#endif /* ISC_PLATFORM_USETHREADS */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum");
- xmlTextWriterWriteFormatString(writer, "%d", mgr->default_quantum);
- xmlTextWriterEndElement(writer); /* default-quantum */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d",
+ mgr->default_quantum));
+ TRY0(xmlTextWriterEndElement(writer)); /* default-quantum */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running");
- xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running);
- xmlTextWriterEndElement(writer); /* tasks-running */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running));
+ TRY0(xmlTextWriterEndElement(writer)); /* tasks-running */
- xmlTextWriterEndElement(writer); /* thread-model */
+ TRY0(xmlTextWriterEndElement(writer)); /* thread-model */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks"));
task = ISC_LIST_HEAD(mgr->tasks);
while (task != NULL) {
LOCK(&task->lock);
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "task");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "task"));
if (task->name[0] != 0) {
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteFormatString(writer, "%s",
- task->name);
- xmlTextWriterEndElement(writer); /* name */
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%s",
+ task->name));
+ TRY0(xmlTextWriterEndElement(writer)); /* name */
}
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
- xmlTextWriterWriteFormatString(writer, "%d", task->references);
- xmlTextWriterEndElement(writer); /* references */
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "references"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d",
+ task->references));
+ TRY0(xmlTextWriterEndElement(writer)); /* references */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "id");
- xmlTextWriterWriteFormatString(writer, "%p", task);
- xmlTextWriterEndElement(writer); /* id */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%p", task));
+ TRY0(xmlTextWriterEndElement(writer)); /* id */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "state");
- xmlTextWriterWriteFormatString(writer, "%s",
- statenames[task->state]);
- xmlTextWriterEndElement(writer); /* state */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "state"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%s",
+ statenames[task->state]));
+ TRY0(xmlTextWriterEndElement(writer)); /* state */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum");
- xmlTextWriterWriteFormatString(writer, "%d", task->quantum);
- xmlTextWriterEndElement(writer); /* quantum */
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d",
+ task->quantum));
+ TRY0(xmlTextWriterEndElement(writer)); /* quantum */
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterEndElement(writer));
UNLOCK(&task->lock);
task = ISC_LIST_NEXT(task, link);
}
- xmlTextWriterEndElement(writer); /* tasks */
+ TRY0(xmlTextWriterEndElement(writer)); /* tasks */
+ error:
+ if (task != NULL)
+ UNLOCK(&task->lock);
UNLOCK(&mgr->lock);
+
+ return (xmlrc);
}
#endif /* HAVE_LIBXML2 && BIND9 */
diff --git a/lib/isc/taskpool.c b/lib/isc/taskpool.c
index 936732c..7324cfa 100644
--- a/lib/isc/taskpool.c
+++ b/lib/isc/taskpool.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -52,13 +52,15 @@ alloc_pool(isc_taskmgr_t *tmgr, isc_mem_t *mctx, unsigned int ntasks,
pool = isc_mem_get(mctx, sizeof(*pool));
if (pool == NULL)
return (ISC_R_NOMEMORY);
- pool->mctx = mctx;
+
+ pool->mctx = NULL;
+ isc_mem_attach(mctx, &pool->mctx);
pool->ntasks = ntasks;
pool->quantum = quantum;
pool->tmgr = tmgr;
pool->tasks = isc_mem_get(mctx, ntasks * sizeof(isc_task_t *));
if (pool->tasks == NULL) {
- isc_mem_put(mctx, pool, sizeof(*pool));
+ isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
return (ISC_R_NOMEMORY);
}
for (i = 0; i < ntasks; i++)
@@ -169,7 +171,7 @@ isc_taskpool_destroy(isc_taskpool_t **poolp) {
}
isc_mem_put(pool->mctx, pool->tasks,
pool->ntasks * sizeof(isc_task_t *));
- isc_mem_put(pool->mctx, pool, sizeof(*pool));
+ isc_mem_putanddetach(&pool->mctx, pool, sizeof(*pool));
*poolp = NULL;
}
diff --git a/lib/isc/timer.c b/lib/isc/timer.c
index 0da251f..23fcbbe 100644
--- a/lib/isc/timer.c
+++ b/lib/isc/timer.c
@@ -130,12 +130,12 @@ struct isc__timermgr {
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_create(isc_timermgr_t *manager, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
+ const isc_time_t *expires, const isc_interval_t *interval,
isc_task_t *task, isc_taskaction_t action, const void *arg,
isc_timer_t **timerp);
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_reset(isc_timer_t *timer, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
+ const isc_time_t *expires, const isc_interval_t *interval,
isc_boolean_t purge);
ISC_TIMERFUNC_SCOPE isc_timertype_t
isc__timer_gettype(isc_timer_t *timer);
@@ -392,7 +392,7 @@ destroy(isc__timer_t *timer) {
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
+ const isc_time_t *expires, const isc_interval_t *interval,
isc_task_t *task, isc_taskaction_t action, const void *arg,
isc_timer_t **timerp)
{
@@ -514,7 +514,7 @@ isc__timer_create(isc_timermgr_t *manager0, isc_timertype_t type,
ISC_TIMERFUNC_SCOPE isc_result_t
isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
+ const isc_time_t *expires, const isc_interval_t *interval,
isc_boolean_t purge)
{
isc__timer_t *timer = (isc__timer_t *)timer0;
@@ -692,7 +692,7 @@ dispatch(isc__timermgr_t *manager, isc_time_t *now) {
while (manager->nscheduled > 0 && !done) {
timer = isc_heap_element(manager->heap, 1);
- INSIST(timer->type != isc_timertype_inactive);
+ INSIST(timer != NULL && timer->type != isc_timertype_inactive);
if (isc_time_compare(now, &timer->due) >= 0) {
if (timer->type == isc_timertype_ticker) {
type = ISC_TIMEREVENT_TICK;
diff --git a/lib/isc/timer_api.c b/lib/isc/timer_api.c
index 97e62b3..39b33e3 100644
--- a/lib/isc/timer_api.c
+++ b/lib/isc/timer_api.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2009, 2012 Internet Systems Consortium, Inc. ("ISC")
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -96,7 +96,7 @@ isc_timermgr_destroy(isc_timermgr_t **managerp) {
isc_result_t
isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
+ const isc_time_t *expires, const isc_interval_t *interval,
isc_task_t *task, isc_taskaction_t action, const void *arg,
isc_timer_t **timerp)
{
@@ -128,7 +128,7 @@ isc_timer_detach(isc_timer_t **timerp) {
isc_result_t
isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
- isc_time_t *expires, isc_interval_t *interval,
+ const isc_time_t *expires, const isc_interval_t *interval,
isc_boolean_t purge)
{
REQUIRE(ISCAPI_TIMER_VALID(timer));
diff --git a/lib/isc/unix/entropy.c b/lib/isc/unix/entropy.c
index ab53faf..9c422b5 100644
--- a/lib/isc/unix/entropy.c
+++ b/lib/isc/unix/entropy.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) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -536,8 +536,7 @@ isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname) {
memset(&sname, 0, sizeof(sname));
sname.sun_family = AF_UNIX;
- strncpy(sname.sun_path, fname, sizeof(sname.sun_path));
- sname.sun_path[sizeof(sname.sun_path)-1] = '0';
+ strlcpy(sname.sun_path, fname, sizeof(sname.sun_path));
#ifdef ISC_PLATFORM_HAVESALEN
#if !defined(SUN_LEN)
#define SUN_LEN(su) \
diff --git a/lib/isc/unix/file.c b/lib/isc/unix/file.c
index 99c02ec..7bb25d7 100644
--- a/lib/isc/unix/file.c
+++ b/lib/isc/unix/file.c
@@ -396,6 +396,24 @@ isc_file_isplainfile(const char *filename) {
return(ISC_R_SUCCESS);
}
+isc_result_t
+isc_file_isdirectory(const char *filename) {
+ /*
+ * This function returns success if filename exists and is a
+ * directory.
+ */
+ struct stat filestat;
+ memset(&filestat,0,sizeof(struct stat));
+
+ if ((stat(filename, &filestat)) == -1)
+ return(isc__errno2result(errno));
+
+ if(! S_ISDIR(filestat.st_mode))
+ return(ISC_R_INVALIDFILE);
+
+ return(ISC_R_SUCCESS);
+}
+
isc_boolean_t
isc_file_isabsolute(const char *filename) {
REQUIRE(filename != NULL);
@@ -542,6 +560,9 @@ isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirname, char **basename)
{
char *dir, *file, *slash;
+ if (path == NULL)
+ return (ISC_R_INVALIDFILE);
+
slash = strrchr(path, '/');
if (slash == path) {
diff --git a/lib/isc/unix/include/isc/time.h b/lib/isc/unix/include/isc/time.h
index dc1cef9..d81d854 100644
--- a/lib/isc/unix/include/isc/time.h
+++ b/lib/isc/unix/include/isc/time.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-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
@@ -41,7 +41,7 @@ struct isc_interval {
unsigned int nanoseconds;
};
-extern isc_interval_t *isc_interval_zero;
+extern const isc_interval_t * const isc_interval_zero;
ISC_LANG_BEGINDECLS
@@ -85,7 +85,7 @@ struct isc_time {
unsigned int nanoseconds;
};
-extern isc_time_t *isc_time_epoch;
+extern const isc_time_t * const isc_time_epoch;
void
isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds);
diff --git a/lib/isc/unix/net.c b/lib/isc/unix/net.c
index ea4a504..1fedbc4 100644
--- a/lib/isc/unix/net.c
+++ b/lib/isc/unix/net.c
@@ -301,8 +301,6 @@ try_ipv6only(void) {
goto close;
}
- close(s);
-
ipv6only_result = ISC_R_SUCCESS;
close:
@@ -358,7 +356,6 @@ try_ipv6pktinfo(void) {
goto close;
}
- close(s);
ipv6pktinfo_result = ISC_R_SUCCESS;
close:
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
index 9d64a77..d007598 100644
--- a/lib/isc/unix/socket.c
+++ b/lib/isc/unix/socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -613,7 +613,7 @@ enum {
STATID_SENDFAIL = 8,
STATID_RECVFAIL = 9
};
-static const isc_statscounter_t upd4statsindex[] = {
+static const isc_statscounter_t udp4statsindex[] = {
isc_sockstatscounter_udp4open,
isc_sockstatscounter_udp4openfail,
isc_sockstatscounter_udp4close,
@@ -625,7 +625,7 @@ static const isc_statscounter_t upd4statsindex[] = {
isc_sockstatscounter_udp4sendfail,
isc_sockstatscounter_udp4recvfail
};
-static const isc_statscounter_t upd6statsindex[] = {
+static const isc_statscounter_t udp6statsindex[] = {
isc_sockstatscounter_udp6open,
isc_sockstatscounter_udp6openfail,
isc_sockstatscounter_udp6close,
@@ -1192,7 +1192,7 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
struct in6_pktinfo *pktinfop;
#endif
#ifdef SO_TIMESTAMP
- struct timeval *timevalp;
+ void *timevalp;
#endif
#endif
@@ -1259,9 +1259,11 @@ process_cmsg(isc__socket_t *sock, struct msghdr *msg, isc_socketevent_t *dev) {
#ifdef SO_TIMESTAMP
if (cmsgp->cmsg_level == SOL_SOCKET
&& cmsgp->cmsg_type == SCM_TIMESTAMP) {
- timevalp = (struct timeval *)CMSG_DATA(cmsgp);
- dev->timestamp.seconds = timevalp->tv_sec;
- dev->timestamp.nanoseconds = timevalp->tv_usec * 1000;
+ struct timeval tv;
+ timevalp = CMSG_DATA(cmsgp);
+ memcpy(&tv, timevalp, sizeof(tv));
+ dev->timestamp.seconds = tv.tv_sec;
+ dev->timestamp.nanoseconds = tv.tv_usec * 1000;
dev->attributes |= ISC_SOCKEVENTATTR_TIMESTAMP;
goto next;
}
@@ -2052,7 +2054,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
sock->sendcmsgbuf = NULL;
/*
- * set up cmsg buffers
+ * Set up cmsg buffers.
*/
cmsgbuflen = 0;
#if defined(USE_CMSG) && defined(ISC_PLATFORM_HAVEIN6PKTINFO)
@@ -2094,7 +2096,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
sock->tag = NULL;
/*
- * set up list of readers and writers to be initially empty
+ * Set up list of readers and writers to be initially empty.
*/
ISC_LIST_INIT(sock->recv_list);
ISC_LIST_INIT(sock->send_list);
@@ -2109,7 +2111,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
sock->bound = 0;
/*
- * initialize the lock
+ * Initialize the lock.
*/
result = isc_mutex_init(&sock->lock);
if (result != ISC_R_SUCCESS) {
@@ -2119,7 +2121,7 @@ allocate_socket(isc__socketmgr_t *manager, isc_sockettype_t type,
}
/*
- * Initialize readable and writable events
+ * Initialize readable and writable events.
*/
ISC_EVENT_INIT(&sock->readable_ev, sizeof(intev_t),
ISC_EVENTATTR_NOPURGE, NULL, ISC_SOCKEVENT_INTR,
@@ -2223,13 +2225,38 @@ clear_bsdcompat(void) {
}
#endif
+static void
+use_min_mtu(isc__socket_t *sock) {
+#if !defined(IPV6_USE_MIN_MTU) && !defined(IPV6_MTU)
+ UNUSED(sock);
+#endif
+#ifdef IPV6_USE_MIN_MTU
+ /* use minimum MTU */
+ if (sock->pf == AF_INET6) {
+ int on = 1;
+ (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
+ (void *)&on, sizeof(on));
+ }
+#endif
+#if defined(IPV6_MTU)
+ /*
+ * Use minimum MTU on IPv6 sockets.
+ */
+ if (sock->pf == AF_INET6) {
+ int mtu = 1280;
+ (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU,
+ &mtu, sizeof(mtu));
+ }
+#endif
+}
+
static isc_result_t
opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) {
isc_result_t result;
char strbuf[ISC_STRERRORSIZE];
const char *err = "socket";
int tries = 0;
-#if defined(USE_CMSG) || defined(SO_BSDCOMPAT)
+#if defined(USE_CMSG) || defined(SO_BSDCOMPAT) || defined(SO_NOSIGPIPE)
int on = 1;
#endif
#if defined(SO_RCVBUF)
@@ -2367,6 +2394,11 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) {
}
#endif
+ /*
+ * Use minimum mtu if possible.
+ */
+ use_min_mtu(sock);
+
#if defined(USE_CMSG) || defined(SO_RCVBUF)
if (sock->type == isc_sockettype_udp) {
@@ -2431,32 +2463,6 @@ opensocket(isc__socketmgr_t *manager, isc__socket_t *sock) {
}
#endif /* IPV6_RECVPKTINFO */
#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */
-#ifdef IPV6_USE_MIN_MTU /* RFC 3542, not too common yet*/
- /* use minimum MTU */
- if (sock->pf == AF_INET6 &&
- setsockopt(sock->fd, IPPROTO_IPV6, IPV6_USE_MIN_MTU,
- (void *)&on, sizeof(on)) < 0) {
- isc__strerror(errno, strbuf, sizeof(strbuf));
- UNEXPECTED_ERROR(__FILE__, __LINE__,
- "setsockopt(%d, IPV6_USE_MIN_MTU) "
- "%s: %s", sock->fd,
- isc_msgcat_get(isc_msgcat,
- ISC_MSGSET_GENERAL,
- ISC_MSG_FAILED,
- "failed"),
- strbuf);
- }
-#endif
-#if defined(IPV6_MTU)
- /*
- * Use minimum MTU on IPv6 sockets.
- */
- if (sock->pf == AF_INET6) {
- int mtu = 1280;
- (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_MTU,
- &mtu, sizeof(mtu));
- }
-#endif
#if defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DONT)
/*
* Turn off Path MTU discovery on IPv6/UDP sockets.
@@ -2546,7 +2552,7 @@ isc__socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type,
switch (sock->type) {
case isc_sockettype_udp:
sock->statsindex =
- (pf == AF_INET) ? upd4statsindex : upd6statsindex;
+ (pf == AF_INET) ? udp4statsindex : udp6statsindex;
break;
case isc_sockettype_tcp:
sock->statsindex =
@@ -3209,23 +3215,27 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
if (fd != -1) {
int lockid = FDLOCK_ID(fd);
- LOCK(&manager->fdlock[lockid]);
- manager->fds[fd] = NEWCONNSOCK(dev);
- manager->fdstate[fd] = MANAGED;
- UNLOCK(&manager->fdlock[lockid]);
-
- LOCK(&manager->lock);
- ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link);
-
NEWCONNSOCK(dev)->fd = fd;
NEWCONNSOCK(dev)->bound = 1;
NEWCONNSOCK(dev)->connected = 1;
/*
+ * Use minimum mtu if possible.
+ */
+ use_min_mtu(NEWCONNSOCK(dev));
+
+ /*
* Save away the remote address
*/
dev->address = NEWCONNSOCK(dev)->peer_address;
+ LOCK(&manager->fdlock[lockid]);
+ manager->fds[fd] = NEWCONNSOCK(dev);
+ manager->fdstate[fd] = MANAGED;
+ UNLOCK(&manager->fdlock[lockid]);
+
+ LOCK(&manager->lock);
+
#ifdef USE_SELECT
if (manager->maxfd < fd)
manager->maxfd = fd;
@@ -3236,6 +3246,8 @@ internal_accept(isc_task_t *me, isc_event_t *ev) {
"accepted connection, new socket %p",
dev->newsocket);
+ ISC_LIST_APPEND(manager->socklist, NEWCONNSOCK(dev), link);
+
UNLOCK(&manager->lock);
inc_stats(manager->stats, sock->statsindex[STATID_ACCEPT]);
@@ -5851,94 +5863,112 @@ _socktype(isc_sockettype_t type)
return ("not-initialized");
}
-ISC_SOCKETFUNC_SCOPE void
+#define TRY0(a) do { xmlrc = (a); if (xmlrc < 0) goto error; } while(0)
+ISC_SOCKETFUNC_SCOPE int
isc_socketmgr_renderxml(isc_socketmgr_t *mgr0, xmlTextWriterPtr writer) {
isc__socketmgr_t *mgr = (isc__socketmgr_t *)mgr0;
- isc__socket_t *sock;
+ isc__socket_t *sock = NULL;
char peerbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_t addr;
ISC_SOCKADDR_LEN_T len;
+ int xmlrc;
LOCK(&mgr->lock);
#ifdef USE_SHARED_MANAGER
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
- xmlTextWriterWriteFormatString(writer, "%d", mgr->refs);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "references"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d", mgr->refs));
+ TRY0(xmlTextWriterEndElement(writer));
#endif /* USE_SHARED_MANAGER */
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "sockets"));
sock = ISC_LIST_HEAD(mgr->socklist);
while (sock != NULL) {
LOCK(&sock->lock);
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "socket"));
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "id");
- xmlTextWriterWriteFormatString(writer, "%p", sock);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "id"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%p", sock));
+ TRY0(xmlTextWriterEndElement(writer));
if (sock->name[0] != 0) {
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
- xmlTextWriterWriteFormatString(writer, "%s",
- sock->name);
- xmlTextWriterEndElement(writer); /* name */
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "name"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%s",
+ sock->name));
+ TRY0(xmlTextWriterEndElement(writer)); /* name */
}
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
- xmlTextWriterWriteFormatString(writer, "%d", sock->references);
- xmlTextWriterEndElement(writer);
+ TRY0(xmlTextWriterStartElement(writer,
+ ISC_XMLCHAR "references"));
+ TRY0(xmlTextWriterWriteFormatString(writer, "%d",
+ sock->references));
+ TRY0(xmlTextWriterEndElement(writer));
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type",
- ISC_XMLCHAR _socktype(sock->type));
+ TRY0(xmlTextWriterWriteElement(writer, ISC_XMLCHAR "type",
+ ISC_XMLCHAR _socktype(sock->type)));
if (sock->connected) {
isc_sockaddr_format(&sock->peer_address, peerbuf,
sizeof(peerbuf));
- xmlTextWriterWriteElement(writer,
+ TRY0(xmlTextWriterWriteElement(writer,
ISC_XMLCHAR "peer-address",
- ISC_XMLCHAR peerbuf);
+ ISC_XMLCHAR peerbuf));
}
len = sizeof(addr);
if (getsockname(sock->fd, &addr.type.sa, (void *)&len) == 0) {
isc_sockaddr_format(&addr, peerbuf, sizeof(peerbuf));
- xmlTextWriterWriteElement(writer,
+ TRY0(xmlTextWriterWriteElement(writer,
ISC_XMLCHAR "local-address",
- ISC_XMLCHAR peerbuf);
+ ISC_XMLCHAR peerbuf));
}
- xmlTextWriterStartElement(writer, ISC_XMLCHAR "states");
+ TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "states"));
if (sock->pending_recv)
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state",
- ISC_XMLCHAR "pending-receive");
+ TRY0(xmlTextWriterWriteElement(writer,
+ ISC_XMLCHAR "state",
+ ISC_XMLCHAR "pending-receive"));
if (sock->pending_send)
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state",
- ISC_XMLCHAR "pending-send");
+ TRY0(xmlTextWriterWriteElement(writer,
+ ISC_XMLCHAR "state",
+ ISC_XMLCHAR "pending-send"));
if (sock->pending_accept)
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state",
- ISC_XMLCHAR "pending_accept");
+ TRY0(xmlTextWriterWriteElement(writer,
+ ISC_XMLCHAR "state",
+ ISC_XMLCHAR "pending_accept"));
if (sock->listener)
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state",
- ISC_XMLCHAR "listener");
+ TRY0(xmlTextWriterWriteElement(writer,
+ ISC_XMLCHAR "state",
+ ISC_XMLCHAR "listener"));
if (sock->connected)
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state",
- ISC_XMLCHAR "connected");
+ TRY0(xmlTextWriterWriteElement(writer,
+ ISC_XMLCHAR "state",
+ ISC_XMLCHAR "connected"));
if (sock->connecting)
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state",
- ISC_XMLCHAR "connecting");
+ TRY0(xmlTextWriterWriteElement(writer,
+ ISC_XMLCHAR "state",
+ ISC_XMLCHAR "connecting"));
if (sock->bound)
- xmlTextWriterWriteElement(writer, ISC_XMLCHAR "state",
- ISC_XMLCHAR "bound");
+ TRY0(xmlTextWriterWriteElement(writer,
+ ISC_XMLCHAR "state",
+ ISC_XMLCHAR "bound"));
- xmlTextWriterEndElement(writer); /* states */
+ TRY0(xmlTextWriterEndElement(writer)); /* states */
- xmlTextWriterEndElement(writer); /* socket */
+ TRY0(xmlTextWriterEndElement(writer)); /* socket */
UNLOCK(&sock->lock);
sock = ISC_LIST_NEXT(sock, link);
}
- xmlTextWriterEndElement(writer); /* sockets */
+ TRY0(xmlTextWriterEndElement(writer)); /* sockets */
+
+ error:
+ if (sock != NULL)
+ UNLOCK(&sock->lock);
UNLOCK(&mgr->lock);
+
+ return (xmlrc);
}
#endif /* HAVE_LIBXML2 */
diff --git a/lib/isc/unix/time.c b/lib/isc/unix/time.c
index ac23ae0..e820afb 100644
--- a/lib/isc/unix/time.c
+++ b/lib/isc/unix/time.c
@@ -54,8 +54,8 @@
*** Intervals
***/
-static isc_interval_t zero_interval = { 0, 0 };
-isc_interval_t *isc_interval_zero = &zero_interval;
+static const isc_interval_t zero_interval = { 0, 0 };
+const isc_interval_t * const isc_interval_zero = &zero_interval;
#if ISC_FIX_TV_USEC
static inline void
@@ -110,8 +110,8 @@ isc_interval_iszero(const isc_interval_t *i) {
*** Absolute Times
***/
-static isc_time_t epoch = { 0, 0 };
-isc_time_t *isc_time_epoch = &epoch;
+static const isc_time_t epoch = { 0, 0 };
+const isc_time_t * const isc_time_epoch = &epoch;
void
isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
diff --git a/lib/isccc/api b/lib/isccc/api
index ba19dd9..461b9ac 100644
--- a/lib/isccc/api
+++ b/lib/isccc/api
@@ -1,8 +1,9 @@
# LIBINTERFACE ranges
# 9.6: 50-59, 110-119
# 9.7: 60-79
-# 9.8: 80-89
+# 9.8: 80-89, 120-129
# 9.9: 90-109
+# 9.9-sub: 130-139
LIBINTERFACE = 80
-LIBREVISION = 2
+LIBREVISION = 3
LIBAGE = 0
diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c
index 1ab9479..07f8157 100644
--- a/lib/isccc/cc.c
+++ b/lib/isccc/cc.c
@@ -561,8 +561,10 @@ isccc_cc_createack(isccc_sexpr_t *message, isc_boolean_t ok,
return (result);
_ctrl = isccc_alist_lookup(ack, "_ctrl");
- if (_ctrl == NULL)
- return (ISC_R_FAILURE);
+ if (_ctrl == NULL) {
+ result = ISC_R_FAILURE;
+ goto bad;
+ }
if (isccc_cc_definestring(ack, "_ack", (ok) ? "1" : "0") == NULL) {
result = ISC_R_NOMEMORY;
goto bad;
@@ -608,7 +610,7 @@ isc_result_t
isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now,
isccc_time_t expires, isccc_sexpr_t **alistp)
{
- char *_frm, *_to, *type;
+ char *_frm, *_to, *type = NULL;
isc_uint32_t serial;
isccc_sexpr_t *alist, *_ctrl, *_data;
isc_result_t result;
@@ -617,8 +619,7 @@ isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now,
_ctrl = isccc_alist_lookup(message, "_ctrl");
_data = isccc_alist_lookup(message, "_data");
- if (_ctrl == NULL ||
- _data == NULL ||
+ if (_ctrl == NULL || _data == NULL ||
isccc_cc_lookupuint32(_ctrl, "_ser", &serial) != ISC_R_SUCCESS ||
isccc_cc_lookupstring(_data, "type", &type) != ISC_R_SUCCESS)
return (ISC_R_FAILURE);
@@ -637,21 +638,33 @@ isccc_cc_createresponse(isccc_sexpr_t *message, isccc_time_t now,
&alist);
if (result != ISC_R_SUCCESS)
return (result);
+
_ctrl = isccc_alist_lookup(alist, "_ctrl");
- if (_ctrl == NULL)
- return (ISC_R_FAILURE);
+ if (_ctrl == NULL) {
+ result = ISC_R_FAILURE;
+ goto bad;
+ }
+
_data = isccc_alist_lookup(alist, "_data");
- if (_data == NULL)
- return (ISC_R_FAILURE);
+ if (_data == NULL) {
+ result = ISC_R_FAILURE;
+ goto bad;
+ }
+
if (isccc_cc_definestring(_ctrl, "_rpl", "1") == NULL ||
- isccc_cc_definestring(_data, "type", type) == NULL) {
- isccc_sexpr_free(&alist);
- return (ISC_R_NOMEMORY);
+ isccc_cc_definestring(_data, "type", type) == NULL)
+ {
+ result = ISC_R_NOMEMORY;
+ goto bad;
}
*alistp = alist;
return (ISC_R_SUCCESS);
+
+ bad:
+ isccc_sexpr_free(&alist);
+ return (result);
}
isccc_sexpr_t *
@@ -687,6 +700,8 @@ isccc_cc_lookupstring(isccc_sexpr_t *alist, const char *key, char **strp)
{
isccc_sexpr_t *kv, *v;
+ REQUIRE(strp == NULL || *strp == NULL);
+
kv = isccc_alist_assq(alist, key);
if (kv != NULL) {
v = ISCCC_SEXPR_CDR(kv);
@@ -785,7 +800,7 @@ isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message,
{
const char *_frm;
const char *_to;
- char *_ser, *_tim, *tmp;
+ char *_ser = NULL, *_tim = NULL, *tmp;
isc_result_t result;
char *key;
size_t len;
@@ -797,13 +812,19 @@ isccc_cc_checkdup(isccc_symtab_t *symtab, isccc_sexpr_t *message,
isccc_cc_lookupstring(_ctrl, "_ser", &_ser) != ISC_R_SUCCESS ||
isccc_cc_lookupstring(_ctrl, "_tim", &_tim) != ISC_R_SUCCESS)
return (ISC_R_FAILURE);
+
+ INSIST(_ser != NULL);
+ INSIST(_tim != NULL);
+
/*
* _frm and _to are optional.
*/
+ tmp = NULL;
if (isccc_cc_lookupstring(_ctrl, "_frm", &tmp) != ISC_R_SUCCESS)
_frm = "";
else
_frm = tmp;
+ tmp = NULL;
if (isccc_cc_lookupstring(_ctrl, "_to", &tmp) != ISC_R_SUCCESS)
_to = "";
else
diff --git a/lib/isccfg/Makefile.in b/lib/isccfg/Makefile.in
index bc42880..19ec61e 100644
--- a/lib/isccfg/Makefile.in
+++ b/lib/isccfg/Makefile.in
@@ -68,7 +68,8 @@ libisccfg.la: ${OBJS}
${LIBTOOL_MODE_LINK} \
${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisccfg.la -rpath ${libdir} \
-version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
- ${OBJS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS} ${LIBS}
+ ${OBJS} ${DNSLIBS} ${ISCCCLIBS} ${ISCLIBS} @DNS_CRYPTO_LIBS@ \
+ ${LIBS}
timestamp: libisccfg.@A@
touch timestamp
diff --git a/lib/isccfg/aclconf.c b/lib/isccfg/aclconf.c
index 469989a..af56599 100644
--- a/lib/isccfg/aclconf.c
+++ b/lib/isccfg/aclconf.c
@@ -192,7 +192,7 @@ convert_keyname(const cfg_obj_t *keyobj, isc_log_t *lctx, isc_mem_t *mctx,
const char *txtname = cfg_obj_asstring(keyobj);
keylen = strlen(txtname);
- isc_buffer_init(&buf, txtname, keylen);
+ isc_buffer_constinit(&buf, txtname, keylen);
isc_buffer_add(&buf, keylen);
dns_fixedname_init(&fixname);
result = dns_name_fromtext(dns_fixedname_name(&fixname), &buf,
diff --git a/lib/isccfg/api b/lib/isccfg/api
index cde1e2f..39585b0 100644
--- a/lib/isccfg/api
+++ b/lib/isccfg/api
@@ -1,8 +1,9 @@
# LIBINTERFACE ranges
# 9.6: 50-59, 110-119
# 9.7: 60-79
-# 9.8: 80-89
+# 9.8: 80-89, 120-129
# 9.9: 90-109
+# 9.9-sub: 130-139
LIBINTERFACE = 82
-LIBREVISION = 3
+LIBREVISION = 7
LIBAGE = 0
diff --git a/lib/isccfg/include/isccfg/cfg.h b/lib/isccfg/include/isccfg/cfg.h
index f467768..b21a3d8 100644
--- a/lib/isccfg/include/isccfg/cfg.h
+++ b/lib/isccfg/include/isccfg/cfg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2007, 2010, 2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -411,6 +411,10 @@ cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **obj);
/*%<
* Delete a reference to a configuration object; destroy the object if
* there are no more references.
+ *
+ * Require:
+ * \li '*obj' is a valid cfg_obj_t.
+ * \li 'pctx' is a valid cfg_parser_t.
*/
void
diff --git a/lib/isccfg/namedconf.c b/lib/isccfg/namedconf.c
index 4d09f11..287ce14 100644
--- a/lib/isccfg/namedconf.c
+++ b/lib/isccfg/namedconf.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -526,6 +526,12 @@ static cfg_type_t cfg_type_checkmode = {
&cfg_rep_string, &checkmode_enums
};
+static const char *warn_enums[] = { "warn", "ignore", NULL };
+static cfg_type_t cfg_type_warn = {
+ "warn", cfg_parse_enum, cfg_print_ustring, cfg_doc_enum,
+ &cfg_rep_string, &warn_enums
+};
+
static cfg_tuplefielddef_t checknames_fields[] = {
{ "type", &cfg_type_checktype, 0 },
{ "mode", &cfg_type_checkmode, 0 },
@@ -1018,10 +1024,9 @@ static cfg_type_t cfg_type_masterformat = {
* response-policy {
* zone <string> [ policy (given|disabled|passthru|
* nxdomain|nodata|cname <domain> ) ]
- * [ recursive-only yes|no ]
- * [ max-policy-ttl number ] ;
- * } [ recursive-only yes|no ] [ break-dnssec yes|no ]
- * [ max-policy-ttl number ] ;
+ * [ recursive-only yes|no ] [ max-policy-ttl number ] ;
+ * } [ recursive-only yes|no ] [ max-policy-ttl number ] ;
+ * [ break-dnssec yes|no ] [ min-ns-dots number ] ;
*/
static void
@@ -1223,6 +1228,7 @@ static cfg_tuplefielddef_t rpz_fields[] = {
{ "recursive-only", &cfg_type_boolean, 0 },
{ "break-dnssec", &cfg_type_boolean, 0 },
{ "max-policy-ttl", &cfg_type_uint32, 0 },
+ { "min-ns-dots", &cfg_type_uint32, 0 },
{ NULL, NULL, 0 }
};
static cfg_type_t cfg_type_rpz = {
@@ -1461,6 +1467,7 @@ zone_clauses[] = {
{ "check-mx", &cfg_type_checkmode, 0 },
{ "check-mx-cname", &cfg_type_checkmode, 0 },
{ "check-sibling", &cfg_type_boolean, 0 },
+ { "check-spf", &cfg_type_warn, 0 },
{ "check-srv-cname", &cfg_type_checkmode, 0 },
{ "check-wildcard", &cfg_type_boolean, 0 },
{ "dialup", &cfg_type_dialuptype, 0 },
diff --git a/lib/isccfg/parser.c b/lib/isccfg/parser.c
index ef20184..de0fa31 100644
--- a/lib/isccfg/parser.c
+++ b/lib/isccfg/parser.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2013 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -387,13 +387,15 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) {
if (pctx == NULL)
return (ISC_R_NOMEMORY);
+ pctx->mctx = NULL;
+ isc_mem_attach(mctx, &pctx->mctx);
+
result = isc_refcount_init(&pctx->references, 1);
if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, pctx, sizeof(*pctx));
+ isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx));
return (result);
}
- pctx->mctx = mctx;
pctx->lctx = lctx;
pctx->lexer = NULL;
pctx->seen_eof = ISC_FALSE;
@@ -434,7 +436,7 @@ cfg_parser_create(isc_mem_t *mctx, isc_log_t *lctx, cfg_parser_t **ret) {
isc_lex_destroy(&pctx->lexer);
CLEANUP_OBJ(pctx->open_files);
CLEANUP_OBJ(pctx->closed_files);
- isc_mem_put(mctx, pctx, sizeof(*pctx));
+ isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx));
return (result);
}
@@ -555,7 +557,7 @@ cfg_parser_destroy(cfg_parser_t **pctxp) {
*/
CLEANUP_OBJ(pctx->open_files);
CLEANUP_OBJ(pctx->closed_files);
- isc_mem_put(pctx->mctx, pctx, sizeof(*pctx));
+ isc_mem_putanddetach(&pctx->mctx, pctx, sizeof(*pctx));
}
*pctxp = NULL;
}
@@ -2426,9 +2428,14 @@ cfg_obj_istype(const cfg_obj_t *obj, const cfg_type_t *type) {
*/
void
cfg_obj_destroy(cfg_parser_t *pctx, cfg_obj_t **objp) {
- cfg_obj_t *obj = *objp;
+ cfg_obj_t *obj;
unsigned int refs;
+ REQUIRE(objp != NULL && *objp != NULL);
+ REQUIRE(pctx != NULL);
+
+ obj = *objp;
+
isc_refcount_decrement(&obj->references, &refs);
if (refs == 0) {
obj->type->rep->free(pctx, obj);
diff --git a/lib/lwres/api b/lib/lwres/api
index 1e51baa..2a5c388 100644
--- a/lib/lwres/api
+++ b/lib/lwres/api
@@ -1,8 +1,9 @@
# LIBINTERFACE ranges
# 9.6: 50-59, 110-119
# 9.7: 60-79
-# 9.8: 80-89
+# 9.8: 80-89, 120-129
# 9.9: 90-109
+# 9.9-sub: 130-139
LIBINTERFACE = 80
-LIBREVISION = 3
+LIBREVISION = 6
LIBAGE = 0
diff --git a/lib/lwres/context.c b/lib/lwres/context.c
index 64bdaa1..047707f 100644
--- a/lib/lwres/context.c
+++ b/lib/lwres/context.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 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
@@ -377,6 +377,7 @@ lwres_context_send(lwres_context_t *ctx,
lwresult = context_connect(ctx);
if (lwresult != LWRES_R_SUCCESS)
return (lwresult);
+ INSIST(ctx->sock >= 0);
}
ret = sendto(ctx->sock, sendbase, sendlen, 0, NULL, 0);
diff --git a/lib/lwres/getaddrinfo.c b/lib/lwres/getaddrinfo.c
index 811a2fe..7d5f2fb 100644
--- a/lib/lwres/getaddrinfo.c
+++ b/lib/lwres/getaddrinfo.c
@@ -573,10 +573,8 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
(void) lwres_conf_parse(lwrctx, lwres_resolv_conf);
if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
ai = ai_clone(*aip, AF_INET);
- if (ai == NULL) {
- lwres_freeaddrinfo(*aip);
+ if (ai == NULL)
SETERROR(EAI_MEMORY);
- }
*aip = ai;
ai->ai_socktype = socktype;
@@ -594,10 +592,8 @@ add_ipv4(const char *hostname, int flags, struct addrinfo **aip,
addr = LWRES_LIST_HEAD(by->addrs);
while (addr != NULL) {
ai = ai_clone(*aip, AF_INET);
- if (ai == NULL) {
- lwres_freeaddrinfo(*aip);
+ if (ai == NULL)
SETERROR(EAI_MEMORY);
- }
*aip = ai;
ai->ai_socktype = socktype;
SIN(ai->ai_addr)->sin_port = port;
@@ -641,10 +637,8 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
if (hostname == NULL && (flags & AI_PASSIVE) == 0) {
ai = ai_clone(*aip, AF_INET6);
- if (ai == NULL) {
- lwres_freeaddrinfo(*aip);
+ if (ai == NULL)
SETERROR(EAI_MEMORY);
- }
*aip = ai;
ai->ai_socktype = socktype;
@@ -662,10 +656,8 @@ add_ipv6(const char *hostname, int flags, struct addrinfo **aip,
addr = LWRES_LIST_HEAD(by->addrs);
while (addr != NULL) {
ai = ai_clone(*aip, AF_INET6);
- if (ai == NULL) {
- lwres_freeaddrinfo(*aip);
+ if (ai == NULL)
SETERROR(EAI_MEMORY);
- }
*aip = ai;
ai->ai_socktype = socktype;
SIN6(ai->ai_addr)->sin6_port = port;
diff --git a/lib/lwres/getipnode.c b/lib/lwres/getipnode.c
index 3bd8217..300376e 100644
--- a/lib/lwres/getipnode.c
+++ b/lib/lwres/getipnode.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005, 2007, 2009, 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
@@ -466,6 +466,9 @@ lwres_freehostent(struct hostent *he) {
int names = 1;
int addresses = 1;
+ if (he == NULL)
+ return;
+
free(he->h_name);
cpp = he->h_addr_list;
@@ -950,8 +953,9 @@ copyandmerge(struct hostent *he1, struct hostent *he2, int af, int *error_num)
* Copy aliases.
*/
npp = he->h_aliases;
- cpp = (he1 != NULL) ? he1->h_aliases : he2->h_aliases;
- while (*cpp != NULL) {
+ cpp = (he1 != NULL) ? he1->h_aliases
+ : ((he2 != NULL) ? he2->h_aliases : NULL);
+ while (cpp != NULL && *cpp != NULL) {
len = strlen (*cpp) + 1;
*npp = malloc(len);
if (*npp == NULL)
@@ -1115,6 +1119,8 @@ hostfromname(lwres_gabnresponse_t *name, int af) {
* Copy aliases.
*/
he->h_aliases = malloc(sizeof(char *) * (name->naliases + 1));
+ if (he->h_aliases == NULL)
+ goto cleanup;
for (i = 0; i < name->naliases; i++) {
he->h_aliases[i] = strdup(name->aliases[i]);
if (he->h_aliases[i] == NULL)
@@ -1126,6 +1132,8 @@ hostfromname(lwres_gabnresponse_t *name, int af) {
* Copy addresses.
*/
he->h_addr_list = malloc(sizeof(char *) * (name->naddrs + 1));
+ if (he->h_addr_list == NULL)
+ goto cleanup;
addr = LWRES_LIST_HEAD(name->addrs);
i = 0;
while (addr != NULL) {
diff --git a/lib/lwres/getnameinfo.c b/lib/lwres/getnameinfo.c
index 92a34a1..08ebf93 100644
--- a/lib/lwres/getnameinfo.c
+++ b/lib/lwres/getnameinfo.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004, 2005, 2007, 2011-2013 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -161,7 +161,7 @@ int
lwres_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
size_t hostlen, char *serv, size_t servlen, int flags)
{
- struct afd *afd;
+ struct afd *afd = NULL;
struct servent *sp;
unsigned short port;
#ifdef LWRES_PLATFORM_HAVESALEN
diff --git a/lib/lwres/getrrset.c b/lib/lwres/getrrset.c
index d8b6cc3..16af741 100644
--- a/lib/lwres/getrrset.c
+++ b/lib/lwres/getrrset.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) 2000-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -21,12 +21,12 @@
/**
* DESCRIPTION
- *
+ *
* lwres_getrrsetbyname() gets a set of resource records associated with
* a hostname, class, and type. hostname is a pointer a to
* null-terminated string. The flags field is currently unused and must
* be zero.
- *
+ *
* After a successful call to lwres_getrrsetbyname(), *res is a pointer
* to an #rrsetinfo structure, containing a list of one or more #rdatainfo
* structures containing resource records and potentially another list of
@@ -37,7 +37,7 @@
* in uncompressed DNS wire format. Properties of the rdataset are
* represented in the #rri_flags bitfield. If the #RRSET_VALIDATED bit is
* set, the data has been DNSSEC validated and the signatures verified.
- *
+ *
* All of the information returned by lwres_getrrsetbyname() is
* dynamically allocated: the rrsetinfo and rdatainfo structures, and the
* canonical host name strings pointed to by the rrsetinfostructure.
@@ -45,15 +45,15 @@
* successful call to lwres_getrrsetbyname() is released by
* lwres_freerrset(). rrset is a pointer to a struct rrset created by a
* call to lwres_getrrsetbyname().
- *
+ *
* The following structures are used:
- *
+ *
* \code
* struct rdatainfo {
* unsigned int rdi_length; // length of data
* unsigned char *rdi_data; // record data
* };
- *
+ *
* struct rrsetinfo {
* unsigned int rri_flags; // RRSET_VALIDATED...
* unsigned int rri_rdclass; // class number
@@ -66,23 +66,23 @@
* struct rdatainfo *rri_sigs; // individual signatures
* };
* \endcode
- *
+ *
* \section getrrset_return Return Values
- *
+ *
* lwres_getrrsetbyname() returns zero on success, and one of the
* following error codes if an error occurred:
- *
+ *
* \li #ERRSET_NONAME: the name does not exist
- *
+ *
* \li #ERRSET_NODATA:
* the name exists, but does not have data of the desired type
- *
+ *
* \li #ERRSET_NOMEMORY:
* memory could not be allocated
- *
+ *
* \li #ERRSET_INVAL:
* a parameter is invalid
- *
+ *
* \li #ERRSET_FAIL:
* other failure
*/
@@ -179,7 +179,7 @@ lwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
lwflags = 0;
lwresult = lwres_getrdatabyname(lwrctx, hostname,
- (lwres_uint16_t)rdclass,
+ (lwres_uint16_t)rdclass,
(lwres_uint16_t)rdtype,
lwflags, &response);
if (lwresult != LWRES_R_SUCCESS) {
@@ -271,18 +271,22 @@ lwres_getrrsetbyname(const char *hostname, unsigned int rdclass,
void
lwres_freerrset(struct rrsetinfo *rrset) {
unsigned int i;
- for (i = 0; i < rrset->rri_nrdatas; i++) {
- if (rrset->rri_rdatas[i].rdi_data == NULL)
- break;
- free(rrset->rri_rdatas[i].rdi_data);
+ if (rrset->rri_rdatas != NULL) {
+ for (i = 0; i < rrset->rri_nrdatas; i++) {
+ if (rrset->rri_rdatas[i].rdi_data == NULL)
+ break;
+ free(rrset->rri_rdatas[i].rdi_data);
+ }
+ free(rrset->rri_rdatas);
}
- free(rrset->rri_rdatas);
- for (i = 0; i < rrset->rri_nsigs; i++) {
- if (rrset->rri_sigs[i].rdi_data == NULL)
- break;
- free(rrset->rri_sigs[i].rdi_data);
+ if (rrset->rri_sigs != NULL) {
+ for (i = 0; i < rrset->rri_nsigs; i++) {
+ if (rrset->rri_sigs[i].rdi_data == NULL)
+ break;
+ free(rrset->rri_sigs[i].rdi_data);
+ }
+ free(rrset->rri_sigs);
}
- free(rrset->rri_sigs);
free(rrset->rri_name);
free(rrset);
}
diff --git a/lib/lwres/lwinetaton.c b/lib/lwres/lwinetaton.c
index e40c28f..5a0d85a 100644
--- a/lib/lwres/lwinetaton.c
+++ b/lib/lwres/lwinetaton.c
@@ -1,5 +1,5 @@
/*
- * Portions Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 2004, 2005, 2007, 2012 Internet Systems Consortium, Inc. ("ISC")
* Portions Copyright (C) 1996-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -95,7 +95,7 @@ static char rcsid[] = "$Id: lwinetaton.c,v 1.16 2007/06/19 23:47:22 tbox Exp $";
*/
int
lwres_net_aton(const char *cp, struct in_addr *addr) {
- unsigned long val;
+ lwres_uint32_t val;
int base, n;
unsigned char c;
lwres_uint8_t parts[4];
@@ -120,7 +120,7 @@ lwres_net_aton(const char *cp, struct in_addr *addr) {
c = *++cp;
if (c == 'x' || c == 'X') {
base = 16;
- c = *++cp;
+ c = *++cp;
} else {
base = 8;
digit = 1;
diff --git a/lib/lwres/print.c b/lib/lwres/print.c
index 591ed36..87f3032 100644
--- a/lib/lwres/print.c
+++ b/lib/lwres/print.c
@@ -470,12 +470,16 @@ lwres__print_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
pad--;
}
break;
+
case 'D': /*deprecated*/
INSIST("use %ld instead of %D" == NULL);
+ break;
case 'O': /*deprecated*/
INSIST("use %lo instead of %O" == NULL);
+ break;
case 'U': /*deprecated*/
INSIST("use %lu instead of %U" == NULL);
+ break;
case 'L':
#ifdef HAVE_LONG_DOUBLE
OpenPOWER on IntegriCloud