Update the resolver part of libc to bind-4.9.3-beta24 level (from beta9p1)

Note that this was done by selective patching from diffs, to not conflict
with the 4.4bsd base code..  This was *not* a trivial task..  I have been
testing this code (apart from cosmetic changes) in my libc for a while now.

Obtained from: Paul Vixie <paul@vix.com>
This commit is contained in:
Peter Wemm 1995-08-20 20:03:06 +00:00
parent d58a9efd01
commit e5ad4f8712
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=10133
9 changed files with 420 additions and 215 deletions

View File

@ -3,6 +3,7 @@
# machine-independent net sources
.PATH: ${.CURDIR}/${MACHINE}/net ${.CURDIR}/net
CFLAGS+= -I${.CURDIR}/net
SRCS+= gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \
getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \
getproto.c getprotoent.c getprotoname.c getservbyname.c \

View File

@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp $";
static char rcsid[] = "$Id: gethostbydns.c,v 1.4 1995/05/30 05:40:43 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@ -61,16 +61,16 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <syslog.h>
#define BYADDR 0
#define BYNAME 1
#include <res_config.h>
#define MAXALIASES 35
#define MAXADDRS 35
@ -78,7 +78,7 @@ static char rcsid[] = "$Id: gethostbydns.c,v 1.3 1994/12/01 22:25:38 wollman Exp
#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
static const char AskedForGot[] =
"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
static char *h_addr_ptrs[MAXADDRS + 1];
@ -87,8 +87,6 @@ static char *host_aliases[MAXALIASES];
static char hostbuf[8*1024];
static struct in_addr host_addr;
static FILE *hostf = NULL;
static char hostaddr[MAXADDRS];
static char *host_addrs[2];
static int stayopen = 0;
#if PACKETSZ > 1024
@ -109,6 +107,24 @@ typedef union {
extern int h_errno;
#ifdef DEBUG
static void
dprintf(msg, num)
char *msg;
int num;
{
if (_res.options & RES_DEBUG) {
int save = errno;
printf(msg, num);
errno = save;
}
}
#else
# define dprintf(msg, num) /*nada*/
#endif
#ifdef RESOLVSORT
static void
addrsort(ap, num)
@ -122,7 +138,7 @@ addrsort(ap, num)
p = ap;
for (i = 0; i < num; i++, p++) {
for (j = 0 ; j < _res.nsort; j++)
for (j = 0 ; (unsigned)j < _res.nsort; j++)
if (_res.sort_list[j].addr.s_addr ==
(((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
break;
@ -240,7 +256,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
cp += n;
if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
"gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
"gethostby*.gethostanswer: asked for \"%s\", got CNAME for \"%s\"",
host.h_name, bp);
continue; /* XXX - had_error++ ? */
}
@ -262,9 +278,12 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
continue;
}
if (type != qtype) {
/* CNAME->PTR should not cause a log message. */
if (!(qtype == T_PTR && type == T_CNAME))
syslog(LOG_NOTICE|LOG_AUTH,
"gethostby*.getanswer: asked for type %d(%s), got %d(%s)",
qtype, qname, type, bp);
"gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
qname, p_class(qclass), p_type(qtype),
p_type(type));
cp += n;
continue; /* XXX - had_error++ ? */
}
@ -297,6 +316,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
break;
#else
host.h_name = bp;
h_errno = NETDB_SUCCESS;
return (&host);
#endif
case T_A:
@ -327,14 +347,13 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
bp += sizeof(align) - ((u_long)bp % sizeof(align));
if (bp + n >= &hostbuf[sizeof hostbuf]) {
if (_res.options & RES_DEBUG)
printf("size (%d) too big\n", n);
dprintf("size (%d) too big\n", n);
had_error++;
continue;
}
if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
if (_res.options & RES_DEBUG && !toobig++)
printf("Too many addresses (%d)\n",
if (!toobig++)
dprintf("Too many addresses (%d)\n",
MAXADDRS);
cp += n;
continue;
@ -344,7 +363,9 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
cp += n;
break;
default:
abort();
dprintf("Impossible condition (type=%d)\n", type);
h_errno = NO_RECOVERY;
return (NULL);
} /*switch*/
if (!had_error)
haveanswer++;
@ -367,6 +388,7 @@ gethostanswer(answer, anslen, qname, qclass, qtype)
strcpy(bp, qname);
host.h_name = bp;
}
h_errno = NETDB_SUCCESS;
return (&host);
} else {
h_errno = TRY_AGAIN;
@ -382,6 +404,19 @@ _gethostbydnsname(name)
register const char *cp;
int n;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
}
/*
* if there aren't any dots, it could be a user-level alias.
* this is also done in res_query() since we are not the only
* function that looks up host names.
*/
if (!strchr(name, '.') && (cp = __hostalias(name)))
name = cp;
/*
* disallow names consisting only of digits/dots, unless
* they end in a dot.
@ -400,7 +435,9 @@ _gethostbydnsname(name)
h_errno = HOST_NOT_FOUND;
return (NULL);
}
host.h_name = (char *)name;
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
host.h_name = hostbuf;
host.h_aliases = host_aliases;
host_aliases[0] = NULL;
host.h_addrtype = AF_INET;
@ -415,8 +452,7 @@ _gethostbydnsname(name)
}
if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
if (_res.options & RES_DEBUG)
printf("res_search failed\n");
dprintf("res_search failed (%d)\n", n);
return (NULL);
}
return (gethostanswer(&buf, n, name, C_IN, T_A));
@ -431,33 +467,70 @@ _gethostbydnsaddr(addr, len, type)
querybuf buf;
register struct hostent *hp;
char qbuf[MAXDNAME+1];
int o_res_options = _res.options;
#ifdef SUNSECURITY
register struct hostent *rhp;
char **haddr;
u_long old_options;
char hname2[MAXDNAME+1];
#endif /*SUNSECURITY*/
if (type != AF_INET)
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
}
if (type != AF_INET) {
errno = EAFNOSUPPORT;
h_errno = NETDB_INTERNAL;
return (NULL);
}
(void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
((unsigned)addr[3] & 0xff),
((unsigned)addr[2] & 0xff),
((unsigned)addr[1] & 0xff),
((unsigned)addr[0] & 0xff));
_res.options |= RES_RECURSE;
n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
_res.options = o_res_options;
if (n < 0) {
if (_res.options & RES_DEBUG)
printf("res_query failed\n");
dprintf("res_query failed (%d)\n", n);
return (NULL);
}
if (!(hp = gethostanswer(&buf, n, qbuf, C_IN, T_PTR)))
return (NULL); /* h_errno was set by gethostanswer() */
#ifdef SUNSECURITY
/*
* turn off search as the name should be absolute,
* 'localhost' should be matched by defnames
*/
strncpy(hname2, hp->h_name, MAXDNAME);
hname2[MAXDNAME] = '\0';
old_options = _res.options;
_res.options &= ~RES_DNSRCH;
_res.options |= RES_DEFNAMES;
if (!(rhp = gethostbyname(hname2))) {
syslog(LOG_NOTICE|LOG_AUTH,
"gethostbyaddr: No A record for %s (verifying [%s])",
hname2, inet_ntoa(*((struct in_addr *)addr)));
_res.options = old_options;
h_errno = HOST_NOT_FOUND;
return (NULL);
}
_res.options = old_options;
for (haddr = rhp->h_addr_list; *haddr; haddr++)
if (!memcmp(*haddr, addr, INADDRSZ))
break;
if (!*haddr) {
syslog(LOG_NOTICE|LOG_AUTH,
"gethostbyaddr: A record of %s != PTR record [%s]",
hname2, inet_ntoa(*((struct in_addr *)addr)));
h_errno = HOST_NOT_FOUND;
return (NULL);
}
#endif /*SUNSECURITY*/
hp->h_addrtype = type;
hp->h_length = len;
h_addr_ptrs[0] = (char *)&host_addr;
h_addr_ptrs[1] = NULL;
host_addr = *(struct in_addr *)addr;
#if BSD < 43 && !defined(h_addr) /* new-style hostent structure */
hp->h_addr = h_addr_ptrs[0];
#endif
h_errno = NETDB_SUCCESS;
return (hp);
}

