resolver.c revision d2358a453e2c69a2348d804c389961f58cc36a69
ca41b452ede6feaa9d8739ec3cae19389a7b0d03Bob Halley * Copyright (C) 1999 Internet Software Consortium.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * Permission to use, copy, modify, and distribute this software for any
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * purpose with or without fee is hereby granted, provided that the above
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * copyright notice and this permission notice appear in all copies.
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
1633838b8255282d10af15c5c84cee5a51466712Bob Halley * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
ea872078bfa9473cfe9c89b474dae2496377797bDavid Lawrence#define RTRACE(m) printf("res %p: %s\n", res, (m))
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley#define RRTRACE(r, m) printf("res %p: %s\n", (r), (m))
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence#define FCTXTRACE(m) printf("fctx %p: %s\n", fctx, (m))
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley#define FTRACE(m) printf("fetch %p (fctx %p): %s\n", \
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley#define QTRACE(m) printf("query %p (res %p fctx %p): %s\n", \
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleytypedef struct query {
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley /* Not locked. */
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence unsigned int magic;
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley /* Locked by fctx lock. */
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleytypedef enum {
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence /* Not locked. */
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence unsigned int magic;
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence /* Locked by lock. */
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence /* Only changable by event actions running in the context's task */
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley unsigned int magic;
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence#define DNS_FETCH_MAGIC 0x46746368U /* Ftch */
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley#define DNS_FETCH_VALID(fetch) ((fetch) != NULL && \
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halleytypedef struct fctxbucket {
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley /* Unlocked */
9fbefe0ace2ae7dba287f914b278153004bef428Bob Halley unsigned int magic;
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence /* Locked by lock. */
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence#define VALID_RESOLVER(res) ((res) != NULL && \
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrencestatic void empty_bucket(dns_resolver_t *res);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrencestatic void query_response(isc_task_t *task, isc_event_t *event);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrence * Internal fetch routines. Caller must be holding the proper lock.
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley return (isc_timer_reset(fctx->timer, isc_timertype_once,
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halleystatic inline void
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley * We don't return a result if resetting the timer to inactive fails
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley * since there's nothing to be done about it. Resetting to inactive
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley * should never fail anyway, since the code as currently written
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley * cannot fail in that case.
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley result = isc_timer_reset(fctx->timer, isc_timertype_inactive,
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley "isc_timer_reset(): %s",
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halleystatic inline void
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halleyfctx_cancelquery(resquery_t *query, dns_dispatchevent_t **deventp) {
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley * XXXRTH I don't think that dns_dispatch_removeresponse() will
0fc87fa2f38df7b293b650deacfa5e6c3d50eff9Bob Halley * reclaim events posted to this task. What do we do
4d6964d70a114b53a11a3bd778d9b8f5179a7934Bob Halley * about this? Doing what we're doing now is bad, because
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley * we're destroying the query while there may be outstanding
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley * references to it.
b592e197fe354d7258dc4166fce0a9425a338b0bBob Halley dns_dispatch_removeresponse(query->dispatch, &query->dispentry,
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence isc_mem_put(fctx->res->mctx, query, sizeof *query);
d5069ac954d067aa45ad395fc338f7e499b834c1David Lawrencefctx_done(fetchctx_t *fctx, isc_result_t result) {
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence /* XXXRTH Free our scaffolding addresses. */
585529aaeb95a71cd3d95df2602a4688fc7c3292David Lawrence for (address = ISC_LIST_HEAD(fctx->addresses);
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence isc_mem_put(fctx->res->mctx, address, sizeof *address);
11d732daac76a24a0f3e5948a2758a4b866a0825David Lawrence isc_task_sendanddetach(&task, (isc_event_t **)&event);
(void)task;
static isc_result_t
isc_region_t r;
return (result);
goto cleanup_temps;
goto cleanup_temps;
return (ISC_R_NOMEMORY);
goto cleanup_query;
case AF_INET:
case AF_INET6:
goto cleanup_query;
task,
goto cleanup_query;
goto cleanup_message;
DNS_SECTION_QUESTION, 0, 0);
goto cleanup_message;
DNS_SECTION_ADDITIONAL, 0, 0);
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
return (ISC_R_SUCCESS);
NULL);
return (result);
static isc_result_t
isc_region_t r;
sizeof *address);
link);
return (result);
INSIST(0);
static isc_boolean_t
unsigned int bucketnum;
return (ISC_TRUE);
return (ISC_FALSE);
unsigned int bucketnum;
if (need_done)
else if (bucket_empty)
unsigned int bucketnum;
if (!done) {
} else if (bucket_empty)
static inline isc_result_t
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
static isc_result_t
return (ISC_R_NOMEMORY);
goto cleanup_fetch;
goto cleanup_name;
goto cleanup_domain;
goto cleanup_qmessage;
goto cleanup_rmessage;
goto cleanup_rmessage;
return (ISC_R_SUCCESS);
return (result);
#ifdef obsolete
static inline isc_result_t
return (DNS_R_FORMERR);
return (result);
return (DNS_R_FORMERR);
return (ISC_R_SUCCESS);
(void)task;
switch (result) {
case DNS_R_FORMERR:
case DNS_R_UNEXPECTEDEND:
case DNS_R_MOREDATA:
goto done;
goto done;
goto done;
goto done;
goto foo;
goto foo;
goto done;
foo:
done:
if (bad_sender) {
&devent);
if (need_destroy)
unsigned int i, buckets_created = 0;
return (ISC_R_NOMEMORY);
goto cleanup_res;
for (i = 0; i < ntasks; i++) {
goto cleanup_buckets;
goto cleanup_buckets;
goto cleanup_buckets;
goto cleanup_buckets;
goto cleanup_udpsocket4;
goto cleanup_dispatch4;
goto cleanup_udpsocket6;
goto cleanup_dispatch6;
return (ISC_R_SUCCESS);
for (i = 0; i < buckets_created; i++) {
return (result);
if (need_destroy)
static inline isc_boolean_t
unsigned int options)
return (ISC_FALSE);
unsigned int bucketnum;
(void)forwarders;
return (DNS_R_NOTIMPLEMENTED);
return (ISC_R_NOMEMORY);
goto unlock;
goto unlock;
if (new_fctx) {
return (result);
link);
&cevent);