summaryrefslogtreecommitdiffstats
path: root/contrib/bind/bin/named/ns_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind/bin/named/ns_init.c')
-rw-r--r--contrib/bind/bin/named/ns_init.c240
1 files changed, 146 insertions, 94 deletions
diff --git a/contrib/bind/bin/named/ns_init.c b/contrib/bind/bin/named/ns_init.c
index 920bfeb..cc95ce6 100644
--- a/contrib/bind/bin/named/ns_init.c
+++ b/contrib/bind/bin/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 8.40 1998/04/07 18:11:58 halley Exp $";
+static const char sccsid[] = "@(#)ns_init.c 4.38 (Berkeley) 3/21/91";
+static const char rcsid[] = "$Id: ns_init.c,v 8.63 1999/10/15 19:49:04 vixie Exp $";
#endif /* not lint */
/*
@@ -57,7 +57,7 @@ static char rcsid[] = "$Id: ns_init.c,v 8.40 1998/04/07 18:11:58 halley Exp $";
*/
/*
- * Portions Copyright (c) 1996, 1997 by Internet Software Consortium.
+ * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -79,6 +79,7 @@ static char rcsid[] = "$Id: ns_init.c,v 8.40 1998/04/07 18:11:58 halley Exp $";
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
+#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
@@ -97,6 +98,8 @@ static char rcsid[] = "$Id: ns_init.c,v 8.40 1998/04/07 18:11:58 halley Exp $";
#include <isc/logging.h>
#include <isc/memcluster.h>
+#include <isc/dst.h>
+
#include "port_after.h"
#include "named.h"
@@ -138,25 +141,37 @@ ns_init(const char *conffile) {
gettime(&tt);
if (loads == 0) {
- zones = (struct zoneinfo *)memget(64 * sizeof *zones);
- if (zones == NULL)
- ns_panic(ns_log_config, 0,
- "Not enough memory to allocate initial zones array");
- memset(zones, 0, 64 * sizeof *zones);
- nzones = 1; /* zone zero is cache data */
- /* allocate cache hash table, formerly the root hash table. */
+ /* Init zone data. */
+ zones = NULL;
+ INIT_LIST(freezones);
+ INIT_LIST(reloadingzones);
+ nzones = 0;
+ make_new_zones();
+
+ /* Init cache. */
+ zones[0].z_type = z_cache;
+ zones[0].z_origin = savestr("", 1);
+
+ /* Allocate cache hash table, formerly the root hash table. */
hashtab = savehash((struct hashbuf *)NULL);
- /* allocate root-hints/file-cache hash table */
+ /* Allocate root-hints/file-cache hash table. */
fcachetab = savehash((struct hashbuf *)NULL);
- /* init zone data */
- zones[0].z_type = Z_CACHE;
- zones[0].z_origin = savestr("", 1);
+
+ /* Init other misc stuff. */
+ dst_init();
init_configuration();
} else {
/* Mark previous zones as not yet found in boot file. */
+ block_signals();
for (zp = &zones[1]; zp < &zones[nzones]; zp++)
- zp->z_flags &= ~Z_FOUND;
+ if (zp->z_type != z_nil) {
+ zp->z_flags &= ~Z_FOUND;
+ if (LINKED(zp, z_reloadlink))
+ UNLINK(reloadingzones, zp,
+ z_reloadlink);
+ }
+ unblock_signals();
}
#ifdef DEBUG
@@ -169,26 +184,20 @@ ns_init(const char *conffile) {
load_configuration(conffile);
/* Erase all old zones that were not found. */
- for (zp = &zones[1]; zp < &zones[nzones]; zp++) {
- if (zp->z_type && (zp->z_flags & Z_FOUND) == 0) {
-#ifdef BIND_UPDATE
- /*
- * A dynamic zone might have changed, so we
- * need to dump it before removing it.
- */
- if ((zp->z_flags & Z_DYNAMIC) &&
- ((zp->z_flags & Z_NEED_SOAUPDATE) ||
- (zp->z_flags & Z_NEED_DUMP)))
- (void)zonedump(zp);
-#endif
- ns_stopxfrs(zp);
- do_reload(zp->z_origin, zp->z_type, zp->z_class);
- ns_notice(ns_log_config,
- "%s zone \"%s\" (%s) removed",
- zoneTypeString(zp), zp->z_origin,
- p_class(zp->z_class));
- free_zone_contents(zp, 1);
- memset(zp, 0, sizeof(*zp));
+ for (zp = &zones[0]; zp < &zones[nzones]; zp++) {
+ if (zp->z_type == z_cache)
+ continue;
+ if (zp->z_type != z_nil && (zp->z_flags & Z_FOUND) == 0)
+ remove_zone(zp, "removed");
+ }
+ /* Reload parent zones of zones removed */
+ for (zp = &zones[0]; zp < &zones[nzones]; zp++) {
+ if (zp->z_type == z_cache)
+ continue;
+ if (zp->z_type != z_nil &&
+ (zp->z_flags & Z_PARENT_RELOAD) != 0) {
+ zp->z_flags &= ~Z_PARENT_RELOAD;
+ purgeandload(zp);
}
}
@@ -215,20 +224,22 @@ zoneinit(struct zoneinfo *zp) {
* we will refresh the zone from a primary
* immediately.
*/
- if (!zp->z_source)
+ if (zp->z_source == NULL)
return;
result = stat(zp->z_source, &sb);
if (result != -1) {
ns_stopxfrs(zp);
purge_zone(zp->z_origin, hashtab, zp->z_class);
}
- if (result == -1 || db_load(zp->z_source, zp->z_origin, zp, NULL)) {
+ if (result == -1 ||
+ db_load(zp->z_source, zp->z_origin, zp, NULL, ISNOTIXFR))
+ {
/*
* Set zone to be refreshed immediately.
*/
zp->z_refresh = INIT_REFRESH;
zp->z_retry = INIT_REFRESH;
- if (!(zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING))) {
+ if ((zp->z_flags & (Z_QSERIAL|Z_XFER_RUNNING)) == 0) {
zp->z_time = tt.tv_sec;
sched_zone_maint(zp);
}
@@ -240,12 +251,17 @@ zoneinit(struct zoneinfo *zp) {
}
}
+/*
+ * Purge the zone and reload all parent zones. This needs to be done when
+ * we unload a zone, since the child zone will have stomped the parent's
+ * delegation to that child when it was first loaded.
+ */
void
-do_reload(const char *domain, int type, int class) {
+do_reload(const char *domain, int type, int class, int mark) {
struct zoneinfo *zp;
- ns_debug(ns_log_config, 1, "do_reload: %s %d %d",
- *domain ? domain : ".", type, class);
+ ns_debug(ns_log_config, 1, "do_reload: %s %d %d %d",
+ *domain ? domain : ".", type, class, mark);
/*
* Check if the zone has changed type. If so, we might not need to
@@ -259,15 +275,11 @@ do_reload(const char *domain, int type, int class) {
*
* NOTE: we take care not to match ourselves.
*/
- if ((type != z_master &&
- find_zone(domain, z_master, class) != NULL) ||
- (type != z_slave &&
- (zp = find_zone(domain, z_slave, class)) != NULL &&
- zp->z_serial != 0) ||
- (type != z_stub &&
- (zp = find_zone(domain, z_stub, class)) != NULL &&
- zp->z_serial != 0)
- )
+ zp = find_zone(domain, class);
+ if (zp != NULL &&
+ (type != z_master && zp->z_type == z_master) ||
+ (type != z_slave && zp->z_type == z_slave && zp->z_serial != 0) ||
+ (type != z_stub && zp->z_type == z_stub && zp->z_serial != 0))
return;
/*
@@ -301,49 +313,51 @@ do_reload(const char *domain, int type, int class) {
else
domain = ""; /* root zone */
- if ((zp = find_zone(domain, Z_STUB, class)) ||
- (zp = find_zone(domain, Z_CACHE, class)) ||
- (zp = find_zone(domain, Z_PRIMARY, class)) ||
- (zp = find_zone(domain, Z_SECONDARY, class))) {
-
+ zp = find_zone(domain, class);
+ if (zp != NULL) {
ns_debug(ns_log_config, 1, "do_reload: matched %s",
*domain ? domain : ".");
-
- if (zp->z_type == Z_CACHE)
- purge_zone(zp->z_origin, fcachetab,
- zp->z_class);
+ if (mark)
+ zp->z_flags |= Z_PARENT_RELOAD;
else
- purge_zone(zp->z_origin, hashtab, zp->z_class);
-
- zp->z_flags &= ~Z_AUTH;
-
- switch (zp->z_type) {
- case Z_SECONDARY:
- case Z_STUB:
- zoneinit(zp);
- break;
- case Z_PRIMARY:
- if (db_load(zp->z_source, zp->z_origin, zp, 0)
- == 0)
- zp->z_flags |= Z_AUTH;
- break;
- case Z_CACHE:
- (void)db_load(zp->z_source, zp->z_origin, zp,
- 0);
- break;
- }
+ purgeandload(zp);
break;
}
}
}
+void
+purgeandload(struct zoneinfo *zp) {
+ if (zp->z_type == Z_HINT)
+ purge_zone(zp->z_origin, fcachetab, zp->z_class);
+ else
+ purge_zone(zp->z_origin, hashtab, zp->z_class);
+
+ zp->z_flags &= ~Z_AUTH;
+
+ switch (zp->z_type) {
+ case Z_SECONDARY:
+ case Z_STUB:
+ zoneinit(zp);
+ break;
+ case Z_PRIMARY:
+ if (db_load(zp->z_source, zp->z_origin, zp, 0, ISNOTIXFR) == 0)
+ zp->z_flags |= Z_AUTH;
+ break;
+ case Z_HINT:
+ case Z_CACHE:
+ (void)db_load(zp->z_source, zp->z_origin, zp, 0, ISNOTIXFR);
+ break;
+ }
+}
+
#ifdef DEBUG
/* prints out the content of zones */
static void
content_zone(int end, int level) {
int i;
- for (i = 1; i <= end; i++) {
+ for (i = 0; i <= end; i++) {
printzoneinfo(i, ns_log_config, level);
}
}
@@ -353,7 +367,8 @@ enum context
ns_ptrcontext(owner)
const char *owner;
{
- if (samedomain(owner, "in-addr.arpa") || samedomain(owner, "ip6.int"))
+ if (ns_samedomain(owner, "in-addr.arpa") ||
+ ns_samedomain(owner, "ip6.int"))
return (hostname_ctx);
return (domain_ctx);
}
@@ -370,6 +385,7 @@ ns_ownercontext(type, transport)
case T_WKS:
case T_MX:
switch (transport) {
+ case update_trans:
case primary_trans:
case secondary_trans:
context = owner_ctx;
@@ -394,8 +410,8 @@ ns_ownercontext(type, transport)
}
int
-ns_nameok(const char *name, int class, struct zoneinfo *zp,
- enum transport transport,
+ns_nameok(const struct qinfo *qry, const char *name, int class,
+ struct zoneinfo *zp, enum transport transport,
enum context context,
const char *owner,
struct in_addr source)
@@ -428,19 +444,45 @@ ns_nameok(const char *name, int class, struct zoneinfo *zp,
"unexpected context %d in ns_nameok", (int)context);
}
if (!ok) {
- char *s, *o;
+ char *q, *s, *o;
if (source.s_addr == INADDR_ANY)
s = savestr(transport_strings[transport], 0);
else {
s = newstr(strlen(transport_strings[transport]) +
- sizeof " from [000.000.000.000]", 0);
+ sizeof " from [000.000.000.000] for [000.000.000.000]", 0);
if (s)
- sprintf(s, "%s from [%s]",
+ if ( (transport == response_trans) &&
+ (qry != NULL) ) {
+
+ if ( qry->q_flags & Q_PRIMING ) {
+ sprintf(s, "%s from [%s] for priming",
+ transport_strings[transport],
+ inet_ntoa(source));
+ } else if ( qry->q_flags & Q_ZSERIAL ) {
+ sprintf(s, "%s from [%s] for soacheck",
transport_strings[transport],
inet_ntoa(source));
+ } else if ( qry->q_flags & Q_SYSTEM ) {
+ sprintf(s, "%s from [%s] for sysquery",
+ transport_strings[transport],
+ inet_ntoa(source));
+ } else {
+ q=strdup(inet_ntoa(qry->q_from.sin_addr));
+ sprintf(s, "%s from [%s] for [%s]",
+ transport_strings[transport],
+ inet_ntoa(source),
+ q != NULL ? q : "memget failed");
+ free(q);
+ }
+
+ } else {
+ sprintf(s, "%s from [%s]",
+ transport_strings[transport],
+ inet_ntoa(source));
+ }
}
- if (strcasecmp(owner, name) == 0)
+ if (ns_samename(owner, name) == 1)
o = savestr("", 0);
else {
const char *t = (*owner == '\0') ? "." : owner;
@@ -454,8 +496,11 @@ ns_nameok(const char *name, int class, struct zoneinfo *zp,
* the message formatting and arguments.
*/
log_write(log_ctx, ns_log_default,
- (transport == response_trans) ?
- log_info : log_notice,
+ (transport != response_trans) ||
+ (o == NULL) || (s == NULL) ||
+ ( (qry != NULL) &&
+ (qry->q_flags & (Q_PRIMING|Q_ZSERIAL)) ) ?
+ log_warning : log_info,
"%s name \"%s\"%s %s (%s) is invalid - %s",
context_strings[context],
name, o != NULL ? o : "[memget failed]",
@@ -484,29 +529,36 @@ void
ns_shutdown() {
struct zoneinfo *zp;
+#ifdef BIND_NOTIFY
+ ns_unnotify();
+#endif
/* Erase zones. */
for (zp = &zones[0]; zp < &zones[nzones]; zp++) {
if (zp->z_type) {
- if (zp->z_type != z_hint) {
+ if (zp->z_type != z_hint && zp->z_type != z_cache) {
ns_stopxfrs(zp);
purge_zone(zp->z_origin, hashtab, zp->z_class);
- }
+ } else if (zp->z_type == z_hint)
+ purge_zone(zp->z_origin, fcachetab,
+ zp->z_class);
free_zone_contents(zp, 1);
}
}
- memput(zones, ((nzones / 64) + 1) * 64 * sizeof *zones);
/* Erase the cache. */
clean_cache(hashtab, 1);
hashtab->h_cnt = 0; /* ??? */
rm_hash(hashtab);
+ hashtab = NULL;
clean_cache(fcachetab, 1);
fcachetab->h_cnt = 0; /* ??? */
rm_hash(fcachetab);
+ fcachetab = NULL;
+
+ if (zones != NULL)
+ memput(zones, nzones * sizeof *zones);
+ zones = NULL;
-#ifdef BIND_NOTIFY
- db_cancel_pending_notifies();
-#endif
freeComplaints();
shutdown_configuration();
}
OpenPOWER on IntegriCloud