From: Jan Lentfer Date: Mon, 29 Mar 2010 08:23:56 +0000 (+0200) Subject: vendor/BIND: Update to 9.5.2-P3 X-Git-Url: https://gitweb.dragonflybsd.org/~syl/dragonfly.git/commitdiff_plain/40c29c6adfed851fa4c5d6246067a494de11603f vendor/BIND: Update to 9.5.2-P3 --- diff --git a/contrib/bind/CHANGES b/contrib/bind/CHANGES index f89ca86c86..55f79e0b25 100644 --- a/contrib/bind/CHANGES +++ b/contrib/bind/CHANGES @@ -1,3 +1,7 @@ + --- 9.5.2-P3 released --- + +2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619] + --- 9.5.2-P2 released --- 2831. [security] Do not attempt to validate or cache diff --git a/contrib/bind/COPYRIGHT b/contrib/bind/COPYRIGHT index fe042aafc8..4e437f228d 100644 --- a/contrib/bind/COPYRIGHT +++ b/contrib/bind/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") +Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") Copyright (C) 1996-2003 Internet Software Consortium. Permission to use, copy, modify, and/or distribute this software for any @@ -13,7 +13,7 @@ LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -$Id: COPYRIGHT,v 1.13.130.2 2009/01/05 23:46:51 tbox Exp $ +$Id: COPYRIGHT,v 1.13.130.2.2.1 2010/02/25 05:23:41 tbox Exp $ Portions Copyright (C) 1996-2001 Nominum, Inc. diff --git a/contrib/bind/FAQ b/contrib/bind/FAQ index b256ed8b10..9e3469ce4a 100644 --- a/contrib/bind/FAQ +++ b/contrib/bind/FAQ @@ -1,6 +1,6 @@ Frequently Asked Questions about BIND 9 -Copyright © 2004-2009 Internet Systems Consortium, Inc. ("ISC") +Copyright © 2004-2010 Internet Systems Consortium, Inc. ("ISC") Copyright © 2000-2003 Internet Software Consortium. @@ -784,6 +784,22 @@ A: Red Hat Security Enhanced Linux (SELinux) policy security protections : See these man-pages for more information : selinux(8), named_selinux (8), chcon(1), setsebool(8) +Q: I'm running BIND on Ubuntu - + + Why can't named update slave zone database files? + + Why can't named create DDNS journal files or update the master zones + from journals? + + Why can't named create custom log files? + +A: Ubuntu uses AppArmor in + addition to normal file system permissions to protect the system. + + Adjust the paths to use those specified in /etc/apparmor.d/ + usr.sbin.named or adjust /etc/apparmor.d/usr.sbin.named to allow named + to write at the location specified in named.conf. + Q: Listening on individual IPv6 interfaces does not work. A: This is usually due to "/proc/net/if_inet6" not being available in the diff --git a/contrib/bind/bin/named/server.c b/contrib/bind/bin/named/server.c index d3fdb01444..7812b164c8 100644 --- a/contrib/bind/bin/named/server.c +++ b/contrib/bind/bin/named/server.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: server.c,v 1.495.10.29 2009/07/11 04:28:14 marka Exp $ */ +/* $Id: server.c,v 1.495.10.29.2.2 2010/02/25 10:56:00 tbox Exp $ */ /*! \file */ @@ -4722,6 +4722,8 @@ dumpdone(void *arg, isc_result_t result) { } if (dctx->cache != NULL) { dns_adb_dump(dctx->view->view->adb, dctx->fp); + dns_resolver_printbadcache(dctx->view->view->resolver, + dctx->fp); dns_db_detach(&dctx->cache); } if (dctx->dumpzones) { diff --git a/contrib/bind/lib/dns/api b/contrib/bind/lib/dns/api index 1099c302a8..75cda1d411 100644 --- a/contrib/bind/lib/dns/api +++ b/contrib/bind/lib/dns/api @@ -1,3 +1,3 @@ -LIBINTERFACE = 47 +LIBINTERFACE = 48 LIBREVISION = 0 -LIBAGE = 0 +LIBAGE = 1 diff --git a/contrib/bind/lib/dns/include/dns/rdataset.h b/contrib/bind/lib/dns/include/dns/rdataset.h index 8a557b5cc2..7fbd8d767a 100644 --- a/contrib/bind/lib/dns/include/dns/rdataset.h +++ b/contrib/bind/lib/dns/include/dns/rdataset.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.h,v 1.62.128.2 2009/01/19 23:47:03 tbox Exp $ */ +/* $Id: rdataset.h,v 1.62.128.2.2.2 2010/02/25 10:56:02 tbox Exp $ */ #ifndef DNS_RDATASET_H #define DNS_RDATASET_H 1 @@ -104,6 +104,9 @@ typedef struct dns_rdatasetmethods { dns_rdataset_t *rdataset, dns_rdatasetadditional_t type, dns_rdatatype_t qtype); + void (*settrust)(dns_rdataset_t *rdataset, + dns_trust_t trust); + void (*expire)(dns_rdataset_t *rdataset); } dns_rdatasetmethods_t; #define DNS_RDATASET_MAGIC ISC_MAGIC('D','N','S','R') @@ -592,6 +595,19 @@ dns_rdataset_putadditional(dns_acache_t *acache, * information for 'rdataset.' */ +void +dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); +/*%< + * Set the trust of the 'rdataset' to trust in any in the backing database. + * The local trust level of 'rdataset' is also set. + */ + +void +dns_rdataset_expire(dns_rdataset_t *rdataset); +/*%< + * Mark the rdataset to be expired in the backing database. + */ + ISC_LANG_ENDDECLS #endif /* DNS_RDATASET_H */ diff --git a/contrib/bind/lib/dns/include/dns/resolver.h b/contrib/bind/lib/dns/include/dns/resolver.h index a1c51a0cbe..0b457df82a 100644 --- a/contrib/bind/lib/dns/include/dns/resolver.h +++ b/contrib/bind/lib/dns/include/dns/resolver.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.h,v 1.56.128.7 2009/01/29 22:41:45 jinmei Exp $ */ +/* $Id: resolver.h,v 1.56.128.7.2.2 2010/02/25 10:56:02 tbox Exp $ */ #ifndef DNS_RESOLVER_H #define DNS_RESOLVER_H 1 @@ -508,6 +508,48 @@ dns_resolver_setzeronosoattl(dns_resolver_t *resolver, isc_boolean_t state); unsigned int dns_resolver_getoptions(dns_resolver_t *resolver); +void +dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *expire); +/*%< + * Add a entry to the bad cache for that will expire at 'expire'. + * + * Requires: + * \li resolver to be valid. + * \li name to be valid. + */ + +isc_boolean_t +dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *now); +/*%< + * Check to see if there is a unexpired entry in the bad cache for + * . + * + * Requires: + * \li resolver to be valid. + * \li name to be valid. + */ + +void +dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name); +/*%< + * Flush the bad cache of all entries at 'name' if 'name' is non NULL. + * Flush the entire bad cache if 'name' is NULL. + * + * Requires: + * \li resolver to be valid. + */ + +void +dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp); +/*% + * Print out the contents of the bad cache to 'fp'. + * + * Requires: + * \li resolver to be valid. + */ + ISC_LANG_ENDDECLS #endif /* DNS_RESOLVER_H */ diff --git a/contrib/bind/lib/dns/include/dns/result.h b/contrib/bind/lib/dns/include/dns/result.h index 37d61b5c6e..6a0573fe28 100644 --- a/contrib/bind/lib/dns/include/dns/result.h +++ b/contrib/bind/lib/dns/include/dns/result.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.h,v 1.114 2007/06/19 23:47:17 tbox Exp $ */ +/* $Id: result.h,v 1.114.288.2 2010/02/25 10:56:02 tbox Exp $ */ #ifndef DNS_RESULT_H #define DNS_RESULT_H 1 @@ -147,8 +147,11 @@ #define DNS_R_COVERINGNSEC (ISC_RESULTCLASS_DNS + 101) #define DNS_R_MXISADDRESS (ISC_RESULTCLASS_DNS + 102) #define DNS_R_DUPLICATE (ISC_RESULTCLASS_DNS + 103) +#define DNS_R_INVALIDNSEC3 (ISC_RESULTCLASS_DNS + 104) +#define DNS_R_NOTMASTER (ISC_RESULTCLASS_DNS + 105) +#define DNS_R_BROKENCHAIN (ISC_RESULTCLASS_DNS + 106) -#define DNS_R_NRESULTS 104 /*%< Number of results */ +#define DNS_R_NRESULTS 107 /*%< Number of results */ /* * DNS wire format rcodes. diff --git a/contrib/bind/lib/dns/include/dns/validator.h b/contrib/bind/lib/dns/include/dns/validator.h index 746bee156f..811bb373b3 100644 --- a/contrib/bind/lib/dns/include/dns/validator.h +++ b/contrib/bind/lib/dns/include/dns/validator.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.h,v 1.39.52.3 2009/01/19 00:01:11 marka Exp $ */ +/* $Id: validator.h,v 1.39.52.3.2.2 2010/02/25 10:56:02 tbox Exp $ */ #ifndef DNS_VALIDATOR_H #define DNS_VALIDATOR_H 1 @@ -151,6 +151,8 @@ struct dns_validator { isc_boolean_t mustbesecure; unsigned int dlvlabels; unsigned int depth; + unsigned int authcount; + unsigned int authfail; }; /*% diff --git a/contrib/bind/lib/dns/ncache.c b/contrib/bind/lib/dns/ncache.c index a779e01cac..e9c0caa86b 100644 --- a/contrib/bind/lib/dns/ncache.c +++ b/contrib/bind/lib/dns/ncache.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: ncache.c,v 1.41 2007/06/19 23:47:16 tbox Exp $ */ +/* $Id: ncache.c,v 1.41.288.2 2010/02/25 10:56:01 tbox Exp $ */ /*! \file */ @@ -478,6 +478,8 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind/lib/dns/rbtdb.c b/contrib/bind/lib/dns/rbtdb.c index 91ced3ec81..6c54a87302 100644 --- a/contrib/bind/lib/dns/rbtdb.c +++ b/contrib/bind/lib/dns/rbtdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.248.12.18.2.2 2009/12/31 21:45:53 each Exp $ */ +/* $Id: rbtdb.c,v 1.248.12.18.2.5 2010/02/26 00:26:54 marka Exp $ */ /*! \file */ @@ -497,6 +497,8 @@ static void expire_header(dns_rbtdb_t *rbtdb, rdatasetheader_t *header, static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start, isc_stdtime_t now, isc_boolean_t tree_locked); static void prune_tree(isc_task_t *task, isc_event_t *event); +static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust); +static void rdataset_expire(dns_rdataset_t *rdataset); static dns_rdatasetmethods_t rdataset_methods = { rdataset_disassociate, @@ -509,7 +511,9 @@ static dns_rdatasetmethods_t rdataset_methods = { rdataset_getnoqname, rdataset_getadditional, rdataset_setadditional, - rdataset_putadditional + rdataset_putadditional, + rdataset_settrust, + rdataset_expire }; static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp); @@ -6548,6 +6552,34 @@ rdataset_getnoqname(dns_rdataset_t *rdataset, dns_name_t *name, return (ISC_R_SUCCESS); } +static void +rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + rdatasetheader_t *header = rdataset->private3; + + header--; + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); + header->trust = rdataset->trust = trust; + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); +} + +static void +rdataset_expire(dns_rdataset_t *rdataset) { + dns_rbtdb_t *rbtdb = rdataset->private1; + dns_rbtnode_t *rbtnode = rdataset->private2; + rdatasetheader_t *header = rdataset->private3; + + header--; + NODE_LOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); + expire_header(rbtdb, header, ISC_FALSE); + NODE_UNLOCK(&rbtdb->node_locks[rbtnode->locknum].lock, + isc_rwlocktype_write); +} + /* * Rdataset Iterator Methods */ diff --git a/contrib/bind/lib/dns/rdatalist.c b/contrib/bind/lib/dns/rdatalist.c index 836d997493..2c855292e4 100644 --- a/contrib/bind/lib/dns/rdatalist.c +++ b/contrib/bind/lib/dns/rdatalist.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2008, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdatalist.c,v 1.33.128.2 2008/04/03 06:08:27 tbox Exp $ */ +/* $Id: rdatalist.c,v 1.33.128.2.28.2 2010/02/25 10:56:01 tbox Exp $ */ /*! \file */ @@ -43,6 +43,8 @@ static dns_rdatasetmethods_t methods = { isc__rdatalist_getnoqname, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind/lib/dns/rdataset.c b/contrib/bind/lib/dns/rdataset.c index ea2d90f005..142438ed17 100644 --- a/contrib/bind/lib/dns/rdataset.c +++ b/contrib/bind/lib/dns/rdataset.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataset.c,v 1.79.128.2 2009/01/19 23:47:02 tbox Exp $ */ +/* $Id: rdataset.c,v 1.79.128.2.2.2 2010/02/25 10:56:01 tbox Exp $ */ /*! \file */ @@ -179,6 +179,8 @@ static dns_rdatasetmethods_t question_methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; @@ -707,3 +709,22 @@ dns_rdataset_putadditional(dns_acache_t *acache, return (ISC_R_FAILURE); } +void +dns_rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) { + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (rdataset->methods->settrust != NULL) + (rdataset->methods->settrust)(rdataset, trust); + else + rdataset->trust = trust; +} + +void +dns_rdataset_expire(dns_rdataset_t *rdataset) { + REQUIRE(DNS_RDATASET_VALID(rdataset)); + REQUIRE(rdataset->methods != NULL); + + if (rdataset->methods->expire != NULL) + (rdataset->methods->expire)(rdataset); +} diff --git a/contrib/bind/lib/dns/rdataslab.c b/contrib/bind/lib/dns/rdataslab.c index 28d95c94d7..48dc0e0e4d 100644 --- a/contrib/bind/lib/dns/rdataslab.c +++ b/contrib/bind/lib/dns/rdataslab.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rdataslab.c,v 1.43.128.4 2009/01/19 23:47:02 tbox Exp $ */ +/* $Id: rdataslab.c,v 1.43.128.4.2.2 2010/02/25 10:56:01 tbox Exp $ */ /*! \file */ @@ -401,6 +401,8 @@ static dns_rdatasetmethods_t rdataset_methods = { NULL, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind/lib/dns/resolver.c b/contrib/bind/lib/dns/resolver.c index 82fbafb281..429fa46ce0 100644 --- a/contrib/bind/lib/dns/resolver.c +++ b/contrib/bind/lib/dns/resolver.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.355.12.44.2.2 2010/01/07 17:19:22 each Exp $ */ +/* $Id: resolver.c,v 1.355.12.44.2.5 2010/02/25 10:56:01 tbox Exp $ */ /*! \file */ @@ -328,6 +328,18 @@ typedef struct alternate { ISC_LINK(struct alternate) link; } alternate_t; +typedef struct dns_badcache dns_badcache_t; +struct dns_badcache { + dns_badcache_t * next; + dns_rdatatype_t type; + isc_time_t expire; + unsigned int hashval; + dns_name_t name; +}; +#define DNS_BADCACHE_SIZE 1021 +#define DNS_BADCACHE_TTL(fctx) \ + (((fctx)->res->lame_ttl > 30 ) ? (fctx)->res->lame_ttl : 30) + struct dns_resolver { /* Unlocked. */ unsigned int magic; @@ -374,6 +386,13 @@ struct dns_resolver { isc_boolean_t priming; unsigned int spillat; /* clients-per-query */ unsigned int nextdisp; + + /* Bad cache. */ + dns_badcache_t ** badcache; + unsigned int badcount; + unsigned int badhash; + unsigned int badsweep; + /* Locked by primelock. */ dns_fetch_t * primefetch; /* Locked by nlock. */ @@ -401,7 +420,8 @@ static void empty_bucket(dns_resolver_t *res); static isc_result_t resquery_send(resquery_t *query); static void resquery_response(isc_task_t *task, isc_event_t *event); static void resquery_connected(isc_task_t *task, isc_event_t *event); -static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying); +static void fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, + isc_boolean_t badcache); static isc_boolean_t fctx_destroy(fetchctx_t *fctx); static isc_result_t ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node, @@ -1153,7 +1173,7 @@ process_sendevent(resquery_t *query, isc_event_t *event) { if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } } @@ -2050,7 +2070,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } } @@ -2112,7 +2132,7 @@ fctx_finddone(isc_task_t *task, isc_event_t *event) { dns_adb_destroyfind(&find); if (want_try) - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); else if (want_done) fctx_done(fctx, ISC_R_FAILURE, __LINE__); else if (bucket_empty) @@ -2475,7 +2495,7 @@ isstrictsubdomain(dns_name_t *name1, dns_name_t *name2) { } static isc_result_t -fctx_getaddresses(fetchctx_t *fctx) { +fctx_getaddresses(fetchctx_t *fctx, isc_boolean_t badcache) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; dns_resolver_t *res; @@ -2694,12 +2714,24 @@ fctx_getaddresses(fetchctx_t *fctx) { */ result = DNS_R_WAIT; } else { + isc_time_t expire; + isc_interval_t i; /* * We've lost completely. We don't know any * addresses, and the ADB has told us it can't get * them. */ FCTXTRACE("no addresses"); + isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); + result = isc_time_nowplusinterval(&expire, &i); + if (badcache && + (fctx->type == dns_rdatatype_dnskey || + fctx->type == dns_rdatatype_dlv || + fctx->type == dns_rdatatype_ds) && + result == ISC_R_SUCCESS) + dns_resolver_addbadcache(fctx->res, + &fctx->name, + fctx->type, &expire); result = ISC_R_FAILURE; } } else { @@ -2921,7 +2953,7 @@ fctx_nextaddress(fetchctx_t *fctx) { } static void -fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) { +fctx_try(fetchctx_t *fctx, isc_boolean_t retrying, isc_boolean_t badcache) { isc_result_t result; dns_adbaddrinfo_t *addrinfo; @@ -2939,7 +2971,7 @@ fctx_try(fetchctx_t *fctx, isc_boolean_t retrying) { fctx_cleanupaltfinds(fctx); fctx_cleanupforwaddrs(fctx); fctx_cleanupaltaddrs(fctx); - result = fctx_getaddresses(fctx); + result = fctx_getaddresses(fctx, badcache); if (result == DNS_R_WAIT) { /* * Sleep waiting for addresses. @@ -3104,7 +3136,7 @@ fctx_timeout(isc_task_t *task, isc_event_t *event) { /* * Keep trying. */ - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } isc_event_free(&event); @@ -3274,7 +3306,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) { if (result != ISC_R_SUCCESS) fctx_done(fctx, result, __LINE__); else - fctx_try(fctx, ISC_FALSE); + fctx_try(fctx, ISC_FALSE, ISC_FALSE); } else if (bucket_empty) empty_bucket(res); } @@ -3850,6 +3882,8 @@ validated(isc_task_t *task, isc_event_t *event) { LOCK(&fctx->res->buckets[fctx->bucketnum].lock); + isc_stdtime_get(&now); + /* * If chaining, we need to make sure that the right result code is * returned, and that the rdatasets are bound. @@ -3896,35 +3930,80 @@ validated(isc_task_t *task, isc_event_t *event) { inc_stats(fctx->res, dns_resstatscounter_valfail); fctx->valfail++; fctx->vresult = vevent->result; - result = ISC_R_NOTFOUND; - if (vevent->rdataset != NULL) - result = dns_db_findnode(fctx->cache, vevent->name, - ISC_TRUE, &node); - if (result == ISC_R_SUCCESS) - (void)dns_db_deleterdataset(fctx->cache, node, NULL, - vevent->type, 0); - 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; + if (fctx->vresult != DNS_R_BROKENCHAIN) { + result = ISC_R_NOTFOUND; + if (vevent->rdataset != NULL) + result = dns_db_findnode(fctx->cache, + vevent->name, + ISC_TRUE, &node); + if (result == ISC_R_SUCCESS) + (void)dns_db_deleterdataset(fctx->cache, node, + NULL, + vevent->type, 0); + 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); + } + if (fctx->vresult == DNS_R_BROKENCHAIN && !negative) { + /* + * Cache the data as pending for later validation. + */ + result = ISC_R_NOTFOUND; + if (vevent->rdataset != NULL) + result = dns_db_findnode(fctx->cache, + vevent->name, + ISC_TRUE, &node); + if (result == ISC_R_SUCCESS) { + (void)dns_db_addrdataset(fctx->cache, node, + NULL, now, + vevent->rdataset, 0, + NULL); + } + if (result == ISC_R_SUCCESS && + vevent->sigrdataset != NULL) + (void)dns_db_addrdataset(fctx->cache, node, + NULL, now, + vevent->sigrdataset, + 0, NULL); + if (result == ISC_R_SUCCESS) + dns_db_detachnode(fctx->cache, &node); + } + result = fctx->vresult; add_bad(fctx, addrinfo, result, badns_validation); isc_event_free(&event); UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock); INSIST(fctx->validator == NULL); fctx->validator = ISC_LIST_HEAD(fctx->validators); - if (fctx->validator != NULL) { + if (fctx->validator != NULL) dns_validator_send(fctx->validator); - } else if (sentresponse) + else if (sentresponse) fctx_done(fctx, result, __LINE__); /* Locks bucket. */ - else - fctx_try(fctx, ISC_TRUE); /* Locks bucket. */ + else if (result == DNS_R_BROKENCHAIN) { + isc_result_t tresult; + isc_time_t expire; + isc_interval_t i; + + isc_interval_set(&i, DNS_BADCACHE_TTL(fctx), 0); + tresult = isc_time_nowplusinterval(&expire, &i); + if (negative && + (fctx->type == dns_rdatatype_dnskey || + fctx->type == dns_rdatatype_dlv || + fctx->type == dns_rdatatype_ds) && + tresult == ISC_R_SUCCESS) + dns_resolver_addbadcache(fctx->res, + &fctx->name, + fctx->type, &expire); + fctx_done(fctx, result, __LINE__); /* Locks bucket. */ + } else + fctx_try(fctx, ISC_TRUE, ISC_TRUE); /* Locks bucket. */ return; } - isc_stdtime_get(&now); if (negative) { dns_rdatatype_t covers; @@ -5703,7 +5782,7 @@ resume_dslookup(isc_task_t *task, isc_event_t *event) { /* * Try again. */ - fctx_try(fctx, ISC_TRUE); + fctx_try(fctx, ISC_TRUE, ISC_FALSE); } else { unsigned int n; dns_rdataset_t *nsrdataset = NULL; @@ -6542,7 +6621,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) { /* * Try again. */ - fctx_try(fctx, !get_nameservers); + fctx_try(fctx, !get_nameservers, ISC_FALSE); } else if (resend) { /* * Resend (probably with changed options). @@ -6604,6 +6683,27 @@ resquery_response(isc_task_t *task, isc_event_t *event) { /*** *** Resolver Methods ***/ +static void +destroy_badcache(dns_resolver_t *res) { + dns_badcache_t *bad, *next; + unsigned int i; + + if (res->badcache != NULL) { + for (i = 0; i < res->badhash; i++) + for (bad = res->badcache[i]; bad != NULL; + bad = next) { + next = bad->next; + isc_mem_put(res->mctx, bad, sizeof(*bad) + + bad->name.length); + res->badcount--; + } + isc_mem_put(res->mctx, res->badcache, + sizeof(*res->badcache) * res->badhash); + res->badcache = NULL; + res->badhash = 0; + INSIST(res->badcount == 0); + } +} static void destroy(dns_resolver_t *res) { @@ -6641,6 +6741,7 @@ destroy(dns_resolver_t *res) { isc_mem_put(res->mctx, a, sizeof(*a)); } dns_resolver_reset_algorithms(res); + destroy_badcache(res); dns_resolver_resetmustbesecure(res); #if USE_ALGLOCK isc_rwlock_destroy(&res->alglock); @@ -6764,6 +6865,10 @@ dns_resolver_create(dns_view_t *view, ISC_LIST_INIT(res->alternates); res->udpsize = RECV_BUFFER_SIZE; res->algorithms = NULL; + res->badcache = NULL; + res->badcount = 0; + res->badhash = 0; + res->badsweep = 0; res->mustbesecure = NULL; res->spillatmin = res->spillat = 10; res->spillatmax = 100; @@ -7605,6 +7710,256 @@ dns_resolver_getudpsize(dns_resolver_t *resolver) { return (resolver->udpsize); } +void +dns_resolver_flushbadcache(dns_resolver_t *resolver, dns_name_t *name) { + unsigned int i; + dns_badcache_t *bad, *prev, *next; + + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + if (resolver->badcache == NULL) + goto unlock; + + if (name != NULL) { + isc_time_t now; + isc_result_t result; + result = isc_time_now(&now); + if (result != ISC_R_SUCCESS) + isc_time_settoepoch(&now); + i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + int n; + next = bad->next; + n = isc_time_compare(&bad->expire, &now); + if (n < 0 || dns_name_equal(name, &bad->name)) { + if (prev == NULL) + resolver->badcache[i] = bad->next; + else + prev->next = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } else + prev = bad; + } + } else + destroy_badcache(resolver); + + unlock: + UNLOCK(&resolver->lock); + +} + +static void +resizehash(dns_resolver_t *resolver, isc_time_t *now, isc_boolean_t grow) { + unsigned int newsize; + dns_badcache_t **new, *bad, *next; + unsigned int i; + + if (grow) + newsize = resolver->badhash * 2 + 1; + else + newsize = (resolver->badhash - 1) / 2; + + new = isc_mem_get(resolver->mctx, + sizeof(*resolver->badcache) * newsize); + if (new == NULL) + return; + memset(new, 0, sizeof(*resolver->badcache) * newsize); + for (i = 0; i < resolver->badhash; i++) { + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + if (isc_time_compare(&bad->expire, now) < 0) { + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } else { + bad->next = new[bad->hashval % newsize]; + new[bad->hashval % newsize] = bad; + } + } + } + isc_mem_put(resolver->mctx, resolver->badcache, + sizeof(*resolver->badcache) * resolver->badhash); + resolver->badhash = newsize; + resolver->badcache = new; +} + +void +dns_resolver_addbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *expire) +{ + isc_time_t now; + isc_result_t result = ISC_R_SUCCESS; + unsigned int i, hashval; + dns_badcache_t *bad, *prev, *next; + + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + if (resolver->badcache == NULL) { + resolver->badcache = isc_mem_get(resolver->mctx, + sizeof(*resolver->badcache) * + DNS_BADCACHE_SIZE); + if (resolver->badcache == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + resolver->badhash = DNS_BADCACHE_SIZE; + memset(resolver->badcache, 0, sizeof(*resolver->badcache) * + resolver->badhash); + } + + result = isc_time_now(&now); + if (result != ISC_R_SUCCESS) + isc_time_settoepoch(&now); + hashval = dns_name_hash(name, ISC_FALSE); + i = hashval % resolver->badhash; + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + if (bad->type == type && dns_name_equal(name, &bad->name)) + break; + if (isc_time_compare(&bad->expire, &now) < 0) { + if (prev == NULL) + resolver->badcache[i] = bad->next; + else + prev->next = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } else + prev = bad; + } + if (bad == NULL) { + isc_buffer_t buffer; + bad = isc_mem_get(resolver->mctx, sizeof(*bad) + name->length); + if (bad == NULL) { + result = ISC_R_NOMEMORY; + goto cleanup; + } + bad->type = type; + bad->hashval = hashval; + isc_buffer_init(&buffer, bad + 1, name->length); + dns_name_init(&bad->name, NULL); + dns_name_copy(name, &bad->name, &buffer); + bad->next = resolver->badcache[i]; + resolver->badcache[i] = bad; + resolver->badcount++; + if (resolver->badcount > resolver->badhash * 8) + resizehash(resolver, &now, ISC_TRUE); + if (resolver->badcount < resolver->badhash * 2 && + resolver->badhash > DNS_BADCACHE_SIZE) + resizehash(resolver, &now, ISC_FALSE); + } + bad->expire = *expire; + cleanup: + UNLOCK(&resolver->lock); +} + +isc_boolean_t +dns_resolver_getbadcache(dns_resolver_t *resolver, dns_name_t *name, + dns_rdatatype_t type, isc_time_t *now) +{ + dns_badcache_t *bad, *prev, *next; + isc_boolean_t answer = ISC_FALSE; + unsigned int i; + + REQUIRE(VALID_RESOLVER(resolver)); + + LOCK(&resolver->lock); + if (resolver->badcache == NULL) + goto unlock; + + i = dns_name_hash(name, ISC_FALSE) % resolver->badhash; + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + /* + * Search the hash list. Clean out expired records as we go. + */ + if (isc_time_compare(&bad->expire, now) < 0) { + if (prev != NULL) + prev->next = bad->next; + else + resolver->badcache[i] = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + continue; + } + if (bad->type == type && dns_name_equal(name, &bad->name)) { + answer = ISC_TRUE; + break; + } + prev = bad; + } + + /* + * Slow sweep to clean out stale records. + */ + i = resolver->badsweep++ % resolver->badhash; + bad = resolver->badcache[i]; + if (bad != NULL && isc_time_compare(&bad->expire, now) < 0) { + resolver->badcache[i] = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + } + + unlock: + UNLOCK(&resolver->lock); + return (answer); +} + +void +dns_resolver_printbadcache(dns_resolver_t *resolver, FILE *fp) { + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; + dns_badcache_t *bad, *next, *prev; + isc_time_t now; + unsigned int i; + isc_uint64_t t; + + LOCK(&resolver->lock); + fprintf(fp, ";\n; Bad cache\n;\n"); + + if (resolver->badcache == NULL) + goto unlock; + + TIME_NOW(&now); + for (i = 0; i < resolver->badhash; i++) { + prev = NULL; + for (bad = resolver->badcache[i]; bad != NULL; bad = next) { + next = bad->next; + if (isc_time_compare(&bad->expire, &now) < 0) { + if (prev != NULL) + prev->next = bad->next; + else + resolver->badcache[i] = bad->next; + isc_mem_put(resolver->mctx, bad, sizeof(*bad) + + bad->name.length); + resolver->badcount--; + continue; + } + prev = bad; + dns_name_format(&bad->name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(bad->type, typebuf, + sizeof(typebuf)); + t = isc_time_microdiff(&bad->expire, &now); + t /= 1000; + fprintf(fp, "; %s/%s [ttl " + "%" ISC_PLATFORM_QUADFORMAT "u]\n", + namebuf, typebuf, t); + } + } + + unlock: + UNLOCK(&resolver->lock); +} + static void free_algorithm(void *node, void *arg) { unsigned char *algorithms = node; diff --git a/contrib/bind/lib/dns/result.c b/contrib/bind/lib/dns/result.c index 2e060542fa..0d433dca23 100644 --- a/contrib/bind/lib/dns/result.c +++ b/contrib/bind/lib/dns/result.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004, 2005, 2007, 2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1998-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: result.c,v 1.123 2007/06/19 23:47:16 tbox Exp $ */ +/* $Id: result.c,v 1.123.288.2 2010/02/25 10:56:02 tbox Exp $ */ /*! \file */ @@ -155,7 +155,11 @@ static const char *text[DNS_R_NRESULTS] = { "must-be-secure", /*%< 100 DNS_R_MUSTBESECURE */ "covering NSEC record returned", /*%< 101 DNS_R_COVERINGNSEC */ "MX is an address", /*%< 102 DNS_R_MXISADDRESS */ - "duplicate query" /*%< 103 DNS_R_DUPLICATE */ + "duplicate query", /*%< 103 DNS_R_DUPLICATE */ + "invalid NSEC3 owner name (wildcard)", /*%< 104 DNS_R_INVALIDNSEC3 */ + + "not master", /*%< 105 DNS_R_NOTMASTER */ + "broken trust chain", /*%< 106 DNS_R_BROKENCHAIN */ }; static const char *rcode_text[DNS_R_NRCODERESULTS] = { diff --git a/contrib/bind/lib/dns/sdb.c b/contrib/bind/lib/dns/sdb.c index 1c80f97f25..5bf888d2f0 100644 --- a/contrib/bind/lib/dns/sdb.c +++ b/contrib/bind/lib/dns/sdb.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000, 2001, 2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdb.c,v 1.59.94.8 2009/06/26 06:23:47 marka Exp $ */ +/* $Id: sdb.c,v 1.59.94.8.2.2 2010/02/25 10:56:02 tbox Exp $ */ /*! \file */ @@ -1376,6 +1376,8 @@ static dns_rdatasetmethods_t methods = { isc__rdatalist_getnoqname, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind/lib/dns/sdlz.c b/contrib/bind/lib/dns/sdlz.c index 11993939bc..60fe69bd9e 100644 --- a/contrib/bind/lib/dns/sdlz.c +++ b/contrib/bind/lib/dns/sdlz.c @@ -1,5 +1,5 @@ /* - * Portions Copyright (C) 2005-2009 Internet Systems Consortium, Inc. ("ISC") + * Portions Copyright (C) 2005-2010 Internet Systems Consortium, Inc. ("ISC") * Portions Copyright (C) 1999-2001 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -50,7 +50,7 @@ * USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: sdlz.c,v 1.14.94.6 2009/06/26 06:23:47 marka Exp $ */ +/* $Id: sdlz.c,v 1.14.94.6.2.2 2010/02/25 10:56:02 tbox Exp $ */ /*! \file */ @@ -1200,6 +1200,8 @@ static dns_rdatasetmethods_t rdataset_methods = { isc__rdatalist_getnoqname, NULL, NULL, + NULL, + NULL, NULL }; diff --git a/contrib/bind/lib/dns/validator.c b/contrib/bind/lib/dns/validator.c index 937da6688f..756da8fe21 100644 --- a/contrib/bind/lib/dns/validator.c +++ b/contrib/bind/lib/dns/validator.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 2000-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: validator.c,v 1.155.52.14.2.2 2009/12/31 21:02:44 each Exp $ */ +/* $Id: validator.c,v 1.155.52.14.2.4 2010/02/25 10:56:02 tbox Exp $ */ #include @@ -168,9 +168,16 @@ static inline void markanswer(dns_validator_t *val) { validator_log(val, ISC_LOG_DEBUG(3), "marking as answer"); if (val->event->rdataset != NULL) - val->event->rdataset->trust = dns_trust_answer; + dns_rdataset_settrust(val->event->rdataset, dns_trust_answer); if (val->event->sigrdataset != NULL) - val->event->sigrdataset->trust = dns_trust_answer; + dns_rdataset_settrust(val->event->sigrdataset, + dns_trust_answer); +} + +static inline void +marksecure(dns_validatorevent_t *event) { + dns_rdataset_settrust(event->rdataset, dns_trust_secure); + dns_rdataset_settrust(event->sigrdataset, dns_trust_secure); } static void @@ -335,7 +342,7 @@ fetch_callback_validator(isc_task_t *task, isc_event_t *event) { if (eresult == ISC_R_CANCELED) validator_done(val, eresult); else - validator_done(val, DNS_R_NOVALIDKEY); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -405,7 +412,7 @@ dsfetched(isc_task_t *task, isc_event_t *event) { if (eresult == ISC_R_CANCELED) validator_done(val, eresult); else - validator_done(val, DNS_R_NOVALIDDS); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -545,10 +552,16 @@ keyvalidated(isc_task_t *task, isc_event_t *event) { if (result != DNS_R_WAIT) validator_done(val, result); } else { + if (eresult != DNS_R_BROKENCHAIN) { + if (dns_rdataset_isassociated(&val->frdataset)) + dns_rdataset_expire(&val->frdataset); + if (dns_rdataset_isassociated(&val->fsigrdataset)) + dns_rdataset_expire(&val->fsigrdataset); + } validator_log(val, ISC_LOG_DEBUG(3), "keyvalidated: got %s", isc_result_totext(eresult)); - validator_done(val, eresult); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -595,10 +608,16 @@ dsvalidated(isc_task_t *task, isc_event_t *event) { if (result != DNS_R_WAIT) validator_done(val, result); } else { + if (eresult != DNS_R_BROKENCHAIN) { + if (dns_rdataset_isassociated(&val->frdataset)) + dns_rdataset_expire(&val->frdataset); + if (dns_rdataset_isassociated(&val->fsigrdataset)) + dns_rdataset_expire(&val->fsigrdataset); + } validator_log(val, ISC_LOG_DEBUG(3), "dsvalidated: got %s", isc_result_totext(eresult)); - validator_done(val, eresult); + validator_done(val, DNS_R_BROKENCHAIN); } want_destroy = exit_check(val); UNLOCK(&val->lock); @@ -800,6 +819,8 @@ authvalidated(isc_task_t *task, isc_event_t *event) { validator_log(val, ISC_LOG_DEBUG(3), "authvalidated: got %s", isc_result_totext(result)); + if (result == DNS_R_BROKENCHAIN) + val->authfail++; if (result == ISC_R_CANCELED) validator_done(val, result); else { @@ -865,6 +886,7 @@ authvalidated(isc_task_t *task, isc_event_t *event) { * \li DNS_R_NCACHENXRRSET * \li DNS_R_NXRRSET * \li DNS_R_NXDOMAIN + * \li DNS_R_BROKENCHAIN */ static inline isc_result_t view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { @@ -874,9 +896,12 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { dns_rdata_t rdata = DNS_RDATA_INIT; isc_result_t result; unsigned int options; + isc_time_t now; char buf1[DNS_NAME_FORMATSIZE]; char buf2[DNS_NAME_FORMATSIZE]; char buf3[DNS_NAME_FORMATSIZE]; + char namebuf[DNS_NAME_FORMATSIZE]; + char typebuf[DNS_RDATATYPE_FORMATSIZE]; if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); @@ -886,6 +911,16 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { if (val->view->zonetable == NULL) return (ISC_R_CANCELED); + if (isc_time_now(&now) == ISC_R_SUCCESS && + dns_resolver_getbadcache(val->view->resolver, name, type, &now)) { + + dns_name_format(name, namebuf, sizeof(namebuf)); + dns_rdatatype_format(type, typebuf, sizeof(typebuf)); + validator_log(val, ISC_LOG_INFO, "bad cache hit (%s/%s)", + namebuf, typebuf); + return (DNS_R_BROKENCHAIN); + } + options = DNS_DBFIND_PENDINGOK; if (type == dns_rdatatype_dlv) options |= DNS_DBFIND_COVERINGNSEC; @@ -894,6 +929,7 @@ view_find(dns_validator_t *val, dns_name_t *name, dns_rdatatype_t type) { result = dns_view_find(val->view, name, type, 0, options, ISC_FALSE, NULL, NULL, foundname, &val->frdataset, &val->fsigrdataset); + if (result == DNS_R_NXDOMAIN) { if (dns_rdataset_isassociated(&val->frdataset)) dns_rdataset_disassociate(&val->frdataset); @@ -1238,7 +1274,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { /* * We don't know anything about this key. */ - result = create_fetch(val, &siginfo->signer, dns_rdatatype_dnskey, + result = create_fetch(val, &siginfo->signer, + dns_rdatatype_dnskey, fetch_callback_validator, "get_key"); if (result != ISC_R_SUCCESS) return (result); @@ -1253,7 +1290,8 @@ get_key(dns_validator_t *val, dns_rdata_rrsig_t *siginfo) { * This key doesn't exist. */ result = DNS_R_CONTINUE; - } + } else if (result == DNS_R_BROKENCHAIN) + return (result); if (dns_rdataset_isassociated(&val->frdataset) && val->keyset != &val->frdataset) @@ -1501,8 +1539,7 @@ validate(dns_validator_t *val, isc_boolean_t resume) { "looking for noqname proof"); return (nsecvalidate(val, ISC_FALSE)); } else if (result == ISC_R_SUCCESS) { - event->rdataset->trust = dns_trust_secure; - event->sigrdataset->trust = dns_trust_secure; + marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); return (result); @@ -1678,8 +1715,7 @@ dlv_validatezonekey(dns_validator_t *val) { "no RRSIG matching DLV key"); } if (result == ISC_R_SUCCESS) { - val->event->rdataset->trust = dns_trust_secure; - val->event->sigrdataset->trust = dns_trust_secure; + marksecure(val->event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); return (result); } else if (result == ISC_R_NOMORE && !supported_algorithm) { @@ -1780,8 +1816,7 @@ validatezonekey(dns_validator_t *val) { keynode = nextnode; } if (result == ISC_R_SUCCESS) { - event->rdataset->trust = dns_trust_secure; - event->sigrdataset->trust = dns_trust_secure; + marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "signed by trusted key; " "marking as secure"); @@ -1808,11 +1843,14 @@ validatezonekey(dns_validator_t *val) { */ dns_name_format(val->event->name, namebuf, sizeof(namebuf)); - validator_log(val, ISC_LOG_DEBUG(2), + validator_log(val, ISC_LOG_NOTICE, "unable to find a DNSKEY which verifies " "the DNSKEY RRset and also matches one " "of specified trusted-keys for '%s'", namebuf); + validator_log(val, ISC_LOG_NOTICE, + "please check the 'trusted-keys' for " + "'%s' in named.conf.", namebuf); return (DNS_R_NOVALIDKEY); } @@ -1873,7 +1911,8 @@ validatezonekey(dns_validator_t *val) { dns_rdataset_disassociate(&val->fsigrdataset); validator_log(val, ISC_LOG_DEBUG(2), "no DS record"); return (DNS_R_NOVALIDSIG); - } + } else if (result == DNS_R_BROKENCHAIN) + return (result); } /* @@ -2022,8 +2061,7 @@ validatezonekey(dns_validator_t *val) { "no RRSIG matching DS key"); } if (result == ISC_R_SUCCESS) { - event->rdataset->trust = dns_trust_secure; - event->sigrdataset->trust = dns_trust_secure; + marksecure(event); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); return (result); } else if (result == ISC_R_NOMORE && !supported_algorithm) { @@ -2229,6 +2267,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { "nsecvalidate"); if (result != ISC_R_SUCCESS) return (result); + val->authcount++; return (DNS_R_WAIT); } @@ -2250,8 +2289,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { "noqname proof found"); validator_log(val, ISC_LOG_DEBUG(3), "marking as secure"); - val->event->rdataset->trust = dns_trust_secure; - val->event->sigrdataset->trust = dns_trust_secure; + marksecure(val->event); return (ISC_R_SUCCESS); } validator_log(val, ISC_LOG_DEBUG(3), @@ -2282,6 +2320,8 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) { return (ISC_R_SUCCESS); } + if (val->authcount == val->authfail) + return (DNS_R_BROKENCHAIN); validator_log(val, ISC_LOG_DEBUG(3), "nonexistence proof(s) not found"); val->attributes |= VALATTR_INSECURITY; @@ -2313,6 +2353,58 @@ check_ds(dns_validator_t *val, dns_name_t *name, dns_rdataset_t *rdataset) { return (ISC_FALSE); } +static void +dlvvalidated(isc_task_t *task, isc_event_t *event) { + dns_validatorevent_t *devent; + dns_validator_t *val; + isc_result_t eresult; + isc_boolean_t want_destroy; + + 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 dlvvalidated"); + LOCK(&val->lock); + if (CANCELED(val)) { + validator_done(val, ISC_R_CANCELED); + } else if (eresult == ISC_R_SUCCESS) { + validator_log(val, ISC_LOG_DEBUG(3), + "dlvset with trust %d", val->frdataset.trust); + dns_rdataset_clone(&val->frdataset, &val->dlv); + val->havedlvsep = ISC_TRUE; + if (dlv_algorithm_supported(val)) + dlv_validator_start(val); + else { + markanswer(val); + validator_done(val, ISC_R_SUCCESS); + } + } else { + if (eresult != DNS_R_BROKENCHAIN) { + if (dns_rdataset_isassociated(&val->frdataset)) + dns_rdataset_expire(&val->frdataset); + if (dns_rdataset_isassociated(&val->fsigrdataset)) + dns_rdataset_expire(&val->fsigrdataset); + } + validator_log(val, ISC_LOG_DEBUG(3), + "dlvvalidated: got %s", + isc_result_totext(eresult)); + validator_done(val, DNS_R_BROKENCHAIN); + } + want_destroy = exit_check(val); + UNLOCK(&val->lock); + if (want_destroy) + destroy(val); +} + /*% * Callback from fetching a DLV record. * @@ -2532,6 +2624,24 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { namebuf); result = view_find(val, dlvname, dns_rdatatype_dlv); if (result == ISC_R_SUCCESS) { + if (DNS_TRUST_PENDING(val->frdataset.trust) && + dns_rdataset_isassociated(&val->fsigrdataset)) + { + dns_fixedname_init(&val->fname); + dns_name_copy(dlvname, + dns_fixedname_name(&val->fname), + NULL); + result = create_validator(val, + dns_fixedname_name(&val->fname), + dns_rdatatype_dlv, + &val->frdataset, + &val->fsigrdataset, + dlvvalidated, + "finddlvsep"); + if (result != ISC_R_SUCCESS) + return (result); + return (DNS_R_WAIT); + } if (val->frdataset.trust < dns_trust_secure) return (DNS_R_NOVALIDSIG); val->havedlvsep = ISC_TRUE; @@ -2582,6 +2692,7 @@ finddlvsep(dns_validator_t *val, isc_boolean_t resume) { * \li DNS_R_NOVALIDSIG * \li DNS_R_NOVALIDNSEC * \li DNS_R_NOTINSECURE + * \li DNS_R_BROKENCHAIN */ static isc_result_t proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) @@ -2798,7 +2909,8 @@ proveunsecure(dns_validator_t *val, isc_boolean_t have_ds, isc_boolean_t resume) if (result != ISC_R_SUCCESS) goto out; return (DNS_R_WAIT); - } + } else if (result == DNS_R_BROKENCHAIN) + return (result); } validator_log(val, ISC_LOG_DEBUG(3), "insecurity proof failed"); return (DNS_R_NOTINSECURE); /* Couldn't complete insecurity proof */ @@ -3005,6 +3117,8 @@ dns_validator_create(dns_view_t *view, dns_name_t *name, dns_rdatatype_t type, val->seensig = ISC_FALSE; val->havedlvsep = ISC_FALSE; val->depth = 0; + val->authcount = 0; + val->authfail = 0; val->mustbesecure = dns_resolver_getmustbesecure(view->resolver, name); dns_rdataset_init(&val->frdataset); dns_rdataset_init(&val->fsigrdataset); diff --git a/contrib/bind/lib/dns/view.c b/contrib/bind/lib/dns/view.c index 5766cd5b40..08095b1bb6 100644 --- a/contrib/bind/lib/dns/view.c +++ b/contrib/bind/lib/dns/view.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC") + * Copyright (C) 2004-2010 Internet Systems Consortium, Inc. ("ISC") * Copyright (C) 1999-2003 Internet Software Consortium. * * Permission to use, copy, modify, and/or distribute this software for any @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: view.c,v 1.143.128.9 2009/01/29 23:47:13 tbox Exp $ */ +/* $Id: view.c,v 1.143.128.9.2.2 2010/02/25 10:56:02 tbox Exp $ */ /*! \file */ @@ -1270,10 +1270,11 @@ dns_view_dumpdbtostream(dns_view_t *view, FILE *fp) { (void)fprintf(fp, ";\n; Cache dump of view '%s'\n;\n", view->name); result = dns_master_dumptostream(view->mctx, view->cachedb, NULL, - &dns_master_style_cache, fp); + &dns_master_style_cache, fp); if (result != ISC_R_SUCCESS) return (result); dns_adb_dump(view->adb, fp); + dns_resolver_printbadcache(view->resolver, fp); return (ISC_R_SUCCESS); } @@ -1294,6 +1295,8 @@ dns_view_flushcache(dns_view_t *view) { dns_cache_attachdb(view->cache, &view->cachedb); if (view->acache != NULL) dns_acache_setdb(view->acache, view->cachedb); + if (view->resolver != NULL) + dns_resolver_flushbadcache(view->resolver, NULL); dns_adb_flush(view->adb); return (ISC_R_SUCCESS); @@ -1308,6 +1311,8 @@ dns_view_flushname(dns_view_t *view, dns_name_t *name) { dns_adb_flushname(view->adb, name); if (view->cache == NULL) return (ISC_R_SUCCESS); + if (view->resolver != NULL) + dns_resolver_flushbadcache(view->resolver, name); return (dns_cache_flushname(view->cache, name)); } diff --git a/contrib/bind/version b/contrib/bind/version index dadbc08b08..e0ff895e63 100644 --- a/contrib/bind/version +++ b/contrib/bind/version @@ -1,4 +1,4 @@ -# $Id: version,v 1.39.18.13.2.2 2009/12/31 21:02:44 each Exp $ +# $Id: version,v 1.39.18.13.2.3 2010/02/25 10:49:12 marka Exp $ # # This file must follow /bin/sh rules. It is imported directly via # configure. @@ -7,4 +7,4 @@ MAJORVER=9 MINORVER=5 PATCHVER=2 RELEASETYPE=-P -RELEASEVER=2 +RELEASEVER=3