dighost.c revision 233514c1da6c51f056dad8bd2c8a82deea5ce3ef
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * Copyright (C) 2000 Internet Software Consortium.
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * Permission to use, copy, modify, and distribute this software for any
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * purpose with or without fee is hereby granted, provided that the above
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * copyright notice and this permission notice appear in all copies.
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
bf8267aa453e5d2a735ed732a043b77a0b355b20Mark Andrews * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1d32b1df372d6be6bac6450739b9e5ea23819995Evan Hunt/* $Id: dighost.c,v 1.144 2000/10/13 17:53:58 mws Exp $ */
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * Notice to programmers: Do not use this code as an example of how to
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * use the ISC library to perform DNS lookups. Dig and Host both operate
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * on the request level, since they allow fine-tuning of output and are
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * intended as debugging tools. As a result, they perform many of the
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyer * functions which could be better handled using the dns_resolver
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt * functions in most applications.
30a60d2aff0ec1810262a8b8efc532e28b32bd57Evan Hunt#if (!(defined(HAVE_ADDRINFO) && defined(HAVE_GETADDRINFO)))
c3c6770e537ea916265c78d0294ad108233e17c1Michael Sawyerunsigned int timeout = 0;
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * Exit Codes:
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * 0 Everything went well, including things like NXDOMAIN
222d38735f97f771054e223b03f84c5858252332Evan Hunt * 1 Usage error
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * 7 Got too many RR's or Names
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * 8 Couldn't open batch file
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * 9 No reply from server
9069215eac23e32f4ef1c8e44ad7ff2865cfcdacEvan Hunt * 10 Internal error
222d38735f97f771054e223b03f84c5858252332Evan Hunt * Apply and clear locks at the event level in global task.
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt * Can I get rid of these using shutdown events? XXX
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt check_result(isc_mutex_lock((&lookup_lock)), "isc_mutex_lock");\
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt debug("unlock_lookup %s:%d", __FILE__, __LINE__);\
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt "isc_mutex_unlock");\
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Huntconnect_timeout(isc_task_t *task, isc_event_t *event);
b5b934a0bb46aded1552a17473652b5a7f4a3274Evan Hunt while (*s != '\0') {
47e70d820ed07895a25e5b3520adf953114ac01eEvan Hunt if (*s == '.')
6de9744cf9c64be2145f663e4051196a4eaa9d45Evan Hunt unsigned int len;
cba23be7ba724b527f6a60c14caaeca9502fbc79Evan Huntcheck_result(isc_result_t result, const char *msg) {
a69070d8fab55dbc63ba9f96c9d3e34f0ea9119aMark Andrews * Create a server structure, which is part of the lookup structure.
a69070d8fab55dbc63ba9f96c9d3e34f0ea9119aMark Andrews * This is little more than a linked list of servers to query in hopes
a69070d8fab55dbc63ba9f96c9d3e34f0ea9119aMark Andrews * of finding the answer the user is looking for
a69070d8fab55dbc63ba9f96c9d3e34f0ea9119aMark Andrews srv = isc_mem_allocate(mctx, sizeof(struct dig_server));
c5272fb3303425f794dab68f734f6a2a45dce01eMichael Sawyer * Produce a cloned server list. The dest list must have already had
c5272fb3303425f794dab68f734f6a2a45dce01eMichael Sawyer * ISC_LIST_INIT applied.
dc9c461b27df798ba7c3d9ba1446840c5f85553bMichael Sawyer * Create an empty lookup structure, which holds all the information needed
1b003261c2dd3e32778337c7a2788e4829066bd9Andreas Gustafsson * to get an answer to a user's question. This structure contains two
1b003261c2dd3e32778337c7a2788e4829066bd9Andreas Gustafsson * linked lists: the server list (servers to query) and the query list
1b003261c2dd3e32778337c7a2788e4829066bd9Andreas Gustafsson * (outstanding queries which have been made to the listed servers).
3ad7f12f7439471a0922ed3952221e93aef9db69Andreas Gustafsson looknew = isc_mem_allocate(mctx, sizeof(struct dig_lookup));
222d38735f97f771054e223b03f84c5858252332Evan Hunt looknew->cmdline[0] = 0; /* Not copied in clone_lookup! */
5337a9e53c7df1ef40d70528f2360c5e4cb9a7d1Andreas Gustafsson * Clone a lookup, perhaps copying the server list. This does not clone
222d38735f97f771054e223b03f84c5858252332Evan Hunt * the query list, since it will be regenerated by the setup_lookup()
5337a9e53c7df1ef40d70528f2360c5e4cb9a7d1Andreas Gustafsson * function, nor does it queue up the new lookup for processing.
5337a9e53c7df1ef40d70528f2360c5e4cb9a7d1Andreas Gustafsson * Caution: If you don't clone the servers, you MUST clone the server
5337a9e53c7df1ef40d70528f2360c5e4cb9a7d1Andreas Gustafsson * list seperately from somewhere else, or construct it by hand.
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrewsclone_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews strncpy(looknew->textname, lookold-> textname, MXNAME);
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews looknew->servfail_stops = lookold->servfail_stops;
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews looknew->ns_search_only = lookold->ns_search_only;
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews looknew->section_question = lookold->section_question;
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews looknew->section_answer = lookold->section_answer;
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews looknew->section_authority = lookold->section_authority;
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews looknew->section_additional = lookold->section_additional;
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews strncpy(looknew->viewname, lookold-> viewname, MXNAME);
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews strncpy(looknew->zonename, lookold-> zonename, MXNAME);
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews#endif /* DNS_OPT_NEWCODES */
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * Requeue a lookup for further processing, perhaps copying the server
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * list. The new lookup structure is returned to the caller, and is
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * queued for processing. If servers are not cloned in the requeue, they
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * must be added before allowing the current event to complete, since the
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * completion of the event may result in the next entry on the lookup
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews * queue getting run.
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrewsrequeue_lookup(dig_lookup_t *lookold, isc_boolean_t servers) {
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews "-> %p, new@%p -> %p",
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews lookold, lookold->link.next, looknew, looknew->link.next);
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews "%p, new = %p, new -> %p",
8aee18709f238406719768b8a6b843a15c5075f8Mark Andrews unsigned char *secretstore;
e2f470bebb3a0c107bc4ac86c6920c21e50e83e0Brian Wellington result = isc_buffer_allocate(mctx, &namebuf, MXNAME);
e2f470bebb3a0c107bc4ac86c6920c21e50e83e0Brian Wellington check_result(result, "isc_buffer_allocate");
f0a1134d331b2aa871306c73d2787960918eaab1Andreas Gustafsson secretstore = isc_mem_allocate(mctx, secretsize);
e2f470bebb3a0c107bc4ac86c6920c21e50e83e0Brian Wellington isc_buffer_init(&secretbuf, secretstore, secretsize);
82f0630bae09598209cc37c1db00ff4356efee27Mark Andrews secretsize = isc_buffer_usedlength(&secretbuf);
16cc4a1f56d0f9a300419da7e75e3b72169e608aMark Andrews result = dns_tsigkey_create(&keyname, dns_tsig_hmacmd5_name,
f5b7359c5730d39ff6eff24ae87c9c74a04c2e5cMark Andrews result = dst_key_fromnamedfile(keyfile, DST_TYPE_PRIVATE,
f5b7359c5730d39ff6eff24ae87c9c74a04c2e5cMark Andrews fprintf(stderr, "Couldn't read key from %s: %s\n",
f5b7359c5730d39ff6eff24ae87c9c74a04c2e5cMark Andrews * Get key size in bits, convert to bytes, rounding up (?)
f5b7359c5730d39ff6eff24ae87c9c74a04c2e5cMark Andrews secretstore = isc_mem_allocate(mctx, secretlen);
f5b7359c5730d39ff6eff24ae87c9c74a04c2e5cMark Andrews isc_buffer_init(&secretbuf, secretstore, secretlen);
f5b7359c5730d39ff6eff24ae87c9c74a04c2e5cMark Andrews fprintf(stderr, "Couldn't read key from %s: %s\n",
d1f43359e4349bb9d934b96b7aa22b54ae7cef7cMark Andrews dns_name_clone(dst_key_name(dstkey), &keyname);
d1f43359e4349bb9d934b96b7aa22b54ae7cef7cMark Andrews result = dns_tsigkey_create(&keyname, dns_tsig_hmacmd5_name,
d1f43359e4349bb9d934b96b7aa22b54ae7cef7cMark Andrews * Setup the system as a whole, reading key information and resolv.conf
de5890da9b87cb4b91aca033db0e25b1fdb68c77Evan Hunt if (fixeddomain[0] != 0) {
de5890da9b87cb4b91aca033db0e25b1fdb68c77Evan Hunt search = isc_mem_allocate(mctx, sizeof(struct dig_server));
/* XXX Use lwres resolv.conf reader */
if (get_servers &&
ndots);
!= NULL) {
ptr);
mctx, sizeof(struct
dig_server));
__LINE__);
ptr,
link);
(fixeddomain[0] == 0 )){
!= NULL) {
mctx, sizeof(struct
dig_server));
__LINE__);
ptr,
link);
if (keyfile[0] != 0)
else if (keysecret[0] != 0)
setup_libs(void) {
#ifdef DNS_OPT_NEWCODES
unsigned int i, optsize = 0;
#ifdef DNS_OPT_NEWCODES
* part of dig.c, host.c, or nslookup.c) to either shutdown the system as
check_if_done(void) {
sendcount == 0) {
link);
link);
sockcount--;
static isc_boolean_t
dig_server_t *s;
dig_query_t *q;
void *ptr;
if (debugging) {
while (q != NULL) {
q->servname);
return (ISC_FALSE);
while (s != NULL) {
s, lookup);
ptr = s;
return (ISC_TRUE);
start_lookup(void) {
if (cancel_now)
start_lookup();
isc_region_t r;
int len;
BUFSIZE);
NULL,
isc_buffer_usedregion(b, &r);
(char *)r.base);
if (!success) {
if (section ==
query->
query->
isc_buffer_free(&b);
static isc_boolean_t
if (!usesearch)
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
int len;
isc_region_t r;
isc_buffer_t b;
lookup_counter = 0;
* is TRUE or we got a domain line in the resolv.conf file.
isc_buffer_usedregion(&b, &r);
#ifndef DNS_OPT_NEWCODES
#ifdef DNS_OPT_NEWCODES
NULL);
MXNAME);
wirebuf);
#ifdef DNS_OPT_NEWCODES
DNS_SECTION_QUESTION, 0);
ISC_TRUE);
sendcount--;
dig_lookup_t *l;
unsigned int local_timeout;
if (timeout == 0) {
NULL,
&l->interval,
l, &l->timer);
dig_lookup_t *l;
if (specified_source &&
sockcount++;
if (specified_source)
if (l->ns_search_only) {
sockcount++;
if (specified_source) {
link);
query);
recvcount++;
link);
sendcount++;
if (l->ns_search_only) {
if (!l->tcp_mode)
if (!l->tcp_mode) {
l->retries--;
l->retries);
cancel_lookup(l);
l->retries--;
cancel_lookup(l);
isc_region_t r;
dig_lookup_t *l;
recvcount--;
isc_buffer_usedregion(b, &r);
isc_buffer_free(&b);
sockcount--;
length);
recvcount++;
dig_lookup_t *l;
sockcount--;
if (include_question) {
link);
recvcount++;
sendcount++;
dig_lookup_t *l;
isc_region_t r;
sockcount--;
isc_buffer_usedregion(b, &r);
sockcount--;
isc_buffer_free(&b);
static isc_boolean_t
isc_buffer_t b;
isc_region_t r;
return (ISC_TRUE);
&name);
return (ISC_TRUE);
goto next_rdata;
&soa,
mctx);
goto doexit;
goto next_rdata;
goto doexit;
goto doexit;
goto next_rdata;
goto doexit;
goto next_rdata;
goto doexit;
if (atlimit) {
isc_buffer_usedregion(&b, &r);
if (atlimit)
return (ISC_TRUE);
return (ISC_FALSE);
isc_region_t r;
dig_lookup_t *n, *l;
unsigned int local_timeout;
if (show_packets)
recvcount--;
|| cancel_now) {
&msg);
l->sendmsg,
l->querysig);
if (l->msgcounter != 0)
l->msgcounter++;
if (l->besteffort)
hex_dump(b);
cancel_lookup(l);
cancel_lookup(l);
l->servfail_stops) {
if (l->tcp_mode)
l->querysig);
&l->querysig);
l->doing_xfr ) {
if (timeout == 0) {
if (l->tcp_mode)
local_timeout, 0);
NULL,
&l->interval,
if ((l->trace)||
(l->ns_search_only)) {
ISC_TRUE);
MXNAME);
&ab);
(char *)r.base,
query);
l->trace_root)
ISC_TRUE);
&ab);
(char *)r.base,
query);
l->doing_xfr)
== ISC_R_SUCCESS) &&
l->ns_search_only &&
!l->trace_root ) {
if (l->pending)
if (l->doing_xfr) {
if (docancel) {
cancel_lookup(l);
&ab);
(char *)r.base,
query);
cancel_lookup(l);
sockcount--;
int result;
if (result != 0) {
port);
start_lookup();
cancel_all(void) {
dig_lookup_t *l, *n;
if (is_blocking) {
if (free_now) {
while (q != NULL) {
q, current_lookup);
clear_query (q);
q = nq;
while (l != NULL) {
try_clear_lookup(l);
destroy_libs(void) {
void *ptr;
dig_server_t *s;
dig_searchlist_t *o;
while (s != NULL) {
ptr = s;
while (o != NULL) {
ptr = o;
if (is_dst_up) {
if (isc_mem_debugging != 0)