PageRenderTime 148ms CodeModel.GetById 34ms app.highlight 80ms RepoModel.GetById 1ms app.codeStats 3ms

/contrib/bind9/lib/dns/zone.c

https://bitbucket.org/freebsd/freebsd-head/
C | 14592 lines | 11254 code | 1786 blank | 1552 comment | 3275 complexity | d13f256320707749935465f4f1a2a4ac MD5 | raw file

Large files files are truncated, but you can click here to view the full file

   1/*
   2 * Copyright (C) 2004-2012  Internet Systems Consortium, Inc. ("ISC")
   3 * Copyright (C) 1999-2003  Internet Software Consortium.
   4 *
   5 * Permission to use, copy, modify, and/or distribute this software for any
   6 * purpose with or without fee is hereby granted, provided that the above
   7 * copyright notice and this permission notice appear in all copies.
   8 *
   9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  11 * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  15 * PERFORMANCE OF THIS SOFTWARE.
  16 */
  17
  18/* $Id$ */
  19
  20/*! \file */
  21
  22#include <config.h>
  23#include <errno.h>
  24
  25#include <isc/file.h>
  26#include <isc/mutex.h>
  27#include <isc/print.h>
  28#include <isc/random.h>
  29#include <isc/ratelimiter.h>
  30#include <isc/refcount.h>
  31#include <isc/rwlock.h>
  32#include <isc/serial.h>
  33#include <isc/strerror.h>
  34#include <isc/stats.h>
  35#include <isc/stdtime.h>
  36#include <isc/string.h>
  37#include <isc/taskpool.h>
  38#include <isc/timer.h>
  39#include <isc/util.h>
  40
  41#include <dns/acache.h>
  42#include <dns/acl.h>
  43#include <dns/adb.h>
  44#include <dns/callbacks.h>
  45#include <dns/db.h>
  46#include <dns/dbiterator.h>
  47#include <dns/dnssec.h>
  48#include <dns/events.h>
  49#include <dns/journal.h>
  50#include <dns/keydata.h>
  51#include <dns/keytable.h>
  52#include <dns/keyvalues.h>
  53#include <dns/log.h>
  54#include <dns/master.h>
  55#include <dns/masterdump.h>
  56#include <dns/message.h>
  57#include <dns/name.h>
  58#include <dns/nsec.h>
  59#include <dns/nsec3.h>
  60#include <dns/peer.h>
  61#include <dns/private.h>
  62#include <dns/rbt.h>
  63#include <dns/rcode.h>
  64#include <dns/rdataclass.h>
  65#include <dns/rdatalist.h>
  66#include <dns/rdataset.h>
  67#include <dns/rdatasetiter.h>
  68#include <dns/rdatastruct.h>
  69#include <dns/rdatatype.h>
  70#include <dns/request.h>
  71#include <dns/resolver.h>
  72#include <dns/result.h>
  73#include <dns/rriterator.h>
  74#include <dns/soa.h>
  75#include <dns/ssu.h>
  76#include <dns/stats.h>
  77#include <dns/time.h>
  78#include <dns/tsig.h>
  79#include <dns/xfrin.h>
  80#include <dns/zone.h>
  81
  82#include <dst/dst.h>
  83
  84#define ZONE_MAGIC			ISC_MAGIC('Z', 'O', 'N', 'E')
  85#define DNS_ZONE_VALID(zone)		ISC_MAGIC_VALID(zone, ZONE_MAGIC)
  86
  87#define NOTIFY_MAGIC			ISC_MAGIC('N', 't', 'f', 'y')
  88#define DNS_NOTIFY_VALID(notify)	ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
  89
  90#define STUB_MAGIC			ISC_MAGIC('S', 't', 'u', 'b')
  91#define DNS_STUB_VALID(stub)		ISC_MAGIC_VALID(stub, STUB_MAGIC)
  92
  93#define ZONEMGR_MAGIC			ISC_MAGIC('Z', 'm', 'g', 'r')
  94#define DNS_ZONEMGR_VALID(stub)		ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
  95
  96#define LOAD_MAGIC			ISC_MAGIC('L', 'o', 'a', 'd')
  97#define DNS_LOAD_VALID(load)		ISC_MAGIC_VALID(load, LOAD_MAGIC)
  98
  99#define FORWARD_MAGIC			ISC_MAGIC('F', 'o', 'r', 'w')
 100#define DNS_FORWARD_VALID(load)		ISC_MAGIC_VALID(load, FORWARD_MAGIC)
 101
 102#define IO_MAGIC			ISC_MAGIC('Z', 'm', 'I', 'O')
 103#define DNS_IO_VALID(load)		ISC_MAGIC_VALID(load, IO_MAGIC)
 104
 105/*%
 106 * Ensure 'a' is at least 'min' but not more than 'max'.
 107 */
 108#define RANGE(a, min, max) \
 109		(((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
 110
 111#define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
 112
 113/*%
 114 * Key flags
 115 */
 116#define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
 117#define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
 118#define ALG(x) dst_key_alg(x)
 119
 120/*
 121 * Default values.
 122 */
 123#define DNS_DEFAULT_IDLEIN 3600		/*%< 1 hour */
 124#define DNS_DEFAULT_IDLEOUT 3600	/*%< 1 hour */
 125#define MAX_XFER_TIME (2*3600)		/*%< Documented default is 2 hours */
 126#define RESIGN_DELAY 3600		/*%< 1 hour */
 127
 128#ifndef DNS_MAX_EXPIRE
 129#define DNS_MAX_EXPIRE	14515200	/*%< 24 weeks */
 130#endif
 131
 132#ifndef DNS_DUMP_DELAY
 133#define DNS_DUMP_DELAY 900		/*%< 15 minutes */
 134#endif
 135
 136typedef struct dns_notify dns_notify_t;
 137typedef struct dns_stub dns_stub_t;
 138typedef struct dns_load dns_load_t;
 139typedef struct dns_forward dns_forward_t;
 140typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
 141typedef struct dns_io dns_io_t;
 142typedef ISC_LIST(dns_io_t) dns_iolist_t;
 143typedef struct dns_signing dns_signing_t;
 144typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
 145typedef struct dns_nsec3chain dns_nsec3chain_t;
 146typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
 147typedef struct dns_keyfetch dns_keyfetch_t;
 148
 149#define DNS_ZONE_CHECKLOCK
 150#ifdef DNS_ZONE_CHECKLOCK
 151#define LOCK_ZONE(z) \
 152	 do { LOCK(&(z)->lock); \
 153	      INSIST((z)->locked == ISC_FALSE); \
 154	     (z)->locked = ISC_TRUE; \
 155		} while (0)
 156#define UNLOCK_ZONE(z) \
 157	do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
 158#define LOCKED_ZONE(z) ((z)->locked)
 159#else
 160#define LOCK_ZONE(z) LOCK(&(z)->lock)
 161#define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
 162#define LOCKED_ZONE(z) ISC_TRUE
 163#endif
 164
 165#ifdef ISC_RWLOCK_USEATOMIC
 166#define ZONEDB_INITLOCK(l)	isc_rwlock_init((l), 0, 0)
 167#define ZONEDB_DESTROYLOCK(l)	isc_rwlock_destroy(l)
 168#define ZONEDB_LOCK(l, t)	RWLOCK((l), (t))
 169#define ZONEDB_UNLOCK(l, t)	RWUNLOCK((l), (t))
 170#else
 171#define ZONEDB_INITLOCK(l)	isc_mutex_init(l)
 172#define ZONEDB_DESTROYLOCK(l)	DESTROYLOCK(l)
 173#define ZONEDB_LOCK(l, t)	LOCK(l)
 174#define ZONEDB_UNLOCK(l, t)	UNLOCK(l)
 175#endif
 176
 177struct dns_zone {
 178	/* Unlocked */
 179	unsigned int		magic;
 180	isc_mutex_t		lock;
 181#ifdef DNS_ZONE_CHECKLOCK
 182	isc_boolean_t		locked;
 183#endif
 184	isc_mem_t		*mctx;
 185	isc_refcount_t		erefs;
 186
 187#ifdef ISC_RWLOCK_USEATOMIC
 188	isc_rwlock_t		dblock;
 189#else
 190	isc_mutex_t		dblock;
 191#endif
 192	dns_db_t		*db;		/* Locked by dblock */
 193
 194	/* Locked */
 195	dns_zonemgr_t		*zmgr;
 196	ISC_LINK(dns_zone_t)	link;		/* Used by zmgr. */
 197	isc_timer_t		*timer;
 198	unsigned int		irefs;
 199	dns_name_t		origin;
 200	char			*masterfile;
 201	dns_masterformat_t	masterformat;
 202	char			*journal;
 203	isc_int32_t		journalsize;
 204	dns_rdataclass_t	rdclass;
 205	dns_zonetype_t		type;
 206	unsigned int		flags;
 207	unsigned int		options;
 208	unsigned int		db_argc;
 209	char			**db_argv;
 210	isc_time_t		expiretime;
 211	isc_time_t		refreshtime;
 212	isc_time_t		dumptime;
 213	isc_time_t		loadtime;
 214	isc_time_t		notifytime;
 215	isc_time_t		resigntime;
 216	isc_time_t		keywarntime;
 217	isc_time_t		signingtime;
 218	isc_time_t		nsec3chaintime;
 219	isc_time_t		refreshkeytime;
 220	isc_uint32_t		refreshkeycount;
 221	isc_uint32_t		refresh;
 222	isc_uint32_t		retry;
 223	isc_uint32_t		expire;
 224	isc_uint32_t		minimum;
 225	isc_stdtime_t		key_expiry;
 226	isc_stdtime_t		log_key_expired_timer;
 227	char			*keydirectory;
 228
 229	isc_uint32_t		maxrefresh;
 230	isc_uint32_t		minrefresh;
 231	isc_uint32_t		maxretry;
 232	isc_uint32_t		minretry;
 233
 234	isc_sockaddr_t		*masters;
 235	dns_name_t		**masterkeynames;
 236	isc_boolean_t		*mastersok;
 237	unsigned int		masterscnt;
 238	unsigned int		curmaster;
 239	isc_sockaddr_t		masteraddr;
 240	dns_notifytype_t	notifytype;
 241	isc_sockaddr_t		*notify;
 242	unsigned int		notifycnt;
 243	isc_sockaddr_t		notifyfrom;
 244	isc_task_t		*task;
 245	isc_sockaddr_t		notifysrc4;
 246	isc_sockaddr_t		notifysrc6;
 247	isc_sockaddr_t		xfrsource4;
 248	isc_sockaddr_t		xfrsource6;
 249	isc_sockaddr_t		altxfrsource4;
 250	isc_sockaddr_t		altxfrsource6;
 251	isc_sockaddr_t		sourceaddr;
 252	dns_xfrin_ctx_t		*xfr;		/* task locked */
 253	dns_tsigkey_t		*tsigkey;	/* key used for xfr */
 254	/* Access Control Lists */
 255	dns_acl_t		*update_acl;
 256	dns_acl_t		*forward_acl;
 257	dns_acl_t		*notify_acl;
 258	dns_acl_t		*query_acl;
 259	dns_acl_t		*queryon_acl;
 260	dns_acl_t		*xfr_acl;
 261	isc_boolean_t		update_disabled;
 262	isc_boolean_t		zero_no_soa_ttl;
 263	dns_severity_t		check_names;
 264	ISC_LIST(dns_notify_t)	notifies;
 265	dns_request_t		*request;
 266	dns_loadctx_t		*lctx;
 267	dns_io_t		*readio;
 268	dns_dumpctx_t		*dctx;
 269	dns_io_t		*writeio;
 270	isc_uint32_t		maxxfrin;
 271	isc_uint32_t		maxxfrout;
 272	isc_uint32_t		idlein;
 273	isc_uint32_t		idleout;
 274	isc_event_t		ctlevent;
 275	dns_ssutable_t		*ssutable;
 276	isc_uint32_t		sigvalidityinterval;
 277	isc_uint32_t		sigresigninginterval;
 278	dns_view_t		*view;
 279	dns_acache_t		*acache;
 280	dns_checkmxfunc_t	checkmx;
 281	dns_checksrvfunc_t	checksrv;
 282	dns_checknsfunc_t	checkns;
 283	/*%
 284	 * Zones in certain states such as "waiting for zone transfer"
 285	 * or "zone transfer in progress" are kept on per-state linked lists
 286	 * in the zone manager using the 'statelink' field.  The 'statelist'
 287	 * field points at the list the zone is currently on.  It the zone
 288	 * is not on any such list, statelist is NULL.
 289	 */
 290	ISC_LINK(dns_zone_t)	statelink;
 291	dns_zonelist_t		*statelist;
 292	/*%
 293	 * Statistics counters about zone management.
 294	 */
 295	isc_stats_t		*stats;
 296	/*%
 297	 * Optional per-zone statistics counters.  Counted outside of this
 298	 * module.
 299	 */
 300	isc_boolean_t		requeststats_on;
 301	isc_stats_t		*requeststats;
 302	isc_uint32_t		notifydelay;
 303	dns_isselffunc_t	isself;
 304	void			*isselfarg;
 305
 306	char *			strnamerd;
 307	char *			strname;
 308	char *			strrdclass;
 309	char *			strviewname;
 310
 311	/*%
 312	 * Serial number for deferred journal compaction.
 313	 */
 314	isc_uint32_t		compact_serial;
 315	/*%
 316	 * Keys that are signing the zone for the first time.
 317	 */
 318	dns_signinglist_t	signing;
 319	dns_nsec3chainlist_t	nsec3chain;
 320	/*%
 321	 * Signing / re-signing quantum stopping parameters.
 322	 */
 323	isc_uint32_t		signatures;
 324	isc_uint32_t		nodes;
 325	dns_rdatatype_t		privatetype;
 326
 327	/*%
 328	 * Autosigning/key-maintenance options
 329	 */
 330	isc_uint32_t		keyopts;
 331
 332	/*%
 333	 * True if added by "rndc addzone"
 334	 */
 335	isc_boolean_t           added;
 336
 337	/*%
 338	 * whether a rpz radix was needed when last loaded
 339	 */
 340	isc_boolean_t           rpz_zone;
 341
 342	/*%
 343	 * Outstanding forwarded UPDATE requests.
 344	 */
 345	dns_forwardlist_t	forwards;
 346};
 347
 348#define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
 349#define DNS_ZONE_SETFLAG(z,f) do { \
 350		INSIST(LOCKED_ZONE(z)); \
 351		(z)->flags |= (f); \
 352		} while (0)
 353#define DNS_ZONE_CLRFLAG(z,f) do { \
 354		INSIST(LOCKED_ZONE(z)); \
 355		(z)->flags &= ~(f); \
 356		} while (0)
 357	/* XXX MPA these may need to go back into zone.h */
 358#define DNS_ZONEFLG_REFRESH	0x00000001U	/*%< refresh check in progress */
 359#define DNS_ZONEFLG_NEEDDUMP	0x00000002U	/*%< zone need consolidation */
 360#define DNS_ZONEFLG_USEVC	0x00000004U	/*%< use tcp for refresh query */
 361#define DNS_ZONEFLG_DUMPING	0x00000008U	/*%< a dump is in progress */
 362#define DNS_ZONEFLG_HASINCLUDE	0x00000010U	/*%< $INCLUDE in zone file */
 363#define DNS_ZONEFLG_LOADED	0x00000020U	/*%< database has loaded */
 364#define DNS_ZONEFLG_EXITING	0x00000040U	/*%< zone is being destroyed */
 365#define DNS_ZONEFLG_EXPIRED	0x00000080U	/*%< zone has expired */
 366#define DNS_ZONEFLG_NEEDREFRESH	0x00000100U	/*%< refresh check needed */
 367#define DNS_ZONEFLG_UPTODATE	0x00000200U	/*%< zone contents are
 368						 * uptodate */
 369#define DNS_ZONEFLG_NEEDNOTIFY	0x00000400U	/*%< need to send out notify
 370						 * messages */
 371#define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U	/*%< generate a journal diff on
 372						 * reload */
 373#define DNS_ZONEFLG_NOMASTERS	0x00001000U	/*%< an attempt to refresh a
 374						 * zone with no masters
 375						 * occurred */
 376#define DNS_ZONEFLG_LOADING	0x00002000U	/*%< load from disk in progress*/
 377#define DNS_ZONEFLG_HAVETIMERS	0x00004000U	/*%< timer values have been set
 378						 * from SOA (if not set, we
 379						 * are still using
 380						 * default timer values) */
 381#define DNS_ZONEFLG_FORCEXFER	0x00008000U	/*%< Force a zone xfer */
 382#define DNS_ZONEFLG_NOREFRESH	0x00010000U
 383#define DNS_ZONEFLG_DIALNOTIFY	0x00020000U
 384#define DNS_ZONEFLG_DIALREFRESH	0x00040000U
 385#define DNS_ZONEFLG_SHUTDOWN	0x00080000U
 386#define DNS_ZONEFLAG_NOIXFR	0x00100000U	/*%< IXFR failed, force AXFR */
 387#define DNS_ZONEFLG_FLUSH	0x00200000U
 388#define DNS_ZONEFLG_NOEDNS	0x00400000U
 389#define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
 390#define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
 391#define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
 392#define DNS_ZONEFLG_REFRESHING	0x04000000U	/*%< Refreshing keydata */
 393#define DNS_ZONEFLG_THAW	0x08000000U
 394/* #define DNS_ZONEFLG_XXXXX	0x10000000U   XXXMPA unused. */
 395#define DNS_ZONEFLG_NODELAY	0x20000000U
 396
 397#define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
 398#define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
 399
 400/* Flags for zone_load() */
 401#define DNS_ZONELOADFLAG_NOSTAT	0x00000001U	/* Do not stat() master files */
 402#define DNS_ZONELOADFLAG_THAW	0x00000002U	/* Thaw the zone on successful
 403						   load. */
 404
 405#define UNREACH_CHACHE_SIZE	10U
 406#define UNREACH_HOLD_TIME	600	/* 10 minutes */
 407
 408#define CHECK(op) \
 409	do { result = (op); \
 410		if (result != ISC_R_SUCCESS) goto failure; \
 411	} while (0)
 412
 413struct dns_unreachable {
 414	isc_sockaddr_t	remote;
 415	isc_sockaddr_t	local;
 416	isc_uint32_t	expire;
 417	isc_uint32_t	last;
 418};
 419
 420struct dns_zonemgr {
 421	unsigned int		magic;
 422	isc_mem_t *		mctx;
 423	int			refs;		/* Locked by rwlock */
 424	isc_taskmgr_t *		taskmgr;
 425	isc_timermgr_t *	timermgr;
 426	isc_socketmgr_t *	socketmgr;
 427	isc_taskpool_t *	zonetasks;
 428	isc_task_t *		task;
 429	isc_ratelimiter_t *	rl;
 430	isc_rwlock_t		rwlock;
 431	isc_mutex_t		iolock;
 432	isc_rwlock_t		urlock;
 433
 434	/* Locked by rwlock. */
 435	dns_zonelist_t		zones;
 436	dns_zonelist_t		waiting_for_xfrin;
 437	dns_zonelist_t		xfrin_in_progress;
 438
 439	/* Configuration data. */
 440	isc_uint32_t		transfersin;
 441	isc_uint32_t		transfersperns;
 442	unsigned int		serialqueryrate;
 443
 444	/* Locked by iolock */
 445	isc_uint32_t		iolimit;
 446	isc_uint32_t		ioactive;
 447	dns_iolist_t		high;
 448	dns_iolist_t		low;
 449
 450	/* Locked by urlock. */
 451	/* LRU cache */
 452	struct dns_unreachable	unreachable[UNREACH_CHACHE_SIZE];
 453};
 454
 455/*%
 456 * Hold notify state.
 457 */
 458struct dns_notify {
 459	unsigned int		magic;
 460	unsigned int		flags;
 461	isc_mem_t		*mctx;
 462	dns_zone_t		*zone;
 463	dns_adbfind_t		*find;
 464	dns_request_t		*request;
 465	dns_name_t		ns;
 466	isc_sockaddr_t		dst;
 467	ISC_LINK(dns_notify_t)	link;
 468};
 469
 470#define DNS_NOTIFY_NOSOA	0x0001U
 471
 472/*%
 473 *	dns_stub holds state while performing a 'stub' transfer.
 474 *	'db' is the zone's 'db' or a new one if this is the initial
 475 *	transfer.
 476 */
 477
 478struct dns_stub {
 479	unsigned int		magic;
 480	isc_mem_t		*mctx;
 481	dns_zone_t		*zone;
 482	dns_db_t		*db;
 483	dns_dbversion_t		*version;
 484};
 485
 486/*%
 487 *	Hold load state.
 488 */
 489struct dns_load {
 490	unsigned int		magic;
 491	isc_mem_t		*mctx;
 492	dns_zone_t		*zone;
 493	dns_db_t		*db;
 494	isc_time_t		loadtime;
 495	dns_rdatacallbacks_t	callbacks;
 496};
 497
 498/*%
 499 *	Hold forward state.
 500 */
 501struct dns_forward {
 502	unsigned int		magic;
 503	isc_mem_t		*mctx;
 504	dns_zone_t		*zone;
 505	isc_buffer_t		*msgbuf;
 506	dns_request_t		*request;
 507	isc_uint32_t		which;
 508	isc_sockaddr_t		addr;
 509	dns_updatecallback_t	callback;
 510	void			*callback_arg;
 511	ISC_LINK(dns_forward_t)	link;
 512};
 513
 514/*%
 515 *	Hold IO request state.
 516 */
 517struct dns_io {
 518	unsigned int	magic;
 519	dns_zonemgr_t	*zmgr;
 520	isc_boolean_t	high;
 521	isc_task_t	*task;
 522	ISC_LINK(dns_io_t) link;
 523	isc_event_t	*event;
 524};
 525
 526/*%
 527 *	Hold state for when we are signing a zone with a new
 528 *	DNSKEY as result of an update.
 529 */
 530struct dns_signing {
 531	unsigned int		magic;
 532	dns_db_t		*db;
 533	dns_dbiterator_t	*dbiterator;
 534	dns_secalg_t		algorithm;
 535	isc_uint16_t		keyid;
 536	isc_boolean_t		delete;
 537	isc_boolean_t		done;
 538	ISC_LINK(dns_signing_t)	link;
 539};
 540
 541struct dns_nsec3chain {
 542	unsigned int			magic;
 543	dns_db_t			*db;
 544	dns_dbiterator_t		*dbiterator;
 545	dns_rdata_nsec3param_t		nsec3param;
 546	unsigned char			salt[255];
 547	isc_boolean_t			done;
 548	isc_boolean_t			seen_nsec;
 549	isc_boolean_t			delete_nsec;
 550	isc_boolean_t			save_delete_nsec;
 551	ISC_LINK(dns_nsec3chain_t)	link;
 552};
 553/*%<
 554 * 'dbiterator' contains a iterator for the database.  If we are creating
 555 * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
 556 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
 557 * iterated.
 558 *
 559 * 'nsec3param' contains the parameters of the NSEC3 chain being created
 560 * or removed.
 561 *
 562 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
 563 *
 564 * 'seen_nsec' will be set to true if, while iterating the zone to create a
 565 * NSEC3 chain, a NSEC record is seen.
 566 *
 567 * 'delete_nsec' will be set to true if, at the completion of the creation
 568 * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
 569 * are in the process of deleting the NSEC chain.
 570 *
 571 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
 572 * so it can be recovered in the event of a error.
 573 */
 574
 575struct dns_keyfetch {
 576	dns_fixedname_t name;
 577	dns_rdataset_t keydataset;
 578	dns_rdataset_t dnskeyset;
 579	dns_rdataset_t dnskeysigset;
 580	dns_zone_t *zone;
 581	dns_db_t *db;
 582	dns_fetch_t *fetch;
 583};
 584
 585#define HOUR 3600
 586#define DAY (24*HOUR)
 587#define MONTH (30*DAY)
 588
 589#define SEND_BUFFER_SIZE 2048
 590
 591static void zone_settimer(dns_zone_t *, isc_time_t *);
 592static void cancel_refresh(dns_zone_t *);
 593static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
 594			  const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
 595static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
 596     ISC_FORMAT_PRINTF(3, 4);
 597static void queue_xfrin(dns_zone_t *zone);
 598static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
 599				  dns_diff_t *diff, dns_diffop_t op,
 600				  dns_name_t *name, dns_ttl_t ttl,
 601				  dns_rdata_t *rdata);
 602static void zone_unload(dns_zone_t *zone);
 603static void zone_expire(dns_zone_t *zone);
 604static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
 605static void zone_idetach(dns_zone_t **zonep);
 606static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
 607				   isc_boolean_t dump);
 608static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
 609static inline void zone_detachdb(dns_zone_t *zone);
 610static isc_result_t default_journal(dns_zone_t *zone);
 611static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
 612static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
 613				  isc_time_t loadtime, isc_result_t result);
 614static void zone_needdump(dns_zone_t *zone, unsigned int delay);
 615static void zone_shutdown(isc_task_t *, isc_event_t *);
 616static void zone_loaddone(void *arg, isc_result_t result);
 617static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
 618				   isc_time_t loadtime);
 619static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
 620static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
 621static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
 622static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
 623
 624#if 0
 625/* ondestroy example */
 626static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
 627#endif
 628
 629static void refresh_callback(isc_task_t *, isc_event_t *);
 630static void stub_callback(isc_task_t *, isc_event_t *);
 631static void queue_soa_query(dns_zone_t *zone);
 632static void soa_query(isc_task_t *, isc_event_t *);
 633static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
 634		     dns_stub_t *stub);
 635static int message_count(dns_message_t *msg, dns_section_t section,
 636			 dns_rdatatype_t type);
 637static void notify_cancel(dns_zone_t *zone);
 638static void notify_find_address(dns_notify_t *notify);
 639static void notify_send(dns_notify_t *notify);
 640static isc_result_t notify_createmessage(dns_zone_t *zone,
 641					 unsigned int flags,
 642					 dns_message_t **messagep);
 643static void notify_done(isc_task_t *task, isc_event_t *event);
 644static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
 645static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
 646static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
 647static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
 648					     dns_zone_t *zone);
 649static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
 650static void zonemgr_free(dns_zonemgr_t *zmgr);
 651static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
 652				  isc_task_t *task, isc_taskaction_t action,
 653				  void *arg, dns_io_t **iop);
 654static void zonemgr_putio(dns_io_t **iop);
 655static void zonemgr_cancelio(dns_io_t *io);
 656
 657static isc_result_t
 658zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
 659		 unsigned int *soacount, isc_uint32_t *serial,
 660		 isc_uint32_t *refresh, isc_uint32_t *retry,
 661		 isc_uint32_t *expire, isc_uint32_t *minimum,
 662		 unsigned int *errors);
 663
 664static void zone_freedbargs(dns_zone_t *zone);
 665static void forward_callback(isc_task_t *task, isc_event_t *event);
 666static void zone_saveunique(dns_zone_t *zone, const char *path,
 667			    const char *templat);
 668static void zone_maintenance(dns_zone_t *zone);
 669static void zone_notify(dns_zone_t *zone, isc_time_t *now);
 670static void dump_done(void *arg, isc_result_t result);
 671static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
 672				     isc_uint16_t keyid, isc_boolean_t delete);
 673static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
 674				dns_dbnode_t *node, dns_name_t *name,
 675				dns_diff_t *diff);
 676static void zone_rekey(dns_zone_t *zone);
 677static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
 678			       dst_key_t **keys, unsigned int nkeys);
 679
 680#define ENTER zone_debuglog(zone, me, 1, "enter")
 681
 682static const unsigned int dbargc_default = 1;
 683static const char *dbargv_default[] = { "rbt" };
 684
 685#define DNS_ZONE_JITTER_ADD(a, b, c) \
 686	do { \
 687		isc_interval_t _i; \
 688		isc_uint32_t _j; \
 689		_j = isc_random_jitter((b), (b)/4); \
 690		isc_interval_set(&_i, _j, 0); \
 691		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
 692			dns_zone_log(zone, ISC_LOG_WARNING, \
 693				     "epoch approaching: upgrade required: " \
 694				     "now + %s failed", #b); \
 695			isc_interval_set(&_i, _j/2, 0); \
 696			(void)isc_time_add((a), &_i, (c)); \
 697		} \
 698	} while (0)
 699
 700#define DNS_ZONE_TIME_ADD(a, b, c) \
 701	do { \
 702		isc_interval_t _i; \
 703		isc_interval_set(&_i, (b), 0); \
 704		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
 705			dns_zone_log(zone, ISC_LOG_WARNING, \
 706				     "epoch approaching: upgrade required: " \
 707				     "now + %s failed", #b); \
 708			isc_interval_set(&_i, (b)/2, 0); \
 709			(void)isc_time_add((a), &_i, (c)); \
 710		} \
 711	} while (0)
 712
 713/*%
 714 * Increment resolver-related statistics counters.  Zone must be locked.
 715 */
 716static inline void
 717inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
 718	if (zone->stats != NULL)
 719		isc_stats_increment(zone->stats, counter);
 720}
 721
 722/***
 723 ***	Public functions.
 724 ***/
 725
 726isc_result_t
 727dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
 728	isc_result_t result;
 729	dns_zone_t *zone;
 730	isc_time_t now;
 731
 732	REQUIRE(zonep != NULL && *zonep == NULL);
 733	REQUIRE(mctx != NULL);
 734
 735	TIME_NOW(&now);
 736	zone = isc_mem_get(mctx, sizeof(*zone));
 737	if (zone == NULL)
 738		return (ISC_R_NOMEMORY);
 739
 740	zone->mctx = NULL;
 741	isc_mem_attach(mctx, &zone->mctx);
 742
 743	result = isc_mutex_init(&zone->lock);
 744	if (result != ISC_R_SUCCESS)
 745		goto free_zone;
 746
 747	result = ZONEDB_INITLOCK(&zone->dblock);
 748	if (result != ISC_R_SUCCESS)
 749		goto free_mutex;
 750
 751	/* XXX MPA check that all elements are initialised */
 752#ifdef DNS_ZONE_CHECKLOCK
 753	zone->locked = ISC_FALSE;
 754#endif
 755	zone->db = NULL;
 756	zone->zmgr = NULL;
 757	ISC_LINK_INIT(zone, link);
 758	result = isc_refcount_init(&zone->erefs, 1);	/* Implicit attach. */
 759	if (result != ISC_R_SUCCESS)
 760		goto free_dblock;
 761	zone->irefs = 0;
 762	dns_name_init(&zone->origin, NULL);
 763	zone->strnamerd = NULL;
 764	zone->strname = NULL;
 765	zone->strrdclass = NULL;
 766	zone->strviewname = NULL;
 767	zone->masterfile = NULL;
 768	zone->masterformat = dns_masterformat_none;
 769	zone->keydirectory = NULL;
 770	zone->journalsize = -1;
 771	zone->journal = NULL;
 772	zone->rdclass = dns_rdataclass_none;
 773	zone->type = dns_zone_none;
 774	zone->flags = 0;
 775	zone->options = 0;
 776	zone->keyopts = 0;
 777	zone->db_argc = 0;
 778	zone->db_argv = NULL;
 779	isc_time_settoepoch(&zone->expiretime);
 780	isc_time_settoepoch(&zone->refreshtime);
 781	isc_time_settoepoch(&zone->dumptime);
 782	isc_time_settoepoch(&zone->loadtime);
 783	zone->notifytime = now;
 784	isc_time_settoepoch(&zone->resigntime);
 785	isc_time_settoepoch(&zone->keywarntime);
 786	isc_time_settoepoch(&zone->signingtime);
 787	isc_time_settoepoch(&zone->nsec3chaintime);
 788	isc_time_settoepoch(&zone->refreshkeytime);
 789	zone->refreshkeycount = 0;
 790	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
 791	zone->retry = DNS_ZONE_DEFAULTRETRY;
 792	zone->expire = 0;
 793	zone->minimum = 0;
 794	zone->maxrefresh = DNS_ZONE_MAXREFRESH;
 795	zone->minrefresh = DNS_ZONE_MINREFRESH;
 796	zone->maxretry = DNS_ZONE_MAXRETRY;
 797	zone->minretry = DNS_ZONE_MINRETRY;
 798	zone->masters = NULL;
 799	zone->masterkeynames = NULL;
 800	zone->mastersok = NULL;
 801	zone->masterscnt = 0;
 802	zone->curmaster = 0;
 803	zone->notify = NULL;
 804	zone->notifytype = dns_notifytype_yes;
 805	zone->notifycnt = 0;
 806	zone->task = NULL;
 807	zone->update_acl = NULL;
 808	zone->forward_acl = NULL;
 809	zone->notify_acl = NULL;
 810	zone->query_acl = NULL;
 811	zone->queryon_acl = NULL;
 812	zone->xfr_acl = NULL;
 813	zone->update_disabled = ISC_FALSE;
 814	zone->zero_no_soa_ttl = ISC_TRUE;
 815	zone->check_names = dns_severity_ignore;
 816	zone->request = NULL;
 817	zone->lctx = NULL;
 818	zone->readio = NULL;
 819	zone->dctx = NULL;
 820	zone->writeio = NULL;
 821	zone->timer = NULL;
 822	zone->idlein = DNS_DEFAULT_IDLEIN;
 823	zone->idleout = DNS_DEFAULT_IDLEOUT;
 824	zone->log_key_expired_timer = 0;
 825	ISC_LIST_INIT(zone->notifies);
 826	isc_sockaddr_any(&zone->notifysrc4);
 827	isc_sockaddr_any6(&zone->notifysrc6);
 828	isc_sockaddr_any(&zone->xfrsource4);
 829	isc_sockaddr_any6(&zone->xfrsource6);
 830	isc_sockaddr_any(&zone->altxfrsource4);
 831	isc_sockaddr_any6(&zone->altxfrsource6);
 832	zone->xfr = NULL;
 833	zone->tsigkey = NULL;
 834	zone->maxxfrin = MAX_XFER_TIME;
 835	zone->maxxfrout = MAX_XFER_TIME;
 836	zone->ssutable = NULL;
 837	zone->sigvalidityinterval = 30 * 24 * 3600;
 838	zone->sigresigninginterval = 7 * 24 * 3600;
 839	zone->view = NULL;
 840	zone->acache = NULL;
 841	zone->checkmx = NULL;
 842	zone->checksrv = NULL;
 843	zone->checkns = NULL;
 844	ISC_LINK_INIT(zone, statelink);
 845	zone->statelist = NULL;
 846	zone->stats = NULL;
 847	zone->requeststats_on = ISC_FALSE;
 848	zone->requeststats = NULL;
 849	zone->notifydelay = 5;
 850	zone->isself = NULL;
 851	zone->isselfarg = NULL;
 852	ISC_LIST_INIT(zone->signing);
 853	ISC_LIST_INIT(zone->nsec3chain);
 854	zone->signatures = 10;
 855	zone->nodes = 100;
 856	zone->privatetype = (dns_rdatatype_t)0xffffU;
 857	zone->added = ISC_FALSE;
 858	zone->rpz_zone = ISC_FALSE;
 859	ISC_LIST_INIT(zone->forwards);
 860
 861	zone->magic = ZONE_MAGIC;
 862
 863	/* Must be after magic is set. */
 864	result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
 865	if (result != ISC_R_SUCCESS)
 866		goto free_erefs;
 867
 868	ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
 869		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
 870		       NULL, NULL);
 871	*zonep = zone;
 872	return (ISC_R_SUCCESS);
 873
 874 free_erefs:
 875	isc_refcount_decrement(&zone->erefs, NULL);
 876	isc_refcount_destroy(&zone->erefs);
 877
 878 free_dblock:
 879	ZONEDB_DESTROYLOCK(&zone->dblock);
 880
 881 free_mutex:
 882	DESTROYLOCK(&zone->lock);
 883
 884 free_zone:
 885	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
 886	return (result);
 887}
 888
 889/*
 890 * Free a zone.  Because we require that there be no more
 891 * outstanding events or references, no locking is necessary.
 892 */
 893static void
 894zone_free(dns_zone_t *zone) {
 895	isc_mem_t *mctx = NULL;
 896	dns_signing_t *signing;
 897	dns_nsec3chain_t *nsec3chain;
 898
 899	REQUIRE(DNS_ZONE_VALID(zone));
 900	REQUIRE(isc_refcount_current(&zone->erefs) == 0);
 901	REQUIRE(zone->irefs == 0);
 902	REQUIRE(!LOCKED_ZONE(zone));
 903	REQUIRE(zone->timer == NULL);
 904
 905	/*
 906	 * Managed objects.  Order is important.
 907	 */
 908	if (zone->request != NULL)
 909		dns_request_destroy(&zone->request); /* XXXMPA */
 910	INSIST(zone->readio == NULL);
 911	INSIST(zone->statelist == NULL);
 912	INSIST(zone->writeio == NULL);
 913
 914	if (zone->task != NULL)
 915		isc_task_detach(&zone->task);
 916	if (zone->zmgr != NULL)
 917		dns_zonemgr_releasezone(zone->zmgr, zone);
 918
 919	/* Unmanaged objects */
 920	for (signing = ISC_LIST_HEAD(zone->signing);
 921	     signing != NULL;
 922	     signing = ISC_LIST_HEAD(zone->signing)) {
 923		ISC_LIST_UNLINK(zone->signing, signing, link);
 924		dns_db_detach(&signing->db);
 925		dns_dbiterator_destroy(&signing->dbiterator);
 926		isc_mem_put(zone->mctx, signing, sizeof *signing);
 927	}
 928	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
 929	     nsec3chain != NULL;
 930	     nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
 931		ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
 932		dns_db_detach(&nsec3chain->db);
 933		dns_dbiterator_destroy(&nsec3chain->dbiterator);
 934		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
 935	}
 936	if (zone->masterfile != NULL)
 937		isc_mem_free(zone->mctx, zone->masterfile);
 938	zone->masterfile = NULL;
 939	if (zone->keydirectory != NULL)
 940		isc_mem_free(zone->mctx, zone->keydirectory);
 941	zone->keydirectory = NULL;
 942	zone->journalsize = -1;
 943	if (zone->journal != NULL)
 944		isc_mem_free(zone->mctx, zone->journal);
 945	zone->journal = NULL;
 946	if (zone->stats != NULL)
 947		isc_stats_detach(&zone->stats);
 948	if (zone->requeststats != NULL)
 949		isc_stats_detach(&zone->requeststats);
 950	if (zone->db != NULL)
 951		zone_detachdb(zone);
 952	if (zone->acache != NULL)
 953		dns_acache_detach(&zone->acache);
 954	zone_freedbargs(zone);
 955	RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
 956		      == ISC_R_SUCCESS);
 957	RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
 958		      == ISC_R_SUCCESS);
 959	zone->check_names = dns_severity_ignore;
 960	if (zone->update_acl != NULL)
 961		dns_acl_detach(&zone->update_acl);
 962	if (zone->forward_acl != NULL)
 963		dns_acl_detach(&zone->forward_acl);
 964	if (zone->notify_acl != NULL)
 965		dns_acl_detach(&zone->notify_acl);
 966	if (zone->query_acl != NULL)
 967		dns_acl_detach(&zone->query_acl);
 968	if (zone->queryon_acl != NULL)
 969		dns_acl_detach(&zone->queryon_acl);
 970	if (zone->xfr_acl != NULL)
 971		dns_acl_detach(&zone->xfr_acl);
 972	if (dns_name_dynamic(&zone->origin))
 973		dns_name_free(&zone->origin, zone->mctx);
 974	if (zone->strnamerd != NULL)
 975		isc_mem_free(zone->mctx, zone->strnamerd);
 976	if (zone->strname != NULL)
 977		isc_mem_free(zone->mctx, zone->strname);
 978	if (zone->strrdclass != NULL)
 979		isc_mem_free(zone->mctx, zone->strrdclass);
 980	if (zone->strviewname != NULL)
 981		isc_mem_free(zone->mctx, zone->strviewname);
 982	if (zone->ssutable != NULL)
 983		dns_ssutable_detach(&zone->ssutable);
 984
 985	/* last stuff */
 986	ZONEDB_DESTROYLOCK(&zone->dblock);
 987	DESTROYLOCK(&zone->lock);
 988	isc_refcount_destroy(&zone->erefs);
 989	zone->magic = 0;
 990	mctx = zone->mctx;
 991	isc_mem_put(mctx, zone, sizeof(*zone));
 992	isc_mem_detach(&mctx);
 993}
 994
 995/*
 996 *	Single shot.
 997 */
 998void
 999dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1000	char namebuf[1024];
