1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-28 00:21:52 +03:00

* resolv/res_send.c (__libc_res_nsend): Take additional parameter.

Use it instead of locally defined resplen2 variable.
	(res_nsend): Adjust for __libc_res_nsend interface change.
	(send_vc): Initialize *resplen2 if necessary.  Read length of
	package into an appropriately aligned variable.  Store converted length
	in new variable and use it appropriately.
	Add branch prediction help.
	* resolv/res_query.c (__libc_res_nquery): Take additional parameter
	and pass it on to __libc_res_nsend.  Adjust all callers.
	(__libc_res_nsearch): Likewise.
	(__libc_res_nqeurydomain): Likewise.
	* resolv/nss_dns/dns-host.c: Adjust for __libc_res_nsearch interface
	change.
	(_nss_dns_gethostbyname4): Don't unconditionally allocate tmp array.
	Define resplen2 variable and pass it to __libc_res_nsearch and then
	to gaih_getanswer.
	(getanswer_r): In case of incorrect DNS data don't overread buffer.
	Add branch prediction.
	(gaih_getanswer_slice): Likewise.  Check for invalid data types.
	(gaih_getanswer): Don't decode second slice if first one failed due
	to a too small buffer.  Don't let not found status of second
	decoder shadow results of the first.
	* resolv/gethnamaddr.c (gethostbyname2): Adjust for __libc_res_nsearch
	and __libc_res_nquery interface changes
	(gethostbyaddr): Adjust for __libc_res_nquery interface change.
	* include/resolv.h: Adjust prototypes for __libc_res_nquery,
	__libc_res_nsearch, and __libc_res_nsend.
	* resolv/nss_dns/dns-canon.c: Adjust for __libc_res_nquery interface
	change.
	* resolv/nss_dns/dns-network.c: Adjust for __libc_res_nquery and
	__libc_res_nsearch interface changes.
This commit is contained in:
Ulrich Drepper
2008-07-28 22:55:10 +00:00
parent 372aece0e4
commit b7da31a164
8 changed files with 132 additions and 71 deletions

View File

@ -1,3 +1,37 @@
2008-07-28 Ulrich Drepper <drepper@redhat.com>
* resolv/res_send.c (__libc_res_nsend): Take additional parameter.
Use it instead of locally defined resplen2 variable.
(res_nsend): Adjust for __libc_res_nsend interface change.
(send_vc): Initialize *resplen2 if necessary. Read length of
package into an appropriately aligned variable. Store converted length
in new variable and use it appropriately.
Add branch prediction help.
* resolv/res_query.c (__libc_res_nquery): Take additional parameter
and pass it on to __libc_res_nsend. Adjust all callers.
(__libc_res_nsearch): Likewise.
(__libc_res_nqeurydomain): Likewise.
* resolv/nss_dns/dns-host.c: Adjust for __libc_res_nsearch interface
change.
(_nss_dns_gethostbyname4): Don't unconditionally allocate tmp array.
Define resplen2 variable and pass it to __libc_res_nsearch and then
to gaih_getanswer.
(getanswer_r): In case of incorrect DNS data don't overread buffer.
Add branch prediction.
(gaih_getanswer_slice): Likewise. Check for invalid data types.
(gaih_getanswer): Don't decode second slice if first one failed due
to a too small buffer. Don't let not found status of second
decoder shadow results of the first.
* resolv/gethnamaddr.c (gethostbyname2): Adjust for __libc_res_nsearch
and __libc_res_nquery interface changes
(gethostbyaddr): Adjust for __libc_res_nquery interface change.
* include/resolv.h: Adjust prototypes for __libc_res_nquery,
__libc_res_nsearch, and __libc_res_nsend.
* resolv/nss_dns/dns-canon.c: Adjust for __libc_res_nquery interface
change.
* resolv/nss_dns/dns-network.c: Adjust for __libc_res_nquery and
__libc_res_nsearch interface changes.
2008-07-27 Ulrich Drepper <drepper@redhat.com> 2008-07-27 Ulrich Drepper <drepper@redhat.com>
* libio/iopopen.c (_IO_new_proc_open): Remove unnecessary volatile. * libio/iopopen.c (_IO_new_proc_open): Remove unnecessary volatile.

