summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorLaMont Jones <lamont@debian.org>2009-03-20 08:26:10 -0600
committerLaMont Jones <lamont@debian.org>2009-03-20 08:26:10 -0600
commit457d065cf051a7ad041ace140c5ae6184fd5d208 (patch)
treee023610b78adf4253e9eecde3e96f1b1a022e577 /lib
parent95cab7ab13c7aedf768b3273a9a736f23239c18f (diff)
downloadbind9-457d065cf051a7ad041ace140c5ae6184fd5d208.tar.gz
9.6.0rc1
Diffstat (limited to 'lib')
-rw-r--r--lib/bind9/api2
-rw-r--r--lib/bind9/check.c15
-rw-r--r--lib/dns/api2
-rw-r--r--lib/dns/dispatch.c145
-rw-r--r--lib/dns/dnssec.c39
-rw-r--r--lib/dns/dst_api.c9
-rw-r--r--lib/dns/gssapi_link.c5
-rw-r--r--lib/dns/include/dns/Makefile.in8
-rw-r--r--lib/dns/nsec3.c6
-rw-r--r--lib/dns/rbtdb.c13
-rw-r--r--lib/dns/resolver.c29
-rw-r--r--lib/dns/tsig.c3
-rw-r--r--lib/dns/validator.c29
-rw-r--r--lib/isc/api2
-rw-r--r--lib/isc/include/isc/Makefile.in6
-rw-r--r--lib/isc/unix/socket.c129
-rw-r--r--lib/isc/win32/dir.c11
17 files changed, 388 insertions, 65 deletions
diff --git a/lib/bind9/api b/lib/bind9/api
index 8459d423..2240cdda 100644
--- a/lib/bind9/api
+++ b/lib/bind9/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 50
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 0
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index f067e530..f4756910 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: check.c,v 1.93 2008/09/12 06:02:31 each Exp $ */
+/* $Id: check.c,v 1.95 2008/11/19 05:38:49 marka Exp $ */
/*! \file */
@@ -792,6 +792,19 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx) {
}
}
+ /*
+ * Check that server-id is not too long.
+ * 1024 bytes should be big enough.
+ */
+ obj = NULL;
+ (void)cfg_map_get(options, "server-id", &obj);
+ if (obj != NULL && cfg_obj_isstring(obj) &&
+ strlen(cfg_obj_asstring(obj)) > 1024U) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "'server-id' too big (>1024 bytes)");
+ result = ISC_R_FAILURE;
+ }
+
return (result);
}
diff --git a/lib/dns/api b/lib/dns/api
index 8459d423..2240cdda 100644
--- a/lib/dns/api
+++ b/lib/dns/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 50
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 0
diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c
index 2c7add37..4ab2f3ee 100644
--- a/lib/dns/dispatch.c
+++ b/lib/dns/dispatch.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dispatch.c,v 1.154 2008/09/04 00:23:14 jinmei Exp $ */
+/* $Id: dispatch.c,v 1.155 2008/11/12 23:10:57 marka Exp $ */
/*! \file */
@@ -49,9 +49,12 @@
typedef ISC_LIST(dns_dispentry_t) dns_displist_t;
-typedef struct dispsocket dispsocket_t;
+typedef struct dispsocket dispsocket_t;
typedef ISC_LIST(dispsocket_t) dispsocketlist_t;
+typedef struct dispportentry dispportentry_t;
+typedef ISC_LIST(dispportentry_t) dispportlist_t;
+
/* ARC4 Random generator state */
typedef struct arc4ctx {
isc_uint8_t i;
@@ -172,7 +175,8 @@ struct dispsocket {
isc_socket_t *socket;
dns_dispatch_t *disp;
isc_sockaddr_t host;
- in_port_t localport;
+ in_port_t localport; /* XXX: should be removed later */
+ dispportentry_t *portentry;
dns_dispentry_t *resp;
isc_task_t *task;
ISC_LINK(dispsocket_t) link;
@@ -180,6 +184,21 @@ struct dispsocket {
ISC_LINK(dispsocket_t) blink;
};
+/*%
+ * A port table entry. We remember every port we first open in a table with a
+ * reference counter so that we can 'reuse' the same port (with different
+ * destination addresses) using the SO_REUSEADDR socket option.
+ */
+struct dispportentry {
+ in_port_t port;
+ unsigned int refs;
+ ISC_LINK(struct dispportentry) link;
+};
+
+#ifndef DNS_DISPATCH_PORTTABLESIZE
+#define DNS_DISPATCH_PORTTABLESIZE 1024
+#endif
+
#define INVALID_BUCKET (0xffffdead)
/*%
@@ -229,6 +248,8 @@ struct dns_dispatch {
dns_tcpmsg_t tcpmsg; /*%< for tcp streams */
dns_qid_t *qid;
arc4ctx_t arc4ctx; /*%< for QID/UDP port num */
+ dispportlist_t *port_table; /*%< hold ports 'owned' by us */
+ isc_mempool_t *portpool; /*%< port table entries */
};
#define QID_MAGIC ISC_MAGIC('Q', 'i', 'd', ' ')
@@ -679,6 +700,64 @@ destroy_disp(isc_task_t *task, isc_event_t *event) {
}
/*%
+ * Manipulate port table per dispatch: find an entry for a given port number,
+ * create a new entry, and decrement a given entry with possible clean-up.
+ */
+static dispportentry_t *
+port_search(dns_dispatch_t *disp, in_port_t port) {
+ dispportentry_t *portentry;
+
+ REQUIRE(disp->port_table != NULL);
+
+ portentry = ISC_LIST_HEAD(disp->port_table[port %
+ DNS_DISPATCH_PORTTABLESIZE]);
+ while (portentry != NULL) {
+ if (portentry->port == port)
+ return (portentry);
+ portentry = ISC_LIST_NEXT(portentry, link);
+ }
+
+ return (NULL);
+}
+
+static dispportentry_t *
+new_portentry(dns_dispatch_t *disp, in_port_t port) {
+ dispportentry_t *portentry;
+
+ REQUIRE(disp->port_table != NULL);
+
+ portentry = isc_mempool_get(disp->portpool);
+ if (portentry == NULL)
+ return (portentry);
+
+ portentry->port = port;
+ portentry->refs = 0;
+ ISC_LINK_INIT(portentry, link);
+ ISC_LIST_APPEND(disp->port_table[port % DNS_DISPATCH_PORTTABLESIZE],
+ portentry, link);
+
+ return (portentry);
+}
+
+static void
+deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) {
+ dispportentry_t *portentry = *portentryp;
+
+ REQUIRE(disp->port_table != NULL);
+ REQUIRE(portentry != NULL && portentry->refs > 0);
+
+ portentry->refs--;
+ if (portentry->refs == 0) {
+ ISC_LIST_UNLINK(disp->port_table[portentry->port %
+ DNS_DISPATCH_PORTTABLESIZE],
+ portentry, link);
+ isc_mempool_put(disp->portpool, portentry);
+ }
+
+ *portentryp = NULL;
+}
+
+/*%
* Find a dispsocket for socket address 'dest', and port number 'port'.
* Return NULL if no such entry exists.
*/
@@ -694,7 +773,7 @@ socket_search(dns_qid_t *qid, isc_sockaddr_t *dest, in_port_t port,
while (dispsock != NULL) {
if (isc_sockaddr_equal(dest, &dispsock->host) &&
- dispsock->localport == port)
+ dispsock->portentry->port == port)
return (dispsock);
dispsock = ISC_LIST_NEXT(dispsock, blink);
}
@@ -722,6 +801,8 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
dispsocket_t *dispsock;
unsigned int nports;
in_port_t *ports;
+ unsigned int bindoptions = 0;
+ dispportentry_t *portentry = NULL;
if (isc_sockaddr_pf(&disp->local) == AF_INET) {
nports = disp->mgr->nv4ports;
@@ -747,6 +828,7 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
dispsock->socket = NULL;
dispsock->disp = disp;
dispsock->resp = NULL;
+ dispsock->portentry = NULL;
isc_random_get(&r);
dispsock->task = NULL;
isc_task_attach(disp->task[r % disp->ntasks], &dispsock->task);
@@ -769,16 +851,28 @@ get_dispsocket(dns_dispatch_t *disp, isc_sockaddr_t *dest,
bucket = dns_hash(qid, dest, 0, port);
if (socket_search(qid, dest, port, bucket) != NULL)
continue;
-
- result = open_socket(sockmgr, &localaddr, 0, &sock);
- if (result == ISC_R_SUCCESS || result != ISC_R_ADDRINUSE)
+ portentry = port_search(disp, port);
+ if (portentry != NULL)
+ bindoptions |= ISC_SOCKET_REUSEADDRESS;
+ result = open_socket(sockmgr, &localaddr, bindoptions, &sock);
+ if (result == ISC_R_SUCCESS) {
+ if (portentry == NULL) {
+ portentry = new_portentry(disp, port);
+ if (portentry == NULL) {
+ result = ISC_R_NOMEMORY;
+ break;
+ }
+ }
+ portentry->refs++;
+ break;
+ } else if (result != ISC_R_ADDRINUSE)
break;
}
if (result == ISC_R_SUCCESS) {
dispsock->socket = sock;
dispsock->host = *dest;
- dispsock->localport = port;
+ dispsock->portentry = portentry;
dispsock->bucket = bucket;
ISC_LIST_APPEND(qid->sock_table[bucket], dispsock, blink);
*dispsockp = dispsock;
@@ -815,6 +909,8 @@ destroy_dispsocket(dns_dispatch_t *disp, dispsocket_t **dispsockp) {
disp->nsockets--;
dispsock->magic = 0;
+ if (dispsock->portentry != NULL)
+ deref_portentry(disp, &dispsock->portentry);
if (dispsock->socket != NULL)
isc_socket_detach(&dispsock->socket);
if (ISC_LINK_LINKED(dispsock, blink)) {
@@ -849,6 +945,9 @@ deactivate_dispsocket(dns_dispatch_t *disp, dispsocket_t *dispsock) {
dispsock->resp->dispsocket = NULL;
}
+ INSIST(dispsock->portentry != NULL);
+ deref_portentry(disp, &dispsock->portentry);
+
if (disp->nsockets > DNS_DISPATCH_POOLSOCKS)
destroy_dispsocket(disp, &dispsock);
else {
@@ -2289,6 +2388,8 @@ dispatch_allocate(dns_dispatchmgr_t *mgr, unsigned int maxrequests,
ISC_LIST_INIT(disp->inactivesockets);
disp->nsockets = 0;
dispatch_arc4init(&disp->arc4ctx, mgr->entropy, NULL);
+ disp->port_table = NULL;
+ disp->portpool = NULL;
result = isc_mutex_init(&disp->lock);
if (result != ISC_R_SUCCESS)
@@ -2325,6 +2426,7 @@ dispatch_free(dns_dispatch_t **dispp)
{
dns_dispatch_t *disp;
dns_dispatchmgr_t *mgr;
+ int i;
REQUIRE(VALID_DISPATCH(*dispp));
disp = *dispp;
@@ -2349,6 +2451,18 @@ dispatch_free(dns_dispatch_t **dispp)
if (disp->qid != NULL)
qid_destroy(mgr->mctx, &disp->qid);
+
+ if (disp->port_table != NULL) {
+ for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++)
+ INSIST(ISC_LIST_EMPTY(disp->port_table[i]));
+ isc_mem_put(mgr->mctx, disp->port_table,
+ sizeof(disp->port_table[0]) *
+ DNS_DISPATCH_PORTTABLESIZE);
+ }
+
+ if (disp->portpool != NULL)
+ isc_mempool_destroy(&disp->portpool);
+
disp->mgr = NULL;
DESTROYLOCK(&disp->lock);
disp->magic = 0;
@@ -2669,6 +2783,21 @@ dispatch_createudp(dns_dispatchmgr_t *mgr, isc_socketmgr_t *sockmgr,
if (result != ISC_R_SUCCESS)
goto deallocate_dispatch;
}
+
+ disp->port_table = isc_mem_get(mgr->mctx,
+ sizeof(disp->port_table[0]) *
+ DNS_DISPATCH_PORTTABLESIZE);
+ if (disp->port_table == NULL)
+ goto deallocate_dispatch;
+ for (i = 0; i < DNS_DISPATCH_PORTTABLESIZE; i++)
+ ISC_LIST_INIT(disp->port_table[i]);
+
+ result = isc_mempool_create(mgr->mctx, sizeof(dispportentry_t),
+ &disp->portpool);
+ if (result != ISC_R_SUCCESS)
+ goto deallocate_dispatch;
+ isc_mempool_setname(disp->portpool, "disp_portpool");
+ isc_mempool_setfreemax(disp->portpool, 128);
}
disp->socktype = isc_sockettype_udp;
disp->socket = sock;
diff --git a/lib/dns/dnssec.c b/lib/dns/dnssec.c
index 98d7579a..f06d715c 100644
--- a/lib/dns/dnssec.c
+++ b/lib/dns/dnssec.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2003 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -16,7 +16,7 @@
*/
/*
- * $Id: dnssec.c,v 1.91 2007/09/14 04:32:50 marka Exp $
+ * $Id: dnssec.c,v 1.93 2008/11/14 23:47:33 tbox Exp $
*/
/*! \file */
@@ -366,6 +366,9 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
if (ret != ISC_R_SUCCESS)
return (ret);
+ if (set->type != sig.covered)
+ return (DNS_R_SIGINVALID);
+
if (isc_serial_lt(sig.timeexpire, sig.timesigned))
return (DNS_R_SIGINVALID);
@@ -382,6 +385,27 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
}
/*
+ * NS, SOA and DNSSKEY records are signed by their owner.
+ * DS records are signed by the parent.
+ */
+ switch (set->type) {
+ case dns_rdatatype_ns:
+ case dns_rdatatype_soa:
+ case dns_rdatatype_dnskey:
+ if (!dns_name_equal(name, &sig.signer))
+ return (DNS_R_SIGINVALID);
+ break;
+ case dns_rdatatype_ds:
+ if (dns_name_equal(name, &sig.signer))
+ return (DNS_R_SIGINVALID);
+ /* FALLTHROUGH */
+ default:
+ if (!dns_name_issubdomain(name, &sig.signer))
+ return (DNS_R_SIGINVALID);
+ break;
+ }
+
+ /*
* Is the key allowed to sign data?
*/
flags = dst_key_flags(key);
@@ -407,7 +431,7 @@ dns_dnssec_verify2(dns_name_t *name, dns_rdataset_t *set, dst_key_t *key,
dns_fixedname_init(&fnewname);
labels = dns_name_countlabels(name) - 1;
RUNTIME_CHECK(dns_name_downcase(name, dns_fixedname_name(&fnewname),
- NULL) == ISC_R_SUCCESS);
+ NULL) == ISC_R_SUCCESS);
if (labels - sig.labels > 0)
dns_name_split(dns_fixedname_name(&fnewname), sig.labels + 1,
NULL, dns_fixedname_name(&fnewname));
@@ -487,9 +511,9 @@ cleanup_struct:
dns_rdata_freestruct(&sig);
if (ret == ISC_R_SUCCESS && labels - sig.labels > 0) {
- if (wild != NULL)
+ if (wild != NULL)
RUNTIME_CHECK(dns_name_concatenate(dns_wildcardname,
- dns_fixedname_name(&fnewname),
+ dns_fixedname_name(&fnewname),
wild, NULL) == ISC_R_SUCCESS);
ret = DNS_R_FROMWILDCARD;
}
@@ -541,6 +565,9 @@ dns_dnssec_findzonekeys2(dns_db_t *db, dns_dbversion_t *ver,
if (!is_zone_key(pubkey) ||
(dst_key_flags(pubkey) & DNS_KEYTYPE_NOAUTH) != 0)
goto next;
+ /* Corrupted .key file? */
+ if (!dns_name_equal(name, dst_key_name(pubkey)))
+ goto next;
keys[count] = NULL;
result = dst_key_fromfile(dst_key_name(pubkey),
dst_key_id(pubkey),
@@ -802,7 +829,7 @@ dns_dnssec_verifymessage(isc_buffer_t *source, dns_message_t *msg,
RETERR(dst_context_create(key, mctx, &ctx));
/*
- * Digest the SIG(0) record, except for the signature.
+ * Digest the SIG(0) record, except for the signature.
*/
dns_rdata_toregion(&rdata, &r);
r.length -= sig.siglen;
diff --git a/lib/dns/dst_api.c b/lib/dns/dst_api.c
index 4bfcfe8d..32f894d5 100644
--- a/lib/dns/dst_api.c
+++ b/lib/dns/dst_api.c
@@ -31,7 +31,7 @@
/*
* Principal Author: Brian Wellington
- * $Id: dst_api.c,v 1.15 2008/09/24 02:46:22 marka Exp $
+ * $Id: dst_api.c,v 1.16 2008/11/14 22:53:46 marka Exp $
*/
/*! \file */
@@ -997,6 +997,13 @@ dst_key_read_public(const char *filename, int type,
NEXTTOKEN(lex, opt, &token);
if (token.type != isc_tokentype_string)
BADTOKEN();
+
+ /*
+ * We don't support "@" in .key files.
+ */
+ if (!strcmp(DST_AS_STR(token), "@"))
+ BADTOKEN();
+
dns_fixedname_init(&name);
isc_buffer_init(&b, DST_AS_STR(token), strlen(DST_AS_STR(token)));
isc_buffer_add(&b, strlen(DST_AS_STR(token)));
diff --git a/lib/dns/gssapi_link.c b/lib/dns/gssapi_link.c
index 2216c962..0dd27bbe 100644
--- a/lib/dns/gssapi_link.c
+++ b/lib/dns/gssapi_link.c
@@ -16,7 +16,7 @@
*/
/*
- * $Id: gssapi_link.c,v 1.11 2008/07/23 10:26:54 marka Exp $
+ * $Id: gssapi_link.c,v 1.12 2008/11/11 03:55:01 marka Exp $
*/
#include <config.h>
@@ -291,7 +291,8 @@ static dst_func_t gssapi_functions = {
NULL, /*%< fromdns */
NULL, /*%< tofile */
NULL, /*%< parse */
- NULL /*%< cleanup */
+ NULL, /*%< cleanup */
+ NULL /*%< fromlabel */
};
isc_result_t
diff --git a/lib/dns/include/dns/Makefile.in b/lib/dns/include/dns/Makefile.in
index 7397d56d..e9e049e2 100644
--- a/lib/dns/include/dns/Makefile.in
+++ b/lib/dns/include/dns/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
# Copyright (C) 1998-2003 Internet Software Consortium.
#
# Permission to use, copy, modify, and/or distribute this software for any
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.53 2007/09/12 01:09:08 each Exp $
+# $Id: Makefile.in,v 1.55 2008/11/14 23:47:33 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -23,14 +23,14 @@ top_srcdir = @top_srcdir@
HEADERS = acl.h adb.h byaddr.h cache.h callbacks.h \
cert.h compress.h \
- db.h dbiterator.h dbtable.h diff.h dispatch.h \
+ db.h dbiterator.h dbtable.h diff.h dispatch.h dlz.h \
dnssec.h ds.h events.h fixedname.h iptable.h journal.h keyflags.h \
keytable.h keyvalues.h lib.h log.h master.h masterdump.h \
message.h name.h ncache.h \
nsec.h peer.h portlist.h rbt.h rcode.h \
rdata.h rdataclass.h rdatalist.h rdataset.h rdatasetiter.h \
rdataslab.h rdatatype.h request.h resolver.h result.h \
- rootns.h sdb.h secalg.h secproto.h soa.h ssu.h \
+ rootns.h sdb.h sdlz.h secalg.h secproto.h soa.h ssu.h \
tcpmsg.h time.h tkey.h \
tsig.h ttl.h types.h validator.h version.h view.h xfrin.h \
zone.h zonekey.h zt.h
diff --git a/lib/dns/nsec3.c b/lib/dns/nsec3.c
index edcd1fd2..54a6993e 100644
--- a/lib/dns/nsec3.c
+++ b/lib/dns/nsec3.c
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: nsec3.c,v 1.5 2008/09/26 01:24:55 marka Exp $ */
+/* $Id: nsec3.c,v 1.6 2008/11/17 23:46:42 marka Exp $ */
#include <config.h>
@@ -152,7 +152,9 @@ dns_nsec3_buildrdata(dns_db_t *db, dns_dbversion_t *version,
if (rdataset.type > max_type)
max_type = rdataset.type;
set_bit(bm, rdataset.type, 1);
- found = ISC_TRUE;
+ /* Don't set RRSIG for insecure delegation. */
+ if (rdataset.type != dns_rdatatype_ns)
+ found = ISC_TRUE;
}
dns_rdataset_disassociate(&rdataset);
}
diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c
index 8d0010e5..5cdbcad9 100644
--- a/lib/dns/rbtdb.c
+++ b/lib/dns/rbtdb.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: rbtdb.c,v 1.269 2008/10/29 05:53:12 marka Exp $ */
+/* $Id: rbtdb.c,v 1.270 2008/11/14 14:07:48 marka Exp $ */
/*! \file */
@@ -3082,7 +3082,7 @@ static inline isc_result_t
find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_name_t *foundname, dns_rdataset_t *rdataset,
dns_rdataset_t *sigrdataset, dns_rbt_t *tree,
- isc_boolean_t need_sig)
+ dns_db_secure_t secure)
{
dns_rbtnode_t *node;
rdatasetheader_t *header, *header_next, *found, *foundsig;
@@ -3093,6 +3093,7 @@ find_closest_nsec(rbtdb_search_t *search, dns_dbnode_t **nodep,
dns_rdatatype_t type;
rbtdb_rdatatype_t sigtype;
isc_boolean_t wraps;
+ isc_boolean_t need_sig = ISC_TF(secure == dns_db_secure);
if (tree == search->rbtdb->nsec3) {
type = dns_rdatatype_nsec3;
@@ -3351,7 +3352,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* If we're here, then the name does not exist, is not
* beneath a zonecut, and there's no matching wildcard.
*/
- if ((search.rbtversion->secure &&
+ if ((search.rbtversion->secure == dns_db_secure &&
!search.rbtversion->havensec3) ||
(search.options & DNS_DBFIND_FORCENSEC) != 0 ||
(search.options & DNS_DBFIND_FORCENSEC3) != 0)
@@ -3592,7 +3593,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
* The desired type doesn't exist.
*/
result = DNS_R_NXRRSET;
- if (search.rbtversion->secure &&
+ if (search.rbtversion->secure == dns_db_secure &&
!search.rbtversion->havensec3 &&
(nsecheader == NULL || nsecsig == NULL)) {
/*
@@ -3628,7 +3629,7 @@ zone_find(dns_db_t *db, dns_name_t *name, dns_dbversion_t *version,
new_reference(search.rbtdb, node);
*nodep = node;
}
- if ((search.rbtversion->secure &&
+ if ((search.rbtversion->secure == dns_db_secure &&
!search.rbtversion->havensec3) ||
(search.options & DNS_DBFIND_FORCENSEC) != 0)
{
@@ -6963,7 +6964,7 @@ dns_rbtdb_create
free_rbtdb(rbtdb, ISC_FALSE, NULL);
return (ISC_R_NOMEMORY);
}
- rbtdb->current_version->secure = ISC_FALSE;
+ rbtdb->current_version->secure = dns_db_insecure;
rbtdb->current_version->havensec3 = ISC_FALSE;
rbtdb->current_version->flags = 0;
rbtdb->current_version->iterations = 0;
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 5c9f348a..9d1c2feb 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.382 2008/10/17 21:58:09 jinmei Exp $ */
+/* $Id: resolver.c,v 1.384 2008/11/07 00:52:34 marka Exp $ */
/*! \file */
@@ -552,14 +552,13 @@ fctx_stoptimer(fetchctx_t *fctx) {
static inline isc_result_t
-fctx_startidletimer(fetchctx_t *fctx) {
+fctx_startidletimer(fetchctx_t *fctx, isc_interval_t *interval) {
/*
* Start the idle timer for fctx. The lifetime timer continues
* to be in effect.
*/
return (isc_timer_reset(fctx->timer, isc_timertype_once,
- &fctx->expires, &fctx->interval,
- ISC_FALSE));
+ &fctx->expires, interval, ISC_FALSE));
}
/*
@@ -1121,7 +1120,7 @@ fctx_setretryinterval(fetchctx_t *fctx, unsigned int rtt) {
unsigned int us;
/*
- * We retry every .5 seconds the first two times through the address
+ * We retry every .8 seconds the first two times through the address
* list, and then we do exponential back-off.
*/
if (fctx->restarts < 3)
@@ -1173,7 +1172,7 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
srtt = 1000000;
fctx_setretryinterval(fctx, srtt);
- result = fctx_startidletimer(fctx);
+ result = fctx_startidletimer(fctx, &fctx->interval);
if (result != ISC_R_SUCCESS)
return (result);
@@ -1771,6 +1770,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
isc_socketevent_t *sevent = (isc_socketevent_t *)event;
resquery_t *query = event->ev_arg;
isc_boolean_t retry = ISC_FALSE;
+ isc_interval_t interval;
isc_result_t result;
unsigned int attrs;
fetchctx_t *fctx;
@@ -1803,6 +1803,20 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
} else {
switch (sevent->result) {
case ISC_R_SUCCESS:
+
+ /*
+ * Extend the idle timer for TCP. 20 seconds
+ * should be long enough for a TCP connection to be
+ * established, a single DNS request to be sent,
+ * and the response received.
+ */
+ isc_interval_set(&interval, 20, 0);
+ result = fctx_startidletimer(query->fctx, &interval);
+ if (result != ISC_R_SUCCESS) {
+ fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
+ fctx_done(fctx, result);
+ break;
+ }
/*
* We are connected. Create a dispatcher and
* send the query.
@@ -1835,8 +1849,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
result = resquery_send(query);
if (result != ISC_R_SUCCESS) {
- fctx_cancelquery(&query, NULL, NULL,
- ISC_FALSE);
+ fctx_cancelquery(&query, NULL, NULL, ISC_FALSE);
fctx_done(fctx, result);
}
break;
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c
index 1aa194dc..74a7af32 100644
--- a/lib/dns/tsig.c
+++ b/lib/dns/tsig.c
@@ -16,7 +16,7 @@
*/
/*
- * $Id: tsig.c,v 1.135 2008/04/02 02:37:42 marka Exp $
+ * $Id: tsig.c,v 1.136 2008/11/04 21:23:14 marka Exp $
*/
/*! \file */
#include <config.h>
@@ -445,7 +445,6 @@ cleanup_ring(dns_tsig_keyring_t *ring)
dns_rbtnodechain_current(&chain, &foundname, origin, &node);
tkey = node->data;
if (tkey != NULL) {
- tsig_log(tkey, 2, "tsig expire: generated=%d, refs=%d, expire=%d)", tkey->generated, isc_refcount_current(&tkey->refs), now - tkey->expire);
if (tkey->generated
&& isc_refcount_current(&tkey->refs) == 1
&& tkey->inception != tkey->expire
diff --git a/lib/dns/validator.c b/lib/dns/validator.c
index cd6de2d3..39c17d57 100644
--- a/lib/dns/validator.c
+++ b/lib/dns/validator.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: validator.c,v 1.162 2008/09/24 02:46:22 marka Exp $ */
+/* $Id: validator.c,v 1.164 2008/11/14 23:47:33 tbox Exp $ */
#include <config.h>
@@ -1544,6 +1544,23 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) {
*/
if (dns_rdatatype_atparent(val->event->rdataset->type))
return (DNS_R_CONTINUE);
+ } else {
+ /*
+ * SOA and NS RRsets can only be signed by a key with
+ * the same name.
+ */
+ if (val->event->rdataset->type == dns_rdatatype_soa ||
+ val->event->rdataset->type == dns_rdatatype_ns) {
+ const char *typename;
+
+ if (val->event->rdataset->type == dns_rdatatype_soa)
+ typename = "SOA";
+ else
+ typename = "NS";
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "%s signer mismatch", typename);
+ return (DNS_R_CONTINUE);
+ }
}
/*
@@ -2115,6 +2132,10 @@ validatezonekey(dns_validator_t *val) {
&sigrdata);
result = dns_rdata_tostruct(&sigrdata, &sig, NULL);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
+
+ if (!dns_name_equal(val->event->name, &sig.signer))
+ continue;
+
result = dns_keytable_findkeynode(val->keytable,
val->event->name,
sig.algorithm,
@@ -2355,7 +2376,11 @@ validatezonekey(dns_validator_t *val) {
if (ds.key_tag != sig.keyid ||
ds.algorithm != sig.algorithm)
continue;
-
+ if (!dns_name_equal(val->event->name, &sig.signer)) {
+ validator_log(val, ISC_LOG_DEBUG(3),
+ "DNSKEY signer mismatch");
+ continue;
+ }
dstkey = NULL;
result = dns_dnssec_keyfromrdata(val->event->name,
&keyrdata,
diff --git a/lib/isc/api b/lib/isc/api
index 8459d423..2240cdda 100644
--- a/lib/isc/api
+++ b/lib/isc/api
@@ -1,3 +1,3 @@
LIBINTERFACE = 50
-LIBREVISION = 0
+LIBREVISION = 1
LIBAGE = 0
diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in
index ea8e2e48..236865df 100644
--- a/lib/isc/include/isc/Makefile.in
+++ b/lib/isc/include/isc/Makefile.in
@@ -1,4 +1,4 @@
-# Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 2004-2008 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
@@ -13,7 +13,7 @@
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
-# $Id: Makefile.in,v 1.62 2007/06/19 23:47:18 tbox Exp $
+# $Id: Makefile.in,v 1.64 2008/11/14 23:47:33 tbox Exp $
srcdir = @srcdir@
VPATH = @srcdir@
@@ -35,7 +35,7 @@ HEADERS = app.h assertions.h base64.h bitstring.h boolean.h buffer.h \
lfsr.h lib.h list.h log.h \
magic.h md5.h mem.h msgcat.h msgs.h \
mutexblock.h netaddr.h ondestroy.h os.h parseint.h \
- print.h quota.h random.h ratelimiter.h \
+ print.h quota.h radix.h random.h ratelimiter.h \
refcount.h region.h resource.h \
result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
sockaddr.h socket.h stdio.h stdlib.h string.h \
diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c
index 67f34c8d..98d0ab6e 100644
--- a/lib/isc/unix/socket.c
+++ b/lib/isc/unix/socket.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: socket.c,v 1.304 2008/10/17 21:49:23 jinmei Exp $ */
+/* $Id: socket.c,v 1.308 2008/11/20 00:04:17 jinmei Exp $ */
/*! \file */
@@ -148,6 +148,35 @@ struct isc_socketwait {
#endif /* __APPLE__ */
#endif /* USE_SELECT */
+#ifdef ISC_SOCKET_USE_POLLWATCH
+/*%
+ * If this macro is defined, enable workaround for a Solaris /dev/poll kernel
+ * bug: DP_POLL ioctl could keep sleeping even if socket I/O is possible for
+ * some of the specified FD. The idea is based on the observation that it's
+ * likely for a busy server to keep receiving packets. It specifically works
+ * as follows: the socket watcher is first initialized with the state of
+ * "poll_idle". While it's in the idle state it keeps sleeping until a socket
+ * event occurs. When it wakes up for a socket I/O event, it moves to the
+ * poll_active state, and sets the poll timeout to a short period
+ * (ISC_SOCKET_POLLWATCH_TIMEOUT msec). If timeout occurs in this state, the
+ * watcher goes to the poll_checking state with the same timeout period.
+ * In this state, the watcher tries to detect whether this is a break
+ * during intermittent events or the kernel bug is triggered. If the next
+ * polling reports an event within the short period, the previous timeout is
+ * likely to be a kernel bug, and so the watcher goes back to the active state.
+ * Otherwise, it moves to the idle state again.
+ *
+ * It's not clear whether this is a thread-related bug, but since we've only
+ * seen this with threads, this workaround is used only when enabling threads.
+ */
+
+typedef enum { poll_idle, poll_active, poll_checking } pollstate_t;
+
+#ifndef ISC_SOCKET_POLLWATCH_TIMEOUT
+#define ISC_SOCKET_POLLWATCH_TIMEOUT 10
+#endif /* ISC_SOCKET_POLLWATCH_TIMEOUT */
+#endif /* ISC_SOCKET_USE_POLLWATCH */
+
/*%
* Size of per-FD lock buckets.
*/
@@ -464,6 +493,38 @@ socket_log(isc_socket_t *sock, isc_sockaddr_t *address,
}
}
+#if defined(_AIX) && defined(ISC_NET_BSD44MSGHDR) && \
+ defined(USE_CMSG) && defined(IPV6_RECVPKTINFO)
+/*
+ * AIX has a kernel bug where IPV6_RECVPKTINFO gets cleared by
+ * setting IPV6_V6ONLY.
+ */
+static void
+FIX_IPV6_RECVPKTINFO(isc_socket_t *sock)
+{
+ char strbuf[ISC_STRERRORSIZE];
+ int on = 1;
+
+ if (sock->pf != AF_INET6 || sock->type != isc_sockettype_udp)
+ return;
+
+ if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_RECVPKTINFO,
+ (void *)&on, sizeof(on)) < 0) {
+
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "setsockopt(%d, IPV6_RECVPKTINFO) "
+ "%s: %s", sock->fd,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ }
+}
+#else
+#define FIX_IPV6_RECVPKTINFO(sock) (void)0
+#endif
+
static inline isc_result_t
watch_fd(isc_socketmgr_t *manager, int fd, int msg) {
isc_result_t result = ISC_R_SUCCESS;
@@ -1256,15 +1317,17 @@ dump_msg(struct msghdr *msg) {
unsigned int i;
printf("MSGHDR %p\n", msg);
- printf("\tname %p, namelen %d\n", msg->msg_name, msg->msg_namelen);
- printf("\tiov %p, iovlen %d\n", msg->msg_iov, msg->msg_iovlen);
+ printf("\tname %p, namelen %ld\n", msg->msg_name,
+ (long) msg->msg_namelen);
+ printf("\tiov %p, iovlen %ld\n", msg->msg_iov,
+ (long) msg->msg_iovlen);
for (i = 0; i < (unsigned int)msg->msg_iovlen; i++)
- printf("\t\t%d\tbase %p, len %d\n", i,
+ printf("\t\t%d\tbase %p, len %ld\n", i,
msg->msg_iov[i].iov_base,
- msg->msg_iov[i].iov_len);
+ (long) msg->msg_iov[i].iov_len);
#ifdef ISC_NET_BSD44MSGHDR
- printf("\tcontrol %p, controllen %d\n", msg->msg_control,
- msg->msg_controllen);
+ printf("\tcontrol %p, controllen %ld\n", msg->msg_control,
+ (long) msg->msg_controllen);
#endif
}
#endif
@@ -3230,6 +3293,9 @@ watcher(void *uap) {
int maxfd;
#endif
char strbuf[ISC_STRERRORSIZE];
+#ifdef ISC_SOCKET_USE_POLLWATCH
+ pollstate_t pollstate = poll_idle;
+#endif
/*
* Get the control fd here. This will never change.
@@ -3247,7 +3313,14 @@ watcher(void *uap) {
#elif defined(USE_DEVPOLL)
dvp.dp_fds = manager->events;
dvp.dp_nfds = manager->nevents;
+#ifndef ISC_SOCKET_USE_POLLWATCH
dvp.dp_timeout = -1;
+#else
+ if (pollstate == poll_idle)
+ dvp.dp_timeout = -1;
+ else
+ dvp.dp_timeout = ISC_SOCKET_POLLWATCH_TIMEOUT;
+#endif /* ISC_SOCKET_USE_POLLWATCH */
cc = ioctl(manager->devpoll_fd, DP_POLL, &dvp);
#elif defined(USE_SELECT)
LOCK(&manager->lock);
@@ -3271,6 +3344,32 @@ watcher(void *uap) {
ISC_MSG_FAILED,
"failed"), strbuf);
}
+
+#if defined(USE_DEVPOLL) && defined(ISC_SOCKET_USE_POLLWATCH)
+ if (cc == 0) {
+ if (pollstate == poll_active)
+ pollstate = poll_checking;
+ else if (pollstate == poll_checking)
+ pollstate = poll_idle;
+ } else if (cc > 0) {
+ if (pollstate == poll_checking) {
+ /*
+ * XXX: We'd like to use a more
+ * verbose log level as it's actually an
+ * unexpected event, but the kernel bug
+ * reportedly happens pretty frequently
+ * (and it can also be a false positive)
+ * so it would be just too noisy.
+ */
+ manager_log(manager,
+ ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET,
+ ISC_LOG_DEBUG(1),
+ "unexpected POLL timeout");
+ }
+ pollstate = poll_active;
+ }
+#endif
} while (cc < 0);
#if defined(USE_KQUEUE) || defined (USE_EPOLL) || defined (USE_DEVPOLL)
@@ -5022,9 +5121,21 @@ isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes) {
#ifdef IPV6_V6ONLY
if (sock->pf == AF_INET6) {
- (void)setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
- (void *)&onoff, sizeof(onoff));
+ if (setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
+ (void *)&onoff, sizeof(int)) < 0) {
+ char strbuf[ISC_STRERRORSIZE];
+
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "setsockopt(%d, IPV6_V6ONLY) "
+ "%s: %s", sock->fd,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ }
}
+ FIX_IPV6_RECVPKTINFO(sock); /* AIX */
#endif
}
diff --git a/lib/isc/win32/dir.c b/lib/isc/win32/dir.c
index 3d0ae609..93cc650e 100644
--- a/lib/isc/win32/dir.c
+++ b/lib/isc/win32/dir.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2004, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
* Copyright (C) 1999-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and/or distribute this software for any
@@ -15,15 +15,10 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: dir.c,v 1.14 2007/06/19 23:47:19 tbox Exp $ */
+/* $Id: dir.c,v 1.16 2008/11/02 23:47:01 tbox Exp $ */
/* Principal Authors: DCL */
-/*
- * isc_dir_chroot is currently stubbed out for Win32
- * This will need to be revisited
- */
-
#include <config.h>
#include <string.h>
@@ -242,7 +237,7 @@ isc_dir_chdir(const char *dirname) {
isc_result_t
isc_dir_chroot(const char *dirname) {
- return (ISC_R_SUCCESS);
+ return (ISC_R_NOTIMPLEMENTED);
}
isc_result_t