From 93357d25160373499d1be166f2df69454a23b5ce Mon Sep 17 00:00:00 2001 From: Marco S Hyman Date: Tue, 28 Jan 2003 04:58:01 +0000 Subject: 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@ --- lib/libc/include/thread_private.h | 11 ++- lib/libc/net/getaddrinfo.c | 76 ++++++++++------ lib/libc/net/gethostnamadr.c | 60 ++++++------ lib/libc/net/getnameinfo.c | 9 +- lib/libc/net/getnetnamadr.c | 20 ++-- lib/libc/net/getrrsetbyname.c | 13 ++- lib/libc/net/res_debug.c | 51 ++++++----- lib/libc/net/res_init.c | 187 ++++++++++++++++++++------------------ lib/libc/net/res_mkquery.c | 22 +++-- lib/libc/net/res_query.c | 42 +++++---- lib/libc/net/res_send.c | 109 ++++++++++++---------- lib/libc/net/sethostent.c | 13 ++- 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_ @@ -86,6 +86,15 @@ void * _libc_private_storage(volatile struct _thread_private_key_struct *, _libc_private_storage(&__THREAD_KEY_NAME(keyname), \ &(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. */ 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:""); #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 @@ -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 #include +#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 #include +#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 #include +#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 #include +#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 #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 #include +#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 #include +#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:"", 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 #include +#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 @@ -41,20 +41,25 @@ static char rcsid[] = "$OpenBSD: sethostent.c,v 1.4 1997/03/15 21:53:50 pefo Exp #include #include +#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(); } -- cgit v1.2.3