summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco S Hyman <marc@cvs.openbsd.org>2003-01-28 04:58:01 +0000
committerMarco S Hyman <marc@cvs.openbsd.org>2003-01-28 04:58:01 +0000
commit93357d25160373499d1be166f2df69454a23b5ce (patch)
treea7f3c3fa5b4bd253c97080e2afa6b65819c90383
parent06732d397fb40c90813f9782585e8d1d9fa1c367 (diff)
thread safer libc (note: safer, not safe)
Access to the global _res structure replaced by pointers to a per thread instance. If unthreaded the pointer is to the global structure. Also replaced a 64k stack array with malloc-ed memory so threaded aps (with a default 64k stack) have a chance at working. ok deraadt@
-rw-r--r--lib/libc/include/thread_private.h11
-rw-r--r--lib/libc/net/getaddrinfo.c76
-rw-r--r--lib/libc/net/gethostnamadr.c60
-rw-r--r--lib/libc/net/getnameinfo.c9
-rw-r--r--lib/libc/net/getnetnamadr.c20
-rw-r--r--lib/libc/net/getrrsetbyname.c13
-rw-r--r--lib/libc/net/res_debug.c51
-rw-r--r--lib/libc/net/res_init.c187
-rw-r--r--lib/libc/net/res_mkquery.c22
-rw-r--r--lib/libc/net/res_query.c42
-rw-r--r--lib/libc/net/res_send.c109
-rw-r--r--lib/libc/net/sethostent.c13
12 files changed, 348 insertions, 265 deletions
diff --git a/lib/libc/include/thread_private.h b/lib/libc/include/thread_private.h
index 0b0be6cb389..4212e7dcb2e 100644
--- a/lib/libc/include/thread_private.h
+++ b/lib/libc/include/thread_private.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: thread_private.h,v 1.14 2002/11/05 22:19:55 marc Exp $ */
+/* $OpenBSD: thread_private.h,v 1.15 2003/01/28 04:58:00 marc Exp $ */
#ifndef _THREAD_PRIVATE_H_
#define _THREAD_PRIVATE_H_
@@ -87,6 +87,15 @@ void * _libc_private_storage(volatile struct _thread_private_key_struct *,
&(storage), sizeof (storage), error)
/*
+ * Keys used to access the per thread instances of resolver global data.
+ * These are not static as they are referenced in several places.
+ */
+extern volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res);
+#ifdef INET6
+extern volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res_ext);
+#endif
+
+/*
* File descriptor locking definitions.
*/
#define FD_READ 0x1
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c
index 915286a404b..7406f107145 100644
--- a/lib/libc/net/getaddrinfo.c
+++ b/lib/libc/net/getaddrinfo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getaddrinfo.c,v 1.43 2002/08/27 08:53:13 itojun Exp $ */
+/* $OpenBSD: getaddrinfo.c,v 1.44 2003/01/28 04:58:00 marc Exp $ */
/* $KAME: getaddrinfo.c,v 1.31 2000/08/31 17:36:43 itojun Exp $ */
/*
@@ -499,8 +499,6 @@ getaddrinfo(hostname, servname, hints, res)
* FQDN hostname, DNS lookup
*/
-_THREAD_PRIVATE_MUTEX(getaddrinfo_explore_fqdn);
-
static int
explore_fqdn(pai, hostname, servname, res)
const struct addrinfo *pai;
@@ -508,13 +506,13 @@ explore_fqdn(pai, hostname, servname, res)
const char *servname;
struct addrinfo **res;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
struct addrinfo *result;
struct addrinfo *cur;
int error = 0;
char lookups[MAXDNSLUS];
int i;
-
- _THREAD_PRIVATE_MUTEX_LOCK(getaddrinfo_explore_fqdn);
+ _THREAD_PRIVATE_MUTEX(_explore_mutex);
result = NULL;
@@ -525,7 +523,6 @@ explore_fqdn(pai, hostname, servname, res)
* XXX does not handle PF_UNSPEC case, should filter final result
*/
if ((pai->ai_flags & AI_ADDRCONFIG) != 0 && !addrconfig(pai)) {
- _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
return 0;
}
#endif
@@ -534,18 +531,22 @@ explore_fqdn(pai, hostname, servname, res)
* if the servname does not match socktype/protocol, ignore it.
*/
if (get_portmatch(pai, servname) != 0) {
- _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
return 0;
}
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
strlcpy(lookups, "f", sizeof lookups);
else {
- bcopy(_res.lookups, lookups, sizeof lookups);
+ bcopy(_resp->lookups, lookups, sizeof lookups);
if (lookups[0] == '\0')
strlcpy(lookups, "bf", sizeof lookups);
}
+ /*
+ * The yp/dns/files getaddrinfo functions are not thread safe.
+ * Protect them with a mutex.
+ */
+ _THREAD_PRIVATE_MUTEX_LOCK(_explore_mutex);
for (i = 0; i < MAXDNSLUS && result == NULL && lookups[i]; i++) {
switch (lookups[i]) {
#ifdef YP
@@ -561,13 +562,13 @@ explore_fqdn(pai, hostname, servname, res)
break;
}
}
+ _THREAD_PRIVATE_MUTEX_UNLOCK(_explore_mutex);
if (result) {
for (cur = result; cur; cur = cur->ai_next) {
GET_PORT(cur, servname);
/* canonname should be filled already */
}
*res = result;
- _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
return 0;
} else {
/* translate error code */
@@ -599,7 +600,6 @@ explore_fqdn(pai, hostname, servname, res)
free:
if (result)
freeaddrinfo(result);
- _THREAD_PRIVATE_MUTEX_UNLOCK(getaddrinfo_explore_fqdn);
return error;
}
@@ -867,6 +867,7 @@ get_port(ai, servname, matchonly)
struct servent *sp;
int port;
int allownumeric;
+ _THREAD_PRIVATE_MUTEX(serv_mutex);
if (servname == NULL)
return 0;
@@ -914,7 +915,10 @@ get_port(ai, servname, matchonly)
break;
}
- if ((sp = getservbyname(servname, proto)) == NULL)
+ _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
+ sp = getservbyname(servname, proto);
+ _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
+ if (sp == NULL)
return EAI_SERVICE;
port = sp->s_port;
}
@@ -1563,18 +1567,26 @@ res_queryN(name, target)
const char *name; /* domain name */
struct res_target *target;
{
- u_char buf[MAXPACKET];
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
+ u_char *buf;
HEADER *hp;
int n;
struct res_target *t;
int rcode;
int ancount;
+ buf = malloc(MAXPACKET);
+ if (buf == NULL) {
+ h_errno = NETDB_INTERNAL;
+ return (-1);
+ }
+
rcode = NOERROR;
ancount = 0;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
+ free(buf);
return (-1);
}
@@ -1592,30 +1604,32 @@ res_queryN(name, target)
answer = t->answer;
anslen = t->anslen;
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_query(%s, %d, %d)\n", name, class, type);
#endif
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
- buf, sizeof(buf));
- if (n > 0 && (_res.options & RES_USE_EDNS0) != 0)
- n = res_opt(n, buf, sizeof(buf), anslen);
+ buf, MAXPACKET);
+ if (n > 0 && (_resp->options & RES_USE_EDNS0) != 0)
+ n = res_opt(n, buf, MAXPACKET, anslen);
if (n <= 0) {
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_query: mkquery failed\n");
#endif
h_errno = NO_RECOVERY;
+ free(buf);
return (n);
}
n = res_send(buf, n, answer, anslen);
#if 0
if (n < 0) {
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_query: send error\n");
#endif
h_errno = TRY_AGAIN;
+ free(buf);
return (n);
}
#endif
@@ -1623,7 +1637,7 @@ res_queryN(name, target)
if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
rcode = hp->rcode; /* record most recent error */
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; rcode = %u, ancount=%u\n", hp->rcode,
ntohs(hp->ancount));
#endif
@@ -1653,8 +1667,10 @@ res_queryN(name, target)
h_errno = NO_RECOVERY;
break;
}
+ free(buf);
return (-1);
}
+ free(buf);
return (ancount);
}
@@ -1669,13 +1685,14 @@ res_searchN(name, target)
const char *name; /* domain name */
struct res_target *target;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
const char *cp, * const *domain;
HEADER *hp = (HEADER *)(void *)target->answer; /*XXX*/
u_int dots;
int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
@@ -1700,7 +1717,7 @@ res_searchN(name, target)
* 'as is'. The threshold can be set with the "ndots" option.
*/
saved_herrno = -1;
- if (dots >= _res.ndots) {
+ if (dots >= _resp->ndots) {
ret = res_querydomainN(name, NULL, target);
if (ret > 0)
return (ret);
@@ -1714,11 +1731,11 @@ res_searchN(name, target)
* - there is at least one dot, there is no trailing dot,
* and RES_DNSRCH is set.
*/
- if ((!dots && (_res.options & RES_DEFNAMES)) ||
- (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
+ if ((!dots && (_resp->options & RES_DEFNAMES)) ||
+ (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
int done = 0;
- for (domain = (const char * const *)_res.dnsrch;
+ for (domain = (const char * const *)_resp->dnsrch;
*domain && !done;
domain++) {
@@ -1766,7 +1783,7 @@ res_searchN(name, target)
* if we got here for some reason other than DNSRCH,
* we only wanted one iteration of the loop, so stop.
*/
- if (!(_res.options & RES_DNSRCH))
+ if (!(_resp->options & RES_DNSRCH))
done++;
}
}
@@ -1808,16 +1825,17 @@ res_querydomainN(name, domain, target)
const char *name, *domain;
struct res_target *target;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
char nbuf[MAXDNAME];
const char *longname = nbuf;
size_t n, d;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_querydomain(%s, %s)\n",
name, domain?domain:"<Nil>");
#endif
diff --git a/lib/libc/net/gethostnamadr.c b/lib/libc/net/gethostnamadr.c
index 909ce573b73..5211f423c60 100644
--- a/lib/libc/net/gethostnamadr.c
+++ b/lib/libc/net/gethostnamadr.c
@@ -52,7 +52,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.53 2002/08/27 08:53:13 itojun Exp $";
+static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.54 2003/01/28 04:58:00 marc Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -160,6 +160,7 @@ getanswer(answer, anslen, qname, qtype)
const char *qname;
int qtype;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
register const HEADER *hp;
register const u_char *cp;
register int n;
@@ -339,7 +340,7 @@ getanswer(answer, anslen, qname, qtype)
break;
#else
host.h_name = bp;
- if (_res.options & RES_USE_INET6) {
+ if (_resp->options & RES_USE_INET6) {
n = strlen(bp) + 1; /* for the \0 */
bp += n;
map_v4v6_hostent(&host, &bp, ep);
@@ -379,7 +380,7 @@ getanswer(answer, anslen, qname, qtype)
if (bp + n >= &hostbuf[sizeof hostbuf]) {
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf("size (%d) too big\n", n);
#endif
had_error++;
@@ -388,7 +389,7 @@ getanswer(answer, anslen, qname, qtype)
if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
if (!toobig++)
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf("Too many addresses (%d)\n", MAXADDRS);
#endif
cp += n;
@@ -411,7 +412,7 @@ getanswer(answer, anslen, qname, qtype)
* in its return structures - should give it the "best"
* address in that case, not some random one
*/
- if (_res.nsort && haveanswer > 1 && qtype == T_A)
+ if (_resp->nsort && haveanswer > 1 && qtype == T_A)
addrsort(h_addr_ptrs, haveanswer);
# endif /*RESOLVSORT*/
if (!host.h_name) {
@@ -422,7 +423,7 @@ getanswer(answer, anslen, qname, qtype)
host.h_name = bp;
bp += n;
}
- if (_res.options & RES_USE_INET6)
+ if (_resp->options & RES_USE_INET6)
map_v4v6_hostent(&host, &bp, ep);
h_errno = NETDB_SUCCESS;
return (&host);
@@ -484,27 +485,24 @@ gethostbyaddr_r(addr, len, af, he, buf, buflen, errorp)
/* XXX RFC2133 expects a gethostbyname2_r() -- unimplemented */
#endif
-_THREAD_PRIVATE_MUTEX(gethostnamadr);
-
struct hostent *
gethostbyname(name)
const char *name;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
struct hostent *hp;
extern struct hostent *_gethtbyname2();
- _THREAD_PRIVATE_MUTEX_LOCK(gethostnamadr);
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
hp = _gethtbyname2(name, AF_INET);
- else if (_res.options & RES_USE_INET6) {
+ else if (_resp->options & RES_USE_INET6) {
hp = gethostbyname2(name, AF_INET6);
if (hp == NULL)
hp = gethostbyname2(name, AF_INET);
}
else
hp = gethostbyname2(name, AF_INET);
- _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
return hp;
}
@@ -513,6 +511,7 @@ gethostbyname2(name, af)
const char *name;
int af;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
querybuf *buf;
register const char *cp;
char *bp, *ep;
@@ -521,7 +520,7 @@ gethostbyname2(name, af)
register struct hostent *hp;
char lookups[MAXDNSLUS];
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
return (_gethtbyname2(name, af));
switch (af) {
@@ -577,7 +576,7 @@ gethostbyname2(name, af)
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)
+ if (_resp->options & RES_USE_INET6)
map_v4v6_hostent(&host, &bp, ep);
h_errno = NETDB_SUCCESS;
return (&host);
@@ -616,7 +615,7 @@ gethostbyname2(name, af)
break;
}
- bcopy(_res.lookups, lookups, sizeof lookups);
+ bcopy(_resp->lookups, lookups, sizeof lookups);
if (lookups[0] == '\0')
strlcpy(lookups, "bf", sizeof lookups);
@@ -638,7 +637,7 @@ gethostbyname2(name, af)
sizeof(buf->buf))) < 0) {
free(buf);
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf("res_search failed\n");
#endif
break;
@@ -660,6 +659,7 @@ gethostbyaddr(addr, len, af)
const char *addr; /* XXX should have been def'd as u_char! */
int len, af;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
const u_char *uaddr = (const u_char *)addr;
int n, size, i;
querybuf *buf;
@@ -669,10 +669,8 @@ gethostbyaddr(addr, len, af)
char lookups[MAXDNSLUS];
struct hostent *res;
- _THREAD_PRIVATE_MUTEX_LOCK(gethostnamadr);
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
res = _gethtbyaddr(addr, len, af);
- _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
return (res);
}
@@ -701,13 +699,11 @@ gethostbyaddr(addr, len, af)
default:
errno = EAFNOSUPPORT;
h_errno = NETDB_INTERNAL;
- _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
return (NULL);
}
if (size != len) {
errno = EINVAL;
h_errno = NETDB_INTERNAL;
- _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
return (NULL);
}
switch (af) {
@@ -725,7 +721,7 @@ gethostbyaddr(addr, len, af)
break;
}
- bcopy(_res.lookups, lookups, sizeof lookups);
+ bcopy(_resp->lookups, lookups, sizeof lookups);
if (lookups[0] == '\0')
strlcpy(lookups, "bf", sizeof lookups);
@@ -755,7 +751,7 @@ gethostbyaddr(addr, len, af)
if (n < 0) {
free(buf);
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf("res_query failed\n");
#endif
break;
@@ -770,7 +766,7 @@ gethostbyaddr(addr, len, af)
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)) {
+ if (af == AF_INET && (_resp->options & RES_USE_INET6)) {
map_v4v6_address((char*)host_addr,
(char*)host_addr);
hp->h_addrtype = AF_INET6;
@@ -783,7 +779,6 @@ gethostbyaddr(addr, len, af)
break;
}
}
- _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr);
/* XXX h_errno not correct in all cases... */
return (hp);
}
@@ -811,6 +806,7 @@ _endhtent()
struct hostent *
_gethtent()
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
char *p;
register char *cp, **q;
int af;
@@ -842,7 +838,7 @@ _gethtent()
af = AF_INET6;
len = IN6ADDRSZ;
} else if (inet_pton(AF_INET, p, host_addr) > 0) {
- if (_res.options & RES_USE_INET6) {
+ if (_resp->options & RES_USE_INET6) {
map_v4v6_address((char*)host_addr, (char*)host_addr);
af = AF_INET6;
len = IN6ADDRSZ;
@@ -880,7 +876,7 @@ _gethtent()
*cp++ = '\0';
}
*q = NULL;
- if (_res.options & RES_USE_INET6) {
+ if (_resp->options & RES_USE_INET6) {
char *bp = hostbuf;
char *ep = hostbuf + sizeof hostbuf;
@@ -894,10 +890,11 @@ struct hostent *
_gethtbyname(name)
const char *name;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
extern struct hostent *_gethtbyname2();
struct hostent *hp;
- if (_res.options & RES_USE_INET6) {
+ if (_resp->options & RES_USE_INET6) {
hp = _gethtbyname2(name, AF_INET6);
if (hp)
return (hp);
@@ -1136,6 +1133,7 @@ addrsort(ap, num)
char **ap;
int num;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int i, j;
char **p;
short aval[MAXADDRS];
@@ -1143,9 +1141,9 @@ addrsort(ap, num)
p = ap;
for (i = 0; i < num; i++, p++) {
- for (j = 0 ; (unsigned)j < _res.nsort; j++)
- if (_res.sort_list[j].addr.s_addr ==
- (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
+ for (j = 0 ; (unsigned)j < _resp->nsort; j++)
+ if (_resp->sort_list[j].addr.s_addr ==
+ (((struct in_addr *)(*p))->s_addr & _resp->sort_list[j].mask))
break;
aval[i] = j;
if (needsort == 0 && i > 0 && j < aval[i-1])
diff --git a/lib/libc/net/getnameinfo.c b/lib/libc/net/getnameinfo.c
index 2311eba7a02..d3a9678cbd6 100644
--- a/lib/libc/net/getnameinfo.c
+++ b/lib/libc/net/getnameinfo.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnameinfo.c,v 1.25 2002/06/27 09:24:28 itojun Exp $ */
+/* $OpenBSD: getnameinfo.c,v 1.26 2003/01/28 04:58:00 marc Exp $ */
/* $KAME: getnameinfo.c,v 1.45 2000/09/25 22:43:56 itojun Exp $ */
/*
@@ -59,6 +59,8 @@
#include <string.h>
#include <stddef.h>
+#include "thread_private.h"
+
static const struct afd {
int a_af;
int a_addrlen;
@@ -106,6 +108,7 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
int h_error;
char numserv[512];
char numaddr[512];
+ _THREAD_PRIVATE_MUTEX(serv_mutex);
if (sa == NULL)
return EAI_FAIL;
@@ -140,8 +143,10 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
if (flags & NI_NUMERICSERV)
sp = NULL;
else {
+ _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
sp = getservbyport(port,
(flags & NI_DGRAM) ? "udp" : "tcp");
+ _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
}
if (sp) {
if (strlen(sp->s_name) + 1 > servlen)
@@ -228,7 +233,9 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags)
break;
}
} else {
+ _THREAD_PRIVATE_MUTEX_LOCK(serv_mutex);
hp = gethostbyaddr(addr, afd->a_addrlen, afd->a_af);
+ _THREAD_PRIVATE_MUTEX_UNLOCK(serv_mutex);
h_error = h_errno;
if (hp) {
diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c
index f183fbe3fef..75a75243efd 100644
--- a/lib/libc/net/getnetnamadr.c
+++ b/lib/libc/net/getnetnamadr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getnetnamadr.c,v 1.19 2002/11/14 02:48:00 millert Exp $ */
+/* $OpenBSD: getnetnamadr.c,v 1.20 2003/01/28 04:58:00 marc Exp $ */
/*
* Copyright (c) 1997, Jason Downs. All rights reserved.
@@ -77,7 +77,7 @@ static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93";
static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03";
static char rcsid[] = "$From: getnetnamadr.c,v 8.7 1996/08/05 08:31:35 vixie Exp $";
#else
-static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.19 2002/11/14 02:48:00 millert Exp $";
+static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.20 2003/01/28 04:58:00 marc Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -96,6 +96,8 @@ static char rcsid[] = "$OpenBSD: getnetnamadr.c,v 1.19 2002/11/14 02:48:00 mille
#include <string.h>
#include <stdlib.h>
+#include "thread_private.h"
+
extern int h_errno;
struct netent *_getnetbyaddr(in_addr_t net, int type);
@@ -262,6 +264,7 @@ getnetbyaddr(net, net_type)
register in_addr_t net;
register int net_type;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
unsigned int netbr[4];
int nn, anslen;
querybuf *buf;
@@ -271,10 +274,10 @@ getnetbyaddr(net, net_type)
char lookups[MAXDNSLUS];
int i;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
return(_getnetbyaddr(net, net_type));
- bcopy(_res.lookups, lookups, sizeof lookups);
+ bcopy(_resp->lookups, lookups, sizeof lookups);
if (lookups[0] == '\0')
strlcpy(lookups, "bf", sizeof lookups);
@@ -320,7 +323,7 @@ getnetbyaddr(net, net_type)
if (anslen < 0) {
free(buf);
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf("res_query failed\n");
#endif
break;
@@ -352,6 +355,7 @@ struct netent *
getnetbyname(net)
register const char *net;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int anslen;
querybuf *buf;
char qbuf[MAXDNAME];
@@ -359,10 +363,10 @@ getnetbyname(net)
char lookups[MAXDNSLUS];
int i;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
return (_getnetbyname(net));
- bcopy(_res.lookups, lookups, sizeof lookups);
+ bcopy(_resp->lookups, lookups, sizeof lookups);
if (lookups[0] == '\0')
strlcpy(lookups, "bf", sizeof lookups);
@@ -383,7 +387,7 @@ getnetbyname(net)
if (anslen < 0) {
free(buf);
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf("res_query failed\n");
#endif
break;
diff --git a/lib/libc/net/getrrsetbyname.c b/lib/libc/net/getrrsetbyname.c
index 1ec60486b3d..e4bd9a936ec 100644
--- a/lib/libc/net/getrrsetbyname.c
+++ b/lib/libc/net/getrrsetbyname.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: getrrsetbyname.c,v 1.5 2002/09/07 20:54:04 jakob Exp $ */
+/* $OpenBSD: getrrsetbyname.c,v 1.6 2003/01/28 04:58:00 marc Exp $ */
/*
* Copyright (c) 2001 Jakob Schlyter. All rights reserved.
@@ -51,6 +51,8 @@
#include <stdlib.h>
#include <string.h>
+#include "thread_private.h"
+
#define ANSWER_BUFFER_SIZE 1024*64
struct dns_query {
@@ -95,6 +97,7 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
unsigned int rdtype, unsigned int flags,
struct rrsetinfo **res)
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int result;
struct rrsetinfo *rrset = NULL;
struct dns_response *response;
@@ -122,19 +125,19 @@ getrrsetbyname(const char *hostname, unsigned int rdclass,
}
/* initialize resolver */
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
result = ERRSET_FAIL;
goto fail;
}
#ifdef DEBUG
- _res.options |= RES_DEBUG;
+ _resp->options |= RES_DEBUG;
#endif /* DEBUG */
#ifdef RES_USE_DNSSEC
/* turn on DNSSEC if EDNS0 is configured */
- if (_res.options & RES_USE_EDNS0)
- _res.options |= RES_USE_DNSSEC;
+ if (_resp->options & RES_USE_EDNS0)
+ _resp->options |= RES_USE_DNSSEC;
#endif /* RES_USE_DNSEC */
/* make query */
diff --git a/lib/libc/net/res_debug.c b/lib/libc/net/res_debug.c
index 2ea9173fe90..f4e4c271ed2 100644
--- a/lib/libc/net/res_debug.c
+++ b/lib/libc/net/res_debug.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_debug.c,v 1.14 2002/07/25 21:55:30 deraadt Exp $ */
+/* $OpenBSD: res_debug.c,v 1.15 2003/01/28 04:58:00 marc Exp $ */
/*
* ++Copyright++ 1985, 1990, 1993
@@ -82,7 +82,7 @@
static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$From: res_debug.c,v 8.19 1996/11/26 10:11:23 vixie Exp $";
#else
-static char rcsid[] = "$OpenBSD: res_debug.c,v 1.14 2002/07/25 21:55:30 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: res_debug.c,v 1.15 2003/01/28 04:58:00 marc Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -102,6 +102,8 @@ static char rcsid[] = "$OpenBSD: res_debug.c,v 1.14 2002/07/25 21:55:30 deraadt
#include <stdlib.h>
#include <string.h>
+#include "thread_private.h"
+
extern const char *_res_opcodes[];
extern const char *_res_resultcodes[];
@@ -200,19 +202,20 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)
const char *hs;
FILE *file;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int n;
int sflag;
/*
* Print answer records.
*/
- sflag = (_res.pfcode & pflag);
+ sflag = (_resp->pfcode & pflag);
if ((n = ntohs(cnt))) {
- if ((!_res.pfcode) ||
- ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
+ if ((!_resp->pfcode) ||
+ ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
fprintf(file, "%s", hs);
while (--n >= 0) {
- if ((!_res.pfcode) || sflag) {
+ if ((!_resp->pfcode) || sflag) {
cp = p_rr(cp, msg, file);
} else {
unsigned int dlen;
@@ -227,8 +230,8 @@ do_rrset(msg, len, cp, cnt, pflag, file, hs)
if ((cp - msg) > len)
return (NULL);
}
- if ((!_res.pfcode) ||
- ((sflag) && (_res.pfcode & RES_PRF_HEAD1)))
+ if ((!_resp->pfcode) ||
+ ((sflag) && (_resp->pfcode & RES_PRF_HEAD1)))
putc('\n', file);
}
return (cp);
@@ -271,11 +274,12 @@ __fp_nquery(msg, len, file)
int len;
FILE *file;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
register const u_char *cp, *endMark;
register const HEADER *hp;
register int n;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
return;
#define TruncTest(x) if (x > endMark) goto trunc
@@ -287,16 +291,16 @@ __fp_nquery(msg, len, file)
hp = (HEADER *)msg;
cp = msg + HFIXEDSZ;
endMark = msg + len;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) {
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX) || hp->rcode) {
fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %u",
_res_opcodes[hp->opcode],
_res_resultcodes[hp->rcode],
ntohs(hp->id));
putc('\n', file);
}
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEADX))
putc(';', file);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD2)) {
fprintf(file, "; flags:");
if (hp->qr)
fprintf(file, " qr");
@@ -315,13 +319,13 @@ __fp_nquery(msg, len, file)
if (hp->cd)
fprintf(file, " cd");
}
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_HEAD1)) {
fprintf(file, "; Ques: %u", ntohs(hp->qdcount));
fprintf(file, ", Ans: %u", ntohs(hp->ancount));
fprintf(file, ", Auth: %u", ntohs(hp->nscount));
fprintf(file, ", Addit: %u", ntohs(hp->arcount));
}
- if ((!_res.pfcode) || (_res.pfcode &
+ if ((!_resp->pfcode) || (_resp->pfcode &
(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
putc('\n',file);
}
@@ -329,13 +333,13 @@ __fp_nquery(msg, len, file)
* Print question records.
*/
if ((n = ntohs(hp->qdcount))) {
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
fprintf(file, ";; QUESTIONS:\n");
while (--n >= 0) {
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
fprintf(file, ";;\t");
TruncTest(cp);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
cp = p_cdnname(cp, msg, len, file);
else {
int n;
@@ -349,16 +353,16 @@ __fp_nquery(msg, len, file)
}
ErrorTest(cp);
TruncTest(cp);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
fprintf(file, ", type = %s",
__p_type(_getshort((u_char*)cp)));
cp += INT16SZ;
TruncTest(cp);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
fprintf(file, ", class = %s\n",
__p_class(_getshort((u_char*)cp)));
cp += INT16SZ;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_QUES))
putc('\n', file);
}
}
@@ -478,6 +482,7 @@ __p_rr(cp, msg, file)
const u_char *cp, *msg;
FILE *file;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int type, class, dlen, n, c;
struct in_addr inaddr;
const u_char *cp1, *cp2;
@@ -487,7 +492,7 @@ __p_rr(cp, msg, file)
char rrname[MAXDNAME]; /* The fqdn of this RR */
char base64_key[MAX_KEY_BASE64];
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (NULL);
}
@@ -505,9 +510,9 @@ __p_rr(cp, msg, file)
dlen = _getshort((u_char*)cp);
cp += INT16SZ;
cp1 = cp;
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_TTLID))
fprintf(file, "\t%lu", (u_long)tmpttl);
- if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS))
+ if ((!_resp->pfcode) || (_resp->pfcode & RES_PRF_CLASS))
fprintf(file, "\t%s", __p_class(class));
fprintf(file, "\t%s", __p_type(type));
/*
diff --git a/lib/libc/net/res_init.c b/lib/libc/net/res_init.c
index c55c7763a4e..a1d69f57b5e 100644
--- a/lib/libc/net/res_init.c
+++ b/lib/libc/net/res_init.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_init.c,v 1.27 2002/07/25 21:13:45 deraadt Exp $ */
+/* $OpenBSD: res_init.c,v 1.28 2003/01/28 04:58:00 marc Exp $ */
/*
* ++Copyright++ 1985, 1989, 1993
@@ -64,7 +64,7 @@
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
static char rcsid[] = "$From: res_init.c,v 8.7 1996/09/28 06:51:07 vixie Exp $";
#else
-static char rcsid[] = "$OpenBSD: res_init.c,v 1.27 2002/07/25 21:13:45 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: res_init.c,v 1.28 2003/01/28 04:58:00 marc Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -86,6 +86,8 @@ static char rcsid[] = "$OpenBSD: res_init.c,v 1.27 2002/07/25 21:13:45 deraadt E
#include <netdb.h>
#endif /* INET6 */
+#include "thread_private.h"
+
/*-------------------------------------- info about "sortlist" --------------
* Marc Majka 1994/04/16
* Allan Nathanson 1994/10/29 (BIND 4.9.3.x)
@@ -120,6 +122,9 @@ static u_int32_t net_mask(struct in_addr);
/*
* Resolver state default settings.
*/
+volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res) = {
+ PTHREAD_ONCE_INIT, 0
+};
struct __res_state _res
# if defined(__BIND_RES_TEXT)
@@ -127,6 +132,10 @@ struct __res_state _res
# endif
;
#ifdef INET6
+volatile struct _thread_private_key_struct __THREAD_KEY_NAME(_res_ext) = {
+ PTHREAD_ONCE_INIT, 0
+};
+
struct __res_state_ext _res_ext;
#endif /* INET6 */
@@ -154,6 +163,11 @@ struct __res_state_ext _res_ext;
int
res_init()
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
+#ifdef INET6
+ struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
+ &_res_ext);
+#endif
register FILE *fp;
register char *cp, **pp;
register int n;
@@ -189,33 +203,33 @@ res_init()
* set in RES_DEFAULT). Our solution is to declare such applications
* "broken". They could fool us by setting RES_INIT but none do (yet).
*/
- if (!_res.retrans)
- _res.retrans = RES_TIMEOUT;
- if (!_res.retry)
- _res.retry = 4;
- if (!(_res.options & RES_INIT))
- _res.options = RES_DEFAULT;
+ if (!_resp->retrans)
+ _resp->retrans = RES_TIMEOUT;
+ if (!_resp->retry)
+ _resp->retry = 4;
+ if (!(_resp->options & RES_INIT))
+ _resp->options = RES_DEFAULT;
#ifdef USELOOPBACK
- _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
+ _resp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
- _res.nsaddr.sin_addr.s_addr = INADDR_ANY;
+ _resp->nsaddr.sin_addr.s_addr = INADDR_ANY;
#endif
- _res.nsaddr.sin_family = AF_INET;
- _res.nsaddr.sin_port = htons(NAMESERVER_PORT);
- _res.nsaddr.sin_len = sizeof(struct sockaddr_in);
+ _resp->nsaddr.sin_family = AF_INET;
+ _resp->nsaddr.sin_port = htons(NAMESERVER_PORT);
+ _resp->nsaddr.sin_len = sizeof(struct sockaddr_in);
#ifdef INET6
- if (sizeof(_res_ext.nsaddr) >= _res.nsaddr.sin_len)
- memcpy(&_res_ext.nsaddr, &_res.nsaddr, _res.nsaddr.sin_len);
+ if (sizeof(_res_extp->nsaddr) >= _resp->nsaddr.sin_len)
+ memcpy(&_res_extp->nsaddr, &_resp->nsaddr, _resp->nsaddr.sin_len);
#endif
- _res.nscount = 1;
- _res.ndots = 1;
- _res.pfcode = 0;
- strlcpy(_res.lookups, "f", sizeof _res.lookups);
+ _resp->nscount = 1;
+ _resp->ndots = 1;
+ _resp->pfcode = 0;
+ strlcpy(_resp->lookups, "f", sizeof _resp->lookups);
/* Allow user to override the local domain definition */
if (issetugid() == 0 && (cp = getenv("LOCALDOMAIN")) != NULL) {
- strlcpy(_res.defdname, cp, sizeof(_res.defdname));
+ strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
haveenv++;
/*
@@ -225,10 +239,10 @@ res_init()
* one that they want to use as an individual (even more
* important now that the rfc1535 stuff restricts searches)
*/
- cp = _res.defdname;
- pp = _res.dnsrch;
+ cp = _resp->defdname;
+ pp = _resp->dnsrch;
*pp++ = cp;
- for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
if (*cp == '\n') /* silly backwards compat */
break;
else if (*cp == ' ' || *cp == '\t') {
@@ -253,7 +267,7 @@ res_init()
line[sizeof(name) - 1] == '\t'))
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
- strlcpy(_res.lookups, "bf", sizeof _res.lookups);
+ strlcpy(_resp->lookups, "bf", sizeof _resp->lookups);
/* read the config file */
buf[0] = '\0';
@@ -277,8 +291,8 @@ res_init()
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
- strlcpy(_res.defdname, cp, sizeof(_res.defdname));
- if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
+ strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
+ if ((cp = strpbrk(_resp->defdname, " \t\n")) != NULL)
*cp = '\0';
havesearch = 0;
continue;
@@ -287,7 +301,7 @@ res_init()
if (MATCH(buf, "lookup")) {
char *sp = NULL;
- bzero(_res.lookups, sizeof _res.lookups);
+ bzero(_resp->lookups, sizeof _resp->lookups);
cp = buf + sizeof("lookup") - 1;
for (n = 0;; cp++) {
if (n == MAXDNSLUS)
@@ -295,14 +309,14 @@ res_init()
if ((*cp == '\0') || (*cp == '\n')) {
if (sp) {
if (*sp=='y' || *sp=='b' || *sp=='f')
- _res.lookups[n++] = *sp;
+ _resp->lookups[n++] = *sp;
sp = NULL;
}
break;
} else if ((*cp == ' ') || (*cp == '\t') || (*cp == ',')) {
if (sp) {
if (*sp=='y' || *sp=='b' || *sp=='f')
- _res.lookups[n++] = *sp;
+ _resp->lookups[n++] = *sp;
sp = NULL;
}
} else if (sp == NULL)
@@ -319,17 +333,17 @@ res_init()
cp++;
if ((*cp == '\0') || (*cp == '\n'))
continue;
- strlcpy(_res.defdname, cp, sizeof(_res.defdname));
- if ((cp = strchr(_res.defdname, '\n')) != NULL)
+ strlcpy(_resp->defdname, cp, sizeof(_resp->defdname));
+ if ((cp = strchr(_resp->defdname, '\n')) != NULL)
*cp = '\0';
/*
* Set search list to be blank-separated strings
* on rest of line.
*/
- cp = _res.defdname;
- pp = _res.dnsrch;
+ cp = _resp->defdname;
+ pp = _resp->dnsrch;
*pp++ = cp;
- for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
+ for (n = 0; *cp && pp < _resp->dnsrch + MAXDNSRCH; cp++) {
if (*cp == ' ' || *cp == '\t') {
*cp = 0;
n = 1;
@@ -375,19 +389,19 @@ res_init()
res = NULL;
if (getaddrinfo(cp, pbuf, &hints, &res) == 0 &&
res->ai_next == NULL) {
- if (res->ai_addrlen <= sizeof(_res_ext.nsaddr_list[nserv])) {
- memcpy(&_res_ext.nsaddr_list[nserv], res->ai_addr,
+ if (res->ai_addrlen <= sizeof(_res_extp->nsaddr_list[nserv])) {
+ memcpy(&_res_extp->nsaddr_list[nserv], res->ai_addr,
res->ai_addrlen);
} else {
- memset(&_res_ext.nsaddr_list[nserv], 0,
- sizeof(_res_ext.nsaddr_list[nserv]));
+ memset(&_res_extp->nsaddr_list[nserv], 0,
+ sizeof(_res_extp->nsaddr_list[nserv]));
}
- if (res->ai_addrlen <= sizeof(_res.nsaddr_list[nserv])) {
- memcpy(&_res.nsaddr_list[nserv], res->ai_addr,
+ if (res->ai_addrlen <= sizeof(_resp->nsaddr_list[nserv])) {
+ memcpy(&_resp->nsaddr_list[nserv], res->ai_addr,
res->ai_addrlen);
} else {
- memset(&_res.nsaddr_list[nserv], 0,
- sizeof(_res.nsaddr_list[nserv]));
+ memset(&_resp->nsaddr_list[nserv], 0,
+ sizeof(_resp->nsaddr_list[nserv]));
}
nserv++;
}
@@ -395,11 +409,11 @@ res_init()
freeaddrinfo(res);
#else /* INET6 */
if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
- _res.nsaddr_list[nserv].sin_addr = a;
- _res.nsaddr_list[nserv].sin_family = AF_INET;
- _res.nsaddr_list[nserv].sin_port =
+ _resp->nsaddr_list[nserv].sin_addr = a;
+ _resp->nsaddr_list[nserv].sin_family = AF_INET;
+ _resp->nsaddr_list[nserv].sin_port =
htons(NAMESERVER_PORT);
- _res.nsaddr_list[nserv].sin_len =
+ _resp->nsaddr_list[nserv].sin_len =
sizeof(struct sockaddr_in);
nserv++;
}
@@ -428,7 +442,7 @@ res_init()
n = *cp;
*cp = 0;
if (inet_aton(net, &a)) {
- _res.sort_list[nsort].addr = a;
+ _resp->sort_list[nsort].addr = a;
if (ISSORTMASK(n)) {
*cp++ = n;
net = cp;
@@ -438,29 +452,29 @@ res_init()
n = *cp;
*cp = 0;
if (inet_aton(net, &a)) {
- _res.sort_list[nsort].mask = a.s_addr;
+ _resp->sort_list[nsort].mask = a.s_addr;
} else {
- _res.sort_list[nsort].mask =
- net_mask(_res.sort_list[nsort].addr);
+ _resp->sort_list[nsort].mask =
+ net_mask(_resp->sort_list[nsort].addr);
}
} else {
- _res.sort_list[nsort].mask =
- net_mask(_res.sort_list[nsort].addr);
+ _resp->sort_list[nsort].mask =
+ net_mask(_resp->sort_list[nsort].addr);
}
#ifdef INET6
- _res_ext.sort_list[nsort].af = AF_INET;
- _res_ext.sort_list[nsort].addr.ina =
- _res.sort_list[nsort].addr;
- _res_ext.sort_list[nsort].mask.ina.s_addr =
- _res.sort_list[nsort].mask;
+ _res_extp->sort_list[nsort].af = AF_INET;
+ _res_extp->sort_list[nsort].addr.ina =
+ _resp->sort_list[nsort].addr;
+ _res_extp->sort_list[nsort].mask.ina.s_addr =
+ _resp->sort_list[nsort].mask;
#endif /* INET6 */
nsort++;
}
#ifdef INET6
else if (inet_pton(AF_INET6, net, &a6) == 1) {
- _res_ext.sort_list[nsort].af = AF_INET6;
- _res_ext.sort_list[nsort].addr.in6a = a6;
- u = (u_char *)&_res_ext.sort_list[nsort].mask.in6a;
+ _res_extp->sort_list[nsort].af = AF_INET6;
+ _res_extp->sort_list[nsort].addr.in6a = a6;
+ u = (u_char *)&_res_extp->sort_list[nsort].mask.in6a;
*cp++ = n;
net = cp;
while (*cp && *cp != ';' &&
@@ -510,33 +524,33 @@ res_init()
}
}
if (nserv > 1)
- _res.nscount = nserv;
+ _resp->nscount = nserv;
#ifdef RESOLVSORT
- _res.nsort = nsort;
+ _resp->nsort = nsort;
#endif
(void) fclose(fp);
}
- if (_res.defdname[0] == 0 &&
- gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
+ if (_resp->defdname[0] == 0 &&
+ gethostname(buf, sizeof(_resp->defdname) - 1) == 0 &&
(cp = strchr(buf, '.')) != NULL)
{
- strlcpy(_res.defdname, cp + 1,
- sizeof(_res.defdname));
+ strlcpy(_resp->defdname, cp + 1,
+ sizeof(_resp->defdname));
}
/* find components of local domain that might be searched */
if (havesearch == 0) {
- pp = _res.dnsrch;
- *pp++ = _res.defdname;
+ pp = _resp->dnsrch;
+ *pp++ = _resp->defdname;
*pp = NULL;
#ifndef RFC1535
dots = 0;
- for (cp = _res.defdname; *cp; cp++)
+ for (cp = _resp->defdname; *cp; cp++)
dots += (*cp == '.');
- cp = _res.defdname;
- while (pp < _res.dnsrch + MAXDFLSRCH) {
+ cp = _resp->defdname;
+ while (pp < _resp->dnsrch + MAXDFLSRCH) {
if (dots < LOCALDOMAINPARTS)
break;
cp = strchr(cp, '.') + 1; /* we know there is one */
@@ -545,9 +559,9 @@ res_init()
}
*pp = NULL;
#ifdef DEBUG
- if (_res.options & RES_DEBUG) {
+ if (_resp->options & RES_DEBUG) {
printf(";; res_init()... default dnsrch list:\n");
- for (pp = _res.dnsrch; *pp; pp++)
+ for (pp = _resp->dnsrch; *pp; pp++)
printf(";;\t%s\n", *pp);
printf(";;\t..END..\n");
}
@@ -556,10 +570,10 @@ res_init()
}
if (issetugid())
- _res.options |= RES_NOALIASES;
+ _resp->options |= RES_NOALIASES;
else if ((cp = getenv("RES_OPTIONS")) != NULL)
res_setoptions(cp, "env");
- _res.options |= RES_INIT;
+ _resp->options |= RES_INIT;
return (0);
}
@@ -568,12 +582,13 @@ static void
res_setoptions(options, source)
char *options, *source;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
char *cp = options;
char *endp;
long l;
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_setoptions(\"%s\", \"%s\")...\n",
options, source);
#endif
@@ -588,31 +603,31 @@ res_setoptions(options, source)
if (l >= 0 && endp != p &&
(*endp = '\0' || isspace(*endp))) {
if (l <= RES_MAXNDOTS)
- _res.ndots = l;
+ _resp->ndots = l;
else
- _res.ndots = RES_MAXNDOTS;
+ _resp->ndots = RES_MAXNDOTS;
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
- printf(";;\tndots=%u\n", _res.ndots);
+ if (_resp->options & RES_DEBUG)
+ printf(";;\tndots=%u\n", _resp->ndots);
#endif
}
} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
#ifdef DEBUG
- if (!(_res.options & RES_DEBUG)) {
+ if (!(_resp->options & RES_DEBUG)) {
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
options, source);
- _res.options |= RES_DEBUG;
+ _resp->options |= RES_DEBUG;
}
printf(";;\tdebug\n");
#endif
} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
- _res.options |= RES_USE_INET6;
+ _resp->options |= RES_USE_INET6;
} else if (!strncmp(cp, "insecure1", sizeof("insecure1") - 1)) {
- _res.options |= RES_INSECURE1;
+ _resp->options |= RES_INSECURE1;
} else if (!strncmp(cp, "insecure2", sizeof("insecure2") - 1)) {
- _res.options |= RES_INSECURE2;
+ _resp->options |= RES_INSECURE2;
} else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
- _res.options |= RES_USE_EDNS0;
+ _resp->options |= RES_USE_EDNS0;
} else {
/* XXX - print a warning here? */
}
diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c
index 6cd6a00dbe4..bb8f1f07258 100644
--- a/lib/libc/net/res_mkquery.c
+++ b/lib/libc/net/res_mkquery.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_mkquery.c,v 1.12 2002/08/28 03:19:38 itojun Exp $ */
+/* $OpenBSD: res_mkquery.c,v 1.13 2003/01/28 04:58:00 marc Exp $ */
/*
* ++Copyright++ 1985, 1993
@@ -60,7 +60,7 @@
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$From: res_mkquery.c,v 8.5 1996/08/27 08:33:28 vixie Exp $";
#else
-static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.12 2002/08/28 03:19:38 itojun Exp $";
+static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.13 2003/01/28 04:58:00 marc Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -74,6 +74,8 @@ static char rcsid[] = "$OpenBSD: res_mkquery.c,v 1.12 2002/08/28 03:19:38 itojun
#include <resolv.h>
#include <string.h>
+#include "thread_private.h"
+
/*
* Form all types of queries.
* Returns the size of the result or -1.
@@ -90,17 +92,18 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
u_char *buf; /* buffer to put query */
int buflen; /* size of buffer */
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
register HEADER *hp;
register u_char *cp, *ep;
register int n;
u_char *dnptrs[20], **dpp, **lastdnptr;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_mkquery(%d, %s, %d, %d)\n",
op, dname, class, type);
#endif
@@ -116,10 +119,10 @@ res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
return (-1);
bzero(buf, HFIXEDSZ);
hp = (HEADER *) buf;
- _res.id = res_randomid();
- hp->id = htons(_res.id);
+ _resp->id = res_randomid();
+ hp->id = htons(_resp->id);
hp->opcode = op;
- hp->rd = (_res.options & RES_RECURSE) != 0;
+ hp->rd = (_resp->options & RES_RECURSE) != 0;
hp->rcode = NOERROR;
cp = buf + HFIXEDSZ;
ep = buf + buflen;
@@ -203,6 +206,7 @@ res_opt(n0, buf, buflen, anslen)
int buflen; /* size of buffer */
int anslen; /* answer buffer length */
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
register HEADER *hp;
register u_char *cp, *ep;
@@ -223,9 +227,9 @@ res_opt(n0, buf, buflen, anslen)
cp += INT16SZ;
*cp++ = NOERROR; /* extended RCODE */
*cp++ = 0; /* EDNS version */
- if (_res.options & RES_USE_DNSSEC) {
+ if (_resp->options & RES_USE_DNSSEC) {
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_opt()... ENDS0 DNSSEC OK\n");
#endif /* DEBUG */
__putshort(DNS_MESSAGEEXTFLAG_DO, cp); /* EDNS Z field */
diff --git a/lib/libc/net/res_query.c b/lib/libc/net/res_query.c
index 9c1aef1218f..1e949e8efaf 100644
--- a/lib/libc/net/res_query.c
+++ b/lib/libc/net/res_query.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun Exp $ */
+/* $OpenBSD: res_query.c,v 1.20 2003/01/28 04:58:00 marc Exp $ */
/*
* ++Copyright++ 1988, 1993
@@ -60,7 +60,7 @@
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $";
#else
-static char rcsid[] = "$OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun Exp $";
+static char rcsid[] = "$OpenBSD: res_query.c,v 1.20 2003/01/28 04:58:00 marc Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -79,6 +79,8 @@ static char rcsid[] = "$OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun E
#include <string.h>
#include <unistd.h>
+#include "thread_private.h"
+
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
#else
@@ -106,31 +108,32 @@ res_query(name, class, type, answer, anslen)
u_char *answer; /* buffer to put answer */
int anslen; /* size of answer buffer */
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
u_char buf[MAXPACKET];
register HEADER *hp = (HEADER *) answer;
int n;
hp->rcode = NOERROR; /* default */
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_query(%s, %d, %d)\n", name, class, type);
#endif
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
buf, sizeof(buf));
- if (n > 0 && ((_res.options & RES_USE_EDNS0) ||
- (_res.options & RES_USE_DNSSEC))) {
+ if (n > 0 && ((_resp->options & RES_USE_EDNS0) ||
+ (_resp->options & RES_USE_DNSSEC))) {
n = res_opt(n, buf, sizeof(buf), anslen);
}
if (n <= 0) {
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_query: mkquery failed\n");
#endif
h_errno = NO_RECOVERY;
@@ -139,7 +142,7 @@ res_query(name, class, type, answer, anslen)
n = res_send(buf, n, answer, anslen);
if (n < 0) {
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_query: send error\n");
#endif
h_errno = TRY_AGAIN;
@@ -148,7 +151,7 @@ res_query(name, class, type, answer, anslen)
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; rcode = %u, ancount=%u\n", hp->rcode,
ntohs(hp->ancount));
#endif
@@ -188,12 +191,13 @@ res_search(name, class, type, answer, anslen)
int anslen; /* size of answer */
{
register const char *cp, * const *domain;
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
HEADER *hp = (HEADER *) answer;
u_int dots;
int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
@@ -217,7 +221,7 @@ res_search(name, class, type, answer, anslen)
* 'as is'. The threshold can be set with the "ndots" option.
*/
saved_herrno = -1;
- if (dots >= _res.ndots) {
+ if (dots >= _resp->ndots) {
ret = res_querydomain(name, NULL, class, type, answer, anslen);
if (ret > 0)
return (ret);
@@ -231,11 +235,11 @@ res_search(name, class, type, answer, anslen)
* - there is at least one dot, there is no trailing dot,
* and RES_DNSRCH is set.
*/
- if ((!dots && (_res.options & RES_DEFNAMES)) ||
- (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
+ if ((!dots && (_resp->options & RES_DEFNAMES)) ||
+ (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
int done = 0;
- for (domain = (const char * const *)_res.dnsrch;
+ for (domain = (const char * const *)_resp->dnsrch;
*domain && !done;
domain++) {
@@ -284,7 +288,7 @@ res_search(name, class, type, answer, anslen)
/* if we got here for some reason other than DNSRCH,
* we only wanted one iteration of the loop, so stop.
*/
- if (!(_res.options & RES_DNSRCH))
+ if (!(_resp->options & RES_DNSRCH))
done++;
}
}
@@ -326,16 +330,17 @@ res_querydomain(name, domain, class, type, answer, anslen)
u_char *answer; /* buffer to put answer */
int anslen; /* size of answer */
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
char nbuf[MAXDNAME*2+1+1];
const char *longname = nbuf;
int n;
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
h_errno = NETDB_INTERNAL;
return (-1);
}
#ifdef DEBUG
- if (_res.options & RES_DEBUG)
+ if (_resp->options & RES_DEBUG)
printf(";; res_querydomain(%s, %s, %d, %d)\n",
name, domain?domain:"<Nil>", class, type);
#endif
@@ -361,6 +366,7 @@ const char *
hostalias(name)
register const char *name;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
register char *cp1, *cp2;
FILE *fp;
char *file;
@@ -368,7 +374,7 @@ hostalias(name)
static char abuf[MAXDNAME];
size_t len;
- if (_res.options & RES_NOALIASES)
+ if (_resp->options & RES_NOALIASES)
return (NULL);
file = getenv("HOSTALIASES");
if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL)
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index b043e7c9fb7..282675a533d 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_send.c,v 1.12 2002/09/06 18:35:12 deraadt Exp $ */
+/* $OpenBSD: res_send.c,v 1.13 2003/01/28 04:58:00 marc Exp $ */
/*
* ++Copyright++ 1985, 1989, 1993
@@ -64,7 +64,7 @@
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $";
#else
-static char rcsid[] = "$OpenBSD: res_send.c,v 1.12 2002/09/06 18:35:12 deraadt Exp $";
+static char rcsid[] = "$OpenBSD: res_send.c,v 1.13 2003/01/28 04:58:00 marc Exp $";
#endif
#endif /* LIBC_SCCS and not lint */
@@ -96,6 +96,8 @@ static char rcsid[] = "$OpenBSD: res_send.c,v 1.12 2002/09/06 18:35:12 deraadt E
#include <string.h>
#include <unistd.h>
+#include "thread_private.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 ciruit? */
@@ -136,9 +138,10 @@ static void Perror(FILE *, char *, int);
int error;
struct sockaddr *address;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int save = errno;
- if (_res.options & RES_DEBUG) {
+ if (_resp->options & RES_DEBUG) {
if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf),
pbuf, sizeof(pbuf),
NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID) != 0) {
@@ -156,9 +159,10 @@ static void Perror(FILE *, char *, int);
char *string;
int error;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
int save = errno;
- if (_res.options & RES_DEBUG) {
+ if (_resp->options & RES_DEBUG) {
fprintf(file, "res_send: %s: %s\n",
string, strerror(error));
}
@@ -195,30 +199,33 @@ static struct sockaddr *
get_nsaddr(n)
size_t n;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
+ struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext,
+ &_res_ext);
- if (!_res.nsaddr_list[n].sin_family) {
+ if (!_resp->nsaddr_list[n].sin_family) {
/*
- * - _res_ext.nsaddr_list[n] holds an address that is larger
+ * - _res_extp->nsaddr_list[n] holds an address that is larger
* than struct sockaddr, and
- * - user code did not update _res.nsaddr_list[n].
+ * - user code did not update _resp->nsaddr_list[n].
*/
- return (struct sockaddr *)&_res_ext.nsaddr_list[n];
+ return (struct sockaddr *)&_res_extp->nsaddr_list[n];
} else {
/*
* - user code updated _res.nsaddr_list[n], or
- * - _res.nsaddr_list[n] has the same content as
- * _res_ext.nsaddr_list[n].
+ * - _resp->nsaddr_list[n] has the same content as
+ * _res_extp->nsaddr_list[n].
*/
- return (struct sockaddr *)&_res.nsaddr_list[n];
+ return (struct sockaddr *)&_resp->nsaddr_list[n];
}
}
#else
-#define get_nsaddr(n) ((struct sockaddr *)&_res.nsaddr_list[(n)])
+#define get_nsaddr(n) ((struct sockaddr *)&_resp->nsaddr_list[(n)])
#endif
/* int
* res_isourserver(ina)
- * looks up "ina" in _res.ns_addr_list[]
+ * looks up "ina" in _resp->ns_addr_list[]
* returns:
* 0 : not found
* >0 : found
@@ -229,6 +236,7 @@ int
res_isourserver(inp)
const struct sockaddr_in *inp;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
#ifdef INET6
const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp;
const struct sockaddr_in6 *srv6;
@@ -240,7 +248,7 @@ res_isourserver(inp)
switch (inp->sin_family) {
#ifdef INET6
case AF_INET6:
- for (ns = 0; ns < _res.nscount; ns++) {
+ for (ns = 0; ns < _resp->nscount; ns++) {
srv6 = (struct sockaddr_in6 *)get_nsaddr(ns);
if (srv6->sin6_family == in6p->sin6_family &&
srv6->sin6_port == in6p->sin6_port &&
@@ -255,7 +263,7 @@ res_isourserver(inp)
break;
#endif
case AF_INET:
- for (ns = 0; ns < _res.nscount; ns++) {
+ for (ns = 0; ns < _resp->nscount; ns++) {
srv = (struct sockaddr_in *)get_nsaddr(ns);
if (srv->sin_family == inp->sin_family &&
srv->sin_port == inp->sin_port &&
@@ -351,19 +359,20 @@ res_send(buf, buflen, ans, anssiz)
u_char *ans;
int anssiz;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
HEADER *hp = (HEADER *) buf;
HEADER *anhp = (HEADER *) ans;
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns;
register int n;
u_int badns; /* XXX NSMAX can't exceed #/bits in this var */
- if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
/* errno should have been set by res_init() in this case. */
return (-1);
}
- DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
+ DprintQ((_resp->options & RES_DEBUG) || (_resp->pfcode & RES_PRF_QUERY),
(stdout, ";; res_send()\n"), buf, buflen);
- v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
+ v_circuit = (_resp->options & RES_USEVC) || buflen > PACKETSZ;
gotsomewhere = 0;
connreset = 0;
terrno = ETIMEDOUT;
@@ -372,8 +381,8 @@ res_send(buf, buflen, ans, anssiz)
/*
* Send request, RETRY times, or until successful
*/
- for (try = 0; try < _res.retry; try++) {
- for (ns = 0; ns < _res.nscount; ns++) {
+ for (try = 0; try < _resp->retry; try++) {
+ for (ns = 0; ns < _resp->nscount; ns++) {
struct sockaddr *nsap = get_nsaddr(ns);
socklen_t salen;
@@ -425,7 +434,7 @@ res_send(buf, buflen, ans, anssiz)
} while (!done);
}
- Dprint((_res.options & RES_DEBUG) &&
+ Dprint((_resp->options & RES_DEBUG) &&
getnameinfo(nsap, salen, abuf, sizeof(abuf),
NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) == 0,
(stdout, ";; Querying server (# %d) address = %s\n",
@@ -441,7 +450,7 @@ res_send(buf, buflen, ans, anssiz)
* Use virtual circuit;
* at most one attempt per server.
*/
- try = _res.retry;
+ try = _resp->retry;
truncated = 0;
if ((s < 0) || (!vc) || (af != nsap->sa_family)) {
if (s >= 0)
@@ -520,7 +529,7 @@ read_len:
}
resplen = _getshort(ans);
if (resplen > anssiz) {
- Dprint(_res.options & RES_DEBUG,
+ Dprint(_resp->options & RES_DEBUG,
(stdout, ";; response truncated\n")
);
truncated = 1;
@@ -566,8 +575,8 @@ read_len:
* wait for the correct one.
*/
if (hp->id != anhp->id) {
- DprintQ((_res.options & RES_DEBUG) ||
- (_res.pfcode & RES_PRF_REPLY),
+ DprintQ((_resp->options & RES_DEBUG) ||
+ (_resp->pfcode & RES_PRF_REPLY),
(stdout, ";; old answer (unexpected):\n"),
ans, (resplen>anssiz)?anssiz:resplen);
goto read_len;
@@ -625,8 +634,8 @@ read_len:
* as we wish to receive answers from the first
* server to respond.
*/
- if (!(_res.options & RES_INSECURE1) &&
- (_res.nscount == 1 || (try == 0 && ns == 0))) {
+ if (!(_resp->options & RES_INSECURE1) &&
+ (_resp->nscount == 1 || (try == 0 && ns == 0))) {
/*
* Connect only if we are sure we won't
* receive a response from another server.
@@ -673,7 +682,7 @@ read_len:
goto bad_dg_sock;
(void) dup2(s1, s);
(void) close(s1);
- Dprint(_res.options & RES_DEBUG,
+ Dprint(_resp->options & RES_DEBUG,
(stdout, ";; new DG socket\n"))
#endif
#ifdef IPV6_MINMTU
@@ -699,9 +708,9 @@ read_len:
/*
* Wait for reply
*/
- timeout.tv_sec = (_res.retrans << try);
+ timeout.tv_sec = (_resp->retrans << try);
if (try > 0)
- timeout.tv_sec /= _res.nscount;
+ timeout.tv_sec /= _resp->nscount;
if ((long) timeout.tv_sec <= 0)
timeout.tv_sec = 1;
timeout.tv_usec = 0;
@@ -727,7 +736,7 @@ read_len:
/*
* timeout
*/
- Dprint(_res.options & RES_DEBUG,
+ Dprint(_resp->options & RES_DEBUG,
(stdout, ";; timeout\n"));
gotsomewhere = 1;
res_close();
@@ -749,28 +758,28 @@ read_len:
* XXX - potential security hazard could
* be detected here.
*/
- DprintQ((_res.options & RES_DEBUG) ||
- (_res.pfcode & RES_PRF_REPLY),
+ DprintQ((_resp->options & RES_DEBUG) ||
+ (_resp->pfcode & RES_PRF_REPLY),
(stdout, ";; old answer:\n"),
ans, (resplen>anssiz)?anssiz:resplen);
goto wait;
}
#if CHECK_SRVR_ADDR
- if (!(_res.options & RES_INSECURE1) &&
+ if (!(_resp->options & RES_INSECURE1) &&
!res_isourserver((struct sockaddr_in *)&from)) {
/*
* response from wrong server? ignore it.
* XXX - potential security hazard could
* be detected here.
*/
- DprintQ((_res.options & RES_DEBUG) ||
- (_res.pfcode & RES_PRF_REPLY),
+ DprintQ((_resp->options & RES_DEBUG) ||
+ (_resp->pfcode & RES_PRF_REPLY),
(stdout, ";; not our server:\n"),
ans, (resplen>anssiz)?anssiz:resplen);
goto wait;
}
#endif
- if (!(_res.options & RES_INSECURE2) &&
+ if (!(_resp->options & RES_INSECURE2) &&
!res_queriesmatch(buf, buf + buflen,
ans, ans + anssiz)) {
/*
@@ -778,8 +787,8 @@ read_len:
* XXX - potential security hazard could
* be detected here.
*/
- DprintQ((_res.options & RES_DEBUG) ||
- (_res.pfcode & RES_PRF_REPLY),
+ DprintQ((_resp->options & RES_DEBUG) ||
+ (_resp->pfcode & RES_PRF_REPLY),
(stdout, ";; wrong query name:\n"),
ans, (resplen>anssiz)?anssiz:resplen);
goto wait;
@@ -787,33 +796,33 @@ read_len:
if (anhp->rcode == SERVFAIL ||
anhp->rcode == NOTIMP ||
anhp->rcode == REFUSED) {
- DprintQ(_res.options & RES_DEBUG,
+ DprintQ(_resp->options & RES_DEBUG,
(stdout, "server rejected query:\n"),
ans, (resplen>anssiz)?anssiz:resplen);
badns |= (1 << ns);
res_close();
/* don't retry if called from dig */
- if (!_res.pfcode)
+ if (!_resp->pfcode)
goto next_ns;
}
- if (!(_res.options & RES_IGNTC) && anhp->tc) {
+ if (!(_resp->options & RES_IGNTC) && anhp->tc) {
/*
* get rest of answer;
* use TCP with same server.
*/
- Dprint(_res.options & RES_DEBUG,
+ Dprint(_resp->options & RES_DEBUG,
(stdout, ";; truncated answer\n"));
v_circuit = 1;
res_close();
goto same_ns;
}
} /*if vc/dg*/
- Dprint((_res.options & RES_DEBUG) ||
- ((_res.pfcode & RES_PRF_REPLY) &&
- (_res.pfcode & RES_PRF_HEAD1)),
+ Dprint((_resp->options & RES_DEBUG) ||
+ ((_resp->pfcode & RES_PRF_REPLY) &&
+ (_resp->pfcode & RES_PRF_HEAD1)),
(stdout, ";; got answer:\n"));
- DprintQ((_res.options & RES_DEBUG) ||
- (_res.pfcode & RES_PRF_REPLY),
+ DprintQ((_resp->options & RES_DEBUG) ||
+ (_resp->pfcode & RES_PRF_REPLY),
(stdout, "%s", ""),
ans, (resplen>anssiz)?anssiz:resplen);
/*
@@ -824,8 +833,8 @@ read_len:
* or if we haven't been asked to keep a socket open,
* close the socket.
*/
- if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
- !(_res.options & RES_STAYOPEN)) {
+ if ((v_circuit && (!(_resp->options & RES_USEVC) || ns != 0)) ||
+ !(_resp->options & RES_STAYOPEN)) {
res_close();
}
if (Rhook) {
diff --git a/lib/libc/net/sethostent.c b/lib/libc/net/sethostent.c
index 5392a2f11bb..40a5a809629 100644
--- a/lib/libc/net/sethostent.c
+++ b/lib/libc/net/sethostent.c
@@ -32,7 +32,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$OpenBSD: sethostent.c,v 1.4 1997/03/15 21:53:50 pefo Exp $";
+static char rcsid[] = "$OpenBSD: sethostent.c,v 1.5 2003/01/28 04:58:00 marc Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/param.h>
@@ -41,20 +41,25 @@ static char rcsid[] = "$OpenBSD: sethostent.c,v 1.4 1997/03/15 21:53:50 pefo Exp
#include <netdb.h>
#include <resolv.h>
+#include "thread_private.h"
+
void
sethostent(stayopen)
int stayopen;
{
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
- if ((_res.options & RES_INIT) == 0 && res_init() == -1)
+ if ((_resp->options & RES_INIT) == 0 && res_init() == -1)
return;
if (stayopen)
- _res.options |= RES_STAYOPEN | RES_USEVC;
+ _resp->options |= RES_STAYOPEN | RES_USEVC;
}
void
endhostent()
{
- _res.options &= ~(RES_STAYOPEN | RES_USEVC);
+ struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
+
+ _resp->options &= ~(RES_STAYOPEN | RES_USEVC);
res_close();
}