diff options
author | Ulrich Drepper <drepper@redhat.com> | 2008-07-28 22:55:10 +0000 |
---|---|---|
committer | Ulrich Drepper <drepper@redhat.com> | 2008-07-28 22:55:10 +0000 |
commit | b7da31a1647e378258174d1d69097a594e31f89b (patch) | |
tree | a38031232a20545f6c044a94f6823ecfb6090ead /resolv/res_send.c | |
parent | 372aece0e4b7497f894f21b36bcc32ec52344ad5 (diff) | |
download | glibc-b7da31a1647e378258174d1d69097a594e31f89b.tar.gz glibc-b7da31a1647e378258174d1d69097a594e31f89b.tar.xz glibc-b7da31a1647e378258174d1d69097a594e31f89b.zip |
* resolv/res_send.c (__libc_res_nsend): Take additional parameter. cvs/fedora-glibc-20080728T2320
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.
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r-- | resolv/res_send.c | 53 |
1 files changed, 26 insertions, 27 deletions
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. */ |