View File

@ -58,11 +58,11 @@ libc_hidden_proto (__res_randomid)
libc_hidden_proto (__res_state) libc_hidden_proto (__res_state)
int __libc_res_nquery (res_state, const char *, int, int, u_char *, int, int __libc_res_nquery (res_state, const char *, int, int, u_char *, int,
u_char **, u_char **, int *); u_char **, u_char **, int *, int *);
int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int, int __libc_res_nsearch (res_state, const char *, int, int, u_char *, int,
u_char **, u_char **, int *); u_char **, u_char **, int *, int *);
int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int, int __libc_res_nsend (res_state, const u_char *, int, const u_char *, int,
u_char *, int, u_char **, u_char **, int *) u_char *, int, u_char **, u_char **, int *, int *)
attribute_hidden; attribute_hidden;
libresolv_hidden_proto (_sethtent) libresolv_hidden_proto (_sethtent)

View File

@ -621,7 +621,7 @@ gethostbyname2(name, af)
buf.buf = origbuf = (querybuf *) alloca (1024); buf.buf = origbuf = (querybuf *) alloca (1024);
if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024, if ((n = __libc_res_nsearch(&_res, name, C_IN, type, buf.buf->buf, 1024,
&buf.ptr, NULL, NULL)) < 0) { &buf.ptr, NULL, NULL, NULL)) < 0) {
if (buf.buf != origbuf) if (buf.buf != origbuf)
free (buf.buf); free (buf.buf);
Dprintf("res_nsearch failed (%d)\n", n); Dprintf("res_nsearch failed (%d)\n", n);
@ -716,12 +716,12 @@ gethostbyaddr(addr, len, af)
buf.buf = orig_buf = (querybuf *) alloca (1024); buf.buf = orig_buf = (querybuf *) alloca (1024);
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024, n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, 1024,
&buf.ptr, NULL, NULL); &buf.ptr, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) { if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) {
strcpy(qp, "ip6.int"); strcpy(qp, "ip6.int");
n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf,
buf.buf != orig_buf ? MAXPACKET : 1024, buf.buf != orig_buf ? MAXPACKET : 1024,
&buf.ptr, NULL, NULL); &buf.ptr, NULL, NULL, NULL);
} }
if (n < 0) { if (n < 0) {
if (buf.buf != orig_buf) if (buf.buf != orig_buf)

View File

@ -61,7 +61,8 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen,
for (int i = 0; i < nqtypes; ++i) for (int i = 0; i < nqtypes; ++i)
{ {
int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i], int r = __libc_res_nquery (&_res, name, ns_c_in, qtypes[i],
buf, sizeof (buf), &ansp.ptr, NULL, NULL); buf, sizeof (buf), &ansp.ptr, NULL, NULL,
NULL);
if (r > 0) if (r > 0)
{ {
/* We need to decode the response. Just one question record. /* We need to decode the response. Just one question record.

View File

@ -195,7 +195,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024); host_buffer.buf = orig_host_buffer = (querybuf *) alloca (1024);
n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf, n = __libc_res_nsearch (&_res, name, C_IN, type, host_buffer.buf->buf,
1024, &host_buffer.ptr, NULL, NULL); 1024, &host_buffer.ptr, NULL, NULL, NULL);
if (n < 0) if (n < 0)
{ {
status = (errno == ECONNREFUSED status = (errno == ECONNREFUSED
@ -213,7 +213,7 @@ _nss_dns_gethostbyname3_r (const char *name, int af, struct hostent *result,
n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf, n = __libc_res_nsearch (&_res, name, C_IN, T_A, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr, ? MAXPACKET : 1024, &host_buffer.ptr,
NULL, NULL); NULL, NULL, NULL);
if (n < 0) if (n < 0)
{ {
@ -273,8 +273,6 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
if (__res_maybe_init (&_res, 0) == -1) if (__res_maybe_init (&_res, 0) == -1)
return NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
char tmp[NS_MAXDNAME];
/* /*
* if there aren't any dots, it could be a user-level alias. * if there aren't any dots, it could be a user-level alias.
* this is also done in res_query() since we are not the only * this is also done in res_query() since we are not the only
@ -282,7 +280,8 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
*/ */
if (strchr (name, '.') == NULL) if (strchr (name, '.') == NULL)
{ {
const char *cp = res_hostalias (&_res, name, tmp, sizeof (tmp)); char *tmp = alloca (NS_MAXDNAME);
const char *cp = res_hostalias (&_res, name, tmp, NS_MAXDNAME);
if (cp != NULL) if (cp != NULL)
name = cp; name = cp;
} }
@ -296,12 +295,13 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048); host_buffer.buf = orig_host_buffer = (querybuf *) alloca (2048);
u_char *ans2p = NULL; u_char *ans2p = NULL;
int nans2p = 0; int nans2p = 0;
int resplen2 = 0;
int olderr = errno; int olderr = errno;
enum nss_status status; enum nss_status status;
int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC,
host_buffer.buf->buf, 2048, &host_buffer.ptr, host_buffer.buf->buf, 2048, &host_buffer.ptr,
&ans2p, &nans2p); &ans2p, &nans2p, &resplen2);
if (n < 0) if (n < 0)
{ {
status = (errno == ECONNREFUSED status = (errno == ECONNREFUSED
@ -319,7 +319,7 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat,
} }
status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p, status = gaih_getanswer(host_buffer.buf, n, (const querybuf *) ans2p,
nans2p, name, pat, buffer, buflen, resplen2, name, pat, buffer, buflen,
errnop, herrnop, ttlp); errnop, herrnop, ttlp);
if (host_buffer.buf != orig_host_buffer) if (host_buffer.buf != orig_host_buffer)
@ -417,7 +417,7 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
strcpy (qp, "].ip6.arpa"); strcpy (qp, "].ip6.arpa");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR,
host_buffer.buf->buf, 1024, &host_buffer.ptr, host_buffer.buf->buf, 1024, &host_buffer.ptr,
NULL, NULL); NULL, NULL, NULL);
if (n >= 0) if (n >= 0)
goto got_it_already; goto got_it_already;
} }
@ -438,14 +438,14 @@ _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af,
} }
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
1024, &host_buffer.ptr, NULL, NULL); 1024, &host_buffer.ptr, NULL, NULL, NULL);
if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0)
{ {
strcpy (qp, "ip6.int"); strcpy (qp, "ip6.int");
n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf,
host_buffer.buf != orig_host_buffer host_buffer.buf != orig_host_buffer
? MAXPACKET : 1024, &host_buffer.ptr, ? MAXPACKET : 1024, &host_buffer.ptr,
NULL, NULL); NULL, NULL, NULL);
} }
if (n < 0) if (n < 0)
{ {
@ -685,12 +685,19 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
n = -1; n = -1;
} }
if (n < 0 || (*name_ok) (bp) == 0) if (__builtin_expect (n < 0 || (*name_ok) (bp) == 0, 0))
{ {
++had_error; ++had_error;
continue; continue;
} }
cp += n; /* name */ cp += n; /* name */
if (__builtin_expect (cp + 10 > end_of_message, 0))
{
++had_error;
continue;
}
type = ns_get16 (cp); type = ns_get16 (cp);
cp += INT16SZ; /* type */ cp += INT16SZ; /* type */
class = ns_get16 (cp); class = ns_get16 (cp);
@ -699,7 +706,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
cp += INT32SZ; /* TTL */ cp += INT32SZ; /* TTL */
n = ns_get16 (cp); n = ns_get16 (cp);
cp += INT16SZ; /* len */ cp += INT16SZ; /* len */
if (class != C_IN) if (__builtin_expect (class != C_IN, 0))
{ {
/* XXX - debug? syslog? */ /* XXX - debug? syslog? */
cp += n; cp += n;
@ -711,7 +718,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1]) if (ap >= &host_data->aliases[MAX_NR_ALIASES - 1])
continue; continue;
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
if (n < 0 || (*name_ok) (tbuf) == 0) if (__builtin_expect (n < 0 || (*name_ok) (tbuf) == 0, 0))
{ {
++had_error; ++had_error;
continue; continue;
@ -745,7 +752,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
if (qtype == T_PTR && type == T_CNAME) if (qtype == T_PTR && type == T_CNAME)
{ {
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
if (n < 0 || res_dnok (tbuf) == 0) if (__builtin_expect (n < 0 || res_dnok (tbuf) == 0, 0))
{ {
++had_error; ++had_error;
continue; continue;
@ -792,7 +799,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
switch (type) switch (type)
{ {
case T_PTR: case T_PTR:
if (__strcasecmp (tname, bp) != 0) if (__builtin_expect (__strcasecmp (tname, bp) != 0, 0))
{ {
syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp); syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp);
cp += n; cp += n;
@ -809,7 +816,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
n = -1; n = -1;
} }
if (n < 0 || res_hnok (bp) == 0) if (__builtin_expect (n < 0 || res_hnok (bp) == 0, 0))
{ {
++had_error; ++had_error;
break; break;
@ -839,7 +846,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype,
if (have_to_map) if (have_to_map)
{ {
n = strlen (bp) + 1; /* for the \0 */ n = strlen (bp) + 1; /* for the \0 */
if (n >= MAXHOSTNAMELEN) if (__builtin_expect (n >= MAXHOSTNAMELEN, 0))
{ {
++had_error; ++had_error;
break; break;
@ -957,7 +964,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
return NSS_STATUS_UNAVAIL; return NSS_STATUS_UNAVAIL;
} }
u_char packtmp[NS_MAXCDNAME]; u_char packtmp[NS_MAXCDNAME];
int n = __ns_name_unpack (answer->buf, end_of_message, cp, int n = __ns_name_unpack (answer->buf, end_of_message, cp,
packtmp, sizeof packtmp); packtmp, sizeof packtmp);
/* We unpack the name to check it for validity. But we do not need /* We unpack the name to check it for validity. But we do not need
@ -1005,7 +1012,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
n = -1; n = -1;
} }
if (n < 0 || res_hnok (buffer) == 0) if (__builtin_expect (n < 0 || res_hnok (buffer) == 0, 0))
{ {
++had_error; ++had_error;
continue; continue;
@ -1018,6 +1025,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
} }
cp += n; /* name */ cp += n; /* name */
if (__builtin_expect (cp + 10 > end_of_message, 0))
{
++had_error;
continue;
}
int type = ns_get16 (cp); int type = ns_get16 (cp);
cp += INT16SZ; /* type */ cp += INT16SZ; /* type */
int class = ns_get16 (cp); int class = ns_get16 (cp);
@ -1037,7 +1051,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
{ {
char tbuf[MAXDNAME]; char tbuf[MAXDNAME];
n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf); n = dn_expand (answer->buf, end_of_message, cp, tbuf, sizeof tbuf);
if (n < 0 || res_hnok (tbuf) == 0) if (__builtin_expect (n < 0 || res_hnok (tbuf) == 0, 0))
{ {
++had_error; ++had_error;
continue; continue;
@ -1130,6 +1144,12 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname,
} }
(*pat)->family = type == T_A ? AF_INET : AF_INET6; (*pat)->family = type == T_A ? AF_INET : AF_INET6;
if (__builtin_expect ((type == T_A && n != INADDRSZ)
|| (type == T_AAAA && n != IN6ADDRSZ), 0))
{
++had_error;
continue;
}
memcpy ((*pat)->addr, cp, n); memcpy ((*pat)->addr, cp, n);
cp += n; cp += n;
(*pat)->scopeid = 0; (*pat)->scopeid = 0;
@ -1172,14 +1192,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2,
errnop, h_errnop, ttlp, errnop, h_errnop, ttlp,
&first); &first);
if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND if ((status == NSS_STATUS_SUCCESS || status == NSS_STATUS_NOTFOUND
|| status == NSS_STATUS_TRYAGAIN) || (status == NSS_STATUS_TRYAGAIN
&& (errno != ERANGE || *h_errnop != NO_RECOVERY)))
&& answer2 != NULL && anslen2 > 0) && answer2 != NULL && anslen2 > 0)
{ {
enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname, enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname,
&pat, &buffer, &buflen, &pat, &buffer, &buflen,
errnop, h_errnop, ttlp, errnop, h_errnop, ttlp,
&first); &first);
if (status != NSS_STATUS_SUCCESS) if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND)
status = status2; status = status2;
} }

View File

@ -130,7 +130,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result,
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, anslen = __libc_res_nsearch (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
1024, &net_buffer.ptr, NULL, NULL); 1024, &net_buffer.ptr, NULL, NULL, NULL);
if (anslen < 0) if (anslen < 0)
{ {
/* Nothing found. */ /* Nothing found. */
@ -206,7 +206,7 @@ _nss_dns_getnetbyaddr_r (uint32_t net, int type, struct netent *result,
net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024);
anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf, anslen = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, net_buffer.buf->buf,
1024, &net_buffer.ptr, NULL, NULL); 1024, &net_buffer.ptr, NULL, NULL, NULL);
if (anslen < 0) if (anslen < 0)
{ {
/* Nothing found. */ /* Nothing found. */

View File

@ -97,7 +97,8 @@ static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vix
static int static int
__libc_res_nquerydomain(res_state statp, const char *name, const char *domain, __libc_res_nquerydomain(res_state statp, const char *name, const char *domain,
int class, int type, u_char *answer, int anslen, int class, int type, u_char *answer, int anslen,
u_char **answerp, u_char **answerp2, int *nanswerp2); u_char **answerp, u_char **answerp2, int *nanswerp2,
int *resplen2);
/* /*
* Formulate a normal query, send, and await answer. * Formulate a normal query, send, and await answer.
@ -117,7 +118,8 @@ __libc_res_nquery(res_state statp,
int anslen, /* size of answer buffer */ int anslen, /* size of answer buffer */
u_char **answerp, /* if buffer needs to be enlarged */ u_char **answerp, /* if buffer needs to be enlarged */
u_char **answerp2, u_char **answerp2,
int *nanswerp2) int *nanswerp2,
int *resplen2)
{ {
HEADER *hp = (HEADER *) answer; HEADER *hp = (HEADER *) answer;
int n, use_malloc = 0; int n, use_malloc = 0;
@ -221,7 +223,7 @@ __libc_res_nquery(res_state statp,
} }
assert (answerp == NULL || (void *) *answerp == (void *) answer); assert (answerp == NULL || (void *) *answerp == (void *) answer);
n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer, n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer,
anslen, answerp, answerp2, nanswerp2); anslen, answerp, answerp2, nanswerp2, resplen2);
if (use_malloc) if (use_malloc)
free (buf); free (buf);
if (n < 0) { if (n < 0) {
@ -307,7 +309,7 @@ res_nquery(res_state statp,
int anslen) /* size of answer buffer */ int anslen) /* size of answer buffer */
{ {
return __libc_res_nquery(statp, name, class, type, answer, anslen, return __libc_res_nquery(statp, name, class, type, answer, anslen,
NULL, NULL, NULL); NULL, NULL, NULL, NULL);
} }
libresolv_hidden_def (res_nquery) libresolv_hidden_def (res_nquery)
@ -325,7 +327,8 @@ __libc_res_nsearch(res_state statp,
int anslen, /* size of answer */ int anslen, /* size of answer */
u_char **answerp, u_char **answerp,
u_char **answerp2, u_char **answerp2,
int *nanswerp2) int *nanswerp2,
int *resplen2)
{ {
const char *cp, * const *domain; const char *cp, * const *domain;
HEADER *hp = (HEADER *) answer; HEADER *hp = (HEADER *) answer;
@ -349,7 +352,7 @@ __libc_res_nsearch(res_state statp,
if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL) if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
return (__libc_res_nquery(statp, cp, class, type, answer, return (__libc_res_nquery(statp, cp, class, type, answer,
anslen, answerp, answerp2, anslen, answerp, answerp2,
nanswerp2)); nanswerp2, resplen2));
#ifdef DEBUG #ifdef DEBUG
if (statp->options & RES_DEBUG) if (statp->options & RES_DEBUG)
@ -366,7 +369,7 @@ __libc_res_nsearch(res_state statp,
if (dots >= statp->ndots || trailing_dot) { if (dots >= statp->ndots || trailing_dot) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type, ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp, answer, anslen, answerp,
answerp2, nanswerp2); answerp2, nanswerp2, resplen2);
if (ret > 0 || trailing_dot) if (ret > 0 || trailing_dot)
return (ret); return (ret);
saved_herrno = h_errno; saved_herrno = h_errno;
@ -404,7 +407,8 @@ __libc_res_nsearch(res_state statp,
ret = __libc_res_nquerydomain(statp, name, *domain, ret = __libc_res_nquerydomain(statp, name, *domain,
class, type, class, type,
answer, anslen, answerp, answer, anslen, answerp,
answerp2, nanswerp2); answerp2, nanswerp2,
resplen2);
if (ret > 0) if (ret > 0)
return (ret); return (ret);
@ -473,7 +477,7 @@ __libc_res_nsearch(res_state statp,
if (dots && !(tried_as_is || root_on_list)) { if (dots && !(tried_as_is || root_on_list)) {
ret = __libc_res_nquerydomain(statp, name, NULL, class, type, ret = __libc_res_nquerydomain(statp, name, NULL, class, type,
answer, anslen, answerp, answer, anslen, answerp,
answerp2, nanswerp2); answerp2, nanswerp2, resplen2);
if (ret > 0) if (ret > 0)
return (ret); return (ret);
} }
@ -508,7 +512,7 @@ res_nsearch(res_state statp,
int anslen) /* size of answer */ int anslen) /* size of answer */
{ {
return __libc_res_nsearch(statp, name, class, type, answer, return __libc_res_nsearch(statp, name, class, type, answer,
anslen, NULL, NULL, NULL); anslen, NULL, NULL, NULL, NULL);
} }
libresolv_hidden_def (res_nsearch) libresolv_hidden_def (res_nsearch)
@ -525,7 +529,8 @@ __libc_res_nquerydomain(res_state statp,
int anslen, /* size of answer */ int anslen, /* size of answer */
u_char **answerp, u_char **answerp,
u_char **answerp2, u_char **answerp2,
int *nanswerp2) int *nanswerp2,
int *resplen2)
{ {
char nbuf[MAXDNAME]; char nbuf[MAXDNAME];
const char *longname = nbuf; const char *longname = nbuf;
@ -562,7 +567,8 @@ __libc_res_nquerydomain(res_state statp,
sprintf(nbuf, "%s.%s", name, domain); sprintf(nbuf, "%s.%s", name, domain);
} }
return (__libc_res_nquery(statp, longname, class, type, answer, return (__libc_res_nquery(statp, longname, class, type, answer,
anslen, answerp, answerp2, nanswerp2)); anslen, answerp, answerp2, nanswerp2,
resplen2));
} }
int int
@ -574,7 +580,7 @@ res_nquerydomain(res_state statp,
int anslen) /* size of answer */ int anslen) /* size of answer */
{ {
return __libc_res_nquerydomain(statp, name, domain, class, type, return __libc_res_nquerydomain(statp, name, domain, class, type,
answer, anslen, NULL, NULL, NULL); answer, anslen, NULL, NULL, NULL, NULL);
} }
libresolv_hidden_def (res_nquerydomain) libresolv_hidden_def (res_nquerydomain)

View File

@ -339,9 +339,9 @@ int
__libc_res_nsend(res_state statp, const u_char *buf, int buflen, __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
const u_char *buf2, int buflen2, const u_char *buf2, int buflen2,
u_char *ans, int anssiz, u_char **ansp, u_char **ansp2, u_char *ans, int anssiz, u_char **ansp, u_char **ansp2,
int *nansp2) int *nansp2, int *resplen2)
{ {
int gotsomewhere, terrno, try, v_circuit, resplen, resplen2, ns, n; int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
if (statp->nscount == 0) { if (statp->nscount == 0) {
__set_errno (ESRCH); __set_errno (ESRCH);
@ -539,7 +539,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
try = statp->retry; try = statp->retry;
n = send_vc(statp, buf, buflen, buf2, buflen2, n = send_vc(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno, &ans, &anssiz, &terrno,
ns, ansp, ansp2, nansp2, &resplen2); ns, ansp, ansp2, nansp2, resplen2);
if (n < 0) if (n < 0)
return (-1); return (-1);
if (n == 0) if (n == 0)
@ -549,14 +549,14 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
n = send_dg(statp, buf, buflen, buf2, buflen2, n = send_dg(statp, buf, buflen, buf2, buflen2,
&ans, &anssiz, &terrno, &ans, &anssiz, &terrno,
ns, &v_circuit, &gotsomewhere, ansp, ns, &v_circuit, &gotsomewhere, ansp,
ansp2, nansp2, &resplen2); ansp2, nansp2, resplen2);
if (n < 0) if (n < 0)
return (-1); return (-1);
if (n == 0) if (n == 0)
goto next_ns; goto next_ns;
if (v_circuit) if (v_circuit)
// XXX Check whether both requests failed or // XXX Check whether both requests failed or
// XXX whether one have been answered successfully // XXX whether one has been answered successfully
goto same_ns; goto same_ns;
} }
@ -575,7 +575,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen,
DprintQ((statp->options & RES_DEBUG) || DprintQ((statp->options & RES_DEBUG) ||
(statp->pfcode & RES_PRF_REPLY), (statp->pfcode & RES_PRF_REPLY),
(stdout, "%s", ""), (stdout, "%s", ""),
*ansp2, (resplen2 > *nansp2) ? *nansp2 : resplen2); *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2);
/* /*
* If we have temporarily opened a virtual circuit, * If we have temporarily opened a virtual circuit,
@ -638,7 +638,7 @@ res_nsend(res_state statp,
const u_char *buf, int buflen, u_char *ans, int anssiz) const u_char *buf, int buflen, u_char *ans, int anssiz)
{ {
return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz, return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz,
NULL, NULL, NULL); NULL, NULL, NULL, NULL);
} }
libresolv_hidden_def (res_nsend) libresolv_hidden_def (res_nsend)
@ -665,6 +665,8 @@ send_vc(res_state statp,
u_short len2; u_short len2;
u_char *cp; u_char *cp;
if (resplen2 != NULL)
*resplen2 = 0;
connreset = 0; connreset = 0;
same_ns: same_ns:
truncating = 0; truncating = 0;
@ -734,8 +736,9 @@ send_vc(res_state statp,
int recvresp2 = buf2 == NULL; int recvresp2 = buf2 == NULL;
read_len: read_len:
cp = ans; cp = ans;
len = INT16SZ; uint16_t rlen16;
while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, (char *)cp, len = sizeof(rlen16);
while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, &rlen16,
(int)len))) > 0) { (int)len))) > 0) {
cp += n; cp += n;
if ((len -= n) <= 0) if ((len -= n) <= 0)
@ -760,11 +763,7 @@ send_vc(res_state statp,
} }
return (0); return (0);
} }
#ifdef _STRING_ARCH_unaligned int rlen = ntohs (rlen16);
resplen = ntohs (*(uint16_t *) ans);
#else
resplen = ns_get16(ans);
#endif
int *thisanssizp; int *thisanssizp;
u_char **thisansp; u_char **thisansp;
@ -795,11 +794,11 @@ send_vc(res_state statp,
} }
anhp = (HEADER *) *thisansp; anhp = (HEADER *) *thisansp;
*thisresplenp = resplen; *thisresplenp = rlen;
if (resplen > *thisanssizp) { if (rlen > *thisanssizp) {
/* Yes, we test ANSCP here. If we have two buffers /* Yes, we test ANSCP here. If we have two buffers
both will be allocatable. */ both will be allocatable. */
if (anscp) { if (__builtin_expect (anscp != NULL, 1)) {
u_char *newp = malloc (MAXPACKET); u_char *newp = malloc (MAXPACKET);
if (newp == NULL) { if (newp == NULL) {
*terrno = ENOMEM; *terrno = ENOMEM;
@ -809,7 +808,7 @@ send_vc(res_state statp,
*thisanssizp = MAXPACKET; *thisanssizp = MAXPACKET;
*thisansp = newp; *thisansp = newp;
anhp = (HEADER *) newp; anhp = (HEADER *) newp;
len = resplen; len = rlen;
} else { } else {
Dprint(statp->options & RES_DEBUG, Dprint(statp->options & RES_DEBUG,
(stdout, ";; response truncated\n") (stdout, ";; response truncated\n")
@ -818,9 +817,9 @@ send_vc(res_state statp,
len = *thisanssizp; len = *thisanssizp;
} }
} else } else
len = resplen; len = rlen;
if (len < HFIXEDSZ) { if (__builtin_expect (len < HFIXEDSZ, 0)) {
/* /*
* Undersized message. * Undersized message.
*/ */
@ -836,18 +835,18 @@ send_vc(res_state statp,
cp += n; cp += n;
len -= n; len -= n;
} }
if (n <= 0) { if (__builtin_expect (n <= 0, 0)) {
*terrno = errno; *terrno = errno;
Perror(statp, stderr, "read(vc)", errno); Perror(statp, stderr, "read(vc)", errno);
__res_iclose(statp, false); __res_iclose(statp, false);
return (0); return (0);
} }
if (truncating) { if (__builtin_expect (truncating, 0)) {
/* /*
* Flush rest of answer so connection stays in synch. * Flush rest of answer so connection stays in synch.
*/ */
anhp->tc = 1; anhp->tc = 1;
len = resplen - *thisanssizp; len = rlen - *thisanssizp;
while (len != 0) { while (len != 0) {
char junk[PACKETSZ]; char junk[PACKETSZ];
@ -872,7 +871,7 @@ send_vc(res_state statp,
(statp->pfcode & RES_PRF_REPLY), (statp->pfcode & RES_PRF_REPLY),
(stdout, ";; old answer (unexpected):\n"), (stdout, ";; old answer (unexpected):\n"),
*thisansp, *thisansp,
(resplen > *thisanssiz) ? *thisanssiz: resplen); (rlen > *thisanssiz) ? *thisanssiz: rlen);
goto read_len; goto read_len;
} }
@ -889,7 +888,7 @@ send_vc(res_state statp,
* All is well, or the error is fatal. Signal that the * All is well, or the error is fatal. Signal that the
* next nameserver ought not be tried. * next nameserver ought not be tried.
*/ */
return (resplen); return resplen;
} }
static int static int
@ -1084,7 +1083,7 @@ send_dg(res_state statp,
*thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp, *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp,
*thisanssizp, 0, *thisanssizp, 0,
(struct sockaddr *)&from, &fromlen); (struct sockaddr *)&from, &fromlen);
if (*thisresplenp <= 0) { if (__builtin_expect (*thisresplenp <= 0, 0)) {
if (errno == EINTR || errno == EAGAIN) { if (errno == EINTR || errno == EAGAIN) {
need_recompute = 1; need_recompute = 1;
goto wait; goto wait;
@ -1093,7 +1092,7 @@ send_dg(res_state statp,
goto err_out; goto err_out;
} }
*gotsomewhere = 1; *gotsomewhere = 1;
if (*thisresplenp < HFIXEDSZ) { if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) {
/* /*
* Undersized message. * Undersized message.
*/ */