View File

@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$Id: herror.c,v 1.1.1.1 1994/05/27 04:57:15 rgrimes Exp $";
static char rcsid[] = "$Id: herror.c,v 1.2 1995/05/30 05:40:49 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@ -62,8 +62,8 @@ static char rcsid[] = "$Id: herror.c,v 1.1.1.1 1994/05/27 04:57:15 rgrimes Exp $
#include <unistd.h>
#include <string.h>
char *h_errlist[] = {
"Error 0",
const char *h_errlist[] = {
"Resolver Error 0 (no error)",
"Unknown host", /* 1 HOST_NOT_FOUND */
"Host name lookup failure", /* 2 TRY_AGAIN */
"Unknown server error", /* 3 NO_RECOVERY */
@ -92,8 +92,7 @@ herror(s)
v->iov_len = 2;
v++;
}
v->iov_base = (u_int)h_errno < h_nerr ?
h_errlist[h_errno] : "Unknown error";
v->iov_base = (char *)hstrerror(h_errno);
v->iov_len = strlen(v->iov_base);
v++;
v->iov_base = "\n";
@ -101,9 +100,13 @@ herror(s)
writev(STDERR_FILENO, iov, (v - iov) + 1);
}
char *
const char *
hstrerror(err)
int err;
{
return (u_int)err < h_nerr ? h_errlist[err] : "Unknown resolver error";
if (err < 0)
return ("Resolver internal error");
else if (err < h_nerr)
return (h_errlist[err]);
return ("Unknown resolver error");
}

View File

@ -0,0 +1,7 @@
#define DEBUG /* enable debugging code (needed for dig) */
#undef ALLOW_T_UNSPEC /* enable the "unspec" RR type for old athena */
#define RESOLVSORT /* allow sorting of addresses in gethostbyname */
#undef RFC1535 /* comply with RFC1535 */
#undef ALLOW_UPDATES /* destroy your system security */
#undef USELOOPBACK /* res_init() bind to localhost */
#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */

View File

