#include <netdb.h>
#include <resolv/resolv-internal.h>
#include <signal.h>
-#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
}
-/* Options. Leave them on. */
-/* #undef DEBUG */
-#include "res_debug.h"
-
#define EXT(res) ((res)->_u._ext)
/* Forward. */
u_char **, int *, int *, int,
int *, int *, u_char **,
u_char **, int *, int *, int *);
-#ifdef DEBUG
-static void Aerror(const res_state, FILE *, const char *, int,
- const struct sockaddr *);
-static void Perror(const res_state, FILE *, const char *, int);
-#endif
static int sock_eq(struct sockaddr_in6 *, struct sockaddr_in6 *);
/* Public. */
return (-1);
}
- DprintQ((statp->options & RES_DEBUG) || (statp->pfcode & RES_PRF_QUERY),
- (stdout, ";; res_send()\n"), buf, buflen);
v_circuit = ((statp->options & RES_USEVC)
|| buflen > PACKETSZ
|| buflen2 > PACKETSZ);
unsigned int ns = ns_shift + ns_offset;
if (ns >= statp->nscount)
ns -= statp->nscount;
-#ifdef DEBUG
- char tmpbuf[40];
- struct sockaddr *nsap = get_nsaddr (statp, ns);
-#endif
same_ns:
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; Querying server (# %d) address = %s\n",
- ns + 1, inet_ntop(nsap->sa_family,
- (nsap->sa_family == AF_INET6
- ? (void *) &((struct sockaddr_in6 *) nsap)->sin6_addr
- : (void *) &((struct sockaddr_in *) nsap)->sin_addr),
- tmpbuf, sizeof (tmpbuf))));
-
if (__glibc_unlikely (v_circuit)) {
/* Use VC; at most one attempt per server. */
try = statp->retry;
resplen = n;
- Dprint((statp->options & RES_DEBUG) ||
- ((statp->pfcode & RES_PRF_REPLY) &&
- (statp->pfcode & RES_PRF_HEAD1)),
- (stdout, ";; got answer:\n"));
-
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, "%s", ""),
- ans, (resplen > anssiz) ? anssiz : resplen);
- if (buf2 != NULL) {
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, "%s", ""),
- *ansp2, (*resplen2 > *nansp2) ? *nansp2 : *resplen2);
- }
-
/*
* If we have temporarily opened a virtual circuit,
* or if we haven't been asked to keep a socket open,
(nsap->sa_family, SOCK_STREAM | SOCK_CLOEXEC, 0);
if (statp->_vcsock < 0) {
*terrno = errno;
- Perror(statp, stderr, "socket(vc)", errno);
if (resplen2 != NULL)
*resplen2 = 0;
return (-1);
? sizeof (struct sockaddr_in)
: sizeof (struct sockaddr_in6)) < 0) {
*terrno = errno;
- Aerror(statp, stderr, "connect/vc", errno, nsap);
return close_and_return_error (statp, resplen2);
}
statp->_flags |= RES_F_VC;
}
if (TEMP_FAILURE_RETRY (writev(statp->_vcsock, iov, niov)) != explen) {
*terrno = errno;
- Perror(statp, stderr, "write failed", errno);
return close_and_return_error (statp, resplen2);
}
/*
}
if (n <= 0) {
*terrno = errno;
- Perror(statp, stderr, "read failed", errno);
/*
* A long running process might get its TCP
* connection reset if the remote server was
read RLEN bytes instead. */
len = rlen;
} else {
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; response truncated\n")
- );
truncating = 1;
len = *thisanssizp;
}
/*
* Undersized message.
*/
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; undersized: %d\n", len));
*terrno = EMSGSIZE;
return close_and_return_error (statp, resplen2);
}
}
if (__glibc_unlikely (n <= 0)) {
*terrno = errno;
- Perror(statp, stderr, "read(vc)", errno);
return close_and_return_error (statp, resplen2);
}
if (__glibc_unlikely (truncating)) {
* wait for the correct one.
*/
if ((recvresp1 || hp->id != anhp->id)
- && (recvresp2 || hp2->id != anhp->id)) {
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; old answer (unexpected):\n"),
- *thisansp,
- (rlen > *thisanssizp) ? *thisanssizp: rlen);
+ && (recvresp2 || hp2->id != anhp->id))
goto read_len;
- }
/* Mark which reply we received. */
if (recvresp1 == 0 && hp->id == anhp->id)
}
if (EXT(statp).nssocks[ns] < 0) {
*terrno = errno;
- Perror(statp, stderr, "socket(dg)", errno);
return (-1);
}
DIAG_IGNORE_Os_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
if (connect(EXT(statp).nssocks[ns], nsap, slen) < 0) {
DIAG_POP_NEEDS_COMMENT;
- Aerror(statp, stderr, "connect(dg)", errno, nsap);
__res_iclose(statp, false);
return (0);
}
evNowTime(&now);
if (evCmpTime(finish, now) <= 0) {
poll_err_out:
- Perror(statp, stderr, "poll", errno);
return close_and_return_error (statp, resplen2);
}
evSubTime(&timeout, &finish, &now);
need_recompute = 1;
}
if (n == 0) {
- Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
if (resplen > 1 && (recvresp1 || (buf2 != NULL && recvresp2)))
{
/* There are quite a few broken name servers out
#endif
fail_sendmmsg:
- Perror(statp, stderr, "sendmmsg", errno);
return close_and_return_error (statp, resplen2);
}
}
if (sr != (nwritten != 0 ? buflen2 : buflen)) {
if (errno == EINTR || errno == EAGAIN)
goto recompute_resend;
- Perror(statp, stderr, "send", errno);
return close_and_return_error (statp, resplen2);
}
just_one:
MSG_TRUNC which is only available on Linux. We
can abstract out the Linux-specific feature in the
future to detect truncation. */
- if (__glibc_unlikely (*thisanssizp < *thisresplenp)) {
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; response may be truncated (UDP)\n")
- );
- }
-
HEADER *anhp = (HEADER *) *thisansp;
socklen_t fromlen = sizeof(struct sockaddr_in6);
assert (sizeof(from) <= fromlen);
need_recompute = 1;
goto wait;
}
- Perror(statp, stderr, "recvfrom", errno);
return close_and_return_error (statp, resplen2);
}
*gotsomewhere = 1;
/*
* Undersized message.
*/
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; undersized: %d\n",
- *thisresplenp));
*terrno = EMSGSIZE;
return close_and_return_error (statp, resplen2);
}
* XXX - potential security hazard could
* be detected here.
*/
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; old answer:\n"),
- *thisansp,
- (*thisresplenp > *thisanssizp)
- ? *thisanssizp : *thisresplenp);
goto wait;
}
if (!(statp->options & RES_INSECURE1) &&
* XXX - potential security hazard could
* be detected here.
*/
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; not our server:\n"),
- *thisansp,
- (*thisresplenp > *thisanssizp)
- ? *thisanssizp : *thisresplenp);
goto wait;
}
if (!(statp->options & RES_INSECURE2)
* XXX - potential security hazard could
* be detected here.
*/
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; wrong query name:\n"),
- *thisansp,
- (*thisresplenp > *thisanssizp)
- ? *thisanssizp : *thisresplenp);
goto wait;
}
if (anhp->rcode == SERVFAIL ||
anhp->rcode == NOTIMP ||
anhp->rcode == REFUSED) {
- DprintQ(statp->options & RES_DEBUG,
- (stdout, "server rejected query:\n"),
- *thisansp,
- (*thisresplenp > *thisanssizp)
- ? *thisanssizp : *thisresplenp);
-
next_ns:
if (recvresp1 || (buf2 != NULL && recvresp2)) {
*resplen2 = 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"),
- *thisansp,
- (*thisresplenp > *thisanssizp)
- ? *thisanssizp : *thisresplenp);
goto next_ns;
}
if (!(statp->options & RES_IGNTC) && anhp->tc) {
* To get the rest of answer,
* use TCP with same server.
*/
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; truncated answer\n"));
*v_circuit = 1;
__res_iclose(statp, false);
// XXX if we have received one reply we could
}
}
-#ifdef DEBUG
-static void
-Aerror(const res_state statp, FILE *file, const char *string, int error,
- const struct sockaddr *address)
-{
- int save = errno;
-
- if ((statp->options & RES_DEBUG) != 0) {
- char tmp[sizeof "xxxx.xxxx.xxxx.255.255.255.255"];
-
- 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)),
- (address->sa_family == AF_INET
- ? ntohs(((struct sockaddr_in *) address)->sin_port)
- : address->sa_family == AF_INET6
- ? ntohs(((struct sockaddr_in6 *) address)->sin6_port)
- : 0),
- strerror(error));
- }
- __set_errno (save);
-}
-
-static void
-Perror(const res_state statp, FILE *file, const char *string, int error) {
- int save = errno;
-
- if ((statp->options & RES_DEBUG) != 0)
- fprintf(file, "res_send: %s: %s\n",
- string, strerror(error));
- __set_errno (save);
-}
-#endif
-
static int
sock_eq(struct sockaddr_in6 *a1, struct sockaddr_in6 *a2) {
if (a1->sin6_family == a2->sin6_family) {