aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/bind9/lib/dns/resolver.c
diff options
context:
space:
mode:
authorDoug Barton <dougb@FreeBSD.org>2005-12-29 04:22:58 +0000
committerDoug Barton <dougb@FreeBSD.org>2005-12-29 04:22:58 +0000
commita00aca3467ce973cd6d2414c81fd5e39559374b3 (patch)
tree570b6e4f35462e81147786cc2f272d28fac7f470 /contrib/bind9/lib/dns/resolver.c
parentadaaaab975815edcabdc20da6c7f0ad57ca75402 (diff)
downloadsrc-a00aca3467ce973cd6d2414c81fd5e39559374b3.tar.gz
src-a00aca3467ce973cd6d2414c81fd5e39559374b3.zip
Vendor import of BIND 9.3.2
Notes
Notes: svn path=/vendor/bind9/dist/; revision=153816
Diffstat (limited to 'contrib/bind9/lib/dns/resolver.c')
-rw-r--r--contrib/bind9/lib/dns/resolver.c224
1 files changed, 142 insertions, 82 deletions
diff --git a/contrib/bind9/lib/dns/resolver.c b/contrib/bind9/lib/dns/resolver.c
index 790a2f41686f..6f803eb192f4 100644
--- a/contrib/bind9/lib/dns/resolver.c
+++ b/contrib/bind9/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.218.2.18.4.51 2005/02/08 23:59:44 marka Exp $ */
+/* $Id: resolver.c,v 1.218.2.18.4.56 2005/10/14 01:38:48 marka Exp $ */
#include <config.h>
@@ -244,6 +244,11 @@ struct fetchctx {
#define TRIEDFIND(f) (((f)->attributes & FCTX_ATTR_TRIEDFIND) != 0)
#define TRIEDALT(f) (((f)->attributes & FCTX_ATTR_TRIEDALT) != 0)
+typedef struct {
+ dns_adbaddrinfo_t * addrinfo;
+ fetchctx_t * fctx;
+} dns_valarg_t;
+
struct dns_fetch {
unsigned int magic;
fetchctx_t * private;
@@ -342,6 +347,35 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
isc_stdtime_t now, dns_ttl_t maxttl,
dns_rdataset_t *ardataset,
isc_result_t *eresultp);
+static void validated(isc_task_t *task, isc_event_t *event);
+
+static isc_result_t
+valcreate(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, dns_name_t *name,
+ dns_rdatatype_t type, dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset, unsigned int valoptions,
+ isc_task_t *task)
+{
+ dns_validator_t *validator = NULL;
+ dns_valarg_t *valarg;
+ isc_result_t result;
+
+ valarg = isc_mem_get(fctx->res->mctx, sizeof(*valarg));
+ if (valarg == NULL)
+ return (ISC_R_NOMEMORY);
+
+ valarg->fctx = fctx;
+ valarg->addrinfo = addrinfo;
+
+ result = dns_validator_create(fctx->res->view, name, type, rdataset,
+ sigrdataset, fctx->rmessage,
+ valoptions, task, validated, valarg,
+ &validator);
+ if (result == ISC_R_SUCCESS)
+ ISC_LIST_APPEND(fctx->validators, validator, link);
+ else
+ isc_mem_put(fctx->res->mctx, valarg, sizeof(*valarg));
+ return (result);
+}
static isc_boolean_t
fix_mustbedelegationornxdomain(dns_message_t *message, fetchctx_t *fctx) {
@@ -1424,6 +1458,7 @@ resquery_connected(isc_task_t *task, isc_event_t *event) {
case ISC_R_CONNREFUSED:
case ISC_R_NOPERM:
case ISC_R_ADDRNOTAVAIL:
+ case ISC_R_CONNECTIONRESET:
/*
* No route to remote.
*/
@@ -1855,7 +1890,6 @@ fctx_getaddresses(fetchctx_t *fctx) {
isc_boolean_t pruned, all_bad;
dns_rdata_ns_t ns;
isc_boolean_t need_alternate = ISC_FALSE;
- isc_boolean_t unshared;
FCTXTRACE("getaddresses");
@@ -1871,7 +1905,6 @@ fctx_getaddresses(fetchctx_t *fctx) {
res = fctx->res;
pruned = ISC_FALSE;
stdoptions = 0; /* Keep compiler happy. */
- unshared = ISC_TF((fctx->options | DNS_FETCHOPT_UNSHARED) != 0);
/*
* Forwarders.
@@ -2668,7 +2701,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
isc_result_t result;
isc_result_t iresult;
isc_interval_t interval;
- dns_fixedname_t qdomain;
+ dns_fixedname_t fixed;
unsigned int findoptions = 0;
char buf[DNS_NAME_FORMATSIZE + DNS_RDATATYPE_FORMATSIZE];
char typebuf[DNS_RDATATYPE_FORMATSIZE];
@@ -2747,8 +2780,10 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
dns_name_getlabelsequence(name, 1, labels - 1, &suffix);
name = &suffix;
}
- result = dns_fwdtable_find(fctx->res->view->fwdtable, name,
- &forwarders);
+ dns_fixedname_init(&fixed);
+ domain = dns_fixedname_name(&fixed);
+ result = dns_fwdtable_find2(fctx->res->view->fwdtable, name,
+ domain, &forwarders);
if (result == ISC_R_SUCCESS)
fctx->fwdpolicy = forwarders->fwdpolicy;
@@ -2760,27 +2795,22 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type,
*/
if (dns_rdatatype_atparent(type))
findoptions |= DNS_DBFIND_NOEXACT;
- dns_fixedname_init(&qdomain);
- result = dns_view_findzonecut(res->view, name,
- dns_fixedname_name(&qdomain), 0,
- findoptions, ISC_TRUE,
+ result = dns_view_findzonecut(res->view, name, domain,
+ 0, findoptions, ISC_TRUE,
&fctx->nameservers,
NULL);
if (result != ISC_R_SUCCESS)
goto cleanup_name;
- result = dns_name_dup(dns_fixedname_name(&qdomain),
- res->mctx, &fctx->domain);
+ result = dns_name_dup(domain, res->mctx, &fctx->domain);
if (result != ISC_R_SUCCESS) {
dns_rdataset_disassociate(&fctx->nameservers);
goto cleanup_name;
}
} else {
/*
- * We're in forward-only mode. Set the query domain
- * to ".".
+ * We're in forward-only mode. Set the query domain.
*/
- result = dns_name_dup(dns_rootname, res->mctx,
- &fctx->domain);
+ result = dns_name_dup(domain, res->mctx, &fctx->domain);
if (result != ISC_R_SUCCESS)
goto cleanup_name;
}
@@ -3090,11 +3120,15 @@ validated(isc_task_t *task, isc_event_t *event) {
dns_name_t *name;
dns_rdataset_t *rdataset;
dns_rdataset_t *sigrdataset;
+ dns_valarg_t *valarg;
+ dns_adbaddrinfo_t *addrinfo;
UNUSED(task); /* for now */
REQUIRE(event->ev_type == DNS_EVENT_VALIDATORDONE);
- fctx = event->ev_arg;
+ valarg = event->ev_arg;
+ fctx = valarg->fctx;
+ addrinfo = valarg->addrinfo;
REQUIRE(VALID_FCTX(fctx));
REQUIRE(!ISC_LIST_EMPTY(fctx->validators));
@@ -3109,6 +3143,7 @@ validated(isc_task_t *task, isc_event_t *event) {
* destroy the fctx if necessary.
*/
dns_validator_destroy(&vevent->validator);
+ isc_mem_put(fctx->res->mctx, valarg, sizeof(*valarg));
negative = ISC_TF(vevent->rdataset == NULL);
@@ -3166,21 +3201,27 @@ validated(isc_task_t *task, isc_event_t *event) {
if (vevent->result != ISC_R_SUCCESS) {
FCTXTRACE("validation failed");
- if (vevent->rdataset != NULL) {
+ result = ISC_R_NOTFOUND;
+ if (vevent->rdataset != NULL)
result = dns_db_findnode(fctx->cache, vevent->name,
ISC_TRUE, &node);
- if (result != ISC_R_SUCCESS)
- goto noanswer_response;
+ if (result == ISC_R_SUCCESS)
(void)dns_db_deleterdataset(fctx->cache, node, NULL,
vevent->type, 0);
- if (vevent->sigrdataset != NULL)
- (void)dns_db_deleterdataset(fctx->cache,
- node, NULL,
- dns_rdatatype_rrsig,
- vevent->type);
- }
+ 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;
- goto noanswer_response;
+ add_bad(fctx, &addrinfo->sockaddr, result);
+ isc_event_free(&event);
+ if (sentresponse)
+ fctx_done(fctx, result);
+ else
+ fctx_try(fctx);
+ return;
}
isc_stdtime_get(&now);
@@ -3350,7 +3391,8 @@ validated(isc_task_t *task, isc_event_t *event) {
}
static inline isc_result_t
-cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
+cache_name(fetchctx_t *fctx, dns_name_t *name, dns_adbaddrinfo_t *addrinfo,
+ isc_stdtime_t now) {
dns_rdataset_t *rdataset, *sigrdataset;
dns_rdataset_t *addedrdataset, *ardataset, *asigrdataset;
dns_rdataset_t *valrdataset = NULL, *valsigrdataset = NULL;
@@ -3363,8 +3405,8 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
dns_fetchevent_t *event;
unsigned int options;
isc_task_t *task;
- dns_validator_t *validator;
isc_boolean_t fail;
+ unsigned int valoptions = 0;
/*
* The appropriate bucket lock must be held.
@@ -3385,8 +3427,10 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
if (result != ISC_R_SUCCESS)
return (result);
- if (res->view->dlv != NULL)
+ if (!secure_domain && res->view->dlv != NULL) {
+ valoptions = DNS_VALIDATOR_DLV;
secure_domain = ISC_TRUE;
+ }
if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
need_validation = ISC_FALSE;
@@ -3437,7 +3481,7 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
/*
* Cache or validate each cacheable rdataset.
*/
- fail = (fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0;
+ fail = ISC_TF((fctx->res->options & DNS_RESOLVER_CHECKNAMESFAIL) != 0);
for (rdataset = ISC_LIST_HEAD(name->list);
rdataset != NULL;
rdataset = ISC_LIST_NEXT(rdataset, link)) {
@@ -3569,23 +3613,11 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
* having to remember which
* rdatasets needed validation.
*/
- validator = NULL;
- result = dns_validator_create(
- res->view,
- name,
- rdataset->type,
- rdataset,
- sigrdataset,
- fctx->rmessage,
- 0,
- task,
- validated,
- fctx,
- &validator);
- if (result == ISC_R_SUCCESS)
- ISC_LIST_APPEND(
- fctx->validators,
- validator, link);
+ result = valcreate(fctx, addrinfo,
+ name, rdataset->type,
+ rdataset,
+ sigrdataset,
+ valoptions, task);
}
} else if (CHAINING(rdataset)) {
if (rdataset->type == dns_rdatatype_cname)
@@ -3660,22 +3692,10 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
}
}
- if (valrdataset != NULL) {
- validator = NULL;
- result = dns_validator_create(res->view,
- name,
- fctx->type,
- valrdataset,
- valsigrdataset,
- fctx->rmessage,
- 0,
- task,
- validated,
- fctx,
- &validator);
- if (result == ISC_R_SUCCESS)
- ISC_LIST_APPEND(fctx->validators, validator, link);
- }
+ if (valrdataset != NULL)
+ result = valcreate(fctx, addrinfo, name, fctx->type,
+ valrdataset, valsigrdataset, valoptions,
+ task);
if (result == ISC_R_SUCCESS && have_answer) {
fctx->attributes |= FCTX_ATTR_HAVEANSWER;
@@ -3695,7 +3715,8 @@ cache_name(fetchctx_t *fctx, dns_name_t *name, isc_stdtime_t now) {
}
static inline isc_result_t
-cache_message(fetchctx_t *fctx, isc_stdtime_t now) {
+cache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo, isc_stdtime_t now)
+{
isc_result_t result;
dns_section_t section;
dns_name_t *name;
@@ -3715,7 +3736,7 @@ cache_message(fetchctx_t *fctx, isc_stdtime_t now) {
dns_message_currentname(fctx->rmessage, section,
&name);
if ((name->attributes & DNS_NAMEATTR_CACHE) != 0) {
- result = cache_name(fctx, name, now);
+ result = cache_name(fctx, name, addrinfo, now);
if (result != ISC_R_SUCCESS)
break;
}
@@ -3783,7 +3804,9 @@ ncache_adderesult(dns_message_t *message, dns_db_t *cache, dns_dbnode_t *node,
}
static inline isc_result_t
-ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
+ncache_message(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
+ dns_rdatatype_t covers, isc_stdtime_t now)
+{
isc_result_t result, eresult;
dns_name_t *name;
dns_resolver_t *res;
@@ -3794,6 +3817,7 @@ ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
dns_name_t *aname;
dns_fetchevent_t *event;
isc_uint32_t ttl;
+ unsigned int valoptions = 0;
FCTXTRACE("ncache_message");
@@ -3820,8 +3844,10 @@ ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
if (result != ISC_R_SUCCESS)
return (result);
- if (res->view->dlv != NULL)
+ if (!secure_domain && res->view->dlv != NULL) {
+ valoptions = DNS_VALIDATOR_DLV;
secure_domain = ISC_TRUE;
+ }
if ((fctx->options & DNS_FETCHOPT_NOVALIDATE) != 0)
need_validation = ISC_FALSE;
@@ -3858,23 +3884,15 @@ ncache_message(fetchctx_t *fctx, dns_rdatatype_t covers, isc_stdtime_t now) {
/*
* Do negative response validation.
*/
- dns_validator_t *validator = NULL;
- isc_task_t *task = res->buckets[fctx->bucketnum].task;
-
- result = dns_validator_create(res->view, name, fctx->type,
- NULL, NULL,
- fctx->rmessage, 0, task,
- validated, fctx,
- &validator);
- if (result != ISC_R_SUCCESS)
- return (result);
- ISC_LIST_APPEND(fctx->validators, validator, link);
+ result = valcreate(fctx, addrinfo, name, fctx->type,
+ NULL, NULL, valoptions,
+ res->buckets[fctx->bucketnum].task);
/*
* If validation is necessary, return now. Otherwise continue
* to process the message, letting the validation complete
* in its own good time.
*/
- return (ISC_R_SUCCESS);
+ return (result);
}
LOCK(&res->buckets[fctx->bucketnum].lock);
@@ -4992,6 +5010,43 @@ checknames(dns_message_t *message) {
}
static void
+log_packet(dns_message_t *message, int level, isc_mem_t *mctx) {
+ isc_buffer_t buffer;
+ char *buf = NULL;
+ int len = 1024;
+ isc_result_t result;
+
+ if (! isc_log_wouldlog(dns_lctx, level))
+ return;
+
+ /*
+ * Note that these are multiline debug messages. We want a newline
+ * to appear in the log after each message.
+ */
+
+ do {
+ buf = isc_mem_get(mctx, len);
+ if (buf == NULL)
+ break;
+ isc_buffer_init(&buffer, buf, len);
+ result = dns_message_totext(message, &dns_master_style_debug,
+ 0, &buffer);
+ if (result == ISC_R_NOSPACE) {
+ isc_mem_put(mctx, buf, len);
+ len += 1024;
+ } else if (result == ISC_R_SUCCESS)
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_RESOLVER,
+ DNS_LOGMODULE_RESOLVER, level,
+ "received packet:\n%.*s",
+ (int)isc_buffer_usedlength(&buffer),
+ buf);
+ } while (result == ISC_R_NOSPACE);
+
+ if (buf != NULL)
+ isc_mem_put(mctx, buf, len);
+}
+
+static void
resquery_response(isc_task_t *task, isc_event_t *event) {
isc_result_t result = ISC_R_SUCCESS;
resquery_t *query = event->ev_arg;
@@ -5160,6 +5215,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
/*
+ * Log the incoming packet.
+ */
+ log_packet(message, ISC_LOG_DEBUG(10), fctx->res->mctx);
+
+ /*
* If the message is signed, check the signature. If not, this
* returns success anyway.
*/
@@ -5427,7 +5487,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
* work to be queued to the DNSSEC validator.
*/
if (WANTCACHE(fctx)) {
- result = cache_message(fctx, now);
+ result = cache_message(fctx, query->addrinfo, now);
if (result != ISC_R_SUCCESS)
goto done;
}
@@ -5446,7 +5506,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
/*
* Cache any negative cache entries in the message.
*/
- result = ncache_message(fctx, covers, now);
+ result = ncache_message(fctx, query->addrinfo, covers, now);
}
done: