make gethostby*() thread-safe.
This commit is contained in:
parent
7b671d902b
commit
aa2f4ec72a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=145633
@ -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;
|
||||
|
@ -71,51 +71,41 @@ __FBSDID("$FreeBSD$");
|
||||
#include <resolv.h> /* XXX */
|
||||
#include "netdb_private.h"
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static struct hostent host;
|
||||
static char *host_aliases[MAXALIASES];
|
||||
static char hostbuf[BUFSIZ+1];
|
||||
static FILE *hostf = NULL;
|
||||
static u_int32_t host_addr[4]; /* IPv4 or IPv6 */
|
||||
static char *h_addr_ptrs[2];
|
||||
static int stayopen = 0;
|
||||
|
||||
void
|
||||
_sethosthtent(f)
|
||||
int f;
|
||||
_sethosthtent(int f, struct hostent_data *hed)
|
||||
{
|
||||
if (!hostf)
|
||||
hostf = fopen(_PATH_HOSTS, "r" );
|
||||
if (!hed->hostf)
|
||||
hed->hostf = fopen(_PATH_HOSTS, "r");
|
||||
else
|
||||
rewind(hostf);
|
||||
stayopen = f;
|
||||
rewind(hed->hostf);
|
||||
hed->stayopen = f;
|
||||
}
|
||||
|
||||
void
|
||||
_endhosthtent()
|
||||
_endhosthtent(struct hostent_data *hed)
|
||||
{
|
||||
if (hostf && !stayopen) {
|
||||
(void) fclose(hostf);
|
||||
hostf = NULL;
|
||||
if (hed->hostf && !hed->stayopen) {
|
||||
(void) fclose(hed->hostf);
|
||||
hed->hostf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostent()
|
||||
int
|
||||
gethostent_r(struct hostent *he, struct hostent_data *hed)
|
||||
{
|
||||
char *p;
|
||||
char *p, *bp, *ep;
|
||||
char *cp, **q;
|
||||
int af, len;
|
||||
char hostbuf[BUFSIZ + 1];
|
||||
|
||||
if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
|
||||
if (!hed->hostf && !(hed->hostf = fopen(_PATH_HOSTS, "r"))) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (NULL);
|
||||
return -1;
|
||||
}
|
||||
again:
|
||||
if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
|
||||
if (!(p = fgets(hostbuf, sizeof hostbuf, hed->hostf))) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return (NULL);
|
||||
return -1;
|
||||
}
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
@ -125,12 +115,13 @@ gethostent()
|
||||
if (!(cp = strpbrk(p, " \t")))
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
if (inet_pton(AF_INET6, p, host_addr) > 0) {
|
||||
if (inet_pton(AF_INET6, p, hed->host_addr) > 0) {
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else if (inet_pton(AF_INET, p, host_addr) > 0) {
|
||||
} else if (inet_pton(AF_INET, p, hed->host_addr) > 0) {
|
||||
if (_res.options & RES_USE_INET6) {
|
||||
_map_v4v6_address((char*)host_addr, (char*)host_addr);
|
||||
_map_v4v6_address((char *)hed->host_addr,
|
||||
(char *)hed->host_addr);
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else {
|
||||
@ -140,30 +131,59 @@ gethostent()
|
||||
} else {
|
||||
goto again;
|
||||
}
|
||||
h_addr_ptrs[0] = (char *)host_addr;
|
||||
h_addr_ptrs[1] = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
host.h_length = len;
|
||||
host.h_addrtype = af;
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
he->h_length = len;
|
||||
he->h_addrtype = af;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
host.h_name = cp;
|
||||
q = host.h_aliases = host_aliases;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
bp = hed->hostbuf;
|
||||
ep = hed->hostbuf + sizeof hed->hostbuf;
|
||||
he->h_name = bp;
|
||||
q = he->h_aliases = hed->host_aliases;
|
||||
if ((p = strpbrk(cp, " \t")) != NULL)
|
||||
*p++ = '\0';
|
||||
len = strlen(cp) + 1;
|
||||
if (ep - bp < len) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
bp += len;
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
if (q >= &hed->host_aliases[_MAXALIASES - 1])
|
||||
break;
|
||||
if ((p = strpbrk(cp, " \t")) != NULL)
|
||||
*p++ = '\0';
|
||||
len = strlen(cp) + 1;
|
||||
if (ep - bp < len)
|
||||
break;
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
*q++ = bp;
|
||||
bp += len;
|
||||
cp = p;
|
||||
}
|
||||
*q = NULL;
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostent(void)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostent_r(&hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
}
|
||||
|
||||
int
|
||||
@ -171,27 +191,30 @@ _ht_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *name;
|
||||
int af;
|
||||
struct hostent *p;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
char **cp;
|
||||
int error;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
af = va_arg(ap, int);
|
||||
|
||||
sethostent(0);
|
||||
while ((p = gethostent()) != NULL) {
|
||||
if (p->h_addrtype != af)
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
|
||||
sethostent_r(0, hed);
|
||||
while ((error = gethostent_r(he, hed)) == 0) {
|
||||
if (he->h_addrtype != af)
|
||||
continue;
|
||||
if (strcasecmp(p->h_name, name) == 0)
|
||||
if (strcasecmp(he->h_name, name) == 0)
|
||||
break;
|
||||
for (cp = p->h_aliases; *cp != 0; cp++)
|
||||
for (cp = he->h_aliases; *cp != 0; cp++)
|
||||
if (strcasecmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
endhostent();
|
||||
*(struct hostent **)rval = p;
|
||||
|
||||
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
endhostent_r(hed);
|
||||
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
}
|
||||
|
||||
int
|
||||
@ -199,18 +222,21 @@ _ht_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
const char *addr;
|
||||
int len, af;
|
||||
struct hostent *p;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
int error;
|
||||
|
||||
addr = va_arg(ap, const char *);
|
||||
len = va_arg(ap, int);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
|
||||
sethostent(0);
|
||||
while ((p = gethostent()) != NULL)
|
||||
if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
|
||||
sethostent_r(0, hed);
|
||||
while ((error = gethostent_r(he, hed)) == 0)
|
||||
if (he->h_addrtype == af && !bcmp(he->h_addr, addr, len))
|
||||
break;
|
||||
endhostent();
|
||||
endhostent_r(hed);
|
||||
|
||||
*(struct hostent **)rval = p;
|
||||
return (p != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
}
|
||||
|
@ -366,14 +366,14 @@ function first appeared in
|
||||
.Tn BIND
|
||||
version 4.9.4.
|
||||
.Sh BUGS
|
||||
These functions use static data storage;
|
||||
These functions use a thread-specific data storage;
|
||||
if the data is needed for future use, it should be
|
||||
copied before any subsequent calls overwrite it.
|
||||
Threaded applications should never use them, as they will also conflict
|
||||
with the
|
||||
.Pp
|
||||
Though these functions are thread-safe,
|
||||
still it is recommended to use the
|
||||
.Xr getaddrinfo 3
|
||||
and
|
||||
.Xr getipnodebyname 3
|
||||
families of functions (which should be used instead).
|
||||
family of functions, instead.
|
||||
.Pp
|
||||
Only the Internet
|
||||
address format is currently understood.
|
||||
|
@ -44,27 +44,18 @@ __FBSDID("$FreeBSD$");
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
#include "netdb_private.h"
|
||||
|
||||
#ifdef YP
|
||||
static char *host_aliases[MAXALIASES];
|
||||
static uint32_t host_addr[4]; /* IPv4 or IPv6 */
|
||||
static char *host_addrs[2];
|
||||
|
||||
static struct hostent *
|
||||
_gethostbynis(name, map, af)
|
||||
const char *name;
|
||||
char *map;
|
||||
int af;
|
||||
static int
|
||||
_gethostbynis(const char *name, char *map, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
char *p, *bp, *ep;
|
||||
char *cp, **q;
|
||||
char *result;
|
||||
int resultlen, size, addrok = 0;
|
||||
static struct hostent h;
|
||||
static char *domain = (char *)NULL;
|
||||
static char ypbuf[YPMAXRECORD + 2];
|
||||
char ypbuf[YPMAXRECORD + 2];
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
@ -76,18 +67,19 @@ _gethostbynis(name, map, af)
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&domain)) {
|
||||
if (hed->yp_domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&hed->yp_domain)) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return ((struct hostent *)NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (yp_match(domain, map, name, strlen(name), &result, &resultlen)) {
|
||||
if (yp_match(hed->yp_domain, map, name, strlen(name), &result,
|
||||
&resultlen)) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return ((struct hostent *)NULL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* avoid potential memory leak */
|
||||
@ -101,46 +93,65 @@ _gethostbynis(name, map, af)
|
||||
|
||||
cp = strpbrk(result, " \t");
|
||||
*cp++ = '\0';
|
||||
h.h_addr_list = host_addrs;
|
||||
h.h_addr = (char *)host_addr;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
he->h_addr = (char *)hed->host_addr;
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
addrok = inet_aton(result, (struct in_addr *)host_addr);
|
||||
addrok = inet_aton(result, (struct in_addr *)hed->host_addr);
|
||||
break;
|
||||
case AF_INET6:
|
||||
addrok = inet_pton(af, result, host_addr);
|
||||
addrok = inet_pton(af, result, hed->host_addr);
|
||||
break;
|
||||
}
|
||||
if (addrok != 1) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
h.h_length = size;
|
||||
h.h_addrtype = af;
|
||||
he->h_addr_list[1] = NULL;
|
||||
he->h_length = size;
|
||||
he->h_addrtype = af;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
h.h_name = cp;
|
||||
q = h.h_aliases = host_aliases;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
bp = hed->hostbuf;
|
||||
ep = hed->hostbuf + sizeof hed->hostbuf;
|
||||
he->h_name = bp;
|
||||
q = he->h_aliases = hed->host_aliases;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
size = strlen(cp) + 1;
|
||||
if (ep - bp < size) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return -1;
|
||||
}
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
bp += size;
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
if (q >= &hed->host_aliases[_MAXALIASES - 1])
|
||||
break;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
size = strlen(cp) + 1;
|
||||
if (ep - bp < size)
|
||||
break;
|
||||
strlcpy(bp, cp, ep - bp);
|
||||
*q++ = bp;
|
||||
bp += size;
|
||||
cp = p;
|
||||
}
|
||||
*q = NULL;
|
||||
return (&h);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
_gethostbynisname_p(const char *name, int af)
|
||||
static int
|
||||
_gethostbynisname_r(const char *name, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
char *map;
|
||||
|
||||
@ -152,11 +163,12 @@ _gethostbynisname_p(const char *name, int af)
|
||||
map = "ipnodes.byname";
|
||||
break;
|
||||
}
|
||||
return _gethostbynis(name, map, af);
|
||||
return _gethostbynis(name, map, af, he, hed);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
_gethostbynisaddr_p(const char *addr, int len, int af)
|
||||
static int
|
||||
_gethostbynisaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
char *map;
|
||||
|
||||
@ -168,7 +180,8 @@ _gethostbynisaddr_p(const char *addr, int len, int af)
|
||||
map = "ipnodes.byaddr";
|
||||
break;
|
||||
}
|
||||
return _gethostbynis(inet_ntoa(*(struct in_addr *)addr), map, af);
|
||||
return _gethostbynis(inet_ntoa(*(struct in_addr *)addr), map, af, he,
|
||||
hed);
|
||||
}
|
||||
#endif /* YP */
|
||||
|
||||
@ -177,7 +190,15 @@ struct hostent *
|
||||
_gethostbynisname(const char *name, int af)
|
||||
{
|
||||
#ifdef YP
|
||||
return _gethostbynisname_p(name, af);
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NULL;
|
||||
}
|
||||
if (_gethostbynisname_r(name, af, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
@ -187,25 +208,37 @@ struct hostent *
|
||||
_gethostbynisaddr(const char *addr, int len, int af)
|
||||
{
|
||||
#ifdef YP
|
||||
return _gethostbynisaddr_p(addr, len, af);
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NULL;
|
||||
}
|
||||
if (_gethostbynisaddr_r(addr, len, af, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_nis_gethostbyname(void *rval, void *cb_data, va_list ap)
|
||||
{
|
||||
#ifdef YP
|
||||
const char *name;
|
||||
int af;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
int error;
|
||||
|
||||
name = va_arg(ap, const char *);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
|
||||
*(struct hostent **)rval = _gethostbynisname_p(name, af);
|
||||
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
error = _gethostbynisname_r(name, af, he, hed);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
#endif
|
||||
@ -218,13 +251,18 @@ _nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
|
||||
const char *addr;
|
||||
int len;
|
||||
int af;
|
||||
struct hostent *he;
|
||||
struct hostent_data *hed;
|
||||
int error;
|
||||
|
||||
addr = va_arg(ap, const char *);
|
||||
len = va_arg(ap, int);
|
||||
af = va_arg(ap, int);
|
||||
he = va_arg(ap, struct hostent *);
|
||||
hed = va_arg(ap, struct hostent_data *);
|
||||
|
||||
*(struct hostent **)rval =_gethostbynisaddr_p(addr, len, af);
|
||||
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
error = _gethostbynisaddr_r(addr, len, af, he, hed);
|
||||
return (error == 0) ? NS_SUCCESS : NS_NOTFOUND;
|
||||
#else
|
||||
return NS_UNAVAIL;
|
||||
#endif
|
||||
|
@ -27,6 +27,7 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include "namespace.h"
|
||||
#include "reentrant.h"
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
@ -35,6 +36,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <nsswitch.h>
|
||||
@ -51,7 +53,8 @@ extern int _dns_gethostbyaddr(void *, void *, va_list);
|
||||
extern int _nis_gethostbyaddr(void *, void *, va_list);
|
||||
extern const char *_res_hostalias(const char *, char *, size_t);
|
||||
|
||||
static struct hostent *gethostbyname_internal(const char *, int);
|
||||
static int gethostbyname_internal(const char *, int, struct hostent *,
|
||||
struct hostent_data *);
|
||||
|
||||
/* Host lookup order if nsswitch.conf is broken or nonexistant */
|
||||
static const ns_src default_src[] = {
|
||||
@ -60,47 +63,87 @@ static const ns_src default_src[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct hostent *
|
||||
gethostbyname(const char *name)
|
||||
static struct hostdata hostdata;
|
||||
static thread_key_t hostdata_key;
|
||||
static once_t hostdata_init_once = ONCE_INITIALIZER;
|
||||
static int hostdata_thr_keycreated = 0;
|
||||
|
||||
static void
|
||||
hostdata_free(void *ptr)
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct hostdata *hd = ptr;
|
||||
|
||||
if (hd == NULL)
|
||||
return;
|
||||
hd->data.stayopen = 0;
|
||||
_endhosthtent(&hd->data);
|
||||
free(hd);
|
||||
}
|
||||
|
||||
static void
|
||||
hostdata_keycreate(void)
|
||||
{
|
||||
hostdata_thr_keycreated =
|
||||
(thr_keycreate(&hostdata_key, hostdata_free) == 0);
|
||||
}
|
||||
|
||||
struct hostdata *
|
||||
__hostdata_init(void)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if (thr_main() != 0)
|
||||
return &hostdata;
|
||||
if (thr_once(&hostdata_init_once, hostdata_keycreate) != 0 ||
|
||||
!hostdata_thr_keycreated)
|
||||
return NULL;
|
||||
if ((hd = thr_getspecific(hostdata_key)) != NULL)
|
||||
return hd;
|
||||
if ((hd = calloc(1, sizeof(*hd))) == NULL)
|
||||
return NULL;
|
||||
if (thr_setspecific(hostdata_key, hd) == 0)
|
||||
return hd;
|
||||
free(hd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
gethostbyname_r(const char *name, struct hostent *he, struct hostent_data *hed)
|
||||
{
|
||||
int error;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
if (_res.options & RES_USE_INET6) {
|
||||
hp = gethostbyname_internal(name, AF_INET6);
|
||||
if (hp)
|
||||
return hp;
|
||||
error = gethostbyname_internal(name, AF_INET6, he, hed);
|
||||
if (error == 0)
|
||||
return 0;
|
||||
}
|
||||
return gethostbyname_internal(name, AF_INET);
|
||||
return gethostbyname_internal(name, AF_INET, he, hed);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname2(const char *name, int af)
|
||||
int
|
||||
gethostbyname2_r(const char *name, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
return gethostbyname_internal(name, af);
|
||||
return gethostbyname_internal(name, af, he, hed);
|
||||
}
|
||||
|
||||
static struct hostent *
|
||||
gethostbyname_internal(const char *name, int af)
|
||||
static int
|
||||
gethostbyname_internal(const char *name, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
const char *cp;
|
||||
char *bp, *ep;
|
||||
struct hostent *hp = 0;
|
||||
int size, rval;
|
||||
char abuf[MAXDNAME];
|
||||
|
||||
static struct hostent host;
|
||||
static char *h_addr_ptrs[2];
|
||||
static char *host_aliases[1];
|
||||
static char hostbuf[MAXDNAME + IN6ADDRSZ + sizeof(uint32_t)];
|
||||
static uint32_t host_addr[4]; /* IPv4 or IPv6 */
|
||||
static const ns_dtab dtab[] = {
|
||||
NS_FILES_CB(_ht_gethostbyname, NULL)
|
||||
{ NSSRC_DNS, _dns_gethostbyname, NULL },
|
||||
@ -118,11 +161,11 @@ gethostbyname_internal(const char *name, int af)
|
||||
default:
|
||||
h_errno = NETDB_INTERNAL;
|
||||
errno = EAFNOSUPPORT;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
host.h_addrtype = af;
|
||||
host.h_length = size;
|
||||
he->h_addrtype = af;
|
||||
he->h_length = size;
|
||||
|
||||
/*
|
||||
* if there aren't any dots, it could be a user-level alias.
|
||||
@ -147,24 +190,24 @@ gethostbyname_internal(const char *name, int af)
|
||||
* Fake up a hostent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, host_addr) <= 0) {
|
||||
if (inet_pton(af, name, hed->host_addr) <= 0) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
strncpy(hostbuf, name, MAXDNAME);
|
||||
hostbuf[MAXDNAME] = '\0';
|
||||
bp = hostbuf + MAXDNAME;
|
||||
ep = hostbuf + sizeof hostbuf;
|
||||
host.h_name = hostbuf;
|
||||
host.h_aliases = host_aliases;
|
||||
host_aliases[0] = NULL;
|
||||
h_addr_ptrs[0] = (char *)host_addr;
|
||||
h_addr_ptrs[1] = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
hed->hostbuf[MAXDNAME] = '\0';
|
||||
bp = hed->hostbuf + MAXDNAME + 1;
|
||||
ep = hed->hostbuf + sizeof hed->hostbuf;
|
||||
he->h_name = hed->hostbuf;
|
||||
he->h_aliases = hed->host_aliases;
|
||||
hed->host_aliases[0] = NULL;
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
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;
|
||||
}
|
||||
if (!isdigit((u_char)*cp) && *cp != '.')
|
||||
break;
|
||||
@ -180,38 +223,35 @@ gethostbyname_internal(const char *name, int af)
|
||||
* Fake up a hostent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, host_addr) <= 0) {
|
||||
if (inet_pton(af, name, hed->host_addr) <= 0) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return NULL;
|
||||
return -1;
|
||||
}
|
||||
strncpy(hostbuf, name, MAXDNAME);
|
||||
hostbuf[MAXDNAME] = '\0';
|
||||
host.h_name = hostbuf;
|
||||
host.h_aliases = host_aliases;
|
||||
host_aliases[0] = NULL;
|
||||
h_addr_ptrs[0] = (char *)host_addr;
|
||||
h_addr_ptrs[1] = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
strncpy(hed->hostbuf, name, MAXDNAME);
|
||||
hed->hostbuf[MAXDNAME] = '\0';
|
||||
he->h_name = hed->hostbuf;
|
||||
he->h_aliases = hed->host_aliases;
|
||||
hed->host_aliases[0] = NULL;
|
||||
hed->h_addr_ptrs[0] = (char *)hed->host_addr;
|
||||
hed->h_addr_ptrs[1] = NULL;
|
||||
he->h_addr_list = hed->h_addr_ptrs;
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return &host;
|
||||
return 0;
|
||||
}
|
||||
if (!isxdigit((u_char)*cp) && *cp != ':' && *cp != '.')
|
||||
break;
|
||||
}
|
||||
|
||||
rval = _nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname",
|
||||
default_src, name, af);
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_HOSTS, "gethostbyname",
|
||||
default_src, name, af, he, hed);
|
||||
|
||||
if (rval != NS_SUCCESS)
|
||||
return NULL;
|
||||
else
|
||||
return hp;
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyaddr(const char *addr, int len, int type)
|
||||
int
|
||||
gethostbyaddr_r(const char *addr, int len, int af, struct hostent *he,
|
||||
struct hostent_data *hed)
|
||||
{
|
||||
struct hostent *hp = 0;
|
||||
int rval;
|
||||
|
||||
static const ns_dtab dtab[] = {
|
||||
@ -219,28 +259,80 @@ gethostbyaddr(const char *addr, int len, int type)
|
||||
{ NSSRC_DNS, _dns_gethostbyaddr, NULL },
|
||||
NS_NIS_CB(_nis_gethostbyaddr, NULL) /* force -DHESIOD */
|
||||
{ 0 }
|
||||
};
|
||||
};
|
||||
|
||||
rval = _nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyaddr",
|
||||
default_src, addr, len, type);
|
||||
rval = _nsdispatch(NULL, dtab, NSDB_HOSTS, "gethostbyaddr",
|
||||
default_src, addr, len, af, he, hed);
|
||||
|
||||
if (rval != NS_SUCCESS)
|
||||
return NULL;
|
||||
else
|
||||
return hp;
|
||||
return (rval == NS_SUCCESS) ? 0 : -1;
|
||||
}
|
||||
|
||||
void
|
||||
sethostent(stayopen)
|
||||
int stayopen;
|
||||
sethostent_r(int stayopen, struct hostent_data *hed)
|
||||
{
|
||||
_sethosthtent(stayopen);
|
||||
_sethosthtent(stayopen, hed);
|
||||
_sethostdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endhostent()
|
||||
endhostent_r(struct hostent_data *hed)
|
||||
{
|
||||
_endhosthtent();
|
||||
_endhosthtent(hed);
|
||||
_endhostdnsent();
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname(const char *name)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostbyname_r(name, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname2(const char *name, int af)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostbyname2_r(name, af, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyaddr(const char *addr, int len, int af)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return NULL;
|
||||
if (gethostbyaddr_r(addr, len, af, &hd->host, &hd->data) != 0)
|
||||
return NULL;
|
||||
return &hd->host;
|
||||
}
|
||||
|
||||
void
|
||||
sethostent(int stayopen)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return;
|
||||
sethostent_r(stayopen, &hd->data);
|
||||
}
|
||||
|
||||
void
|
||||
endhostent(void)
|
||||
{
|
||||
struct hostdata *hd;
|
||||
|
||||
if ((hd = __hostdata_init()) == NULL)
|
||||
return;
|
||||
endhostent_r(&hd->data);
|
||||
}
|
||||
|
@ -28,13 +28,32 @@
|
||||
#ifndef _NETDB_PRIVATE_H_
|
||||
#define _NETDB_PRIVATE_H_
|
||||
|
||||
#include <sys/_types.h>
|
||||
#include <stdio.h> /* XXX: for FILE */
|
||||
|
||||
#ifndef _UINT32_T_DECLARED
|
||||
typedef __uint32_t uint32_t;
|
||||
#define _UINT32_T_DECLARED
|
||||
#endif
|
||||
|
||||
#define _MAXALIASES 35
|
||||
#define _MAXLINELEN 1024
|
||||
#define _MAXADDRS 35
|
||||
#define _HOSTBUFSIZE (8 * 1024)
|
||||
#define _NETBUFSIZE 1025
|
||||
|
||||
struct hostent_data {
|
||||
uint32_t host_addr[4]; /* IPv4 or IPv6 */
|
||||
char *h_addr_ptrs[_MAXADDRS + 1];
|
||||
char *host_aliases[_MAXALIASES];
|
||||
char hostbuf[_HOSTBUFSIZE];
|
||||
FILE *hostf;
|
||||
int stayopen;
|
||||
#ifdef YP
|
||||
char *yp_domain;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct netent_data {
|
||||
char *net_aliases[_MAXALIASES];
|
||||
char netbuf[_NETBUFSIZE];
|
||||
@ -68,6 +87,11 @@ struct servent_data {
|
||||
#endif
|
||||
};
|
||||
|
||||
struct hostdata {
|
||||
struct hostent host;
|
||||
struct hostent_data data;
|
||||
};
|
||||
|
||||
struct netdata {
|
||||
struct netent net;
|
||||
struct netent_data data;
|
||||
@ -83,9 +107,14 @@ struct servdata {
|
||||
struct servent_data data;
|
||||
};
|
||||
|
||||
#define endhostent_r __endhostent_r
|
||||
#define endnetent_r __endnetent_r
|
||||
#define endprotoent_r __endprotoent_r
|
||||
#define endservent_r __endservent_r
|
||||
#define gethostbyaddr_r __gethostbyaddr_r
|
||||
#define gethostbyname_r __gethostbyname_r
|
||||
#define gethostbyname2_r __gethostbyname2_r
|
||||
#define gethostent_r __gethostent_r
|
||||
#define getnetbyaddr_r __getnetbyaddr_r
|
||||
#define getnetbyname_r __getnetbyname_r
|
||||
#define getnetent_r __getnetent_r
|
||||
@ -95,15 +124,17 @@ struct servdata {
|
||||
#define getservbyname_r __getservbyname_r
|
||||
#define getservbyport_r __getservbyport_r
|
||||
#define getservent_r __getservent_r
|
||||
#define sethostent_r __sethostent_r
|
||||
#define setnetent_r __setnetent_r
|
||||
#define setprotoent_r __setprotoent_r
|
||||
#define setservent_r __setservent_r
|
||||
|
||||
struct hostdata *__hostdata_init(void);
|
||||
struct netdata *__netdata_init(void);
|
||||
struct protodata *__protodata_init(void);
|
||||
struct servdata *__servdata_init(void);
|
||||
void _endhostdnsent(void);
|
||||
void _endhosthtent(void);
|
||||
void _endhosthtent(struct hostent_data *);
|
||||
void _endnetdnsent(void);
|
||||
void _endnethtent(struct netent_data *);
|
||||
struct hostent *_gethostbynisaddr(const char *, int, int);
|
||||
@ -111,12 +142,19 @@ struct hostent *_gethostbynisname(const char *, int);
|
||||
void _map_v4v6_address(const char *, char *);
|
||||
void _map_v4v6_hostent(struct hostent *, char **, char **);
|
||||
void _sethostdnsent(int);
|
||||
void _sethosthtent(int);
|
||||
void _sethosthtent(int, struct hostent_data *);
|
||||
void _setnetdnsent(int);
|
||||
void _setnethtent(int, struct netent_data *);
|
||||
void endhostent_r(struct hostent_data *);
|
||||
void endnetent_r(struct netent_data *);
|
||||
void endprotoent_r(struct protoent_data *);
|
||||
void endservent_r(struct servent_data *);
|
||||
int gethostbyaddr_r(const char *, int, int, struct hostent *,
|
||||
struct hostent_data *);
|
||||
int gethostbyname_r(const char *, struct hostent *, struct hostent_data *);
|
||||
int gethostbyname2_r(const char *, int, struct hostent *,
|
||||
struct hostent_data *);
|
||||
int gethostent_r(struct hostent *, struct hostent_data *);
|
||||
int getnetbyaddr_r(unsigned long addr, int af, struct netent *,
|
||||
struct netent_data *);
|
||||
int getnetbyname_r(const char *, struct netent *, struct netent_data *);
|
||||
@ -129,6 +167,7 @@ int getservbyname_r(const char *, const char *, struct servent *,
|
||||
int getservbyport_r(int, const char *, struct servent *,
|
||||
struct servent_data *);
|
||||
int getservent_r(struct servent *, struct servent_data *);
|
||||
void sethostent_r(int, struct hostent_data *);
|
||||
void setnetent_r(int, struct netent_data *);
|
||||
void setprotoent_r(int, struct protoent_data *);
|
||||
void setservent_r(int, struct servent_data *);
|
||||
|
Loading…
Reference in New Issue
Block a user