diff options
author | asmodai <asmodai@FreeBSD.org> | 2000-05-26 07:17:19 +0000 |
---|---|---|
committer | asmodai <asmodai@FreeBSD.org> | 2000-05-26 07:17:19 +0000 |
commit | 3f83b2963e3f1302f6507d3968aa3bfc93d7472d (patch) | |
tree | 58c578d1f5a84acb9535b8fc95abe2637662f30f /contrib/bind/lib | |
parent | 08dfda8209739c209911999e8c76d369945766ed (diff) | |
download | FreeBSD-src-3f83b2963e3f1302f6507d3968aa3bfc93d7472d.zip FreeBSD-src-3f83b2963e3f1302f6507d3968aa3bfc93d7472d.tar.gz |
Virgin import of BIND v8.2.3-T5B
Diffstat (limited to 'contrib/bind/lib')
37 files changed, 896 insertions, 711 deletions
diff --git a/contrib/bind/lib/Makefile b/contrib/bind/lib/Makefile index 18fa7c8..15aa655 100644 --- a/contrib/bind/lib/Makefile +++ b/contrib/bind/lib/Makefile @@ -15,7 +15,7 @@ # $Id: Makefile,v 8.22 1999/06/08 01:42:57 vixie Exp $ -SUBDIRS = resolv irs isc bsd inet nameser dst +SUBDIRS = resolv irs isc bsd inet nameser dst cylink dnssafe # 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 diff --git a/contrib/bind/lib/dst/Makefile b/contrib/bind/lib/dst/Makefile index f99813c..28befe8 100644 --- a/contrib/bind/lib/dst/Makefile +++ b/contrib/bind/lib/dst/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 1.13 1999/03/07 09:33:47 vixie Exp $ +# $Id: Makefile,v 1.16 2000/02/29 03:38:21 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 @@ -50,8 +50,8 @@ OBJS= dst_api.${O} prandom.${O} rsaref_link.${O} support.${O} \ bsafe_link.${O} cylink_link.${O} hmac_link.${O} md5_dgst.${O} \ eay_dss_link.${O} -CRYPTINCL= -CRYPTFLAGS= -DHMAC_MD5 -DUSE_MD5 +CRYPTINCL= -I../cylink -I../dnssafe +CRYPTFLAGS= -DCYLINK_DSS -DHMAC_MD5 -DUSE_MD5 -DDNSSAFE all: ${LIBBIND} @@ -63,13 +63,14 @@ ${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} ${CRYPTINCL} ${CRYPTFLAGS} -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} ${CRYPTINCL} ${CRYPTFLAGS} -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} $(SRCS):: $(HDRS) @@ -80,7 +81,7 @@ clean: FRC rm -f *.${O} *.BAK *.CKP *~ rm -f prand_conf.h 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/dst/dst_api.c b/contrib/bind/lib/dst/dst_api.c index 6dde481..f25438e 100644 --- a/contrib/bind/lib/dst/dst_api.c +++ b/contrib/bind/lib/dst/dst_api.c @@ -1,5 +1,5 @@ #ifndef LINT -static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/dst_api.c,v 1.13 1999/10/13 16:39:22 vixie Exp $"; +static const char rcsid[] = "$Header: /proj/cvs/isc/bind/src/lib/dst/dst_api.c,v 1.14 2000/02/28 07:51:50 vixie Exp $"; #endif /* @@ -334,7 +334,7 @@ dst_read_key(const char *in_keyname, const u_int16_t in_id, in_alg)); return (NULL); } - if ((type && (DST_PUBLIC | DST_PRIVATE)) == 0) + if ((type & (DST_PUBLIC | DST_PRIVATE)) == 0) return (NULL); if (in_keyname == NULL) { EREPORT(("dst_read_private_key(): Null key name passed in\n")); diff --git a/contrib/bind/lib/inet/Makefile b/contrib/bind/lib/inet/Makefile index 04c4c1f..b007412 100644 --- a/contrib/bind/lib/inet/Makefile +++ b/contrib/bind/lib/inet/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.16 1999/03/03 08:07:16 vixie Exp $ +# $Id: Makefile,v 8.19 2000/02/29 03:38:22 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 @@ -61,14 +61,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 @@ -76,7 +77,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 diff --git a/contrib/bind/lib/irs/Makefile b/contrib/bind/lib/irs/Makefile index 3421b8b..2c50e62 100644 --- a/contrib/bind/lib/irs/Makefile +++ b/contrib/bind/lib/irs/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.16 1999/02/22 02:47:58 vixie Exp $ +# $Id: Makefile,v 8.19 2000/02/29 03:38:22 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 @@ -82,14 +82,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} && \ - ${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 @@ -97,7 +98,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/irs/dns.c b/contrib/bind/lib/irs/dns.c index 7ba7eec..66bdbf5 100644 --- a/contrib/bind/lib/irs/dns.c +++ b/contrib/bind/lib/irs/dns.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns.c,v 1.14 1999/01/18 07:46:47 vixie Exp $"; +static const char rcsid[] = "$Id: dns.c,v 1.15 2000/02/28 07:52:16 vixie Exp $"; #endif /* @@ -116,7 +116,7 @@ dns_res_get(struct irs_acc *this) { dns_res_set(this, res, free); } - if ((dns->res->options | RES_INIT) == 0 && + if ((dns->res->options & RES_INIT) == 0 && res_ninit(dns->res) < 0) return (NULL); diff --git a/contrib/bind/lib/irs/dns_ho.c b/contrib/bind/lib/irs/dns_ho.c index e319f96..8b2df77 100644 --- a/contrib/bind/lib/irs/dns_ho.c +++ b/contrib/bind/lib/irs/dns_ho.c @@ -52,7 +52,7 @@ /* BIND Id: gethnamaddr.c,v 8.15 1996/05/22 04:56:30 vixie Exp $ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_ho.c,v 1.26 1999/10/15 19:49:09 vixie Exp $"; +static const char rcsid[] = "$Id: dns_ho.c,v 1.28 2000/04/20 07:47:54 vixie Exp $"; #endif /* LIBC_SCCS and not lint */ /* Imports. */ @@ -394,7 +394,7 @@ gethostans(struct irs_ho *this, const HEADER *hp; const u_char *eom; const u_char *cp; - const char *tname; + const char *tname, **tap; char *bp, **ap, **hap; char tbuf[MAXDNAME+1]; @@ -583,9 +583,9 @@ gethostans(struct irs_ho *this, bp += nn; buflen -= nn; } - + /* Ensure alignment. */ bp += sizeof(align) - ((u_long)bp % sizeof(align)); - + /* Avoid overflows. */ if (bp + n >= &pvt->hostbuf[sizeof pvt->hostbuf]) { had_error++; continue; @@ -594,7 +594,19 @@ gethostans(struct irs_ho *this, cp += n; continue; } + /* Suppress duplicates. */ + for (tap = (const char **)pvt->h_addr_ptrs; + *tap != NULL; + tap++) + if (memcmp(*tap, cp, n) == 0) + break; + if (*tap != NULL) { + cp += n; + continue; + } + /* Store address. */ memcpy(*hap++ = bp, cp, n); + *hap = NULL; bp += n; cp += n; break; @@ -606,7 +618,6 @@ gethostans(struct irs_ho *this, } if (haveanswer) { *ap = NULL; - *hap = NULL; if (pvt->res->nsort && haveanswer > 1 && qtype == T_A) addrsort(pvt->res, pvt->h_addr_ptrs, haveanswer); diff --git a/contrib/bind/lib/irs/dns_sv.c b/contrib/bind/lib/irs/dns_sv.c index ea0ba70..e6cb2df 100644 --- a/contrib/bind/lib/irs/dns_sv.c +++ b/contrib/bind/lib/irs/dns_sv.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: dns_sv.c,v 1.17 1999/09/04 22:06:14 vixie Exp $"; +static const char rcsid[] = "$Id: dns_sv.c,v 1.19 2000/03/30 22:53:56 vixie Exp $"; #endif /* Imports */ @@ -105,8 +105,8 @@ irs_dns_sv(struct irs_acc *this) { sv->rewind = sv_rewind; sv->close = sv_close; sv->minimize = sv_minimize; - sv->res_get = sv_res_get; - sv->res_set = sv_res_set; + sv->res_get = NULL; /* sv_res_get; */ + sv->res_set = NULL; /* sv_res_set; */ return (sv); } @@ -150,7 +150,7 @@ sv_byport(struct irs_sv *this, int port, const char *proto) { char portstr[16]; char **hes_list; - sprintf(portstr, "%d", port); + sprintf(portstr, "%d", ntohs(port)); if (!(hes_list = hesiod_resolve(dns->hes_ctx, portstr, "port"))) return (NULL); @@ -193,12 +193,13 @@ parse_hes_list(struct irs_sv *this, char **hes_list, const char *proto) { p++; if (!*p) continue; - proto_len = strlen(proto); - if (strncasecmp(++p, proto, proto_len) != 0) - continue; - if (p[proto_len] && !isspace(p[proto_len])) - continue; - + if (proto) { + proto_len = strlen(proto); + if (strncasecmp(++p, proto, proto_len) != 0) + continue; + if (p[proto_len] && !isspace(p[proto_len])) + continue; + } /* OK, we've got a live one. Let's parse it for real. */ if (pvt->svbuf) free(pvt->svbuf); diff --git a/contrib/bind/lib/irs/gethostent.c b/contrib/bind/lib/irs/gethostent.c index ac66520..5d316c8 100644 --- a/contrib/bind/lib/irs/gethostent.c +++ b/contrib/bind/lib/irs/gethostent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: gethostent.c,v 1.25 1999/10/19 22:27:20 cyarnell Exp $"; +static const char rcsid[] = "$Id: gethostent.c,v 1.27 2000/04/20 07:10:33 vixie Exp $"; #endif /* Imports */ @@ -461,8 +461,32 @@ freehostent(struct hostent *he) { static int scan_interfaces(int *have_v4, int *have_v6) { - struct ifconf ifc; - struct ifreq ifreq; +#ifndef SIOCGLIFCONF +/* map new to old */ +#define SIOCGLIFCONF SIOCGIFCONF +#define lifc_len ifc_len +#define lifc_buf ifc_buf + struct ifconf lifc; +#else +#define SETFAMILYFLAGS + struct lifconf lifc; +#endif + +#ifndef SIOCGLIFADDR +/* map new to old */ +#define SIOCGLIFADDR SIOCGIFADDR +#endif + +#ifndef SIOCGLIFFLAGS +#define SIOCGLIFFLAGS SIOCGIFFLAGS +#define lifr_addr ifr_addr +#define lifr_name ifr_name +#define lifr_flags ifr_flags +#define ss_family sa_family + struct ifreq lifreq; +#else + struct lifreq lifreq; +#endif struct in_addr in4; struct in6_addr in6; char *buf = NULL, *cp, *cplim; @@ -484,27 +508,31 @@ scan_interfaces(int *have_v4, int *have_v6) { buf = memget(bufsiz); if (buf == NULL) goto err_ret; - ifc.ifc_len = bufsiz; - ifc.ifc_buf = buf; +#ifdef SETFAMILYFLAGS + lifc.lifc_family = AF_UNSPEC; + lifc.lifc_flags = 0; +#endif + lifc.lifc_len = bufsiz; + lifc.lifc_buf = buf; #ifdef IRIX_EMUL_IOCTL_SIOCGIFCONF /* * This is a fix for IRIX OS in which the call to ioctl with * the flag SIOCGIFCONF may not return an entry for all the * interfaces like most flavors of Unix. */ - if (emul_ioctl(&ifc) >= 0) + if (emul_ioctl(&lifc) >= 0) break; #else - if ((n = ioctl(s, SIOCGIFCONF, (char *)&ifc)) != -1) { + if ((n = ioctl(s, SIOCGLIFCONF, (char *)&lifc)) != -1) { /* * Some OS's just return what will fit rather * than set EINVAL if the buffer is too small * to fit all the interfaces in. If - * ifc.ifc_len is too near to the end of the + * lifc.lifc_len is too near to the end of the * buffer we will grow it just in case and * retry. */ - if (ifc.ifc_len + 2 * sizeof(ifreq) < bufsiz) + if (lifc.lifc_len + 2 * sizeof(lifreq) < bufsiz) break; } #endif @@ -519,44 +547,45 @@ scan_interfaces(int *have_v4, int *have_v6) { } /* Parse system's interface list. */ - cplim = buf + ifc.ifc_len; /* skip over if's with big ifr_addr's */ + cplim = buf + lifc.lifc_len; /* skip over if's with big ifr_addr's */ for (cp = buf; (*have_v4 == 0 || *have_v6 == 0) && cp < cplim; cp += cpsize) { - memcpy(&ifreq, cp, sizeof ifreq); + memcpy(&lifreq, cp, sizeof lifreq); #ifdef HAVE_SA_LEN #ifdef FIX_ZERO_SA_LEN - if (ifreq.ifr_addr.sa_len == 0) - ifreq.ifr_addr.sa_len = 16; + if (lifreq.lifr_addr.sa_len == 0) + lifreq.lifr_addr.sa_len = 16; #endif #ifdef HAVE_MINIMUM_IFREQ - cpsize = sizeof ifreq; - if (ifreq.ifr_addr.sa_len > sizeof (struct sockaddr)) - cpsize += (int)ifreq.ifr_addr.sa_len - + cpsize = sizeof lifreq; + if (lifreq.lifr_addr.sa_len > sizeof (struct sockaddr)) + cpsize += (int)lifreq.lifr_addr.sa_len - (int)(sizeof (struct sockaddr)); #else - cpsize = sizeof ifreq.ifr_name + ifreq.ifr_addr.sa_len; + cpsize = sizeof lifreq.lifr_name + lifreq.lifr_addr.sa_len; #endif /* HAVE_MINIMUM_IFREQ */ #elif defined SIOCGIFCONF_ADDR - cpsize = sizeof ifreq; + cpsize = sizeof lifreq; #else - cpsize = sizeof ifreq.ifr_name; + cpsize = sizeof lifreq.lifr_name; /* XXX maybe this should be a hard error? */ - if (ioctl(s, SIOCGIFADDR, (char *)&ifreq) < 0) + if (ioctl(s, SOICGLIFADDR, (char *)&lifreq) < 0) continue; #endif - switch (ifreq.ifr_addr.sa_family) { + switch (lifreq.lifr_addr.ss_family) { case AF_INET: if (*have_v4 == 0) { memcpy(&in4, &((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr, sizeof in4); + &lifreq.lifr_addr)->sin_addr, + sizeof in4); if (in4.s_addr == INADDR_ANY) break; - n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq); + n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq); if (n < 0) break; - if ((ifreq.ifr_flags & IFF_UP) == 0) + if ((lifreq.lifr_flags & IFF_UP) == 0) break; *have_v4 = 1; } @@ -565,13 +594,13 @@ scan_interfaces(int *have_v4, int *have_v6) { if (*have_v6 == 0) { memcpy(&in6, &((struct sockaddr_in6 *) - &ifreq.ifr_addr)->sin6_addr, sizeof in6); + &lifreq.lifr_addr)->sin6_addr, sizeof in6); if (memcmp(&in6, &in6addr_any, sizeof in6) == 0) break; - n = ioctl(s, SIOCGIFFLAGS, (char *)&ifreq); + n = ioctl(s, SIOCGLIFFLAGS, (char *)&lifreq); if (n < 0) break; - if ((ifreq.ifr_flags & IFF_UP) == 0) + if ((lifreq.lifr_flags & IFF_UP) == 0) break; *have_v6 = 1; } @@ -581,12 +610,14 @@ scan_interfaces(int *have_v4, int *have_v6) { if (buf != NULL) memput(buf, bufsiz); close(s); + /* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */ return (0); err_ret: if (buf != NULL) memput(buf, bufsiz); if (s != -1) close(s); + /* printf("scan interface -> 4=%d 6=%d\n", *have_v4, *have_v6); */ return (-1); } diff --git a/contrib/bind/lib/irs/getnameinfo.c b/contrib/bind/lib/irs/getnameinfo.c index 3157c66..7bd30ae 100644 --- a/contrib/bind/lib/irs/getnameinfo.c +++ b/contrib/bind/lib/irs/getnameinfo.c @@ -110,7 +110,6 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) #endif int family, i; char *addr, *p; - u_long v4a; u_char pfx; static int firsttime = 1; static char numserv[512]; @@ -182,15 +181,11 @@ getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) switch (sa->sa_family) { case AF_INET: - v4a = ((struct sockaddr_in *)sa)->sin_addr.s_addr; - if (IN_MULTICAST(v4a) || IN_EXPERIMENTAL(v4a)) - flags |= NI_NUMERICHOST; - v4a >>= IN_CLASSA_NSHIFT; - if (v4a == 0 || v4a == IN_LOOPBACKNET) + if (ntohl(*(u_long *)addr) >> IN_CLASSA_NSHIFT == 0) flags |= NI_NUMERICHOST; break; case AF_INET6: - pfx = ((struct sockaddr_in6 *)sa)->sin6_addr.s6_addr[0]; + pfx = *addr; if (pfx == 0 || pfx == 0xfe || pfx == 0xff) flags |= NI_NUMERICHOST; break; diff --git a/contrib/bind/lib/irs/getpwent.c b/contrib/bind/lib/irs/getpwent.c index 94f2df5..7f536a4 100644 --- a/contrib/bind/lib/irs/getpwent.c +++ b/contrib/bind/lib/irs/getpwent.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: getpwent.c,v 1.20 1999/10/13 16:39:31 vixie Exp $"; +static const char rcsid[] = "$Id: getpwent.c,v 1.21 2000/02/21 21:40:56 vixie Exp $"; #endif /* Imports */ @@ -97,7 +97,7 @@ void endpwent() { struct net_data *net_data = init(); - return (endpwent_p(net_data)); + endpwent_p(net_data); } /* Shared private. */ diff --git a/contrib/bind/lib/irs/hesiod.c b/contrib/bind/lib/irs/hesiod.c index 54a6657..40826eb 100644 --- a/contrib/bind/lib/irs/hesiod.c +++ b/contrib/bind/lib/irs/hesiod.c @@ -1,5 +1,5 @@ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: hesiod.c,v 1.20 1999/02/22 04:09:06 vixie Exp $"; +static const char rcsid[] = "$Id: hesiod.c,v 1.21 2000/02/28 14:51:08 vixie Exp $"; #endif /* @@ -85,6 +85,7 @@ hesiod_init(void **context) { ctx->LHS = NULL; ctx->RHS = NULL; + ctx->res = NULL; if (parse_config_file(ctx, _PATH_HESIOD_CONF) < 0) { #ifdef DEF_RHS diff --git a/contrib/bind/lib/irs/irp.c b/contrib/bind/lib/irs/irp.c index c2b64ab..a6c8f4f 100644 --- a/contrib/bind/lib/irs/irp.c +++ b/contrib/bind/lib/irs/irp.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: irp.c,v 8.5 1999/10/13 17:11:18 vixie Exp $"; +static const char rcsid[] = "$Id: irp.c,v 8.6 2000/02/04 08:28:33 vixie Exp $"; #endif /* Imports */ @@ -151,7 +151,9 @@ irs_irp_connect(struct irp_p *pvt) { int flags; struct sockaddr *addr; struct sockaddr_in iaddr; +#ifndef NO_SOCKADDR_UN struct sockaddr_un uaddr; +#endif long ipaddr; const char *irphost; int code; @@ -163,7 +165,9 @@ irs_irp_connect(struct irp_p *pvt) { return (-1); } +#ifndef NO_SOCKADDR_UN memset(&uaddr, 0, sizeof uaddr); +#endif memset(&iaddr, 0, sizeof iaddr); irphost = getenv(IRPD_HOST_ENV); @@ -171,6 +175,7 @@ irs_irp_connect(struct irp_p *pvt) { irphost = "127.0.0.1"; } +#ifndef NO_SOCKADDR_UN if (irphost[0] == '/') { addr = (struct sockaddr *)&uaddr; strncpy(uaddr.sun_path, irphost, sizeof uaddr.sun_path); @@ -179,7 +184,9 @@ irs_irp_connect(struct irp_p *pvt) { #ifdef HAVE_SA_LEN uaddr.sun_len = socklen; #endif - } else { + } else +#endif + { if (inet_pton(AF_INET, irphost, &ipaddr) != 1) { errno = EADDRNOTAVAIL; perror("inet_pton"); diff --git a/contrib/bind/lib/irs/lcl.c b/contrib/bind/lib/irs/lcl.c index 46c7743..16e167f 100644 --- a/contrib/bind/lib/irs/lcl.c +++ b/contrib/bind/lib/irs/lcl.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: lcl.c,v 1.15 1999/10/13 16:39:32 vixie Exp $"; +static const char rcsid[] = "$Id: lcl.c,v 1.16 2000/02/28 07:52:16 vixie Exp $"; #endif /* Imports */ @@ -104,7 +104,7 @@ lcl_res_get(struct irs_acc *this) { lcl_res_set(this, res, free); } - if ((lcl->res->options | RES_INIT) == 0 && + if ((lcl->res->options & RES_INIT) == 0 && res_ninit(lcl->res) < 0) return (NULL); diff --git a/contrib/bind/lib/irs/nis.c b/contrib/bind/lib/irs/nis.c index fcd9b79..e19068a 100644 --- a/contrib/bind/lib/irs/nis.c +++ b/contrib/bind/lib/irs/nis.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: nis.c,v 1.13 1999/01/18 07:46:58 vixie Exp $"; +static const char rcsid[] = "$Id: nis.c,v 1.14 2000/02/28 07:52:16 vixie Exp $"; #endif /* Imports */ @@ -114,7 +114,7 @@ nis_res_get(struct irs_acc *this) { nis_res_set(this, res, free); } - if ((nis->res->options | RES_INIT) == 0 && + if ((nis->res->options & RES_INIT) == 0 && res_ninit(nis->res) < 0) return (NULL); diff --git a/contrib/bind/lib/irs/util.c b/contrib/bind/lib/irs/util.c index 8965af5..1d097c6 100644 --- a/contrib/bind/lib/irs/util.c +++ b/contrib/bind/lib/irs/util.c @@ -16,7 +16,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static const char rcsid[] = "$Id: util.c,v 1.10 1999/01/08 19:25:11 vixie Exp $"; +static const char rcsid[] = "$Id: util.c,v 1.11 2000/02/04 08:28:33 vixie Exp $"; #endif #include "port_before.h" @@ -48,18 +48,18 @@ static const char rcsid[] = "$Id: util.c,v 1.10 1999/01/08 19:25:11 vixie Exp $" void map_v4v6_address(const char *src, char *dst) { u_char *p = (u_char *)dst; - char tmp[INADDRSZ]; + char tmp[NS_INADDRSZ]; int i; /* Stash a temporary copy so our caller can update in place. */ - memcpy(tmp, src, INADDRSZ); + memcpy(tmp, src, NS_INADDRSZ); /* Mark this ipv6 addr as a mapped ipv4. */ for (i = 0; i < 10; i++) *p++ = 0x00; *p++ = 0xff; *p++ = 0xff; /* Retrieve the saved copy and we're done. */ - memcpy((void*)p, tmp, INADDRSZ); + memcpy((void*)p, tmp, NS_INADDRSZ); } int diff --git a/contrib/bind/lib/isc/Makefile b/contrib/bind/lib/isc/Makefile index 87e20f2..364c442 100644 --- a/contrib/bind/lib/isc/Makefile +++ b/contrib/bind/lib/isc/Makefile @@ -13,7 +13,7 @@ # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS # SOFTWARE. -# $Id: Makefile,v 8.22 1999/02/22 02:47:58 vixie Exp $ +# $Id: Makefile,v 8.25 2000/02/29 03:38:23 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 @@ -64,14 +64,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 @@ -79,7 +80,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/isc/ctl_p.c b/contrib/bind/lib/isc/ctl_p.c index d70a05f..7d9058c 100644 --- a/contrib/bind/lib/isc/ctl_p.c +++ b/contrib/bind/lib/isc/ctl_p.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ctl_p.c,v 8.6 1999/10/13 16:39:34 vixie Exp $"; +static const char rcsid[] = "$Id: ctl_p.c,v 8.7 2000/02/04 08:28:33 vixie Exp $"; #endif /* not lint */ /* @@ -125,6 +125,7 @@ ctl_sa_ntop(const struct sockaddr *sa, (void) sprintf(buf, "[%s].%u", tmp, ntohs(in->sin_port)); return (buf); } +#ifndef NO_SOCKADDR_UN case AF_UNIX: { const struct sockaddr_un *un = (struct sockaddr_un *) sa; int x = sizeof un->sun_path; @@ -135,6 +136,7 @@ ctl_sa_ntop(const struct sockaddr *sa, buf[x - 1] = '\0'; return (buf); } +#endif default: return (punt); } @@ -146,9 +148,11 @@ ctl_sa_copy(const struct sockaddr *src, struct sockaddr *dst) { case AF_INET: *((struct sockaddr_in *)dst) = *((struct sockaddr_in *)src); break; +#ifndef NO_SOCKADDR_UN case AF_UNIX: *((struct sockaddr_un *)dst) = *((struct sockaddr_un *)src); break; +#endif default: *dst = *src; break; diff --git a/contrib/bind/lib/isc/ctl_srvr.c b/contrib/bind/lib/isc/ctl_srvr.c index 0bdc8c8..ff1fc82 100644 --- a/contrib/bind/lib/isc/ctl_srvr.c +++ b/contrib/bind/lib/isc/ctl_srvr.c @@ -1,5 +1,5 @@ #if !defined(lint) && !defined(SABER) -static const char rcsid[] = "$Id: ctl_srvr.c,v 8.21 1999/10/17 08:41:57 cyarnell Exp $"; +static const char rcsid[] = "$Id: ctl_srvr.c,v 8.23 2000/02/04 08:28:33 vixie Exp $"; #endif /* not lint */ /* @@ -73,7 +73,9 @@ enum state { union sa_un { struct sockaddr_in in; +#ifndef NO_SOCKADDR_UN struct sockaddr_un un; +#endif }; struct ctl_sess { @@ -229,8 +231,12 @@ ctl_server(evContext lev, const struct sockaddr *sap, size_t sap_len, me, strerror(errno)); } if (bind(ctx->sock, sap, sap_len) < 0) { + char tmp[MAX_NTOP]; save_errno = errno; - (*ctx->logger)(ctl_error, "%s: bind: %s", me, strerror(errno)); + (*ctx->logger)(ctl_error, "%s: bind: %s: %s", + me, ctl_sa_ntop((struct sockaddr *)sap, + tmp, sizeof tmp, ctx->logger), + strerror(save_errno)); close(ctx->sock); memput(ctx, sizeof *ctx); errno = save_errno; @@ -561,7 +567,8 @@ ctl_readable(evContext lev, void *uap, int fd, int evmask) { ctl_close(sess); return; } - n = read(sess->sock, sess->inbuf.text, MAX_LINELEN - sess->inbuf.used); + n = read(sess->sock, sess->inbuf.text + sess->inbuf.used, + MAX_LINELEN - sess->inbuf.used); if (n <= 0) { (*ctx->logger)(ctl_debug, "%s: %s: read: %s", me, address_expr, diff --git a/contrib/bind/lib/isc/ev_connects.c b/contrib/bind/lib/isc/ev_connects.c index 237bcb1..1da5c10 100644 --- a/contrib/bind/lib/isc/ev_connects.c +++ b/contrib/bind/lib/isc/ev_connects.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_connects.c,v 8.25 1999/10/07 20:44:04 vixie Exp $"; +static const char rcsid[] = "$Id: ev_connects.c,v 8.26 2000/02/04 08:28:34 vixie Exp $"; #endif /* Import. */ @@ -235,7 +235,7 @@ evTryAccept(evContext opaqueCtx, evConnID id, int *sys_errno) { OKNEW(new); new->conn = conn; new->ralen = sizeof new->ra; - new->fd = accept(conn->fd, &new->ra, &new->ralen); + new->fd = accept(conn->fd, &new->ra.sa, &new->ralen); if (new->fd > ctx->highestFD) { close(new->fd); new->fd = -1; @@ -243,7 +243,7 @@ evTryAccept(evContext opaqueCtx, evConnID id, int *sys_errno) { } if (new->fd >= 0) { new->lalen = sizeof new->la; - if (GETXXXNAME(getsockname, new->fd, new->la, new->lalen) < 0) { + if (GETXXXNAME(getsockname, new->fd, new->la.sa, new->lalen) < 0) { new->ioErrno = errno; (void) close(new->fd); new->fd = -1; @@ -267,12 +267,18 @@ static void listener(evContext opaqueCtx, void *uap, int fd, int evmask) { evContext_p *ctx = opaqueCtx.opaque; evConn *conn = uap; - struct sockaddr la, ra; - int new, lalen, ralen; + union { + struct sockaddr sa; + struct sockaddr_in in; +#ifndef NO_SOCKADDR_UN + struct sockaddr_un un; +#endif + } la, ra; + int new, lalen = 0, ralen; REQUIRE((evmask & EV_READ) != 0); ralen = sizeof ra; - new = accept(fd, &ra, &ralen); + new = accept(fd, &ra.sa, &ralen); if (new > ctx->highestFD) { close(new); new = -1; @@ -280,7 +286,7 @@ listener(evContext opaqueCtx, void *uap, int fd, int evmask) { } if (new >= 0) { lalen = sizeof la; - if (GETXXXNAME(getsockname, new, la, lalen) < 0) { + if (GETXXXNAME(getsockname, new, la.sa, lalen) < 0) { int save = errno; (void) close(new); @@ -289,13 +295,19 @@ listener(evContext opaqueCtx, void *uap, int fd, int evmask) { } } else if (errno == EAGAIN || errno == EWOULDBLOCK) return; - (*conn->func)(opaqueCtx, conn->uap, new, &la, lalen, &ra, ralen); + (*conn->func)(opaqueCtx, conn->uap, new, &la.sa, lalen, &ra.sa, ralen); } static void connector(evContext opaqueCtx, void *uap, int fd, int evmask) { evConn *conn = uap; - struct sockaddr la, ra; + union { + struct sockaddr sa; + struct sockaddr_in in; +#ifndef NO_SOCKADDR_UN + struct sockaddr_un un; +#endif + } la, ra; int lalen, ralen; char buf[1]; void *conn_uap; @@ -325,13 +337,13 @@ connector(evContext opaqueCtx, void *uap, int fd, int evmask) { #else read(fd, buf, 0) < 0 || #endif - GETXXXNAME(getsockname, fd, la, lalen) < 0 || - GETXXXNAME(getpeername, fd, ra, ralen) < 0) { + GETXXXNAME(getsockname, fd, la.sa, lalen) < 0 || + GETXXXNAME(getpeername, fd, ra.sa, ralen) < 0) { int save = errno; (void) close(fd); /* XXX closing caller's fd */ errno = save; fd = -1; } - (*conn_func)(opaqueCtx, conn_uap, fd, &la, lalen, &ra, ralen); + (*conn_func)(opaqueCtx, conn_uap, fd, &la.sa, lalen, &ra.sa, ralen); } diff --git a/contrib/bind/lib/isc/ev_waits.c b/contrib/bind/lib/isc/ev_waits.c index c336dcb..e7bfbf7 100644 --- a/contrib/bind/lib/isc/ev_waits.c +++ b/contrib/bind/lib/isc/ev_waits.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: ev_waits.c,v 8.9 1999/10/13 17:11:20 vixie Exp $"; +static const char rcsid[] = "$Id: ev_waits.c,v 8.10 2000/02/04 07:25:50 vixie Exp $"; #endif #include "port_before.h" @@ -212,6 +212,8 @@ evNewWaitList(evContext_p *ctx) { new->first = new->last = NULL; new->prev = NULL; new->next = ctx->waitLists; + if (new->next != NULL) + new->next->prev = new; ctx->waitLists = new; return (new); } diff --git a/contrib/bind/lib/isc/eventlib.c b/contrib/bind/lib/isc/eventlib.c index 6cb227b..cea98ac 100644 --- a/contrib/bind/lib/isc/eventlib.c +++ b/contrib/bind/lib/isc/eventlib.c @@ -20,7 +20,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: eventlib.c,v 1.44 1999/10/13 17:11:20 vixie Exp $"; +static const char rcsid[] = "$Id: eventlib.c,v 1.45 2000/02/04 07:25:39 vixie Exp $"; #endif #include "port_before.h" @@ -345,7 +345,8 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) { } ERR(pselect_errno); } - if (x == 0 && (nextTimer && !timerPast) && (options & EV_POLL)) + if (x == 0 && (nextTimer == NULL || !timerPast) && + (options & EV_POLL)) ERR(EWOULDBLOCK); ctx->fdCount = x; #ifdef EVENTLIB_TIME_CHECKS diff --git a/contrib/bind/lib/isc/eventlib_p.h b/contrib/bind/lib/isc/eventlib_p.h index 80dc160..b4d7ecc 100644 --- a/contrib/bind/lib/isc/eventlib_p.h +++ b/contrib/bind/lib/isc/eventlib_p.h @@ -18,7 +18,7 @@ /* eventlib_p.h - private interfaces for eventlib * vix 09sep95 [initial] * - * $Id: eventlib_p.h,v 1.27 1999/06/03 20:36:05 vixie Exp $ + * $Id: eventlib_p.h,v 1.28 2000/02/04 08:28:34 vixie Exp $ */ #ifndef _EVENTLIB_P_H @@ -27,6 +27,8 @@ #include <sys/param.h> #include <sys/types.h> #include <sys/socket.h> +#include <netinet/in.h> +#include <sys/un.h> #define EVENTLIB_DEBUG 1 @@ -76,9 +78,21 @@ typedef struct evConn { typedef struct evAccept { int fd; - struct sockaddr la; + union { + struct sockaddr sa; + struct sockaddr_in in; +#ifndef NO_SOCKADDR_UN + struct sockaddr_un un; +#endif + } la; int lalen; - struct sockaddr ra; + union { + struct sockaddr sa; + struct sockaddr_in in; +#ifndef NO_SOCKADDR_UN + struct sockaddr_un un; +#endif + } ra; int ralen; int ioErrno; evConn * conn; diff --git a/contrib/bind/lib/isc/logging.c b/contrib/bind/lib/isc/logging.c index a3988e4..7d6964b 100644 --- a/contrib/bind/lib/isc/logging.c +++ b/contrib/bind/lib/isc/logging.c @@ -16,7 +16,7 @@ */ #if !defined(LINT) && !defined(CODECENTER) -static const char rcsid[] = "$Id: logging.c,v 8.24 1999/10/13 16:39:34 vixie Exp $"; +static const char rcsid[] = "$Id: logging.c,v 8.26 2000/04/23 02:19:02 vixie Exp $"; #endif /* not lint */ #include "port_before.h" @@ -127,7 +127,7 @@ log_open_stream(log_channel chan) { flags = O_WRONLY|O_CREAT|O_APPEND; - if (chan->flags & LOG_TRUNCATE) { + if ((chan->flags & LOG_TRUNCATE) != 0) { if (regular) { (void)unlink(chan->out.file.name); flags |= O_EXCL; @@ -155,6 +155,7 @@ log_open_stream(log_channel chan) { chan->flags |= LOG_CHANNEL_BROKEN; return (NULL); } + (void) fchown(fd, chan->out.file.owner, chan->out.file.group); chan->out.file.stream = stream; return (stream); @@ -617,10 +618,23 @@ log_new_file_channel(unsigned int flags, int level, chan->out.file.stream = stream; chan->out.file.versions = versions; chan->out.file.max_size = max_size; + chan->out.file.owner = getuid(); + chan->out.file.group = getgid(); chan->references = 0; return (chan); } +int +log_set_file_owner(log_channel chan, uid_t owner, gid_t group) { + if (chan->type != log_file) { + errno = EBADF; + return (-1); + } + chan->out.file.owner = owner; + chan->out.file.group = group; + return (0); +} + log_channel log_new_null_channel() { log_channel chan; diff --git a/contrib/bind/lib/isc/logging.mdoc b/contrib/bind/lib/isc/logging.mdoc index 6b48943..47d4312 100644 --- a/contrib/bind/lib/isc/logging.mdoc +++ b/contrib/bind/lib/isc/logging.mdoc @@ -1,4 +1,4 @@ -.\" $Id: logging.mdoc,v 8.3 1999/01/08 19:25:41 vixie Exp $ +.\" $Id: logging.mdoc,v 8.4 2000/04/23 02:19:02 vixie Exp $ .\" .\"Copyright (c) 1995-1999 by Internet Software Consortium .\" @@ -36,6 +36,7 @@ .Nm log_category_is_active , .Nm log_new_syslog_channel , .Nm log_new_file_channel , +.Nm log_set_file_owner , .Nm log_new_null_channel , .Nm log_inc_references , .Nm log_dec_references , @@ -80,6 +81,8 @@ .Fn log_new_file_channel "unsigned int flags" "int level" \ "char *name" "FILE *stream" "unsigned int versions" \ "unsigned long max_size" +.Ft int +.Fn log_set_file_owner "log_channel chan" "uid_t owner" "gid_t group" .Ft log_channel .Fn log_new_null_channel "void" .Ft int @@ -187,7 +190,12 @@ filename. The and .Fn log_get_filename functions return the stream or filename, respectively, of such a logging -channel. +channel. Also unique to logging channels of type +.Dv log_file +is the +.Fn log_set_file_owner +function, which tells the logging system what user and group ought to own +newly created files (which is only effective if the caller is privileged.) .Pp Callers provide .Dq Nm categories , diff --git a/contrib/bind/lib/isc/logging_p.h b/contrib/bind/lib/isc/logging_p.h index e94102e..875da0e 100644 --- a/contrib/bind/lib/isc/logging_p.h +++ b/contrib/bind/lib/isc/logging_p.h @@ -24,6 +24,8 @@ typedef struct log_file_desc { FILE *stream; unsigned int versions; unsigned long max_size; + uid_t owner; + gid_t group; } log_file_desc; typedef union log_output { diff --git a/contrib/bind/lib/nameser/Makefile b/contrib/bind/lib/nameser/Makefile index 52a102f..ed068b1 100644 --- a/contrib/bind/lib/nameser/Makefile +++ b/contrib/bind/lib/nameser/Makefile @@ -15,7 +15,7 @@ # SOFTWARE. # -# $Id: Makefile,v 8.16 1999/09/07 08:47:28 vixie Exp $ +# $Id: Makefile,v 8.19 2000/02/29 03:38:23 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 @@ -59,14 +59,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 @@ -74,7 +75,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/nameser/ns_name.c b/contrib/bind/lib/nameser/ns_name.c index 6bd668d..2424eed 100644 --- a/contrib/bind/lib/nameser/ns_name.c +++ b/contrib/bind/lib/nameser/ns_name.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_name.c,v 8.12 1999/10/13 17:11:23 vixie Exp $"; +static const char rcsid[] = "$Id: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie Exp $"; #endif #include "port_before.h" @@ -379,7 +379,7 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, u_char *dstp; const u_char **cpp, **lpp, *eob, *msg; const u_char *srcp; - int n, l; + int n, l, first = 1; srcp = src; dstp = dst; @@ -428,9 +428,10 @@ ns_name_pack(const u_char *src, u_char *dst, int dstsiz, } /* Not found, save it. */ if (lastdnptr != NULL && cpp < lastdnptr - 1 && - (dstp - msg) < 0x4000) { + (dstp - msg) < 0x4000 && first) { *cpp++ = dstp; *cpp = NULL; + first = 0; } } /* copy label to buffer */ @@ -503,6 +504,23 @@ ns_name_compress(const char *src, u_char *dst, size_t dstsiz, } /* + * Reset dnptrs so that there are no active references to pointers at or + * after src. + */ +void +ns_name_rollback(const u_char *src, const u_char **dnptrs, + const u_char **lastdnptr) +{ + while (dnptrs < lastdnptr && *dnptrs != NULL) { + if (*dnptrs >= src) { + *dnptrs = NULL; + break; + } + dnptrs++; + } +} + +/* * ns_name_skip(ptrptr, eom) * Advance *ptrptr to skip over the compressed name it points at. * return: @@ -604,36 +622,48 @@ dn_find(const u_char *domain, const u_char *msg, u_int n; for (cpp = dnptrs; cpp < lastdnptr; cpp++) { - dn = domain; - sp = cp = *cpp; - while ((n = *cp++) != 0) { - /* - * check for indirection - */ - switch (n & NS_CMPRSFLGS) { - case 0: /* normal case, n == len */ - if (n != *dn++) - goto next; - for ((void)NULL; n > 0; n--) - if (mklower(*dn++) != mklower(*cp++)) + sp = *cpp; + /* + * terminate search on: + * root label + * compression pointer + * unusable offset + */ + while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 && + (sp - msg) < 0x4000) { + dn = domain; + cp = sp; + while ((n = *cp++) != 0) { + /* + * check for indirection + */ + switch (n & NS_CMPRSFLGS) { + case 0: /* normal case, n == len */ + if (n != *dn++) goto next; - /* Is next root for both ? */ - if (*dn == '\0' && *cp == '\0') - return (sp - msg); - if (*dn) - continue; - goto next; - - case NS_CMPRSFLGS: /* indirection */ - cp = msg + (((n & 0x3f) << 8) | *cp); - break; - - default: /* illegal type */ - errno = EMSGSIZE; - return (-1); + for ((void)NULL; n > 0; n--) + if (mklower(*dn++) != + mklower(*cp++)) + goto next; + /* Is next root for both ? */ + if (*dn == '\0' && *cp == '\0') + return (sp - msg); + if (*dn) + continue; + goto next; + + case NS_CMPRSFLGS: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + break; + + default: /* illegal type */ + errno = EMSGSIZE; + return (-1); + } } + next: + sp += *sp + 1; } - next: ; } errno = ENOENT; return (-1); diff --git a/contrib/bind/lib/nameser/ns_print.c b/contrib/bind/lib/nameser/ns_print.c index 93f1e91..6c47882 100644 --- a/contrib/bind/lib/nameser/ns_print.c +++ b/contrib/bind/lib/nameser/ns_print.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_print.c,v 8.17 1999/10/19 02:06:54 gson Exp $"; +static const char rcsid[] = "$Id: ns_print.c,v 8.18 2000/02/29 05:48:12 vixie Exp $"; #endif /* Import. */ @@ -127,9 +127,10 @@ ns_sprintrrf(const u_char *msg, size_t msglen, T(addstr("@\t\t\t", 4, &buf, &buflen)); } else { T(addstr(name, len, &buf, &buflen)); - /* Origin not used and no trailing dot? */ - if ((!origin || !origin[0] || name[len] == '\0') && - name[len - 1] != '.') { + /* Origin not used or not root, and no trailing dot? */ + if (((origin == NULL || origin[0] == '\0') || + (origin[0] != '.' && origin[1] != '\0' && + name[len] == '\0')) && name[len - 1] != '.') { T(addstr(".", 1, &buf, &buflen)); len++; } @@ -751,20 +752,22 @@ addname(const u_char *msg, size_t msglen, if (n < 0) goto enospc; /* Guess. */ newlen = prune_origin(*buf, origin); - if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') && - (newlen == 0 || (*buf)[newlen - 1] != '.')) { - /* No trailing dot. */ - if (newlen + 2 > *buflen) - goto enospc; /* No room for ".\0". */ - (*buf)[newlen++] = '.'; - (*buf)[newlen] = '\0'; - } if (newlen == 0) { /* Use "@" instead of name. */ if (newlen + 2 > *buflen) goto enospc; /* No room for "@\0". */ (*buf)[newlen++] = '@'; (*buf)[newlen] = '\0'; + } else { + if (((origin == NULL || origin[0] == '\0') || + (origin[0] != '.' && origin[1] != '\0' && + (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') { + /* No trailing dot. */ + if (newlen + 2 > *buflen) + goto enospc; /* No room for ".\0". */ + (*buf)[newlen++] = '.'; + (*buf)[newlen] = '\0'; + } } *pp += n; addlen(newlen, buf, buflen); diff --git a/contrib/bind/lib/nameser/ns_verify.c b/contrib/bind/lib/nameser/ns_verify.c index 316da13..0f19913 100644 --- a/contrib/bind/lib/nameser/ns_verify.c +++ b/contrib/bind/lib/nameser/ns_verify.c @@ -16,7 +16,7 @@ */ #ifndef lint -static const char rcsid[] = "$Id: ns_verify.c,v 8.11 1999/10/15 21:06:51 vixie Exp $"; +static const char rcsid[] = "$Id: ns_verify.c,v 8.13 2000/03/29 15:55:00 bwelling Exp $"; #endif /* Import. */ @@ -231,6 +231,7 @@ ns_verify(u_char *msg, int *msglen, void *k, if (key != NULL && error != ns_r_badsig && error != ns_r_badkey) { void *ctx; u_char buf[MAXDNAME]; + u_char buf2[MAXDNAME]; /* Digest the query signature, if this is a response. */ dst_verify_data(SIG_MODE_INIT, key, &ctx, NULL, 0, NULL, 0); @@ -247,7 +248,12 @@ ns_verify(u_char *msg, int *msglen, void *k, NULL, 0); /* Digest the key name. */ - n = ns_name_ntol(recstart, buf, sizeof(buf)); + n = ns_name_pton(name, buf2, sizeof(buf2)); + if (n < 0) + return (-1); + n = ns_name_ntol(buf2, buf, sizeof(buf)); + if (n < 0) + return (-1); dst_verify_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0); /* Digest the class and TTL. */ @@ -256,7 +262,12 @@ ns_verify(u_char *msg, int *msglen, void *k, INT16SZ + INT32SZ, NULL, 0); /* Digest the algorithm. */ - n = ns_name_ntol(rdatastart, buf, sizeof(buf)); + n = ns_name_pton(alg, buf2, sizeof(buf2)); + if (n < 0) + return (-1); + n = ns_name_ntol(buf2, buf, sizeof(buf)); + if (n < 0) + return (-1); dst_verify_data(SIG_MODE_UPDATE, key, &ctx, buf, n, NULL, 0); /* Digest the time signed and fudge. */ @@ -450,9 +461,6 @@ ns_verify_tcp(u_char *msg, int *msglen, ns_tcp_tsig_state *state, return (-ns_r_badsig); if (sigfieldlen > sizeof(state->sig)) - return (ns_r_badsig); - - if (sigfieldlen > sizeof(state->sig)) return (NS_TSIG_ERROR_NO_SPACE); memcpy(state->sig, sigstart, sigfieldlen); 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; |