resolver.c revision fea89edbab192b516033e58bc9768e5d650790e8
7d32c065c7bb56f281651ae3dd2888f32ce4f1d9Bob Halley * Copyright (C) 1999 Internet Software Consortium.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * Permission to use, copy, modify, and distribute this software for any
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * purpose with or without fee is hereby granted, provided that the above
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * copyright notice and this permission notice appear in all copies.
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews "res %p: %s", (r), (m))
d981ca645597116d227a48bf37cc5edc061c854dBob Halley "fetch %p (fctx %p): %s", \
940e4ef72b64a8a82a1038fdf08b324eec6e43a9Michael Graff "resquery %p (fctx %p): %s", \
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Grafftypedef struct query {
940e4ef72b64a8a82a1038fdf08b324eec6e43a9Michael Graff /* Not locked. */
940e4ef72b64a8a82a1038fdf08b324eec6e43a9Michael Graff unsigned int magic;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Locked by fctx lock. */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#define VALID_QUERY(query) ((query) != NULL && \
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrewstypedef enum {
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Not locked. */
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews unsigned int magic;
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews unsigned int options;
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews /* Locked by lock. */
7c0539bea56022274da04263eb41fbb5b8835c38Mark Andrews /* Only changable by event actions running in the context's task */
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews unsigned int pending;
f7b99290c31abeb20c55fc55391510450ce60423Mark Andrews#define HAVE_ANSWER(f) (((f)->attributes & FCTX_ATTR_HAVEANSWER) != \
5d51e67c3b4f35c1be742574aacc1d88fe6ed444Mark Andrews#define GLUING(f) (((f)->attributes & FCTX_ATTR_GLUING) != \
4529cdaedaf1a0a5f8ff89aeca510b7a4475446cBob Halley#define ADDRWAIT(f) (((f)->attributes & FCTX_ATTR_ADDRWAIT) != \
940e4ef72b64a8a82a1038fdf08b324eec6e43a9Michael Graff#define SHUTTINGDOWN(f) (((f)->attributes & FCTX_ATTR_SHUTTINGDOWN) \
d981ca645597116d227a48bf37cc5edc061c854dBob Halley#define DNS_FETCH_VALID(fetch) ((fetch) != NULL && \
82ca33427bdd4f3bc4ed3431e86bd810fe751674Andreas Gustafssontypedef struct fctxbucket {
3ddd814a97de1d152ba0913c592d6e6dc83d38a6Michael Graff /* Unlocked */
940e4ef72b64a8a82a1038fdf08b324eec6e43a9Michael Graff unsigned int magic;
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley /* Locked by lock. */
e27a69f8bd9538e08f775265167ba6cc5f47c587Bob Halley unsigned int references;
854d0238dbc2908490197984b3b9d558008a53dfMark Andrews unsigned int nbuckets;
unsigned int activebuckets;
static inline isc_result_t
ISC_FALSE));
static inline isc_result_t
ISC_FALSE));
deventp);
(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);
unsigned int bucketnum;
(void)task;
if (want_try)
else if (want_done)
else if (bucket_empty)
static isc_result_t
isc_region_t r;
unsigned int options;
return (result);
&find);
return (result);
return (result);
return (result);
static inline dns_adbaddrinfo_t *
int count = 0;
count++;
return (addrinfo);
static isc_boolean_t
unsigned int bucketnum;
return (ISC_TRUE);
return (ISC_FALSE);
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
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);
static inline isc_result_t
return (DNS_R_FORMERR);
return (result);
return (DNS_R_FORMERR);
return (ISC_R_SUCCESS);
static inline isc_result_t
void *data;
return (result);
return (result);
&node);
return (result);
if (need_validation) {
return (DNS_R_NOTIMPLEMENTED);
eresult =
eresult =
return (result);
static inline isc_result_t
section++) {
&name);
return (result);
static inline isc_result_t
void *data;
return (result);
goto unlock;
&node);
goto unlock;
goto unlock;
return (result);
if (gluing)
if (external)
static isc_result_t
NULL);
gluing);
&rdataset);
gluing);
* See query.c.
return (ISC_R_SUCCESS);
static inline isc_result_t
isc_region_t r;
return (result);
return (ISC_R_SUCCESS);
static inline isc_result_t
isc_region_t r;
int order;
return (result);
&nbits);
return (DNS_R_FORMERR);
return (result);
static isc_result_t
return (DNS_R_FORMERR);
(void)dns_rdataset_additionaldata(
fctx);
return (DNS_R_FORMERR);
if (aa)
return (result);
return (ISC_R_SUCCESS);
return (DNS_R_FORMERR);
return (DNS_R_FORMERR);
return (ISC_R_SUCCESS);
return (DNS_R_FORMERR);
return (result);
return (DNS_R_DELEGATION);
return (ISC_R_SUCCESS);
static inline isc_result_t
unsigned int aflag;
aflag = 0;
return (DNS_R_FORMERR);
&tname);
return (result);
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 (aa)
} else if (external) {
if (want_chaining) {
&dname);
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);
return (ISC_R_SUCCESS);
(void)task;
covers = 0;
goto done;
switch (result) {
case DNS_R_FORMERR:
case DNS_R_UNEXPECTEDEND:
case DNS_R_MOREDATA:
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
done:
if (keep_trying) {
if (get_nameservers) {
NULL);
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;
port++;
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);