diff options
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r-- | resolv/res_send.c | 123 |
1 files changed, 54 insertions, 69 deletions
diff --git a/resolv/res_send.c b/resolv/res_send.c index 887d048e19..8fb21a9446 100644 --- a/resolv/res_send.c +++ b/resolv/res_send.c @@ -267,8 +267,8 @@ res_nameinquery(const char *name, int type, int class, cp += n; if (cp + 2 * INT16SZ > eom) return (-1); - NS_GET16(ttype, cp); - NS_GET16(tclass, cp); + ttype = ns_get16(cp); cp += INT16SZ; + tclass = ns_get16(cp); cp += INT16SZ; if (ttype == type && tclass == class && ns_samename(tname, name) == 1) return (1); @@ -292,6 +292,9 @@ int res_queriesmatch(const u_char *buf1, const u_char *eom1, const u_char *buf2, const u_char *eom2) { + const u_char *cp = buf1 + HFIXEDSZ; + int qdcount = ntohs(((HEADER*)buf1)->qdcount); + if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2) return (-1); @@ -303,16 +306,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, (((HEADER *)buf2)->opcode == ns_o_update)) return (1); - /* Note that we initially do not convert QDCOUNT to the host byte - order. We can compare it with the second buffer's QDCOUNT - value without doing this. */ - int qdcount = ((HEADER*)buf1)->qdcount; - if (qdcount != ((HEADER*)buf2)->qdcount) + if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) return (0); - - qdcount = htons (qdcount); - const u_char *cp = buf1 + HFIXEDSZ; - while (qdcount-- > 0) { char tname[MAXDNAME+1]; int n, ttype, tclass; @@ -323,8 +318,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1, cp += n; if (cp + 2 * INT16SZ > eom1) return (-1); - NS_GET16(ttype, cp); - NS_GET16(tclass, cp); + ttype = ns_get16(cp); cp += INT16SZ; + tclass = ns_get16(cp); cp += INT16SZ; if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) return (0); } @@ -386,7 +381,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, } } if (needclose) - __res_iclose(statp, false); + res_nclose(statp); } /* @@ -493,7 +488,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, done = 1; break; case res_nextns: - __res_iclose(statp, false); + res_nclose(statp); goto next_ns; case res_done: return (resplen); @@ -558,7 +553,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, */ if ((v_circuit && (statp->options & RES_USEVC) == 0) || (statp->options & RES_STAYOPEN) == 0) { - __res_iclose(statp, false); + res_nclose(statp); } if (statp->rhook) { int done = 0, loops = 0; @@ -575,7 +570,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, done = 1; break; case res_nextns: - __res_iclose(statp, false); + res_nclose(statp); goto next_ns; case res_modified: /* give the hook another try */ @@ -594,7 +589,7 @@ __libc_res_nsend(res_state statp, const u_char *buf, int buflen, next_ns: ; } /*foreach ns*/ } /*foreach retry*/ - __res_iclose(statp, false); + res_nclose(statp); if (!v_circuit) { if (!gotsomewhere) __set_errno (ECONNREFUSED); /* no nameservers found */ @@ -637,19 +632,19 @@ send_vc(res_state statp, /* Are we still talking to whom we want to talk to? */ if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) { struct sockaddr_in6 peer; - socklen_t size = sizeof peer; + int size = sizeof peer; if (getpeername(statp->_vcsock, (struct sockaddr *)&peer, &size) < 0 || !sock_eq(&peer, nsap)) { - __res_iclose(statp, false); + res_nclose(statp); statp->_flags &= ~RES_F_VC; } } if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) { if (statp->_vcsock >= 0) - __res_iclose(statp, false); + res_nclose(statp); statp->_vcsock = socket(nsap->sin6_family, SOCK_STREAM, 0); if (statp->_vcsock < 0) { @@ -659,13 +654,11 @@ send_vc(res_state statp, } __set_errno (0); if (connect(statp->_vcsock, (struct sockaddr *)nsap, - nsap->sin6_family == AF_INET - ? sizeof (struct sockaddr_in) - : sizeof (struct sockaddr_in6)) < 0) { + sizeof *nsap) < 0) { *terrno = errno; Aerror(statp, stderr, "connect/vc", errno, (struct sockaddr *) nsap); - __res_iclose(statp, false); + res_nclose(statp); return (0); } statp->_flags |= RES_F_VC; @@ -674,14 +667,14 @@ send_vc(res_state statp, /* * Send length & message */ - ns_put16((u_short)buflen, (u_char*)&len); + putshort((u_short)buflen, (u_char*)&len); evConsIovec(&len, INT16SZ, &iov[0]); evConsIovec((void*)buf, buflen, &iov[1]); if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, 2)) != (INT16SZ + buflen)) { *terrno = errno; Perror(statp, stderr, "write failed", errno); - __res_iclose(statp, false); + res_nclose(statp); return (0); } /* @@ -699,7 +692,7 @@ send_vc(res_state statp, if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read failed", errno); - __res_iclose(statp, false); + res_nclose(statp); /* * A long running process might get its TCP * connection reset if the remote server was @@ -711,8 +704,10 @@ send_vc(res_state statp, */ if (*terrno == ECONNRESET && !connreset) { connreset = 1; + res_nclose(statp); goto same_ns; } + res_nclose(statp); return (0); } resplen = ns_get16(ans); @@ -721,7 +716,7 @@ send_vc(res_state statp, ans = malloc (MAXPACKET); if (ans == NULL) { *terrno = ENOMEM; - __res_iclose(statp, false); + res_nclose(statp); return (0); } anssiz = MAXPACKET; @@ -746,7 +741,7 @@ send_vc(res_state statp, Dprint(statp->options & RES_DEBUG, (stdout, ";; undersized: %d\n", len)); *terrno = EMSGSIZE; - __res_iclose(statp, false); + res_nclose(statp); return (0); } cp = ans; @@ -757,7 +752,7 @@ send_vc(res_state statp, if (n <= 0) { *terrno = errno; Perror(statp, stderr, "read(vc)", errno); - __res_iclose(statp, false); + res_nclose(statp); return (0); } if (truncating) { @@ -814,8 +809,7 @@ send_dg(res_state statp, int ptimeout; struct sockaddr_in6 from; static int socket_pf = 0; - socklen_t fromlen; - int resplen, seconds, n; + int fromlen, resplen, seconds, n; if (EXT(statp).nssocks[ns] == -1) { /* only try IPv6 if IPv6 NS and if not failed before */ @@ -850,7 +844,7 @@ send_dg(res_state statp, sizeof *nsap) < 0) { Aerror(statp, stderr, "connect(dg)", errno, (struct sockaddr *) nsap); - __res_iclose(statp, false); + res_nclose(statp); return (0); } /* Make socket non-blocking. */ @@ -879,13 +873,10 @@ send_dg(res_state statp, pfd[0].events = POLLOUT; wait: if (need_recompute) { - recompute_resend: evNowTime(&now); if (evCmpTime(finish, now) <= 0) { - poll_err_out: - Perror(statp, stderr, "poll", errno); - err_out: - __res_iclose(statp, false); + Perror(statp, stderr, "select", errno); + res_nclose(statp); return (0); } evSubTime(&timeout, &finish, &now); @@ -907,18 +898,26 @@ send_dg(res_state statp, return (0); } if (n < 0) { - if (errno == EINTR) - goto recompute_resend; - - goto poll_err_out; + if (errno == EINTR) { + recompute_resend: + evNowTime(&now); + if (evCmpTime(finish, now) > 0) { + evSubTime(&timeout, &finish, &now); + goto wait; + } + } + Perror(statp, stderr, "poll", errno); + res_nclose(statp); + return (0); } __set_errno (0); if (pfd[0].revents & POLLOUT) { - if (send (pfd[0].fd, buf, buflen, MSG_NOSIGNAL) != buflen) { + if (send(pfd[0].fd, (char*)buf, buflen, 0) != buflen) { if (errno == EINTR || errno == EAGAIN) goto recompute_resend; Perror(statp, stderr, "send", errno); - goto err_out; + res_nclose(statp); + return (0); } pfd[0].events = POLLIN; ++nwritten; @@ -948,7 +947,8 @@ send_dg(res_state statp, goto wait; } Perror(statp, stderr, "recvfrom", errno); - goto err_out; + res_nclose(statp); + return (0); } *gotsomewhere = 1; if (resplen < HFIXEDSZ) { @@ -959,7 +959,8 @@ send_dg(res_state statp, (stdout, ";; undersized: %d\n", resplen)); *terrno = EMSGSIZE; - goto err_out; + res_nclose(statp); + return (0); } if (hp->id != anhp->id) { /* @@ -1006,19 +1007,11 @@ send_dg(res_state statp, DprintQ(statp->options & RES_DEBUG, (stdout, "server rejected query:\n"), ans, (resplen > anssiz) ? anssiz : resplen); - next_ns: - __res_iclose(statp, false); + res_nclose(statp); /* don't retry if called from dig */ if (!statp->pfcode) return (0); } - if (anhp->rcode == NOERROR && anhp->ancount == 0 - && anhp->aa == 0 && anhp->ra == 0 && anhp->arcount == 0) { - DprintQ(statp->options & RES_DEBUG, - (stdout, "referred query:\n"), - ans, (resplen > anssiz) ? anssiz : resplen); - goto next_ns; - } if (!(statp->options & RES_IGNTC) && anhp->tc) { /* * To get the rest of answer, @@ -1027,7 +1020,7 @@ send_dg(res_state statp, Dprint(statp->options & RES_DEBUG, (stdout, ";; truncated answer\n")); *v_circuit = 1; - __res_iclose(statp, false); + res_nclose(statp); return (1); } /* @@ -1037,11 +1030,8 @@ send_dg(res_state statp, return (resplen); } else if (pfd[0].revents & (POLLERR | POLLHUP | POLLNVAL)) { /* Something went wrong. We can stop trying. */ - goto err_out; - } - else { - /* poll should not have returned > 0 in this case. */ - abort (); + res_nclose(statp); + return (0); } } @@ -1057,13 +1047,8 @@ Aerror(const res_state statp, FILE *file, const char *string, int error, fprintf(file, "res_send: %s ([%s].%u): %s\n", string, - (address->sa_family == AF_INET - ? inet_ntop(address->sa_family, - &((const struct sockaddr_in *) address)->sin_addr, - tmp, sizeof tmp) - : inet_ntop(address->sa_family, - &((const struct sockaddr_in6 *) address)->sin6_addr, - tmp, sizeof tmp)), + inet_ntop(address->sa_family, address->sa_data, + tmp, sizeof tmp), (address->sa_family == AF_INET ? ntohs(((struct sockaddr_in *) address)->sin_port) : address->sa_family == AF_INET6 |