summaryrefslogtreecommitdiffstats
path: root/lib/libc/net/gethostbydns.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/net/gethostbydns.c')
-rw-r--r--lib/libc/net/gethostbydns.c184
1 files changed, 91 insertions, 93 deletions
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c
index cc67011..63bda78 100644
--- a/lib/libc/net/gethostbydns.c
+++ b/lib/libc/net/gethostbydns.c
@@ -84,19 +84,9 @@ __FBSDID("$FreeBSD$");
#define SPRINTF(x) ((size_t)sprintf x)
-#define MAXALIASES 35
-#define MAXADDRS 35
-
static const char AskedForGot[] =
"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
-static char *h_addr_ptrs[MAXADDRS + 1];
-
-static struct hostent host;
-static char *host_aliases[MAXALIASES];
-static char hostbuf[8*1024];
-static u_char host_addr[16]; /* IPv4 or IPv6 */
-
#ifdef RESOLVSORT
static void addrsort(char **, int);
#endif
@@ -141,7 +131,7 @@ dprintf(msg, num)
cp += x; \
if (cp > eom) { \
h_errno = NO_RECOVERY; \
- return (NULL); \
+ return -1; \
} \
} while (0)
@@ -149,16 +139,13 @@ dprintf(msg, num)
do { \
if ((ptr) + (count) > eom) { \
h_errno = NO_RECOVERY; \
- return (NULL); \
+ return -1; \
} \
} while (0)
-static struct hostent *
-gethostanswer(answer, anslen, qname, qtype)
- const querybuf *answer;
- int anslen;
- const char *qname;
- int qtype;
+static int
+gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype,
+ struct hostent *he, struct hostent_data *hed)
{
const HEADER *hp;
const u_char *cp;
@@ -173,7 +160,7 @@ gethostanswer(answer, anslen, qname, qtype)
int (*name_ok)(const char *);
tname = qname;
- host.h_name = NULL;
+ he->h_name = NULL;
eom = answer->buf + anslen;
switch (qtype) {
case T_A:
@@ -185,7 +172,7 @@ gethostanswer(answer, anslen, qname, qtype)
break;
default:
h_errno = NO_RECOVERY;
- return (NULL); /* XXX should be abort(); */
+ return -1; /* XXX should be abort(); */
}
/*
* find first satisfactory answer
@@ -193,18 +180,18 @@ gethostanswer(answer, anslen, qname, qtype)
hp = &answer->hdr;
ancount = ntohs(hp->ancount);
qdcount = ntohs(hp->qdcount);
- bp = hostbuf;
- ep = hostbuf + sizeof hostbuf;
+ bp = hed->hostbuf;
+ ep = hed->hostbuf + sizeof hed->hostbuf;
cp = answer->buf;
BOUNDED_INCR(HFIXEDSZ);
if (qdcount != 1) {
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
n = dn_expand(answer->buf, eom, cp, bp, ep - bp);
if ((n < 0) || !(*name_ok)(bp)) {
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
BOUNDED_INCR(n + QFIXEDSZ);
if (qtype == T_A || qtype == T_AAAA) {
@@ -215,19 +202,19 @@ gethostanswer(answer, anslen, qname, qtype)
n = strlen(bp) + 1; /* for the \0 */
if (n >= MAXHOSTNAMELEN) {
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
- host.h_name = bp;
+ he->h_name = bp;
bp += n;
/* The qname can be abbreviated, but h_name is now absolute. */
- qname = host.h_name;
+ qname = he->h_name;
}
- ap = host_aliases;
+ ap = hed->host_aliases;
*ap = NULL;
- host.h_aliases = host_aliases;
- hap = h_addr_ptrs;
+ he->h_aliases = hed->host_aliases;
+ hap = hed->h_addr_ptrs;
*hap = NULL;
- host.h_addr_list = h_addr_ptrs;
+ he->h_addr_list = hed->h_addr_ptrs;
haveanswer = 0;
had_error = 0;
_dns_ttl_ = -1;
@@ -256,7 +243,7 @@ gethostanswer(answer, anslen, qname, qtype)
continue; /* XXX - had_error++ ? */
}
if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
- if (ap >= &host_aliases[MAXALIASES-1])
+ if (ap >= &hed->host_aliases[_MAXALIASES-1])
continue;
n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
if ((n < 0) || !(*name_ok)(tbuf)) {
@@ -266,7 +253,7 @@ gethostanswer(answer, anslen, qname, qtype)
cp += n;
if (cp != erdata) {
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
/* Store alias. */
*ap++ = bp;
@@ -283,7 +270,7 @@ gethostanswer(answer, anslen, qname, qtype)
continue;
}
strcpy(bp, tbuf);
- host.h_name = bp;
+ he->h_name = bp;
bp += n;
continue;
}
@@ -296,7 +283,7 @@ gethostanswer(answer, anslen, qname, qtype)
cp += n;
if (cp != erdata) {
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
/* Get canonical name. */
n = strlen(tbuf) + 1; /* for the \0 */
@@ -335,11 +322,11 @@ gethostanswer(answer, anslen, qname, qtype)
cp += n;
if (cp != erdata) {
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
if (!haveanswer)
- host.h_name = bp;
- else if (ap < &host_aliases[MAXALIASES-1])
+ he->h_name = bp;
+ else if (ap < &hed->host_aliases[_MAXALIASES-1])
*ap++ = bp;
else
n = -1;
@@ -353,7 +340,7 @@ gethostanswer(answer, anslen, qname, qtype)
}
break;
#else
- host.h_name = bp;
+ he->h_name = bp;
if (_res.options & RES_USE_INET6) {
n = strlen(bp) + 1; /* for the \0 */
if (n >= MAXHOSTNAMELEN) {
@@ -361,27 +348,27 @@ gethostanswer(answer, anslen, qname, qtype)
break;
}
bp += n;
- _map_v4v6_hostent(&host, &bp, &ep);
+ _map_v4v6_hostent(he, &bp, &ep);
}
h_errno = NETDB_SUCCESS;
- return (&host);
+ return 0;
#endif
case T_A:
case T_AAAA:
- if (strcasecmp(host.h_name, bp) != 0) {
+ if (strcasecmp(he->h_name, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
- AskedForGot, host.h_name, bp);
+ AskedForGot, he->h_name, bp);
cp += n;
continue; /* XXX - had_error++ ? */
}
- if (n != host.h_length) {
+ if (n != he->h_length) {
cp += n;
continue;
}
if (!haveanswer) {
int nn;
- host.h_name = bp;
+ he->h_name = bp;
nn = strlen(bp) + 1; /* for the \0 */
bp += nn;
}
@@ -393,10 +380,10 @@ gethostanswer(answer, anslen, qname, qtype)
had_error++;
continue;
}
- if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
+ if (hap >= &hed->h_addr_ptrs[_MAXADDRS-1]) {
if (!toobig++)
dprintf("Too many addresses (%d)\n",
- MAXADDRS);
+ _MAXADDRS);
cp += n;
continue;
}
@@ -405,13 +392,13 @@ gethostanswer(answer, anslen, qname, qtype)
cp += n;
if (cp != erdata) {
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
break;
default:
dprintf("Impossible condition (type=%d)\n", type);
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
/* BIND has abort() here, too risky on bad data */
}
if (!had_error)
@@ -427,46 +414,52 @@ gethostanswer(answer, anslen, qname, qtype)
* address in that case, not some random one
*/
if (_res.nsort && haveanswer > 1 && qtype == T_A)
- addrsort(h_addr_ptrs, haveanswer);
+ addrsort(hed->h_addr_ptrs, haveanswer);
# endif /*RESOLVSORT*/
- if (!host.h_name) {
+ if (!he->h_name) {
n = strlen(qname) + 1; /* for the \0 */
if (n > ep - bp || n >= MAXHOSTNAMELEN)
goto no_recovery;
strcpy(bp, qname);
- host.h_name = bp;
+ he->h_name = bp;
bp += n;
}
if (_res.options & RES_USE_INET6)
- _map_v4v6_hostent(&host, &bp, &ep);
+ _map_v4v6_hostent(he, &bp, &ep);
h_errno = NETDB_SUCCESS;
- return (&host);
+ return 0;
}
no_recovery:
h_errno = NO_RECOVERY;
- return (NULL);
+ return -1;
}
+/* XXX: for async DNS resolver in ypserv */
struct hostent *
-__dns_getanswer(answer, anslen, qname, qtype)
- const char *answer;
- int anslen;
- const char *qname;
- int qtype;
+__dns_getanswer(const char *answer, int anslen, const char *qname, int qtype)
{
- switch(qtype) {
+ struct hostdata *hd;
+ int error;
+
+ if ((hd = __hostdata_init()) == NULL) {
+ h_errno = NETDB_INTERNAL;
+ return NULL;
+ }
+ switch (qtype) {
case T_AAAA:
- host.h_addrtype = AF_INET6;
- host.h_length = IN6ADDRSZ;
+ hd->host.h_addrtype = AF_INET6;
+ hd->host.h_length = IN6ADDRSZ;
break;
case T_A:
default:
- host.h_addrtype = AF_INET;
- host.h_length = INADDRSZ;
+ hd->host.h_addrtype = AF_INET;
+ hd->host.h_length = INADDRSZ;
break;
}
- return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
+ error = gethostanswer((const querybuf *)answer, anslen, qname, qtype,
+ &hd->host, &hd->data);
+ return (error == 0) ? &hd->host : NULL;
}
int
@@ -474,12 +467,15 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
{
const char *name;
int af;
+ struct hostent *he;
+ struct hostent_data *hed;
querybuf *buf;
- int n, size, type;
+ int n, size, type, error;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
- *(struct hostent **)rval = NULL;
+ he = va_arg(ap, struct hostent *);
+ hed = va_arg(ap, struct hostent_data *);
switch (af) {
case AF_INET:
@@ -496,8 +492,8 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
return NS_UNAVAIL;
}
- host.h_addrtype = af;
- host.h_length = size;
+ he->h_addrtype = af;
+ he->h_length = size;
if ((buf = malloc(sizeof(*buf))) == NULL) {
h_errno = NETDB_INTERNAL;
@@ -513,9 +509,9 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap)
dprintf("static buffer is too small (%d)\n", n);
return (0);
}
- *(struct hostent **)rval = gethostanswer(buf, n, name, type);
+ error = gethostanswer(buf, n, name, type, he, hed);
free(buf);
- return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
+ return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
}
int
@@ -523,15 +519,17 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
{
const char *addr; /* XXX should have been def'd as u_char! */
int len, af;
+ struct hostent *he;
+ struct hostent_data *hed;
const u_char *uaddr;
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
- int n, size;
+ int n, size, error;
querybuf *buf;
- struct hostent *hp;
char qbuf[MAXDNAME+1], *qp;
#ifdef SUNSECURITY
- struct hostent *rhp;
+ struct hostdata rhd;
+ struct hostent *rhe;
char **haddr;
u_long old_options;
char hname2[MAXDNAME+1];
@@ -541,9 +539,9 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
uaddr = (const u_char *)addr;
len = va_arg(ap, int);
af = va_arg(ap, int);
-
- *(struct hostent **)rval = NULL;
-
+ he = va_arg(ap, struct hostent *);
+ hed = va_arg(ap, struct hostent_data *);
+
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return NS_UNAVAIL;
@@ -609,7 +607,7 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
dprintf("static buffer is too small (%d)\n", n);
return NS_UNAVAIL;
}
- if (!(hp = gethostanswer(buf, n, qbuf, T_PTR))) {
+ if ((error = gethostanswer(buf, n, qbuf, T_PTR, he, hed)) != 0) {
free(buf);
return NS_NOTFOUND; /* h_errno was set by gethostanswer() */
}
@@ -620,12 +618,13 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
* turn off search as the name should be absolute,
* 'localhost' should be matched by defnames
*/
- strncpy(hname2, hp->h_name, MAXDNAME);
+ strncpy(hname2, he->h_name, MAXDNAME);
hname2[MAXDNAME] = '\0';
old_options = _res.options;
_res.options &= ~RES_DNSRCH;
_res.options |= RES_DEFNAMES;
- if (!(rhp = gethostbyname(hname2))) {
+ memset(&rhd, 0, sizeof rhd);
+ if (!(rhe = gethostbyname_r(hname2, &rhd.host, &rhd.data))) {
syslog(LOG_NOTICE|LOG_AUTH,
"gethostbyaddr: No A record for %s (verifying [%s])",
hname2, inet_ntoa(*((struct in_addr *)addr)));
@@ -634,7 +633,7 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
return NS_NOTFOUND;
}
_res.options = old_options;
- for (haddr = rhp->h_addr_list; *haddr; haddr++)
+ for (haddr = rhe->h_addr_list; *haddr; haddr++)
if (!memcmp(*haddr, addr, INADDRSZ))
break;
if (!*haddr) {
@@ -646,19 +645,18 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap)
}
}
#endif /*SUNSECURITY*/
- hp->h_addrtype = af;
- hp->h_length = len;
- bcopy(addr, host_addr, len);
- h_addr_ptrs[0] = (char *)host_addr;
- h_addr_ptrs[1] = NULL;
+ he->h_addrtype = af;
+ he->h_length = len;
+ bcopy(addr, hed->host_addr, len);
+ hed->h_addr_ptrs[0] = (char *)hed->host_addr;
+ hed->h_addr_ptrs[1] = NULL;
if (af == AF_INET && (_res.options & RES_USE_INET6)) {
- _map_v4v6_address((char*)host_addr, (char*)host_addr);
- hp->h_addrtype = AF_INET6;
- hp->h_length = IN6ADDRSZ;
+ _map_v4v6_address((char*)hed->host_addr, (char*)hed->host_addr);
+ he->h_addrtype = AF_INET6;
+ he->h_length = IN6ADDRSZ;
}
h_errno = NETDB_SUCCESS;
- *(struct hostent **)rval = hp;
- return (hp != NULL) ? NS_SUCCESS : NS_NOTFOUND;
+ return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
}
#ifdef RESOLVSORT
@@ -669,7 +667,7 @@ addrsort(ap, num)
{
int i, j;
char **p;
- short aval[MAXADDRS];
+ short aval[_MAXADDRS];
int needsort = 0;
p = ap;
OpenPOWER on IntegriCloud