diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/net/name6.c | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c index 3fa8aae..26008d0 100644 --- a/lib/libc/net/name6.c +++ b/lib/libc/net/name6.c @@ -967,11 +967,7 @@ struct __res_type_list { int rtl_type; }; -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (64*1024) typedef union { HEADER hdr; @@ -1268,7 +1264,7 @@ _res_search_multi(name, rtl, errp) int trailing_dot, ret, saved_herrno; int got_nodata = 0, got_servfail = 0, tried_as_is = 0; struct __res_type_list *rtl0 = rtl; - querybuf buf; + querybuf *buf; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { *errp = NETDB_INTERNAL; @@ -1281,17 +1277,23 @@ _res_search_multi(name, rtl, errp) if (cp > name && *--cp == '.') trailing_dot++; + buf = malloc(sizeof(*buf)); + if (buf == NULL) { + *errp = NETDB_INTERNAL; + return NULL; + } + /* If there aren't any dots, it could be a user-level alias */ if (!dots && (cp = hostalias(name)) != NULL) { for(rtl = rtl0; rtl != NULL; rtl = SLIST_NEXT(rtl, rtl_entry)) { - ret = res_query(cp, C_IN, rtl->rtl_type, buf.buf, - sizeof(buf.buf)); - if (ret > 0 && ret < sizeof(buf.buf)) { + ret = res_query(cp, C_IN, rtl->rtl_type, buf->buf, + sizeof(buf->buf)); + if (ret > 0 && ret < sizeof(buf->buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); - hp = getanswer(&buf, ret, name, rtl->rtl_type, + hp = getanswer(buf, ret, name, rtl->rtl_type, &hpbuf, errp); if (!hp) continue; @@ -1299,6 +1301,7 @@ _res_search_multi(name, rtl, errp) hp0 = _hpmerge(hp0, hp, errp); } } + free(buf); return (hp0); } @@ -1311,12 +1314,12 @@ _res_search_multi(name, rtl, errp) for(rtl = rtl0; rtl != NULL; rtl = SLIST_NEXT(rtl, rtl_entry)) { ret = res_querydomain(name, NULL, C_IN, rtl->rtl_type, - buf.buf, sizeof(buf.buf)); - if (ret > 0 && ret < sizeof(buf.buf)) { + buf->buf, sizeof(buf->buf)); + if (ret > 0 && ret < sizeof(buf->buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); - hp = getanswer(&buf, ret, name, rtl->rtl_type, + hp = getanswer(buf, ret, name, rtl->rtl_type, &hpbuf, errp); if (!hp) continue; @@ -1324,8 +1327,10 @@ _res_search_multi(name, rtl, errp) hp0 = _hpmerge(hp0, hp, errp); } } - if (hp0 != NULL) + if (hp0 != NULL) { + free(buf); return (hp0); + } saved_herrno = *errp; tried_as_is++; } @@ -1348,12 +1353,12 @@ _res_search_multi(name, rtl, errp) rtl = SLIST_NEXT(rtl, rtl_entry)) { ret = res_querydomain(name, *domain, C_IN, rtl->rtl_type, - buf.buf, sizeof(buf.buf)); - if (ret > 0 && ret < sizeof(buf.buf)) { + buf->buf, sizeof(buf->buf)); + if (ret > 0 && ret < sizeof(buf->buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); - hp = getanswer(&buf, ret, name, + hp = getanswer(buf, ret, name, rtl->rtl_type, &hpbuf, errp); if (!hp) continue; @@ -1361,8 +1366,10 @@ _res_search_multi(name, rtl, errp) hp0 = _hpmerge(hp0, hp, errp); } } - if (hp0 != NULL) + if (hp0 != NULL) { + free(buf); return (hp0); + } /* * If no server present, give up. @@ -1378,6 +1385,7 @@ _res_search_multi(name, rtl, errp) * fully-qualified. */ if (errno == ECONNREFUSED) { + free(buf); *errp = TRY_AGAIN; return (NULL); } @@ -1390,7 +1398,7 @@ _res_search_multi(name, rtl, errp) /* keep trying */ break; case TRY_AGAIN: - if (buf.hdr.rcode == SERVFAIL) { + if (buf->hdr.rcode == SERVFAIL) { /* try next search element, if any */ got_servfail++; break; @@ -1418,12 +1426,12 @@ _res_search_multi(name, rtl, errp) for(rtl = rtl0; rtl != NULL; rtl = SLIST_NEXT(rtl, rtl_entry)) { ret = res_querydomain(name, NULL, C_IN, rtl->rtl_type, - buf.buf, sizeof(buf.buf)); - if (ret > 0 && ret < sizeof(buf.buf)) { + buf->buf, sizeof(buf->buf)); + if (ret > 0 && ret < sizeof(buf->buf)) { hpbuf.h_addrtype = (rtl->rtl_type == T_AAAA) ? AF_INET6 : AF_INET; hpbuf.h_length = ADDRLEN(hpbuf.h_addrtype); - hp = getanswer(&buf, ret, name, rtl->rtl_type, + hp = getanswer(buf, ret, name, rtl->rtl_type, &hpbuf, errp); if (!hp) continue; @@ -1431,10 +1439,14 @@ _res_search_multi(name, rtl, errp) hp0 = _hpmerge(hp0, hp, errp); } } - if (hp0 != NULL) + if (hp0 != NULL) { + free(buf); return (hp0); + } } + free(buf); + /* if we got here, we didn't satisfy the search. * if we did an initial full query, return that query's h_errno * (note that we wouldn't be here if that query had succeeded). @@ -1506,7 +1518,7 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap) #ifdef INET6 static const char hex[] = "0123456789abcdef"; #endif - querybuf buf; + querybuf *buf; char qbuf[MAXDNAME+1]; char *hlist[2]; @@ -1566,18 +1578,27 @@ _dns_ghbyaddr(void *rval, void *cb_data, va_list ap) break; } - n = res_query(qbuf, C_IN, T_PTR, buf.buf, sizeof buf.buf); + buf = malloc(sizeof(*buf)); + if (buf == NULL) { + *errp = NETDB_INTERNAL; + return NS_UNAVAIL; + } + + n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); if (n < 0) { + free(buf); *errp = h_errno; return NS_UNAVAIL; - } else if (n > sizeof(buf.buf)) { + } else if (n > sizeof(buf->buf)) { + free(buf); #if 0 errno = ERANGE; /* XXX is it OK to set errno here? */ #endif *errp = NETDB_INTERNAL; return NS_UNAVAIL; } - hp = getanswer(&buf, n, qbuf, T_PTR, &hbuf, errp); + hp = getanswer(buf, n, qbuf, T_PTR, &hbuf, errp); + free(buf); if (!hp) return NS_NOTFOUND; hbuf.h_addrtype = af; |