zone.c revision 24b22ddce73e79214161730edd2f43704f10d48f
d7201de09b85929a86b157f4b2d91667c68c6b52Automatic Updater * Copyright (C) 1999 Internet Software Consortium.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * Permission to use, copy, modify, and distribute this software for any
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * purpose with or without fee is hereby granted, provided that the above
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister * copyright notice and this permission notice appear in all copies.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
d7201de09b85929a86b157f4b2d91667c68c6b52Automatic Updater /* $Id: zone.c,v 1.44 1999/12/13 07:56:26 marka Exp $ */
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson/* XXX remove once config changes are in place */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define dns_zone_uptodate(x) zone_log(x, me, ISC_LOG_INFO, "dns_zone_uptodate")
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define MAX_XFER_TIME (2*3600) /* Documented default is 2 hours. */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define RANGE(a, b, c) (((a) < (b)) ? (b) : ((a) < (c) ? (a) : (c)))
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristertypedef enum {
1f1d36a87b65186d9f89aac7f456ab1fd2a39ef6Andreas Gustafsson /* Unlocked */
b3e77535185043f089b346166440402d092030c3David Lawrence ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister unsigned int flags;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister unsigned int options;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister unsigned int db_argc;
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews /* Access Control Lists */
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews ISC_LIST(dns_zone_checkservers_t) checkservers;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_FLAG(z,f) (((z)->flags & (f)) != 0)
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence /* XXX MPA these may need to go back into zone.h */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_F_REFRESH 0x00000001U /* refresh check in progress */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_F_NEEDDUMP 0x00000002U /* zone need consolidation */
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews#define DNS_ZONE_F_SERVERS 0x00000004U /* servers check in progress */
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews#define DNS_ZONE_F_PARENTS 0x00000008U /* parents check in progress */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_F_CHILDREN 0x00000010U /* child check in progress */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence#define DNS_ZONE_F_LOADED 0x00000020U /* database has loaded */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_F_EXITING 0x00000040U /* zone is being destroyed */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_F_EXPIRED 0x00000080U /* zone has expired */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence#define DNS_ZONE_F_NEEDREFRESH 0x00000100U /* refresh check needed */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_F_UPTODATE 0x00000200U /* zone contents are
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister * uptodate */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister#define DNS_ZONE_OPTION(z,o) ((((z)->setoptions & (o)) != 0) ? \
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister (((z)->options & (o)) != 0) : \
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister /* Locked by rwlock. */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic void refresh_callback(isc_task_t *, isc_event_t *);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencestatic void zone_shutdown(isc_task_t *, isc_event_t *);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic void soa_query(dns_zone_t *, isc_taskaction_t);
b3e77535185043f089b346166440402d092030c3David Lawrencestatic dns_result_t zone_settimer(dns_zone_t *, isc_stdtime_t);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic dns_result_t dns_notify(dns_name_t *, isc_sockaddr_t *, dns_rdatatype_t,
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews dns_rdataclass_t, isc_sockaddr_t *, isc_mem_t *);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic void checkservers_callback(isc_task_t *task, isc_event_t *event);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic void zone_log(dns_zone_t *zone, const char *, int, const char *msg, ...);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic int message_count(dns_message_t *msg, dns_section_t section,
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic void sockaddr_fromaddr(isc_sockaddr_t *sockaddr, dns_c_addr_t *a,
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic void add_address_tocheck(dns_message_t *msg,
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsextern void dns_zone_transfer_in(dns_zone_t *zone);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic void record_serial(void);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrewsstatic dns_result_t dns_zone_tostr(dns_zone_t *zone, isc_mem_t *mctx, char **s);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrewsstatic dns_result_t replacedb(dns_zone_t *zone, dns_db_t *db,
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencestatic dns_result_t default_journal(dns_zone_t *zone);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerstatic void releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone);
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencestatic void xfrin_start_temporary_kludge(dns_zone_t *zone);
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafssonstatic void xfrdone(dns_zone_t *zone, dns_result_t result);
4844ed026a9b5a91044e76399cee80a6514cbf0dMark Andrews char *s = NULL; \
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister printf("%p: %s: references = %d\n", zone, s, \
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews#define DNS_ENTER zone_log(zone, me, ISC_LOG_DEBUG(10), "enter")
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews#define DNS_LEAVE zone_log(zone, me, ISC_LOG_DEBUG(10), "leave")
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence *** Public functions.
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrencedns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister isc_sockaddr_fromin6(&sockaddr_any, &in6addr_any, 0);
b3e77535185043f089b346166440402d092030c3David Lawrence "isc_mutex_init() failed: %s",
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister /* XXX MPA check that all elements are initialised */
f3ca27e9fe307b55e35ea8d7b37351650630e5a3Andreas Gustafsson zone->check_names = dns_c_severity_ignore;
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister /* managed objects */
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister /* order is important */
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence dns_resolver_destroyfetch(zone->res, &zone->fetch);
b3e77535185043f089b346166440402d092030c3David Lawrence /* unmanaged objects */
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister /* last stuff */
5475a2d296215b7a93bd89804dc33c36a6de7cb5James Brister * Single shot.
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellingtondns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington /* test and set */
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington REQUIRE(zone->rdclass == dns_rdataclass_none ||
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellington * Single shot.
d25dd5b0567f67ecf40b7ed1cb20e0dce7b41c49Brian Wellingtondns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews /* test and set */
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews REQUIRE(zone->type == dns_zone_none || zone->type == type);
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrewsdns_zone_setdbtype(dns_zone_t *zone, char *db_type) {
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews zone->db_type = isc_mem_strdup(zone->mctx, db_type);
3e42bdfdc901b6b921b02028bd51ca2af8e84adcMark Andrewsdns_zone_setorigin(dns_zone_t *zone, char *origin) {
40f53fa8d9c6a4fc38c0014495e7a42b08f52481David Lawrence isc_buffer_init(&buffer, origin, strlen(origin), ISC_BUFFERTYPE_TEXT);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister result = dns_name_fromtext(dns_fixedname_name(&fixed),
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister result = dns_name_dup(dns_fixedname_name(&fixed), zone->mctx,
b3e77535185043f089b346166440402d092030c3David Lawrencedns_zone_setdatabase(dns_zone_t *zone, const char *database) {
b3e77535185043f089b346166440402d092030c3David Lawrence zone->database = isc_mem_strdup(zone->mctx, database);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister len = strlen(zone->database) + sizeof ".jnl"; /* includes '\0' */
b3e77535185043f089b346166440402d092030c3David Lawrence zone->journal = isc_mem_allocate(zone->mctx, len);
2cde028c51055c9fd4837337116cd4fdfe8ff623James Bristerdns_zone_setjournal(dns_zone_t *zone, const char *journal) {
2cde028c51055c9fd4837337116cd4fdfe8ff623James Brister zone->journal = isc_mem_strdup(zone->mctx, journal);
6f7abb89ec22aef5eda40ed60fcf605a42b78d4dMark Andrews REQUIRE(dns_name_countlabels(&zone->origin) != 0);
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington /*FALLTHROUGH*/
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington REQUIRE(zone->rdclass != dns_rdataclass_none);
590f840d3484114576d9f8a7f7d73fbe31228888Brian Wellington REQUIRE(zone->rdclass == dns_rdataclass_none);
600cbd1fcea3c9cc9706dc1ff8fc0d0034ebdeacTatuya JINMEI 神明達哉 if (isc_stdtime_get(&now) != ISC_R_SUCCESS) {
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews result = dns_db_create(zone->mctx, zone->db_type,
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews * Initiate zone transfer? We may need a error code that
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews * indicates that the "permanent" form does not exist.
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews * XXX better error feedback to log.
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews "database %s: dns_db_load failed: %s",
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews * Apply update log, if any.
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews result = dns_journal_rollforward(zone->mctx, db, zone->journal);
45e1bd63587102c3bb361eaca42ee7b714fb3542Mark Andrews if (result != DNS_R_SUCCESS && result != DNS_R_NOTFOUND &&
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL)
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews "journal out of sync with zone");
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews "dns_journal_rollforward: %s",
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews * Obtain ns and soa counts for top of zone.
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
7d4a465de03b26bf9f5ef131d03253b8f6afc169Mark Andrews result = dns_db_findrdataset(db, node, version,
1c153afce556ff3c687986fb7c4a0b0a7f5e7cd8Mark Andrews result = dns_db_findrdataset(db, node, version,
08c90261660649ca7d92065f6f13a61ec5a9a86dMark Andrews * Master / Slave / Stub zones require both NS and SOA records at
08c90261660649ca7d92065f6f13a61ec5a9a86dMark Andrews * the top of the zone.
08c90261660649ca7d92065f6f13a61ec5a9a86dMark Andrews * Hint zones only require NS records.
08c90261660649ca7d92065f6f13a61ec5a9a86dMark Andrews * Cache zones have no reqirements.
08c90261660649ca7d92065f6f13a61ec5a9a86dMark Andrews "no NS records");
db30f4bdcb66afb7eb1ab0c6882cc70be9a53d79Mark Andrews if (!isc_serial_gt(soa.serial, zone->serial)) {
08c90261660649ca7d92065f6f13a61ec5a9a86dMark Andrews "zone serial has gone backwards");
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);