summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/resolv
diff options
context:
space:
mode:
authorasmodai <asmodai@FreeBSD.org>2000-05-26 07:17:19 +0000
committerasmodai <asmodai@FreeBSD.org>2000-05-26 07:17:19 +0000
commit3f83b2963e3f1302f6507d3968aa3bfc93d7472d (patch)
tree58c578d1f5a84acb9535b8fc95abe2637662f30f /contrib/bind/lib/resolv
parent08dfda8209739c209911999e8c76d369945766ed (diff)
downloadFreeBSD-src-3f83b2963e3f1302f6507d3968aa3bfc93d7472d.zip
FreeBSD-src-3f83b2963e3f1302f6507d3968aa3bfc93d7472d.tar.gz
Virgin import of BIND v8.2.3-T5B
Diffstat (limited to 'contrib/bind/lib/resolv')
-rw-r--r--contrib/bind/lib/resolv/Makefile15
-rw-r--r--contrib/bind/lib/resolv/res_debug.c32
-rw-r--r--contrib/bind/lib/resolv/res_debug.h4
-rw-r--r--contrib/bind/lib/resolv/res_findzonecut.c11
-rw-r--r--contrib/bind/lib/resolv/res_init.c35
-rw-r--r--contrib/bind/lib/resolv/res_query.c33
-rw-r--r--contrib/bind/lib/resolv/res_send.c965
7 files changed, 562 insertions, 533 deletions
diff --git a/contrib/bind/lib/resolv/Makefile b/contrib/bind/lib/resolv/Makefile
index 243e69b..78741be 100644
--- a/contrib/bind/lib/resolv/Makefile
+++ b/contrib/bind/lib/resolv/Makefile
@@ -13,7 +13,7 @@
# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
# SOFTWARE.
-# $Id: Makefile,v 8.30 1999/10/07 08:24:15 vixie Exp $
+# $Id: Makefile,v 8.33 2000/02/29 03:38:24 vixie Exp $
# these are only appropriate for BSD 4.4 or derivatives, and are used in
# development. normal builds will be done in the top level directory and
@@ -62,14 +62,15 @@ ${LIBBIND}: ${OBJS}
${RANLIB} ${LIBBIND}
.c.${O}:
- if test ! -d ${THREADED} ; then mkdir ${THREADED} ; fi
+ if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi
${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \
-o ${THREADED}/$*.${O}
- -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} -o a.out && \
- ${LDS} mv a.out ${THREADED}/$*.${O}
+ -${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \
+ -o ${THREADED}/$*.out && \
+ ${LDS} mv ${THREADED}/$*.out ${THREADED}/$*.${O}
${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} -c $*.c
- -${LDS} ${LD} ${LD_LIBFLAGS} $*.${O} -o a.out && \
- ${LDS} mv a.out $*.${O}
+ -${LDS} ${LD} ${LD_LIBFLAGS} $*.${O} -o $*.out && \
+ ${LDS} mv $*.out $*.${O}
distclean: clean
@@ -77,7 +78,7 @@ clean: FRC
rm -f .depend a.out core ${LIB} tags
rm -f *.${O} *.BAK *.CKP *~
rm -f ${THREADED}/*.${O}
- -rmdir ${THREADED}
+ -if test -d ${THREADED} ; then rmdir ${THREADED}; else true; fi
depend: FRC
mkdep -I${INCL} -I${PORTINCL} ${CPPFLAGS} ${SRCS}
diff --git a/contrib/bind/lib/resolv/res_debug.c b/contrib/bind/lib/resolv/res_debug.c
index 39f5e9f..180d67f 100644
--- a/contrib/bind/lib/resolv/res_debug.c
+++ b/contrib/bind/lib/resolv/res_debug.c
@@ -95,7 +95,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_debug.c,v 8.32 1999/10/13 16:39:39 vixie Exp $";
+static const char rcsid[] = "$Id: res_debug.c,v 8.34 2000/02/29 05:30:55 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -149,7 +149,8 @@ do_section(const res_state statp,
int pflag, FILE *file)
{
int n, sflag, rrnum;
- char buf[2048]; /* XXX need to malloc */
+ static int buflen = 2048;
+ char *buf;
ns_opcode opcode;
ns_rr rr;
@@ -160,6 +161,12 @@ do_section(const res_state statp,
if (statp->pfcode && !sflag)
return;
+ buf = malloc(buflen);
+ if (buf == NULL) {
+ fprintf(file, ";; memory allocation failure\n");
+ return;
+ }
+
opcode = (ns_opcode) ns_msg_getflag(*handle, ns_f_opcode);
rrnum = 0;
for (;;) {
@@ -170,7 +177,7 @@ do_section(const res_state statp,
else if (rrnum > 0 && sflag != 0 &&
(statp->pfcode & RES_PRF_HEAD1))
putc('\n', file);
- return;
+ goto cleanup;
}
if (rrnum == 0 && sflag != 0 && (statp->pfcode & RES_PRF_HEAD1))
fprintf(file, ";; %s SECTION:\n",
@@ -182,17 +189,32 @@ do_section(const res_state statp,
p_class(ns_rr_class(rr)));
else {
n = ns_sprintrr(handle, &rr, NULL, NULL,
- buf, sizeof buf);
+ buf, buflen);
if (n < 0) {
+ if (errno == ENOSPC) {
+ free(buf);
+ buf = NULL;
+ if (buflen < 131072)
+ buf = malloc(buflen += 1024);
+ if (buf == NULL) {
+ fprintf(file,
+ ";; memory allocation failure\n");
+ return;
+ }
+ continue;
+ }
fprintf(file, ";; ns_sprintrr: %s\n",
strerror(errno));
- return;
+ goto cleanup;
}
fputs(buf, file);
fputc('\n', file);
}
rrnum++;
}
+ cleanup:
+ if (buf != NULL)
+ free(buf);
}
/*
diff --git a/contrib/bind/lib/resolv/res_debug.h b/contrib/bind/lib/resolv/res_debug.h
index 1150551..4a0aa99 100644
--- a/contrib/bind/lib/resolv/res_debug.h
+++ b/contrib/bind/lib/resolv/res_debug.h
@@ -21,8 +21,8 @@
#ifndef DEBUG
# define Dprint(cond, args) /*empty*/
# define DprintQ(cond, args, query, size) /*empty*/
-# define Aerror(file, string, error, address) /*empty*/
-# define Perror(file, string, error) /*empty*/
+# define Aerror(statp, file, string, error, address) /*empty*/
+# define Perror(statp, file, string, error) /*empty*/
#else
# define Dprint(cond, args) if (cond) {fprintf args;} else {}
# define DprintQ(cond, args, query, size) if (cond) {\
diff --git a/contrib/bind/lib/resolv/res_findzonecut.c b/contrib/bind/lib/resolv/res_findzonecut.c
index 73a42a2..e65faa1 100644
--- a/contrib/bind/lib/resolv/res_findzonecut.c
+++ b/contrib/bind/lib/resolv/res_findzonecut.c
@@ -1,5 +1,5 @@
#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_findzonecut.c,v 8.8 1999/10/15 19:49:11 vixie Exp $";
+static const char rcsid[] = "$Id: res_findzonecut.c,v 8.9 1999/12/21 09:33:34 cyarnell Exp $";
#endif /* not lint */
/*
@@ -399,11 +399,16 @@ get_glue(res_state statp, ns_class class, rrset_ns *nsrrsp) {
if (EMPTY(nsrr->addrs)) {
n = do_query(statp, nsrr->name, class, ns_t_a,
resp, &msg);
- if (n != 0) {
+ if (n < 0) {
DPRINTF(("get_glue: do_query('%s', %s') failed",
- nsrr->name, p_class(class), n));
+ nsrr->name, p_class(class)));
return (-1);
}
+ if (n > 0) {
+ DPRINTF((
+ "get_glue: do_query('%s', %s') CNAME or DNAME found",
+ nsrr->name, p_class(class)));
+ }
if (save_a(statp, &msg, ns_s_an, nsrr->name, class,
&nsrr->addrs) < 0) {
DPRINTF(("get_glue: save_r('%s', %s) failed",
diff --git a/contrib/bind/lib/resolv/res_init.c b/contrib/bind/lib/resolv/res_init.c
index 85dc7e3..12d9969 100644
--- a/contrib/bind/lib/resolv/res_init.c
+++ b/contrib/bind/lib/resolv/res_init.c
@@ -70,7 +70,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
-static const char rcsid[] = "$Id: res_init.c,v 8.13 1999/10/13 16:39:40 vixie Exp $";
+static const char rcsid[] = "$Id: res_init.c,v 8.16 2000/05/09 07:10:12 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -95,7 +95,6 @@ static const char rcsid[] = "$Id: res_init.c,v 8.13 1999/10/13 16:39:40 vixie Ex
/* Options. Should all be left alone. */
#define RESOLVSORT
-#define RFC1535
#define DEBUG
static void res_setoptions __P((res_state, const char *, const char *));
@@ -156,9 +155,7 @@ __res_vinit(res_state statp, int preinit) {
int nsort = 0;
char *net;
#endif
-#ifndef RFC1535
int dots;
-#endif
if (!preinit) {
statp->retrans = RES_TIMEOUT;
@@ -177,10 +174,11 @@ __res_vinit(res_state statp, int preinit) {
statp->nscount = 1;
statp->ndots = 1;
statp->pfcode = 0;
- statp->_sock = -1;
+ statp->_vcsock = -1;
statp->_flags = 0;
statp->qhook = NULL;
statp->rhook = NULL;
+ statp->_u._ext.nscount = 0;
/* Allow user to override the local domain definition */
if ((cp = getenv("LOCALDOMAIN")) != NULL) {
@@ -363,7 +361,6 @@ __res_vinit(res_state statp, int preinit) {
*pp++ = statp->defdname;
*pp = NULL;
-#ifndef RFC1535
dots = 0;
for (cp = statp->defdname; *cp; cp++)
dots += (*cp == '.');
@@ -385,7 +382,6 @@ __res_vinit(res_state statp, int preinit) {
printf(";;\t..END..\n");
}
#endif
-#endif /* !RFC1535 */
}
if ((cp = getenv("RES_OPTIONS")) != NULL)
@@ -479,3 +475,28 @@ res_randomid(void) {
gettimeofday(&now, NULL);
return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
}
+
+/*
+ * This routine is for closing the socket if a virtual circuit is used and
+ * the program wants to close it. This provides support for endhostent()
+ * which expects to close the socket.
+ *
+ * This routine is not expected to be user visible.
+ */
+void
+res_nclose(res_state statp) {
+ int ns;
+
+ if (statp->_vcsock >= 0) {
+ (void) close(statp->_vcsock);
+ statp->_vcsock = -1;
+ statp->_flags &= ~(RES_F_VC | RES_F_CONN);
+ }
+ for (ns = 0; ns < statp->_u._ext.nscount; ns++) {
+ if (statp->_u._ext.nssocks[ns] != -1) {
+ (void) close(statp->_u._ext.nssocks[ns]);
+ statp->_u._ext.nssocks[ns] = -1;
+ }
+ }
+ statp->_u._ext.nscount = 0;
+}
diff --git a/contrib/bind/lib/resolv/res_query.c b/contrib/bind/lib/resolv/res_query.c
index 26c1a60..3147f1e 100644
--- a/contrib/bind/lib/resolv/res_query.c
+++ b/contrib/bind/lib/resolv/res_query.c
@@ -70,7 +70,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_query.c,v 8.19 1999/10/15 19:49:11 vixie Exp $";
+static const char rcsid[] = "$Id: res_query.c,v 8.20 2000/02/29 05:39:12 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -190,8 +190,9 @@ res_nsearch(res_state statp,
HEADER *hp = (HEADER *) answer;
char tmp[NS_MAXDNAME];
u_int dots;
- int trailing_dot, ret;
+ int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, root_on_list = 0;
+ int tried_as_is = 0;
errno = 0;
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); /* True if we never query. */
@@ -208,12 +209,19 @@ res_nsearch(res_state statp,
return (res_nquery(statp, cp, class, type, answer, anslen));
/*
- * If there are enough dots in the name, do no searching.
- * (The threshold can be set with the "ndots" option.)
+ * If there are enough dots in the name, let's just give it a
+ * try 'as is'. The threshold can be set with the "ndots" option.
+ * Also, query 'as is', if there is a trailing dot in the name.
*/
- if (dots >= statp->ndots || trailing_dot)
- return (res_nquerydomain(statp, name, NULL, class, type,
- answer, anslen));
+ saved_herrno = -1;
+ if (dots >= statp->ndots || trailing_dot) {
+ ret = res_nquerydomain(statp, name, NULL, class, type,
+ answer, anslen);
+ if (ret > 0 || trailing_dot)
+ return (ret);
+ saved_herrno = h_errno;
+ tried_as_is++;
+ }
/*
* We do at least one level of search if
@@ -285,10 +293,11 @@ res_nsearch(res_state statp,
}
/*
- * If the name has any dots at all, and "." is not on the search
- * list, then try an as-is query now.
+ * If the name has any dots at all, and no earlier 'as-is' query
+ * for the name, and "." is not on the search list, then try an as-is
+ * query now.
*/
- if (statp->ndots) {
+ if (statp->ndots && !(tried_as_is || root_on_list)) {
ret = res_nquerydomain(statp, name, NULL, class, type,
answer, anslen);
if (ret > 0)
@@ -302,7 +311,9 @@ res_nsearch(res_state statp,
* else send back meaningless H_ERRNO, that being the one from
* the last DNSRCH we did.
*/
- if (got_nodata)
+ if (saved_herrno != -1)
+ RES_SET_H_ERRNO(statp, saved_herrno);
+ else if (got_nodata)
RES_SET_H_ERRNO(statp, NO_DATA);
else if (got_servfail)
RES_SET_H_ERRNO(statp, TRY_AGAIN);
diff --git a/contrib/bind/lib/resolv/res_send.c b/contrib/bind/lib/resolv/res_send.c
index 80c9e44..af674a1 100644
--- a/contrib/bind/lib/resolv/res_send.c
+++ b/contrib/bind/lib/resolv/res_send.c
@@ -70,7 +70,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_send.c,v 8.36 1999/10/15 19:49:11 vixie Exp $";
+static const char rcsid[] = "$Id: res_send.c,v 8.38 2000/03/30 20:16:51 vixie Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -107,47 +107,33 @@ static const char rcsid[] = "$Id: res_send.c,v 8.36 1999/10/15 19:49:11 vixie Ex
#define DEBUG
#include "res_debug.h"
+#define EXT(res) ((res)->_u._ext)
+
+static const int highestFD = FD_SETSIZE - 1;
+
+/* Forward. */
+
+static int send_vc(res_state, const u_char *, int,
+ u_char *, int, int *, int);
+static int send_dg(res_state, const u_char *, int,
+ u_char *, int, int *, int,
+ int *, int *);
+static void Aerror(const res_state, FILE *, const char *, int,
+ struct sockaddr_in);
+static void Perror(const res_state, FILE *, const char *, int);
+static int sock_eq(struct sockaddr_in *, struct sockaddr_in *);
#ifdef NEED_PSELECT
static int pselect(int, void *, void *, void *,
struct timespec *,
const sigset_t *);
#endif
-#define CHECK_SRVR_ADDR
-
-#ifdef DEBUG
- static void
- Aerror(const res_state statp, FILE *file, const char *string, int error,
- struct sockaddr_in address)
- {
- int save = errno;
-
- if ((statp->options & RES_DEBUG) != 0) {
- char tmp[sizeof "255.255.255.255"];
-
- fprintf(file, "res_send: %s ([%s].%u): %s\n",
- string,
- inet_ntop(address.sin_family, &address.sin_addr,
- tmp, sizeof tmp),
- ntohs(address.sin_port),
- strerror(error));
- }
- 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));
- errno = save;
- }
-#endif
+/* Reachover. */
-static int cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2);
void res_pquery(const res_state, const u_char *, int, FILE *);
+/* Public. */
+
/* int
* res_isourserver(ina)
* looks up "ina" in _res.ns_addr_list[]
@@ -163,7 +149,7 @@ res_ourserver_p(const res_state statp, const struct sockaddr_in *inp) {
int ns;
ina = *inp;
- for (ns = 0; ns < statp->nscount; ns++) {
+ for (ns = 0; ns < statp->nscount; ns++) {
const struct sockaddr_in *srv = &statp->nsaddr_list[ns];
if (srv->sin_family == ina.sin_family &&
@@ -238,8 +224,8 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1,
* Only header section present in replies to
* dynamic update packets.
*/
- if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
- (((HEADER *)buf2)->opcode == ns_o_update) )
+ if ((((HEADER *)buf1)->opcode == ns_o_update) &&
+ (((HEADER *)buf2)->opcode == ns_o_update))
return (1);
if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
@@ -266,12 +252,12 @@ int
res_nsend(res_state statp,
const u_char *buf, int buflen, u_char *ans, int anssiz)
{
- HEADER *hp = (HEADER *) buf;
- HEADER *anhp = (HEADER *) ans;
- int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
- u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */
- static int highestFD = FD_SETSIZE - 1;
+ int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
+ if (statp->nscount == 0) {
+ errno = ESRCH;
+ return (-1);
+ }
if (anssiz < HFIXEDSZ) {
errno = EINVAL;
return (-1);
@@ -280,14 +266,46 @@ res_nsend(res_state statp,
(stdout, ";; res_send()\n"), buf, buflen);
v_circuit = (statp->options & RES_USEVC) || buflen > PACKETSZ;
gotsomewhere = 0;
- connreset = 0;
terrno = ETIMEDOUT;
- badns = 0;
/*
- * Some callers want to even out the load on their resolver list.
+ * If the ns_addr_list in the resolver context has changed, then
+ * invalidate our cached copy and the associated timing data.
*/
- if (statp->nscount > 0 && (statp->options & RES_ROTATE) != 0) {
+ if (EXT(statp).nscount != 0) {
+ int needclose = 0;
+
+ if (EXT(statp).nscount != statp->nscount)
+ needclose++;
+ else
+ for (ns = 0; ns < statp->nscount; ns++)
+ if (!sock_eq(&statp->nsaddr_list[ns],
+ &EXT(statp).nsaddrs[ns])) {
+ needclose++;
+ break;
+ }
+ if (needclose)
+ res_nclose(statp);
+ }
+
+ /*
+ * Maybe initialize our private copy of the ns_addr_list.
+ */
+ if (EXT(statp).nscount == 0) {
+ for (ns = 0; ns < statp->nscount; ns++) {
+ EXT(statp).nsaddrs[ns] = statp->nsaddr_list[ns];
+ EXT(statp).nstimes[ns] = RES_MAXTIME;
+ EXT(statp).nssocks[ns] = -1;
+ }
+ EXT(statp).nscount = statp->nscount;
+ }
+
+ /*
+ * Some resolvers want to even out the load on their nameservers.
+ * Note that RES_BLAST overrides RES_ROTATE.
+ */
+ if ((statp->options & RES_ROTATE) != 0 &&
+ (statp->options & RES_BLAST) == 0) {
struct sockaddr_in ina;
int lastns = statp->nscount - 1;
@@ -298,17 +316,12 @@ res_nsend(res_state statp,
}
/*
- * Send request, RETRY times, or until successful
+ * Send request, RETRY times, or until successful.
*/
for (try = 0; try < statp->retry; try++) {
for (ns = 0; ns < statp->nscount; ns++) {
struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
same_ns:
- if (badns & (1 << ns)) {
- res_nclose(statp);
- goto next_ns;
- }
-
if (statp->qhook) {
int done = 0, loops = 0;
@@ -344,454 +357,45 @@ res_nsend(res_state statp,
ns + 1, inet_ntoa(nsap->sin_addr)));
if (v_circuit) {
- int truncated;
- struct iovec iov[2];
- u_short len;
- u_char *cp;
-
/* Use VC; at most one attempt per server. */
try = statp->retry;
- truncated = 0;
-
- /* Are we still talking to whom we want to talk to? */
- if (statp->_sock >= 0 &&
- (statp->_flags & RES_F_VC) != 0) {
- struct sockaddr_in peer;
- int size = sizeof(peer);
-
- if (getpeername(statp->_sock,
- (struct sockaddr *)&peer,
- &size) < 0) {
- res_nclose(statp);
- statp->_flags &= ~RES_F_VC;
- } else if (!cmpsock(&peer, nsap)) {
- res_nclose(statp);
- statp->_flags &= ~RES_F_VC;
- }
- }
-
- if (statp->_sock < 0 ||
- (statp->_flags & RES_F_VC) == 0) {
- if (statp->_sock >= 0)
- res_nclose(statp);
-
- statp->_sock = socket(PF_INET,
- SOCK_STREAM, 0);
- if (statp->_sock < 0 ||
- statp->_sock > highestFD) {
- terrno = errno;
- Perror(statp, stderr,
- "socket(vc)", errno);
- return (-1);
- }
- errno = 0;
- if (connect(statp->_sock,
- (struct sockaddr *)nsap,
- sizeof *nsap) < 0) {
- terrno = errno;
- Aerror(statp, stderr, "connect/vc",
- errno, *nsap);
- badns |= (1 << ns);
- res_nclose(statp);
- goto next_ns;
- }
- statp->_flags |= RES_F_VC;
- }
- /*
- * Send length & message
- */
- putshort((u_short)buflen, (u_char*)&len);
- iov[0].iov_base = (caddr_t)&len;
- iov[0].iov_len = INT16SZ;
- iov[1].iov_base = (caddr_t)buf;
- iov[1].iov_len = buflen;
- if (writev(statp->_sock, iov, 2) !=
- (INT16SZ + buflen)) {
- terrno = errno;
- Perror(statp, stderr, "write failed", errno);
- badns |= (1 << ns);
- res_nclose(statp);
+ n = send_vc(statp, buf, buflen, ans, anssiz, &terrno,
+ ns);
+ if (n < 0)
+ return (-1);
+ if (n == 0)
goto next_ns;
- }
- /*
- * Receive length & response
- */
- read_len:
- cp = ans;
- len = INT16SZ;
- while ((n = read(statp->_sock,
- (char *)cp, (int)len)) > 0) {
- cp += n;
- if ((len -= n) <= 0)
- break;
- }
- if (n <= 0) {
- terrno = errno;
- Perror(statp, stderr, "read failed", errno);
- res_nclose(statp);
- /*
- * A long running process might get its TCP
- * connection reset if the remote server was
- * restarted. Requery the server instead of
- * trying a new one. When there is only one
- * server, this means that a query might work
- * instead of failing. We only allow one reset
- * per query to prevent looping.
- */
- if (terrno == ECONNRESET && !connreset) {
- connreset = 1;
- res_nclose(statp);
- goto same_ns;
- }
- res_nclose(statp);
- goto next_ns;
- }
- resplen = ns_get16(ans);
- if (resplen > anssiz) {
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; response truncated\n")
- );
- truncated = 1;
- len = anssiz;
- } else
- len = resplen;
- if (len < HFIXEDSZ) {
- /*
- * Undersized message.
- */
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; undersized: %d\n", len));
- terrno = EMSGSIZE;
- badns |= (1 << ns);
- res_nclose(statp);
- goto next_ns;
- }
- cp = ans;
- while (len != 0 &&
- (n = read(statp->_sock, (char *)cp, (int)len))
- > 0) {
- cp += n;
- len -= n;
- }
- if (n <= 0) {
- terrno = errno;
- Perror(statp, stderr, "read(vc)", errno);
- res_nclose(statp);
- goto next_ns;
- }
- if (truncated) {
- /*
- * Flush rest of answer
- * so connection stays in synch.
- */
- anhp->tc = 1;
- len = resplen - anssiz;
- while (len != 0) {
- char junk[PACKETSZ];
-
- n = (len > sizeof(junk)
- ? sizeof(junk)
- : len);
- n = read(statp->_sock, junk, n);
- if (n > 0)
- len -= n;
- else
- break;
- }
- }
- /*
- * The calling applicating has bailed out of
- * a previous call and failed to arrange to have
- * the circuit closed or the server has got
- * itself confused. Anyway drop the packet and
- * wait for the correct one.
- */
- if (hp->id != anhp->id) {
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; old answer (unexpected):\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto read_len;
- }
+ resplen = n;
} else {
- /*
- * Use datagrams.
- */
- struct timespec start, timeout, finish;
- fd_set dsmask;
- struct sockaddr_in from;
- int fromlen, seconds;
-
- if (statp->_sock < 0 ||
- (statp->_flags & RES_F_VC) != 0) {
- if ((statp->_flags & RES_F_VC) != 0)
- res_nclose(statp);
- statp->_sock = socket(PF_INET, SOCK_DGRAM, 0);
- if (statp->_sock < 0 ||
- statp->_sock > highestFD) {
-#ifndef CAN_RECONNECT
- bad_dg_sock:
-#endif
- terrno = errno;
- Perror(statp, stderr,
- "socket(dg)", errno);
- return (-1);
- }
- statp->_flags &= ~RES_F_CONN;
- }
-#ifndef CANNOT_CONNECT_DGRAM
- /*
- * On a 4.3BSD+ machine (client and server,
- * actually), sending to a nameserver datagram
- * port with no nameserver will cause an
- * ICMP port unreachable message to be returned.
- * If our datagram socket is "connected" to the
- * server, we get an ECONNREFUSED error on the next
- * socket operation, and select returns if the
- * error message is received. We can thus detect
- * the absence of a nameserver without timing out.
- * If we have sent queries to at least two servers,
- * however, we don't want to remain connected,
- * as we wish to receive answers from the first
- * server to respond.
- */
- if (statp->nscount == 1 || (try == 0 && ns == 0)) {
- /*
- * Connect only if we are sure we won't
- * receive a response from another server.
- */
- if ((statp->_flags & RES_F_CONN) == 0) {
- if (connect(statp->_sock,
- (struct sockaddr *)nsap,
- sizeof *nsap) < 0) {
- Aerror(statp, stderr,
- "connect(dg)",
- errno, *nsap);
- badns |= (1 << ns);
- res_nclose(statp);
- goto next_ns;
- }
- statp->_flags |= RES_F_CONN;
- }
- if (send(statp->_sock, (char*)buf, buflen, 0)
- != buflen) {
- Perror(statp, stderr, "send", errno);
- badns |= (1 << ns);
- res_nclose(statp);
- goto next_ns;
- }
- } else {
- /*
- * Disconnect if we want to listen
- * for responses from more than one server.
- */
- if ((statp->_flags & RES_F_CONN) != 0) {
-#ifdef CAN_RECONNECT
- struct sockaddr_in no_addr;
-
- no_addr.sin_family = AF_INET;
- no_addr.sin_addr.s_addr = INADDR_ANY;
- no_addr.sin_port = 0;
- (void) connect(statp->_sock,
- (struct sockaddr *)
- &no_addr,
- sizeof no_addr);
-#else
- struct sockaddr_in local_addr;
- int len, result, s1;
-
- len = sizeof(local_addr);
- s1 = socket(PF_INET, SOCK_DGRAM, 0);
- result = getsockname(statp->_sock,
- (struct sockaddr *)&local_addr,
- &len);
- if (s1 < 0)
- goto bad_dg_sock;
- (void) dup2(s1, statp->_sock);
- (void) close(s1);
- if (result == 0) {
- /*
- * Attempt to rebind to old
- * port. Note connected socket
- * has an sin_addr set.
- */
- local_addr.sin_addr.s_addr =
- htonl(0);
- (void)bind(statp->_sock,
- (struct sockaddr *)
- &local_addr, len);
- }
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; new DG socket\n"))
-#endif /* CAN_RECONNECT */
- statp->_flags &= ~RES_F_CONN;
- errno = 0;
- }
-#endif /* !CANNOT_CONNECT_DGRAM */
- if (sendto(statp->_sock,
- (char*)buf, buflen, 0,
- (struct sockaddr *)nsap,
- sizeof *nsap)
- != buflen) {
- Aerror(statp, stderr, "sendto", errno, *nsap);
- badns |= (1 << ns);
- res_nclose(statp);
- goto next_ns;
- }
-#ifndef CANNOT_CONNECT_DGRAM
- }
-#endif /* !CANNOT_CONNECT_DGRAM */
-
- if (statp->_sock < 0 || statp->_sock > highestFD) {
- Perror(statp, stderr,
- "fd out-of-bounds", EMFILE);
- res_nclose(statp);
- goto next_ns;
- }
-
- /*
- * Wait for reply
- */
- seconds = (statp->retrans << try);
- if (try > 0)
- seconds /= statp->nscount;
- if (seconds <= 0)
- seconds = 1;
- start = evNowTime();
- timeout = evConsTime(seconds, 0);
- finish = evAddTime(start, timeout);
- wait:
- FD_ZERO(&dsmask);
- FD_SET(statp->_sock, &dsmask);
- n = pselect(statp->_sock + 1,
- &dsmask, NULL, NULL,
- &timeout, NULL);
- if (n == 0) {
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; timeout\n"));
- gotsomewhere = 1;
- goto next_ns;
- }
- if (n < 0) {
- if (errno == EINTR) {
- struct timespec now;
-
- now = evNowTime();
- if (evCmpTime(finish, now) >= 0) {
- timeout = evSubTime(finish,
- now);
- goto wait;
- }
- }
- Perror(statp, stderr, "select", errno);
- res_nclose(statp);
- goto next_ns;
- }
- errno = 0;
- fromlen = sizeof(struct sockaddr_in);
- resplen = recvfrom(statp->_sock, (char*)ans, anssiz,0,
- (struct sockaddr *)&from, &fromlen);
- if (resplen <= 0) {
- Perror(statp, stderr, "recvfrom", errno);
- res_nclose(statp);
- goto next_ns;
- }
- gotsomewhere = 1;
- if (resplen < HFIXEDSZ) {
- /*
- * Undersized message.
- */
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; undersized: %d\n",
- resplen));
- terrno = EMSGSIZE;
- badns |= (1 << ns);
- res_nclose(statp);
+ /* Use datagrams. */
+ n = send_dg(statp, buf, buflen, ans, anssiz, &terrno,
+ ns, &v_circuit, &gotsomewhere);
+ if (n < 0)
+ return (-1);
+ if (n == 0)
goto next_ns;
- }
- if (hp->id != anhp->id) {
- /*
- * response from old query, ignore it.
- * XXX - potential security hazard could
- * be detected here.
- */
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; old answer:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto wait;
- }
-#ifdef CHECK_SRVR_ADDR
- if (!(statp->options & RES_INSECURE1) &&
- !res_ourserver_p(statp, &from)) {
- /*
- * response from wrong server? ignore it.
- * XXX - potential security hazard could
- * be detected here.
- */
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; not our server:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto wait;
- }
-#endif
- if (!(statp->options & RES_INSECURE2) &&
- !res_queriesmatch(buf, buf + buflen,
- ans, ans + anssiz)) {
- /*
- * response contains wrong query? ignore it.
- * XXX - potential security hazard could
- * be detected here.
- */
- DprintQ((statp->options & RES_DEBUG) ||
- (statp->pfcode & RES_PRF_REPLY),
- (stdout, ";; wrong query name:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- goto wait;
- }
- if (anhp->rcode == SERVFAIL ||
- anhp->rcode == NOTIMP ||
- anhp->rcode == REFUSED) {
- DprintQ(statp->options & RES_DEBUG,
- (stdout, "server rejected query:\n"),
- ans, (resplen>anssiz)?anssiz:resplen);
- badns |= (1 << ns);
- res_nclose(statp);
- /* don't retry if called from dig */
- if (!statp->pfcode)
- goto next_ns;
- }
- if (!(statp->options & RES_IGNTC) && anhp->tc) {
- /*
- * get rest of answer;
- * use TCP with same server.
- */
- Dprint(statp->options & RES_DEBUG,
- (stdout, ";; truncated answer\n"));
- v_circuit = 1;
- res_nclose(statp);
+ if (v_circuit)
goto same_ns;
- }
- } /*if vc/dg*/
+ 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, ""),
- ans, (resplen>anssiz)?anssiz:resplen);
+ ans, (resplen > anssiz) ? anssiz : resplen);
+
/*
- * If using virtual circuits, we assume that the first server
- * is preferred over the rest (i.e. it is on the local
- * machine) and only keep that one open.
* If we have temporarily opened a virtual circuit,
* or if we haven't been asked to keep a socket open,
* close the socket.
*/
- if ((v_circuit && (!(statp->options & RES_USEVC) || ns != 0)) ||
- !(statp->options & RES_STAYOPEN)) {
+ if (v_circuit && (statp->options & RES_USEVC) == 0 ||
+ (statp->options & RES_STAYOPEN) == 0) {
res_nclose(statp);
}
if (statp->rhook) {
@@ -838,25 +442,391 @@ res_nsend(res_state statp,
return (-1);
}
-/*
- * This routine is for closing the socket if a virtual circuit is used and
- * the program wants to close it. This provides support for endhostent()
- * which expects to close the socket.
- *
- * This routine is not expected to be user visible.
- */
-void
-res_nclose(res_state statp) {
- if (statp->_sock >= 0) {
- (void) close(statp->_sock);
- statp->_sock = -1;
- statp->_flags &= ~(RES_F_VC | RES_F_CONN);
+/* Private */
+
+static int
+send_vc(res_state statp,
+ const u_char *buf, int buflen, u_char *ans, int anssiz,
+ int *terrno, int ns)
+{
+ const HEADER *hp = (HEADER *) buf;
+ HEADER *anhp = (HEADER *) ans;
+ struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+ int truncating, connreset, resplen, n;
+ struct iovec iov[2];
+ u_short len;
+ u_char *cp;
+
+ connreset = 0;
+ same_ns:
+ truncating = 0;
+
+ /* Are we still talking to whom we want to talk to? */
+ if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
+ struct sockaddr_in peer;
+ int size = sizeof peer;
+
+ if (getpeername(statp->_vcsock,
+ (struct sockaddr *)&peer, &size) < 0 ||
+ !sock_eq(&peer, nsap)) {
+ res_nclose(statp);
+ statp->_flags &= ~RES_F_VC;
+ }
}
+
+ if (statp->_vcsock < 0 || (statp->_flags & RES_F_VC) == 0) {
+ if (statp->_vcsock >= 0)
+ res_nclose(statp);
+
+ statp->_vcsock = socket(PF_INET, SOCK_STREAM, 0);
+ if (statp->_vcsock > highestFD) {
+ res_nclose(statp);
+ errno = ENOTSOCK;
+ }
+ if (statp->_vcsock < 0) {
+ *terrno = errno;
+ Perror(statp, stderr, "socket(vc)", errno);
+ return (-1);
+ }
+ errno = 0;
+ if (connect(statp->_vcsock, (struct sockaddr *)nsap,
+ sizeof *nsap) < 0) {
+ *terrno = errno;
+ Aerror(statp, stderr, "connect/vc", errno, *nsap);
+ res_nclose(statp);
+ return (0);
+ }
+ statp->_flags |= RES_F_VC;
+ }
+
+ /*
+ * Send length & message
+ */
+ putshort((u_short)buflen, (u_char*)&len);
+ iov[0] = evConsIovec(&len, INT16SZ);
+ iov[1] = evConsIovec((void*)buf, buflen);
+ if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
+ *terrno = errno;
+ Perror(statp, stderr, "write failed", errno);
+ res_nclose(statp);
+ return (0);
+ }
+ /*
+ * Receive length & response
+ */
+ read_len:
+ cp = ans;
+ len = INT16SZ;
+ while ((n = read(statp->_vcsock, (char *)cp, (int)len)) > 0) {
+ cp += n;
+ if ((len -= n) <= 0)
+ break;
+ }
+ if (n <= 0) {
+ *terrno = errno;
+ Perror(statp, stderr, "read failed", errno);
+ res_nclose(statp);
+ /*
+ * A long running process might get its TCP
+ * connection reset if the remote server was
+ * restarted. Requery the server instead of
+ * trying a new one. When there is only one
+ * server, this means that a query might work
+ * instead of failing. We only allow one reset
+ * per query to prevent looping.
+ */
+ if (*terrno == ECONNRESET && !connreset) {
+ connreset = 1;
+ res_nclose(statp);
+ goto same_ns;
+ }
+ res_nclose(statp);
+ return (0);
+ }
+ resplen = ns_get16(ans);
+ if (resplen > anssiz) {
+ Dprint(statp->options & RES_DEBUG,
+ (stdout, ";; response truncated\n")
+ );
+ truncating = 1;
+ len = anssiz;
+ } else
+ len = resplen;
+ if (len < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(statp->options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n", len));
+ *terrno = EMSGSIZE;
+ res_nclose(statp);
+ return (0);
+ }
+ cp = ans;
+ while (len != 0 && (n = read(statp->_vcsock, (char *)cp, (int)len)) > 0){
+ cp += n;
+ len -= n;
+ }
+ if (n <= 0) {
+ *terrno = errno;
+ Perror(statp, stderr, "read(vc)", errno);
+ res_nclose(statp);
+ return (0);
+ }
+ if (truncating) {
+ /*
+ * Flush rest of answer so connection stays in synch.
+ */
+ anhp->tc = 1;
+ len = resplen - anssiz;
+ while (len != 0) {
+ char junk[PACKETSZ];
+
+ n = read(statp->_vcsock, junk,
+ (len > sizeof junk) ? sizeof junk : len);
+ if (n > 0)
+ len -= n;
+ else
+ break;
+ }
+ }
+ /*
+ * If the calling applicating has bailed out of
+ * a previous call and failed to arrange to have
+ * the circuit closed or the server has got
+ * itself confused, then drop the packet and
+ * wait for the correct one.
+ */
+ if (hp->id != anhp->id) {
+ DprintQ((statp->options & RES_DEBUG) ||
+ (statp->pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer (unexpected):\n"),
+ ans, (resplen > anssiz) ? anssiz: resplen);
+ goto read_len;
+ }
+
+ /*
+ * All is well, or the error is fatal. Signal that the
+ * next nameserver ought not be tried.
+ */
+ return (resplen);
+}
+
+static int
+send_dg(res_state statp,
+ const u_char *buf, int buflen, u_char *ans, int anssiz,
+ int *terrno, int ns, int *v_circuit, int *gotsomewhere)
+{
+ const HEADER *hp = (HEADER *) buf;
+ HEADER *anhp = (HEADER *) ans;
+ const struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+ struct timespec now, timeout, finish;
+ fd_set dsmask;
+ struct sockaddr_in from;
+ int fromlen, resplen, seconds, n, s;
+
+ if (EXT(statp).nssocks[ns] == -1) {
+ EXT(statp).nssocks[ns] = socket(PF_INET, SOCK_DGRAM, 0);
+ if (EXT(statp).nssocks[ns] > highestFD) {
+ res_nclose(statp);
+ errno = ENOTSOCK;
+ }
+ if (EXT(statp).nssocks[ns] < 0) {
+ *terrno = errno;
+ Perror(statp, stderr, "socket(dg)", errno);
+ return (-1);
+ }
+#ifndef CANNOT_CONNECT_DGRAM
+ /*
+ * On a 4.3BSD+ machine (client and server,
+ * actually), sending to a nameserver datagram
+ * port with no nameserver will cause an
+ * ICMP port unreachable message to be returned.
+ * If our datagram socket is "connected" to the
+ * server, we get an ECONNREFUSED error on the next
+ * socket operation, and select returns if the
+ * error message is received. We can thus detect
+ * the absence of a nameserver without timing out.
+ */
+ if (connect(EXT(statp).nssocks[ns], (struct sockaddr *)nsap,
+ sizeof *nsap) < 0) {
+ Aerror(statp, stderr, "connect(dg)", errno, *nsap);
+ res_nclose(statp);
+ return (0);
+ }
+#endif /* !CANNOT_CONNECT_DGRAM */
+ Dprint(statp->options & RES_DEBUG,
+ (stdout, ";; new DG socket\n"))
+ }
+ s = EXT(statp).nssocks[ns];
+#ifndef CANNOT_CONNECT_DGRAM
+ if (send(s, (char*)buf, buflen, 0) != buflen) {
+ Perror(statp, stderr, "send", errno);
+ res_nclose(statp);
+ return (0);
+ }
+#else /* !CANNOT_CONNECT_DGRAM */
+ if (sendto(s, (char*)buf, buflen, 0,
+ (struct sockaddr *)nsap, sizeof *nsap) != buflen)
+ {
+ Aerror(statp, stderr, "sendto", errno, *nsap);
+ res_nclose(statp);
+ return (0);
+ }
+#endif /* !CANNOT_CONNECT_DGRAM */
+
+ /*
+ * Wait for reply.
+ */
+ seconds = (statp->retrans << ns);
+ if (ns > 0)
+ seconds /= statp->nscount;
+ if (seconds <= 0)
+ seconds = 1;
+ now = evNowTime();
+ timeout = evConsTime(seconds, 0);
+ finish = evAddTime(now, timeout);
+ wait:
+ FD_ZERO(&dsmask);
+ FD_SET(s, &dsmask);
+ n = pselect(s + 1, &dsmask, NULL, NULL, &timeout, NULL);
+ if (n == 0) {
+ Dprint(statp->options & RES_DEBUG, (stdout, ";; timeout\n"));
+ *gotsomewhere = 1;
+ return (0);
+ }
+ if (n < 0) {
+ if (errno == EINTR) {
+ now = evNowTime();
+ if (evCmpTime(finish, now) > 0) {
+ timeout = evSubTime(finish, now);
+ goto wait;
+ }
+ }
+ Perror(statp, stderr, "select", errno);
+ res_nclose(statp);
+ return (0);
+ }
+ errno = 0;
+ fromlen = sizeof(struct sockaddr_in);
+ resplen = recvfrom(s, (char*)ans, anssiz,0,
+ (struct sockaddr *)&from, &fromlen);
+ if (resplen <= 0) {
+ Perror(statp, stderr, "recvfrom", errno);
+ res_nclose(statp);
+ return (0);
+ }
+ *gotsomewhere = 1;
+ if (resplen < HFIXEDSZ) {
+ /*
+ * Undersized message.
+ */
+ Dprint(statp->options & RES_DEBUG,
+ (stdout, ";; undersized: %d\n",
+ resplen));
+ *terrno = EMSGSIZE;
+ res_nclose(statp);
+ return (0);
+ }
+ if (hp->id != anhp->id) {
+ /*
+ * response from old query, ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((statp->options & RES_DEBUG) ||
+ (statp->pfcode & RES_PRF_REPLY),
+ (stdout, ";; old answer:\n"),
+ ans, (resplen > anssiz) ? anssiz : resplen);
+ goto wait;
+ }
+ if (!(statp->options & RES_INSECURE1) &&
+ !res_ourserver_p(statp, &from)) {
+ /*
+ * response from wrong server? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((statp->options & RES_DEBUG) ||
+ (statp->pfcode & RES_PRF_REPLY),
+ (stdout, ";; not our server:\n"),
+ ans, (resplen > anssiz) ? anssiz : resplen);
+ goto wait;
+ }
+ if (!(statp->options & RES_INSECURE2) &&
+ !res_queriesmatch(buf, buf + buflen,
+ ans, ans + anssiz)) {
+ /*
+ * response contains wrong query? ignore it.
+ * XXX - potential security hazard could
+ * be detected here.
+ */
+ DprintQ((statp->options & RES_DEBUG) ||
+ (statp->pfcode & RES_PRF_REPLY),
+ (stdout, ";; wrong query name:\n"),
+ ans, (resplen > anssiz) ? anssiz : resplen);
+ goto wait;
+ }
+ if (anhp->rcode == SERVFAIL ||
+ anhp->rcode == NOTIMP ||
+ anhp->rcode == REFUSED) {
+ DprintQ(statp->options & RES_DEBUG,
+ (stdout, "server rejected query:\n"),
+ ans, (resplen > anssiz) ? anssiz : resplen);
+ res_nclose(statp);
+ /* don't retry if called from dig */
+ if (!statp->pfcode)
+ return (0);
+ }
+ 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_nclose(statp);
+ return (1);
+ }
+ /*
+ * All is well, or the error is fatal. Signal that the
+ * next nameserver ought not be tried.
+ */
+ return (resplen);
+}
+
+static void
+Aerror(const res_state statp, FILE *file, const char *string, int error,
+ struct sockaddr_in address)
+{
+ int save = errno;
+
+ if ((statp->options & RES_DEBUG) != 0) {
+ char tmp[sizeof "255.255.255.255"];
+
+ fprintf(file, "res_send: %s ([%s].%u): %s\n",
+ string,
+ inet_ntop(address.sin_family, &address.sin_addr,
+ tmp, sizeof tmp),
+ ntohs(address.sin_port),
+ strerror(error));
+ }
+ 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));
+ errno = save;
}
-/* Private */
static int
-cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2) {
+sock_eq(struct sockaddr_in *a1, struct sockaddr_in *a2) {
return ((a1->sin_family == a2->sin_family) &&
(a1->sin_port == a2->sin_port) &&
(a1->sin_addr.s_addr == a2->sin_addr.s_addr));
@@ -866,8 +836,7 @@ cmpsock(struct sockaddr_in *a1, struct sockaddr_in *a2) {
/* XXX needs to move to the porting library. */
static int
pselect(int nfds, void *rfds, void *wfds, void *efds,
- struct timespec *tsp,
- const sigset_t *sigmask)
+ struct timespec *tsp, const sigset_t *sigmask)
{
struct timeval tv, *tvp;
sigset_t sigs;
OpenPOWER on IntegriCloud