diff options
| author | marc <> | 2003-01-28 04:58:00 +0000 |
|---|---|---|
| committer | marc <> | 2003-01-28 04:58:00 +0000 |
| commit | 547ebab319b228b064cf5dcb3ff0ae1bf23d24a2 (patch) | |
| tree | f57454716593fb3b68672505c6dccab6438498f1 /src/lib/libc/net/gethostnamadr.c | |
| parent | 98a78d57b176408b5aca87705f9681c5b155b47c (diff) | |
| download | openbsd-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 '')
| -rw-r--r-- | src/lib/libc/net/gethostnamadr.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/src/lib/libc/net/gethostnamadr.c b/src/lib/libc/net/gethostnamadr.c index 909ce573b7..5211f423c6 100644 --- a/src/lib/libc/net/gethostnamadr.c +++ b/src/lib/libc/net/gethostnamadr.c | |||
| @@ -52,7 +52,7 @@ | |||
| 52 | */ | 52 | */ |
| 53 | 53 | ||
| 54 | #if defined(LIBC_SCCS) && !defined(lint) | 54 | #if defined(LIBC_SCCS) && !defined(lint) |
| 55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.53 2002/08/27 08:53:13 itojun Exp $"; | 55 | static char rcsid[] = "$OpenBSD: gethostnamadr.c,v 1.54 2003/01/28 04:58:00 marc Exp $"; |
| 56 | #endif /* LIBC_SCCS and not lint */ | 56 | #endif /* LIBC_SCCS and not lint */ |
| 57 | 57 | ||
| 58 | #include <sys/param.h> | 58 | #include <sys/param.h> |
| @@ -160,6 +160,7 @@ getanswer(answer, anslen, qname, qtype) | |||
| 160 | const char *qname; | 160 | const char *qname; |
| 161 | int qtype; | 161 | int qtype; |
| 162 | { | 162 | { |
| 163 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
| 163 | register const HEADER *hp; | 164 | register const HEADER *hp; |
| 164 | register const u_char *cp; | 165 | register const u_char *cp; |
| 165 | register int n; | 166 | register int n; |
| @@ -339,7 +340,7 @@ getanswer(answer, anslen, qname, qtype) | |||
| 339 | break; | 340 | break; |
| 340 | #else | 341 | #else |
| 341 | host.h_name = bp; | 342 | host.h_name = bp; |
| 342 | if (_res.options & RES_USE_INET6) { | 343 | if (_resp->options & RES_USE_INET6) { |
| 343 | n = strlen(bp) + 1; /* for the \0 */ | 344 | n = strlen(bp) + 1; /* for the \0 */ |
| 344 | bp += n; | 345 | bp += n; |
| 345 | map_v4v6_hostent(&host, &bp, ep); | 346 | map_v4v6_hostent(&host, &bp, ep); |
| @@ -379,7 +380,7 @@ getanswer(answer, anslen, qname, qtype) | |||
| 379 | 380 | ||
| 380 | if (bp + n >= &hostbuf[sizeof hostbuf]) { | 381 | if (bp + n >= &hostbuf[sizeof hostbuf]) { |
| 381 | #ifdef DEBUG | 382 | #ifdef DEBUG |
| 382 | if (_res.options & RES_DEBUG) | 383 | if (_resp->options & RES_DEBUG) |
| 383 | printf("size (%d) too big\n", n); | 384 | printf("size (%d) too big\n", n); |
| 384 | #endif | 385 | #endif |
| 385 | had_error++; | 386 | had_error++; |
| @@ -388,7 +389,7 @@ getanswer(answer, anslen, qname, qtype) | |||
| 388 | if (hap >= &h_addr_ptrs[MAXADDRS-1]) { | 389 | if (hap >= &h_addr_ptrs[MAXADDRS-1]) { |
| 389 | if (!toobig++) | 390 | if (!toobig++) |
| 390 | #ifdef DEBUG | 391 | #ifdef DEBUG |
| 391 | if (_res.options & RES_DEBUG) | 392 | if (_resp->options & RES_DEBUG) |
| 392 | printf("Too many addresses (%d)\n", MAXADDRS); | 393 | printf("Too many addresses (%d)\n", MAXADDRS); |
| 393 | #endif | 394 | #endif |
| 394 | cp += n; | 395 | cp += n; |
| @@ -411,7 +412,7 @@ getanswer(answer, anslen, qname, qtype) | |||
| 411 | * in its return structures - should give it the "best" | 412 | * in its return structures - should give it the "best" |
| 412 | * address in that case, not some random one | 413 | * address in that case, not some random one |
| 413 | */ | 414 | */ |
| 414 | if (_res.nsort && haveanswer > 1 && qtype == T_A) | 415 | if (_resp->nsort && haveanswer > 1 && qtype == T_A) |
| 415 | addrsort(h_addr_ptrs, haveanswer); | 416 | addrsort(h_addr_ptrs, haveanswer); |
| 416 | # endif /*RESOLVSORT*/ | 417 | # endif /*RESOLVSORT*/ |
| 417 | if (!host.h_name) { | 418 | if (!host.h_name) { |
| @@ -422,7 +423,7 @@ getanswer(answer, anslen, qname, qtype) | |||
| 422 | host.h_name = bp; | 423 | host.h_name = bp; |
| 423 | bp += n; | 424 | bp += n; |
| 424 | } | 425 | } |
| 425 | if (_res.options & RES_USE_INET6) | 426 | if (_resp->options & RES_USE_INET6) |
| 426 | map_v4v6_hostent(&host, &bp, ep); | 427 | map_v4v6_hostent(&host, &bp, ep); |
| 427 | h_errno = NETDB_SUCCESS; | 428 | h_errno = NETDB_SUCCESS; |
| 428 | return (&host); | 429 | return (&host); |
| @@ -484,27 +485,24 @@ gethostbyaddr_r(addr, len, af, he, buf, buflen, errorp) | |||
| 484 | /* XXX RFC2133 expects a gethostbyname2_r() -- unimplemented */ | 485 | /* XXX RFC2133 expects a gethostbyname2_r() -- unimplemented */ |
| 485 | #endif | 486 | #endif |
| 486 | 487 | ||
| 487 | _THREAD_PRIVATE_MUTEX(gethostnamadr); | ||
| 488 | |||
| 489 | struct hostent * | 488 | struct hostent * |
| 490 | gethostbyname(name) | 489 | gethostbyname(name) |
| 491 | const char *name; | 490 | const char *name; |
| 492 | { | 491 | { |
| 492 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
| 493 | struct hostent *hp; | 493 | struct hostent *hp; |
| 494 | extern struct hostent *_gethtbyname2(); | 494 | extern struct hostent *_gethtbyname2(); |
| 495 | 495 | ||
| 496 | _THREAD_PRIVATE_MUTEX_LOCK(gethostnamadr); | 496 | if ((_resp->options & RES_INIT) == 0 && res_init() == -1) |
| 497 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | ||
| 498 | hp = _gethtbyname2(name, AF_INET); | 497 | hp = _gethtbyname2(name, AF_INET); |
| 499 | 498 | ||
| 500 | else if (_res.options & RES_USE_INET6) { | 499 | else if (_resp->options & RES_USE_INET6) { |
| 501 | hp = gethostbyname2(name, AF_INET6); | 500 | hp = gethostbyname2(name, AF_INET6); |
| 502 | if (hp == NULL) | 501 | if (hp == NULL) |
| 503 | hp = gethostbyname2(name, AF_INET); | 502 | hp = gethostbyname2(name, AF_INET); |
| 504 | } | 503 | } |
| 505 | else | 504 | else |
| 506 | hp = gethostbyname2(name, AF_INET); | 505 | hp = gethostbyname2(name, AF_INET); |
| 507 | _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr); | ||
| 508 | return hp; | 506 | return hp; |
| 509 | } | 507 | } |
| 510 | 508 | ||
| @@ -513,6 +511,7 @@ gethostbyname2(name, af) | |||
| 513 | const char *name; | 511 | const char *name; |
| 514 | int af; | 512 | int af; |
| 515 | { | 513 | { |
| 514 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
| 516 | querybuf *buf; | 515 | querybuf *buf; |
| 517 | register const char *cp; | 516 | register const char *cp; |
| 518 | char *bp, *ep; | 517 | char *bp, *ep; |
| @@ -521,7 +520,7 @@ gethostbyname2(name, af) | |||
| 521 | register struct hostent *hp; | 520 | register struct hostent *hp; |
| 522 | char lookups[MAXDNSLUS]; | 521 | char lookups[MAXDNSLUS]; |
| 523 | 522 | ||
| 524 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) | 523 | if ((_resp->options & RES_INIT) == 0 && res_init() == -1) |
| 525 | return (_gethtbyname2(name, af)); | 524 | return (_gethtbyname2(name, af)); |
| 526 | 525 | ||
| 527 | switch (af) { | 526 | switch (af) { |
| @@ -577,7 +576,7 @@ gethostbyname2(name, af) | |||
| 577 | h_addr_ptrs[0] = (char *)host_addr; | 576 | h_addr_ptrs[0] = (char *)host_addr; |
| 578 | h_addr_ptrs[1] = NULL; | 577 | h_addr_ptrs[1] = NULL; |
| 579 | host.h_addr_list = h_addr_ptrs; | 578 | host.h_addr_list = h_addr_ptrs; |
| 580 | if (_res.options & RES_USE_INET6) | 579 | if (_resp->options & RES_USE_INET6) |
| 581 | map_v4v6_hostent(&host, &bp, ep); | 580 | map_v4v6_hostent(&host, &bp, ep); |
| 582 | h_errno = NETDB_SUCCESS; | 581 | h_errno = NETDB_SUCCESS; |
| 583 | return (&host); | 582 | return (&host); |
| @@ -616,7 +615,7 @@ gethostbyname2(name, af) | |||
| 616 | break; | 615 | break; |
| 617 | } | 616 | } |
| 618 | 617 | ||
| 619 | bcopy(_res.lookups, lookups, sizeof lookups); | 618 | bcopy(_resp->lookups, lookups, sizeof lookups); |
| 620 | if (lookups[0] == '\0') | 619 | if (lookups[0] == '\0') |
| 621 | strlcpy(lookups, "bf", sizeof lookups); | 620 | strlcpy(lookups, "bf", sizeof lookups); |
| 622 | 621 | ||
| @@ -638,7 +637,7 @@ gethostbyname2(name, af) | |||
| 638 | sizeof(buf->buf))) < 0) { | 637 | sizeof(buf->buf))) < 0) { |
| 639 | free(buf); | 638 | free(buf); |
| 640 | #ifdef DEBUG | 639 | #ifdef DEBUG |
| 641 | if (_res.options & RES_DEBUG) | 640 | if (_resp->options & RES_DEBUG) |
| 642 | printf("res_search failed\n"); | 641 | printf("res_search failed\n"); |
| 643 | #endif | 642 | #endif |
| 644 | break; | 643 | break; |
| @@ -660,6 +659,7 @@ gethostbyaddr(addr, len, af) | |||
| 660 | const char *addr; /* XXX should have been def'd as u_char! */ | 659 | const char *addr; /* XXX should have been def'd as u_char! */ |
| 661 | int len, af; | 660 | int len, af; |
| 662 | { | 661 | { |
| 662 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
| 663 | const u_char *uaddr = (const u_char *)addr; | 663 | const u_char *uaddr = (const u_char *)addr; |
| 664 | int n, size, i; | 664 | int n, size, i; |
| 665 | querybuf *buf; | 665 | querybuf *buf; |
| @@ -669,10 +669,8 @@ gethostbyaddr(addr, len, af) | |||
| 669 | char lookups[MAXDNSLUS]; | 669 | char lookups[MAXDNSLUS]; |
| 670 | struct hostent *res; | 670 | struct hostent *res; |
| 671 | 671 | ||
| 672 | _THREAD_PRIVATE_MUTEX_LOCK(gethostnamadr); | 672 | if ((_resp->options & RES_INIT) == 0 && res_init() == -1) { |
| 673 | if ((_res.options & RES_INIT) == 0 && res_init() == -1) { | ||
| 674 | res = _gethtbyaddr(addr, len, af); | 673 | res = _gethtbyaddr(addr, len, af); |
| 675 | _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr); | ||
| 676 | return (res); | 674 | return (res); |
| 677 | } | 675 | } |
| 678 | 676 | ||
| @@ -701,13 +699,11 @@ gethostbyaddr(addr, len, af) | |||
| 701 | default: | 699 | default: |
| 702 | errno = EAFNOSUPPORT; | 700 | errno = EAFNOSUPPORT; |
| 703 | h_errno = NETDB_INTERNAL; | 701 | h_errno = NETDB_INTERNAL; |
| 704 | _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr); | ||
| 705 | return (NULL); | 702 | return (NULL); |
| 706 | } | 703 | } |
| 707 | if (size != len) { | 704 | if (size != len) { |
| 708 | errno = EINVAL; | 705 | errno = EINVAL; |
| 709 | h_errno = NETDB_INTERNAL; | 706 | h_errno = NETDB_INTERNAL; |
| 710 | _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr); | ||
| 711 | return (NULL); | 707 | return (NULL); |
| 712 | } | 708 | } |
| 713 | switch (af) { | 709 | switch (af) { |
| @@ -725,7 +721,7 @@ gethostbyaddr(addr, len, af) | |||
| 725 | break; | 721 | break; |
| 726 | } | 722 | } |
| 727 | 723 | ||
| 728 | bcopy(_res.lookups, lookups, sizeof lookups); | 724 | bcopy(_resp->lookups, lookups, sizeof lookups); |
| 729 | if (lookups[0] == '\0') | 725 | if (lookups[0] == '\0') |
| 730 | strlcpy(lookups, "bf", sizeof lookups); | 726 | strlcpy(lookups, "bf", sizeof lookups); |
| 731 | 727 | ||
| @@ -755,7 +751,7 @@ gethostbyaddr(addr, len, af) | |||
| 755 | if (n < 0) { | 751 | if (n < 0) { |
| 756 | free(buf); | 752 | free(buf); |
| 757 | #ifdef DEBUG | 753 | #ifdef DEBUG |
| 758 | if (_res.options & RES_DEBUG) | 754 | if (_resp->options & RES_DEBUG) |
| 759 | printf("res_query failed\n"); | 755 | printf("res_query failed\n"); |
| 760 | #endif | 756 | #endif |
| 761 | break; | 757 | break; |
| @@ -770,7 +766,7 @@ gethostbyaddr(addr, len, af) | |||
| 770 | bcopy(addr, host_addr, len); | 766 | bcopy(addr, host_addr, len); |
| 771 | h_addr_ptrs[0] = (char *)host_addr; | 767 | h_addr_ptrs[0] = (char *)host_addr; |
| 772 | h_addr_ptrs[1] = NULL; | 768 | h_addr_ptrs[1] = NULL; |
| 773 | if (af == AF_INET && (_res.options & RES_USE_INET6)) { | 769 | if (af == AF_INET && (_resp->options & RES_USE_INET6)) { |
| 774 | map_v4v6_address((char*)host_addr, | 770 | map_v4v6_address((char*)host_addr, |
| 775 | (char*)host_addr); | 771 | (char*)host_addr); |
| 776 | hp->h_addrtype = AF_INET6; | 772 | hp->h_addrtype = AF_INET6; |
| @@ -783,7 +779,6 @@ gethostbyaddr(addr, len, af) | |||
| 783 | break; | 779 | break; |
| 784 | } | 780 | } |
| 785 | } | 781 | } |
| 786 | _THREAD_PRIVATE_MUTEX_UNLOCK(gethostnamadr); | ||
| 787 | /* XXX h_errno not correct in all cases... */ | 782 | /* XXX h_errno not correct in all cases... */ |
| 788 | return (hp); | 783 | return (hp); |
| 789 | } | 784 | } |
| @@ -811,6 +806,7 @@ _endhtent() | |||
| 811 | struct hostent * | 806 | struct hostent * |
| 812 | _gethtent() | 807 | _gethtent() |
| 813 | { | 808 | { |
| 809 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
| 814 | char *p; | 810 | char *p; |
| 815 | register char *cp, **q; | 811 | register char *cp, **q; |
| 816 | int af; | 812 | int af; |
| @@ -842,7 +838,7 @@ _gethtent() | |||
| 842 | af = AF_INET6; | 838 | af = AF_INET6; |
| 843 | len = IN6ADDRSZ; | 839 | len = IN6ADDRSZ; |
| 844 | } else if (inet_pton(AF_INET, p, host_addr) > 0) { | 840 | } else if (inet_pton(AF_INET, p, host_addr) > 0) { |
| 845 | if (_res.options & RES_USE_INET6) { | 841 | if (_resp->options & RES_USE_INET6) { |
| 846 | map_v4v6_address((char*)host_addr, (char*)host_addr); | 842 | map_v4v6_address((char*)host_addr, (char*)host_addr); |
| 847 | af = AF_INET6; | 843 | af = AF_INET6; |
| 848 | len = IN6ADDRSZ; | 844 | len = IN6ADDRSZ; |
| @@ -880,7 +876,7 @@ _gethtent() | |||
| 880 | *cp++ = '\0'; | 876 | *cp++ = '\0'; |
| 881 | } | 877 | } |
| 882 | *q = NULL; | 878 | *q = NULL; |
| 883 | if (_res.options & RES_USE_INET6) { | 879 | if (_resp->options & RES_USE_INET6) { |
| 884 | char *bp = hostbuf; | 880 | char *bp = hostbuf; |
| 885 | char *ep = hostbuf + sizeof hostbuf; | 881 | char *ep = hostbuf + sizeof hostbuf; |
| 886 | 882 | ||
| @@ -894,10 +890,11 @@ struct hostent * | |||
| 894 | _gethtbyname(name) | 890 | _gethtbyname(name) |
| 895 | const char *name; | 891 | const char *name; |
| 896 | { | 892 | { |
| 893 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
| 897 | extern struct hostent *_gethtbyname2(); | 894 | extern struct hostent *_gethtbyname2(); |
| 898 | struct hostent *hp; | 895 | struct hostent *hp; |
| 899 | 896 | ||
| 900 | if (_res.options & RES_USE_INET6) { | 897 | if (_resp->options & RES_USE_INET6) { |
| 901 | hp = _gethtbyname2(name, AF_INET6); | 898 | hp = _gethtbyname2(name, AF_INET6); |
| 902 | if (hp) | 899 | if (hp) |
| 903 | return (hp); | 900 | return (hp); |
| @@ -1136,6 +1133,7 @@ addrsort(ap, num) | |||
| 1136 | char **ap; | 1133 | char **ap; |
| 1137 | int num; | 1134 | int num; |
| 1138 | { | 1135 | { |
| 1136 | struct __res_state *_resp = _THREAD_PRIVATE(_res, _res, &_res); | ||
| 1139 | int i, j; | 1137 | int i, j; |
| 1140 | char **p; | 1138 | char **p; |
| 1141 | short aval[MAXADDRS]; | 1139 | short aval[MAXADDRS]; |
| @@ -1143,9 +1141,9 @@ addrsort(ap, num) | |||
| 1143 | 1141 | ||
| 1144 | p = ap; | 1142 | p = ap; |
| 1145 | for (i = 0; i < num; i++, p++) { | 1143 | for (i = 0; i < num; i++, p++) { |
| 1146 | for (j = 0 ; (unsigned)j < _res.nsort; j++) | 1144 | for (j = 0 ; (unsigned)j < _resp->nsort; j++) |
| 1147 | if (_res.sort_list[j].addr.s_addr == | 1145 | if (_resp->sort_list[j].addr.s_addr == |
| 1148 | (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) | 1146 | (((struct in_addr *)(*p))->s_addr & _resp->sort_list[j].mask)) |
| 1149 | break; | 1147 | break; |
| 1150 | aval[i] = j; | 1148 | aval[i] = j; |
| 1151 | if (needsort == 0 && i > 0 && j < aval[i-1]) | 1149 | if (needsort == 0 && i > 0 && j < aval[i-1]) |
