diff options
author | LaMont Jones <lamont@debian.org> | 2009-03-20 08:26:10 -0600 |
---|---|---|
committer | LaMont Jones <lamont@debian.org> | 2009-03-20 08:26:10 -0600 |
commit | 457d065cf051a7ad041ace140c5ae6184fd5d208 (patch) | |
tree | e023610b78adf4253e9eecde3e96f1b1a022e577 /lib | |
parent | 95cab7ab13c7aedf768b3273a9a736f23239c18f (diff) | |
download | bind9-457d065cf051a7ad041ace140c5ae6184fd5d208.tar.gz |
9.6.0rc1
Diffstat (limited to 'lib')
-rw-r--r-- | lib/bind9/api | 2 | ||||
-rw-r--r-- | lib/bind9/check.c | 15 | ||||
-rw-r--r-- | lib/dns/api | 2 | ||||
-rw-r--r-- | lib/dns/dispatch.c | 145 | ||||
-rw-r--r-- | lib/dns/dnssec.c | 39 | ||||
-rw-r--r-- | lib/dns/dst_api.c | 9 | ||||
-rw-r--r-- | lib/dns/gssapi_link.c | 5 | ||||
-rw-r--r-- | lib/dns/include/dns/Makefile.in | 8 | ||||
-rw-r--r-- | lib/dns/nsec3.c | 6 | ||||
-rw-r--r-- | lib/dns/rbtdb.c | 13 | ||||
-rw-r--r-- | lib/dns/resolver.c | 29 | ||||
-rw-r--r-- | lib/dns/tsig.c | 3 | ||||
-rw-r--r-- | lib/dns/validator.c | 29 | ||||
-rw-r--r-- | lib/isc/api | 2 | ||||
-rw-r--r-- | lib/isc/include/isc/Makefile.in | 6 | ||||
-rw-r--r-- | lib/isc/unix/socket.c | 129 | ||||
-rw-r--r-- | lib/isc/win32/dir.c | 11 |
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 |