diff options
Diffstat (limited to 'src/lib/libc/net/res_send.c')
-rw-r--r-- | src/lib/libc/net/res_send.c | 109 |
1 files changed, 59 insertions, 50 deletions
diff --git a/src/lib/libc/net/res_send.c b/src/lib/libc/net/res_send.c index b043e7c9fb..282675a533 100644 --- a/src/lib/libc/net/res_send.c +++ b/src/lib/libc/net/res_send.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: res_send.c,v 1.12 2002/09/06 18:35:12 deraadt Exp $ */ | 1 | /* $OpenBSD: res_send.c,v 1.13 2003/01/28 04:58:00 marc Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * ++Copyright++ 1985, 1989, 1993 | 4 | * ++Copyright++ 1985, 1989, 1993 |
@@ -64,7 +64,7 @@ | |||
64 | static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; | 64 | static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; |
65 | static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $"; | 65 | static char rcsid[] = "$From: res_send.c,v 8.12 1996/10/08 04:51:06 vixie Exp $"; |
66 | #else | 66 | #else |
67 | static char rcsid[] = "$OpenBSD: res_send.c,v 1.12 2002/09/06 18:35:12 deraadt Exp $"; | 67 | static char rcsid[] = "$OpenBSD: res_send.c,v 1.13 2003/01/28 04:58:00 marc Exp $"; |
68 | #endif | 68 | #endif |
69 | #endif /* LIBC_SCCS and not lint */ | 69 | #endif /* LIBC_SCCS and not lint */ |
70 | 70 | ||
@@ -96,6 +96,8 @@ static char rcsid[] = "$OpenBSD: res_send.c,v 1.12 2002/09/06 18:35:12 deraadt E | |||
96 | #include <string.h> | 96 | #include <string.h> |
97 | #include <unistd.h> | 97 | #include <unistd.h> |
98 | 98 | ||
99 | #include "thread_private.h" | ||
100 | |||
99 | static int s = -1; /* socket used for communications */ | 101 | static int s = -1; /* socket used for communications */ |
100 | static int connected = 0; /* is the socket connected */ | 102 | static int connected = 0; /* is the socket connected */ |
101 | static int vc = 0; /* is the socket a virtual ciruit? */ | 103 | static int vc = 0; /* is the socket a virtual ciruit? */ |
@@ -136,9 +138,10 @@ static void Perror(FILE *, char *, int); | |||
136 | int error; | 138 | int error; |
137 | struct sockaddr *address; | 139 | struct sockaddr *address; |
138 | { | 140 | { |
141 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
139 | int save = errno; | 142 | int save = errno; |
140 | 143 | ||
141 | if (_res.options & RES_DEBUG) { | 144 | if (_resp->options & RES_DEBUG) { |
142 | if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf), | 145 | if (getnameinfo(address, address->sa_len, abuf, sizeof(abuf), |
143 | pbuf, sizeof(pbuf), | 146 | pbuf, sizeof(pbuf), |
144 | NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID) != 0) { | 147 | NI_NUMERICHOST|NI_NUMERICSERV|NI_WITHSCOPEID) != 0) { |
@@ -156,9 +159,10 @@ static void Perror(FILE *, char *, int); | |||
156 | char *string; | 159 | char *string; |
157 | int error; | 160 | int error; |
158 | { | 161 | { |
162 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
159 | int save = errno; | 163 | int save = errno; |
160 | 164 | ||
161 | if (_res.options & RES_DEBUG) { | 165 | if (_resp->options & RES_DEBUG) { |
162 | fprintf(file, "res_send: %s: %s\n", | 166 | fprintf(file, "res_send: %s: %s\n", |
163 | string, strerror(error)); | 167 | string, strerror(error)); |
164 | } | 168 | } |
@@ -195,30 +199,33 @@ static struct sockaddr * | |||
195 | get_nsaddr(n) | 199 | get_nsaddr(n) |
196 | size_t n; | 200 | size_t n; |
197 | { | 201 | { |
202 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
203 | struct __res_state_ext *_res_extp = _THREAD_PRIVATE(_res_ext, _res_ext, | ||
204 | &_res_ext); | ||
198 | 205 | ||
199 | if (!_res.nsaddr_list[n].sin_family) { | 206 | if (!_resp->nsaddr_list[n].sin_family) { |
200 | /* | 207 | /* |
201 | * - _res_ext.nsaddr_list[n] holds an address that is larger | 208 | * - _res_extp->nsaddr_list[n] holds an address that is larger |
202 | * than struct sockaddr, and | 209 | * than struct sockaddr, and |
203 | * - user code did not update _res.nsaddr_list[n]. | 210 | * - user code did not update _resp->nsaddr_list[n]. |
204 | */ | 211 | */ |
205 | return (struct sockaddr *)&_res_ext.nsaddr_list[n]; | 212 | return (struct sockaddr *)&_res_extp->nsaddr_list[n]; |
206 | } else { | 213 | } else { |
207 | /* | 214 | /* |
208 | * - user code updated _res.nsaddr_list[n], or | 215 | * - user code updated _res.nsaddr_list[n], or |
209 | * - _res.nsaddr_list[n] has the same content as | 216 | * - _resp->nsaddr_list[n] has the same content as |
210 | * _res_ext.nsaddr_list[n]. | 217 | * _res_extp->nsaddr_list[n]. |
211 | */ | 218 | */ |
212 | return (struct sockaddr *)&_res.nsaddr_list[n]; | 219 | return (struct sockaddr *)&_resp->nsaddr_list[n]; |
213 | } | 220 | } |
214 | } | 221 | } |
215 | #else | 222 | #else |
216 | #define get_nsaddr(n) ((struct sockaddr *)&_res.nsaddr_list[(n)]) | 223 | #define get_nsaddr(n) ((struct sockaddr *)&_resp->nsaddr_list[(n)]) |
217 | #endif | 224 | #endif |
218 | 225 | ||
219 | /* int | 226 | /* int |
220 | * res_isourserver(ina) | 227 | * res_isourserver(ina) |
221 | * looks up "ina" in _res.ns_addr_list[] | 228 | * looks up "ina" in _resp->ns_addr_list[] |
222 | * returns: | 229 | * returns: |
223 | * 0 : not found | 230 | * 0 : not found |
224 | * >0 : found | 231 | * >0 : found |
@@ -229,6 +236,7 @@ int | |||
229 | res_isourserver(inp) | 236 | res_isourserver(inp) |
230 | const struct sockaddr_in *inp; | 237 | const struct sockaddr_in *inp; |
231 | { | 238 | { |
239 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
232 | #ifdef INET6 | 240 | #ifdef INET6 |
233 | const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp; | 241 | const struct sockaddr_in6 *in6p = (const struct sockaddr_in6 *)inp; |
234 | const struct sockaddr_in6 *srv6; | 242 | const struct sockaddr_in6 *srv6; |
@@ -240,7 +248,7 @@ res_isourserver(inp) | |||
240 | switch (inp->sin_family) { | 248 | switch (inp->sin_family) { |
241 | #ifdef INET6 | 249 | #ifdef INET6 |
242 | case AF_INET6: | 250 | case AF_INET6: |
243 | for (ns = 0; ns < _res.nscount; ns++) { | 251 | for (ns = 0; ns < _resp->nscount; ns++) { |
244 | srv6 = (struct sockaddr_in6 *)get_nsaddr(ns); | 252 | srv6 = (struct sockaddr_in6 *)get_nsaddr(ns); |
245 | if (srv6->sin6_family == in6p->sin6_family && | 253 | if (srv6->sin6_family == in6p->sin6_family && |
246 | srv6->sin6_port == in6p->sin6_port && | 254 | srv6->sin6_port == in6p->sin6_port && |
@@ -255,7 +263,7 @@ res_isourserver(inp) | |||
255 | break; | 263 | break; |
256 | #endif | 264 | #endif |
257 | case AF_INET: | 265 | case AF_INET: |
258 | for (ns = 0; ns < _res.nscount; ns++) { | 266 | for (ns = 0; ns < _resp->nscount; ns++) { |
259 | srv = (struct sockaddr_in *)get_nsaddr(ns); | 267 | srv = (struct sockaddr_in *)get_nsaddr(ns); |
260 | if (srv->sin_family == inp->sin_family && | 268 | if (srv->sin_family == inp->sin_family && |
261 | srv->sin_port == inp->sin_port && | 269 | srv->sin_port == inp->sin_port && |
@@ -351,19 +359,20 @@ res_send(buf, buflen, ans, anssiz) | |||
351 | u_char *ans; | 359 | u_char *ans; |
352 | int anssiz; | 360 | int anssiz; |
353 | { | 361 | { |
362 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
354 | HEADER *hp = (HEADER *) buf; | 363 | HEADER *hp = (HEADER *) buf; |
355 | HEADER *anhp = (HEADER *) ans; | 364 | HEADER *anhp = (HEADER *) ans; |
356 | int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; | 365 | int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; |
357 | register int n; | 366 | register int n; |
358 | u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ | 367 | u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ |
359 | 368 | ||
360 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | 369 | if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { |
361 | /* errno should have been set by res_init() in this case. */ | 370 | /* errno should have been set by res_init() in this case. */ |
362 | return (-1); | 371 | return (-1); |
363 | } | 372 | } |
364 | DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY), | 373 | DprintQ((_resp->options & RES_DEBUG) || (_resp->pfcode & RES_PRF_QUERY), |
365 | (stdout, ";; res_send()\n"), buf, buflen); | 374 | (stdout, ";; res_send()\n"), buf, buflen); |
366 | v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; | 375 | v_circuit = (_resp->options & RES_USEVC) || buflen > PACKETSZ; |
367 | gotsomewhere = 0; | 376 | gotsomewhere = 0; |
368 | connreset = 0; | 377 | connreset = 0; |
369 | terrno = ETIMEDOUT; | 378 | terrno = ETIMEDOUT; |
@@ -372,8 +381,8 @@ res_send(buf, buflen, ans, anssiz) | |||
372 | /* | 381 | /* |
373 | * Send request, RETRY times, or until successful | 382 | * Send request, RETRY times, or until successful |
374 | */ | 383 | */ |
375 | for (try = 0; try < _res.retry; try++) { | 384 | for (try = 0; try < _resp->retry; try++) { |
376 | for (ns = 0; ns < _res.nscount; ns++) { | 385 | for (ns = 0; ns < _resp->nscount; ns++) { |
377 | struct sockaddr *nsap = get_nsaddr(ns); | 386 | struct sockaddr *nsap = get_nsaddr(ns); |
378 | socklen_t salen; | 387 | socklen_t salen; |
379 | 388 | ||
@@ -425,7 +434,7 @@ res_send(buf, buflen, ans, anssiz) | |||
425 | } while (!done); | 434 | } while (!done); |
426 | } | 435 | } |
427 | 436 | ||
428 | Dprint((_res.options & RES_DEBUG) && | 437 | Dprint((_resp->options & RES_DEBUG) && |
429 | getnameinfo(nsap, salen, abuf, sizeof(abuf), | 438 | getnameinfo(nsap, salen, abuf, sizeof(abuf), |
430 | NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) == 0, | 439 | NULL, 0, NI_NUMERICHOST | NI_WITHSCOPEID) == 0, |
431 | (stdout, ";; Querying server (# %d) address = %s\n", | 440 | (stdout, ";; Querying server (# %d) address = %s\n", |
@@ -441,7 +450,7 @@ res_send(buf, buflen, ans, anssiz) | |||
441 | * Use virtual circuit; | 450 | * Use virtual circuit; |
442 | * at most one attempt per server. | 451 | * at most one attempt per server. |
443 | */ | 452 | */ |
444 | try = _res.retry; | 453 | try = _resp->retry; |
445 | truncated = 0; | 454 | truncated = 0; |
446 | if ((s < 0) || (!vc) || (af != nsap->sa_family)) { | 455 | if ((s < 0) || (!vc) || (af != nsap->sa_family)) { |
447 | if (s >= 0) | 456 | if (s >= 0) |
@@ -520,7 +529,7 @@ read_len: | |||
520 | } | 529 | } |
521 | resplen = _getshort(ans); | 530 | resplen = _getshort(ans); |
522 | if (resplen > anssiz) { | 531 | if (resplen > anssiz) { |
523 | Dprint(_res.options & RES_DEBUG, | 532 | Dprint(_resp->options & RES_DEBUG, |
524 | (stdout, ";; response truncated\n") | 533 | (stdout, ";; response truncated\n") |
525 | ); | 534 | ); |
526 | truncated = 1; | 535 | truncated = 1; |
@@ -566,8 +575,8 @@ read_len: | |||
566 | * wait for the correct one. | 575 | * wait for the correct one. |
567 | */ | 576 | */ |
568 | if (hp->id != anhp->id) { | 577 | if (hp->id != anhp->id) { |
569 | DprintQ((_res.options & RES_DEBUG) || | 578 | DprintQ((_resp->options & RES_DEBUG) || |
570 | (_res.pfcode & RES_PRF_REPLY), | 579 | (_resp->pfcode & RES_PRF_REPLY), |
571 | (stdout, ";; old answer (unexpected):\n"), | 580 | (stdout, ";; old answer (unexpected):\n"), |
572 | ans, (resplen>anssiz)?anssiz:resplen); | 581 | ans, (resplen>anssiz)?anssiz:resplen); |
573 | goto read_len; | 582 | goto read_len; |
@@ -625,8 +634,8 @@ read_len: | |||
625 | * as we wish to receive answers from the first | 634 | * as we wish to receive answers from the first |
626 | * server to respond. | 635 | * server to respond. |
627 | */ | 636 | */ |
628 | if (!(_res.options & RES_INSECURE1) && | 637 | if (!(_resp->options & RES_INSECURE1) && |
629 | (_res.nscount == 1 || (try == 0 && ns == 0))) { | 638 | (_resp->nscount == 1 || (try == 0 && ns == 0))) { |
630 | /* | 639 | /* |
631 | * Connect only if we are sure we won't | 640 | * Connect only if we are sure we won't |
632 | * receive a response from another server. | 641 | * receive a response from another server. |
@@ -673,7 +682,7 @@ read_len: | |||
673 | goto bad_dg_sock; | 682 | goto bad_dg_sock; |
674 | (void) dup2(s1, s); | 683 | (void) dup2(s1, s); |
675 | (void) close(s1); | 684 | (void) close(s1); |
676 | Dprint(_res.options & RES_DEBUG, | 685 | Dprint(_resp->options & RES_DEBUG, |
677 | (stdout, ";; new DG socket\n")) | 686 | (stdout, ";; new DG socket\n")) |
678 | #endif | 687 | #endif |
679 | #ifdef IPV6_MINMTU | 688 | #ifdef IPV6_MINMTU |
@@ -699,9 +708,9 @@ read_len: | |||
699 | /* | 708 | /* |
700 | * Wait for reply | 709 | * Wait for reply |
701 | */ | 710 | */ |
702 | timeout.tv_sec = (_res.retrans << try); | 711 | timeout.tv_sec = (_resp->retrans << try); |
703 | if (try > 0) | 712 | if (try > 0) |
704 | timeout.tv_sec /= _res.nscount; | 713 | timeout.tv_sec /= _resp->nscount; |
705 | if ((long) timeout.tv_sec <= 0) | 714 | if ((long) timeout.tv_sec <= 0) |
706 | timeout.tv_sec = 1; | 715 | timeout.tv_sec = 1; |
707 | timeout.tv_usec = 0; | 716 | timeout.tv_usec = 0; |
@@ -727,7 +736,7 @@ read_len: | |||
727 | /* | 736 | /* |
728 | * timeout | 737 | * timeout |
729 | */ | 738 | */ |
730 | Dprint(_res.options & RES_DEBUG, | 739 | Dprint(_resp->options & RES_DEBUG, |
731 | (stdout, ";; timeout\n")); | 740 | (stdout, ";; timeout\n")); |
732 | gotsomewhere = 1; | 741 | gotsomewhere = 1; |
733 | res_close(); | 742 | res_close(); |
@@ -749,28 +758,28 @@ read_len: | |||
749 | * XXX - potential security hazard could | 758 | * XXX - potential security hazard could |
750 | * be detected here. | 759 | * be detected here. |
751 | */ | 760 | */ |
752 | DprintQ((_res.options & RES_DEBUG) || | 761 | DprintQ((_resp->options & RES_DEBUG) || |
753 | (_res.pfcode & RES_PRF_REPLY), | 762 | (_resp->pfcode & RES_PRF_REPLY), |
754 | (stdout, ";; old answer:\n"), | 763 | (stdout, ";; old answer:\n"), |
755 | ans, (resplen>anssiz)?anssiz:resplen); | 764 | ans, (resplen>anssiz)?anssiz:resplen); |
756 | goto wait; | 765 | goto wait; |
757 | } | 766 | } |
758 | #if CHECK_SRVR_ADDR | 767 | #if CHECK_SRVR_ADDR |
759 | if (!(_res.options & RES_INSECURE1) && | 768 | if (!(_resp->options & RES_INSECURE1) && |
760 | !res_isourserver((struct sockaddr_in *)&from)) { | 769 | !res_isourserver((struct sockaddr_in *)&from)) { |
761 | /* | 770 | /* |
762 | * response from wrong server? ignore it. | 771 | * response from wrong server? ignore it. |
763 | * XXX - potential security hazard could | 772 | * XXX - potential security hazard could |
764 | * be detected here. | 773 | * be detected here. |
765 | */ | 774 | */ |
766 | DprintQ((_res.options & RES_DEBUG) || | 775 | DprintQ((_resp->options & RES_DEBUG) || |
767 | (_res.pfcode & RES_PRF_REPLY), | 776 | (_resp->pfcode & RES_PRF_REPLY), |
768 | (stdout, ";; not our server:\n"), | 777 | (stdout, ";; not our server:\n"), |
769 | ans, (resplen>anssiz)?anssiz:resplen); | 778 | ans, (resplen>anssiz)?anssiz:resplen); |
770 | goto wait; | 779 | goto wait; |
771 | } | 780 | } |
772 | #endif | 781 | #endif |
773 | if (!(_res.options & RES_INSECURE2) && | 782 | if (!(_resp->options & RES_INSECURE2) && |
774 | !res_queriesmatch(buf, buf + buflen, | 783 | !res_queriesmatch(buf, buf + buflen, |
775 | ans, ans + anssiz)) { | 784 | ans, ans + anssiz)) { |
776 | /* | 785 | /* |
@@ -778,8 +787,8 @@ read_len: | |||
778 | * XXX - potential security hazard could | 787 | * XXX - potential security hazard could |
779 | * be detected here. | 788 | * be detected here. |
780 | */ | 789 | */ |
781 | DprintQ((_res.options & RES_DEBUG) || | 790 | DprintQ((_resp->options & RES_DEBUG) || |
782 | (_res.pfcode & RES_PRF_REPLY), | 791 | (_resp->pfcode & RES_PRF_REPLY), |
783 | (stdout, ";; wrong query name:\n"), | 792 | (stdout, ";; wrong query name:\n"), |
784 | ans, (resplen>anssiz)?anssiz:resplen); | 793 | ans, (resplen>anssiz)?anssiz:resplen); |
785 | goto wait; | 794 | goto wait; |
@@ -787,33 +796,33 @@ read_len: | |||
787 | if (anhp->rcode == SERVFAIL || | 796 | if (anhp->rcode == SERVFAIL || |
788 | anhp->rcode == NOTIMP || | 797 | anhp->rcode == NOTIMP || |
789 | anhp->rcode == REFUSED) { | 798 | anhp->rcode == REFUSED) { |
790 | DprintQ(_res.options & RES_DEBUG, | 799 | DprintQ(_resp->options & RES_DEBUG, |
791 | (stdout, "server rejected query:\n"), | 800 | (stdout, "server rejected query:\n"), |
792 | ans, (resplen>anssiz)?anssiz:resplen); | 801 | ans, (resplen>anssiz)?anssiz:resplen); |
793 | badns |= (1 << ns); | 802 | badns |= (1 << ns); |
794 | res_close(); | 803 | res_close(); |
795 | /* don't retry if called from dig */ | 804 | /* don't retry if called from dig */ |
796 | if (!_res.pfcode) | 805 | if (!_resp->pfcode) |
797 | goto next_ns; | 806 | goto next_ns; |
798 | } | 807 | } |
799 | if (!(_res.options & RES_IGNTC) && anhp->tc) { | 808 | if (!(_resp->options & RES_IGNTC) && anhp->tc) { |
800 | /* | 809 | /* |
801 | * get rest of answer; | 810 | * get rest of answer; |
802 | * use TCP with same server. | 811 | * use TCP with same server. |
803 | */ | 812 | */ |
804 | Dprint(_res.options & RES_DEBUG, | 813 | Dprint(_resp->options & RES_DEBUG, |
805 | (stdout, ";; truncated answer\n")); | 814 | (stdout, ";; truncated answer\n")); |
806 | v_circuit = 1; | 815 | v_circuit = 1; |
807 | res_close(); | 816 | res_close(); |
808 | goto same_ns; | 817 | goto same_ns; |
809 | } | 818 | } |
810 | } /*if vc/dg*/ | 819 | } /*if vc/dg*/ |
811 | Dprint((_res.options & RES_DEBUG) || | 820 | Dprint((_resp->options & RES_DEBUG) || |
812 | ((_res.pfcode & RES_PRF_REPLY) && | 821 | ((_resp->pfcode & RES_PRF_REPLY) && |
813 | (_res.pfcode & RES_PRF_HEAD1)), | 822 | (_resp->pfcode & RES_PRF_HEAD1)), |
814 | (stdout, ";; got answer:\n")); | 823 | (stdout, ";; got answer:\n")); |
815 | DprintQ((_res.options & RES_DEBUG) || | 824 | DprintQ((_resp->options & RES_DEBUG) || |
816 | (_res.pfcode & RES_PRF_REPLY), | 825 | (_resp->pfcode & RES_PRF_REPLY), |
817 | (stdout, "%s", ""), | 826 | (stdout, "%s", ""), |
818 | ans, (resplen>anssiz)?anssiz:resplen); | 827 | ans, (resplen>anssiz)?anssiz:resplen); |
819 | /* | 828 | /* |
@@ -824,8 +833,8 @@ read_len: | |||
824 | * or if we haven't been asked to keep a socket open, | 833 | * or if we haven't been asked to keep a socket open, |
825 | * close the socket. | 834 | * close the socket. |
826 | */ | 835 | */ |
827 | if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || | 836 | if ((v_circuit && (!(_resp->options & RES_USEVC) || ns != 0)) || |
828 | !(_res.options & RES_STAYOPEN)) { | 837 | !(_resp->options & RES_STAYOPEN)) { |
829 | res_close(); | 838 | res_close(); |
830 | } | 839 | } |
831 | if (Rhook) { | 840 | if (Rhook) { |