summaryrefslogtreecommitdiff
path: root/usr.sbin/bind/lib/dns
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bind/lib/dns')
-rw-r--r--usr.sbin/bind/lib/dns/adb.c12
-rw-r--r--usr.sbin/bind/lib/dns/api4
-rw-r--r--usr.sbin/bind/lib/dns/cache.c27
-rw-r--r--usr.sbin/bind/lib/dns/include/dns/rdataset.h37
-rw-r--r--usr.sbin/bind/lib/dns/message.c62
-rw-r--r--usr.sbin/bind/lib/dns/name.c28
-rw-r--r--usr.sbin/bind/lib/dns/rbt.c9
-rw-r--r--usr.sbin/bind/lib/dns/rbtdb.c43
-rw-r--r--usr.sbin/bind/lib/dns/rdata.c14
-rw-r--r--usr.sbin/bind/lib/dns/rdata/any_255/tsig_250.c16
-rw-r--r--usr.sbin/bind/lib/dns/rdata/generic/ds_43.c12
-rw-r--r--usr.sbin/bind/lib/dns/rdata/generic/rt_21.c6
-rw-r--r--usr.sbin/bind/lib/dns/resolver.c224
-rw-r--r--usr.sbin/bind/lib/dns/tsig.c6
-rw-r--r--usr.sbin/bind/lib/dns/validator.c618
-rw-r--r--usr.sbin/bind/lib/dns/xfrin.c10
-rw-r--r--usr.sbin/bind/lib/dns/zone.c245
17 files changed, 795 insertions, 578 deletions
diff --git a/usr.sbin/bind/lib/dns/adb.c b/usr.sbin/bind/lib/dns/adb.c
index e21965a91ae..9dd4f19bebc 100644
--- a/usr.sbin/bind/lib/dns/adb.c
+++ b/usr.sbin/bind/lib/dns/adb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: adb.c,v 1.181.2.11.2.20 2004/11/10 22:32:40 marka Exp $ */
+/* $ISC: adb.c,v 1.181.2.11.2.24 2005/10/14 05:19:00 marka Exp $ */
/*
* Implementation notes
@@ -1784,7 +1784,7 @@ shutdown_task(isc_task_t *task, isc_event_t *ev) {
static isc_boolean_t
check_expire_name(dns_adbname_t **namep, isc_stdtime_t now) {
dns_adbname_t *name;
- isc_result_t result = ISC_FALSE;
+ isc_boolean_t result = ISC_FALSE;
INSIST(namep != NULL && DNS_ADBNAME_VALID(*namep));
name = *namep;
@@ -1861,7 +1861,7 @@ static isc_boolean_t
cleanup_names(dns_adb_t *adb, int bucket, isc_stdtime_t now) {
dns_adbname_t *name;
dns_adbname_t *next_name;
- isc_result_t result = ISC_FALSE;
+ isc_boolean_t result = ISC_FALSE;
DP(CLEAN_LEVEL, "cleaning name bucket %d", bucket);
@@ -3347,7 +3347,7 @@ dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone,
bucket = addr->entry->lock_bucket;
LOCK(&adb->entrylocks[bucket]);
zi = ISC_LIST_HEAD(addr->entry->zoneinfo);
- while (zi != NULL && dns_name_equal(zone, &zi->zone))
+ while (zi != NULL && !dns_name_equal(zone, &zi->zone))
zi = ISC_LIST_NEXT(zi, plink);
if (zi != NULL) {
if (expire_time > zi->lame_timer)
@@ -3366,7 +3366,7 @@ dns_adb_marklame(dns_adb_t *adb, dns_adbaddrinfo_t *addr, dns_name_t *zone,
unlock:
UNLOCK(&adb->entrylocks[bucket]);
- return (ISC_R_SUCCESS);
+ return (result);
}
void
diff --git a/usr.sbin/bind/lib/dns/api b/usr.sbin/bind/lib/dns/api
index c06a62ec803..7df81573fd7 100644
--- a/usr.sbin/bind/lib/dns/api
+++ b/usr.sbin/bind/lib/dns/api
@@ -1,3 +1,3 @@
-LIBINTERFACE = 20
-LIBREVISION = 2
+LIBINTERFACE = 21
+LIBREVISION = 1
LIBAGE = 0
diff --git a/usr.sbin/bind/lib/dns/cache.c b/usr.sbin/bind/lib/dns/cache.c
index 83f4629ee81..8175a0a0144 100644
--- a/usr.sbin/bind/lib/dns/cache.c
+++ b/usr.sbin/bind/lib/dns/cache.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: cache.c,v 1.45.2.4.8.7 2004/03/08 02:07:52 marka Exp $ */
+/* $ISC: cache.c,v 1.45.2.4.8.9 2005/03/17 03:58:30 marka Exp $ */
#include <config.h>
@@ -1021,27 +1021,10 @@ dns_cache_flushname(dns_cache_t *cache, dns_name_t *name) {
dns_rdataset_init(&rdataset);
dns_rdatasetiter_current(iter, &rdataset);
-
- for (result = dns_rdataset_first(&rdataset);
- result == ISC_R_SUCCESS;
- result = dns_rdataset_next(&rdataset))
- {
- dns_rdata_t rdata = DNS_RDATA_INIT;
- dns_rdatatype_t covers;
-
- dns_rdataset_current(&rdataset, &rdata);
- if (rdata.type == dns_rdatatype_rrsig)
- covers = dns_rdata_covers(&rdata);
- else
- covers = 0;
- result = dns_db_deleterdataset(cache->db, node, NULL,
- rdata.type, covers);
- if (result != ISC_R_SUCCESS &&
- result != DNS_R_UNCHANGED)
- break;
- }
+ result = dns_db_deleterdataset(cache->db, node, NULL,
+ rdataset.type, rdataset.covers);
dns_rdataset_disassociate(&rdataset);
- if (result != ISC_R_NOMORE)
+ if (result != ISC_R_SUCCESS && result != DNS_R_UNCHANGED)
break;
}
if (result == ISC_R_NOMORE)
diff --git a/usr.sbin/bind/lib/dns/include/dns/rdataset.h b/usr.sbin/bind/lib/dns/include/dns/rdataset.h
index 595a9af30fd..ca06b0e34cb 100644
--- a/usr.sbin/bind/lib/dns/include/dns/rdataset.h
+++ b/usr.sbin/bind/lib/dns/include/dns/rdataset.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rdataset.h,v 1.41.2.5.2.6 2004/03/08 02:08:01 marka Exp $ */
+/* $ISC: rdataset.h,v 1.41.2.5.2.8 2005/03/17 03:58:31 marka Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
@@ -130,22 +130,23 @@ struct dns_rdataset {
* Used by message.c to indicate that the rdataset's rdata had differing
* TTL values, and the rdataset->ttl holds the smallest.
*/
-#define DNS_RDATASETATTR_QUESTION 0x0001
-#define DNS_RDATASETATTR_RENDERED 0x0002 /* Used by message.c */
-#define DNS_RDATASETATTR_ANSWERED 0x0004 /* Used by server. */
-#define DNS_RDATASETATTR_CACHE 0x0008 /* Used by resolver. */
-#define DNS_RDATASETATTR_ANSWER 0x0010 /* Used by resolver. */
-#define DNS_RDATASETATTR_ANSWERSIG 0x0020 /* Used by resolver. */
-#define DNS_RDATASETATTR_EXTERNAL 0x0040 /* Used by resolver. */
-#define DNS_RDATASETATTR_NCACHE 0x0080 /* Used by resolver. */
-#define DNS_RDATASETATTR_CHAINING 0x0100 /* Used by resolver. */
-#define DNS_RDATASETATTR_TTLADJUSTED 0x0200 /* Used by message.c */
-#define DNS_RDATASETATTR_FIXEDORDER 0x0400
-#define DNS_RDATASETATTR_RANDOMIZE 0x0800
-#define DNS_RDATASETATTR_CHASE 0x1000 /* Used by resolver. */
-#define DNS_RDATASETATTR_NXDOMAIN 0x2000
-#define DNS_RDATASETATTR_NOQNAME 0x4000
-#define DNS_RDATASETATTR_CHECKNAMES 0x8000 /* Used by resolver. */
+#define DNS_RDATASETATTR_QUESTION 0x00000001
+#define DNS_RDATASETATTR_RENDERED 0x00000002 /* Used by message.c */
+#define DNS_RDATASETATTR_ANSWERED 0x00000004 /* Used by server. */
+#define DNS_RDATASETATTR_CACHE 0x00000008 /* Used by resolver. */
+#define DNS_RDATASETATTR_ANSWER 0x00000010 /* Used by resolver. */
+#define DNS_RDATASETATTR_ANSWERSIG 0x00000020 /* Used by resolver. */
+#define DNS_RDATASETATTR_EXTERNAL 0x00000040 /* Used by resolver. */
+#define DNS_RDATASETATTR_NCACHE 0x00000080 /* Used by resolver. */
+#define DNS_RDATASETATTR_CHAINING 0x00000100 /* Used by resolver. */
+#define DNS_RDATASETATTR_TTLADJUSTED 0x00000200 /* Used by message.c */
+#define DNS_RDATASETATTR_FIXEDORDER 0x00000400
+#define DNS_RDATASETATTR_RANDOMIZE 0x00000800
+#define DNS_RDATASETATTR_CHASE 0x00001000 /* Used by resolver. */
+#define DNS_RDATASETATTR_NXDOMAIN 0x00002000
+#define DNS_RDATASETATTR_NOQNAME 0x00004000
+#define DNS_RDATASETATTR_CHECKNAMES 0x00008000 /* Used by resolver. */
+#define DNS_RDATASETATTR_REQUIREDGLUE 0x00010000
/*
* _OMITDNSSEC:
diff --git a/usr.sbin/bind/lib/dns/message.c b/usr.sbin/bind/lib/dns/message.c
index ea6f863e1af..5dbaa35c31a 100644
--- a/usr.sbin/bind/lib/dns/message.c
+++ b/usr.sbin/bind/lib/dns/message.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: message.c,v 1.194.2.10.2.17 2004/05/05 01:32:16 marka Exp $ */
+/* $ISC: message.c,v 1.194.2.10.2.20 2005/06/07 01:42:23 marka Exp $ */
/***
*** Imports
@@ -1476,6 +1476,13 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
free_name = ISC_FALSE;
}
+ if (seen_problem) {
+ if (free_name)
+ isc_mempool_put(msg->namepool, name);
+ if (free_rdataset)
+ isc_mempool_put(msg->rdspool, rdataset);
+ free_name = free_rdataset = ISC_FALSE;
+ }
INSIST(free_name == ISC_FALSE);
INSIST(free_rdataset == ISC_FALSE);
}
@@ -1783,6 +1790,57 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid,
if (msg->reserved == 0 && (options & DNS_MESSAGERENDER_PARTIAL) != 0)
partial = ISC_TRUE;
+ /*
+ * Render required glue first. Set TC if it won't fit.
+ */
+ name = ISC_LIST_HEAD(*section);
+ if (name != NULL) {
+ rdataset = ISC_LIST_HEAD(name->list);
+ if (rdataset != NULL &&
+ (rdataset->attributes & DNS_RDATASETATTR_REQUIREDGLUE) != 0 &&
+ (rdataset->attributes & DNS_RDATASETATTR_RENDERED) == 0) {
+ void *order_arg = msg->order_arg;
+ st = *(msg->buffer);
+ count = 0;
+ if (partial)
+ result = dns_rdataset_towirepartial(rdataset,
+ name,
+ msg->cctx,
+ msg->buffer,
+ msg->order,
+ order_arg,
+ rd_options,
+ &count,
+ NULL);
+ else
+ result = dns_rdataset_towiresorted(rdataset,
+ name,
+ msg->cctx,
+ msg->buffer,
+ msg->order,
+ order_arg,
+ rd_options,
+ &count);
+ total += count;
+ if (partial && result == ISC_R_NOSPACE) {
+ msg->flags |= DNS_MESSAGEFLAG_TC;
+ msg->buffer->length += msg->reserved;
+ msg->counts[sectionid] += total;
+ return (result);
+ }
+ if (result != ISC_R_SUCCESS) {
+ INSIST(st.used < 65536);
+ dns_compress_rollback(msg->cctx,
+ (isc_uint16_t)st.used);
+ *(msg->buffer) = st; /* rollback */
+ msg->buffer->length += msg->reserved;
+ msg->counts[sectionid] += total;
+ return (result);
+ }
+ rdataset->attributes |= DNS_RDATASETATTR_RENDERED;
+ }
+ }
+
do {
name = ISC_LIST_HEAD(*section);
if (name == NULL) {
diff --git a/usr.sbin/bind/lib/dns/name.c b/usr.sbin/bind/lib/dns/name.c
index f32f7636317..4a176c7e0ce 100644
--- a/usr.sbin/bind/lib/dns/name.c
+++ b/usr.sbin/bind/lib/dns/name.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: name.c,v 1.127.2.7.2.11 2004/09/01 05:19:59 marka Exp $ */
+/* $ISC: name.c,v 1.127.2.7.2.14 2005/10/14 01:38:48 marka Exp $ */
#include <config.h>
@@ -945,9 +945,9 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
unsigned char *ndata, *label;
char *tdata;
char c;
- ft_state state, kind;
- unsigned int value, count, tbcount, bitlength, maxlength;
- unsigned int n1, n2, vlen, tlen, nrem, nused, digits, labels, tused;
+ ft_state state;
+ unsigned int value, count;
+ unsigned int n1, n2, tlen, nrem, nused, digits, labels, tused;
isc_boolean_t done;
unsigned char *offsets;
dns_offsets_t odata;
@@ -985,15 +985,10 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
*/
n1 = 0;
n2 = 0;
- vlen = 0;
label = NULL;
digits = 0;
value = 0;
count = 0;
- tbcount = 0;
- bitlength = 0;
- maxlength = 0;
- kind = ft_init;
/*
* Make 'name' empty in case of failure.
@@ -1051,7 +1046,6 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
state = ft_initialescape;
break;
}
- kind = ft_ordinary;
state = ft_ordinary;
if (nrem == 0)
return (ISC_R_NOSPACE);
@@ -1094,7 +1088,6 @@ dns_name_fromtext(dns_name_t *name, isc_buffer_t *source,
*/
return (DNS_R_BADLABELTYPE);
}
- kind = ft_ordinary;
state = ft_escape;
/* FALLTHROUGH */
case ft_escape:
@@ -1305,13 +1298,14 @@ dns_name_totext(dns_name_t *name, isc_boolean_t omit_final_dot,
trem--;
nlen--;
} else {
- char buf[5];
if (trem < 4)
return (ISC_R_NOSPACE);
- snprintf(buf, sizeof(buf),
- "\\%03u", c);
- memcpy(tdata, buf, 4);
- tdata += 4;
+ *tdata++ = 0x5c;
+ *tdata++ = 0x30 +
+ ((c / 100) % 10);
+ *tdata++ = 0x30 +
+ ((c / 10) % 10);
+ *tdata++ = 0x30 + (c % 10);
trem -= 4;
ndata++;
nlen--;
diff --git a/usr.sbin/bind/lib/dns/rbt.c b/usr.sbin/bind/lib/dns/rbt.c
index aef9d996ede..fcaee76f80e 100644
--- a/usr.sbin/bind/lib/dns/rbt.c
+++ b/usr.sbin/bind/lib/dns/rbt.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rbt.c,v 1.115.2.2.2.11 2004/10/25 01:36:07 marka Exp $ */
+/* $ISC: rbt.c,v 1.115.2.2.2.13 2005/06/18 01:03:24 marka Exp $ */
/* Principal Authors: DCL */
@@ -2060,7 +2060,10 @@ dns_rbt_deletetreeflat(dns_rbt_t *rbt, unsigned int quantum,
if (DATA(node) != NULL && rbt->data_deleter != NULL)
rbt->data_deleter(DATA(node), rbt->deleter_arg);
- unhash_node(rbt, node);
+ /*
+ * Note: we don't call unhash_node() here as we are destroying
+ * the complete rbt tree.
+ */
#if DNS_RBT_USEMAGIC
node->magic = 0;
#endif
diff --git a/usr.sbin/bind/lib/dns/rbtdb.c b/usr.sbin/bind/lib/dns/rbtdb.c
index 32d787e1219..3c08492e17a 100644
--- a/usr.sbin/bind/lib/dns/rbtdb.c
+++ b/usr.sbin/bind/lib/dns/rbtdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rbtdb.c,v 1.168.2.11.2.16 2004/05/23 11:07:23 marka Exp $ */
+/* $ISC: rbtdb.c,v 1.168.2.11.2.22 2005/10/14 01:38:48 marka Exp $ */
/*
* Principal Author: Bob Halley
@@ -97,6 +97,12 @@ typedef isc_uint32_t rbtdb_rdatatype_t;
#define RBTDB_RDATATYPE_NCACHEANY \
RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_any)
+/*
+ * Allow clients with a virtual time of upto 5 minutes in the past to see
+ * records that would have otherwise have expired.
+ */
+#define RBTDB_VIRTUAL 300
+
struct noqname {
dns_name_t name;
void * nsec;
@@ -413,7 +419,7 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
again:
if (rbtdb->tree != NULL) {
result = dns_rbt_destroy2(&rbtdb->tree,
- (rbtdb->task != NULL) ? 5 : 0);
+ (rbtdb->task != NULL) ? 1000 : 0);
if (result == ISC_R_QUOTA) {
INSIST(rbtdb->task != NULL);
if (event == NULL)
@@ -2752,10 +2758,9 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
isc_result_t result;
dns_fixedname_t fname, forigin;
dns_name_t *name, *origin;
- rbtdb_rdatatype_t matchtype, sigmatchtype, nsectype;
+ rbtdb_rdatatype_t matchtype, sigmatchtype;
matchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_nsec, 0);
- nsectype = RBTDB_RDATATYPE_VALUE(0, dns_rdatatype_nsec);
sigmatchtype = RBTDB_RDATATYPE_VALUE(dns_rdatatype_rrsig,
dns_rdatatype_nsec);
@@ -2786,7 +2791,9 @@ find_coveringnsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
* node as dirty, so it will get cleaned up
* later.
*/
- if (node->references == 0) {
+ if (header->ttl > search->now - RBTDB_VIRTUAL)
+ header_prev = header;
+ else if (node->references == 0) {
INSIST(header->down == NULL);
if (header_prev != NULL)
header_prev->next =
@@ -2943,7 +2950,9 @@ cache_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* mark it as stale, and the node as dirty, so it will
* get cleaned up later.
*/
- if (node->references == 0) {
+ if (header->ttl > now - RBTDB_VIRTUAL)
+ header_prev = header;
+ else if (node->references == 0) {
INSIST(header->down == NULL);
if (header_prev != NULL)
header_prev->next = header->next;
@@ -3210,7 +3219,9 @@ cache_findzonecut(dns_db_t *db, dns_name_t *name, unsigned int options,
* mark it as stale, and the node as dirty, so it will
* get cleaned up later.
*/
- if (node->references == 0) {
+ if (header->ttl > now - RBTDB_VIRTUAL)
+ header_prev = header;
+ else if (node->references == 0) {
INSIST(header->down == NULL);
if (header_prev != NULL)
header_prev->next = header->next;
@@ -3398,7 +3409,7 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) {
LOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
for (header = rbtnode->data; header != NULL; header = header->next)
- if (header->ttl <= now) {
+ if (header->ttl <= now - RBTDB_VIRTUAL) {
/*
* We don't check if rbtnode->references == 0 and try
* to free like we do in cache_find(), because
@@ -3640,8 +3651,10 @@ cache_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
* rbtnode->references must be non-zero. This is so
* because 'node' is an argument to the function.
*/
- header->attributes |= RDATASET_ATTR_STALE;
- rbtnode->dirty = 1;
+ if (header->ttl <= now - RBTDB_VIRTUAL) {
+ header->attributes |= RDATASET_ATTR_STALE;
+ rbtnode->dirty = 1;
+ }
} else if (EXISTS(header)) {
if (header->type == matchtype)
found = header;
@@ -4344,6 +4357,7 @@ subtractrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
changed = add_changed(rbtdb, rbtversion, rbtnode);
if (changed == NULL) {
free_rdataset(rbtdb->common.mctx, newheader);
+ UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock);
return (ISC_R_NOMEMORY);
}
@@ -4909,6 +4923,11 @@ dns_rbtdb_create
isc_mem_attach(mctx, &rbtdb->common.mctx);
/*
+ * Must be initalized before free_rbtdb() is called.
+ */
+ isc_ondestroy_init(&rbtdb->common.ondest);
+
+ /*
* Make a copy of the origin name.
*/
result = dns_name_dupwithoffsets(origin, mctx, &rbtdb->common.origin);
@@ -4986,8 +5005,6 @@ dns_rbtdb_create
rbtdb->future_version = NULL;
ISC_LIST_INIT(rbtdb->open_versions);
- isc_ondestroy_init(&rbtdb->common.ondest);
-
rbtdb->common.magic = DNS_DB_MAGIC;
rbtdb->common.impmagic = RBTDB_MAGIC;
diff --git a/usr.sbin/bind/lib/dns/rdata.c b/usr.sbin/bind/lib/dns/rdata.c
index 6527157414d..9626b3231f5 100644
--- a/usr.sbin/bind/lib/dns/rdata.c
+++ b/usr.sbin/bind/lib/dns/rdata.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1998-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rdata.c,v 1.147.2.11.2.16 2004/10/06 05:37:40 marka Exp $ */
+/* $ISC: rdata.c,v 1.147.2.11.2.20 2005/07/22 05:27:52 marka Exp $ */
#include <config.h>
#include <ctype.h>
@@ -985,11 +985,15 @@ txt_totext(isc_region_t *source, isc_buffer_t *target) {
if (*sp < 0x20 || *sp >= 0x7f) {
if (tl < 4)
return (ISC_R_NOSPACE);
- snprintf(tp, 5, "\\%03u", *sp++);
- tp += 4;
+ *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);
@@ -1212,7 +1216,7 @@ name_tobuffer(dns_name_t *name, isc_buffer_t *target) {
static isc_uint32_t
uint32_fromregion(isc_region_t *region) {
- unsigned long value;
+ isc_uint32_t value;
REQUIRE(region->length >= 4);
value = region->base[0] << 24;
diff --git a/usr.sbin/bind/lib/dns/rdata/any_255/tsig_250.c b/usr.sbin/bind/lib/dns/rdata/any_255/tsig_250.c
index 11734f0288d..a9f0ce25bbc 100644
--- a/usr.sbin/bind/lib/dns/rdata/any_255/tsig_250.c
+++ b/usr.sbin/bind/lib/dns/rdata/any_255/tsig_250.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: tsig_250.c,v 1.52.2.1.2.6 2004/03/08 09:04:40 marka Exp $ */
+/* $ISC: tsig_250.c,v 1.52.2.1.2.8 2005/03/20 22:34:01 marka Exp $ */
/* Reviewed: Thu Mar 16 13:39:43 PST 2000 by gson */
@@ -162,8 +162,10 @@ totext_any_tsig(ARGS_TOTEXT) {
*/
sigtime = ((isc_uint64_t)sr.base[0] << 40) |
((isc_uint64_t)sr.base[1] << 32) |
- (sr.base[2] << 24) | (sr.base[3] << 16) |
- (sr.base[4] << 8) | sr.base[5];
+ ((isc_uint64_t)sr.base[2] << 24) |
+ ((isc_uint64_t)sr.base[3] << 16) |
+ ((isc_uint64_t)sr.base[4] << 8) |
+ (isc_uint64_t)sr.base[5];
isc_region_consume(&sr, 6);
bufp = &buf[sizeof(buf) - 1];
*bufp-- = 0;
@@ -457,8 +459,10 @@ tostruct_any_tsig(ARGS_TOSTRUCT) {
INSIST(sr.length >= 6);
tsig->timesigned = ((isc_uint64_t)sr.base[0] << 40) |
((isc_uint64_t)sr.base[1] << 32) |
- (sr.base[2] << 24) | (sr.base[3] << 16) |
- (sr.base[4] << 8) | sr.base[5];
+ ((isc_uint64_t)sr.base[2] << 24) |
+ ((isc_uint64_t)sr.base[3] << 16) |
+ ((isc_uint64_t)sr.base[4] << 8) |
+ (isc_uint64_t)sr.base[5];
isc_region_consume(&sr, 6);
/*
diff --git a/usr.sbin/bind/lib/dns/rdata/generic/ds_43.c b/usr.sbin/bind/lib/dns/rdata/generic/ds_43.c
index 807d5a4f38f..90724c87e1e 100644
--- a/usr.sbin/bind/lib/dns/rdata/generic/ds_43.c
+++ b/usr.sbin/bind/lib/dns/rdata/generic/ds_43.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: ds_43.c,v 1.6.2.2 2004/03/16 12:38:14 marka Exp $ */
+/* $ISC: ds_43.c,v 1.6.2.4 2005/09/06 07:29:31 marka Exp $ */
/* draft-ietf-dnsext-delegation-signer-05.txt */
@@ -28,6 +28,7 @@
static inline isc_result_t
fromtext_ds(ARGS_FROMTEXT) {
isc_token_t token;
+ unsigned char c;
REQUIRE(type == 43);
@@ -49,11 +50,10 @@ fromtext_ds(ARGS_FROMTEXT) {
/*
* Algorithm.
*/
- RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_number,
+ RETERR(isc_lex_getmastertoken(lexer, &token, isc_tokentype_string,
ISC_FALSE));
- if (token.value.as_ulong > 0xffU)
- RETTOK(ISC_R_RANGE);
- RETERR(uint8_tobuffer(token.value.as_ulong, target));
+ RETTOK(dns_secalg_fromtext(&c, &token.value.as_textregion));
+ RETERR(mem_tobuffer(target, &c, 1));
/*
* Digest type.
diff --git a/usr.sbin/bind/lib/dns/rdata/generic/rt_21.c b/usr.sbin/bind/lib/dns/rdata/generic/rt_21.c
index 85e5764b9d3..4523dad9182 100644
--- a/usr.sbin/bind/lib/dns/rdata/generic/rt_21.c
+++ b/usr.sbin/bind/lib/dns/rdata/generic/rt_21.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001, 2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: rt_21.c,v 1.37.2.1.2.3 2004/03/06 08:14:11 marka Exp $ */
+/* $ISC: rt_21.c,v 1.37.2.1.2.5 2005/03/17 03:58:31 marka Exp $ */
/* reviewed: Thu Mar 16 15:02:31 PST 2000 by brister */
@@ -300,7 +300,7 @@ checknames_rt(ARGS_CHECKNAMES) {
isc_region_consume(&region, 2);
dns_name_init(&name, NULL);
dns_name_fromregion(&name, &region);
- if (dns_name_ishostname(&name, ISC_FALSE)) {
+ if (!dns_name_ishostname(&name, ISC_FALSE)) {
if (bad != NULL)
dns_name_clone(&name, bad);
return (ISC_FALSE);
diff --git a/usr.sbin/bind/lib/dns/resolver.c b/usr.sbin/bind/lib/dns/resolver.c
index 3644c606c7a..5c963917d24 100644
--- a/usr.sbin/bind/lib/dns/resolver.c
+++ b/usr.sbin/bind/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: resolver.c,v 1.218.2.18.4.51 2005/02/08 23:59:44 marka Exp $ */
+/* $ISC: resolver.c,v 1.218.2.18.4.56 2005/10/14 01:38:48 marka Exp $ */
#include <config.h>
@@ -244,6 +244,11 @@ struct fetchctx {
#define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0)
#define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0)
+typedef struct {
+ dns_adbaddrinfo_t * addrinfo;
+ fetchctx_t * fctx;
+} dns_valarg_t;
+
struct dns_fetch {
unsigned int magic;
fetchctx_t * private;
@@ -342,6 +347,35 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
isc_stdtime_t now, dns_ttl_t maxttl,
dns_rdataset_t *ardataset,
isc_result_t *eresultp);
+static void validated(isc_task_t *task, isc_event_t *event);
+
+static isc_result_t
+valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
+ dns_rdatatype_t type, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset, unsigned int valoptions,
+ isc_task_t *task)
+{
+ dns_validator_t *validator = NULL;
+ dns_valarg_t *valarg;
+ isc_result_t result;
+
+ valarg = isc_mem_get(fctx->res->mctx, sizeof(*valarg));
+ if (valarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ valarg->fctx = fctx;
+ valarg->addrinfo = addrinfo;
+
+ result = dns_validator_create(fctx->res->view, name, type, rdataset,
+ sigrdataset, fctx->rmessage,
+ valoptions, task, validated, valarg,
+ &validator);
+ if (result == ISC_R_SUCCESS)
+ ISC_LIST_APPEND(fctx->validators, validator, link);
+ else
+ isc_mem_put(fctx->res->mctx, valarg, sizeof(*valarg));
+ return (result);
+}
static isc_boolean_t
fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
@@ -1424,6 +1458,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
case ISC_R_CONNREFUSED:
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
+ case ISC_R_CONNECTIONRESET:
/*
* No route to remote.
*/
@@ -1855,7 +1890,6 @@ fctx_getaddresses(fetchctx_t *fctx) {
isc_boolean_t pruned, all_bad;
dns_rdata_ns_t ns;
isc_boolean_t need_alternate = ISC_FALSE;
- isc_boolean_t unshared;
FCTXTRACE("getaddresses");
@@ -1871,7 +1905,6 @@ fctx_getaddresses(fetchctx_t *fctx) {
res = fctx->res;
pruned = ISC_FALSE;
stdoptions = 0; /* Keep compiler happy. */
- unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);
/*
* Forwarders.
@@ -2668,7 +2701,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
isc_result_t result;
isc_result_t iresult;
isc_interval_t interval;
- dns_fixedname_t qdomain;
+ dns_fixedname_t fixed;
unsigned int findoptions = 0;
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
@@ -2747,8 +2780,10 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
name = &suffix;
}
- result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
- &forwarders);
+ dns_fixedname_init(&fixed);
+ domain = dns_fixedname_name(&fixed);
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
+ domain, &forwarders);
if (result == ISC_R_SUCCESS)
fctx->fwdpolicy = forwarders->fwdpolicy;
@@ -2760,27 +2795,22 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
*/
if (dns_rdatatype_atparent(type))
findoptions |= DNS_DBFIND_NOEXACT;
- dns_fixedname_init(&qdomain);
- result = dns_view_findzonecut(res->view, name,
- dns_fixedname_name(&qdomain), 0,
- findoptions, ISC_TRUE,
+ result = dns_view_findzonecut(res->view, name, domain,
+ 0, findoptions, ISC_TRUE,
&fctx->nameservers,
NULL);
if (result != ISC_R_SUCCESS)
goto cleanup_name;
- result = dns_name_dup(dns_fixedname_name(&qdomain),
- res->mctx, &fctx->domain);
+ result = dns_name_dup(domain, res->mctx, &fctx->domain);
if (result != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&fctx->nameservers);
goto cleanup_name;
}
} else {
/*
- * We're in forward-only mode. Set the query domain
- * to ".".
+ * We're in forward-only mode. Set the query domain.
*/
- result = dns_name_dup(dns_rootname, res->mctx,
- &fctx->domain);
+ result = dns_name_dup(domain, res->mctx, &fctx->domain);
if (result != ISC_R_SUCCESS)
goto cleanup_name;
}
@@ -3090,11 +3120,15 @@ validated(isc_task_t *task, isc_event_t *event) {
dns_name_t *name;
dns_rdataset_t *rdataset;
dns_rdataset_t *sigrdataset;
+ dns_valarg_t *valarg;
+ dns_adbaddrinfo_t *addrinfo;
UNUSED(task); /* for now */
REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
- fctx = event->ev_arg;
+ valarg = event->ev_arg;
+ fctx = valarg->fctx;
+ addrinfo = valarg->addrinfo;
REQUIRE(VALID_FCTX(fctx));
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
@@ -3109,6 +3143,7 @@ validated(isc_task_t *task, isc_event_t *event) {
* destroy the fctx if necessary.
*/
dns_validator_destroy(&vevent->validator);
+ isc_mem_put(fctx->res->mctx, valarg, sizeof(*valarg));
negative = ISC_TF(vevent->rdataset == NULL);
@@ -3166,21 +3201,27 @@ validated(isc_task_t *task, isc_event_t *event) {
if (vevent->result != ISC_R_SUCCESS) {
FCTXTRACE("validation failed");
- if (vevent->rdataset != NULL) {
+ result = ISC_R_NOTFOUND;
+ if (vevent->rdataset != NULL)
result = dns_db_findnode(fctx->cache, vevent->name,
ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto noanswer_response;
+ if (result == ISC_R_SUCCESS)
(void)dns_db_deleterdataset(fctx->cache, node, NULL,
vevent->type, 0);
- if (vevent->sigrdataset != NULL)
- (void)dns_db_deleterdataset(fctx->cache,
- node, NULL,
- dns_rdatatype_rrsig,
- vevent->type);
- }
+ if (result == ISC_R_SUCCESS && vevent->sigrdataset != NULL)
+ (void)dns_db_deleterdataset(fctx->cache, node, NULL,
+ dns_rdatatype_rrsig,
+ vevent->type);
+ if (result == ISC_R_SUCCESS)
+ dns_db_detachnode(fctx->cache, &node);
result = vevent->result;
- goto noanswer_response;
+ add_bad(fctx, &addrinfo->sockaddr, result);
+ isc_event_free(&event);
+ if (sentresponse)
+ fctx_done(fctx, result);
+ else
+ fctx_try(fctx);
+ return;
}
isc_stdtime_get(&now);
@@ -3350,7 +3391,8 @@ validated(isc_task_t *task, isc_event_t *event) {
}
static inline isc_result_t
-cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
+cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
+ isc_stdtime_t now) {
dns_rdataset_t *rdataset, *sigrdataset;
dns_rdataset_t *addedrdataset, *ardataset, *asigrdataset;
dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL;
@@ -3363,8 +3405,8 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
dns_fetchevent_t *event;
unsigned int options;
isc_task_t *task;
- dns_validator_t *validator;
isc_boolean_t fail;
+ unsigned int valoptions = 0;
/*
* The appropriate bucket lock must be held.
@@ -3385,8 +3427,10 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
if (result != ISC_R_SUCCESS)
return (result);
- if (res->view->dlv != NULL)
+ if (!secure_domain && res->view->dlv != NULL) {
+ valoptions = DNS_VALIDATOR_DLV;
secure_domain = ISC_TRUE;
+ }
if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
need_validation = ISC_FALSE;
@@ -3437,7 +3481,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
/*
* Cache or validate each cacheable rdataset.
*/
- fail = (fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0;
+ fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0);
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
@@ -3569,23 +3613,11 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
* having to remember which
* rdatasets needed validation.
*/
- validator = NULL;
- result = dns_validator_create(
- res->view,
- name,
- rdataset->type,
- rdataset,
- sigrdataset,
- fctx->rmessage,
- 0,
- task,
- validated,
- fctx,
- &validator);
- if (result == ISC_R_SUCCESS)
- ISC_LIST_APPEND(
- fctx->validators,
- validator, link);
+ result = valcreate(fctx, addrinfo,
+ name, rdataset->type,
+ rdataset,
+ sigrdataset,
+ valoptions, task);
}
} else if (CHAINING(rdataset)) {
if (rdataset->type == dns_rdatatype_cname)
@@ -3660,22 +3692,10 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
}
}
- if (valrdataset != NULL) {
- validator = NULL;
- result = dns_validator_create(res->view,
- name,
- fctx->type,
- valrdataset,
- valsigrdataset,
- fctx->rmessage,
- 0,
- task,
- validated,
- fctx,
- &validator);
- if (result == ISC_R_SUCCESS)
- ISC_LIST_APPEND(fctx->validators, validator, link);
- }
+ if (valrdataset != NULL)
+ result = valcreate(fctx, addrinfo, name, fctx->type,
+ valrdataset, valsigrdataset, valoptions,
+ task);
if (result == ISC_R_SUCCESS && have_answer) {
fctx->attributes |= FCTX_ATTR_HAVEANSWER;
@@ -3695,7 +3715,8 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
}
static inline isc_result_t
-cache_message(fetchctx_t *fctx, isc_stdtime_t now) {
+cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
+{
isc_result_t result;
dns_section_t section;
dns_name_t *name;
@@ -3715,7 +3736,7 @@ cache_message(fetchctx_t *fctx, isc_stdtime_t now) {
dns_message_currentname(fctx->rmessage, section,
&name);
if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) {
- result = cache_name(fctx, name, now);
+ result = cache_name(fctx, name, addrinfo, now);
if (result != ISC_R_SUCCESS)
break;
}
@@ -3783,7 +3804,9 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
}
static inline isc_result_t
-ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
+ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
+ dns_rdatatype_t covers, isc_stdtime_t now)
+{
isc_result_t result, eresult;
dns_name_t *name;
dns_resolver_t *res;
@@ -3794,6 +3817,7 @@ ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
dns_name_t *aname;
dns_fetchevent_t *event;
isc_uint32_t ttl;
+ unsigned int valoptions = 0;
FCTXTRACE("ncache_message");
@@ -3820,8 +3844,10 @@ ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
if (result != ISC_R_SUCCESS)
return (result);
- if (res->view->dlv != NULL)
+ if (!secure_domain && res->view->dlv != NULL) {
+ valoptions = DNS_VALIDATOR_DLV;
secure_domain = ISC_TRUE;
+ }
if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
need_validation = ISC_FALSE;
@@ -3858,23 +3884,15 @@ ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
/*
* Do negative response validation.
*/
- dns_validator_t *validator = NULL;
- isc_task_t *task = res->buckets[fctx->bucketnum].task;
-
- result = dns_validator_create(res->view, name, fctx->type,
- NULL, NULL,
- fctx->rmessage, 0, task,
- validated, fctx,
- &validator);
- if (result != ISC_R_SUCCESS)
- return (result);
- ISC_LIST_APPEND(fctx->validators, validator, link);
+ result = valcreate(fctx, addrinfo, name, fctx->type,
+ NULL, NULL, valoptions,
+ res->buckets[fctx->bucketnum].task);
/*
* If validation is necessary, return now. Otherwise continue
* to process the message, letting the validation complete
* in its own good time.
*/
- return (ISC_R_SUCCESS);
+ return (result);
}
LOCK(&res->buckets[fctx->bucketnum].lock);
@@ -4992,6 +5010,43 @@ checknames(dns_message_t *message) {
}
static void
+log_packet(dns_message_t *message, int level, isc_mem_t *mctx) {
+ isc_buffer_t buffer;
+ char *buf = NULL;
+ int len = 1024;
+ isc_result_t result;
+
+ if (! isc_log_wouldlog(dns_lctx, level))
+ return;
+
+ /*
+ * Note that these are multiline debug messages. We want a newline
+ * to appear in the log after each message.
+ */
+
+ do {
+ buf = isc_mem_get(mctx, len);
+ if (buf == NULL)
+ break;
+ isc_buffer_init(&buffer, buf, len);
+ result = dns_message_totext(message, &dns_master_style_debug,
+ 0, &buffer);
+ if (result == ISC_R_NOSPACE) {
+ isc_mem_put(mctx, buf, len);
+ len += 1024;
+ } else if (result == ISC_R_SUCCESS)
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, level,
+ "received packet:\n%.*s",
+ (int)isc_buffer_usedlength(&buffer),
+ buf);
+ } while (result == ISC_R_NOSPACE);
+
+ if (buf != NULL)
+ isc_mem_put(mctx, buf, len);
+}
+
+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;
@@ -5160,6 +5215,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
/*
+ * Log the incoming packet.
+ */
+ log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
+
+ /*
* If the message is signed, check the signature. If not, this
* returns success anyway.
*/
@@ -5427,7 +5487,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* work to be queued to the DNSSEC validator.
*/
if (WANTCACHE(fctx)) {
- result = cache_message(fctx, now);
+ result = cache_message(fctx, query->addrinfo, now);
if (result != ISC_R_SUCCESS)
goto done;
}
@@ -5446,7 +5506,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/*
* Cache any negative cache entries in the message.
*/
- result = ncache_message(fctx, covers, now);
+ result = ncache_message(fctx, query->addrinfo, covers, now);
}
done:
diff --git a/usr.sbin/bind/lib/dns/tsig.c b/usr.sbin/bind/lib/dns/tsig.c
index 3e4db83633f..1428497e13e 100644
--- a/usr.sbin/bind/lib/dns/tsig.c
+++ b/usr.sbin/bind/lib/dns/tsig.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2002 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -16,7 +16,7 @@
*/
/*
- * $ISC: tsig.c,v 1.112.2.3.8.4 2004/03/08 09:04:32 marka Exp $
+ * $ISC: tsig.c,v 1.112.2.3.8.6 2005/03/17 03:58:31 marka Exp $
*/
#include <config.h>
@@ -167,7 +167,7 @@ dns_tsigkey_createfromkey(dns_name_t *name, dns_name_t *algorithm,
goto cleanup_name;
}
} else {
- if (key != NULL) {
+ if (dstkey != NULL) {
ret = DNS_R_BADALG;
goto cleanup_name;
}
diff --git a/usr.sbin/bind/lib/dns/validator.c b/usr.sbin/bind/lib/dns/validator.c
index 7a5f87c1db7..17709ffa4f2 100644
--- a/usr.sbin/bind/lib/dns/validator.c
+++ b/usr.sbin/bind/lib/dns/validator.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: validator.c,v 1.91.2.5.8.15 2005/02/09 05:13:02 marka Exp $ */
+/* $ISC: validator.c,v 1.91.2.5.8.21 2005/11/02 02:07:47 marka Exp $ */
#include <config.h>
@@ -51,9 +51,7 @@
#define VALATTR_TRIEDVERIFY 0x0004
#define VALATTR_NEGATIVE 0x0008
#define VALATTR_INSECURITY 0x0010
-#define VALATTR_DLV 0x0020
-#define VALATTR_DLVTRIED 0x0040
-#define VALATTR_DLVSEPTRIED 0x0080
+#define VALATTR_DLVTRIED 0x0020
#define VALATTR_NEEDNOQNAME 0x0100
#define VALATTR_NEEDNOWILDCARD 0x0200
@@ -63,13 +61,10 @@
#define VALATTR_FOUNDNOWILDCARD 0x2000
#define VALATTR_FOUNDNODATA 0x4000
-
#define NEEDNODATA(val) ((val->attributes & VALATTR_NEEDNODATA) != 0)
#define NEEDNOQNAME(val) ((val->attributes & VALATTR_NEEDNOQNAME) != 0)
#define NEEDNOWILDCARD(val) ((val->attributes & VALATTR_NEEDNOWILDCARD) != 0)
-#define DLV(val) ((val->attributes & VALATTR_DLV) != 0)
#define DLVTRIED(val) ((val->attributes & VALATTR_DLVTRIED) != 0)
-#define DLVSEPTRIED(val) ((val->attributes & VALATTR_DLVSEPTRIED) != 0)
#define SHUTDOWN(v) (((v)->attributes & VALATTR_SHUTDOWN) != 0)
@@ -110,8 +105,20 @@ static isc_result_t
dlv_validatezonekey(dns_validator_t *val);
static isc_result_t
+dlv_validator_start(dns_validator_t *val);
+
+static isc_result_t
finddlvsep(dns_validator_t *val, isc_boolean_t resume);
+static inline void
+markanswer(dns_validator_t *val) {
+ validator_log(val, ISC_LOG_DEBUG(3), "marking as answer");
+ if (val->event->rdataset)
+ val->event->rdataset->trust = dns_trust_answer;
+ if (val->event->sigrdataset)
+ val->event->sigrdataset->trust = dns_trust_answer;
+}
+
static void
validator_done(dns_validator_t *val, isc_result_t result) {
isc_task_t *task;
@@ -219,6 +226,13 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) {
rdataset = &val->frdataset;
eresult = devent->result;
+ /* Free resources which are not of interest. */
+ if (devent->node != NULL)
+ dns_db_detachnode(devent->db, &devent->node);
+ if (devent->db != NULL)
+ dns_db_detach(&devent->db);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_disassociate(&val->fsigrdataset);
isc_event_free(&event);
dns_resolver_destroyfetch(&val->fetch);
@@ -271,6 +285,13 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
rdataset = &val->frdataset;
eresult = devent->result;
+ /* Free resources which are not of interest. */
+ if (devent->node != NULL)
+ dns_db_detachnode(devent->db, &devent->node);
+ if (devent->db != NULL)
+ dns_db_detach(&devent->db);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_disassociate(&val->fsigrdataset);
isc_event_free(&event);
dns_resolver_destroyfetch(&val->fetch);
@@ -285,18 +306,6 @@ dsfetched(isc_task_t *task, isc_event_t *event) {
result = validatezonekey(val);
if (result != DNS_R_WAIT)
validator_done(val, result);
- } else if (val->view->dlv != NULL && !DLVTRIED(val) &&
- (eresult == DNS_R_NXRRSET ||
- eresult == DNS_R_NCACHENXRRSET) &&
- !dns_name_issubdomain(val->event->name,
- val->view->dlv))
- {
- validator_log(val, ISC_LOG_DEBUG(2),
- "no DS record: looking for DLV");
-
- result = dlv_validatezonekey(val);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
} else if (eresult == DNS_R_NXRRSET ||
eresult == DNS_R_NCACHENXRRSET)
{
@@ -328,7 +337,6 @@ static void
dsfetched2(isc_task_t *task, isc_event_t *event) {
dns_fetchevent_t *devent;
dns_validator_t *val;
- dns_rdataset_t *rdataset;
dns_name_t *tname;
isc_boolean_t want_destroy;
isc_result_t result;
@@ -338,9 +346,15 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
devent = (dns_fetchevent_t *)event;
val = devent->ev_arg;
- rdataset = &val->frdataset;
eresult = devent->result;
+ /* Free resources which are not of interest. */
+ if (devent->node != NULL)
+ dns_db_detachnode(devent->db, &devent->node);
+ if (devent->db != NULL)
+ 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);
@@ -358,7 +372,7 @@ dsfetched2(isc_task_t *task, isc_event_t *event) {
"must be secure failure");
validator_done(val, DNS_R_MUSTBESECURE);
} else {
- val->event->rdataset->trust = dns_trust_answer;
+ markanswer(val);
validator_done(val, ISC_R_SUCCESS);
}
} else {
@@ -553,7 +567,7 @@ nsecnoexistnodata(dns_validator_t *val, dns_name_t* name, dns_name_t *nsecname,
"nsec proves name exists (owner) data=%d",
*data);
return (ISC_R_SUCCESS);
- }
+ }
if (relation == dns_namereln_subdomain &&
dns_nsec_typepresent(&rdata, dns_rdatatype_ns) &&
@@ -627,7 +641,7 @@ static void
authvalidated(isc_task_t *task, isc_event_t *event) {
dns_validatorevent_t *devent;
dns_validator_t *val;
- dns_rdataset_t *rdataset, *sigrdataset;
+ dns_rdataset_t *rdataset;
isc_boolean_t want_destroy;
isc_result_t result;
isc_boolean_t exists, data;
@@ -637,7 +651,6 @@ authvalidated(isc_task_t *task, isc_event_t *event) {
devent = (dns_validatorevent_t *)event;
rdataset = devent->rdataset;
- sigrdataset = devent->sigrdataset;
val = devent->ev_arg;
result = devent->result;
dns_validator_destroy(&val->subvalidator);
@@ -916,8 +929,10 @@ create_validator(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type,
rdataset, sigrdataset, NULL, 0,
val->task, action, val,
&val->subvalidator);
- if (result == ISC_R_SUCCESS)
+ if (result == ISC_R_SUCCESS) {
val->subvalidator->parent = val;
+ val->subvalidator->depth = val->depth + 1;
+ }
return (result);
}
@@ -1252,10 +1267,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
"must be secure failure");
return (DNS_R_MUSTBESECURE);
}
- event->rdataset->trust = dns_trust_answer;
- event->sigrdataset->trust = dns_trust_answer;
- validator_log(val, ISC_LOG_DEBUG(3),
- "marking as answer");
+ markanswer(val);
return (ISC_R_SUCCESS);
}
@@ -1344,110 +1356,9 @@ validate(dns_validator_t *val, isc_boolean_t resume) {
return (DNS_R_NOVALIDSIG);
}
-
-static void
-dlv_validated(isc_task_t *task, isc_event_t *event) {
- dns_validatorevent_t *devent;
- dns_validator_t *val;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_VALIDATORDONE);
-
- devent = (dns_validatorevent_t *)event;
- val = devent->ev_arg;
- eresult = devent->result;
-
- isc_event_free(&event);
- dns_validator_destroy(&val->subvalidator);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in dsvalidated");
- LOCK(&val->lock);
- if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dlv with trust %d", val->frdataset.trust);
- if ((val->attributes & VALATTR_INSECURITY) != 0)
- result = proveunsecure(val, ISC_TRUE);
- else
- result = validatezonekey(val);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dlv_validated: got %s",
- isc_result_totext(eresult));
- validator_done(val, eresult);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-}
-
-static void
-dlv_fetched(isc_task_t *task, isc_event_t *event) {
- dns_fetchevent_t *devent;
- dns_validator_t *val;
- dns_rdataset_t *rdataset;
- isc_boolean_t want_destroy;
- isc_result_t result;
- isc_result_t eresult;
-
- UNUSED(task);
- INSIST(event->ev_type == DNS_EVENT_FETCHDONE);
- devent = (dns_fetchevent_t *)event;
- val = devent->ev_arg;
- rdataset = &val->frdataset;
- eresult = devent->result;
-
- isc_event_free(&event);
- dns_resolver_destroyfetch(&val->fetch);
-
- INSIST(val->event != NULL);
-
- validator_log(val, ISC_LOG_DEBUG(3), "in dlv_fetched");
- LOCK(&val->lock);
- if (eresult == ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dlv set with trust %d", rdataset->trust);
- val->dlv = &val->frdataset;
- result = dlv_validatezonekey(val);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else if (eresult == DNS_R_NXRRSET ||
- eresult == DNS_R_NCACHENXRRSET)
- {
- validator_log(val, ISC_LOG_DEBUG(3),
- "falling back to insecurity proof");
- val->attributes |= VALATTR_INSECURITY;
- result = proveunsecure(val, ISC_FALSE);
- if (result != DNS_R_WAIT)
- validator_done(val, result);
- } else {
- validator_log(val, ISC_LOG_DEBUG(3),
- "dlv_fetched: got %s",
- isc_result_totext(eresult));
- if (eresult == ISC_R_CANCELED)
- validator_done(val, eresult);
- else
- validator_done(val, DNS_R_NOVALIDDS);
- }
- want_destroy = exit_check(val);
- UNLOCK(&val->lock);
- if (want_destroy)
- destroy(val);
-}
-
static isc_result_t
dlv_validatezonekey(dns_validator_t *val) {
- dns_fixedname_t fixed;
dns_keytag_t keytag;
- dns_name_t *name;
- dns_name_t tname;
dns_rdata_dlv_t dlv;
dns_rdata_dnskey_t key;
dns_rdata_rrsig_t sig;
@@ -1460,91 +1371,8 @@ dlv_validatezonekey(dns_validator_t *val) {
isc_boolean_t supported_algorithm;
isc_result_t result;
unsigned char dsbuf[DNS_DS_BUFFERSIZE];
- unsigned int labels;
-
- val->attributes |= VALATTR_DLVTRIED;
-
- dns_name_init(&tname, NULL);
- dns_fixedname_init(&fixed);
- name = dns_fixedname_name(&fixed);
- labels = dns_name_countlabels(val->event->name);
- dns_name_getlabelsequence(val->event->name, 0, labels - 1, &tname);
- result = dns_name_concatenate(&tname, val->view->dlv, name, NULL);
- if (result != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(2),
- "DLV concatenate failed");
- return (DNS_R_NOVALIDSIG);
- }
- if (val->dlv == NULL) {
- result = view_find(val, name, dns_rdatatype_dlv);
- if (result == ISC_R_SUCCESS) {
- /*
- * We have DLV records.
- */
- val->dsset = &val->frdataset;
- if (val->frdataset.trust == dns_trust_pending &&
- dns_rdataset_isassociated(&val->fsigrdataset))
- {
- result = create_validator(val,
- val->event->name,
- dns_rdatatype_ds,
- &val->frdataset,
- &val->fsigrdataset,
- dlv_validated,
- "dlv_validatezonekey");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- } else if (val->frdataset.trust == dns_trust_pending) {
- /*
- * There should never be an unsigned DLV.
- */
- dns_rdataset_disassociate(&val->frdataset);
- validator_log(val, ISC_LOG_DEBUG(2),
- "unsigned DLV record");
- return (DNS_R_NOVALIDSIG);
- } else
- result = ISC_R_SUCCESS;
- } else if (result == ISC_R_NOTFOUND) {
- result = create_fetch(val, name, dns_rdatatype_dlv,
- dlv_fetched,
- "dlv_validatezonekey");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
- } else if (result == DNS_R_NCACHENXDOMAIN ||
- result == DNS_R_NCACHENXRRSET ||
- result == DNS_R_NXDOMAIN ||
- result == DNS_R_NXRRSET)
- {
- /*
- * The DS does not exist.
- */
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
- validator_log(val, ISC_LOG_DEBUG(2), "no DLV record");
- return (DNS_R_NOVALIDSIG);
- }
- }
-
- /*
- * We have a DLV set.
- */
- INSIST(val->dlv != NULL);
-
- if (val->dlv->trust < dns_trust_secure) {
- if (val->mustbesecure) {
- validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
- return (DNS_R_MUSTBESECURE);
- }
- val->event->rdataset->trust = dns_trust_answer;
- val->event->sigrdataset->trust = dns_trust_answer;
- return (ISC_R_SUCCESS);
- }
+ validator_log(val, ISC_LOG_DEBUG(3), "dlv_validatezonekey");
/*
* Look through the DLV record and find the keys that can sign the
* key set and the matching signature. For each such key, attempt
@@ -1553,15 +1381,16 @@ dlv_validatezonekey(dns_validator_t *val) {
supported_algorithm = ISC_FALSE;
- for (result = dns_rdataset_first(val->dlv);
+ for (result = dns_rdataset_first(&val->dlv);
result == ISC_R_SUCCESS;
- result = dns_rdataset_next(val->dlv))
+ result = dns_rdataset_next(&val->dlv))
{
dns_rdata_reset(&dlvrdata);
- dns_rdataset_current(val->dlv, &dlvrdata);
+ dns_rdataset_current(&val->dlv, &dlvrdata);
(void)dns_rdata_tostruct(&dlvrdata, &dlv, NULL);
- if (!dns_resolver_algorithm_supported(val->view->resolver,
+ if (dlv.digest_type != DNS_DSDIGEST_SHA1 ||
+ !dns_resolver_algorithm_supported(val->view->resolver,
val->event->name,
dlv.algorithm))
continue;
@@ -1586,8 +1415,12 @@ dlv_validatezonekey(dns_validator_t *val) {
result = dns_ds_buildrdata(val->event->name,
&keyrdata, dlv.digest_type,
dsbuf, &newdsrdata);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "dns_ds_buildrdata() -> %s",
+ dns_result_totext(result));
continue;
+ }
/* Covert to DLV */
newdsrdata.type = dns_rdatatype_dlv;
if (dns_rdata_compare(&dlvrdata, &newdsrdata) == 0)
@@ -1598,7 +1431,9 @@ dlv_validatezonekey(dns_validator_t *val) {
"no DNSKEY matching DLV");
continue;
}
-
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "Found matching DLV record: checking for signature");
+
for (result = dns_rdataset_first(val->event->sigrdataset);
result == ISC_R_SUCCESS;
result = dns_rdataset_next(val->event->sigrdataset))
@@ -1610,7 +1445,6 @@ dlv_validatezonekey(dns_validator_t *val) {
if (dlv.key_tag != sig.keyid &&
dlv.algorithm != sig.algorithm)
continue;
-
dstkey = NULL;
result = dns_dnssec_keyfromrdata(val->event->name,
&keyrdata,
@@ -1644,10 +1478,9 @@ dlv_validatezonekey(dns_validator_t *val) {
"must be secure failure");
return (DNS_R_MUSTBESECURE);
}
- val->event->rdataset->trust = dns_trust_answer;
- val->event->sigrdataset->trust = dns_trust_answer;
validator_log(val, ISC_LOG_DEBUG(3),
- "no supported algorithm (dlv)");
+ "no supported algorithm/digest (dlv)");
+ markanswer(val);
return (ISC_R_SUCCESS);
} else
return (DNS_R_NOVALIDSIG);
@@ -1685,6 +1518,10 @@ validatezonekey(dns_validator_t *val) {
event = val->event;
+ if (val->havedlvsep && val->dlv.trust >= dns_trust_secure &&
+ dns_name_equal(event->name, dns_fixedname_name(&val->dlvsep)))
+ return (dlv_validatezonekey(val));
+
if (val->dsset == NULL) {
/*
* First, see if this key was signed by a trusted key.
@@ -1783,22 +1620,6 @@ validatezonekey(dns_validator_t *val) {
if (result != ISC_R_SUCCESS)
return (result);
return (DNS_R_WAIT);
- } else if (val->view->dlv != NULL && !DLVTRIED(val) &&
- (result == DNS_R_NCACHENXRRSET ||
- result == DNS_R_NXRRSET) &&
- !dns_name_issubdomain(val->event->name,
- val->view->dlv))
- {
-
- if (dns_rdataset_isassociated(&val->frdataset))
- dns_rdataset_disassociate(&val->frdataset);
- if (dns_rdataset_isassociated(&val->fsigrdataset))
- dns_rdataset_disassociate(&val->fsigrdataset);
-
- validator_log(val, ISC_LOG_DEBUG(2),
- "no DS record: looking for DLV");
-
- return (dlv_validatezonekey(val));
} else if (result == DNS_R_NCACHENXDOMAIN ||
result == DNS_R_NCACHENXRRSET ||
result == DNS_R_NXDOMAIN ||
@@ -1827,8 +1648,7 @@ validatezonekey(dns_validator_t *val) {
"must be secure failure");
return (DNS_R_MUSTBESECURE);
}
- val->event->rdataset->trust = dns_trust_answer;
- val->event->sigrdataset->trust = dns_trust_answer;
+ markanswer(val);
return (ISC_R_SUCCESS);
}
@@ -1848,6 +1668,8 @@ validatezonekey(dns_validator_t *val) {
dns_rdataset_current(val->dsset, &dsrdata);
(void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
+ if (ds.digest_type != DNS_DSDIGEST_SHA1)
+ continue;
if (!dns_resolver_algorithm_supported(val->view->resolver,
val->event->name,
ds.algorithm))
@@ -1923,24 +1745,15 @@ validatezonekey(dns_validator_t *val) {
event->sigrdataset->trust = dns_trust_secure;
validator_log(val, ISC_LOG_DEBUG(3), "marking as secure");
return (result);
- } else if (result == ISC_R_NOMORE && val->view->dlv != NULL &&
- !DLVTRIED(val) && !dns_name_issubdomain(val->event->name,
- val->view->dlv))
- {
- validator_log(val, ISC_LOG_DEBUG(2),
- "no DS/DNSKEY pair: looking for DLV");
-
- return (dlv_validatezonekey(val));
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
"must be secure failure");
return (DNS_R_MUSTBESECURE);
}
- val->event->rdataset->trust = dns_trust_answer;
- val->event->sigrdataset->trust = dns_trust_answer;
validator_log(val, ISC_LOG_DEBUG(3),
- "no supported algorithm (ds)");
+ "no supported algorithm/digest (DS)");
+ markanswer(val);
return (ISC_R_SUCCESS);
} else
return (DNS_R_NOVALIDSIG);
@@ -2174,7 +1987,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
if ((val->attributes & VALATTR_FOUNDNONEXISTENCE) == 0) {
if (!val->seensig && val->soaset != NULL) {
- result = create_validator(val, name, dns_rdatatype_soa,
+ result = create_validator(val, val->soaname,
+ dns_rdatatype_soa,
val->soaset, NULL,
negauthvalidated,
"nsecvalidate");
@@ -2193,8 +2007,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
}
static isc_boolean_t
-check_ds_algorithm(dns_validator_t *val, dns_name_t *name,
- dns_rdataset_t *rdataset) {
+check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) {
dns_rdata_t dsrdata = DNS_RDATA_INIT;
dns_rdata_ds_t ds;
isc_result_t result;
@@ -2205,16 +2018,20 @@ check_ds_algorithm(dns_validator_t *val, dns_name_t *name,
dns_rdataset_current(rdataset, &dsrdata);
(void)dns_rdata_tostruct(&dsrdata, &ds, NULL);
- if (dns_resolver_algorithm_supported(val->view->resolver,
- name, ds.algorithm))
+ if (ds.digest_type == DNS_DSDIGEST_SHA1 &&
+ dns_resolver_algorithm_supported(val->view->resolver,
+ name, ds.algorithm)) {
+ dns_rdata_reset(&dsrdata);
return (ISC_TRUE);
+ }
dns_rdata_reset(&dsrdata);
}
return (ISC_FALSE);
}
static void
-dlv_fetched2(isc_task_t *task, isc_event_t *event) {
+dlvfetched(isc_task_t *task, isc_event_t *event) {
+ char namebuf[DNS_NAME_FORMATSIZE];
dns_fetchevent_t *devent;
dns_validator_t *val;
isc_boolean_t want_destroy;
@@ -2226,18 +2043,29 @@ dlv_fetched2(isc_task_t *task, isc_event_t *event) {
devent = (dns_fetchevent_t *)event;
val = devent->ev_arg;
eresult = devent->result;
-
+
+ /* Free resources which are not of interest. */
+ if (devent->node != NULL)
+ dns_db_detachnode(devent->db, &devent->node);
+ if (devent->db != NULL)
+ dns_db_detach(&devent->db);
+ 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 dlv_fetched2: %s",
+ validator_log(val, ISC_LOG_DEBUG(3), "in dlvfetched: %s",
dns_result_totext(eresult));
LOCK(&val->lock);
if (eresult == ISC_R_SUCCESS) {
+ dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
+ sizeof(namebuf));
+ dns_rdataset_clone(&val->frdataset, &val->dlv);
val->havedlvsep = ISC_TRUE;
- result = proveunsecure(val, ISC_FALSE);
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
+ result = dlv_validator_start(val);
if (result != DNS_R_WAIT)
validator_done(val, result);
} else if (eresult == DNS_R_NXRRSET ||
@@ -2246,13 +2074,26 @@ dlv_fetched2(isc_task_t *task, isc_event_t *event) {
eresult == DNS_R_NCACHENXDOMAIN) {
result = finddlvsep(val, ISC_TRUE);
if (result == ISC_R_SUCCESS) {
- result = proveunsecure(val, ISC_FALSE);
+ dns_name_format(dns_fixedname_name(&val->dlvsep),
+ namebuf, sizeof(namebuf));
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found",
+ namebuf);
+ result = dlv_validator_start(val);
if (result != DNS_R_WAIT)
validator_done(val, result);
} else if (result == ISC_R_NOTFOUND) {
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
+ markanswer(val);
validator_done(val, ISC_R_SUCCESS);
- } else if (result != DNS_R_WAIT)
- validator_done(val, result);
+ } else {
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
+ dns_result_totext(result));
+ if (result != DNS_R_WAIT)
+ validator_done(val, result);
+ }
+ } else {
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
+ dns_result_totext(eresult));
}
want_destroy = exit_check(val);
UNLOCK(&val->lock);
@@ -2261,19 +2102,72 @@ dlv_fetched2(isc_task_t *task, isc_event_t *event) {
}
static isc_result_t
+startfinddlvsep(dns_validator_t *val, dns_name_t *unsecure) {
+ char namebuf[DNS_NAME_FORMATSIZE];
+ isc_result_t result;
+
+ INSIST(!DLVTRIED(val));
+
+ val->attributes |= VALATTR_DLVTRIED;
+
+ dns_name_format(unsecure, namebuf, sizeof(namebuf));
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "plain DNSSEC returns unsecure (%s): looking for DLV",
+ namebuf);
+
+ if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
+ validator_log(val, ISC_LOG_WARNING, "must be secure failure");
+ return (DNS_R_MUSTBESECURE);
+ }
+
+ val->dlvlabels = dns_name_countlabels(unsecure) - 1;
+ result = finddlvsep(val, ISC_FALSE);
+ if (result == ISC_R_NOTFOUND) {
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV not found");
+ markanswer(val);
+ return (ISC_R_SUCCESS);
+ }
+ if (result != ISC_R_SUCCESS) {
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV lookup: %s",
+ dns_result_totext(result));
+ return (result);
+ }
+ dns_name_format(dns_fixedname_name(&val->dlvsep), namebuf,
+ sizeof(namebuf));
+ validator_log(val, ISC_LOG_DEBUG(3), "DLV %s found", namebuf);
+ return (dlv_validator_start(val));
+}
+
+static isc_result_t
finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
+ char namebuf[DNS_NAME_FORMATSIZE];
dns_fixedname_t dlvfixed;
dns_name_t *dlvname;
dns_name_t *dlvsep;
dns_name_t noroot;
isc_result_t result;
unsigned int labels;
+
+ INSIST(val->view->dlv != NULL);
if (!resume) {
+
+ if (dns_name_issubdomain(val->event->name, val->view->dlv)) {
+ validator_log(val, ISC_LOG_WARNING,
+ "must be secure failure");
+ return (DNS_R_MUSTBESECURE);
+ }
+
dns_fixedname_init(&val->dlvsep);
dlvsep = dns_fixedname_name(&val->dlvsep);
dns_name_copy(val->event->name, dlvsep, NULL);
- val->attributes |= VALATTR_DLVSEPTRIED;
+ if (val->event->type == dns_rdatatype_ds) {
+ labels = dns_name_countlabels(dlvsep);
+ if (labels == 0)
+ return (ISC_R_NOTFOUND);
+ dns_name_getlabelsequence(dlvsep, 1, labels - 1,
+ dlvsep);
+ }
} else {
dlvsep = dns_fixedname_name(&val->dlvsep);
labels = dns_name_countlabels(dlvsep);
@@ -2283,6 +2177,8 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
dns_fixedname_init(&dlvfixed);
dlvname = dns_fixedname_name(&dlvfixed);
labels = dns_name_countlabels(dlvsep);
+ if (labels == 0)
+ return (ISC_R_NOTFOUND);
dns_name_getlabelsequence(dlvsep, 0, labels - 1, &noroot);
result = dns_name_concatenate(&noroot, val->view->dlv, dlvname, NULL);
while (result == ISC_R_NOSPACE) {
@@ -2297,32 +2193,37 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
return (DNS_R_NOVALIDSIG);
}
- while (dns_name_countlabels(dlvname) >
- dns_name_countlabels(val->view->dlv))
- {
+ while (dns_name_countlabels(dlvname) >=
+ dns_name_countlabels(val->view->dlv) + val->dlvlabels) {
+ dns_name_format(dlvname, namebuf, sizeof(namebuf));
+ validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV %s",
+ namebuf);
result = view_find(val, dlvname, dns_rdatatype_dlv);
if (result == ISC_R_SUCCESS) {
if (val->frdataset.trust < dns_trust_secure)
return (DNS_R_NOVALIDSIG);
val->havedlvsep = ISC_TRUE;
+ dns_rdataset_clone(&val->frdataset, &val->dlv);
return (ISC_R_SUCCESS);
}
if (result == ISC_R_NOTFOUND) {
- result = create_fetch(val, dlvname, dns_rdatatype_dlv,
- dlv_fetched2, "finddlvsep");
- if (result != ISC_R_SUCCESS)
- return (result);
- return (DNS_R_WAIT);
+ result = create_fetch(val, dlvname, dns_rdatatype_dlv,
+ dlvfetched, "finddlvsep");
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ return (DNS_R_WAIT);
}
if (result != DNS_R_NXRRSET &&
result != DNS_R_NXDOMAIN &&
result != DNS_R_NCACHENXRRSET &&
- result != DNS_R_NCACHENXDOMAIN)
+ result != DNS_R_NCACHENXDOMAIN)
return (result);
/*
* Strip first labels from both dlvsep and dlvname.
*/
labels = dns_name_countlabels(dlvsep);
+ if (labels == 0)
+ break;
dns_name_getlabelsequence(dlvsep, 1, labels - 1, dlvsep);
labels = dns_name_countlabels(dlvname);
dns_name_getlabelsequence(dlvname, 1, labels - 1, dlvname);
@@ -2330,73 +2231,76 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) {
return (ISC_R_NOTFOUND);
}
+/*
+ * proveunsecure walks down from the SEP looking for a break in the
+ * chain of trust. That occurs when we can prove the DS record does
+ * not exist at a delegation point or the DS exists at a delegation
+ * but we don't support the algorithm/digest.
+ */
static isc_result_t
proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
isc_result_t result;
- isc_result_t tresult;
- dns_fixedname_t secroot;
+ dns_fixedname_t fixedsecroot;
+ dns_name_t *secroot;
dns_name_t *tname;
+ char namebuf[DNS_NAME_FORMATSIZE];
- dns_fixedname_init(&secroot);
- result = dns_keytable_finddeepestmatch(val->keytable,
- val->event->name,
- dns_fixedname_name(&secroot));
- /*
- * If the name is not under a security root, it must be insecure.
- */
- if (val->view->dlv != NULL && !DLVSEPTRIED(val) &&
- !dns_name_issubdomain(val->event->name, val->view->dlv)) {
- tresult = finddlvsep(val, ISC_FALSE);
- if (tresult != ISC_R_NOTFOUND && tresult != ISC_R_SUCCESS) {
- validator_log(val, ISC_LOG_DEBUG(3),
- "finddlvsep returned: %s",
- dns_result_totext(tresult));
- return (tresult);
- }
- }
+ dns_fixedname_init(&fixedsecroot);
+ secroot = dns_fixedname_name(&fixedsecroot);
+ if (val->havedlvsep)
+ dns_name_copy(dns_fixedname_name(&val->dlvsep), secroot, NULL);
+ else {
+ result = dns_keytable_finddeepestmatch(val->keytable,
+ val->event->name,
+ secroot);
- if (result == ISC_R_NOTFOUND) {
- if (!val->havedlvsep) {
+ if (result == ISC_R_NOTFOUND) {
validator_log(val, ISC_LOG_DEBUG(3),
- "not beneath secure root / DLV");
+ "not beneath secure root");
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
"must be secure failure");
result = DNS_R_MUSTBESECURE;
goto out;
}
- val->event->rdataset->trust = dns_trust_answer;
- return (ISC_R_SUCCESS);
- }
- dns_name_copy(dns_fixedname_name(&val->dlvsep),
- dns_fixedname_name(&secroot), NULL);
- } else if (result != ISC_R_SUCCESS)
- return (result);
- else if (val->havedlvsep &&
- dns_name_issubdomain(dns_fixedname_name(&val->dlvsep),
- dns_fixedname_name(&secroot))) {
- dns_name_copy(dns_fixedname_name(&val->dlvsep),
- dns_fixedname_name(&secroot), NULL);
+ if (val->view->dlv == NULL || DLVTRIED(val)) {
+ markanswer(val);
+ return (ISC_R_SUCCESS);
+ }
+ return (startfinddlvsep(val, dns_rootname));
+ } else if (result != ISC_R_SUCCESS)
+ return (result);
}
if (!resume) {
- val->labels =
- dns_name_countlabels(dns_fixedname_name(&secroot)) + 1;
+ /*
+ * We are looking for breaks below the SEP so add a label.
+ */
+ val->labels = dns_name_countlabels(secroot) + 1;
} else {
validator_log(val, ISC_LOG_DEBUG(3), "resuming proveunsecure");
if (val->frdataset.trust >= dns_trust_secure &&
- !check_ds_algorithm(val, dns_fixedname_name(&val->fname),
- &val->frdataset)) {
+ !check_ds(val, dns_fixedname_name(&val->fname),
+ &val->frdataset)) {
+ dns_name_format(dns_fixedname_name(&val->fname),
+ namebuf, sizeof(namebuf));
if (val->mustbesecure) {
validator_log(val, ISC_LOG_WARNING,
- "must be secure failure");
+ "must be secure failure at '%s'",
+ namebuf);
result = DNS_R_MUSTBESECURE;
goto out;
}
validator_log(val, ISC_LOG_DEBUG(3),
- "no supported algorithm (ds)");
- val->event->rdataset->trust = dns_trust_answer;
- result = ISC_R_SUCCESS;
+ "no supported algorithm/digest (%s/DS)",
+ namebuf);
+ if (val->view->dlv == NULL || DLVTRIED(val)) {
+ markanswer(val);
+ result = ISC_R_SUCCESS;
+ goto out;
+ }
+ result = startfinddlvsep(val,
+ dns_fixedname_name(&val->fname));
goto out;
}
val->labels++;
@@ -2406,7 +2310,6 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
val->labels <= dns_name_countlabels(val->event->name);
val->labels++)
{
- char namebuf[DNS_NAME_FORMATSIZE];
dns_fixedname_init(&val->fname);
tname = dns_fixedname_name(&val->fname);
@@ -2425,7 +2328,7 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
if (result == DNS_R_NXRRSET || result == DNS_R_NCACHENXRRSET) {
/*
* There is no DS. If this is a delegation,
- * we're done.
+ * we maybe done.
*/
if (val->frdataset.trust < dns_trust_secure) {
/*
@@ -2443,8 +2346,11 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
"must be secure failure");
return (DNS_R_MUSTBESECURE);
}
- val->event->rdataset->trust = dns_trust_answer;
- return (ISC_R_SUCCESS);
+ if (val->view->dlv == NULL || DLVTRIED(val)) {
+ markanswer(val);
+ return (ISC_R_SUCCESS);
+ }
+ return (startfinddlvsep(val, tname));
}
continue;
} else if (result == ISC_R_SUCCESS) {
@@ -2453,10 +2359,10 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
* continue.
*/
if (val->frdataset.trust >= dns_trust_secure) {
- if (!check_ds_algorithm(val, tname,
- &val->frdataset)) {
+ if (!check_ds(val, tname, &val->frdataset)) {
validator_log(val, ISC_LOG_DEBUG(3),
- "no supported algorithm (ds)");
+ "no supported algorithm/"
+ "digest (%s/DS)", namebuf);
if (val->mustbesecure) {
validator_log(val,
ISC_LOG_WARNING,
@@ -2464,9 +2370,13 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
result = DNS_R_MUSTBESECURE;
goto out;
}
- val->event->rdataset->trust =
- dns_trust_answer;
- result = ISC_R_SUCCESS;
+ if (val->view->dlv == NULL ||
+ DLVTRIED(val)) {
+ markanswer(val);
+ result = ISC_R_SUCCESS;
+ goto out;
+ }
+ result = startfinddlvsep(val, tname);
goto out;
}
continue;
@@ -2531,6 +2441,23 @@ proveunsecure(dns_validator_t *val, isc_boolean_t resume) {
return (result);
}
+static isc_result_t
+dlv_validator_start(dns_validator_t *val) {
+ isc_event_t *event;
+
+ validator_log(val, ISC_LOG_DEBUG(3), "dlv_validator_start");
+
+ /*
+ * Reset state and try again.
+ */
+ val->attributes &= VALATTR_DLVTRIED;
+ val->options &= ~DNS_VALIDATOR_DLV;
+
+ event = (isc_event_t *)val->event;
+ isc_task_send(val->task, &event);
+ return (DNS_R_WAIT);
+}
+
static void
validator_start(isc_task_t *task, isc_event_t *event) {
dns_validator_t *val;
@@ -2547,11 +2474,18 @@ validator_start(isc_task_t *task, isc_event_t *event) {
if (val->event == NULL)
return;
- validator_log(val, ISC_LOG_DEBUG(3), "starting");
+ if (DLVTRIED(val))
+ validator_log(val, ISC_LOG_DEBUG(3), "restarting using DLV");
+ else
+ validator_log(val, ISC_LOG_DEBUG(3), "starting");
LOCK(&val->lock);
- if (val->event->rdataset != NULL && val->event->sigrdataset != NULL) {
+ if ((val->options & DNS_VALIDATOR_DLV) != 0) {
+ validator_log(val, ISC_LOG_DEBUG(3), "looking for DLV");
+ result = startfinddlvsep(val, dns_rootname);
+ } else if (val->event->rdataset != NULL &&
+ val->event->sigrdataset != NULL) {
isc_result_t saved_result;
/*
@@ -2635,7 +2569,6 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
REQUIRE(type != 0);
REQUIRE(rdataset != NULL ||
(rdataset == NULL && sigrdataset == NULL && message != NULL));
- REQUIRE(options == 0);
REQUIRE(validatorp != NULL && *validatorp == NULL);
tclone = NULL;
@@ -2685,12 +2618,13 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type,
val->currentset = NULL;
val->keyset = NULL;
val->dsset = NULL;
- val->dlv = NULL;
+ dns_rdataset_init(&val->dlv);
val->soaset = NULL;
val->nsecset = NULL;
val->soaname = NULL;
val->seensig = ISC_FALSE;
val->havedlvsep = ISC_FALSE;
+ val->depth = 0;
val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name);
dns_rdataset_init(&val->frdataset);
dns_rdataset_init(&val->fsigrdataset);
@@ -2749,6 +2683,12 @@ destroy(dns_validator_t *val) {
dns_keytable_detach(&val->keytable);
if (val->subvalidator != NULL)
dns_validator_destroy(&val->subvalidator);
+ if (val->havedlvsep)
+ dns_rdataset_disassociate(&val->dlv);
+ if (dns_rdataset_isassociated(&val->frdataset))
+ dns_rdataset_disassociate(&val->frdataset);
+ if (dns_rdataset_isassociated(&val->fsigrdataset))
+ dns_rdataset_disassociate(&val->fsigrdataset);
mctx = val->view->mctx;
if (val->siginfo != NULL)
isc_mem_put(mctx, val->siginfo, sizeof(*val->siginfo));
@@ -2787,9 +2727,14 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category,
isc_logmodule_t *module, int level, const char *fmt, va_list ap)
{
char msgbuf[2048];
+ static const char spaces[] = " *";
+ int depth = val->depth * 2;
vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap);
+ if ((unsigned int) depth >= sizeof spaces)
+ depth = sizeof spaces - 1;
+
if (val->event != NULL && val->event->name != NULL) {
char namebuf[DNS_NAME_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
@@ -2798,11 +2743,12 @@ validator_logv(dns_validator_t *val, isc_logcategory_t *category,
dns_rdatatype_format(val->event->type, typebuf,
sizeof(typebuf));
isc_log_write(dns_lctx, category, module, level,
- "validating %s %s: %s", namebuf, typebuf,
- msgbuf);
+ "%.*svalidating @%p: %s %s: %s", depth, spaces,
+ val, namebuf, typebuf, msgbuf);
} else {
isc_log_write(dns_lctx, category, module, level,
- "validator @%p: %s", val, msgbuf);
+ "%.*svalidator @%p: %s", depth, spaces,
+ val, msgbuf);
}
}
diff --git a/usr.sbin/bind/lib/dns/xfrin.c b/usr.sbin/bind/lib/dns/xfrin.c
index 55b6e2a5749..a0bd284617f 100644
--- a/usr.sbin/bind/lib/dns/xfrin.c
+++ b/usr.sbin/bind/lib/dns/xfrin.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: xfrin.c,v 1.124.2.4.2.9 2004/10/13 22:28:42 marka Exp $ */
+/* $ISC: xfrin.c,v 1.124.2.4.2.12 2005/11/03 23:08:41 marka Exp $ */
#include <config.h>
@@ -232,7 +232,7 @@ xfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,
ISC_FORMAT_PRINTF(5, 6);
static void
-xfrin_log(dns_xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...)
+xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
ISC_FORMAT_PRINTF(3, 4);
/**************************************************************************/
@@ -581,7 +581,7 @@ dns_xfrin_create2(dns_zone_t *zone, dns_rdatatype_t xfrtype,
isc_task_t *task, dns_xfrindone_t done, dns_xfrin_ctx_t **xfrp)
{
dns_name_t *zonename = dns_zone_getorigin(zone);
- dns_xfrin_ctx_t *xfr;
+ dns_xfrin_ctx_t *xfr = NULL;
isc_result_t result;
dns_db_t *db = NULL;
@@ -1391,7 +1391,7 @@ xfrin_log1(int level, dns_name_t *zonename, dns_rdataclass_t rdclass,
*/
static void
-xfrin_log(dns_xfrin_ctx_t *xfr, unsigned int level, const char *fmt, ...)
+xfrin_log(dns_xfrin_ctx_t *xfr, int level, const char *fmt, ...)
{
va_list ap;
diff --git a/usr.sbin/bind/lib/dns/zone.c b/usr.sbin/bind/lib/dns/zone.c
index 775c9c8079b..b8156cf9e81 100644
--- a/usr.sbin/bind/lib/dns/zone.c
+++ b/usr.sbin/bind/lib/dns/zone.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $ISC: zone.c,v 1.333.2.23.2.55 2005/02/03 23:50:45 marka Exp $ */
+/* $ISC: zone.c,v 1.333.2.23.2.59 2005/07/29 00:38:33 marka Exp $ */
#include <config.h>
@@ -167,6 +167,7 @@ struct dns_zone {
isc_sockaddr_t *masters;
dns_name_t **masterkeynames;
+ isc_boolean_t *mastersok;
unsigned int masterscnt;
unsigned int curmaster;
isc_sockaddr_t masteraddr;
@@ -536,6 +537,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->minretry = DNS_ZONE_MINRETRY;
zone->masters = NULL;
zone->masterkeynames = NULL;
+ zone->mastersok = NULL;
zone->masterscnt = 0;
zone->curmaster = 0;
zone->notify = NULL;
@@ -590,7 +592,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
free_mutex:
DESTROYLOCK(&zone->lock);
- return (ISC_R_NOMEMORY);
+ isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
+ return (result);
}
/*
@@ -1250,6 +1253,7 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
isc_uint32_t serial, refresh, retry, expire, minimum;
isc_time_t now;
isc_boolean_t needdump = ISC_FALSE;
+ isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
TIME_NOW(&now);
@@ -1355,10 +1359,32 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
if (result != ISC_R_SUCCESS)
goto cleanup;
if (zone->db != NULL) {
- if (!isc_serial_ge(serial, zone->serial)) {
+ /*
+ * This is checked in zone_replacedb() for slave zones
+ * as they don't reload from disk.
+ */
+ if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
+ !isc_serial_gt(serial, zone->serial)) {
+ isc_uint32_t serialmin, serialmax;
+
+ INSIST(zone->type == dns_zone_master);
+
+ serialmin = (zone->serial + 1) & 0xffffffffU;
+ serialmax = (zone->serial + 0x7fffffffU) &
+ 0xffffffffU;
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "ixfr-from-differences: "
+ "new serial (%u) out of range "
+ "[%u - %u]", serial, serialmin,
+ serialmax);
+ result = DNS_R_BADZONE;
+ goto cleanup;
+ } else if (!isc_serial_ge(serial, zone->serial))
dns_zone_log(zone, ISC_LOG_ERROR,
"zone serial has gone backwards");
- }
+ else if (serial == zone->serial && !hasinclude)
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "zone serial unchanged");
}
zone->serial = serial;
zone->refresh = RANGE(refresh,
@@ -1943,6 +1969,7 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters,
isc_sockaddr_t *new;
isc_result_t result = ISC_R_SUCCESS;
dns_name_t **newname;
+ isc_boolean_t *newok;
unsigned int i;
REQUIRE(DNS_ZONE_VALID(zone));
@@ -1972,10 +1999,15 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters,
zone->masterscnt * sizeof(dns_name_t *));
zone->masterkeynames = NULL;
}
+ if (zone->mastersok != NULL) {
+ isc_mem_put(zone->mctx, zone->mastersok,
+ zone->masterscnt * sizeof(isc_boolean_t));
+ zone->mastersok = NULL;
+ }
zone->masterscnt = 0;
/*
- * If count == 0, don't allocate any space for masters or keynames
- * so internally, those pointers are NULL if count == 0
+ * If count == 0, don't allocate any space for masters, mastersok or
+ * keynames so internally, those pointers are NULL if count == 0
*/
if (count == 0)
goto unlock;
@@ -1983,27 +2015,35 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters,
/*
* masters must countain count elements!
*/
- new = isc_mem_get(zone->mctx,
- count * sizeof(isc_sockaddr_t));
+ new = isc_mem_get(zone->mctx, count * sizeof(*new));
if (new == NULL) {
result = ISC_R_NOMEMORY;
goto unlock;
}
memcpy(new, masters, count * sizeof(*new));
- zone->masters = new;
- zone->masterscnt = count;
- DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
+
+ /*
+ * Similarly for mastersok.
+ */
+ newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
+ if (newok == NULL) {
+ result = ISC_R_NOMEMORY;
+ isc_mem_put(zone->mctx, new, count * sizeof(*new));
+ goto unlock;
+ };
+ for (i = 0; i < count; i++)
+ newok[i] = ISC_FALSE;
/*
* if keynames is non-NULL, it must contain count elements!
*/
+ newname = NULL;
if (keynames != NULL) {
- newname = isc_mem_get(zone->mctx,
- count * sizeof(dns_name_t *));
+ newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
if (newname == NULL) {
result = ISC_R_NOMEMORY;
- isc_mem_put(zone->mctx, zone->masters,
- count * sizeof(*new));
+ isc_mem_put(zone->mctx, new, count * sizeof(*new));
+ isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
goto unlock;
}
for (i = 0; i < count; i++)
@@ -2024,16 +2064,27 @@ dns_zone_setmasterswithkeys(dns_zone_t *zone, isc_sockaddr_t *masters,
dns_name_free(
newname[i],
zone->mctx);
- isc_mem_put(zone->mctx, zone->masters,
+ isc_mem_put(zone->mctx, new,
count * sizeof(*new));
+ isc_mem_put(zone->mctx, newok,
+ count * sizeof(*newok));
isc_mem_put(zone->mctx, newname,
count * sizeof(*newname));
goto unlock;
}
}
}
- zone->masterkeynames = newname;
}
+
+ /*
+ * Everything is ok so attach to the zone.
+ */
+ zone->masters = new;
+ zone->mastersok = newok;
+ zone->masterkeynames = newname;
+ zone->masterscnt = count;
+ DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
+
unlock:
UNLOCK_ZONE(zone);
return (result);
@@ -2222,6 +2273,7 @@ void
dns_zone_refresh(dns_zone_t *zone) {
isc_interval_t i;
isc_uint32_t oldflags;
+ unsigned int j;
REQUIRE(DNS_ZONE_VALID(zone));
@@ -2266,6 +2318,8 @@ dns_zone_refresh(dns_zone_t *zone) {
zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
zone->curmaster = 0;
+ for (j = 0; j < zone->masterscnt; j++)
+ zone->mastersok[j] = ISC_FALSE;
/* initiate soa query */
queue_soa_query(zone);
unlock:
@@ -3186,6 +3240,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;
stub = revent->ev_arg;
INSIST(DNS_STUB_VALID(stub));
@@ -3360,13 +3415,37 @@ stub_callback(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
LOCK_ZONE(zone);
dns_request_destroy(&zone->request);
- zone->curmaster++;
+ /*
+ * Skip to next failed / untried master.
+ */
+ do {
+ zone->curmaster++;
+ } while (zone->curmaster < zone->masterscnt &&
+ zone->mastersok[zone->curmaster]);
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
if (exiting || zone->curmaster >= zone->masterscnt) {
+ isc_boolean_t done = ISC_TRUE;
if (!exiting &&
DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
+ /*
+ * Did we get a good answer from all the masters?
+ */
+ for (j = 0; j < zone->masterscnt; j++)
+ if (zone->mastersok[j] == ISC_FALSE) {
+ done = ISC_FALSE;
+ break;
+ }
+ } else
+ done = ISC_TRUE;
+ if (!done) {
zone->curmaster = 0;
+ /*
+ * Find the next failed master.
+ */
+ while (zone->curmaster < zone->masterscnt &&
+ zone->mastersok[zone->curmaster])
+ zone->curmaster++;
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
} else {
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
@@ -3420,6 +3499,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
dns_rdata_soa_t soa;
isc_result_t result;
isc_uint32_t serial;
+ unsigned int j;
zone = revent->ev_arg;
INSIST(DNS_ZONE_VALID(zone));
@@ -3668,6 +3748,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
}
DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
+ zone->mastersok[zone->curmaster] = ISC_TRUE;
goto next_master;
} else {
if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
@@ -3676,6 +3757,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
soa.serial, master, zone->serial);
else
zone_debuglog(zone, me, 1, "ahead");
+ zone->mastersok[zone->curmaster] = ISC_TRUE;
goto next_master;
}
if (msg != NULL)
@@ -3688,13 +3770,37 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
isc_event_free(&event);
LOCK_ZONE(zone);
dns_request_destroy(&zone->request);
- zone->curmaster++;
+ /*
+ * Skip to next failed / untried master.
+ */
+ do {
+ zone->curmaster++;
+ } while (zone->curmaster < zone->masterscnt &&
+ zone->mastersok[zone->curmaster]);
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
if (zone->curmaster >= zone->masterscnt) {
+ isc_boolean_t done = ISC_TRUE;
if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
+ /*
+ * Did we get a good answer from all the masters?
+ */
+ for (j = 0; j < zone->masterscnt; j++)
+ if (zone->mastersok[j] == ISC_FALSE) {
+ done = ISC_FALSE;
+ break;
+ }
+ } else
+ done = ISC_TRUE;
+ if (!done) {
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
zone->curmaster = 0;
+ /*
+ * Find the next failed master.
+ */
+ while (zone->curmaster < zone->masterscnt &&
+ zone->mastersok[zone->curmaster])
+ zone->curmaster++;
goto requeue;
}
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
@@ -4023,7 +4129,13 @@ soa_query(isc_task_t *task, isc_event_t *event) {
skip_master:
if (key != NULL)
dns_tsigkey_detach(&key);
- zone->curmaster++;
+ /*
+ * Skip to next failed / untried master.
+ */
+ do {
+ zone->curmaster++;
+ } while (zone->curmaster < zone->masterscnt &&
+ zone->mastersok[zone->curmaster]);
if (zone->curmaster < zone->masterscnt)
goto again;
zone->curmaster = 0;
@@ -5275,40 +5387,58 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
* is enabled in the configuration.
*/
if (zone->db != NULL && zone->journal != NULL &&
- DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
- isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
- DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
- "generating diffs");
- result = dns_db_diff(zone->mctx, db, ver,
- zone->db, NULL /* XXX */,
+ DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
+ !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
+ isc_uint32_t serial;
+
+ dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
+
+ result = dns_db_getsoaserial(db, ver, &serial);
+ if (result != ISC_R_SUCCESS) {
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "ixfr-from-differences: unable to get "
+ "new serial");
+ goto fail;
+ }
+
+ /*
+ * This is checked in zone_postload() for master zones.
+ */
+ if (zone->type == dns_zone_slave &&
+ !isc_serial_gt(serial, zone->serial)) {
+ isc_uint32_t serialmin, serialmax;
+ serialmin = (zone->serial + 1) & 0xffffffffU;
+ serialmax = (zone->serial + 0x7fffffffU) & 0xffffffffU;
+ dns_zone_log(zone, ISC_LOG_ERROR,
+ "ixfr-from-differences: failed: "
+ "new serial (%u) out of range [%u - %u]",
+ serial, serialmin, serialmax);
+ result = ISC_R_RANGE;
+ goto fail;
+ }
+
+ result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
zone->journal);
if (result != ISC_R_SUCCESS)
goto fail;
if (dump)
zone_needdump(zone, DNS_DUMP_DELAY);
else if (zone->journalsize != -1) {
- isc_uint32_t serial;
-
- result = dns_db_getsoaserial(db, ver, &serial);
- if (result == ISC_R_SUCCESS) {
- result = dns_journal_compact(zone->mctx,
- zone->journal,
- serial,
- zone->journalsize);
- switch (result) {
- case ISC_R_SUCCESS:
- case ISC_R_NOSPACE:
- case ISC_R_NOTFOUND:
- dns_zone_log(zone, ISC_LOG_DEBUG(3),
- "dns_journal_compact: %s",
- dns_result_totext(result));
- break;
- default:
- dns_zone_log(zone, ISC_LOG_ERROR,
+ result = dns_journal_compact(zone->mctx, zone->journal,
+ serial, zone->journalsize);
+ switch (result) {
+ case ISC_R_SUCCESS:
+ case ISC_R_NOSPACE:
+ case ISC_R_NOTFOUND:
+ dns_zone_log(zone, ISC_LOG_DEBUG(3),
+ "dns_journal_compact: %s",
+ dns_result_totext(result));
+ break;
+ default:
+ dns_zone_log(zone, ISC_LOG_ERROR,
"dns_journal_compact failed: %s",
- dns_result_totext(result));
- break;
- }
+ dns_result_totext(result));
+ break;
}
}
} else {
@@ -5503,7 +5633,14 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
default:
next_master:
- zone->curmaster++;
+ /*
+ * Skip to next failed / untried master.
+ */
+ do {
+ zone->curmaster++;
+ } while (zone->curmaster < zone->masterscnt &&
+ zone->mastersok[zone->curmaster]);
+ /* FALLTHROUGH */
same_master:
if (zone->curmaster >= zone->masterscnt) {
zone->curmaster = 0;
@@ -5511,6 +5648,9 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
+ while (zone->curmaster < zone->masterscnt &&
+ zone->mastersok[zone->curmaster])
+ zone->curmaster++;
again = ISC_TRUE;
} else
DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
@@ -5697,7 +5837,11 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
"requesting AXFR of "
"initial version from %s", mastertext);
xfrtype = dns_rdatatype_axfr;
- } else if (dns_zone_isforced(zone)) {
+ } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
+ dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
+ "set, requesting AXFR from %s", mastertext);
+ xfrtype = dns_rdatatype_axfr;
+ } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
dns_zone_log(zone, ISC_LOG_DEBUG(1),
"forced reload, requesting AXFR of "
"initial version from %s", mastertext);
@@ -6663,6 +6807,9 @@ void
dns_zone_forcereload(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
+ if (zone->type == dns_zone_master)
+ return;
+
LOCK_ZONE(zone);
DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
UNLOCK_ZONE(zone);