summaryrefslogtreecommitdiff
path: root/lib/dns/resolver.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/dns/resolver.c')
-rw-r--r--lib/dns/resolver.c86
1 files changed, 62 insertions, 24 deletions
diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c
index 49823d31..6b64461b 100644
--- a/lib/dns/resolver.c
+++ b/lib/dns/resolver.c
@@ -15,7 +15,7 @@
* PERFORMANCE OF THIS SOFTWARE.
*/
-/* $Id: resolver.c,v 1.437 2011-10-27 23:46:31 tbox Exp $ */
+/* $Id: resolver.c,v 1.442 2011-11-16 22:18:52 marka Exp $ */
/*! \file */
@@ -453,7 +453,7 @@ static isc_result_t ncache_adderesult(dns_message_t *message,
dns_rdataset_t *ardataset,
isc_result_t *eresultp);
static void validated(isc_task_t *task, isc_event_t *event);
-static void maybe_destroy(fetchctx_t *fctx);
+static void maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked);
static void add_bad(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
isc_result_t reason, badnstype_t badtype);
@@ -747,7 +747,7 @@ resquery_destroy(resquery_t **queryp) {
query->fctx->nqueries--;
if (SHUTTINGDOWN(query->fctx))
- maybe_destroy(query->fctx); /* Locks bucket. */
+ maybe_destroy(query->fctx, ISC_FALSE); /* Locks bucket. */
query->magic = 0;
isc_mem_put(query->mctx, query, sizeof(*query));
*queryp = NULL;
@@ -1564,9 +1564,11 @@ fctx_query(fetchctx_t *fctx, dns_adbaddrinfo_t *addrinfo,
dns_dispatch_detach(&query->dispatch);
cleanup_query:
- query->magic = 0;
- isc_mem_put(res->buckets[fctx->bucketnum].mctx,
- query, sizeof(*query));
+ if (query->connects == 0) {
+ query->magic = 0;
+ isc_mem_put(res->buckets[fctx->bucketnum].mctx,
+ query, sizeof(*query));
+ }
stop_idle_timer:
RUNTIME_CHECK(fctx_stopidletimer(fctx) == ISC_R_SUCCESS);
@@ -1684,6 +1686,7 @@ resquery_send(resquery_t *query) {
dns_compress_t cctx;
isc_boolean_t cleanup_cctx = ISC_FALSE;
isc_boolean_t secure_domain;
+ isc_boolean_t connecting = ISC_FALSE;
unsigned int edns_fetchopt_flag;
isc_stdtime_t now;
@@ -1843,6 +1846,7 @@ resquery_send(resquery_t *query) {
fctx->timeouts > MAX_EDNS0_TIMEOUTS) &&
(query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
query->options |= DNS_FETCHOPT_NOEDNS0;
+ query->options |= DNS_FETCHOPT_CACHENOEDNS;
fctx->reason = "disabling EDNS";
} else if ((triededns(fctx, &query->addrinfo->sockaddr) ||
fctx->timeouts >= 1) &&
@@ -1914,21 +1918,18 @@ resquery_send(resquery_t *query) {
goto cleanup_message;
}
- if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0)
+ if ((query->options & DNS_FETCHOPT_NOEDNS0) == 0) {
add_triededns(fctx, &query->addrinfo->sockaddr);
- if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
- add_triededns512(fctx, &query->addrinfo->sockaddr);
+ if ((query->options & DNS_FETCHOPT_EDNS512) != 0)
+ add_triededns512(fctx, &query->addrinfo->sockaddr);
+ }
/*
- * Clear CD if EDNS is not in use and set NOEDNS0 in adb.
+ * Clear CD if EDNS is not in use.
*/
- if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0) {
+ if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0)
fctx->qmessage->flags &= ~DNS_MESSAGEFLAG_CD;
- dns_adb_changeflags(fctx->adb, query->addrinfo,
- DNS_FETCHOPT_NOEDNS0,
- DNS_FETCHOPT_NOEDNS0);
- }
/*
* Add TSIG record tailored to the current recipient.
@@ -1996,6 +1997,7 @@ resquery_send(resquery_t *query) {
query);
if (result != ISC_R_SUCCESS)
goto cleanup_message;
+ connecting = ISC_TRUE;
query->connects++;
}
}
@@ -2007,8 +2009,19 @@ resquery_send(resquery_t *query) {
*/
result = isc_socket_sendto(socket, &r, task, resquery_senddone,
query, address, NULL);
- if (result != ISC_R_SUCCESS)
+ if (result != ISC_R_SUCCESS) {
+ if (connecting) {
+ /*
+ * This query is still connecting.
+ * Mark it as canceled so that it will just be
+ * cleaned up when the connected event is received.
+ * Keep fctx around until the event is processed.
+ */
+ query->fctx->nqueries++;
+ query->attributes |= RESQUERY_ATTR_CANCELED;
+ }
goto cleanup_message;
+ }
query->sends++;
@@ -3905,7 +3918,7 @@ clone_results(fetchctx_t *fctx) {
* '*fctx' is shutting down.
*/
static void
-maybe_destroy(fetchctx_t *fctx) {
+maybe_destroy(fetchctx_t *fctx, isc_boolean_t locked) {
unsigned int bucketnum;
isc_boolean_t bucket_empty = ISC_FALSE;
dns_resolver_t *res = fctx->res;
@@ -3923,10 +3936,12 @@ maybe_destroy(fetchctx_t *fctx) {
}
bucketnum = fctx->bucketnum;
- LOCK(&res->buckets[bucketnum].lock);
+ if (!locked)
+ LOCK(&res->buckets[bucketnum].lock);
if (fctx->references == 0 && ISC_LIST_EMPTY(fctx->validators))
bucket_empty = fctx_destroy(fctx);
- UNLOCK(&res->buckets[bucketnum].lock);
+ if (!locked)
+ UNLOCK(&res->buckets[bucketnum].lock);
if (bucket_empty)
empty_bucket(res);
@@ -3971,6 +3986,8 @@ validated(isc_task_t *task, isc_event_t *event) {
FCTXTRACE("received validation completion event");
+ LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
+
ISC_LIST_UNLINK(fctx->validators, vevent->validator, link);
fctx->validator = NULL;
@@ -3992,12 +4009,11 @@ validated(isc_task_t *task, isc_event_t *event) {
* so, destroy the fctx.
*/
if (SHUTTINGDOWN(fctx) && !sentresponse) {
- maybe_destroy(fctx); /* Locks bucket. */
+ maybe_destroy(fctx, ISC_TRUE);
+ UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
goto cleanup_event;
}
- LOCK(&fctx->res->buckets[fctx->bucketnum].lock);
-
isc_stdtime_get(&now);
/*
@@ -4210,7 +4226,7 @@ validated(isc_task_t *task, isc_event_t *event) {
dns_db_detachnode(fctx->cache, &node);
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
if (SHUTTINGDOWN(fctx))
- maybe_destroy(fctx); /* Locks bucket. */
+ maybe_destroy(fctx, ISC_FALSE); /* Locks bucket. */
goto cleanup_event;
}
@@ -4301,7 +4317,6 @@ validated(isc_task_t *task, isc_event_t *event) {
dns_db_detachnode(fctx->cache, &node);
UNLOCK(&fctx->res->buckets[fctx->bucketnum].lock);
-
fctx_done(fctx, result, __LINE__); /* Locks bucket. */
cleanup_event:
@@ -6565,6 +6580,25 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
}
}
goto done;
+#if 0
+ } else if ((query->options & DNS_FETCHOPT_NOEDNS0) != 0 &&
+ (query->options & DNS_FETCHOPT_CACHENOEDNS) != 0 &&
+ triededns512(fctx, &query->addrinfo->sockaddr)) {
+ char addrbuf[ISC_SOCKADDR_FORMATSIZE];
+ isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
+ sizeof(addrbuf));
+ /*
+ * We had a successful response to a DNS_FETCHOPT_NOEDNS0
+ * query.
+ */
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
+ "%s: setting NOEDNS flag in adb cache for '%s'",
+ fctx->info, addrbuf);
+ dns_adb_changeflags(fctx->adb, query->addrinfo,
+ DNS_FETCHOPT_NOEDNS0,
+ DNS_FETCHOPT_NOEDNS0);
+#endif
}
message = fctx->rmessage;
@@ -6708,6 +6742,10 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
char addrbuf[ISC_SOCKADDR_FORMATSIZE];
isc_sockaddr_format(&query->addrinfo->sockaddr, addrbuf,
sizeof(addrbuf));
+ isc_log_write(dns_lctx, DNS_LOGCATEGORY_EDNS_DISABLED,
+ DNS_LOGMODULE_RESOLVER, ISC_LOG_INFO,
+ "%s: changed rcode: setting NOEDNS flag in "
+ "adb cache for '%s'", fctx->info, addrbuf);
dns_adb_changeflags(fctx->adb, query->addrinfo,
DNS_FETCHOPT_NOEDNS0,
DNS_FETCHOPT_NOEDNS0);