summaryrefslogtreecommitdiff
path: root/lib/libc/net/res_init.c
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 /lib/libc/net/res_init.c
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@
Diffstat (limited to 'lib/libc/net/res_init.c')
-rw-r--r--lib/libc/net/res_init.c187
1 files changed, 101 insertions, 86 deletions
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? */
}