diff options
Diffstat (limited to 'lib/dns')
-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 |
11 files changed, 246 insertions, 42 deletions
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, |