zone.c revision 607dc8013a8cb34cd03b59292aa1ac01e008c9c1
c110d61b173a68420d19858abb80285be0dc1120Tinderbox User * Copyright (C) 1999 Internet Software Consortium.
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * Permission to use, copy, modify, and distribute this software for any
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * purpose with or without fee is hereby granted, provided that the above
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * copyright notice and this permission notice appear in all copies.
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
8a07de2f032b0137d89ae8af14faa1a915aaf9faAutomatic Updater /* $Id: zone.c,v 1.45 1999/12/15 17:14:52 explorer Exp $ */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews/* XXX remove once config changes are in place */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define dns_zone_uptodate(x) zone_log(x, me, ISC_LOG_INFO, "dns_zone_uptodate")
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define MAX_XFER_TIME (2*3600) /* Documented default is 2 hours. */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define RANGE(a, b, c) (((a) < (b)) ? (b) : ((a) < (c) ? (a) : (c)))
8a07de2f032b0137d89ae8af14faa1a915aaf9faAutomatic Updater#define DNS_DEFAULT_IDLEOUT 3600 /* 1 hour */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewstypedef enum {
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews /* Unlocked */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews unsigned int magic;
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews /* Locked */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews unsigned int flags;
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews unsigned int options;
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews unsigned int db_argc;
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews /* Access Control Lists */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews ISC_LIST(dns_zone_checkservers_t) checkservers;
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_FLAG(z,f) (((z)->flags & (f)) != 0)
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews /* XXX MPA these may need to go back into zone.h */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_REFRESH 0x00000001U /* refresh check in progress */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_NEEDDUMP 0x00000002U /* zone need consolidation */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_SERVERS 0x00000004U /* servers check in progress */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_PARENTS 0x00000008U /* parents check in progress */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_CHILDREN 0x00000010U /* child check in progress */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_LOADED 0x00000020U /* database has loaded */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_EXITING 0x00000040U /* zone is being destroyed */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_EXPIRED 0x00000080U /* zone has expired */
8a07de2f032b0137d89ae8af14faa1a915aaf9faAutomatic Updater#define DNS_ZONE_F_NEEDREFRESH 0x00000100U /* refresh check needed */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_F_UPTODATE 0x00000200U /* zone contents are
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews * uptodate */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ZONE_OPTION(z,o) ((((z)->setoptions & (o)) != 0) ? \
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews (((z)->options & (o)) != 0) : \
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews /* Locked by rwlock. */
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void refresh_callback(isc_task_t *, isc_event_t *);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void zone_shutdown(isc_task_t *, isc_event_t *);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void soa_query(dns_zone_t *, isc_taskaction_t);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic dns_result_t zone_settimer(dns_zone_t *, isc_stdtime_t);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic dns_result_t dns_notify(dns_name_t *, isc_sockaddr_t *, dns_rdatatype_t,
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews dns_rdataclass_t, isc_sockaddr_t *, isc_mem_t *);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void checkservers_callback(isc_task_t *task, isc_event_t *event);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void zone_log(dns_zone_t *zone, const char *, int, const char *msg, ...);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic int message_count(dns_message_t *msg, dns_section_t section,
8a07de2f032b0137d89ae8af14faa1a915aaf9faAutomatic Updaterstatic void sockaddr_fromaddr(isc_sockaddr_t *sockaddr, dns_c_addr_t *a,
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void add_address_tocheck(dns_message_t *msg,
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsextern void dns_zone_transfer_in(dns_zone_t *zone);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void record_serial(void);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic dns_result_t dns_zone_tostr(dns_zone_t *zone, isc_mem_t *mctx, char **s);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic dns_result_t replacedb(dns_zone_t *zone, dns_db_t *db,
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic dns_result_t default_journal(dns_zone_t *zone);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void xfrin_start_temporary_kludge(dns_zone_t *zone);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsstatic void xfrdone(dns_zone_t *zone, dns_result_t result);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews char *s = NULL; \
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_ENTER zone_log(zone, me, ISC_LOG_DEBUG(10), "enter")
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews#define DNS_LEAVE zone_log(zone, me, ISC_LOG_DEBUG(10), "leave")
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews *** Public functions.
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrewsdns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews isc_sockaddr_fromin6(&sockaddr_any, &in6addr_any, 0);
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews "isc_mutex_init() failed: %s",
d1bcaec0d6c3a2f6afe004c1a087314015cb77c0Mark Andrews /* XXX MPA check that all elements are initialised */
9c03f13e18c1b0c32f62391a17300378605bbc7bEvan Hunt /* managed objects */
9c03f13e18c1b0c32f62391a17300378605bbc7bEvan Hunt /* order is important */
9c03f13e18c1b0c32f62391a17300378605bbc7bEvan Hunt dns_resolver_destroyfetch(zone->res, &zone->fetch);
9c03f13e18c1b0c32f62391a17300378605bbc7bEvan Hunt /* unmanaged objects */
return (result);
return (result);
return (result);
return (result);
static dns_result_t
int len;
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
return (result);
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
case dns_zone_hint:
case dns_zone_forward:
case dns_zone_cache:
int soacount = 0;
int nscount = 0;
goto cleanup;
case dns_zone_forward:
case dns_zone_none:
goto cleanup;
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
case dns_zone_hint:
case dns_zone_cache:
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
nscount = 0;
soacount = 0;
NULL);
nscount++;
NULL);
if (soacount == 0)
soacount++;
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
if (nscount == 0)
goto cleanup;
case dns_zone_hint:
if (nscount == 0) {
goto cleanup;
case dns_zone_cache:
goto cleanup;
goto cleanup;
if (soacount != 0)
return (result);
#ifdef notyet
NULL);
sizeof *checkservers);
#ifdef notyet
switch (state) {
case get_a6:
case get_aaaa:
case get_a:
case get_ns:
case get_soa:
goto cleanup;
switch (state) {
case get_a6:
case get_aaaa:
case get_a:
case get_ns:
case get_soa:
goto cleanup;
goto cleanup_msgsoa;
goto cleanup_msgsoa;
goto cleanup_msgsoa;
server);
goto cleanup_zonesoa;
goto cleanup_zonesoa;
server);
switch (type) {
case dns_rdatatype_a:
dns_rdata_freestruct(&a);
case dns_rdatatype_a6:
INSIST(0);
static dns_result_t
if (value)
if (value)
unsigned int *optionsmask)
goto cleanup;
goto cleanup;
return (DNS_R_SUCCESS);
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
goto cleanup;
return (DNS_R_SUCCESS);
return (DNS_R_NOMEMORY);
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
return (result);
case dns_zone_slave:
case dns_zone_stub:
case dns_zone_slave:
case dns_zone_stub:
case dns_zone_master:
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
#ifdef notyet
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
#ifdef notyet
&rdsiter);
goto retry;
return (result);
(void)tmgr;
return (DNS_R_SUCCESS);
return (DNS_R_UNEXPECTED);
return (DNS_R_UNEXPECTED);
isc_socket_t *s;
== ISC_R_SUCCESS);
s = NULL;
return (result);
isc_socket_detach(&s);
return (DNS_R_SUCCESS);
goto cleanup1;
goto cleanup2;
(void)task;
(void)event;
char *master;
&masterbuf);
goto next_master;
goto next_master;
goto next_master;
if (cnamecnt != 0) {
goto next_master;
goto next_master;
goto next_master;
goto next_master;
goto next_master;
goto next_master;
goto next_master;
goto next_master;
goto next_master;
#ifdef notyet
static dns_result_t
case dns_zone_master:
case dns_zone_slave:
case dns_zone_stub:
if (next == 0) {
return (DNS_R_UNEXPECTED);
return (DNS_R_SUCCESS);
static dns_result_t
return (result);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
return (result);
return (DNS_R_REFUSED);
return (DNS_R_REFUSED);
&rdataset);
return (DNS_R_SUCCESS);
return (DNS_R_SUCCESS);
return (DNS_R_SUCCESS);
isc_uint32_t i;
const char *origin;
return (result);
if (o == NULL)
return (DNS_R_NOMEMORY);
return (result);
return (result);
case dns_c_zone_master:
return (iresult);
return (iresult);
return (result);
case dns_c_zone_forward:
#ifdef notyet
case dns_c_zone_slave:
return (iresult);
return (iresult);
return (result);
case dns_c_zone_stub:
return (iresult);
return (iresult);
return (result);
case dns_c_zone_hint:
return (iresult);
return (result);
return (DNS_R_SUCCESS);
const char *fmt, ...) {
int len;
int res = 0;
res++;
return (res);
if (idlein == 0)
if (idleout == 0)
record_serial() {
return (ISC_FALSE);
return (result);
static dns_result_t
goto fail;
if (dump) {
goto fail;
return (DNS_R_SUCCESS);
fail:
return (result);
switch (result) {
case DNS_R_UPTODATE:
case DNS_R_SUCCESS:
if (port == 0)
port);
xfrdone);
return (ISC_R_NOMEMORY);
return (DNS_R_UNEXPECTED);
goto failure;
goto failure;
return (ISC_R_SUCCESS);
return (result);
goto failure;
goto cleanup;
return (result);
dns_zone_t *p;
p != NULL;
return (ISC_R_SUCCESS);