@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$Id: res_debug.c,v 1.2 1994/09/25 02:12:34 pst Exp $";
static char rcsid[] = "$Id: res_debug.c,v 1.3 1995/05/30 05:40:54 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@ -65,13 +65,17 @@ static char rcsid[] = "$Id: res_debug.c,v 1.2 1994/09/25 02:12:34 pst Exp $";
#include <stdio.h>
#include <resolv.h>
#include <string.h>
#include <netdb.h>
#include <res_config.h>
const char *_res_opcodes[] = {
"QUERY",
"IQUERY",
"CQUERYM",
"CQUERYU",
"4",
"CQUERYU", /* experimental */
"NOTIFY", /* experimental */
"5",
"6",
"7",
@ -104,12 +108,13 @@ const char *_res_resultcodes[] = {
"NOCHANGE",
};
static char retbuf[16];
/* XXX: we should use getservbyport() instead. */
static const char *
dewks(wks)
int wks;
{
static char nbuf[20];
switch (wks) {
case 5: return "rje";
case 7: return "echo";
@ -157,14 +162,17 @@ dewks(wks)
case 161: return "snmp";
case 162: return "snmp-trap";
case 170: return "print-srv";
default: (void) sprintf(retbuf, "%d", wks); return (retbuf);
default: (void) sprintf(nbuf, "%d", wks); return (nbuf);
}
}
/* XXX: we should use getprotobynumber() instead. */
static const char *
deproto(protonum)
int protonum;
{
static char nbuf[20];
switch (protonum) {
case 1: return "icmp";
case 2: return "igmp";
@ -178,13 +186,13 @@ deproto(protonum)
case 12: return "pup";
case 16: return "chaos";
case 17: return "udp";
default: (void) sprintf(retbuf, "%d", protonum); return (retbuf);
default: (void) sprintf(nbuf, "%d", protonum); return (nbuf);
}
}
static const u_char *
do_rrset(msg, cp, cnt, pflag, file, hs)
int cnt, pflag;
do_rrset(msg, len, cp, cnt, pflag, file, hs)
int cnt, pflag, len;
const u_char *cp, *msg;
const char *hs;
FILE *file;
@ -201,8 +209,19 @@ do_rrset(msg, cp, cnt, pflag, file, hs)
((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
fprintf(file, hs);
while (--n >= 0) {
if ((!_res.pfcode) || sflag) {
cp = p_rr(cp, msg, file);
if ((cp - msg) > PACKETSZ)
} else {
unsigned int dlen;
cp += __dn_skipname(cp, cp + MAXCDNAME);
cp += INT16SZ;
cp += INT16SZ;
cp += INT32SZ;
dlen = _getshort((u_char*)cp);
cp += INT16SZ;
cp += dlen;
}
if ((cp - msg) > len)
return (NULL);
}
if ((!_res.pfcode) ||
@ -253,6 +272,9 @@ __fp_nquery(msg, len, file)
register const HEADER *hp;
register int n;
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
return;
#define TruncTest(x) if (x >= endMark) goto trunc
#define ErrorTest(x) if (x == NULL) goto error
@ -282,8 +304,6 @@ __fp_nquery(msg, len, file)
fprintf(file, " rd");
if (hp->ra)
fprintf(file, " ra");
if (hp->pr)
fprintf(file, " pr");
}
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
fprintf(file, "; Ques: %d", ntohs(hp->qdcount));
@ -304,7 +324,7 @@ __fp_nquery(msg, len, file)
while (--n >= 0) {
fprintf(file,";;\t");
TruncTest(cp);
cp = p_cdname(cp, msg, file);
cp = p_cdnname(cp, msg, len, file);
ErrorTest(cp);
TruncTest(cp);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
@ -323,7 +343,7 @@ __fp_nquery(msg, len, file)
* Print authoritative answer records
*/
TruncTest(cp);
cp = do_rrset(msg, cp, hp->ancount, RES_PRF_ANS, file,
cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file,
";; ANSWERS:\n");
ErrorTest(cp);
@ -331,7 +351,7 @@ __fp_nquery(msg, len, file)
* print name server records
*/
TruncTest(cp);
cp = do_rrset(msg, cp, hp->nscount, RES_PRF_AUTH, file,
cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file,
";; AUTHORITY RECORDS:\n");
ErrorTest(cp);
@ -339,7 +359,7 @@ __fp_nquery(msg, len, file)
/*
* print additional records
*/
cp = do_rrset(msg, cp, hp->arcount, RES_PRF_ADD, file,
cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file,
";; ADDITIONAL RECORDS:\n");
ErrorTest(cp);
return;
@ -393,7 +413,7 @@ __p_fqname(cp, msg, file)
FILE *file;
{
char name[MAXDNAME];
int n, len;
int n;
if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0)
return (NULL);
@ -422,6 +442,10 @@ __p_rr(cp, msg, file)
u_int32_t tmpttl, t;
int lcnt;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
}
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL); /* compression error */
type = _getshort((u_char*)cp);
@ -434,7 +458,7 @@ __p_rr(cp, msg, file)
cp += INT16SZ;
cp1 = cp;
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
fprintf(file, "\t%lu", tmpttl);
fprintf(file, "\t%lu", (u_long)tmpttl);
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
fprintf(file, "\t%s", __p_class(class));
fprintf(file, "\t%s", __p_type(type));
@ -476,37 +500,46 @@ __p_rr(cp, msg, file)
case T_NS:
case T_PTR:
putc('\t', file);
cp = p_fqname(cp, msg, file);
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
break;
case T_HINFO:
case T_ISDN:
cp2 = cp + dlen;
if (n = *cp++) {
fprintf(file,"\t%.*s", n, cp);
cp += n;
}
if (n = *cp++) {
if ((cp < cp2) && (n = *cp++)) {
fprintf(file,"\t%.*s", n, cp);
cp += n;
}
} else if (type == T_HINFO)
fprintf(file, "\n;; *** Warning *** OS-type missing");
break;
case T_SOA:
putc('\t', file);
cp = p_fqname(cp, msg, file); /* origin */
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
putc(' ', file);
cp = p_fqname(cp, msg, file); /* mail addr */
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
fputs(" (\n", file);
t = _getlong((u_char*)cp); cp += INT32SZ;
fprintf(file,"\t\t\t%lu\t; serial\n", t);
fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t);
t = _getlong((u_char*)cp); cp += INT32SZ;
fprintf(file,"\t\t\t%lu\t; refresh (%s)\n", t, __p_time(t));
fprintf(file, "\t\t\t%lu\t; refresh (%s)\n",
(u_long)t, __p_time(t));
t = _getlong((u_char*)cp); cp += INT32SZ;
fprintf(file,"\t\t\t%lu\t; retry (%s)\n", t, __p_time(t));
fprintf(file, "\t\t\t%lu\t; retry (%s)\n",
(u_long)t, __p_time(t));
t = _getlong((u_char*)cp); cp += INT32SZ;
fprintf(file,"\t\t\t%lu\t; expire (%s)\n", t, __p_time(t));
fprintf(file, "\t\t\t%lu\t; expire (%s)\n",
(u_long)t, __p_time(t));
t = _getlong((u_char*)cp); cp += INT32SZ;
fprintf(file,"\t\t\t%lu )\t; minimum (%s)", t, __p_time(t));
fprintf(file, "\t\t\t%lu )\t; minimum (%s)",
(u_long)t, __p_time(t));
break;
case T_MX:
@ -514,7 +547,18 @@ __p_rr(cp, msg, file)
case T_RT:
fprintf(file,"\t%d ", _getshort((u_char*)cp));
cp += INT16SZ;
cp = p_fqname(cp, msg, file);
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
break;
case T_PX:
fprintf(file, "\t%d ", _getshort((u_char*)cp));
cp += INT16SZ;
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
putc(' ', file);
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
break;
case T_TXT:
@ -524,7 +568,7 @@ __p_rr(cp, msg, file)
while (cp < cp2) {
if (n = (unsigned char) *cp++) {
for (c = n; c > 0 && cp < cp2; c--)
if (*cp == '\n') {
if ((*cp == '\n') || (*cp == '"')) {
(void) putc('\\', file);
(void) putc(*cp++, file);
} else
@ -546,9 +590,11 @@ __p_rr(cp, msg, file)
case T_MINFO:
case T_RP:
putc('\t', file);
cp = p_fqname(cp, msg, file);
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
putc(' ', file);
cp = p_fqname(cp, msg, file);
if ((cp = p_fqname(cp, msg, file)) == NULL)
return (NULL);
break;
case T_UINFO:
@ -628,8 +674,6 @@ __p_rr(cp, msg, file)
return (cp);
}
static char nbuf[40];
/*
* Return a string for the type
*/
@ -637,6 +681,8 @@ const char *
__p_type(type)
int type;
{
static char nbuf[20];
switch (type) {
case T_A: return "A";
case T_NS: return "NS";
@ -652,12 +698,19 @@ __p_type(type)
case T_MINFO: return "MINFO";
case T_MX: return "MX";
case T_TXT: return "TXT";
case T_NSAP: return "NSAP";
case T_RP: return "RP";
case T_AFSDB: return "AFSDB";
case T_X25: return "X25";
case T_ISDN: return "ISDN";
case T_RT: return "RT";
case T_NSAP: return "NSAP";
case T_NSAP_PTR: return "NSAP_PTR";
case T_SIG: return "SIG";
case T_KEY: return "KEY";
case T_PX: return "PX";
case T_GPOS: return "GPOS";
case T_AAAA: return "AAAA";
case T_LOC: return "LOC";
case T_AXFR: return "AXFR";
case T_MAILB: return "MAILB";
case T_MAILA: return "MAILA";
@ -679,10 +732,12 @@ const char *
__p_class(class)
int class;
{
static char nbuf[20];
switch (class) {
case C_IN: return("IN");
case C_HS: return("HS");
case C_ANY: return("ANY");
case C_IN: return "IN";
case C_HS: return "HS";
case C_ANY: return "ANY";
default: (void)sprintf(nbuf, "%d", class); return (nbuf);
}
}
@ -694,12 +749,14 @@ const char *
__p_option(option)
u_long option;
{
static char nbuf[40];
switch (option) {
case RES_INIT: return "init";
case RES_DEBUG: return "debug";
case RES_AAONLY: return "aaonly";
case RES_AAONLY: return "aaonly(unimpl)";
case RES_USEVC: return "usevc";
case RES_PRIMARY: return "primry";
case RES_PRIMARY: return "primry(unimpl)";
case RES_IGNTC: return "igntc";
case RES_RECURSE: return "recurs";
case RES_DEFNAMES: return "defnam";
@ -707,7 +764,8 @@ __p_option(option)
case RES_DNSRCH: return "dnsrch";
case RES_INSECURE1: return "insecure1";
case RES_INSECURE2: return "insecure2";
default: sprintf(nbuf, "?0x%x?", option); return nbuf;
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
return (nbuf);
}
}
@ -718,6 +776,7 @@ char *
__p_time(value)
u_int32_t value;
{
static char nbuf[40];
int secs, mins, hours, days;
register char *p;

View File

@ -53,11 +53,12 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
static char rcsid[] = "$Id: res_init.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
static char rcsid[] = "$Id: res_init.c,v 1.4 1995/05/30 05:40:55 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
@ -69,9 +70,13 @@ static char rcsid[] = "$Id: res_init.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
#include <stdlib.h>
#include <string.h>
#include <res_config.h>
static void res_setoptions __P((char *, char *));
#ifdef RESOLVSORT
static const char sort_mask[] = "/&";
#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
static u_int32_t net_mask __P((struct in_addr));
#endif
@ -102,11 +107,12 @@ struct __res_state _res;
*
* Return 0 if completes successfully, -1 on error
*/
int
res_init()
{
register FILE *fp;
register char *cp, **pp;
register int n, dots;
register int n;
char buf[BUFSIZ];
int nserv = 0; /* number of nameserver records read from file */
int haveenv = 0;
@ -115,9 +121,12 @@ res_init()
int nsort = 0;
char *net;
#endif
#ifndef RFC1535
int dots;
#endif
/*
* These four fields used to be statically initialized. This made
* These three fields used to be statically initialized. This made
* it hard to use this code in a shared library. It is necessary,
* now that we're doing dynamic initialization here, that we preserve
* the old semantics: if an application modifies one of these three
@ -128,14 +137,27 @@ res_init()
* will follow. Zero for any of these fields would make no sense,
* so one can safely assume that the applications were already getting
* unexpected results.
*
* _res.options is tricky since some apps were known to diddle the bits
* before res_init() was first called. We can't replicate that semantic
* with dynamic initialization (they may have turned bits off that are
* set in RES_DEFAULT). Our solution is to declare such applications
* "broken". They could fool us by setting RES_INIT but none do (yet).
*/
if (!_res.retrans)
_res.retrans = RES_TIMEOUT;
if (!_res.retry)
_res.retry = 4;
if (!_res.options)
if (!(_res.options & RES_INIT))
_res.options = RES_DEFAULT;
/*
* This one used to initialize implicitly to zero, so unless the app
* has set it to something in particular, we can randomize it now.
*/
if (!_res.id)
_res.id = res_randomid();
#ifdef USELOOPBACK
_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
@ -181,14 +203,19 @@ res_init()
*pp++ = 0;
}
#define MATCH(line, name) \
(!strncmp(line, name, sizeof(name) - 1) && \
(line[sizeof(name) - 1] == ' ' || \
line[sizeof(name) - 1] == '\t'))
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
/* read the config file */
while (fgets(buf, sizeof(buf), fp) != NULL) {
/* skip comments */
if ((*buf == ';') || (*buf == '#'))
if (*buf == ';' || *buf == '#')
continue;
/* read default domain name */
if (!strncmp(buf, "domain", sizeof("domain") - 1)) {
if (MATCH(buf, "domain")) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("domain") - 1;
@ -204,7 +231,7 @@ res_init()
continue;
}
/* set search list */
if (!strncmp(buf, "search", sizeof("search") - 1)) {
if (MATCH(buf, "search")) {
if (haveenv) /* skip if have from environ */
continue;
cp = buf + sizeof("search") - 1;
@ -223,9 +250,7 @@ res_init()
cp = _res.defdname;
pp = _res.dnsrch;
*pp++ = cp;
for (n = 0;
*cp && pp < _res.dnsrch + MAXDNSRCH;
cp++) {
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
if (*cp == ' ' || *cp == '\t') {
*cp = 0;
n = 1;
@ -243,8 +268,7 @@ res_init()
continue;
}
/* read nameservers to query */
if (!strncmp(buf, "nameserver", sizeof("nameserver") - 1) &&
nserv < MAXNS) {
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
struct in_addr a;
cp = buf + sizeof("nameserver") - 1;
@ -260,7 +284,7 @@ res_init()
continue;
}
#ifdef RESOLVSORT
if (!strncmp(buf, "sortlist", sizeof("sortlist") -1)) {
if (MATCH(buf, "sortlist")) {
struct in_addr a;
cp = buf + sizeof("sortlist") - 1;
@ -270,17 +294,18 @@ res_init()
if (*cp == '\0' || *cp == '\n' || *cp == ';')
break;
net = cp;
while (*cp && *cp != '/' &&
while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
if (inet_aton(net, &a)) {
_res.sort_list[nsort].addr = a;
if (n == '/') {
if (ISSORTMASK(n)) {
*cp++ = n;
net = cp;
while (*cp && isascii(*cp) && !isspace(*cp))
while (*cp && *cp != ';' &&
isascii(*cp) && !isspace(*cp))
cp++;
n = *cp;
*cp = 0;
@ -296,12 +321,12 @@ res_init()
}
nsort++;
}
*cp++ = n;
*cp = n;
}
continue;
}
#endif
if (!strncmp(buf, "options", sizeof("options") -1)) {
if (MATCH(buf, "options")) {
res_setoptions(buf + sizeof("options") - 1, "conf");
continue;
}
@ -312,13 +337,11 @@ res_init()
_res.nsort = nsort;
#endif
(void) fclose(fp);
} /*if(fopen)*/
if (_res.defdname[0] == 0) {
if (gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
(cp = strchr(buf, '.'))) {
(void)strcpy(_res.defdname, cp + 1);
}
}
if (_res.defdname[0] == 0 &&
gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
(cp = strchr(buf, '.')) != NULL)
strcpy(_res.defdname, cp + 1);
/* find components of local domain that might be searched */
if (havesearch == 0) {
@ -333,32 +356,30 @@ res_init()
cp = _res.defdname;
while (pp < _res.dnsrch + MAXDFLSRCH) {
if (dots < LOCALDOMAINPARTS) {
if (dots < LOCALDOMAINPARTS)
break;
}
cp = strchr(cp, '.') + 1; /* we know there is one */
*pp++ = cp;
dots--;
}
*pp = NULL;
#ifdef DEBUG
if (_res.options & RES_DEBUG) {
printf(";; res_init()... default dnsrch list:\n");
for (pp = _res.dnsrch; *pp; pp++) {
for (pp = _res.dnsrch; *pp; pp++)
printf(";;\t%s\n", *pp);
}
printf(";;\t..END..\n");
}
#endif /* DEBUG */
#endif /*!RFC1535*/
}
if ((cp = getenv("RES_OPTIONS")) != NULL) {
if ((cp = getenv("RES_OPTIONS")) != NULL)
res_setoptions(cp, "env");
}
_res.options |= RES_INIT;
return (0);
}
static void
res_setoptions(options, source)
char *options, *source;
@ -366,10 +387,11 @@ res_setoptions(options, source)
char *cp = options;
int i;
if (_res.options & RES_DEBUG) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_setoptions(\"%s\", \"%s\")...\n",
options, source);
}
#endif
while (*cp) {
/* skip leading and inner runs of spaces */
while (*cp == ' ' || *cp == '\t')
@ -381,16 +403,19 @@ res_setoptions(options, source)
_res.ndots = i;
else
_res.ndots = RES_MAXNDOTS;
if (_res.options & RES_DEBUG) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";;\tndots=%d\n", _res.ndots);
}
#endif
} else if (!strncmp(cp, "debug", sizeof("debug")-1)) {
#ifdef DEBUG
if (!(_res.options & RES_DEBUG)) {
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
options, source);
_res.options |= RES_DEBUG;
}
printf(";;\tdebug\n");
#endif
} else {
/* XXX - print a warning here? */
}
@ -401,6 +426,7 @@ res_setoptions(options, source)
}
#ifdef RESOLVSORT
/* XXX - should really support CIDR which means explicit masks always. */
static u_int32_t
net_mask(in) /* XXX - should really use system's version of this */
struct in_addr in;
@ -411,7 +437,15 @@ net_mask(in) /* XXX - should really use system's version of this */
return (htonl(IN_CLASSA_NET));
else if (IN_CLASSB(i))
return (htonl(IN_CLASSB_NET));
else
return (htonl(IN_CLASSC_NET));
return (htonl(IN_CLASSC_NET));
}
#endif
u_int16_t
res_randomid()
{
struct timeval now;
gettimeofday(&now, NULL);
return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
}

View File

@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$Id: res_mkquery.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
static char rcsid[] = "$Id: res_mkquery.c,v 1.4 1995/05/30 05:40:56 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@ -63,6 +63,10 @@ static char rcsid[] = "$Id: res_mkquery.c,v 1.3 1994/09/25 17:45:39 pst Exp $";
#include <stdio.h>
#include <resolv.h>
#include <string.h>
#include <netdb.h>
#include <res_config.h>
/*
* Form all types of queries.
@ -82,12 +86,20 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
register HEADER *hp;
register u_char *cp;
register int n;
#ifdef ALLOW_UPDATES
struct rrec *newrr = (struct rrec *) newrr_in;
#endif
u_char *dnptrs[20], **dpp, **lastdnptr;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_mkquery(%d, %s, %d, %d)\n",
op, dname, class, type);
#endif
/*
* Initialize header fields.
*/
@ -97,7 +109,6 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
hp = (HEADER *) buf;
hp->id = htons(++_res.id);
hp->opcode = op;
hp->pr = (_res.options & RES_PRIMARY) != 0;
hp->rd = (_res.options & RES_RECURSE) != 0;
hp->rcode = NOERROR;
cp = buf + HFIXEDSZ;
@ -110,7 +121,8 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
* perform opcode specific processing
*/
switch (op) {
case QUERY:
case QUERY: /*FALLTHROUGH*/
case NS_NOTIFY_OP:
if ((buflen -= QFIXEDSZ) < 0)
return(-1);
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
@ -222,8 +234,9 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
}
hp->ancount = htons(0);
break;
#endif /* ALLOW_UPDATES */
default:
return (-1);
}
return (cp - buf);
}

View File

@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$Id: res_query.c,v 1.3 1994/09/25 17:45:40 pst Exp $";
static char rcsid[] = "$Id: res_query.c,v 1.4 1995/05/30 05:40:57 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@ -66,16 +66,10 @@ static char rcsid[] = "$Id: res_query.c,v 1.3 1994/09/25 17:45:40 pst Exp $";
#include <resolv.h>
#include <ctype.h>
#include <errno.h>
#if defined(BSD) && (BSD >= 199306)
# include <stdlib.h>
# include <string.h>
#else
# include "../conf/portability.h"
#endif
#include <stdlib.h>
#include <string.h>
#if defined(USE_OPTIONS_H)
# include <../conf/options.h>
#endif
#include <res_config.h>
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
@ -109,31 +103,41 @@ res_query(name, class, type, answer, anslen)
hp->rcode = NOERROR; /* default */
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query(%s, %d, %d)\n", name, class, type);
#endif
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
buf, sizeof(buf));
if (n <= 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query: mkquery failed\n");
#endif
h_errno = NO_RECOVERY;
return (n);
}
n = res_send(buf, n, answer, anslen);
if (n < 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_query: send error\n");
#endif
h_errno = TRY_AGAIN;
return (n);
}
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; rcode = %d, ancount=%d\n", hp->rcode,
ntohs(hp->ancount));
#endif
switch (hp->rcode) {
case NXDOMAIN:
h_errno = HOST_NOT_FOUND;
@ -175,22 +179,23 @@ res_search(name, class, type, answer, anslen)
int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
errno = 0;
h_errno = HOST_NOT_FOUND; /* default, if we never query */
dots = 0;
for (cp = name; *cp; cp++)
dots += (*cp == '.');
trailing_dot = 0;
if ((cp > name) && (*--cp == '.'))
if (cp > name && *--cp == '.')
trailing_dot++;
/*
* if there aren't any dots, it could be a user-level alias
*/
if ((!dots) && (cp = __hostalias(name)))
if (!dots && (cp = __hostalias(name)) != NULL)
return (res_query(cp, class, type, answer, anslen));
/*
@ -212,9 +217,8 @@ res_search(name, class, type, answer, anslen)
* - there is at least one dot, there is no trailing dot,
* and RES_DNSRCH is set.
*/
if (((!dots) && _res.options & RES_DEFNAMES) ||
(dots && (!trailing_dot) && _res.options & RES_DNSRCH)
) {
if ((!dots && (_res.options & RES_DEFNAMES)) ||
(dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
int done = 0;
for (domain = (const char * const *)_res.dnsrch;
@ -279,7 +283,6 @@ res_search(name, class, type, answer, anslen)
ret = res_querydomain(name, NULL, class, type, answer, anslen);
if (ret > 0)
return (ret);
saved_herrno = h_errno;
}
/* if we got here, we didn't satisfy the search.
@ -313,9 +316,15 @@ res_querydomain(name, domain, class, type, answer, anslen)
const char *longname = nbuf;
int n;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
#ifdef DEBUG
if (_res.options & RES_DEBUG)
printf(";; res_querydomain(%s, %s, %d, %d)\n",
name, domain?domain:"<Nil>", class, type);
#endif
if (domain == NULL) {
/*
* Check for trailing '.';
@ -327,10 +336,8 @@ res_querydomain(name, domain, class, type, answer, anslen)
nbuf[n] = '\0';
} else
longname = name;
} else {
sprintf(nbuf, "%.*s.%.*s",
MAXDNAME, name, MAXDNAME, domain);
}
} else
sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain);
return (res_query(longname, class, type, answer, anslen));
}
@ -345,22 +352,28 @@ __hostalias(name)
char buf[BUFSIZ];
static char abuf[MAXDNAME];
if (_res.options & RES_NOALIASES)
return (NULL);
file = getenv("HOSTALIASES");
if (file == NULL || (fp = fopen(file, "r")) == NULL)
return (NULL);
setbuf(fp, NULL);
buf[sizeof(buf) - 1] = '\0';
while (fgets(buf, sizeof(buf), fp)) {
for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1);
for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
;
if (!*cp1)
break;
*cp1 = '\0';
if (!strcasecmp(buf, name)) {
while (isspace(*++cp1));
while (isspace(*++cp1))
;
if (!*cp1)
break;
for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2);
for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
;
abuf[sizeof(abuf) - 1] = *cp2 = '\0';
(void)strncpy(abuf, cp1, sizeof(abuf) - 1);
strncpy(abuf, cp1, sizeof(abuf) - 1);
fclose(fp);
return (abuf);
}

View File

@ -53,7 +53,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
static char rcsid[] = "$Id: res_send.c,v 1.4 1995/05/30 05:40:58 rgrimes Exp $";
#endif /* LIBC_SCCS and not lint */
/* change this to "0"
@ -61,7 +61,7 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
* of multi-homed SunOS
* ("broken") name servers.
*/
#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */
#define CHECK_SRVR_ADDR 1 /* XXX - should be in res_config.h */
/*
* Send query to name server and wait for reply.
@ -78,8 +78,12 @@ static char rcsid[] = "$Id: res_send.c,v 1.3 1994/09/25 17:45:41 pst Exp $";
#include <stdio.h>
#include <errno.h>
#include <resolv.h>
#include <netdb.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <res_config.h>
void _res_close __P((void));
@ -87,12 +91,17 @@ static int s = -1; /* socket used for communications */
static int connected = 0; /* is the socket connected */
static int vc = 0; /* is the socket a virtual ciruit? */
#ifndef DEBUG
# define Dprint(cond, args) /*empty*/
# define DprintQ(cond, args, query, size) /*empty*/
# define Aerror(file, string, error, address) /*empty*/
# define Perror(file, string, error) /*empty*/
#else
# define Dprint(cond, args) if (cond) {fprintf args;} else {}
# define DprintQ(cond, args, query) if (cond) {\
# define DprintQ(cond, args, query, size) if (cond) {\
fprintf args;\
__p_query(query);\
__fp_nquery(query, size, stdout);\
} else {}
static void
Aerror(file, string, error, address)
FILE *file;
@ -103,15 +112,14 @@ Aerror(file, string, error, address)
int save = errno;
if (_res.options & RES_DEBUG) {
fprintf(file, "res_send: %s ([%s].%d): %s\n",
fprintf(file, "res_send: %s ([%s].%u): %s\n",
string,
inet_ntoa(address.sin_addr),
address.sin_port,
ntohs(address.sin_port),
strerror(error));
}
errno = save;
}
static void
Perror(file, string, error)
FILE *file;
@ -126,6 +134,7 @@ Perror(file, string, error)
}
errno = save;
}
#endif
static res_send_qhook Qhook = NULL;
static res_send_rhook Rhook = NULL;
@ -134,6 +143,7 @@ void
res_send_setqhook(hook)
res_send_qhook hook;
{
Qhook = hook;
}
@ -141,11 +151,12 @@ void
res_send_setrhook(hook)
res_send_rhook hook;
{
Rhook = hook;
}
/* int
* our_server(ina)
* res_isourserver(ina)
* looks up "ina" in _res.ns_addr_list[]
* returns:
* 0 : not found
@ -153,8 +164,8 @@ res_send_setrhook(hook)
* author:
* paul vixie, 29may94
*/
static int
our_server(inp)
int
res_isourserver(inp)
const struct sockaddr_in *inp;
{
struct sockaddr_in ina;
@ -177,15 +188,17 @@ our_server(inp)
}
/* int
* name_in_query(name, type, class, buf, eom)
* res_nameinquery(name, type, class, buf, eom)
* look for (name,type,class) in the query section of packet (buf,eom)
* returns:
* -1 : format error
* 0 : not found
* >0 : found
* author:
* paul vixie, 29may94
*/
static int
name_in_query(name, type, class, buf, eom)
int
res_nameinquery(name, type, class, buf, eom)
const char *name;
register int type, class;
const u_char *buf, *eom;
@ -212,16 +225,18 @@ name_in_query(name, type, class, buf, eom)
}
/* int
* queries_match(buf1, eom1, buf2, eom2)
* res_queriesmatch(buf1, eom1, buf2, eom2)
* is there a 1:1 mapping of (name,type,class)
* in (buf1,eom1) and (buf2,eom2)?
* returns:
* -1 : format error
* 0 : not a 1:1 mapping
* >0 : is a 1:1 mapping
* author:
* paul vixie, 29may94
*/
static int
queries_match(buf1, eom1, buf2, eom2)
int
res_queriesmatch(buf1, eom1, buf2, eom2)
const u_char *buf1, *eom1;
const u_char *buf2, *eom2;
{
@ -240,7 +255,7 @@ queries_match(buf1, eom1, buf2, eom2)
cp += n;
ttype = _getshort(cp); cp += INT16SZ;
tclass = _getshort(cp); cp += INT16SZ;
if (!name_in_query(tname, ttype, tclass, buf2, eom2))
if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
return (0);
}
return (1);
@ -255,21 +270,20 @@ res_send(buf, buflen, ans, anssiz)
{
HEADER *hp = (HEADER *) buf;
HEADER *anhp = (HEADER *) ans;
int gotsomewhere = 0,
connreset = 0,
terrno = ETIMEDOUT;
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
register int n;
int try, v_circuit, resplen, ns;
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
(stdout, ";; res_send()\n"), buf);
if (!(_res.options & RES_INIT)) {
if (res_init() == -1)
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
/* errno should have been set by res_init() in this case. */
return (-1);
}
DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
(stdout, ";; res_send()\n"), buf, buflen);
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
gotsomewhere = 0;
connreset = 0;
terrno = ETIMEDOUT;
badns = 0;
/*
@ -290,12 +304,8 @@ res_send(buf, buflen, ans, anssiz)
do {
res_sendhookact act;
act = (*Qhook)(&nsap,
&buf,
&buflen,
ans,
anssiz,
&resplen);
act = (*Qhook)(&nsap, &buf, &buflen,
ans, anssiz, &resplen);
switch (act) {
case res_goahead:
done = 1;
@ -338,16 +348,15 @@ res_send(buf, buflen, ans, anssiz)
if (s >= 0)
_res_close();
s = socket(AF_INET, SOCK_STREAM, PF_UNSPEC);
s = socket(PF_INET, SOCK_STREAM, 0);
if (s < 0) {
terrno = errno;
Perror(stderr, "socket(vc)", errno);
return (-1);
}
if (connect(s,
(struct sockaddr *)nsap,
sizeof(struct sockaddr))
< 0) {
errno = 0;
if (connect(s, (struct sockaddr *)nsap,
sizeof(struct sockaddr)) < 0) {
terrno = errno;
Aerror(stderr, "connect/vc",
errno, *nsap);
@ -414,8 +423,7 @@ res_send(buf, buflen, ans, anssiz)
len = resplen;
cp = ans;
while (len != 0 &&
(n = read(s, (char *)cp, (int)len)) > 0
) {
(n = read(s, (char *)cp, (int)len)) > 0) {
cp += n;
len -= n;
}
@ -433,7 +441,7 @@ res_send(buf, buflen, ans, anssiz)
anhp->tc = 1;
len = resplen - anssiz;
while (len != 0) {
char junk[512];
char junk[PACKETSZ];
n = (len > sizeof(junk)
? sizeof(junk)
@ -456,9 +464,9 @@ res_send(buf, buflen, ans, anssiz)
if ((s < 0) || vc) {
if (vc)
_res_close();
s = socket(AF_INET, SOCK_DGRAM, PF_UNSPEC);
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
bad_dg_sock: terrno = errno;
terrno = errno;
Perror(stderr, "socket(dg)", errno);
return (-1);
}
@ -485,11 +493,9 @@ res_send(buf, buflen, ans, anssiz)
* receive a response from another server.
*/
if (!connected) {
if (connect(s,
(struct sockaddr *)nsap,
if (connect(s, (struct sockaddr *)nsap,
sizeof(struct sockaddr)
) < 0
) {
) < 0) {
Aerror(stderr,
"connect(dg)",
errno, *nsap);
@ -499,7 +505,7 @@ res_send(buf, buflen, ans, anssiz)
}
connected = 1;
}
if (send(s, buf, buflen, 0) != buflen) {
if (send(s, (char*)buf, buflen, 0) != buflen) {
Perror(stderr, "send", errno);
badns |= (1<<ns);
_res_close();
@ -523,7 +529,7 @@ res_send(buf, buflen, ans, anssiz)
connected = 0;
errno = 0;
}
if (sendto(s, buf, buflen, 0,
if (sendto(s, (char*)buf, buflen, 0,
(struct sockaddr *)nsap,
sizeof(struct sockaddr))
!= buflen) {
@ -558,14 +564,14 @@ res_send(buf, buflen, ans, anssiz)
* timeout
*/
Dprint(_res.options & RES_DEBUG,
(stdout, ";; timeout\n")
);
(stdout, ";; timeout\n"));
gotsomewhere = 1;
_res_close();
goto next_ns;
}
errno = 0;
fromlen = sizeof(struct sockaddr_in);
resplen = recvfrom(s, ans, anssiz, 0,
resplen = recvfrom(s, (char*)ans, anssiz, 0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
Perror(stderr, "recvfrom", errno);
@ -582,12 +588,12 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; old answer:\n"),
ans);
ans, resplen);
goto wait;
}
#if CHECK_SRVR_ADDR
if (!(_res.options & RES_INSECURE1) &&
!our_server(&from)) {
!res_isourserver(&from)) {
/*
* response from wrong server? ignore it.
* XXX - potential security hazard could
@ -596,12 +602,12 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; not our server:\n"),
ans);
ans, resplen);
goto wait;
}
#endif
if (!(_res.options & RES_INSECURE2) &&
!queries_match(buf, buf + buflen,
!res_queriesmatch(buf, buf + buflen,
ans, ans + anssiz)) {
/*
* response contains wrong query? ignore it.
@ -611,7 +617,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; wrong query name:\n"),
ans);
ans, resplen);
goto wait;
}
if (anhp->rcode == SERVFAIL ||
@ -619,9 +625,11 @@ res_send(buf, buflen, ans, anssiz)
anhp->rcode == REFUSED) {
DprintQ(_res.options & RES_DEBUG,
(stdout, "server rejected query:\n"),
ans);
ans, resplen);
badns |= (1<<ns);
_res_close();
/* don't retry if called from dig */
if (!_res.pfcode)
goto next_ns;
}
if (!(_res.options & RES_IGNTC) && anhp->tc) {
@ -630,8 +638,7 @@ res_send(buf, buflen, ans, anssiz)
* use TCP with same server.
*/
Dprint(_res.options & RES_DEBUG,
(stdout, ";; truncated answer\n")
);
(stdout, ";; truncated answer\n"));
v_circuit = 1;
_res_close();
goto same_ns;
@ -640,7 +647,7 @@ res_send(buf, buflen, ans, anssiz)
DprintQ((_res.options & RES_DEBUG) ||
(_res.pfcode & RES_PRF_REPLY),
(stdout, ";; got answer:\n"),
ans);
ans, resplen);
/*
* If using virtual circuits, we assume that the first server
* is preferred over the rest (i.e. it is on the local
@ -659,12 +666,8 @@ res_send(buf, buflen, ans, anssiz)
do {
res_sendhookact act;
act = (*Rhook)(nsap,
buf,
buflen,
ans,
anssiz,
&resplen);
act = (*Rhook)(nsap, buf, buflen,
ans, anssiz, &resplen);
switch (act) {
case res_goahead:
case res_done:
@ -691,14 +694,13 @@ res_send(buf, buflen, ans, anssiz)
} /*foreach ns*/
} /*foreach retry*/
_res_close();
if (!v_circuit) {
if (!v_circuit)
if (!gotsomewhere)
errno = ECONNREFUSED; /* no nameservers found */
else
errno = ETIMEDOUT; /* no answer obtained */
} else {
else
errno = terrno;
}
return (-1);
}