summaryrefslogtreecommitdiff
path: root/resolv/res_send.c
diff options
context:
space:
mode:
Diffstat (limited to 'resolv/res_send.c')
-rw-r--r--resolv/res_send.c123
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