1001
1002	REQUIRE(DNS_ZONE_VALID(zone));
1003	REQUIRE(rdclass != dns_rdataclass_none);
1004
1005	/*
1006	 * Test and set.
1007	 */
1008	LOCK_ZONE(zone);
1009	REQUIRE(zone->rdclass == dns_rdataclass_none ||
1010		zone->rdclass == rdclass);
1011	zone->rdclass = rdclass;
1012
1013	if (zone->strnamerd != NULL)
1014		isc_mem_free(zone->mctx, zone->strnamerd);
1015	if (zone->strrdclass != NULL)
1016		isc_mem_free(zone->mctx, zone->strrdclass);
1017
1018	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1019	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1020	zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1021	zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1022
1023	UNLOCK_ZONE(zone);
1024}
1025
1026dns_rdataclass_t
1027dns_zone_getclass(dns_zone_t *zone) {
1028	REQUIRE(DNS_ZONE_VALID(zone));
1029
1030	return (zone->rdclass);
1031}
1032
1033void
1034dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1035	REQUIRE(DNS_ZONE_VALID(zone));
1036
1037	LOCK_ZONE(zone);
1038	zone->notifytype = notifytype;
1039	UNLOCK_ZONE(zone);
1040}
1041
1042isc_result_t
1043dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1044	isc_result_t result;
1045
1046	REQUIRE(DNS_ZONE_VALID(zone));
1047	REQUIRE(serialp != NULL);
1048
1049	LOCK_ZONE(zone);
1050	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1051	if (zone->db != NULL) {
1052		result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
1053					  NULL, NULL, NULL, NULL, NULL);
1054	} else
1055		result = DNS_R_NOTLOADED;
1056	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1057	UNLOCK_ZONE(zone);
1058
1059	return (result);
1060}
1061
1062isc_uint32_t
1063dns_zone_getserial(dns_zone_t *zone) {
1064	isc_result_t result;
1065	isc_uint32_t serial;
1066
1067	result = dns_zone_getserial2(zone, &serial);
1068	if (result != ISC_R_SUCCESS)
1069		serial = 0; /* XXX: not really correct, but no other choice */
1070
1071	return (serial);
1072}
1073
1074/*
1075 *	Single shot.
1076 */
1077void
1078dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1079
1080	REQUIRE(DNS_ZONE_VALID(zone));
1081	REQUIRE(type != dns_zone_none);
1082
1083	/*
1084	 * Test and set.
1085	 */
1086	LOCK_ZONE(zone);
1087	REQUIRE(zone->type == dns_zone_none || zone->type == type);
1088	zone->type = type;
1089	UNLOCK_ZONE(zone);
1090}
1091
1092static void
1093zone_freedbargs(dns_zone_t *zone) {
1094	unsigned int i;
1095
1096	/* Free the old database argument list. */
1097	if (zone->db_argv != NULL) {
1098		for (i = 0; i < zone->db_argc; i++)
1099			isc_mem_free(zone->mctx, zone->db_argv[i]);
1100		isc_mem_put(zone->mctx, zone->db_argv,
1101			    zone->db_argc * sizeof(*zone->db_argv));
1102	}
1103	zone->db_argc = 0;
1104	zone->db_argv = NULL;
1105}
1106
1107isc_result_t
1108dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1109	size_t size = 0;
1110	unsigned int i;
1111	isc_result_t result = ISC_R_SUCCESS;
1112	void *mem;
1113	char **tmp, *tmp2;
1114
1115	REQUIRE(DNS_ZONE_VALID(zone));
1116	REQUIRE(argv != NULL && *argv == NULL);
1117
1118	LOCK_ZONE(zone);
1119	size = (zone->db_argc + 1) * sizeof(char *);
1120	for (i = 0; i < zone->db_argc; i++)
1121		size += strlen(zone->db_argv[i]) + 1;
1122	mem = isc_mem_allocate(mctx, size);
1123	if (mem != NULL) {
1124		tmp = mem;
1125		tmp2 = mem;
1126		tmp2 += (zone->db_argc + 1) * sizeof(char *);
1127		for (i = 0; i < zone->db_argc; i++) {
1128			*tmp++ = tmp2;
1129			strcpy(tmp2, zone->db_argv[i]);
1130			tmp2 += strlen(tmp2) + 1;
1131		}
1132		*tmp = NULL;
1133	} else
1134		result = ISC_R_NOMEMORY;
1135	UNLOCK_ZONE(zone);
1136	*argv = mem;
1137	return (result);
1138}
1139
1140isc_result_t
1141dns_zone_setdbtype(dns_zone_t *zone,
1142		   unsigned int dbargc, const char * const *dbargv) {
1143	isc_result_t result = ISC_R_SUCCESS;
1144	char **new = NULL;
1145	unsigned int i;
1146
1147	REQUIRE(DNS_ZONE_VALID(zone));
1148	REQUIRE(dbargc >= 1);
1149	REQUIRE(dbargv != NULL);
1150
1151	LOCK_ZONE(zone);
1152
1153	/* Set up a new database argument list. */
1154	new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1155	if (new == NULL)
1156		goto nomem;
1157	for (i = 0; i < dbargc; i++)
1158		new[i] = NULL;
1159	for (i = 0; i < dbargc; i++) {
1160		new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1161		if (new[i] == NULL)
1162			goto nomem;
1163	}
1164
1165	/* Free the old list. */
1166	zone_freedbargs(zone);
1167
1168	zone->db_argc = dbargc;
1169	zone->db_argv = new;
1170	result = ISC_R_SUCCESS;
1171	goto unlock;
1172
1173 nomem:
1174	if (new != NULL) {
1175		for (i = 0; i < dbargc; i++)
1176			if (new[i] != NULL)
1177				isc_mem_free(zone->mctx, new[i]);
1178		isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1179	}
1180	result = ISC_R_NOMEMORY;
1181
1182 unlock:
1183	UNLOCK_ZONE(zone);
1184	return (result);
1185}
1186
1187void
1188dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1189	char namebuf[1024];
1190	REQUIRE(DNS_ZONE_VALID(zone));
1191
1192	LOCK_ZONE(zone);
1193	if (zone->view != NULL)
1194		dns_view_weakdetach(&zone->view);
1195	dns_view_weakattach(view, &zone->view);
1196
1197	if (zone->strviewname != NULL)
1198		isc_mem_free(zone->mctx, zone->strviewname);
1199	if (zone->strnamerd != NULL)
1200		isc_mem_free(zone->mctx, zone->strnamerd);
1201
1202	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1203	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1204	zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1205	zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1206
1207	UNLOCK_ZONE(zone);
1208}
1209
1210
1211dns_view_t *
1212dns_zone_getview(dns_zone_t *zone) {
1213	REQUIRE(DNS_ZONE_VALID(zone));
1214
1215	return (zone->view);
1216}
1217
1218
1219isc_result_t
1220dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1221	isc_result_t result;
1222	char namebuf[1024];
1223
1224	REQUIRE(DNS_ZONE_VALID(zone));
1225	REQUIRE(origin != NULL);
1226
1227	LOCK_ZONE(zone);
1228	if (dns_name_dynamic(&zone->origin)) {
1229		dns_name_free(&zone->origin, zone->mctx);
1230		dns_name_init(&zone->origin, NULL);
1231	}
1232	result = dns_name_dup(origin, zone->mctx, &zone->origin);
1233
1234	if (zone->strnamerd != NULL)
1235		isc_mem_free(zone->mctx, zone->strnamerd);
1236	if (zone->strname != NULL)
1237		isc_mem_free(zone->mctx, zone->strname);
1238
1239	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1240	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1241	zone_name_tostr(zone, namebuf, sizeof namebuf);
1242	zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1243
1244	UNLOCK_ZONE(zone);
1245	return (result);
1246}
1247
1248void
1249dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1250	REQUIRE(DNS_ZONE_VALID(zone));
1251	REQUIRE(acache != NULL);
1252
1253	LOCK_ZONE(zone);
1254	if (zone->acache != NULL)
1255		dns_acache_detach(&zone->acache);
1256	dns_acache_attach(acache, &zone->acache);
1257	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1258	if (zone->db != NULL) {
1259		isc_result_t result;
1260
1261		/*
1262		 * If the zone reuses an existing DB, the DB needs to be
1263		 * set in the acache explicitly.  We can safely ignore the
1264		 * case where the DB is already set.  If other error happens,
1265		 * the acache will not work effectively.
1266		 */
1267		result = dns_acache_setdb(acache, zone->db);
1268		if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1269			UNEXPECTED_ERROR(__FILE__, __LINE__,
1270					 "dns_acache_setdb() failed: %s",
1271					 isc_result_totext(result));
1272		}
1273	}
1274	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1275	UNLOCK_ZONE(zone);
1276}
1277
1278static isc_result_t
1279dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1280	char *copy;
1281
1282	if (value != NULL) {
1283		copy = isc_mem_strdup(zone->mctx, value);
1284		if (copy == NULL)
1285			return (ISC_R_NOMEMORY);
1286	} else {
1287		copy = NULL;
1288	}
1289
1290	if (*field != NULL)
1291		isc_mem_free(zone->mctx, *field);
1292
1293	*field = copy;
1294	return (ISC_R_SUCCESS);
1295}
1296
1297isc_result_t
1298dns_zone_setfile(dns_zone_t *zone, const char *file) {
1299	return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1300}
1301
1302isc_result_t
1303dns_zone_setfile2(dns_zone_t *zone, const char *file,
1304		  dns_masterformat_t format) {
1305	isc_result_t result = ISC_R_SUCCESS;
1306
1307	REQUIRE(DNS_ZONE_VALID(zone));
1308
1309	LOCK_ZONE(zone);
1310	result = dns_zone_setstring(zone, &zone->masterfile, file);
1311	if (result == ISC_R_SUCCESS) {
1312		zone->masterformat = format;
1313		result = default_journal(zone);
1314	}
1315	UNLOCK_ZONE(zone);
1316
1317	return (result);
1318}
1319
1320const char *
1321dns_zone_getfile(dns_zone_t *zone) {
1322	REQUIRE(DNS_ZONE_VALID(zone));
1323
1324	return (zone->masterfile);
1325}
1326
1327static isc_result_t
1328default_journal(dns_zone_t *zone) {
1329	isc_result_t result;
1330	char *journal;
1331
1332	REQUIRE(DNS_ZONE_VALID(zone));
1333	REQUIRE(LOCKED_ZONE(zone));
1334
1335	if (zone->masterfile != NULL) {
1336		/* Calculate string length including '\0'. */
1337		int len = strlen(zone->masterfile) + sizeof(".jnl");
1338		journal = isc_mem_allocate(zone->mctx, len);
1339		if (journal == NULL)
1340			return (ISC_R_NOMEMORY);
1341		strcpy(journal, zone->masterfile);
1342		strcat(journal, ".jnl");
1343	} else {
1344		journal = NULL;
1345	}
1346	result = dns_zone_setstring(zone, &zone->journal, journal);
1347	if (journal != NULL)
1348		isc_mem_free(zone->mctx, journal);
1349	return (result);
1350}
1351
1352isc_result_t
1353dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1354	isc_result_t result = ISC_R_SUCCESS;
1355
1356	REQUIRE(DNS_ZONE_VALID(zone));
1357
1358	LOCK_ZONE(zone);
1359	result = dns_zone_setstring(zone, &zone->journal, journal);
1360	UNLOCK_ZONE(zone);
1361
1362	return (result);
1363}
1364
1365char *
1366dns_zone_getjournal(dns_zone_t *zone) {
1367	REQUIRE(DNS_ZONE_VALID(zone));
1368
1369	return (zone->journal);
1370}
1371
1372/*
1373 * Return true iff the zone is "dynamic", in the sense that the zone's
1374 * master file (if any) is written by the server, rather than being
1375 * updated manually and read by the server.
1376 *
1377 * This is true for slave zones, stub zones, key zones, and zones that
1378 * allow dynamic updates either by having an update policy ("ssutable")
1379 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1380 */
1381static isc_boolean_t
1382zone_isdynamic(dns_zone_t *zone) {
1383	REQUIRE(DNS_ZONE_VALID(zone));
1384
1385	return (ISC_TF(zone->type == dns_zone_slave ||
1386		       zone->type == dns_zone_stub ||
1387		       zone->type == dns_zone_key ||
1388		       (!zone->update_disabled && zone->ssutable != NULL) ||
1389		       (!zone->update_disabled && zone->update_acl != NULL &&
1390			!dns_acl_isnone(zone->update_acl))));
1391}
1392
1393
1394static isc_result_t
1395zone_load(dns_zone_t *zone, unsigned int flags) {
1396	isc_result_t result;
1397	isc_time_t now;
1398	isc_time_t loadtime, filetime;
1399	dns_db_t *db = NULL;
1400	isc_boolean_t rbt;
1401
1402	REQUIRE(DNS_ZONE_VALID(zone));
1403
1404	LOCK_ZONE(zone);
1405	TIME_NOW(&now);
1406
1407	INSIST(zone->type != dns_zone_none);
1408
1409	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1410		if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1411			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1412		result = DNS_R_CONTINUE;
1413		goto cleanup;
1414	}
1415
1416
1417	INSIST(zone->db_argc >= 1);
1418
1419	rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1420	      strcmp(zone->db_argv[0], "rbt64") == 0;
1421
1422	if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1423		/*
1424		 * The zone has no master file configured.
1425		 */
1426		result = ISC_R_SUCCESS;
1427		goto cleanup;
1428	}
1429
1430	if (zone->db != NULL && zone_isdynamic(zone)) {
1431		/*
1432		 * This is a slave, stub, or dynamically updated
1433		 * zone being reloaded.  Do nothing - the database
1434		 * we already have is guaranteed to be up-to-date.
1435		 */
1436		if (zone->type == dns_zone_master)
1437			result = DNS_R_DYNAMIC;
1438		else
1439			result = ISC_R_SUCCESS;
1440		goto cleanup;
1441	}
1442
1443	/*
1444	 * Store the current time before the zone is loaded, so that if the
1445	 * file changes between the time of the load and the time that
1446	 * zone->loadtime is set, then the file will still be reloaded
1447	 * the next time dns_zone_load is called.
1448	 */
1449	TIME_NOW(&loadtime);
1450
1451	/*
1452	 * Don't do the load if the file that stores the zone is older
1453	 * than the last time the zone was loaded.  If the zone has not
1454	 * been loaded yet, zone->loadtime will be the epoch.
1455	 */
1456	if (zone->masterfile != NULL) {
1457		/*
1458		 * The file is already loaded.	If we are just doing a
1459		 * "rndc reconfig", we are done.
1460		 */
1461		if (!isc_time_isepoch(&zone->loadtime) &&
1462		    (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 &&
1463		    zone->rpz_zone == dns_rpz_needed()) {
1464			result = ISC_R_SUCCESS;
1465			goto cleanup;
1466		}
1467
1468		result = isc_file_getmodtime(zone->masterfile, &filetime);
1469		if (result == ISC_R_SUCCESS) {
1470			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1471			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1472			    isc_time_compare(&filetime, &zone->loadtime) <= 0 &&
1473			    zone->rpz_zone == dns_rpz_needed()) {
1474				dns_zone_log(zone, ISC_LOG_DEBUG(1),
1475					     "skipping load: master file "
1476					     "older than last load");
1477				result = DNS_R_UPTODATE;
1478				goto cleanup;
1479			}
1480			loadtime = filetime;
1481			zone->rpz_zone = dns_rpz_needed();
1482		}
1483	}
1484
1485	/*
1486	 * Built in zones (with the exception of empty zones) don't need
1487	 * to be reloaded.
1488	 */
1489	if (zone->type == dns_zone_master &&
1490	    strcmp(zone->db_argv[0], "_builtin") == 0 &&
1491	    (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1492	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1493		result = ISC_R_SUCCESS;
1494		goto cleanup;
1495	}
1496
1497	if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1498	    rbt) {
1499		if (zone->masterfile == NULL ||
1500		    !isc_file_exists(zone->masterfile)) {
1501			if (zone->masterfile != NULL) {
1502				dns_zone_log(zone, ISC_LOG_DEBUG(1),
1503					     "no master file");
1504			}
1505			zone->refreshtime = now;
1506			if (zone->task != NULL)
1507				zone_settimer(zone, &now);
1508			result = ISC_R_SUCCESS;
1509			goto cleanup;
1510		}
1511	}
1512
1513	dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1514
1515	result = dns_db_create(zone->mctx, zone->db_argv[0],
1516			       &zone->origin, (zone->type == dns_zone_stub) ?
1517			       dns_dbtype_stub : dns_dbtype_zone,
1518			       zone->rdclass,
1519			       zone->db_argc - 1, zone->db_argv + 1,
1520			       &db);
1521
1522	if (result != ISC_R_SUCCESS) {
1523		dns_zone_log(zone, ISC_LOG_ERROR,
1524			     "loading zone: creating database: %s",
1525			     isc_result_totext(result));
1526		goto cleanup;
1527	}
1528	dns_db_settask(db, zone->task);
1529
1530	if (! dns_db_ispersistent(db)) {
1531		if (zone->masterfile != NULL) {
1532			result = zone_startload(db, zone, loadtime);
1533		} else {
1534			result = DNS_R_NOMASTERFILE;
1535			if (zone->type == dns_zone_master) {
1536				dns_zone_log(zone, ISC_LOG_ERROR,
1537					     "loading zone: "
1538					     "no master file configured");
1539				goto cleanup;
1540			}
1541			dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1542				     "no master file configured: continuing");
1543		}
1544	}
1545
1546	if (result == DNS_R_CONTINUE) {
1547		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1548		if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1549			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1550		goto cleanup;
1551	}
1552
1553	result = zone_postload(zone, db, loadtime, result);
1554
1555 cleanup:
1556	UNLOCK_ZONE(zone);
1557	if (db != NULL)
1558		dns_db_detach(&db);
1559	return (result);
1560}
1561
1562isc_result_t
1563dns_zone_load(dns_zone_t *zone) {
1564	return (zone_load(zone, 0));
1565}
1566
1567isc_result_t
1568dns_zone_loadnew(dns_zone_t *zone) {
1569	return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1570}
1571
1572isc_result_t
1573dns_zone_loadandthaw(dns_zone_t *zone) {
1574	isc_result_t result;
1575
1576	result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1577	switch (result) {
1578	case DNS_R_CONTINUE:
1579		/* Deferred thaw. */
1580		break;
1581	case ISC_R_SUCCESS:
1582	case DNS_R_UPTODATE:
1583	case DNS_R_SEENINCLUDE:
1584		zone->update_disabled = ISC_FALSE;
1585		break;
1586	case DNS_R_NOMASTERFILE:
1587		zone->update_disabled = ISC_FALSE;
1588		break;
1589	default:
1590		/* Error, remain in disabled state. */
1591		break;
1592	}
1593	return (result);
1594}
1595
1596static unsigned int
1597get_master_options(dns_zone_t *zone) {
1598	unsigned int options;
1599
1600	options = DNS_MASTER_ZONE;
1601	if (zone->type == dns_zone_slave)
1602		options |= DNS_MASTER_SLAVE;
1603	if (zone->type == dns_zone_key)
1604		options |= DNS_MASTER_KEY;
1605	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1606		options |= DNS_MASTER_CHECKNS;
1607	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1608		options |= DNS_MASTER_FATALNS;
1609	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1610		options |= DNS_MASTER_CHECKNAMES;
1611	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1612		options |= DNS_MASTER_CHECKNAMESFAIL;
1613	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1614		options |= DNS_MASTER_CHECKMX;
1615	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1616		options |= DNS_MASTER_CHECKMXFAIL;
1617	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1618		options |= DNS_MASTER_CHECKWILDCARD;
1619	if (zone->type == dns_zone_master &&
1620	    ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1621	      zone->ssutable != NULL))
1622		options |= DNS_MASTER_RESIGN;
1623	return (options);
1624}
1625
1626static void
1627zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1628	dns_load_t *load = event->ev_arg;
1629	isc_result_t result = ISC_R_SUCCESS;
1630	unsigned int options;
1631
1632	REQUIRE(DNS_LOAD_VALID(load));
1633
1634	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1635		result = ISC_R_CANCELED;
1636	isc_event_free(&event);
1637	if (result == ISC_R_CANCELED)
1638		goto fail;
1639
1640	options = get_master_options(load->zone);
1641
1642	result = dns_master_loadfileinc3(load->zone->masterfile,
1643					 dns_db_origin(load->db),
1644					 dns_db_origin(load->db),
1645					 load->zone->rdclass,
1646					 options,
1647					 load->zone->sigresigninginterval,
1648					 &load->callbacks, task,
1649					 zone_loaddone, load,
1650					 &load->zone->lctx, load->zone->mctx,
1651					 load->zone->masterformat);
1652	if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1653	    result != DNS_R_SEENINCLUDE)
1654		goto fail;
1655	return;
1656
1657 fail:
1658	zone_loaddone(load, result);
1659}
1660
1661static void
1662zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1663	const char me[] = "zone_gotwritehandle";
1664	dns_zone_t *zone = event->ev_arg;
1665	isc_result_t result = ISC_R_SUCCESS;
1666	dns_dbversion_t *version = NULL;
1667
1668	REQUIRE(DNS_ZONE_VALID(zone));
1669	INSIST(task == zone->task);
1670	ENTER;
1671
1672	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1673		result = ISC_R_CANCELED;
1674	isc_event_free(&event);
1675	if (result == ISC_R_CANCELED)
1676		goto fail;
1677
1678	LOCK_ZONE(zone);
1679	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1680	if (zone->db != NULL) {
1681		dns_db_currentversion(zone->db, &version);
1682		result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1683					     &dns_master_style_default,
1684					     zone->masterfile, zone->task,
1685					     dump_done, zone, &zone->dctx,
1686					     zone->masterformat);
1687		dns_db_closeversion(zone->db, &version, ISC_FALSE);
1688	} else
1689		result = ISC_R_CANCELED;
1690	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1691	UNLOCK_ZONE(zone);
1692	if (result != DNS_R_CONTINUE)
1693		goto fail;
1694	return;
1695
1696 fail:
1697	dump_done(zone, result);
1698}
1699
1700static isc_result_t
1701zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1702	dns_load_t *load;
1703	isc_result_t result;
1704	isc_result_t tresult;
1705	unsigned int options;
1706
1707	options = get_master_options(zone);
1708
1709	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1710		options |= DNS_MASTER_MANYERRORS;
1711
1712	if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1713		load = isc_mem_get(zone->mctx, sizeof(*load));
1714		if (load == NULL)
1715			return (ISC_R_NOMEMORY);
1716
1717		load->mctx = NULL;
1718		load->zone = NULL;
1719		load->db = NULL;
1720		load->loadtime = loadtime;
1721		load->magic = LOAD_MAGIC;
1722
1723		isc_mem_attach(zone->mctx, &load->mctx);
1724		zone_iattach(zone, &load->zone);
1725		dns_db_attach(db, &load->db);
1726		dns_rdatacallbacks_init(&load->callbacks);
1727		result = dns_db_beginload(db, &load->callbacks.add,
1728					  &load->callbacks.add_private);
1729		if (result != ISC_R_SUCCESS)
1730			goto cleanup;
1731		result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1732				       zone_gotreadhandle, load,
1733				       &zone->readio);
1734		if (result != ISC_R_SUCCESS) {
1735			/*
1736			 * We can't report multiple errors so ignore
1737			 * the result of dns_db_endload().
1738			 */
1739			(void)dns_db_endload(load->db,
1740					     &load->callbacks.add_private);
1741			goto cleanup;
1742		} else
1743			result = DNS_R_CONTINUE;
1744	} else {
1745		dns_rdatacallbacks_t callbacks;
1746
1747		dns_rdatacallbacks_init(&callbacks);
1748		result = dns_db_beginload(db, &callbacks.add,
1749					  &callbacks.add_private);
1750		if (result != ISC_R_SUCCESS)
1751			return (result);
1752		result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1753					      &zone->origin, zone->rdclass,
1754					      options, zone->sigresigninginterval,
1755					      &callbacks, zone->mctx,
1756					      zone->masterformat);
1757		tresult = dns_db_endload(db, &callbacks.add_private);
1758		if (result == ISC_R_SUCCESS)
1759			result = tresult;
1760	}
1761
1762	return (result);
1763
1764 cleanup:
1765	load->magic = 0;
1766	dns_db_detach(&load->db);
1767	zone_idetach(&load->zone);
1768	isc_mem_detach(&load->mctx);
1769	isc_mem_put(zone->mctx, load, sizeof(*load));
1770	return (result);
1771}
1772
1773static isc_boolean_t
1774zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1775	      dns_name_t *owner)
1776{
1777	isc_result_t result;
1778	char ownerbuf[DNS_NAME_FORMATSIZE];
1779	char namebuf[DNS_NAME_FORMATSIZE];
1780	char altbuf[DNS_NAME_FORMATSIZE];
1781	dns_fixedname_t fixed;
1782	dns_name_t *foundname;
1783	int level;
1784
1785	/*
1786	 * "." means the services does not exist.
1787	 */
1788	if (dns_name_equal(name, dns_rootname))
1789		return (ISC_TRUE);
1790
1791	/*
1792	 * Outside of zone.
1793	 */
1794	if (!dns_name_issubdomain(name, &zone->origin)) {
1795		if (zone->checkmx != NULL)
1796			return ((zone->checkmx)(zone, name, owner));
1797		return (ISC_TRUE);
1798	}
1799
1800	if (zone->type == dns_zone_master)
1801		level = ISC_LOG_ERROR;
1802	else
1803		level = ISC_LOG_WARNING;
1804
1805	dns_fixedname_init(&fixed);
1806	foundname = dns_fixedname_name(&fixed);
1807
1808	result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1809			     0, 0, NULL, foundname, NULL, NULL);
1810	if (result == ISC_R_SUCCESS)
1811		return (ISC_TRUE);
1812
1813	if (result == DNS_R_NXRRSET) {
1814		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1815				    

Large files files are truncated, but you can click here to view the full file