diff options
| author | Hajimu UMEMOTO <ume@FreeBSD.org> | 2002-10-23 14:48:22 +0000 |
|---|---|---|
| committer | Hajimu UMEMOTO <ume@FreeBSD.org> | 2002-10-23 14:48:22 +0000 |
| commit | 57f9b3e30a651a88454928698fff35cb39836d9c (patch) | |
| tree | cc326b70d1c7d04f032d65be8963ec859631ba6b /lib | |
| parent | 526df856a210f4b57b9918af50fe7977f025cf13 (diff) | |
Notes
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/libc/net/getaddrinfo.c | 69 | ||||
| -rw-r--r-- | lib/libc/net/gethostbydns.c | 39 | ||||
| -rw-r--r-- | lib/libc/net/getnetbydns.c | 33 | ||||
| -rw-r--r-- | lib/libc/net/name6.c | 79 | ||||
| -rw-r--r-- | lib/libc/net/res_mkquery.c | 2 |
5 files changed, 152 insertions, 70 deletions
diff --git a/lib/libc/net/getaddrinfo.c b/lib/libc/net/getaddrinfo.c index 7847cd31d6c3..ed46d3f4bf57 100644 --- a/lib/libc/net/getaddrinfo.c +++ b/lib/libc/net/getaddrinfo.c @@ -182,11 +182,7 @@ static const struct explore explore[] = { #define PTON_MAX 4 #endif -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (64*1024) typedef union { HEADER hdr; @@ -1407,7 +1403,7 @@ _dns_getaddrinfo(pai, hostname, res) struct addrinfo **res; { struct addrinfo *ai; - querybuf buf, buf2; + querybuf *buf, *buf2; const char *name; struct addrinfo sentinel, *cur; struct res_target q, q2; @@ -1417,47 +1413,66 @@ _dns_getaddrinfo(pai, hostname, res) memset(&sentinel, 0, sizeof(sentinel)); cur = &sentinel; + buf = malloc(sizeof(*buf)); + if (!buf) { + h_errno = NETDB_INTERNAL; + return EAI_MEMORY; + } + buf2 = malloc(sizeof(*buf2)); + if (!buf2) { + free(buf); + h_errno = NETDB_INTERNAL; + return EAI_MEMORY; + } + switch (pai->ai_family) { case AF_UNSPEC: /* prefer IPv6 */ q.qclass = C_IN; q.qtype = T_AAAA; - q.answer = buf.buf; - q.anslen = sizeof(buf); + q.answer = buf->buf; + q.anslen = sizeof(buf->buf); q.next = &q2; q2.qclass = C_IN; q2.qtype = T_A; - q2.answer = buf2.buf; - q2.anslen = sizeof(buf2); + q2.answer = buf2->buf; + q2.anslen = sizeof(buf2->buf); break; case AF_INET: q.qclass = C_IN; q.qtype = T_A; - q.answer = buf.buf; - q.anslen = sizeof(buf); + q.answer = buf->buf; + q.anslen = sizeof(buf->buf); break; case AF_INET6: q.qclass = C_IN; q.qtype = T_AAAA; - q.answer = buf.buf; - q.anslen = sizeof(buf); + q.answer = buf->buf; + q.anslen = sizeof(buf->buf); break; default: + free(buf); + free(buf2); return EAI_FAIL; } - if (res_searchN(hostname, &q) < 0) + if (res_searchN(hostname, &q) < 0) { + free(buf); + free(buf2); return EAI_NODATA; - ai = getanswer(&buf, q.n, q.name, q.qtype, pai); + } + ai = getanswer(buf, q.n, q.name, q.qtype, pai); if (ai) { cur->ai_next = ai; while (cur && cur->ai_next) cur = cur->ai_next; } if (q.next) { - ai = getanswer(&buf2, q2.n, q2.name, q2.qtype, pai); + ai = getanswer(buf2, q2.n, q2.name, q2.qtype, pai); if (ai) cur->ai_next = ai; } + free(buf); + free(buf2); if (sentinel.ai_next == NULL) switch (h_errno) { case HOST_NOT_FOUND: @@ -1662,7 +1677,7 @@ res_queryN(name, target) const char *name; /* domain name */ struct res_target *target; { - u_char buf[MAXPACKET]; + u_char *buf; HEADER *hp; int n; struct res_target *t; @@ -1677,6 +1692,12 @@ res_queryN(name, target) return (-1); } + buf = malloc(MAXPACKET); + if (!buf) { + h_errno = NETDB_INTERNAL; + return (-1); + } + for (t = target; t; t = t->next) { int class, type; u_char *answer; @@ -1696,14 +1717,15 @@ res_queryN(name, target) #endif n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, - buf, sizeof(buf)); + buf, MAXPACKET); if (n > 0 && (_res.options & RES_USE_EDNS0) != 0) - n = res_opt(n, buf, sizeof(buf), anslen); + n = res_opt(n, buf, MAXPACKET, anslen); if (n <= 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) printf(";; res_query: mkquery failed\n"); #endif + free(buf); h_errno = NO_RECOVERY; return (n); } @@ -1714,12 +1736,15 @@ res_queryN(name, target) if (_res.options & RES_DEBUG) printf(";; res_query: send error\n"); #endif + free(buf); h_errno = TRY_AGAIN; return (n); } #endif - if (n < 0 || hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { + if (n < 0 || n > anslen) + hp->rcode = FORMERR; /* XXX not very informative */ + if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { rcode = hp->rcode; /* record most recent error */ #ifdef DEBUG if (_res.options & RES_DEBUG) @@ -1734,6 +1759,8 @@ res_queryN(name, target) t->n = n; } + free(buf); + if (ancount == 0) { switch (rcode) { case NXDOMAIN: diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c index 52ac91a041be..5df45eb7e747 100644 --- a/lib/libc/net/gethostbydns.c +++ b/lib/libc/net/gethostbydns.c @@ -67,6 +67,7 @@ static char rcsid[] = "$FreeBSD$"; #include <arpa/nameser.h> #include <stdio.h> +#include <stdlib.h> #include <unistd.h> #include <string.h> #include <netdb.h> @@ -96,11 +97,7 @@ static u_char host_addr[16]; /* IPv4 or IPv6 */ static void addrsort __P((char **, int)); #endif -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (64*1024) typedef union { HEADER hdr; @@ -480,10 +477,11 @@ _gethostbydnsname(name, af) const char *name; int af; { - querybuf buf; + querybuf *buf; register const char *cp; char *bp; int n, size, type, len; + struct hostent *hp; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; @@ -584,11 +582,19 @@ _gethostbydnsname(name, af) break; } - if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { + if ((buf = malloc(sizeof(*buf))) == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + n = res_search(name, C_IN, type, buf->buf, sizeof(buf->buf)); + if (n < 0) { + free(buf); dprintf("res_search failed (%d)\n", n); return (NULL); } - return (gethostanswer(&buf, n, name, type)); + hp = gethostanswer(buf, n, name, type); + free(buf); + return (hp); } struct hostent * @@ -600,7 +606,7 @@ _gethostbydnsaddr(addr, len, af) static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; int n, size; - querybuf buf; + querybuf *buf; register struct hostent *hp; char qbuf[MAXDNAME+1], *qp; #ifdef SUNSECURITY @@ -660,17 +666,26 @@ _gethostbydnsaddr(addr, len, af) default: abort(); } - n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + if ((buf = malloc(sizeof(*buf))) == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf->buf, sizeof buf->buf); if (n < 0) { + free(buf); dprintf("res_query failed (%d)\n", n); return (NULL); } - if (n > sizeof buf.buf) { + if (n > sizeof buf->buf) { + free(buf); dprintf("static buffer is too small (%d)\n", n); return (NULL); } - if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR))) + if (!(hp = gethostanswer(buf, n, qbuf, T_PTR))) { + free(buf); return (NULL); /* h_errno was set by gethostanswer() */ + } + free(buf); #ifdef SUNSECURITY if (af == AF_INET) { /* diff --git a/lib/libc/net/getnetbydns.c b/lib/libc/net/getnetbydns.c index e1a11d2e5d3a..5de46df9169f 100644 --- a/lib/libc/net/getnetbydns.c +++ b/lib/libc/net/getnetbydns.c @@ -70,6 +70,7 @@ static char rcsid[] = "$FreeBSD$"; #include <arpa/nameser.h> #include <stdio.h> +#include <stdlib.h> #include <netdb.h> #include <resolv.h> #include <ctype.h> @@ -85,11 +86,7 @@ extern int h_errno; #define BYNAME 1 #define MAXALIASES 35 -#if PACKETSZ > 1024 -#define MAXPACKET PACKETSZ -#else -#define MAXPACKET 1024 -#endif +#define MAXPACKET (64*1024) typedef union { HEADER hdr; @@ -226,7 +223,7 @@ _getnetbydnsaddr(net, net_type) { unsigned int netbr[4]; int nn, anslen; - querybuf buf; + querybuf *buf; char qbuf[MAXDNAME]; unsigned long net2; struct netent *net_entry; @@ -252,15 +249,21 @@ _getnetbydnsaddr(net, net_type) netbr[1], netbr[0]); break; } - anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + if ((buf = malloc(sizeof(*buf))) == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)buf, sizeof(*buf)); if (anslen < 0) { + free(buf); #ifdef DEBUG if (_res.options & RES_DEBUG) printf("res_query failed\n"); #endif return (NULL); } - net_entry = getnetanswer(&buf, anslen, BYADDR); + net_entry = getnetanswer(buf, anslen, BYADDR); + free(buf); if (net_entry) { unsigned u_net = net; /* maybe net should be unsigned ? */ @@ -278,24 +281,32 @@ _getnetbydnsname(net) register const char *net; { int anslen; - querybuf buf; + querybuf *buf; char qbuf[MAXDNAME]; + struct netent *net_entry; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return (NULL); } + if ((buf = malloc(sizeof(*buf))) == NULL) { + h_errno = NETDB_INTERNAL; + return (NULL); + } strncpy(qbuf, net, sizeof(qbuf) - 1); qbuf[sizeof(qbuf) - 1] = '\0'; - anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)buf, sizeof(*buf)); if (anslen < 0) { + free(buf); #ifdef DEBUG if (_res.options & RES_DEBUG) printf("res_query failed\n"); #endif return (NULL); } - return getnetanswer(&buf, anslen, BYNAME); + net_entry = getnetanswer(buf, anslen, BYNAME); + free(buf); + return net_entry; } void diff --git a/lib/libc/net/name6.c b/lib/libc/net/name6.c index 401786811b50..070280a6c166 100644 --- a/lib/libc/net/name6.c +++ b/lib/libc/net/name6.c @@ -994,11 +994,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; @@ -1305,7 +1301,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; @@ -1318,17 +1314,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 = 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; @@ -1336,6 +1338,7 @@ _res_search_multi(name, rtl, errp) hp0 = _hpmerge(hp0, hp, errp); } } + free(buf); return (hp0); } @@ -1348,12 +1351,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) { + 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; @@ -1361,8 +1364,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++; } @@ -1385,12 +1390,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) { + 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; @@ -1398,8 +1403,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. @@ -1415,6 +1422,7 @@ _res_search_multi(name, rtl, errp) * fully-qualified. */ if (errno == ECONNREFUSED) { + free(buf); *errp = TRY_AGAIN; return (NULL); } @@ -1427,7 +1435,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; @@ -1455,12 +1463,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) { + 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; @@ -1468,10 +1476,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). @@ -1531,7 +1543,7 @@ _dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp) #ifdef INET6 static const char hex[] = "0123456789abcdef"; #endif - querybuf buf; + querybuf *buf; char qbuf[MAXDNAME+1]; char *hlist[2]; @@ -1584,12 +1596,27 @@ _dns_ghbyaddr(const void *addr, int addrlen, int af, int *errp) 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 NULL; + } + + n = res_query(qbuf, C_IN, T_PTR, buf->buf, sizeof buf->buf); if (n < 0) { + free(buf); *errp = h_errno; return NULL; + } else if (n > sizeof(buf->buf)) { + free(buf); + *errp = NETDB_INTERNAL; +#if 0 + errno = ERANGE; /* XXX is it OK to set errno here? */ +#endif + return NULL; } - hp = getanswer(&buf, n, qbuf, T_PTR, &hbuf, errp); + hp = getanswer(buf, n, qbuf, T_PTR, &hbuf, errp); + free(buf); if (!hp) return NULL; hbuf.h_addrtype = af; diff --git a/lib/libc/net/res_mkquery.c b/lib/libc/net/res_mkquery.c index 6cbd37394b92..bacc4d58fe6b 100644 --- a/lib/libc/net/res_mkquery.c +++ b/lib/libc/net/res_mkquery.c @@ -228,6 +228,8 @@ res_opt(n0, buf, buflen, anslen) __putshort(T_OPT, cp); /* TYPE */ cp += INT16SZ; + if (anslen > 0xffff) + anslen = 0xffff; /* limit to 16bit value */ __putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */ cp += INT16SZ; *cp++ = NOERROR; /* extended RCODE */ |
