summaryrefslogtreecommitdiff
path: root/src/lib/libc/net/res_query.c
diff options
context:
space:
mode:
authormarc <>2003-01-28 04:58:00 +0000
committermarc <>2003-01-28 04:58:00 +0000
commit547ebab319b228b064cf5dcb3ff0ae1bf23d24a2 (patch)
treef57454716593fb3b68672505c6dccab6438498f1 /src/lib/libc/net/res_query.c
parent98a78d57b176408b5aca87705f9681c5b155b47c (diff)
downloadopenbsd-547ebab319b228b064cf5dcb3ff0ae1bf23d24a2.tar.gz
openbsd-547ebab319b228b064cf5dcb3ff0ae1bf23d24a2.tar.bz2
openbsd-547ebab319b228b064cf5dcb3ff0ae1bf23d24a2.zip
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 'src/lib/libc/net/res_query.c')
-rw-r--r--src/lib/libc/net/res_query.c42
1 files changed, 24 insertions, 18 deletions
diff --git a/src/lib/libc/net/res_query.c b/src/lib/libc/net/res_query.c
index 9c1aef1218..1e949e8efa 100644
--- a/src/lib/libc/net/res_query.c
+++ b/src/lib/libc/net/res_query.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun Exp $ */ 1/* $OpenBSD: res_query.c,v 1.20 2003/01/28 04:58:00 marc Exp $ */
2 2
3/* 3/*
4 * ++Copyright++ 1988, 1993 4 * ++Copyright++ 1988, 1993
@@ -60,7 +60,7 @@
60static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; 60static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
61static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $"; 61static char rcsid[] = "$From: res_query.c,v 8.9 1996/09/22 00:13:28 vixie Exp $";
62#else 62#else
63static char rcsid[] = "$OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun Exp $"; 63static char rcsid[] = "$OpenBSD: res_query.c,v 1.20 2003/01/28 04:58:00 marc Exp $";
64#endif 64#endif
65#endif /* LIBC_SCCS and not lint */ 65#endif /* LIBC_SCCS and not lint */
66 66
@@ -79,6 +79,8 @@ static char rcsid[] = "$OpenBSD: res_query.c,v 1.19 2002/06/27 09:55:49 itojun E
79#include <string.h> 79#include <string.h>
80#include <unistd.h> 80#include <unistd.h>
81 81
82#include "thread_private.h"
83
82#if PACKETSZ > 1024 84#if PACKETSZ > 1024
83#define MAXPACKET PACKETSZ 85#define MAXPACKET PACKETSZ
84#else 86#else
@@ -106,31 +108,32 @@ res_query(name, class, type, answer, anslen)
106 u_char *answer; /* buffer to put answer */ 108 u_char *answer; /* buffer to put answer */
107 int anslen; /* size of answer buffer */ 109 int anslen; /* size of answer buffer */
108{ 110{
111 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
109 u_char buf[MAXPACKET]; 112 u_char buf[MAXPACKET];
110 register HEADER *hp = (HEADER *) answer; 113 register HEADER *hp = (HEADER *) answer;
111 int n; 114 int n;
112 115
113 hp->rcode = NOERROR; /* default */ 116 hp->rcode = NOERROR; /* default */
114 117
115 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 118 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
116 h_errno = NETDB_INTERNAL; 119 h_errno = NETDB_INTERNAL;
117 return (-1); 120 return (-1);
118 } 121 }
119#ifdef DEBUG 122#ifdef DEBUG
120 if (_res.options & RES_DEBUG) 123 if (_resp->options & RES_DEBUG)
121 printf(";; res_query(%s, %d, %d)\n", name, class, type); 124 printf(";; res_query(%s, %d, %d)\n", name, class, type);
122#endif 125#endif
123 126
124 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, 127 n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
125 buf, sizeof(buf)); 128 buf, sizeof(buf));
126 if (n > 0 && ((_res.options & RES_USE_EDNS0) || 129 if (n > 0 && ((_resp->options & RES_USE_EDNS0) ||
127 (_res.options & RES_USE_DNSSEC))) { 130 (_resp->options & RES_USE_DNSSEC))) {
128 n = res_opt(n, buf, sizeof(buf), anslen); 131 n = res_opt(n, buf, sizeof(buf), anslen);
129 } 132 }
130 133
131 if (n <= 0) { 134 if (n <= 0) {
132#ifdef DEBUG 135#ifdef DEBUG
133 if (_res.options & RES_DEBUG) 136 if (_resp->options & RES_DEBUG)
134 printf(";; res_query: mkquery failed\n"); 137 printf(";; res_query: mkquery failed\n");
135#endif 138#endif
136 h_errno = NO_RECOVERY; 139 h_errno = NO_RECOVERY;
@@ -139,7 +142,7 @@ res_query(name, class, type, answer, anslen)
139 n = res_send(buf, n, answer, anslen); 142 n = res_send(buf, n, answer, anslen);
140 if (n < 0) { 143 if (n < 0) {
141#ifdef DEBUG 144#ifdef DEBUG
142 if (_res.options & RES_DEBUG) 145 if (_resp->options & RES_DEBUG)
143 printf(";; res_query: send error\n"); 146 printf(";; res_query: send error\n");
144#endif 147#endif
145 h_errno = TRY_AGAIN; 148 h_errno = TRY_AGAIN;
@@ -148,7 +151,7 @@ res_query(name, class, type, answer, anslen)
148 151
149 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { 152 if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
150#ifdef DEBUG 153#ifdef DEBUG
151 if (_res.options & RES_DEBUG) 154 if (_resp->options & RES_DEBUG)
152 printf(";; rcode = %u, ancount=%u\n", hp->rcode, 155 printf(";; rcode = %u, ancount=%u\n", hp->rcode,
153 ntohs(hp->ancount)); 156 ntohs(hp->ancount));
154#endif 157#endif
@@ -188,12 +191,13 @@ res_search(name, class, type, answer, anslen)
188 int anslen; /* size of answer */ 191 int anslen; /* size of answer */
189{ 192{
190 register const char *cp, * const *domain; 193 register const char *cp, * const *domain;
194 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
191 HEADER *hp = (HEADER *) answer; 195 HEADER *hp = (HEADER *) answer;
192 u_int dots; 196 u_int dots;
193 int trailing_dot, ret, saved_herrno; 197 int trailing_dot, ret, saved_herrno;
194 int got_nodata = 0, got_servfail = 0, tried_as_is = 0; 198 int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
195 199
196 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 200 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
197 h_errno = NETDB_INTERNAL; 201 h_errno = NETDB_INTERNAL;
198 return (-1); 202 return (-1);
199 } 203 }
@@ -217,7 +221,7 @@ res_search(name, class, type, answer, anslen)
217 * 'as is'. The threshold can be set with the "ndots" option. 221 * 'as is'. The threshold can be set with the "ndots" option.
218 */ 222 */
219 saved_herrno = -1; 223 saved_herrno = -1;
220 if (dots >= _res.ndots) { 224 if (dots >= _resp->ndots) {
221 ret = res_querydomain(name, NULL, class, type, answer, anslen); 225 ret = res_querydomain(name, NULL, class, type, answer, anslen);
222 if (ret > 0) 226 if (ret > 0)
223 return (ret); 227 return (ret);
@@ -231,11 +235,11 @@ res_search(name, class, type, answer, anslen)
231 * - there is at least one dot, there is no trailing dot, 235 * - there is at least one dot, there is no trailing dot,
232 * and RES_DNSRCH is set. 236 * and RES_DNSRCH is set.
233 */ 237 */
234 if ((!dots && (_res.options & RES_DEFNAMES)) || 238 if ((!dots && (_resp->options & RES_DEFNAMES)) ||
235 (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { 239 (dots && !trailing_dot && (_resp->options & RES_DNSRCH))) {
236 int done = 0; 240 int done = 0;
237 241
238 for (domain = (const char * const *)_res.dnsrch; 242 for (domain = (const char * const *)_resp->dnsrch;
239 *domain && !done; 243 *domain && !done;
240 domain++) { 244 domain++) {
241 245
@@ -284,7 +288,7 @@ res_search(name, class, type, answer, anslen)
284 /* if we got here for some reason other than DNSRCH, 288 /* if we got here for some reason other than DNSRCH,
285 * we only wanted one iteration of the loop, so stop. 289 * we only wanted one iteration of the loop, so stop.
286 */ 290 */
287 if (!(_res.options & RES_DNSRCH)) 291 if (!(_resp->options & RES_DNSRCH))
288 done++; 292 done++;
289 } 293 }
290 } 294 }
@@ -326,16 +330,17 @@ res_querydomain(name, domain, class, type, answer, anslen)
326 u_char *answer; /* buffer to put answer */ 330 u_char *answer; /* buffer to put answer */
327 int anslen; /* size of answer */ 331 int anslen; /* size of answer */
328{ 332{
333 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
329 char nbuf[MAXDNAME*2+1+1]; 334 char nbuf[MAXDNAME*2+1+1];
330 const char *longname = nbuf; 335 const char *longname = nbuf;
331 int n; 336 int n;
332 337
333 if ((_res.options & RES_INIT) == 0 && res_init() == -1) { 338 if ((_resp->options & RES_INIT) == 0 && res_init() == -1) {
334 h_errno = NETDB_INTERNAL; 339 h_errno = NETDB_INTERNAL;
335 return (-1); 340 return (-1);
336 } 341 }
337#ifdef DEBUG 342#ifdef DEBUG
338 if (_res.options & RES_DEBUG) 343 if (_resp->options & RES_DEBUG)
339 printf(";; res_querydomain(%s, %s, %d, %d)\n", 344 printf(";; res_querydomain(%s, %s, %d, %d)\n",
340 name, domain?domain:"<Nil>", class, type); 345 name, domain?domain:"<Nil>", class, type);
341#endif 346#endif
@@ -361,6 +366,7 @@ const char *
361hostalias(name) 366hostalias(name)
362 register const char *name; 367 register const char *name;
363{ 368{
369 struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res);
364 register char *cp1, *cp2; 370 register char *cp1, *cp2;
365 FILE *fp; 371 FILE *fp;
366 char *file; 372 char *file;
@@ -368,7 +374,7 @@ hostalias(name)
368 static char abuf[MAXDNAME]; 374 static char abuf[MAXDNAME];
369 size_t len; 375 size_t len;
370 376
371 if (_res.options & RES_NOALIASES) 377 if (_resp->options & RES_NOALIASES)
372 return (NULL); 378 return (NULL);
373 file = getenv("HOSTALIASES"); 379 file = getenv("HOSTALIASES");
374 if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL) 380 if (issetugid() != 0 || file == NULL || (fp = fopen(file, "r")) == NULL)