resolver.c revision ecb55f9962f881ee8db2c24b90ef85906d9a3394
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * Copyright (C) 1999-2001 Internet Software Consortium.
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * Permission to use, copy, modify, and distribute this software for any
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * purpose with or without fee is hereby granted, provided that the above
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * copyright notice and this permission notice appear in all copies.
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff/* $Id: resolver.c,v 1.236 2002/02/05 01:15:21 bwelling Exp $ */
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff#define RRTRACE(r, m) isc_log_write(dns_lctx, \
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff "res %p: %s", (r), (m))
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff "fetch %p (fctx %p): %s", \
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff "resquery %p (fctx %p): %s", \
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * Maximum EDNS0 input packet size.
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff#define SEND_BUFFER_SIZE 2048 /* XXXRTH Constant. */
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * This defines the maximum number of timeouts we will permit before we
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff * disable EDNS0 on the query.
5585e5da649f170b57a6b70d2014729956c621a7Michael Grafftypedef struct query {
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff /* Locked by task event serialization. */
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff unsigned int magic;
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff unsigned int options;
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff unsigned int sends;
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff#define QUERY_MAGIC ISC_MAGIC('Q', '!', '!', '!')
5585e5da649f170b57a6b70d2014729956c621a7Michael Graff#define VALID_QUERY(query) ISC_MAGIC_VALID(query, QUERY_MAGIC)
RESQUERY_ATTR_CANCELED) != 0)
} fetchstate;
struct fetchctx {
unsigned int magic;
unsigned int options;
unsigned int bucketnum;
unsigned int references;
unsigned int attributes;
unsigned int pending;
unsigned int restarts;
unsigned int timeouts;
struct dns_fetch {
unsigned int magic;
typedef struct fctxbucket {
} fctxbucket_t;
struct dns_resolver {
unsigned int magic;
unsigned int options;
unsigned int nbuckets;
unsigned int references;
unsigned int activebuckets;
unsigned int nfctx;
FCTX_ADDRINFO_FORWARDER) != 0)
static inline isc_result_t
ISC_TRUE));
static inline isc_result_t
ISC_FALSE));
unsigned int rtt;
unsigned int factor;
static inline isc_result_t
return (result);
return (result);
return (result);
unsigned int seconds;
static isc_result_t
unsigned int options)
return (result);
goto stop_idle_timer;
int pf;
switch (pf) {
case PF_INET:
&addr);
case PF_INET6:
&addr);
goto cleanup_query;
goto cleanup_query;
goto cleanup_socket;
case PF_INET:
case PF_INET6:
goto cleanup_query;
goto cleanup_socket;
goto cleanup_dispatch;
return (ISC_R_SUCCESS);
return (result);
static isc_result_t
isc_region_t r;
goto cleanup_temps;
goto cleanup_temps;
task,
goto cleanup_temps;
goto cleanup_message;
goto cleanup_message;
DNS_SECTION_QUESTION, 0);
goto cleanup_message;
!useedns)
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
goto cleanup_message;
return (ISC_R_SUCCESS);
if (cleanup_cctx)
return (result);
unsigned int attrs;
attrs = 0;
unsigned int bucketnum;
if (want_try)
else if (want_done)
else if (bucket_empty)
static inline isc_boolean_t
return (ISC_TRUE);
return (ISC_FALSE);
static inline isc_boolean_t
return (all_bad);
static isc_result_t
return (DNS_R_SERVFAIL);
goto out;
return (result);
out:
if (all_bad) {
} else if (pruned) {
goto restart;
return (result);
int match;
match > 0)
if (aborted) {
static inline dns_adbaddrinfo_t *
return (addrinfo);
return (addrinfo);
static isc_boolean_t
unsigned int bucketnum;
return (ISC_TRUE);
return (ISC_FALSE);
&cevent);
unsigned int bucketnum;
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
unsigned int findoptions = 0;
return (ISC_R_NOMEMORY);
goto cleanup_fetch;
NULL);
goto cleanup_name;
goto cleanup_name;
goto cleanup_name;
goto cleanup_name;
goto cleanup_domain;
goto cleanup_qmessage;
goto cleanup_rmessage;
goto cleanup_rmessage;
return (ISC_R_SUCCESS);
return (result);
static inline isc_boolean_t
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
int order;
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
return (ISC_FALSE);
static inline isc_result_t
return (DNS_R_FORMERR);
return (result);
return (DNS_R_FORMERR);
return (ISC_R_SUCCESS);
unsigned int bucketnum;
if (bucket_empty)
goto cleanup_event;
!negative &&
goto noanswer_response;
goto noanswer_response;
if (negative) {
&node);
goto noanswer_response;
ttl = 0;
goto noanswer_response;
goto answer_response;
goto noanswer_response;
goto noanswer_response;
goto noanswer_response;
if (sentresponse) {
goto cleanup_event;
goto cleanup_event;
== ISC_R_SUCCESS);
static inline isc_result_t
unsigned int options;
return (result);
!need_validation) {
return (result);
return (result);
* Cache this rdataset/sigrdataset pair as
if (!need_validation)
if (!need_validation)
sigrdataset, 0,
name,
task,
fctx,
&validator);
options = 0;
eresult =
eresult =
name,
task,
fctx,
&validator);
return (result);
static inline isc_result_t
section++) {
&name);
return (result);
static isc_result_t
return (result);
static inline isc_result_t
return (result);
if (secure_domain) {
&tname);
return (result);
if (need_validation) {
&validator);
return (result);
return (ISC_R_SUCCESS);
goto unlock;
goto unlock;
ttl = 0;
goto unlock;
return (result);
if (gluing) {
if (external)
static isc_result_t
NULL);
gluing);
&rdataset);
gluing);
return (ISC_R_SUCCESS);
&name);
fctx);
if (rescan)
goto again;
static inline isc_result_t
return (result);
return (result);
return (ISC_R_SUCCESS);
static inline isc_result_t
int order;
return (result);
return (result);
&nbits);
return (DNS_R_FORMERR);
return (result);
return (result);
static isc_result_t
return (ISC_R_SUCCESS);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
if (aa)
return (result);
return (ISC_R_SUCCESS);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
fctx);
return (result);
return (DNS_R_DELEGATION);
return (ISC_R_SUCCESS);
static isc_result_t
unsigned int aflag;
aflag = 0;
&& !found_cname) {
&& !found_type) {
return (DNS_R_FORMERR);
&tname);
return (result);
&& !found_type) {
if (found) {
if (!chaining) {
if (aflag ==
if (aa)
} else if (external) {
(void)dns_rdataset_additionaldata(
fctx);
if (want_chaining) {
aflag = 0;
return (DNS_R_FORMERR);
&dname);
return (result);
if (found) {
if (!chaining) {
if (aflag ==
if (aa)
} else if (external) {
if (want_chaining) {
NULL);
return (result);
&fqname);
return (result);
if (!have_answer)
return (DNS_R_FORMERR);
if (want_chaining) {
return (DNS_R_FORMERR);
if (!external) {
(void)dns_rdataset_additionaldata(
fctx);
return (result);
unsigned int options;
goto done;
goto done;
goto done;
goto done;
switch (result) {
case ISC_R_UNEXPECTEDEND:
goto done;
case DNS_R_FORMERR:
goto done;
goto done;
goto done;
if (truncated) {
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto force_referral;
goto done;
goto done;
goto done;
goto done;
done:
if (keep_trying) {
if (broken_server) {
if (get_nameservers) {
NULL);
} else if (resend) {
unsigned int options,
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_dispatches;
goto cleanup_lock;
return (ISC_R_SUCCESS);
for (i = 0; i < buckets_created; i++) {
return (result);
if (want_priming) {
if (need_destroy)
static inline isc_boolean_t
unsigned int options)
return (ISC_FALSE);
unsigned int bucketnum;
return (ISC_R_NOMEMORY);
goto unlock;
goto unlock;
if (new_fctx) {
return (result);
unsigned int bucketnum;
if (bucket_empty)