Date: Thu, 9 Aug 2001 16:02:24 -0400 (EDT) From: "Alexander Litvin"@FreeBSD.ORG, archer@whichever.org To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: bin/29581: proposed gethostbyXXXX_r() implementation Message-ID: <200108092002.f79K2OT19276@unknown.whichever.org>
next in thread | raw e-mail | index | archive | help
>Number: 29581
>Category: bin
>Synopsis: proposed gethostbyXXXX_r() implementation
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Aug 09 13:10:19 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Alexander Litvin
>Release: FreeBSD 5.0-CURRENT i386
>Organization:
unknown
>Environment:
System: FreeBSD unknown.whichever.org 5.0-CURRENT FreeBSD 5.0-CURRENT #2: Wed Aug 8 09:20:55 EDT 2001 root@unknown.whichever.org:/var/src/sys/i386/compile/UNKNOWN i386
>Description:
Below is a patch, which adds implementation of gethostbyname_r()
and gethostbyaddr_r() reentrant functions to FreeBSD libc.
Notes:
* Patch essentially eliminates usage of static buffers
when gethostbyXXXX_r are called.
* Also, global _res and h_errno are replaced by
function calls (similar to errno) and for threaded
applications are stored in thread-specific data
* Although all static variables relevant to gethostbyXXXX()
and resolver library were eliminated, to clame that
this implementation is thread-safe it is necessary
to check all possible code paths.
* Patch implements reentrant functions only for dns/files
configuration. In case of nis implementation is not
reentrant. This can be easily done (it looks easier
then to modify dns/files code) , but I chose to omit
this, because I have no environment to test it.
* Code was not tested on non-i386 hardware.
>How-To-Repeat:
>Fix:
----------------------------
*** src/include/netdb.h.orig Sun Jul 22 14:10:08 2001
--- src/include/netdb.h Wed Aug 8 23:26:57 2001
***************
*** 77,83 ****
#define _PATH_PROTOCOLS "/etc/protocols"
#define _PATH_SERVICES "/etc/services"
! extern int h_errno;
/*
* Structures returned by network data base library. All addresses are
--- 77,86 ----
#define _PATH_PROTOCOLS "/etc/protocols"
#define _PATH_SERVICES "/etc/services"
! __BEGIN_DECLS
! int * __h_errno_accessor __P((void));
! __END_DECLS
! #define h_errno (* __h_errno_accessor())
/*
* Structures returned by network data base library. All addresses are
***************
*** 244,249 ****
--- 247,263 ----
char *gai_strerror __P((int));
void setnetgrent __P((const char *));
void setservent __P((int));
+
+ struct hostent *gethostbyaddr_r __P((const char *, int, int, struct hostent *,
+ char *, int, int *));
+ struct hostent *gethostbyname_r __P((const char *, struct hostent *,
+ char *, int, int *));
+ struct hostent *gethostbyname2_r __P((const char *, int, struct hostent *,
+ char *, int, int *));
+ struct hostent *gethostent_r __P((struct hostent *, char *, int));
+
+ #define CAST_ALIGN(ptr, type) \
+ (char*)(type)ptr<(char*)ptr?((type)ptr)+1:(type)ptr
/*
* PRIVATE functions specific to the FreeBSD implementation
*** src/include/resolv.h.orig Sun Jun 10 16:25:21 2001
--- src/include/resolv.h Wed Aug 8 23:26:57 2001
***************
*** 198,206 ****
char * humanname; /* Its fun name, like "mail exchanger" */
};
! extern struct __res_state _res;
/* for INET6 */
! extern struct __res_state_ext _res_ext;
extern const struct res_sym __p_class_syms[];
extern const struct res_sym __p_type_syms[];
--- 198,206 ----
char * humanname; /* Its fun name, like "mail exchanger" */
};
! /*extern struct __res_state _res;*/
/* for INET6 */
! /*extern struct __res_state_ext _res_ext;*/
extern const struct res_sym __p_class_syms[];
extern const struct res_sym __p_type_syms[];
***************
*** 224,229 ****
--- 224,230 ----
#define fp_query __fp_query
#define fp_nquery __fp_nquery
#define hostalias __hostalias
+ #define hostalias_r __hostalias_r
#define putlong __putlong
#define putshort __putshort
#define p_class __p_class
***************
*** 273,278 ****
--- 274,280 ----
void fp_query __P((const u_char *, FILE *));
void fp_nquery __P((const u_char *, int, FILE *));
const char * hostalias __P((const char *));
+ const char * hostalias_r __P((const char *, char *, int));
void putlong __P((u_int32_t, u_char *));
void putshort __P((u_int16_t, u_char *));
const char * p_class __P((int));
***************
*** 316,320 ****
--- 318,344 ----
void res_freeupdrec __P((ns_updrec *));
#endif
__END_DECLS
+
+ struct __res_data {
+ int h_errno_res;
+ int s; /* socket used for communications */
+ int connected : 1; /* is the socket connected */
+ int vc : 1; /* is the socket a virtual circuit? */
+ int af; /* address family of socket */
+ res_send_qhook Qhook;
+ res_send_rhook Rhook;
+ FILE* hostf;
+ int stayopen;
+ struct __res_state *res;
+ struct __res_state_ext *res_ext;
+ };
+
+ __BEGIN_DECLS
+ struct __res_data * __res_data_accessor __P((void));
+ struct __res_state * __res_accessor __P((void));
+ __END_DECLS
+ #define _res_data (* __res_data_accessor())
+ #define _res (* __res_accessor())
+ #define _res_ext (* (__res_data_accessor()->res_ext))
#endif /* !_RESOLV_H_ */
*** src/lib/libc/net/getaddrinfo.c.orig Sun Jun 10 16:25:23 2001
--- src/lib/libc/net/getaddrinfo.c Wed Aug 8 23:26:57 2001
***************
*** 1668,1674 ****
/* resolver logic */
extern const char *__hostalias __P((const char *));
- extern int h_errno;
/*
* Formulate a normal query, send, and await answer.
--- 1668,1673 ----
*** src/lib/libc/net/gethostbydns.c.orig Wed Sep 6 14:16:40 2000
--- src/lib/libc/net/gethostbydns.c Wed Aug 8 23:26:57 2001
***************
*** 88,98 ****
"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 __P((char **, int));
--- 88,98 ----
"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
static char *h_addr_ptrs[MAXADDRS + 1];
static char *host_aliases[MAXALIASES];
! static struct hostent host_s = { NULL, host_aliases, 0, 0, h_addr_ptrs };
!
! static char hostbuf_s[8*1024];
! static u_char host_addr_s[16]; /* IPv4 or IPv6 */
#ifdef RESOLVSORT
static void addrsort __P((char **, int));
***************
*** 114,120 ****
char ac;
} align;
- extern int h_errno;
int _dns_ttl_;
#ifdef DEBUG
--- 114,119 ----
***************
*** 152,162 ****
} while (0)
static struct hostent *
! gethostanswer(answer, anslen, qname, qtype)
const querybuf *answer;
int anslen;
const char *qname;
int qtype;
{
register const HEADER *hp;
register const u_char *cp;
--- 151,164 ----
} while (0)
static struct hostent *
! gethostanswer(answer, anslen, qname, qtype, host, hostbuf, hostbuflen)
const querybuf *answer;
int anslen;
const char *qname;
int qtype;
+ struct hostent *host;
+ char *hostbuf;
+ int hostbuflen;
{
register const HEADER *hp;
register const u_char *cp;
***************
*** 171,177 ****
int (*name_ok) __P((const char *));
tname = qname;
! host.h_name = NULL;
eom = answer->buf + anslen;
switch (qtype) {
case T_A:
--- 173,179 ----
int (*name_ok) __P((const char *));
tname = qname;
! host->h_name = NULL;
eom = answer->buf + anslen;
switch (qtype) {
case T_A:
***************
*** 192,198 ****
ancount = ntohs(hp->ancount);
qdcount = ntohs(hp->qdcount);
bp = hostbuf;
! buflen = sizeof hostbuf;
cp = answer->buf;
BOUNDED_INCR(HFIXEDSZ);
if (qdcount != 1) {
--- 194,200 ----
ancount = ntohs(hp->ancount);
qdcount = ntohs(hp->qdcount);
bp = hostbuf;
! buflen = hostbuflen;
cp = answer->buf;
BOUNDED_INCR(HFIXEDSZ);
if (qdcount != 1) {
***************
*** 215,232 ****
h_errno = NO_RECOVERY;
return (NULL);
}
! host.h_name = bp;
bp += n;
buflen -= n;
/* The qname can be abbreviated, but h_name is now absolute. */
! qname = host.h_name;
}
! ap = host_aliases;
*ap = NULL;
! host.h_aliases = host_aliases;
! hap = h_addr_ptrs;
*hap = NULL;
- host.h_addr_list = h_addr_ptrs;
haveanswer = 0;
had_error = 0;
_dns_ttl_ = -1;
--- 217,232 ----
h_errno = NO_RECOVERY;
return (NULL);
}
! host->h_name = bp;
bp += n;
buflen -= n;
/* The qname can be abbreviated, but h_name is now absolute. */
! qname = host->h_name;
}
! ap = host->h_aliases;
*ap = NULL;
! hap = host->h_addr_list;
*hap = NULL;
haveanswer = 0;
had_error = 0;
_dns_ttl_ = -1;
***************
*** 255,261 ****
continue; /* XXX - had_error++ ? */
}
if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
! if (ap >= &host_aliases[MAXALIASES-1])
continue;
n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
if ((n < 0) || !(*name_ok)(tbuf)) {
--- 255,261 ----
continue; /* XXX - had_error++ ? */
}
if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
! if (ap >= &host->h_aliases[MAXALIASES-1])
continue;
n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
if ((n < 0) || !(*name_ok)(tbuf)) {
***************
*** 283,289 ****
continue;
}
strcpy(bp, tbuf);
! host.h_name = bp;
bp += n;
buflen -= n;
continue;
--- 283,289 ----
continue;
}
strcpy(bp, tbuf);
! host->h_name = bp;
bp += n;
buflen -= n;
continue;
***************
*** 340,347 ****
return (NULL);
}
if (!haveanswer)
! host.h_name = bp;
! else if (ap < &host_aliases[MAXALIASES-1])
*ap++ = bp;
else
n = -1;
--- 340,347 ----
return (NULL);
}
if (!haveanswer)
! host->h_name = bp;
! else if (ap < &host->h_aliases[MAXALIASES-1])
*ap++ = bp;
else
n = -1;
***************
*** 356,362 ****
}
break;
#else
! host.h_name = bp;
if (_res.options & RES_USE_INET6) {
n = strlen(bp) + 1; /* for the \0 */
if (n >= MAXHOSTNAMELEN) {
--- 356,362 ----
}
break;
#else
! host->h_name = bp;
if (_res.options & RES_USE_INET6) {
n = strlen(bp) + 1; /* for the \0 */
if (n >= MAXHOSTNAMELEN) {
***************
*** 365,391 ****
}
bp += n;
buflen -= n;
! _map_v4v6_hostent(&host, &bp, &buflen);
}
h_errno = NETDB_SUCCESS;
! return (&host);
#endif
case T_A:
case T_AAAA:
! if (strcasecmp(host.h_name, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
! AskedForGot, host.h_name, bp);
cp += n;
continue; /* XXX - had_error++ ? */
}
! if (n != host.h_length) {
cp += n;
continue;
}
if (!haveanswer) {
register int nn;
! host.h_name = bp;
nn = strlen(bp) + 1; /* for the \0 */
bp += nn;
buflen -= nn;
--- 365,391 ----
}
bp += n;
buflen -= n;
! _map_v4v6_hostent(host, &bp, &buflen);
}
h_errno = NETDB_SUCCESS;
! return (host);
#endif
case T_A:
case T_AAAA:
! if (strcasecmp(host->h_name, bp) != 0) {
syslog(LOG_NOTICE|LOG_AUTH,
! AskedForGot, host->h_name, bp);
cp += n;
continue; /* XXX - had_error++ ? */
}
! if (n != host->h_length) {
cp += n;
continue;
}
if (!haveanswer) {
register int nn;
! host->h_name = bp;
nn = strlen(bp) + 1; /* for the \0 */
bp += nn;
buflen -= nn;
***************
*** 393,404 ****
bp += sizeof(align) - ((u_long)bp % sizeof(align));
! if (bp + n >= &hostbuf[sizeof hostbuf]) {
dprintf("size (%d) too big\n", n);
had_error++;
continue;
}
! if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
if (!toobig++)
dprintf("Too many addresses (%d)\n",
MAXADDRS);
--- 393,404 ----
bp += sizeof(align) - ((u_long)bp % sizeof(align));
! if (bp + n >= &hostbuf[hostbuflen]) {
dprintf("size (%d) too big\n", n);
had_error++;
continue;
}
! if (hap >= &host->h_addr_list[MAXADDRS-1]) {
if (!toobig++)
dprintf("Too many addresses (%d)\n",
MAXADDRS);
***************
*** 433,453 ****
* address in that case, not some random one
*/
if (_res.nsort && haveanswer > 1 && qtype == T_A)
! addrsort(h_addr_ptrs, haveanswer);
# endif /*RESOLVSORT*/
! if (!host.h_name) {
n = strlen(qname) + 1; /* for the \0 */
if (n > buflen || n >= MAXHOSTNAMELEN)
goto no_recovery;
strcpy(bp, qname);
! host.h_name = bp;
bp += n;
buflen -= n;
}
if (_res.options & RES_USE_INET6)
! _map_v4v6_hostent(&host, &bp, &buflen);
h_errno = NETDB_SUCCESS;
! return (&host);
}
no_recovery:
h_errno = NO_RECOVERY;
--- 433,453 ----
* address in that case, not some random one
*/
if (_res.nsort && haveanswer > 1 && qtype == T_A)
! addrsort(host->h_addr_list, haveanswer);
# endif /*RESOLVSORT*/
! if (!host->h_name) {
n = strlen(qname) + 1; /* for the \0 */
if (n > buflen || n >= MAXHOSTNAMELEN)
goto no_recovery;
strcpy(bp, qname);
! host->h_name = bp;
bp += n;
buflen -= n;
}
if (_res.options & RES_USE_INET6)
! _map_v4v6_hostent(host, &bp, &buflen);
h_errno = NETDB_SUCCESS;
! return (host);
}
no_recovery:
h_errno = NO_RECOVERY;
***************
*** 461,479 ****
const char *qname;
int qtype;
{
switch(qtype) {
case T_AAAA:
! host.h_addrtype = AF_INET6;
! host.h_length = IN6ADDRSZ;
break;
case T_A:
default:
! host.h_addrtype = AF_INET;
! host.h_length = INADDRSZ;
break;
}
! return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
}
int
--- 461,484 ----
const char *qname;
int qtype;
{
+ struct hostent *host = &host_s;
+ char *hostbuf = hostbuf_s;
+ int hostbuflen = sizeof hostbuf_s;
+
switch(qtype) {
case T_AAAA:
! host->h_addrtype = AF_INET6;
! host->h_length = IN6ADDRSZ;
break;
case T_A:
default:
! host->h_addrtype = AF_INET;
! host->h_length = INADDRSZ;
break;
}
! return(gethostanswer((const querybuf *)answer, anslen, qname, qtype,
! host, hostbuf, hostbuflen));
}
int
***************
*** 481,495 ****
--- 486,543 ----
{
const char *name;
int af;
+ struct hostent *host;
+ char *hostbuf;
+ int hostbuflen;
+ u_char *host_addr;
querybuf buf;
register const char *cp;
char *bp;
int n, size, type, len;
+ char abuf[MAXDNAME];
name = va_arg(ap, const char *);
af = va_arg(ap, int);
+ host = va_arg(ap, struct hostent *);
+ hostbuf = va_arg(ap, char*);
+ hostbuflen = va_arg(ap, int);
*(struct hostent **)rval = NULL;
+ /* XXX */
+ printf("gethostbyname %s\n",name);
+
+ if(hostbuflen!=0 && hostbuf != NULL && host != NULL) {
+ host->h_aliases = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_aliases + sizeof(char*[MAXALIASES]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host->h_addr_list = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_addr_list + sizeof(char*[MAXADDRS + 1]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host_addr = hostbuf;
+ bp = (char*)host_addr + sizeof(u_char[16]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < MAXDNAME+1) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ } else {
+ host = &host_s;
+ hostbuf = hostbuf_s;
+ hostbuflen = sizeof hostbuf_s;
+ host_addr = host_addr_s;
+ }
+
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return NS_UNAVAIL;
***************
*** 510,524 ****
return NS_UNAVAIL;
}
! host.h_addrtype = af;
! host.h_length = size;
/*
* 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;
/*
--- 558,572 ----
return NS_UNAVAIL;
}
! host->h_addrtype = af;
! host->h_length = size;
/*
* 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_r(name, abuf, sizeof abuf)))
name = cp;
/*
***************
*** 542,558 ****
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
bp = hostbuf + MAXDNAME;
! len = sizeof hostbuf - MAXDNAME;
! 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;
if (_res.options & RES_USE_INET6)
! _map_v4v6_hostent(&host, &bp, &len);
h_errno = NETDB_SUCCESS;
! *(struct hostent **)rval = &host;
return NS_SUCCESS;
}
if (!isdigit((unsigned char)*cp) && *cp != '.')
--- 590,604 ----
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
bp = hostbuf + MAXDNAME;
! len = hostbuflen - MAXDNAME;
! host->h_name = hostbuf;
! host->h_aliases[0] = NULL;
! host->h_addr_list[0] = (char *)host_addr;
! host->h_addr_list[1] = NULL;
if (_res.options & RES_USE_INET6)
! _map_v4v6_hostent(host, &bp, &len);
h_errno = NETDB_SUCCESS;
! *(struct hostent **)rval = host;
return NS_SUCCESS;
}
if (!isdigit((unsigned char)*cp) && *cp != '.')
***************
*** 576,590 ****
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
bp = hostbuf + MAXDNAME;
! len = sizeof hostbuf - MAXDNAME;
! 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;
h_errno = NETDB_SUCCESS;
! *(struct hostent **)rval = &host;
return NS_SUCCESS;
}
if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.')
--- 622,634 ----
strncpy(hostbuf, name, MAXDNAME);
hostbuf[MAXDNAME] = '\0';
bp = hostbuf + MAXDNAME;
! len = hostbuflen - MAXDNAME;
! host->h_name = hostbuf;
! host->h_aliases[0] = NULL;
! host->h_addr_list[0] = (char *)host_addr;
! host->h_addr_list[1] = NULL;
h_errno = NETDB_SUCCESS;
! *(struct hostent **)rval = host;
return NS_SUCCESS;
}
if (!isxdigit((unsigned char)*cp) && *cp != ':' && *cp != '.')
***************
*** 595,601 ****
dprintf("res_search failed (%d)\n", n);
return NS_UNAVAIL;
}
! *(struct hostent **)rval = gethostanswer(&buf, n, name, type);
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
--- 639,646 ----
dprintf("res_search failed (%d)\n", n);
return NS_UNAVAIL;
}
! *(struct hostent **)rval = gethostanswer(&buf, n, name, type,
! host, hostbuf, hostbuflen);
return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
}
***************
*** 604,609 ****
--- 649,658 ----
{
const char *addr; /* XXX should have been def'd as u_char! */
int len, af;
+ struct hostent *host;
+ char *hostbuf;
+ int hostbuflen;
+ char *bp;
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 };
***************
*** 617,630 ****
u_long old_options;
char hname2[MAXDNAME+1];
#endif /*SUNSECURITY*/
addr = va_arg(ap, const char *);
uaddr = (const u_char *)addr;
len = va_arg(ap, int);
af = va_arg(ap, int);
!
*(struct hostent **)rval = NULL;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return NS_UNAVAIL;
--- 666,713 ----
u_long old_options;
char hname2[MAXDNAME+1];
#endif /*SUNSECURITY*/
+ u_char *host_addr = host_addr_s;
addr = va_arg(ap, const char *);
uaddr = (const u_char *)addr;
len = va_arg(ap, int);
af = va_arg(ap, int);
! host = va_arg(ap, struct hostent *);
! hostbuf = va_arg(ap, char*);
! hostbuflen = va_arg(ap, int);
*(struct hostent **)rval = NULL;
+ if(hostbuflen!=0 && hostbuf != NULL && host != NULL) {
+ host->h_aliases = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_aliases + sizeof(char*[MAXALIASES]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host->h_addr_list = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_addr_list + sizeof(char*[MAXADDRS + 1]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host_addr = hostbuf;
+ bp = (char*)host_addr + sizeof(u_char[16]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < MAXDNAME+1) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ } else {
+ host = &host_s;
+ hostbuf = hostbuf_s;
+ hostbuflen = sizeof hostbuf_s;
+ }
+
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return NS_UNAVAIL;
***************
*** 684,690 ****
dprintf("static buffer is too small (%d)\n", n);
return NS_UNAVAIL;
}
! if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR)))
return NS_NOTFOUND; /* h_errno was set by gethostanswer() */
#ifdef SUNSECURITY
if (af == AF_INET) {
--- 767,773 ----
dprintf("static buffer is too small (%d)\n", n);
return NS_UNAVAIL;
}
! if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR, host, hostbuf, hostbuflen)))
return NS_NOTFOUND; /* h_errno was set by gethostanswer() */
#ifdef SUNSECURITY
if (af == AF_INET) {
***************
*** 721,728 ****
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;
if (af == AF_INET && (_res.options & RES_USE_INET6)) {
_map_v4v6_address((char*)host_addr, (char*)host_addr);
hp->h_addrtype = AF_INET6;
--- 804,811 ----
hp->h_addrtype = af;
hp->h_length = len;
bcopy(addr, host_addr, len);
! host->h_addr_list[0] = (char *)host_addr;
! host->h_addr_list[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;
*** src/lib/libc/net/gethostbyht.c.orig Wed Jan 24 08:00:26 2001
--- src/lib/libc/net/gethostbyht.c Wed Aug 8 23:26:57 2001
***************
*** 71,117 ****
#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;
{
! if (!hostf)
! hostf = fopen(_PATH_HOSTS, "r" );
else
! rewind(hostf);
! stayopen = f;
}
void
_endhosthtent()
{
! if (hostf && !stayopen) {
! (void) fclose(hostf);
! hostf = NULL;
}
}
struct hostent *
gethostent()
{
char *p;
register char *cp, **q;
int af, len;
! if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
h_errno = NETDB_INTERNAL;
return (NULL);
}
again:
! if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
h_errno = HOST_NOT_FOUND;
return (NULL);
}
--- 71,122 ----
#define MAXALIASES 35
static char *h_addr_ptrs[2];
! static char *host_aliases[MAXALIASES];
! static struct hostent host_s = { NULL, host_aliases, 0, 0, h_addr_ptrs };
!
! static char hostbuf_s[BUFSIZ+1];
! static u_int32_t host_addr_s[4]; /* IPv4 or IPv6 */
void
_sethosthtent(f)
int f;
{
! if (!_res_data.hostf)
! _res_data.hostf = fopen(_PATH_HOSTS, "r" );
else
! rewind(_res_data.hostf);
! _res_data.stayopen = f;
}
void
_endhosthtent()
{
! if (_res_data.hostf && !_res_data.stayopen) {
! (void) fclose(_res_data.hostf);
! _res_data.hostf = NULL;
}
}
struct hostent *
gethostent()
{
+ return (gethostent_r(&host_s, hostbuf_s, sizeof hostbuf_s));
+ }
+
+ struct hostent *
+ gethostent_r(struct hostent *host, char *hostbuf, int hostbuflen)
+ {
char *p;
register char *cp, **q;
int af, len;
! if (!_res_data.hostf && !(_res_data.hostf = fopen(_PATH_HOSTS, "r" ))) {
h_errno = NETDB_INTERNAL;
return (NULL);
}
again:
! if (!(p = fgets(hostbuf, hostbuflen, _res_data.hostf))) {
h_errno = HOST_NOT_FOUND;
return (NULL);
}
***************
*** 123,134 ****
if (!(cp = strpbrk(p, " \t")))
goto again;
*cp++ = '\0';
! if (inet_pton(AF_INET6, p, host_addr) > 0) {
af = AF_INET6;
len = IN6ADDRSZ;
! } else if (inet_pton(AF_INET, p, host_addr) > 0) {
if (_res.options & RES_USE_INET6) {
! _map_v4v6_address((char*)host_addr, (char*)host_addr);
af = AF_INET6;
len = IN6ADDRSZ;
} else {
--- 128,139 ----
if (!(cp = strpbrk(p, " \t")))
goto again;
*cp++ = '\0';
! if (inet_pton(AF_INET6, p, host->h_addr_list[0]) > 0) {
af = AF_INET6;
len = IN6ADDRSZ;
! } else if (inet_pton(AF_INET, p, host->h_addr_list[0]) > 0) {
if (_res.options & RES_USE_INET6) {
! _map_v4v6_address(host->h_addr_list[0], host->h_addr_list[0]);
af = AF_INET6;
len = IN6ADDRSZ;
} else {
***************
*** 138,152 ****
} 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;
while (*cp == ' ' || *cp == '\t')
cp++;
! host.h_name = cp;
! q = host.h_aliases = host_aliases;
if ((cp = strpbrk(cp, " \t")) != NULL)
*cp++ = '\0';
while (cp && *cp) {
--- 143,154 ----
} else {
goto again;
}
! host->h_length = len;
! host->h_addrtype = af;
while (*cp == ' ' || *cp == '\t')
cp++;
! host->h_name = cp;
! q = host->h_aliases;
if ((cp = strpbrk(cp, " \t")) != NULL)
*cp++ = '\0';
while (cp && *cp) {
***************
*** 154,167 ****
cp++;
continue;
}
! if (q < &host_aliases[MAXALIASES - 1])
*q++ = cp;
if ((cp = strpbrk(cp, " \t")) != NULL)
*cp++ = '\0';
}
*q = NULL;
h_errno = NETDB_SUCCESS;
! return (&host);
}
int
--- 156,169 ----
cp++;
continue;
}
! if (q < &host->h_aliases[MAXALIASES - 1])
*q++ = cp;
if ((cp = strpbrk(cp, " \t")) != NULL)
*cp++ = '\0';
}
*q = NULL;
h_errno = NETDB_SUCCESS;
! return (host);
}
int
***************
*** 169,182 ****
{
const char *name;
int af;
register struct hostent *p;
register char **cp;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
sethostent(0);
! while ((p = gethostent()) != NULL) {
if (p->h_addrtype != af)
continue;
if (strcasecmp(p->h_name, name) == 0)
--- 171,226 ----
{
const char *name;
int af;
+ struct hostent *host;
+ char *hostbuf, *bp;
+ int hostbuflen;
+ u_int32_t *host_addr;
register struct hostent *p;
register char **cp;
name = va_arg(ap, const char *);
af = va_arg(ap, int);
+ host = va_arg(ap, struct hostent *);
+ hostbuf = va_arg(ap, char*);
+ hostbuflen = va_arg(ap, int);
+ if(hostbuflen!=0 && hostbuf != NULL && host != NULL) {
+ host->h_aliases = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_aliases + sizeof(char*[MAXALIASES]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host->h_addr_list = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_addr_list + sizeof(char*[2]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host_addr = CAST_ALIGN(hostbuf, u_int32_t*);
+ bp = (char*)host_addr + sizeof(u_int32_t[4]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < BUFSIZ+1) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ } else {
+ host = &host_s;
+ hostbuf = hostbuf_s;
+ hostbuflen = sizeof hostbuf_s;
+ host_addr = host_addr_s;
+ }
+
+ host->h_addr_list[0] = (char *)host_addr;
+ host->h_addr_list[1] = NULL;
+
sethostent(0);
! while ((p = gethostent_r(host, hostbuf, hostbuflen)) != NULL) {
if (p->h_addrtype != af)
continue;
if (strcasecmp(p->h_name, name) == 0)
***************
*** 197,210 ****
{
const char *addr;
int len, af;
register struct hostent *p;
addr = va_arg(ap, const char *);
len = va_arg(ap, int);
af = va_arg(ap, int);
sethostent(0);
! while ((p = gethostent()) != NULL)
if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
break;
endhostent();
--- 241,296 ----
{
const char *addr;
int len, af;
+ struct hostent *host;
+ char *hostbuf, *bp;
+ int hostbuflen;
+ u_int32_t *host_addr;
register struct hostent *p;
addr = va_arg(ap, const char *);
len = va_arg(ap, int);
af = va_arg(ap, int);
+ host = va_arg(ap, struct hostent *);
+ hostbuf = va_arg(ap, char*);
+ hostbuflen = va_arg(ap, int);
+
+ if(hostbuflen!=0 && hostbuf != NULL && host != NULL) {
+ host->h_aliases = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_aliases + sizeof(char*[MAXALIASES]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host->h_addr_list = CAST_ALIGN(hostbuf, char**);
+ bp = (char*)host->h_addr_list + sizeof(char*[2]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < 0) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ host_addr = CAST_ALIGN(hostbuf, u_int32_t*);
+ bp = (char*)host_addr + sizeof(u_int32_t[4]);
+ hostbuflen -= (bp - hostbuf);
+ hostbuf = bp;
+ if(hostbuflen < BUFSIZ+1) {
+ h_errno = NO_RECOVERY;
+ return NS_UNAVAIL;
+ }
+ } else {
+ host = &host_s;
+ hostbuf = hostbuf_s;
+ hostbuflen = sizeof hostbuf_s;
+ host_addr = host_addr_s;
+ }
+
+ host->h_addr_list[0] = (char *)host_addr;
+ host->h_addr_list[1] = NULL;
sethostent(0);
! while ((p = gethostent_r(host,hostbuf,hostbuflen)) != NULL)
if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
break;
endhostent();
*** src/lib/libc/net/gethostnamadr.c.orig Wed Jan 24 08:00:26 2001
--- src/lib/libc/net/gethostnamadr.c Wed Aug 8 23:26:57 2001
***************
*** 56,79 ****
};
struct hostent *
! gethostbyname(const char *name)
{
struct hostent *hp;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
! h_errno = NETDB_INTERNAL;
return (NULL);
}
if (_res.options & RES_USE_INET6) { /* XXX */
! hp = gethostbyname2(name, AF_INET6); /* XXX */
if (hp) /* XXX */
return (hp); /* XXX */
} /* XXX */
! return (gethostbyname2(name, AF_INET));
}
struct hostent *
! gethostbyname2(const char *name, int type)
{
struct hostent *hp = 0;
int rval;
--- 56,89 ----
};
struct hostent *
! gethostbyname_r(const char *name, struct hostent *resp,
! char *buffer, int buflen, int *h_errnop)
{
struct hostent *hp;
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
! *h_errnop = NETDB_INTERNAL;
return (NULL);
}
if (_res.options & RES_USE_INET6) { /* XXX */
! hp = gethostbyname2_r(name, AF_INET6, resp,
! buffer, buflen, h_errnop); /* XXX */
if (hp) /* XXX */
return (hp); /* XXX */
} /* XXX */
! return (gethostbyname2_r(name, AF_INET, resp,
! buffer, buflen, h_errnop));
}
struct hostent *
! gethostbyname(const char *name)
! {
! return (gethostbyname_r(name, NULL, NULL, 0, &h_errno));
! }
!
! struct hostent *
! gethostbyname2_r(const char *name, int type, struct hostent *resp,
! char *buffer, int buflen, int *h_errnop)
{
struct hostent *hp = 0;
int rval;
***************
*** 86,92 ****
};
rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname",
! default_src, name, type);
if (rval != NS_SUCCESS)
return NULL;
--- 96,104 ----
};
rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyname",
! default_src, name, type, resp, buffer, buflen);
!
! *h_errnop = h_errno;
if (rval != NS_SUCCESS)
return NULL;
***************
*** 95,101 ****
}
struct hostent *
! gethostbyaddr(const char *addr, int len, int type)
{
struct hostent *hp = 0;
int rval;
--- 107,120 ----
}
struct hostent *
! gethostbyname2(const char *name, int type)
! {
! return (gethostbyname2_r(name, type, NULL, NULL, 0, &h_errno));
! }
!
! struct hostent *
! gethostbyaddr_r(const char *addr, int len, int type, struct hostent *resp,
! char *buffer, int buflen, int *h_errnop)
{
struct hostent *hp = 0;
int rval;
***************
*** 108,114 ****
};
rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyaddr",
! default_src, addr, len, type);
if (rval != NS_SUCCESS)
return NULL;
--- 127,135 ----
};
rval = nsdispatch((void *)&hp, dtab, NSDB_HOSTS, "gethostbyaddr",
! default_src, addr, len, type, resp, buffer, buflen);
!
! *h_errnop = h_errno;
if (rval != NS_SUCCESS)
return NULL;
***************
*** 116,126 ****
return hp;
}
struct hostent_data;
/*
* Temporary function (not thread safe)
- */
int gethostbyaddr_r(const char *addr, int len, int type,
struct hostent *result, struct hostent_data *buffer)
{
--- 137,152 ----
return hp;
}
+ struct hostent *
+ gethostbyaddr(const char *addr, int len, int type)
+ {
+ return (gethostbyaddr_r(addr, len, type, NULL, NULL, 0, &h_errno));
+ }
+
struct hostent_data;
/*
* Temporary function (not thread safe)
int gethostbyaddr_r(const char *addr, int len, int type,
struct hostent *result, struct hostent_data *buffer)
{
***************
*** 134,139 ****
--- 160,166 ----
}
return(ret);
}
+ */
void
sethostent(stayopen)
*** src/lib/libc/net/getnetbydns.c.orig Wed Jan 24 08:00:26 2001
--- src/lib/libc/net/getnetbydns.c Wed Aug 8 23:26:57 2001
***************
*** 81,88 ****
#include "res_config.h"
- extern int h_errno;
-
#define BYADDR 0
#define BYNAME 1
#define MAXALIASES 35
--- 81,86 ----
*** src/lib/libc/net/herror.c.orig Wed Jan 24 08:00:26 2001
--- src/lib/libc/net/herror.c Wed Aug 8 23:26:57 2001
***************
*** 70,77 ****
};
int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
- int h_errno;
-
/*
* herror --
* print the error indicated by the h_errno value.
--- 70,75 ----
***************
*** 109,111 ****
--- 107,125 ----
return (h_errlist[err]);
return ("Unknown resolver error");
}
+
+ #undef h_errno
+ int h_errno;
+
+ /*
+ * Declare a weak reference in case the application is not linked
+ * with libpthread.
+ */
+ __weak_reference(__h_errno_accessor_unthreaded, __h_errno_accessor);
+
+ int *
+ __h_errno_accessor_unthreaded()
+ {
+ return &h_errno;
+ }
+
*** src/lib/libc/net/res_init.c.orig Sun Jun 10 16:25:23 2001
--- src/lib/libc/net/res_init.c Wed Aug 8 23:26:57 2001
***************
*** 103,119 ****
# define isascii(c) (!(c & 0200))
#endif
- /*
- * Resolver state default settings.
- */
-
- struct __res_state _res
- # if defined(__BIND_RES_TEXT)
- = { RES_TIMEOUT, } /* Motorola, et al. */
- # endif
- ;
-
- struct __res_state_ext _res_ext;
/*
* Set up default settings. If the configuration file exist, the values
--- 103,108 ----
***************
*** 153,158 ****
--- 142,150 ----
#ifndef RFC1535
int dots;
#endif
+
+ if(&_res_data==NULL)
+ return -1;
/*
* These three fields used to be statically initialized. This made
***************
*** 574,576 ****
--- 566,605 ----
*/
#undef res_init
__weak_reference(__res_init, res_init);
+
+ /*
+ * Resolver state default settings.
+ */
+
+ #undef _res
+ #undef _res_ext
+ #undef _res_data
+
+ struct __res_state _res
+ # if defined(__BIND_RES_TEXT)
+ = { RES_TIMEOUT, } /* Motorola, et al. */
+ # endif
+ ;
+
+ struct __res_state_ext _res_ext;
+
+ struct __res_data _res_data = { 0, -1, 0, 0, 0, NULL, NULL, NULL, 0, &_res, &_res_ext };
+
+ /*
+ * Declare a weak reference in case the application is not linked
+ * with libpthread.
+ */
+ __weak_reference(__res_data_accessor_unthreaded, __res_data_accessor);
+ __weak_reference(__res_accessor_unthreaded, __res_accessor);
+
+ struct __res_data *
+ __res_data_accessor_unthreaded()
+ {
+ return &_res_data;
+ }
+
+ struct __res_state *
+ __res_accessor_unthreaded()
+ {
+ return _res_data.res;
+ }
*** src/lib/libc/net/res_query.c.orig Sun Jun 10 16:25:23 2001
--- src/lib/libc/net/res_query.c Wed Aug 8 23:26:57 2001
***************
*** 373,383 ****
hostalias(name)
const char *name;
{
register char *cp1, *cp2;
FILE *fp;
char *file;
char buf[BUFSIZ];
- static char abuf[MAXDNAME];
if (_res.options & RES_NOALIASES)
return (NULL);
--- 373,392 ----
hostalias(name)
const char *name;
{
+ static char abuf[MAXDNAME];
+ return (hostalias_r(name, abuf, sizeof abuf));
+ }
+
+ const char *
+ hostalias_r(name, abuf, len)
+ const char *name;
+ char *abuf;
+ int len;
+ {
register char *cp1, *cp2;
FILE *fp;
char *file;
char buf[BUFSIZ];
if (_res.options & RES_NOALIASES)
return (NULL);
***************
*** 401,408 ****
break;
for (cp2 = cp1 + 1; *cp2 && !isspace((unsigned char)*cp2); ++cp2)
;
! abuf[sizeof(abuf) - 1] = *cp2 = '\0';
! strncpy(abuf, cp1, sizeof(abuf) - 1);
fclose(fp);
return (abuf);
}
--- 410,417 ----
break;
for (cp2 = cp1 + 1; *cp2 && !isspace((unsigned char)*cp2); ++cp2)
;
! abuf[len - 1] = *cp2 = '\0';
! strncpy(abuf, cp1, len - 1);
fclose(fp);
return (abuf);
}
*** src/lib/libc/net/res_send.c.orig Sat Jun 23 02:54:28 2001
--- src/lib/libc/net/res_send.c Wed Aug 8 23:26:57 2001
***************
*** 101,113 ****
#include "res_config.h"
- 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 circuit? */
- static int af = 0; /* address family of socket */
- static res_send_qhook Qhook = NULL;
- static res_send_rhook Rhook = NULL;
-
#define CAN_RECONNECT 1
--- 101,106 ----
***************
*** 169,175 ****
res_send_qhook hook;
{
! Qhook = hook;
}
void
--- 162,168 ----
res_send_qhook hook;
{
! _res_data.Qhook = hook;
}
void
***************
*** 177,183 ****
res_send_rhook hook;
{
! Rhook = hook;
}
static struct sockaddr * get_nsaddr __P((size_t));
--- 170,176 ----
res_send_rhook hook;
{
! _res_data.Rhook = hook;
}
static struct sockaddr * get_nsaddr __P((size_t));
***************
*** 405,417 ****
goto next_ns;
}
! if (Qhook) {
int done = 0, loops = 0;
do {
res_sendhookact act;
! act = (*Qhook)((struct sockaddr_in **)&nsap,
&buf, &buflen,
ans, anssiz, &resplen);
switch (act) {
--- 398,410 ----
goto next_ns;
}
! if (_res_data.Qhook) {
int done = 0, loops = 0;
do {
res_sendhookact act;
! act = (*_res_data.Qhook)((struct sockaddr_in **)&nsap,
&buf, &buflen,
ans, anssiz, &resplen);
switch (act) {
***************
*** 456,469 ****
*/
try = _res.retry;
truncated = 0;
! if (s < 0 || !vc || hp->opcode == ns_o_update ||
! af != nsap->sa_family) {
! if (s >= 0)
res_close();
! af = nsap->sa_family;
! s = _socket(af, SOCK_STREAM, 0);
! if (s < 0) {
terrno = errno;
Perror(stderr, "socket(vc)", errno);
badns |= (1 << ns);
--- 449,462 ----
*/
try = _res.retry;
truncated = 0;
! if (_res_data.s < 0 || !_res_data.vc || hp->opcode == ns_o_update ||
! _res_data.af != nsap->sa_family) {
! if (_res_data.s >= 0)
res_close();
! _res_data.af = nsap->sa_family;
! _res_data.s = _socket(_res_data.af, SOCK_STREAM, 0);
! if (_res_data.s < 0) {
terrno = errno;
Perror(stderr, "socket(vc)", errno);
badns |= (1 << ns);
***************
*** 471,477 ****
goto next_ns;
}
errno = 0;
! if (_connect(s, nsap, salen) < 0) {
terrno = errno;
Aerror(stderr, "connect/vc",
errno, nsap);
--- 464,470 ----
goto next_ns;
}
errno = 0;
! if (_connect(_res_data.s, nsap, salen) < 0) {
terrno = errno;
Aerror(stderr, "connect/vc",
errno, nsap);
***************
*** 479,485 ****
res_close();
goto next_ns;
}
! vc = 1;
}
/*
* Send length & message
--- 472,478 ----
res_close();
goto next_ns;
}
! _res_data.vc = 1;
}
/*
* Send length & message
***************
*** 489,495 ****
iov[0].iov_len = INT16SZ;
iov[1].iov_base = (caddr_t)buf;
iov[1].iov_len = buflen;
! if (_writev(s, iov, 2) != (INT16SZ + buflen)) {
terrno = errno;
Perror(stderr, "write failed", errno);
badns |= (1 << ns);
--- 482,488 ----
iov[0].iov_len = INT16SZ;
iov[1].iov_base = (caddr_t)buf;
iov[1].iov_len = buflen;
! if (_writev(_res_data.s, iov, 2) != (INT16SZ + buflen)) {
terrno = errno;
Perror(stderr, "write failed", errno);
badns |= (1 << ns);
***************
*** 502,508 ****
read_len:
cp = ans;
len = INT16SZ;
! while ((n = _read(s, (char *)cp, (int)len)) > 0) {
cp += n;
if ((len -= n) <= 0)
break;
--- 495,501 ----
read_len:
cp = ans;
len = INT16SZ;
! while ((n = _read(_res_data.s, (char *)cp, (int)len)) > 0) {
cp += n;
if ((len -= n) <= 0)
break;
***************
*** 550,556 ****
}
cp = ans;
while (len != 0 &&
! (n = _read(s, (char *)cp, (int)len)) > 0) {
cp += n;
len -= n;
}
--- 543,549 ----
}
cp = ans;
while (len != 0 &&
! (n = _read(_res_data.s, (char *)cp, (int)len)) > 0) {
cp += n;
len -= n;
}
***************
*** 573,579 ****
n = (len > sizeof(junk)
? sizeof(junk)
: len);
! if ((n = _read(s, junk, n)) > 0)
len -= n;
else
break;
--- 566,572 ----
n = (len > sizeof(junk)
? sizeof(junk)
: len);
! if ((n = _read(_res_data.s, junk, n)) > 0)
len -= n;
else
break;
***************
*** 603,614 ****
struct sockaddr_storage from;
int fromlen;
! if (s < 0 || vc || af != nsap->sa_family) {
! if (vc)
! res_close();
! af = nsap->sa_family;
! s = _socket(af, SOCK_DGRAM, 0);
! if (s < 0) {
#ifndef CAN_RECONNECT
bad_dg_sock:
#endif
--- 596,608 ----
struct sockaddr_storage from;
int fromlen;
! if (_res_data.s < 0 || _res_data.vc ||
! _res_data.af != nsap->sa_family) {
! if (_res_data.vc)
! res_close();
! _res_data.af = nsap->sa_family;
! _res_data.s = _socket(_res_data.af, SOCK_DGRAM, 0);
! if (_res_data.s < 0) {
#ifndef CAN_RECONNECT
bad_dg_sock:
#endif
***************
*** 618,624 ****
res_close();
goto next_ns;
}
! connected = 0;
}
#ifndef CANNOT_CONNECT_DGRAM
/*
--- 612,618 ----
res_close();
goto next_ns;
}
! _res_data.connected = 0;
}
#ifndef CANNOT_CONNECT_DGRAM
/*
***************
*** 641,648 ****
* Connect only if we are sure we won't
* receive a response from another server.
*/
! if (!connected) {
! if (_connect(s, nsap, salen) < 0) {
Aerror(stderr,
"connect(dg)",
errno, nsap);
--- 635,642 ----
* Connect only if we are sure we won't
* receive a response from another server.
*/
! if (!_res_data.connected) {
! if (_connect(_res_data.s, nsap, salen) < 0) {
Aerror(stderr,
"connect(dg)",
errno, nsap);
***************
*** 650,658 ****
res_close();
goto next_ns;
}
! connected = 1;
}
! if (send(s, (char*)buf, buflen, 0) != buflen) {
Perror(stderr, "send", errno);
badns |= (1 << ns);
res_close();
--- 644,652 ----
res_close();
goto next_ns;
}
! _res_data.connected = 1;
}
! if (send(_res_data.s, (char*)buf, buflen, 0) != buflen) {
Perror(stderr, "send", errno);
badns |= (1 << ns);
res_close();
***************
*** 663,669 ****
* Disconnect if we want to listen
* for responses from more than one server.
*/
! if (connected) {
#ifdef CAN_RECONNECT
/* XXX: any errornous address */
struct sockaddr_in no_addr;
--- 657,663 ----
* Disconnect if we want to listen
* for responses from more than one server.
*/
! if (_res_data.connected) {
#ifdef CAN_RECONNECT
/* XXX: any errornous address */
struct sockaddr_in no_addr;
***************
*** 671,694 ****
no_addr.sin_family = AF_INET;
no_addr.sin_addr.s_addr = INADDR_ANY;
no_addr.sin_port = 0;
! (void) _connect(s,
(struct sockaddr *)
&no_addr,
sizeof no_addr);
#else
! int s1 = _socket(af, SOCK_DGRAM,0);
if (s1 < 0)
goto bad_dg_sock;
! (void)_dup2(s1, s);
(void)_close(s1);
Dprint(_res.options & RES_DEBUG,
(stdout, ";; new DG socket\n"))
#endif /* CAN_RECONNECT */
! connected = 0;
errno = 0;
}
#endif /* !CANNOT_CONNECT_DGRAM */
! if (_sendto(s, (char*)buf, buflen, 0,
nsap, salen) != buflen) {
Aerror(stderr, "sendto", errno, nsap);
badns |= (1 << ns);
--- 665,688 ----
no_addr.sin_family = AF_INET;
no_addr.sin_addr.s_addr = INADDR_ANY;
no_addr.sin_port = 0;
! (void) _connect(_res_data.s,
(struct sockaddr *)
&no_addr,
sizeof no_addr);
#else
! int s1 = _socket(_res_data.af, SOCK_DGRAM,0);
if (s1 < 0)
goto bad_dg_sock;
! (void)_dup2(s1, _res_data.s);
(void)_close(s1);
Dprint(_res.options & RES_DEBUG,
(stdout, ";; new DG socket\n"))
#endif /* CAN_RECONNECT */
! _res_data.connected = 0;
errno = 0;
}
#endif /* !CANNOT_CONNECT_DGRAM */
! if (_sendto(_res_data.s, (char*)buf, buflen, 0,
nsap, salen) != buflen) {
Aerror(stderr, "sendto", errno, nsap);
badns |= (1 << ns);
***************
*** 713,725 ****
(void) gettimeofday(&ctv, NULL);
timeradd(&timeout, &ctv, &timeout);
wait:
! if (s < 0) {
Perror(stderr, "s out-of-bounds", EMFILE);
res_close();
goto next_ns;
}
! EV_SET(&kv, s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0,0,0);
n = _kevent(kq, &kv, 1, &kv, 1, &ts);
if (n < 0) {
--- 707,719 ----
(void) gettimeofday(&ctv, NULL);
timeradd(&timeout, &ctv, &timeout);
wait:
! if (_res_data.s < 0) {
Perror(stderr, "s out-of-bounds", EMFILE);
res_close();
goto next_ns;
}
! EV_SET(&kv, _res_data.s, EVFILT_READ, EV_ADD | EV_ONESHOT, 0,0,0);
n = _kevent(kq, &kv, 1, &kv, 1, &ts);
if (n < 0) {
***************
*** 749,755 ****
}
errno = 0;
fromlen = sizeof(from);
! resplen = _recvfrom(s, (char*)ans, anssiz, 0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
Perror(stderr, "recvfrom", errno);
--- 743,749 ----
}
errno = 0;
fromlen = sizeof(from);
! resplen = _recvfrom(_res_data.s, (char*)ans, anssiz, 0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
Perror(stderr, "recvfrom", errno);
***************
*** 854,866 ****
!(_res.options & RES_STAYOPEN)) {
res_close();
}
! if (Rhook) {
int done = 0, loops = 0;
do {
res_sendhookact act;
! act = (*Rhook)((struct sockaddr_in *)nsap,
buf, buflen,
ans, anssiz, &resplen);
switch (act) {
--- 848,860 ----
!(_res.options & RES_STAYOPEN)) {
res_close();
}
! if (_res_data.Rhook) {
int done = 0, loops = 0;
do {
res_sendhookact act;
! act = (*_res_data.Rhook)((struct sockaddr_in *)nsap,
buf, buflen,
ans, anssiz, &resplen);
switch (act) {
***************
*** 912,923 ****
void
res_close()
{
! if (s >= 0) {
! (void)_close(s);
! s = -1;
! connected = 0;
! vc = 0;
! af = 0;
}
}
--- 906,917 ----
void
res_close()
{
! if (_res_data.s >= 0) {
! (void)_close(_res_data.s);
! _res_data.s = -1;
! _res_data.connected = 0;
! _res_data.vc = 0;
! _res_data.af = 0;
}
}
*** src/lib/libc_r/sys/Makefile.inc.orig Wed Aug 8 23:25:32 2001
--- src/lib/libc_r/sys/Makefile.inc Wed Aug 8 23:26:13 2001
***************
*** 2,6 ****
.PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH}
! SRCS+= uthread_error.c _atomic_lock.S
--- 2,6 ----
.PATH: ${.CURDIR}/sys ${.CURDIR}/arch/${MACHINE_ARCH}
! SRCS+= uthread_error.c uthread_resolv.c _atomic_lock.S
*** src/lib/libc_r/sys/uthread_resolv.c.orig Wed Aug 8 23:24:38 2001
--- src/lib/libc_r/sys/uthread_resolv.c Thu Aug 9 15:49:45 2001
***************
*** 0 ****
--- 1,142 ----
+ /*-
+ * Copyright (c) 2001 Alexandr Litvin <archer@whichever.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ */
+
+ #ifdef _THREAD_SAFE
+ #include <sys/types.h>
+ #include <netinet/in.h>
+ #include <arpa/nameser.h>
+ #include <resolv.h>
+ #include <netdb.h>
+ #include <stdlib.h>
+ #include <pthread.h>
+ #include "pthread_private.h"
+
+ #undef h_errno
+ #undef _res
+ #undef _res_ext
+ #undef _res_data
+
+ extern int h_errno;
+ extern struct __res_data _res_data;
+
+ static pthread_once_t once = PTHREAD_ONCE_INIT;
+ static pthread_key_t key;
+
+
+ static void __res_data_destroy(void *p)
+ {
+ struct __res_data *_res_datap = (struct __res_data *)p;
+ if(_res_datap->res)
+ free(_res_datap->res);
+ if(_res_datap->res_ext)
+ free(_res_datap->res_ext);
+ if(_res_datap->s>=0)
+ close(_res_datap->s);
+ if(_res_datap->hostf)
+ fclose(_res_datap->hostf);
+ free(_res_datap);
+ }
+
+ static void __res_data_init()
+ {
+ pthread_key_create(&key,__res_data_destroy);
+ }
+
+ struct __res_data * __res_data_accessor()
+ {
+ struct __res_data *_res_datap;
+ if (_thread_run == _thread_initial) {
+ _res_datap = &_res_data;
+ } else {
+ pthread_once(&once,__res_data_init);
+ _res_datap = (struct __res_data *)pthread_getspecific(key);
+ if(_res_datap==NULL) {
+ _res_datap = malloc(sizeof(struct __res_data));
+ if(_res_datap==NULL)
+ return NULL;
+ bzero(_res_datap,sizeof(struct __res_data));
+ _res_datap->res = malloc(sizeof(struct __res_state));
+ if(_res_datap->res==NULL) {
+ free(_res_datap);
+ return NULL;
+ }
+ bzero(_res_datap->res,sizeof(struct __res_state));
+ _res_datap->res_ext = malloc(sizeof(struct __res_state_ext));
+ if(_res_datap->res_ext==NULL) {
+ free(_res_datap->res);
+ free(_res_datap);
+ return NULL;
+ }
+ bzero(_res_datap->res_ext,sizeof(struct __res_state_ext));
+ _res_datap->s = -1;
+ pthread_setspecific(key,_res_datap);
+ }
+ }
+ return(_res_datap);
+ }
+
+ static struct __res_state dummy_res;
+ static int dummy_h_errno;
+
+ struct __res_state * __res_accessor()
+ {
+ struct __res_state *resp;
+ struct __res_data *_res_datap;
+ if (_thread_run == _thread_initial) {
+ resp = _res_data.res;
+ } else {
+ _res_datap = __res_data_accessor();
+ if(_res_datap) {
+ resp = _res_datap->res;
+ } else {
+ dummy_res.options = RES_DEFAULT;
+ resp = &dummy_res;
+ }
+ }
+ return(resp);
+ }
+
+ int * __h_errno_accessor()
+ {
+ int *h_errnop;
+ struct __res_data *_res_datap;
+ if (_thread_run == _thread_initial) {
+ h_errnop = &h_errno;
+ } else {
+ _res_datap = __res_data_accessor();
+ if(_res_datap) {
+ h_errnop = &_res_datap->h_errno_res;
+ } else {
+ dummy_h_errno = NETDB_INTERNAL;
+ h_errnop = &dummy_h_errno;
+ }
+ }
+ return(h_errnop);
+ }
+
+ #endif
+
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200108092002.f79K2OT19276>
