dighost.c revision efb028b6c879c67b4e5b858f0e318a57b1073f69
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * Copyright (C) 2004-2015 Internet Systems Consortium, Inc. ("ISC")
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * Copyright (C) 2000-2003 Internet Software Consortium.
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * Permission to use, copy, modify, and/or distribute this software for any
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * purpose with or without fee is hereby granted, provided that the above
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * copyright notice and this permission notice appear in all copies.
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * PERFORMANCE OF THIS SOFTWARE.
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * Notice to programmers: Do not use this code as an example of how to
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * use the ISC library to perform DNS lookups. Dig and Host both operate
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * on the request level, since they allow fine-tuning of output and are
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * intended as debugging tools. As a result, they perform many of the
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * functions which could be better handled using the dns_resolver
a39a5f4d816ca7d3f43106712ca668dd1ab31d69Mark Andrews * functions in most applications.
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#ifdef HAVE_LOCALE_H
#include <locale.h>
#ifdef WITH_IDN
#ifdef DIG_SIGCHASE
#include <ctype.h>
#ifdef PKCS11CRYPTO
#if ! defined(NS_INADDRSZ)
#if ! defined(NS_IN6ADDRSZ)
unsigned int timeout = 0;
unsigned int extrabytes;
int sendcount = 0;
int recvcount = 0;
int sockcount = 0;
int lookup_counter = 0;
#ifdef WITH_IDN
static void initialize_idn(void);
unsigned int used_org,
int idnoptions = 0;
int exitcode = 0;
int fatalexit = 0;
unsigned int digestbits = 0;
#ifdef DIG_SIGCHASE
int section);
void dump_database(void);
void clean_trustedkey(void);
#if DIG_SIGCHASE_BU
#if DIG_SIGCHASE_TD
#if DIG_SIGCHASE_TD
#if DIG_SIGCHASE_BU
#if DIG_SIGCHASE_TD
typedef struct struct_trusted_key_list {
int nb_tk;
#define LOCK_LOOKUP {\
#define UNLOCK_LOOKUP {\
static isc_boolean_t
char *res;
return (res);
s = string;
unsigned int len, i;
isc_region_t r;
isc_buffer_usedregion(b, &r);
static isc_result_t
return (ISC_R_NOSPACE);
*p += len;
return (ISC_R_SUCCESS);
static isc_result_t
int len;
return (result);
return (result);
unsigned int options = 0;
if (ip6_int)
return (result);
return (ISC_R_SUCCESS);
char *p = reverse;
return (DNS_R_BADDOTTEDQUAD);
return (result);
return (result);
return (ISC_R_SUCCESS);
if (fatalexit != 0)
isc_time_t t;
if (debugging) {
if (debugtiming) {
TIME_NOW(&t);
return (srv);
int af = 0;
switch (lwresaddrtype) {
case LWRES_ADDRTYPE_V4:
case LWRES_ADDRTYPE_V6:
return (af);
int af;
flush_server_list(void) {
while (s != NULL) {
ps = s;
int count, i;
for (i = 0; i < count; i++) {
static isc_result_t
return (ISC_R_FAILURE);
switch (af) {
case AF_INET:
case AF_INET6:
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
return (ISC_R_FAILURE);
make_empty_lookup(void) {
#ifdef DIG_SIGCHASE
#if DIG_SIGCHASE_TD
return (looknew);
#if DIG_SIGCHASE_TD
#ifdef DIG_SIGCHASE
#if DIG_SIGCHASE_TD
if (servers)
return (looknew);
return (looknew);
setup_text_key(void) {
int secretsize;
unsigned char *secretstore;
goto failure;
goto failure;
goto failure;
static isc_result_t
isc_uint32_t n;
return (result);
*uip = n;
return (ISC_R_SUCCESS);
const char *desc) {
const char *desc) {
static isc_uint32_t
return (tmp);
} else if (netmask != 0) {
if (!parsed)
return (ISC_R_SUCCESS);
int len;
digestbits = 0;
digestbits = 0;
* Get a key from a named.conf format keyfile
static isc_result_t
read_confkey(void) {
const char *keyname;
const char *secretstr;
const char *algorithm;
return (ISC_R_FILENOTFOUND);
goto cleanup;
&file);
goto cleanup;
goto cleanup;
return (result);
setup_file_key(void) {
&dstkey);
goto failure;
case DST_ALG_HMACMD5:
case DST_ALG_HMACSHA1:
case DST_ALG_HMACSHA224:
case DST_ALG_HMACSHA256:
case DST_ALG_HMACSHA384:
case DST_ALG_HMACSHA512:
goto failure;
goto failure;
static dig_searchlist_t *
return (search);
clear_searchlist(void) {
* Setup the system as a whole, reading key information and resolv.conf
unsigned int lwresflags;
if (ipv4only) {
if (have_ipv4) {
if (ipv6only) {
if (have_ipv6) {
if (have_ipv4)
if (have_ipv6)
/* If user doesn't specify server use nameservers from resolv.conf. */
if (have_ipv4) {
if (have_ipv6) {
#ifdef WITH_IDN
if (keyfile[0] != 0)
else if (keysecret[0] != 0)
#ifdef DIG_SIGCHASE
#if DIG_SIGCHASE_TD
#if DIG_SIGCHASE_BU
* Override the search list derived from resolv.conf by 'domain'.
setup_libs(void) {
#ifdef PKCS11CRYPTO
static unsigned char ednsoptscnt = 0;
isc_buffer_t b;
char *buf;
ednsoptscnt++;
* 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_query_t *q;
if (debugging) {
while (q != NULL) {
while (q != NULL) {
q->servname);
return (ISC_FALSE);
return (ISC_TRUE);
dig_server_t *s;
void *ptr;
while (s != NULL) {
ptr = s;
start_lookup(void) {
if (cancel_now)
#if DIG_SIGCHASE_TD
isc_region_t r;
goto novalidation;
goto novalidation;
ISC_FALSE, b);
isc_buffer_usedregion(b, &r);
MXNAME);
isc_buffer_free(&b);
&chase_name);
start_lookup();
int numLookups = 0;
int num;
0, &rdataset);
&rdataset);
unsigned int nlabels;
int order;
if (!horizontal)
if (!bad)
if (!success) {
isc_uint32_t i, j;
i = numLookups;
INSIST(i > 0);
isc_random_get(&j);
return (numLookups);
static isc_boolean_t
if (!usesearch)
return (ISC_FALSE);
0, NULL);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_FALSE);
return (ISC_TRUE);
int len;
isc_buffer_t b;
#ifdef WITH_IDN
#ifdef WITH_IDN
lookup_counter = 0;
#ifdef WITH_IDN
* is TRUE or we got a domain line in the resolv.conf file.
#ifdef WITH_IDN
#ifdef WITH_IDN
sizeof(utf8_origin));
sizeof(utf8_textname));
return (ISC_FALSE);
#ifdef WITH_IDN
dns_rootname, 0,
dns_rootname, 0,
unsigned int flags;
isc_buffer_putuint8(&b, 0);
if (addrl > 0) {
mask));
isc_buffer_putuint8(&b, 0);
if (addrl > 0) {
mask));
sizeof(cookiebuf));
DNS_SECTION_QUESTION, 0);
extrabytes = 0;
ISC_TRUE);
return (ISC_TRUE);
dig_lookup_t *l;
sendcount--;
b != NULL;
dig_lookup_t *l;
unsigned int local_timeout;
if (timeout == 0)
l, &l->timer);
connect_timeout, l,
sizeof(isc_event_t));
dig_lookup_t *l;
if (specified_source &&
sockcount++;
goto search;
sockcount++;
if (specified_source)
static isc_buffer_t *
return (buffer);
sockcount++;
if (specified_source) {
link);
recvcount++;
sendcount++;
if (!l->tcp_mode)
if (!l->tcp_mode) {
l->retries--;
l->retries);
l->retries--;
cancel_lookup(l);
cancel_lookup(l);
dig_lookup_t *l;
recvcount--;
sizeof(sockstr));
sockcount--;
if (length == 0) {
recvcount++;
dig_lookup_t *l;
sockcount--;
if (include_question) {
recvcount++;
sendcount++;
dig_lookup_t *l;
sockcount--;
sockcount--;
if (keep_open) {
static isc_boolean_t
if (ixfr)
return (ISC_TRUE);
&name);
return (ISC_TRUE);
goto next_rdata;
goto next_rdata;
serial);
serial)) {
goto doexit;
goto next_rdata;
if (axfr) {
goto doexit;
goto doexit;
serial);
goto next_rdata;
goto next_rdata;
goto doexit;
return (ISC_FALSE);
return (ISC_TRUE);
const unsigned char *sent;
if (copy) {
isc_region_t r;
switch (optcode) {
case DNS_OPT_COOKIE:
#ifdef DIG_SIGCHASE
dig_lookup_t *n, *l;
unsigned int parseflags;
unsigned int msgflags;
#ifdef DIG_SIGCHASE
isc_region_t r;
int newedns;
recvcount--;
sockcount--;
if (!l->tcp_mode &&
sizeof(buf1));
sizeof(buf2));
if (l->tcp_mode) {
if (fail) {
if (!match)
goto udp_mismatch;
&l->querysig);
if (l->msgcounter != 0)
l->msgcounter++;
#ifdef DIG_SIGCHASE
if (!l->sigchase) {
parseflags = 0;
if (l->besteffort) {
hex_dump(b);
cancel_lookup(l);
&name);
sizeof(namestr));
sizeof(typebuf));
sizeof(classbuf));
if (!match) {
if (l->tcp_mode) {
goto udp_mismatch;
if (l->comments)
newedns);
cancel_lookup(l);
if (l->comments)
cancel_lookup(l);
if (l->comments)
if (l->seenbadcookie)
cancel_lookup(l);
if (l->tcp_mode)
if (l->comments)
unsigned int local_timeout;
if (timeout == 0) {
if (l->tcp_mode)
NULL,
&l->interval,
#ifdef DIG_SIGCHASE
if (!do_sigchase)
} else if (l->trace) {
int nl = 0;
if (!l->ns_search_only)
if (!l->trace_root)
} else if (count == 0)
if (nl == 0)
if (l->trace_root) {
int nl;
if (nl == 0)
#ifdef DIG_SIGCHASE
if (!do_sigchase)
#ifdef DIG_SIGCHASE
if (do_sigchase) {
sizeof(dig_message_t));
link);
isc_buffer_usedregion(b, &r);
sizeof(dig_message_t));
link);
#ifdef DIG_SIGCHASE
if (l->pending)
if (l->doing_xfr) {
if (!docancel)
if (docancel) {
cancel_lookup(l);
#ifdef DIG_SIGCHASE
if (!l->sigchase)
#ifdef DIG_SIGCHASE
if (!do_sigchase)
cancel_lookup(l);
#ifdef DIG_SIGCHASE
if (do_sigchase)
recvcount++;
int count;
if (is_running)
if (is_running)
return (result);
return (ISC_R_SUCCESS);
int count, i;
for (i = 0; i < count; i++) {
return count;
start_lookup();
cancel_all(void) {
dig_lookup_t *l, *n;
if (free_now) {
q != NULL;
q = nq)
q, current_lookup);
clear_query(q);
q != NULL;
q = nq)
q, current_lookup);
clear_query(q);
while (l != NULL) {
try_clear_lookup(l);
destroy_libs(void) {
#ifdef DIG_SIGCHASE
void * ptr;
#ifdef WITH_IDN
#ifdef WITH_IDN
if (is_dst_up) {
#ifdef DIG_SIGCHASE
#if DIG_SIGCHASE_TD
#if DIG_SIGCHASE_BU
while (ednsoptscnt > 0U) {
ednsoptscnt--;
if (memdebugging != 0)
#ifdef WITH_IDN
initialize_idn(void) {
idn_result_t r;
#ifdef HAVE_SETLOCALE
if (r != idn_success)
idn_result_tostring(r));
static isc_result_t
return (ISC_R_SUCCESS);
fromlen++;
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
tolen--;
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
static idn_result_t
return idn_success;
return idn_buffer_overflow;
return idn_success;
if (r != idn_success) {
#ifdef DIG_SIGCHASE
isc_region_t r;
isc_buffer_usedregion(b, &r);
isc_buffer_free(&b);
dump_database(void) {
== ISC_R_SUCCESS)
== ISC_R_SUCCESS)
== ISC_R_SUCCESS)
return (rdataset);
return (rdataset);
return (rdataset);
return (NULL);
int section)
return (NULL);
return (rdataset);
return (NULL);
== ISC_R_SUCCESS)
return (rdataset);
== ISC_R_SUCCESS)
rdataset =
return (rdataset);
== ISC_R_SUCCESS)
rdataset =
return (rdataset);
return (NULL);
isc_region_t r;
return (temp);
return (NULL);
isc_buffer_usedregion(b, &r);
isc_buffer_free(&b);
return (NULL);
return (NULL);
return (ISC_R_SUCCESS);
isc_buffer_t b;
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
for (i= 0; i < MAX_TRUSTED_KEY; i++) {
char alphnum[] =
int tempnamekeylen;
return (ISC_R_NOMEMORY);
return (result);
get_trusted_key(void) {
return (ISC_R_FAILURE);
return (ISC_R_FAILURE);
#if DIG_SIGCHASE_TD
dig_server_t *s;
void *ptr;
while (s != NULL) {
s, lookup);
ptr = s;
#define __FOLLOW_GLUE__
#ifdef __FOLLOW_GLUE__
isc_region_t r;
#ifdef __FOLLOW_GLUE__
dns_rdatatype_any, &true);
isc_buffer_usedregion(b, &r);
isc_buffer_free(&b);
dns_rdatatype_any, &true);
isc_buffer_usedregion(b, &r);
isc_buffer_free(&b);
dns_rdata_reset(&a);
return (ISC_R_SUCCESS);
int orderp;
unsigned int nlabelsp;
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
goto cleanup;
return (result);
dns_rdatatype_any, &true);
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
isc_region_t r;
isc_buffer_usedregion(b, &r);
isc_buffer_free(&b);
return (ISC_R_FAILURE);
== ISC_TRUE) {
goto cleanup;
return (result);
goto cleanup;
return (result);
goto cleanup;
return (result);
goto cleanup;
&newdsrdata) == 0) {
goto cleanup;
return (result);
return (ISC_R_SUCCESS);
if (tmplookedup)
return (ISC_R_FAILURE);
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
#if DIG_SIGCHASE_TD
isc_buffer_t b;
== ISC_R_SUCCESS) {
have_answer = true;
&name);
if (have_answer) {
goto cleanandgo;
goto cleanandgo;
if (!delegation_follow) {
goto cleanandgo;
if (have_response) {
goto cleanandgo;
goto cleanandgo;
&tmp_name);
if (have_response)
goto finalstep;
if (have_delegation_ns) {
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
goto cleanandgo;
#if DIG_SIGCHASE_BU
!= ISC_R_SUCCESS) {
return (ISC_R_ADDRNOTAVAIL);
dns_rdatatype_any, &true);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
return (ISC_R_NOTFOUND);
dns_rdatatype_ds, &true);
int ret;
#if DIG_SIGCHASE_TD
#if DIG_SIGCHASE_BU
unsigned int nblabel1;
unsigned int nblabel2;
int min_lum_label;
if (ret < 0)
else if (ret > 0)
!= ISC_R_SUCCESS) {
return (ISC_R_FAILURE);
return (ISC_R_FAILURE);
return (ISC_R_SUCCESS);
== ISC_R_SUCCESS);
return (ISC_R_FAILURE);
return (ISC_R_FAILURE);
return (ret);
!= ISC_R_SUCCESS) {
return (ISC_R_FAILURE);
return (ret);
return (ISC_R_SUCCESS);
return (ret);