summaryrefslogtreecommitdiffstats
path: root/lib/dns
diff options
context:
space:
mode:
authorerwin <erwin@FreeBSD.org>2013-07-24 07:12:55 +0000
committererwin <erwin@FreeBSD.org>2013-07-24 07:12:55 +0000
commitdc235a59431db02e1a04d85de49af9e278510ac8 (patch)
treee392027bf54f7a1fd2a6f3a16ecb4487844b44e9 /lib/dns
parent9ef4e0591273b7d40b98ef46084442638150b2fc (diff)
downloadFreeBSD-src-dc235a59431db02e1a04d85de49af9e278510ac8.zip
FreeBSD-src-dc235a59431db02e1a04d85de49af9e278510ac8.tar.gz
Vendor import of Bind 9.8.5-P1
Approved by: delphij (mentor) Sponsored by: DK Hostmaster A/S
Diffstat (limited to 'lib/dns')
-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
84 files changed, 4266 insertions, 1241 deletions
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);
OpenPOWER on IntegriCloud