2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-30 22:15:20 +00:00

Connect zone transfers to refresh timers.

Various logging changes.
Add dns_zone_getclass().
Added locking to zonemgr.
This commit is contained in:
Mark Andrews
1999-12-13 03:04:55 +00:00
parent 0b87eaccdb
commit 8436cbc6a4
2 changed files with 312 additions and 128 deletions

View File

@@ -90,6 +90,14 @@ void dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass);
* 'rdclass' != dns_rdataclass_none.
*/
dns_rdataclass_t dns_zone_getclass(dns_zone_t *zone);
/*
* Returns the current zone class.
*
* Requires:
* 'zone' to be a valid initalised zone.
*/
void dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type);
/*
* Sets the zone type. This operation can only be performed once on
@@ -713,6 +721,42 @@ dns_zone_equal(dns_zone_t *oldzone, dns_zone_t *newzone);
* ISC_FALSE if the configurations differ.
*/
isc_uint32_t
dns_zone_getidlein(dns_zone_t *zone);
/*
* Requires 'zone' to be valid.
*
* Returns:
* number of seconds of idle time before we abort the transfer in.
*/
void
dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein);
/*
* Set the idle timeout for transfer the.
* Zero set the default value, 1 hour.
*
* Requires 'zone' to be valid.
*/
isc_uint32_t
dns_zone_getidleout(dns_zone_t *zone);
/*
* Requires 'zone' to be valid.
*
* Returns:
* number of seconds of idle time before we abort a transfer out.
*/
void
dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout);
/*
* Set the idle timeout for transfers out.
* Zero set the default value, 1 hour.
*
* Requires 'zone' to be valid.
*/
void
dns_zone_print(dns_zone_t *zone);
/*
@@ -757,6 +801,9 @@ dns_zonemgr_destroy(dns_zonemgr_t **zmgrp);
* '*zmgrp' is NULL.
*/
void
dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
ISC_LANG_ENDDECLS
#endif /* DNS_ZONE_H */

View File

