diff options
Diffstat (limited to 'lib/libc/net/gethostbydns.c')
-rw-r--r-- | lib/libc/net/gethostbydns.c | 124 |
1 files changed, 67 insertions, 57 deletions
diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c index 6cb43f0..b4c80d4 100644 --- a/lib/libc/net/gethostbydns.c +++ b/lib/libc/net/gethostbydns.c @@ -88,11 +88,11 @@ static const char AskedForGot[] = "gethostby*.gethostanswer: asked for \"%s\", got \"%s\""; #ifdef RESOLVSORT -static void addrsort(char **, int); +static void addrsort(char **, int, res_state); #endif #ifdef DEBUG -static void dprintf(char *, int) __printflike(1, 0); +static void dprintf(char *, int, res_state) __printflike(1, 0); #endif #define MAXPACKET (64*1024) @@ -111,11 +111,12 @@ int _dns_ttl_; #ifdef DEBUG static void -dprintf(msg, num) +dprintf(msg, num, res) char *msg; int num; + res_state res; { - if (_res.options & RES_DEBUG) { + if (res->options & RES_DEBUG) { int save = errno; printf(msg, num); @@ -123,14 +124,14 @@ dprintf(msg, num) } } #else -# define dprintf(msg, num) /*nada*/ +# define dprintf(msg, num, res) /*nada*/ #endif #define BOUNDED_INCR(x) \ do { \ cp += x; \ if (cp > eom) { \ - h_errno = NO_RECOVERY; \ + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); \ return -1; \ } \ } while (0) @@ -138,7 +139,7 @@ dprintf(msg, num) #define BOUNDS_CHECK(ptr, count) \ do { \ if ((ptr) + (count) > eom) { \ - h_errno = NO_RECOVERY; \ + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); \ return -1; \ } \ } while (0) @@ -171,7 +172,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, name_ok = res_dnok; break; default: - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; /* XXX should be abort(); */ } /* @@ -185,12 +186,12 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, cp = answer->buf; BOUNDED_INCR(HFIXEDSZ); if (qdcount != 1) { - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } n = dn_expand(answer->buf, eom, cp, bp, ep - bp); if ((n < 0) || !(*name_ok)(bp)) { - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } BOUNDED_INCR(n + QFIXEDSZ); @@ -201,7 +202,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, */ n = strlen(bp) + 1; /* for the \0 */ if (n >= MAXHOSTNAMELEN) { - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } he->h_name = bp; @@ -252,7 +253,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, } cp += n; if (cp != erdata) { - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } /* Store alias. */ @@ -282,7 +283,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, } cp += n; if (cp != erdata) { - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } /* Get canonical name. */ @@ -321,7 +322,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, #if MULTI_PTRS_ARE_ALIASES cp += n; if (cp != erdata) { - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } if (!haveanswer) @@ -341,7 +342,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, break; #else he->h_name = bp; - if (_res.options & RES_USE_INET6) { + if (hed->res->options & RES_USE_INET6) { n = strlen(bp) + 1; /* for the \0 */ if (n >= MAXHOSTNAMELEN) { had_error++; @@ -350,7 +351,7 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, bp += n; _map_v4v6_hostent(he, &bp, ep); } - h_errno = NETDB_SUCCESS; + RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS); return 0; #endif case T_A: @@ -376,14 +377,14 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, bp += sizeof(align) - ((u_long)bp % sizeof(align)); if (bp + n >= ep) { - dprintf("size (%d) too big\n", n); + dprintf("size (%d) too big\n", n, hed->res); had_error++; continue; } if (hap >= &hed->h_addr_ptrs[_MAXADDRS-1]) { if (!toobig++) dprintf("Too many addresses (%d)\n", - _MAXADDRS); + _MAXADDRS, hed->res); cp += n; continue; } @@ -391,13 +392,14 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, bp += n; cp += n; if (cp != erdata) { - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } break; default: - dprintf("Impossible condition (type=%d)\n", type); - h_errno = NO_RECOVERY; + dprintf("Impossible condition (type=%d)\n", type, + hed->res); + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; /* BIND has abort() here, too risky on bad data */ } @@ -413,8 +415,8 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int 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) - addrsort(hed->h_addr_ptrs, haveanswer); + if (hed->res->nsort && haveanswer > 1 && qtype == T_A) + addrsort(hed->h_addr_ptrs, haveanswer, hed->res); # endif /*RESOLVSORT*/ if (!he->h_name) { n = strlen(qname) + 1; /* for the \0 */ @@ -424,13 +426,13 @@ gethostanswer(const querybuf *answer, int anslen, const char *qname, int qtype, he->h_name = bp; bp += n; } - if (_res.options & RES_USE_INET6) + if (hed->res->options & RES_USE_INET6) _map_v4v6_hostent(he, &bp, ep); - h_errno = NETDB_SUCCESS; + RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS); return 0; } no_recovery: - h_errno = NO_RECOVERY; + RES_SET_H_ERRNO(hed->res, NO_RECOVERY); return -1; } @@ -440,11 +442,14 @@ __dns_getanswer(const char *answer, int anslen, const char *qname, int qtype) { struct hostdata *hd; int error; + res_state statp; + statp = __res_state(); if ((hd = __hostdata_init()) == NULL) { - h_errno = NETDB_INTERNAL; + RES_SET_H_ERRNO(statp, NETDB_INTERNAL); return NULL; } + hd->data.res = statp; switch (qtype) { case T_AAAA: hd->host.h_addrtype = AF_INET6; @@ -487,7 +492,7 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap) type = T_AAAA; break; default: - h_errno = NETDB_INTERNAL; + RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL); errno = EAFNOSUPPORT; return NS_UNAVAIL; } @@ -496,17 +501,17 @@ _dns_gethostbyname(void *rval, void *cb_data, va_list ap) he->h_length = size; if ((buf = malloc(sizeof(*buf))) == NULL) { - h_errno = NETDB_INTERNAL; + RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL); return NS_NOTFOUND; } - n = res_search(name, C_IN, type, buf->buf, sizeof(buf->buf)); + n = res_nsearch(hed->res, name, C_IN, type, buf->buf, sizeof(buf->buf)); if (n < 0) { free(buf); - dprintf("res_search failed (%d)\n", n); + dprintf("res_nsearch failed (%d)\n", n, hed->res); return (0); } else if (n > sizeof(buf->buf)) { free(buf); - dprintf("static buffer is too small (%d)\n", n); + dprintf("static buffer is too small (%d)\n", n, hed->res); return (0); } error = gethostanswer(buf, n, name, type, he, hed); @@ -538,10 +543,6 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap) he = va_arg(ap, struct hostent *); hed = va_arg(ap, struct hostent_data *); - if ((_res.options & RES_INIT) == 0 && res_init() == -1) { - h_errno = NETDB_INTERNAL; - return NS_UNAVAIL; - } switch (af) { case AF_INET: (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", @@ -563,18 +564,19 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap) abort(); } if ((buf = malloc(sizeof(*buf))) == NULL) { - h_errno = NETDB_INTERNAL; + RES_SET_H_ERRNO(hed->res, NETDB_INTERNAL); return NS_NOTFOUND; } - n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf->buf, sizeof buf->buf); + n = res_nquery(hed->res, qbuf, C_IN, T_PTR, (u_char *)buf->buf, + sizeof buf->buf); if (n < 0) { free(buf); - dprintf("res_query failed (%d)\n", n); + dprintf("res_nquery failed (%d)\n", n, hed->res); return NS_UNAVAIL; } if (n > sizeof buf->buf) { free(buf); - dprintf("static buffer is too small (%d)\n", n); + dprintf("static buffer is too small (%d)\n", n, hed->res); return NS_UNAVAIL; } if ((error = gethostanswer(buf, n, qbuf, T_PTR, he, hed)) != 0) { @@ -590,9 +592,9 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap) */ strncpy(hname2, he->h_name, MAXDNAME); hname2[MAXDNAME] = '\0'; - old_options = _res.options; - _res.options &= ~RES_DNSRCH; - _res.options |= RES_DEFNAMES; + old_options = hed->res->options; + hed->res->options &= ~RES_DNSRCH; + hed->res->options |= RES_DEFNAMES; memset(&rhd, 0, sizeof rhd); if (!(rhe = gethostbyname_r(hname2, &rhd.host, &rhd.data))) { if (inet_ntop(af, addr, numaddr, sizeof(numaddr)) == NULL) @@ -600,11 +602,11 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap) syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: No A record for %s (verifying [%s])", hname2, numaddr); - _res.options = old_options; - h_errno = HOST_NOT_FOUND; + hed->res->options = old_options; + RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND); return NS_NOTFOUND; } - _res.options = old_options; + hed->res->options = old_options; for (haddr = rhe->h_addr_list; *haddr; haddr++) if (!memcmp(*haddr, addr, INADDRSZ)) break; @@ -614,7 +616,7 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap) syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: A record of %s != PTR record [%s]", hname2, numaddr); - h_errno = HOST_NOT_FOUND; + RES_SET_H_ERRNO(hed->res, HOST_NOT_FOUND); return NS_NOTFOUND; } } @@ -624,20 +626,21 @@ _dns_gethostbyaddr(void *rval, void *cb_data, va_list ap) memcpy(hed->host_addr, uaddr, len); hed->h_addr_ptrs[0] = (char *)hed->host_addr; hed->h_addr_ptrs[1] = NULL; - if (af == AF_INET && (_res.options & RES_USE_INET6)) { + if (af == AF_INET && (hed->res->options & RES_USE_INET6)) { _map_v4v6_address((char*)hed->host_addr, (char*)hed->host_addr); he->h_addrtype = AF_INET6; he->h_length = IN6ADDRSZ; } - h_errno = NETDB_SUCCESS; + RES_SET_H_ERRNO(hed->res, NETDB_SUCCESS); return (error == 0) ? NS_SUCCESS : NS_NOTFOUND; } #ifdef RESOLVSORT static void -addrsort(ap, num) +addrsort(ap, num, res) char **ap; int num; + res_state res; { int i, j; char **p; @@ -646,9 +649,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 < res->nsort; j++) + if (res->sort_list[j].addr.s_addr == + (((struct in_addr *)(*p))->s_addr & res->sort_list[j].mask)) break; aval[i] = j; if (needsort == 0 && i > 0 && j < aval[i-1]) @@ -677,19 +680,26 @@ addrsort(ap, num) } } #endif + void _sethostdnsent(stayopen) int stayopen; { - if ((_res.options & RES_INIT) == 0 && res_init() == -1) + res_state statp; + + statp = __res_state(); + if ((statp->options & RES_INIT) == 0 && res_ninit(statp) == -1) return; if (stayopen) - _res.options |= RES_STAYOPEN | RES_USEVC; + statp->options |= RES_STAYOPEN | RES_USEVC; } void _endhostdnsent() { - _res.options &= ~(RES_STAYOPEN | RES_USEVC); - res_close(); + res_state statp; + + statp = __res_state(); + statp->options &= ~(RES_STAYOPEN | RES_USEVC); + res_nclose(statp); } |