summaryrefslogtreecommitdiffstats
path: root/contrib/bind/lib/resolv
diff options
context:
space:
mode:
authornectar <nectar@FreeBSD.org>2002-02-04 19:12:46 +0000
committernectar <nectar@FreeBSD.org>2002-02-04 19:12:46 +0000
commitebeabb1ba32f14e308ae9aff9a2a7151265259cf (patch)
tree71ba64d0a82be4894e23f6d65f36b61203ec3875 /contrib/bind/lib/resolv
parent1385a0dca8f9199ece158336f4c6a9f1e2e03c3e (diff)
downloadFreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.zip
FreeBSD-src-ebeabb1ba32f14e308ae9aff9a2a7151265259cf.tar.gz
Import of ISC BIND 8.3.1-REL.
Diffstat (limited to 'contrib/bind/lib/resolv')
-rw-r--r--contrib/bind/lib/resolv/Makefile4
-rw-r--r--contrib/bind/lib/resolv/herror.c18
-rw-r--r--contrib/bind/lib/resolv/res_debug.c206
-rw-r--r--contrib/bind/lib/resolv/res_findzonecut.c12
-rw-r--r--contrib/bind/lib/resolv/res_init.c237
-rw-r--r--contrib/bind/lib/resolv/res_mkquery.c63
-rw-r--r--contrib/bind/lib/resolv/res_mkupdate.c10
-rw-r--r--contrib/bind/lib/resolv/res_private.h20
-rw-r--r--contrib/bind/lib/resolv/res_query.c38
-rw-r--r--contrib/bind/lib/resolv/res_send.c285
-rw-r--r--contrib/bind/lib/resolv/res_update.c54
11 files changed, 751 insertions, 196 deletions
diff --git a/contrib/bind/lib/resolv/Makefile b/contrib/bind/lib/resolv/Makefile
index bfb49ec..3f98a20 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.35 2000/12/23 08:03:03 vixie Exp $
+# $Id: Makefile,v 8.36 2001/08/14 05:58:11 marka 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
@@ -63,7 +63,7 @@ ${LIBBIND}: ${OBJS}
${RANLIB} ${LIBBIND}
.c.${O}:
- if test ! -d ${THREADED} ; then mkdir ${THREADED} ; else true ; fi
+ mkdir ${THREADED} 2> /dev/null || test -d ${THREADED} -a -w ${THREADED}
${CC} ${CPPFLAGS} ${CFLAGS} ${BOUNDS} ${REENTRANT} -c $*.c \
-o ${THREADED}/$*.${O}
-${LDS} ${LD} ${LD_LIBFLAGS} ${THREADED}/$*.${O} \
diff --git a/contrib/bind/lib/resolv/herror.c b/contrib/bind/lib/resolv/herror.c
index bf4cce6..8265597 100644
--- a/contrib/bind/lib/resolv/herror.c
+++ b/contrib/bind/lib/resolv/herror.c
@@ -50,7 +50,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: herror.c,v 8.11 1999/10/13 16:39:39 vixie Exp $";
+static const char rcsid[] = "$Id: herror.c,v 8.13 2001/06/18 14:44:06 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -89,20 +89,24 @@ int h_errno;
void
herror(const char *s) {
struct iovec iov[4], *v = iov;
- extern int * __h_errno();
+ char *t;
if (s != NULL && *s != '\0') {
- v->iov_base = (/*noconst*/ char *)s;
- v->iov_len = strlen(s);
+ DE_CONST(s, t);
+ v->iov_base = t;
+ v->iov_len = strlen(t);
v++;
- v->iov_base = ": ";
+ DE_CONST(": ", t);
+ v->iov_base = t;
v->iov_len = 2;
v++;
}
- v->iov_base = (char *)hstrerror(*__h_errno());
+ DE_CONST(hstrerror(*__h_errno()), t);
+ v->iov_base = t;
v->iov_len = strlen(v->iov_base);
v++;
- v->iov_base = "\n";
+ DE_CONST("\n", t);
+ v->iov_base = t;
v->iov_len = 1;
writev(STDERR_FILENO, iov, (v - iov) + 1);
}
diff --git a/contrib/bind/lib/resolv/res_debug.c b/contrib/bind/lib/resolv/res_debug.c
index cff6473..9b61e11 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.38 2001/02/13 23:12:56 marka Exp $";
+static const char rcsid[] = "$Id: res_debug.c,v 8.45 2001/12/19 12:05:56 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -187,7 +187,12 @@ do_section(const res_state statp,
ns_rr_name(rr),
p_type(ns_rr_type(rr)),
p_class(ns_rr_class(rr)));
- else {
+ else if (section == ns_s_ar && ns_rr_type(rr) == ns_t_opt) {
+ u_int32_t ttl = ns_rr_ttl(rr);
+ fprintf(file,
+ "; EDNS: version: %u, udp=%u, flags=%04x\n",
+ (ttl>>16)&0xff, ns_rr_class(rr), ttl&0xffff);
+ } else {
n = ns_sprintrr(handle, &rr, NULL, NULL,
buf, buflen);
if (n < 0) {
@@ -356,32 +361,32 @@ p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
* C_ANY, but you can't have any records of that class in the database.)
*/
const struct res_sym __p_class_syms[] = {
- {C_IN, "IN"},
- {C_CHAOS, "CHAOS"},
- {C_HS, "HS"},
- {C_HS, "HESIOD"},
- {C_ANY, "ANY"},
- {C_NONE, "NONE"},
- {C_IN, (char *)0}
+ {C_IN, "IN", (char *)0},
+ {C_CHAOS, "CHAOS", (char *)0},
+ {C_HS, "HS", (char *)0},
+ {C_HS, "HESIOD", (char *)0},
+ {C_ANY, "ANY", (char *)0},
+ {C_NONE, "NONE", (char *)0},
+ {C_IN, (char *)0, (char *)0}
};
/*
* Names of message sections.
*/
const struct res_sym __p_default_section_syms[] = {
- {ns_s_qd, "QUERY"},
- {ns_s_an, "ANSWER"},
- {ns_s_ns, "AUTHORITY"},
- {ns_s_ar, "ADDITIONAL"},
- {0, (char *)0}
+ {ns_s_qd, "QUERY", (char *)0},
+ {ns_s_an, "ANSWER", (char *)0},
+ {ns_s_ns, "AUTHORITY", (char *)0},
+ {ns_s_ar, "ADDITIONAL", (char *)0},
+ {0, (char *)0, (char *)0}
};
const struct res_sym __p_update_section_syms[] = {
- {S_ZONE, "ZONE"},
- {S_PREREQ, "PREREQUISITE"},
- {S_UPDATE, "UPDATE"},
- {S_ADDT, "ADDITIONAL"},
- {0, (char *)0}
+ {S_ZONE, "ZONE", (char *)0},
+ {S_PREREQ, "PREREQUISITE", (char *)0},
+ {S_UPDATE, "UPDATE", (char *)0},
+ {S_ADDT, "ADDITIONAL", (char *)0},
+ {0, (char *)0, (char *)0}
};
const struct res_sym __p_key_syms[] = {
@@ -536,7 +541,17 @@ sym_ntop(const struct res_sym *syms, int number, int *success) {
*/
const char *
p_type(int type) {
- return (sym_ntos(__p_type_syms, type, (int *)0));
+ int success;
+ const char *result;
+ static char typebuf[20];
+
+ result = sym_ntos(__p_type_syms, type, &success);
+ if (success)
+ return (result);
+ if (type < 0 || type > 0xfff)
+ return ("BADTYPE");
+ sprintf(typebuf, "TYPE%d", type);
+ return (typebuf);
}
/*
@@ -562,7 +577,17 @@ p_section(int section, int opcode) {
*/
const char *
p_class(int class) {
- return (sym_ntos(__p_class_syms, class, (int *)0));
+ int success;
+ const char *result;
+ static char classbuf[20];
+
+ result = sym_ntos(__p_class_syms, class, &success);
+ if (success)
+ return (result);
+ if (class < 0 || class > 0xfff)
+ return ("BADCLASS");
+ sprintf(classbuf, "CLASS%d", class);
+ return (classbuf);
}
/*
@@ -585,6 +610,24 @@ p_option(u_long option) {
case RES_DNSRCH: return "dnsrch";
case RES_INSECURE1: return "insecure1";
case RES_INSECURE2: return "insecure2";
+ case RES_NOALIASES: return "noaliases";
+ case RES_USE_INET6: return "inet6";
+#ifdef RES_USE_EDNS0 /* KAME extension */
+ case RES_USE_EDNS0: return "edns0";
+#endif
+#ifdef RES_USE_A6
+ case RES_USE_A6: return "a6";
+#endif
+#ifdef RES_USE_DNAME
+ case RES_USE_DNAME: return "dname";
+#endif
+#ifdef RES_USE_DNSSEC
+ case RES_USE_DNSSEC: return "dnssec";
+#endif
+#ifdef RES_NOTLDQUERY
+ case RES_NOTLDQUERY: return "no-tld-query";
+#endif
+
/* XXX nonreentrant */
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
return (nbuf);
@@ -651,14 +694,14 @@ precsize_aton(strptr)
cp = *strptr;
- while (isdigit(*cp))
+ while (isdigit((unsigned char)*cp))
mval = mval * 10 + (*cp++ - '0');
if (*cp == '.') { /* centimeters */
cp++;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char)*cp)) {
cmval = (*cp++ - '0') * 10;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char)*cp)) {
cmval += (*cp++ - '0');
}
}
@@ -692,44 +735,44 @@ latlon2ul(latlonstrptr,which)
cp = *latlonstrptr;
- while (isdigit(*cp))
+ while (isdigit((unsigned char)*cp))
deg = deg * 10 + (*cp++ - '0');
- while (isspace(*cp))
+ while (isspace((unsigned char)*cp))
cp++;
- if (!(isdigit(*cp)))
+ if (!(isdigit((unsigned char)*cp)))
goto fndhemi;
- while (isdigit(*cp))
+ while (isdigit((unsigned char)*cp))
min = min * 10 + (*cp++ - '0');
- while (isspace(*cp))
+ while (isspace((unsigned char)*cp))
cp++;
- if (!(isdigit(*cp)))
+ if (!(isdigit((unsigned char)*cp)))
goto fndhemi;
- while (isdigit(*cp))
+ while (isdigit((unsigned char)*cp))
secs = secs * 10 + (*cp++ - '0');
if (*cp == '.') { /* decimal seconds */
cp++;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char)*cp)) {
secsfrac = (*cp++ - '0') * 100;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char)*cp)) {
secsfrac += (*cp++ - '0') * 10;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char)*cp)) {
secsfrac += (*cp++ - '0');
}
}
}
}
- while (!isspace(*cp)) /* if any trailing garbage */
+ while (!isspace((unsigned char)*cp)) /* if any trailing garbage */
cp++;
- while (isspace(*cp))
+ while (isspace((unsigned char)*cp))
cp++;
fndhemi:
@@ -767,10 +810,10 @@ latlon2ul(latlonstrptr,which)
cp++; /* skip the hemisphere */
- while (!isspace(*cp)) /* if any trailing garbage */
+ while (!isspace((unsigned char)*cp)) /* if any trailing garbage */
cp++;
- while (isspace(*cp)) /* move to next field */
+ while (isspace((unsigned char)*cp)) /* move to next field */
cp++;
*latlonstrptr = cp;
@@ -828,14 +871,14 @@ loc_aton(ascii, binary)
if (*cp == '+')
cp++;
- while (isdigit(*cp))
+ while (isdigit((unsigned char)*cp))
altmeters = altmeters * 10 + (*cp++ - '0');
if (*cp == '.') { /* decimal meters */
cp++;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char)*cp)) {
altfrac = (*cp++ - '0') * 10;
- if (isdigit(*cp)) {
+ if (isdigit((unsigned char)*cp)) {
altfrac += (*cp++ - '0');
}
}
@@ -843,10 +886,10 @@ loc_aton(ascii, binary)
alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
- while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
cp++;
- while (isspace(*cp) && (cp < maxcp))
+ while (isspace((unsigned char)*cp) && (cp < maxcp))
cp++;
if (cp >= maxcp)
@@ -854,10 +897,10 @@ loc_aton(ascii, binary)
siz = precsize_aton(&cp);
- while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
cp++;
- while (isspace(*cp) && (cp < maxcp))
+ while (isspace((unsigned char)*cp) && (cp < maxcp))
cp++;
if (cp >= maxcp)
@@ -865,10 +908,10 @@ loc_aton(ascii, binary)
hp = precsize_aton(&cp);
- while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
+ while (!isspace((unsigned char)*cp) && (cp < maxcp)) /* if trailing garbage or m */
cp++;
- while (isspace(*cp) && (cp < maxcp))
+ while (isspace((unsigned char)*cp) && (cp < maxcp))
cp++;
if (cp >= maxcp)
@@ -896,14 +939,15 @@ loc_ntoa(binary, ascii)
const u_char *binary;
char *ascii;
{
- static char *error = "?";
+ static const char *error = "?";
static char tmpbuf[sizeof
"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
const u_char *cp = binary;
int latdeg, latmin, latsec, latsecfrac;
int longdeg, longmin, longsec, longsecfrac;
- char northsouth, eastwest, *altsign;
+ char northsouth, eastwest;
+ const char *altsign;
int altmeters, altfrac;
const u_int32_t referencealt = 100000 * 100;
@@ -975,24 +1019,24 @@ loc_ntoa(binary, ascii)
altfrac = altval % 100;
altmeters = (altval / 100);
- if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
- sizestr = error;
- if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
- hpstr = error;
- if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
- vpstr = error;
+ sizestr = strdup(precsize_ntoa(sizeval));
+ hpstr = strdup(precsize_ntoa(hpval));
+ vpstr = strdup(precsize_ntoa(vpval));
sprintf(ascii,
"%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %s%d.%.2dm %sm %sm %sm",
latdeg, latmin, latsec, latsecfrac, northsouth,
longdeg, longmin, longsec, longsecfrac, eastwest,
- altsign, altmeters, altfrac, sizestr, hpstr, vpstr);
+ altsign, altmeters, altfrac,
+ (sizestr != NULL) ? sizestr : error,
+ (hpstr != NULL) ? hpstr : error,
+ (vpstr != NULL) ? vpstr : error);
- if (sizestr != error)
+ if (sizestr != NULL)
free(sizestr);
- if (hpstr != error)
+ if (hpstr != NULL)
free(hpstr);
- if (vpstr != error)
+ if (vpstr != NULL)
free(vpstr);
return (ascii);
@@ -1048,3 +1092,47 @@ p_secstodate (u_long secs) {
time->tm_hour, time->tm_min, time->tm_sec);
return (output);
}
+
+u_int16_t
+res_nametoclass(const char *buf, int *successp) {
+ unsigned long result;
+ char *endptr;
+ int success;
+
+ result = sym_ston(__p_class_syms, buf, &success);
+ if (success)
+ goto done;
+
+ if (strncasecmp(buf, "CLASS", 5) != 0 ||
+ !isdigit((unsigned char)buf[5]))
+ goto done;
+ result = strtoul(buf + 5, &endptr, 10);
+ if (*endptr == '\0' && result <= 0xffff)
+ success = 1;
+ done:
+ if (successp)
+ *successp = success;
+ return (result);
+}
+
+u_int16_t
+res_nametotype(const char *buf, int *successp) {
+ unsigned long result;
+ char *endptr;
+ int success;
+
+ result = sym_ston(__p_type_syms, buf, &success);
+ if (success)
+ goto done;
+
+ if (strncasecmp(buf, "type", 4) != 0 ||
+ !isdigit((unsigned char)buf[4]))
+ goto done;
+ result = strtoul(buf + 4, &endptr, 10);
+ if (*endptr == '\0' && result <= 0xffff)
+ success = 1;
+ done:
+ if (successp)
+ *successp = success;
+ return (result);
+}
diff --git a/contrib/bind/lib/resolv/res_findzonecut.c b/contrib/bind/lib/resolv/res_findzonecut.c
index 2e8df2c..02a28da 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.12 2000/11/22 01:20:44 marka Exp $";
+static const char rcsid[] = "$Id: res_findzonecut.c,v 8.15 2001/11/01 05:21:22 marka Exp $";
#endif /* not lint */
/*
@@ -78,13 +78,13 @@ static void free_nsrr(rrset_ns *, rr_ns *);
static rr_ns * find_ns(rrset_ns *, const char *);
static int do_query(res_state, const char *, ns_class, ns_type,
u_char *, ns_msg *);
-static void dprintf(const char *, ...);
+static void res_dprintf(const char *, ...) ISC_FORMAT_PRINTF(1, 2);
/* Macros. */
#define DPRINTF(x) do {\
int save_errno = errno; \
- if ((statp->options & RES_DEBUG) != 0) dprintf x; \
+ if ((statp->options & RES_DEBUG) != 0) res_dprintf x; \
errno = save_errno; \
} while (0)
@@ -527,12 +527,14 @@ free_nsrrset(rrset_ns *nsrrsp) {
static void
free_nsrr(rrset_ns *nsrrsp, rr_ns *nsrr) {
rr_a *arr;
+ char *tmp;
while ((arr = HEAD(nsrr->addrs)) != NULL) {
UNLINK(nsrr->addrs, arr, link);
free(arr);
}
- free((char *)nsrr->name);
+ DE_CONST(nsrr->name, tmp);
+ free(tmp);
UNLINK(*nsrrsp, nsrr, link);
free(nsrr);
}
@@ -590,7 +592,7 @@ do_query(res_state statp, const char *dname, ns_class class, ns_type qtype,
}
static void
-dprintf(const char *fmt, ...) {
+res_dprintf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
diff --git a/contrib/bind/lib/resolv/res_init.c b/contrib/bind/lib/resolv/res_init.c
index 8c63351..8dc72f4 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.19 2001/03/08 03:57:16 marka Exp $";
+static const char rcsid[] = "$Id: res_init.c,v 8.28 2002/01/30 01:07:35 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -85,14 +85,19 @@ static const char rcsid[] = "$Id: res_init.c,v 8.19 2001/03/08 03:57:16 marka Ex
#include <arpa/nameser.h>
#include <ctype.h>
-#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <netdb.h>
#include "port_after.h"
+/* ensure that sockaddr_in6 and IN6ADDR_ANY_INIT are declared / defined */
+#include <resolv.h>
+
+#include "res_private.h"
+
/* Options. Should all be left alone. */
#define RESOLVSORT
#define DEBUG
@@ -164,6 +169,9 @@ __res_vinit(res_state statp, int preinit) {
statp->id = res_randomid();
}
+ if ((statp->options & RES_INIT) != 0)
+ res_ndestroy(statp);
+
#ifdef USELOOPBACK
statp->nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
#else
@@ -171,6 +179,9 @@ __res_vinit(res_state statp, int preinit) {
#endif
statp->nsaddr.sin_family = AF_INET;
statp->nsaddr.sin_port = htons(NAMESERVER_PORT);
+#ifdef HAVE_SA_LEN
+ statp->nsaddr.sin_len = sizeof(struct sockaddr_in);
+#endif
statp->nscount = 1;
statp->ndots = 1;
statp->pfcode = 0;
@@ -179,6 +190,13 @@ __res_vinit(res_state statp, int preinit) {
statp->qhook = NULL;
statp->rhook = NULL;
statp->_u._ext.nscount = 0;
+ statp->_u._ext.ext = malloc(sizeof(*statp->_u._ext.ext));
+ if (statp->_u._ext.ext != NULL) {
+ memset(statp->_u._ext.ext, 0, sizeof(*statp->_u._ext.ext));
+ statp->_u._ext.ext->nsaddrs[0].sin = statp->nsaddr;
+ strcpy(statp->_u._ext.ext->nsuffix, "ip6.int");
+ strcpy(statp->_u._ext.ext->bsuffix, "ip6.arpa");
+ }
#ifdef RESOLVSORT
statp->nsort = 0;
#endif
@@ -284,17 +302,36 @@ __res_vinit(res_state statp, int preinit) {
}
/* read nameservers to query */
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
- struct in_addr a;
+ struct addrinfo hints, *ai;
+ char sbuf[NI_MAXSERV];
+ const size_t minsiz =
+ sizeof(statp->_u._ext.ext->nsaddrs[0]);
cp = buf + sizeof("nameserver") - 1;
while (*cp == ' ' || *cp == '\t')
cp++;
- if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
- statp->nsaddr_list[nserv].sin_addr = a;
- statp->nsaddr_list[nserv].sin_family = AF_INET;
- statp->nsaddr_list[nserv].sin_port =
- htons(NAMESERVER_PORT);
- nserv++;
+ cp[strcspn(cp, ";# \t\n")] = '\0';
+ if ((*cp != '\0') && (*cp != '\n')) {
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_NUMERICHOST;
+ sprintf(sbuf, "%u", NAMESERVER_PORT);
+ if (getaddrinfo(cp, sbuf, &hints, &ai) == 0 &&
+ ai->ai_addrlen <= minsiz) {
+ if (statp->_u._ext.ext != NULL) {
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+ ai->ai_addr, ai->ai_addrlen);
+ }
+ if (ai->ai_addrlen <=
+ sizeof(statp->nsaddr_list[nserv])) {
+ memcpy(&statp->nsaddr_list[nserv],
+ ai->ai_addr, ai->ai_addrlen);
+ } else
+ statp->nsaddr_list[nserv].sin_family = 0;
+ freeaddrinfo(ai);
+ nserv++;
+ }
}
continue;
}
@@ -310,7 +347,7 @@ __res_vinit(res_state statp, int preinit) {
break;
net = cp;
while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
+ isascii(*cp) && !isspace((unsigned char)*cp))
cp++;
n = *cp;
*cp = 0;
@@ -320,7 +357,8 @@ __res_vinit(res_state statp, int preinit) {
*cp++ = n;
net = cp;
while (*cp && *cp != ';' &&
- isascii(*cp) && !isspace(*cp))
+ isascii(*cp) &&
+ !isspace((unsigned char)*cp))
cp++;
n = *cp;
*cp = 0;
@@ -346,8 +384,7 @@ __res_vinit(res_state statp, int preinit) {
continue;
}
}
-
- if (nserv > 1)
+ if (nserv > 1)
statp->nscount = nserv;
#ifdef RESOLVSORT
statp->nsort = nsort;
@@ -404,9 +441,11 @@ __res_vinit(res_state statp, int preinit) {
}
static void
-res_setoptions(res_state statp, const char *options, const char *source) {
+res_setoptions(res_state statp, const char *options, const char *source)
+{
const char *cp = options;
int i;
+ struct __res_state_ext *ext = statp->_u._ext.ext;
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -449,6 +488,11 @@ res_setoptions(res_state statp, const char *options, const char *source) {
}
printf(";;\tdebug\n");
#endif
+ } else if (!strncmp(cp, "no_tld_query",
+ sizeof("no_tld_query") - 1) ||
+ !strncmp(cp, "no-tld-query",
+ sizeof("no-tld-query") - 1)) {
+ statp->options |= RES_NOTLDQUERY;
} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
statp->options |= RES_USE_INET6;
} else if (!strncmp(cp, "rotate", sizeof("rotate") - 1)) {
@@ -456,9 +500,52 @@ res_setoptions(res_state statp, const char *options, const char *source) {
} else if (!strncmp(cp, "no-check-names",
sizeof("no-check-names") - 1)) {
statp->options |= RES_NOCHECKNAME;
- } else {
+ }
+#ifdef RES_USE_EDNS0
+ else if (!strncmp(cp, "edns0", sizeof("edns0") - 1)) {
+ statp->options |= RES_USE_EDNS0;
+ }
+#endif
+ else if (!strncmp(cp, "a6", sizeof("a6") - 1)) {
+ statp->options |= RES_USE_A6;
+ }
+ else if (!strncmp(cp, "dname", sizeof("dname") - 1)) {
+ statp->options |= RES_USE_DNAME;
+ }
+ else if (!strncmp(cp, "nibble:", sizeof("nibble:") - 1)) {
+ if (ext == NULL)
+ goto skip;
+ cp += sizeof("nibble:") - 1;
+ i = MIN(strcspn(cp, " \t"), sizeof(ext->nsuffix) - 1);
+ strncpy(ext->nsuffix, cp, i);
+ ext->nsuffix[i] = '\0';
+ }
+ else if (!strncmp(cp, "bitstring:", sizeof("bitstring:") - 1)) {
+ if (ext == NULL)
+ goto skip;
+ cp += sizeof("bitstring:") - 1;
+ i = MIN(strcspn(cp, " \t"), sizeof(ext->bsuffix) - 1);
+ strncpy(ext->bsuffix, cp, i);
+ ext->bsuffix[i] = '\0';
+ }
+ else if (!strncmp(cp, "v6revmode:", sizeof("v6revmode:") - 1)) {
+ cp += sizeof("v6revmode:") - 1;
+ if (!strncmp(cp, "nibble", sizeof("nibble") - 1)) {
+ statp->options &= ~RES_NO_NIBBLE;
+ statp->options |= RES_NO_BITSTRING;
+ } else if (!strncmp(cp, "bitstring",
+ sizeof("bitstring") - 1)) {
+ statp->options |= RES_NO_NIBBLE;
+ statp->options &= ~RES_NO_BITSTRING;
+ } else if (!strncmp(cp, "both", sizeof("both") - 1)) {
+ statp->options &=
+ ~(RES_NO_NIBBLE|RES_NO_BITSTRING);
+ }
+ }
+ else {
/* XXX - print a warning here? */
}
+ skip:
/* skip to next run of spaces */
while (*cp && *cp != ' ' && *cp != '\t')
cp++;
@@ -512,3 +599,123 @@ res_nclose(res_state statp) {
}
}
}
+
+void
+res_ndestroy(res_state statp) {
+ res_nclose(statp);
+ if (statp->_u._ext.ext != NULL)
+ free(statp->_u._ext.ext);
+ statp->options &= ~RES_INIT;
+ statp->_u._ext.ext = NULL;
+}
+
+const char *
+res_get_nibblesuffix(res_state statp) {
+ if (statp->_u._ext.ext)
+ return (statp->_u._ext.ext->nsuffix);
+ return ("ip6.int");
+}
+
+const char *
+res_get_bitstringsuffix(res_state statp) {
+ if (statp->_u._ext.ext)
+ return (statp->_u._ext.ext->bsuffix);
+ return ("ip6.arpa");
+}
+
+void
+res_setservers(res_state statp, const union res_sockaddr_union *set, int cnt) {
+ int i, nserv;
+ size_t size;
+
+ /* close open servers */
+ res_nclose(statp);
+
+ /* cause rtt times to be forgotten */
+ statp->_u._ext.nscount = 0;
+
+ nserv = 0;
+ for (i = 0; i < cnt && nserv < MAXNS; i++) {
+ switch (set->sin.sin_family) {
+ case AF_INET:
+ size = sizeof(set->sin);
+ if (statp->_u._ext.ext)
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+ &set->sin, size);
+ if (size <= sizeof(statp->nsaddr_list[nserv]))
+ memcpy(&statp->nsaddr_list[nserv],
+ &set->sin, size);
+ else
+ statp->nsaddr_list[nserv].sin_family = 0;
+ nserv++;
+ break;
+
+#ifdef HAS_INET6_STRUCTS
+ case AF_INET6:
+ size = sizeof(set->sin6);
+ if (statp->_u._ext.ext)
+ memcpy(&statp->_u._ext.ext->nsaddrs[nserv],
+ &set->sin6, size);
+ if (size <= sizeof(statp->nsaddr_list[nserv]))
+ memcpy(&statp->nsaddr_list[nserv],
+ &set->sin6, size);
+ else
+ statp->nsaddr_list[nserv].sin_family = 0;
+ nserv++;
+ break;
+#endif
+
+ default:
+ break;
+ }
+ set++;
+ }
+ statp->nscount = nserv;
+
+}
+
+int
+res_getservers(res_state statp, union res_sockaddr_union *set, int cnt) {
+ int i;
+ size_t size;
+ u_int16_t family;
+
+ for (i = 0; i < statp->nscount && i < cnt; i++) {
+ if (statp->_u._ext.ext)
+ family = statp->_u._ext.ext->nsaddrs[i].sin.sin_family;
+ else
+ family = statp->nsaddr_list[i].sin_family;
+
+ switch (family) {
+ case AF_INET:
+ size = sizeof(set->sin);
+ if (statp->_u._ext.ext)
+ memcpy(&set->sin,
+ &statp->_u._ext.ext->nsaddrs[i],
+ size);
+ else
+ memcpy(&set->sin, &statp->nsaddr_list[i],
+ size);
+ break;
+
+#ifdef HAS_INET6_STRUCTS
+ case AF_INET6:
+ size = sizeof(set->sin6);
+ if (statp->_u._ext.ext)
+ memcpy(&set->sin6,
+ &statp->_u._ext.ext->nsaddrs[i],
+ size);
+ else
+ memcpy(&set->sin6, &statp->nsaddr_list[i],
+ size);
+ break;
+#endif
+
+ default:
+ set->sin.sin_family = 0;
+ break;
+ }
+ set++;
+ }
+ return (statp->nscount);
+}
diff --git a/contrib/bind/lib/resolv/res_mkquery.c b/contrib/bind/lib/resolv/res_mkquery.c
index 17b1ccf..7041227 100644
--- a/contrib/bind/lib/resolv/res_mkquery.c
+++ b/contrib/bind/lib/resolv/res_mkquery.c
@@ -70,7 +70,7 @@
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
-static const char rcsid[] = "$Id: res_mkquery.c,v 8.12 1999/10/13 16:39:40 vixie Exp $";
+static const char rcsid[] = "$Id: res_mkquery.c,v 8.14 2001/09/24 13:50:27 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -109,6 +109,8 @@ res_nmkquery(res_state statp,
register int n;
u_char *dnptrs[20], **dpp, **lastdnptr;
+ UNUSED(newrr_in);
+
#ifdef DEBUG
if (statp->options & RES_DEBUG)
printf(";; res_nmkquery(%s, %s, %s, %s)\n",
@@ -154,7 +156,7 @@ res_nmkquery(res_state statp,
* Make an additional record for completion domain.
*/
buflen -= RRFIXEDSZ;
- n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
+ n = dn_comp((const char *)data, cp, buflen, dnptrs, lastdnptr);
if (n < 0)
return (-1);
cp += n;
@@ -197,3 +199,60 @@ res_nmkquery(res_state statp,
}
return (cp - buf);
}
+
+#ifdef RES_USE_EDNS0
+/* attach OPT pseudo-RR, as documented in RFC2671 (EDNS0). */
+#ifndef T_OPT
+#define T_OPT 41
+#endif
+
+int
+res_nopt(statp, n0, buf, buflen, anslen)
+ res_state statp;
+ int n0;
+ u_char *buf; /* buffer to put query */
+ int buflen; /* size of buffer */
+ int anslen; /* answer buffer length */
+{
+ register HEADER *hp;
+ register u_char *cp;
+ u_int16_t flags = 0;
+
+#ifdef DEBUG
+ if ((statp->options & RES_DEBUG) != 0)
+ printf(";; res_nopt()\n");
+#endif
+
+ hp = (HEADER *) buf;
+ cp = buf + n0;
+ buflen -= n0;
+
+ if (buflen < 1 + RRFIXEDSZ)
+ return -1;
+
+ *cp++ = 0; /* "." */
+ buflen--;
+
+ __putshort(T_OPT, cp); /* TYPE */
+ cp += INT16SZ;
+ __putshort(anslen & 0xffff, cp); /* CLASS = UDP payload size */
+ cp += INT16SZ;
+ *cp++ = NOERROR; /* extended RCODE */
+ *cp++ = 0; /* EDNS version */
+ if (statp->options & RES_USE_DNSSEC) {
+#ifdef DEBUG
+ if (statp->options & RES_DEBUG)
+ printf(";; res_opt()... ENDS0 DNSSEC\n");
+#endif
+ flags |= NS_OPT_DNSSEC_OK;
+ }
+ __putshort(flags, cp);
+ cp += INT16SZ;
+ __putshort(0, cp); /* RDLEN */
+ cp += INT16SZ;
+ hp->arcount = htons(ntohs(hp->arcount) + 1);
+ buflen -= RRFIXEDSZ;
+
+ return cp - buf;
+}
+#endif
diff --git a/contrib/bind/lib/resolv/res_mkupdate.c b/contrib/bind/lib/resolv/res_mkupdate.c
index ecf66dd..6071360 100644
--- a/contrib/bind/lib/resolv/res_mkupdate.c
+++ b/contrib/bind/lib/resolv/res_mkupdate.c
@@ -21,7 +21,7 @@
*/
#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_mkupdate.c,v 1.25 2000/11/22 01:20:46 marka Exp $";
+static const char rcsid[] = "$Id: res_mkupdate.c,v 1.26 2001/05/29 05:49:47 marka Exp $";
#endif /* not lint */
#include "port_before.h"
@@ -328,7 +328,7 @@ res_nmkupdate(res_state statp, ns_updrec *rrecp_in, u_char *buf, int buflen) {
break;
case T_WKS: {
char bm[MAXPORT/8];
- int maxbm = 0;
+ unsigned int maxbm = 0;
if (!getword_str(buf2, sizeof buf2, &startp, endp))
return (-1);
@@ -890,7 +890,7 @@ struct valuelist {
};
static struct valuelist *servicelist, *protolist;
-void
+static void
res_buildservicelist() {
struct servent *sp;
struct valuelist *slp;
@@ -936,7 +936,7 @@ res_destroyservicelist() {
}
void
-res_buildprotolist() {
+res_buildprotolist(void) {
struct protoent *pp;
struct valuelist *slp;
@@ -965,7 +965,7 @@ res_buildprotolist() {
}
void
-res_destroyprotolist() {
+res_destroyprotolist(void) {
struct valuelist *plp, *plp_next;
for (plp = protolist; plp != NULL; plp = plp_next) {
diff --git a/contrib/bind/lib/resolv/res_private.h b/contrib/bind/lib/resolv/res_private.h
new file mode 100644
index 0000000..2c7fa5e
--- /dev/null
+++ b/contrib/bind/lib/resolv/res_private.h
@@ -0,0 +1,20 @@
+#ifndef res_private_h
+#define res_private_h
+
+struct __res_state_ext {
+ union res_sockaddr_union nsaddrs[MAXNS];
+ struct sort_list {
+ int af;
+ union {
+ struct in_addr ina;
+ struct in6_addr in6a;
+ } addr, mask;
+ } sort_list[MAXRESOLVSORT];
+ char nsuffix[64];
+ char bsuffix[64];
+};
+
+extern int
+res_ourserver_p(const res_state statp, const struct sockaddr *sa);
+
+#endif
diff --git a/contrib/bind/lib/resolv/res_query.c b/contrib/bind/lib/resolv/res_query.c
index 3147f1e..61f5df9 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.20 2000/02/29 05:39:12 vixie Exp $";
+static const char rcsid[] = "$Id: res_query.c,v 8.23 2001/09/24 13:50:29 marka Exp $";
#endif /* LIBC_SCCS and not lint */
#include "port_before.h"
@@ -117,7 +117,11 @@ res_nquery(res_state statp,
u_char buf[MAXPACKET];
HEADER *hp = (HEADER *) answer;
int n;
+ u_int oflags;
+ oflags = statp->_flags;
+
+again:
hp->rcode = NOERROR; /* default */
#ifdef DEBUG
@@ -127,6 +131,11 @@ res_nquery(res_state statp,
n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
buf, sizeof(buf));
+#ifdef RES_USE_EDNS0
+ if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 &&
+ (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0)
+ n = res_nopt(statp, n, buf, sizeof(buf), anslen);
+#endif
if (n <= 0) {
#ifdef DEBUG
if (statp->options & RES_DEBUG)
@@ -137,6 +146,16 @@ res_nquery(res_state statp,
}
n = res_nsend(statp, buf, n, answer, anslen);
if (n < 0) {
+#ifdef RES_USE_EDNS0
+ /* if the query choked with EDNS0, retry without EDNS0 */
+ if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0 &&
+ ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
+ statp->_flags |= RES_F_EDNS0ERR;
+ if (statp->options & RES_DEBUG)
+ printf(";; res_nquery: retry without EDNS0\n");
+ goto again;
+ }
+#endif
#ifdef DEBUG
if (statp->options & RES_DEBUG)
printf(";; res_query: send error\n");
@@ -193,6 +212,7 @@ res_nsearch(res_state statp,
int trailing_dot, ret, saved_herrno;
int got_nodata = 0, got_servfail = 0, root_on_list = 0;
int tried_as_is = 0;
+ int searched = 0;
errno = 0;
RES_SET_H_ERRNO(statp, HOST_NOT_FOUND); /* True if we never query. */
@@ -236,6 +256,7 @@ res_nsearch(res_state statp,
for (domain = (const char * const *)statp->dnsrch;
*domain && !done;
domain++) {
+ searched = 1;
if (domain[0][0] == '\0' ||
(domain[0][0] == '.' && domain[0][1] == '\0'))
@@ -293,11 +314,11 @@ res_nsearch(res_state statp,
}
/*
- * 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 the query has not already been tried as is then try it
+ * unless RES_NOTLDQUERY is set and there were no dots.
*/
- if (statp->ndots && !(tried_as_is || root_on_list)) {
+ if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0) &&
+ !(tried_as_is || root_on_list)) {
ret = res_nquerydomain(statp, name, NULL, class, type,
answer, anslen);
if (ret > 0)
@@ -383,17 +404,18 @@ res_hostalias(const res_state statp, const char *name, char *dst, size_t siz) {
setbuf(fp, NULL);
buf[sizeof(buf) - 1] = '\0';
while (fgets(buf, sizeof(buf), fp)) {
- for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
+ for (cp1 = buf; *cp1 && !isspace((unsigned char)*cp1); ++cp1)
;
if (!*cp1)
break;
*cp1 = '\0';
if (ns_samename(buf, name) == 1) {
- while (isspace(*++cp1))
+ while (isspace((unsigned char)*++cp1))
;
if (!*cp1)
break;
- for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
+ for (cp2 = cp1 + 1; *cp2 &&
+ !isspace((unsigned char)*cp2); ++cp2)
;
*cp2 = '\0';
strncpy(dst, cp1, siz - 1);
diff --git a/contrib/bind/lib/resolv/res_send.c b/contrib/bind/lib/resolv/res_send.c
index ade9eac..6dfea59 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.42 2001/03/07 06:48:03 marka Exp $";
+static const char rcsid[] = "$Id: res_send.c,v 8.48 2001/07/03 06:27:17 marka Exp $";
#endif /* LIBC_SCCS and not lint */
/*
@@ -106,6 +106,7 @@ static const char rcsid[] = "$Id: res_send.c,v 8.42 2001/03/07 06:48:03 marka Ex
/* Options. Leave them on. */
#define DEBUG
#include "res_debug.h"
+#include "res_private.h"
#define EXT(res) ((res)->_u._ext)
@@ -113,20 +114,25 @@ static const int highestFD = FD_SETSIZE - 1;
/* Forward. */
+static int get_salen __P((const struct sockaddr *));
+static struct sockaddr * get_nsaddr __P((res_state, size_t));
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);
+ const struct sockaddr *, int);
static void Perror(const res_state, FILE *, const char *, int);
-static int sock_eq(struct sockaddr_in *, struct sockaddr_in *);
+static int sock_eq(struct sockaddr *, struct sockaddr *);
#ifdef NEED_PSELECT
static int pselect(int, void *, void *, void *,
struct timespec *,
const sigset_t *);
#endif
+void res_pquery(const res_state, const u_char *, int, FILE *);
+
+static const int niflags = NI_NUMERICHOST | NI_NUMERICSERV;
/* Public. */
@@ -140,19 +146,38 @@ static int pselect(int, void *, void *, void *,
* paul vixie, 29may94
*/
int
-res_ourserver_p(const res_state statp, const struct sockaddr_in *inp) {
- struct sockaddr_in ina;
+res_ourserver_p(const res_state statp, const struct sockaddr *sa) {
+ const struct sockaddr_in *inp, *srv;
+ const struct sockaddr_in6 *in6p, *srv6;
int ns;
- ina = *inp;
- for (ns = 0; ns < statp->nscount; ns++) {
- const struct sockaddr_in *srv = &statp->nsaddr_list[ns];
-
- if (srv->sin_family == ina.sin_family &&
- srv->sin_port == ina.sin_port &&
- (srv->sin_addr.s_addr == INADDR_ANY ||
- srv->sin_addr.s_addr == ina.sin_addr.s_addr))
- return (1);
+ switch (sa->sa_family) {
+ case AF_INET:
+ inp = (const struct sockaddr_in *)sa;
+ for (ns = 0; ns < statp->nscount; ns++) {
+ srv = (struct sockaddr_in *)get_nsaddr(statp, ns);
+ if (srv->sin_family == inp->sin_family &&
+ srv->sin_port == inp->sin_port &&
+ (srv->sin_addr.s_addr == INADDR_ANY ||
+ srv->sin_addr.s_addr == inp->sin_addr.s_addr))
+ return (1);
+ }
+ break;
+ case AF_INET6:
+ if (EXT(statp).ext == NULL)
+ break;
+ in6p = (const struct sockaddr_in6 *)sa;
+ for (ns = 0; ns < statp->nscount; ns++) {
+ srv6 = (struct sockaddr_in6 *)get_nsaddr(statp, ns);
+ if (srv6->sin6_family == in6p->sin6_family &&
+ srv6->sin6_port == in6p->sin6_port &&
+ (IN6_IS_ADDR_UNSPECIFIED(&srv6->sin6_addr) ||
+ IN6_ARE_ADDR_EQUAL(&srv6->sin6_addr, &in6p->sin6_addr)))
+ return (1);
+ }
+ break;
+ default:
+ break;
}
return (0);
}
@@ -174,7 +199,7 @@ res_nameinquery(const char *name, int type, int class,
const u_char *buf, const u_char *eom)
{
const u_char *cp = buf + HFIXEDSZ;
- int qdcount = ntohs(((HEADER*)buf)->qdcount);
+ int qdcount = ntohs(((const HEADER*)buf)->qdcount);
while (qdcount-- > 0) {
char tname[MAXDNAME+1];
@@ -211,7 +236,7 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1,
const u_char *buf2, const u_char *eom2)
{
const u_char *cp = buf1 + HFIXEDSZ;
- int qdcount = ntohs(((HEADER*)buf1)->qdcount);
+ int qdcount = ntohs(((const HEADER*)buf1)->qdcount);
if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
return (-1);
@@ -220,11 +245,11 @@ 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 ((((const HEADER *)buf1)->opcode == ns_o_update) &&
+ (((const HEADER *)buf2)->opcode == ns_o_update))
return (1);
- if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
+ if (qdcount != ntohs(((const HEADER*)buf2)->qdcount))
return (0);
while (qdcount-- > 0) {
char tname[MAXDNAME+1];
@@ -249,6 +274,7 @@ res_nsend(res_state statp,
const u_char *buf, int buflen, u_char *ans, int anssiz)
{
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
+ char abuf[NI_MAXHOST];
if (statp->nscount == 0) {
errno = ESRCH;
@@ -270,16 +296,34 @@ res_nsend(res_state statp,
*/
if (EXT(statp).nscount != 0) {
int needclose = 0;
+ struct sockaddr_storage peer;
+ ISC_SOCKLEN_T peerlen;
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])) {
+ for (ns = 0; ns < statp->nscount; ns++) {
+ if (statp->nsaddr_list[ns].sin_family &&
+ !sock_eq((struct sockaddr *)&statp->nsaddr_list[ns],
+ (struct sockaddr *)&EXT(statp).ext->nsaddrs[ns])) {
+ needclose++;
+ break;
+ }
+
+ if (EXT(statp).nssocks[ns] == -1)
+ continue;
+ peerlen = sizeof(peer);
+ if (getsockname(EXT(statp).nssocks[ns],
+ (struct sockaddr *)&peer, &peerlen) < 0) {
+ needclose++;
+ break;
+ }
+ if (!sock_eq((struct sockaddr *)&peer,
+ get_nsaddr(statp, ns))) {
needclose++;
break;
}
+ }
if (needclose) {
res_nclose(statp);
EXT(statp).nscount = 0;
@@ -291,9 +335,12 @@ res_nsend(res_state statp,
*/
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;
+ if (!statp->nsaddr_list[ns].sin_family)
+ continue;
+ EXT(statp).ext->nsaddrs[ns].sin =
+ statp->nsaddr_list[ns];
}
EXT(statp).nscount = statp->nscount;
}
@@ -304,19 +351,27 @@ res_nsend(res_state statp,
*/
if ((statp->options & RES_ROTATE) != 0 &&
(statp->options & RES_BLAST) == 0) {
+ union res_sockaddr_union inu;
struct sockaddr_in ina;
int lastns = statp->nscount - 1;
int fd;
u_int16_t nstime;
+ if (EXT(statp).ext != NULL)
+ inu = EXT(statp).ext->nsaddrs[0];
ina = statp->nsaddr_list[0];
fd = EXT(statp).nssocks[0];
- nstime = EXT(statp).nstimes[ns];
+ nstime = EXT(statp).nstimes[0];
for (ns = 0; ns < lastns; ns++) {
+ if (EXT(statp).ext != NULL)
+ EXT(statp).ext->nsaddrs[ns] =
+ EXT(statp).ext->nsaddrs[ns + 1];
statp->nsaddr_list[ns] = statp->nsaddr_list[ns + 1];
EXT(statp).nssocks[ns] = EXT(statp).nssocks[ns + 1];
EXT(statp).nstimes[ns] = EXT(statp).nstimes[ns + 1];
}
+ if (EXT(statp).ext != NULL)
+ EXT(statp).ext->nsaddrs[lastns] = inu;
statp->nsaddr_list[lastns] = ina;
EXT(statp).nssocks[lastns] = fd;
EXT(statp).nstimes[lastns] = nstime;
@@ -327,7 +382,10 @@ res_nsend(res_state statp,
*/
for (try = 0; try < statp->retry; try++) {
for (ns = 0; ns < statp->nscount; ns++) {
- struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+ struct sockaddr *nsap;
+ int nsaplen;
+ nsap = get_nsaddr(statp, ns);
+ nsaplen = get_salen(nsap);
same_ns:
if (statp->qhook) {
int done = 0, loops = 0;
@@ -359,9 +417,12 @@ res_nsend(res_state statp,
} while (!done);
}
- Dprint(statp->options & RES_DEBUG,
+ Dprint(((statp->options & RES_DEBUG) &&
+ getnameinfo(nsap, nsaplen, abuf, sizeof(abuf),
+ NULL, 0, niflags) == 0),
(stdout, ";; Querying server (# %d) address = %s\n",
- ns + 1, inet_ntoa(nsap->sin_addr)));
+ ns + 1, abuf));
+
if (v_circuit) {
/* Use VC; at most one attempt per server. */
@@ -393,7 +454,7 @@ res_nsend(res_state statp,
DprintQ((statp->options & RES_DEBUG) ||
(statp->pfcode & RES_PRF_REPLY),
- (stdout, ""),
+ (stdout, "%s", ""),
ans, (resplen > anssiz) ? anssiz : resplen);
/*
@@ -455,17 +516,67 @@ res_nsend(res_state statp,
/* Private */
static int
+get_salen(sa)
+ const struct sockaddr *sa;
+{
+
+#ifdef HAVE_SA_LEN
+ /* there are people do not set sa_len. be forgibing to them */
+ if (sa->sa_len)
+ return sa->sa_len;
+#endif
+
+ if (sa->sa_family == AF_INET)
+ return sizeof(struct sockaddr_in);
+ else if (sa->sa_family == AF_INET)
+ return sizeof(struct sockaddr_in6);
+ else
+ return 0; /* unknown, die on connect */
+}
+
+/*
+ * pick appropriate nsaddr_list for use. see res_init() for initialization.
+ */
+static struct sockaddr *
+get_nsaddr(statp, n)
+ res_state statp;
+ size_t n;
+{
+
+ if (!statp->nsaddr_list[n].sin_family && EXT(statp).ext) {
+ /*
+ * - EXT(statp).ext->nsaddrs[n] holds an address that is larger
+ * than struct sockaddr, and
+ * - user code did not update statp->nsaddr_list[n].
+ */
+ return (struct sockaddr *)(void *)&EXT(statp).ext->nsaddrs[n];
+ } else {
+ /*
+ * - user code updated statp->nsaddr_list[n], or
+ * - statp->nsaddr_list[n] has the same content as
+ * EXT(statp).ext->nsaddrs[n].
+ */
+ return (struct sockaddr *)(void *)&statp->nsaddr_list[n];
+ }
+}
+
+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;
+ const HEADER *hp = (const HEADER *) buf;
HEADER *anhp = (HEADER *) ans;
- struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+ struct sockaddr *nsap;
+ int nsaplen;
int truncating, connreset, resplen, n;
struct iovec iov[2];
u_short len;
u_char *cp;
+ void *tmp;
+
+ nsap = get_nsaddr(statp, ns);
+ nsaplen = get_salen(nsap);
connreset = 0;
same_ns:
@@ -473,12 +584,12 @@ send_vc(res_state statp,
/* Are we still talking to whom we want to talk to? */
if (statp->_vcsock >= 0 && (statp->_flags & RES_F_VC) != 0) {
- struct sockaddr_in peer;
- int size = sizeof peer;
+ struct sockaddr_storage peer;
+ ISC_SOCKLEN_T size = sizeof peer;
if (getpeername(statp->_vcsock,
(struct sockaddr *)&peer, &size) < 0 ||
- !sock_eq(&peer, nsap)) {
+ !sock_eq((struct sockaddr *)&peer, nsap)) {
res_nclose(statp);
statp->_flags &= ~RES_F_VC;
}
@@ -488,7 +599,7 @@ send_vc(res_state statp,
if (statp->_vcsock >= 0)
res_nclose(statp);
- statp->_vcsock = socket(PF_INET, SOCK_STREAM, 0);
+ statp->_vcsock = socket(nsap->sa_family, SOCK_STREAM, 0);
if (statp->_vcsock > highestFD) {
res_nclose(statp);
errno = ENOTSOCK;
@@ -499,10 +610,10 @@ send_vc(res_state statp,
return (-1);
}
errno = 0;
- if (connect(statp->_vcsock, (struct sockaddr *)nsap,
- sizeof *nsap) < 0) {
+ if (connect(statp->_vcsock, nsap, nsaplen) < 0) {
*terrno = errno;
- Aerror(statp, stderr, "connect/vc", errno, *nsap);
+ Aerror(statp, stderr, "connect/vc", errno, nsap,
+ nsaplen);
res_nclose(statp);
return (0);
}
@@ -514,7 +625,8 @@ send_vc(res_state statp,
*/
putshort((u_short)buflen, (u_char*)&len);
iov[0] = evConsIovec(&len, INT16SZ);
- iov[1] = evConsIovec((void*)buf, buflen);
+ DE_CONST(buf, tmp);
+ iov[1] = evConsIovec(tmp, buflen);
if (writev(statp->_vcsock, iov, 2) != (INT16SZ + buflen)) {
*terrno = errno;
Perror(statp, stderr, "write failed", errno);
@@ -627,16 +739,20 @@ 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;
+ const HEADER *hp = (const HEADER *) buf;
HEADER *anhp = (HEADER *) ans;
- const struct sockaddr_in *nsap = &statp->nsaddr_list[ns];
+ const struct sockaddr *nsap;
+ int nsaplen;
struct timespec now, timeout, finish;
fd_set dsmask;
- struct sockaddr_in from;
- int fromlen, resplen, seconds, n, s;
+ struct sockaddr_storage from;
+ ISC_SOCKLEN_T fromlen;
+ int resplen, seconds, n, s;
+ nsap = get_nsaddr(statp, ns);
+ nsaplen = get_salen(nsap);
if (EXT(statp).nssocks[ns] == -1) {
- EXT(statp).nssocks[ns] = socket(PF_INET, SOCK_DGRAM, 0);
+ EXT(statp).nssocks[ns] = socket(nsap->sa_family, SOCK_DGRAM, 0);
if (EXT(statp).nssocks[ns] > highestFD) {
res_nclose(statp);
errno = ENOTSOCK;
@@ -658,9 +774,9 @@ send_dg(res_state statp,
* 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);
+ if (connect(EXT(statp).nssocks[ns], nsap, nsaplen) < 0) {
+ Aerror(statp, stderr, "connect(dg)", errno, nsap,
+ nsaplen);
res_nclose(statp);
return (0);
}
@@ -670,16 +786,15 @@ send_dg(res_state statp,
}
s = EXT(statp).nssocks[ns];
#ifndef CANNOT_CONNECT_DGRAM
- if (send(s, (char*)buf, buflen, 0) != buflen) {
+ if (send(s, (const 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)
+ if (sendto(s, (const char*)buf, buflen, 0, nsap, nsaplen) != buflen)
{
- Aerror(statp, stderr, "sendto", errno, *nsap);
+ Aerror(statp, stderr, "sendto", errno, nsap, nsaplen);
res_nclose(statp);
return (0);
}
@@ -720,7 +835,7 @@ send_dg(res_state statp,
return (0);
}
errno = 0;
- fromlen = sizeof(struct sockaddr_in);
+ fromlen = sizeof(from);
resplen = recvfrom(s, (char*)ans, anssiz,0,
(struct sockaddr *)&from, &fromlen);
if (resplen <= 0) {
@@ -753,7 +868,7 @@ send_dg(res_state statp,
goto wait;
}
if (!(statp->options & RES_INSECURE1) &&
- !res_ourserver_p(statp, &from)) {
+ !res_ourserver_p(statp, (struct sockaddr *)&from)) {
/*
* response from wrong server? ignore it.
* XXX - potential security hazard could
@@ -765,6 +880,22 @@ send_dg(res_state statp,
ans, (resplen > anssiz) ? anssiz : resplen);
goto wait;
}
+#ifdef RES_USE_EDNS0
+ if (anhp->rcode == FORMERR && (statp->options & RES_USE_EDNS0) != 0) {
+ /*
+ * Do not retry if the server do not understand EDNS0.
+ * The case has to be captured here, as FORMERR packet do not
+ * carry query section, hence res_queriesmatch() returns 0.
+ */
+ DprintQ(statp->options & RES_DEBUG,
+ (stdout, "server rejected query with EDNS0:\n"),
+ ans, (resplen > anssiz) ? anssiz : resplen);
+ /* record the error */
+ statp->_flags |= RES_F_EDNS0ERR;
+ res_nclose(statp);
+ return (0);
+ }
+#endif
if (!(statp->options & RES_INSECURE2) &&
!res_queriesmatch(buf, buf + buflen,
ans, ans + anssiz)) {
@@ -810,19 +941,24 @@ send_dg(res_state statp,
static void
Aerror(const res_state statp, FILE *file, const char *string, int error,
- struct sockaddr_in address)
+ const struct sockaddr *address, int alen)
{
int save = errno;
+ char hbuf[NI_MAXHOST];
+ char sbuf[NI_MAXSERV];
- if ((statp->options & RES_DEBUG) != 0) {
- char tmp[sizeof "255.255.255.255"];
+ alen = alen;
- 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));
+ if ((statp->options & RES_DEBUG) != 0) {
+ if (getnameinfo(address, alen, hbuf, sizeof(hbuf),
+ sbuf, sizeof(sbuf), niflags)) {
+ strncpy(hbuf, "?", sizeof(hbuf) - 1);
+ hbuf[sizeof(hbuf) - 1] = '\0';
+ strncpy(sbuf, "?", sizeof(sbuf) - 1);
+ sbuf[sizeof(sbuf) - 1] = '\0';
+ }
+ fprintf(file, "res_send: %s ([%s].%s): %s\n",
+ string, hbuf, sbuf, strerror(error));
}
errno = save;
}
@@ -838,10 +974,29 @@ Perror(const res_state statp, FILE *file, const char *string, int error) {
}
static int
-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));
+sock_eq(struct sockaddr *a, struct sockaddr *b) {
+ struct sockaddr_in *a4, *b4;
+ struct sockaddr_in6 *a6, *b6;
+
+ if (a->sa_family != b->sa_family)
+ return 0;
+ switch (a->sa_family) {
+ case AF_INET:
+ a4 = (struct sockaddr_in *)a;
+ b4 = (struct sockaddr_in *)b;
+ return a4->sin_port == b4->sin_port &&
+ a4->sin_addr.s_addr == b4->sin_addr.s_addr;
+ case AF_INET6:
+ a6 = (struct sockaddr_in6 *)a;
+ b6 = (struct sockaddr_in6 *)b;
+ return a6->sin6_port == b6->sin6_port &&
+#ifdef HAVE_SIN6_SCOPE_ID
+ a6->sin6_scope_id == b6->sin6_scope_id &&
+#endif
+ IN6_ARE_ADDR_EQUAL(&a6->sin6_addr, &b6->sin6_addr);
+ default:
+ return 0;
+ }
}
#ifdef NEED_PSELECT
diff --git a/contrib/bind/lib/resolv/res_update.c b/contrib/bind/lib/resolv/res_update.c
index 1434d5c..54d3b15 100644
--- a/contrib/bind/lib/resolv/res_update.c
+++ b/contrib/bind/lib/resolv/res_update.c
@@ -1,5 +1,5 @@
#if !defined(lint) && !defined(SABER)
-static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka Exp $";
+static const char rcsid[] = "$Id: res_update.c,v 1.31 2001/11/01 05:21:23 marka Exp $";
#endif /* not lint */
/*
@@ -37,7 +37,6 @@ static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka
#include <errno.h>
#include <limits.h>
#include <netdb.h>
-#include <resolv.h>
#include <res_update.h>
#include <stdarg.h>
#include <stdio.h>
@@ -45,8 +44,10 @@ static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka
#include <string.h>
#include <isc/list.h>
+#include <resolv.h>
#include "port_after.h"
+#include "res_private.h"
/*
* Separate a linked list of records into groups so that all records
@@ -65,7 +66,7 @@ static const char rcsid[] = "$Id: res_update.c,v 1.26 2001/03/05 04:03:00 marka
struct zonegrp {
char z_origin[MAXDNAME];
ns_class z_class;
- struct in_addr z_nsaddrs[MAXNS];
+ union res_sockaddr_union z_nsaddrs[MAXNS];
int z_nscount;
int z_flags;
LIST(ns_updrec) z_rrlist;
@@ -76,15 +77,15 @@ struct zonegrp {
/* Forward. */
-static int nscopy(struct sockaddr_in *, const struct sockaddr_in *, int);
-static int nsprom(struct sockaddr_in *, const struct in_addr *, int);
-static void dprintf(const char *, ...);
+static int nscopy(union res_sockaddr_union *,
+ const union res_sockaddr_union *, int);
+static void res_dprintf(const char *, ...);
/* Macros. */
#define DPRINTF(x) do {\
int save_errno = errno; \
- if ((statp->options & RES_DEBUG) != 0) dprintf x; \
+ if ((statp->options & RES_DEBUG) != 0) res_dprintf x; \
errno = save_errno; \
} while (0)
@@ -97,12 +98,20 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
struct zonegrp *zptr, tgrp;
LIST(struct zonegrp) zgrps;
int nzones = 0, nscount = 0, n;
- struct sockaddr_in nsaddrs[MAXNS];
+ union res_sockaddr_union nsaddrs[MAXNS];
/* Thread all of the updates onto a list of groups. */
INIT_LIST(zgrps);
for (rrecp = rrecp_in; rrecp;
rrecp = LINKED(rrecp, r_link) ? NEXT(rrecp, r_link) : NULL) {
+ struct in_addr nsaddrs[MAXNS];
+ int i;
+ /* XXX need to rewrite res_findzonecut */
+ for (i = 0; i < MAXNS; i++) {
+ nsaddrs[i].s_addr = 0;
+ if (tgrp.z_nsaddrs[i].sin.sin_family == AF_INET)
+ nsaddrs[i] = tgrp.z_nsaddrs[i].sin.sin_addr;
+ }
/* Find the origin for it if there is one. */
tgrp.z_class = rrecp->r_class;
tgrp.z_nscount =
@@ -110,7 +119,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
RES_EXHAUSTIVE,
tgrp.z_origin,
sizeof tgrp.z_origin,
- tgrp.z_nsaddrs, MAXNS);
+ nsaddrs, MAXNS);
if (tgrp.z_nscount <= 0) {
DPRINTF(("res_findzonecut failed (%d)",
tgrp.z_nscount));
@@ -157,8 +166,8 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
goto done;
/* Temporarily replace the resolver's nameserver set. */
- nscount = nscopy(nsaddrs, statp->nsaddr_list, statp->nscount);
- statp->nscount = nsprom(statp->nsaddr_list,
+ nscount = nscopy(nsaddrs, statp->_u._ext.ext->nsaddrs, statp->nscount);
+ statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs,
zptr->z_nsaddrs, zptr->z_nscount);
/* Send the update and remember the result. */
@@ -176,7 +185,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
nzones++;
/* Restore resolver's nameserver set. */
- statp->nscount = nscopy(statp->nsaddr_list, nsaddrs, nscount);
+ statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount);
nscount = 0;
}
done:
@@ -188,7 +197,7 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
free(zptr);
}
if (nscount != 0)
- statp->nscount = nscopy(statp->nsaddr_list, nsaddrs, nscount);
+ statp->nscount = nscopy(statp->_u._ext.ext->nsaddrs, nsaddrs, nscount);
return (nzones);
}
@@ -196,7 +205,9 @@ res_nupdate(res_state statp, ns_updrec *rrecp_in, ns_tsig_key *key) {
/* Private. */
static int
-nscopy(struct sockaddr_in *dst, const struct sockaddr_in *src, int n) {
+nscopy(union res_sockaddr_union *dst, const union res_sockaddr_union *src,
+ int n)
+{
int i;
for (i = 0; i < n; i++)
@@ -204,21 +215,8 @@ nscopy(struct sockaddr_in *dst, const struct sockaddr_in *src, int n) {
return (n);
}
-static int
-nsprom(struct sockaddr_in *dst, const struct in_addr *src, int n) {
- int i;
-
- for (i = 0; i < n; i++) {
- memset(&dst[i], 0, sizeof dst[i]);
- dst[i].sin_family = AF_INET;
- dst[i].sin_port = htons(NS_DEFAULTPORT);
- dst[i].sin_addr = src[i];
- }
- return (n);
-}
-
static void
-dprintf(const char *fmt, ...) {
+res_dprintf(const char *fmt, ...) {
va_list ap;
va_start(ap, fmt);
OpenPOWER on IntegriCloud