@@ -15,20 +15,21 @@
* SOFTWARE.
*/
/* $Id: zone.c,v 1.41 1999/12/11 14:05:22 marka Exp $ */
/* $Id: zone.c,v 1.42 1999/12/13 03:04:55 marka Exp $ */
#include <config.h>
#include <string.h>
#include <../isc/util.h> /* XXX MPA */
#include <isc/assertions.h>
#include <isc/error.h>
#include <../isc/util.h> /* XXX MPA */
#include <isc/timer.h>
#include <isc/print.h>
#include <isc/serial.h>
#include <isc/magic.h>
#include <isc/print.h>
#include <isc/rwlock.h>
#include <isc/serial.h>
#include <isc/taskpool.h>
#include <isc/timer.h>
#include <dns/confparser.h>
#include <dns/db.h>
@@ -48,7 +49,7 @@
#include <dns/zt.h>
/* XXX remove once config changes are in place */
#define dns_zone_uptodate(x) dns_zone_logerror(x, "dns_zone_uptodate")
#define dns_zone_uptodate(x) zone_log(x, me, ISC_LOG_INFO, "dns_zone_uptodate")
#define referral(x) ISC_FALSE
#include <stdarg.h>
@@ -76,6 +77,8 @@
#define DNS_MIN_RETRY 1
#define DNS_MAX_RETRY 1209600 /* 2 weeks */
#define DNS_MAX_EXPIRE 14515200 /* 24 weeks */
#define DNS_DEFAULT_IDLEIN 3600 /* 1 hour */
#define DNS_DEFAULT_IDLEOUT 3600 /* 1 hour */
typedef enum {
get_a6, get_aaaa, get_a, get_ns, get_soa
@@ -104,7 +107,6 @@ struct dns_zone {
dns_db_t *top;
dns_zonemgr_t *zmgr;
ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
isc_timermgr_t *timgr;
isc_timer_t *timer;
unsigned int references;
dns_name_t origin;
@@ -150,6 +152,8 @@ struct dns_zone {
dns_resolver_t *res;
isc_socketmgr_t *socketmgr;
isc_uint32_t xfrtime;
isc_uint32_t idlein;
isc_uint32_t idleout;
isc_boolean_t diff_on_reload;
};
@@ -180,6 +184,8 @@ struct dns_zonemgr {
struct soaquery {
isc_task_t * task;
} soaquery;
isc_rwlock_t rwlock;
/* Locked by rwlock. */
ISC_LIST(dns_zone_t) zones;
};
@@ -192,7 +198,7 @@ static dns_result_t dns_notify(dns_name_t *, isc_sockaddr_t *, dns_rdatatype_t,
dns_rdataclass_t, isc_sockaddr_t *, isc_mem_t *);
static void checkservers_callback(isc_task_t *task, isc_event_t *event);
static void dns_zone_logerror(dns_zone_t *zone, const char *msg, ...);
static void zone_log(dns_zone_t *zone, const char *, int, const char *msg, ...);
static int message_count(dns_message_t *msg, dns_section_t section,
dns_rdatatype_t type);
#if 0
@@ -210,6 +216,10 @@ static void expire(dns_zone_t *zone);
static dns_result_t replacedb(dns_zone_t *zone, dns_db_t *db,
isc_boolean_t dump);
static dns_result_t default_journal(dns_zone_t *zone);
static void releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
static void xfrin_start_temporary_kludge(dns_zone_t *zone);
static void xfrdone(dns_zone_t *zone, dns_result_t result);
#define PRINT_ZONE_REF(zone) \
@@ -224,6 +234,8 @@ static dns_result_t default_journal(dns_zone_t *zone);
} \
} while (0)
#define DNS_ENTER zone_log(zone, me, ISC_LOG_DEBUG(10), "enter")
#define DNS_LEAVE zone_log(zone, me, ISC_LOG_DEBUG(10), "leave")
/***
*** Public functions.
@@ -258,7 +270,6 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->top = NULL;
zone->zmgr = NULL;
ISC_LINK_INIT(zone, link);
zone->timgr = NULL;
zone->references = 1; /* Implicit attach. */
dns_name_init(&zone->origin, NULL);
zone->database = NULL;
@@ -299,6 +310,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->res = NULL;
zone->socketmgr = NULL;
zone->timer = NULL;
zone->idlein = DNS_DEFAULT_IDLEIN;
zone->idleout = DNS_DEFAULT_IDLEOUT;
ISC_LIST_INIT(zone->checkservers);
zone->xfrsource = sockaddr_any;
zone->xfrtime = MAX_XFER_TIME;
@@ -330,12 +343,12 @@ zone_free(dns_zone_t *zone) {
dns_resolver_detach(&zone->res);
if (zone->fetch != NULL)
dns_resolver_destroyfetch(zone->res, &zone->fetch);
if (zone->timgr != NULL)
isc_timermgr_destroy(&zone->timgr);
if (zone->task != NULL)
isc_task_destroy(&zone->task);
isc_task_detach(&zone->task);
if (zone->socketmgr != NULL)
isc_socketmgr_destroy(&zone->socketmgr);
if (zone->zmgr)
dns_zonemgr_releasezone(zone->zmgr, zone);
/* unmanaged objects */
if (zone->database != NULL)
@@ -388,6 +401,13 @@ dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
UNLOCK(&zone->lock);
}
dns_rdataclass_t
dns_zone_getclass(dns_zone_t *zone){
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->rdclass);
}
/*
* Single shot.
*/
@@ -535,6 +555,7 @@ dns_zone_validate(dns_zone_t *zone) {
dns_result_t
dns_zone_load(dns_zone_t *zone) {
const char me[] = "dns_zone_load";
int soacount = 0;
int nscount = 0;
dns_result_t result;
@@ -591,9 +612,9 @@ dns_zone_load(dns_zone_t *zone) {
* XXX better error feedback to log.
*/
if (result != DNS_R_SUCCESS) {
dns_zone_logerror(zone, "database %s: dns_db_load failed: %s",
zone->database,
dns_result_totext(result));
zone_log(zone, me, ISC_LOG_ERROR,
"database %s: dns_db_load failed: %s",
zone->database, dns_result_totext(result));
goto cleanup;
}
@@ -605,6 +626,14 @@ dns_zone_load(dns_zone_t *zone) {
if (result != DNS_R_SUCCESS && result != DNS_R_NOTFOUND &&
result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL)
goto cleanup;
if (result == DNS_R_NOTFOUND) {
zone_log(zone, me, ISC_LOG_ERROR,
"journal out of sync with zone");
goto cleanup;
}
zone_log(zone, me, ISC_LOG_DEBUG(1),
"dns_journal_rollforward: %s",
dns_result_totext(result));
if (result == DNS_R_SUCCESS)
zone->flags |= DNS_ZONE_F_NEEDDUMP;
}
@@ -666,18 +695,18 @@ dns_zone_load(dns_zone_t *zone) {
case dns_zone_stub:
if (soacount != 1 || nscount == 0) {
if (soacount != 1)
dns_zone_logerror(zone,
"has %d SOA record%s",
soacount,
(soacount != 0) ? "s" : "");
zone_log(zone, me, ISC_LOG_ERROR,
"has %d SOA record%s", soacount,
(soacount != 0) ? "s" : "");
if (nscount == 0)
dns_zone_logerror(zone, "no NS records");
zone_log(zone, me, ISC_LOG_ERROR,
"no NS records");
result = DNS_R_BADZONE;
goto cleanup;
}
if (zone->top != NULL) {
if (!isc_serial_gt(soa.serial, zone->serial)) {
dns_zone_logerror(zone,
zone_log(zone, me, ISC_LOG_ERROR,
"zone serial has gone backwards");
}
}
@@ -691,13 +720,14 @@ dns_zone_load(dns_zone_t *zone) {
zone->minimum = soa.minimum;
if (zone->type == dns_zone_slave ||
zone->type == dns_zone_stub) {
/* XXX need database modification time */
zone->expiretime = now /*XXX*/ + zone->expire;
zone->refreshtime = now + zone->refresh /*XXX*/;
zone->refreshtime = now /*XXX*/;
}
break;
case dns_zone_hint:
if (nscount == 0) {
dns_zone_logerror(zone, "no NS records");
zone_log(zone, me, ISC_LOG_ERROR, "no NS records");
result = DNS_R_BADZONE;
goto cleanup;
}
@@ -846,6 +876,7 @@ dns_zone_checkservers(dns_zone_t *zone) {
#ifdef notyet
static void
checkservers_callback(isc_task_t *task, isc_event_t *event) {
const char me[] = "checkservers_callback";
dns_fetchdoneevent_t *devent = (dns_fetchdoneevent_t *)event;
dns_zone_checkservers_t *checkservers = event->arg;
dns_zone_state_t state;
@@ -872,13 +903,13 @@ checkservers_callback(isc_task_t *task, isc_event_t *event) {
case get_a6:
case get_aaaa:
case get_a:
dns_zone_logerror(zone,
"unable to obtain address for (%s)");
zone_log(zone, me, ISC_LOG_INFO,
"unable to obtain address for (%s)");
break;
case get_ns:
case get_soa:
dns_zone_logerror(zone,
"unable to obtain %s RRset from %s"
zone_log(zone, me, ISC_LOG_INFO,
"unable to obtain %s RRset from %s"
);
}
goto cleanup;
@@ -924,22 +955,22 @@ checkservers_callback(isc_task_t *task, isc_event_t *event) {
isc_buffer_init(&rb, rcode, sizeof rcode,
ISC_BUFFERTYPE_TEXT);
dns_rcode_totext(msg->rcode, &rb);
dns_zone_logerror(zone,
"server %s (%s) unexpected rcode = %.*s",
rb.used, rcode);
zone_log(zone, me, ISC_LOG_INFO,
"server %s (%s) unexpected rcode = %.*s",
rb.used, rcode);
break;
}
if (msg->counts[DNS_SECTION_ANSWER] == 0) {
if (referral(msg))
dns_zone_logerror(zone,
zone_log(zone, me, ISC_LOG_INFO,
"server %s (%s) referral response");
else
dns_zone_logerror(zone,
zone_log(zone, me, ISC_LOG_INFO,
"server %s (%s) type = %s NODATA response");
}
if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
dns_zone_logerror(zone,
zone_log(zone,<EFBFBD>me, ISC_LOG_INFO,
"server %s (%s) not authorative");
}
if (state == get_ns) {
@@ -996,9 +1027,8 @@ cmp_soa(dns_message_t *msg, dns_zone_t *zone, char *server) {
dns_rdatatype_soa,
dns_rdatatype_none, NULL, &rdataset);
if (result != DNS_R_SUCCESS) {
dns_zone_logerror(zone,
"Unable to extract SOA from answer: %s",
server);
zone_log(zone, me, ISC_LOG_INFO,
"Unable to extract SOA from answer: %s", server);
return;
}
result = dns_rdataset_first(rdataset);
@@ -1010,9 +1040,8 @@ cmp_soa(dns_message_t *msg, dns_zone_t *zone, char *server) {
return;
result = dns_rdataset_next(rdataset);
if (DNS_R_NOMORE != result) {
dns_zone_logerror(zone,
"More that one SOA record returned: %s",
server);
zone_log(zone, me, ISC_LOG_INFO,
"More that one SOA record returned: %s", server);
goto cleanup_msgsoa;
}
@@ -1040,7 +1069,7 @@ cmp_soa(dns_message_t *msg, dns_zone_t *zone, char *server) {
return;
result = dns_rdataset_next(&zonerdataset);
if (DNS_R_NOMORE != result) {
dns_zone_logerror(zone, "More that one SOA in zone");
zone_log(zone, me, ISC_LOG_INFO, "More that one SOA in zone");
goto cleanup_msgsoa;
}
dns_rdataset_disassociate(&zonerdataset);
@@ -1055,7 +1084,7 @@ cmp_soa(dns_message_t *msg, dns_zone_t *zone, char *server) {
*/
if (msgsoa.serial != zonesoa.serial) {
if (!isc_serial_lt(msgsoa.serial, zonesoa.serial)) {
dns_zone_logerror(zone,
zone_log(zone, me, ISC_LOG_INFO,
"slave serial not less than or equal to zone serial: %s",
server);
goto cleanup_zonesoa;
@@ -1071,8 +1100,8 @@ cmp_soa(dns_message_t *msg, dns_zone_t *zone, char *server) {
dns_name_compare(&msgsoa.origin, &zonesoa.origin) != 0 ||
dns_name_compare(&msgsoa.mname, &zonesoa.mname) != 0) {
dns_zone_logerror(zone, "SOA contents differ: %s",
server);
zone_log(zone, me, ISC_LOG_INFO, "SOA contents differ: %s",
server);
}
cleanup_zonesoa:
dns_rdata_freestruct(&zonesoa);
@@ -1441,9 +1470,7 @@ dns_zone_clearmasters(dns_zone_t *zone) {
LOCK(&zone->lock);
while (DNS_ZONE_FLAG(zone, DNS_ZONE_F_REFRESH)) {
UNLOCK(&zone->lock);
cancel_refresh(zone);
LOCK(&zone->lock);
}
if (zone->masters != NULL) {
isc_mem_put(zone->mctx, zone->masters,
@@ -1477,10 +1504,11 @@ dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
void
dns_zone_maintenance(dns_zone_t *zone) {
const char me[] = "dns_zone_maintenance";
isc_stdtime_t now;
REQUIRE(DNS_ZONE_VALID(zone));
fprintf(stderr, "dns_zone_maintenance\n");
DNS_ENTER;
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
return;
@@ -1636,9 +1664,12 @@ dns_zone_refresh(dns_zone_t *zone) {
zone->refreshtime = now + zone->retry;
zone->curmaster = 0;
/* initiate soa query */
#ifdef notyet
/* initiate soa query */
soa_query(zone, refresh_callback);
#else
/* initiate zone transfer */
xfrin_start_temporary_kludge(zone);
#endif
}
@@ -1746,9 +1777,10 @@ dns_zone_unmount(dns_zone_t *zone) {
dns_result_t
dns_zone_manage(dns_zone_t *zone, isc_taskmgr_t *tmgr) {
#if 1
(void)zone;
REQUIRE(DNS_ZONE_VALID(zone));
(void)tmgr;
return (DNS_R_NOTIMPLEMENTED);
dns_zone_maintenance(zone);
return (DNS_R_SUCCESS);
#else
isc_result_t iresult;
dns_result_t result;
@@ -1759,7 +1791,6 @@ dns_zone_manage(dns_zone_t *zone, isc_taskmgr_t *tmgr) {
REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(zone->task == NULL);
REQUIRE(zone->timgr == NULL);
iresult = isc_task_create(tmgr, zone->mctx, 0, &zone->task);
if (iresult != ISC_R_SUCCESS) {
@@ -1771,12 +1802,6 @@ dns_zone_manage(dns_zone_t *zone, isc_taskmgr_t *tmgr) {
/* XXX */
return (DNS_R_UNEXPECTED);
}
iresult = isc_timermgr_create(zone->mctx, &zone->timgr);
if (iresult != ISC_R_SUCCESS) {
/* XXX */
return (DNS_R_UNEXPECTED);
}
if (zone->res == NULL) {
isc_socket_t *s;
dns_dispatch_t *dispatch;
@@ -1952,8 +1977,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
master = "<UNKNOWN>";
if (devent->result != DNS_R_SUCCESS) {
dns_zone_logerror(zone, "refresh: failure for %s: %s",
master, dns_result_totext(devent->result));
zone_log(zone, me, ISC_LOG_INFO, "failure for %s: %s",
master, dns_result_totext(devent->result));
goto next_master;
}
@@ -1969,17 +1994,17 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
isc_buffer_init(&rb, rcode, sizeof rcode, ISC_BUFFERTYPE_TEXT);
dns_rcode_totext(msg->rcode, &rb);
dns_zone_logerror(zone,
"refresh: unexpected rcode (%.*s) from %s\n",
rb.used, rcode, master);
zone_log(zone, me, ISC_LOG_INFO,
"unexpected rcode (%.*s) from %s\n",
rb.used, rcode, master);
goto next_master;
}
/*
* if non-auth log and next master;
*/
if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
dns_zone_logerror(zone,
"refresh: non-authorative answer from %s", master);
zone_log(zone, me, ISC_LOG_INFO,
"non-authorative answer from %s", master);
goto next_master;
}
/*
@@ -1989,15 +2014,14 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
if (cnamecnt != 0) {
dns_zone_logerror(zone,
"refresh: CNAME discovered: master %s", master);
zone_log(zone, me, ISC_LOG_INFO,
"CNAME discovered: master %s", master);
goto next_master;
}
if (soacnt != 1) {
dns_zone_logerror(zone,
"refresh: SOA count (%d) != 1: master %s",
soacnt, master);
zone_log(zone, me, ISC_LOG_INFO,
"SOA count (%d) != 1: master %s", soacnt, master);
goto next_master;
}
@@ -2008,8 +2032,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
* if referral log and next master;
*/
if (soacnt == 0 && soacount == 0 && nscount != 0) {
dns_zone_logerror(zone,
"refresh: referral: master %s", master);
zone_log(zone, me, ISC_LOG_INFO,
"referral from: master %s", master);
goto next_master;
}
@@ -2017,7 +2041,8 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
* if nodata log and next master;
*/
if (soacnt == 0 && nscount == 0) {
dns_zone_logerror(zone, "refresh: NODATA: master %s", master);
zone_log(zone, me, ISC_LOG_INFO,
"NODATA from master %s", master);
goto next_master;
}
@@ -2029,20 +2054,21 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
dns_rdatatype_soa, dns_rdatatype_none,
NULL, &rdataset);
if (result != DNS_R_SUCCESS) {
dns_zone_logerror(zone, "refresh: unable to get soa record");
zone_log(zone, me, ISC_LOG_INFO,
"unable to get soa record from %s", master);
goto next_master;
}
result = dns_rdataset_first(rdataset);
if (result != DNS_R_SUCCESS) {
dns_zone_logerror(zone, "refresh: dns_rdataset_first failed");
zone_log(zone, me, ISC_LOG_INFO, "dns_rdataset_first failed");
goto next_master;
}
dns_rdataset_current(rdataset, &rdata);
result = dns_rdata_tostruct(&rdata, &soa, zone->mctx);
if (result != DNS_R_SUCCESS) {
dns_zone_logerror(zone, "refresh: dns_rdata_tostruct failed");
zone_log(zone, me, ISC_LOG_INFO, "dns_rdata_tostruct failed");
goto next_master;
}
@@ -2112,8 +2138,11 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
static void
zone_timer(isc_task_t *task, isc_event_t *event) {
const char me[] = "zone_timer";
dns_zone_t *zone = (dns_zone_t *)event->arg;
fprintf(stderr, "zone_timer\n");
DNS_ENTER;
dns_zone_maintenance(zone);
isc_event_free(&event);
task = task; /* XXX */
@@ -2121,6 +2150,7 @@ zone_timer(isc_task_t *task, isc_event_t *event) {
static dns_result_t
zone_settimer(dns_zone_t *zone, isc_stdtime_t now) {
const char me[] = "zone_settimer";
isc_stdtime_t next = 0;
isc_time_t expires;
isc_interval_t interval;
@@ -2165,12 +2195,12 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) {
default:
break;
}
fprintf(stdout, "settimer %d %d = %d seconds\n",
next, now, next - now);
zone_log(zone, me, ISC_LOG_INFO, "settimer %d %d = %d seconds\n",
next, now, next - now);
if (next == 0) {
if (zone->timer != NULL)
isc_timer_detach(&zone->timer);
iresult = isc_timer_reset(zone->timer, isc_timertype_inactive,
NULL, NULL, ISC_TRUE);
} else {
isc_time_settoepoch(&expires);
@@ -2179,23 +2209,12 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) {
else
isc_interval_set(&interval, next - now, 0);
if (zone->timer != NULL) {
iresult = isc_timer_reset(zone->timer,
isc_timertype_once,
&expires, &interval,
ISC_TRUE);
} else {
iresult = isc_timer_create(zone->timgr,
isc_timertype_once,
&expires, &interval,
zone->task, zone_timer,
zone, &zone->timer);
}
if (iresult != ISC_R_SUCCESS) {
/* XXX */
return (DNS_R_UNEXPECTED);
}
iresult = isc_timer_reset(zone->timer, isc_timertype_once,
&expires, &interval, ISC_TRUE);
}
if (iresult != ISC_R_SUCCESS) {
/* XXX */
return (DNS_R_UNEXPECTED);
}
return (DNS_R_SUCCESS);
}
@@ -2203,13 +2222,12 @@ zone_settimer(dns_zone_t *zone, isc_stdtime_t now) {
static void
cancel_refresh(dns_zone_t *zone) {
isc_stdtime_t now;
/*
* caller to lock.
*/
REQUIRE(DNS_ZONE_VALID(zone));
/* XXX MPA*/
LOCK(&zone->lock);
zone->flags &= ~DNS_ZONE_F_REFRESH;
UNLOCK(&zone->lock);
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
return;
if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
@@ -2403,6 +2421,7 @@ dns_zone_copy(isc_log_t *lctx, dns_c_ctx_t *ctx, dns_c_zone_t *czone,
isc_sockaddr_t sockaddr_any;
ctx = ctx; /* unused */
lctx = lctx; /* XXX unused */
isc_sockaddr_fromin6(&sockaddr_any, &in6addr_any, 0);
dns_zone_setclass(zone, czone->zclass);
@@ -2497,7 +2516,7 @@ dns_zone_copy(isc_log_t *lctx, dns_c_ctx_t *ctx, dns_c_zone_t *czone,
#else
iresult = dns_c_zone_getpubkey(lctx, czone, &pubkey);
iresult = dns_c_zone_getpubkey(czone, &pubkey);
if (iresult == ISC_R_SUCCESS)
dns_zone_setpubkey(zone, pubkey);
else
@@ -2550,7 +2569,7 @@ dns_zone_copy(isc_log_t *lctx, dns_c_ctx_t *ctx, dns_c_zone_t *czone,
#else
iresult = dns_c_zone_getpubkey(lctx, czone, &pubkey);
iresult = dns_c_zone_getpubkey(czone, &pubkey);
if (iresult == ISC_R_SUCCESS)
dns_zone_setpubkey(zone, pubkey);
else
@@ -2620,7 +2639,7 @@ dns_zone_copy(isc_log_t *lctx, dns_c_ctx_t *ctx, dns_c_zone_t *czone,
#else
iresult = dns_c_zone_getpubkey(lctx, czone, &pubkey);
iresult = dns_c_zone_getpubkey(czone, &pubkey);
if (iresult == ISC_R_SUCCESS)
dns_zone_setpubkey(zone, pubkey);
else
@@ -2655,7 +2674,6 @@ dns_zone_copy(isc_log_t *lctx, dns_c_ctx_t *ctx, dns_c_zone_t *czone,
zone->xfrsource = sockaddr;
else
zone->xfrsource = sockaddr_any;
break;
case dns_c_zone_hint:
@@ -2683,7 +2701,7 @@ dns_zone_copy(isc_log_t *lctx, dns_c_ctx_t *ctx, dns_c_zone_t *czone,
#else
iresult = dns_c_zone_getpubkey(lctx, czone, &pubkey);
iresult = dns_c_zone_getpubkey(czone, &pubkey);
if (iresult == ISC_R_SUCCESS)
dns_zone_setpubkey(zone, pubkey);
else
@@ -2855,27 +2873,28 @@ dns_zone_getmasterport(dns_zone_t *zone) {
}
static void
dns_zone_logerror(dns_zone_t *zone, const char *fmt, ...) {
zone_log(dns_zone_t *zone, const char *me, int level,
const char *fmt, ...) {
va_list ap;
char message[4096];
char namebuf[1024];
char namebuf[1024+32];
isc_buffer_t buffer;
int len;
dns_result_t result;
isc_buffer_init(&buffer, namebuf, sizeof namebuf, ISC_BUFFERTYPE_TEXT);
result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
if (result == DNS_R_SUCCESS)
len = buffer.used;
else
len = 0;
result = dns_name_totext(&zone->origin, ISC_FALSE, &buffer);
if (result != DNS_R_SUCCESS)
(void)isc_buffer_putstr(&buffer, "<UNKNOWN>");
(void)isc_buffer_putstr(&buffer, "/");
(void)dns_rdataclass_totext(zone->rdclass, &buffer);
len = buffer.used; /* XXX */
va_start(ap, fmt);
vsnprintf(message, sizeof message, fmt, ap);
va_end(ap);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
DNS_LOGMODULE_ZONE, ISC_LOG_ERROR,
"zone %.*s: %s", len, namebuf, message);
isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
level, "%s: zone %.*s: %s", me, len, namebuf, message);
}
static int
@@ -2970,6 +2989,38 @@ dns_zone_getdatabase(dns_zone_t *zone) {
return (zone->database);
}
void
dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
REQUIRE(DNS_ZONE_VALID(zone));
if (idlein == 0)
idlein = DNS_DEFAULT_IDLEIN;
zone->idlein = idlein;
}
isc_uint32_t
dns_zone_getidlein(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->idlein);
}
void
dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
REQUIRE(DNS_ZONE_VALID(zone));
if (idleout == 0)
idleout = DNS_DEFAULT_IDLEOUT;
zone->idleout = idleout;
}
isc_uint32_t
dns_zone_getidleout(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
return (zone->idleout);
}
static void
record_serial() {
}
@@ -3126,6 +3177,38 @@ replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
return (result);
}
static void
xfrdone(dns_zone_t *zone, dns_result_t result) {
const char me[] = "xfrdone";
isc_stdtime_t now;
REQUIRE(DNS_ZONE_VALID(zone));
zone_log(zone, me, ISC_LOG_DEBUG(1), "%s", dns_result_totext(result));
LOCK(&zone->lock);
INSIST((zone->flags & DNS_ZONE_F_REFRESH) != 0);
zone->flags &= ~DNS_ZONE_F_REFRESH;
switch (result) {
case DNS_R_UPTODATE:
case DNS_R_SUCCESS:
if (isc_stdtime_get(&now) != ISC_R_SUCCESS)
return;
zone->refreshtime = now + zone->refresh;
zone_settimer(zone, now);
break;
default:
zone->curmaster++;
if (zone->curmaster >= zone->masterscnt)
zone->curmaster = 0;
else
xfrin_start_temporary_kludge(zone);
break;
}
UNLOCK(&zone->lock);
}
/***
*** Zone manager.
***/
@@ -3139,11 +3222,13 @@ xfrin_start_temporary_kludge(dns_zone_t *zone) {
port = zone->masterport;
if (port == 0)
port = 53; /* XXX is this the right place? */
isc_sockaddr_fromin(&sa, &zone->masters[0].type.sin.sin_addr,
isc_sockaddr_fromin(&sa,
&zone->masters[zone->curmaster].type.sin.sin_addr,
port);
dns_xfrin_start(zone, &sa, zone->mctx,
zone->zmgr->taskmgr, zone->zmgr->timermgr,
zone->zmgr->socketmgr);
zone->zmgr->socketmgr,
xfrdone);
}
isc_result_t
@@ -3164,6 +3249,14 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
zmgr->zonetasks = NULL;
zmgr->soaquery.task = NULL;
ISC_LIST_INIT(zmgr->zones);
result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
if (result != ISC_R_SUCCESS) {
isc_mem_put(mctx, zmgr, sizeof *zmgr);
UNEXPECTED_ERROR(__FILE__, __LINE__,
"isc_rwlock_init() failed: %s",
isc_result_totext(result));
return (DNS_R_UNEXPECTED);
}
/* Create the zone task pool. */
result = isc_taskpool_create(taskmgr, mctx,
@@ -3178,6 +3271,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
*zmgrp = zmgr;
return (ISC_R_SUCCESS);
failure:
dns_zonemgr_destroy(&zmgr);
return (result);
@@ -3187,53 +3281,96 @@ isc_result_t
dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
isc_result_t result;
REQUIRE(DNS_ZONE_VALID(zone));
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
LOCK(&zone->lock);
REQUIRE(zone->task == NULL);
REQUIRE(zone->timer == NULL);
REQUIRE(zone->zmgr == NULL);
isc_taskpool_gettask(zmgr->zonetasks,
dns_name_hash(dns_zone_getorigin(zone),
ISC_FALSE),
&zone->task);
#ifdef notyet
result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
NULL, NULL,
zmgr->soaquery.task, soa_query_wanted, zone,
zmgr->soaquery.task, zone_timer, zone,
&zone->timer);
#else
result = ISC_R_SUCCESS;
#endif
zone->zmgr = zmgr;
ISC_LIST_APPEND(zmgr->zones, zone, link);
/* XXX more? */
if (result != ISC_R_SUCCESS)
goto failure;
zone->zmgr = zmgr;
ISC_LIST_APPEND(zmgr->zones, zone, link);
goto cleanup;
failure:
if (zone->task != NULL)
isc_task_detach(&zone->task);
cleanup:
UNLOCK(&zone->lock);
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
return (result);
}
static void
releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
/*
* Caller to lock zone and zmgr
*/
ISC_LIST_UNLINK(zmgr->zones, zone, link);
zone->zmgr = NULL;
}
void
dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone));
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
LOCK(&zone->lock);
releasezone(zmgr, zone);
UNLOCK(&zone->lock);
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
}
isc_result_t
dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
dns_zone_t *p;
RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
for (p = ISC_LIST_HEAD(zmgr->zones);
p != NULL;
p = ISC_LIST_NEXT(p, link))
{
if (p->type == dns_zone_slave)
xfrin_start_temporary_kludge(p);
dns_zone_maintenance(p);
}
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
return (ISC_R_SUCCESS);
}
void
dns_zonemgr_destroy(dns_zonemgr_t **zmgrp) {
dns_zonemgr_t *zmgr = *zmgrp;
dns_zone_t *zone;
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
zone = ISC_LIST_HEAD(zmgr->zones);
while (zone != NULL) {
LOCK(&zone->lock);
releasezone(zmgr, zone);
UNLOCK(&zone->lock);
zone = ISC_LIST_HEAD(zmgr->zones);
}
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
if (zmgr->soaquery.task != NULL)
isc_task_destroy(&zmgr->soaquery.task);
if (zmgr->zonetasks != NULL)
isc_taskpool_destroy(&zmgr->zonetasks);
isc_rwlock_destroy(&zmgr->rwlock);
isc_mem_put(zmgr->mctx, zmgr, sizeof *zmgr);
*zmgrp = NULL;
}