2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619]

This commit is contained in:
Mark Andrews
2010-02-25 05:05:09 +00:00
parent 507806f969
commit 8a98023414
19 changed files with 689 additions and 73 deletions
+2
View File
@@ -1,3 +1,5 @@
2852. [bug] Handle broken DNSSEC trust chains better. [RT #15619]
2851. [doc] nslookup.1, removed <informalexample> from the docbook
source as it produced bad nroff. [RT #21007]
+3 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: server.c,v 1.556.8.6 2010/01/13 23:48:19 tbox Exp $ */
/* $Id: server.c,v 1.556.8.7 2010/02/25 05:05:07 marka Exp $ */
/*! \file */
@@ -5528,6 +5528,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) {
+8 -1
View File
@@ -18,7 +18,7 @@
- PERFORMANCE OF THIS SOFTWARE.
-->
<!-- File: $Id: Bv9ARM-book.xml,v 1.450.4.5 2010/02/03 01:32:43 each Exp $ -->
<!-- File: $Id: Bv9ARM-book.xml,v 1.450.4.6 2010/02/25 05:05:07 marka Exp $ -->
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<title>BIND 9 Administrator Reference Manual</title>
@@ -8176,6 +8176,13 @@ avoid-v6-udp-ports { 40000; range 50000 60000; };
<literal>1800</literal> (30 minutes).
</para>
<para>
Lame-ttl also controls the amount of time DNSSEC
validation failures are cached. There is a minimum
of 30 seconds applied to bad cache entries if the
lame-ttl is set to less than 30 seconds.
</para>
</listitem>
</varlistentry>
+13 -2
View File
@@ -14,7 +14,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: ecdb.c,v 1.4 2009/11/06 04:19:28 marka Exp $ */
/* $Id: ecdb.c,v 1.4.24.1 2010/02/25 05:05:08 marka Exp $ */
#include "config.h"
@@ -99,6 +99,7 @@ static isc_result_t rdataset_next(dns_rdataset_t *rdataset);
static void rdataset_current(dns_rdataset_t *rdataset, dns_rdata_t *rdata);
static void rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target);
static unsigned int rdataset_count(dns_rdataset_t *rdataset);
static void rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust);
static dns_rdatasetmethods_t rdataset_methods = {
rdataset_disassociate,
@@ -113,7 +114,9 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL, /* getclosest */
NULL, /* getadditional */
NULL, /* setadditional */
NULL /* putadditional */
NULL, /* putadditional */
rdataset_settrust, /* settrust */
NULL /* expire */
};
typedef struct ecdb_rdatasetiter {
@@ -736,6 +739,14 @@ rdataset_count(dns_rdataset_t *rdataset) {
return (count);
}
static void
rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
rdatasetheader_t *header = rdataset->private3;
header--;
header->trust = rdataset->trust = trust;
}
/*
* Rdataset Iterator Methods
*/
+17 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdataset.h,v 1.67 2009/01/17 23:47:43 tbox Exp $ */
/* $Id: rdataset.h,v 1.67.186.1 2010/02/25 05:05:09 marka Exp $ */
#ifndef DNS_RDATASET_H
#define DNS_RDATASET_H 1
@@ -110,6 +110,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')
@@ -634,6 +637,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 */
+43 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.h,v 1.64 2009/09/01 00:22:26 jinmei Exp $ */
/* $Id: resolver.h,v 1.64.104.1 2010/02/25 05:05:09 marka Exp $ */
#ifndef DNS_RESOLVER_H
#define DNS_RESOLVER_H 1
@@ -509,6 +509,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 <name,type> 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
* <name,type>.
*
* 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 */
+3 -2
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: result.h,v 1.118 2009/10/12 23:48:02 tbox Exp $ */
/* $Id: result.h,v 1.118.50.1 2010/02/25 05:05:09 marka Exp $ */
#ifndef DNS_RESULT_H
#define DNS_RESULT_H 1
@@ -149,8 +149,9 @@
#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 106 /*%< Number of results */
#define DNS_R_NRESULTS 107 /*%< Number of results */
/*
* DNS wire format rcodes.
+3 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: validator.h,v 1.44 2009/01/17 13:20:45 fdupont Exp $ */
/* $Id: validator.h,v 1.44.186.1 2010/02/25 05:05:09 marka Exp $ */
#ifndef DNS_VALIDATOR_H
#define DNS_VALIDATOR_H 1
@@ -159,6 +159,8 @@ struct dns_validator {
isc_boolean_t mustbesecure;
unsigned int dlvlabels;
unsigned int depth;
unsigned int authcount;
unsigned int authfail;
};
/*%
+3 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: ncache.c,v 1.43 2008/09/25 04:02:38 tbox Exp $ */
/* $Id: ncache.c,v 1.43.268.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -519,6 +519,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
+28 -2
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rbtdb.c,v 1.292.8.6 2010/01/04 23:48:10 tbox Exp $ */
/* $Id: rbtdb.c,v 1.292.8.7 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -522,6 +522,8 @@ static void overmem_purge(dns_rbtdb_t *rbtdb, unsigned int locknum_start,
static isc_result_t resign_insert(dns_rbtdb_t *rbtdb, int idx,
rdatasetheader_t *newheader);
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,
@@ -536,7 +538,9 @@ static dns_rdatasetmethods_t rdataset_methods = {
rdataset_getclosest,
rdataset_getadditional,
rdataset_setadditional,
rdataset_putadditional
rdataset_putadditional,
rdataset_settrust,
rdataset_expire
};
static void rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp);
@@ -7662,6 +7666,28 @@ rdataset_getclosest(dns_rdataset_t *rdataset, dns_name_t *name,
return (ISC_R_SUCCESS);
}
static void
rdataset_settrust(dns_rdataset_t *rdataset, dns_trust_t trust) {
rdatasetheader_t *header = rdataset->private3;
header--;
header->trust = rdataset->trust = trust;
}
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
*/
+3 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdatalist.c,v 1.36 2008/09/24 02:46:22 marka Exp $ */
/* $Id: rdatalist.c,v 1.36.270.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -46,6 +46,8 @@ static dns_rdatasetmethods_t methods = {
isc__rdatalist_getclosest,
NULL,
NULL,
NULL,
NULL,
NULL
};
+22 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdataset.c,v 1.84 2009/01/17 23:47:43 tbox Exp $ */
/* $Id: rdataset.c,v 1.84.186.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -182,6 +182,8 @@ static dns_rdatasetmethods_t question_methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
@@ -732,3 +734,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);
}
+3 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: rdataslab.c,v 1.50 2009/01/17 23:47:43 tbox Exp $ */
/* $Id: rdataslab.c,v 1.50.186.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -436,6 +436,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
+386 -31
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: resolver.c,v 1.413.14.2 2010/01/07 23:48:16 tbox Exp $ */
/* $Id: resolver.c,v 1.413.14.3 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -336,6 +336,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;
@@ -382,6 +394,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. */
@@ -412,7 +431,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,
@@ -1172,7 +1192,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);
}
}
@@ -2073,7 +2093,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);
}
}
@@ -2135,7 +2155,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)
@@ -2543,7 +2563,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;
@@ -2762,12 +2782,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 {
@@ -2990,7 +3022,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;
@@ -3008,7 +3040,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.
@@ -3173,7 +3205,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);
@@ -3343,7 +3375,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);
}
@@ -3965,6 +3997,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.
@@ -4011,35 +4045,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;
@@ -6102,7 +6181,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;
@@ -6981,7 +7060,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).
@@ -7043,6 +7122,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) {
@@ -7080,6 +7180,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);
@@ -7203,6 +7304,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;
@@ -8046,6 +8151,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;
+3 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: result.c,v 1.128 2009/10/12 20:48:12 each Exp $ */
/* $Id: result.c,v 1.128.50.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -157,7 +157,9 @@ static const char *text[DNS_R_NRESULTS] = {
"MX is an address", /*%< 102 DNS_R_MXISADDRESS */
"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] = {
+3 -1
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sdb.c,v 1.71 2009/10/08 23:13:07 marka Exp $ */
/* $Id: sdb.c,v 1.71.54.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -1387,6 +1387,8 @@ static dns_rdatasetmethods_t methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
+3 -1
View File
@@ -50,7 +50,7 @@
* USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: sdlz.c,v 1.22 2009/09/01 00:22:26 jinmei Exp $ */
/* $Id: sdlz.c,v 1.22.104.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -1211,6 +1211,8 @@ static dns_rdatasetmethods_t rdataset_methods = {
NULL,
NULL,
NULL,
NULL,
NULL,
NULL
};
+136 -22
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: validator.c,v 1.182.16.1 2009/12/30 06:46:36 each Exp $ */
/* $Id: validator.c,v 1.182.16.2 2010/02/25 05:05:08 marka Exp $ */
#include <config.h>
@@ -177,9 +177,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
@@ -425,7 +432,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);
@@ -495,7 +502,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);
@@ -636,10 +643,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);
@@ -686,10 +699,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);
@@ -1200,6 +1219,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 {
@@ -1272,6 +1293,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) {
@@ -1281,9 +1303,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);
@@ -1293,6 +1318,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;
@@ -1301,6 +1336,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);
@@ -1663,7 +1699,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);
@@ -1678,7 +1715,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)
@@ -1930,8 +1968,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, "
"noqname proof not needed");
@@ -2108,8 +2145,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 (dlv)");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
@@ -2219,8 +2255,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");
@@ -2252,11 +2287,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 a "
"trusted key for '%s'",
namebuf);
validator_log(val, ISC_LOG_NOTICE,
"please check the 'trusted-keys' for "
"'%s' in named.conf.", namebuf);
return (DNS_R_NOVALIDKEY);
}
@@ -2317,7 +2355,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);
}
/*
@@ -2467,8 +2506,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 (DS)");
return (result);
} else if (result == ISC_R_NOMORE && !supported_algorithm) {
@@ -2875,6 +2913,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
"nsecvalidate");
if (result != ISC_R_SUCCESS)
return (result);
val->authcount++;
return (DNS_R_WAIT);
}
@@ -2897,8 +2936,7 @@ nsecvalidate(dns_validator_t *val, isc_boolean_t resume) {
(val->attributes & VALATTR_FOUNDCLOSEST) != 0) {
validator_log(val, ISC_LOG_DEBUG(3),
"marking as secure, noqname proof found");
val->event->rdataset->trust = dns_trust_secure;
val->event->sigrdataset->trust = dns_trust_secure;
marksecure(val->event);
return (ISC_R_SUCCESS);
} else if ((val->attributes & VALATTR_FOUNDOPTOUT) != 0 &&
dns_name_countlabels(dns_fixedname_name(&val->wild))
@@ -2951,6 +2989,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;
@@ -2982,6 +3022,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.
*
@@ -3204,6 +3296,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) {
validator_log(val, ISC_LOG_DEBUG(3),
"DLV not validated");
@@ -3257,6 +3367,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)
@@ -3518,7 +3629,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);
}
/*
@@ -3744,6 +3856,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);
+7 -2
View File
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $Id: view.c,v 1.159 2009/11/28 15:57:37 vjs Exp $ */
/* $Id: view.c,v 1.159.8.1 2010/02/25 05:05:08 marka Exp $ */
/*! \file */
@@ -1325,10 +1325,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);
}
#endif
@@ -1360,6 +1361,8 @@ dns_view_flushcache2(dns_view_t *view, isc_boolean_t fixuponly) {
#ifdef BIND9
if (view->acache != NULL)
dns_acache_setdb(view->acache, view->cachedb);
if (view->resolver != NULL)
dns_resolver_flushbadcache(view->resolver, NULL);
#endif
dns_adb_flush(view->adb);
@@ -1375,6 +1378,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));
}