From b7da31a1647e378258174d1d69097a594e31f89b Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Mon, 28 Jul 2008 22:55:10 +0000 Subject: * 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. --- ChangeLog | 34 +++++++++++++++++++++++ include/resolv.h | 6 ++-- resolv/gethnamaddr.c | 6 ++-- resolv/nss_dns/dns-canon.c | 3 +- resolv/nss_dns/dns-host.c | 65 +++++++++++++++++++++++++++++--------------- resolv/nss_dns/dns-network.c | 4 +-- resolv/res_query.c | 32 +++++++++++++--------- resolv/res_send.c | 53 ++++++++++++++++++------------------ 8 files changed, 132 insertions(+), 71 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4d5b530cf7..d4cccb6837 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,37 @@ +2008-07-28 Ulrich Drepper + + * 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 * libio/iopopen.c (_IO_new_proc_open): Remove unnecessary volatile. diff --git a/include/resolv.h b/include/resolv.h index 925746f685..6dae0495b2 100644 --- a/include/resolv.h +++ b/include/resolv.h @@ -58,11 +58,11 @@ libc_hidden_proto (__res_randomid) libc_hidden_proto (__res_state) 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, - 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, - u_char *, int, u_char **, u_char **, int *) + u_char *, int, u_char **, u_char **, int *, int *) attribute_hidden; libresolv_hidden_proto (_sethtent) diff --git a/resolv/gethnamaddr.c b/resolv/gethnamaddr.c index 2a9bd0b3c2..5cf660a8d4 100644 --- a/resolv/gethnamaddr.c +++ b/resolv/gethnamaddr.c @@ -621,7 +621,7 @@ gethostbyname2(name, af) buf.buf = origbuf = (querybuf *) alloca (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) free (buf.buf); Dprintf("res_nsearch failed (%d)\n", n); @@ -716,12 +716,12 @@ gethostbyaddr(addr, len, af) buf.buf = orig_buf = (querybuf *) alloca (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) { strcpy(qp, "ip6.int"); n = __libc_res_nquery(&_res, qbuf, C_IN, T_PTR, buf.buf->buf, buf.buf != orig_buf ? MAXPACKET : 1024, - &buf.ptr, NULL, NULL); + &buf.ptr, NULL, NULL, NULL); } if (n < 0) { if (buf.buf != orig_buf) diff --git a/resolv/nss_dns/dns-canon.c b/resolv/nss_dns/dns-canon.c index 47949b862f..cee3d57bc1 100644 --- a/resolv/nss_dns/dns-canon.c +++ b/resolv/nss_dns/dns-canon.c @@ -61,7 +61,8 @@ _nss_dns_getcanonname_r (const char *name, char *buffer, size_t buflen, for (int i = 0; i < nqtypes; ++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) { /* We need to decode the response. Just one question record. diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index cae077445f..80c0bd9fa8 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -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); 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) { 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, host_buffer.buf != orig_host_buffer ? MAXPACKET : 1024, &host_buffer.ptr, - NULL, NULL); + NULL, NULL, NULL); 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) return NSS_STATUS_UNAVAIL; - char tmp[NS_MAXDNAME]; - /* * 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 @@ -282,7 +280,8 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, */ 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) 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); u_char *ans2p = NULL; int nans2p = 0; + int resplen2 = 0; int olderr = errno; enum nss_status status; int n = __libc_res_nsearch (&_res, name, C_IN, T_UNSPEC, host_buffer.buf->buf, 2048, &host_buffer.ptr, - &ans2p, &nans2p); + &ans2p, &nans2p, &resplen2); if (n < 0) { 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, - nans2p, name, pat, buffer, buflen, + resplen2, name, pat, buffer, buflen, errnop, herrnop, ttlp); 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"); n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, 1024, &host_buffer.ptr, - NULL, NULL); + NULL, NULL, NULL); if (n >= 0) 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, - 1024, &host_buffer.ptr, NULL, NULL); + 1024, &host_buffer.ptr, NULL, NULL, NULL); if (n < 0 && af == AF_INET6 && (_res.options & RES_NOIP6DOTINT) == 0) { strcpy (qp, "ip6.int"); n = __libc_res_nquery (&_res, qbuf, C_IN, T_PTR, host_buffer.buf->buf, host_buffer.buf != orig_host_buffer ? MAXPACKET : 1024, &host_buffer.ptr, - NULL, NULL); + NULL, NULL, NULL); } if (n < 0) { @@ -685,12 +685,19 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, n = -1; } - if (n < 0 || (*name_ok) (bp) == 0) + if (__builtin_expect (n < 0 || (*name_ok) (bp) == 0, 0)) { ++had_error; continue; } cp += n; /* name */ + + if (__builtin_expect (cp + 10 > end_of_message, 0)) + { + ++had_error; + continue; + } + type = ns_get16 (cp); cp += INT16SZ; /* type */ class = ns_get16 (cp); @@ -699,7 +706,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, cp += INT32SZ; /* TTL */ n = ns_get16 (cp); cp += INT16SZ; /* len */ - if (class != C_IN) + if (__builtin_expect (class != C_IN, 0)) { /* XXX - debug? syslog? */ 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]) continue; 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; continue; @@ -745,7 +752,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, if (qtype == T_PTR && type == T_CNAME) { 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; continue; @@ -792,7 +799,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, switch (type) { case T_PTR: - if (__strcasecmp (tname, bp) != 0) + if (__builtin_expect (__strcasecmp (tname, bp) != 0, 0)) { syslog (LOG_NOTICE | LOG_AUTH, AskedForGot, qname, bp); cp += n; @@ -809,7 +816,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, n = -1; } - if (n < 0 || res_hnok (bp) == 0) + if (__builtin_expect (n < 0 || res_hnok (bp) == 0, 0)) { ++had_error; break; @@ -839,7 +846,7 @@ getanswer_r (const querybuf *answer, int anslen, const char *qname, int qtype, if (have_to_map) { n = strlen (bp) + 1; /* for the \0 */ - if (n >= MAXHOSTNAMELEN) + if (__builtin_expect (n >= MAXHOSTNAMELEN, 0)) { ++had_error; break; @@ -957,7 +964,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, 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, packtmp, sizeof packtmp); /* 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; } - if (n < 0 || res_hnok (buffer) == 0) + if (__builtin_expect (n < 0 || res_hnok (buffer) == 0, 0)) { ++had_error; continue; @@ -1018,6 +1025,13 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, } cp += n; /* name */ + + if (__builtin_expect (cp + 10 > end_of_message, 0)) + { + ++had_error; + continue; + } + int type = ns_get16 (cp); cp += INT16SZ; /* type */ int class = ns_get16 (cp); @@ -1037,7 +1051,7 @@ gaih_getanswer_slice (const querybuf *answer, int anslen, const char *qname, { char tbuf[MAXDNAME]; 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; 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; + if (__builtin_expect ((type == T_A && n != INADDRSZ) + || (type == T_AAAA && n != IN6ADDRSZ), 0)) + { + ++had_error; + continue; + } memcpy ((*pat)->addr, cp, n); cp += n; (*pat)->scopeid = 0; @@ -1172,14 +1192,15 @@ gaih_getanswer (const querybuf *answer1, int anslen1, const querybuf *answer2, errnop, h_errnop, ttlp, &first); 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) { enum nss_status status2 = gaih_getanswer_slice(answer2, anslen2, qname, &pat, &buffer, &buflen, errnop, h_errnop, ttlp, &first); - if (status != NSS_STATUS_SUCCESS) + if (status != NSS_STATUS_SUCCESS && status2 != NSS_STATUS_NOTFOUND) status = status2; } diff --git a/resolv/nss_dns/dns-network.c b/resolv/nss_dns/dns-network.c index 40736fbe94..c9969e08dc 100644 --- a/resolv/nss_dns/dns-network.c +++ b/resolv/nss_dns/dns-network.c @@ -130,7 +130,7 @@ _nss_dns_getnetbyname_r (const char *name, struct netent *result, net_buffer.buf = orig_net_buffer = (querybuf *) alloca (1024); 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) { /* 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); 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) { /* Nothing found. */ diff --git a/resolv/res_query.c b/resolv/res_query.c index b2b45acde7..7102ba948e 100644 --- a/resolv/res_query.c +++ b/resolv/res_query.c @@ -97,7 +97,8 @@ static const char rcsid[] = "$BINDId: res_query.c,v 8.20 2000/02/29 05:39:12 vix static int __libc_res_nquerydomain(res_state statp, const char *name, const char *domain, 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. @@ -117,7 +118,8 @@ __libc_res_nquery(res_state statp, int anslen, /* size of answer buffer */ u_char **answerp, /* if buffer needs to be enlarged */ u_char **answerp2, - int *nanswerp2) + int *nanswerp2, + int *resplen2) { HEADER *hp = (HEADER *) answer; int n, use_malloc = 0; @@ -221,7 +223,7 @@ __libc_res_nquery(res_state statp, } assert (answerp == NULL || (void *) *answerp == (void *) answer); n = __libc_res_nsend(statp, query1, nquery1, query2, nquery2, answer, - anslen, answerp, answerp2, nanswerp2); + anslen, answerp, answerp2, nanswerp2, resplen2); if (use_malloc) free (buf); if (n < 0) { @@ -307,7 +309,7 @@ res_nquery(res_state statp, int anslen) /* size of answer buffer */ { return __libc_res_nquery(statp, name, class, type, answer, anslen, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); } libresolv_hidden_def (res_nquery) @@ -325,7 +327,8 @@ __libc_res_nsearch(res_state statp, int anslen, /* size of answer */ u_char **answerp, u_char **answerp2, - int *nanswerp2) + int *nanswerp2, + int *resplen2) { const char *cp, * const *domain; 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) return (__libc_res_nquery(statp, cp, class, type, answer, anslen, answerp, answerp2, - nanswerp2)); + nanswerp2, resplen2)); #ifdef DEBUG if (statp->options & RES_DEBUG) @@ -366,7 +369,7 @@ __libc_res_nsearch(res_state statp, if (dots >= statp->ndots || trailing_dot) { ret = __libc_res_nquerydomain(statp, name, NULL, class, type, answer, anslen, answerp, - answerp2, nanswerp2); + answerp2, nanswerp2, resplen2); if (ret > 0 || trailing_dot) return (ret); saved_herrno = h_errno; @@ -404,7 +407,8 @@ __libc_res_nsearch(res_state statp, ret = __libc_res_nquerydomain(statp, name, *domain, class, type, answer, anslen, answerp, - answerp2, nanswerp2); + answerp2, nanswerp2, + resplen2); if (ret > 0) return (ret); @@ -473,7 +477,7 @@ __libc_res_nsearch(res_state statp, if (dots && !(tried_as_is || root_on_list)) { ret = __libc_res_nquerydomain(statp, name, NULL, class, type, answer, anslen, answerp, - answerp2, nanswerp2); + answerp2, nanswerp2, resplen2); if (ret > 0) return (ret); } @@ -508,7 +512,7 @@ res_nsearch(res_state statp, int anslen) /* size of answer */ { return __libc_res_nsearch(statp, name, class, type, answer, - anslen, NULL, NULL, NULL); + anslen, NULL, NULL, NULL, NULL); } libresolv_hidden_def (res_nsearch) @@ -525,7 +529,8 @@ __libc_res_nquerydomain(res_state statp, int anslen, /* size of answer */ u_char **answerp, u_char **answerp2, - int *nanswerp2) + int *nanswerp2, + int *resplen2) { char nbuf[MAXDNAME]; const char *longname = nbuf; @@ -562,7 +567,8 @@ __libc_res_nquerydomain(res_state statp, sprintf(nbuf, "%s.%s", name, domain); } return (__libc_res_nquery(statp, longname, class, type, answer, - anslen, answerp, answerp2, nanswerp2)); + anslen, answerp, answerp2, nanswerp2, + resplen2)); } int @@ -574,7 +580,7 @@ res_nquerydomain(res_state statp, int anslen) /* size of answer */ { 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) diff --git a/resolv/res_send.c b/resolv/res_send.c index dec3ac7a3f..3130f64281 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -339,9 +339,9 @@ int __libc_res_nsend(res_state statp, const u_char *buf, int buflen, const u_char *buf2, int buflen2, 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) { __set_errno (ESRCH); @@ -539,7 +539,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, try = statp->retry; n = send_vc(statp, buf, buflen, buf2, buflen2, &ans, &anssiz, &terrno, - ns, ansp, ansp2, nansp2, &resplen2); + ns, ansp, ansp2, nansp2, resplen2); if (n < 0) return (-1); 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, &ans, &anssiz, &terrno, ns, &v_circuit, &gotsomewhere, ansp, - ansp2, nansp2, &resplen2); + ansp2, nansp2, resplen2); if (n < 0) return (-1); if (n == 0) goto next_ns; if (v_circuit) // XXX Check whether both requests failed or - // XXX whether one have been answered successfully + // XXX whether one has been answered successfully goto same_ns; } @@ -575,7 +575,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_REPLY), (stdout, "%s", ""), - *ansp2, (resplen2 > *nansp2) ? *nansp2 : resplen2); + *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2); /* * 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) { return __libc_res_nsend(statp, buf, buflen, NULL, 0, ans, anssiz, - NULL, NULL, NULL); + NULL, NULL, NULL, NULL); } libresolv_hidden_def (res_nsend) @@ -665,6 +665,8 @@ send_vc(res_state statp, u_short len2; u_char *cp; + if (resplen2 != NULL) + *resplen2 = 0; connreset = 0; same_ns: truncating = 0; @@ -734,8 +736,9 @@ send_vc(res_state statp, int recvresp2 = buf2 == NULL; read_len: cp = ans; - len = INT16SZ; - while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, (char *)cp, + uint16_t rlen16; + len = sizeof(rlen16); + while ((n = TEMP_FAILURE_RETRY (read(statp->_vcsock, &rlen16, (int)len))) > 0) { cp += n; if ((len -= n) <= 0) @@ -760,11 +763,7 @@ send_vc(res_state statp, } return (0); } -#ifdef _STRING_ARCH_unaligned - resplen = ntohs (*(uint16_t *) ans); -#else - resplen = ns_get16(ans); -#endif + int rlen = ntohs (rlen16); int *thisanssizp; u_char **thisansp; @@ -795,11 +794,11 @@ send_vc(res_state statp, } anhp = (HEADER *) *thisansp; - *thisresplenp = resplen; - if (resplen > *thisanssizp) { + *thisresplenp = rlen; + if (rlen > *thisanssizp) { /* Yes, we test ANSCP here. If we have two buffers both will be allocatable. */ - if (anscp) { + if (__builtin_expect (anscp != NULL, 1)) { u_char *newp = malloc (MAXPACKET); if (newp == NULL) { *terrno = ENOMEM; @@ -809,7 +808,7 @@ send_vc(res_state statp, *thisanssizp = MAXPACKET; *thisansp = newp; anhp = (HEADER *) newp; - len = resplen; + len = rlen; } else { Dprint(statp->options & RES_DEBUG, (stdout, ";; response truncated\n") @@ -818,9 +817,9 @@ send_vc(res_state statp, len = *thisanssizp; } } else - len = resplen; + len = rlen; - if (len < HFIXEDSZ) { + if (__builtin_expect (len < HFIXEDSZ, 0)) { /* * Undersized message. */ @@ -836,18 +835,18 @@ send_vc(res_state statp, cp += n; len -= n; } - if (n <= 0) { + if (__builtin_expect (n <= 0, 0)) { *terrno = errno; Perror(statp, stderr, "read(vc)", errno); __res_iclose(statp, false); return (0); } - if (truncating) { + if (__builtin_expect (truncating, 0)) { /* * Flush rest of answer so connection stays in synch. */ anhp->tc = 1; - len = resplen - *thisanssizp; + len = rlen - *thisanssizp; while (len != 0) { char junk[PACKETSZ]; @@ -872,7 +871,7 @@ send_vc(res_state statp, (statp->pfcode & RES_PRF_REPLY), (stdout, ";; old answer (unexpected):\n"), *thisansp, - (resplen > *thisanssiz) ? *thisanssiz: resplen); + (rlen > *thisanssiz) ? *thisanssiz: rlen); goto read_len; } @@ -889,7 +888,7 @@ send_vc(res_state statp, * All is well, or the error is fatal. Signal that the * next nameserver ought not be tried. */ - return (resplen); + return resplen; } static int @@ -1084,7 +1083,7 @@ send_dg(res_state statp, *thisresplenp = recvfrom(pfd[0].fd, (char*)*thisansp, *thisanssizp, 0, (struct sockaddr *)&from, &fromlen); - if (*thisresplenp <= 0) { + if (__builtin_expect (*thisresplenp <= 0, 0)) { if (errno == EINTR || errno == EAGAIN) { need_recompute = 1; goto wait; @@ -1093,7 +1092,7 @@ send_dg(res_state statp, goto err_out; } *gotsomewhere = 1; - if (*thisresplenp < HFIXEDSZ) { + if (__builtin_expect (*thisresplenp < HFIXEDSZ, 0)) { /* * Undersized message. */ -- cgit v1.2.3