summaryrefslogtreecommitdiffstats
path: root/usr.sbin/named
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1996-01-07 05:22:00 +0000
committerpeter <peter@FreeBSD.org>1996-01-07 05:22:00 +0000
commit5b44da0e8ac60fdd5383276b64f9d162209a1bc0 (patch)
treeac9e6187688a673a4129674d70ce1cbebfabd94e /usr.sbin/named
parentb4f783dc8b43b4346372791a65d153fbb79592d4 (diff)
downloadFreeBSD-src-5b44da0e8ac60fdd5383276b64f9d162209a1bc0.zip
FreeBSD-src-5b44da0e8ac60fdd5383276b64f9d162209a1bc0.tar.gz
At last.. :-) Import of bind-4.9.3-REL. (part 1 of several)
Diffstat (limited to 'usr.sbin/named')
-rw-r--r--usr.sbin/named/db_dump.c16
-rw-r--r--usr.sbin/named/db_func.h7
-rw-r--r--usr.sbin/named/db_glob.h6
-rw-r--r--usr.sbin/named/db_glue.c121
-rw-r--r--usr.sbin/named/db_load.c145
-rw-r--r--usr.sbin/named/db_lookup.c9
-rw-r--r--usr.sbin/named/db_secure.c20
-rw-r--r--usr.sbin/named/db_update.c9
-rw-r--r--usr.sbin/named/dmalloc.c4
-rw-r--r--usr.sbin/named/ns_defs.h14
-rw-r--r--usr.sbin/named/ns_forw.c101
-rw-r--r--usr.sbin/named/ns_func.h24
-rw-r--r--usr.sbin/named/ns_glob.h10
-rw-r--r--usr.sbin/named/ns_init.c52
-rw-r--r--usr.sbin/named/ns_main.c151
-rw-r--r--usr.sbin/named/ns_maint.c456
-rw-r--r--usr.sbin/named/ns_ncache.c2
-rw-r--r--usr.sbin/named/ns_req.c136
-rw-r--r--usr.sbin/named/ns_resp.c736
-rw-r--r--usr.sbin/named/ns_sort.c4
-rw-r--r--usr.sbin/named/ns_validate.c87
-rw-r--r--usr.sbin/named/options.h5
-rw-r--r--usr.sbin/named/portability.h24
-rw-r--r--usr.sbin/named/tools/ndc/ndc.sh35
-rw-r--r--usr.sbin/named/xfer/named-xfer.c34
25 files changed, 1268 insertions, 940 deletions
diff --git a/usr.sbin/named/db_dump.c b/usr.sbin/named/db_dump.c
index 99b3b80..36fe713 100644
--- a/usr.sbin/named/db_dump.c
+++ b/usr.sbin/named/db_dump.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_dump.c 4.33 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: db_dump.c,v 8.7 1995/06/29 09:26:17 vixie Exp $";
+static char rcsid[] = "$Id: db_dump.c,v 8.8 1995/12/06 20:34:38 vixie Exp $";
#endif /* not lint */
/*
@@ -305,8 +305,14 @@ zt_dump(fp)
char *pre, buf[64];
u_int cnt;
+ if (!zp->z_origin)
+ continue;
+
fprintf(fp, "; %s (type %d, class %d, source %s)\n",
- zp->z_origin, zp->z_type, zp->z_class,
+ zp->z_origin
+ ? (*zp->z_origin ? zp->z_origin : ".")
+ : "Nil",
+ zp->z_type, zp->z_class,
zp->z_source ? zp->z_source : "Nil");
fprintf(fp, ";\ttime=%ld, lastupdate=%ld, serial=%u,\n",
zp->z_time, zp->z_lastupdate, zp->z_serial);
@@ -478,12 +484,12 @@ db_dump(htp, fp, zone, origin)
case T_HINFO:
case T_ISDN:
- if (n = *cp++) {
+ if ((n = *cp++) != '\0') {
fprintf(fp, "\"%.*s\"", (int)n, cp);
cp += n;
} else
fprintf(fp, "\"\"");
- if (n = *cp++)
+ if ((n = *cp++) != '\0')
fprintf(fp, " \"%.*s\"", (int)n, cp);
else
fprintf(fp, " \"\"");
@@ -536,7 +542,7 @@ db_dump(htp, fp, zone, origin)
end = (u_char *)dp->d_data + dp->d_size;
(void) putc('"', fp);
while (cp < end) {
- if (n = *cp++) {
+ if ((n = *cp++) != '\0') {
for (j = n ; j > 0 && cp < end ; j--)
if (*cp == '\n') {
(void) putc('\\', fp);
diff --git a/usr.sbin/named/db_func.h b/usr.sbin/named/db_func.h
index 8db6c2f..e0b2a8f 100644
--- a/usr.sbin/named/db_func.h
+++ b/usr.sbin/named/db_func.h
@@ -1,6 +1,6 @@
/* db_proc.h - prototypes for functions in db_*.c
*
- * $Id: db_func.h,v 8.5 1995/06/19 08:34:49 vixie Exp $
+ * $Id: db_func.h,v 8.7 1995/12/22 10:20:30 vixie Exp $
*/
/* ++from db_update.c++ */
@@ -48,7 +48,7 @@ extern void endline __P((FILE *)),
get_netlist __P((FILE *, struct netinfo **,
int, char *)),
free_netlist __P((struct netinfo **));
-extern int getword __P((char *, int, FILE *)),
+extern int getword __P((char *, int, FILE *, int)),
getnum __P((FILE *, const char *, int)),
db_load __P((const char *, const char *,
struct zoneinfo *, const char *)),
@@ -79,7 +79,6 @@ extern int servicenumber __P((char *)),
extern char *protocolname __P((int)),
*servicename __P((u_int16_t, char *)),
*savestr __P((const char *));
-extern const char *inet_etoa __P((const struct sockaddr_in *));
#ifndef BSD
extern int getdtablesize __P((void));
#endif
@@ -100,6 +99,8 @@ extern char * loc_ntoa __P((const u_char *binary, char *ascii));
#endif
extern char * ctimel __P((long));
extern struct in_addr data_inaddr __P((const u_char *data));
+extern void setsignal __P((int, int, SIG_FN (*)())),
+ resignal __P((int, int, SIG_FN (*)()));
/* --from db_glue.c-- */
/* ++from db_lookup.c++ */
diff --git a/usr.sbin/named/db_glob.h b/usr.sbin/named/db_glob.h
index 630b824..b339b5b 100644
--- a/usr.sbin/named/db_glob.h
+++ b/usr.sbin/named/db_glob.h
@@ -1,6 +1,6 @@
/*
* from db.h 4.16 (Berkeley) 6/1/90
- * $Id: db_glob.h,v 8.2 1995/06/20 23:58:50 vixie Exp $
+ * $Id: db_glob.h,v 8.3 1995/12/06 20:34:38 vixie Exp $
*/
/*
@@ -65,8 +65,8 @@
/* ONE_WEEK maximum ttl */
DECL int max_cache_ttl INIT(7*24*60*60);
- /* 5 minute minimum ttl */
-DECL int min_cache_ttl INIT(5*60);
+ /* no minimum ttl */
+DECL int min_cache_ttl INIT(0);
/* current line number */
DECL int lineno;
diff --git a/usr.sbin/named/db_glue.c b/usr.sbin/named/db_glue.c
index ff9c06d..a3a7050 100644
--- a/usr.sbin/named/db_glue.c
+++ b/usr.sbin/named/db_glue.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_glue.c 4.4 (Berkeley) 6/1/90";
-static char rcsid[] = "$Id: db_glue.c,v 1.1.1.3 1995/10/23 09:26:04 peter Exp $";
+static char rcsid[] = "$Id: db_glue.c,v 8.10 1995/12/22 10:20:30 vixie Exp $";
#endif /* not lint */
/*
@@ -80,7 +80,8 @@ struct valuelist {
char *name;
char *proto;
int port;
-} *servicelist, *protolist;
+};
+static struct valuelist *servicelist, *protolist;
#if defined(ultrix)
/* ultrix 4.0 has some icky packaging details. work around them here.
@@ -98,13 +99,14 @@ const char *
sin_ntoa(sin)
const struct sockaddr_in *sin;
{
- static char ret[sizeof("[111.222.333.444].55555")];
+ static char ret[sizeof "[111.222.333.444].55555"];
if (!sin)
strcpy(ret, "[sin_ntoa(NULL)]");
else
sprintf(ret, "[%s].%u",
- inet_ntoa(sin->sin_addr), ntohs(sin->sin_port));
+ inet_ntoa(sin->sin_addr),
+ ntohs(sin->sin_port));
return (ret);
}
@@ -120,7 +122,7 @@ panic(err, msg)
syslog(LOG_CRIT, "%s - ABORT", msg);
else
syslog(LOG_CRIT, "%s: %s - ABORT", msg, strerror(err));
- signal(SIGIOT, SIG_DFL);
+ signal(SIGIOT, SIG_DFL); /* no POSIX needed here. */
abort();
}
@@ -137,9 +139,11 @@ buildservicelist()
#endif
while (sp = getservent()) {
slp = (struct valuelist *)malloc(sizeof(struct valuelist));
+ if (!slp)
+ panic(errno, "malloc(servent)");
slp->name = savestr(sp->s_name);
slp->proto = savestr(sp->s_proto);
- slp->port = ntohs((u_int16_t)sp->s_port);
+ slp->port = ntohs((u_int16_t)sp->s_port); /* host byt order */
slp->next = servicelist;
slp->prev = NULL;
if (servicelist)
@@ -162,8 +166,10 @@ buildprotolist()
#endif
while (pp = getprotoent()) {
slp = (struct valuelist *)malloc(sizeof(struct valuelist));
+ if (!slp)
+ panic(errno, "malloc(protoent)");
slp->name = savestr(pp->p_name);
- slp->port = pp->p_proto;
+ slp->port = pp->p_proto; /* host byte order */
slp->next = protolist;
slp->prev = NULL;
if (protolist)
@@ -191,7 +197,7 @@ findservice(s, list)
lp->next = *list;
*list = lp;
}
- return (lp->port);
+ return (lp->port); /* host byte order */
}
if (sscanf(s, "%d", &n) != 1 || n <= 0)
n = -1;
@@ -220,12 +226,12 @@ protocolnumber(p)
#if defined(__STDC__) || defined(__GNUC__)
static struct servent *
-cgetservbyport(u_int16_t port,
+cgetservbyport(u_int16_t port, /* net byte order */
char *proto)
#else
static struct servent *
cgetservbyport(port, proto)
- u_int16_t port;
+ u_int16_t port; /* net byte order */
char *proto;
#endif
{
@@ -233,9 +239,9 @@ cgetservbyport(port, proto)
register struct valuelist *lp = *list;
static struct servent serv;
- port = htons(port);
+ port = ntohs(port);
for (; lp != NULL; lp = lp->next) {
- if (port != (u_int16_t)lp->port)
+ if (port != (u_int16_t)lp->port) /* host byte order */
continue;
if (strcasecmp(lp->proto, proto) == 0) {
if (lp != *list) {
@@ -257,14 +263,14 @@ cgetservbyport(port, proto)
static struct protoent *
cgetprotobynumber(proto)
- register int proto;
+ register int proto; /* host byte order */
{
register struct valuelist **list = &protolist;
register struct valuelist *lp = *list;
static struct protoent prot;
for (; lp != NULL; lp = lp->next)
- if (lp->port == proto) {
+ if (lp->port == proto) { /* host byte order */
if (lp != *list) {
lp->prev->next = lp->next;
if (lp->next)
@@ -274,7 +280,7 @@ cgetprotobynumber(proto)
*list = lp;
}
prot.p_name = lp->name;
- prot.p_proto = lp->port;
+ prot.p_proto = lp->port; /* host byte order */
return (&prot);
}
return (0);
@@ -297,11 +303,11 @@ protocolname(num)
#if defined(__STDC__) || defined(__GNUC__)
char *
-servicename(u_int16_t port, char *proto)
+servicename(u_int16_t port, char *proto) /* host byte order */
#else
char *
servicename(port, proto)
- u_int16_t port;
+ u_int16_t port; /* host byte order */
char *proto;
#endif
{
@@ -428,27 +434,12 @@ savestr(str)
char *cp;
cp = (char *)malloc(strlen(str) + 1);
- if (cp == NULL)
- panic(errno, "savestr: malloc");
- (void) strcpy(cp, str);
+ if (!cp)
+ panic(errno, "malloc(savestr)");
+ strcpy(cp, str);
return (cp);
}
-/*
- * Uniform formatting of IP/UDP addresses.
- */
-const char *
-inet_etoa(sin)
- const struct sockaddr_in *sin;
-{
- static char retbuf[sizeof("[xxx.xxx.xxx.xxx].xxxxx")];
-
- (void) sprintf(retbuf, "[%s].%u",
- inet_ntoa(sin->sin_addr),
- ntohs(sin->sin_port));
- return (retbuf);
-}
-
int
writemsg(rfd, msg, msglen)
int rfd;
@@ -654,10 +645,8 @@ saveinv()
register struct invbuf *ip;
ip = (struct invbuf *) malloc(sizeof(struct invbuf));
- if (ip == NULL) {
- syslog(LOG_ERR, "saveinv: malloc: %m");
- exit(1);
- }
+ if (!ip)
+ panic(errno, "malloc(saveinv)");
ip->i_next = NULL;
bzero((char *)ip->i_dname, sizeof(ip->i_dname));
return (ip);
@@ -1059,7 +1048,7 @@ loc_ntoa(binary,ascii)
const u_char *binary;
char *ascii;
{
- char tmpbuf[255*3];
+ static char tmpbuf[255*3];
register char *cp;
register const u_char *rcp;
@@ -1078,12 +1067,7 @@ loc_ntoa(binary,ascii)
char *sizestr, *hpstr, *vpstr;
rcp = binary;
- if (ascii)
- cp = ascii;
- else {
- ascii = tmpbuf;
- cp = tmpbuf;
- }
+ cp = (ascii != NULL) ? ascii : tmpbuf;
versionval = *rcp++;
@@ -1193,3 +1177,48 @@ data_inaddr(data)
ret.s_addr = tmp;
return (ret);
}
+
+/* Signal abstraction. */
+
+void
+setsignal(catch, block, handler)
+ int catch, block;
+ SIG_FN (*handler)();
+{
+#ifdef POSIX_SIGNALS
+ /* Modern system - preferred. */
+ struct sigaction sa;
+ memset(&sa, 0, sizeof sa);
+ sa.sa_handler = handler;
+ sigemptyset(&sa.sa_mask);
+ if (block != -1)
+ sigaddset(&sa.sa_mask, block);
+ (void) sigaction(catch, &sa, NULL);
+#else /*POSIX_SIGNALS*/
+#ifdef SYSV
+ /* Ancient system - ugly. */
+ if (block != -1)
+ syslog(LOG_DEBUG, "danger - unable to block signal %d from %d",
+ block, catch);
+ (void) signal(catch, handler);
+#else /*SYSV*/
+ /* BSD<=4.3 system - odd. */
+ struct sigvec sv;
+ bzero(&sv, sizeof sv);
+ sv.sv_handler = handler;
+ sv.sv_mask = sigmask(block);
+ (void) sigvec(catch, &sv, NULL);
+#endif /*SYSV*/
+#endif /*POSIX_SIGNALS*/
+}
+
+void
+resignal(catch, block, handler)
+ int catch, block;
+ SIG_FN (*handler)();
+{
+#if !defined(POSIX_SIGNALS) && defined(SYSV)
+ /* Unreliable signals. Set it back up again. */
+ setsignal(catch, block, handler);
+#endif
+}
diff --git a/usr.sbin/named/db_load.c b/usr.sbin/named/db_load.c
index 5c36196..357f4f8 100644
--- a/usr.sbin/named/db_load.c
+++ b/usr.sbin/named/db_load.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_load.c 4.38 (Berkeley) 3/2/91";
-static char rcsid[] = "$Id: db_load.c,v 8.10 1995/07/04 06:35:12 vixie Exp $";
+static char rcsid[] = "$Id: db_load.c,v 8.15 1995/12/31 23:28:17 vixie Exp $";
#endif /* not lint */
/*
@@ -72,6 +72,7 @@ static char rcsid[] = "$Id: db_load.c,v 8.10 1995/07/04 06:35:12 vixie Exp $";
#include <ctype.h>
#include <netdb.h>
#include <resolv.h>
+#include <errno.h>
#include "named.h"
@@ -168,7 +169,7 @@ db_load(filename, in_origin, zp, def_domain)
struct zoneinfo *zp;
const char *def_domain;
{
- static int read_soa, read_ns;
+ static int read_soa, read_ns, rrcount;
register char *cp;
register struct map *mp;
char domain[MAXDNAME];
@@ -177,22 +178,24 @@ db_load(filename, in_origin, zp, def_domain)
char buf[MAXDATA];
char data[MAXDATA];
const char *cp1, *op;
- int c, class, type, ttl, dbflags, dataflags, multiline;
+ int c, class, type, dbflags, dataflags, multiline;
+ u_int32_t ttl;
struct databuf *dp;
FILE *fp;
- int slineno, i, errs, didinclude, rrcount;
+ int slineno, i, errs, didinclude;
register u_int32_t n;
struct stat sb;
struct in_addr ina;
+ int escape;
#ifdef DO_WARN_SERIAL
u_int32_t serial;
#endif
errs = 0;
didinclude = 0;
- rrcount = 0;
if (!def_domain) {
/* This is not the result of a $INCLUDE. */
+ rrcount = 0;
read_soa = 0;
read_ns = 0;
clev = db_getclev(in_origin);
@@ -204,7 +207,7 @@ db_load(filename, in_origin, zp, def_domain)
(void) strcpy(origin, in_origin);
if ((fp = fopen(filename, "r")) == NULL) {
- syslog(LOG_NOTICE, "%s: %m", filename);
+ syslog(LOG_WARNING, "%s: %m", filename);
dprintf(1, (ddt, "db_load: error opening file %s\n",
filename));
return (-1);
@@ -223,7 +226,7 @@ db_load(filename, in_origin, zp, def_domain)
}
gettime(&tt);
if (fstat(fileno(fp), &sb) < 0) {
- syslog(LOG_NOTICE, "%s: %m", filename);
+ syslog(LOG_WARNING, "%s: %m", filename);
sb.st_mtime = (int)tt.tv_sec;
}
slineno = lineno;
@@ -237,10 +240,10 @@ db_load(filename, in_origin, zp, def_domain)
while ((c = gettoken(fp, filename)) != EOF) {
switch (c) {
case INCLUDE:
- if (!getword((char *)buf, sizeof(buf), fp))
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
/* file name*/
break;
- if (!getword(tmporigin, sizeof(tmporigin), fp))
+ if (!getword(tmporigin, sizeof(tmporigin), fp, 1))
strcpy(tmporigin, origin);
else {
makename(tmporigin, origin);
@@ -252,7 +255,7 @@ db_load(filename, in_origin, zp, def_domain)
case ORIGIN:
(void) strcpy((char *)buf, origin);
- if (!getword(origin, sizeof(origin), fp))
+ if (!getword(origin, sizeof(origin), fp, 1))
break;
dprintf(3, (ddt, "db_load: origin %s, buf %s\n",
origin, buf));
@@ -261,7 +264,7 @@ db_load(filename, in_origin, zp, def_domain)
continue;
case DNAME:
- if (!getword(domain, sizeof(domain), fp))
+ if (!getword(domain, sizeof(domain), fp, 1))
break;
n = strlen(domain) - 1;
if (domain[n] == '.')
@@ -281,13 +284,13 @@ db_load(filename, in_origin, zp, def_domain)
/* FALLTHROUGH */
case CURRENT:
gotdomain:
- if (!getword((char *)buf, sizeof(buf), fp)) {
+ if (!getword((char *)buf, sizeof(buf), fp, 0)) {
if (c == CURRENT)
continue;
break;
}
cp = buf;
- ttl = 0;
+ ttl = USE_MINIMUM;
if (isdigit(*cp)) {
n = 0;
do {
@@ -309,14 +312,14 @@ db_load(filename, in_origin, zp, def_domain)
n += sb.st_mtime;
}
ttl = n;
- if (!getword((char *)buf, sizeof(buf), fp))
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
break;
}
for (mp = m_class; mp < m_class+M_CLASS_CNT; mp++)
if (!strcasecmp((char *)buf, mp->token)) {
class = mp->val;
(void) getword((char *)buf,
- sizeof(buf), fp);
+ sizeof(buf), fp, 0);
break;
}
for (mp = m_type; mp < m_type+M_TYPE_CNT; mp++)
@@ -337,7 +340,22 @@ db_load(filename, in_origin, zp, def_domain)
*/
if (type != T_UNSPEC) {
#endif
- if (!getword((char *)buf, sizeof(buf), fp))
+ switch (type) {
+ case T_SOA:
+ case T_MINFO:
+ case T_RP:
+ case T_NS:
+ case T_CNAME:
+ case T_MB:
+ case T_MG:
+ case T_MR:
+ case T_PTR:
+ escape = 1;
+ break;
+ default:
+ escape = 0;
+ }
+ if (!getword((char *)buf, sizeof(buf), fp, escape))
break;
dprintf(3,
(ddt,
@@ -375,7 +393,7 @@ db_load(filename, in_origin, zp, def_domain)
if (n == 0)
goto err;
n++;
- if (!getword((char *)buf, sizeof(buf), fp))
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
i = 0;
else {
endline(fp);
@@ -416,7 +434,8 @@ db_load(filename, in_origin, zp, def_domain)
makename(data, origin);
cp = data + strlen((char *)data) + 1;
if (!getword((char *)cp,
- (sizeof data) - (cp - data), fp))
+ (sizeof data) - (cp - data),
+ fp, 1))
goto err;
makename(cp, origin);
cp += strlen((char *)cp) + 1;
@@ -591,7 +610,7 @@ db_load(filename, in_origin, zp, def_domain)
cp = data;
PUTSHORT((u_int16_t)n, cp);
- if (!getword((char *)buf, sizeof(buf), fp))
+ if (!getword((char *)buf, sizeof(buf), fp, 1))
goto err;
(void) strcpy((char *)cp, (char *)buf);
makename(cp, origin);
@@ -614,13 +633,13 @@ db_load(filename, in_origin, zp, def_domain)
cp = data;
PUTSHORT((u_int16_t)n, cp);
- if (!getword((char *)buf, sizeof(buf), fp))
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
goto err;
(void) strcpy((char *)cp, (char *)buf);
makename(cp, origin);
/* advance pointer to next field */
cp += strlen((char *)cp) +1;
- if (!getword((char *)buf, sizeof(buf), fp))
+ if (!getword((char *)buf, sizeof(buf), fp, 0))
goto err;
(void) strcpy((char *)cp, (char *)buf);
makename(cp, origin);
@@ -675,10 +694,10 @@ db_load(filename, in_origin, zp, def_domain)
while ((i = getc(fp), *cp = i, i != EOF)
&& *cp != '\n'
&& (n < MAXDATA)) {
- cp++; n++;
+ cp++; n++;
}
if (*cp == '\n') /* leave \n for getword */
- ungetc(*cp, fp);
+ ungetc(*cp, fp);
*cp = '\0';
/* now process the whole line */
n = loc_aton(buf, (u_char *)data);
@@ -787,7 +806,8 @@ db_load(filename, in_origin, zp, def_domain)
msg = "no relevant RRs found";
if (msg != NULL) {
errs++;
- syslog(LOG_NOTICE, "Zone \"%s\" (file %s): %s",
+ syslog(LOG_WARNING,
+ "Zone \"%s\" (file %s): %s",
zp->z_origin, filename, msg);
}
}
@@ -831,7 +851,7 @@ gettoken(fp, src)
return (EOF);
case '$':
- if (getword(op, sizeof(op), fp)) {
+ if (getword(op, sizeof(op), fp, 0)) {
if (!strcasecmp("include", op))
return (INCLUDE);
if (!strcasecmp("origin", op))
@@ -869,52 +889,59 @@ gettoken(fp, src)
}
/* int
- * getword(buf, size, fp)
+ * getword(buf, size, fp, preserve)
* get next word, skipping blanks & comments.
+ * '\' '\n' outside of "quotes" is considered a blank.
* parameters:
* buf - destination
* size - of destination
* fp - file to read from
+ * preserve - should we preserve \ before \\ and \.?
* return value:
* 0 = no word; perhaps EOL or EOF
* 1 = word was read
*/
int
-getword(buf, size, fp)
+getword(buf, size, fp, preserve)
char *buf;
int size;
FILE *fp;
+ int preserve;
{
- register char *cp;
+ register char *cp = buf;
register int c;
- empty_token = 0;
- for (cp = buf; (c = getc(fp)) != EOF; ) {
+ empty_token = 0; /* XXX global side effect. */
+ while ((c = getc(fp)) != EOF) {
if (c == ';') {
+ /* Comment. Skip to end of line. */
while ((c = getc(fp)) != EOF && c != '\n')
- ;
+ NULL;
c = '\n';
}
if (c == '\n') {
+ /*
+ * Unescaped newline. It's a terminator unless we're
+ * already midway into a token.
+ */
if (cp != buf)
ungetc(c, fp);
else
lineno++;
break;
}
- if (isspace(c)) {
- while (isspace(c = getc(fp)) && c != '\n')
- ;
- ungetc(c, fp);
- if (cp != buf) /* Trailing whitespace */
- break;
- continue; /* Leading whitespace */
- }
if (c == '"') {
- while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
+ /* "Quoted string." Gather the whole string here. */
+ while ((c = getc(fp)) != EOF && c!='"' && c!='\n') {
if (c == '\\') {
if ((c = getc(fp)) == EOF)
c = '\\';
+ if (preserve &&
+ (c == '\\' || c == '.')) {
+ if (cp >= buf+size-1)
+ break;
+ *cp++ = '\\';
+ }
if (c == '\n')
lineno++;
}
@@ -922,24 +949,42 @@ getword(buf, size, fp)
break;
*cp++ = c;
}
+ /*
+ * Newline string terminators are
+ * not token terminators.
+ */
if (c == '\n') {
lineno++;
break;
}
+ /* Sample following character, check for terminator. */
if ((c = getc(fp)) != EOF)
ungetc(c, fp);
- if (c == EOF || isspace(c) || c == '\n') {
+ if (c == EOF || isspace(c)) {
*cp = '\0';
return (1);
}
- else
- continue;
+ continue;
}
if (c == '\\') {
+ /* Do escape processing. */
if ((c = getc(fp)) == EOF)
c = '\\';
- if (c == '\n')
- lineno++;
+ if (preserve && (c == '\\' || c == '.')) {
+ if (cp >= buf+size-1)
+ break;
+ *cp++ = '\\';
+ }
+ }
+ if (isspace(c)) {
+ /* Blank of some kind. Skip run. */
+ while (isspace(c = getc(fp)) && c != '\n')
+ NULL;
+ ungetc(c, fp);
+ /* Blank means terminator if the token is nonempty. */
+ if (cp != buf) /* Trailing whitespace */
+ break;
+ continue; /* Leading whitespace */
}
if (cp >= buf+size-1)
break;
@@ -1163,7 +1208,7 @@ getprotocol(fp, src)
int k;
char b[MAXLEN];
- (void) getword(b, sizeof(b), fp);
+ (void) getword(b, sizeof(b), fp, 0);
k = protocolnumber(b);
if (k == -1)
@@ -1190,7 +1235,7 @@ getservices(n, data, fp, src)
bm[j] = 0;
maxl = 0;
bracket = 0;
- while (getword(b, sizeof(b), fp) || bracket) {
+ while (getword(b, sizeof(b), fp, 0) || bracket) {
if (feof(fp) || ferror(fp))
break;
if (strlen(b) == 0)
@@ -1257,14 +1302,16 @@ get_netlist(fp, netlistp, allow, print_tag)
;
ntp = NULL;
dprintf(1, (ddt, "get_netlist(%s)", print_tag));
- while (getword(buf, sizeof(buf), fp)) {
+ while (getword(buf, sizeof(buf), fp, 0)) {
if (strlen(buf) == 0)
break;
if ((maskp = strchr(buf, '&')) != NULL)
*maskp++ = '\0';
dprintf(1, (ddt," %s", buf));
- if (ntp == NULL) {
+ if (!ntp) {
ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
+ if (!ntp)
+ panic(errno, "malloc(netinfo)");
}
if (!inet_aton(buf, &ntp->my_addr)) {
syslog(LOG_INFO, "%s contains bogus element (%s)",
diff --git a/usr.sbin/named/db_lookup.c b/usr.sbin/named/db_lookup.c
index db7cd97..e46d37c 100644
--- a/usr.sbin/named/db_lookup.c
+++ b/usr.sbin/named/db_lookup.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_lookup.c 4.18 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: db_lookup.c,v 8.2 1995/06/29 09:26:17 vixie Exp $";
+static char rcsid[] = "$Id: db_lookup.c,v 8.3 1995/12/06 20:34:38 vixie Exp $";
#endif /* not lint */
/*
@@ -90,12 +90,13 @@ nlookup(name, htpp, fname, insert)
register unsigned hval;
register struct hashbuf *htp;
struct namebuf *parent = NULL;
+ int escaped = 0;
htp = *htpp;
hval = 0;
*fname = "???";
for (cp = name; c = *cp++; ) {
- if (c == '.') {
+ if (!escaped && (c == '.')) {
parent = np = nlookup(cp, htpp, fname, insert);
if (np == NULL)
return (NULL);
@@ -116,6 +117,10 @@ nlookup(name, htpp, fname, insert)
}
hval <<= HASHSHIFT;
hval += (isupper(c) ? tolower(c) : c) & HASHMASK;
+ if (escaped)
+ escaped = 0;
+ else if (c == '\\')
+ escaped = 1;
}
cp--;
/*
diff --git a/usr.sbin/named/db_secure.c b/usr.sbin/named/db_secure.c
index 9c418f4..870f8c5 100644
--- a/usr.sbin/named/db_secure.c
+++ b/usr.sbin/named/db_secure.c
@@ -1,5 +1,5 @@
#ifndef LINT
-static char rcsid[] = "$Id: db_secure.c,v 8.4 1995/06/29 09:26:17 vixie Exp $";
+static char rcsid[] = "$Id: db_secure.c,v 8.5 1995/12/06 20:34:38 vixie Exp $";
#endif
/* this file was contributed by Gregory Neil Shapiro of WPI in August 1993 */
@@ -11,6 +11,7 @@ static char rcsid[] = "$Id: db_secure.c,v 8.4 1995/06/29 09:26:17 vixie Exp $";
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <syslog.h>
+#include <errno.h>
#include "named.h"
@@ -74,18 +75,8 @@ build_secure_netlist(zp)
zp->z_origin, buf));
if (ntp == NULL) {
ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
- if (!ntp) {
- dprintf(1, (ddt,
- "build_secure_netlist (%s): malloc fail\n",
- zp->z_origin));
- syslog(LOG_NOTICE,
- "build_secure_netlist (%s): Out of Memory",
- zp->z_origin);
- if (!securezone) {
- zp->secure_nets = NULL;
- }
- return (1);
- }
+ if (!ntp)
+ panic(errno, "malloc(netinfo)");
}
if (!inet_aton(buf, &ntp->my_addr)) {
syslog(LOG_INFO,
@@ -148,7 +139,8 @@ build_secure_netlist(zp)
if (debug > 1) {
for (ntp = *netlistp; ntp != NULL; ntp = ntp->next) {
fprintf(ddt, "ntp x%lx addr x%lx mask x%lx",
- (u_long)ntp, ntp->addr, ntp->mask);
+ (u_long)ntp, (u_long)ntp->addr,
+ (u_long)ntp->mask);
fprintf(ddt, " my_addr %#lx",
(u_long)ntp->my_addr.s_addr);
fprintf(ddt, " %s", inet_ntoa(ntp->my_addr));
diff --git a/usr.sbin/named/db_update.c b/usr.sbin/named/db_update.c
index 70e7bde..523f967 100644
--- a/usr.sbin/named/db_update.c
+++ b/usr.sbin/named/db_update.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)db_update.c 4.28 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: db_update.c,v 8.6 1995/06/29 09:26:17 vixie Exp $";
+static char rcsid[] = "$Id: db_update.c,v 8.7 1995/12/06 20:34:38 vixie Exp $";
#endif /* not lint */
/*
@@ -343,11 +343,6 @@ db_update(name, odp, newdp, flags, htp)
if (!newdp || newdp->d_class != dp->d_class)
goto skip;
- /* XXX:
- * The next three clauses do not deal
- * correctly with glue records. mpa.
- */
-
/* if the new data is authorative
* remove any data for this domain with
* the same class that isn't as credable
@@ -360,12 +355,14 @@ db_update(name, odp, newdp, flags, htp)
*/
goto delete;
+#if 0 /* caught by findMyZone() now. */
/* if we have authoritative data for a
* node, don't add in other data.
*/
if (dp->d_cred == DB_C_ZONE &&
newdp->d_cred < dp->d_cred)
return (AUTH);
+#endif
/* if the new data is authoritative but
* but isn't as credible, reject it.
diff --git a/usr.sbin/named/dmalloc.c b/usr.sbin/named/dmalloc.c
index 50db523..3c42a52 100644
--- a/usr.sbin/named/dmalloc.c
+++ b/usr.sbin/named/dmalloc.c
@@ -3,7 +3,7 @@
* vix 24mar92 [added size calcs, improved printout]
* vix 22mar92 [original work]
*
- * $Id: dmalloc.c,v 8.1 1994/12/15 06:24:14 vixie Exp $
+ * $Id: dmalloc.c,v 8.2 1995/12/06 20:34:38 vixie Exp $
*/
/*
@@ -198,6 +198,8 @@ dmalloc(file, line, size)
c = findCaller(&Callers, file, line, TRUE);
d = (datum *) malloc(sizeof(datum) + size);
+ if (!d)
+ return (NULL);
d->size = size;
d->caller = ((char *)c) - memory;
c->calls++;
diff --git a/usr.sbin/named/ns_defs.h b/usr.sbin/named/ns_defs.h
index 0a21a71..054ff81 100644
--- a/usr.sbin/named/ns_defs.h
+++ b/usr.sbin/named/ns_defs.h
@@ -1,6 +1,6 @@
/*
* from ns.h 4.33 (Berkeley) 8/23/90
- * $Id: ns_defs.h,v 8.2 1995/06/19 20:55:40 vixie Exp $
+ * $Id: ns_defs.h,v 8.4 1995/12/22 10:20:30 vixie Exp $
*/
/*
@@ -102,9 +102,17 @@
#define BETA 1.2 /* How much to penalize response time on failure */
#define GAMMA 0.98 /* How much to decay unused response times */
+#define USE_MINIMUM 0xffffffff
+
/* sequence-space arithmetic */
#define SEQ_GT(a,b) ((int32_t)((a)-(b)) > 0)
+ /* wildcard predicate */
+#define WILDCARD_P(str) (str[0] == '*' && str[1] == '\0')
+
+ /* cheap garbage collection */
+#define FREE_ONCE(p) { if (p) { free(p); p = NULL; } }
+
/* these fields are ordered to maintain word-alignment;
* be careful about changing them.
*/
@@ -167,6 +175,8 @@ struct notify {
#define Z_DYNADDONLY 0x0800 /* dynamic mode: add new data only */
#define Z_CHANGED 0x1000 /* zone has changed */
#endif /* ALLOW_UPDATES */
+#define Z_XFER_ABORTED 0x2000 /* zone transfer has been aborted */
+#define Z_XFER_GONE 0x4000 /* zone transfer process is gone */
/* named_xfer exit codes */
#define XFER_UPTODATE 0 /* zone is up-to-date */
@@ -217,7 +227,7 @@ struct qinfo {
int16_t q_nqueries; /* # of queries required */
struct qstream *q_stream; /* TCP stream, null if UDP */
struct zoneinfo *q_zquery; /* Zone query is about (Q_ZSERIAL) */
-#ifdef LAME_DELEGATION
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
char q_domain[MAXDNAME]; /* domain for servers we are querying */
#endif
#ifdef BIND_NOTIFY
diff --git a/usr.sbin/named/ns_forw.c b/usr.sbin/named/ns_forw.c
index 4bb7202..a756a78 100644
--- a/usr.sbin/named/ns_forw.c
+++ b/usr.sbin/named/ns_forw.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_forw.c 4.32 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: ns_forw.c,v 1.1.1.3 1995/10/23 09:26:14 peter Exp $";
+static char rcsid[] = "$Id: ns_forw.c,v 8.9 1995/12/22 10:20:30 vixie Exp $";
#endif /* not lint */
/*
@@ -119,7 +119,7 @@ ns_forw(nsp, msg, msglen, fp, qsp, dfd, qpp, dname, np)
}
qp = qnew();
-#ifdef LAME_DELEGATION
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
getname(np, qp->q_domain, sizeof qp->q_domain);
#endif
qp->q_from = *fp; /* nslookup wants to know this */
@@ -127,7 +127,7 @@ ns_forw(nsp, msg, msglen, fp, qsp, dfd, qpp, dname, np)
dprintf(2, (ddt, "forw: nslookup reports danger\n"));
qfree(qp);
return (FW_SERVFAIL);
- } else if (n == 0 && !(forward_only && fwdtab)) {
+ } else if (n == 0 && !fwdtab) {
dprintf(2, (ddt, "forw: no nameservers found\n"));
qfree(qp);
return (FW_NOSERVER);
@@ -139,9 +139,9 @@ ns_forw(nsp, msg, msglen, fp, qsp, dfd, qpp, dname, np)
qp->q_id = id;
qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2;
hp->id = qp->q_nsid = htons(nsid_next());
- hp->ancount = 0;
- hp->nscount = 0;
- hp->arcount = 0;
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
if ((qp->q_msg = (u_char *)malloc((unsigned)msglen)) == NULL) {
syslog(LOG_NOTICE, "forw: malloc: %m");
qfree(qp);
@@ -251,16 +251,18 @@ haveComplained(tag1, tag2)
}
if (!r) {
cur = (struct complaint *)malloc(sizeof(struct complaint));
- cur->tag1 = tag1;
- cur->tag2 = tag2;
- cur->expire = tt.tv_sec + INIT_REFRESH; /* "10 minutes" */
- cur->next = NULL;
- if (prev)
- prev->next = cur;
- else
- List = cur;
+ if (cur) {
+ cur->tag1 = tag1;
+ cur->tag2 = tag2;
+ cur->expire = tt.tv_sec + INIT_REFRESH; /* "10:00" */
+ cur->next = NULL;
+ if (prev)
+ prev->next = cur;
+ else
+ List = cur;
+ }
}
- return r;
+ return (r);
}
/* void
@@ -272,21 +274,52 @@ haveComplained(tag1, tag2)
* complaint is a string describing what is wrong.
* dname and a_rr are the problematic other name server.
*/
-void
-nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr)
+static void
+nslookupComplain(sysloginfo, queryname, complaint, dname, a_rr, nsdp)
const char *sysloginfo, *queryname, *complaint, *dname;
- const struct databuf *a_rr;
+ const struct databuf *a_rr, *nsdp;
{
+#ifdef STATS
+ char nsbuf[20];
+ char abuf[20];
+#endif
+ char *a, *ns;
+
dprintf(2, (ddt, "NS '%s' %s\n", dname, complaint));
if (sysloginfo && queryname && !haveComplained(queryname, complaint))
{
char buf[999];
+ a = ns = (char *)NULL;
+#ifdef STATS
+ if (nsdp) {
+ if (nsdp->d_ns) {
+ strcpy(nsbuf, inet_ntoa(nsdp->d_ns->addr));
+ ns = nsbuf;
+ } else {
+ ns = zones[nsdp->d_zone].z_origin;
+ }
+ }
+ if (a_rr->d_ns) {
+ strcpy(abuf, inet_ntoa(a_rr->d_ns->addr));
+ a = abuf;
+ } else {
+ a = zones[a_rr->d_zone].z_origin;
+ }
+#endif
/* syslog only takes 5 params */
- sprintf(buf, "%s: query(%s) %s (%s:%s)",
- sysloginfo, queryname,
- complaint, dname,
- inet_ntoa(data_inaddr(a_rr->d_data)));
+ if ( a != NULL || ns != NULL)
+ sprintf(buf, "%s: query(%s) %s (%s:%s) learnt (A=%s:NS=%s)",
+ sysloginfo, queryname,
+ complaint, dname,
+ inet_ntoa(data_inaddr(a_rr->d_data)),
+ a ? a : "<Not Available>",
+ ns ? ns : "<Not Available>" );
+ else
+ sprintf(buf, "%s: query(%s) %s (%s:%s)",
+ sysloginfo, queryname,
+ complaint, dname,
+ inet_ntoa(data_inaddr(a_rr->d_data)));
syslog(LOG_INFO, buf);
}
}
@@ -370,30 +403,34 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
if (dp->d_type != T_A || dp->d_class != class)
continue;
if (data_inaddr(dp->d_data).s_addr == INADDR_ANY) {
- syslog(LOG_INFO, "Bogus (0.0.0.0) A RR for %s",
- dname);
+ static char *complaint = "Bogus (0.0.0.0) A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
continue;
}
#ifdef INADDR_LOOPBACK
if (ntohl(data_inaddr(dp->d_data).s_addr) ==
INADDR_LOOPBACK) {
- syslog(LOG_INFO, "Bogus LOOPBACK A RR for %s",
- dname);
+ static char *complaint = "Bogus LOOPBACK A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
continue;
}
#endif
#ifdef INADDR_BROADCAST
if (ntohl(data_inaddr(dp->d_data).s_addr) ==
INADDR_BROADCAST) {
- syslog(LOG_INFO, "Bogus BROADCAST A RR for %s",
- dname);
+ static char *complaint = "Bogus BROADCAST A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
continue;
}
#endif
#ifdef IN_MULTICAST
if (IN_MULTICAST(ntohl(data_inaddr(dp->d_data).s_addr))) {
- syslog(LOG_INFO, "Bogus MULTICAST A RR for %s",
- dname);
+ static char *complaint = "Bogus MULTICAST A RR";
+ nslookupComplain(sysloginfo, syslogdname,
+ complaint, dname, dp, nsdp);
continue;
}
#endif
@@ -461,7 +498,7 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
if (aIsUs(nsa)) {
static char *complaint = "contains our address";
nslookupComplain(sysloginfo, syslogdname,
- complaint, dname, dp);
+ complaint, dname, dp, nsdp);
return (-1);
}
/*
@@ -475,7 +512,7 @@ nslookup(nsp, qp, syslogdname, sysloginfo)
{
static char *complaint = "forwarding loop";
nslookupComplain(sysloginfo, syslogdname,
- complaint, dname, dp);
+ complaint, dname, dp, nsdp);
return (-1);
}
#ifdef BOGUSNS
diff --git a/usr.sbin/named/ns_func.h b/usr.sbin/named/ns_func.h
index 6a8e3c5..5fa32d9 100644
--- a/usr.sbin/named/ns_func.h
+++ b/usr.sbin/named/ns_func.h
@@ -1,6 +1,6 @@
/* ns_func.h - declarations for ns_*.c's externally visible functions
*
- * $Id: ns_func.h,v 8.3 1995/06/29 09:26:17 vixie Exp $
+ * $Id: ns_func.h,v 8.6 1995/12/22 10:20:30 vixie Exp $
*/
/* ++from ns_resp.c++ */
@@ -22,7 +22,7 @@ extern int doupdate __P((u_char *, int, u_char *, int,
wanted __P((struct databuf *, int, int)),
add_data __P((struct namebuf *,
struct databuf **,
- u_char *, int));
+ u_char *, int, int *));
/* --from ns_resp.c-- */
/* ++from ns_req.c++ */
@@ -63,10 +63,7 @@ extern int ns_forw __P((struct databuf *nsp[],
const char *sysloginfo)),
qcomp __P((struct qserv *, struct qserv *));
extern struct qdatagram *aIsUs __P((struct in_addr));
-extern void nslookupComplain __P((const char *, const char *,
- const char *, const char *,
- const struct databuf *)),
- schedretry __P((struct qinfo *, time_t)),
+extern void schedretry __P((struct qinfo *, time_t)),
unsched __P((struct qinfo *)),
retry __P((struct qinfo *)),
qflush __P((void)),
@@ -108,7 +105,10 @@ extern void ns_maint __P((void)),
loadxfer __P((void)),
qserial_query __P((struct zoneinfo *)),
qserial_answer __P((struct qinfo *, u_int32_t));
-extern SIG_FN endxfer __P(());
+extern void holdsigchld __P((void));
+extern void releasesigchld __P((void));
+extern SIG_FN reapchild __P(());
+extern void endxfer __P((void));
extern const char * zoneTypeString __P((const struct zoneinfo *));
#ifdef DEBUG
extern void printzoneinfo __P((int));
@@ -147,15 +147,15 @@ extern void nameserIncr __P((struct in_addr addr,
/* ++from ns_validate.c++ */
extern int
#ifdef NCACHE
- validate __P((char *, struct sockaddr_in *,
+ validate __P((char *, char *, struct sockaddr_in *,
int, int, char *, int, int)),
#else
- validate __P((char *, struct sockaddr_in *,
+ validate __P((char *, char *, struct sockaddr_in *,
int, int, char *, int)),
#endif
dovalidate __P((u_char *, int, u_char *, int, int,
- struct sockaddr_in *, int *)),
+ char *, struct sockaddr_in *, int *)),
update_msg __P((u_char *, int *, int Vlist[], int));
-extern void store_name_addr __P((char *, struct in_addr,
- char *, char *));
+extern void store_name_addr __P((const char *, struct in_addr,
+ const char *, const char *));
/* --from ns_validate.c-- */
diff --git a/usr.sbin/named/ns_glob.h b/usr.sbin/named/ns_glob.h
index f37a85a..708d771 100644
--- a/usr.sbin/named/ns_glob.h
+++ b/usr.sbin/named/ns_glob.h
@@ -1,6 +1,6 @@
/*
* from ns.h 4.33 (Berkeley) 8/23/90
- * $Id: ns_glob.h,v 1.1.1.3 1995/10/23 09:26:16 peter Exp $
+ * $Id: ns_glob.h,v 8.6 1995/12/22 10:20:30 vixie Exp $
*/
/*
@@ -108,6 +108,9 @@ DECL int cache_interval INIT(60*60);
DECL int stats_interval INIT(60*60);
#endif
+ /* need to process finished zone transfers */
+DECL int needendxfer INIT(0);
+
/* need to reload secondary zone(s) */
DECL int needzoneload INIT(0);
@@ -142,9 +145,12 @@ DECL int needToExit INIT(0);
DECL int qrylog INIT(0);
#endif /*QRYLOG*/
- /* is this a root server that should therefore not recurse? */
+ /* should this server not recurse? */
DECL int NoRecurse INIT(0);
+ /* should this server never fetch glue? */
+DECL int NoFetchGlue INIT(0);
+
/*
* We keep a list of favored networks headed by nettab.
* There are three (possibly empty) parts to this list, in this order:
diff --git a/usr.sbin/named/ns_init.c b/usr.sbin/named/ns_init.c
index adf5d01..f5f4b51 100644
--- a/usr.sbin/named/ns_init.c
+++ b/usr.sbin/named/ns_init.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91";
-static char rcsid[] = "$Id: ns_init.c,v 1.1.1.3 1995/10/23 09:26:17 peter Exp $";
+static char rcsid[] = "$Id: ns_init.c,v 8.12 1995/12/29 07:16:18 vixie Exp $";
#endif /* not lint */
/*
@@ -69,7 +69,6 @@ static char rcsid[] = "$Id: ns_init.c,v 1.1.1.3 1995/10/23 09:26:17 peter Exp $"
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
-#include <assert.h>
#include "named.h"
@@ -101,7 +100,8 @@ ns_refreshtime(zp, timebase)
struct zoneinfo *zp;
time_t timebase;
{
- register time_t half = ((zp->z_refresh + 1) / 2);
+ u_long refresh = (zp->z_refresh > 0) ? zp->z_refresh : INIT_REFRESH;
+ time_t half = (refresh + 1) / 2;
zp->z_time = timebase + half + (rand() % half);
}
@@ -238,6 +238,8 @@ boot_read(filename, includefile)
if ((fp = fopen(filename, "r")) == NULL) {
syslog(LOG_ERR, "%s: %m", filename);
+ if (includefile)
+ return;
exit(1);
}
@@ -246,7 +248,7 @@ boot_read(filename, includefile)
while (!feof(fp) && !ferror(fp)) {
/* read named.boot keyword and process args */
- if (!getword(buf, sizeof(buf), fp)) {
+ if (!getword(buf, sizeof(buf), fp, 0)) {
/*
* This is a blank line, a commented line, or the
* '\n' of the previous line.
@@ -254,7 +256,7 @@ boot_read(filename, includefile)
continue;
}
if (strcasecmp(buf, "directory") == 0) {
- (void) getword(buf, sizeof(buf), fp);
+ (void) getword(buf, sizeof(buf), fp, 0);
if (chdir(buf) < 0) {
syslog(LOG_CRIT, "directory %s: %m\n",
buf);
@@ -268,11 +270,11 @@ boot_read(filename, includefile)
max_xfers_running = getnum(fp, filename, GETNUM_NONE);
continue;
} else if (strcasecmp(buf, "limit") == 0) {
- (void) getword(buf, sizeof(buf), fp);
+ (void) getword(buf, sizeof(buf), fp, 0);
ns_limit(buf, getnum(fp, filename, GETNUM_SCALED));
continue;
} else if (strcasecmp(buf, "options") == 0) {
- while (getword(buf, sizeof(buf), fp))
+ while (getword(buf, sizeof(buf), fp, 0))
ns_option(buf);
continue;
} else if (strcasecmp(buf, "forwarders") == 0) {
@@ -294,12 +296,12 @@ boot_read(filename, includefile)
#endif
#ifdef LOCALDOM
} else if (strcasecmp(buf, "domain") == 0) {
- if (getword(buf, sizeof(buf), fp))
+ if (getword(buf, sizeof(buf), fp, 1))
localdomain = savestr(buf);
continue;
#endif
} else if (strcasecmp(buf, "include") == 0) {
- if (getword(buf, sizeof(buf), fp))
+ if (getword(buf, sizeof(buf), fp, 0))
boot_read(buf, 1);
continue;
} else if (strncasecmp(buf, "cache", 5) == 0) {
@@ -351,7 +353,7 @@ boot_read(filename, includefile)
/*
* read zone origin
*/
- if (!getword(obuf, sizeof(obuf), fp)) {
+ if (!getword(obuf, sizeof(obuf), fp, 1)) {
syslog(LOG_NOTICE, "%s: line %d: missing origin\n",
filename, lineno);
continue;
@@ -367,7 +369,7 @@ boot_read(filename, includefile)
/*
* Read source file or host address.
*/
- if (!getword(buf, sizeof(buf), fp)) {
+ if (!getword(buf, sizeof(buf), fp, 0)) {
syslog(LOG_NOTICE, "%s: line %d: missing %s\n",
filename, lineno,
#ifdef STUBS
@@ -404,7 +406,7 @@ boot_read(filename, includefile)
zp = (struct zoneinfo *)
malloc((64 + nzones)
* sizeof(struct zoneinfo));
- if (zp == (struct zoneinfo *)0) {
+ if (!zp) {
syslog(LOG_NOTICE,
"no memory for more zones");
endline(fp);
@@ -431,7 +433,7 @@ boot_read(filename, includefile)
source = savestr(buf);
dprintf(1, (ddt, ", source = %s\n", source));
zp->z_refresh = 0; /* by default, no dumping */
- if (getword(buf, sizeof(buf), fp)) {
+ if (getword(buf, sizeof(buf), fp, 0)) {
#ifdef notyet
zp->z_refresh = atoi(buf);
if (zp->z_refresh <= 0) {
@@ -481,7 +483,7 @@ boot_read(filename, includefile)
case Z_PRIMARY:
source = savestr(buf);
#ifdef ALLOW_UPDATES
- if (getword(buf, sizeof(buf), fp)) {
+ if (getword(buf, sizeof(buf), fp, 0)) {
endline(fp);
flag = buf;
while (flag) {
@@ -564,7 +566,7 @@ boot_read(filename, includefile)
dprintf(1, (ddt,
"\nns.h NSMAX reached\n"));
}
- } while (getword(buf, sizeof(buf), fp));
+ } while (getword(buf, sizeof(buf), fp, 0));
dprintf(1, (ddt, "addrcnt = %d\n", zp->z_addrcnt));
if (!source) {
/*
@@ -610,7 +612,8 @@ boot_read(filename, includefile)
** Force secondary to try transfer right away
** after SIGHUP.
*/
- if (reloading) {
+ if (!(zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING))
+ && reloading) {
zp->z_time = tt.tv_sec;
needmaint = 1;
}
@@ -666,8 +669,10 @@ zoneinit(zp)
*/
zp->z_refresh = INIT_REFRESH;
zp->z_retry = INIT_REFRESH;
- zp->z_time = tt.tv_sec;
- needmaint = 1;
+ if (!(zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING))) {
+ zp->z_time = tt.tv_sec;
+ needmaint = 1;
+ }
} else {
zp->z_flags |= Z_AUTH;
}
@@ -706,6 +711,8 @@ findzone(dname, class)
string as the zone name */
dZoneNameLen = strlen(dZoneName);
for (zoneNum = 1; zoneNum < nzones; zoneNum++) {
+ if (zones[zoneNum].z_type == Z_NIL)
+ continue;
zoneName = (zones[zoneNum]).z_origin;
zoneNameLen = strlen(zoneName);
/* The zone name may or may not end with a '.' */
@@ -764,12 +771,15 @@ get_forwarders(fp)
}
#endif /* SLAVE_FORWARD */
- while (getword(buf, sizeof(buf), fp)) {
+ while (getword(buf, sizeof(buf), fp, 0)) {
if (strlen(buf) == 0)
break;
dprintf(1, (ddt," %s",buf));
- if (ftp == NULL)
+ if (!ftp) {
ftp = (struct fwdinfo *)malloc(sizeof(struct fwdinfo));
+ if (!ftp)
+ panic(errno, "malloc(fwdinfo)");
+ }
if (inet_aton(buf, &ftp->fwdaddr.sin_addr)) {
ftp->fwdaddr.sin_port = ns_port;
ftp->fwdaddr.sin_family = AF_INET;
@@ -930,6 +940,8 @@ ns_option(name)
{
if (!strcasecmp(name, "no-recursion")) {
NoRecurse = 1;
+ } else if (!strcasecmp(name, "no-fetch-glue")) {
+ NoFetchGlue = 1;
#ifdef QRYLOG
} else if (!strcasecmp(name, "query-log")) {
qrylog = 1;
diff --git a/usr.sbin/named/ns_main.c b/usr.sbin/named/ns_main.c
index 954bc13..6e10230 100644
--- a/usr.sbin/named/ns_main.c
+++ b/usr.sbin/named/ns_main.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_main.c 4.55 (Berkeley) 7/1/91";
-static char rcsid[] = "$Id: ns_main.c,v 1.1.1.3 1995/10/23 09:26:19 peter Exp $";
+static char rcsid[] = "$Id: ns_main.c,v 8.12 1995/12/29 07:16:18 vixie Exp $";
#endif /* not lint */
/*
@@ -62,12 +62,12 @@ static char rcsid[] = "$Id: ns_main.c,v 1.1.1.3 1995/10/23 09:26:19 peter Exp $"
char copyright[] =
"@(#) Copyright (c) 1986, 1989, 1990 The Regents of the University of California.\n\
portions Copyright (c) 1993 Digital Equipment Corporation\n\
- portions Copyright (c) 1993 Berkeley Network Software Consortium\n\
+ portions Copyright (c) 1995 Internet Software Consortium\n\
All rights reserved.\n";
#endif /* not lint */
/*
- * Internet Name server (see rfc883 & others).
+ * Internet Name server (see RCF1035 & others).
*/
#include <sys/param.h>
@@ -389,19 +389,14 @@ main(argc, argv, envp)
/*
* named would be terminated if one of these is sent and no handler.
*/
- (void) signal(SIGINT, setdumpflg);
- (void) signal(SIGQUIT, setchkptflg);
- (void) signal(SIGIOT, setstatsflg);
-#if defined(SIGUSR1) && defined(SIGUSR2)
- (void) signal(SIGUSR1, setIncrDbgFlg);
- (void) signal(SIGUSR2, setNoDbgFlg);
-#else /* SIGUSR1&&SIGUSR2 */
- (void) signal(SIGEMT, setIncrDbgFlg);
- (void) signal(SIGFPE, setNoDbgFlg);
-#endif /* SIGUSR1&&SIGUSR2 */
+ setsignal(SIGINT, -1, setdumpflg);
+ setsignal(SIGQUIT, -1, setchkptflg);
+ setsignal(SIGIOT, -1, setstatsflg);
+ setsignal(SIGUSR1, -1, setIncrDbgFlg);
+ setsignal(SIGUSR2, -1, setNoDbgFlg);
#if defined(SIGWINCH) && defined(QRYLOG)
- (void) signal(SIGWINCH, setQrylogFlg);
+ setsignal(SIGWINCH, -1, setQrylogFlg);
#endif
/*
@@ -428,50 +423,29 @@ main(argc, argv, envp)
time(&boottime);
resettime = boottime;
- (void) signal(SIGHUP, onhup);
+ setsignal(SIGALRM, SIGCHLD, maint_alarm);
+ setsignal(SIGCHLD, SIGALRM, reapchild);
+ setsignal(SIGPIPE, -1, (SIG_FN (*)())SIG_IGN);
+ setsignal(SIGHUP, -1, onhup);
+
#if defined(SIGXFSZ)
- (void) signal(SIGXFSZ, onhup); /* wierd DEC Hesiodism, harmless */
+ /* Wierd DEC Hesiodism, harmless. */
+ setsignal(SIGXFSZ, -1, onhup);
#endif
-#if defined(POSIX_SIGNALS)
- bzero((char *)&sact, sizeof(sact));
- sact.sa_handler = maint_alarm;
- sigemptyset(&sact.sa_mask);
- sigaddset(&sact.sa_mask, SIGCHLD);
- (void) sigaction(SIGALRM, &sact, (struct sigaction *)NULL);
-
- sact.sa_handler = endxfer;
- sigemptyset(&sact.sa_mask);
- sigaddset(&sact.sa_mask, SIGALRM);
- (void) sigaction(SIGCHLD, &sact, (struct sigaction *)NULL);
-#else
-#if defined(SYSV)
- (void) signal(SIGCLD, (SIG_FN (*)()) endxfer);
- (void) signal(SIGALRM, maint_alarm);
-#else
- bzero((char *)&vec, sizeof(vec));
- vec.sv_handler = maint_alarm;
- vec.sv_mask = sigmask(SIGCHLD);
- (void) sigvec(SIGALRM, &vec, (struct sigvec *)NULL);
-
- vec.sv_handler = endxfer;
- vec.sv_mask = sigmask(SIGALRM);
- (void) sigvec(SIGCHLD, &vec, (struct sigvec *)NULL);
-#endif /* SYSV */
-#endif /* POSIX_SIGNALS */
- (void) signal(SIGPIPE, SIG_IGN);
+
#ifdef SIGSYS
- (void) signal(SIGSYS, sigprof);
+ setsignal(SIGSYS, -1, sigprof);
#endif /* SIGSYS */
#ifdef ALLOW_UPDATES
/* Catch SIGTERM so we can dump the database upon shutdown if it
has changed since it was last dumped/booted */
- (void) signal(SIGTERM, onintr);
+ setsignal(SIGTERM, -1, onintr);
#endif
#ifdef XSTATS
/* Catch SIGTERM so we can write stats before exiting. */
- (void) signal(SIGTERM, onintr);
+ setsignal(SIGTERM, -1, onintr);
#endif
dprintf(1, (ddt, "database initialized\n"));
@@ -617,6 +591,12 @@ main(argc, argv, envp)
needStatsDump = 0;
ns_stats();
}
+ if (needendxfer) {
+ holdsigchld();
+ needendxfer = 0; /* should be safe even if not held */
+ endxfer(); /* releases SIGCHLD */
+ }
+ releasesigchld();
if (needzoneload) {
needzoneload = 0;
loadxfer();
@@ -845,11 +825,11 @@ main(argc, argv, envp)
}
if ((sp->s_bufp - (u_char *)&sp->s_tempsize) ==
INT16SZ) {
- sp->s_size = htons(sp->s_tempsize);
+ sp->s_size = ntohs(sp->s_tempsize);
if (sp->s_bufsize == 0) {
- if ( (sp->s_buf = (u_char *)
+ if (!(sp->s_buf = (u_char *)
malloc(rbufsize))
- == NULL) {
+ ) {
sp->s_buf = buf;
sp->s_size = sizeof(buf);
} else {
@@ -953,7 +933,7 @@ getnetconf()
exit(1);
}
ntp = NULL;
-#if defined(AF_LINK) && !defined(RISCOS_BSD)
+#if defined(AF_LINK) && !defined(RISCOS_BSD) && !defined(M_UNIX)
#define my_max(a, b) (a > b ? a : b)
#define my_size(p) my_max((p).sa_len, sizeof(p))
#else
@@ -1035,6 +1015,8 @@ getnetconf()
*/
if (ntp == NULL) {
ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
+ if (!ntp)
+ panic(errno, "malloc(netinfo)");
}
ntp->my_addr = ((struct sockaddr_in *)
&ifreq.ifr_addr)->sin_addr;
@@ -1109,10 +1091,8 @@ getnetconf()
* wildcard address.
*/
if (first) {
- if (!(dqp = (struct qdatagram *)calloc(1, sizeof(*dqp)))) {
- syslog(LOG_ERR, "getnetconf: malloc: %m");
- exit(12);
- }
+ if (!(dqp = (struct qdatagram *)calloc(1, sizeof(*dqp))))
+ panic(errno, "malloc(qdatagram)");
dqp->dq_next = datagramq;
datagramq = dqp;
dqp->dq_addr.s_addr = INADDR_ANY;
@@ -1131,11 +1111,9 @@ getnetconf()
if (findnetinfo(ntp->my_addr))
continue;
ontp = (struct netinfo *)
- malloc(sizeof(struct netinfo));
- if (ontp == NULL) {
- syslog(LOG_ERR, "getnetconf: malloc: %m");
- exit(12);
- }
+ malloc(sizeof(struct netinfo));
+ if (!ontp)
+ panic(errno, "malloc(netinfo)");
ontp->my_addr = ntp->my_addr;
ontp->mask = nm;
ontp->addr = ontp->my_addr.s_addr & nm;
@@ -1247,9 +1225,8 @@ static SIG_FN
onhup()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGHUP, (SIG_FN (*)())onhup);
-#endif /* SYSV */
+
+ resignal(SIGHUP, -1, onhup);
needreload = 1;
errno = save_errno;
}
@@ -1264,9 +1241,8 @@ static SIG_FN
maint_alarm()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGALRM, (SIG_FN (*)())maint_alarm);
-#endif /* SYSV */
+
+ resignal(SIGALRM, SIGCHLD, maint_alarm);
needmaint = 1;
errno = save_errno;
}
@@ -1280,7 +1256,11 @@ maint_alarm()
static SIG_FN
onintr()
{
+ int save_errno = errno;
+
+ resignal(SIGTERM, -1, onintr);
needToExit = 1;
+ errno = save_errno;
}
#endif /* ALLOW_UPDATES */
@@ -1291,7 +1271,11 @@ onintr()
static SIG_FN
onintr()
{
- needToExit = 1;
+ int save_errno = errno;
+
+ resignal(SIGTERM, -1, onintr);
+ needToExit = 1; /* XXX variable reuse */
+ errno = save_errno;
}
#endif /* XSTATS */
@@ -1305,9 +1289,8 @@ static SIG_FN
setdumpflg()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGINT, (SIG_FN (*)())setdumpflg);
-#endif /* SYSV */
+
+ resignal(SIGINT, -1, setdumpflg);
needToDoadump = 1;
errno = save_errno;
}
@@ -1364,9 +1347,8 @@ static SIG_FN
setIncrDbgFlg()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGUSR1, (SIG_FN (*)())setIncrDbgFlg);
-#endif /* SYSV */
+
+ resignal(SIGUSR1, -1, setIncrDbgFlg);
#ifdef DEBUG
if (debug == 0) {
debug++;
@@ -1388,9 +1370,8 @@ static SIG_FN
setNoDbgFlg()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGUSR2, (SIG_FN (*)())setNoDbgFlg);
-#endif /* SYSV */
+
+ resignal(SIGUSR2, -1, setNoDbgFlg);
setdebug(0);
errno = save_errno;
}
@@ -1403,9 +1384,8 @@ static SIG_FN
setQrylogFlg()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGWINCH, (SIG_FN (*)())setQrylogFlg);
-#endif /* SYSV */
+
+ resignal(SIGWINCH, -1, setQrylogFlg);
qrylog = !qrylog;
syslog(LOG_NOTICE, "query log %s\n", qrylog ?"on" :"off");
errno = save_errno;
@@ -1419,9 +1399,8 @@ static SIG_FN
setstatsflg()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGIOT, (SIG_FN (*)())setstatsflg);
-#endif /* SYSV */
+
+ resignal(SIGIOT, -1, setstatsflg);
needStatsDump = 1;
errno = save_errno;
}
@@ -1430,9 +1409,8 @@ static SIG_FN
setchkptflg()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGQUIT, (SIG_FN (*)())setchkptflg);
-#endif /* SYSV */
+
+ resignal(SIGQUIT, -1, setchkptflg);
needToChkpt = 1;
errno = save_errno;
}
@@ -1449,9 +1427,8 @@ static SIG_FN
sigprof()
{
int save_errno = errno;
-#if defined(SYSV)
- (void)signal(SIGSYS, (SIG_FN (*)())sigprof);
-#endif /* SYSV */
+
+ resignal(SIGSYS, -1, sigprof);
dprintf(1, (ddt, "sigprof()\n"));
if (fork() == 0)
{
diff --git a/usr.sbin/named/ns_maint.c b/usr.sbin/named/ns_maint.c
index 920b8d4..9a56097 100644
--- a/usr.sbin/named/ns_maint.c
+++ b/usr.sbin/named/ns_maint.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_maint.c 4.39 (Berkeley) 3/2/91";
-static char rcsid[] = "$Id: ns_maint.c,v 1.1.1.3 1995/10/23 09:26:20 peter Exp $";
+static char rcsid[] = "$Id: ns_maint.c,v 8.11 1995/12/22 10:20:30 vixie Exp $";
#endif /* not lint */
/*
@@ -143,7 +143,6 @@ ns_maint()
}
if (zp->z_flags & Z_XFER_RUNNING) {
abortxfer(zp);
- ns_retrytime(zp, tt.tv_sec);
break;
}
qserial_query(zp);
@@ -207,7 +206,7 @@ sched_maint()
* Schedule the next call to ns_maint.
* Don't visit any sooner than maint_interval.
*/
- bzero((char *)&ival, sizeof (ival));
+ bzero((char *)&ival, sizeof ival);
if (next_refresh != 0) {
if (next_refresh == next_alarm && alarm_pending) {
dprintf(1, (ddt, "sched_maint: no schedule change\n"));
@@ -269,8 +268,8 @@ markUpToDate(zp)
setting it to tt.tv_sec in order to avoid any
possible rounding problems in utimes(). */
if (stat(zp->z_source, &f_time) != -1)
- zp->z_ftime = f_time.st_mtime;
- /* XXX log if stat fails? XXX */
+ zp->z_ftime = f_time.st_mtime;
+ /* XXX log if stat fails? */
}
/*
@@ -345,6 +344,57 @@ qserial_answer(qp, serial)
}
/*
+ * Hold and release SIGCHLD
+ */
+#ifdef POSIX_SIGNALS
+static sigset_t sset;
+#else
+#ifndef SYSV
+static int omask;
+#endif
+#endif /* POSIX_SIGNALS */
+
+void holdsigchld()
+{
+#ifdef POSIX_SIGNALS
+ sigemptyset(&sset);
+ sigaddset(&sset,SIGCHLD);
+ sigprocmask(SIG_BLOCK,&sset,NULL);
+#else /* POSIX_SIGNALS */
+#ifndef SYSV
+ omask = sigblock(sigmask(SIGCHLD));
+#else /* SYSV */
+ /* XXX - out of luck? */
+#endif /* SYSV */
+#endif /* POSIX_SIGNALS */
+}
+
+void releasesigchld()
+{
+#ifdef POSIX_SIGNALS
+ sigprocmask(SIG_UNBLOCK,&sset,NULL);
+#else
+#ifndef SYSV
+ (void) sigsetmask(omask);
+#endif
+#endif /* POSIX_SIGNALS */
+}
+
+ /* State of all running zone transfers */
+static struct {
+ pid_t xfer_pid;
+ int xfer_state; /* see below */
+#ifdef sequent
+ union wait xfer_status;
+#else
+ int xfer_status;
+#endif
+} xferstatus[MAX_XFERS_RUNNING];
+#define XFER_IDLE 0
+#define XFER_RUNNING 1
+#define XFER_DONE 2
+
+/*
* Start an asynchronous zone transfer for a zone.
* Depends on current time being in tt.
* The caller must call sched_maint after startxfer.
@@ -354,7 +404,7 @@ startxfer(zp)
struct zoneinfo *zp;
{
static char *argv[NSMAX + 20], argv_ns[NSMAX][MAXDNAME];
- int argc = 0, argc_ns = 0, pid, omask;
+ int argc = 0, argc_ns = 0, pid, i;
unsigned int cnt;
char debug_str[10];
char serial_str[10];
@@ -362,13 +412,10 @@ startxfer(zp)
#ifdef GEN_AXFR
char class_str[10];
#endif
-#ifdef POSIX_SIGNALS
- sigset_t sset;
-#endif
dprintf(1, (ddt, "startxfer() %s\n", zp->z_origin));
- argv[argc++] = "named-xfer";
+ argv[argc++] = _PATH_XFER;
argv[argc++] = "-z";
argv[argc++] = zp->z_origin;
argv[argc++] = "-f";
@@ -405,21 +452,20 @@ startxfer(zp)
#endif
if (zp->z_xaddr.s_addr != 0) {
- /* address was specified by the qserial logic, use it */
+ /* Address was specified by the qserial logic, use it. */
argv[argc++] = strcpy(argv_ns[argc_ns++],
inet_ntoa(zp->z_xaddr));
} else {
/*
* Copy the server ip addresses into argv, after converting
- * to ascii and saving the static inet_ntoa result
+ * to ascii and saving the static inet_ntoa result.
*/
for (cnt = 0; cnt < zp->z_addrcnt; cnt++) {
struct in_addr a;
a = zp->z_addr[cnt];
- if (aIsUs(a)
- && !haveComplained(zp->z_origin,
- (char*)startxfer)) {
+ if (aIsUs(a) &&
+ !haveComplained(zp->z_origin, (char*)startxfer)) {
syslog(LOG_NOTICE,
"attempted to fetch zone %s from self (%s)",
zp->z_origin, inet_ntoa(a));
@@ -435,7 +481,6 @@ startxfer(zp)
#ifdef DEBUG
#ifdef ECHOARGS
if (debug) {
- int i;
for (i = 0; i < argc; i++)
fprintf(ddt, "Arg %d=%s\n", i, argv[i]);
}
@@ -443,48 +488,36 @@ startxfer(zp)
#endif /* DEBUG */
gettime(&tt);
-#ifndef SYSV
-#if defined(POSIX_SIGNALS)
- sigemptyset(&sset);
- sigaddset(&sset,SIGCHLD);
- sigprocmask(SIG_BLOCK,&sset,NULL);
-#else
- omask = sigblock(sigmask(SIGCHLD));
-#endif
-#endif
+ holdsigchld();
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_pid == 0) {
+ xferstatus[i].xfer_state = XFER_RUNNING;
+ break;
+ }
+ }
if ((pid = vfork()) == -1) {
syslog(LOG_ERR, "xfer vfork: %m");
-#ifndef SYSV
-#if defined(POSIX_SIGNALS)
- sigprocmask(SIG_UNBLOCK,&sset,NULL);
-#else
- (void) sigsetmask(omask);
-#endif
-#endif
+ releasesigchld();
zp->z_time = tt.tv_sec + 10;
return;
}
if (pid == 0) {
- /* child */
+ /* Child. */
execv(_PATH_XFER, argv);
syslog(LOG_ERR, "can't exec %s: %m", _PATH_XFER);
- _exit(XFER_FAIL); /* avoid duplicate buffer flushes */
+ _exit(XFER_FAIL); /* Avoid duplicate buffer flushes. */
}
- /* parent */
+ /* Parent. */
+ xferstatus[i].xfer_pid = pid; /* XXX - small race condition here if we
+ * can't hold signals */
dprintf(1, (ddt, "started xfer child %d\n", pid));
zp->z_flags &= ~Z_NEED_XFER;
zp->z_flags |= Z_XFER_RUNNING;
zp->z_xferpid = pid;
xfers_running++;
zp->z_time = tt.tv_sec + MAX_XFER_TIME;
-#ifndef SYSV
-#if defined(POSIX_SIGNALS)
- sigprocmask(SIG_UNBLOCK,&sset,NULL);
-#else
- (void) sigsetmask(omask);
-#endif
-#endif
+ releasesigchld();
}
const char *
@@ -509,7 +542,7 @@ zoneTypeString(zp)
#ifdef DEBUG
void
printzoneinfo(zonenum)
-int zonenum;
+ int zonenum;
{
struct timeval tt;
struct zoneinfo *zp = &zones[zonenum];
@@ -517,13 +550,13 @@ int zonenum;
if (!debug)
return;
+ if (!zp->z_origin)
+ return;
+
fprintf(ddt, "printzoneinfo(%d):\n", zonenum);
gettime(&tt);
- if (zp->z_origin != NULL && (zp->z_origin[0] == '\0'))
- fprintf(ddt, "origin ='.'");
- else
- fprintf(ddt, "origin ='%s'", zp->z_origin);
+ fprintf(ddt, "origin ='%s'", zp->z_origin[0] ? zp->z_origin : ".");
#ifdef GEN_AXFR
fprintf(ddt, ", class = %d", zp->z_class);
#endif
@@ -539,7 +572,7 @@ int zonenum;
if (zp->z_time) {
fprintf(ddt, ", now time : %lu sec", (u_long)tt.tv_sec);
fprintf(ddt, ", time left: %lu sec",
- (int)(zp->z_time - tt.tv_sec));
+ (long)(zp->z_time - tt.tv_sec));
}
fprintf(ddt, "; flags %lx\n", (u_long)zp->z_flags);
}
@@ -566,49 +599,50 @@ remove_zone(htp, zone)
struct namebuf **npp, **nppend;
nppend = htp->h_tab + htp->h_size;
- for (npp = htp->h_tab; npp < nppend; npp++)
- for (pnp = NULL, np = *npp; np != NULL; np = npn) {
- for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
-#ifdef CLEANCACHE
- if (dp->d_zone == zone && (all || stale(dp)))
-#else
- if (dp->d_zone == zone)
+ for (npp = htp->h_tab; npp < nppend; npp++) {
+ for (pnp = NULL, np = *npp; np != NULL; np = npn) {
+ for (pdp = NULL, dp = np->n_data; dp != NULL; NULL) {
+ if (dp->d_zone == zone
+#ifdef CLEANCACHE
+ && (all || stale(dp))
#endif
- dp = rm_datum(dp, np, pdp);
- else {
- pdp = dp;
- dp = dp->d_next;
- }
- }
+ ) {
+ dp = rm_datum(dp, np, pdp);
+ } else {
+ pdp = dp;
+ dp = dp->d_next;
+ }
+ } /*for(pdp)*/
- if (np->n_hash) {
- /* call recursively to remove subdomains. */
+ if (np->n_hash) {
+ /* call recursively to remove subdomains. */
+ remove_zone(np->n_hash, zone
#ifdef CLEANCACHE
- remove_zone(np->n_hash, zone, all);
-#else
- remove_zone(np->n_hash, zone);
+ , all
#endif
+ );
- /* if now empty, free it */
- if (np->n_hash->h_cnt == 0) {
- free((char*)np->n_hash);
- np->n_hash = NULL;
+ /* if now empty, free it */
+ if (np->n_hash->h_cnt == 0) {
+ free((char*)np->n_hash);
+ np->n_hash = NULL;
+ }
}
- }
- if ((np->n_hash == NULL) && (np->n_data == NULL)) {
- npn = rm_name(np, npp, pnp);
- htp->h_cnt--;
- } else {
- npn = np->n_next;
- pnp = np;
- }
- }
+ if ((np->n_hash == NULL) && (np->n_data == NULL)) {
+ npn = rm_name(np, npp, pnp);
+ htp->h_cnt--;
+ } else {
+ npn = np->n_next;
+ pnp = np;
+ }
+ } /*for(pnp)*/
+ } /*for(npp)*/
}
#ifdef PURGE_ZONE
-static void purge_z_2();
-static bottom_of_zone();
+static void purge_z_2 __P((struct hashbuf *, int));
+static bottom_of_zone __P((struct databuf *, int));
void
purge_zone(dname, htp, class)
@@ -622,10 +656,11 @@ purge_zone(dname, htp, class)
struct hashbuf *phtp = htp;
dprintf(1, (ddt, "purge_zone(%s,%d)\n", dname, class));
- if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname) {
+ if ((np = nlookup(dname, &phtp, &fname, 0)) && dname == fname &&
+ !WILDCARD_P(dname)) {
for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
if (dp->d_class == class)
- dp = rm_datum(dp, np, pdp);
+ dp = rm_datum(dp, np, pdp);
else {
pdp = dp;
dp = dp->d_next;
@@ -633,48 +668,45 @@ purge_zone(dname, htp, class)
}
if (np->n_hash) {
-
- purge_z_2(np->n_hash, class);
-
- if (np->n_hash->h_cnt == 0) {
- free((char*)np->n_hash);
- np->n_hash = NULL;
- }
+ purge_z_2(np->n_hash, class);
+ if (np->n_hash->h_cnt == 0) {
+ free((char*)np->n_hash);
+ np->n_hash = NULL;
+ }
}
/* remove entry from cache, if required */
if ((np->n_hash == NULL) && (np->n_data == NULL)) {
- struct namebuf **npp, **nppend;
- struct namebuf *npn, *pnp, *nnp;
-
- dprintf(3,(ddt, "purge_zone: cleaning cache\n"));
-
- /* walk parent hashtable looking for ourself */
- if (np->n_parent)
- phtp = np->n_parent->n_hash;
- else
- phtp = htp; /* top / root zone */
-
- if (phtp) {
- nppend = phtp->h_tab + phtp->h_size;
-
- for (npp = phtp->h_tab; npp < nppend; npp++) {
- for (pnp = NULL, nnp = *npp;
- nnp != NULL;
- nnp = npn
- ) {
- if (nnp == np) {
- dprintf(3,(ddt, "purge_zone: found our selves\n"));
- npn = rm_name(nnp, npp, pnp);
- phtp->h_cnt--;
- } else {
- npn = nnp->n_next;
- pnp = nnp;
+ struct namebuf **npp, **nppend;
+ struct namebuf *npn, *pnp, *nnp;
+
+ dprintf(3,(ddt, "purge_zone: cleaning cache\n"));
+
+ /* walk parent hashtable looking for ourself */
+ if (np->n_parent)
+ phtp = np->n_parent->n_hash;
+ else
+ phtp = htp; /* top / root zone */
+
+ if (phtp) {
+ nppend = phtp->h_tab + phtp->h_size;
+ for (npp = phtp->h_tab; npp < nppend; npp++) {
+ for (pnp = NULL, nnp = *npp;
+ nnp != NULL;
+ nnp = npn) {
+ if (nnp == np) {
+ dprintf(3, (ddt,
+ "purge_zone: found our selves\n"
+ ));
+ npn = rm_name(nnp,npp,pnp);
+ phtp->h_cnt--;
+ } else {
+ npn = nnp->n_next;
+ pnp = nnp;
+ }
+ }
}
- }
}
- }
-
}
}
}
@@ -689,39 +721,38 @@ purge_z_2(htp, class)
struct namebuf **npp, **nppend;
nppend = htp->h_tab + htp->h_size;
- for (npp = htp->h_tab; npp < nppend; npp++)
- for (pnp = NULL, np = *npp; np != NULL; np = npn) {
- if (!bottom_of_zone(np->n_data, class)) {
- for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
- if (dp->d_class == class)
- dp = rm_datum(dp, np, pdp);
- else {
- pdp = dp;
- dp = dp->d_next;
+ for (npp = htp->h_tab; npp < nppend; npp++) {
+ for (pnp = NULL, np = *npp; np != NULL; np = npn) {
+ if (!bottom_of_zone(np->n_data, class)) {
+ for (pdp = NULL, dp = np->n_data; dp != NULL; ) {
+ if (dp->d_class == class)
+ dp = rm_datum(dp, np, pdp);
+ else {
+ pdp = dp;
+ dp = dp->d_next;
+ }
+ }
+ if (np->n_hash) {
+ /* call recursively to rm subdomains */
+ purge_z_2(np->n_hash, class);
+
+ /* if now empty, free it */
+ if (np->n_hash->h_cnt == 0) {
+ free((char*)np->n_hash);
+ np->n_hash = NULL;
+ }
+ }
}
- }
-
- if (np->n_hash) {
- /* call recursively to remove subdomains. */
- purge_z_2(np->n_hash, class);
- /* if now empty, free it */
- if (np->n_hash->h_cnt == 0) {
- free((char*)np->n_hash);
- np->n_hash = NULL;
+ if ((np->n_hash == NULL) && (np->n_data == NULL)) {
+ npn = rm_name(np, npp, pnp);
+ htp->h_cnt--;
+ } else {
+ npn = np->n_next;
+ pnp = np;
}
- }
-
- }
-
- if ((np->n_hash == NULL) && (np->n_data == NULL)) {
- npn = rm_name(np, npp, pnp);
- htp->h_cnt--;
- } else {
- npn = np->n_next;
- pnp = np;
}
- }
+ }
}
static int
@@ -783,12 +814,51 @@ static void
abortxfer(zp)
struct zoneinfo *zp;
{
- kill(zp->z_xferpid, SIGKILL);
- syslog(LOG_NOTICE, "zone transfer timeout for \"%s\"; pid %lu killed",
- zp->z_origin, (u_long)zp->z_xferpid);
- ns_retrytime(zp, tt.tv_sec);
- (void) nxfers(zp, -1);
- xfers_running--;
+ if (zp->z_flags & (Z_XFER_GONE|Z_XFER_ABORTED)) {
+ int i;
+
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_pid == zp->z_xferpid) {
+ xferstatus[i].xfer_pid = 0;
+ xferstatus[i].xfer_state = XFER_IDLE;
+ break;
+ }
+ }
+
+ if (zp->z_flags & Z_XFER_GONE)
+ syslog(LOG_WARNING,
+ "zone transfer timeout for \"%s\"; pid %lu missing",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ else if (kill(zp->z_xferpid, SIGKILL) == -1)
+ syslog(LOG_WARNING,
+ "zone transfer timeout for \"%s\"; kill pid %lu: %m",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ else
+ syslog(LOG_WARNING,
+"zone transfer timeout for \"%s\"; second kill\
+pid %lu - forgetting, processes may accumulate",
+ zp->z_origin, (u_long)zp->z_xferpid);
+
+ zp->z_xferpid = 0;
+ xfers_running--;
+ (void)nxfers(zp, -1);
+ zp->z_flags &= ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE);
+ } else if (kill(zp->z_xferpid, SIGKILL) == -1) {
+ if (errno == ESRCH)
+ /* No warning on first time, it may have just exited */
+ zp->z_flags |= Z_XFER_GONE;
+ else {
+ syslog(LOG_WARNING,
+ "zone transfer timeout for \"%s\"; pid %lu kill failed %m",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ zp->z_flags |= Z_XFER_ABORTED;
+ }
+ } else {
+ syslog(LOG_NOTICE,
+ "zone transfer timeout for \"%s\"; pid %lu killed",
+ zp->z_origin, (u_long)zp->z_xferpid);
+ zp->z_flags |= Z_XFER_ABORTED;
+ }
}
/*
@@ -796,18 +866,19 @@ abortxfer(zp)
* (Note: also called when outgoing transfer completes.)
*/
SIG_FN
-endxfer()
+reapchild()
{
- register struct zoneinfo *zp;
- int exitstatus, pid, xfers, save_errno;
+ int pid, i, save_errno;
#if defined(sequent)
union wait status;
#else
int status;
#endif /* sequent */
+#if defined(MUST_REARM_SIGS)
+ (void)signal(SIGCLD, (SIG_FN (*)()) reapchild);
+#endif
save_errno = errno;
- xfers = 0;
gettime(&tt);
#if defined(USE_WAITPID)
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
@@ -815,18 +886,51 @@ endxfer()
{
pid = wait(&status);
#endif /* USE_WAITPID */
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_pid == pid) {
+ xferstatus[i].xfer_status = status;
+ xferstatus[i].xfer_state = XFER_DONE;
+ needendxfer++;
+ break;
+ }
+ }
+ }
+ errno = save_errno;
+}
+
+/*
+ * Finish processing of of finished xfers
+ */
+void
+endxfer()
+{
+ register struct zoneinfo *zp;
+ int exitstatus, pid, i;
+#if defined(sequent)
+ union wait status;
+#else
+ int status;
+#endif /* sequent */
+
+ gettime(&tt);
+
+ for (i = 0; i < MAX_XFERS_RUNNING; i++) {
+ if (xferstatus[i].xfer_state != XFER_DONE)
+ continue;
+ pid = xferstatus[i].xfer_pid;
+ status = xferstatus[i].xfer_status;
exitstatus = WIFEXITED(status) ?WEXITSTATUS(status) :0;
for (zp = zones; zp < &zones[nzones]; zp++) {
if (zp->z_xferpid != pid)
continue;
- xfers++;
xfers_running--;
(void) nxfers(zp, -1);
zp->z_xferpid = 0;
- zp->z_flags &= ~Z_XFER_RUNNING;
+ zp->z_flags &=
+ ~(Z_XFER_RUNNING|Z_XFER_ABORTED|Z_XFER_GONE);
dprintf(1, (ddt,
- "\nendxfer: child %d zone %s returned status=%d termsig=%d\n",
+ "\nendxfer: child %d zone %s returned status=%d termsig=%d\n",
pid, zp->z_origin, exitstatus,
WIFSIGNALED(status) ?WTERMSIG(status) :-1
)
@@ -845,6 +949,7 @@ endxfer()
break;
case XFER_SUCCESS:
+ /* XXX should incorporate loadxfer() */
zp->z_flags |= Z_NEED_RELOAD;
zp->z_flags &= ~Z_SYSLOGGED;
needzoneload++;
@@ -855,7 +960,7 @@ endxfer()
zp->z_flags |= Z_SYSLOGGED;
syslog(LOG_NOTICE,
"zoneref: Masters for secondary zone \"%s\" unreachable",
- zp->z_origin);
+ zp->z_origin);
}
ns_retrytime(zp, tt.tv_sec);
break;
@@ -865,23 +970,23 @@ endxfer()
zp->z_flags |= Z_SYSLOGGED;
syslog(LOG_NOTICE,
"named-xfer for \"%s\" exited %d",
- zp->z_origin, exitstatus);
+ zp->z_origin,
+ exitstatus);
}
/* FALLTHROUGH */
case XFER_FAIL:
zp->z_flags |= Z_SYSLOGGED;
ns_retrytime(zp, tt.tv_sec);
break;
- } /*switch*/
+ }
break;
- } /*if/else*/
- } /*for*/
- } /*while*/
+ }
+ }
+ xferstatus[i].xfer_state = XFER_IDLE;
+ xferstatus[i].xfer_pid = 0;
+ }
+ releasesigchld();
tryxfer();
-#if defined(SYSV)
- (void)signal(SIGCLD, (SIG_FN (*)()) endxfer);
-#endif
- errno = save_errno;
}
/*
@@ -954,8 +1059,7 @@ tryxfer() {
* Reload zones whose transfers have completed.
*/
void
-loadxfer()
-{
+loadxfer() {
register struct zoneinfo *zp;
gettime(&tt);
@@ -964,11 +1068,11 @@ loadxfer()
dprintf(1, (ddt, "loadxfer() \"%s\"\n",
zp->z_origin[0] ? zp->z_origin : "."));
zp->z_flags &= ~(Z_NEED_RELOAD|Z_AUTH);
+ remove_zone(hashtab, zp - zones
#ifdef CLEANCACHE
- remove_zone(hashtab, zp - zones, 1);
-#else
- remove_zone(hashtab, zp - zones);
+ , 1
#endif
+ );
#ifdef PURGE_ZONE
purge_zone(zp->z_origin, hashtab, zp->z_class);
#endif
diff --git a/usr.sbin/named/ns_ncache.c b/usr.sbin/named/ns_ncache.c
index bea17c6..bf63fb8 100644
--- a/usr.sbin/named/ns_ncache.c
+++ b/usr.sbin/named/ns_ncache.c
@@ -53,7 +53,7 @@ cache_n_resp(msg, msglen)
dname, type, class));
#ifdef VALIDATE
- Vcode = validate(dname, &from_addr, type, class, NULL, 0,
+ Vcode = validate(dname, dname, &from_addr, type, class, NULL, 0,
hp->rcode == NXDOMAIN ? NXDOMAIN : NOERROR_NODATA);
if (Vcode == INVALID || Vcode == VALID_NO_CACHE) {
/*Valid_no_cache should never occur but doesn't hurt to check*/
diff --git a/usr.sbin/named/ns_req.c b/usr.sbin/named/ns_req.c
index 3de6213..4d399c6 100644
--- a/usr.sbin/named/ns_req.c
+++ b/usr.sbin/named/ns_req.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_req.c 4.47 (Berkeley) 7/1/91";
-static char rcsid[] = "$Id: ns_req.c,v 1.1.1.3 1995/10/23 09:26:22 peter Exp $";
+static char rcsid[] = "$Id: ns_req.c,v 8.15 1995/12/29 07:16:18 vixie Exp $";
#endif /* not lint */
/*
@@ -133,6 +133,9 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
{
register HEADER *hp = (HEADER *) msg;
u_char *cp, *eom;
+#ifdef DEBUG
+ const char *sortmsgtxt;
+#endif
enum req_action action;
int n;
@@ -227,10 +230,10 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
dprintf(1, (ddt, "ns_req: Opcode %d not implemented\n",
hp->opcode));
/* XXX - should syslog, limited by haveComplained */
- hp->qdcount = 0;
- hp->ancount = 0;
- hp->nscount = 0;
- hp->arcount = 0;
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
hp->rcode = NOTIMP;
action = Finish;
}
@@ -257,20 +260,23 @@ ns_req(msg, msglen, buflen, qsp, from, dfd)
*/
hp->qr = 1; /* set Response flag */
hp->ra = (NoRecurse == 0);
- hp->ancount = htons(hp->ancount);
n = doaddinfo(hp, cp, buflen);
cp += n;
buflen -= n;
- dprintf(1, (ddt, "ns_req: answer -> %s fd=%d id=%d size=%d %s\n",
- sin_ntoa(from),
- (qsp == QSTREAM_NULL) ?dfd :qsp->s_rfd,
- ntohs(hp->id), cp - msg, local(from) == NULL ? "Remote" : "Local"));
#ifdef DEBUG
+#ifdef SORT_RESPONSE
+ sortmsgtxt = local(from) == NULL ? "Remote" : "Local";
+#else /*SORT*/
+ sortmsgtxt = "(not sorting)";
+#endif /*SORT*/
+ dprintf(1, (ddt, "ns_req: answer -> %s fd=%d id=%d size=%d %s\n",
+ sin_ntoa(from), (qsp == QSTREAM_NULL) ? dfd : qsp->s_rfd,
+ ntohs(hp->id), cp - msg, sortmsgtxt));
if (debug >= 10)
fp_nquery(msg, cp - msg, ddt);
-#endif
+#endif /*DEBUG*/
if (qsp == QSTREAM_NULL) {
if (sendto(dfd, (char*)msg, cp - msg, 0,
(struct sockaddr *)from,
@@ -328,14 +334,14 @@ req_notify(hp, cpp, eom, msg, from)
/* valid notify's have one question and zero answers */
if ((ntohs(hp->qdcount) != 1)
- || hp->ancount
- || hp->nscount
- || hp->arcount) {
+ || ntohs(hp->ancount) != 0
+ || ntohs(hp->nscount) != 0
+ || ntohs(hp->arcount) != 0) {
dprintf(1, (ddt, "FORMERR Notify header counts wrong\n"));
- hp->qdcount = 0;
- hp->ancount = 0;
- hp->nscount = 0;
- hp->arcount = 0;
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
hp->rcode = FORMERR;
return (Finish);
}
@@ -460,14 +466,14 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
/* valid queries have one question and zero answers */
if ((ntohs(hp->qdcount) != 1)
- || hp->ancount
- || hp->nscount
- || hp->arcount) {
+ || ntohs(hp->ancount) != 0
+ || ntohs(hp->nscount) != 0
+ || ntohs(hp->arcount) != 0) {
dprintf(1, (ddt, "FORMERR Query header counts wrong\n"));
- hp->qdcount = 0;
- hp->ancount = 0;
- hp->nscount = 0;
- hp->arcount = 0;
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
hp->rcode = FORMERR;
return (Finish);
}
@@ -550,7 +556,7 @@ req_query(hp, cpp, eom, qsp, buflenp, msglenp, msg, dfd, from)
try_again:
dprintf(1, (ddt, "req: nlookup(%s) id %d type=%d class=%d\n",
- dname, hp->id, type, class));
+ dname, ntohs(hp->id), type, class));
htp = hashtab; /* lookup relative to root */
if ((anp = np = nlookup(dname, &htp, &fname, 0)) == NULL)
fname = "";
@@ -637,21 +643,21 @@ try_again:
*/
for (dp = np->n_data; dp ; dp = dp->d_next) {
if (!stale(dp) && (dp->d_rcode == NXDOMAIN) &&
- (dp->d_class == class)) {
+ (dp->d_class == class)) {
#ifdef RETURNSOA
- n = finddata(np, class, T_SOA, hp, &dname,
+ n = finddata(np, class, T_SOA, hp, &dname,
buflenp, &count);
- if (n != 0 ) {
+ if (n != 0 ) {
if (hp->rcode == NOERROR_NODATA) {
- /* this should not occur */
- hp->rcode = NOERROR;
- return (Finish);
+ /* this should not occur */
+ hp->rcode = NOERROR;
+ return (Finish);
}
*cpp += n;
*buflenp -= n;
*msglenp += n;
hp->nscount = htons((u_int16_t)count);
- }
+ }
#endif
hp->rcode = NXDOMAIN;
hp->aa = 1;
@@ -688,7 +694,7 @@ try_again:
*cpp += n;
*buflenp -= n;
*msglenp += n;
- hp->ancount += count;
+ hp->ancount = htons(ntohs(hp->ancount) + (u_int16_t)count);
if (fname != dname && type != T_CNAME && type != T_ANY) {
if (cname++ >= MAXCNAMES) {
dprintf(3, (ddt,
@@ -703,8 +709,10 @@ try_again:
"req: foundname=%d, count=%d, founddata=%d, cname=%d\n",
foundname, count, founddata, cname));
+#ifdef SORT_RESPONSE
if ((lp = local(from)) != NULL)
sort_response(answers, count, lp, *cpp);
+#endif
#ifdef BIND_NOTIFY
if (type == T_SOA &&
from->sin_port == ns_port &&
@@ -729,7 +737,6 @@ try_again:
}
#endif /*BIND_NOTIFY*/
if (type == T_AXFR) {
- hp->ancount = htons(hp->ancount);
startxfr(qsp, np, msg, *cpp - msg, class, dname);
sqrm(qsp);
return (Return);
@@ -737,8 +744,7 @@ try_again:
#ifdef notdef
/*
- * If we found an authoritative answer,
- * we're done.
+ * If we found an authoritative answer, we're done.
*/
if (hp->aa)
return (Finish);
@@ -746,6 +752,12 @@ try_again:
fetchns:
/*
+ * If we're already out of room in the response, we're done.
+ */
+ if (hp->tc)
+ return (Finish);
+
+ /*
* Look for name servers to refer to and fill in the authority
* section or record the address for forwarding the query
* (recursion desired).
@@ -758,9 +770,8 @@ fetchns:
switch (findns(&np, class, nsp, &count, 0)) {
case NXDOMAIN:
/* We are authoritative for this np. */
- if (!foundname) {
+ if (!foundname)
hp->rcode = NXDOMAIN;
- }
dprintf(3, (ddt, "req: leaving (%s, rcode %d)\n",
dname, hp->rcode));
if (class != C_ANY) {
@@ -774,7 +785,7 @@ fetchns:
*cpp += n;
*buflenp -= n;
#ifdef ADDAUTH
- } else if (hp->ancount) {
+ } else if (ntohs(hp->ancount) != 0) {
/* don't add NS records for NOERROR NODATA
as some servers can get confused */
#ifdef DATUMREFCNT
@@ -789,7 +800,7 @@ fetchns:
(type != T_NS || np != anp)
) {
n = add_data(np, nsp, *cpp,
- *buflenp);
+ *buflenp, &count);
if (n < 0) {
hp->tc = 1;
n = (-n);
@@ -826,14 +837,15 @@ fetchns:
* never recursing, then add the nameserver references
* ("authority section") here and we're done.
*/
- if (founddata || (!hp->rd) || NoRecurse) {
- /* If the qtype was NS, and the np of the authority is
+ if (founddata || !hp->rd || NoRecurse) {
+ /*
+ * If the qtype was NS, and the np of the authority is
* the same as the np of the data, we don't need to add
* another copy of the answer here in the authority
* section.
*/
if (!founddata || type != T_NS || anp != np) {
- n = add_data(np, nsp, *cpp, *buflenp);
+ n = add_data(np, nsp, *cpp, *buflenp, &count);
if (n < 0) {
hp->tc = 1;
n = (-n);
@@ -867,7 +879,6 @@ fetchns:
return (Finish);
}
id = hp->id;
- hp->ancount = htons(hp->ancount);
omsglen = *msglenp;
bcopy(msg, omsg, omsglen);
n = res_mkquery(QUERY, dname, class, type,
@@ -973,16 +984,15 @@ req_iquery(hp, cpp, eom, buflenp, msg, from)
nameserIncr(from->sin_addr, nssRcvdIQ);
- hp->ancount = htons(hp->ancount);
- if ((hp->ancount != 1)
- || hp->qdcount
- || hp->nscount
- || hp->arcount) {
+ if (ntohs(hp->ancount) != 1
+ || ntohs(hp->qdcount) != 0
+ || ntohs(hp->nscount) != 0
+ || ntohs(hp->arcount) != 0) {
dprintf(1, (ddt, "FORMERR IQuery header counts wrong\n"));
- hp->qdcount = 0;
- hp->ancount = 0;
- hp->nscount = 0;
- hp->arcount = 0;
+ hp->qdcount = htons(0);
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
hp->rcode = FORMERR;
return (Finish);
}
@@ -1187,8 +1197,8 @@ stale(dp)
case Z_CACHE:
if (dp->d_flags & DB_F_HINT || dp->d_ttl >= tt.tv_sec)
return (0);
- dprintf(3, (ddt, "stale: ttl %d %d (x%lx)\n",
- dp->d_ttl, dp->d_ttl - tt.tv_sec,
+ dprintf(3, (ddt, "stale: ttl %d %ld (x%lx)\n",
+ dp->d_ttl, (long)(dp->d_ttl - tt.tv_sec),
(u_long)dp->d_flags));
return (1);
@@ -1215,10 +1225,10 @@ make_rr(name, dp, buf, buflen, doadd)
u_char *cp1, *sp;
struct zoneinfo *zp;
register int32_t n;
- register int32_t ttl;
+ register u_int32_t ttl;
u_char **edp = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
- dprintf(5, (ddt, "make_rr(%s, %lx, %lx, %d, %d) %d zone %d ttl %d\n",
+ dprintf(5, (ddt, "make_rr(%s, %lx, %lx, %d, %d) %d zone %d ttl %lu\n",
name, (u_long)dp, (u_long)buf,
buflen, doadd, dp->d_size, dp->d_zone, dp->d_ttl));
@@ -1242,7 +1252,7 @@ make_rr(name, dp, buf, buflen, doadd)
ttl = 0;
}
} else {
- if (dp->d_ttl)
+ if (dp->d_ttl != USE_MINIMUM)
ttl = dp->d_ttl;
else
ttl = zp->z_minimum; /* really default */
@@ -1528,11 +1538,7 @@ doaddinfo(hp, msg, msglen)
/* Cache invalidate the address RR's */
delete_all(np, (int)ap->a_class, T_A);
}
- if (
-#if 0 /*XXX*/
- !NoRecurse &&
-#endif
- !foundcname && (foundstale || !foundany)) {
+ if (!NoFetchGlue && !foundcname && (foundstale || !foundany)) {
/* ask a real server for this info */
(void) sysquery(ap->a_dname, (int)ap->a_class, T_A,
NULL, 0, QUERY);
@@ -1581,7 +1587,7 @@ doaddauth(hp, cp, buflen, np, dp)
}
return (0);
}
- hp->nscount = htons((u_int16_t)1);
+ hp->nscount = htons(ntohs(hp->nscount) + 1);
return (n);
}
diff --git a/usr.sbin/named/ns_resp.c b/usr.sbin/named/ns_resp.c
index 208cc75..4a987ab8 100644
--- a/usr.sbin/named/ns_resp.c
+++ b/usr.sbin/named/ns_resp.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_resp.c 4.65 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: ns_resp.c,v 1.1.1.3 1995/10/23 09:26:24 peter Exp $";
+static char rcsid[] = "$Id: ns_resp.c,v 8.18 1995/12/29 21:08:13 vixie Exp $";
#endif /* not lint */
/*
@@ -77,6 +77,7 @@ static void check_root __P((void)),
static u_int8_t norootlogged[MAXCLASS]; /* XXX- should be a bitmap */
static const char skipnameFailedAnswer[] = "skipname failed in answer",
+ skipnameFailedAuth[] = "skipname failed in authority",
skipnameFailedQuery[] = "skipname failed in query",
outofDataQuery[] = "ran out of data in query",
outofDataAnswer[] = "ran out of data in answer",
@@ -86,6 +87,7 @@ static const char skipnameFailedAnswer[] = "skipname failed in answer",
expandFailedAuth[] = "dn_expand failed in authority",
outofDataAuth[] = "ran out of data in authority",
dlenOverrunAnswer[] = "dlen overrun in answer",
+ dlenOverrunAuth[] = "dlen overrun in authority",
dlenUnderrunAnswer[] = "dlen underrun in answer",
outofDataFinal[] = "out of data in final pass",
outofDataAFinal[] = "out of data after final pass",
@@ -155,14 +157,14 @@ learntFrom(qp, server)
#else
# define LEARNTFROM " '%s'"
#endif
- if (buf = malloc(strlen(a = (*a ? a : "\".\"")) +
- strlen(ns = (*ns ? ns : "\".\"")) +
- strlen(na = (*na ? na : "\".\"")) +
- sizeof(LEARNTFROM))) {
- sprintf(buf, LEARNTFROM, na, a, ns);
- return (buf);
- }
- return("");
+ buf = malloc(strlen(a = (*a ? a : "\".\"")) +
+ strlen(ns = (*ns ? ns : "\".\"")) +
+ strlen(na = (*na ? na : "\".\"")) +
+ sizeof(LEARNTFROM));
+ if (!buf)
+ return ("");
+ sprintf(buf, LEARNTFROM, na, a, ns);
+ return (buf);
}
void
@@ -176,17 +178,19 @@ ns_resp(msg, msglen)
register struct databuf *ns, *ns2;
register u_char *cp;
u_char *eom = msg + msglen;
-#ifdef VALIDATE
register u_char *tempcp;
+#ifdef VALIDATE
struct sockaddr_in *server = &from_addr;
- int *validatelist;
- int lesscount, old_ancount;
+ struct { char *name; int type, class; u_int cred; } defer_rm[99];
+ int defer_rm_count;
#endif
struct sockaddr_in *nsa;
- struct databuf *nsp[NSMAX], **nspp;
+ struct databuf *nsp[NSMAX];
int i, c, n, qdcount, ancount, aucount, nscount, arcount;
int qtype, qclass, dbflags;
- int cname = 0; /* flag for processing cname response */
+ int restart; /* flag for processing cname response */
+ int validanswer;
+ int cname;
int count, founddata, foundname;
int buflen;
int newmsglen;
@@ -194,7 +198,7 @@ ns_resp(msg, msglen)
char *dname;
const char *fname;
const char *formerrmsg = "brain damage";
- u_char newmsg[BUFSIZ];
+ u_char newmsg[PACKETSZ];
u_char **dpp, *tp;
time_t rtrip;
struct hashbuf *htp;
@@ -264,7 +268,7 @@ ns_resp(msg, msglen)
qclass = 0;
}
- /* cp now points after the query section (if there was one). */
+ /* cp now points after the query section. */
/*
* Here we handle bad responses from servers.
@@ -276,11 +280,6 @@ ns_resp(msg, msglen)
* this server and immediately force a retry.
*/
if ((hp->rcode != NOERROR && hp->rcode != NXDOMAIN)
-#ifndef NCACHE
- || (hp->rcode == NXDOMAIN && !hp->aa) /* must accept this one if
- * we allow negative caching
- */
-#endif
|| (hp->opcode != QUERY
#ifdef BIND_NOTIFY
&& hp->opcode != NS_NOTIFY_OP
@@ -301,12 +300,13 @@ ns_resp(msg, msglen)
}
/* mark server as bad */
if (!qp->q_fwd)
- for (i = 0; i < (int)qp->q_naddr; i++)
- if (qp->q_addr[i].ns_addr.sin_addr.s_addr
- == from_addr.sin_addr.s_addr)
- qp->q_addr[i].nretry = MAXRETRY;
- /* XXX - doesn't handle responses sent from the wrong
- * interface on a multihomed server
+ for (i = 0; i < (int)qp->q_naddr; i++)
+ if (qp->q_addr[i].ns_addr.sin_addr.s_addr
+ == from_addr.sin_addr.s_addr)
+ qp->q_addr[i].nretry = MAXRETRY;
+ /*
+ * XXX: doesn't handle responses sent from the wrong
+ * interface on a multihomed server.
*/
if (qp->q_fwd ||
qp->q_addr[qp->q_curaddr].ns_addr.sin_addr.s_addr
@@ -321,85 +321,6 @@ ns_resp(msg, msglen)
goto formerr;
}
-#ifdef LAME_DELEGATION
- /*
- * Non-authoritative, no answer, no error
- */
- if (qdcount == 1 && hp->rcode == NOERROR && !hp->aa && ancount == 0
- && aucount > 0
-#ifdef BIND_NOTIFY
- && hp->opcode != NS_NOTIFY_OP
-#endif
- ) {
- u_char *tp;
- int type, class;
-#ifdef DEBUG
- if (debug > 0)
- fp_nquery(msg, msglen, ddt);
-#endif
- /*
- * Since there is no answer section (ancount == 0),
- * we must be pointing at the authority section (aucount > 0).
- */
- tp = cp;
- n = dn_expand(msg, eom, tp, name, sizeof name);
- if (n < 0) {
- formerrmsg = expandFailedAuth;
- goto formerr;
- }
- tp += n;
- GETSHORT(type, tp);
- if (tp >= eom) {
- formerrmsg = outofDataAuth;
- goto formerr;
- }
- GETSHORT(class, tp);
- if (tp >= eom) {
- formerrmsg = outofDataAuth;
- goto formerr;
- }
-
- /*
- * If the answer delegates us either to the same level in
- * the hierarchy or closer to the root, we consider this
- * server lame. Note that for now we only log the message
- * if the T_NS was C_IN, which is technically wrong (NS is
- * visible in all classes) but necessary anyway (non-IN
- * classes tend to not have good strong delegation graphs).
- */
-
- if (type == T_NS && samedomain(qp->q_domain, name)) {
- nameserIncr(from_addr.sin_addr, nssRcvdLDel);
- /* mark server as bad */
- if (!qp->q_fwd)
- for (i = 0; i < (int)qp->q_naddr; i++)
- if (qp->q_addr[i].ns_addr.sin_addr.s_addr
- == from_addr.sin_addr.s_addr)
- qp->q_addr[i].nretry = MAXRETRY;
-#ifdef LAME_LOGGING
- if (class == C_IN &&
- !haveComplained((char*)nhash(inet_etoa(&from_addr)),
- (char*)nhash(qp->q_domain)))
- syslog(LAME_LOGGING,
- "Lame server on '%s' (in '%s'?): %s%s\n",
- qname, qp->q_domain,
- inet_etoa(&from_addr),
- learntFrom(qp, &from_addr)
- );
-
-#endif /* LAME_LOGGING */
- /* XXX - doesn't handle responses sent from the wrong
- * interface on a multihomed server
- */
- if (qp->q_fwd ||
- qp->q_addr[qp->q_curaddr].ns_addr.sin_addr.s_addr
- == from_addr.sin_addr.s_addr)
- retry(qp);
- return;
- }
- }
-#endif /* LAME_DELEGATION */
-
#ifdef ALLOW_UPDATES
if ( (hp->rcode == NOERROR) &&
(hp->opcode == UPDATEA || hp->opcode == UPDATED ||
@@ -427,11 +348,12 @@ ns_resp(msg, msglen)
for (fwd = fwdtab; fwd != (struct fwdinfo *)NULL; fwd = fwd->next) {
if (fwd->fwdaddr.sin_addr.s_addr ==
from_addr.sin_addr.s_addr) {
- /* XXX - should put this in STATS somewhere */
+ /* XXX - should put this in STATS somewhere. */
break;
}
}
- /* XXX: note bad ambiguity here. if one of our forwarders is also
+ /*
+ * XXX: note bad ambiguity here. if one of our forwarders is also
* a delegated server for some domain, then we will not update
* the RTT information on any replies we get from those servers.
* Workaround: disable recursion on authoritative servers so that
@@ -453,7 +375,7 @@ ns_resp(msg, msglen)
"unexpected source")) {
syslog(LOG_INFO,
"Response from unexpected source (%s)",
- inet_etoa(&from_addr));
+ sin_ntoa(&from_addr));
}
/*
* We don't know who this response came from so it
@@ -466,8 +388,8 @@ ns_resp(msg, msglen)
/* Handle response from different (untried) interface */
if ((qs->ns != NULL) && (stp->tv_sec == 0)) {
ns = qs->ns;
- while (qs > qp->q_addr &&
- (qs->stime.tv_sec == 0 || qs->ns != ns))
+ while (qs > qp->q_addr
+ && (qs->stime.tv_sec == 0 || qs->ns != ns))
qs--;
*stp = qs->stime;
/* XXX - sometimes stp still ends up pointing to
@@ -475,9 +397,9 @@ ns_resp(msg, msglen)
* Why? What should we do about it?
*/
dprintf(1, (ddt,
- "Response from unused address %s, assuming %s\n",
- inet_etoa(&from_addr),
- inet_etoa(&qs->ns_addr)));
+ "Response from unused address %s, assuming %s\n",
+ sin_ntoa(&from_addr),
+ sin_ntoa(&qs->ns_addr)));
/* XXX - catch aliases here */
}
@@ -488,10 +410,10 @@ ns_resp(msg, msglen)
* as big as an int.
*/
if ((tt.tv_sec - stp->tv_sec) > (INT_MAX-999)/1000) {
- rtrip = INT_MAX;
+ rtrip = INT_MAX;
} else {
- rtrip = ((tt.tv_sec - stp->tv_sec) * 1000 +
- (tt.tv_usec - stp->tv_usec) / 1000);
+ rtrip = ((tt.tv_sec - stp->tv_sec) * 1000 +
+ (tt.tv_usec - stp->tv_usec) / 1000);
}
dprintf(3, (ddt, "stime %lu/%lu now %lu/%lu rtt %ld\n",
@@ -529,7 +451,7 @@ ns_resp(msg, msglen)
if (ns && qs->ns && (qp->q_nusedns < NSMAX)) {
qp->q_usedns[qp->q_nusedns++] = qs->ns;
dprintf(2, (ddt, "NS #%d addr %s used, rtt %d\n",
- n, inet_etoa(&qs->ns_addr),
+ n, sin_ntoa(&qs->ns_addr),
ns->d_nstime));
}
@@ -544,7 +466,9 @@ ns_resp(msg, msglen)
* and are no longer the correct type. XXX
*/
- for (n = 0, qs = qp->q_addr; (u_int)n < qp->q_naddr; n++, qs++) {
+ for (n = 0, qs = qp->q_addr;
+ (u_int)n < qp->q_naddr;
+ n++, qs++) {
ns2 = qs->nsdata;
if ((!ns2) || (ns2 == ns))
continue;
@@ -563,7 +487,7 @@ ns_resp(msg, msglen)
} else
ns2->d_nstime = (u_int32_t)(ns2->d_nstime * GAMMA);
dprintf(2, (ddt, "NS #%d %s rtt now %d\n", n,
- inet_etoa(&qs->ns_addr),
+ sin_ntoa(&qs->ns_addr),
ns2->d_nstime));
}
}
@@ -579,68 +503,83 @@ ns_resp(msg, msglen)
}
#endif
- /*************************************************************/
-
+#ifdef LAME_DELEGATION
/*
- * Save answers, authority, and additional records for future use.
+ * Non-authoritative, no answer, no error
*/
- nscount = 0;
- tp = cp;
- dprintf(3, (ddt, "resp: ancount %d, aucount %d, arcount %d\n",
- ancount, aucount, arcount));
+ if (qdcount == 1 && hp->rcode == NOERROR && !hp->aa && ancount == 0
+ && aucount > 0
+#ifdef BIND_NOTIFY
+ && hp->opcode != NS_NOTIFY_OP
+#endif
+ ) {
+ u_char *tp;
+ int type, class;
+#ifdef DEBUG
+ if (debug > 0)
+ fp_nquery(msg, msglen, ddt);
+#endif
+ /*
+ * Since there is no answer section (ancount == 0),
+ * we must be pointing at the authority section (aucount > 0).
+ */
+ tp = cp;
+ n = dn_expand(msg, eom, tp, name, sizeof name);
+ if (n < 0) {
+ formerrmsg = expandFailedAuth;
+ goto formerr;
+ }
+ tp += n;
+ GETSHORT(type, tp);
+ if (tp >= eom) {
+ formerrmsg = outofDataAuth;
+ goto formerr;
+ }
+ GETSHORT(class, tp);
+ if (tp >= eom) {
+ formerrmsg = outofDataAuth;
+ goto formerr;
+ }
- /*
- * If there's an answer, check if it's a CNAME response;
- * if no answer but aucount > 0, see if there is an NS
- * or just an SOA. (NOTE: ancount might be 1 with a CNAME,
- * and NS records may still be in the authority section;
- * we don't bother counting them, as we only use nscount
- * if ancount == 0.)
- */
- if (ancount == 1 || (ancount == 0 && aucount > 0)) {
- c = aucount;
- do {
- if (tp >= eom) {
- formerrmsg = outofDataAnswer;
- goto formerr;
- }
- n = dn_skipname(tp, eom);
- if (n <= 0) {
- formerrmsg = skipnameFailedAnswer;
- goto formerr;
- }
- tp += n; /* name */
- GETSHORT(i, tp); /* type */
- tp += INT16SZ; /* class */
- tp += INT32SZ; /* ttl */
- GETSHORT(count, tp); /* dlen */
- if (tp + count > eom) {
- formerrmsg = dlenOverrunAnswer;
- goto formerr;
- }
- tp += count;
- if (ancount && i == T_CNAME) {
- cname++;
- dprintf(1,
- (ddt,
- "CNAME - needs more processing\n"
- )
- );
- if (!qp->q_cmsglen) {
- qp->q_cmsg = qp->q_msg;
- qp->q_cmsglen = qp->q_msglen;
- qp->q_msg = NULL;
- qp->q_msglen = 0;
- }
- }
- /*
- * See if authority record is a nameserver.
+ /*
+ * If the answer delegates us either to the same level in
+ * the hierarchy or closer to the root, we consider this
+ * server lame. Note that for now we only log the message
+ * if the T_NS was C_IN, which is technically wrong (NS is
+ * visible in all classes) but necessary anyway (non-IN
+ * classes tend to not have good strong delegation graphs).
+ */
+
+ if (type == T_NS && samedomain(qp->q_domain, name)) {
+ nameserIncr(from_addr.sin_addr, nssRcvdLDel);
+ /* mark server as bad */
+ if (!qp->q_fwd)
+ for (i = 0; i < (int)qp->q_naddr; i++)
+ if (qp->q_addr[i].ns_addr.sin_addr.s_addr
+ == from_addr.sin_addr.s_addr)
+ qp->q_addr[i].nretry = MAXRETRY;
+#ifdef LAME_LOGGING
+ if (class == C_IN &&
+ !haveComplained((char*)nhash(sin_ntoa(&from_addr)),
+ (char*)nhash(qp->q_domain)))
+ syslog(LAME_LOGGING,
+ "Lame server on '%s' (in '%s'?): %s%s\n",
+ qname, qp->q_domain,
+ sin_ntoa(&from_addr),
+ learntFrom(qp, &from_addr));
+
+#endif /* LAME_LOGGING */
+ /* XXX - doesn't handle responses sent from the wrong
+ * interface on a multihomed server
*/
- if (ancount == 0 && i == T_NS)
- nscount++;
- } while (--c > 0);
- tp = cp;
+ if (qp->q_fwd ||
+ qp->q_addr[qp->q_curaddr].ns_addr.sin_addr.s_addr
+ == from_addr.sin_addr.s_addr)
+ retry(qp);
+ return;
+ }
}
+#endif /* LAME_DELEGATION */
if (qp->q_flags & Q_ZSERIAL) {
if (hp->aa && ancount > 0 && hp->rcode == NOERROR &&
@@ -702,14 +641,13 @@ ns_resp(msg, msglen)
* Add the info received in the response to the data base.
*/
c = ancount + aucount + arcount;
-#ifdef NCACHE
+
/* -ve $ing non-existence of record, must handle non-authoritative
* NOERRORs with c == 0.
*/
- if (!hp->aa && hp->rcode == NOERROR && c == 0) {
+ if (!hp->aa && hp->rcode == NOERROR && c == 0)
goto return_msg;
- } /*should ideally validate message before returning it*/
-#endif /*NCACHE*/
+
#ifdef notdef
/*
* If the request was for a CNAME that doesn't exist,
@@ -729,7 +667,6 @@ ns_resp(msg, msglen)
}
#endif /* notdef */
- nspp = nsp;
if (qp->q_flags & Q_SYSTEM)
dbflags = DB_NOTAUTH | DB_NODATA;
else
@@ -747,88 +684,175 @@ ns_resp(msg, msglen)
}
/* XXX - should retry this query with TCP */
}
+
+ tp = cp;
+
+ restart = 0;
+ validanswer = 0;
+ nscount = 0;
+ cname = 0;
#ifdef VALIDATE
- tempcp = cp;
- validatelist = (int *)malloc(count * sizeof(int));
- lesscount = 0; /*initialize*/
- old_ancount = ancount;
+ defer_rm_count = 0;
+#endif
+
for (i = 0; i < count; i++) {
+ struct databuf *ns3 = NULL;
+ u_char cred;
int VCode;
- if (tempcp >= eom) {
- free((char *)validatelist);
+ u_int16_t type, class;
+
+ if (cp >= eom) {
formerrmsg = outofDataFinal;
goto formerr;
}
- if ((n = dovalidate(msg, msglen, tempcp, 0,
- dbflags, server, &VCode)) < 0) {
- dprintf(1, (ddt,
- "resp: leaving, dovalidate failed\n"));
- free((char *)validatelist);
- /* return code filled in by dovalidate */
- goto return_msg;
+ /* Get the DNAME. */
+ tempcp = cp;
+ n = dn_expand(msg, eom, tempcp, name, sizeof name);
+ if (n <= 0) {
+ formerrmsg = outofDataFinal;
+ goto formerr;
}
- validatelist[i] = VCode;
- if (VCode == INVALID) lesscount++;
tempcp += n;
- }
-
- /* need to delete INVALID records from the message
- * and change fields appropriately
- */
- n = update_msg(msg, &msglen, validatelist, count);
- free((char *)validatelist);
- if (n < 0) {
- formerrmsg = editFailed;
- goto formerr;
- }
- count -= lesscount;
+ GETSHORT(type, tempcp);
+ GETSHORT(class, tempcp);
- ancount = ntohs(hp->ancount);
- if (old_ancount && !ancount) {
- /* We lost all the answers */
- dprintf(1, (ddt, "validate count -> 0"));
- return;
- }
-#endif
-
- for (i = 0; i < count; i++) {
- struct databuf *ns3;
- u_char cred;
+ /*
+ * See if there are any NS RRs in the authority section
+ * for the negative caching logic below. We'll count
+ * these before validation.
+ */
+ if (type == T_NS && i >= ancount && i < ancount + aucount)
+ nscount++;
- if (cp >= eom) {
- formerrmsg = outofDataFinal;
- goto formerr;
- }
+ /* Decide what credibility this ought to have in the cache. */
if (i < ancount)
- cred = hp->aa ? DB_C_AUTH : DB_C_ANSWER;
+ cred = (hp->aa && !strcasecmp(name, qname))
+ ? DB_C_AUTH
+ : DB_C_ANSWER;
else
cred = (qp->q_flags & Q_PRIMING)
? DB_C_ANSWER
: DB_C_ADDITIONAL;
- ns3 = 0;
+#ifdef VALIDATE
+ if ((n = dovalidate(msg, msglen, cp, 0,
+ dbflags, qp->q_domain, server,
+ &VCode)) < 0) {
+ formerrmsg = outofDataFinal;
+ goto formerr;
+ }
+ if (VCode == INVALID && !(qp->q_flags & Q_SYSTEM)) {
+ /*
+ * If anything in the answer section fails
+ * validation this means that it definitely did
+ * not reside below the domain owning the NS RRs
+ * that we sent the query to. This means either
+ * that it was the target of a CNAME early in the
+ * response, in which case we will treat this the
+ * same as if the answer was incomplete and restart
+ * the query on the CNAME target, or that someone
+ * was trying to spoof us.
+ */
+ if (i < ancount)
+ restart = 1;
+ /*
+ * Restart or no, if we're here it means we are not
+ * going to cache this RR. That being the case, we
+ * must burn down whatever partial RRset we've got
+ * in the cache now, lest we inadvertently answer
+ * with a truncated RRset in some future section.
+ */
+ for (c = 0; c < defer_rm_count; c++)
+ if (!strcasecmp(defer_rm[c].name, name) &&
+ defer_rm[c].class == class &&
+ defer_rm[c].type == type)
+ break;
+ if (c < defer_rm_count) {
+ if (defer_rm[c].cred < cred)
+ defer_rm[c].cred = cred;
+ } else {
+ if (defer_rm_count+1 >=
+ (sizeof defer_rm / sizeof defer_rm[0])) {
+ formerrmsg = "too many RRs in ns_resp";
+ goto formerr;
+ }
+ defer_rm[defer_rm_count].name = savestr(name);
+ defer_rm[defer_rm_count].type = type;
+ defer_rm[defer_rm_count].class = class;
+ defer_rm[defer_rm_count].cred = cred;
+ defer_rm_count++;
+ }
+ } else {
+#endif
+ if (i < ancount) {
+ /*
+ * If there are any non-CNAME RRs (or
+ * CNAME RRs if they are an acceptable)
+ * then the query is complete unless an
+ * intermediate CNAME didn't pass validation,
+ * but that's OK.
+ */
+ if (type != T_CNAME || qtype == T_CNAME ||
+ qtype == T_ANY)
+ validanswer = 1;
+ else
+ cname = 1;
+ }
n = doupdate(msg, msglen, cp, 0, &ns3, dbflags, cred);
- if (n < 0) {
- dprintf(1, (ddt, "resp: leaving, doupdate failed\n"));
-
- /* return code filled in by doupdate */
- goto return_msg;
+#ifdef VALIDATE
}
- /*
- * Remember nameservers from the authority section
- * for referrals.
- * (This is usually overwritten by findns below(?). XXX
- */
- if (ns3 && i >= ancount && i < ancount + aucount &&
- nspp < &nsp[NSMAX-1]) {
- *nspp++ = ns3;
-#ifdef DATUMREFCNT
- ns3->d_rcnt++;
- *nspp = NULL;
#endif
+ if (n < 0) {
+ dprintf(1, (ddt, "resp: leaving, doupdate failed\n"));
+ formerrmsg = outofDataFinal;
+ goto formerr;
}
cp += n;
}
+#ifdef VALIDATE
+ if (defer_rm_count > 0) {
+ for (i = 0; i < defer_rm_count; i++) {
+ register struct databuf *db = NULL;
+
+ fname = "";
+ htp = hashtab; /* lookup relative to root */
+ np = nlookup(defer_rm[i].name, &htp, &fname, 0);
+ if (np && fname == defer_rm[i].name &&
+ defer_rm[i].class != C_ANY &&
+ defer_rm[i].type != T_ANY) {
+ /*
+ * If doupdate() wouldn't have cached this
+ * RR anyway, there's no need to delete it.
+ */
+ for (db = np->n_data;
+ db != NULL;
+ db = db->d_next) {
+ if (!db->d_zone &&
+ match(db, defer_rm[i].class,
+ defer_rm[i].type) &&
+ db->d_cred >= defer_rm[i].cred) {
+ break;
+ }
+ }
+ if (db == NULL)
+ delete_all(np, defer_rm[i].class,
+ defer_rm[i].type);
+ /* XXX: should delete name node if empty? */
+ }
+ syslog(LOG_DEBUG, "defer_rm [%s %s %s] (np%#x, db%#x)",
+ defer_rm[i].name,
+ p_class(defer_rm[i].class),
+ p_type(defer_rm[i].type),
+ np, db);
+ free(defer_rm[i].name);
+ }
+ }
+#endif
+
+ if (cp > eom) {
+ formerrmsg = outofDataAFinal;
+ goto formerr;
+ }
if ((qp->q_flags & Q_SYSTEM) && ancount) {
if (qp->q_flags & Q_PRIMING)
@@ -847,30 +871,31 @@ ns_resp(msg, msglen)
}
#endif
qremove(qp);
-#ifdef DATUMREFCNT
- free_nsp(nsp);
-#endif
return;
}
- if (cp > eom) {
- formerrmsg = outofDataAFinal;
- goto formerr;
- }
+ if (ancount && !validanswer)
+ /*
+ * Everything passed validation but we didn't get the
+ * final answer. The response must have contained
+ * a dangling CNAME. Force a restart of the query.
+ */
+ restart = 1;
/*
* If there are addresses and this is a local query,
* sort them appropriately for the local context.
*/
- if (ancount > 1 && (lp = local(&qp->q_from)) != NULL)
+#ifdef SORT_RESPONSE
+ if (!restart && ancount > 1 && (lp = local(&qp->q_from)) != NULL)
sort_response(tp, ancount, lp, eom);
+#endif
/*
* An answer to a T_ANY query or a successful answer to a
* regular query with no indirection, then just return answer.
*/
- if ((qtype == T_ANY && ancount) ||
- (!cname && !qp->q_cmsglen && ancount)) {
+ if (!restart && ancount && (qtype == T_ANY || !qp->q_cmsglen)) {
dprintf(3, (ddt, "resp: got as much answer as there is\n"));
goto return_msg;
}
@@ -884,6 +909,7 @@ ns_resp(msg, msglen)
/* we have an authoritative NO */
dprintf(3, (ddt, "resp: leaving auth NO\n"));
if (qp->q_cmsglen) {
+ /* XXX - what about additional CNAMEs in the chain? */
msg = qp->q_cmsg;
msglen = qp->q_cmsglen;
hp = (HEADER *)msg;
@@ -906,7 +932,17 @@ ns_resp(msg, msglen)
founddata = 0;
foundname = 0;
dname = name;
- if (!cname && qp->q_cmsglen && ancount) {
+ /*
+ * Even with VALIDATE, if restart==0 and ancount > 0, we should
+ * have some valid data because because the data in the answer
+ * section is owned by the query name and that passes the
+ * validation test by definition
+ *
+ * XXX - the restart stuff doesn't work if any of the answer RRs
+ * is not cacheable (TTL==0 or unknown RR type), since all of the
+ * answer must pass through the cache and be re-assembled.
+ */
+ if ((!restart || !cname) && qp->q_cmsglen && ancount) {
dprintf(1, (ddt, "Cname second pass\n"));
newmsglen = qp->q_cmsglen;
bcopy(qp->q_cmsg, newmsg, newmsglen);
@@ -915,23 +951,32 @@ ns_resp(msg, msglen)
bcopy(msg, newmsg, newmsglen);
}
hp = (HEADER *) newmsg;
- hp->ancount = 0;
- hp->nscount = 0;
- hp->arcount = 0;
+ hp->ancount = htons(0);
+ hp->nscount = htons(0);
+ hp->arcount = htons(0);
dnptrs[0] = newmsg;
dnptrs[1] = NULL;
cp = newmsg + HFIXEDSZ;
- if (cname)
- cp += dn_skipname(cp, newmsg + newmsglen) + QFIXEDSZ;
- n = dn_expand(newmsg, newmsg + newmsglen, cp, dname, sizeof name);
+ /*
+ * Keep in mind that none of this code works when QDCOUNT>1.
+ * cp ends up pointed just past the query section in both cases.
+ */
+ /*
+ * Arrange for dname to contain the query name. The query
+ * name can be either the original query name if restart==0
+ * or the target of the last CNAME if we are following a
+ * CNAME chain and were referred.
+ */
+ n = dn_expand(newmsg, newmsg + newmsglen, cp, dname,
+ sizeof name);
if (n < 0) {
dprintf(1, (ddt, "dn_expand failed\n"));
goto servfail;
}
- if (!cname)
- cp += n + QFIXEDSZ;
+ cp += n + QFIXEDSZ;
buflen = sizeof(newmsg) - (cp - newmsg);
+ cname = 0;
try_again:
dprintf(1, (ddt, "resp: nlookup(%s) qtype=%d\n", dname, qtype));
fname = "";
@@ -949,7 +994,7 @@ ns_resp(msg, msglen)
goto fetch_ns; /* NO data available */
cp += n;
buflen -= n;
- hp->ancount += count;
+ hp->ancount = htons(ntohs(hp->ancount) + (u_int16_t)count);
if (fname != dname && qtype != T_CNAME && qtype != T_ANY) {
cname++;
goto try_again;
@@ -961,7 +1006,10 @@ ns_resp(msg, msglen)
foundname, count, founddata, cname));
fetch_ns:
- hp->ancount = htons(hp->ancount);
+
+ if (hp->tc)
+ goto return_newmsg;
+
/*
* Look for name servers to refer to and fill in the authority
* section or record the address for forwarding the query
@@ -983,9 +1031,9 @@ ns_resp(msg, msglen)
* in the auth. section if there's no error.
*/
if (foundname == 0 && np) {
- n = doaddauth(hp, cp, buflen, np, nsp[0]);
- cp += n;
- buflen -= n;
+ n = doaddauth(hp, cp, buflen, np, nsp[0]);
+ cp += n;
+ buflen -= n;
}
}
goto return_newmsg;
@@ -996,7 +1044,7 @@ ns_resp(msg, msglen)
if (founddata) {
hp = (HEADER *)newmsg;
- n = add_data(np, nsp, cp, buflen);
+ n = add_data(np, nsp, cp, buflen, &count);
if (n < 0) {
hp->tc = 1;
n = (-n);
@@ -1028,36 +1076,36 @@ ns_resp(msg, msglen)
const char *result;
if (qp->q_addr[i].ns != NULL) {
+ if ((--(qp->q_addr[i].ns->d_rcnt)))
+ result = busy;
+ else
+ result = freed;
dprintf(1, (ddt, "ns_resp: ns %s rcnt %d (%s)\n",
qp->q_addr[i].ns->d_data,
qp->q_addr[i].ns->d_rcnt,
result));
- if ((--(qp->q_addr[i].ns->d_rcnt)))
- result = busy;
- else {
+ if (result == freed)
free((char*)qp->q_addr[i].ns);
- result = freed;
- }
}
if (qp->q_addr[i].nsdata != NULL) {
if ((--(qp->q_addr[i].nsdata->d_rcnt)))
result = busy;
- else {
- free((char*)qp->q_addr[i].nsdata);
+ else
result = freed;
- }
dprintf(1, (ddt,
"ns_resp: nsdata %08.8X rcnt %d (%s)\n",
*(int32_t *)(qp->q_addr[i].nsdata->d_data),
qp->q_addr[i].nsdata->d_rcnt,
result));
+ if (result == freed)
+ free((char*)qp->q_addr[i].nsdata);
}
}
#endif
qp->q_naddr = 0;
qp->q_curaddr = 0;
qp->q_fwd = fwdtab;
-#ifdef LAME_DELEGATION
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
getname(np, qp->q_domain, sizeof(qp->q_domain));
#endif /* LAME_DELEGATION */
if ((n = nslookup(nsp, qp, dname, "ns_resp")) <= 0) {
@@ -1080,10 +1128,13 @@ ns_resp(msg, msglen)
"resp: leaving, MAXCNAMES exceeded\n"));
goto servfail;
}
- dprintf(1, (ddt, "q_cname = %d\n",qp->q_cname));
+ dprintf(1, (ddt, "q_cname = %d\n", qp->q_cname));
dprintf(3, (ddt,
"resp: building recursive query; nslookup\n"));
- if (qp->q_msg)
+ if (!qp->q_cmsg) {
+ qp->q_cmsg = qp->q_msg;
+ qp->q_cmsglen = qp->q_msglen;
+ } else if (qp->q_msg)
(void) free(qp->q_msg);
if ((qp->q_msg = (u_char *)malloc(BUFSIZ)) == NULL) {
syslog(LOG_NOTICE, "resp: malloc error\n");
@@ -1098,7 +1149,7 @@ ns_resp(msg, msglen)
}
qp->q_msglen = n;
hp = (HEADER *) qp->q_msg;
- hp->rd = 0;
+ hp->rd = 0;
} else
hp = (HEADER *) qp->q_msg;
hp->id = qp->q_nsid = htons(nsid_next());
@@ -1108,7 +1159,7 @@ ns_resp(msg, msglen)
schedretry(qp, retrytime(qp));
nsa = Q_NEXTADDR(qp, 0);
dprintf(1, (ddt, "resp: forw -> %s ds=%d nsid=%d id=%d %dms\n",
- inet_etoa(nsa), ds,
+ sin_ntoa(nsa), ds,
ntohs(qp->q_nsid), ntohs(qp->q_id),
(qp->q_addr[0].nsdata != NULL)
? qp->q_addr[0].nsdata->d_nstime
@@ -1122,7 +1173,7 @@ ns_resp(msg, msglen)
sizeof(struct sockaddr_in)) < 0) {
if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
syslog(LOG_INFO, "ns_resp: sendto(%s): %m",
- inet_etoa(nsa));
+ sin_ntoa(nsa));
nameserIncr(nsa->sin_addr, nssSendtoErr);
}
hp->rd = 0; /* leave set to 0 for dup detection */
@@ -1138,7 +1189,7 @@ ns_resp(msg, msglen)
if (!haveComplained((char*)from_addr.sin_addr.s_addr,
(char*)nhash(formerrmsg)))
syslog(LOG_INFO, "Malformed response from %s (%s)\n",
- inet_etoa(&from_addr), formerrmsg);
+ sin_ntoa(&from_addr), formerrmsg);
nameserIncr(from_addr.sin_addr, nssSentFErr);
#ifdef DATUMREFCNT
free_nsp(nsp);
@@ -1408,13 +1459,11 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
*/
if ( (hp->opcode == UPDATED) || (hp->opcode == UPDATEDA) ) {
if (cp != (u_char *)(msg + msglen)) {
- dprintf(1,
- (ddt,
- "FORMERR UPDATE message length off\n"
- )
- );
- hp->rcode = FORMERR;
- return (-1);
+ dprintf(1, (ddt,
+ "FORMERR UPDATE message length off\n"
+ ));
+ hp->rcode = FORMERR;
+ return (-1);
}
}
if ((zonenum = findzone(dname, class)) == 0) {
@@ -1533,7 +1582,7 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
ttl += tt.tv_sec;
#if defined(TRACEROOT) || defined(BOGUSNS)
if ((type == T_NS) && (savens != NULL)) {
- char qname[MAXDNAME], *temp;
+ char *temp, qname[MAXDNAME];
register int bogus = 0;
int bogusns = 0;
#ifdef BOGUSNS
@@ -1558,7 +1607,7 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
"bogus root NS"))
syslog(LOG_NOTICE,
"bogus root NS %s rcvd from %s on query for \"%s\"",
- data, inet_etoa(&from_addr), qname);
+ data, sin_ntoa(&from_addr), qname);
return (cp - rrp);
}
#ifdef BOGUSNS
@@ -1566,8 +1615,8 @@ doupdate(msg, msglen, rrp, zone, savens, flags, cred)
if (!haveComplained((char*)from_addr.sin_addr.s_addr,
"bogus nonroot NS"))
syslog(LOG_INFO,
- "bogus nonroot NS %s rcvd from %s on query for \"%s\"",
- data, inet_etoa(&from_addr), qname);
+ "bogus nonroot NS %s rcvd from %s on query for \"%s\"",
+ data, sin_ntoa(&from_addr), qname);
return (cp - rrp);
}
#endif
@@ -1602,13 +1651,13 @@ send_msg(msg, msglen, qp)
#ifdef DEBUG
if (debug) {
fprintf(ddt,"send_msg -> %s (%s %d) id=%d\n",
- inet_etoa(&qp->q_from),
+ sin_ntoa(&qp->q_from),
qp->q_stream == QSTREAM_NULL ? "UDP" : "TCP",
qp->q_stream == QSTREAM_NULL ? qp->q_dfd
: qp->q_stream->s_rfd,
ntohs(qp->q_id));
}
- if (debug>4) {
+ if (debug > 4) {
struct qinfo *tqp;
for (tqp = nsqhead; tqp!=QINFO_NULL; tqp = tqp->q_link) {
@@ -1623,7 +1672,7 @@ send_msg(msg, msglen, qp)
(u_long)qp->q_next, (u_long)qp->q_link);
}
}
- if (debug >= 10)
+ if (debug > 5)
fp_nquery(msg, msglen, ddt);
#endif /* DEBUG */
if (qp->q_stream == QSTREAM_NULL) {
@@ -1637,7 +1686,7 @@ send_msg(msg, msglen, qp)
#endif
syslog(LOG_INFO,
"send_msg: sendto(%s): %m",
- inet_etoa(&qp->q_from));
+ sin_ntoa(&qp->q_from));
nameserIncr(qp->q_from.sin_addr, nssSendtoErr);
return (1);
}
@@ -1889,7 +1938,7 @@ sysquery(dname, class, type, nss, nsc, opcode)
qp->q_fwd = fwdtab;
qp->q_expire = tt.tv_sec + RETRY_TIMEOUT*2;
qp->q_flags |= Q_SYSTEM;
-#ifdef LAME_DELEGATION
+#if defined(LAME_DELEGATION) || defined(VALIDATE)
getname(np, qp->q_domain, sizeof(qp->q_domain));
#endif /* LAME_DELEGATION */
@@ -1910,7 +1959,7 @@ sysquery(dname, class, type, nss, nsc, opcode)
hp->rd = (qp->q_fwd ? 1 : 0);
/* First check for an already pending query for this data */
- for (oqp = nsqhead; oqp != QINFO_NULL; oqp = oqp->q_link) {
+ for (oqp = nsqhead; oqp != QINFO_NULL; oqp = oqp->q_link) {
if ((oqp != qp)
&& (oqp->q_msglen == qp->q_msglen)
&& bcmp((char *)oqp->q_msg+2,
@@ -1968,8 +2017,8 @@ sysquery(dname, class, type, nss, nsc, opcode)
nsa = Q_NEXTADDR(qp, 0);
dprintf(1, (ddt,
- "sysquery: send -> %s dfd=%d nsid=%d id=%d retry=%ld\n",
- inet_etoa(nsa), qp->q_dfd,
+ "sysquery: send -> %s dfd=%d nsid=%d id=%d retry=%ld\n",
+ sin_ntoa(nsa), qp->q_dfd,
ntohs(qp->q_nsid), ntohs(qp->q_id),
qp->q_time));
#ifdef DEBUG
@@ -1981,7 +2030,7 @@ sysquery(dname, class, type, nss, nsc, opcode)
sizeof(struct sockaddr_in)) < 0) {
if (!haveComplained((char*)nsa->sin_addr.s_addr, sendtoStr))
syslog(LOG_INFO, "sysquery: sendto(%s): %m",
- inet_etoa(nsa));
+ sin_ntoa(nsa));
nameserIncr(nsa->sin_addr, nssSendtoErr);
}
nameserIncr(nsa->sin_addr, nssSentSysQ);
@@ -2057,9 +2106,9 @@ check_ns()
for (np = hashtab->h_tab[0]; np != NULL; np = np->n_next) {
if (np->n_dname[0] != 0)
continue;
- for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
- if (dp->d_type != T_NS)
- continue;
+ for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
+ if (dp->d_type != T_NS)
+ continue;
/* look for A records */
dname = (caddr_t) dp->d_data;
@@ -2069,29 +2118,31 @@ check_ns()
dprintf(3, (ddt,
"check_ns: %s: not found %s %#lx\n",
dname, fname, (u_long)tnp));
- sysquery(dname, dp->d_class, T_A, NULL, 0, QUERY);
- continue;
+ sysquery(dname, dp->d_class, T_A, NULL,
+ 0, QUERY);
+ continue;
}
/* look for name server addresses */
found_arr = 0;
- for (tdp=tnp->n_data; tdp!=NULL; tdp=tdp->d_next) {
- if (tdp->d_type != T_A ||
- tdp->d_class != dp->d_class)
- continue;
- if ((tdp->d_zone == 0) &&
- (tdp->d_ttl < curtime)) {
- dprintf(3, (ddt,
- "check_ns: stale entry '%s'\n",
- tnp->n_dname));
- /* Cache invalidate the address RR's */
- delete_all(tnp, dp->d_class, T_A);
- found_arr = 0;
- break;
- }
- found_arr++;
+ for (tdp=tnp->n_data; tdp != NULL; tdp=tdp->d_next) {
+ if (tdp->d_type != T_A ||
+ tdp->d_class != dp->d_class)
+ continue;
+ if ((tdp->d_zone == 0) &&
+ (tdp->d_ttl < curtime)) {
+ dprintf(3, (ddt,
+ "check_ns: stale entry '%s'\n",
+ tnp->n_dname));
+ /* Cache invalidate the address RR's */
+ delete_all(tnp, dp->d_class, T_A);
+ found_arr = 0;
+ break;
+ }
+ found_arr++;
}
if (!found_arr)
- sysquery(dname, dp->d_class, T_A, NULL, 0, QUERY);
+ sysquery(dname, dp->d_class, T_A, NULL,
+ 0, QUERY);
}
}
}
@@ -2240,9 +2291,9 @@ try_parent:
}
/*
- * Extract RR's from the given node that match class and type.
- * Return number of bytes added to response.
- * If no matching data is found, then 0 is returned.
+ * Extract RR's from the given node that match class and type.
+ * Return number of bytes added to response.
+ * If no matching data is found, then 0 is returned.
*/
int
finddata(np, class, type, hp, dnamep, lenp, countp)
@@ -2262,7 +2313,7 @@ finddata(np, class, type, hp, dnamep, lenp, countp)
register struct databuf **dpp;
- for (dpp = &np->n_data; dp = *dpp; dpp = &dp->d_next) {
+ for (dpp = &np->n_data; dp = *dpp; dpp = &dp->d_next) {
if (dp->d_next && wanted(dp, class, type)) {
register struct databuf *lp;
@@ -2279,7 +2330,7 @@ finddata(np, class, type, hp, dnamep, lenp, countp)
}
}
#endif /*ROUND_ROBIN*/
-
+
buflen = *lenp;
#ifdef DEBUG
if (buflen > PACKETSZ)
@@ -2336,7 +2387,7 @@ finddata(np, class, type, hp, dnamep, lenp, countp)
* This should not happen, yet it does...
*/
syslog(LOG_INFO,
- "NODATA & data for \"%s\" type %d class %d",
+ "NODATA & data for \"%s\" type %d class %d",
*dnamep, type, class);
continue;
}
@@ -2444,12 +2495,12 @@ wanted(dp, class, type)
return (1);
case T_CNAME:
#ifdef NCACHE
- if (dp->d_rcode != NOERROR_NODATA)
+ if (dp->d_rcode != NOERROR_NODATA)
#endif
- return (1);
+ return (1);
#ifdef NCACHE
- else
- break;
+ else
+ break;
#endif
}
switch (type) {
@@ -2479,20 +2530,21 @@ wanted(dp, class, type)
/*
* Add RR entries from dpp array to a query/response.
* Return the number of bytes added or negative the amount
- * added if truncation was required. Typically you are
+ * added if truncation occured. Typically you are
* adding NS records to a response.
*/
int
-add_data(np, dpp, cp, buflen)
+add_data(np, dpp, cp, buflen, countp)
struct namebuf *np;
struct databuf **dpp;
register u_char *cp;
- int buflen;
+ int buflen, *countp;
{
register struct databuf *dp;
char dname[MAXDNAME];
- register int n, count = 0;
+ register int n, bytes;
+ bytes = *countp = 0;
getname(np, dname, sizeof(dname));
for (dp = *dpp++; dp != NULL; dp = *dpp++) {
if (stale(dp))
@@ -2502,18 +2554,20 @@ add_data(np, dpp, cp, buflen)
continue;
#endif
if ((n = make_rr(dname, dp, cp, buflen, 1)) < 0)
- return (-count); /* Truncation */
+ return (-bytes); /* Truncation */
cp += n;
buflen -= n;
- count += n;
+ bytes += n;
+ (*countp)++;
}
- return (count);
+ return (bytes);
}
/*
* This is best thought of as a "cache invalidate" function.
* It is called whenever a piece of data is determined to have
- * timed out. It is better to have no information, than to
+ * become invalid either through a timeout or a validation
+ * failure. It is better to have no information, than to
* have partial information you pass off as complete.
*/
void
diff --git a/usr.sbin/named/ns_sort.c b/usr.sbin/named/ns_sort.c
index 499a5b4..0f53cce 100644
--- a/usr.sbin/named/ns_sort.c
+++ b/usr.sbin/named/ns_sort.c
@@ -1,6 +1,6 @@
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)ns_sort.c 4.10 (Berkeley) 3/3/91";
-static char rcsid[] = "$Id: ns_sort.c,v 8.2 1995/06/29 09:26:17 vixie Exp $";
+static char rcsid[] = "$Id: ns_sort.c,v 8.3 1995/12/22 10:20:30 vixie Exp $";
#endif /* not lint */
/*
@@ -73,6 +73,7 @@ static char rcsid[] = "$Id: ns_sort.c,v 8.2 1995/06/29 09:26:17 vixie Exp $";
static int sort_rr __P((u_char *cp, int count, struct netinfo *ntp, u_char *eom));
+#ifdef SORT_RESPONSE
struct netinfo *
local(from)
struct sockaddr_in *from;
@@ -167,3 +168,4 @@ sort_rr(cp, count, ntp, eom)
}
return (0);
}
+#endif
diff --git a/usr.sbin/named/ns_validate.c b/usr.sbin/named/ns_validate.c
index 6978de1..a0c14d8 100644
--- a/usr.sbin/named/ns_validate.c
+++ b/usr.sbin/named/ns_validate.c
@@ -10,8 +10,11 @@
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/file.h>
+
#include <netinet/in.h>
#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
#include <syslog.h>
#include <errno.h>
#include <stdio.h>
@@ -50,7 +53,7 @@ static int VQcount;
* VALID_NO_CACHE if the name is something we are authoritative for.
*
* pseudocode for function validate is as follows:
- * validate(domain, server, type, class, data, dlen, rcode) {
+ * validate(domain, qdomain, server, type, class, data, dlen, rcode) {
*
* if (dname or a higher level name not found in cache)
* return INVALID;
@@ -65,6 +68,8 @@ static int VQcount;
* else return INVALID;
*
* if (we are not authoritative) /findns() returned OK;/
+ * if (domain lives below the qdomain)
+ * return VALID_CACHE;
* if (address records for NS's found in cache){
* if ("server" = one of the addresses){
* return VALID_CACHE;
@@ -88,15 +93,14 @@ static int VQcount;
* we have needs_prime_cache = 0;
*****************************************************************************/
int
-validate(dname, server, type, class, data, dlen
+validate(dname, qdomain, server, type, class, data, dlen
#ifdef NCACHE
,rcode
#endif
)
- char *dname;
+ char *dname, *qdomain;
struct sockaddr_in *server;
- int type;
- int class;
+ int type, class;
char *data;
int dlen;
#ifdef NCACHE
@@ -107,7 +111,7 @@ validate(dname, server, type, class, data, dlen
struct hashbuf *htp;
struct databuf *nsp[NSMAX];
int count;
- char *fname;
+ const char *fname;
int exactmatch = 0;
struct fwdinfo *fwd;
@@ -133,10 +137,8 @@ validate(dname, server, type, class, data, dlen
/* we were able to locate namebufs for this domain, or a parent domain,
* or ??? */
- if (np == NULL) {
- fname = (char *)malloc(1);
- fname[0] = '\0';
- }
+ if (np == NULL)
+ fname = "";
dprintf(5, (ddt,
"validate:namebuf found np:%#lx, d:\"%s\", f:\"%s\"\n",
(u_long)np, dname, fname));
@@ -145,8 +147,6 @@ validate(dname, server, type, class, data, dlen
dnamep = np;
exactmatch = 1;
}
- if (np == NULL && fname != NULL)
- free((char *)fname);
switch (findns(&np, class, nsp, &count, 0)) {
case NXDOMAIN:
/** we are authoritative for this domain, lookup name
@@ -216,12 +216,11 @@ validate(dname, server, type, class, data, dlen
return (INVALID);
case OK: /*proceed */
- dprintf(5,
- (ddt,
- "validate:found ns records:calling check_addr_ns\n"));
+ dprintf(5, (ddt, "validate:found ns records\n"));
if (needs_prime_cache)
needs_prime_cache = 0;
- if (check_addr_ns(nsp, server, dname)) {
+ if (samedomain(dname, qdomain) ||
+ check_addr_ns(nsp, server, dname)) {
#ifdef DATUMREFCNT
free_nsp(nsp);
#endif
@@ -390,7 +389,7 @@ isvalid(np, type, class, data, dlen)
if (x != 0)
break;
td += (strlen(td) + 1);
- tdp += (strlen(tdp) + 1);
+ tdp += (strlen((char *)tdp) + 1);
/* compare second string */
x = strncasecmp(td, (char *)tdp,
@@ -436,9 +435,8 @@ check_addr_ns(nsp, server, dname)
struct in_addr *saddr = &(server->sin_addr);
struct databuf **nsdp;
- dprintf(5, (ddt,
- "check_addr_ns: s:[%s], db:0x%x, d:\"%s\"\n",
- inet_ntoa(*saddr), nsp, dname));
+ dprintf(5, (ddt, "check_addr_ns: s:[%s], db:0x%lx, d:\"%s\"\n",
+ inet_ntoa(*saddr), (u_long)nsp, dname));
for(i = lastNA; i != firstNA; i = (i+1) % MAXNAMECACHE) {
if (!bcmp((char *)saddr,
@@ -484,12 +482,12 @@ check_in_tables(nsp, server, syslogdname)
register struct namebuf *np;
register struct databuf *dp, *nsdp;
struct hashbuf *tmphtp;
- char *dname, *fname;
+ const char *dname, *fname;
int class;
int qcomp();
- dprintf(3, (ddt, "check_in_tables(nsp=x%x,qp=x%x,'%s')\n",
- nsp, server, syslogdname));
+ dprintf(3, (ddt, "check_in_tables(nsp=x%lx, qp=x%x, '%s')\n",
+ (u_long)nsp, server, syslogdname));
while ((nsdp = *nsp++) != NULL) {
class = nsdp->d_class;
@@ -532,10 +530,10 @@ check_in_tables(nsp, server, syslogdname)
*************************************************************************/
void
store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
- char *servername;
+ const char *servername;
struct in_addr serveraddr;
- char *syslogdname;
- char *sysloginfo;
+ const char *syslogdname;
+ const char *sysloginfo;
{
int i;
@@ -575,17 +573,13 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
syslogdname);
#endif
free(nameaddrlist[i].nsname);
- nameaddrlist[i].nsname =
- (char *)malloc((unsigned)strlen(servername)+1);
- strcpy(nameaddrlist[i].nsname, servername);
+ nameaddrlist[i].nsname = savestr(servername);
return;
}
}
/* we have to add this one to our cache */
- nameaddrlist[firstNA].nsname =
- (char *)malloc((unsigned)strlen(servername)+1);
- strcpy(nameaddrlist[firstNA].nsname, servername);
+ nameaddrlist[firstNA].nsname = savestr(servername);
bcopy((char *)&serveraddr,
(char *)&(nameaddrlist[firstNA].ns_addr),
INADDRSZ);
@@ -613,9 +607,10 @@ store_name_addr(servername, serveraddr, syslogdname, sysloginfo)
* delete/keep the record from the outgoing message.
*/
int
-dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
+dovalidate(msg, msglen, rrp, zone, flags, qdomain, server, VCode)
u_char *msg, *rrp;
int msglen, zone, flags;
+ char *qdomain;
struct sockaddr_in *server;
int *VCode;
{
@@ -783,7 +778,7 @@ dovalidate(msg, msglen, rrp, zone, flags, server, VCode)
return (-1);
}
- *VCode = validate(dname, server, type, class,(char *)cp1, n
+ *VCode = validate(dname, qdomain, server, type, class,(char *)cp1, n
#ifdef NCACHE
,NOERROR
#endif
@@ -821,12 +816,12 @@ stick_in_queue(dname, type, class, data)
if (validateQ == NULL) {
validateQ = (TO_Validate *)malloc(sizeof(TO_Validate));
+ if (!validateQ)
+ panic(errno, "malloc(validateQ)");
validateQ->type = type;
validateQ->class = class;
- validateQ->dname = malloc((unsigned)strlen(dname)+1);
- strcpy(validateQ->dname, dname);
- validateQ->data = malloc((unsigned)strlen(data)+1);
- strcpy(validateQ->data, data);
+ validateQ->dname = savestr(dname);
+ validateQ->data = savestr(data); /* XXX no \0 */
gettimeofday(&tp, &tzp);
validateQ->time = tp.tv_sec;
VQcount = 1;
@@ -836,12 +831,12 @@ stick_in_queue(dname, type, class, data)
}
if (VQcount < MAXVQ) {
tempVQ =(TO_Validate *)malloc(sizeof(TO_Validate));
+ if (!tempVQ)
+ panic(errno, "malloc(tempVQ)");
tempVQ->type = type;
tempVQ->class = class;
- tempVQ->dname = malloc((unsigned)strlen(dname)+1);
- strcpy(tempVQ->dname, dname);
- tempVQ->data = malloc((unsigned)strlen(data)+1);
- strcpy(tempVQ->data, data);
+ tempVQ->dname = savestr(dname);
+ tempVQ->data = savestr(data); /* XXX no \0 */
gettimeofday(&tp,&tzp);
tempVQ->time = tp.tv_sec;
tempVQ->next = currentVQ->next;
@@ -879,7 +874,8 @@ stick_in_queue(dname, type, class, data)
return;
}
#endif
-
+
+#ifdef BAD_IDEA
/* removes any INVALID RR's from the msg being returned, updates msglen to
* reflect the new message length.
*/
@@ -935,6 +931,8 @@ update_msg(msg, msglen, Vlist, c)
dprintf(2, (ddt, "update_msg: NEEDS updating:\n"));
RRlen = (int *)malloc((unsigned)c*sizeof(int));
+ if (!RRlen)
+ panic(errno, "malloc(RRlen)");
hp = (HEADER *)msg;
new_ancount = ancount = ntohs(hp->ancount);
new_nscount = nscount = ntohs(hp->nscount);
@@ -945,7 +943,7 @@ update_msg(msg, msglen, Vlist, c)
/* skip the query section */
qlen = dn_expand(msg, eom, cp, qname, sizeof qname);
if (qlen <= 0) {
- dprintf(2, (ddt, "dn_skipname() failed, bad record\n"));
+ dprintf(2, (ddt, "dn_expand() failed, bad record\n"));
goto badend;
}
cp +=qlen;
@@ -1242,5 +1240,6 @@ badend:
free((char *)RRlen);
return (-1);
}
+#endif /*BAD_IDEA*/
#endif /*VALIDATE*/
diff --git a/usr.sbin/named/options.h b/usr.sbin/named/options.h
index 27c223b..81f27f3 100644
--- a/usr.sbin/named/options.h
+++ b/usr.sbin/named/options.h
@@ -1,7 +1,7 @@
/* options.h - specify the conditionally-compiled features
* vix 28mar92 [moved out of the Makefile because they were getting too big]
*
- * $Id: options.h,v 1.1.1.1 1995/10/23 09:26:10 peter Exp $
+ * $Id: options.h,v 8.7 1995/12/29 21:08:13 vixie Exp $
*/
/*
@@ -95,7 +95,7 @@
#define DOTTED_SERIAL /* if you want to be able to specify dotted serial#s */
/*#define SENSIBLE_DOTS /* if you want dotted serial#s to make numeric sense */
#define NCACHE /* negative caching (anant@isi.edu) */
-/*#define VALIDATE /* validation procedure (anant@isi.edu) (DO NOT USE!)*/
+/*#define VALIDATE /* validation procedure (anant@isi.edu) (BUGGY!) */
/*#define SHORT_FNAMES /* file names used in named-xfer need to be short */
#define RESOLVSORT /* allow sorting of addresses in gethostbyname (mpa) */
#define STUBS /* allow transfers of NS only for a zone (mpa) */
@@ -119,6 +119,7 @@
#define XSTATS /* extended statistics, syslogged periodically (bg) */
/*#define BIND_NOTIFY /* experimental - do not enable in customer products */
/*#define LOC_RR /* support for (draft) LOC record parsing (ckd) */
+#define SORT_RESPONSE /* should we try to sort responses optimally? (vix) */
/*--------------------------------------------*
* no user-servicable parts beyond this point *
diff --git a/usr.sbin/named/portability.h b/usr.sbin/named/portability.h
index aff50d4..160b435 100644
--- a/usr.sbin/named/portability.h
+++ b/usr.sbin/named/portability.h
@@ -1,7 +1,7 @@
/* portability.h - include or define things that aren't present on all systems
* vixie@decwrl 26dec92 [new]
*
- * $Id: portability.h,v 1.1.1.1 1995/10/23 09:26:09 peter Exp $
+ * $Id: portability.h,v 8.11 1995/12/22 10:20:19 vixie Exp $
*/
/*
@@ -62,6 +62,7 @@
/* XXX: this file has become a hopeless morass, and will be redone someday. */
#include <string.h>
+#include <signal.h>
#include <sys/types.h>
#include <sys/param.h>
#ifndef TIME_H_INCLUDED
@@ -122,6 +123,7 @@
#ifdef NeXT
# define NEED_PUTENV
# define NEED_SETENV
+# define inet_addr(a) __inet_addr(a)
#endif
#if defined(__sgi)
@@ -133,6 +135,11 @@
# define BSD 43
#endif
+#if defined(__osf__) && defined(__alpha)
+# undef BSD
+# define BSD 199103
+#endif
+
#if defined(_AUX_SOURCE)
# define vfork fork
# define NEED_STRERROR
@@ -319,7 +326,8 @@ extern int close(), setitimer(), recv(), sendto(), sigsetmask(),
#if !defined(bcopy) /* some machines have their own macros for this */
# if defined(USE_POSIX) || \
- (defined(__STDC__) && !defined(sun) && !defined(sequent))
+ (defined(__STDC__) && !defined(sun) && !defined(sequent) \
+ && !defined(M_UNIX))
/* use ANSI C3.159-1989 (``ANSI C'') functions if possible;
* ideally we would change the code to use them and then
* define them in terms of bcopy et al if !defined(__STDC__)
@@ -389,6 +397,14 @@ extern int bcmp();
# endif /*BSD*/
#endif
+#if !defined(SIGUSR1) && !defined(SIGUSR2)
+# define SIGUSR1 SIGEMT
+# define SIGUSR2 SIGFPE
+#endif
+#if !defined(SIGCHLD)
+# define SIGCHLD SIGCLD
+#endif
+
#if !defined(ntohl) && !defined(htonl) && defined(BSD) && (BSD <= 43)
/* if these aren't null macros in netinet/in.h, extern them here. */
extern u_short htons(), ntohs();
@@ -545,3 +561,7 @@ extern int putenv __P((char *));
#ifdef NEED_GETTIMEOFDAY
extern int gettimeofday __P((struct timeval *, struct _TIMEZONE *));
#endif
+
+#if defined(SVR4) && defined(sun)
+extern int gethostname __P((char *, size_t));
+#endif
diff --git a/usr.sbin/named/tools/ndc/ndc.sh b/usr.sbin/named/tools/ndc/ndc.sh
index a9a0557..883dabc 100644
--- a/usr.sbin/named/tools/ndc/ndc.sh
+++ b/usr.sbin/named/tools/ndc/ndc.sh
@@ -9,17 +9,19 @@ USAGE='echo \
PATH=%DESTSBIN%:/bin:/usr/bin:/usr/ucb:$PATH
PIDFILE=%PIDDIR%/named.pid
-[ -f $PIDFILE ] || {
- echo "$0: $PIDFILE does not exist"
- exit 1
-}
-PID=`cat $PIDFILE`
-PS=`%PS% $PID | tail -1 | grep $PID`
-RUNNING=1
-[ `echo $PS | wc -w` -ne 0 ] || {
- PS="named (pid $PID?) not running"
+if [ -f $PIDFILE ]
+then
+ PID=`cat $PIDFILE`
+ PS=`%PS% $PID | tail -1 | grep $PID`
+ RUNNING=1
+ [ `echo $PS | wc -w` -ne 0 ] || {
+ PS="named (pid $PID?) not running"
+ RUNNING=0
+ }
+else
+ PS="named (no pid file) not running"
RUNNING=0
-}
+fi
for ARG
do
@@ -46,7 +48,11 @@ do
echo "$0: start: named (pid $PID) already running"
continue
}
- %INDOT%named && echo Name Server Started
+ rm -f $PIDFILE
+ %INDOT%named && {
+ sleep 5
+ echo Name Server Started
+ }
;;
stop)
[ $RUNNING -eq 0 ] && {
@@ -55,6 +61,7 @@ do
}
kill $PID && {
sleep 5
+ rm -f $PIDFILE
echo Name Server Stopped
}
;;
@@ -62,7 +69,11 @@ do
[ $RUNNING -eq 1 ] && {
kill $PID && sleep 5
}
- %INDOT%named && echo Name Server Restarted
+ rm -f $PIDFILE
+ %INDOT%named && {
+ sleep 5
+ echo Name Server Restarted
+ }
;;
*) eval "$USAGE";;
esac
diff --git a/usr.sbin/named/xfer/named-xfer.c b/usr.sbin/named/xfer/named-xfer.c
index 679be16..c33eb85 100644
--- a/usr.sbin/named/xfer/named-xfer.c
+++ b/usr.sbin/named/xfer/named-xfer.c
@@ -70,7 +70,7 @@ char copyright[] =
#if !defined(lint) && !defined(SABER)
static char sccsid[] = "@(#)named-xfer.c 4.18 (Berkeley) 3/7/91";
-static char rcsid[] = "$Id: named-xfer.c,v 8.9 1995/06/29 09:26:17 vixie Exp $";
+static char rcsid[] = "$Id: named-xfer.c,v 8.10 1995/12/06 20:34:38 vixie Exp $";
#endif /* not lint */
#include <sys/param.h>
@@ -96,7 +96,9 @@ static char rcsid[] = "$Id: named-xfer.c,v 8.9 1995/06/29 09:26:17 vixie Exp $";
#include <resolv.h>
#include <stdio.h>
#include <syslog.h>
-#include <math.h>
+#if !defined(SVR4) || !defined(sun)
+# include <math.h>
+#endif
#include <ctype.h>
#include <signal.h>
@@ -166,9 +168,9 @@ main(argc, argv)
closed += (close(fd) == 0);
#ifdef RENICE
- nice (-40); /* this is the recommended procedure to */
- nice (20); /* reset the priority of the current process */
- nice (0); /* to "normal" (== 0) - see nice(3) */
+ nice(-40); /* this is the recommended procedure to */
+ nice(20); /* reset the priority of the current process */
+ nice(0); /* to "normal" (== 0) - see nice(3) */
#endif
#ifdef LOG_DAEMON
@@ -194,7 +196,9 @@ main(argc, argv)
break;
case 'l':
ddtfile = (char *)malloc(strlen(optarg) +
- sizeof(".XXXXXX") + 1);
+ sizeof(".XXXXXX") + 1);
+ if (!ddtfile)
+ panic(errno, "malloc(ddtfile)");
#ifdef SHORT_FNAMES
filenamecpy(ddtfile, optarg);
#else
@@ -219,6 +223,8 @@ main(argc, argv)
dbfile = optarg;
tmpname = (char *)malloc((unsigned)strlen(optarg) +
sizeof(".XXXXXX") + 1);
+ if (!tmpname)
+ panic(errno, "malloc(tmpname)");
#ifdef SHORT_FNAMES
filenamecpy(tmpname, optarg);
#else
@@ -398,6 +404,7 @@ main(argc, argv)
}
dprintf(1, (ddt, "addrcnt = %d\n", zp->z_addrcnt));
+ res_init();
_res.options &= ~(RES_DEFNAMES | RES_DNSRCH | RES_RECURSE);
result = getzone(zp, serial_no, port);
(void) my_fclose(dbfp);
@@ -655,10 +662,13 @@ getzone(zp, serial_no, port)
goto tryagain;
}
#endif
- syslog(LOG_INFO,
- "%s from [%s], zone %s: rcode %d, aa %d, ancount %d, aucount %d\n",
- "bad response to SOA query",
- inet_ntoa(sin.sin_addr), zp->z_origin,
+ syslog(LOG_NOTICE,
+ "[%s] %s for %s, SOA query got rcode %d, aa %d, ancount %d, aucount %d",
+ inet_ntoa(sin.sin_addr),
+ (hp->aa
+ ? (qdcount==1 ?"no SOA found" :"bad response")
+ : "not authoritative"),
+ zp->z_origin[0] != '\0' ? zp->z_origin : ".",
hp->rcode, hp->aa, ancount, aucount);
error++;
(void) my_close(s);
@@ -1109,7 +1119,7 @@ soa_zinfo(zp, cp, eom)
GETSHORT(class, cp);
GETLONG(ttl, cp);
cp += INT16SZ; /* dlen */
- if (type != T_SOA || class != curclass || ttl == 0)
+ if (type != T_SOA || class != curclass)
return ("zinfo wrong typ/cla/ttl");
/* Skip master name and contact name, we can't validate them. */
if ((n = dn_skipname(cp, eom)) == -1)
@@ -1401,7 +1411,7 @@ print_output(msg, msglen, rrp)
tab = 1;
}
- if (ttl != 0 && ttl != minimum_ttl)
+ if (ttl != minimum_ttl)
(void) fprintf(dbfp, "%d\t", (int) ttl);
else if (tab)
(void) putc('\t', dbfp);
OpenPOWER on IntegriCloud