Home | History | Annotate | Line # | Download | only in dns
zone.c revision 1.4
      1 /*	$NetBSD: zone.c,v 1.4 2019/02/24 20:01:30 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * This Source Code Form is subject to the terms of the Mozilla Public
      7  * License, v. 2.0. If a copy of the MPL was not distributed with this
      8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
      9  *
     10  * See the COPYRIGHT file distributed with this work for additional
     11  * information regarding copyright ownership.
     12  */
     13 
     14 /*! \file */
     15 
     16 #include <config.h>
     17 
     18 #include <errno.h>
     19 #include <inttypes.h>
     20 #include <stdbool.h>
     21 
     22 #include <isc/file.h>
     23 #include <isc/hex.h>
     24 #include <isc/mutex.h>
     25 #include <isc/pool.h>
     26 #include <isc/print.h>
     27 #include <isc/random.h>
     28 #include <isc/ratelimiter.h>
     29 #include <isc/refcount.h>
     30 #include <isc/rwlock.h>
     31 #include <isc/serial.h>
     32 #include <isc/stats.h>
     33 #include <isc/stdtime.h>
     34 #include <isc/strerr.h>
     35 #include <isc/string.h>
     36 #include <isc/taskpool.h>
     37 #include <isc/thread.h>
     38 #include <isc/timer.h>
     39 #include <isc/util.h>
     40 
     41 #include <dns/acl.h>
     42 #include <dns/adb.h>
     43 #include <dns/callbacks.h>
     44 #include <dns/catz.h>
     45 #include <dns/db.h>
     46 #include <dns/dbiterator.h>
     47 #include <dns/dlz.h>
     48 #include <dns/dnssec.h>
     49 #include <dns/events.h>
     50 #include <dns/journal.h>
     51 #include <dns/keydata.h>
     52 #include <dns/keytable.h>
     53 #include <dns/keyvalues.h>
     54 #include <dns/log.h>
     55 #include <dns/master.h>
     56 #include <dns/masterdump.h>
     57 #include <dns/message.h>
     58 #include <dns/name.h>
     59 #include <dns/nsec.h>
     60 #include <dns/nsec3.h>
     61 #include <dns/peer.h>
     62 #include <dns/private.h>
     63 #include <dns/rcode.h>
     64 #include <dns/rdata.h>
     65 #include <dns/rdataclass.h>
     66 #include <dns/rdatalist.h>
     67 #include <dns/rdataset.h>
     68 #include <dns/rdatasetiter.h>
     69 #include <dns/rdatastruct.h>
     70 #include <dns/rdatatype.h>
     71 #include <dns/request.h>
     72 #include <dns/resolver.h>
     73 #include <dns/result.h>
     74 #include <dns/rriterator.h>
     75 #include <dns/soa.h>
     76 #include <dns/ssu.h>
     77 #include <dns/stats.h>
     78 #include <dns/time.h>
     79 #include <dns/tsig.h>
     80 #include <dns/update.h>
     81 #include <dns/xfrin.h>
     82 #include <dns/zone.h>
     83 #include <dns/zoneverify.h>
     84 #include <dns/zt.h>
     85 
     86 #include <dst/dst.h>
     87 
     88 #include "zone_p.h"
     89 
     90 #define ZONE_MAGIC			ISC_MAGIC('Z', 'O', 'N', 'E')
     91 #define DNS_ZONE_VALID(zone)		ISC_MAGIC_VALID(zone, ZONE_MAGIC)
     92 
     93 #define NOTIFY_MAGIC			ISC_MAGIC('N', 't', 'f', 'y')
     94 #define DNS_NOTIFY_VALID(notify)	ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
     95 
     96 #define STUB_MAGIC			ISC_MAGIC('S', 't', 'u', 'b')
     97 #define DNS_STUB_VALID(stub)		ISC_MAGIC_VALID(stub, STUB_MAGIC)
     98 
     99 #define ZONEMGR_MAGIC			ISC_MAGIC('Z', 'm', 'g', 'r')
    100 #define DNS_ZONEMGR_VALID(stub)		ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
    101 
    102 #define LOAD_MAGIC			ISC_MAGIC('L', 'o', 'a', 'd')
    103 #define DNS_LOAD_VALID(load)		ISC_MAGIC_VALID(load, LOAD_MAGIC)
    104 
    105 #define FORWARD_MAGIC			ISC_MAGIC('F', 'o', 'r', 'w')
    106 #define DNS_FORWARD_VALID(load)		ISC_MAGIC_VALID(load, FORWARD_MAGIC)
    107 
    108 #define IO_MAGIC			ISC_MAGIC('Z', 'm', 'I', 'O')
    109 #define DNS_IO_VALID(load)		ISC_MAGIC_VALID(load, IO_MAGIC)
    110 
    111 /*%
    112  * Ensure 'a' is at least 'min' but not more than 'max'.
    113  */
    114 #define RANGE(a, min, max) \
    115 		(((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
    116 
    117 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
    118 
    119 /*%
    120  * Key flags
    121  */
    122 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
    123 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
    124 #define ALG(x) dst_key_alg(x)
    125 
    126 /*
    127  * Default values.
    128  */
    129 #define DNS_DEFAULT_IDLEIN 3600		/*%< 1 hour */
    130 #define DNS_DEFAULT_IDLEOUT 3600	/*%< 1 hour */
    131 #define MAX_XFER_TIME (2*3600)		/*%< Documented default is 2 hours */
    132 #define RESIGN_DELAY 3600		/*%< 1 hour */
    133 
    134 #ifndef DNS_MAX_EXPIRE
    135 #define DNS_MAX_EXPIRE	14515200	/*%< 24 weeks */
    136 #endif
    137 
    138 #ifndef DNS_DUMP_DELAY
    139 #define DNS_DUMP_DELAY 900		/*%< 15 minutes */
    140 #endif
    141 
    142 typedef struct dns_notify dns_notify_t;
    143 typedef struct dns_stub dns_stub_t;
    144 typedef struct dns_load dns_load_t;
    145 typedef struct dns_forward dns_forward_t;
    146 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
    147 typedef struct dns_io dns_io_t;
    148 typedef ISC_LIST(dns_io_t) dns_iolist_t;
    149 typedef struct dns_signing dns_signing_t;
    150 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
    151 typedef struct dns_nsec3chain dns_nsec3chain_t;
    152 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
    153 typedef struct dns_keyfetch dns_keyfetch_t;
    154 typedef struct dns_asyncload dns_asyncload_t;
    155 typedef struct dns_include dns_include_t;
    156 
    157 #define DNS_ZONE_CHECKLOCK
    158 #ifdef DNS_ZONE_CHECKLOCK
    159 #define LOCK_ZONE(z) \
    160 	 do { LOCK(&(z)->lock); \
    161 	      INSIST((z)->locked == false); \
    162 	     (z)->locked = true; \
    163 		} while (/*CONSTCOND*/0)
    164 #define UNLOCK_ZONE(z) \
    165 	do { (z)->locked = false; UNLOCK(&(z)->lock); } while (/*CONSTCON*/0)
    166 #define LOCKED_ZONE(z) ((z)->locked)
    167 #define TRYLOCK_ZONE(result, z) \
    168 	do { \
    169 	      result = isc_mutex_trylock(&(z)->lock); \
    170 	      if (result == ISC_R_SUCCESS) {  \
    171 		     INSIST((z)->locked == false); \
    172 		     (z)->locked = true; \
    173 	      } \
    174 	} while (/*CONSTCOND*/0)
    175 #else
    176 #define LOCK_ZONE(z) LOCK(&(z)->lock)
    177 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
    178 #define LOCKED_ZONE(z) true
    179 #define TRYLOCK_ZONE(result, z) \
    180 	do { result = isc_mutex_trylock(&(z)->lock); } while (/*CONSTCOND*/0)
    181 #endif
    182 
    183 #define ZONEDB_INITLOCK(l)	isc_rwlock_init((l), 0, 0)
    184 #define ZONEDB_DESTROYLOCK(l)	isc_rwlock_destroy(l)
    185 #define ZONEDB_LOCK(l, t)	RWLOCK((l), (t))
    186 #define ZONEDB_UNLOCK(l, t)	RWUNLOCK((l), (t))
    187 
    188 #ifdef ENABLE_AFL
    189 extern bool dns_fuzzing_resolver;
    190 #endif
    191 
    192 struct dns_zone {
    193 	/* Unlocked */
    194 	unsigned int		magic;
    195 	isc_mutex_t		lock;
    196 #ifdef DNS_ZONE_CHECKLOCK
    197 	bool		locked;
    198 #endif
    199 	isc_mem_t		*mctx;
    200 	isc_refcount_t		erefs;
    201 
    202 	isc_rwlock_t		dblock;
    203 	dns_db_t		*db;		/* Locked by dblock */
    204 
    205 	/* Locked */
    206 	dns_zonemgr_t		*zmgr;
    207 	ISC_LINK(dns_zone_t)	link;		/* Used by zmgr. */
    208 	isc_timer_t		*timer;
    209 	unsigned int		irefs;
    210 	dns_name_t		origin;
    211 	char			*masterfile;
    212 	ISC_LIST(dns_include_t)	includes;	/* Include files */
    213 	ISC_LIST(dns_include_t)	newincludes;	/* Loading */
    214 	unsigned int		nincludes;
    215 	dns_masterformat_t	masterformat;
    216 	const dns_master_style_t *masterstyle;
    217 	char			*journal;
    218 	int32_t		journalsize;
    219 	dns_rdataclass_t	rdclass;
    220 	dns_zonetype_t		type;
    221 	unsigned int		flags;
    222 	dns_zoneopt_t		options;
    223 	unsigned int		db_argc;
    224 	char			**db_argv;
    225 	isc_time_t		expiretime;
    226 	isc_time_t		refreshtime;
    227 	isc_time_t		dumptime;
    228 	isc_time_t		loadtime;
    229 	isc_time_t		notifytime;
    230 	isc_time_t		resigntime;
    231 	isc_time_t		keywarntime;
    232 	isc_time_t		signingtime;
    233 	isc_time_t		nsec3chaintime;
    234 	isc_time_t		refreshkeytime;
    235 	uint32_t		refreshkeyinterval;
    236 	uint32_t		refreshkeycount;
    237 	uint32_t		refresh;
    238 	uint32_t		retry;
    239 	uint32_t		expire;
    240 	uint32_t		minimum;
    241 	isc_stdtime_t		key_expiry;
    242 	isc_stdtime_t		log_key_expired_timer;
    243 	char			*keydirectory;
    244 
    245 	uint32_t		maxrefresh;
    246 	uint32_t		minrefresh;
    247 	uint32_t		maxretry;
    248 	uint32_t		minretry;
    249 
    250 	uint32_t		maxrecords;
    251 
    252 	isc_sockaddr_t		*masters;
    253 	isc_dscp_t		*masterdscps;
    254 	dns_name_t		**masterkeynames;
    255 	bool		*mastersok;
    256 	unsigned int		masterscnt;
    257 	unsigned int		curmaster;
    258 	isc_sockaddr_t		masteraddr;
    259 	dns_notifytype_t	notifytype;
    260 	isc_sockaddr_t		*notify;
    261 	dns_name_t		**notifykeynames;
    262 	isc_dscp_t		*notifydscp;
    263 	unsigned int		notifycnt;
    264 	isc_sockaddr_t		notifyfrom;
    265 	isc_task_t		*task;
    266 	isc_task_t		*loadtask;
    267 	isc_sockaddr_t		notifysrc4;
    268 	isc_sockaddr_t		notifysrc6;
    269 	isc_sockaddr_t		xfrsource4;
    270 	isc_sockaddr_t		xfrsource6;
    271 	isc_sockaddr_t		altxfrsource4;
    272 	isc_sockaddr_t		altxfrsource6;
    273 	isc_sockaddr_t		sourceaddr;
    274 	isc_dscp_t		notifysrc4dscp;
    275 	isc_dscp_t		notifysrc6dscp;
    276 	isc_dscp_t		xfrsource4dscp;
    277 	isc_dscp_t		xfrsource6dscp;
    278 	isc_dscp_t		altxfrsource4dscp;
    279 	isc_dscp_t		altxfrsource6dscp;
    280 	dns_xfrin_ctx_t		*xfr;		/* task locked */
    281 	dns_tsigkey_t		*tsigkey;	/* key used for xfr */
    282 	/* Access Control Lists */
    283 	dns_acl_t		*update_acl;
    284 	dns_acl_t		*forward_acl;
    285 	dns_acl_t		*notify_acl;
    286 	dns_acl_t		*query_acl;
    287 	dns_acl_t		*queryon_acl;
    288 	dns_acl_t		*xfr_acl;
    289 	bool		update_disabled;
    290 	bool		zero_no_soa_ttl;
    291 	dns_severity_t		check_names;
    292 	ISC_LIST(dns_notify_t)	notifies;
    293 	dns_request_t		*request;
    294 	dns_loadctx_t		*lctx;
    295 	dns_io_t		*readio;
    296 	dns_dumpctx_t		*dctx;
    297 	dns_io_t		*writeio;
    298 	uint32_t		maxxfrin;
    299 	uint32_t		maxxfrout;
    300 	uint32_t		idlein;
    301 	uint32_t		idleout;
    302 	isc_event_t		ctlevent;
    303 	dns_ssutable_t		*ssutable;
    304 	uint32_t		sigvalidityinterval;
    305 	uint32_t		keyvalidityinterval;
    306 	uint32_t		sigresigninginterval;
    307 	dns_view_t		*view;
    308 	dns_view_t		*prev_view;
    309 	dns_checkmxfunc_t	checkmx;
    310 	dns_checksrvfunc_t	checksrv;
    311 	dns_checknsfunc_t	checkns;
    312 	/*%
    313 	 * Zones in certain states such as "waiting for zone transfer"
    314 	 * or "zone transfer in progress" are kept on per-state linked lists
    315 	 * in the zone manager using the 'statelink' field.  The 'statelist'
    316 	 * field points at the list the zone is currently on.  It the zone
    317 	 * is not on any such list, statelist is NULL.
    318 	 */
    319 	ISC_LINK(dns_zone_t)	statelink;
    320 	dns_zonelist_t		*statelist;
    321 	/*%
    322 	 * Statistics counters about zone management.
    323 	 */
    324 	isc_stats_t		*stats;
    325 	/*%
    326 	 * Optional per-zone statistics counters.  Counted outside of this
    327 	 * module.
    328 	 */
    329 	dns_zonestat_level_t	statlevel;
    330 	bool		requeststats_on;
    331 	isc_stats_t		*requeststats;
    332 	dns_stats_t		*rcvquerystats;
    333 	uint32_t		notifydelay;
    334 	dns_isselffunc_t	isself;
    335 	void			*isselfarg;
    336 
    337 	char *			strnamerd;
    338 	char *			strname;
    339 	char *			strrdclass;
    340 	char *			strviewname;
    341 
    342 	/*%
    343 	 * Serial number for deferred journal compaction.
    344 	 */
    345 	uint32_t		compact_serial;
    346 	/*%
    347 	 * Keys that are signing the zone for the first time.
    348 	 */
    349 	dns_signinglist_t	signing;
    350 	dns_nsec3chainlist_t	nsec3chain;
    351 	/*%
    352 	 * List of outstanding NSEC3PARAM change requests.
    353 	 */
    354 	isc_eventlist_t		setnsec3param_queue;
    355 	/*%
    356 	 * Signing / re-signing quantum stopping parameters.
    357 	 */
    358 	uint32_t		signatures;
    359 	uint32_t		nodes;
    360 	dns_rdatatype_t		privatetype;
    361 
    362 	/*%
    363 	 * Autosigning/key-maintenance options
    364 	 */
    365 	uint32_t		keyopts;
    366 
    367 	/*%
    368 	 * True if added by "rndc addzone"
    369 	 */
    370 	bool           added;
    371 
    372 	/*%
    373 	 * True if added by automatically by named.
    374 	 */
    375 	bool           automatic;
    376 
    377 	/*%
    378 	 * response policy data to be relayed to the database
    379 	 */
    380 	dns_rpz_zones_t		*rpzs;
    381 	dns_rpz_num_t		rpz_num;
    382 
    383 	/*%
    384 	 * catalog zone data
    385 	 */
    386 	dns_catz_zones_t	*catzs;
    387 
    388 	/*%
    389 	 * parent catalog zone
    390 	 */
    391 	dns_catz_zone_t		*parentcatz;
    392 
    393 	/*%
    394 	 * Serial number update method.
    395 	 */
    396 	dns_updatemethod_t	updatemethod;
    397 
    398 	/*%
    399 	 * whether ixfr is requested
    400 	 */
    401 	bool		requestixfr;
    402 
    403 	/*%
    404 	 * whether EDNS EXPIRE is requested
    405 	 */
    406 	bool		requestexpire;
    407 
    408 	/*%
    409 	 * Outstanding forwarded UPDATE requests.
    410 	 */
    411 	dns_forwardlist_t	forwards;
    412 
    413 	dns_zone_t		*raw;
    414 	dns_zone_t		*secure;
    415 
    416 	bool		sourceserialset;
    417 	uint32_t		sourceserial;
    418 
    419 	/*%
    420 	 * maximum zone ttl
    421 	 */
    422 	dns_ttl_t		maxttl;
    423 
    424 	/*
    425 	 * Inline zone signing state.
    426 	 */
    427 	dns_diff_t		rss_diff;
    428 	isc_eventlist_t		rss_events;
    429 	dns_dbversion_t		*rss_newver;
    430 	dns_dbversion_t		*rss_oldver;
    431 	dns_db_t		*rss_db;
    432 	dns_zone_t		*rss_raw;
    433 	isc_event_t		*rss_event;
    434 	dns_update_state_t      *rss_state;
    435 
    436 	isc_stats_t             *gluecachestats;
    437 };
    438 
    439 #define zonediff_init(z, d) \
    440 	do { \
    441 		dns__zonediff_t *_z = (z); \
    442 		(_z)->diff = (d); \
    443 		(_z)->offline = false; \
    444 	} while (/*CONSTCOND*/0)
    445 
    446 #define DNS_ZONE_FLAG(z,f) ((z)->flags & (f))
    447 #define DNS_ZONE_SETFLAG(z,f) do { \
    448 		INSIST(LOCKED_ZONE(z)); \
    449 		(z)->flags |= (f); \
    450 		} while (/*CONSTCOND*/0)
    451 #define DNS_ZONE_CLRFLAG(z,f) do { \
    452 		INSIST(LOCKED_ZONE(z)); \
    453 		(z)->flags &= ~(f); \
    454 		} while (/*CONSTCOND*/0)
    455 	/* XXX MPA these may need to go back into zone.h */
    456 #define DNS_ZONEFLG_REFRESH	0x00000001U	/*%< refresh check in progress */
    457 #define DNS_ZONEFLG_NEEDDUMP	0x00000002U	/*%< zone need consolidation */
    458 #define DNS_ZONEFLG_USEVC	0x00000004U	/*%< use tcp for refresh query */
    459 #define DNS_ZONEFLG_DUMPING	0x00000008U	/*%< a dump is in progress */
    460 #define DNS_ZONEFLG_HASINCLUDE	0x00000010U	/*%< $INCLUDE in zone file */
    461 #define DNS_ZONEFLG_LOADED	0x00000020U	/*%< database has loaded */
    462 #define DNS_ZONEFLG_EXITING	0x00000040U	/*%< zone is being destroyed */
    463 #define DNS_ZONEFLG_EXPIRED	0x00000080U	/*%< zone has expired */
    464 #define DNS_ZONEFLG_NEEDREFRESH	0x00000100U	/*%< refresh check needed */
    465 #define DNS_ZONEFLG_UPTODATE	0x00000200U	/*%< zone contents are
    466 						 * uptodate */
    467 #define DNS_ZONEFLG_NEEDNOTIFY	0x00000400U	/*%< need to send out notify
    468 						 * messages */
    469 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U	/*%< generate a journal diff on
    470 						 * reload */
    471 #define DNS_ZONEFLG_NOMASTERS	0x00001000U	/*%< an attempt to refresh a
    472 						 * zone with no masters
    473 						 * occurred */
    474 #define DNS_ZONEFLG_LOADING	0x00002000U	/*%< load from disk in progress*/
    475 #define DNS_ZONEFLG_HAVETIMERS	0x00004000U	/*%< timer values have been set
    476 						 * from SOA (if not set, we
    477 						 * are still using
    478 						 * default timer values) */
    479 #define DNS_ZONEFLG_FORCEXFER	0x00008000U	/*%< Force a zone xfer */
    480 #define DNS_ZONEFLG_NOREFRESH	0x00010000U
    481 #define DNS_ZONEFLG_DIALNOTIFY	0x00020000U
    482 #define DNS_ZONEFLG_DIALREFRESH	0x00040000U
    483 #define DNS_ZONEFLG_SHUTDOWN	0x00080000U
    484 #define DNS_ZONEFLAG_NOIXFR	0x00100000U	/*%< IXFR failed, force AXFR */
    485 #define DNS_ZONEFLG_FLUSH	0x00200000U
    486 #define DNS_ZONEFLG_NOEDNS	0x00400000U
    487 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
    488 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
    489 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
    490 #define DNS_ZONEFLG_REFRESHING	0x04000000U	/*%< Refreshing keydata */
    491 #define DNS_ZONEFLG_THAW	0x08000000U
    492 #define DNS_ZONEFLG_LOADPENDING	0x10000000U	/*%< Loading scheduled */
    493 #define DNS_ZONEFLG_NODELAY	0x20000000U
    494 #define DNS_ZONEFLG_SENDSECURE  0x40000000U
    495 #define DNS_ZONEFLG_NEEDSTARTUPNOTIFY 0x80000000U /*%< need to send out notify
    496 						   *   due to the zone just
    497 						   *   being loaded for the
    498 						   *   first time.  */
    499 
    500 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
    501 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
    502 
    503 /* Flags for zone_load() */
    504 #define DNS_ZONELOADFLAG_NOSTAT        0x00000001U     /* Do not stat() master files */
    505 #define DNS_ZONELOADFLAG_THAW  0x00000002U     /* Thaw the zone on successful
    506 						  load. */
    507 
    508 #define UNREACH_CHACHE_SIZE	10U
    509 #define UNREACH_HOLD_TIME	600	/* 10 minutes */
    510 
    511 #define CHECK(op) \
    512 	do { result = (op); \
    513 		if (result != ISC_R_SUCCESS) goto failure; \
    514 	} while (/*CONSTCOND*/0)
    515 
    516 struct dns_unreachable {
    517 	isc_sockaddr_t	remote;
    518 	isc_sockaddr_t	local;
    519 	uint32_t	expire;
    520 	uint32_t	last;
    521 	uint32_t	count;
    522 };
    523 
    524 struct dns_zonemgr {
    525 	unsigned int		magic;
    526 	isc_mem_t *		mctx;
    527 	int			refs;		/* Locked by rwlock */
    528 	isc_taskmgr_t *		taskmgr;
    529 	isc_timermgr_t *	timermgr;
    530 	isc_socketmgr_t *	socketmgr;
    531 	isc_taskpool_t *	zonetasks;
    532 	isc_taskpool_t *	loadtasks;
    533 	isc_task_t *		task;
    534 	isc_pool_t *		mctxpool;
    535 	isc_ratelimiter_t *	notifyrl;
    536 	isc_ratelimiter_t *	refreshrl;
    537 	isc_ratelimiter_t *	startupnotifyrl;
    538 	isc_ratelimiter_t *	startuprefreshrl;
    539 	isc_rwlock_t		rwlock;
    540 	isc_mutex_t		iolock;
    541 	isc_rwlock_t		urlock;
    542 
    543 	/* Locked by rwlock. */
    544 	dns_zonelist_t		zones;
    545 	dns_zonelist_t		waiting_for_xfrin;
    546 	dns_zonelist_t		xfrin_in_progress;
    547 
    548 	/* Configuration data. */
    549 	uint32_t		transfersin;
    550 	uint32_t		transfersperns;
    551 	unsigned int		notifyrate;
    552 	unsigned int		startupnotifyrate;
    553 	unsigned int		serialqueryrate;
    554 	unsigned int		startupserialqueryrate;
    555 
    556 	/* Locked by iolock */
    557 	uint32_t		iolimit;
    558 	uint32_t		ioactive;
    559 	dns_iolist_t		high;
    560 	dns_iolist_t		low;
    561 
    562 	/* Locked by urlock. */
    563 	/* LRU cache */
    564 	struct dns_unreachable	unreachable[UNREACH_CHACHE_SIZE];
    565 };
    566 
    567 /*%
    568  * Hold notify state.
    569  */
    570 struct dns_notify {
    571 	unsigned int		magic;
    572 	unsigned int		flags;
    573 	isc_mem_t		*mctx;
    574 	dns_zone_t		*zone;
    575 	dns_adbfind_t		*find;
    576 	dns_request_t		*request;
    577 	dns_name_t		ns;
    578 	isc_sockaddr_t		dst;
    579 	dns_tsigkey_t		*key;
    580 	isc_dscp_t		dscp;
    581 	ISC_LINK(dns_notify_t)	link;
    582 	isc_event_t		*event;
    583 };
    584 
    585 #define DNS_NOTIFY_NOSOA	0x0001U
    586 #define DNS_NOTIFY_STARTUP	0x0002U
    587 
    588 /*%
    589  *	dns_stub holds state while performing a 'stub' transfer.
    590  *	'db' is the zone's 'db' or a new one if this is the initial
    591  *	transfer.
    592  */
    593 
    594 struct dns_stub {
    595 	unsigned int		magic;
    596 	isc_mem_t		*mctx;
    597 	dns_zone_t		*zone;
    598 	dns_db_t		*db;
    599 	dns_dbversion_t		*version;
    600 };
    601 
    602 /*%
    603  *	Hold load state.
    604  */
    605 struct dns_load {
    606 	unsigned int		magic;
    607 	isc_mem_t		*mctx;
    608 	dns_zone_t		*zone;
    609 	dns_db_t		*db;
    610 	isc_time_t		loadtime;
    611 	dns_rdatacallbacks_t	callbacks;
    612 };
    613 
    614 /*%
    615  *	Hold forward state.
    616  */
    617 struct dns_forward {
    618 	unsigned int		magic;
    619 	isc_mem_t		*mctx;
    620 	dns_zone_t		*zone;
    621 	isc_buffer_t		*msgbuf;
    622 	dns_request_t		*request;
    623 	uint32_t		which;
    624 	isc_sockaddr_t		addr;
    625 	dns_updatecallback_t	callback;
    626 	void			*callback_arg;
    627 	unsigned int		options;
    628 	ISC_LINK(dns_forward_t)	link;
    629 };
    630 
    631 /*%
    632  *	Hold IO request state.
    633  */
    634 struct dns_io {
    635 	unsigned int	magic;
    636 	dns_zonemgr_t	*zmgr;
    637 	bool	high;
    638 	isc_task_t	*task;
    639 	ISC_LINK(dns_io_t) link;
    640 	isc_event_t	*event;
    641 };
    642 
    643 /*%
    644  *	Hold state for when we are signing a zone with a new
    645  *	DNSKEY as result of an update.
    646  */
    647 struct dns_signing {
    648 	unsigned int		magic;
    649 	dns_db_t		*db;
    650 	dns_dbiterator_t	*dbiterator;
    651 	dns_secalg_t		algorithm;
    652 	uint16_t		keyid;
    653 	bool		deleteit;
    654 	bool		done;
    655 	ISC_LINK(dns_signing_t)	link;
    656 };
    657 
    658 struct dns_nsec3chain {
    659 	unsigned int			magic;
    660 	dns_db_t			*db;
    661 	dns_dbiterator_t		*dbiterator;
    662 	dns_rdata_nsec3param_t		nsec3param;
    663 	unsigned char			salt[255];
    664 	bool			done;
    665 	bool			seen_nsec;
    666 	bool			delete_nsec;
    667 	bool			save_delete_nsec;
    668 	ISC_LINK(dns_nsec3chain_t)	link;
    669 };
    670 /*%<
    671  * 'dbiterator' contains a iterator for the database.  If we are creating
    672  * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
    673  * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
    674  * iterated.
    675  *
    676  * 'nsec3param' contains the parameters of the NSEC3 chain being created
    677  * or removed.
    678  *
    679  * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
    680  *
    681  * 'seen_nsec' will be set to true if, while iterating the zone to create a
    682  * NSEC3 chain, a NSEC record is seen.
    683  *
    684  * 'delete_nsec' will be set to true if, at the completion of the creation
    685  * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
    686  * are in the process of deleting the NSEC chain.
    687  *
    688  * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
    689  * so it can be recovered in the event of a error.
    690  */
    691 
    692 struct dns_keyfetch {
    693 	dns_fixedname_t name;
    694 	dns_rdataset_t keydataset;
    695 	dns_rdataset_t dnskeyset;
    696 	dns_rdataset_t dnskeysigset;
    697 	dns_zone_t *zone;
    698 	dns_db_t *db;
    699 	dns_fetch_t *fetch;
    700 };
    701 
    702 /*%
    703  * Hold state for an asynchronous load
    704  */
    705 struct dns_asyncload {
    706 	dns_zone_t *zone;
    707 	unsigned int flags;
    708 	dns_zt_zoneloaded_t loaded;
    709 	void *loaded_arg;
    710 };
    711 
    712 /*%
    713  * Reference to an include file encountered during loading
    714  */
    715 struct dns_include {
    716 	char *name;
    717 	isc_time_t filetime;
    718 	ISC_LINK(dns_include_t)	link;
    719 };
    720 
    721 /*
    722  * These can be overridden by the -T mkeytimers option on the command
    723  * line, so that we can test with shorter periods than specified in
    724  * RFC 5011.
    725  */
    726 #define HOUR 3600
    727 #define DAY (24*HOUR)
    728 #define MONTH (30*DAY)
    729 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR;
    730 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY;
    731 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH;
    732 
    733 #define SEND_BUFFER_SIZE 2048
    734 
    735 static void zone_settimer(dns_zone_t *, isc_time_t *);
    736 static void cancel_refresh(dns_zone_t *);
    737 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
    738 			  const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
    739 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
    740      ISC_FORMAT_PRINTF(3, 4);
    741 static void dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...)
    742      ISC_FORMAT_PRINTF(3, 4);
    743 static void queue_xfrin(dns_zone_t *zone);
    744 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
    745 				  dns_diff_t *diff, dns_diffop_t op,
    746 				  dns_name_t *name, dns_ttl_t ttl,
    747 				  dns_rdata_t *rdata);
    748 static void zone_unload(dns_zone_t *zone);
    749 static void zone_expire(dns_zone_t *zone);
    750 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
    751 static void zone_idetach(dns_zone_t **zonep);
    752 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
    753 				   bool dump);
    754 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
    755 static inline void zone_detachdb(dns_zone_t *zone);
    756 static isc_result_t default_journal(dns_zone_t *zone);
    757 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
    758 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
    759 				  isc_time_t loadtime, isc_result_t result);
    760 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
    761 static void zone_shutdown(isc_task_t *, isc_event_t *);
    762 static void zone_loaddone(void *arg, isc_result_t result);
    763 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
    764 				   isc_time_t loadtime);
    765 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
    766 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
    767 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
    768 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
    769 static isc_result_t zone_send_secureserial(dns_zone_t *zone,
    770 					   uint32_t serial);
    771 static void refresh_callback(isc_task_t *, isc_event_t *);
    772 static void stub_callback(isc_task_t *, isc_event_t *);
    773 static void queue_soa_query(dns_zone_t *zone);
    774 static void soa_query(isc_task_t *, isc_event_t *);
    775 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
    776 		     dns_stub_t *stub);
    777 static int message_count(dns_message_t *msg, dns_section_t section,
    778 			 dns_rdatatype_t type);
    779 static void notify_cancel(dns_zone_t *zone);
    780 static void notify_find_address(dns_notify_t *notify);
    781 static void notify_send(dns_notify_t *notify);
    782 static isc_result_t notify_createmessage(dns_zone_t *zone,
    783 					 unsigned int flags,
    784 					 dns_message_t **messagep);
    785 static void notify_done(isc_task_t *task, isc_event_t *event);
    786 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
    787 static isc_result_t zone_dump(dns_zone_t *, bool);
    788 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
    789 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
    790 					     dns_zone_t *zone);
    791 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi);
    792 static void zonemgr_free(dns_zonemgr_t *zmgr);
    793 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, bool high,
    794 				  isc_task_t *task, isc_taskaction_t action,
    795 				  void *arg, dns_io_t **iop);
    796 static void zonemgr_putio(dns_io_t **iop);
    797 static void zonemgr_cancelio(dns_io_t *io);
    798 
    799 static isc_result_t
    800 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
    801 		 unsigned int *soacount, uint32_t *serial,
    802 		 uint32_t *refresh, uint32_t *retry,
    803 		 uint32_t *expire, uint32_t *minimum,
    804 		 unsigned int *errors);
    805 
    806 static void zone_freedbargs(dns_zone_t *zone);
    807 static void forward_callback(isc_task_t *task, isc_event_t *event);
    808 static void zone_saveunique(dns_zone_t *zone, const char *path,
    809 			    const char *templat);
    810 static void zone_maintenance(dns_zone_t *zone);
    811 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
    812 static void dump_done(void *arg, isc_result_t result);
    813 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
    814 				     uint16_t keyid,
    815 				     bool deleteit);
    816 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
    817 				dns_dbnode_t *node, dns_name_t *name,
    818 				dns_diff_t *diff);
    819 static void zone_rekey(dns_zone_t *zone);
    820 static isc_result_t zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
    821 static void setrl(isc_ratelimiter_t *rl, unsigned int *rate,
    822 		  unsigned int value);
    823 
    824 #define ENTER zone_debuglog(zone, me, 1, "enter")
    825 
    826 static const unsigned int dbargc_default = 1;
    827 static const char *dbargv_default[] = { "rbt" };
    828 
    829 #define DNS_ZONE_JITTER_ADD(a, b, c) \
    830 	do { \
    831 		isc_interval_t _i; \
    832 		uint32_t _j; \
    833 		_j = (b) - isc_random_uniform((b)/4);	\
    834 		isc_interval_set(&_i, _j, 0); \
    835 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
    836 			dns_zone_log(zone, ISC_LOG_WARNING, \
    837 				     "epoch approaching: upgrade required: " \
    838 				     "now + %s failed", #b); \
    839 			isc_interval_set(&_i, _j/2, 0); \
    840 			(void)isc_time_add((a), &_i, (c)); \
    841 		} \
    842 	} while (/*CONSTCOND*/0)
    843 
    844 #define DNS_ZONE_TIME_ADD(a, b, c) \
    845 	do { \
    846 		isc_interval_t _i; \
    847 		isc_interval_set(&_i, (b), 0); \
    848 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
    849 			dns_zone_log(zone, ISC_LOG_WARNING, \
    850 				     "epoch approaching: upgrade required: " \
    851 				     "now + %s failed", #b); \
    852 			isc_interval_set(&_i, (b)/2, 0); \
    853 			(void)isc_time_add((a), &_i, (c)); \
    854 		} \
    855 	} while (/*CONSTCOND*/0)
    856 
    857 typedef struct nsec3param nsec3param_t;
    858 struct nsec3param {
    859 	unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
    860 	unsigned int length;
    861 	bool nsec;
    862 	bool replace;
    863 	ISC_LINK(nsec3param_t)	link;
    864 };
    865 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
    866 struct np3event {
    867 	isc_event_t event;
    868 	nsec3param_t params;
    869 };
    870 
    871 struct ssevent {
    872 	isc_event_t event;
    873 	uint32_t serial;
    874 };
    875 
    876 /*%
    877  * Increment resolver-related statistics counters.  Zone must be locked.
    878  */
    879 static inline void
    880 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
    881 	if (zone->stats != NULL)
    882 		isc_stats_increment(zone->stats, counter);
    883 }
    884 
    885 /***
    886  ***	Public functions.
    887  ***/
    888 
    889 isc_result_t
    890 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
    891 	isc_result_t result;
    892 	dns_zone_t *zone;
    893 	isc_time_t now;
    894 
    895 	REQUIRE(zonep != NULL && *zonep == NULL);
    896 	REQUIRE(mctx != NULL);
    897 
    898 	TIME_NOW(&now);
    899 	zone = isc_mem_get(mctx, sizeof(*zone));
    900 	if (zone == NULL) {
    901 		return (ISC_R_NOMEMORY);
    902 	}
    903 
    904 	zone->mctx = NULL;
    905 	isc_mem_attach(mctx, &zone->mctx);
    906 
    907 	isc_mutex_init(&zone->lock);
    908 
    909 	result = ZONEDB_INITLOCK(&zone->dblock);
    910 	if (result != ISC_R_SUCCESS) {
    911 		goto free_mutex;
    912 	}
    913 
    914 	/* XXX MPA check that all elements are initialised */
    915 #ifdef DNS_ZONE_CHECKLOCK
    916 	zone->locked = false;
    917 #endif
    918 	zone->db = NULL;
    919 	zone->zmgr = NULL;
    920 	ISC_LINK_INIT(zone, link);
    921 	isc_refcount_init(&zone->erefs, 1);	/* Implicit attach. */
    922 	zone->irefs = 0;
    923 	dns_name_init(&zone->origin, NULL);
    924 	zone->strnamerd = NULL;
    925 	zone->strname = NULL;
    926 	zone->strrdclass = NULL;
    927 	zone->strviewname = NULL;
    928 	zone->masterfile = NULL;
    929 	ISC_LIST_INIT(zone->includes);
    930 	ISC_LIST_INIT(zone->newincludes);
    931 	zone->nincludes = 0;
    932 	zone->masterformat = dns_masterformat_none;
    933 	zone->masterstyle = NULL;
    934 	zone->keydirectory = NULL;
    935 	zone->journalsize = -1;
    936 	zone->journal = NULL;
    937 	zone->rdclass = dns_rdataclass_none;
    938 	zone->type = dns_zone_none;
    939 	zone->flags = 0;
    940 	zone->options = 0;
    941 	zone->keyopts = 0;
    942 	zone->db_argc = 0;
    943 	zone->db_argv = NULL;
    944 	isc_time_settoepoch(&zone->expiretime);
    945 	isc_time_settoepoch(&zone->refreshtime);
    946 	isc_time_settoepoch(&zone->dumptime);
    947 	isc_time_settoepoch(&zone->loadtime);
    948 	zone->notifytime = now;
    949 	isc_time_settoepoch(&zone->resigntime);
    950 	isc_time_settoepoch(&zone->keywarntime);
    951 	isc_time_settoepoch(&zone->signingtime);
    952 	isc_time_settoepoch(&zone->nsec3chaintime);
    953 	isc_time_settoepoch(&zone->refreshkeytime);
    954 	zone->refreshkeyinterval = 0;
    955 	zone->refreshkeycount = 0;
    956 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
    957 	zone->retry = DNS_ZONE_DEFAULTRETRY;
    958 	zone->expire = 0;
    959 	zone->minimum = 0;
    960 	zone->maxrefresh = DNS_ZONE_MAXREFRESH;
    961 	zone->minrefresh = DNS_ZONE_MINREFRESH;
    962 	zone->maxretry = DNS_ZONE_MAXRETRY;
    963 	zone->minretry = DNS_ZONE_MINRETRY;
    964 	zone->masters = NULL;
    965 	zone->masterdscps = NULL;
    966 	zone->masterkeynames = NULL;
    967 	zone->mastersok = NULL;
    968 	zone->masterscnt = 0;
    969 	zone->curmaster = 0;
    970 	zone->maxttl = 0;
    971 	zone->notify = NULL;
    972 	zone->notifykeynames = NULL;
    973 	zone->notifydscp = NULL;
    974 	zone->notifytype = dns_notifytype_yes;
    975 	zone->notifycnt = 0;
    976 	zone->task = NULL;
    977 	zone->loadtask = NULL;
    978 	zone->update_acl = NULL;
    979 	zone->forward_acl = NULL;
    980 	zone->notify_acl = NULL;
    981 	zone->query_acl = NULL;
    982 	zone->queryon_acl = NULL;
    983 	zone->xfr_acl = NULL;
    984 	zone->update_disabled = false;
    985 	zone->zero_no_soa_ttl = true;
    986 	zone->check_names = dns_severity_ignore;
    987 	zone->request = NULL;
    988 	zone->lctx = NULL;
    989 	zone->readio = NULL;
    990 	zone->dctx = NULL;
    991 	zone->writeio = NULL;
    992 	zone->timer = NULL;
    993 	zone->idlein = DNS_DEFAULT_IDLEIN;
    994 	zone->idleout = DNS_DEFAULT_IDLEOUT;
    995 	zone->log_key_expired_timer = 0;
    996 	ISC_LIST_INIT(zone->notifies);
    997 	isc_sockaddr_any(&zone->notifysrc4);
    998 	isc_sockaddr_any6(&zone->notifysrc6);
    999 	isc_sockaddr_any(&zone->xfrsource4);
   1000 	isc_sockaddr_any6(&zone->xfrsource6);
   1001 	isc_sockaddr_any(&zone->altxfrsource4);
   1002 	isc_sockaddr_any6(&zone->altxfrsource6);
   1003 	zone->notifysrc4dscp = -1;
   1004 	zone->notifysrc6dscp = -1;
   1005 	zone->xfrsource4dscp = -1;
   1006 	zone->xfrsource6dscp = -1;
   1007 	zone->altxfrsource4dscp = -1;
   1008 	zone->altxfrsource6dscp = -1;
   1009 	zone->xfr = NULL;
   1010 	zone->tsigkey = NULL;
   1011 	zone->maxxfrin = MAX_XFER_TIME;
   1012 	zone->maxxfrout = MAX_XFER_TIME;
   1013 	zone->ssutable = NULL;
   1014 	zone->sigvalidityinterval = 30 * 24 * 3600;
   1015 	zone->keyvalidityinterval = 0;
   1016 	zone->sigresigninginterval = 7 * 24 * 3600;
   1017 	zone->view = NULL;
   1018 	zone->prev_view = NULL;
   1019 	zone->checkmx = NULL;
   1020 	zone->checksrv = NULL;
   1021 	zone->checkns = NULL;
   1022 	ISC_LINK_INIT(zone, statelink);
   1023 	zone->statelist = NULL;
   1024 	zone->stats = NULL;
   1025 	zone->requeststats_on = false;
   1026 	zone->statlevel = dns_zonestat_none;
   1027 	zone->requeststats = NULL;
   1028 	zone->rcvquerystats = NULL;
   1029 	zone->notifydelay = 5;
   1030 	zone->isself = NULL;
   1031 	zone->isselfarg = NULL;
   1032 	ISC_LIST_INIT(zone->signing);
   1033 	ISC_LIST_INIT(zone->nsec3chain);
   1034 	ISC_LIST_INIT(zone->setnsec3param_queue);
   1035 	zone->signatures = 10;
   1036 	zone->nodes = 100;
   1037 	zone->privatetype = (dns_rdatatype_t)0xffffU;
   1038 	zone->added = false;
   1039 	zone->automatic = false;
   1040 	zone->rpzs = NULL;
   1041 	zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1042 
   1043 	zone->catzs = NULL;
   1044 	zone->parentcatz = NULL;
   1045 
   1046 	ISC_LIST_INIT(zone->forwards);
   1047 	zone->raw = NULL;
   1048 	zone->secure = NULL;
   1049 	zone->sourceserial = 0;
   1050 	zone->sourceserialset = false;
   1051 	zone->requestixfr = true;
   1052 	zone->requestexpire = true;
   1053 	ISC_LIST_INIT(zone->rss_events);
   1054 	zone->rss_db = NULL;
   1055 	zone->rss_raw = NULL;
   1056 	zone->rss_newver = NULL;
   1057 	zone->rss_oldver = NULL;
   1058 	zone->rss_event = NULL;
   1059 	zone->rss_state = NULL;
   1060 	zone->updatemethod = dns_updatemethod_increment;
   1061 	zone->maxrecords = 0U;
   1062 
   1063 	zone->magic = ZONE_MAGIC;
   1064 
   1065 	zone->gluecachestats = NULL;
   1066 	result = isc_stats_create(mctx, &zone->gluecachestats,
   1067 				  dns_gluecachestatscounter_max);
   1068 	if (result != ISC_R_SUCCESS) {
   1069 		goto free_erefs;
   1070 	}
   1071 
   1072 	/* Must be after magic is set. */
   1073 	result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
   1074 	if (result != ISC_R_SUCCESS) {
   1075 		goto free_stats;
   1076 	}
   1077 
   1078 	ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
   1079 		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
   1080 		       NULL, NULL);
   1081 	*zonep = zone;
   1082 	return (ISC_R_SUCCESS);
   1083 
   1084  free_stats:
   1085 	if (zone->gluecachestats != NULL)
   1086 		isc_stats_detach(&zone->gluecachestats);
   1087 
   1088  free_erefs:
   1089 	INSIST(isc_refcount_decrement(&zone->erefs) > 0);
   1090 	isc_refcount_destroy(&zone->erefs);
   1091 
   1092 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1093 
   1094  free_mutex:
   1095 	isc_mutex_destroy(&zone->lock);
   1096 
   1097 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1098 	return (result);
   1099 }
   1100 
   1101 /*
   1102  * Free a zone.  Because we require that there be no more
   1103  * outstanding events or references, no locking is necessary.
   1104  */
   1105 static void
   1106 zone_free(dns_zone_t *zone) {
   1107 	isc_mem_t *mctx = NULL;
   1108 	dns_signing_t *signing;
   1109 	dns_nsec3chain_t *nsec3chain;
   1110 	isc_event_t *setnsec3param_event;
   1111 	dns_include_t *include;
   1112 
   1113 	REQUIRE(DNS_ZONE_VALID(zone));
   1114 	REQUIRE(isc_refcount_current(&zone->erefs) == 0);
   1115 	REQUIRE(zone->irefs == 0);
   1116 	REQUIRE(!LOCKED_ZONE(zone));
   1117 	REQUIRE(zone->timer == NULL);
   1118 	REQUIRE(zone->zmgr == NULL);
   1119 
   1120 	/*
   1121 	 * Managed objects.  Order is important.
   1122 	 */
   1123 	if (zone->request != NULL) {
   1124 		dns_request_destroy(&zone->request); /* XXXMPA */
   1125 	}
   1126 	INSIST(zone->readio == NULL);
   1127 	INSIST(zone->statelist == NULL);
   1128 	INSIST(zone->writeio == NULL);
   1129 
   1130 	if (zone->task != NULL) {
   1131 		isc_task_detach(&zone->task);
   1132 	}
   1133 	if (zone->loadtask != NULL) {
   1134 		isc_task_detach(&zone->loadtask);
   1135 	}
   1136 	if (zone->view != NULL) {
   1137 		dns_view_weakdetach(&zone->view);
   1138 	}
   1139 	if (zone->prev_view != NULL) {
   1140 		dns_view_weakdetach(&zone->prev_view);
   1141 	}
   1142 
   1143 	/* Unmanaged objects */
   1144 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   1145 		setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   1146 		ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
   1147 				ev_link);
   1148 		isc_event_free(&setnsec3param_event);
   1149 	}
   1150 	for (signing = ISC_LIST_HEAD(zone->signing);
   1151 	     signing != NULL;
   1152 	     signing = ISC_LIST_HEAD(zone->signing)) {
   1153 		ISC_LIST_UNLINK(zone->signing, signing, link);
   1154 		dns_db_detach(&signing->db);
   1155 		dns_dbiterator_destroy(&signing->dbiterator);
   1156 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   1157 	}
   1158 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   1159 	     nsec3chain != NULL;
   1160 	     nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
   1161 		ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   1162 		dns_db_detach(&nsec3chain->db);
   1163 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   1164 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   1165 	}
   1166 	for (include = ISC_LIST_HEAD(zone->includes);
   1167 	     include != NULL;
   1168 	     include = ISC_LIST_HEAD(zone->includes)) {
   1169 		ISC_LIST_UNLINK(zone->includes, include, link);
   1170 		isc_mem_free(zone->mctx, include->name);
   1171 		isc_mem_put(zone->mctx, include, sizeof *include);
   1172 	}
   1173 	for (include = ISC_LIST_HEAD(zone->newincludes);
   1174 	     include != NULL;
   1175 	     include = ISC_LIST_HEAD(zone->newincludes)) {
   1176 		ISC_LIST_UNLINK(zone->newincludes, include, link);
   1177 		isc_mem_free(zone->mctx, include->name);
   1178 		isc_mem_put(zone->mctx, include, sizeof *include);
   1179 	}
   1180 	if (zone->masterfile != NULL) {
   1181 		isc_mem_free(zone->mctx, zone->masterfile);
   1182 	}
   1183 	zone->masterfile = NULL;
   1184 	if (zone->keydirectory != NULL) {
   1185 		isc_mem_free(zone->mctx, zone->keydirectory);
   1186 	}
   1187 	zone->keydirectory = NULL;
   1188 	zone->journalsize = -1;
   1189 	if (zone->journal != NULL) {
   1190 		isc_mem_free(zone->mctx, zone->journal);
   1191 	}
   1192 	zone->journal = NULL;
   1193 	if (zone->stats != NULL) {
   1194 		isc_stats_detach(&zone->stats);
   1195 	}
   1196 	if (zone->requeststats != NULL) {
   1197 		isc_stats_detach(&zone->requeststats);
   1198 	}
   1199 	if (zone->rcvquerystats != NULL){
   1200 		dns_stats_detach(&zone->rcvquerystats);
   1201 	}
   1202 	if (zone->db != NULL) {
   1203 		zone_detachdb(zone);
   1204 	}
   1205 	if (zone->rpzs != NULL) {
   1206 		REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
   1207 		dns_rpz_detach_rpzs(&zone->rpzs);
   1208 		zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1209 	}
   1210 	if (zone->catzs != NULL) {
   1211 		dns_catz_catzs_detach(&zone->catzs);
   1212 	}
   1213 	zone_freedbargs(zone);
   1214 	RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL,
   1215 						  NULL, 0) == ISC_R_SUCCESS);
   1216 	RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
   1217 	zone->check_names = dns_severity_ignore;
   1218 	if (zone->update_acl != NULL) {
   1219 		dns_acl_detach(&zone->update_acl);
   1220 	}
   1221 	if (zone->forward_acl != NULL) {
   1222 		dns_acl_detach(&zone->forward_acl);
   1223 	}
   1224 	if (zone->notify_acl != NULL) {
   1225 		dns_acl_detach(&zone->notify_acl);
   1226 	}
   1227 	if (zone->query_acl != NULL) {
   1228 		dns_acl_detach(&zone->query_acl);
   1229 	}
   1230 	if (zone->queryon_acl != NULL) {
   1231 		dns_acl_detach(&zone->queryon_acl);
   1232 	}
   1233 	if (zone->xfr_acl != NULL) {
   1234 		dns_acl_detach(&zone->xfr_acl);
   1235 	}
   1236 	if (dns_name_dynamic(&zone->origin)) {
   1237 		dns_name_free(&zone->origin, zone->mctx);
   1238 	}
   1239 	if (zone->strnamerd != NULL) {
   1240 		isc_mem_free(zone->mctx, zone->strnamerd);
   1241 	}
   1242 	if (zone->strname != NULL) {
   1243 		isc_mem_free(zone->mctx, zone->strname);
   1244 	}
   1245 	if (zone->strrdclass != NULL) {
   1246 		isc_mem_free(zone->mctx, zone->strrdclass);
   1247 	}
   1248 	if (zone->strviewname != NULL) {
   1249 		isc_mem_free(zone->mctx, zone->strviewname);
   1250 	}
   1251 	if (zone->ssutable != NULL) {
   1252 		dns_ssutable_detach(&zone->ssutable);
   1253 	}
   1254 	if (zone->gluecachestats != NULL) {
   1255 		isc_stats_detach(&zone->gluecachestats);
   1256 	}
   1257 
   1258 	/* last stuff */
   1259 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1260 	isc_mutex_destroy(&zone->lock);
   1261 	zone->magic = 0;
   1262 	mctx = zone->mctx;
   1263 	isc_mem_put(mctx, zone, sizeof(*zone));
   1264 	isc_mem_detach(&mctx);
   1265 }
   1266 
   1267 /*
   1268  * Returns true iff this the signed side of an inline-signing zone.
   1269  * Caller should hold zone lock.
   1270  */
   1271 static inline bool
   1272 inline_secure(dns_zone_t *zone) {
   1273 	REQUIRE(DNS_ZONE_VALID(zone));
   1274 	if (zone->raw != NULL)
   1275 		return (true);
   1276 	return (false);
   1277 }
   1278 
   1279 /*
   1280  * Returns true iff this the unsigned side of an inline-signing zone
   1281  * Caller should hold zone lock.
   1282  */
   1283 static inline bool
   1284 inline_raw(dns_zone_t *zone) {
   1285 	REQUIRE(DNS_ZONE_VALID(zone));
   1286 	if (zone->secure != NULL)
   1287 		return (true);
   1288 	return (false);
   1289 }
   1290 
   1291 /*
   1292  *	Single shot.
   1293  */
   1294 void
   1295 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
   1296 	char namebuf[1024];
   1297 
   1298 	REQUIRE(DNS_ZONE_VALID(zone));
   1299 	REQUIRE(rdclass != dns_rdataclass_none);
   1300 
   1301 	/*
   1302 	 * Test and set.
   1303 	 */
   1304 	LOCK_ZONE(zone);
   1305 	INSIST(zone != zone->raw);
   1306 	REQUIRE(zone->rdclass == dns_rdataclass_none ||
   1307 		zone->rdclass == rdclass);
   1308 	zone->rdclass = rdclass;
   1309 
   1310 	if (zone->strnamerd != NULL)
   1311 		isc_mem_free(zone->mctx, zone->strnamerd);
   1312 	if (zone->strrdclass != NULL)
   1313 		isc_mem_free(zone->mctx, zone->strrdclass);
   1314 
   1315 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1316 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1317 	zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
   1318 	zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
   1319 
   1320 	if (inline_secure(zone))
   1321 		dns_zone_setclass(zone->raw, rdclass);
   1322 	UNLOCK_ZONE(zone);
   1323 }
   1324 
   1325 dns_rdataclass_t
   1326 dns_zone_getclass(dns_zone_t *zone) {
   1327 	REQUIRE(DNS_ZONE_VALID(zone));
   1328 
   1329 	return (zone->rdclass);
   1330 }
   1331 
   1332 void
   1333 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
   1334 	REQUIRE(DNS_ZONE_VALID(zone));
   1335 
   1336 	LOCK_ZONE(zone);
   1337 	zone->notifytype = notifytype;
   1338 	UNLOCK_ZONE(zone);
   1339 }
   1340 
   1341 isc_result_t
   1342 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
   1343 	isc_result_t result;
   1344 	unsigned int soacount;
   1345 
   1346 	REQUIRE(DNS_ZONE_VALID(zone));
   1347 	REQUIRE(serialp != NULL);
   1348 
   1349 	LOCK_ZONE(zone);
   1350 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   1351 	if (zone->db != NULL) {
   1352 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
   1353 					  serialp, NULL, NULL, NULL, NULL,
   1354 					  NULL);
   1355 		if (result == ISC_R_SUCCESS && soacount == 0)
   1356 			result = ISC_R_FAILURE;
   1357 	} else
   1358 		result = DNS_R_NOTLOADED;
   1359 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   1360 	UNLOCK_ZONE(zone);
   1361 
   1362 	return (result);
   1363 }
   1364 
   1365 /*
   1366  *	Single shot.
   1367  */
   1368 void
   1369 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
   1370 	char namebuf[1024];
   1371 
   1372 	REQUIRE(DNS_ZONE_VALID(zone));
   1373 	REQUIRE(type != dns_zone_none);
   1374 
   1375 	/*
   1376 	 * Test and set.
   1377 	 */
   1378 	LOCK_ZONE(zone);
   1379 	REQUIRE(zone->type == dns_zone_none || zone->type == type);
   1380 	zone->type = type;
   1381 
   1382 	if (zone->strnamerd != NULL)
   1383 		isc_mem_free(zone->mctx, zone->strnamerd);
   1384 
   1385 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1386 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1387 	UNLOCK_ZONE(zone);
   1388 }
   1389 
   1390 static void
   1391 zone_freedbargs(dns_zone_t *zone) {
   1392 	unsigned int i;
   1393 
   1394 	/* Free the old database argument list. */
   1395 	if (zone->db_argv != NULL) {
   1396 		for (i = 0; i < zone->db_argc; i++)
   1397 			isc_mem_free(zone->mctx, zone->db_argv[i]);
   1398 		isc_mem_put(zone->mctx, zone->db_argv,
   1399 			    zone->db_argc * sizeof(*zone->db_argv));
   1400 	}
   1401 	zone->db_argc = 0;
   1402 	zone->db_argv = NULL;
   1403 }
   1404 
   1405 isc_result_t
   1406 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
   1407 	size_t size = 0;
   1408 	unsigned int i;
   1409 	isc_result_t result = ISC_R_SUCCESS;
   1410 	void *mem;
   1411 	char **tmp, *tmp2, *base;
   1412 
   1413 	REQUIRE(DNS_ZONE_VALID(zone));
   1414 	REQUIRE(argv != NULL && *argv == NULL);
   1415 
   1416 	LOCK_ZONE(zone);
   1417 	size = (zone->db_argc + 1) * sizeof(char *);
   1418 	for (i = 0; i < zone->db_argc; i++)
   1419 		size += strlen(zone->db_argv[i]) + 1;
   1420 	mem = isc_mem_allocate(mctx, size);
   1421 	if (mem != NULL) {
   1422 		tmp = mem;
   1423 		tmp2 = mem;
   1424 		base = mem;
   1425 		tmp2 += (zone->db_argc + 1) * sizeof(char *);
   1426 		for (i = 0; i < zone->db_argc; i++) {
   1427 			*tmp++ = tmp2;
   1428 			strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
   1429 			tmp2 += strlen(tmp2) + 1;
   1430 		}
   1431 		*tmp = NULL;
   1432 	} else
   1433 		result = ISC_R_NOMEMORY;
   1434 	UNLOCK_ZONE(zone);
   1435 	*argv = mem;
   1436 	return (result);
   1437 }
   1438 
   1439 isc_result_t
   1440 dns_zone_setdbtype(dns_zone_t *zone,
   1441 		   unsigned int dbargc, const char * const *dbargv)
   1442 {
   1443 	isc_result_t result = ISC_R_SUCCESS;
   1444 	char **argv = NULL;
   1445 	unsigned int i;
   1446 
   1447 	REQUIRE(DNS_ZONE_VALID(zone));
   1448 	REQUIRE(dbargc >= 1);
   1449 	REQUIRE(dbargv != NULL);
   1450 
   1451 	LOCK_ZONE(zone);
   1452 
   1453 	/* Set up a new database argument list. */
   1454 	argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv));
   1455 	if (argv == NULL) {
   1456 		goto nomem;
   1457 	}
   1458 	for (i = 0; i < dbargc; i++) {
   1459 		argv[i] = NULL;
   1460 	}
   1461 	for (i = 0; i < dbargc; i++) {
   1462 		argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
   1463 		if (argv[i] == NULL)
   1464 			goto nomem;
   1465 	}
   1466 
   1467 	/* Free the old list. */
   1468 	zone_freedbargs(zone);
   1469 
   1470 	zone->db_argc = dbargc;
   1471 	zone->db_argv = argv;
   1472 	result = ISC_R_SUCCESS;
   1473 	goto unlock;
   1474 
   1475  nomem:
   1476 	if (argv != NULL) {
   1477 		for (i = 0; i < dbargc; i++) {
   1478 			if (argv[i] != NULL) {
   1479 				isc_mem_free(zone->mctx, argv[i]);
   1480 			}
   1481 		}
   1482 		isc_mem_put(zone->mctx, argv, dbargc * sizeof(*argv));
   1483 	}
   1484 	result = ISC_R_NOMEMORY;
   1485 
   1486  unlock:
   1487 	UNLOCK_ZONE(zone);
   1488 	return (result);
   1489 }
   1490 
   1491 static void
   1492 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
   1493 	char namebuf[1024];
   1494 
   1495 	if (zone->prev_view == NULL && zone->view != NULL) {
   1496 		dns_view_weakattach(zone->view, &zone->prev_view);
   1497 	}
   1498 
   1499 	INSIST(zone != zone->raw);
   1500 	if (zone->view != NULL) {
   1501 		dns_view_weakdetach(&zone->view);
   1502 	}
   1503 	dns_view_weakattach(view, &zone->view);
   1504 
   1505 	if (zone->strviewname != NULL) {
   1506 		isc_mem_free(zone->mctx, zone->strviewname);
   1507 	}
   1508 	if (zone->strnamerd != NULL) {
   1509 		isc_mem_free(zone->mctx, zone->strnamerd);
   1510 	}
   1511 
   1512 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1513 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1514 	zone_viewname_tostr(zone, namebuf, sizeof namebuf);
   1515 	zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
   1516 
   1517 	if (inline_secure(zone)) {
   1518 		dns_zone_setview(zone->raw, view);
   1519 	}
   1520 }
   1521 
   1522 void
   1523 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
   1524 	REQUIRE(DNS_ZONE_VALID(zone));
   1525 
   1526 	LOCK_ZONE(zone);
   1527 	dns_zone_setview_helper(zone, view);
   1528 	UNLOCK_ZONE(zone);
   1529 }
   1530 
   1531 dns_view_t *
   1532 dns_zone_getview(dns_zone_t *zone) {
   1533 	REQUIRE(DNS_ZONE_VALID(zone));
   1534 
   1535 	return (zone->view);
   1536 }
   1537 
   1538 void
   1539 dns_zone_setviewcommit(dns_zone_t *zone) {
   1540 	REQUIRE(DNS_ZONE_VALID(zone));
   1541 
   1542 	LOCK_ZONE(zone);
   1543 	if (zone->prev_view != NULL)
   1544 		dns_view_weakdetach(&zone->prev_view);
   1545 	UNLOCK_ZONE(zone);
   1546 }
   1547 
   1548 void
   1549 dns_zone_setviewrevert(dns_zone_t *zone) {
   1550 	REQUIRE(DNS_ZONE_VALID(zone));
   1551 
   1552 	LOCK_ZONE(zone);
   1553 	if (zone->prev_view != NULL) {
   1554 		dns_zone_setview_helper(zone, zone->prev_view);
   1555 		dns_view_weakdetach(&zone->prev_view);
   1556 	}
   1557 	UNLOCK_ZONE(zone);
   1558 }
   1559 
   1560 isc_result_t
   1561 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
   1562 	isc_result_t result;
   1563 	char namebuf[1024];
   1564 
   1565 	REQUIRE(DNS_ZONE_VALID(zone));
   1566 	REQUIRE(origin != NULL);
   1567 
   1568 	LOCK_ZONE(zone);
   1569 	INSIST(zone != zone->raw);
   1570 	if (dns_name_dynamic(&zone->origin)) {
   1571 		dns_name_free(&zone->origin, zone->mctx);
   1572 		dns_name_init(&zone->origin, NULL);
   1573 	}
   1574 	result = dns_name_dup(origin, zone->mctx, &zone->origin);
   1575 
   1576 	if (zone->strnamerd != NULL)
   1577 		isc_mem_free(zone->mctx, zone->strnamerd);
   1578 	if (zone->strname != NULL)
   1579 		isc_mem_free(zone->mctx, zone->strname);
   1580 
   1581 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1582 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1583 	zone_name_tostr(zone, namebuf, sizeof namebuf);
   1584 	zone->strname = isc_mem_strdup(zone->mctx, namebuf);
   1585 
   1586 	if (result == ISC_R_SUCCESS && inline_secure(zone))
   1587 		result = dns_zone_setorigin(zone->raw, origin);
   1588 	UNLOCK_ZONE(zone);
   1589 	return (result);
   1590 }
   1591 
   1592 static isc_result_t
   1593 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
   1594 	char *copy;
   1595 
   1596 	if (value != NULL) {
   1597 		copy = isc_mem_strdup(zone->mctx, value);
   1598 		if (copy == NULL)
   1599 			return (ISC_R_NOMEMORY);
   1600 	} else {
   1601 		copy = NULL;
   1602 	}
   1603 
   1604 	if (*field != NULL)
   1605 		isc_mem_free(zone->mctx, *field);
   1606 
   1607 	*field = copy;
   1608 	return (ISC_R_SUCCESS);
   1609 }
   1610 
   1611 isc_result_t
   1612 dns_zone_setfile(dns_zone_t *zone, const char *file,
   1613 		 dns_masterformat_t format,
   1614 		 const dns_master_style_t *style)
   1615 {
   1616 	isc_result_t result = ISC_R_SUCCESS;
   1617 
   1618 	REQUIRE(DNS_ZONE_VALID(zone));
   1619 
   1620 	LOCK_ZONE(zone);
   1621 	result = dns_zone_setstring(zone, &zone->masterfile, file);
   1622 	if (result == ISC_R_SUCCESS) {
   1623 		zone->masterformat = format;
   1624 		if (format == dns_masterformat_text)
   1625 			zone->masterstyle = style;
   1626 		result = default_journal(zone);
   1627 	}
   1628 	UNLOCK_ZONE(zone);
   1629 
   1630 	return (result);
   1631 }
   1632 
   1633 const char *
   1634 dns_zone_getfile(dns_zone_t *zone) {
   1635 	REQUIRE(DNS_ZONE_VALID(zone));
   1636 
   1637 	return (zone->masterfile);
   1638 }
   1639 
   1640 dns_ttl_t
   1641 dns_zone_getmaxttl(dns_zone_t *zone) {
   1642 	REQUIRE(DNS_ZONE_VALID(zone));
   1643 
   1644 	return (zone->maxttl);
   1645 }
   1646 
   1647 void
   1648 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
   1649 	REQUIRE(DNS_ZONE_VALID(zone));
   1650 
   1651 	LOCK_ZONE(zone);
   1652 	if (maxttl != 0)
   1653 		zone->options |= DNS_ZONEOPT_CHECKTTL;
   1654 	else
   1655 		zone->options &= ~DNS_ZONEOPT_CHECKTTL;
   1656 	zone->maxttl = maxttl;
   1657 	UNLOCK_ZONE(zone);
   1658 
   1659 	return;
   1660 }
   1661 
   1662 static isc_result_t
   1663 default_journal(dns_zone_t *zone) {
   1664 	isc_result_t result;
   1665 	char *journal;
   1666 
   1667 	REQUIRE(DNS_ZONE_VALID(zone));
   1668 	REQUIRE(LOCKED_ZONE(zone));
   1669 
   1670 	if (zone->masterfile != NULL) {
   1671 		/* Calculate string length including '\0'. */
   1672 		int len = strlen(zone->masterfile) + sizeof(".jnl");
   1673 		journal = isc_mem_allocate(zone->mctx, len);
   1674 		if (journal == NULL)
   1675 			return (ISC_R_NOMEMORY);
   1676 		strlcpy(journal, zone->masterfile, len);
   1677 		strlcat(journal, ".jnl", len);
   1678 	} else {
   1679 		journal = NULL;
   1680 	}
   1681 	result = dns_zone_setstring(zone, &zone->journal, journal);
   1682 	if (journal != NULL)
   1683 		isc_mem_free(zone->mctx, journal);
   1684 	return (result);
   1685 }
   1686 
   1687 isc_result_t
   1688 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
   1689 	isc_result_t result = ISC_R_SUCCESS;
   1690 
   1691 	REQUIRE(DNS_ZONE_VALID(zone));
   1692 
   1693 	LOCK_ZONE(zone);
   1694 	result = dns_zone_setstring(zone, &zone->journal, myjournal);
   1695 	UNLOCK_ZONE(zone);
   1696 
   1697 	return (result);
   1698 }
   1699 
   1700 char *
   1701 dns_zone_getjournal(dns_zone_t *zone) {
   1702 	REQUIRE(DNS_ZONE_VALID(zone));
   1703 
   1704 	return (zone->journal);
   1705 }
   1706 
   1707 /*
   1708  * Return true iff the zone is "dynamic", in the sense that the zone's
   1709  * master file (if any) is written by the server, rather than being
   1710  * updated manually and read by the server.
   1711  *
   1712  * This is true for slave zones, mirror zones, stub zones, key zones,
   1713  * and zones that allow dynamic updates either by having an update
   1714  * policy ("ssutable") or an "allow-update" ACL with a value other than
   1715  * exactly "{ none; }".
   1716  */
   1717 bool
   1718 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
   1719 	REQUIRE(DNS_ZONE_VALID(zone));
   1720 
   1721 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   1722 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   1723 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   1724 		return (true);
   1725 
   1726 	/* Inline zones are always dynamic. */
   1727 	if (zone->type == dns_zone_master && zone->raw != NULL)
   1728 		return (true);
   1729 
   1730 	/* If !ignore_freeze, we need check whether updates are disabled.  */
   1731 	if (zone->type == dns_zone_master &&
   1732 	    (!zone->update_disabled || ignore_freeze) &&
   1733 	    ((zone->ssutable != NULL) ||
   1734 	     (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
   1735 		return (true);
   1736 
   1737 	return (false);
   1738 
   1739 }
   1740 
   1741 /*
   1742  * Set the response policy index and information for a zone.
   1743  */
   1744 isc_result_t
   1745 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
   1746 		    dns_rpz_num_t rpz_num)
   1747 {
   1748 	/*
   1749 	 * Only RBTDB zones can be used for response policy zones,
   1750 	 * because only they have the code to load the create the summary data.
   1751 	 * Only zones that are loaded instead of mmap()ed create the
   1752 	 * summary data and so can be policy zones.
   1753 	 */
   1754 	if (strcmp(zone->db_argv[0], "rbt") != 0 &&
   1755 	    strcmp(zone->db_argv[0], "rbt64") != 0)
   1756 		return (ISC_R_NOTIMPLEMENTED);
   1757 	if (zone->masterformat == dns_masterformat_map)
   1758 		return (ISC_R_NOTIMPLEMENTED);
   1759 
   1760 	/*
   1761 	 * This must happen only once or be redundant.
   1762 	 */
   1763 	LOCK_ZONE(zone);
   1764 	if (zone->rpzs != NULL) {
   1765 		REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
   1766 	} else {
   1767 		REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
   1768 		dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
   1769 		zone->rpz_num = rpz_num;
   1770 	}
   1771 	rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
   1772 	UNLOCK_ZONE(zone);
   1773 
   1774 	return (ISC_R_SUCCESS);
   1775 }
   1776 
   1777 dns_rpz_num_t
   1778 dns_zone_get_rpz_num(dns_zone_t *zone) {
   1779 	return (zone->rpz_num);
   1780 }
   1781 
   1782 /*
   1783  * If a zone is a response policy zone, mark its new database.
   1784  */
   1785 void
   1786 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1787 	isc_result_t result;
   1788 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM)
   1789 		return;
   1790 	REQUIRE(zone->rpzs != NULL);
   1791 	zone->rpzs->zones[zone->rpz_num]->db_registered = true;
   1792 	result = dns_db_updatenotify_register(db,
   1793 					      dns_rpz_dbupdate_callback,
   1794 					      zone->rpzs->zones[zone->rpz_num]);
   1795 	REQUIRE(result == ISC_R_SUCCESS);
   1796 }
   1797 
   1798 void
   1799 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
   1800 	REQUIRE(DNS_ZONE_VALID(zone));
   1801 	REQUIRE(catzs != NULL);
   1802 
   1803 	LOCK_ZONE(zone);
   1804 	INSIST(zone->catzs == NULL || zone->catzs == catzs);
   1805 	dns_catz_catzs_set_view(catzs, zone->view);
   1806 	if (zone->catzs == NULL)
   1807 		dns_catz_catzs_attach(catzs, &zone->catzs);
   1808 	UNLOCK_ZONE(zone);
   1809 }
   1810 
   1811 /*
   1812  * If a zone is a catalog zone, attach it to update notification in database.
   1813  */
   1814 void
   1815 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1816 	REQUIRE(DNS_ZONE_VALID(zone));
   1817 	REQUIRE(db != NULL);
   1818 
   1819 	if (zone->catzs != NULL) {
   1820 		dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
   1821 					     zone->catzs);
   1822 	}
   1823 }
   1824 
   1825 /*
   1826  * Set catalog zone ownership of the zone
   1827  */
   1828 void
   1829 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) {
   1830 	REQUIRE(DNS_ZONE_VALID(zone));
   1831 	REQUIRE(catz != NULL);
   1832 	LOCK_ZONE(zone);
   1833 	INSIST(zone->parentcatz == NULL || zone->parentcatz == catz);
   1834 	zone->parentcatz = catz;
   1835 	UNLOCK_ZONE(zone);
   1836 }
   1837 
   1838 dns_catz_zone_t *
   1839 dns_zone_get_parentcatz(const dns_zone_t *zone) {
   1840 	REQUIRE(DNS_ZONE_VALID(zone));
   1841 	return (zone->parentcatz);
   1842 }
   1843 
   1844 
   1845 static bool
   1846 zone_touched(dns_zone_t *zone) {
   1847 	isc_result_t result;
   1848 	isc_time_t modtime;
   1849 	dns_include_t *include;
   1850 
   1851 	REQUIRE(DNS_ZONE_VALID(zone));
   1852 
   1853 	result = isc_file_getmodtime(zone->masterfile, &modtime);
   1854 	if (result != ISC_R_SUCCESS ||
   1855 	    isc_time_compare(&modtime, &zone->loadtime) > 0)
   1856 		return (true);
   1857 
   1858 	for (include = ISC_LIST_HEAD(zone->includes);
   1859 	     include != NULL;
   1860 	     include = ISC_LIST_NEXT(include, link))
   1861 	{
   1862 		result = isc_file_getmodtime(include->name, &modtime);
   1863 		if (result != ISC_R_SUCCESS ||
   1864 		    isc_time_compare(&modtime, &include->filetime) > 0)
   1865 			return (true);
   1866 	}
   1867 
   1868 	return (false);
   1869 }
   1870 
   1871 /*
   1872  * Note: when dealing with inline-signed zones, external callers will always
   1873  * call zone_load() for the secure zone; zone_load() calls itself recursively
   1874  * in order to load the raw zone.
   1875  */
   1876 static isc_result_t
   1877 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
   1878 	isc_result_t result;
   1879 	isc_time_t now;
   1880 	isc_time_t loadtime;
   1881 	dns_db_t *db = NULL;
   1882 	bool rbt, hasraw;
   1883 
   1884 	REQUIRE(DNS_ZONE_VALID(zone));
   1885 
   1886 	if (!locked)
   1887 		LOCK_ZONE(zone);
   1888 
   1889 	INSIST(zone != zone->raw);
   1890 	hasraw = inline_secure(zone);
   1891 	if (hasraw) {
   1892 		/*
   1893 		 * We are trying to load an inline-signed zone.  First call
   1894 		 * self recursively to try loading the raw version of the zone.
   1895 		 * Assuming the raw zone file is readable, there are two
   1896 		 * possibilities:
   1897 		 *
   1898 		 *  a) the raw zone was not yet loaded and thus it will be
   1899 		 *     loaded now, synchronously; if this succeeds, a
   1900 		 *     subsequent attempt to load the signed zone file will
   1901 		 *     take place and thus zone_postload() will be called
   1902 		 *     twice: first for the raw zone and then for the secure
   1903 		 *     zone; the latter call will take care of syncing the raw
   1904 		 *     version with the secure version,
   1905 		 *
   1906 		 *  b) the raw zone was already loaded and we are trying to
   1907 		 *     reload it, which will happen asynchronously; this means
   1908 		 *     zone_postload() will only be called for the raw zone
   1909 		 *     because "result" returned by the zone_load() call below
   1910 		 *     will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE;
   1911 		 *     zone_postload() called for the raw zone will take care
   1912 		 *     of syncing the raw version with the secure version.
   1913 		 */
   1914 		result = zone_load(zone->raw, flags, false);
   1915 		if (result != ISC_R_SUCCESS) {
   1916 			if (!locked)
   1917 				UNLOCK_ZONE(zone);
   1918 			return(result);
   1919 		}
   1920 		LOCK_ZONE(zone->raw);
   1921 	}
   1922 
   1923 	TIME_NOW(&now);
   1924 
   1925 	INSIST(zone->type != dns_zone_none);
   1926 
   1927 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
   1928 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
   1929 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   1930 		result = DNS_R_CONTINUE;
   1931 		goto cleanup;
   1932 	}
   1933 
   1934 	INSIST(zone->db_argc >= 1);
   1935 
   1936 	rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
   1937 	      strcmp(zone->db_argv[0], "rbt64") == 0;
   1938 
   1939 	if (zone->db != NULL && zone->masterfile == NULL && rbt) {
   1940 		/*
   1941 		 * The zone has no master file configured.
   1942 		 */
   1943 		result = ISC_R_SUCCESS;
   1944 		goto cleanup;
   1945 	}
   1946 
   1947 	if (zone->db != NULL && dns_zone_isdynamic(zone, false)) {
   1948 		/*
   1949 		 * This is a slave, stub, or dynamically updated
   1950 		 * zone being reloaded.  Do nothing - the database
   1951 		 * we already have is guaranteed to be up-to-date.
   1952 		 */
   1953 		if (zone->type == dns_zone_master && !hasraw)
   1954 			result = DNS_R_DYNAMIC;
   1955 		else
   1956 			result = ISC_R_SUCCESS;
   1957 		goto cleanup;
   1958 	}
   1959 
   1960 	/*
   1961 	 * Store the current time before the zone is loaded, so that if the
   1962 	 * file changes between the time of the load and the time that
   1963 	 * zone->loadtime is set, then the file will still be reloaded
   1964 	 * the next time dns_zone_load is called.
   1965 	 */
   1966 	TIME_NOW(&loadtime);
   1967 
   1968 	/*
   1969 	 * Don't do the load if the file that stores the zone is older
   1970 	 * than the last time the zone was loaded.  If the zone has not
   1971 	 * been loaded yet, zone->loadtime will be the epoch.
   1972 	 */
   1973 	if (zone->masterfile != NULL) {
   1974 		isc_time_t filetime;
   1975 
   1976 		/*
   1977 		 * The file is already loaded.	If we are just doing a
   1978 		 * "rndc reconfig", we are done.
   1979 		 */
   1980 		if (!isc_time_isepoch(&zone->loadtime) &&
   1981 		    (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
   1982 			result = ISC_R_SUCCESS;
   1983 			goto cleanup;
   1984 		}
   1985 
   1986 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   1987 		    !zone_touched(zone))
   1988 		{
   1989 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   1990 				      ISC_LOG_DEBUG(1),
   1991 				      "skipping load: master file "
   1992 				      "older than last load");
   1993 			result = DNS_R_UPTODATE;
   1994 			goto cleanup;
   1995 		}
   1996 
   1997 		/*
   1998 		 * If the file modification time is in the past
   1999 		 * set loadtime to that value.
   2000 		 */
   2001 		result = isc_file_getmodtime(zone->masterfile, &filetime);
   2002 		if (result == ISC_R_SUCCESS &&
   2003 		    isc_time_compare(&loadtime, &filetime) > 0)
   2004 			loadtime = filetime;
   2005 	}
   2006 
   2007 	/*
   2008 	 * Built in zones (with the exception of empty zones) don't need
   2009 	 * to be reloaded.
   2010 	 */
   2011 	if (zone->type == dns_zone_master &&
   2012 	    strcmp(zone->db_argv[0], "_builtin") == 0 &&
   2013 	    (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
   2014 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   2015 		result = ISC_R_SUCCESS;
   2016 		goto cleanup;
   2017 	}
   2018 
   2019 	/*
   2020 	 * Zones associated with a DLZ don't need to be loaded either,
   2021 	 * but we need to associate the database with the zone object.
   2022 	 */
   2023 	if (strcmp(zone->db_argv[0], "dlz") == 0) {
   2024 		dns_dlzdb_t *dlzdb;
   2025 		dns_dlzfindzone_t findzone;
   2026 
   2027 		for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
   2028 		     dlzdb != NULL;
   2029 		     dlzdb = ISC_LIST_NEXT(dlzdb, link))
   2030 		{
   2031 			INSIST(DNS_DLZ_VALID(dlzdb));
   2032 			if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0)
   2033 				break;
   2034 		}
   2035 
   2036 		if (dlzdb == NULL) {
   2037 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2038 				      ISC_LOG_ERROR,
   2039 				      "DLZ %s does not exist or is set "
   2040 				      "to 'search yes;'", zone->db_argv[1]);
   2041 			result = ISC_R_NOTFOUND;
   2042 			goto cleanup;
   2043 		}
   2044 
   2045 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   2046 		/* ask SDLZ driver if the zone is supported */
   2047 		findzone = dlzdb->implementation->methods->findzone;
   2048 		result = (*findzone)(dlzdb->implementation->driverarg,
   2049 				     dlzdb->dbdata, dlzdb->mctx,
   2050 				     zone->view->rdclass, &zone->origin,
   2051 				     NULL, NULL, &db);
   2052 		if (result != ISC_R_NOTFOUND) {
   2053 			if (zone->db != NULL)
   2054 				zone_detachdb(zone);
   2055 			zone_attachdb(zone, db);
   2056 			dns_db_detach(&db);
   2057 			result = ISC_R_SUCCESS;
   2058 		}
   2059 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   2060 
   2061 		if (result == ISC_R_SUCCESS) {
   2062 			if (dlzdb->configure_callback == NULL)
   2063 				goto cleanup;
   2064 
   2065 			result = (*dlzdb->configure_callback)(zone->view,
   2066 							      dlzdb, zone);
   2067 			if (result != ISC_R_SUCCESS)
   2068 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2069 					      ISC_LOG_ERROR,
   2070 					      "DLZ configuration callback: %s",
   2071 					      isc_result_totext(result));
   2072 		}
   2073 		goto cleanup;
   2074 	}
   2075 
   2076 	if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   2077 	     zone->type == dns_zone_stub ||
   2078 	     (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
   2079 	    rbt) {
   2080 		if (zone->masterfile == NULL ||
   2081 		    !isc_file_exists(zone->masterfile)) {
   2082 			if (zone->masterfile != NULL) {
   2083 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2084 					      ISC_LOG_DEBUG(1),
   2085 					     "no master file");
   2086 			}
   2087 			zone->refreshtime = now;
   2088 			if (zone->task != NULL)
   2089 				zone_settimer(zone, &now);
   2090 			result = ISC_R_SUCCESS;
   2091 			goto cleanup;
   2092 		}
   2093 	}
   2094 
   2095 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2096 		      ISC_LOG_DEBUG(1), "starting load");
   2097 
   2098 	result = dns_db_create(zone->mctx, zone->db_argv[0],
   2099 			       &zone->origin, (zone->type == dns_zone_stub) ?
   2100 			       dns_dbtype_stub : dns_dbtype_zone,
   2101 			       zone->rdclass,
   2102 			       zone->db_argc - 1, zone->db_argv + 1,
   2103 			       &db);
   2104 
   2105 	if (result != ISC_R_SUCCESS) {
   2106 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   2107 			     "loading zone: creating database: %s",
   2108 			     isc_result_totext(result));
   2109 		goto cleanup;
   2110 	}
   2111 	dns_db_settask(db, zone->task);
   2112 
   2113 	if (zone->type == dns_zone_master || zone->type == dns_zone_slave ||
   2114 	    zone->type == dns_zone_mirror)
   2115 	{
   2116 		result = dns_db_setgluecachestats(db, zone->gluecachestats);
   2117 		if (result == ISC_R_NOTIMPLEMENTED) {
   2118 			result = ISC_R_SUCCESS;
   2119 		}
   2120 		if (result != ISC_R_SUCCESS) {
   2121 			goto cleanup;
   2122 		}
   2123 	}
   2124 
   2125 	if (! dns_db_ispersistent(db)) {
   2126 		if (zone->masterfile != NULL) {
   2127 			result = zone_startload(db, zone, loadtime);
   2128 		} else {
   2129 			result = DNS_R_NOMASTERFILE;
   2130 			if (zone->type == dns_zone_master ||
   2131 			    (zone->type == dns_zone_redirect &&
   2132 			     zone->masters == NULL)) {
   2133 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2134 					      ISC_LOG_ERROR,
   2135 					     "loading zone: "
   2136 					     "no master file configured");
   2137 				goto cleanup;
   2138 			}
   2139 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2140 				      ISC_LOG_INFO, "loading zone: "
   2141 				      "no master file configured: continuing");
   2142 		}
   2143 	}
   2144 
   2145 	if (result == DNS_R_CONTINUE) {
   2146 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
   2147 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
   2148 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2149 		goto cleanup;
   2150 	}
   2151 
   2152 	result = zone_postload(zone, db, loadtime, result);
   2153 
   2154  cleanup:
   2155 	if (hasraw)
   2156 		UNLOCK_ZONE(zone->raw);
   2157 	if (!locked)
   2158 		UNLOCK_ZONE(zone);
   2159 	if (db != NULL)
   2160 		dns_db_detach(&db);
   2161 	return (result);
   2162 }
   2163 
   2164 isc_result_t
   2165 dns_zone_load(dns_zone_t *zone, bool newonly) {
   2166 	return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
   2167 }
   2168 
   2169 static void
   2170 zone_asyncload(isc_task_t *task, isc_event_t *event) {
   2171 	dns_asyncload_t *asl = event->ev_arg;
   2172 	dns_zone_t *zone = asl->zone;
   2173 	isc_result_t result;
   2174 
   2175 	UNUSED(task);
   2176 
   2177 	REQUIRE(DNS_ZONE_VALID(zone));
   2178 
   2179 	isc_event_free(&event);
   2180 
   2181 	LOCK_ZONE(zone);
   2182 	result = zone_load(zone, asl->flags, true);
   2183 	if (result != DNS_R_CONTINUE) {
   2184 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2185 	}
   2186 	UNLOCK_ZONE(zone);
   2187 
   2188 	/* Inform the zone table we've finished loading */
   2189 	if (asl->loaded != NULL)
   2190 		(asl->loaded)(asl->loaded_arg, zone, task);
   2191 
   2192 	isc_mem_put(zone->mctx, asl, sizeof (*asl));
   2193 	dns_zone_idetach(&zone);
   2194 }
   2195 
   2196 isc_result_t
   2197 dns_zone_asyncload(dns_zone_t *zone, bool newonly,
   2198 		   dns_zt_zoneloaded_t done, void *arg)
   2199 {
   2200 	isc_event_t *e;
   2201 	dns_asyncload_t *asl = NULL;
   2202 	isc_result_t result = ISC_R_SUCCESS;
   2203 
   2204 	REQUIRE(DNS_ZONE_VALID(zone));
   2205 
   2206 	if (zone->zmgr == NULL)
   2207 		return (ISC_R_FAILURE);
   2208 
   2209 	/* If we already have a load pending, stop now */
   2210 	LOCK_ZONE(zone);
   2211 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) {
   2212 		UNLOCK_ZONE(zone);
   2213 		return (ISC_R_ALREADYRUNNING);
   2214 	}
   2215 
   2216 	asl = isc_mem_get(zone->mctx, sizeof (*asl));
   2217 	if (asl == NULL)
   2218 		CHECK(ISC_R_NOMEMORY);
   2219 
   2220 	asl->zone = NULL;
   2221 	asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
   2222 	asl->loaded = done;
   2223 	asl->loaded_arg = arg;
   2224 
   2225 	e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr,
   2226 			       DNS_EVENT_ZONELOAD,
   2227 			       zone_asyncload, asl,
   2228 			       sizeof(isc_event_t));
   2229 	if (e == NULL)
   2230 		CHECK(ISC_R_NOMEMORY);
   2231 
   2232 	zone_iattach(zone, &asl->zone);
   2233 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2234 	isc_task_send(zone->loadtask, &e);
   2235 	UNLOCK_ZONE(zone);
   2236 
   2237 	return (ISC_R_SUCCESS);
   2238 
   2239   failure:
   2240 	if (asl != NULL)
   2241 		isc_mem_put(zone->mctx, asl, sizeof (*asl));
   2242 	UNLOCK_ZONE(zone);
   2243 	return (result);
   2244 }
   2245 
   2246 bool
   2247 dns__zone_loadpending(dns_zone_t *zone) {
   2248 	REQUIRE(DNS_ZONE_VALID(zone));
   2249 
   2250 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
   2251 }
   2252 
   2253 isc_result_t
   2254 dns_zone_loadandthaw(dns_zone_t *zone) {
   2255 	isc_result_t result;
   2256 
   2257 	if (inline_raw(zone))
   2258 		result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW,
   2259 				   false);
   2260 	else
   2261 		result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false);
   2262 
   2263 	switch (result) {
   2264 	case DNS_R_CONTINUE:
   2265 		/* Deferred thaw. */
   2266 		break;
   2267 	case DNS_R_UPTODATE:
   2268 	case ISC_R_SUCCESS:
   2269 	case DNS_R_SEENINCLUDE:
   2270 		zone->update_disabled = false;
   2271 		break;
   2272 	case DNS_R_NOMASTERFILE:
   2273 		zone->update_disabled = false;
   2274 		break;
   2275 	default:
   2276 		/* Error, remain in disabled state. */
   2277 		break;
   2278 	}
   2279 	return (result);
   2280 }
   2281 
   2282 static unsigned int
   2283 get_master_options(dns_zone_t *zone) {
   2284 	unsigned int options;
   2285 
   2286 	options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
   2287 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   2288 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   2289 	{
   2290 		options |= DNS_MASTER_SLAVE;
   2291 	}
   2292 	if (zone->type == dns_zone_key) {
   2293 		options |= DNS_MASTER_KEY;
   2294 	}
   2295 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
   2296 		options |= DNS_MASTER_CHECKNS;
   2297 	}
   2298 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
   2299 		options |= DNS_MASTER_FATALNS;
   2300 	}
   2301 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
   2302 		options |= DNS_MASTER_CHECKNAMES;
   2303 	}
   2304 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
   2305 		options |= DNS_MASTER_CHECKNAMESFAIL;
   2306 	}
   2307 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
   2308 		options |= DNS_MASTER_CHECKMX;
   2309 	}
   2310 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2311 		options |= DNS_MASTER_CHECKMXFAIL;
   2312 	}
   2313 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
   2314 		options |= DNS_MASTER_CHECKWILDCARD;
   2315 	}
   2316 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
   2317 		options |= DNS_MASTER_CHECKTTL;
   2318 	}
   2319 
   2320 	return (options);
   2321 }
   2322 
   2323 static void
   2324 zone_registerinclude(const char *filename, void *arg) {
   2325 	isc_result_t result;
   2326 	dns_zone_t *zone = (dns_zone_t *) arg;
   2327 	dns_include_t *inc = NULL;
   2328 
   2329 	REQUIRE(DNS_ZONE_VALID(zone));
   2330 
   2331 	if (filename == NULL)
   2332 		return;
   2333 
   2334 	/*
   2335 	 * Suppress duplicates.
   2336 	 */
   2337 	for (inc = ISC_LIST_HEAD(zone->newincludes);
   2338 	     inc != NULL;
   2339 	     inc = ISC_LIST_NEXT(inc, link))
   2340 		if (strcmp(filename, inc->name) == 0)
   2341 			return;
   2342 
   2343 	inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
   2344 	if (inc == NULL)
   2345 		return;
   2346 	inc->name = isc_mem_strdup(zone->mctx, filename);
   2347 	if (inc->name == NULL) {
   2348 		isc_mem_put(zone->mctx, inc, sizeof(dns_include_t));
   2349 		return;
   2350 	}
   2351 	ISC_LINK_INIT(inc, link);
   2352 
   2353 	result = isc_file_getmodtime(filename, &inc->filetime);
   2354 	if (result != ISC_R_SUCCESS)
   2355 		isc_time_settoepoch(&inc->filetime);
   2356 
   2357 	ISC_LIST_APPEND(zone->newincludes, inc, link);
   2358 }
   2359 
   2360 static void
   2361 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
   2362 	dns_load_t *load = event->ev_arg;
   2363 	isc_result_t result = ISC_R_SUCCESS;
   2364 	unsigned int options;
   2365 
   2366 	REQUIRE(DNS_LOAD_VALID(load));
   2367 
   2368 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
   2369 		result = ISC_R_CANCELED;
   2370 	isc_event_free(&event);
   2371 	if (result == ISC_R_CANCELED)
   2372 		goto fail;
   2373 
   2374 	options = get_master_options(load->zone);
   2375 
   2376 	result = dns_master_loadfileinc(load->zone->masterfile,
   2377 					dns_db_origin(load->db),
   2378 					dns_db_origin(load->db),
   2379 					load->zone->rdclass, options, 0,
   2380 					&load->callbacks, task,
   2381 					zone_loaddone, load,
   2382 					&load->zone->lctx,
   2383 					zone_registerinclude,
   2384 					load->zone, load->zone->mctx,
   2385 					load->zone->masterformat,
   2386 					load->zone->maxttl);
   2387 	if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
   2388 	    result != DNS_R_SEENINCLUDE)
   2389 		goto fail;
   2390 	return;
   2391 
   2392  fail:
   2393 	zone_loaddone(load, result);
   2394 }
   2395 
   2396 static void
   2397 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
   2398 	isc_result_t result;
   2399 	unsigned int soacount;
   2400 
   2401 	LOCK(&raw->lock);
   2402 	if (raw->db != NULL) {
   2403 		result = zone_get_from_db(raw, raw->db, NULL, &soacount,
   2404 					  &rawdata->sourceserial,
   2405 					  NULL, NULL, NULL, NULL,
   2406 					  NULL);
   2407 		if (result == ISC_R_SUCCESS && soacount > 0U)
   2408 			rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
   2409 	}
   2410 	UNLOCK(&raw->lock);
   2411 }
   2412 
   2413 static void
   2414 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
   2415 	const char me[] = "zone_gotwritehandle";
   2416 	dns_zone_t *zone = event->ev_arg;
   2417 	isc_result_t result = ISC_R_SUCCESS;
   2418 	dns_dbversion_t *version = NULL;
   2419 	dns_masterrawheader_t rawdata;
   2420 
   2421 	REQUIRE(DNS_ZONE_VALID(zone));
   2422 	INSIST(task == zone->task);
   2423 	ENTER;
   2424 
   2425 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
   2426 		result = ISC_R_CANCELED;
   2427 	isc_event_free(&event);
   2428 	if (result == ISC_R_CANCELED)
   2429 		goto fail;
   2430 
   2431 	LOCK_ZONE(zone);
   2432 	INSIST(zone != zone->raw);
   2433 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   2434 	if (zone->db != NULL) {
   2435 		const dns_master_style_t *output_style;
   2436 
   2437 		dns_db_currentversion(zone->db, &version);
   2438 		dns_master_initrawheader(&rawdata);
   2439 		if (inline_secure(zone))
   2440 			get_raw_serial(zone->raw, &rawdata);
   2441 		if (zone->type == dns_zone_key)
   2442 			output_style = &dns_master_style_keyzone;
   2443 		else if (zone->masterstyle != NULL)
   2444 			output_style = zone->masterstyle;
   2445 		else
   2446 			output_style = &dns_master_style_default;
   2447 		result = dns_master_dumpinc(zone->mctx, zone->db, version,
   2448 					    output_style, zone->masterfile,
   2449 					    zone->task, dump_done, zone,
   2450 					    &zone->dctx, zone->masterformat,
   2451 					    &rawdata);
   2452 		dns_db_closeversion(zone->db, &version, false);
   2453 	} else
   2454 		result = ISC_R_CANCELED;
   2455 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   2456 	UNLOCK_ZONE(zone);
   2457 	if (result != DNS_R_CONTINUE)
   2458 		goto fail;
   2459 	return;
   2460 
   2461  fail:
   2462 	dump_done(zone, result);
   2463 }
   2464 
   2465 /*
   2466  * Save the raw serial number for inline-signing zones.
   2467  * (XXX: Other information from the header will be used
   2468  * for other purposes in the future, but for now this is
   2469  * all we're interested in.)
   2470  */
   2471 static void
   2472 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2473 	if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0)
   2474 		return;
   2475 
   2476 	zone->sourceserial = header->sourceserial;
   2477 	zone->sourceserialset = true;
   2478 }
   2479 
   2480 void
   2481 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2482 	if (zone == NULL)
   2483 		return;
   2484 
   2485 	LOCK_ZONE(zone);
   2486 	zone_setrawdata(zone, header);
   2487 	UNLOCK_ZONE(zone);
   2488 }
   2489 
   2490 static isc_result_t
   2491 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
   2492 	dns_load_t *load;
   2493 	isc_result_t result;
   2494 	isc_result_t tresult;
   2495 	unsigned int options;
   2496 
   2497 	dns_zone_rpz_enable_db(zone, db);
   2498 	dns_zone_catz_enable_db(zone, db);
   2499 	options = get_master_options(zone);
   2500 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
   2501 		options |= DNS_MASTER_MANYERRORS;
   2502 
   2503 	if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
   2504 		load = isc_mem_get(zone->mctx, sizeof(*load));
   2505 		if (load == NULL)
   2506 			return (ISC_R_NOMEMORY);
   2507 
   2508 		load->mctx = NULL;
   2509 		load->zone = NULL;
   2510 		load->db = NULL;
   2511 		load->loadtime = loadtime;
   2512 		load->magic = LOAD_MAGIC;
   2513 
   2514 		isc_mem_attach(zone->mctx, &load->mctx);
   2515 		zone_iattach(zone, &load->zone);
   2516 		dns_db_attach(db, &load->db);
   2517 		dns_rdatacallbacks_init(&load->callbacks);
   2518 		load->callbacks.rawdata = zone_setrawdata;
   2519 		zone_iattach(zone, &load->callbacks.zone);
   2520 		result = dns_db_beginload(db, &load->callbacks);
   2521 		if (result != ISC_R_SUCCESS)
   2522 			goto cleanup;
   2523 		result = zonemgr_getio(zone->zmgr, true, zone->loadtask,
   2524 				       zone_gotreadhandle, load,
   2525 				       &zone->readio);
   2526 		if (result != ISC_R_SUCCESS) {
   2527 			/*
   2528 			 * We can't report multiple errors so ignore
   2529 			 * the result of dns_db_endload().
   2530 			 */
   2531 			(void)dns_db_endload(load->db, &load->callbacks);
   2532 			goto cleanup;
   2533 		} else
   2534 			result = DNS_R_CONTINUE;
   2535 	} else {
   2536 		dns_rdatacallbacks_t callbacks;
   2537 
   2538 		dns_rdatacallbacks_init(&callbacks);
   2539 		callbacks.rawdata = zone_setrawdata;
   2540 		zone_iattach(zone, &callbacks.zone);
   2541 		result = dns_db_beginload(db, &callbacks);
   2542 		if (result != ISC_R_SUCCESS) {
   2543 			zone_idetach(&callbacks.zone);
   2544 			return (result);
   2545 		}
   2546 		result = dns_master_loadfile(zone->masterfile,
   2547 					     &zone->origin, &zone->origin,
   2548 					     zone->rdclass, options, 0,
   2549 					     &callbacks,
   2550 					     zone_registerinclude,
   2551 					     zone, zone->mctx,
   2552 					     zone->masterformat,
   2553 					     zone->maxttl);
   2554 		tresult = dns_db_endload(db, &callbacks);
   2555 		if (result == ISC_R_SUCCESS)
   2556 			result = tresult;
   2557 		zone_idetach(&callbacks.zone);
   2558 	}
   2559 
   2560 	return (result);
   2561 
   2562  cleanup:
   2563 	load->magic = 0;
   2564 	dns_db_detach(&load->db);
   2565 	zone_idetach(&load->zone);
   2566 	zone_idetach(&load->callbacks.zone);
   2567 	isc_mem_detach(&load->mctx);
   2568 	isc_mem_put(zone->mctx, load, sizeof(*load));
   2569 	return (result);
   2570 }
   2571 
   2572 static bool
   2573 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2574 	      dns_name_t *owner)
   2575 {
   2576 	isc_result_t result;
   2577 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2578 	char namebuf[DNS_NAME_FORMATSIZE];
   2579 	char altbuf[DNS_NAME_FORMATSIZE];
   2580 	dns_fixedname_t fixed;
   2581 	dns_name_t *foundname;
   2582 	int level;
   2583 
   2584 	/*
   2585 	 * "." means the services does not exist.
   2586 	 */
   2587 	if (dns_name_equal(name, dns_rootname))
   2588 		return (true);
   2589 
   2590 	/*
   2591 	 * Outside of zone.
   2592 	 */
   2593 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2594 		if (zone->checkmx != NULL)
   2595 			return ((zone->checkmx)(zone, name, owner));
   2596 		return (true);
   2597 	}
   2598 
   2599 	if (zone->type == dns_zone_master)
   2600 		level = ISC_LOG_ERROR;
   2601 	else
   2602 		level = ISC_LOG_WARNING;
   2603 
   2604 	foundname = dns_fixedname_initname(&fixed);
   2605 
   2606 	result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   2607 			     0, 0, NULL, foundname, NULL, NULL);
   2608 	if (result == ISC_R_SUCCESS)
   2609 		return (true);
   2610 
   2611 	if (result == DNS_R_NXRRSET) {
   2612 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
   2613 				     0, 0, NULL, foundname, NULL, NULL);
   2614 		if (result == ISC_R_SUCCESS)
   2615 			return (true);
   2616 	}
   2617 
   2618 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2619 	dns_name_format(name, namebuf, sizeof namebuf);
   2620 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2621 	    result == DNS_R_EMPTYNAME) {
   2622 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
   2623 			level = ISC_LOG_WARNING;
   2624 		dns_zone_log(zone, level,
   2625 			     "%s/MX '%s' has no address records (A or AAAA)",
   2626 			     ownerbuf, namebuf);
   2627 		return ((level == ISC_LOG_WARNING) ? true : false);
   2628 	}
   2629 
   2630 	if (result == DNS_R_CNAME) {
   2631 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2632 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2633 			level = ISC_LOG_WARNING;
   2634 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2635 			dns_zone_log(zone, level,
   2636 				     "%s/MX '%s' is a CNAME (illegal)",
   2637 				     ownerbuf, namebuf);
   2638 		return ((level == ISC_LOG_WARNING) ? true : false);
   2639 	}
   2640 
   2641 	if (result == DNS_R_DNAME) {
   2642 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2643 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2644 			level = ISC_LOG_WARNING;
   2645 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2646 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2647 			dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
   2648 				     " '%s' (illegal)", ownerbuf, namebuf,
   2649 				     altbuf);
   2650 		}
   2651 		return ((level == ISC_LOG_WARNING) ? true : false);
   2652 	}
   2653 
   2654 	if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
   2655 		return ((zone->checkmx)(zone, name, owner));
   2656 
   2657 	return (true);
   2658 }
   2659 
   2660 static bool
   2661 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2662 	       dns_name_t *owner)
   2663 {
   2664 	isc_result_t result;
   2665 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2666 	char namebuf[DNS_NAME_FORMATSIZE];
   2667 	char altbuf[DNS_NAME_FORMATSIZE];
   2668 	dns_fixedname_t fixed;
   2669 	dns_name_t *foundname;
   2670 	int level;
   2671 
   2672 	/*
   2673 	 * "." means the services does not exist.
   2674 	 */
   2675 	if (dns_name_equal(name, dns_rootname))
   2676 		return (true);
   2677 
   2678 	/*
   2679 	 * Outside of zone.
   2680 	 */
   2681 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2682 		if (zone->checksrv != NULL)
   2683 			return ((zone->checksrv)(zone, name, owner));
   2684 		return (true);
   2685 	}
   2686 
   2687 	if (zone->type == dns_zone_master)
   2688 		level = ISC_LOG_ERROR;
   2689 	else
   2690 		level = ISC_LOG_WARNING;
   2691 
   2692 	foundname = dns_fixedname_initname(&fixed);
   2693 
   2694 	result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   2695 			     0, 0, NULL, foundname, NULL, NULL);
   2696 	if (result == ISC_R_SUCCESS)
   2697 		return (true);
   2698 
   2699 	if (result == DNS_R_NXRRSET) {
   2700 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
   2701 				     0, 0, NULL, foundname, NULL, NULL);
   2702 		if (result == ISC_R_SUCCESS)
   2703 			return (true);
   2704 	}
   2705 
   2706 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2707 	dns_name_format(name, namebuf, sizeof namebuf);
   2708 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2709 	    result == DNS_R_EMPTYNAME) {
   2710 		dns_zone_log(zone, level,
   2711 			     "%s/SRV '%s' has no address records (A or AAAA)",
   2712 			     ownerbuf, namebuf);
   2713 		/* XXX950 make fatal for 9.5.0. */
   2714 		return (true);
   2715 	}
   2716 
   2717 	if (result == DNS_R_CNAME) {
   2718 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2719 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2720 			level = ISC_LOG_WARNING;
   2721 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2722 			dns_zone_log(zone, level,
   2723 				     "%s/SRV '%s' is a CNAME (illegal)",
   2724 				     ownerbuf, namebuf);
   2725 		return ((level == ISC_LOG_WARNING) ? true : false);
   2726 	}
   2727 
   2728 	if (result == DNS_R_DNAME) {
   2729 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2730 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2731 			level = ISC_LOG_WARNING;
   2732 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   2733 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2734 			dns_zone_log(zone, level, "%s/SRV '%s' is below a "
   2735 				     "DNAME '%s' (illegal)", ownerbuf, namebuf,
   2736 				     altbuf);
   2737 		}
   2738 		return ((level == ISC_LOG_WARNING) ? true : false);
   2739 	}
   2740 
   2741 	if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
   2742 		return ((zone->checksrv)(zone, name, owner));
   2743 
   2744 	return (true);
   2745 }
   2746 
   2747 static bool
   2748 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2749 		dns_name_t *owner)
   2750 {
   2751 	bool answer = true;
   2752 	isc_result_t result, tresult;
   2753 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2754 	char namebuf[DNS_NAME_FORMATSIZE];
   2755 	char altbuf[DNS_NAME_FORMATSIZE];
   2756 	dns_fixedname_t fixed;
   2757 	dns_name_t *foundname;
   2758 	dns_rdataset_t a;
   2759 	dns_rdataset_t aaaa;
   2760 	int level;
   2761 
   2762 	/*
   2763 	 * Outside of zone.
   2764 	 */
   2765 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2766 		if (zone->checkns != NULL)
   2767 			return ((zone->checkns)(zone, name, owner, NULL, NULL));
   2768 		return (true);
   2769 	}
   2770 
   2771 	if (zone->type == dns_zone_master)
   2772 		level = ISC_LOG_ERROR;
   2773 	else
   2774 		level = ISC_LOG_WARNING;
   2775 
   2776 	foundname = dns_fixedname_initname(&fixed);
   2777 	dns_rdataset_init(&a);
   2778 	dns_rdataset_init(&aaaa);
   2779 
   2780 	/*
   2781 	 * Perform a regular lookup to catch DNAME records then look
   2782 	 * for glue.
   2783 	 */
   2784 	result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   2785 			     0, 0, NULL, foundname, &a, NULL);
   2786 	switch (result) {
   2787 	case ISC_R_SUCCESS:
   2788 	case DNS_R_DNAME:
   2789 	case DNS_R_CNAME:
   2790 		break;
   2791 	default:
   2792 		if (dns_rdataset_isassociated(&a))
   2793 			dns_rdataset_disassociate(&a);
   2794 		result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   2795 				     DNS_DBFIND_GLUEOK, 0, NULL,
   2796 				     foundname, &a, NULL);
   2797 	}
   2798 	if (result == ISC_R_SUCCESS) {
   2799 		dns_rdataset_disassociate(&a);
   2800 		return (true);
   2801 	} else if (result == DNS_R_DELEGATION)
   2802 		dns_rdataset_disassociate(&a);
   2803 
   2804 	if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
   2805 	    result == DNS_R_GLUE) {
   2806 		tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
   2807 				     DNS_DBFIND_GLUEOK, 0, NULL,
   2808 				     foundname, &aaaa, NULL);
   2809 		if (tresult == ISC_R_SUCCESS) {
   2810 			if (dns_rdataset_isassociated(&a))
   2811 				dns_rdataset_disassociate(&a);
   2812 			dns_rdataset_disassociate(&aaaa);
   2813 			return (true);
   2814 		}
   2815 		if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME)
   2816 			dns_rdataset_disassociate(&aaaa);
   2817 		if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
   2818 			/*
   2819 			 * Check glue against child zone.
   2820 			 */
   2821 			if (zone->checkns != NULL)
   2822 				answer = (zone->checkns)(zone, name, owner,
   2823 							 &a, &aaaa);
   2824 			if (dns_rdataset_isassociated(&a))
   2825 				dns_rdataset_disassociate(&a);
   2826 			if (dns_rdataset_isassociated(&aaaa))
   2827 				dns_rdataset_disassociate(&aaaa);
   2828 			return (answer);
   2829 		}
   2830 	}
   2831 
   2832 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2833 	dns_name_format(name, namebuf, sizeof namebuf);
   2834 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2835 	    result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
   2836 		const char *what;
   2837 		bool required = false;
   2838 		if (dns_name_issubdomain(name, owner)) {
   2839 			what = "REQUIRED GLUE ";
   2840 			required = true;
   2841 		 } else if (result == DNS_R_DELEGATION)
   2842 			what = "SIBLING GLUE ";
   2843 		else
   2844 			what = "";
   2845 
   2846 		if (result != DNS_R_DELEGATION || required ||
   2847 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
   2848 			dns_zone_log(zone, level, "%s/NS '%s' has no %s"
   2849 				     "address records (A or AAAA)",
   2850 				     ownerbuf, namebuf, what);
   2851 			/*
   2852 			 * Log missing address record.
   2853 			 */
   2854 			if (result == DNS_R_DELEGATION && zone->checkns != NULL)
   2855 				(void)(zone->checkns)(zone, name, owner,
   2856 						      &a, &aaaa);
   2857 			/* XXX950 make fatal for 9.5.0. */
   2858 			/* answer = false; */
   2859 		}
   2860 	} else if (result == DNS_R_CNAME) {
   2861 		dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
   2862 			     ownerbuf, namebuf);
   2863 		/* XXX950 make fatal for 9.5.0. */
   2864 		/* answer = false; */
   2865 	} else if (result == DNS_R_DNAME) {
   2866 		dns_name_format(foundname, altbuf, sizeof altbuf);
   2867 		dns_zone_log(zone, level,
   2868 			     "%s/NS '%s' is below a DNAME '%s' (illegal)",
   2869 			     ownerbuf, namebuf, altbuf);
   2870 		/* XXX950 make fatal for 9.5.0. */
   2871 		/* answer = false; */
   2872 	}
   2873 
   2874 	if (dns_rdataset_isassociated(&a))
   2875 		dns_rdataset_disassociate(&a);
   2876 	if (dns_rdataset_isassociated(&aaaa))
   2877 		dns_rdataset_disassociate(&aaaa);
   2878 	return (answer);
   2879 }
   2880 
   2881 static bool
   2882 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
   2883 		     dns_rdataset_t *rdataset)
   2884 {
   2885 	dns_rdataset_t tmprdataset;
   2886 	isc_result_t result;
   2887 	bool answer = true;
   2888 	bool format = true;
   2889 	int level = ISC_LOG_WARNING;
   2890 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2891 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   2892 	unsigned int count1 = 0;
   2893 
   2894 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
   2895 		level = ISC_LOG_ERROR;
   2896 
   2897 	dns_rdataset_init(&tmprdataset);
   2898 	for (result = dns_rdataset_first(rdataset);
   2899 	     result == ISC_R_SUCCESS;
   2900 	     result = dns_rdataset_next(rdataset)) {
   2901 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   2902 		unsigned int count2 = 0;
   2903 
   2904 		count1++;
   2905 		dns_rdataset_current(rdataset, &rdata1);
   2906 		dns_rdataset_clone(rdataset, &tmprdataset);
   2907 		for (result = dns_rdataset_first(&tmprdataset);
   2908 		     result == ISC_R_SUCCESS;
   2909 		     result = dns_rdataset_next(&tmprdataset)) {
   2910 			dns_rdata_t rdata2 = DNS_RDATA_INIT;
   2911 			count2++;
   2912 			if (count1 >= count2)
   2913 				continue;
   2914 			dns_rdataset_current(&tmprdataset, &rdata2);
   2915 			if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
   2916 				if (format) {
   2917 					dns_name_format(owner, ownerbuf,
   2918 							sizeof ownerbuf);
   2919 					dns_rdatatype_format(rdata1.type,
   2920 							     typebuf,
   2921 							     sizeof(typebuf));
   2922 					format = false;
   2923 				}
   2924 				dns_zone_log(zone, level, "%s/%s has "
   2925 					     "semantically identical records",
   2926 					     ownerbuf, typebuf);
   2927 				if (level == ISC_LOG_ERROR)
   2928 					answer = false;
   2929 				break;
   2930 			}
   2931 		}
   2932 		dns_rdataset_disassociate(&tmprdataset);
   2933 		if (!format)
   2934 			break;
   2935 	}
   2936 	return (answer);
   2937 }
   2938 
   2939 static bool
   2940 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
   2941 	dns_dbiterator_t *dbiterator = NULL;
   2942 	dns_dbnode_t *node = NULL;
   2943 	dns_fixedname_t fixed;
   2944 	dns_name_t *name;
   2945 	dns_rdataset_t rdataset;
   2946 	dns_rdatasetiter_t *rdsit = NULL;
   2947 	bool ok = true;
   2948 	isc_result_t result;
   2949 
   2950 	name = dns_fixedname_initname(&fixed);
   2951 	dns_rdataset_init(&rdataset);
   2952 
   2953 	result = dns_db_createiterator(db, 0, &dbiterator);
   2954 	if (result != ISC_R_SUCCESS)
   2955 		return (true);
   2956 
   2957 	for (result = dns_dbiterator_first(dbiterator);
   2958 	     result == ISC_R_SUCCESS;
   2959 	     result = dns_dbiterator_next(dbiterator)) {
   2960 		result = dns_dbiterator_current(dbiterator, &node, name);
   2961 		if (result != ISC_R_SUCCESS)
   2962 			continue;
   2963 
   2964 		result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
   2965 		if (result != ISC_R_SUCCESS)
   2966 			continue;
   2967 
   2968 		for (result = dns_rdatasetiter_first(rdsit);
   2969 		     result == ISC_R_SUCCESS;
   2970 		     result = dns_rdatasetiter_next(rdsit)) {
   2971 			dns_rdatasetiter_current(rdsit, &rdataset);
   2972 			if (!zone_rrset_check_dup(zone, name, &rdataset))
   2973 				ok = false;
   2974 			dns_rdataset_disassociate(&rdataset);
   2975 		}
   2976 		dns_rdatasetiter_destroy(&rdsit);
   2977 		dns_db_detachnode(db, &node);
   2978 	}
   2979 
   2980 	if (node != NULL)
   2981 		dns_db_detachnode(db, &node);
   2982 	dns_dbiterator_destroy(&dbiterator);
   2983 
   2984 	return (ok);
   2985 }
   2986 
   2987 static bool
   2988 isspf(const dns_rdata_t *rdata) {
   2989 	char buf[1024];
   2990 	const unsigned char *data = rdata->data;
   2991 	unsigned int rdl = rdata->length, i = 0, tl, len;
   2992 
   2993 	while (rdl > 0U) {
   2994 		len = tl = *data;
   2995 		++data;
   2996 		--rdl;
   2997 		INSIST(tl <= rdl);
   2998 		if (len > sizeof(buf) - i - 1)
   2999 			len = sizeof(buf) - i - 1;
   3000 		memmove(buf + i, data, len);
   3001 		i += len;
   3002 		data += tl;
   3003 		rdl -= tl;
   3004 	}
   3005 
   3006 	if (i < 6U)
   3007 		return(false);
   3008 
   3009 	buf[i] = 0;
   3010 	if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
   3011 		return (true);
   3012 	return (false);
   3013 }
   3014 
   3015 static bool
   3016 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
   3017 	dns_dbiterator_t *dbiterator = NULL;
   3018 	dns_dbnode_t *node = NULL;
   3019 	dns_rdataset_t rdataset;
   3020 	dns_fixedname_t fixed;
   3021 	dns_fixedname_t fixedbottom;
   3022 	dns_rdata_mx_t mx;
   3023 	dns_rdata_ns_t ns;
   3024 	dns_rdata_in_srv_t srv;
   3025 	dns_rdata_t rdata;
   3026 	dns_name_t *name;
   3027 	dns_name_t *bottom;
   3028 	isc_result_t result;
   3029 	bool ok = true, have_spf, have_txt;
   3030 
   3031 	name = dns_fixedname_initname(&fixed);
   3032 	bottom = dns_fixedname_initname(&fixedbottom);
   3033 	dns_rdataset_init(&rdataset);
   3034 	dns_rdata_init(&rdata);
   3035 
   3036 	result = dns_db_createiterator(db, 0, &dbiterator);
   3037 	if (result != ISC_R_SUCCESS)
   3038 		return (true);
   3039 
   3040 	result = dns_dbiterator_first(dbiterator);
   3041 	while (result == ISC_R_SUCCESS) {
   3042 		result = dns_dbiterator_current(dbiterator, &node, name);
   3043 		if (result != ISC_R_SUCCESS)
   3044 			goto cleanup;
   3045 
   3046 		/*
   3047 		 * Is this name visible in the zone?
   3048 		 */
   3049 		if (!dns_name_issubdomain(name, &zone->origin) ||
   3050 		    (dns_name_countlabels(bottom) > 0 &&
   3051 		     dns_name_issubdomain(name, bottom)))
   3052 			goto next;
   3053 
   3054 		/*
   3055 		 * Don't check the NS records at the origin.
   3056 		 */
   3057 		if (dns_name_equal(name, &zone->origin))
   3058 			goto checkfordname;
   3059 
   3060 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
   3061 					     0, 0, &rdataset, NULL);
   3062 		if (result != ISC_R_SUCCESS)
   3063 			goto checkfordname;
   3064 		/*
   3065 		 * Remember bottom of zone due to NS.
   3066 		 */
   3067 		dns_name_copy(name, bottom, NULL);
   3068 
   3069 		result = dns_rdataset_first(&rdataset);
   3070 		while (result == ISC_R_SUCCESS) {
   3071 			dns_rdataset_current(&rdataset, &rdata);
   3072 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   3073 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3074 			if (!zone_check_glue(zone, db, &ns.name, name))
   3075 				ok = false;
   3076 			dns_rdata_reset(&rdata);
   3077 			result = dns_rdataset_next(&rdataset);
   3078 		}
   3079 		dns_rdataset_disassociate(&rdataset);
   3080 		goto next;
   3081 
   3082  checkfordname:
   3083 		result = dns_db_findrdataset(db, node, NULL,
   3084 					     dns_rdatatype_dname, 0, 0,
   3085 					     &rdataset, NULL);
   3086 		if (result == ISC_R_SUCCESS) {
   3087 			/*
   3088 			 * Remember bottom of zone due to DNAME.
   3089 			 */
   3090 			dns_name_copy(name, bottom, NULL);
   3091 			dns_rdataset_disassociate(&rdataset);
   3092 		}
   3093 
   3094 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
   3095 					     0, 0, &rdataset, NULL);
   3096 		if (result != ISC_R_SUCCESS)
   3097 			goto checksrv;
   3098 		result = dns_rdataset_first(&rdataset);
   3099 		while (result == ISC_R_SUCCESS) {
   3100 			dns_rdataset_current(&rdataset, &rdata);
   3101 			result = dns_rdata_tostruct(&rdata, &mx, NULL);
   3102 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3103 			if (!zone_check_mx(zone, db, &mx.mx, name))
   3104 				ok = false;
   3105 			dns_rdata_reset(&rdata);
   3106 			result = dns_rdataset_next(&rdataset);
   3107 		}
   3108 		dns_rdataset_disassociate(&rdataset);
   3109 
   3110  checksrv:
   3111 		if (zone->rdclass != dns_rdataclass_in)
   3112 			goto next;
   3113 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
   3114 					     0, 0, &rdataset, NULL);
   3115 		if (result != ISC_R_SUCCESS)
   3116 			goto checkspf;
   3117 		result = dns_rdataset_first(&rdataset);
   3118 		while (result == ISC_R_SUCCESS) {
   3119 			dns_rdataset_current(&rdataset, &rdata);
   3120 			result = dns_rdata_tostruct(&rdata, &srv, NULL);
   3121 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3122 			if (!zone_check_srv(zone, db, &srv.target, name))
   3123 				ok = false;
   3124 			dns_rdata_reset(&rdata);
   3125 			result = dns_rdataset_next(&rdataset);
   3126 		}
   3127 		dns_rdataset_disassociate(&rdataset);
   3128 
   3129  checkspf:
   3130 		/*
   3131 		 * Check if there is a type SPF record without an
   3132 		 * SPF-formatted type TXT record also being present.
   3133 		 */
   3134 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
   3135 			goto next;
   3136 		if (zone->rdclass != dns_rdataclass_in)
   3137 			goto next;
   3138 		have_spf = have_txt = false;
   3139 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
   3140 					     0, 0, &rdataset, NULL);
   3141 		if (result == ISC_R_SUCCESS) {
   3142 			dns_rdataset_disassociate(&rdataset);
   3143 			have_spf = true;
   3144 		}
   3145 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
   3146 					     0, 0, &rdataset, NULL);
   3147 		if (result != ISC_R_SUCCESS)
   3148 			goto notxt;
   3149 		result = dns_rdataset_first(&rdataset);
   3150 		while (result == ISC_R_SUCCESS) {
   3151 			dns_rdataset_current(&rdataset, &rdata);
   3152 			have_txt = isspf(&rdata);
   3153 			dns_rdata_reset(&rdata);
   3154 			if (have_txt)
   3155 				break;
   3156 			result = dns_rdataset_next(&rdataset);
   3157 		}
   3158 		dns_rdataset_disassociate(&rdataset);
   3159 
   3160  notxt:
   3161 		if (have_spf && !have_txt) {
   3162 			char namebuf[DNS_NAME_FORMATSIZE];
   3163 
   3164 			dns_name_format(name, namebuf, sizeof(namebuf));
   3165 			dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found type "
   3166 				     "SPF record but no SPF TXT record found, "
   3167 				     "add matching type TXT record", namebuf);
   3168 		}
   3169 
   3170  next:
   3171 		dns_db_detachnode(db, &node);
   3172 		result = dns_dbiterator_next(dbiterator);
   3173 	}
   3174 
   3175  cleanup:
   3176 	if (node != NULL)
   3177 		dns_db_detachnode(db, &node);
   3178 	dns_dbiterator_destroy(&dbiterator);
   3179 
   3180 	return (ok);
   3181 }
   3182 
   3183 /*
   3184  * OpenSSL verification of RSA keys with exponent 3 is known to be
   3185  * broken prior OpenSSL 0.9.8c/0.9.7k.	Look for such keys and warn
   3186  * if they are in use.
   3187  */
   3188 static void
   3189 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
   3190 	dns_dbnode_t *node = NULL;
   3191 	dns_dbversion_t *version = NULL;
   3192 	dns_rdata_dnskey_t dnskey;
   3193 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3194 	dns_rdataset_t rdataset;
   3195 	isc_result_t result;
   3196 	bool logit, foundrsa = false;
   3197 	const char *algorithm;
   3198 
   3199 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3200 	if (result != ISC_R_SUCCESS) {
   3201 		goto cleanup;
   3202 	}
   3203 
   3204 	dns_db_currentversion(db, &version);
   3205 	dns_rdataset_init(&rdataset);
   3206 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   3207 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3208 	if (result != ISC_R_SUCCESS) {
   3209 		goto cleanup;
   3210 	}
   3211 
   3212 	for (result = dns_rdataset_first(&rdataset);
   3213 	     result == ISC_R_SUCCESS;
   3214 	     result = dns_rdataset_next(&rdataset))
   3215 	{
   3216 		dns_rdataset_current(&rdataset, &rdata);
   3217 		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
   3218 		INSIST(result == ISC_R_SUCCESS);
   3219 
   3220 		/* RFC 3110, section 4: Performance Considerations:
   3221 		 *
   3222 		 * A public exponent of 3 minimizes the effort needed to verify
   3223 		 * a signature.  Use of 3 as the public exponent is weak for
   3224 		 * confidentiality uses since, if the same data can be collected
   3225 		 * encrypted under three different keys with an exponent of 3
   3226 		 * then, using the Chinese Remainder Theorem [NETSEC], the
   3227 		 * original plain text can be easily recovered.  If a key is
   3228 		 * known to be used only for authentication, as is the case with
   3229 		 * DNSSEC, then an exponent of 3 is acceptable.  However other
   3230 		 * applications in the future may wish to leverage DNS
   3231 		 * distributed keys for applications that do require
   3232 		 * confidentiality.  For keys which might have such other uses,
   3233 		 * a more conservative choice would be 65537 (F4, the fourth
   3234 		 * fermat number).
   3235 		 */
   3236 		if (dnskey.algorithm == DST_ALG_RSASHA1 &&
   3237 		    dnskey.datalen > 1 && dnskey.data[0] == 1 &&
   3238 		    dnskey.data[1] == 3)
   3239 		{
   3240 			if (dnskey.algorithm == DST_ALG_RSASHA1) {
   3241 				logit = !foundrsa;
   3242 				foundrsa = true;
   3243 				algorithm = "RSASHA1";
   3244 			}
   3245 			if (logit) {
   3246 				dnssec_log(zone, ISC_LOG_WARNING,
   3247 					   "weak %s (%u) key found "
   3248 					   "(exponent=3)", algorithm,
   3249 					   dnskey.algorithm);
   3250 			}
   3251 		}
   3252 		dns_rdata_reset(&rdata);
   3253 	}
   3254 	dns_rdataset_disassociate(&rdataset);
   3255 
   3256  cleanup:
   3257 	if (node != NULL) {
   3258 		dns_db_detachnode(db, &node);
   3259 	}
   3260 	if (version != NULL) {
   3261 		dns_db_closeversion(db, &version, false);
   3262 	}
   3263 }
   3264 
   3265 static void
   3266 resume_signingwithkey(dns_zone_t *zone) {
   3267 	dns_dbnode_t *node = NULL;
   3268 	dns_dbversion_t *version = NULL;
   3269 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3270 	dns_rdataset_t rdataset;
   3271 	isc_result_t result;
   3272 	dns_db_t *db = NULL;
   3273 
   3274 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3275 	if (zone->db != NULL) {
   3276 		dns_db_attach(zone->db, &db);
   3277 	}
   3278 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3279 	if (db == NULL) {
   3280 		goto cleanup;
   3281 	}
   3282 
   3283 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3284 	if (result != ISC_R_SUCCESS) {
   3285 		goto cleanup;
   3286 	}
   3287 
   3288 	dns_db_currentversion(db, &version);
   3289 	dns_rdataset_init(&rdataset);
   3290 	result = dns_db_findrdataset(db, node, version,
   3291 				     zone->privatetype,
   3292 				     dns_rdatatype_none, 0,
   3293 				     &rdataset, NULL);
   3294 	if (result != ISC_R_SUCCESS) {
   3295 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3296 		goto cleanup;
   3297 	}
   3298 
   3299 	for (result = dns_rdataset_first(&rdataset);
   3300 	     result == ISC_R_SUCCESS;
   3301 	     result = dns_rdataset_next(&rdataset))
   3302 	{
   3303 		dns_rdataset_current(&rdataset, &rdata);
   3304 		if (rdata.length != 5 ||
   3305 		    rdata.data[0] == 0 || rdata.data[4] != 0)
   3306 		{
   3307 			dns_rdata_reset(&rdata);
   3308 			continue;
   3309 		}
   3310 
   3311 		result = zone_signwithkey(zone, rdata.data[0],
   3312 					  (rdata.data[1] << 8) | rdata.data[2],
   3313 					  rdata.data[3]);
   3314 		if (result != ISC_R_SUCCESS) {
   3315 			dnssec_log(zone, ISC_LOG_ERROR,
   3316 				   "zone_signwithkey failed: %s",
   3317 				   dns_result_totext(result));
   3318 		}
   3319 		dns_rdata_reset(&rdata);
   3320 	}
   3321 	dns_rdataset_disassociate(&rdataset);
   3322 
   3323  cleanup:
   3324 	if (db != NULL) {
   3325 		if (node != NULL) {
   3326 			dns_db_detachnode(db, &node);
   3327 		}
   3328 		if (version != NULL) {
   3329 			dns_db_closeversion(db, &version, false);
   3330 		}
   3331 		dns_db_detach(&db);
   3332 	}
   3333 }
   3334 
   3335 /*
   3336  * Initiate adding/removing NSEC3 records belonging to the chain defined by the
   3337  * supplied NSEC3PARAM RDATA.
   3338  *
   3339  * Zone must be locked by caller.
   3340  */
   3341 static isc_result_t
   3342 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   3343 	dns_nsec3chain_t *nsec3chain, *current;
   3344 	dns_dbversion_t *version = NULL;
   3345 	bool nseconly = false, nsec3ok = false;
   3346 	isc_result_t result;
   3347 	isc_time_t now;
   3348 	unsigned int options = 0;
   3349 	char saltbuf[255*2+1];
   3350 	char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
   3351 	dns_db_t *db = NULL;
   3352 
   3353 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3354 	if (zone->db != NULL) {
   3355 		dns_db_attach(zone->db, &db);
   3356 	}
   3357 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3358 
   3359 	if (db == NULL) {
   3360 		result = ISC_R_SUCCESS;
   3361 		goto cleanup;
   3362 	}
   3363 
   3364 	/*
   3365 	 * If this zone is not NSEC3-capable, attempting to remove any NSEC3
   3366 	 * chain from it is pointless as it would not be possible for the
   3367 	 * latter to exist in the first place.
   3368 	 */
   3369 	dns_db_currentversion(db, &version);
   3370 	result = dns_nsec_nseconly(db, version, &nseconly);
   3371 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3372 	dns_db_closeversion(db, &version, false);
   3373 	if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
   3374 		result = ISC_R_SUCCESS;
   3375 		goto cleanup;
   3376 	}
   3377 
   3378 	/*
   3379 	 * Allocate and initialize structure preserving state of
   3380 	 * adding/removing records belonging to this NSEC3 chain between
   3381 	 * separate zone_nsec3chain() calls.
   3382 	 */
   3383 	nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
   3384 	if (nsec3chain == NULL) {
   3385 		result = ISC_R_NOMEMORY;
   3386 		goto cleanup;
   3387 	}
   3388 
   3389 	nsec3chain->magic = 0;
   3390 	nsec3chain->done = false;
   3391 	nsec3chain->db = NULL;
   3392 	nsec3chain->dbiterator = NULL;
   3393 	nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
   3394 	nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
   3395 	nsec3chain->nsec3param.hash = nsec3param->hash;
   3396 	nsec3chain->nsec3param.iterations = nsec3param->iterations;
   3397 	nsec3chain->nsec3param.flags = nsec3param->flags;
   3398 	nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
   3399 	memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
   3400 	nsec3chain->nsec3param.salt = nsec3chain->salt;
   3401 	nsec3chain->seen_nsec = false;
   3402 	nsec3chain->delete_nsec = false;
   3403 	nsec3chain->save_delete_nsec = false;
   3404 
   3405 	/*
   3406 	 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA.
   3407 	 */
   3408 	if (nsec3param->flags == 0) {
   3409 		strlcpy(flags, "NONE", sizeof(flags));
   3410 	} else {
   3411 		flags[0] = '\0';
   3412 		if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   3413 			strlcat(flags, "REMOVE", sizeof(flags));
   3414 		}
   3415 		if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) {
   3416 			if (flags[0] == '\0') {
   3417 				strlcpy(flags, "INITIAL", sizeof(flags));
   3418 			} else {
   3419 				strlcat(flags, "|INITIAL", sizeof(flags));
   3420 			}
   3421 		}
   3422 		if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3423 			if (flags[0] == '\0') {
   3424 				strlcpy(flags, "CREATE", sizeof(flags));
   3425 			} else {
   3426 				strlcat(flags, "|CREATE", sizeof(flags));
   3427 			}
   3428 		}
   3429 		if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) {
   3430 			if (flags[0] == '\0') {
   3431 				strlcpy(flags, "NONSEC", sizeof(flags));
   3432 			} else {
   3433 				strlcat(flags, "|NONSEC", sizeof(flags));
   3434 			}
   3435 		}
   3436 		if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) {
   3437 			if (flags[0] == '\0') {
   3438 				strlcpy(flags, "OPTOUT", sizeof(flags));
   3439 			} else {
   3440 				strlcat(flags, "|OPTOUT", sizeof(flags));
   3441 			}
   3442 		}
   3443 	}
   3444 	result = dns_nsec3param_salttotext(nsec3param, saltbuf,
   3445 					   sizeof(saltbuf));
   3446 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3447 	dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)",
   3448 		   nsec3param->hash, flags, nsec3param->iterations, saltbuf);
   3449 
   3450 	/*
   3451 	 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is
   3452 	 * currently being processed, interrupt its processing to avoid
   3453 	 * simultaneously adding and removing records for the same NSEC3 chain.
   3454 	 */
   3455 	for (current = ISC_LIST_HEAD(zone->nsec3chain);
   3456 	     current != NULL;
   3457 	     current = ISC_LIST_NEXT(current, link))
   3458 	{
   3459 		if ((current->db == db) &&
   3460 		    (current->nsec3param.hash == nsec3param->hash) &&
   3461 		    (current->nsec3param.iterations ==
   3462 		     nsec3param->iterations) &&
   3463 		    (current->nsec3param.salt_length ==
   3464 		     nsec3param->salt_length) &&
   3465 		    memcmp(current->nsec3param.salt, nsec3param->salt,
   3466 			   nsec3param->salt_length) == 0)
   3467 		{
   3468 			current->done = true;
   3469 		}
   3470 	}
   3471 
   3472 	/*
   3473 	 * Attach zone database to the structure initialized above and create
   3474 	 * an iterator for it with appropriate options in order to avoid
   3475 	 * creating NSEC3 records for NSEC3 records.
   3476 	 */
   3477 	dns_db_attach(db, &nsec3chain->db);
   3478 	if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3479 		options = DNS_DB_NONSEC3;
   3480 	}
   3481 	result = dns_db_createiterator(nsec3chain->db, options,
   3482 				       &nsec3chain->dbiterator);
   3483 	if (result == ISC_R_SUCCESS) {
   3484 		result = dns_dbiterator_first(nsec3chain->dbiterator);
   3485 	}
   3486 	if (result == ISC_R_SUCCESS) {
   3487 		/*
   3488 		 * Database iterator initialization succeeded.  We are now
   3489 		 * ready to kick off adding/removing records belonging to this
   3490 		 * NSEC3 chain.  Append the structure initialized above to the
   3491 		 * "nsec3chain" list for the zone and set the appropriate zone
   3492 		 * timer so that zone_nsec3chain() is called as soon as
   3493 		 * possible.
   3494 		 */
   3495 		dns_dbiterator_pause(nsec3chain->dbiterator);
   3496 		ISC_LIST_INITANDAPPEND(zone->nsec3chain,
   3497 				       nsec3chain, link);
   3498 		nsec3chain = NULL;
   3499 		if (isc_time_isepoch(&zone->nsec3chaintime)) {
   3500 			TIME_NOW(&now);
   3501 			zone->nsec3chaintime = now;
   3502 			if (zone->task != NULL) {
   3503 				zone_settimer(zone, &now);
   3504 			}
   3505 		}
   3506 	}
   3507 
   3508 	if (nsec3chain != NULL) {
   3509 		if (nsec3chain->db != NULL) {
   3510 			dns_db_detach(&nsec3chain->db);
   3511 		}
   3512 		if (nsec3chain->dbiterator != NULL) {
   3513 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   3514 		}
   3515 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   3516 	}
   3517 
   3518  cleanup:
   3519 	if (db != NULL) {
   3520 		dns_db_detach(&db);
   3521 	}
   3522 	return (result);
   3523 }
   3524 
   3525 /*
   3526  * Find private-type records at the zone apex which signal that an NSEC3 chain
   3527  * should be added or removed.  For each such record, extract NSEC3PARAM RDATA
   3528  * and pass it to zone_addnsec3chain().
   3529  *
   3530  * Zone must be locked by caller.
   3531  */
   3532 static void
   3533 resume_addnsec3chain(dns_zone_t *zone) {
   3534 	dns_dbnode_t *node = NULL;
   3535 	dns_dbversion_t *version = NULL;
   3536 	dns_rdataset_t rdataset;
   3537 	isc_result_t result;
   3538 	dns_rdata_nsec3param_t nsec3param;
   3539 	bool nseconly = false, nsec3ok = false;
   3540 	dns_db_t *db = NULL;
   3541 
   3542 	INSIST(LOCKED_ZONE(zone));
   3543 
   3544 	if (zone->privatetype == 0)
   3545 		return;
   3546 
   3547 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3548 	if (zone->db != NULL) {
   3549 		dns_db_attach(zone->db, &db);
   3550 	}
   3551 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3552 	if (db == NULL) {
   3553 		goto cleanup;
   3554 	}
   3555 
   3556 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3557 	if (result != ISC_R_SUCCESS) {
   3558 		goto cleanup;
   3559 	}
   3560 
   3561 	dns_db_currentversion(db, &version);
   3562 
   3563 	/*
   3564 	 * In order to create NSEC3 chains we need the DNSKEY RRset at zone
   3565 	 * apex to exist and contain no keys using NSEC-only algorithms.
   3566 	 */
   3567 	result = dns_nsec_nseconly(db, version, &nseconly);
   3568 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3569 
   3570 	/*
   3571 	 * Get the RRset containing all private-type records at the zone apex.
   3572 	 */
   3573 	dns_rdataset_init(&rdataset);
   3574 	result = dns_db_findrdataset(db, node, version,
   3575 				     zone->privatetype, dns_rdatatype_none,
   3576 				     0, &rdataset, NULL);
   3577 	if (result != ISC_R_SUCCESS) {
   3578 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3579 		goto cleanup;
   3580 	}
   3581 
   3582 	for (result = dns_rdataset_first(&rdataset);
   3583 	     result == ISC_R_SUCCESS;
   3584 	     result = dns_rdataset_next(&rdataset))
   3585 	{
   3586 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   3587 		dns_rdata_t rdata = DNS_RDATA_INIT;
   3588 		dns_rdata_t private = DNS_RDATA_INIT;
   3589 
   3590 		dns_rdataset_current(&rdataset, &private);
   3591 		/*
   3592 		 * Try extracting NSEC3PARAM RDATA from this private-type
   3593 		 * record.  Failure means this private-type record does not
   3594 		 * represent an NSEC3PARAM record, so skip it.
   3595 		 */
   3596 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   3597 						sizeof(buf)))
   3598 		{
   3599 			continue;
   3600 		}
   3601 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3602 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3603 		if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
   3604 		    ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
   3605 		{
   3606 			/*
   3607 			 * Pass the NSEC3PARAM RDATA contained in this
   3608 			 * private-type record to zone_addnsec3chain() so that
   3609 			 * it can kick off adding or removing NSEC3 records.
   3610 			 */
   3611 			result = zone_addnsec3chain(zone, &nsec3param);
   3612 			if (result != ISC_R_SUCCESS) {
   3613 				dnssec_log(zone, ISC_LOG_ERROR,
   3614 					   "zone_addnsec3chain failed: %s",
   3615 					   dns_result_totext(result));
   3616 			}
   3617 		}
   3618 	}
   3619 	dns_rdataset_disassociate(&rdataset);
   3620 
   3621  cleanup:
   3622 	if (db != NULL) {
   3623 		if (node != NULL) {
   3624 			dns_db_detachnode(db, &node);
   3625 		}
   3626 		if (version != NULL) {
   3627 			dns_db_closeversion(db, &version, false);
   3628 		}
   3629 		dns_db_detach(&db);
   3630 	}
   3631 }
   3632 
   3633 static void
   3634 set_resigntime(dns_zone_t *zone) {
   3635 	dns_rdataset_t rdataset;
   3636 	dns_fixedname_t fixed;
   3637 	unsigned int resign;
   3638 	isc_result_t result;
   3639 	uint32_t nanosecs;
   3640 	dns_db_t *db = NULL;
   3641 
   3642 	/* We only re-sign zones that can be dynamically updated */
   3643 	if (zone->update_disabled)
   3644 		return;
   3645 
   3646 	if (!inline_secure(zone) && (zone->type != dns_zone_master ||
   3647 	    (zone->ssutable == NULL &&
   3648 	     (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
   3649 		return;
   3650 
   3651 	dns_rdataset_init(&rdataset);
   3652 	dns_fixedname_init(&fixed);
   3653 
   3654 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3655 	if (zone->db != NULL)
   3656 		dns_db_attach(zone->db, &db);
   3657 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3658 	if (db == NULL) {
   3659 		isc_time_settoepoch(&zone->resigntime);
   3660 		return;
   3661 	}
   3662 
   3663 	result = dns_db_getsigningtime(db, &rdataset,
   3664 				       dns_fixedname_name(&fixed));
   3665 	if (result != ISC_R_SUCCESS) {
   3666 		isc_time_settoepoch(&zone->resigntime);
   3667 		goto cleanup;
   3668 	}
   3669 
   3670 	resign = rdataset.resign - zone->sigresigninginterval;
   3671 	dns_rdataset_disassociate(&rdataset);
   3672 	nanosecs = isc_random_uniform(1000000000);
   3673 	isc_time_set(&zone->resigntime, resign, nanosecs);
   3674  cleanup:
   3675 	dns_db_detach(&db);
   3676 	return;
   3677 }
   3678 
   3679 static isc_result_t
   3680 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
   3681 	dns_dbnode_t *node = NULL;
   3682 	dns_rdataset_t rdataset;
   3683 	dns_dbversion_t *version = NULL;
   3684 	dns_rdata_nsec3param_t nsec3param;
   3685 	bool ok = false;
   3686 	isc_result_t result;
   3687 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3688 	bool dynamic = (zone->type == dns_zone_master)
   3689 			? dns_zone_isdynamic(zone, false) : false;
   3690 
   3691 	dns_rdataset_init(&rdataset);
   3692 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3693 	if (result != ISC_R_SUCCESS) {
   3694 		dns_zone_log(zone, ISC_LOG_ERROR,
   3695 			     "nsec3param lookup failure: %s",
   3696 			     dns_result_totext(result));
   3697 		return (result);
   3698 	}
   3699 	dns_db_currentversion(db, &version);
   3700 
   3701 	result = dns_db_findrdataset(db, node, version,
   3702 				     dns_rdatatype_nsec3param,
   3703 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3704 	if (result == ISC_R_NOTFOUND) {
   3705 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3706 		result = ISC_R_SUCCESS;
   3707 		goto cleanup;
   3708 	}
   3709 	if (result != ISC_R_SUCCESS) {
   3710 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3711 		dns_zone_log(zone, ISC_LOG_ERROR,
   3712 			     "nsec3param lookup failure: %s",
   3713 			     dns_result_totext(result));
   3714 		goto cleanup;
   3715 	}
   3716 
   3717 	/*
   3718 	 * For dynamic zones we must support every algorithm so we can
   3719 	 * regenerate all the NSEC3 chains.
   3720 	 * For non-dynamic zones we only need to find a supported algorithm.
   3721 	 */
   3722 	for (result = dns_rdataset_first(&rdataset);
   3723 	     result == ISC_R_SUCCESS;
   3724 	     result = dns_rdataset_next(&rdataset))
   3725 	{
   3726 		dns_rdataset_current(&rdataset, &rdata);
   3727 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3728 		dns_rdata_reset(&rdata);
   3729 		INSIST(result == ISC_R_SUCCESS);
   3730 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
   3731 		    nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
   3732 		{
   3733 			dns_zone_log(zone, ISC_LOG_WARNING,
   3734 			     "nsec3 test \"unknown\" hash algorithm found: %u",
   3735 				     nsec3param.hash);
   3736 			ok = true;
   3737 		} else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
   3738 			if (dynamic) {
   3739 				dns_zone_log(zone, ISC_LOG_ERROR,
   3740 					     "unsupported nsec3 hash algorithm"
   3741 					     " in dynamic zone: %u",
   3742 					     nsec3param.hash);
   3743 				result = DNS_R_BADZONE;
   3744 				/* Stop second error message. */
   3745 				ok = true;
   3746 				break;
   3747 			} else
   3748 				dns_zone_log(zone, ISC_LOG_WARNING,
   3749 				     "unsupported nsec3 hash algorithm: %u",
   3750 					     nsec3param.hash);
   3751 		} else {
   3752 			ok = true;
   3753 		}
   3754 	}
   3755 	if (result == ISC_R_NOMORE) {
   3756 		result = ISC_R_SUCCESS;
   3757 	}
   3758 
   3759 	if (!ok) {
   3760 		result = DNS_R_BADZONE;
   3761 		dns_zone_log(zone, ISC_LOG_ERROR,
   3762 			     "no supported nsec3 hash algorithm");
   3763 	}
   3764 
   3765  cleanup:
   3766 	if (dns_rdataset_isassociated(&rdataset)) {
   3767 		dns_rdataset_disassociate(&rdataset);
   3768 	}
   3769 	dns_db_closeversion(db, &version, false);
   3770 	dns_db_detachnode(db, &node);
   3771 	return (result);
   3772 }
   3773 
   3774 /*
   3775  * Set the timer for refreshing the key zone to the soonest future time
   3776  * of the set (current timer, keydata->refresh, keydata->addhd,
   3777  * keydata->removehd).
   3778  */
   3779 static void
   3780 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
   3781 		    isc_stdtime_t now, bool force)
   3782 {
   3783 	const char me[] = "set_refreshkeytimer";
   3784 	isc_stdtime_t then;
   3785 	isc_time_t timenow, timethen;
   3786 	char timebuf[80];
   3787 
   3788 	ENTER;
   3789 	then = key->refresh;
   3790 	if (force)
   3791 		then = now;
   3792 	if (key->addhd > now && key->addhd < then)
   3793 		then = key->addhd;
   3794 	if (key->removehd > now && key->removehd < then)
   3795 		then = key->removehd;
   3796 
   3797 	TIME_NOW(&timenow);
   3798 	if (then > now)
   3799 		DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   3800 	else
   3801 		timethen = timenow;
   3802 	if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
   3803 	    isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
   3804 		zone->refreshkeytime = timethen;
   3805 
   3806 	isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   3807 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
   3808 	zone_settimer(zone, &timenow);
   3809 }
   3810 
   3811 /*
   3812  * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
   3813  * If the key zone is changed, set '*changed' to true.
   3814  */
   3815 static isc_result_t
   3816 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   3817 	       dns_diff_t *diff, dns_keytable_t *keytable,
   3818 	       dns_keynode_t **keynodep, bool *changed)
   3819 {
   3820 	const char me[] = "create_keydata";
   3821 	isc_result_t result = ISC_R_SUCCESS;
   3822 	isc_buffer_t keyb, dstb;
   3823 	unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
   3824 	dns_rdata_keydata_t keydata;
   3825 	dns_rdata_dnskey_t dnskey;
   3826 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3827 	dns_keynode_t *keynode;
   3828 	isc_stdtime_t now;
   3829 	isc_region_t r;
   3830 	dst_key_t *key;
   3831 
   3832 	REQUIRE(keynodep != NULL);
   3833 	keynode = *keynodep;
   3834 
   3835 	ENTER;
   3836 	isc_stdtime_get(&now);
   3837 
   3838 	/* Loop in case there's more than one key. */
   3839 	while (result == ISC_R_SUCCESS) {
   3840 		dns_keynode_t *nextnode = NULL;
   3841 
   3842 		key = dns_keynode_key(keynode);
   3843 		if (key == NULL)
   3844 			goto skip;
   3845 
   3846 		isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
   3847 		CHECK(dst_key_todns(key, &dstb));
   3848 
   3849 		/* Convert DST key to DNSKEY. */
   3850 		dns_rdata_reset(&rdata);
   3851 		isc_buffer_usedregion(&dstb, &r);
   3852 		dns_rdata_fromregion(&rdata, dst_key_class(key),
   3853 				     dns_rdatatype_dnskey, &r);
   3854 
   3855 		/* DSTKEY to KEYDATA. */
   3856 		CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
   3857 		CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
   3858 					     NULL));
   3859 
   3860 		/* KEYDATA to rdata. */
   3861 		dns_rdata_reset(&rdata);
   3862 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   3863 		CHECK(dns_rdata_fromstruct(&rdata,
   3864 					   zone->rdclass, dns_rdatatype_keydata,
   3865 					   &keydata, &keyb));
   3866 
   3867 		/* Add rdata to zone. */
   3868 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
   3869 				    dst_key_name(key), 0, &rdata));
   3870 		*changed = true;
   3871 
   3872 		/* Refresh new keys from the zone apex as soon as possible. */
   3873 		set_refreshkeytimer(zone, &keydata, now, true);
   3874 
   3875  skip:
   3876 		result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
   3877 		if (result != ISC_R_NOTFOUND) {
   3878 			dns_keytable_detachkeynode(keytable, &keynode);
   3879 			keynode = nextnode;
   3880 		}
   3881 	}
   3882 
   3883 	if (keynode != NULL)
   3884 		dns_keytable_detachkeynode(keytable, &keynode);
   3885 	*keynodep = NULL;
   3886 
   3887 	return (ISC_R_SUCCESS);
   3888 
   3889   failure:
   3890 	return (result);
   3891 }
   3892 
   3893 /*
   3894  * Remove from the key zone all the KEYDATA records found in rdataset.
   3895  */
   3896 static isc_result_t
   3897 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   3898 	       dns_name_t *name, dns_rdataset_t *rdataset)
   3899 {
   3900 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3901 	isc_result_t result, uresult;
   3902 
   3903 	for (result = dns_rdataset_first(rdataset);
   3904 	     result == ISC_R_SUCCESS;
   3905 	     result = dns_rdataset_next(rdataset)) {
   3906 		dns_rdata_reset(&rdata);
   3907 		dns_rdataset_current(rdataset, &rdata);
   3908 		uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
   3909 					name, 0, &rdata);
   3910 		if (uresult != ISC_R_SUCCESS)
   3911 			return (uresult);
   3912 	}
   3913 	if (result == ISC_R_NOMORE)
   3914 		result = ISC_R_SUCCESS;
   3915 	return (result);
   3916 }
   3917 
   3918 /*
   3919  * Compute the DNSSEC key ID for a DNSKEY record.
   3920  */
   3921 static isc_result_t
   3922 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
   3923 	    dns_keytag_t *tag)
   3924 {
   3925 	isc_result_t result;
   3926 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3927 	unsigned char data[4096];
   3928 	isc_buffer_t buffer;
   3929 	dst_key_t *dstkey = NULL;
   3930 
   3931 	isc_buffer_init(&buffer, data, sizeof(data));
   3932 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   3933 			     dns_rdatatype_dnskey, dnskey, &buffer);
   3934 
   3935 	result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
   3936 	if (result == ISC_R_SUCCESS) {
   3937 		*tag = dst_key_id(dstkey);
   3938 		dst_key_free(&dstkey);
   3939 	}
   3940 
   3941 	return (result);
   3942 }
   3943 
   3944 /*
   3945  * Add key to the security roots.
   3946  */
   3947 static void
   3948 trust_key(dns_zone_t *zone, dns_name_t *keyname,
   3949 	  dns_rdata_dnskey_t *dnskey, bool initial,
   3950 	  isc_mem_t *mctx)
   3951 {
   3952 	isc_result_t result;
   3953 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3954 	unsigned char data[4096];
   3955 	isc_buffer_t buffer;
   3956 	dns_keytable_t *sr = NULL;
   3957 	dst_key_t *dstkey = NULL;
   3958 
   3959 	/* Convert dnskey to DST key. */
   3960 	isc_buffer_init(&buffer, data, sizeof(data));
   3961 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   3962 			     dns_rdatatype_dnskey, dnskey, &buffer);
   3963 
   3964 	result = dns_view_getsecroots(zone->view, &sr);
   3965 	if (result != ISC_R_SUCCESS)
   3966 		goto failure;
   3967 
   3968 	CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
   3969 	CHECK(dns_keytable_add(sr, true, initial, &dstkey));
   3970 	dns_keytable_detach(&sr);
   3971 
   3972   failure:
   3973 	if (dstkey != NULL)
   3974 		dst_key_free(&dstkey);
   3975 	if (sr != NULL)
   3976 		dns_keytable_detach(&sr);
   3977 	return;
   3978 }
   3979 
   3980 /*
   3981  * Add a null key to the security roots for so that all queries
   3982  * to the zone will fail.
   3983  */
   3984 static void
   3985 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
   3986 	isc_result_t result;
   3987 	dns_keytable_t *sr = NULL;
   3988 
   3989 	result = dns_view_getsecroots(zone->view, &sr);
   3990 	if (result == ISC_R_SUCCESS) {
   3991 		dns_keytable_marksecure(sr, keyname);
   3992 		dns_keytable_detach(&sr);
   3993 	}
   3994 }
   3995 
   3996 /*
   3997  * Scan a set of KEYDATA records from the key zone.  The ones that are
   3998  * valid (i.e., the add holddown timer has expired) become trusted keys.
   3999  */
   4000 static void
   4001 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
   4002 	isc_result_t result;
   4003 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4004 	dns_rdata_keydata_t keydata;
   4005 	dns_rdata_dnskey_t dnskey;
   4006 	isc_mem_t *mctx = zone->mctx;
   4007 	int trusted = 0, revoked = 0, pending = 0;
   4008 	isc_stdtime_t now;
   4009 	dns_keytable_t *sr = NULL;
   4010 
   4011 	isc_stdtime_get(&now);
   4012 
   4013 	result = dns_view_getsecroots(zone->view, &sr);
   4014 	if (result == ISC_R_SUCCESS) {
   4015 		dns_keytable_delete(sr, name);
   4016 		dns_keytable_detach(&sr);
   4017 	}
   4018 
   4019 	/* Now insert all the accepted trust anchors from this keydata set. */
   4020 	for (result = dns_rdataset_first(rdataset);
   4021 	     result == ISC_R_SUCCESS;
   4022 	     result = dns_rdataset_next(rdataset))
   4023 	{
   4024 		dns_rdata_reset(&rdata);
   4025 		dns_rdataset_current(rdataset, &rdata);
   4026 
   4027 		/* Convert rdata to keydata. */
   4028 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   4029 		if (result == ISC_R_UNEXPECTEDEND) {
   4030 			continue;
   4031 		}
   4032 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4033 
   4034 		/* Set the key refresh timer to force a fast refresh. */
   4035 		set_refreshkeytimer(zone, &keydata, now, true);
   4036 
   4037 		/* If the removal timer is nonzero, this key was revoked. */
   4038 		if (keydata.removehd != 0) {
   4039 			revoked++;
   4040 			continue;
   4041 		}
   4042 
   4043 		/*
   4044 		 * If the add timer is still pending, this key is not
   4045 		 * trusted yet.
   4046 		 */
   4047 		if (now < keydata.addhd) {
   4048 			pending++;
   4049 			continue;
   4050 		}
   4051 
   4052 		/* Convert keydata to dnskey. */
   4053 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   4054 
   4055 		/* Add to keytables. */
   4056 		trusted++;
   4057 		trust_key(zone, name, &dnskey, (keydata.addhd == 0), mctx);
   4058 	}
   4059 
   4060 	if (trusted == 0 && pending != 0) {
   4061 		char namebuf[DNS_NAME_FORMATSIZE];
   4062 		dns_name_format(name, namebuf, sizeof namebuf);
   4063 		dnssec_log(zone, ISC_LOG_ERROR,
   4064 			   "No valid trust anchors for '%s'!", namebuf);
   4065 		dnssec_log(zone, ISC_LOG_ERROR,
   4066 			   "%d key(s) revoked, %d still pending",
   4067 			     revoked, pending);
   4068 		dnssec_log(zone, ISC_LOG_ERROR,
   4069 			   "All queries to '%s' will fail", namebuf);
   4070 		fail_secure(zone, name);
   4071 	}
   4072 }
   4073 
   4074 static isc_result_t
   4075 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
   4076 	     dns_diff_t *diff)
   4077 {
   4078 	dns_diff_t temp_diff;
   4079 	isc_result_t result;
   4080 
   4081 	/*
   4082 	 * Create a singleton diff.
   4083 	 */
   4084 	dns_diff_init(diff->mctx, &temp_diff);
   4085 	ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
   4086 
   4087 	/*
   4088 	 * Apply it to the database.
   4089 	 */
   4090 	result = dns_diff_apply(&temp_diff, db, ver);
   4091 	ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
   4092 	if (result != ISC_R_SUCCESS) {
   4093 		dns_difftuple_free(tuple);
   4094 		return (result);
   4095 	}
   4096 
   4097 	/*
   4098 	 * Merge it into the current pending journal entry.
   4099 	 */
   4100 	dns_diff_appendminimal(diff, tuple);
   4101 
   4102 	/*
   4103 	 * Do not clear temp_diff.
   4104 	 */
   4105 	return (ISC_R_SUCCESS);
   4106 }
   4107 
   4108 static isc_result_t
   4109 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4110 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
   4111 	      dns_rdata_t *rdata)
   4112 {
   4113 	dns_difftuple_t *tuple = NULL;
   4114 	isc_result_t result;
   4115 	result = dns_difftuple_create(diff->mctx, op,
   4116 				      name, ttl, rdata, &tuple);
   4117 	if (result != ISC_R_SUCCESS)
   4118 		return (result);
   4119 	return (do_one_tuple(&tuple, db, ver, diff));
   4120 }
   4121 
   4122 static isc_result_t
   4123 update_soa_serial(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4124 		  isc_mem_t *mctx, dns_updatemethod_t method) {
   4125 	dns_difftuple_t *deltuple = NULL;
   4126 	dns_difftuple_t *addtuple = NULL;
   4127 	uint32_t serial;
   4128 	isc_result_t result;
   4129 
   4130 	INSIST(method != dns_updatemethod_none);
   4131 
   4132 	CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
   4133 	CHECK(dns_difftuple_copy(deltuple, &addtuple));
   4134 	addtuple->op = DNS_DIFFOP_ADD;
   4135 
   4136 	serial = dns_soa_getserial(&addtuple->rdata);
   4137 	serial = dns_update_soaserial(serial, method);
   4138 	dns_soa_setserial(serial, &addtuple->rdata);
   4139 	CHECK(do_one_tuple(&deltuple, db, ver, diff));
   4140 	CHECK(do_one_tuple(&addtuple, db, ver, diff));
   4141 	result = ISC_R_SUCCESS;
   4142 
   4143 	failure:
   4144 	if (addtuple != NULL)
   4145 		dns_difftuple_free(&addtuple);
   4146 	if (deltuple != NULL)
   4147 		dns_difftuple_free(&deltuple);
   4148 	return (result);
   4149 }
   4150 
   4151 /*
   4152  * Write all transactions in 'diff' to the zone journal file.
   4153  */
   4154 static isc_result_t
   4155 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial,
   4156 	     const char *caller)
   4157 {
   4158 	const char me[] = "zone_journal";
   4159 	const char *journalfile;
   4160 	isc_result_t result = ISC_R_SUCCESS;
   4161 	dns_journal_t *journal = NULL;
   4162 	unsigned int mode = DNS_JOURNAL_CREATE|DNS_JOURNAL_WRITE;
   4163 
   4164 	ENTER;
   4165 	journalfile = dns_zone_getjournal(zone);
   4166 	if (journalfile != NULL) {
   4167 		result = dns_journal_open(zone->mctx, journalfile, mode,
   4168 					  &journal);
   4169 		if (result != ISC_R_SUCCESS) {
   4170 			dns_zone_log(zone, ISC_LOG_ERROR,
   4171 				     "%s:dns_journal_open -> %s",
   4172 				     caller, dns_result_totext(result));
   4173 			return (result);
   4174 		}
   4175 
   4176 		if (sourceserial != NULL)
   4177 			dns_journal_set_sourceserial(journal, *sourceserial);
   4178 
   4179 		result = dns_journal_write_transaction(journal, diff);
   4180 		if (result != ISC_R_SUCCESS) {
   4181 			dns_zone_log(zone, ISC_LOG_ERROR,
   4182 				     "%s:dns_journal_write_transaction -> %s",
   4183 				     caller, dns_result_totext(result));
   4184 		}
   4185 		dns_journal_destroy(&journal);
   4186 	}
   4187 
   4188 	return (result);
   4189 }
   4190 
   4191 /*
   4192  * Create an SOA record for a newly-created zone
   4193  */
   4194 static isc_result_t
   4195 add_soa(dns_zone_t *zone, dns_db_t *db) {
   4196 	isc_result_t result;
   4197 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4198 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   4199 	dns_dbversion_t *ver = NULL;
   4200 	dns_diff_t diff;
   4201 
   4202 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
   4203 
   4204 	dns_diff_init(zone->mctx, &diff);
   4205 	result = dns_db_newversion(db, &ver);
   4206 	if (result != ISC_R_SUCCESS) {
   4207 		dns_zone_log(zone, ISC_LOG_ERROR,
   4208 			     "add_soa:dns_db_newversion -> %s",
   4209 			     dns_result_totext(result));
   4210 		goto failure;
   4211 	}
   4212 
   4213 	/* Build SOA record */
   4214 	result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
   4215 				    0, 0, 0, 0, 0, buf, &rdata);
   4216 	if (result != ISC_R_SUCCESS) {
   4217 		dns_zone_log(zone, ISC_LOG_ERROR,
   4218 			     "add_soa:dns_soa_buildrdata -> %s",
   4219 			     dns_result_totext(result));
   4220 		goto failure;
   4221 	}
   4222 
   4223 	result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
   4224 			       &zone->origin, 0, &rdata);
   4225 
   4226 failure:
   4227 	dns_diff_clear(&diff);
   4228 	if (ver != NULL)
   4229 		dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS));
   4230 
   4231 	INSIST(ver == NULL);
   4232 
   4233 	return (result);
   4234 }
   4235 
   4236 struct addifmissing_arg {
   4237 	dns_db_t *db;
   4238 	dns_dbversion_t *ver;
   4239 	dns_diff_t *diff;
   4240 	dns_zone_t *zone;
   4241 	bool *changed;
   4242 	isc_result_t result;
   4243 };
   4244 
   4245 static void
   4246 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode, void *arg) {
   4247 	dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
   4248 	dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
   4249 	dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
   4250 	dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
   4251 	bool *changed = ((struct addifmissing_arg *)arg)->changed;
   4252 	isc_result_t result;
   4253 	dns_keynode_t *dummy = NULL;
   4254 
   4255 	if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS)
   4256 		return;
   4257 
   4258 	if (dns_keynode_managed(keynode)) {
   4259 		dns_fixedname_t fname;
   4260 		dns_name_t *keyname;
   4261 		dst_key_t *key;
   4262 
   4263 		key = dns_keynode_key(keynode);
   4264 		if (key == NULL)
   4265 			return;
   4266 		dns_fixedname_init(&fname);
   4267 
   4268 		keyname = dst_key_name(key);
   4269 		result = dns_db_find(db, keyname, ver,
   4270 				     dns_rdatatype_keydata,
   4271 				     DNS_DBFIND_NOWILD, 0, NULL,
   4272 				     dns_fixedname_name(&fname),
   4273 				     NULL, NULL);
   4274 		if (result == ISC_R_SUCCESS)
   4275 			return;
   4276 		dns_keytable_attachkeynode(keytable, keynode, &dummy);
   4277 		result = create_keydata(zone, db, ver, diff, keytable,
   4278 					&dummy, changed);
   4279 		if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE)
   4280 			((struct addifmissing_arg *)arg)->result = result;
   4281 	}
   4282 };
   4283 
   4284 /*
   4285  * Synchronize the set of initializing keys found in managed-keys {}
   4286  * statements with the set of trust anchors found in the managed-keys.bind
   4287  * zone.  If a domain is no longer named in managed-keys, delete all keys
   4288  * from that domain from the key zone.	If a domain is mentioned in in
   4289  * managed-keys but there are no references to it in the key zone, load
   4290  * the key zone with the initializing key(s) for that domain.
   4291  */
   4292 static isc_result_t
   4293 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
   4294 	isc_result_t result = ISC_R_SUCCESS;
   4295 	bool changed = false;
   4296 	bool commit = false;
   4297 	dns_keynode_t *keynode = NULL;
   4298 	dns_view_t *view = zone->view;
   4299 	dns_keytable_t *sr = NULL;
   4300 	dns_dbversion_t *ver = NULL;
   4301 	dns_diff_t diff;
   4302 	dns_rriterator_t rrit;
   4303 	struct addifmissing_arg arg;
   4304 
   4305 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
   4306 
   4307 	dns_diff_init(zone->mctx, &diff);
   4308 
   4309 	CHECK(dns_view_getsecroots(view, &sr));
   4310 
   4311 	result = dns_db_newversion(db, &ver);
   4312 	if (result != ISC_R_SUCCESS) {
   4313 		dnssec_log(zone, ISC_LOG_ERROR,
   4314 			   "sync_keyzone:dns_db_newversion -> %s",
   4315 			   dns_result_totext(result));
   4316 		goto failure;
   4317 	}
   4318 
   4319 	/*
   4320 	 * Walk the zone DB.  If we find any keys whose names are no longer
   4321 	 * in managed-keys (or *are* in trusted-keys, meaning they are
   4322 	 * permanent and not RFC5011-maintained), delete them from the
   4323 	 * zone.  Otherwise call load_secroots(), which loads keys into
   4324 	 * secroots as appropriate.
   4325 	 */
   4326 	dns_rriterator_init(&rrit, db, ver, 0);
   4327 	for (result = dns_rriterator_first(&rrit);
   4328 	     result == ISC_R_SUCCESS;
   4329 	     result = dns_rriterator_nextrrset(&rrit))
   4330 	{
   4331 		dns_rdataset_t *rdataset = NULL;
   4332 		dns_name_t *rrname = NULL;
   4333 		uint32_t ttl;
   4334 
   4335 		dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL);
   4336 		if (!dns_rdataset_isassociated(rdataset)) {
   4337 			dns_rriterator_destroy(&rrit);
   4338 			goto failure;
   4339 		}
   4340 
   4341 		if (rdataset->type != dns_rdatatype_keydata) {
   4342 			continue;
   4343 		}
   4344 
   4345 		result = dns_keytable_find(sr, rrname, &keynode);
   4346 		if ((result != ISC_R_SUCCESS &&
   4347 		     result != DNS_R_PARTIALMATCH) ||
   4348 		    dns_keynode_managed(keynode) == false)
   4349 		{
   4350 			CHECK(delete_keydata(db, ver, &diff,
   4351 					     rrname, rdataset));
   4352 			changed = true;
   4353 		} else {
   4354 			load_secroots(zone, rrname, rdataset);
   4355 		}
   4356 
   4357 		if (keynode != NULL) {
   4358 			dns_keytable_detachkeynode(sr, &keynode);
   4359 		}
   4360 	}
   4361 	dns_rriterator_destroy(&rrit);
   4362 
   4363 	/*
   4364 	 * Now walk secroots to find any managed keys that aren't
   4365 	 * in the zone.  If we find any, we add them to the zone.
   4366 	 */
   4367 	arg.db = db;
   4368 	arg.ver = ver;
   4369 	arg.result = ISC_R_SUCCESS;
   4370 	arg.diff = &diff;
   4371 	arg.zone = zone;
   4372 	arg.changed = &changed;
   4373 	dns_keytable_forall(sr, addifmissing, &arg);
   4374 	result = arg.result;
   4375 	if (changed) {
   4376 		/* Write changes to journal file. */
   4377 		CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
   4378 					zone->updatemethod));
   4379 		CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
   4380 
   4381 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   4382 		zone_needdump(zone, 30);
   4383 		commit = true;
   4384 	}
   4385 
   4386  failure:
   4387 	if (result != ISC_R_SUCCESS &&
   4388 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4389 	{
   4390 		dnssec_log(zone, ISC_LOG_ERROR,
   4391 			   "unable to synchronize managed keys: %s",
   4392 			   dns_result_totext(result));
   4393 		isc_time_settoepoch(&zone->refreshkeytime);
   4394 	}
   4395 	if (keynode != NULL) {
   4396 		dns_keytable_detachkeynode(sr, &keynode);
   4397 	}
   4398 	if (sr != NULL) {
   4399 		dns_keytable_detach(&sr);
   4400 	}
   4401 	if (ver != NULL) {
   4402 		dns_db_closeversion(db, &ver, commit);
   4403 	}
   4404 	dns_diff_clear(&diff);
   4405 
   4406 	INSIST(ver == NULL);
   4407 
   4408 	return (result);
   4409 }
   4410 
   4411 isc_result_t
   4412 dns_zone_synckeyzone(dns_zone_t *zone) {
   4413 	isc_result_t result;
   4414 	dns_db_t *db = NULL;
   4415 
   4416 	if (zone->type != dns_zone_key) {
   4417 		return (DNS_R_BADZONE);
   4418 	}
   4419 
   4420 	CHECK(dns_zone_getdb(zone, &db));
   4421 
   4422 	LOCK_ZONE(zone);
   4423 	result = sync_keyzone(zone, db);
   4424 	UNLOCK_ZONE(zone);
   4425 
   4426  failure:
   4427 	if (db != NULL) {
   4428 		dns_db_detach(&db);
   4429 	}
   4430 	return (result);
   4431 }
   4432 
   4433 static void
   4434 maybe_send_secure(dns_zone_t *zone) {
   4435 	isc_result_t result;
   4436 
   4437 	/*
   4438 	 * We've finished loading, or else failed to load, an inline-signing
   4439 	 * 'secure' zone.  We now need information about the status of the
   4440 	 * 'raw' zone.  If we failed to load, then we need it to send a
   4441 	 * copy of its database; if we succeeded, we need it to send its
   4442 	 * serial number so that we can sync with it.  If it has not yet
   4443 	 * loaded, we set a flag so that it will send the necessary
   4444 	 * information when it has finished loading.
   4445 	 */
   4446 	if (zone->raw->db != NULL) {
   4447 		if (zone->db != NULL) {
   4448 			uint32_t serial;
   4449 			unsigned int soacount;
   4450 
   4451 			result = zone_get_from_db(zone->raw, zone->raw->db,
   4452 						  NULL, &soacount, &serial,
   4453 						  NULL, NULL, NULL, NULL, NULL);
   4454 			if (result == ISC_R_SUCCESS && soacount > 0U)
   4455 				zone_send_secureserial(zone->raw, serial);
   4456 		} else
   4457 			zone_send_securedb(zone->raw, zone->raw->db);
   4458 
   4459 	} else
   4460 		DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
   4461 }
   4462 
   4463 static bool
   4464 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
   4465 	isc_result_t result;
   4466 	bool answer = false;
   4467 	dns_diff_t diff;
   4468 
   4469 	dns_diff_init(mctx, &diff);
   4470 	result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
   4471 	if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples))
   4472 		answer = true;
   4473 	dns_diff_clear(&diff);
   4474 	return (answer);
   4475 }
   4476 
   4477 /*
   4478  * The zone is presumed to be locked.
   4479  * If this is a inline_raw zone the secure version is also locked.
   4480  */
   4481 static isc_result_t
   4482 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
   4483 	      isc_result_t result)
   4484 {
   4485 	unsigned int soacount = 0;
   4486 	unsigned int nscount = 0;
   4487 	unsigned int errors = 0;
   4488 	uint32_t serial, oldserial, refresh, retry, expire, minimum;
   4489 	isc_time_t now;
   4490 	bool needdump = false;
   4491 	bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4492 	bool nomaster = false;
   4493 	bool had_db = false;
   4494 	unsigned int options;
   4495 	dns_include_t *inc;
   4496 
   4497 	INSIST(LOCKED_ZONE(zone));
   4498 	if (inline_raw(zone)) {
   4499 		INSIST(LOCKED_ZONE(zone->secure));
   4500 	}
   4501 
   4502 	TIME_NOW(&now);
   4503 
   4504 	/*
   4505 	 * Initiate zone transfer?  We may need a error code that
   4506 	 * indicates that the "permanent" form does not exist.
   4507 	 * XXX better error feedback to log.
   4508 	 */
   4509 	if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
   4510 		if (zone->type == dns_zone_slave ||
   4511 		    zone->type == dns_zone_mirror ||
   4512 		    zone->type == dns_zone_stub ||
   4513 		    (zone->type == dns_zone_redirect &&
   4514 		     zone->masters == NULL))
   4515 		{
   4516 			if (result == ISC_R_FILENOTFOUND) {
   4517 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4518 					      ISC_LOG_DEBUG(1),
   4519 					     "no master file");
   4520 			} else if (result != DNS_R_NOMASTERFILE) {
   4521 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4522 					      ISC_LOG_ERROR,
   4523 					     "loading from master file %s "
   4524 					     "failed: %s",
   4525 					     zone->masterfile,
   4526 					     dns_result_totext(result));
   4527 			}
   4528 		} else if (zone->type == dns_zone_master &&
   4529 			   inline_secure(zone) && result == ISC_R_FILENOTFOUND)
   4530 		{
   4531 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4532 				      ISC_LOG_DEBUG(1),
   4533 				     "no master file, requesting db");
   4534 			maybe_send_secure(zone);
   4535 		} else {
   4536 			int level = ISC_LOG_ERROR;
   4537 			if (zone->type == dns_zone_key &&
   4538 			    result == ISC_R_FILENOTFOUND)
   4539 				level = ISC_LOG_DEBUG(1);
   4540 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level,
   4541 				     "loading from master file %s failed: %s",
   4542 				     zone->masterfile,
   4543 				     dns_result_totext(result));
   4544 			nomaster = true;
   4545 		}
   4546 
   4547 		if (zone->type != dns_zone_key) {
   4548 			goto cleanup;
   4549 		}
   4550 	}
   4551 
   4552 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
   4553 		     "number of nodes in database: %u",
   4554 		     dns_db_nodecount(db));
   4555 
   4556 	if (result == DNS_R_SEENINCLUDE) {
   4557 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4558 	} else {
   4559 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4560 	}
   4561 
   4562 	/*
   4563 	 * If there's no master file for a key zone, then the zone is new:
   4564 	 * create an SOA record.  (We do this now, instead of later, so that
   4565 	 * if there happens to be a journal file, we can roll forward from
   4566 	 * a sane starting point.)
   4567 	 */
   4568 	if (nomaster && zone->type == dns_zone_key) {
   4569 		result = add_soa(zone, db);
   4570 		if (result != ISC_R_SUCCESS) {
   4571 			goto cleanup;
   4572 		}
   4573 	}
   4574 
   4575 	/*
   4576 	 * Apply update log, if any, on initial load.
   4577 	 */
   4578 	if (zone->journal != NULL &&
   4579 	    ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
   4580 	    ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4581 	{
   4582 		if (zone->type == dns_zone_master && (inline_secure(zone) ||
   4583 		    (zone->update_acl != NULL || zone->ssutable != NULL)))
   4584 		{
   4585 			options = DNS_JOURNALOPT_RESIGN;
   4586 		} else {
   4587 			options = 0;
   4588 		}
   4589 		result = dns_journal_rollforward(zone->mctx, db, options,
   4590 						 zone->journal);
   4591 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
   4592 		    result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
   4593 		    result != ISC_R_RANGE)
   4594 		{
   4595 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4596 				      ISC_LOG_ERROR,
   4597 				     "journal rollforward failed: %s",
   4598 				     dns_result_totext(result));
   4599 			goto cleanup;
   4600 
   4601 
   4602 		}
   4603 		if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
   4604 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4605 				      ISC_LOG_ERROR,
   4606 				     "journal rollforward failed: "
   4607 				     "journal out of sync with zone");
   4608 			goto cleanup;
   4609 		}
   4610 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   4611 			     "journal rollforward completed "
   4612 			     "successfully: %s",
   4613 			     dns_result_totext(result));
   4614 		if (result == ISC_R_SUCCESS) {
   4615 			needdump = true;
   4616 		}
   4617 	}
   4618 
   4619 	/*
   4620 	 * Obtain ns, soa and cname counts for top of zone.
   4621 	 */
   4622 	INSIST(db != NULL);
   4623 	result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
   4624 				  &refresh, &retry, &expire, &minimum,
   4625 				  &errors);
   4626 	if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
   4627 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   4628 			     "could not find NS and/or SOA records");
   4629 	}
   4630 
   4631 	/*
   4632 	 * Check to make sure the journal is up to date, and remove the
   4633 	 * journal file if it isn't, as we wouldn't be able to apply
   4634 	 * updates otherwise.
   4635 	 */
   4636 	if (zone->journal != NULL && dns_zone_isdynamic(zone, true) &&
   4637 	    ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
   4638 	{
   4639 		uint32_t jserial;
   4640 		dns_journal_t *journal = NULL;
   4641 		bool empty = false;
   4642 
   4643 		result = dns_journal_open(zone->mctx, zone->journal,
   4644 					  DNS_JOURNAL_READ, &journal);
   4645 		if (result == ISC_R_SUCCESS) {
   4646 			jserial = dns_journal_last_serial(journal);
   4647 			empty = dns_journal_empty(journal);
   4648 			dns_journal_destroy(&journal);
   4649 		} else {
   4650 			jserial = serial;
   4651 			result = ISC_R_SUCCESS;
   4652 		}
   4653 
   4654 		if (jserial != serial) {
   4655 			if (!empty) {
   4656 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4657 					      ISC_LOG_INFO,
   4658 					     "journal file is out of date: "
   4659 					     "removing journal file");
   4660 			}
   4661 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   4662 				char strbuf[ISC_STRERRORSIZE];
   4663 				strerror_r(errno, strbuf, sizeof(strbuf));
   4664 				isc_log_write(dns_lctx,
   4665 					      DNS_LOGCATEGORY_GENERAL,
   4666 					      DNS_LOGMODULE_ZONE,
   4667 					      ISC_LOG_WARNING,
   4668 					      "unable to remove journal "
   4669 					      "'%s': '%s'",
   4670 					      zone->journal, strbuf);
   4671 			}
   4672 		}
   4673 	}
   4674 
   4675 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   4676 		      "loaded; checking validity");
   4677 
   4678 	/*
   4679 	 * Master / Slave / Mirror / Stub zones require both NS and SOA records
   4680 	 * at the top of the zone.
   4681 	 */
   4682 
   4683 	switch (zone->type) {
   4684 	case dns_zone_dlz:
   4685 	case dns_zone_master:
   4686 	case dns_zone_slave:
   4687 	case dns_zone_mirror:
   4688 	case dns_zone_stub:
   4689 	case dns_zone_redirect:
   4690 		if (soacount != 1) {
   4691 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4692 				      ISC_LOG_ERROR,
   4693 				     "has %d SOA records", soacount);
   4694 			result = DNS_R_BADZONE;
   4695 		}
   4696 		if (nscount == 0) {
   4697 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4698 				      ISC_LOG_ERROR,
   4699 				     "has no NS records");
   4700 			result = DNS_R_BADZONE;
   4701 		}
   4702 		if (result != ISC_R_SUCCESS) {
   4703 			goto cleanup;
   4704 		}
   4705 		if (zone->type == dns_zone_master && errors != 0) {
   4706 			result = DNS_R_BADZONE;
   4707 			goto cleanup;
   4708 		}
   4709 		if (zone->type != dns_zone_stub &&
   4710 		    zone->type != dns_zone_redirect)
   4711 		{
   4712 			result = check_nsec3param(zone, db);
   4713 			if (result != ISC_R_SUCCESS)
   4714 				goto cleanup;
   4715 		}
   4716 		if (zone->type == dns_zone_master &&
   4717 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
   4718 		    !integrity_checks(zone, db))
   4719 		{
   4720 			result = DNS_R_BADZONE;
   4721 			goto cleanup;
   4722 		}
   4723 		if (zone->type == dns_zone_master &&
   4724 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
   4725 		    !zone_check_dup(zone, db))
   4726 		{
   4727 			result = DNS_R_BADZONE;
   4728 			goto cleanup;
   4729 		}
   4730 
   4731 		result = dns_zone_verifydb(zone, db, NULL);
   4732 		if (result != ISC_R_SUCCESS) {
   4733 			goto cleanup;
   4734 		}
   4735 
   4736 		if (zone->db != NULL) {
   4737 			unsigned int oldsoacount;
   4738 
   4739 			/*
   4740 			 * This is checked in zone_replacedb() for slave zones
   4741 			 * as they don't reload from disk.
   4742 			 */
   4743 			result = zone_get_from_db(zone, zone->db, NULL,
   4744 						  &oldsoacount, &oldserial,
   4745 						  NULL, NULL, NULL, NULL,
   4746 						  NULL);
   4747 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4748 			RUNTIME_CHECK(soacount > 0U);
   4749 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   4750 			    !isc_serial_gt(serial, oldserial)) {
   4751 				uint32_t serialmin, serialmax;
   4752 
   4753 				INSIST(zone->type == dns_zone_master);
   4754 				INSIST(zone->raw == NULL);
   4755 
   4756 				if (serial == oldserial &&
   4757 				    zone_unchanged(zone->db, db, zone->mctx)) {
   4758 					dns_zone_logc(zone,
   4759 						      DNS_LOGCATEGORY_ZONELOAD,
   4760 						      ISC_LOG_INFO,
   4761 						     "ixfr-from-differences: "
   4762 						     "unchanged");
   4763 					goto done;
   4764 				}
   4765 
   4766 				serialmin = (oldserial + 1) & 0xffffffffU;
   4767 				serialmax = (oldserial + 0x7fffffffU) &
   4768 					     0xffffffffU;
   4769 				dns_zone_logc(zone,
   4770 					      DNS_LOGCATEGORY_ZONELOAD,
   4771 					      ISC_LOG_ERROR,
   4772 					      "ixfr-from-differences: "
   4773 					      "new serial (%u) out of range "
   4774 					      "[%u - %u]", serial, serialmin,
   4775 					      serialmax);
   4776 				result = DNS_R_BADZONE;
   4777 				goto cleanup;
   4778 			} else if (!isc_serial_ge(serial, oldserial)) {
   4779 				dns_zone_logc(zone,
   4780 					      DNS_LOGCATEGORY_ZONELOAD,
   4781 					      ISC_LOG_ERROR,
   4782 					      "zone serial (%u/%u) has gone "
   4783 					      "backwards", serial, oldserial);
   4784 			} else if (serial == oldserial && !hasinclude &&
   4785 				   strcmp(zone->db_argv[0], "_builtin") != 0)
   4786 			{
   4787 				dns_zone_logc(zone,
   4788 					      DNS_LOGCATEGORY_ZONELOAD,
   4789 					      ISC_LOG_ERROR,
   4790 					      "zone serial (%u) unchanged. "
   4791 					      "zone may fail to transfer "
   4792 					      "to slaves.", serial);
   4793 			}
   4794 		}
   4795 
   4796 		if (zone->type == dns_zone_master &&
   4797 		    (zone->update_acl != NULL || zone->ssutable != NULL) &&
   4798 		    zone->sigresigninginterval < (3 * refresh) &&
   4799 		    dns_db_issecure(db))
   4800 		{
   4801 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4802 				      ISC_LOG_WARNING,
   4803 				      "sig-re-signing-interval less than "
   4804 				      "3 * refresh.");
   4805 		}
   4806 
   4807 		zone->refresh = RANGE(refresh,
   4808 				      zone->minrefresh, zone->maxrefresh);
   4809 		zone->retry = RANGE(retry,
   4810 				    zone->minretry, zone->maxretry);
   4811 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   4812 				     DNS_MAX_EXPIRE);
   4813 		zone->minimum = minimum;
   4814 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   4815 
   4816 		if (zone->type == dns_zone_slave ||
   4817 		    zone->type == dns_zone_mirror ||
   4818 		    zone->type == dns_zone_stub ||
   4819 		    (zone->type == dns_zone_redirect &&
   4820 		     zone->masters != NULL))
   4821 		{
   4822 			isc_time_t t;
   4823 			uint32_t delay;
   4824 
   4825 			result = isc_file_getmodtime(zone->journal, &t);
   4826 			if (result != ISC_R_SUCCESS) {
   4827 				result = isc_file_getmodtime(zone->masterfile,
   4828 							     &t);
   4829 			}
   4830 			if (result == ISC_R_SUCCESS) {
   4831 				DNS_ZONE_TIME_ADD(&t, zone->expire,
   4832 						  &zone->expiretime);
   4833 			} else {
   4834 				DNS_ZONE_TIME_ADD(&now, zone->retry,
   4835 						  &zone->expiretime);
   4836 			}
   4837 
   4838 			delay = (zone->retry -
   4839 				 isc_random_uniform((zone->retry * 3) / 4));
   4840 			DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
   4841 			if (isc_time_compare(&zone->refreshtime,
   4842 					     &zone->expiretime) >= 0)
   4843 			{
   4844 				zone->refreshtime = now;
   4845 			}
   4846 		}
   4847 
   4848 		break;
   4849 
   4850 	case dns_zone_key:
   4851 		result = sync_keyzone(zone, db);
   4852 		if (result != ISC_R_SUCCESS) {
   4853 			goto cleanup;
   4854 		}
   4855 		break;
   4856 
   4857 	default:
   4858 		UNEXPECTED_ERROR(__FILE__, __LINE__,
   4859 				 "unexpected zone type %d", zone->type);
   4860 		result = ISC_R_UNEXPECTED;
   4861 		goto cleanup;
   4862 	}
   4863 
   4864 	/*
   4865 	 * Check for weak DNSKEY's.
   4866 	 */
   4867 	if (zone->type == dns_zone_master) {
   4868 		zone_check_dnskeys(zone, db);
   4869 	}
   4870 
   4871 	/*
   4872 	 * Schedule DNSSEC key refresh.
   4873 	 */
   4874 	if (zone->type == dns_zone_master &&
   4875 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   4876 	{
   4877 		zone->refreshkeytime = now;
   4878 	}
   4879 
   4880 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   4881 	if (zone->db != NULL) {
   4882 		had_db = true;
   4883 		result = zone_replacedb(zone, db, false);
   4884 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   4885 		if (result != ISC_R_SUCCESS) {
   4886 			goto cleanup;
   4887 		}
   4888 	} else {
   4889 		zone_attachdb(zone, db);
   4890 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   4891 		DNS_ZONE_SETFLAG(zone,
   4892 				 DNS_ZONEFLG_LOADED|
   4893 				 DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   4894 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
   4895 		    inline_raw(zone))
   4896 		{
   4897 			if (zone->secure->db == NULL) {
   4898 				zone_send_securedb(zone, db);
   4899 			} else {
   4900 				zone_send_secureserial(zone, serial);
   4901 			}
   4902 		}
   4903 	}
   4904 
   4905 	/*
   4906 	 * Finished loading inline-signing zone; need to get status
   4907 	 * from the raw side now.
   4908 	 */
   4909 	if (zone->type == dns_zone_master && inline_secure(zone)) {
   4910 		maybe_send_secure(zone);
   4911 	}
   4912 
   4913 	result = ISC_R_SUCCESS;
   4914 
   4915 	if (needdump) {
   4916 		if (zone->type == dns_zone_key) {
   4917 			zone_needdump(zone, 30);
   4918 		} else {
   4919 			zone_needdump(zone, DNS_DUMP_DELAY);
   4920 		}
   4921 	}
   4922 
   4923 	if (zone->task != NULL) {
   4924 		if (zone->type == dns_zone_master) {
   4925 			set_resigntime(zone);
   4926 			resume_signingwithkey(zone);
   4927 			resume_addnsec3chain(zone);
   4928 		}
   4929 
   4930 		if (zone->type == dns_zone_master &&
   4931 		    !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
   4932 		    dns_zone_isdynamic(zone, false) &&
   4933 		    dns_db_issecure(db))
   4934 		{
   4935 			dns_name_t *name;
   4936 			dns_fixedname_t fixed;
   4937 			dns_rdataset_t next;
   4938 
   4939 			dns_rdataset_init(&next);
   4940 			name = dns_fixedname_initname(&fixed);
   4941 
   4942 			result = dns_db_getsigningtime(db, &next, name);
   4943 			if (result == ISC_R_SUCCESS) {
   4944 				isc_stdtime_t timenow;
   4945 				char namebuf[DNS_NAME_FORMATSIZE];
   4946 				char typebuf[DNS_RDATATYPE_FORMATSIZE];
   4947 
   4948 				isc_stdtime_get(&timenow);
   4949 				dns_name_format(name, namebuf, sizeof(namebuf));
   4950 				dns_rdatatype_format(next.covers,
   4951 						     typebuf, sizeof(typebuf));
   4952 				dnssec_log(zone, ISC_LOG_DEBUG(3),
   4953 					   "next resign: %s/%s "
   4954 					   "in %d seconds", namebuf, typebuf,
   4955 					   next.resign - timenow -
   4956 					    zone->sigresigninginterval);
   4957 				dns_rdataset_disassociate(&next);
   4958 			} else {
   4959 				dnssec_log(zone, ISC_LOG_WARNING,
   4960 					   "signed dynamic zone has no "
   4961 					   "resign event scheduled");
   4962 			}
   4963 		}
   4964 
   4965 		zone_settimer(zone, &now);
   4966 	}
   4967 
   4968 	/*
   4969 	 * Clear old include list.
   4970 	 */
   4971 	for (inc = ISC_LIST_HEAD(zone->includes);
   4972 	     inc != NULL;
   4973 	     inc = ISC_LIST_HEAD(zone->includes))
   4974 	{
   4975 		ISC_LIST_UNLINK(zone->includes, inc, link);
   4976 		isc_mem_free(zone->mctx, inc->name);
   4977 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   4978 	}
   4979 	zone->nincludes = 0;
   4980 
   4981 	/*
   4982 	 * Transfer new include list.
   4983 	 */
   4984 	for (inc = ISC_LIST_HEAD(zone->newincludes);
   4985 	     inc != NULL;
   4986 	     inc = ISC_LIST_HEAD(zone->newincludes))
   4987 	{
   4988 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   4989 		ISC_LIST_APPEND(zone->includes, inc, link);
   4990 		zone->nincludes++;
   4991 	}
   4992 
   4993 	if (! dns_db_ispersistent(db)) {
   4994 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4995 			      ISC_LOG_INFO, "loaded serial %u%s", serial,
   4996 			      dns_db_issecure(db) ? " (DNSSEC signed)" : "");
   4997 	}
   4998 
   4999 	if (!had_db && zone->type == dns_zone_mirror) {
   5000 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5001 			      "mirror zone is now in use");
   5002 	}
   5003 
   5004 	zone->loadtime = loadtime;
   5005 	goto done;
   5006 
   5007  cleanup:
   5008 	if (zone->type == dns_zone_key && result != ISC_R_SUCCESS) {
   5009 		dnssec_log(zone, ISC_LOG_ERROR,
   5010 			   "failed to initialize managed-keys (%s): "
   5011 			   "DNSSEC validation is at risk",
   5012 			   isc_result_totext(result));
   5013 	}
   5014 
   5015 	for (inc = ISC_LIST_HEAD(zone->newincludes);
   5016 	     inc != NULL;
   5017 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5018 	{
   5019 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5020 		isc_mem_free(zone->mctx, inc->name);
   5021 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5022 	}
   5023 	if (zone->type == dns_zone_slave ||
   5024 	    zone->type == dns_zone_mirror ||
   5025 	    zone->type == dns_zone_stub ||
   5026 	    zone->type == dns_zone_key ||
   5027 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   5028 	{
   5029 		if (result != ISC_R_NOMEMORY) {
   5030 			if (zone->journal != NULL) {
   5031 				zone_saveunique(zone, zone->journal,
   5032 						"jn-XXXXXXXX");
   5033 			}
   5034 			if (zone->masterfile != NULL) {
   5035 				zone_saveunique(zone, zone->masterfile,
   5036 						"db-XXXXXXXX");
   5037 			}
   5038 		}
   5039 
   5040 		/* Mark the zone for immediate refresh. */
   5041 		zone->refreshtime = now;
   5042 		if (zone->task != NULL) {
   5043 			zone_settimer(zone, &now);
   5044 		}
   5045 		result = ISC_R_SUCCESS;
   5046 	} else if (zone->type == dns_zone_master ||
   5047 		   zone->type == dns_zone_redirect)
   5048 	{
   5049 		if (! (inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
   5050 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5051 				      ISC_LOG_ERROR,
   5052 				      "not loaded due to errors.");
   5053 		} else if (zone->type == dns_zone_master) {
   5054 			result = ISC_R_SUCCESS;
   5055 		}
   5056 	}
   5057 
   5058  done:
   5059 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   5060 	/*
   5061 	 * If this is an inline-signed zone and we were called for the raw
   5062 	 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone
   5063 	 * as well, but only if this is a reload, not an initial zone load: in
   5064 	 * the former case, zone_postload() will not be run for the secure
   5065 	 * zone; in the latter case, it will be.  Check which case we are
   5066 	 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the
   5067 	 * secure zone: if it is set, this must be a reload.
   5068 	 */
   5069 	if (inline_raw(zone) &&
   5070 	    DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
   5071 	{
   5072 		DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
   5073 	}
   5074 
   5075 	zone_debuglog(zone, "zone_postload", 99, "done");
   5076 
   5077 	return (result);
   5078 }
   5079 
   5080 static bool
   5081 exit_check(dns_zone_t *zone) {
   5082 	REQUIRE(LOCKED_ZONE(zone));
   5083 
   5084 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) {
   5085 		/*
   5086 		 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
   5087 		 */
   5088 		INSIST(isc_refcount_current(&zone->erefs) == 0);
   5089 		return (true);
   5090 	}
   5091 	return (false);
   5092 }
   5093 
   5094 static bool
   5095 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   5096 	      dns_name_t *name, bool logit)
   5097 {
   5098 	isc_result_t result;
   5099 	char namebuf[DNS_NAME_FORMATSIZE];
   5100 	char altbuf[DNS_NAME_FORMATSIZE];
   5101 	dns_fixedname_t fixed;
   5102 	dns_name_t *foundname;
   5103 	int level;
   5104 
   5105 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
   5106 		return (true);
   5107 
   5108 	if (zone->type == dns_zone_master)
   5109 		level = ISC_LOG_ERROR;
   5110 	else
   5111 		level = ISC_LOG_WARNING;
   5112 
   5113 	foundname = dns_fixedname_initname(&fixed);
   5114 
   5115 	result = dns_db_find(db, name, version, dns_rdatatype_a,
   5116 			     0, 0, NULL, foundname, NULL, NULL);
   5117 	if (result == ISC_R_SUCCESS)
   5118 		return (true);
   5119 
   5120 	if (result == DNS_R_NXRRSET) {
   5121 		result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
   5122 				     0, 0, NULL, foundname, NULL, NULL);
   5123 		if (result == ISC_R_SUCCESS)
   5124 			return (true);
   5125 	}
   5126 
   5127 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   5128 	    result == DNS_R_EMPTYNAME) {
   5129 		if (logit) {
   5130 			dns_name_format(name, namebuf, sizeof namebuf);
   5131 			dns_zone_log(zone, level, "NS '%s' has no address "
   5132 				     "records (A or AAAA)", namebuf);
   5133 		}
   5134 		return (false);
   5135 	}
   5136 
   5137 	if (result == DNS_R_CNAME) {
   5138 		if (logit) {
   5139 			dns_name_format(name, namebuf, sizeof namebuf);
   5140 			dns_zone_log(zone, level, "NS '%s' is a CNAME "
   5141 				     "(illegal)", namebuf);
   5142 		}
   5143 		return (false);
   5144 	}
   5145 
   5146 	if (result == DNS_R_DNAME) {
   5147 		if (logit) {
   5148 			dns_name_format(name, namebuf, sizeof namebuf);
   5149 			dns_name_format(foundname, altbuf, sizeof altbuf);
   5150 			dns_zone_log(zone, level, "NS '%s' is below a DNAME "
   5151 				     "'%s' (illegal)", namebuf, altbuf);
   5152 		}
   5153 		return (false);
   5154 	}
   5155 
   5156 	return (true);
   5157 }
   5158 
   5159 static isc_result_t
   5160 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   5161 		 dns_dbversion_t *version, unsigned int *nscount,
   5162 		 unsigned int *errors, bool logit)
   5163 {
   5164 	isc_result_t result;
   5165 	unsigned int count = 0;
   5166 	unsigned int ecount = 0;
   5167 	dns_rdataset_t rdataset;
   5168 	dns_rdata_t rdata;
   5169 	dns_rdata_ns_t ns;
   5170 
   5171 	dns_rdataset_init(&rdataset);
   5172 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
   5173 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5174 	if (result == ISC_R_NOTFOUND) {
   5175 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5176 		goto success;
   5177 	}
   5178 	if (result != ISC_R_SUCCESS) {
   5179 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5180 		goto invalidate_rdataset;
   5181 	}
   5182 
   5183 	result = dns_rdataset_first(&rdataset);
   5184 	while (result == ISC_R_SUCCESS) {
   5185 		if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
   5186 		    (zone->type == dns_zone_master ||
   5187 		     zone->type == dns_zone_slave ||
   5188 		     zone->type == dns_zone_mirror))
   5189 		{
   5190 			dns_rdata_init(&rdata);
   5191 			dns_rdataset_current(&rdataset, &rdata);
   5192 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   5193 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5194 			if (dns_name_issubdomain(&ns.name, &zone->origin) &&
   5195 			    !zone_check_ns(zone, db, version, &ns.name, logit))
   5196 				ecount++;
   5197 		}
   5198 		count++;
   5199 		result = dns_rdataset_next(&rdataset);
   5200 	}
   5201 	dns_rdataset_disassociate(&rdataset);
   5202 
   5203  success:
   5204 	if (nscount != NULL)
   5205 		*nscount = count;
   5206 	if (errors != NULL)
   5207 		*errors = ecount;
   5208 
   5209 	result = ISC_R_SUCCESS;
   5210 
   5211  invalidate_rdataset:
   5212 	dns_rdataset_invalidate(&rdataset);
   5213 
   5214 	return (result);
   5215 }
   5216 
   5217 static isc_result_t
   5218 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   5219 		 unsigned int *soacount,
   5220 		 uint32_t *serial, uint32_t *refresh,
   5221 		 uint32_t *retry, uint32_t *expire,
   5222 		 uint32_t *minimum)
   5223 {
   5224 	isc_result_t result;
   5225 	unsigned int count;
   5226 	dns_rdataset_t rdataset;
   5227 	dns_rdata_t rdata = DNS_RDATA_INIT;
   5228 	dns_rdata_soa_t soa;
   5229 
   5230 	dns_rdataset_init(&rdataset);
   5231 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
   5232 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5233 	if (result == ISC_R_NOTFOUND) {
   5234 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5235 		if (soacount != NULL)
   5236 			*soacount = 0;
   5237 		if (serial != NULL)
   5238 			*serial = 0;
   5239 		if (refresh != NULL)
   5240 			*refresh = 0;
   5241 		if (retry != NULL)
   5242 			*retry = 0;
   5243 		if (expire != NULL)
   5244 			*expire = 0;
   5245 		if (minimum != NULL)
   5246 			*minimum = 0;
   5247 		result = ISC_R_SUCCESS;
   5248 		goto invalidate_rdataset;
   5249 	}
   5250 	if (result != ISC_R_SUCCESS) {
   5251 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5252 		goto invalidate_rdataset;
   5253 	}
   5254 
   5255 	count = 0;
   5256 	result = dns_rdataset_first(&rdataset);
   5257 	while (result == ISC_R_SUCCESS) {
   5258 		dns_rdata_init(&rdata);
   5259 		dns_rdataset_current(&rdataset, &rdata);
   5260 		count++;
   5261 		if (count == 1) {
   5262 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   5263 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5264 		}
   5265 
   5266 		result = dns_rdataset_next(&rdataset);
   5267 		dns_rdata_reset(&rdata);
   5268 	}
   5269 	dns_rdataset_disassociate(&rdataset);
   5270 
   5271 	if (soacount != NULL)
   5272 		*soacount = count;
   5273 
   5274 	if (count > 0) {
   5275 		if (serial != NULL)
   5276 			*serial = soa.serial;
   5277 		if (refresh != NULL)
   5278 			*refresh = soa.refresh;
   5279 		if (retry != NULL)
   5280 			*retry = soa.retry;
   5281 		if (expire != NULL)
   5282 			*expire = soa.expire;
   5283 		if (minimum != NULL)
   5284 			*minimum = soa.minimum;
   5285 	} else {
   5286 		if (soacount != NULL)
   5287 			*soacount = 0;
   5288 		if (serial != NULL)
   5289 			*serial = 0;
   5290 		if (refresh != NULL)
   5291 			*refresh = 0;
   5292 		if (retry != NULL)
   5293 			*retry = 0;
   5294 		if (expire != NULL)
   5295 			*expire = 0;
   5296 		if (minimum != NULL)
   5297 			*minimum = 0;
   5298 	}
   5299 
   5300 	result = ISC_R_SUCCESS;
   5301 
   5302  invalidate_rdataset:
   5303 	dns_rdataset_invalidate(&rdataset);
   5304 
   5305 	return (result);
   5306 }
   5307 
   5308 /*
   5309  * zone must be locked.
   5310  */
   5311 static isc_result_t
   5312 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
   5313 		 unsigned int *soacount, uint32_t *serial,
   5314 		 uint32_t *refresh, uint32_t *retry,
   5315 		 uint32_t *expire, uint32_t *minimum,
   5316 		 unsigned int *errors)
   5317 {
   5318 	isc_result_t result;
   5319 	isc_result_t answer = ISC_R_SUCCESS;
   5320 	dns_dbversion_t *version = NULL;
   5321 	dns_dbnode_t *node;
   5322 
   5323 	REQUIRE(db != NULL);
   5324 	REQUIRE(zone != NULL);
   5325 
   5326 	dns_db_currentversion(db, &version);
   5327 
   5328 	if (nscount != NULL)
   5329 		*nscount = 0;
   5330 	if (soacount != NULL)
   5331 		*soacount = 0;
   5332 	if (serial != NULL)
   5333 		*serial = 0;
   5334 	if (refresh != NULL)
   5335 		*refresh = 0;
   5336 	if (retry != NULL)
   5337 		*retry = 0;
   5338 	if (expire != NULL)
   5339 		*expire = 0;
   5340 	if (errors != NULL)
   5341 		*errors = 0;
   5342 
   5343 	node = NULL;
   5344 	result = dns_db_findnode(db, &zone->origin, false, &node);
   5345 	if (result != ISC_R_SUCCESS) {
   5346 		answer = result;
   5347 		goto closeversion;
   5348 	}
   5349 
   5350 	if (nscount != NULL || errors != NULL) {
   5351 		result = zone_count_ns_rr(zone, db, node, version,
   5352 					  nscount, errors, true);
   5353 		if (result != ISC_R_SUCCESS)
   5354 			answer = result;
   5355 	}
   5356 
   5357 	if (soacount != NULL || serial != NULL || refresh != NULL
   5358 	    || retry != NULL || expire != NULL || minimum != NULL) {
   5359 		result = zone_load_soa_rr(db, node, version, soacount,
   5360 					  serial, refresh, retry, expire,
   5361 					  minimum);
   5362 		if (result != ISC_R_SUCCESS)
   5363 			answer = result;
   5364 	}
   5365 
   5366 	dns_db_detachnode(db, &node);
   5367  closeversion:
   5368 	dns_db_closeversion(db, &version, false);
   5369 
   5370 	return (answer);
   5371 }
   5372 
   5373 void
   5374 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
   5375 	REQUIRE(DNS_ZONE_VALID(source));
   5376 	REQUIRE(target != NULL && *target == NULL);
   5377 	isc_refcount_increment(&source->erefs);
   5378 	*target = source;
   5379 }
   5380 
   5381 void
   5382 dns_zone_detach(dns_zone_t **zonep) {
   5383 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5384 	dns_zone_t *zone = *zonep;
   5385 	*zonep = NULL;
   5386 
   5387 	bool free_now = false;
   5388 	dns_zone_t *raw = NULL;
   5389 	dns_zone_t *secure = NULL;
   5390 	if (isc_refcount_decrement(&zone->erefs) == 1) {
   5391 		isc_refcount_destroy(&zone->erefs);
   5392 
   5393 		LOCK_ZONE(zone);
   5394 		INSIST(zone != zone->raw);
   5395 		/*
   5396 		 * We just detached the last external reference.
   5397 		 */
   5398 		if (zone->task != NULL) {
   5399 			/*
   5400 			 * This zone is being managed.	Post
   5401 			 * its control event and let it clean
   5402 			 * up synchronously in the context of
   5403 			 * its task.
   5404 			 */
   5405 			isc_event_t *ev = &zone->ctlevent;
   5406 			isc_task_send(zone->task, &ev);
   5407 		} else {
   5408 			/*
   5409 			 * This zone is not being managed; it has
   5410 			 * no task and can have no outstanding
   5411 			 * events.  Free it immediately.
   5412 			 */
   5413 			/*
   5414 			 * Unmanaged zones should not have non-null views;
   5415 			 * we have no way of detaching from the view here
   5416 			 * without causing deadlock because this code is called
   5417 			 * with the view already locked.
   5418 			 */
   5419 			INSIST(zone->view == NULL);
   5420 			free_now = true;
   5421 			raw = zone->raw;
   5422 			zone->raw = NULL;
   5423 			secure = zone->secure;
   5424 			zone->secure = NULL;
   5425 		}
   5426 		UNLOCK_ZONE(zone);
   5427 	}
   5428 	if (free_now) {
   5429 		if (raw != NULL) {
   5430 			dns_zone_detach(&raw);
   5431 		}
   5432 		if (secure != NULL) {
   5433 			dns_zone_idetach(&secure);
   5434 		}
   5435 		zone_free(zone);
   5436 	}
   5437 }
   5438 
   5439 void
   5440 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5441 	REQUIRE(DNS_ZONE_VALID(source));
   5442 	REQUIRE(target != NULL && *target == NULL);
   5443 	LOCK_ZONE(source);
   5444 	zone_iattach(source, target);
   5445 	UNLOCK_ZONE(source);
   5446 }
   5447 
   5448 static void
   5449 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5450 
   5451 	/*
   5452 	 * 'source' locked by caller.
   5453 	 */
   5454 	REQUIRE(LOCKED_ZONE(source));
   5455 	REQUIRE(DNS_ZONE_VALID(source));
   5456 	REQUIRE(target != NULL && *target == NULL);
   5457 	INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
   5458 	source->irefs++;
   5459 	INSIST(source->irefs != 0);
   5460 	*target = source;
   5461 }
   5462 
   5463 static void
   5464 zone_idetach(dns_zone_t **zonep) {
   5465 	dns_zone_t *zone;
   5466 
   5467 	/*
   5468 	 * 'zone' locked by caller.
   5469 	 */
   5470 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5471 	zone = *zonep;
   5472 	REQUIRE(LOCKED_ZONE(*zonep));
   5473 	*zonep = NULL;
   5474 
   5475 	INSIST(zone->irefs > 0);
   5476 	zone->irefs--;
   5477 	INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
   5478 }
   5479 
   5480 void
   5481 dns_zone_idetach(dns_zone_t **zonep) {
   5482 	dns_zone_t *zone;
   5483 	bool free_needed;
   5484 
   5485 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5486 	zone = *zonep;
   5487 	*zonep = NULL;
   5488 
   5489 	LOCK_ZONE(zone);
   5490 	INSIST(zone->irefs > 0);
   5491 	zone->irefs--;
   5492 	free_needed = exit_check(zone);
   5493 	UNLOCK_ZONE(zone);
   5494 	if (free_needed)
   5495 		zone_free(zone);
   5496 }
   5497 
   5498 isc_mem_t *
   5499 dns_zone_getmctx(dns_zone_t *zone) {
   5500 	REQUIRE(DNS_ZONE_VALID(zone));
   5501 
   5502 	return (zone->mctx);
   5503 }
   5504 
   5505 dns_zonemgr_t *
   5506 dns_zone_getmgr(dns_zone_t *zone) {
   5507 	REQUIRE(DNS_ZONE_VALID(zone));
   5508 
   5509 	return (zone->zmgr);
   5510 }
   5511 
   5512 void
   5513 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, bool value) {
   5514 	REQUIRE(DNS_ZONE_VALID(zone));
   5515 
   5516 	LOCK_ZONE(zone);
   5517 	if (value)
   5518 		DNS_ZONE_SETFLAG(zone, flags);
   5519 	else
   5520 		DNS_ZONE_CLRFLAG(zone, flags);
   5521 	UNLOCK_ZONE(zone);
   5522 }
   5523 
   5524 void
   5525 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option,
   5526 		   bool value)
   5527 {
   5528 	REQUIRE(DNS_ZONE_VALID(zone));
   5529 
   5530 	LOCK_ZONE(zone);
   5531 	if (value)
   5532 		zone->options |= option;
   5533 	else
   5534 		zone->options &= ~option;
   5535 	UNLOCK_ZONE(zone);
   5536 }
   5537 
   5538 dns_zoneopt_t
   5539 dns_zone_getoptions(dns_zone_t *zone) {
   5540 	REQUIRE(DNS_ZONE_VALID(zone));
   5541 
   5542 	return (zone->options);
   5543 }
   5544 
   5545 void
   5546 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value)
   5547 {
   5548 	REQUIRE(DNS_ZONE_VALID(zone));
   5549 
   5550 	LOCK_ZONE(zone);
   5551 	if (value)
   5552 		zone->keyopts |= keyopt;
   5553 	else
   5554 		zone->keyopts &= ~keyopt;
   5555 	UNLOCK_ZONE(zone);
   5556 }
   5557 
   5558 unsigned int
   5559 dns_zone_getkeyopts(dns_zone_t *zone) {
   5560 
   5561 	REQUIRE(DNS_ZONE_VALID(zone));
   5562 
   5563 	return (zone->keyopts);
   5564 }
   5565 
   5566 isc_result_t
   5567 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5568 	REQUIRE(DNS_ZONE_VALID(zone));
   5569 
   5570 	LOCK_ZONE(zone);
   5571 	zone->xfrsource4 = *xfrsource;
   5572 	UNLOCK_ZONE(zone);
   5573 
   5574 	return (ISC_R_SUCCESS);
   5575 }
   5576 
   5577 isc_sockaddr_t *
   5578 dns_zone_getxfrsource4(dns_zone_t *zone) {
   5579 	REQUIRE(DNS_ZONE_VALID(zone));
   5580 	return (&zone->xfrsource4);
   5581 }
   5582 
   5583 isc_result_t
   5584 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5585 	REQUIRE(DNS_ZONE_VALID(zone));
   5586 
   5587 	LOCK_ZONE(zone);
   5588 	zone->xfrsource4dscp = dscp;
   5589 	UNLOCK_ZONE(zone);
   5590 
   5591 	return (ISC_R_SUCCESS);
   5592 }
   5593 
   5594 isc_dscp_t
   5595 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
   5596 	REQUIRE(DNS_ZONE_VALID(zone));
   5597 	return (zone->xfrsource4dscp);
   5598 }
   5599 
   5600 isc_result_t
   5601 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5602 	REQUIRE(DNS_ZONE_VALID(zone));
   5603 
   5604 	LOCK_ZONE(zone);
   5605 	zone->xfrsource6 = *xfrsource;
   5606 	UNLOCK_ZONE(zone);
   5607 
   5608 	return (ISC_R_SUCCESS);
   5609 }
   5610 
   5611 isc_sockaddr_t *
   5612 dns_zone_getxfrsource6(dns_zone_t *zone) {
   5613 	REQUIRE(DNS_ZONE_VALID(zone));
   5614 	return (&zone->xfrsource6);
   5615 }
   5616 
   5617 isc_dscp_t
   5618 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
   5619 	REQUIRE(DNS_ZONE_VALID(zone));
   5620 	return (zone->xfrsource6dscp);
   5621 }
   5622 
   5623 isc_result_t
   5624 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5625 	REQUIRE(DNS_ZONE_VALID(zone));
   5626 
   5627 	LOCK_ZONE(zone);
   5628 	zone->xfrsource6dscp = dscp;
   5629 	UNLOCK_ZONE(zone);
   5630 
   5631 	return (ISC_R_SUCCESS);
   5632 }
   5633 
   5634 isc_result_t
   5635 dns_zone_setaltxfrsource4(dns_zone_t *zone,
   5636 			  const isc_sockaddr_t *altxfrsource)
   5637 {
   5638 	REQUIRE(DNS_ZONE_VALID(zone));
   5639 
   5640 	LOCK_ZONE(zone);
   5641 	zone->altxfrsource4 = *altxfrsource;
   5642 	UNLOCK_ZONE(zone);
   5643 
   5644 	return (ISC_R_SUCCESS);
   5645 }
   5646 
   5647 isc_sockaddr_t *
   5648 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
   5649 	REQUIRE(DNS_ZONE_VALID(zone));
   5650 	return (&zone->altxfrsource4);
   5651 }
   5652 
   5653 isc_result_t
   5654 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5655 	REQUIRE(DNS_ZONE_VALID(zone));
   5656 
   5657 	LOCK_ZONE(zone);
   5658 	zone->altxfrsource4dscp = dscp;
   5659 	UNLOCK_ZONE(zone);
   5660 
   5661 	return (ISC_R_SUCCESS);
   5662 }
   5663 
   5664 isc_dscp_t
   5665 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
   5666 	REQUIRE(DNS_ZONE_VALID(zone));
   5667 	return (zone->altxfrsource4dscp);
   5668 }
   5669 
   5670 isc_result_t
   5671 dns_zone_setaltxfrsource6(dns_zone_t *zone,
   5672 			  const isc_sockaddr_t *altxfrsource)
   5673 {
   5674 	REQUIRE(DNS_ZONE_VALID(zone));
   5675 
   5676 	LOCK_ZONE(zone);
   5677 	zone->altxfrsource6 = *altxfrsource;
   5678 	UNLOCK_ZONE(zone);
   5679 
   5680 	return (ISC_R_SUCCESS);
   5681 }
   5682 
   5683 isc_sockaddr_t *
   5684 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
   5685 	REQUIRE(DNS_ZONE_VALID(zone));
   5686 	return (&zone->altxfrsource6);
   5687 }
   5688 
   5689 isc_result_t
   5690 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5691 	REQUIRE(DNS_ZONE_VALID(zone));
   5692 
   5693 	LOCK_ZONE(zone);
   5694 	zone->altxfrsource6dscp = dscp;
   5695 	UNLOCK_ZONE(zone);
   5696 
   5697 	return (ISC_R_SUCCESS);
   5698 }
   5699 
   5700 isc_dscp_t
   5701 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
   5702 	REQUIRE(DNS_ZONE_VALID(zone));
   5703 	return (zone->altxfrsource6dscp);
   5704 }
   5705 
   5706 isc_result_t
   5707 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   5708 	REQUIRE(DNS_ZONE_VALID(zone));
   5709 
   5710 	LOCK_ZONE(zone);
   5711 	zone->notifysrc4 = *notifysrc;
   5712 	UNLOCK_ZONE(zone);
   5713 
   5714 	return (ISC_R_SUCCESS);
   5715 }
   5716 
   5717 isc_sockaddr_t *
   5718 dns_zone_getnotifysrc4(dns_zone_t *zone) {
   5719 	REQUIRE(DNS_ZONE_VALID(zone));
   5720 	return (&zone->notifysrc4);
   5721 }
   5722 
   5723 isc_result_t
   5724 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5725 	REQUIRE(DNS_ZONE_VALID(zone));
   5726 
   5727 	LOCK_ZONE(zone);
   5728 	zone->notifysrc4dscp = dscp;
   5729 	UNLOCK_ZONE(zone);
   5730 
   5731 	return (ISC_R_SUCCESS);
   5732 }
   5733 
   5734 isc_dscp_t
   5735 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
   5736 	REQUIRE(DNS_ZONE_VALID(zone));
   5737 	return (zone->notifysrc4dscp);
   5738 }
   5739 
   5740 isc_result_t
   5741 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   5742 	REQUIRE(DNS_ZONE_VALID(zone));
   5743 
   5744 	LOCK_ZONE(zone);
   5745 	zone->notifysrc6 = *notifysrc;
   5746 	UNLOCK_ZONE(zone);
   5747 
   5748 	return (ISC_R_SUCCESS);
   5749 }
   5750 
   5751 isc_sockaddr_t *
   5752 dns_zone_getnotifysrc6(dns_zone_t *zone) {
   5753 	REQUIRE(DNS_ZONE_VALID(zone));
   5754 	return (&zone->notifysrc6);
   5755 }
   5756 
   5757 static bool
   5758 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
   5759 	   uint32_t count)
   5760 {
   5761 	unsigned int i;
   5762 
   5763 	for (i = 0; i < count; i++)
   5764 		if (!isc_sockaddr_equal(&oldlist[i], &newlist[i]))
   5765 			return (false);
   5766 	return (true);
   5767 }
   5768 
   5769 static bool
   5770 same_keynames(dns_name_t * const *oldlist, dns_name_t * const *newlist,
   5771 	      uint32_t count)
   5772 {
   5773 	unsigned int i;
   5774 
   5775 	if (oldlist == NULL && newlist == NULL)
   5776 		return (true);
   5777 	if (oldlist == NULL || newlist == NULL)
   5778 		return (false);
   5779 
   5780 	for (i = 0; i < count; i++) {
   5781 		if (oldlist[i] == NULL && newlist[i] == NULL)
   5782 			continue;
   5783 		if (oldlist[i] == NULL || newlist[i] == NULL ||
   5784 		    !dns_name_equal(oldlist[i], newlist[i]))
   5785 			return (false);
   5786 	}
   5787 	return (true);
   5788 }
   5789 
   5790 static void
   5791 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
   5792 		     dns_name_t ***keynamesp, unsigned int *countp,
   5793 		     isc_mem_t *mctx)
   5794 {
   5795 	unsigned int count;
   5796 	isc_sockaddr_t *addrs;
   5797 	isc_dscp_t *dscps;
   5798 	dns_name_t **keynames;
   5799 
   5800 	REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
   5801 		keynamesp != NULL);
   5802 
   5803 	count = *countp;
   5804 	*countp = 0;
   5805 	addrs = *addrsp;
   5806 	*addrsp = NULL;
   5807 	dscps = *dscpsp;
   5808 	*dscpsp = NULL;
   5809 	keynames = *keynamesp;
   5810 	*keynamesp = NULL;
   5811 
   5812 	if (addrs != NULL)
   5813 		isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
   5814 
   5815 	if (dscps != NULL)
   5816 		isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
   5817 
   5818 	if (keynames != NULL) {
   5819 		unsigned int i;
   5820 		for (i = 0; i < count; i++) {
   5821 			if (keynames[i] != NULL) {
   5822 				dns_name_free(keynames[i], mctx);
   5823 				isc_mem_put(mctx, keynames[i],
   5824 					    sizeof(dns_name_t));
   5825 				keynames[i] = NULL;
   5826 			}
   5827 		}
   5828 		isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
   5829 	}
   5830 }
   5831 
   5832 static isc_result_t
   5833 set_addrkeylist(unsigned int count,
   5834 		const isc_sockaddr_t *addrs, isc_sockaddr_t **newaddrsp,
   5835 		const isc_dscp_t *dscp, isc_dscp_t **newdscpp,
   5836 		dns_name_t **names, dns_name_t ***newnamesp,
   5837 		isc_mem_t *mctx)
   5838 {
   5839 	isc_result_t result;
   5840 	isc_sockaddr_t *newaddrs = NULL;
   5841 	isc_dscp_t *newdscp = NULL;
   5842 	dns_name_t **newnames = NULL;
   5843 	unsigned int i;
   5844 
   5845 	REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
   5846 	REQUIRE(newdscpp != NULL && *newdscpp == NULL);
   5847 	REQUIRE(newnamesp != NULL && *newnamesp == NULL);
   5848 
   5849 	newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
   5850 	if (newaddrs == NULL)
   5851 		return (ISC_R_NOMEMORY);
   5852 	memmove(newaddrs, addrs, count * sizeof(*newaddrs));
   5853 
   5854 	if (dscp != NULL) {
   5855 		newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
   5856 		if (newdscp == NULL) {
   5857 			isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
   5858 			return (ISC_R_NOMEMORY);
   5859 		}
   5860 		memmove(newdscp, dscp, count * sizeof(*newdscp));
   5861 	} else
   5862 		newdscp = NULL;
   5863 
   5864 	if (names != NULL) {
   5865 		newnames = isc_mem_get(mctx, count * sizeof(*newnames));
   5866 		if (newnames == NULL) {
   5867 			if (newdscp != NULL)
   5868 				isc_mem_put(mctx, newdscp,
   5869 					    count * sizeof(*newdscp));
   5870 			isc_mem_put(mctx, newaddrs, count * sizeof(*newaddrs));
   5871 			return (ISC_R_NOMEMORY);
   5872 		}
   5873 		for (i = 0; i < count; i++)
   5874 			newnames[i] = NULL;
   5875 		for (i = 0; i < count; i++) {
   5876 			if (names[i] != NULL) {
   5877 				newnames[i] = isc_mem_get(mctx,
   5878 							 sizeof(dns_name_t));
   5879 				if (newnames[i] == NULL)
   5880 					goto allocfail;
   5881 				dns_name_init(newnames[i], NULL);
   5882 				result = dns_name_dup(names[i], mctx,
   5883 						      newnames[i]);
   5884 				if (result != ISC_R_SUCCESS) {
   5885 				allocfail:
   5886 					for (i = 0; i < count; i++)
   5887 						if (newnames[i] != NULL)
   5888 							dns_name_free(
   5889 							       newnames[i],
   5890 							       mctx);
   5891 					isc_mem_put(mctx, newaddrs,
   5892 						    count * sizeof(*newaddrs));
   5893 					isc_mem_put(mctx, newdscp,
   5894 						    count * sizeof(*newdscp));
   5895 					isc_mem_put(mctx, newnames,
   5896 						    count * sizeof(*newnames));
   5897 					return (ISC_R_NOMEMORY);
   5898 				}
   5899 			}
   5900 		}
   5901 	} else
   5902 		newnames = NULL;
   5903 
   5904 	*newdscpp = newdscp;
   5905 	*newaddrsp = newaddrs;
   5906 	*newnamesp = newnames;
   5907 	return (ISC_R_SUCCESS);
   5908 }
   5909 
   5910 isc_result_t
   5911 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5912 	REQUIRE(DNS_ZONE_VALID(zone));
   5913 
   5914 	LOCK_ZONE(zone);
   5915 	zone->notifysrc6dscp = dscp;
   5916 	UNLOCK_ZONE(zone);
   5917 
   5918 	return (ISC_R_SUCCESS);
   5919 }
   5920 
   5921 isc_dscp_t
   5922 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
   5923 	REQUIRE(DNS_ZONE_VALID(zone));
   5924 	return (zone->notifysrc6dscp);
   5925 }
   5926 
   5927 isc_result_t
   5928 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
   5929 		       uint32_t count)
   5930 {
   5931 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
   5932 					       count));
   5933 }
   5934 
   5935 isc_result_t
   5936 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   5937 			       dns_name_t **keynames, uint32_t count)
   5938 {
   5939 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
   5940 					       count));
   5941 }
   5942 
   5943 isc_result_t
   5944 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   5945 			       const isc_dscp_t *dscps, dns_name_t **keynames,
   5946 			       uint32_t count)
   5947 {
   5948 	isc_result_t result;
   5949 	isc_sockaddr_t *newaddrs = NULL;
   5950 	isc_dscp_t *newdscps = NULL;
   5951 	dns_name_t **newnames = NULL;
   5952 
   5953 	REQUIRE(DNS_ZONE_VALID(zone));
   5954 	REQUIRE(count == 0 || notify != NULL);
   5955 	if (keynames != NULL)
   5956 		REQUIRE(count != 0);
   5957 
   5958 	LOCK_ZONE(zone);
   5959 
   5960 	if (count == zone->notifycnt &&
   5961 	    same_addrs(zone->notify, notify, count) &&
   5962 	    same_keynames(zone->notifykeynames, keynames, count))
   5963 		goto unlock;
   5964 
   5965 	clear_addresskeylist(&zone->notify, &zone->notifydscp,
   5966 			     &zone->notifykeynames, &zone->notifycnt,
   5967 			     zone->mctx);
   5968 
   5969 	if (count == 0)
   5970 		goto unlock;
   5971 
   5972 	/*
   5973 	 * Set up the notify and notifykey lists
   5974 	 */
   5975 	result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
   5976 				 keynames, &newnames, zone->mctx);
   5977 	if (result != ISC_R_SUCCESS)
   5978 		goto unlock;
   5979 
   5980 	/*
   5981 	 * Everything is ok so attach to the zone.
   5982 	 */
   5983 	zone->notify = newaddrs;
   5984 	zone->notifydscp = newdscps;
   5985 	zone->notifykeynames = newnames;
   5986 	zone->notifycnt = count;
   5987  unlock:
   5988 	UNLOCK_ZONE(zone);
   5989 	return (ISC_R_SUCCESS);
   5990 }
   5991 
   5992 isc_result_t
   5993 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
   5994 		    uint32_t count)
   5995 {
   5996 	isc_result_t result;
   5997 
   5998 	result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
   5999 	return (result);
   6000 }
   6001 
   6002 isc_result_t
   6003 dns_zone_setmasterswithkeys(dns_zone_t *zone,
   6004 			    const isc_sockaddr_t *masters,
   6005 			    dns_name_t **keynames,
   6006 			    uint32_t count)
   6007 {
   6008 	isc_result_t result = ISC_R_SUCCESS;
   6009 	isc_sockaddr_t *newaddrs = NULL;
   6010 	isc_dscp_t *newdscps = NULL;
   6011 	dns_name_t **newnames = NULL;
   6012 	bool *newok;
   6013 	unsigned int i;
   6014 
   6015 	REQUIRE(DNS_ZONE_VALID(zone));
   6016 	REQUIRE(count == 0 || masters != NULL);
   6017 	if (keynames != NULL) {
   6018 		REQUIRE(count != 0);
   6019 	}
   6020 
   6021 	LOCK_ZONE(zone);
   6022 	/*
   6023 	 * The refresh code assumes that 'masters' wouldn't change under it.
   6024 	 * If it will change then kill off any current refresh in progress
   6025 	 * and update the masters info.  If it won't change then we can just
   6026 	 * unlock and exit.
   6027 	 */
   6028 	if (count != zone->masterscnt ||
   6029 	    !same_addrs(zone->masters, masters, count) ||
   6030 	    !same_keynames(zone->masterkeynames, keynames, count)) {
   6031 		if (zone->request != NULL)
   6032 			dns_request_cancel(zone->request);
   6033 	} else
   6034 		goto unlock;
   6035 
   6036 	/*
   6037 	 * This needs to happen before clear_addresskeylist() sets
   6038 	 * zone->masterscnt to 0:
   6039 	 */
   6040 	if (zone->mastersok != NULL) {
   6041 		isc_mem_put(zone->mctx, zone->mastersok,
   6042 			    zone->masterscnt * sizeof(bool));
   6043 		zone->mastersok = NULL;
   6044 	}
   6045 	clear_addresskeylist(&zone->masters, &zone->masterdscps,
   6046 			     &zone->masterkeynames, &zone->masterscnt,
   6047 			     zone->mctx);
   6048 	/*
   6049 	 * If count == 0, don't allocate any space for masters, mastersok or
   6050 	 * keynames so internally, those pointers are NULL if count == 0
   6051 	 */
   6052 	if (count == 0)
   6053 		goto unlock;
   6054 
   6055 	/*
   6056 	 * mastersok must contain count elements
   6057 	 */
   6058 	newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
   6059 	if (newok == NULL) {
   6060 		result = ISC_R_NOMEMORY;
   6061 		isc_mem_put(zone->mctx, newaddrs, count * sizeof(*newaddrs));
   6062 		goto unlock;
   6063 	};
   6064 	for (i = 0; i < count; i++)
   6065 		newok[i] = false;
   6066 
   6067 	/*
   6068 	 * Now set up the masters and masterkey lists
   6069 	 */
   6070 	result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
   6071 				 keynames, &newnames, zone->mctx);
   6072 	INSIST(newdscps == NULL);
   6073 	if (result != ISC_R_SUCCESS) {
   6074 		isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
   6075 		goto unlock;
   6076 	}
   6077 
   6078 	/*
   6079 	 * Everything is ok so attach to the zone.
   6080 	 */
   6081 	zone->curmaster = 0;
   6082 	zone->mastersok = newok;
   6083 	zone->masters = newaddrs;
   6084 	zone->masterdscps = newdscps;
   6085 	zone->masterkeynames = newnames;
   6086 	zone->masterscnt = count;
   6087 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   6088 
   6089  unlock:
   6090 	UNLOCK_ZONE(zone);
   6091 	return (result);
   6092 }
   6093 
   6094 isc_result_t
   6095 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
   6096 	isc_result_t result = ISC_R_SUCCESS;
   6097 
   6098 	REQUIRE(DNS_ZONE_VALID(zone));
   6099 
   6100 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   6101 	if (zone->db == NULL)
   6102 		result = DNS_R_NOTLOADED;
   6103 	else
   6104 		dns_db_attach(zone->db, dpb);
   6105 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   6106 
   6107 	return (result);
   6108 }
   6109 
   6110 void
   6111 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
   6112 	REQUIRE(DNS_ZONE_VALID(zone));
   6113 	REQUIRE(zone->type == dns_zone_staticstub);
   6114 
   6115 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   6116 	REQUIRE(zone->db == NULL);
   6117 	dns_db_attach(db, &zone->db);
   6118 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   6119 }
   6120 
   6121 /*
   6122  * Co-ordinates the starting of routine jobs.
   6123  */
   6124 void
   6125 dns_zone_maintenance(dns_zone_t *zone) {
   6126 	const char me[] = "dns_zone_maintenance";
   6127 	isc_time_t now;
   6128 
   6129 	REQUIRE(DNS_ZONE_VALID(zone));
   6130 	ENTER;
   6131 
   6132 	LOCK_ZONE(zone);
   6133 	TIME_NOW(&now);
   6134 	zone_settimer(zone, &now);
   6135 	UNLOCK_ZONE(zone);
   6136 }
   6137 
   6138 static inline bool
   6139 was_dumping(dns_zone_t *zone) {
   6140 	bool dumping;
   6141 
   6142 	REQUIRE(LOCKED_ZONE(zone));
   6143 
   6144 	dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
   6145 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   6146 	if (!dumping) {
   6147 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   6148 		isc_time_settoepoch(&zone->dumptime);
   6149 	}
   6150 	return (dumping);
   6151 }
   6152 
   6153 /*%
   6154  * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database
   6155  * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'.
   6156  * Only load the public part of a given key if it is not active at timestamp
   6157  * 'now'.  Store the number of keys found in 'nkeys'.
   6158  */
   6159 isc_result_t
   6160 dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   6161 		   isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys,
   6162 		   dst_key_t **keys, unsigned int *nkeys)
   6163 {
   6164 	isc_result_t result;
   6165 	dns_dbnode_t *node = NULL;
   6166 	const char *directory = dns_zone_getkeydirectory(zone);
   6167 
   6168 	CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
   6169 	memset(keys, 0, sizeof(*keys) * maxkeys);
   6170 	result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
   6171 					 directory, now, mctx, maxkeys, keys,
   6172 					 nkeys);
   6173 	if (result == ISC_R_NOTFOUND)
   6174 		result = ISC_R_SUCCESS;
   6175  failure:
   6176 	if (node != NULL)
   6177 		dns_db_detachnode(db, &node);
   6178 	return (result);
   6179 }
   6180 
   6181 static isc_result_t
   6182 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff,
   6183 	dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
   6184 {
   6185 	isc_result_t result;
   6186 
   6187 	if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
   6188 		return (ISC_R_SUCCESS);
   6189 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
   6190 			       name, ttl, rdata);
   6191 	if (result != ISC_R_SUCCESS)
   6192 		return (result);
   6193 	rdata->flags |= DNS_RDATA_OFFLINE;
   6194 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
   6195 			       name, ttl, rdata);
   6196 	zonediff->offline = true;
   6197 	return (result);
   6198 }
   6199 
   6200 static void
   6201 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
   6202 {
   6203 	unsigned int delta;
   6204 	char timebuf[80];
   6205 
   6206 	zone->key_expiry = when;
   6207 	if (when <= now) {
   6208 		dns_zone_log(zone, ISC_LOG_ERROR,
   6209 			     "DNSKEY RRSIG(s) have expired");
   6210 		isc_time_settoepoch(&zone->keywarntime);
   6211 	} else if (when < now + 7 * 24 * 3600) {
   6212 		isc_time_t t;
   6213 		isc_time_set(&t, when, 0);
   6214 		isc_time_formattimestamp(&t, timebuf, 80);
   6215 		dns_zone_log(zone, ISC_LOG_WARNING,
   6216 			     "DNSKEY RRSIG(s) will expire within 7 days: %s",
   6217 			     timebuf);
   6218 		delta = when - now;
   6219 		delta--;		/* loop prevention */
   6220 		delta /= 24 * 3600;	/* to whole days */
   6221 		delta *= 24 * 3600;	/* to seconds */
   6222 		isc_time_set(&zone->keywarntime, when - delta, 0);
   6223 	}  else {
   6224 		isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
   6225 		isc_time_formattimestamp(&zone->keywarntime, timebuf, 80);
   6226 		dns_zone_log(zone, ISC_LOG_NOTICE,
   6227 			     "setting keywarntime to %s", timebuf);
   6228 	}
   6229 }
   6230 
   6231 /*
   6232  * Helper function to del_sigs(). We don't want to delete RRSIGs that
   6233  * have no new key.
   6234  */
   6235 static bool
   6236 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
   6237 	  bool *warn)
   6238 {
   6239 	unsigned int i = 0;
   6240 	bool have_ksk = false, have_zsk = false;
   6241 	bool have_pksk = false, have_pzsk = false;
   6242 
   6243 	for (i = 0; i < nkeys; i++) {
   6244 		if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
   6245 			continue;
   6246 		if (dst_key_isprivate(keys[i])) {
   6247 			if (KSK(keys[i]))
   6248 				have_ksk = have_pksk = true;
   6249 			else
   6250 				have_zsk = have_pzsk = true;
   6251 		} else {
   6252 			if (KSK(keys[i]))
   6253 				have_ksk = true;
   6254 			else
   6255 				have_zsk = true;
   6256 		}
   6257 	}
   6258 
   6259 	if (have_zsk && have_ksk && !have_pzsk)
   6260 		*warn = true;
   6261 
   6262 	/*
   6263 	 * It's okay to delete a signature if there is an active key
   6264 	 * with the same algorithm to replace it.
   6265 	 */
   6266 	if (have_pksk || have_pzsk)
   6267 		return (true);
   6268 
   6269 	/*
   6270 	 * Failing that, it is *not* okay to delete a signature
   6271 	 * if the associated public key is still in the DNSKEY RRset
   6272 	 */
   6273 	for (i = 0; i < nkeys; i++) {
   6274 		if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
   6275 		    (rrsig_ptr->keyid == dst_key_id(keys[i])))
   6276 			return (false);
   6277 	}
   6278 
   6279 	/*
   6280 	 * But if the key is gone, then go ahead.
   6281 	 */
   6282 	return (true);
   6283 }
   6284 
   6285 /*
   6286  * Delete expired RRsigs and any RRsigs we are about to re-sign.
   6287  * See also update.c:del_keysigs().
   6288  */
   6289 static isc_result_t
   6290 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   6291 	 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys,
   6292 	 unsigned int nkeys, isc_stdtime_t now, bool incremental)
   6293 {
   6294 	isc_result_t result;
   6295 	dns_dbnode_t *node = NULL;
   6296 	dns_rdataset_t rdataset;
   6297 	unsigned int i;
   6298 	dns_rdata_rrsig_t rrsig;
   6299 	bool found;
   6300 	int64_t timewarn = 0, timemaybe = 0;
   6301 
   6302 	dns_rdataset_init(&rdataset);
   6303 
   6304 	if (type == dns_rdatatype_nsec3)
   6305 		result = dns_db_findnsec3node(db, name, false, &node);
   6306 	else
   6307 		result = dns_db_findnode(db, name, false, &node);
   6308 	if (result == ISC_R_NOTFOUND)
   6309 		return (ISC_R_SUCCESS);
   6310 	if (result != ISC_R_SUCCESS)
   6311 		goto failure;
   6312 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
   6313 				     (isc_stdtime_t) 0, &rdataset, NULL);
   6314 	dns_db_detachnode(db, &node);
   6315 
   6316 	if (result == ISC_R_NOTFOUND) {
   6317 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6318 		return (ISC_R_SUCCESS);
   6319 	}
   6320 	if (result != ISC_R_SUCCESS) {
   6321 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6322 		goto failure;
   6323 	}
   6324 
   6325 	for (result = dns_rdataset_first(&rdataset);
   6326 	     result == ISC_R_SUCCESS;
   6327 	     result = dns_rdataset_next(&rdataset)) {
   6328 		dns_rdata_t rdata = DNS_RDATA_INIT;
   6329 
   6330 		dns_rdataset_current(&rdataset, &rdata);
   6331 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   6332 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6333 
   6334 		if (type != dns_rdatatype_dnskey) {
   6335 			bool warn = false, deleted = false;
   6336 			if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
   6337 				result = update_one_rr(db, ver, zonediff->diff,
   6338 					       DNS_DIFFOP_DELRESIGN, name,
   6339 					       rdataset.ttl, &rdata);
   6340 				if (result != ISC_R_SUCCESS)
   6341 					break;
   6342 				deleted = true;
   6343 			}
   6344 			if (warn) {
   6345 				/*
   6346 				 * At this point, we've got an RRSIG,
   6347 				 * which is signed by an inactive key.
   6348 				 * An administrator needs to provide a new
   6349 				 * key/alg, but until that time, we want to
   6350 				 * keep the old RRSIG.  Marking the key as
   6351 				 * offline will prevent us spinning waiting
   6352 				 * for the private part.
   6353 				 */
   6354 				if (incremental && !deleted) {
   6355 					result = offline(db, ver, zonediff,
   6356 							 name, rdataset.ttl,
   6357 							 &rdata);
   6358 					if (result != ISC_R_SUCCESS)
   6359 						break;
   6360 				}
   6361 
   6362 				/*
   6363 				 * Log the key id and algorithm of
   6364 				 * the inactive key with no replacement
   6365 				 */
   6366 				if (zone->log_key_expired_timer <= now) {
   6367 					char origin[DNS_NAME_FORMATSIZE];
   6368 					char algbuf[DNS_NAME_FORMATSIZE];
   6369 					dns_name_format(&zone->origin, origin,
   6370 							sizeof(origin));
   6371 					dns_secalg_format(rrsig.algorithm,
   6372 							  algbuf,
   6373 							  sizeof(algbuf));
   6374 					dns_zone_log(zone, ISC_LOG_WARNING,
   6375 						     "Key %s/%s/%d "
   6376 						     "missing or inactive "
   6377 						     "and has no replacement: "
   6378 						     "retaining signatures.",
   6379 						     origin, algbuf,
   6380 						     rrsig.keyid);
   6381 					zone->log_key_expired_timer = now +
   6382 									3600;
   6383 				}
   6384 			}
   6385 			continue;
   6386 		}
   6387 
   6388 		/*
   6389 		 * RRSIG(DNSKEY) requires special processing.
   6390 		 */
   6391 		found = false;
   6392 		for (i = 0; i < nkeys; i++) {
   6393 			if (rrsig.algorithm == dst_key_alg(keys[i]) &&
   6394 			    rrsig.keyid == dst_key_id(keys[i])) {
   6395 				found = true;
   6396 				/*
   6397 				 * Mark offline RRSIG(DNSKEY).
   6398 				 * We want the earliest offline expire time
   6399 				 * iff there is a new offline signature.
   6400 				 */
   6401 				if (!dst_key_inactive(keys[i]) &&
   6402 				    !dst_key_isprivate(keys[i]))
   6403 				{
   6404 					int64_t timeexpire =
   6405 					   dns_time64_from32(rrsig.timeexpire);
   6406 					if (timewarn != 0 &&
   6407 					    timewarn > timeexpire)
   6408 						timewarn = timeexpire;
   6409 					if (rdata.flags & DNS_RDATA_OFFLINE) {
   6410 						if (timemaybe == 0 ||
   6411 						    timemaybe > timeexpire)
   6412 							timemaybe = timeexpire;
   6413 						break;
   6414 					}
   6415 					if (timewarn == 0)
   6416 						timewarn = timemaybe;
   6417 					if (timewarn == 0 ||
   6418 					    timewarn > timeexpire)
   6419 						timewarn = timeexpire;
   6420 					result = offline(db, ver, zonediff,
   6421 							 name, rdataset.ttl,
   6422 							 &rdata);
   6423 					break;
   6424 				}
   6425 				result = update_one_rr(db, ver, zonediff->diff,
   6426 						       DNS_DIFFOP_DELRESIGN,
   6427 						       name, rdataset.ttl,
   6428 						       &rdata);
   6429 				break;
   6430 			}
   6431 		}
   6432 
   6433 		/*
   6434 		 * If there is not a matching DNSKEY then
   6435 		 * delete the RRSIG.
   6436 		 */
   6437 		if (!found)
   6438 			result = update_one_rr(db, ver, zonediff->diff,
   6439 					       DNS_DIFFOP_DELRESIGN, name,
   6440 					       rdataset.ttl, &rdata);
   6441 		if (result != ISC_R_SUCCESS)
   6442 			break;
   6443 	}
   6444 
   6445 	dns_rdataset_disassociate(&rdataset);
   6446 	if (result == ISC_R_NOMORE)
   6447 		result = ISC_R_SUCCESS;
   6448 	if (timewarn > 0) {
   6449 		isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
   6450 		if (timewarn == stdwarn) {
   6451 			set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
   6452 					       now);
   6453 		} else {
   6454 			dns_zone_log(zone, ISC_LOG_ERROR,
   6455 				     "key expiry warning time out of range");
   6456 		}
   6457 	}
   6458  failure:
   6459 	if (node != NULL)
   6460 		dns_db_detachnode(db, &node);
   6461 	return (result);
   6462 }
   6463 
   6464 static isc_result_t
   6465 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   6466 	 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
   6467 	 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
   6468 	 isc_stdtime_t expire, bool check_ksk,
   6469 	 bool keyset_kskonly)
   6470 {
   6471 	isc_result_t result;
   6472 	dns_dbnode_t *node = NULL;
   6473 	dns_rdataset_t rdataset;
   6474 	dns_rdata_t sig_rdata = DNS_RDATA_INIT;
   6475 	unsigned char data[1024]; /* XXX */
   6476 	isc_buffer_t buffer;
   6477 	unsigned int i, j;
   6478 
   6479 	dns_rdataset_init(&rdataset);
   6480 	isc_buffer_init(&buffer, data, sizeof(data));
   6481 
   6482 	if (type == dns_rdatatype_nsec3)
   6483 		result = dns_db_findnsec3node(db, name, false, &node);
   6484 	else
   6485 		result = dns_db_findnode(db, name, false, &node);
   6486 	if (result == ISC_R_NOTFOUND)
   6487 		return (ISC_R_SUCCESS);
   6488 	if (result != ISC_R_SUCCESS)
   6489 		goto failure;
   6490 	result = dns_db_findrdataset(db, node, ver, type, 0,
   6491 				     (isc_stdtime_t) 0, &rdataset, NULL);
   6492 	dns_db_detachnode(db, &node);
   6493 	if (result == ISC_R_NOTFOUND) {
   6494 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6495 		return (ISC_R_SUCCESS);
   6496 	}
   6497 	if (result != ISC_R_SUCCESS) {
   6498 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6499 		goto failure;
   6500 	}
   6501 
   6502 	for (i = 0; i < nkeys; i++) {
   6503 		bool both = false;
   6504 
   6505 		if (!dst_key_isprivate(keys[i]))
   6506 			continue;
   6507 		if (dst_key_inactive(keys[i]))	/* Should be redundant. */
   6508 			continue;
   6509 
   6510 		if (check_ksk && !REVOKE(keys[i])) {
   6511 			bool have_ksk, have_nonksk;
   6512 			if (KSK(keys[i])) {
   6513 				have_ksk = true;
   6514 				have_nonksk = false;
   6515 			} else {
   6516 				have_ksk = false;
   6517 				have_nonksk = true;
   6518 			}
   6519 			for (j = 0; j < nkeys; j++) {
   6520 				if (j == i || ALG(keys[i]) != ALG(keys[j]))
   6521 					continue;
   6522 				if (!dst_key_isprivate(keys[j]))
   6523 					continue;
   6524 				if (dst_key_inactive(keys[j]))	/* SBR */
   6525 					continue;
   6526 				if (REVOKE(keys[j]))
   6527 					continue;
   6528 				if (KSK(keys[j]))
   6529 					have_ksk = true;
   6530 				else
   6531 					have_nonksk = true;
   6532 				both = have_ksk && have_nonksk;
   6533 				if (both)
   6534 					break;
   6535 			}
   6536 		}
   6537 		if (both) {
   6538 			/*
   6539 			 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
   6540 			 */
   6541 			if (type == dns_rdatatype_dnskey ||
   6542 			    type == dns_rdatatype_cdnskey ||
   6543 			    type == dns_rdatatype_cds)
   6544 			{
   6545 				if (!KSK(keys[i]) && keyset_kskonly)
   6546 					continue;
   6547 			} else if (KSK(keys[i])) {
   6548 				continue;
   6549 			}
   6550 		} else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   6551 			continue;
   6552 		}
   6553 
   6554 		/* Calculate the signature, creating a RRSIG RDATA. */
   6555 		isc_buffer_clear(&buffer);
   6556 		CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
   6557 				      &inception, &expire,
   6558 				      mctx, &buffer, &sig_rdata));
   6559 		/* Update the database and journal with the RRSIG. */
   6560 		/* XXX inefficient - will cause dataset merging */
   6561 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
   6562 				    name, rdataset.ttl, &sig_rdata));
   6563 		dns_rdata_reset(&sig_rdata);
   6564 		isc_buffer_init(&buffer, data, sizeof(data));
   6565 	}
   6566 
   6567  failure:
   6568 	if (dns_rdataset_isassociated(&rdataset))
   6569 		dns_rdataset_disassociate(&rdataset);
   6570 	if (node != NULL)
   6571 		dns_db_detachnode(db, &node);
   6572 	return (result);
   6573 }
   6574 
   6575 static void
   6576 zone_resigninc(dns_zone_t *zone) {
   6577 	const char *me = "zone_resigninc";
   6578 	dns_db_t *db = NULL;
   6579 	dns_dbversion_t *version = NULL;
   6580 	dns_diff_t _sig_diff;
   6581 	dns__zonediff_t zonediff;
   6582 	dns_fixedname_t fixed;
   6583 	dns_name_t *name;
   6584 	dns_rdataset_t rdataset;
   6585 	dns_rdatatype_t covers;
   6586 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   6587 	bool check_ksk, keyset_kskonly = false;
   6588 	isc_result_t result;
   6589 	isc_stdtime_t now, inception, soaexpire, expire, stop;
   6590 	uint32_t jitter, sigvalidityinterval;
   6591 	unsigned int i;
   6592 	unsigned int nkeys = 0;
   6593 	unsigned int resign;
   6594 
   6595 	ENTER;
   6596 
   6597 	dns_rdataset_init(&rdataset);
   6598 	dns_diff_init(zone->mctx, &_sig_diff);
   6599 	zonediff_init(&zonediff, &_sig_diff);
   6600 
   6601 	/*
   6602 	 * Zone is frozen or automatic resigning is disabled.
   6603 	 * Pause for 5 minutes.
   6604 	 */
   6605 	if (zone->update_disabled ||
   6606 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
   6607 	{
   6608 		result = ISC_R_FAILURE;
   6609 		goto failure;
   6610 	}
   6611 
   6612 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   6613 	dns_db_attach(zone->db, &db);
   6614 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   6615 
   6616 	result = dns_db_newversion(db, &version);
   6617 	if (result != ISC_R_SUCCESS) {
   6618 		dns_zone_log(zone, ISC_LOG_ERROR,
   6619 			     "zone_resigninc:dns_db_newversion -> %s",
   6620 			     dns_result_totext(result));
   6621 		goto failure;
   6622 	}
   6623 
   6624 	isc_stdtime_get(&now);
   6625 
   6626 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   6627 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   6628 	if (result != ISC_R_SUCCESS) {
   6629 		dns_zone_log(zone, ISC_LOG_ERROR,
   6630 			     "zone_resigninc:dns__zone_findkeys -> %s",
   6631 			     dns_result_totext(result));
   6632 		goto failure;
   6633 	}
   6634 
   6635 	sigvalidityinterval = zone->sigvalidityinterval;
   6636 	inception = now - 3600;	/* Allow for clock skew. */
   6637 	soaexpire = now + sigvalidityinterval;
   6638 	/*
   6639 	 * Spread out signatures over time if they happen to be
   6640 	 * clumped.  We don't do this for each add_sigs() call as
   6641 	 * we still want some clustering to occur.
   6642 	 */
   6643 	if (sigvalidityinterval >= 3600U) {
   6644 		if (sigvalidityinterval > 7200U) {
   6645 			jitter = isc_random_uniform(3600);
   6646 		} else {
   6647 			jitter = isc_random_uniform(1200);
   6648 		}
   6649 		expire = soaexpire - jitter - 1;
   6650 	} else {
   6651 		expire = soaexpire - 1;
   6652 	}
   6653 	stop = now + 5;
   6654 
   6655 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   6656 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   6657 
   6658 	name = dns_fixedname_initname(&fixed);
   6659 	result = dns_db_getsigningtime(db, &rdataset, name);
   6660 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   6661 		dns_zone_log(zone, ISC_LOG_ERROR,
   6662 			     "zone_resigninc:dns_db_getsigningtime -> %s",
   6663 			     dns_result_totext(result));
   6664 	}
   6665 
   6666 	i = 0;
   6667 	while (result == ISC_R_SUCCESS) {
   6668 		resign = rdataset.resign - zone->sigresigninginterval;
   6669 		covers = rdataset.covers;
   6670 		dns_rdataset_disassociate(&rdataset);
   6671 
   6672 		/*
   6673 		 * Stop if we hit the SOA as that means we have walked the
   6674 		 * entire zone.  The SOA record should always be the most
   6675 		 * recent signature.
   6676 		 */
   6677 		/* XXXMPA increase number of RRsets signed pre call */
   6678 		if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
   6679 		    resign > stop)
   6680 			break;
   6681 
   6682 		result = del_sigs(zone, db, version, name, covers, &zonediff,
   6683 				  zone_keys, nkeys, now, true);
   6684 		if (result != ISC_R_SUCCESS) {
   6685 			dns_zone_log(zone, ISC_LOG_ERROR,
   6686 				     "zone_resigninc:del_sigs -> %s",
   6687 				     dns_result_totext(result));
   6688 			break;
   6689 		}
   6690 
   6691 		result = add_sigs(db, version, name, covers, zonediff.diff,
   6692 				  zone_keys, nkeys, zone->mctx, inception,
   6693 				  expire, check_ksk, keyset_kskonly);
   6694 		if (result != ISC_R_SUCCESS) {
   6695 			dns_zone_log(zone, ISC_LOG_ERROR,
   6696 				     "zone_resigninc:add_sigs -> %s",
   6697 				     dns_result_totext(result));
   6698 			break;
   6699 		}
   6700 		result	= dns_db_getsigningtime(db, &rdataset, name);
   6701 		if (nkeys == 0 && result == ISC_R_NOTFOUND) {
   6702 			result = ISC_R_SUCCESS;
   6703 			break;
   6704 		}
   6705 		if (result != ISC_R_SUCCESS)
   6706 			dns_zone_log(zone, ISC_LOG_ERROR,
   6707 			     "zone_resigninc:dns_db_getsigningtime -> %s",
   6708 				     dns_result_totext(result));
   6709 	}
   6710 
   6711 	if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
   6712 		goto failure;
   6713 
   6714 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   6715 			  &zonediff, zone_keys, nkeys, now, true);
   6716 	if (result != ISC_R_SUCCESS) {
   6717 		dns_zone_log(zone, ISC_LOG_ERROR,
   6718 			     "zone_resigninc:del_sigs -> %s",
   6719 			     dns_result_totext(result));
   6720 		goto failure;
   6721 	}
   6722 
   6723 	/*
   6724 	 * Did we change anything in the zone?
   6725 	 */
   6726 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   6727 		/*
   6728 		 * Commit the changes if any key has been marked as offline.
   6729 		 */
   6730 		if (zonediff.offline)
   6731 			dns_db_closeversion(db, &version, true);
   6732 		goto failure;
   6733 	}
   6734 
   6735 	/* Increment SOA serial if we have made changes */
   6736 	result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
   6737 				   zone->updatemethod);
   6738 	if (result != ISC_R_SUCCESS) {
   6739 		dns_zone_log(zone, ISC_LOG_ERROR,
   6740 			     "zone_resigninc:update_soa_serial -> %s",
   6741 			     dns_result_totext(result));
   6742 		goto failure;
   6743 	}
   6744 
   6745 	/*
   6746 	 * Generate maximum life time signatures so that the above loop
   6747 	 * termination is sensible.
   6748 	 */
   6749 	result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
   6750 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   6751 			  inception, soaexpire, check_ksk, keyset_kskonly);
   6752 	if (result != ISC_R_SUCCESS) {
   6753 		dns_zone_log(zone, ISC_LOG_ERROR,
   6754 			     "zone_resigninc:add_sigs -> %s",
   6755 			     dns_result_totext(result));
   6756 		goto failure;
   6757 	}
   6758 
   6759 	/* Write changes to journal file. */
   6760 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
   6761 
   6762 	/* Everything has succeeded. Commit the changes. */
   6763 	dns_db_closeversion(db, &version, true);
   6764 
   6765  failure:
   6766 	dns_diff_clear(&_sig_diff);
   6767 	for (i = 0; i < nkeys; i++)
   6768 		dst_key_free(&zone_keys[i]);
   6769 	if (version != NULL) {
   6770 		dns_db_closeversion(db, &version, false);
   6771 		dns_db_detach(&db);
   6772 	} else if (db != NULL)
   6773 		dns_db_detach(&db);
   6774 	if (result == ISC_R_SUCCESS) {
   6775 		set_resigntime(zone);
   6776 		LOCK_ZONE(zone);
   6777 		zone_needdump(zone, DNS_DUMP_DELAY);
   6778 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   6779 		UNLOCK_ZONE(zone);
   6780 	} else {
   6781 		/*
   6782 		 * Something failed.  Retry in 5 minutes.
   6783 		 */
   6784 		isc_interval_t ival;
   6785 		isc_interval_set(&ival, 300, 0);
   6786 		isc_time_nowplusinterval(&zone->resigntime, &ival);
   6787 	}
   6788 
   6789 	INSIST(version == NULL);
   6790 }
   6791 
   6792 static isc_result_t
   6793 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
   6794 	    dns_name_t *newname, bool bottom)
   6795 {
   6796 	isc_result_t result;
   6797 	dns_dbiterator_t *dbit = NULL;
   6798 	dns_rdatasetiter_t *rdsit = NULL;
   6799 	dns_dbnode_t *node = NULL;
   6800 
   6801 	CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
   6802 	CHECK(dns_dbiterator_seek(dbit, oldname));
   6803 	do {
   6804 		result = dns_dbiterator_next(dbit);
   6805 		if (result == ISC_R_NOMORE)
   6806 			CHECK(dns_dbiterator_first(dbit));
   6807 		CHECK(dns_dbiterator_current(dbit, &node, newname));
   6808 		if (bottom && dns_name_issubdomain(newname, oldname) &&
   6809 		    !dns_name_equal(newname, oldname)) {
   6810 			dns_db_detachnode(db, &node);
   6811 			continue;
   6812 		}
   6813 		/*
   6814 		 * Is this node empty?
   6815 		 */
   6816 		CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
   6817 		result = dns_rdatasetiter_first(rdsit);
   6818 		dns_db_detachnode(db, &node);
   6819 		dns_rdatasetiter_destroy(&rdsit);
   6820 		if (result != ISC_R_NOMORE)
   6821 			break;
   6822 	} while (1);
   6823  failure:
   6824 	if (node != NULL)
   6825 		dns_db_detachnode(db, &node);
   6826 	if (dbit != NULL)
   6827 		dns_dbiterator_destroy(&dbit);
   6828 	return (result);
   6829 }
   6830 
   6831 static bool
   6832 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   6833 		dns_rdatatype_t type, dst_key_t *key)
   6834 {
   6835 	isc_result_t result;
   6836 	dns_rdataset_t rdataset;
   6837 	dns_rdata_t rdata = DNS_RDATA_INIT;
   6838 	dns_rdata_rrsig_t rrsig;
   6839 
   6840 	dns_rdataset_init(&rdataset);
   6841 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
   6842 				     type, 0, &rdataset, NULL);
   6843 	if (result != ISC_R_SUCCESS) {
   6844 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6845 		return (false);
   6846 	}
   6847 	for (result = dns_rdataset_first(&rdataset);
   6848 	     result == ISC_R_SUCCESS;
   6849 	     result = dns_rdataset_next(&rdataset)) {
   6850 		dns_rdataset_current(&rdataset, &rdata);
   6851 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   6852 		INSIST(result == ISC_R_SUCCESS);
   6853 		if (rrsig.algorithm == dst_key_alg(key) &&
   6854 		    rrsig.keyid == dst_key_id(key)) {
   6855 			dns_rdataset_disassociate(&rdataset);
   6856 			return (true);
   6857 		}
   6858 		dns_rdata_reset(&rdata);
   6859 	}
   6860 	dns_rdataset_disassociate(&rdataset);
   6861 	return (false);
   6862 }
   6863 
   6864 static isc_result_t
   6865 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   6866 	 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom,
   6867 	 dns_diff_t *diff)
   6868 {
   6869 	dns_fixedname_t fixed;
   6870 	dns_name_t *next;
   6871 	dns_rdata_t rdata = DNS_RDATA_INIT;
   6872 	isc_result_t result;
   6873 	unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
   6874 
   6875 	next = dns_fixedname_initname(&fixed);
   6876 
   6877 	CHECK(next_active(db, version, name, next, bottom));
   6878 	CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
   6879 				  &rdata));
   6880 	CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
   6881 			    &rdata));
   6882  failure:
   6883 	return (result);
   6884 }
   6885 
   6886 static isc_result_t
   6887 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node,
   6888 			dns_dbversion_t *version, bool *is_bottom_of_zone)
   6889 {
   6890 	isc_result_t result;
   6891 	dns_rdatasetiter_t *iterator = NULL;
   6892 	dns_rdataset_t rdataset;
   6893 	bool seen_soa = false, seen_ns = false, seen_dname = false;
   6894 
   6895 	REQUIRE(is_bottom_of_zone != NULL);
   6896 
   6897 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   6898 	if (result != ISC_R_SUCCESS) {
   6899 		if (result == ISC_R_NOTFOUND) {
   6900 			result = ISC_R_SUCCESS;
   6901 		}
   6902 		return (result);
   6903 	}
   6904 
   6905 	dns_rdataset_init(&rdataset);
   6906 	for (result = dns_rdatasetiter_first(iterator);
   6907 	     result == ISC_R_SUCCESS;
   6908 	     result = dns_rdatasetiter_next(iterator)) {
   6909 		dns_rdatasetiter_current(iterator, &rdataset);
   6910 		switch (rdataset.type) {
   6911 		case dns_rdatatype_soa:
   6912 			seen_soa = true;
   6913 			break;
   6914 		case dns_rdatatype_ns:
   6915 			seen_ns = true;
   6916 			break;
   6917 		case dns_rdatatype_dname:
   6918 			seen_dname = true;
   6919 			break;
   6920 		}
   6921 		dns_rdataset_disassociate(&rdataset);
   6922 	}
   6923 	if (result != ISC_R_NOMORE) {
   6924 		goto failure;
   6925 	}
   6926 	if ((seen_ns && !seen_soa) || seen_dname) {
   6927 		*is_bottom_of_zone = true;
   6928 	}
   6929 	result = ISC_R_SUCCESS;
   6930 
   6931  failure:
   6932 	dns_rdatasetiter_destroy(&iterator);
   6933 
   6934 	return (result);
   6935 }
   6936 
   6937 static isc_result_t
   6938 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
   6939 	    dns_dbversion_t *version, bool build_nsec3,
   6940 	    bool build_nsec, dst_key_t *key,
   6941 	    isc_stdtime_t inception, isc_stdtime_t expire,
   6942 	    unsigned int minimum, bool is_ksk,
   6943 	    bool keyset_kskonly, bool is_bottom_of_zone,
   6944 	    dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx)
   6945 {
   6946 	isc_result_t result;
   6947 	dns_rdatasetiter_t *iterator = NULL;
   6948 	dns_rdataset_t rdataset;
   6949 	dns_rdata_t rdata = DNS_RDATA_INIT;
   6950 	isc_buffer_t buffer;
   6951 	unsigned char data[1024];
   6952 	bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds;
   6953 
   6954 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   6955 	if (result != ISC_R_SUCCESS) {
   6956 		if (result == ISC_R_NOTFOUND)
   6957 			result = ISC_R_SUCCESS;
   6958 		return (result);
   6959 	}
   6960 
   6961 	dns_rdataset_init(&rdataset);
   6962 	isc_buffer_init(&buffer, data, sizeof(data));
   6963 	seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false;
   6964 	for (result = dns_rdatasetiter_first(iterator);
   6965 	     result == ISC_R_SUCCESS;
   6966 	     result = dns_rdatasetiter_next(iterator)) {
   6967 		dns_rdatasetiter_current(iterator, &rdataset);
   6968 		if (rdataset.type == dns_rdatatype_soa)
   6969 			seen_soa = true;
   6970 		else if (rdataset.type == dns_rdatatype_ns)
   6971 			seen_ns = true;
   6972 		else if (rdataset.type == dns_rdatatype_ds)
   6973 			seen_ds = true;
   6974 		else if (rdataset.type == dns_rdatatype_nsec)
   6975 			seen_nsec = true;
   6976 		else if (rdataset.type == dns_rdatatype_nsec3)
   6977 			seen_nsec3 = true;
   6978 		if (rdataset.type != dns_rdatatype_rrsig)
   6979 			seen_rr = true;
   6980 		dns_rdataset_disassociate(&rdataset);
   6981 	}
   6982 	if (result != ISC_R_NOMORE)
   6983 		goto failure;
   6984 	/*
   6985 	 * Going from insecure to NSEC3.
   6986 	 * Don't generate NSEC3 records for NSEC3 records.
   6987 	 */
   6988 	if (build_nsec3 && !seen_nsec3 && seen_rr) {
   6989 		bool unsecure = !seen_ds && seen_ns && !seen_soa;
   6990 		CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
   6991 					  unsecure, diff));
   6992 		(*signatures)--;
   6993 	}
   6994 	/*
   6995 	 * Going from insecure to NSEC.
   6996 	 * Don't generate NSEC records for NSEC3 records.
   6997 	 */
   6998 	if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
   6999 		/*
   7000 		 * Build a NSEC record except at the origin.
   7001 		 */
   7002 		if (!dns_name_equal(name, dns_db_origin(db))) {
   7003 			CHECK(add_nsec(db, version, name, node, minimum,
   7004 				       is_bottom_of_zone, diff));
   7005 			/* Count a NSEC generation as a signature generation. */
   7006 			(*signatures)--;
   7007 		}
   7008 	}
   7009 	result = dns_rdatasetiter_first(iterator);
   7010 	while (result == ISC_R_SUCCESS) {
   7011 		dns_rdatasetiter_current(iterator, &rdataset);
   7012 		if (rdataset.type == dns_rdatatype_soa ||
   7013 		    rdataset.type == dns_rdatatype_rrsig)
   7014 		{
   7015 			goto next_rdataset;
   7016 		}
   7017 		if (rdataset.type == dns_rdatatype_dnskey ||
   7018 		    rdataset.type == dns_rdatatype_cdnskey ||
   7019 		    rdataset.type == dns_rdatatype_cds)
   7020 		{
   7021 			/*
   7022 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7023 			 * (RFC 7344, section 4.1 specifies that they must
   7024 			 * be signed with a key in the current DS RRset,
   7025 			 * which would only include KSK's.)
   7026 			 */
   7027 			if (!is_ksk && keyset_kskonly) {
   7028 				goto next_rdataset;
   7029 			}
   7030 		} else if (is_ksk) {
   7031 			goto next_rdataset;
   7032 		}
   7033 		if (seen_ns && !seen_soa &&
   7034 		    rdataset.type != dns_rdatatype_ds &&
   7035 		    rdataset.type != dns_rdatatype_nsec)
   7036 		{
   7037 			goto next_rdataset;
   7038 		}
   7039 		if (signed_with_key(db, node, version, rdataset.type, key)) {
   7040 			goto next_rdataset;
   7041 		}
   7042 		/* Calculate the signature, creating a RRSIG RDATA. */
   7043 		isc_buffer_clear(&buffer);
   7044 		CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
   7045 				      &expire, mctx, &buffer, &rdata));
   7046 		/* Update the database and journal with the RRSIG. */
   7047 		/* XXX inefficient - will cause dataset merging */
   7048 		CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
   7049 				    name, rdataset.ttl, &rdata));
   7050 		dns_rdata_reset(&rdata);
   7051 		(*signatures)--;
   7052  next_rdataset:
   7053 		dns_rdataset_disassociate(&rdataset);
   7054 		result = dns_rdatasetiter_next(iterator);
   7055 	}
   7056 	if (result == ISC_R_NOMORE)
   7057 		result = ISC_R_SUCCESS;
   7058  failure:
   7059 	if (dns_rdataset_isassociated(&rdataset))
   7060 		dns_rdataset_disassociate(&rdataset);
   7061 	if (iterator != NULL)
   7062 		dns_rdatasetiter_destroy(&iterator);
   7063 	return (result);
   7064 }
   7065 
   7066 /*
   7067  * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
   7068  */
   7069 static isc_result_t
   7070 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7071 	     dns_ttl_t minimum, bool update_only, dns_diff_t *diff)
   7072 {
   7073 	isc_result_t result;
   7074 	dns_rdataset_t rdataset;
   7075 	dns_dbnode_t *node = NULL;
   7076 
   7077 	CHECK(dns_db_getoriginnode(db, &node));
   7078 	if (update_only) {
   7079 		dns_rdataset_init(&rdataset);
   7080 		result = dns_db_findrdataset(db, node, version,
   7081 					     dns_rdatatype_nsec,
   7082 					     dns_rdatatype_none,
   7083 					     0, &rdataset, NULL);
   7084 		if (dns_rdataset_isassociated(&rdataset))
   7085 			dns_rdataset_disassociate(&rdataset);
   7086 		if (result == ISC_R_NOTFOUND)
   7087 			goto success;
   7088 		if (result != ISC_R_SUCCESS)
   7089 			goto failure;
   7090 	}
   7091 	CHECK(delete_nsec(db, version, node, name, diff));
   7092 	CHECK(add_nsec(db, version, name, node, minimum, false, diff));
   7093  success:
   7094 	result = ISC_R_SUCCESS;
   7095  failure:
   7096 	if (node != NULL)
   7097 		dns_db_detachnode(db, &node);
   7098 	return (result);
   7099 }
   7100 
   7101 static isc_result_t
   7102 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
   7103 		  dns_dbversion_t *version, bool build_nsec3,
   7104 		  dns_ttl_t minimum, dns_diff_t *diff)
   7105 {
   7106 	isc_result_t result;
   7107 	dns_dbnode_t *node = NULL;
   7108 	dns_rdataset_t rdataset;
   7109 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7110 	unsigned char data[5];
   7111 	bool seen_done = false;
   7112 	bool have_rr = false;
   7113 
   7114 	dns_rdataset_init(&rdataset);
   7115 	result = dns_db_getoriginnode(signing->db, &node);
   7116 	if (result != ISC_R_SUCCESS)
   7117 		goto failure;
   7118 
   7119 	result = dns_db_findrdataset(signing->db, node, version,
   7120 				     zone->privatetype, dns_rdatatype_none,
   7121 				     0, &rdataset, NULL);
   7122 	if (result == ISC_R_NOTFOUND) {
   7123 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7124 		result = ISC_R_SUCCESS;
   7125 		goto failure;
   7126 	}
   7127 	if (result != ISC_R_SUCCESS) {
   7128 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7129 		goto failure;
   7130 	}
   7131 	for (result = dns_rdataset_first(&rdataset);
   7132 	     result == ISC_R_SUCCESS;
   7133 	     result = dns_rdataset_next(&rdataset)) {
   7134 		dns_rdataset_current(&rdataset, &rdata);
   7135 		/*
   7136 		 * If we don't match the algorithm or keyid skip the record.
   7137 		 */
   7138 		if (rdata.length != 5 ||
   7139 		    rdata.data[0] != signing->algorithm ||
   7140 		    rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
   7141 		    rdata.data[2] != (signing->keyid & 0xff)) {
   7142 			have_rr = true;
   7143 			dns_rdata_reset(&rdata);
   7144 			continue;
   7145 		}
   7146 		/*
   7147 		 * We have a match.  If we were signing (!signing->deleteit)
   7148 		 * and we already have a record indicating that we have
   7149 		 * finished signing (rdata.data[4] != 0) then keep it.
   7150 		 * Otherwise it needs to be deleted as we have removed all
   7151 		 * the signatures (signing->deleteit), so any record indicating
   7152 		 * completion is now out of date, or we have finished signing
   7153 		 * with the new record so we no longer need to remember that
   7154 		 * we need to sign the zone with the matching key across a
   7155 		 * nameserver re-start.
   7156 		 */
   7157 		if (!signing->deleteit && rdata.data[4] != 0) {
   7158 			seen_done = true;
   7159 			have_rr = true;
   7160 		} else
   7161 			CHECK(update_one_rr(signing->db, version, diff,
   7162 					    DNS_DIFFOP_DEL, &zone->origin,
   7163 					    rdataset.ttl, &rdata));
   7164 		dns_rdata_reset(&rdata);
   7165 	}
   7166 	if (result == ISC_R_NOMORE)
   7167 		result = ISC_R_SUCCESS;
   7168 	if (!signing->deleteit && !seen_done) {
   7169 		/*
   7170 		 * If we were signing then we need to indicate that we have
   7171 		 * finished signing the zone with this key.  If it is already
   7172 		 * there we don't need to add it a second time.
   7173 		 */
   7174 		data[0] = signing->algorithm;
   7175 		data[1] = (signing->keyid >> 8) & 0xff;
   7176 		data[2] = signing->keyid & 0xff;
   7177 		data[3] = 0;
   7178 		data[4] = 1;
   7179 		rdata.length = sizeof(data);
   7180 		rdata.data = data;
   7181 		rdata.type = zone->privatetype;
   7182 		rdata.rdclass = dns_db_class(signing->db);
   7183 		CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
   7184 				    &zone->origin, rdataset.ttl, &rdata));
   7185 	} else if (!have_rr) {
   7186 		dns_name_t *origin = dns_db_origin(signing->db);
   7187 		/*
   7188 		 * Rebuild the NSEC/NSEC3 record for the origin as we no
   7189 		 * longer have any private records.
   7190 		 */
   7191 		if (build_nsec3)
   7192 			CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
   7193 						  minimum, false, diff));
   7194 		CHECK(updatesecure(signing->db, version, origin, minimum,
   7195 				   true, diff));
   7196 	}
   7197 
   7198  failure:
   7199 	if (dns_rdataset_isassociated(&rdataset))
   7200 		dns_rdataset_disassociate(&rdataset);
   7201 	if (node != NULL)
   7202 		dns_db_detachnode(signing->db, &node);
   7203 	return (result);
   7204 }
   7205 
   7206 /*
   7207  * Called from zone_nsec3chain() in order to update zone records indicating
   7208  * processing status of given NSEC3 chain:
   7209  *
   7210  *   - If the supplied dns_nsec3chain_t structure has been fully processed
   7211  *     (which is indicated by "active" being set to false):
   7212  *
   7213  *       - remove all NSEC3PARAM records matching the relevant NSEC3 chain,
   7214  *
   7215  *       - remove all private-type records containing NSEC3PARAM RDATA matching
   7216  *         the relevant NSEC3 chain.
   7217  *
   7218  *   - If the supplied dns_nsec3chain_t structure has not been fully processed
   7219  *     (which is indicated by "active" being set to true), only remove the
   7220  *     NSEC3PARAM record which matches the relevant NSEC3 chain and has the
   7221  *     "flags" field set to 0.
   7222  *
   7223  *   - If given NSEC3 chain is being added, add an NSEC3PARAM record contained
   7224  *     in the relevant private-type record, but with the "flags" field set to
   7225  *     0, indicating that this NSEC3 chain is now complete for this zone.
   7226  *
   7227  * Note that this function is called at different processing stages for NSEC3
   7228  * chain additions vs. removals and needs to handle all cases properly.
   7229  */
   7230 static isc_result_t
   7231 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
   7232 		 bool active, dns_rdatatype_t privatetype,
   7233 		 dns_diff_t *diff)
   7234 {
   7235 	dns_dbnode_t *node = NULL;
   7236 	dns_name_t *name = dns_db_origin(db);
   7237 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7238 	dns_rdataset_t rdataset;
   7239 	dns_rdata_nsec3param_t nsec3param;
   7240 	isc_result_t result;
   7241 	isc_buffer_t buffer;
   7242 	unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
   7243 	dns_ttl_t ttl = 0;
   7244 	bool nseconly = false, nsec3ok = false;
   7245 
   7246 	dns_rdataset_init(&rdataset);
   7247 
   7248 	result = dns_db_getoriginnode(db, &node);
   7249 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   7250 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
   7251 				     0, 0, &rdataset, NULL);
   7252 	if (result == ISC_R_NOTFOUND)
   7253 		goto try_private;
   7254 	if (result != ISC_R_SUCCESS)
   7255 		goto failure;
   7256 
   7257 	/*
   7258 	 * Preserve the existing ttl.
   7259 	 */
   7260 	ttl = rdataset.ttl;
   7261 
   7262 	/*
   7263 	 * Delete all NSEC3PARAM records which match that in nsec3chain.
   7264 	 */
   7265 	for (result = dns_rdataset_first(&rdataset);
   7266 	     result == ISC_R_SUCCESS;
   7267 	     result = dns_rdataset_next(&rdataset)) {
   7268 
   7269 		dns_rdataset_current(&rdataset, &rdata);
   7270 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   7271 
   7272 		if (nsec3param.hash != chain->nsec3param.hash ||
   7273 		    (active && nsec3param.flags != 0) ||
   7274 		    nsec3param.iterations != chain->nsec3param.iterations ||
   7275 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   7276 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   7277 			   nsec3param.salt_length)) {
   7278 			dns_rdata_reset(&rdata);
   7279 			continue;
   7280 		}
   7281 
   7282 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
   7283 				    name, rdataset.ttl, &rdata));
   7284 		dns_rdata_reset(&rdata);
   7285 	}
   7286 	if (result != ISC_R_NOMORE)
   7287 		goto failure;
   7288 
   7289 	dns_rdataset_disassociate(&rdataset);
   7290 
   7291  try_private:
   7292 
   7293 	if (active)
   7294 		goto add;
   7295 
   7296 	result = dns_nsec_nseconly(db, ver, &nseconly);
   7297 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   7298 
   7299 	/*
   7300 	 * Delete all private records which match that in nsec3chain.
   7301 	 */
   7302 	result = dns_db_findrdataset(db, node, ver, privatetype,
   7303 				     0, 0, &rdataset, NULL);
   7304 	if (result == ISC_R_NOTFOUND)
   7305 		goto add;
   7306 	if (result != ISC_R_SUCCESS)
   7307 		goto failure;
   7308 
   7309 	for (result = dns_rdataset_first(&rdataset);
   7310 	     result == ISC_R_SUCCESS;
   7311 	     result = dns_rdataset_next(&rdataset)) {
   7312 		dns_rdata_t private = DNS_RDATA_INIT;
   7313 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   7314 
   7315 		dns_rdataset_current(&rdataset, &private);
   7316 		if (!dns_nsec3param_fromprivate(&private, &rdata,
   7317 						buf, sizeof(buf)))
   7318 			continue;
   7319 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   7320 
   7321 		if ((!nsec3ok &&
   7322 		     (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
   7323 		    nsec3param.hash != chain->nsec3param.hash ||
   7324 		    nsec3param.iterations != chain->nsec3param.iterations ||
   7325 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   7326 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   7327 			   nsec3param.salt_length)) {
   7328 			dns_rdata_reset(&rdata);
   7329 			continue;
   7330 		}
   7331 
   7332 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
   7333 				    name, rdataset.ttl, &private));
   7334 		dns_rdata_reset(&rdata);
   7335 	}
   7336 	if (result != ISC_R_NOMORE)
   7337 		goto failure;
   7338 
   7339   add:
   7340 	if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   7341 		result = ISC_R_SUCCESS;
   7342 		goto failure;
   7343 	}
   7344 
   7345 	/*
   7346 	 * Add a NSEC3PARAM record which matches that in nsec3chain but
   7347 	 * with all flags bits cleared.
   7348 	 *
   7349 	 * Note: we do not clear chain->nsec3param.flags as this change
   7350 	 * may be reversed.
   7351 	 */
   7352 	isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
   7353 	CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
   7354 				   dns_rdatatype_nsec3param,
   7355 				   &chain->nsec3param, &buffer));
   7356 	rdata.data[1] = 0;	/* Clear flag bits. */
   7357 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
   7358 
   7359   failure:
   7360 	dns_db_detachnode(db, &node);
   7361 	if (dns_rdataset_isassociated(&rdataset))
   7362 		dns_rdataset_disassociate(&rdataset);
   7363 	return (result);
   7364 }
   7365 
   7366 static isc_result_t
   7367 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   7368 	    dns_name_t *name, dns_diff_t *diff)
   7369 {
   7370 	dns_rdataset_t rdataset;
   7371 	isc_result_t result;
   7372 
   7373 	dns_rdataset_init(&rdataset);
   7374 
   7375 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
   7376 				     0, 0, &rdataset, NULL);
   7377 	if (result == ISC_R_NOTFOUND)
   7378 		return (ISC_R_SUCCESS);
   7379 	if (result != ISC_R_SUCCESS)
   7380 		return (result);
   7381 	for (result = dns_rdataset_first(&rdataset);
   7382 	     result == ISC_R_SUCCESS;
   7383 	     result = dns_rdataset_next(&rdataset)) {
   7384 		dns_rdata_t rdata = DNS_RDATA_INIT;
   7385 
   7386 		dns_rdataset_current(&rdataset, &rdata);
   7387 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7388 				    rdataset.ttl, &rdata));
   7389 	}
   7390 	if (result == ISC_R_NOMORE)
   7391 		result = ISC_R_SUCCESS;
   7392  failure:
   7393 	dns_rdataset_disassociate(&rdataset);
   7394 	return (result);
   7395 }
   7396 
   7397 static isc_result_t
   7398 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   7399 		    dns_name_t *name, const dns_rdata_nsec3param_t *param,
   7400 		    dns_diff_t *diff)
   7401 {
   7402 	dns_rdataset_t rdataset;
   7403 	dns_rdata_nsec3_t nsec3;
   7404 	isc_result_t result;
   7405 
   7406 	dns_rdataset_init(&rdataset);
   7407 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
   7408 				     0, 0, &rdataset, NULL);
   7409 	if (result == ISC_R_NOTFOUND)
   7410 		return (ISC_R_SUCCESS);
   7411 	if (result != ISC_R_SUCCESS)
   7412 		return (result);
   7413 
   7414 	for (result = dns_rdataset_first(&rdataset);
   7415 	     result == ISC_R_SUCCESS;
   7416 	     result = dns_rdataset_next(&rdataset)) {
   7417 		dns_rdata_t rdata = DNS_RDATA_INIT;
   7418 
   7419 		dns_rdataset_current(&rdataset, &rdata);
   7420 		CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
   7421 		if (nsec3.hash != param->hash ||
   7422 		    nsec3.iterations != param->iterations ||
   7423 		    nsec3.salt_length != param->salt_length ||
   7424 		    memcmp(nsec3.salt, param->salt, nsec3.salt_length))
   7425 			continue;
   7426 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7427 				    rdataset.ttl, &rdata));
   7428 	}
   7429 	if (result == ISC_R_NOMORE)
   7430 		result = ISC_R_SUCCESS;
   7431  failure:
   7432 	dns_rdataset_disassociate(&rdataset);
   7433 	return (result);
   7434 }
   7435 
   7436 static isc_result_t
   7437 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
   7438 		const dns_rdata_nsec3param_t *param,
   7439 		bool *answer)
   7440 {
   7441 	dns_dbnode_t *node = NULL;
   7442 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7443 	dns_rdata_nsec3param_t myparam;
   7444 	dns_rdataset_t rdataset;
   7445 	isc_result_t result;
   7446 
   7447 	*answer = false;
   7448 
   7449 	result = dns_db_getoriginnode(db, &node);
   7450 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   7451 
   7452 	dns_rdataset_init(&rdataset);
   7453 
   7454 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
   7455 				     0, 0, &rdataset, NULL);
   7456 	if (result == ISC_R_SUCCESS) {
   7457 		dns_rdataset_disassociate(&rdataset);
   7458 		dns_db_detachnode(db, &node);
   7459 		return (result);
   7460 	}
   7461 	if (result != ISC_R_NOTFOUND) {
   7462 		dns_db_detachnode(db, &node);
   7463 		return (result);
   7464 	}
   7465 
   7466 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
   7467 				     0, 0, &rdataset, NULL);
   7468 	if (result == ISC_R_NOTFOUND) {
   7469 		*answer = true;
   7470 		dns_db_detachnode(db, &node);
   7471 		return (ISC_R_SUCCESS);
   7472 	}
   7473 	if (result != ISC_R_SUCCESS) {
   7474 		dns_db_detachnode(db, &node);
   7475 		return (result);
   7476 	}
   7477 
   7478 	for (result = dns_rdataset_first(&rdataset);
   7479 	     result == ISC_R_SUCCESS;
   7480 	     result = dns_rdataset_next(&rdataset)) {
   7481 		dns_rdataset_current(&rdataset, &rdata);
   7482 		CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
   7483 		dns_rdata_reset(&rdata);
   7484 		/*
   7485 		 * Ignore any NSEC3PARAM removals.
   7486 		 */
   7487 		if (NSEC3REMOVE(myparam.flags))
   7488 			continue;
   7489 		/*
   7490 		 * Ignore the chain that we are in the process of deleting.
   7491 		 */
   7492 		if (myparam.hash == param->hash &&
   7493 		    myparam.iterations == param->iterations &&
   7494 		    myparam.salt_length == param->salt_length &&
   7495 		    !memcmp(myparam.salt, param->salt, myparam.salt_length))
   7496 			continue;
   7497 		/*
   7498 		 * Found an active NSEC3 chain.
   7499 		 */
   7500 		break;
   7501 	}
   7502 	if (result == ISC_R_NOMORE) {
   7503 		*answer = true;
   7504 		result = ISC_R_SUCCESS;
   7505 	}
   7506 
   7507  failure:
   7508 	if (dns_rdataset_isassociated(&rdataset))
   7509 		dns_rdataset_disassociate(&rdataset);
   7510 	dns_db_detachnode(db, &node);
   7511 	return (result);
   7512 }
   7513 
   7514 /*%
   7515  * Given a tuple which is part of a diff, return a pointer to the next tuple in
   7516  * that diff which has the same name and type (or NULL if no such tuple is
   7517  * found).
   7518  */
   7519 static dns_difftuple_t *
   7520 find_next_matching_tuple(dns_difftuple_t *cur) {
   7521 	dns_difftuple_t *next = cur;
   7522 
   7523 	while ((next = ISC_LIST_NEXT(next, link)) != NULL) {
   7524 		if (cur->rdata.type == next->rdata.type &&
   7525 		    dns_name_equal(&cur->name, &next->name))
   7526 		{
   7527 			return (next);
   7528 		}
   7529 	}
   7530 
   7531 	return (NULL);
   7532 }
   7533 
   7534 /*%
   7535  * Remove all tuples with the same name and type as 'cur' from 'src' and append
   7536  * them to 'dst'.
   7537  */
   7538 static void
   7539 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) {
   7540 	do {
   7541 		dns_difftuple_t *next = find_next_matching_tuple(cur);
   7542 		ISC_LIST_UNLINK(src->tuples, cur, link);
   7543 		dns_diff_appendminimal(dst, &cur);
   7544 		cur = next;
   7545 	} while (cur != NULL);
   7546 }
   7547 
   7548 /*%
   7549  * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in
   7550  * 'diff'.  Gradually remove tuples from 'diff' and append them to 'zonediff'
   7551  * along with tuples representing relevant signature changes.
   7552  */
   7553 isc_result_t
   7554 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
   7555 		     dst_key_t *zone_keys[], unsigned int nkeys,
   7556 		     dns_zone_t *zone, isc_stdtime_t inception,
   7557 		     isc_stdtime_t expire, isc_stdtime_t keyexpire,
   7558 		     isc_stdtime_t now, bool check_ksk,
   7559 		     bool keyset_kskonly, dns__zonediff_t *zonediff)
   7560 {
   7561 	dns_difftuple_t *tuple;
   7562 	isc_result_t result;
   7563 
   7564 	while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) {
   7565 		isc_stdtime_t exp = expire;
   7566 
   7567 		if (keyexpire != 0 &&
   7568 		    (tuple->rdata.type == dns_rdatatype_dnskey ||
   7569 		     tuple->rdata.type == dns_rdatatype_cdnskey ||
   7570 		     tuple->rdata.type == dns_rdatatype_cds))
   7571 		{
   7572 			exp = keyexpire;
   7573 		}
   7574 
   7575 		result = del_sigs(zone, db, version, &tuple->name,
   7576 				  tuple->rdata.type, zonediff,
   7577 				  zone_keys, nkeys, now, false);
   7578 		if (result != ISC_R_SUCCESS) {
   7579 			dns_zone_log(zone, ISC_LOG_ERROR,
   7580 				     "dns__zone_updatesigs:del_sigs -> %s",
   7581 				     dns_result_totext(result));
   7582 			return (result);
   7583 		}
   7584 		result = add_sigs(db, version, &tuple->name,
   7585 				  tuple->rdata.type, zonediff->diff,
   7586 				  zone_keys, nkeys, zone->mctx, inception,
   7587 				  exp, check_ksk, keyset_kskonly);
   7588 		if (result != ISC_R_SUCCESS) {
   7589 			dns_zone_log(zone, ISC_LOG_ERROR,
   7590 				     "dns__zone_updatesigs:add_sigs -> %s",
   7591 				     dns_result_totext(result));
   7592 			return (result);
   7593 		}
   7594 
   7595 		/*
   7596 		 * Signature changes for all RRs with name tuple->name and type
   7597 		 * tuple->rdata.type were appended to zonediff->diff.  Now we
   7598 		 * remove all the "raw" changes with the same name and type
   7599 		 * from diff (so that they are not processed by this loop
   7600 		 * again) and append them to zonediff so that they get applied.
   7601 		 */
   7602 		move_matching_tuples(tuple, diff, zonediff->diff);
   7603 	}
   7604 	return (ISC_R_SUCCESS);
   7605 }
   7606 
   7607 /*
   7608  * Incrementally build and sign a new NSEC3 chain using the parameters
   7609  * requested.
   7610  */
   7611 static void
   7612 zone_nsec3chain(dns_zone_t *zone) {
   7613 	const char *me = "zone_nsec3chain";
   7614 	dns_db_t *db = NULL;
   7615 	dns_dbnode_t *node = NULL;
   7616 	dns_dbversion_t *version = NULL;
   7617 	dns_diff_t _sig_diff;
   7618 	dns_diff_t nsec_diff;
   7619 	dns_diff_t nsec3_diff;
   7620 	dns_diff_t param_diff;
   7621 	dns__zonediff_t zonediff;
   7622 	dns_fixedname_t fixed;
   7623 	dns_fixedname_t nextfixed;
   7624 	dns_name_t *name, *nextname;
   7625 	dns_rdataset_t rdataset;
   7626 	dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
   7627 	dns_nsec3chainlist_t cleanup;
   7628 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   7629 	int32_t signatures;
   7630 	bool check_ksk, keyset_kskonly;
   7631 	bool delegation;
   7632 	bool first;
   7633 	isc_result_t result;
   7634 	isc_stdtime_t now, inception, soaexpire, expire;
   7635 	uint32_t jitter, sigvalidityinterval;
   7636 	unsigned int i;
   7637 	unsigned int nkeys = 0;
   7638 	uint32_t nodes;
   7639 	bool unsecure = false;
   7640 	bool seen_soa, seen_ns, seen_dname, seen_ds;
   7641 	bool seen_nsec, seen_nsec3, seen_rr;
   7642 	dns_rdatasetiter_t *iterator = NULL;
   7643 	bool buildnsecchain;
   7644 	bool updatensec = false;
   7645 	dns_rdatatype_t privatetype = zone->privatetype;
   7646 
   7647 	ENTER;
   7648 
   7649 	dns_rdataset_init(&rdataset);
   7650 	name = dns_fixedname_initname(&fixed);
   7651 	nextname = dns_fixedname_initname(&nextfixed);
   7652 	dns_diff_init(zone->mctx, &param_diff);
   7653 	dns_diff_init(zone->mctx, &nsec3_diff);
   7654 	dns_diff_init(zone->mctx, &nsec_diff);
   7655 	dns_diff_init(zone->mctx, &_sig_diff);
   7656 	zonediff_init(&zonediff, &_sig_diff);
   7657 	ISC_LIST_INIT(cleanup);
   7658 
   7659 	/*
   7660 	 * Updates are disabled.  Pause for 5 minutes.
   7661 	 */
   7662 	if (zone->update_disabled) {
   7663 		result = ISC_R_FAILURE;
   7664 		goto failure;
   7665 	}
   7666 
   7667 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   7668 	/*
   7669 	 * This function is called when zone timer fires, after the latter gets
   7670 	 * set by zone_addnsec3chain().  If the action triggering the call to
   7671 	 * zone_addnsec3chain() is closely followed by a zone deletion request,
   7672 	 * it might turn out that the timer thread will not be woken up until
   7673 	 * after the zone is deleted by rmzone(), which calls dns_db_detach()
   7674 	 * for zone->db, causing the latter to become NULL.  Return immediately
   7675 	 * if that happens.
   7676 	 */
   7677 	if (zone->db != NULL) {
   7678 		dns_db_attach(zone->db, &db);
   7679 	}
   7680 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   7681 	if (db == NULL) {
   7682 		return;
   7683 	}
   7684 
   7685 	result = dns_db_newversion(db, &version);
   7686 	if (result != ISC_R_SUCCESS) {
   7687 		dnssec_log(zone, ISC_LOG_ERROR,
   7688 			   "zone_nsec3chain:dns_db_newversion -> %s",
   7689 			   dns_result_totext(result));
   7690 		goto failure;
   7691 	}
   7692 
   7693 	isc_stdtime_get(&now);
   7694 
   7695 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   7696 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   7697 	if (result != ISC_R_SUCCESS) {
   7698 		dnssec_log(zone, ISC_LOG_ERROR,
   7699 			   "zone_nsec3chain:dns__zone_findkeys -> %s",
   7700 			   dns_result_totext(result));
   7701 		goto failure;
   7702 	}
   7703 
   7704 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   7705 	inception = now - 3600;	/* Allow for clock skew. */
   7706 	soaexpire = now + sigvalidityinterval;
   7707 
   7708 	/*
   7709 	 * Spread out signatures over time if they happen to be
   7710 	 * clumped.  We don't do this for each add_sigs() call as
   7711 	 * we still want some clustering to occur.
   7712 	 */
   7713 	if (sigvalidityinterval >= 3600U) {
   7714 		if (sigvalidityinterval > 7200U) {
   7715 			jitter = isc_random_uniform(3600);
   7716 		} else {
   7717 			jitter = isc_random_uniform(1200);
   7718 		}
   7719 		expire = soaexpire - jitter - 1;
   7720 	} else {
   7721 		expire = soaexpire - 1;
   7722 	}
   7723 
   7724 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   7725 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   7726 
   7727 	/*
   7728 	 * We keep pulling nodes off each iterator in turn until
   7729 	 * we have no more nodes to pull off or we reach the limits
   7730 	 * for this quantum.
   7731 	 */
   7732 	nodes = zone->nodes;
   7733 	signatures = zone->signatures;
   7734 	LOCK_ZONE(zone);
   7735 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   7736 	UNLOCK_ZONE(zone);
   7737 	first = true;
   7738 
   7739 	if (nsec3chain != NULL) {
   7740 		nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   7741 	}
   7742 	/*
   7743 	 * Generate new NSEC3 chains first.
   7744 	 *
   7745 	 * The following while loop iterates over nodes in the zone database,
   7746 	 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of
   7747 	 * them.  Once all nodes are processed, the "delete_nsec" field is
   7748 	 * consulted to check whether we are supposed to remove NSEC records
   7749 	 * from the zone database; if so, the database iterator is reset to
   7750 	 * point to the first node and the loop traverses all of them again,
   7751 	 * this time removing NSEC records.  If we hit a node which is obscured
   7752 	 * by a delegation or a DNAME, nodes are skipped over until we find one
   7753 	 * that is not obscured by the same obscuring name and then normal
   7754 	 * processing is resumed.
   7755 	 *
   7756 	 * The above is repeated until all requested NSEC3 chain changes are
   7757 	 * applied or when we reach the limits for this quantum, whichever
   7758 	 * happens first.
   7759 	 *
   7760 	 * Note that the "signatures" variable is only used here to limit the
   7761 	 * amount of work performed.  Actual DNSSEC signatures are only
   7762 	 * generated by dns__zone_updatesigs() calls later in this function.
   7763 	 */
   7764 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   7765 		LOCK_ZONE(zone);
   7766 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   7767 
   7768 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   7769 		if (nsec3chain->done || nsec3chain->db != zone->db) {
   7770 			ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   7771 			ISC_LIST_APPEND(cleanup, nsec3chain, link);
   7772 		}
   7773 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   7774 		UNLOCK_ZONE(zone);
   7775 		if (ISC_LIST_TAIL(cleanup) == nsec3chain)
   7776 			goto next_addchain;
   7777 
   7778 		/*
   7779 		 * Possible future db.
   7780 		 */
   7781 		if (nsec3chain->db != db) {
   7782 			goto next_addchain;
   7783 		}
   7784 
   7785 		if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
   7786 			goto next_addchain;
   7787 
   7788 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   7789 
   7790 		if (nsec3chain->delete_nsec) {
   7791 			delegation = false;
   7792 			dns_dbiterator_pause(nsec3chain->dbiterator);
   7793 			CHECK(delete_nsec(db, version, node, name, &nsec_diff));
   7794 			goto next_addnode;
   7795 		}
   7796 		/*
   7797 		 * On the first pass we need to check if the current node
   7798 		 * has not been obscured.
   7799 		 */
   7800 		delegation = false;
   7801 		unsecure = false;
   7802 		if (first) {
   7803 			dns_fixedname_t ffound;
   7804 			dns_name_t *found;
   7805 			found = dns_fixedname_initname(&ffound);
   7806 			result = dns_db_find(db, name, version,
   7807 					     dns_rdatatype_soa,
   7808 					     DNS_DBFIND_NOWILD, 0, NULL, found,
   7809 					     NULL, NULL);
   7810 			if ((result == DNS_R_DELEGATION ||
   7811 			    result == DNS_R_DNAME) &&
   7812 			    !dns_name_equal(name, found)) {
   7813 				/*
   7814 				 * Remember the obscuring name so that
   7815 				 * we skip all obscured names.
   7816 				 */
   7817 				dns_name_copy(found, name, NULL);
   7818 				delegation = true;
   7819 				goto next_addnode;
   7820 			}
   7821 		}
   7822 
   7823 		/*
   7824 		 * Check to see if this is a bottom of zone node.
   7825 		 */
   7826 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   7827 		if (result == ISC_R_NOTFOUND) {
   7828 			/* Empty node? */
   7829 			goto next_addnode;
   7830 		}
   7831 		if (result != ISC_R_SUCCESS) {
   7832 			goto failure;
   7833 		}
   7834 
   7835 		seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false;
   7836 		for (result = dns_rdatasetiter_first(iterator);
   7837 		     result == ISC_R_SUCCESS;
   7838 		     result = dns_rdatasetiter_next(iterator))
   7839 		{
   7840 			dns_rdatasetiter_current(iterator, &rdataset);
   7841 			INSIST(rdataset.type != dns_rdatatype_nsec3);
   7842 			if (rdataset.type == dns_rdatatype_soa) {
   7843 				seen_soa = true;
   7844 			} else if (rdataset.type == dns_rdatatype_ns) {
   7845 				seen_ns = true;
   7846 			} else if (rdataset.type == dns_rdatatype_dname) {
   7847 				seen_dname = true;
   7848 			} else if (rdataset.type == dns_rdatatype_ds) {
   7849 				seen_ds = true;
   7850 			} else if (rdataset.type == dns_rdatatype_nsec) {
   7851 				seen_nsec = true;
   7852 			}
   7853 			dns_rdataset_disassociate(&rdataset);
   7854 		}
   7855 		dns_rdatasetiter_destroy(&iterator);
   7856 		/*
   7857 		 * Is there a NSEC chain than needs to be cleaned up?
   7858 		 */
   7859 		if (seen_nsec) {
   7860 			nsec3chain->seen_nsec = true;
   7861 		}
   7862 		if (seen_ns && !seen_soa && !seen_ds) {
   7863 			unsecure = true;
   7864 		}
   7865 		if ((seen_ns && !seen_soa) || seen_dname) {
   7866 			delegation = true;
   7867 		}
   7868 
   7869 		/*
   7870 		 * Process one node.
   7871 		 */
   7872 		dns_dbiterator_pause(nsec3chain->dbiterator);
   7873 		result = dns_nsec3_addnsec3(db, version, name,
   7874 					    &nsec3chain->nsec3param,
   7875 					    zone->minimum, unsecure,
   7876 					    &nsec3_diff);
   7877 		if (result != ISC_R_SUCCESS) {
   7878 			dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
   7879 				   "dns_nsec3_addnsec3 -> %s",
   7880 				   dns_result_totext(result));
   7881 			goto failure;
   7882 		}
   7883 
   7884 		/*
   7885 		 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
   7886 		 * two signatures.  Additionally there will, in general, be
   7887 		 * two signature generated below.
   7888 		 *
   7889 		 * If we are only changing the optout flag the cost is half
   7890 		 * that of the cost of generating a completely new chain.
   7891 		 */
   7892 		signatures -= 4;
   7893 
   7894 		/*
   7895 		 * Go onto next node.
   7896 		 */
   7897  next_addnode:
   7898 		first = false;
   7899 		dns_db_detachnode(db, &node);
   7900 		do {
   7901 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   7902 
   7903 			if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
   7904 				dns_dbiterator_pause(nsec3chain->dbiterator);
   7905 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   7906 						       false, privatetype,
   7907 						       &param_diff));
   7908 				LOCK_ZONE(zone);
   7909 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   7910 						link);
   7911 				UNLOCK_ZONE(zone);
   7912 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   7913 				goto next_addchain;
   7914 			}
   7915 			if (result == ISC_R_NOMORE) {
   7916 				dns_dbiterator_pause(nsec3chain->dbiterator);
   7917 				if (nsec3chain->seen_nsec) {
   7918 					CHECK(fixup_nsec3param(db, version,
   7919 							       nsec3chain,
   7920 							       true,
   7921 							       privatetype,
   7922 							       &param_diff));
   7923 					nsec3chain->delete_nsec = true;
   7924 					goto same_addchain;
   7925 				}
   7926 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   7927 						       false, privatetype,
   7928 						       &param_diff));
   7929 				LOCK_ZONE(zone);
   7930 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   7931 						link);
   7932 				UNLOCK_ZONE(zone);
   7933 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   7934 				goto next_addchain;
   7935 			} else if (result != ISC_R_SUCCESS) {
   7936 				dnssec_log(zone, ISC_LOG_ERROR,
   7937 					   "zone_nsec3chain:"
   7938 					   "dns_dbiterator_next -> %s",
   7939 					   dns_result_totext(result));
   7940 				goto failure;
   7941 			} else if (delegation) {
   7942 				dns_dbiterator_current(nsec3chain->dbiterator,
   7943 						       &node, nextname);
   7944 				dns_db_detachnode(db, &node);
   7945 				if (!dns_name_issubdomain(nextname, name))
   7946 					break;
   7947 			} else {
   7948 				break;
   7949 			}
   7950 		} while (1);
   7951 		continue;
   7952 
   7953  same_addchain:
   7954 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   7955 		first = true;
   7956 		continue;
   7957 
   7958  next_addchain:
   7959 		dns_dbiterator_pause(nsec3chain->dbiterator);
   7960 		nsec3chain = nextnsec3chain;
   7961 		first = true;
   7962 		if (nsec3chain != NULL) {
   7963 			nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   7964 		}
   7965 	}
   7966 
   7967 	if (nsec3chain != NULL) {
   7968 		goto skip_removals;
   7969 	}
   7970 
   7971 	/*
   7972 	 * Process removals.
   7973 	 *
   7974 	 * This is a counterpart of the above while loop which takes care of
   7975 	 * removing an NSEC3 chain.  It starts with determining whether the
   7976 	 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an
   7977 	 * NSEC chain by iterating over all nodes in the zone database and only
   7978 	 * then goes on to remove NSEC3 records be iterating over all nodes
   7979 	 * again and calling deletematchingnsec3() for each of them; otherwise,
   7980 	 * it starts removing NSEC3 records immediately.  Rules for processing
   7981 	 * obscured nodes and interrupting work are the same as for the while
   7982 	 * loop above.
   7983 	 */
   7984 	LOCK_ZONE(zone);
   7985 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   7986 	UNLOCK_ZONE(zone);
   7987 	first = true;
   7988 	buildnsecchain = false;
   7989 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   7990 		LOCK_ZONE(zone);
   7991 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   7992 		UNLOCK_ZONE(zone);
   7993 
   7994 		if (nsec3chain->db != db) {
   7995 			goto next_removechain;
   7996 		}
   7997 
   7998 		if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   7999 			goto next_removechain;
   8000 		}
   8001 
   8002 		/*
   8003 		 * Work out if we need to build a NSEC chain as a consequence
   8004 		 * of removing this NSEC3 chain.
   8005 		 */
   8006 		if (first && !updatensec &&
   8007 		    (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
   8008 		{
   8009 			result = need_nsec_chain(db, version,
   8010 						 &nsec3chain->nsec3param,
   8011 						 &buildnsecchain);
   8012 			if (result != ISC_R_SUCCESS) {
   8013 				dnssec_log(zone, ISC_LOG_ERROR,
   8014 					   "zone_nsec3chain:"
   8015 					   "need_nsec_chain -> %s",
   8016 					   dns_result_totext(result));
   8017 				goto failure;
   8018 			}
   8019 		}
   8020 
   8021 		if (first) {
   8022 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   8023 				   "zone_nsec3chain:buildnsecchain = %u\n",
   8024 				   buildnsecchain);
   8025 		}
   8026 
   8027 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8028 		delegation = false;
   8029 
   8030 		if (!buildnsecchain) {
   8031 			/*
   8032 			 * Delete the NSEC3PARAM record matching this chain.
   8033 			 */
   8034 			if (first) {
   8035 				result = fixup_nsec3param(db, version,
   8036 							  nsec3chain,
   8037 							  true, privatetype,
   8038 							  &param_diff);
   8039 				if (result != ISC_R_SUCCESS) {
   8040 					dnssec_log(zone, ISC_LOG_ERROR,
   8041 						   "zone_nsec3chain:"
   8042 						   "fixup_nsec3param -> %s",
   8043 						   dns_result_totext(result));
   8044 					goto failure;
   8045 				}
   8046 			}
   8047 
   8048 			/*
   8049 			 * Delete the NSEC3 records.
   8050 			 */
   8051 			result = deletematchingnsec3(db, version, node, name,
   8052 						     &nsec3chain->nsec3param,
   8053 						     &nsec3_diff);
   8054 			if (result != ISC_R_SUCCESS) {
   8055 				dnssec_log(zone, ISC_LOG_ERROR,
   8056 					   "zone_nsec3chain:"
   8057 					   "deletematchingnsec3 -> %s",
   8058 					   dns_result_totext(result));
   8059 				goto failure;
   8060 			}
   8061 			goto next_removenode;
   8062 		}
   8063 
   8064 		if (first) {
   8065 			dns_fixedname_t ffound;
   8066 			dns_name_t *found;
   8067 			found = dns_fixedname_initname(&ffound);
   8068 			result = dns_db_find(db, name, version,
   8069 					     dns_rdatatype_soa,
   8070 					     DNS_DBFIND_NOWILD, 0, NULL, found,
   8071 					     NULL, NULL);
   8072 			if ((result == DNS_R_DELEGATION ||
   8073 			     result == DNS_R_DNAME) &&
   8074 			    !dns_name_equal(name, found))
   8075 			{
   8076 				/*
   8077 				 * Remember the obscuring name so that
   8078 				 * we skip all obscured names.
   8079 				 */
   8080 				dns_name_copy(found, name, NULL);
   8081 				delegation = true;
   8082 				goto next_removenode;
   8083 			}
   8084 		}
   8085 
   8086 		/*
   8087 		 * Check to see if this is a bottom of zone node.
   8088 		 */
   8089 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8090 		if (result == ISC_R_NOTFOUND) {
   8091 			/* Empty node? */
   8092 			goto next_removenode;
   8093 		}
   8094 		if (result != ISC_R_SUCCESS) {
   8095 			goto failure;
   8096 		}
   8097 
   8098 		seen_soa = seen_ns = seen_dname = seen_nsec3 =
   8099 			   seen_nsec = seen_rr = false;
   8100 		for (result = dns_rdatasetiter_first(iterator);
   8101 		     result == ISC_R_SUCCESS;
   8102 		     result = dns_rdatasetiter_next(iterator))
   8103 		{
   8104 			dns_rdatasetiter_current(iterator, &rdataset);
   8105 			if (rdataset.type == dns_rdatatype_soa) {
   8106 				seen_soa = true;
   8107 			} else if (rdataset.type == dns_rdatatype_ns) {
   8108 				seen_ns = true;
   8109 			} else if (rdataset.type == dns_rdatatype_dname) {
   8110 				seen_dname = true;
   8111 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8112 				seen_nsec = true;
   8113 			} else if (rdataset.type == dns_rdatatype_nsec3) {
   8114 				seen_nsec3 = true;
   8115 			} else if (rdataset.type != dns_rdatatype_rrsig) {
   8116 				seen_rr = true;
   8117 			}
   8118 			dns_rdataset_disassociate(&rdataset);
   8119 		}
   8120 		dns_rdatasetiter_destroy(&iterator);
   8121 
   8122 		if (!seen_rr || seen_nsec3 || seen_nsec) {
   8123 			goto next_removenode;
   8124 		}
   8125 		if ((seen_ns && !seen_soa) || seen_dname) {
   8126 			delegation = true;
   8127 		}
   8128 
   8129 		/*
   8130 		 * Add a NSEC record except at the origin.
   8131 		 */
   8132 		if (!dns_name_equal(name, dns_db_origin(db))) {
   8133 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8134 			CHECK(add_nsec(db, version, name, node, zone->minimum,
   8135 				       delegation, &nsec_diff));
   8136 			signatures--;
   8137 		}
   8138 
   8139  next_removenode:
   8140 		first = false;
   8141 		dns_db_detachnode(db, &node);
   8142 		do {
   8143 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8144 			if (result == ISC_R_NOMORE && buildnsecchain) {
   8145 				/*
   8146 				 * The NSEC chain should now be built.
   8147 				 * We can now remove the NSEC3 chain.
   8148 				 */
   8149 				updatensec = true;
   8150 				goto same_removechain;
   8151 			}
   8152 			if (result == ISC_R_NOMORE) {
   8153 				LOCK_ZONE(zone);
   8154 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8155 						link);
   8156 				UNLOCK_ZONE(zone);
   8157 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8158 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8159 				result = fixup_nsec3param(db, version,
   8160 							  nsec3chain, false,
   8161 							  privatetype,
   8162 							  &param_diff);
   8163 				if (result != ISC_R_SUCCESS) {
   8164 					dnssec_log(zone, ISC_LOG_ERROR,
   8165 						   "zone_nsec3chain:"
   8166 						   "fixup_nsec3param -> %s",
   8167 						   dns_result_totext(result));
   8168 					goto failure;
   8169 				}
   8170 				goto next_removechain;
   8171 			} else if (result != ISC_R_SUCCESS) {
   8172 				dnssec_log(zone, ISC_LOG_ERROR,
   8173 					   "zone_nsec3chain:"
   8174 					   "dns_dbiterator_next -> %s",
   8175 					   dns_result_totext(result));
   8176 				goto failure;
   8177 			} else if (delegation) {
   8178 				dns_dbiterator_current(nsec3chain->dbiterator,
   8179 						       &node, nextname);
   8180 				dns_db_detachnode(db, &node);
   8181 				if (!dns_name_issubdomain(nextname, name)) {
   8182 					break;
   8183 				}
   8184 			} else {
   8185 				break;
   8186 			}
   8187 		} while (1);
   8188 		continue;
   8189 
   8190  same_removechain:
   8191 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8192 		buildnsecchain = false;
   8193 		first = true;
   8194 		continue;
   8195 
   8196  next_removechain:
   8197 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8198 		nsec3chain = nextnsec3chain;
   8199 		first = true;
   8200 	}
   8201 
   8202  skip_removals:
   8203 	/*
   8204 	 * We may need to update the NSEC/NSEC3 records for the zone apex.
   8205 	 */
   8206 	if (!ISC_LIST_EMPTY(param_diff.tuples)) {
   8207 		bool rebuild_nsec = false,
   8208 			      rebuild_nsec3 = false;
   8209 		result = dns_db_getoriginnode(db, &node);
   8210 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8211 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8212 		if (result != ISC_R_SUCCESS) {
   8213 			dnssec_log(zone, ISC_LOG_ERROR,
   8214 				   "zone_nsec3chain:dns_db_allrdatasets -> %s",
   8215 				   dns_result_totext(result));
   8216 			goto failure;
   8217 		}
   8218 		for (result = dns_rdatasetiter_first(iterator);
   8219 		     result == ISC_R_SUCCESS;
   8220 		     result = dns_rdatasetiter_next(iterator))
   8221 		{
   8222 			dns_rdatasetiter_current(iterator, &rdataset);
   8223 			if (rdataset.type == dns_rdatatype_nsec) {
   8224 				rebuild_nsec = true;
   8225 			} else if (rdataset.type == dns_rdatatype_nsec3param) {
   8226 				rebuild_nsec3 = true;
   8227 			}
   8228 			dns_rdataset_disassociate(&rdataset);
   8229 		}
   8230 		dns_rdatasetiter_destroy(&iterator);
   8231 		dns_db_detachnode(db, &node);
   8232 
   8233 		if (rebuild_nsec) {
   8234 			if (nsec3chain != NULL) {
   8235 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8236 			}
   8237 
   8238 			result = updatesecure(db, version, &zone->origin,
   8239 					      zone->minimum, true,
   8240 					      &nsec_diff);
   8241 			if (result != ISC_R_SUCCESS) {
   8242 				dnssec_log(zone, ISC_LOG_ERROR,
   8243 					   "zone_nsec3chain:updatesecure -> %s",
   8244 					   dns_result_totext(result));
   8245 				goto failure;
   8246 			}
   8247 		}
   8248 
   8249 		if (rebuild_nsec3) {
   8250 			if (nsec3chain != NULL) {
   8251 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8252 			}
   8253 
   8254 			result = dns_nsec3_addnsec3s(db, version,
   8255 						     dns_db_origin(db),
   8256 						     zone->minimum, false,
   8257 						     &nsec3_diff);
   8258 			if (result != ISC_R_SUCCESS) {
   8259 				dnssec_log(zone, ISC_LOG_ERROR,
   8260 					   "zone_nsec3chain:"
   8261 					   "dns_nsec3_addnsec3s -> %s",
   8262 					   dns_result_totext(result));
   8263 				goto failure;
   8264 			}
   8265 		}
   8266 	}
   8267 
   8268 	/*
   8269 	 * Add / update signatures for the NSEC3 records.
   8270 	 */
   8271 	if (nsec3chain != NULL) {
   8272 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8273 	}
   8274 	result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys,
   8275 				      nkeys, zone, inception, expire, 0, now,
   8276 				      check_ksk, keyset_kskonly, &zonediff);
   8277 	if (result != ISC_R_SUCCESS) {
   8278 		dnssec_log(zone, ISC_LOG_ERROR,
   8279 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8280 			   dns_result_totext(result));
   8281 		goto failure;
   8282 	}
   8283 
   8284 	/*
   8285 	 * We have changed the NSEC3PARAM or private RRsets
   8286 	 * above so we need to update the signatures.
   8287 	 */
   8288 	result = dns__zone_updatesigs(&param_diff, db, version, zone_keys,
   8289 				      nkeys, zone, inception, expire, 0, now,
   8290 				      check_ksk, keyset_kskonly, &zonediff);
   8291 	if (result != ISC_R_SUCCESS) {
   8292 		dnssec_log(zone, ISC_LOG_ERROR,
   8293 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8294 			   dns_result_totext(result));
   8295 		goto failure;
   8296 	}
   8297 
   8298 	if (updatensec) {
   8299 		result = updatesecure(db, version, &zone->origin,
   8300 				      zone->minimum, false, &nsec_diff);
   8301 		if (result != ISC_R_SUCCESS) {
   8302 			dnssec_log(zone, ISC_LOG_ERROR,
   8303 				   "zone_nsec3chain:updatesecure -> %s",
   8304 				   dns_result_totext(result));
   8305 			goto failure;
   8306 		}
   8307 	}
   8308 
   8309 	result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys,
   8310 				      nkeys, zone, inception, expire, 0, now,
   8311 				      check_ksk, keyset_kskonly, &zonediff);
   8312 	if (result != ISC_R_SUCCESS) {
   8313 		dnssec_log(zone, ISC_LOG_ERROR,
   8314 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8315 			   dns_result_totext(result));
   8316 		goto failure;
   8317 	}
   8318 
   8319 	/*
   8320 	 * If we made no effective changes to the zone then we can just
   8321 	 * cleanup otherwise we need to increment the serial.
   8322 	 */
   8323 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   8324 		/*
   8325 		 * No need to call dns_db_closeversion() here as it is
   8326 		 * called with commit = true below.
   8327 		 */
   8328 		goto done;
   8329 	}
   8330 
   8331 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   8332 			  &zonediff, zone_keys, nkeys, now, false);
   8333 	if (result != ISC_R_SUCCESS) {
   8334 		dnssec_log(zone, ISC_LOG_ERROR,
   8335 			   "zone_nsec3chain:del_sigs -> %s",
   8336 			   dns_result_totext(result));
   8337 		goto failure;
   8338 	}
   8339 
   8340 	result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
   8341 				   zone->updatemethod);
   8342 	if (result != ISC_R_SUCCESS) {
   8343 		dnssec_log(zone, ISC_LOG_ERROR,
   8344 			   "zone_nsec3chain:update_soa_serial -> %s",
   8345 			   dns_result_totext(result));
   8346 		goto failure;
   8347 	}
   8348 
   8349 	result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
   8350 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   8351 			  inception, soaexpire, check_ksk, keyset_kskonly);
   8352 	if (result != ISC_R_SUCCESS) {
   8353 		dnssec_log(zone, ISC_LOG_ERROR,
   8354 			   "zone_nsec3chain:add_sigs -> %s",
   8355 			   dns_result_totext(result));
   8356 		goto failure;
   8357 	}
   8358 
   8359 	/* Write changes to journal file. */
   8360 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
   8361 
   8362 	LOCK_ZONE(zone);
   8363 	zone_needdump(zone, DNS_DUMP_DELAY);
   8364 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   8365 	UNLOCK_ZONE(zone);
   8366 
   8367  done:
   8368 	/*
   8369 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   8370 	 */
   8371 	LOCK_ZONE(zone);
   8372 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8373 	     nsec3chain != NULL;
   8374 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   8375 	{
   8376 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8377 	}
   8378 	UNLOCK_ZONE(zone);
   8379 
   8380 	/*
   8381 	 * Everything has succeeded. Commit the changes.
   8382 	 * Unconditionally commit as zonediff.offline not checked above.
   8383 	 */
   8384 	dns_db_closeversion(db, &version, true);
   8385 
   8386 	/*
   8387 	 * Everything succeeded so we can clean these up now.
   8388 	 */
   8389 	nsec3chain = ISC_LIST_HEAD(cleanup);
   8390 	while (nsec3chain != NULL) {
   8391 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   8392 		dns_db_detach(&nsec3chain->db);
   8393 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   8394 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   8395 		nsec3chain = ISC_LIST_HEAD(cleanup);
   8396 	}
   8397 
   8398 	set_resigntime(zone);
   8399 
   8400  failure:
   8401 	if (result != ISC_R_SUCCESS) {
   8402 		dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
   8403 			   dns_result_totext(result));
   8404 	}
   8405 
   8406 	/*
   8407 	 * On error roll back the current nsec3chain.
   8408 	 */
   8409 	if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
   8410 		if (nsec3chain->done) {
   8411 			dns_db_detach(&nsec3chain->db);
   8412 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   8413 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   8414 		} else {
   8415 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   8416 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8417 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8418 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   8419 		}
   8420 	}
   8421 
   8422 	/*
   8423 	 * Rollback the cleanup list.
   8424 	 */
   8425 	nsec3chain = ISC_LIST_TAIL(cleanup);
   8426 	while (nsec3chain != NULL) {
   8427 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   8428 		if (nsec3chain->done) {
   8429 			dns_db_detach(&nsec3chain->db);
   8430 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   8431 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   8432 		} else {
   8433 			LOCK_ZONE(zone);
   8434 			ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
   8435 			UNLOCK_ZONE(zone);
   8436 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   8437 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8438 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8439 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   8440 		}
   8441 		nsec3chain = ISC_LIST_TAIL(cleanup);
   8442 	}
   8443 
   8444 	LOCK_ZONE(zone);
   8445 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8446 	     nsec3chain != NULL;
   8447 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   8448 	{
   8449 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8450 	}
   8451 	UNLOCK_ZONE(zone);
   8452 
   8453 	dns_diff_clear(&param_diff);
   8454 	dns_diff_clear(&nsec3_diff);
   8455 	dns_diff_clear(&nsec_diff);
   8456 	dns_diff_clear(&_sig_diff);
   8457 
   8458 	if (iterator != NULL) {
   8459 		dns_rdatasetiter_destroy(&iterator);
   8460 	}
   8461 
   8462 	for (i = 0; i < nkeys; i++) {
   8463 		dst_key_free(&zone_keys[i]);
   8464 	}
   8465 
   8466 	if (node != NULL) {
   8467 		dns_db_detachnode(db, &node);
   8468 	}
   8469 	if (version != NULL) {
   8470 		dns_db_closeversion(db, &version, false);
   8471 		dns_db_detach(&db);
   8472 	} else if (db != NULL) {
   8473 		dns_db_detach(&db);
   8474 	}
   8475 
   8476 	LOCK_ZONE(zone);
   8477 	if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
   8478 		isc_interval_t interval;
   8479 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   8480 			isc_interval_set(&interval, 60, 0);	  /* 1 minute */
   8481 		} else {
   8482 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   8483 		}
   8484 		isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
   8485 	} else {
   8486 		isc_time_settoepoch(&zone->nsec3chaintime);
   8487 	}
   8488 	UNLOCK_ZONE(zone);
   8489 
   8490 	INSIST(version == NULL);
   8491 }
   8492 
   8493 /*%
   8494  * Delete all RRSIG records with the given algorithm and keyid.
   8495  * Remove the NSEC record and RRSIGs if nkeys is zero.
   8496  * If all remaining RRsets are signed with the given algorithm
   8497  * set *has_algp to true.
   8498  */
   8499 static isc_result_t
   8500 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   8501 	dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
   8502 	uint16_t keyid, bool *has_algp, dns_diff_t *diff)
   8503 {
   8504 	dns_rdata_rrsig_t rrsig;
   8505 	dns_rdataset_t rdataset;
   8506 	dns_rdatasetiter_t *iterator = NULL;
   8507 	isc_result_t result;
   8508 	bool alg_missed = false;
   8509 	bool alg_found = false;
   8510 
   8511 	char namebuf[DNS_NAME_FORMATSIZE];
   8512 	dns_name_format(name, namebuf, sizeof(namebuf));
   8513 
   8514 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8515 	if (result != ISC_R_SUCCESS) {
   8516 		if (result == ISC_R_NOTFOUND)
   8517 			result = ISC_R_SUCCESS;
   8518 		return (result);
   8519 	}
   8520 
   8521 	dns_rdataset_init(&rdataset);
   8522 	for (result = dns_rdatasetiter_first(iterator);
   8523 	     result == ISC_R_SUCCESS;
   8524 	     result = dns_rdatasetiter_next(iterator)) {
   8525 		bool has_alg = false;
   8526 		dns_rdatasetiter_current(iterator, &rdataset);
   8527 		if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
   8528 			for (result = dns_rdataset_first(&rdataset);
   8529 			     result == ISC_R_SUCCESS;
   8530 			     result = dns_rdataset_next(&rdataset)) {
   8531 				dns_rdata_t rdata = DNS_RDATA_INIT;
   8532 				dns_rdataset_current(&rdataset, &rdata);
   8533 				CHECK(update_one_rr(db, version, diff,
   8534 						    DNS_DIFFOP_DEL, name,
   8535 						    rdataset.ttl, &rdata));
   8536 			}
   8537 			if (result != ISC_R_NOMORE)
   8538 				goto failure;
   8539 			dns_rdataset_disassociate(&rdataset);
   8540 			continue;
   8541 		}
   8542 		if (rdataset.type != dns_rdatatype_rrsig) {
   8543 			dns_rdataset_disassociate(&rdataset);
   8544 			continue;
   8545 		}
   8546 		for (result = dns_rdataset_first(&rdataset);
   8547 		     result == ISC_R_SUCCESS;
   8548 		     result = dns_rdataset_next(&rdataset))
   8549 		{
   8550 			dns_rdata_t rdata = DNS_RDATA_INIT;
   8551 			dns_rdataset_current(&rdataset, &rdata);
   8552 			CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
   8553 			if (nkeys != 0 &&
   8554 			    (rrsig.algorithm != algorithm ||
   8555 			     rrsig.keyid != keyid))
   8556 			{
   8557 				if (rrsig.algorithm == algorithm) {
   8558 					has_alg = true;
   8559 				}
   8560 				continue;
   8561 			}
   8562 			CHECK(update_one_rr(db, version, diff,
   8563 					    DNS_DIFFOP_DELRESIGN, name,
   8564 					    rdataset.ttl, &rdata));
   8565 		}
   8566 		dns_rdataset_disassociate(&rdataset);
   8567 		if (result != ISC_R_NOMORE)
   8568 			break;
   8569 
   8570 		/*
   8571 		 * After deleting, if there's still a signature for
   8572 		 * 'algorithm', set alg_found; if not, set alg_missed.
   8573 		 */
   8574 		if (has_alg) {
   8575 			alg_found = true;
   8576 		} else {
   8577 			alg_missed = true;
   8578 		}
   8579 	}
   8580 	if (result == ISC_R_NOMORE)
   8581 		result = ISC_R_SUCCESS;
   8582 
   8583 	/*
   8584 	 * Set `has_algp` if the algorithm was found in every RRset:
   8585 	 * i.e., found in at least one, and not missing from any.
   8586 	 */
   8587 	*has_algp = (alg_found && !alg_missed);
   8588  failure:
   8589 	if (dns_rdataset_isassociated(&rdataset))
   8590 		dns_rdataset_disassociate(&rdataset);
   8591 	dns_rdatasetiter_destroy(&iterator);
   8592 	return (result);
   8593 }
   8594 
   8595 /*
   8596  * Incrementally sign the zone using the keys requested.
   8597  * Builds the NSEC chain if required.
   8598  */
   8599 static void
   8600 zone_sign(dns_zone_t *zone) {
   8601 	const char *me = "zone_sign";
   8602 	dns_db_t *db = NULL;
   8603 	dns_dbnode_t *node = NULL;
   8604 	dns_dbversion_t *version = NULL;
   8605 	dns_diff_t _sig_diff;
   8606 	dns_diff_t post_diff;
   8607 	dns__zonediff_t zonediff;
   8608 	dns_fixedname_t fixed;
   8609 	dns_fixedname_t nextfixed;
   8610 	dns_name_t *name, *nextname;
   8611 	dns_rdataset_t rdataset;
   8612 	dns_signing_t *signing, *nextsigning;
   8613 	dns_signinglist_t cleanup;
   8614 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   8615 	int32_t signatures;
   8616 	bool check_ksk, keyset_kskonly, is_ksk;
   8617 	bool with_ksk, with_zsk;
   8618 	bool commit = false;
   8619 	bool is_bottom_of_zone;
   8620 	bool build_nsec = false;
   8621 	bool build_nsec3 = false;
   8622 	bool first;
   8623 	isc_result_t result;
   8624 	isc_stdtime_t now, inception, soaexpire, expire;
   8625 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   8626 	unsigned int i, j;
   8627 	unsigned int nkeys = 0;
   8628 	uint32_t nodes;
   8629 
   8630 	ENTER;
   8631 
   8632 	dns_rdataset_init(&rdataset);
   8633 	name = dns_fixedname_initname(&fixed);
   8634 	nextname = dns_fixedname_initname(&nextfixed);
   8635 	dns_diff_init(zone->mctx, &_sig_diff);
   8636 	dns_diff_init(zone->mctx, &post_diff);
   8637 	zonediff_init(&zonediff, &_sig_diff);
   8638 	ISC_LIST_INIT(cleanup);
   8639 
   8640 	/*
   8641 	 * Updates are disabled.  Pause for 1 minute.
   8642 	 */
   8643 	if (zone->update_disabled) {
   8644 		result = ISC_R_FAILURE;
   8645 		goto cleanup;
   8646 	}
   8647 
   8648 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8649 	if (zone->db != NULL) {
   8650 		dns_db_attach(zone->db, &db);
   8651 	}
   8652 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8653 	if (db == NULL) {
   8654 		result = ISC_R_FAILURE;
   8655 		goto cleanup;
   8656 	}
   8657 
   8658 	result = dns_db_newversion(db, &version);
   8659 	if (result != ISC_R_SUCCESS) {
   8660 		dnssec_log(zone, ISC_LOG_ERROR,
   8661 			   "zone_sign:dns_db_newversion -> %s",
   8662 			   dns_result_totext(result));
   8663 		goto cleanup;
   8664 	}
   8665 
   8666 	isc_stdtime_get(&now);
   8667 
   8668 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   8669 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   8670 	if (result != ISC_R_SUCCESS) {
   8671 		dnssec_log(zone, ISC_LOG_ERROR,
   8672 			   "zone_sign:dns__zone_findkeys -> %s",
   8673 			   dns_result_totext(result));
   8674 		goto cleanup;
   8675 	}
   8676 
   8677 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   8678 	inception = now - 3600;	/* Allow for clock skew. */
   8679 	soaexpire = now + sigvalidityinterval;
   8680 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   8681 	if (expiryinterval > sigvalidityinterval) {
   8682 		expiryinterval = sigvalidityinterval;
   8683 	} else {
   8684 		expiryinterval = sigvalidityinterval - expiryinterval;
   8685 	}
   8686 
   8687 	/*
   8688 	 * Spread out signatures over time if they happen to be
   8689 	 * clumped.  We don't do this for each add_sigs() call as
   8690 	 * we still want some clustering to occur.
   8691 	 */
   8692 	if (sigvalidityinterval >= 3600U) {
   8693 		if (sigvalidityinterval > 7200U) {
   8694 			jitter = isc_random_uniform(expiryinterval);
   8695 		} else {
   8696 			jitter = isc_random_uniform(1200);
   8697 		}
   8698 		expire = soaexpire - jitter - 1;
   8699 	} else {
   8700 		expire = soaexpire - 1;
   8701 	}
   8702 
   8703 	/*
   8704 	 * We keep pulling nodes off each iterator in turn until
   8705 	 * we have no more nodes to pull off or we reach the limits
   8706 	 * for this quantum.
   8707 	 */
   8708 	nodes = zone->nodes;
   8709 	signatures = zone->signatures;
   8710 	signing = ISC_LIST_HEAD(zone->signing);
   8711 	first = true;
   8712 
   8713 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   8714 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   8715 
   8716 	/* Determine which type of chain to build */
   8717 	CHECK(dns_private_chains(db, version, zone->privatetype,
   8718 				 &build_nsec, &build_nsec3));
   8719 
   8720 	/* If neither chain is found, default to NSEC */
   8721 	if (!build_nsec && !build_nsec3) {
   8722 		build_nsec = true;
   8723 	}
   8724 
   8725 	while (signing != NULL && nodes-- > 0 && signatures > 0) {
   8726 		bool has_alg = false;
   8727 		nextsigning = ISC_LIST_NEXT(signing, link);
   8728 
   8729 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8730 		if (signing->done || signing->db != zone->db) {
   8731 			/*
   8732 			 * The zone has been reloaded.	We will have
   8733 			 * created new signings as part of the reload
   8734 			 * process so we can destroy this one.
   8735 			 */
   8736 			ISC_LIST_UNLINK(zone->signing, signing, link);
   8737 			ISC_LIST_APPEND(cleanup, signing, link);
   8738 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8739 			goto next_signing;
   8740 		}
   8741 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8742 
   8743 		if (signing->db != db) {
   8744 			goto next_signing;
   8745 		}
   8746 
   8747 		is_bottom_of_zone = false;
   8748 
   8749 		if (first && signing->deleteit) {
   8750 			/*
   8751 			 * Remove the key we are deleting from consideration.
   8752 			 */
   8753 			for (i = 0, j = 0; i < nkeys; i++) {
   8754 				/*
   8755 				 * Find the key we want to remove.
   8756 				 */
   8757 				if (ALG(zone_keys[i]) == signing->algorithm &&
   8758 				    dst_key_id(zone_keys[i]) == signing->keyid)
   8759 				{
   8760 					if (KSK(zone_keys[i]))
   8761 						dst_key_free(&zone_keys[i]);
   8762 					continue;
   8763 				}
   8764 				zone_keys[j] = zone_keys[i];
   8765 				j++;
   8766 			}
   8767 			for (i = j; i < nkeys; i++) {
   8768 				zone_keys[i] = NULL;
   8769 			}
   8770 			nkeys = j;
   8771 		}
   8772 
   8773 		dns_dbiterator_current(signing->dbiterator, &node, name);
   8774 
   8775 		if (signing->deleteit) {
   8776 			dns_dbiterator_pause(signing->dbiterator);
   8777 			CHECK(del_sig(db, version, name, node, nkeys,
   8778 				      signing->algorithm, signing->keyid,
   8779 				      &has_alg, zonediff.diff));
   8780 		}
   8781 
   8782 		/*
   8783 		 * On the first pass we need to check if the current node
   8784 		 * has not been obscured.
   8785 		 */
   8786 		if (first) {
   8787 			dns_fixedname_t ffound;
   8788 			dns_name_t *found;
   8789 			found = dns_fixedname_initname(&ffound);
   8790 			result = dns_db_find(db, name, version,
   8791 					     dns_rdatatype_soa,
   8792 					     DNS_DBFIND_NOWILD, 0, NULL, found,
   8793 					     NULL, NULL);
   8794 			if ((result == DNS_R_DELEGATION ||
   8795 			     result == DNS_R_DNAME) &&
   8796 			    !dns_name_equal(name, found))
   8797 			{
   8798 				/*
   8799 				 * Remember the obscuring name so that
   8800 				 * we skip all obscured names.
   8801 				 */
   8802 				dns_name_copy(found, name, NULL);
   8803 				is_bottom_of_zone = true;
   8804 				goto next_node;
   8805 			}
   8806 		}
   8807 
   8808 		/*
   8809 		 * Process one node.
   8810 		 */
   8811 		with_ksk = false;
   8812 		with_zsk = false;
   8813 		dns_dbiterator_pause(signing->dbiterator);
   8814 
   8815 		CHECK(check_if_bottom_of_zone(db, node, version,
   8816 					      &is_bottom_of_zone));
   8817 
   8818 		for (i = 0; !has_alg && i < nkeys; i++) {
   8819 			bool both = false;
   8820 
   8821 			/*
   8822 			 * Find the keys we want to sign with.
   8823 			 */
   8824 			if (!dst_key_isprivate(zone_keys[i])) {
   8825 				continue;
   8826 			}
   8827 			/*
   8828 			 * Should be redundant.
   8829 			 */
   8830 			if (dst_key_inactive(zone_keys[i])) {
   8831 				continue;
   8832 			}
   8833 
   8834 			/*
   8835 			 * When adding look for the specific key.
   8836 			 */
   8837 			if (!signing->deleteit &&
   8838 			    (dst_key_alg(zone_keys[i]) != signing->algorithm ||
   8839 			     dst_key_id(zone_keys[i]) != signing->keyid))
   8840 			{
   8841 				continue;
   8842 			}
   8843 
   8844 			/*
   8845 			 * When deleting make sure we are properly signed
   8846 			 * with the algorithm that was being removed.
   8847 			 */
   8848 			if (signing->deleteit &&
   8849 			    ALG(zone_keys[i]) != signing->algorithm)
   8850 			{
   8851 				continue;
   8852 			}
   8853 
   8854 			/*
   8855 			 * Do we do KSK processing?
   8856 			 */
   8857 			if (check_ksk && !REVOKE(zone_keys[i])) {
   8858 				bool have_ksk, have_nonksk;
   8859 				if (KSK(zone_keys[i])) {
   8860 					have_ksk = true;
   8861 					have_nonksk = false;
   8862 				} else {
   8863 					have_ksk = false;
   8864 					have_nonksk = true;
   8865 				}
   8866 				for (j = 0; j < nkeys; j++) {
   8867 					if (j == i ||
   8868 					    (ALG(zone_keys[i]) !=
   8869 					     ALG(zone_keys[j])))
   8870 					{
   8871 						continue;
   8872 					}
   8873 					if (!dst_key_isprivate(zone_keys[j])) {
   8874 						continue;
   8875 					}
   8876 					/*
   8877 					 * Should be redundant.
   8878 					 */
   8879 					if (dst_key_inactive(zone_keys[j])) {
   8880 						continue;
   8881 					}
   8882 					if (REVOKE(zone_keys[j])) {
   8883 						continue;
   8884 					}
   8885 					if (KSK(zone_keys[j])) {
   8886 						have_ksk = true;
   8887 					} else {
   8888 						have_nonksk = true;
   8889 					}
   8890 					both = have_ksk && have_nonksk;
   8891 					if (both) {
   8892 						break;
   8893 					}
   8894 				}
   8895 			}
   8896 			if (both || REVOKE(zone_keys[i])) {
   8897 				is_ksk = KSK(zone_keys[i]);
   8898 			} else {
   8899 				is_ksk = false;
   8900 			}
   8901 
   8902 			/*
   8903 			 * If deleting signatures, we need to ensure that
   8904 			 * the RRset is still signed at least once by a
   8905 			 * KSK and a ZSK.
   8906 			 */
   8907 			if (signing->deleteit && !is_ksk && with_zsk) {
   8908 				continue;
   8909 			}
   8910 
   8911 			if (signing->deleteit && is_ksk && with_ksk) {
   8912 				continue;
   8913 			}
   8914 
   8915 			CHECK(sign_a_node(db, name, node, version, build_nsec3,
   8916 					  build_nsec, zone_keys[i], inception,
   8917 					  expire, zone->minimum, is_ksk,
   8918 					  (both && keyset_kskonly),
   8919 					  is_bottom_of_zone, zonediff.diff,
   8920 					  &signatures, zone->mctx));
   8921 			/*
   8922 			 * If we are adding we are done.  Look for other keys
   8923 			 * of the same algorithm if deleting.
   8924 			 */
   8925 			if (!signing->deleteit) {
   8926 				break;
   8927 			}
   8928 			if (!is_ksk) {
   8929 				with_zsk = true;
   8930 			}
   8931 			if (KSK(zone_keys[i])) {
   8932 				with_ksk = true;
   8933 			}
   8934 		}
   8935 
   8936 		/*
   8937 		 * Go onto next node.
   8938 		 */
   8939  next_node:
   8940 		first = false;
   8941 		dns_db_detachnode(db, &node);
   8942 		do {
   8943 			result = dns_dbiterator_next(signing->dbiterator);
   8944 			if (result == ISC_R_NOMORE) {
   8945 				ISC_LIST_UNLINK(zone->signing, signing, link);
   8946 				ISC_LIST_APPEND(cleanup, signing, link);
   8947 				dns_dbiterator_pause(signing->dbiterator);
   8948 				if (nkeys != 0 && build_nsec) {
   8949 					/*
   8950 					 * We have finished regenerating the
   8951 					 * zone with a zone signing key.
   8952 					 * The NSEC chain is now complete and
   8953 					 * there is a full set of signatures
   8954 					 * for the zone.  We can now clear the
   8955 					 * OPT bit from the NSEC record.
   8956 					 */
   8957 					result = updatesecure(db, version,
   8958 							      &zone->origin,
   8959 							      zone->minimum,
   8960 							      false,
   8961 							      &post_diff);
   8962 					if (result != ISC_R_SUCCESS) {
   8963 						dnssec_log(zone, ISC_LOG_ERROR,
   8964 						   "updatesecure -> %s",
   8965 						    dns_result_totext(result));
   8966 						goto cleanup;
   8967 					}
   8968 				}
   8969 				result = updatesignwithkey(zone, signing,
   8970 							   version,
   8971 							   build_nsec3,
   8972 							   zone->minimum,
   8973 							   &post_diff);
   8974 				if (result != ISC_R_SUCCESS) {
   8975 					dnssec_log(zone, ISC_LOG_ERROR,
   8976 						   "updatesignwithkey -> %s",
   8977 						   dns_result_totext(result));
   8978 					goto cleanup;
   8979 				}
   8980 				build_nsec = false;
   8981 				goto next_signing;
   8982 			} else if (result != ISC_R_SUCCESS) {
   8983 				dnssec_log(zone, ISC_LOG_ERROR,
   8984 					   "zone_sign:"
   8985 					   "dns_dbiterator_next -> %s",
   8986 					   dns_result_totext(result));
   8987 				goto cleanup;
   8988 			} else if (is_bottom_of_zone) {
   8989 				dns_dbiterator_current(signing->dbiterator,
   8990 						       &node, nextname);
   8991 				dns_db_detachnode(db, &node);
   8992 				if (!dns_name_issubdomain(nextname, name)) {
   8993 					break;
   8994 				}
   8995 			} else {
   8996 				break;
   8997 			}
   8998 		} while (1);
   8999 		continue;
   9000 
   9001  next_signing:
   9002 		dns_dbiterator_pause(signing->dbiterator);
   9003 		signing = nextsigning;
   9004 		first = true;
   9005 	}
   9006 
   9007 	if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
   9008 		result = dns__zone_updatesigs(&post_diff, db, version,
   9009 					      zone_keys, nkeys, zone,
   9010 					      inception, expire, 0, now,
   9011 					      check_ksk, keyset_kskonly,
   9012 					      &zonediff);
   9013 		if (result != ISC_R_SUCCESS) {
   9014 			dnssec_log(zone, ISC_LOG_ERROR,
   9015 				   "zone_sign:dns__zone_updatesigs -> %s",
   9016 				   dns_result_totext(result));
   9017 			goto cleanup;
   9018 		}
   9019 	}
   9020 
   9021 	/*
   9022 	 * Have we changed anything?
   9023 	 */
   9024 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   9025 		if (zonediff.offline) {
   9026 			commit = true;
   9027 		}
   9028 		result = ISC_R_SUCCESS;
   9029 		goto pauseall;
   9030 	}
   9031 
   9032 	commit = true;
   9033 
   9034 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   9035 			  &zonediff, zone_keys, nkeys, now, false);
   9036 	if (result != ISC_R_SUCCESS) {
   9037 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s",
   9038 			   dns_result_totext(result));
   9039 		goto cleanup;
   9040 	}
   9041 
   9042 	result = update_soa_serial(db, version, zonediff.diff, zone->mctx,
   9043 				   zone->updatemethod);
   9044 	if (result != ISC_R_SUCCESS) {
   9045 		dnssec_log(zone, ISC_LOG_ERROR,
   9046 			   "zone_sign:update_soa_serial -> %s",
   9047 			   dns_result_totext(result));
   9048 		goto cleanup;
   9049 	}
   9050 
   9051 	/*
   9052 	 * Generate maximum life time signatures so that the above loop
   9053 	 * termination is sensible.
   9054 	 */
   9055 	result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
   9056 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   9057 			  inception, soaexpire, check_ksk, keyset_kskonly);
   9058 	if (result != ISC_R_SUCCESS) {
   9059 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s",
   9060 			   dns_result_totext(result));
   9061 		goto cleanup;
   9062 	}
   9063 
   9064 	/*
   9065 	 * Write changes to journal file.
   9066 	 */
   9067 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
   9068 
   9069  pauseall:
   9070 	/*
   9071 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   9072 	 */
   9073 	for (signing = ISC_LIST_HEAD(zone->signing);
   9074 	     signing != NULL;
   9075 	     signing = ISC_LIST_NEXT(signing, link))
   9076 	{
   9077 		dns_dbiterator_pause(signing->dbiterator);
   9078 	}
   9079 
   9080 	for (signing = ISC_LIST_HEAD(cleanup);
   9081 	     signing != NULL;
   9082 	     signing = ISC_LIST_NEXT(signing, link))
   9083 	{
   9084 		dns_dbiterator_pause(signing->dbiterator);
   9085 	}
   9086 
   9087 	/*
   9088 	 * Everything has succeeded. Commit the changes.
   9089 	 */
   9090 	dns_db_closeversion(db, &version, commit);
   9091 
   9092 	/*
   9093 	 * Everything succeeded so we can clean these up now.
   9094 	 */
   9095 	signing = ISC_LIST_HEAD(cleanup);
   9096 	while (signing != NULL) {
   9097 		ISC_LIST_UNLINK(cleanup, signing, link);
   9098 		dns_db_detach(&signing->db);
   9099 		dns_dbiterator_destroy(&signing->dbiterator);
   9100 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   9101 		signing = ISC_LIST_HEAD(cleanup);
   9102 	}
   9103 
   9104 	set_resigntime(zone);
   9105 
   9106 	if (commit) {
   9107 		LOCK_ZONE(zone);
   9108 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   9109 		zone_needdump(zone, DNS_DUMP_DELAY);
   9110 		UNLOCK_ZONE(zone);
   9111 	}
   9112 
   9113  failure:
   9114 	if (result != ISC_R_SUCCESS) {
   9115 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s",
   9116 			   dns_result_totext(result));
   9117 	}
   9118 
   9119  cleanup:
   9120 	/*
   9121 	 * Pause all dbiterators.
   9122 	 */
   9123 	for (signing = ISC_LIST_HEAD(zone->signing);
   9124 	     signing != NULL;
   9125 	     signing = ISC_LIST_NEXT(signing, link))
   9126 	{
   9127 		dns_dbiterator_pause(signing->dbiterator);
   9128 	}
   9129 
   9130 	/*
   9131 	 * Rollback the cleanup list.
   9132 	 */
   9133 	signing = ISC_LIST_HEAD(cleanup);
   9134 	while (signing != NULL) {
   9135 		ISC_LIST_UNLINK(cleanup, signing, link);
   9136 		ISC_LIST_PREPEND(zone->signing, signing, link);
   9137 		dns_dbiterator_first(signing->dbiterator);
   9138 		dns_dbiterator_pause(signing->dbiterator);
   9139 		signing = ISC_LIST_HEAD(cleanup);
   9140 	}
   9141 
   9142 	dns_diff_clear(&_sig_diff);
   9143 
   9144 	for (i = 0; i < nkeys; i++) {
   9145 		dst_key_free(&zone_keys[i]);
   9146 	}
   9147 
   9148 	if (node != NULL) {
   9149 		dns_db_detachnode(db, &node);
   9150 	}
   9151 
   9152 	if (version != NULL) {
   9153 		dns_db_closeversion(db, &version, false);
   9154 		dns_db_detach(&db);
   9155 	} else if (db != NULL) {
   9156 		dns_db_detach(&db);
   9157 	}
   9158 
   9159 	if (ISC_LIST_HEAD(zone->signing) != NULL) {
   9160 		isc_interval_t interval;
   9161 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   9162 			isc_interval_set(&interval, 60, 0);	  /* 1 minute */
   9163 		} else {
   9164 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   9165 		}
   9166 		isc_time_nowplusinterval(&zone->signingtime, &interval);
   9167 	} else {
   9168 		isc_time_settoepoch(&zone->signingtime);
   9169 	}
   9170 
   9171 	INSIST(version == NULL);
   9172 }
   9173 
   9174 static isc_result_t
   9175 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
   9176 	      unsigned char *data, int size)
   9177 {
   9178 	dns_rdata_dnskey_t dnskey;
   9179 	dns_rdata_keydata_t keydata;
   9180 	isc_buffer_t buf;
   9181 	isc_result_t result;
   9182 
   9183 	dns_rdata_reset(target);
   9184 	isc_buffer_init(&buf, data, size);
   9185 
   9186 	switch (rr->type) {
   9187 	    case dns_rdatatype_dnskey:
   9188 		result = dns_rdata_tostruct(rr, &dnskey, NULL);
   9189 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9190 		dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
   9191 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   9192 				     &dnskey, &buf);
   9193 		break;
   9194 	    case dns_rdatatype_keydata:
   9195 		result = dns_rdata_tostruct(rr, &keydata, NULL);
   9196 		if (result == ISC_R_UNEXPECTEDEND)
   9197 			return (result);
   9198 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9199 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   9200 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   9201 				     &dnskey, &buf);
   9202 		break;
   9203 	    default:
   9204 		INSIST(0);
   9205 		ISC_UNREACHABLE();
   9206 	}
   9207 	return (ISC_R_SUCCESS);
   9208 }
   9209 
   9210 /*
   9211  * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
   9212  * a KEYDATA rdataset from the key zone.
   9213  *
   9214  * 'rr' contains either a DNSKEY record, or a KEYDATA record
   9215  *
   9216  * After normalizing keys to the same format (DNSKEY, with revoke bit
   9217  * cleared), return true if a key that matches 'rr' is found in
   9218  * 'rdset', or false if not.
   9219  */
   9220 
   9221 static bool
   9222 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
   9223 	unsigned char data1[4096], data2[4096];
   9224 	dns_rdata_t rdata, rdata1, rdata2;
   9225 	isc_result_t result;
   9226 
   9227 	dns_rdata_init(&rdata);
   9228 	dns_rdata_init(&rdata1);
   9229 	dns_rdata_init(&rdata2);
   9230 
   9231 	result = normalize_key(rr, &rdata1, data1, sizeof(data1));
   9232 	if (result != ISC_R_SUCCESS)
   9233 		return (false);
   9234 
   9235 	for (result = dns_rdataset_first(rdset);
   9236 	     result == ISC_R_SUCCESS;
   9237 	     result = dns_rdataset_next(rdset)) {
   9238 		dns_rdata_reset(&rdata);
   9239 		dns_rdataset_current(rdset, &rdata);
   9240 		result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
   9241 		if (result != ISC_R_SUCCESS)
   9242 			continue;
   9243 		if (dns_rdata_compare(&rdata1, &rdata2) == 0)
   9244 			return (true);
   9245 	}
   9246 
   9247 	return (false);
   9248 }
   9249 
   9250 /*
   9251  * Calculate the refresh interval for a keydata zone, per
   9252  * RFC5011: MAX(1 hr,
   9253  *		MIN(15 days,
   9254  *		    1/2 * OrigTTL,
   9255  *		    1/2 * RRSigExpirationInterval))
   9256  * or for retries: MAX(1 hr,
   9257  *		       MIN(1 day,
   9258  *			   1/10 * OrigTTL,
   9259  *			   1/10 * RRSigExpirationInterval))
   9260  */
   9261 static inline isc_stdtime_t
   9262 refresh_time(dns_keyfetch_t *kfetch, bool retry) {
   9263 	isc_result_t result;
   9264 	uint32_t t;
   9265 	dns_rdataset_t *rdset;
   9266 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   9267 	dns_rdata_sig_t sig;
   9268 	isc_stdtime_t now;
   9269 
   9270 	isc_stdtime_get(&now);
   9271 
   9272 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
   9273 		rdset = &kfetch->dnskeysigset;
   9274 	else
   9275 		return (now + dns_zone_mkey_hour);
   9276 
   9277 	result = dns_rdataset_first(rdset);
   9278 	if (result != ISC_R_SUCCESS)
   9279 		return (now + dns_zone_mkey_hour);
   9280 
   9281 	dns_rdataset_current(rdset, &sigrr);
   9282 	result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   9283 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9284 
   9285 	if (!retry) {
   9286 		t = sig.originalttl / 2;
   9287 
   9288 		if (isc_serial_gt(sig.timeexpire, now)) {
   9289 			uint32_t exp = (sig.timeexpire - now) / 2;
   9290 			if (t > exp)
   9291 				t = exp;
   9292 		}
   9293 
   9294 		if (t > (15 * dns_zone_mkey_day))
   9295 			t = (15 * dns_zone_mkey_day);
   9296 
   9297 		if (t < dns_zone_mkey_hour)
   9298 			t = dns_zone_mkey_hour;
   9299 	} else {
   9300 		t = sig.originalttl / 10;
   9301 
   9302 		if (isc_serial_gt(sig.timeexpire, now)) {
   9303 			uint32_t exp = (sig.timeexpire - now) / 10;
   9304 			if (t > exp)
   9305 				t = exp;
   9306 		}
   9307 
   9308 		if (t > dns_zone_mkey_day)
   9309 			t = dns_zone_mkey_day;
   9310 
   9311 		if (t < dns_zone_mkey_hour)
   9312 			t = dns_zone_mkey_hour;
   9313 	}
   9314 
   9315 	return (now + t);
   9316 }
   9317 
   9318 /*
   9319  * This routine is called when no changes are needed in a KEYDATA
   9320  * record except to simply update the refresh timer.  Caller should
   9321  * hold zone lock.
   9322  */
   9323 static isc_result_t
   9324 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
   9325 {
   9326 	isc_result_t result;
   9327 	isc_buffer_t keyb;
   9328 	unsigned char key_buf[4096];
   9329 	dns_rdata_t rdata = DNS_RDATA_INIT;
   9330 	dns_rdata_keydata_t keydata;
   9331 	dns_name_t *name;
   9332 	dns_zone_t *zone = kfetch->zone;
   9333 	isc_stdtime_t now;
   9334 
   9335 	name = dns_fixedname_name(&kfetch->name);
   9336 	isc_stdtime_get(&now);
   9337 
   9338 	for (result = dns_rdataset_first(&kfetch->keydataset);
   9339 	     result == ISC_R_SUCCESS;
   9340 	     result = dns_rdataset_next(&kfetch->keydataset)) {
   9341 		dns_rdata_reset(&rdata);
   9342 		dns_rdataset_current(&kfetch->keydataset, &rdata);
   9343 
   9344 		/* Delete old version */
   9345 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
   9346 				    name, 0, &rdata));
   9347 
   9348 		/* Update refresh timer */
   9349 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   9350 		if (result == ISC_R_UNEXPECTEDEND)
   9351 			continue;
   9352 		if (result != ISC_R_SUCCESS)
   9353 			goto failure;
   9354 		keydata.refresh = refresh_time(kfetch, true);
   9355 		set_refreshkeytimer(zone, &keydata, now, false);
   9356 
   9357 		dns_rdata_reset(&rdata);
   9358 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   9359 		CHECK(dns_rdata_fromstruct(&rdata,
   9360 					   zone->rdclass, dns_rdatatype_keydata,
   9361 					   &keydata, &keyb));
   9362 
   9363 		/* Insert updated version */
   9364 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
   9365 				    name, 0, &rdata));
   9366 	}
   9367 	result = ISC_R_SUCCESS;
   9368   failure:
   9369 	return (result);
   9370 }
   9371 
   9372 /*
   9373  * Verify that DNSKEY set is signed by the key specified in 'keydata'.
   9374  */
   9375 static bool
   9376 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
   9377 	isc_result_t result;
   9378 	dns_name_t *keyname;
   9379 	isc_mem_t *mctx;
   9380 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   9381 	dns_rdata_t rr = DNS_RDATA_INIT;
   9382 	dns_rdata_rrsig_t sig;
   9383 	dns_rdata_dnskey_t dnskey;
   9384 	dst_key_t *dstkey = NULL;
   9385 	unsigned char key_buf[4096];
   9386 	isc_buffer_t keyb;
   9387 	bool answer = false;
   9388 
   9389 	REQUIRE(kfetch != NULL && keydata != NULL);
   9390 	REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
   9391 
   9392 	keyname = dns_fixedname_name(&kfetch->name);
   9393 	mctx = kfetch->zone->view->mctx;
   9394 
   9395 	/* Generate a key from keydata */
   9396 	isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   9397 	dns_keydata_todnskey(keydata, &dnskey, NULL);
   9398 	dns_rdata_fromstruct(&rr, keydata->common.rdclass,
   9399 			     dns_rdatatype_dnskey, &dnskey, &keyb);
   9400 	result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
   9401 	if (result != ISC_R_SUCCESS) {
   9402 		return (false);
   9403 	}
   9404 
   9405 	/* See if that key generated any of the signatures */
   9406 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
   9407 	     result == ISC_R_SUCCESS;
   9408 	     result = dns_rdataset_next(&kfetch->dnskeysigset))
   9409 	{
   9410 		dns_fixedname_t fixed;
   9411 		dns_fixedname_init(&fixed);
   9412 
   9413 		dns_rdata_reset(&sigrr);
   9414 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
   9415 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   9416 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9417 
   9418 		if (dst_key_alg(dstkey) == sig.algorithm &&
   9419 		    dst_key_rid(dstkey) == sig.keyid)
   9420 		{
   9421 			result = dns_dnssec_verify(keyname,
   9422 						   &kfetch->dnskeyset,
   9423 						   dstkey, false, 0, mctx,
   9424 						   &sigrr,
   9425 						   dns_fixedname_name(&fixed));
   9426 
   9427 			dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3),
   9428 				   "Confirm revoked DNSKEY is self-signed: %s",
   9429 				   dns_result_totext(result));
   9430 
   9431 			if (result == ISC_R_SUCCESS) {
   9432 				answer = true;
   9433 				break;
   9434 			}
   9435 		}
   9436 	}
   9437 
   9438 	dst_key_free(&dstkey);
   9439 	return (answer);
   9440 }
   9441 
   9442 /*
   9443  * A DNSKEY set has been fetched from the zone apex of a zone whose trust
   9444  * anchors are being managed; scan the keyset, and update the key zone and the
   9445  * local trust anchors according to RFC5011.
   9446  */
   9447 static void
   9448 keyfetch_done(isc_task_t *task, isc_event_t *event) {
   9449 	isc_result_t result, eresult;
   9450 	dns_fetchevent_t *devent;
   9451 	dns_keyfetch_t *kfetch;
   9452 	dns_zone_t *zone;
   9453 	isc_mem_t *mctx = NULL;
   9454 	dns_keytable_t *secroots = NULL;
   9455 	dns_dbversion_t *ver = NULL;
   9456 	dns_diff_t diff;
   9457 	bool alldone = false;
   9458 	bool commit = false;
   9459 	dns_name_t *keyname;
   9460 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   9461 	dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
   9462 	dns_rdata_t keydatarr = DNS_RDATA_INIT;
   9463 	dns_rdata_rrsig_t sig;
   9464 	dns_rdata_dnskey_t dnskey;
   9465 	dns_rdata_keydata_t keydata;
   9466 	bool initializing;
   9467 	char namebuf[DNS_NAME_FORMATSIZE];
   9468 	unsigned char key_buf[4096];
   9469 	isc_buffer_t keyb;
   9470 	dst_key_t *dstkey;
   9471 	isc_stdtime_t now;
   9472 	int pending = 0;
   9473 	bool secure = false, initial = false;
   9474 	bool free_needed;
   9475 
   9476 	UNUSED(task);
   9477 	INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
   9478 	INSIST(event->ev_arg != NULL);
   9479 
   9480 	kfetch = event->ev_arg;
   9481 	zone = kfetch->zone;
   9482 	isc_mem_attach(zone->mctx, &mctx);
   9483 	keyname = dns_fixedname_name(&kfetch->name);
   9484 
   9485 	devent = (dns_fetchevent_t *) event;
   9486 	eresult = devent->result;
   9487 
   9488 	/* Free resources which are not of interest */
   9489 	if (devent->node != NULL) {
   9490 		dns_db_detachnode(devent->db, &devent->node);
   9491 	}
   9492 	if (devent->db != NULL) {
   9493 		dns_db_detach(&devent->db);
   9494 	}
   9495 	isc_event_free(&event);
   9496 	dns_resolver_destroyfetch(&kfetch->fetch);
   9497 
   9498 	LOCK_ZONE(zone);
   9499 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) {
   9500 		goto cleanup;
   9501 	}
   9502 
   9503 	isc_stdtime_get(&now);
   9504 	dns_name_format(keyname, namebuf, sizeof(namebuf));
   9505 
   9506 	result = dns_view_getsecroots(zone->view, &secroots);
   9507 	INSIST(result == ISC_R_SUCCESS);
   9508 
   9509 	dns_diff_init(mctx, &diff);
   9510 
   9511 	CHECK(dns_db_newversion(kfetch->db, &ver));
   9512 
   9513 	zone->refreshkeycount--;
   9514 	alldone = (zone->refreshkeycount == 0);
   9515 
   9516 	if (alldone) {
   9517 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   9518 	}
   9519 
   9520 	dnssec_log(zone, ISC_LOG_DEBUG(3),
   9521 		   "Returned from key fetch in keyfetch_done() for '%s': %s",
   9522 		   namebuf, dns_result_totext(eresult));
   9523 
   9524 	/* Fetch failed */
   9525 	if (eresult != ISC_R_SUCCESS ||
   9526 	    !dns_rdataset_isassociated(&kfetch->dnskeyset))
   9527 	{
   9528 		dnssec_log(zone, ISC_LOG_WARNING,
   9529 			   "Unable to fetch DNSKEY set '%s': %s",
   9530 			   namebuf, dns_result_totext(eresult));
   9531 		CHECK(minimal_update(kfetch, ver, &diff));
   9532 		goto done;
   9533 	}
   9534 
   9535 	/* No RRSIGs found */
   9536 	if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
   9537 		dnssec_log(zone, ISC_LOG_WARNING,
   9538 			   "No DNSKEY RRSIGs found for '%s': %s",
   9539 			   namebuf, dns_result_totext(eresult));
   9540 		CHECK(minimal_update(kfetch, ver, &diff));
   9541 		goto done;
   9542 	}
   9543 
   9544 	/*
   9545 	 * Clear any cached trust level, as we need to run validation
   9546 	 * over again; trusted keys might have changed.
   9547 	 */
   9548 	kfetch->dnskeyset.trust = kfetch->dnskeysigset.trust = dns_trust_none;
   9549 
   9550 	/*
   9551 	 * Validate the dnskeyset against the current trusted keys.
   9552 	 */
   9553 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
   9554 	     result == ISC_R_SUCCESS;
   9555 	     result = dns_rdataset_next(&kfetch->dnskeysigset))
   9556 	{
   9557 		dns_keynode_t *keynode = NULL;
   9558 
   9559 		dns_rdata_reset(&sigrr);
   9560 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
   9561 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   9562 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9563 
   9564 		result = dns_keytable_find(secroots, keyname, &keynode);
   9565 		while (result == ISC_R_SUCCESS) {
   9566 			dns_keynode_t *nextnode = NULL;
   9567 			dns_fixedname_t fixed;
   9568 			dns_fixedname_init(&fixed);
   9569 
   9570 			dstkey = dns_keynode_key(keynode);
   9571 			if (dstkey == NULL) {
   9572 				/* fail_secure() was called */
   9573 				break;
   9574 			}
   9575 
   9576 			if (dst_key_alg(dstkey) == sig.algorithm &&
   9577 			    dst_key_id(dstkey) == sig.keyid)
   9578 			{
   9579 				result = dns_dnssec_verify(keyname,
   9580 							   &kfetch->dnskeyset,
   9581 							   dstkey, false,
   9582 							   0,
   9583 							   zone->view->mctx,
   9584 							   &sigrr,
   9585 							   dns_fixedname_name(
   9586 							   &fixed));
   9587 
   9588 				dnssec_log(zone, ISC_LOG_DEBUG(3),
   9589 					   "Verifying DNSKEY set for zone "
   9590 					   "'%s' using key %d/%d: %s",
   9591 					   namebuf, sig.keyid, sig.algorithm,
   9592 					   dns_result_totext(result));
   9593 
   9594 				if (result == ISC_R_SUCCESS) {
   9595 					kfetch->dnskeyset.trust =
   9596 						dns_trust_secure;
   9597 					kfetch->dnskeysigset.trust =
   9598 						dns_trust_secure;
   9599 					secure = true;
   9600 					initial = dns_keynode_initial(keynode);
   9601 					dns_keynode_trust(keynode);
   9602 					break;
   9603 				}
   9604 			}
   9605 
   9606 			result = dns_keytable_nextkeynode(secroots,
   9607 							  keynode, &nextnode);
   9608 			dns_keytable_detachkeynode(secroots, &keynode);
   9609 			keynode = nextnode;
   9610 		}
   9611 
   9612 		if (keynode != NULL) {
   9613 			dns_keytable_detachkeynode(secroots, &keynode);
   9614 		}
   9615 
   9616 		if (secure) {
   9617 			break;
   9618 		}
   9619 	}
   9620 
   9621 	/*
   9622 	 * If we were not able to verify the answer using the current
   9623 	 * trusted keys then all we can do is look at any revoked keys.
   9624 	 */
   9625 	if (!secure) {
   9626 		dnssec_log(zone, ISC_LOG_INFO,
   9627 			   "DNSKEY set for zone '%s' could not be verified "
   9628 			   "with current keys", namebuf);
   9629 	}
   9630 
   9631 	/*
   9632 	 * First scan keydataset to find keys that are not in dnskeyset
   9633 	 *   - Missing keys which are not scheduled for removal,
   9634 	 *     log a warning
   9635 	 *   - Missing keys which are scheduled for removal and
   9636 	 *     the remove hold-down timer has completed should
   9637 	 *     be removed from the key zone
   9638 	 *   - Missing keys whose acceptance timers have not yet
   9639 	 *     completed, log a warning and reset the acceptance
   9640 	 *     timer to 30 days in the future
   9641 	 *   - All keys not being removed have their refresh timers
   9642 	 *     updated
   9643 	 */
   9644 	initializing = true;
   9645 	for (result = dns_rdataset_first(&kfetch->keydataset);
   9646 	     result == ISC_R_SUCCESS;
   9647 	     result = dns_rdataset_next(&kfetch->keydataset))
   9648 	{
   9649 		dns_keytag_t keytag;
   9650 
   9651 		dns_rdata_reset(&keydatarr);
   9652 		dns_rdataset_current(&kfetch->keydataset, &keydatarr);
   9653 		result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   9654 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9655 
   9656 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   9657 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   9658 		if (result != ISC_R_SUCCESS) {
   9659 			/*
   9660 			 * Skip if we cannot compute the key tag.
   9661 			 * This may happen if the algorithm is unsupported
   9662 			 */
   9663 			dns_zone_log(zone, ISC_LOG_ERROR,
   9664 				"Cannot compute tag for key in zone %s: %s "
   9665 				"(skipping)",
   9666 				namebuf, dns_result_totext(result));
   9667 			continue;
   9668 		}
   9669 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9670 
   9671 		/*
   9672 		 * If any keydata record has a nonzero add holddown, then
   9673 		 * there was a pre-existing trust anchor for this domain;
   9674 		 * that means we are *not* initializing it and shouldn't
   9675 		 * automatically trust all the keys we find at the zone apex.
   9676 		 */
   9677 		initializing = initializing && (keydata.addhd == 0);
   9678 
   9679 		if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
   9680 			bool deletekey = false;
   9681 
   9682 			if (!secure) {
   9683 				if (keydata.removehd != 0 &&
   9684 				    keydata.removehd <= now)
   9685 				{
   9686 					deletekey = true;
   9687 				}
   9688 			} else if (keydata.addhd == 0) {
   9689 				deletekey = true;
   9690 			} else if (keydata.addhd > now) {
   9691 				dnssec_log(zone, ISC_LOG_INFO,
   9692 					   "Pending key %d for zone %s "
   9693 					   "unexpectedly missing "
   9694 					   "restarting 30-day acceptance "
   9695 					   "timer", keytag, namebuf);
   9696 				if (keydata.addhd < now + dns_zone_mkey_month) {
   9697 					keydata.addhd =
   9698 						now + dns_zone_mkey_month;
   9699 				}
   9700 				keydata.refresh = refresh_time(kfetch, false);
   9701 			} else if (keydata.removehd == 0) {
   9702 				dnssec_log(zone, ISC_LOG_INFO,
   9703 					   "Active key %d for zone %s "
   9704 					   "unexpectedly missing",
   9705 					   keytag, namebuf);
   9706 				keydata.refresh = now + dns_zone_mkey_hour;
   9707 			} else if (keydata.removehd <= now) {
   9708 				deletekey = true;
   9709 				dnssec_log(zone, ISC_LOG_INFO,
   9710 					   "Revoked key %d for zone %s "
   9711 					   "missing: deleting from "
   9712 					   "managed keys database",
   9713 					   keytag, namebuf);
   9714 			} else {
   9715 				keydata.refresh = refresh_time(kfetch, false);
   9716 			}
   9717 
   9718 			if (secure || deletekey) {
   9719 				/* Delete old version */
   9720 				CHECK(update_one_rr(kfetch->db, ver, &diff,
   9721 						    DNS_DIFFOP_DEL, keyname, 0,
   9722 						    &keydatarr));
   9723 			}
   9724 
   9725 			if (!secure || deletekey) {
   9726 				continue;
   9727 			}
   9728 
   9729 			dns_rdata_reset(&keydatarr);
   9730 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   9731 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   9732 					     dns_rdatatype_keydata,
   9733 					     &keydata, &keyb);
   9734 
   9735 			/* Insert updated version */
   9736 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   9737 					    DNS_DIFFOP_ADD, keyname, 0,
   9738 					    &keydatarr));
   9739 
   9740 			set_refreshkeytimer(zone, &keydata, now, false);
   9741 		}
   9742 	}
   9743 
   9744 	/*
   9745 	 * Next scan dnskeyset:
   9746 	 *   - If new keys are found (i.e., lacking a match in keydataset)
   9747 	 *     add them to the key zone and set the acceptance timer
   9748 	 *     to 30 days in the future (or to immediately if we've
   9749 	 *     determined that we're initializing the zone for the
   9750 	 *     first time)
   9751 	 *   - Previously-known keys that have been revoked
   9752 	 *     must be scheduled for removal from the key zone (or,
   9753 	 *     if they hadn't been accepted as trust anchors yet
   9754 	 *     anyway, removed at once)
   9755 	 *   - Previously-known unrevoked keys whose acceptance timers
   9756 	 *     have completed are promoted to trust anchors
   9757 	 *   - All keys not being removed have their refresh
   9758 	 *     timers updated
   9759 	 */
   9760 	for (result = dns_rdataset_first(&kfetch->dnskeyset);
   9761 	     result == ISC_R_SUCCESS;
   9762 	     result = dns_rdataset_next(&kfetch->dnskeyset))
   9763 	{
   9764 		bool revoked = false;
   9765 		bool newkey = false;
   9766 		bool updatekey = false;
   9767 		bool deletekey = false;
   9768 		bool trustkey = false;
   9769 		dns_keytag_t keytag;
   9770 
   9771 		dns_rdata_reset(&dnskeyrr);
   9772 		dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
   9773 		result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   9774 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9775 
   9776 		/* Skip ZSK's */
   9777 		if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
   9778 			continue;
   9779 		}
   9780 
   9781 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   9782 		if (result != ISC_R_SUCCESS) {
   9783 			/*
   9784 			 * Skip if we cannot compute the key tag.
   9785 			 * This may happen if the algorithm is unsupported
   9786 			 */
   9787 			dns_zone_log(zone, ISC_LOG_ERROR,
   9788 				"Cannot compute tag for key in zone %s: %s "
   9789 				"(skipping)",
   9790 				namebuf, dns_result_totext(result));
   9791 			continue;
   9792 		}
   9793 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9794 
   9795 		revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
   9796 
   9797 		if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
   9798 			dns_rdata_reset(&keydatarr);
   9799 			dns_rdataset_current(&kfetch->keydataset, &keydatarr);
   9800 			result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   9801 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9802 
   9803 			if (revoked && revocable(kfetch, &keydata)) {
   9804 				if (keydata.addhd > now) {
   9805 					/*
   9806 					 * Key wasn't trusted yet, and now
   9807 					 * it's been revoked?  Just remove it
   9808 					 */
   9809 					deletekey = true;
   9810 					dnssec_log(zone, ISC_LOG_INFO,
   9811 						   "Pending key %d for "
   9812 						   "zone %s is now revoked: "
   9813 						   "deleting from the "
   9814 						   "managed keys database",
   9815 						   keytag, namebuf);
   9816 				} else if (keydata.removehd == 0) {
   9817 					/*
   9818 					 * Remove key from secroots.
   9819 					 */
   9820 					dns_view_untrust(zone->view, keyname,
   9821 							 &dnskey, mctx);
   9822 
   9823 					/* If initializing, delete now */
   9824 					if (keydata.addhd == 0) {
   9825 						deletekey = true;
   9826 					} else {
   9827 						keydata.removehd = now +
   9828 							dns_zone_mkey_month;
   9829 						keydata.flags |=
   9830 							DNS_KEYFLAG_REVOKE;
   9831 					}
   9832 
   9833 					dnssec_log(zone, ISC_LOG_INFO,
   9834 						   "Trusted key %d for "
   9835 						   "zone %s is now revoked",
   9836 						   keytag, namebuf);
   9837 				} else if (keydata.removehd < now) {
   9838 					/* Scheduled for removal */
   9839 					deletekey = true;
   9840 
   9841 					dnssec_log(zone, ISC_LOG_INFO,
   9842 						   "Revoked key %d for "
   9843 						   "zone %s removal timer "
   9844 						   "complete: deleting from "
   9845 						   "the managed keys database",
   9846 						   keytag, namebuf);
   9847 				}
   9848 			} else if (revoked && keydata.removehd == 0) {
   9849 				dnssec_log(zone, ISC_LOG_WARNING,
   9850 					   "Active key %d for zone "
   9851 					   "%s is revoked but "
   9852 					   "did not self-sign; "
   9853 					   "ignoring", keytag, namebuf);
   9854 				continue;
   9855 			} else if (secure) {
   9856 				if (keydata.removehd != 0) {
   9857 					/*
   9858 					 * Key isn't revoked--but it
   9859 					 * seems it used to be.
   9860 					 * Remove it now and add it
   9861 					 * back as if it were a fresh key,
   9862 					 * with a 30-day acceptance timer.
   9863 					 */
   9864 					deletekey = true;
   9865 					newkey = true;
   9866 					keydata.removehd = 0;
   9867 					keydata.addhd =
   9868 						now + dns_zone_mkey_month;
   9869 
   9870 					dnssec_log(zone, ISC_LOG_INFO,
   9871 						   "Revoked key %d for "
   9872 						   "zone %s has returned: "
   9873 						   "starting 30-day "
   9874 						   "acceptance timer",
   9875 						   keytag, namebuf);
   9876 				} else if (keydata.addhd > now) {
   9877 					pending++;
   9878 				} else if (keydata.addhd == 0) {
   9879 					keydata.addhd = now;
   9880 				}
   9881 
   9882 				if (keydata.addhd <= now) {
   9883 					trustkey = true;
   9884 					dnssec_log(zone, ISC_LOG_INFO,
   9885 						   "Key %d for zone %s "
   9886 						   "is now trusted (%s)",
   9887 						   keytag, namebuf,
   9888 						   initial
   9889 						    ? "initializing key "
   9890 						       "verified"
   9891 						    : "acceptance timer "
   9892 						       "complete");
   9893 				}
   9894 			} else if (keydata.addhd > now) {
   9895 				/*
   9896 				 * Not secure, and key is pending:
   9897 				 * reset the acceptance timer
   9898 				 */
   9899 				pending++;
   9900 				keydata.addhd = now + dns_zone_mkey_month;
   9901 				dnssec_log(zone, ISC_LOG_INFO,
   9902 					   "Pending key %d "
   9903 					   "for zone %s was "
   9904 					   "not validated: restarting "
   9905 					   "30-day acceptance timer",
   9906 					   keytag, namebuf);
   9907 			}
   9908 
   9909 			if (!deletekey && !newkey) {
   9910 				updatekey = true;
   9911 			}
   9912 		} else if (secure) {
   9913 			/*
   9914 			 * Key wasn't in the key zone but it's
   9915 			 * revoked now anyway, so just skip it
   9916 			 */
   9917 			if (revoked) {
   9918 				continue;
   9919 			}
   9920 
   9921 			/* Key wasn't in the key zone: add it */
   9922 			newkey = true;
   9923 
   9924 			if (initializing) {
   9925 				dnssec_log(zone, ISC_LOG_WARNING,
   9926 					   "Initializing automatic trust "
   9927 					   "anchor management for zone '%s'; "
   9928 					   "DNSKEY ID %d is now trusted, "
   9929 					   "waiving the normal 30-day "
   9930 					   "waiting period.",
   9931 					   namebuf, keytag);
   9932 				trustkey = true;
   9933 			} else {
   9934 				dnssec_log(zone, ISC_LOG_INFO,
   9935 					   "New key %d observed "
   9936 					   "for zone '%s': "
   9937 					   "starting 30-day "
   9938 					   "acceptance timer",
   9939 					   keytag, namebuf);
   9940 			}
   9941 		} else {
   9942 			/*
   9943 			 * No previously known key, and the key is not
   9944 			 * secure, so skip it.
   9945 			 */
   9946 			continue;
   9947 		}
   9948 
   9949 		/* Delete old version */
   9950 		if (deletekey || !newkey) {
   9951 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   9952 					    DNS_DIFFOP_DEL, keyname, 0,
   9953 					    &keydatarr));
   9954 		}
   9955 
   9956 		if (updatekey) {
   9957 			/* Set refresh timer */
   9958 			keydata.refresh = refresh_time(kfetch, false);
   9959 			dns_rdata_reset(&keydatarr);
   9960 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   9961 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   9962 					     dns_rdatatype_keydata,
   9963 					     &keydata, &keyb);
   9964 
   9965 			/* Insert updated version */
   9966 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   9967 					    DNS_DIFFOP_ADD, keyname, 0,
   9968 					    &keydatarr));
   9969 		} else if (newkey) {
   9970 			/* Convert DNSKEY to KEYDATA */
   9971 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   9972 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9973 			dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
   9974 					       NULL);
   9975 			keydata.addhd = initializing
   9976 					 ? now : now + dns_zone_mkey_month;
   9977 			keydata.refresh = refresh_time(kfetch, false);
   9978 			dns_rdata_reset(&keydatarr);
   9979 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   9980 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   9981 					     dns_rdatatype_keydata,
   9982 					     &keydata, &keyb);
   9983 
   9984 			/* Insert into key zone */
   9985 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   9986 					    DNS_DIFFOP_ADD, keyname, 0,
   9987 					    &keydatarr));
   9988 		}
   9989 
   9990 		if (trustkey) {
   9991 			/* Trust this key. */
   9992 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   9993 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9994 			trust_key(zone, keyname, &dnskey, false, mctx);
   9995 		}
   9996 
   9997 		if (secure && !deletekey) {
   9998 			INSIST(newkey || updatekey);
   9999 			set_refreshkeytimer(zone, &keydata, now, false);
   10000 		}
   10001 	}
   10002 
   10003 	/*
   10004 	 * RFC5011 says, "A trust point that has all of its trust anchors
   10005 	 * revoked is considered deleted and is treated as if the trust
   10006 	 * point was never configured."  But if someone revoked their
   10007 	 * active key before the standby was trusted, that would mean the
   10008 	 * zone would suddenly be nonsecured.  We avoid this by checking to
   10009 	 * see if there's pending keydata.  If so, we put a null key in
   10010 	 * the security roots; then all queries to the zone will fail.
   10011 	 */
   10012 	if (pending != 0) {
   10013 		fail_secure(zone, keyname);
   10014 	}
   10015 
   10016  done:
   10017 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10018 		/* Write changes to journal file. */
   10019 		CHECK(update_soa_serial(kfetch->db, ver, &diff, mctx,
   10020 					zone->updatemethod));
   10021 		CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
   10022 		commit = true;
   10023 
   10024 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   10025 		zone_needdump(zone, 30);
   10026 	} else if (result == ISC_R_NOMORE) {
   10027 		/*
   10028 		 * If "updatekey" was true for all keys found in the DNSKEY
   10029 		 * response and the previous update of those keys happened
   10030 		 * during the same second (only possible if a key refresh was
   10031 		 * externally triggered), it may happen that all relevant
   10032 		 * update_one_rr() calls will return ISC_R_SUCCESS, but
   10033 		 * diff.tuples will remain empty.  Reset result to
   10034 		 * ISC_R_SUCCESS to prevent a bogus warning from being logged.
   10035 		 */
   10036 		result = ISC_R_SUCCESS;
   10037 	}
   10038 
   10039  failure:
   10040 	if (result != ISC_R_SUCCESS) {
   10041 		dnssec_log(zone, ISC_LOG_ERROR,
   10042 			   "error during managed-keys processing (%s): "
   10043 			   "DNSSEC validation may be at risk",
   10044 			   isc_result_totext(result));
   10045 	}
   10046 	dns_diff_clear(&diff);
   10047 	if (ver != NULL) {
   10048 		dns_db_closeversion(kfetch->db, &ver, commit);
   10049 	}
   10050 
   10051  cleanup:
   10052 	dns_db_detach(&kfetch->db);
   10053 
   10054 	INSIST(zone->irefs > 0);
   10055 	zone->irefs--;
   10056 	kfetch->zone = NULL;
   10057 
   10058 	if (dns_rdataset_isassociated(&kfetch->keydataset)) {
   10059 		dns_rdataset_disassociate(&kfetch->keydataset);
   10060 	}
   10061 	if (dns_rdataset_isassociated(&kfetch->dnskeyset)) {
   10062 		dns_rdataset_disassociate(&kfetch->dnskeyset);
   10063 	}
   10064 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
   10065 		dns_rdataset_disassociate(&kfetch->dnskeysigset);
   10066 	}
   10067 
   10068 	dns_name_free(keyname, mctx);
   10069 	isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
   10070 	isc_mem_detach(&mctx);
   10071 
   10072 	if (secroots != NULL) {
   10073 		dns_keytable_detach(&secroots);
   10074 	}
   10075 
   10076 	free_needed = exit_check(zone);
   10077 	UNLOCK_ZONE(zone);
   10078 	if (free_needed) {
   10079 		zone_free(zone);
   10080 	}
   10081 
   10082 	INSIST(ver == NULL);
   10083 }
   10084 
   10085 /*
   10086  * Refresh the data in the key zone.  Initiate a fetch to get new DNSKEY
   10087  * records from the zone apex.
   10088  */
   10089 static void
   10090 zone_refreshkeys(dns_zone_t *zone) {
   10091 	const char me[] = "zone_refreshkeys";
   10092 	isc_result_t result;
   10093 	dns_rriterator_t rrit;
   10094 	dns_db_t *db = NULL;
   10095 	dns_dbversion_t *ver = NULL;
   10096 	dns_diff_t diff;
   10097 	dns_rdata_t rdata = DNS_RDATA_INIT;
   10098 	dns_rdata_keydata_t kd;
   10099 	isc_stdtime_t now;
   10100 	bool commit = false;
   10101 	bool fetching = false, fetch_err = false;
   10102 	bool timerset = false;
   10103 
   10104 	ENTER;
   10105 	REQUIRE(zone->db != NULL);
   10106 
   10107 	isc_stdtime_get(&now);
   10108 
   10109 	LOCK_ZONE(zone);
   10110 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   10111 		isc_time_settoepoch(&zone->refreshkeytime);
   10112 		UNLOCK_ZONE(zone);
   10113 		return;
   10114 	}
   10115 
   10116 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   10117 	dns_db_attach(zone->db, &db);
   10118 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   10119 
   10120 	dns_diff_init(zone->mctx, &diff);
   10121 
   10122 	CHECK(dns_db_newversion(db, &ver));
   10123 
   10124 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10125 
   10126 	dns_rriterator_init(&rrit, db, ver, 0);
   10127 	for (result = dns_rriterator_first(&rrit);
   10128 	     result == ISC_R_SUCCESS;
   10129 	     result = dns_rriterator_nextrrset(&rrit))
   10130 	{
   10131 		isc_stdtime_t timer = 0xffffffff;
   10132 		dns_name_t *name = NULL, *kname = NULL;
   10133 		dns_rdataset_t *kdset = NULL;
   10134 		dns_keyfetch_t *kfetch;
   10135 		uint32_t ttl;
   10136 
   10137 		dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
   10138 		if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
   10139 		    !dns_rdataset_isassociated(kdset))
   10140 		{
   10141 			continue;
   10142 		}
   10143 
   10144 		/*
   10145 		 * Scan the stored keys looking for ones that need
   10146 		 * removal or refreshing
   10147 		 */
   10148 		for (result = dns_rdataset_first(kdset);
   10149 		     result == ISC_R_SUCCESS;
   10150 		     result = dns_rdataset_next(kdset))
   10151 		{
   10152 			dns_rdata_reset(&rdata);
   10153 			dns_rdataset_current(kdset, &rdata);
   10154 			result = dns_rdata_tostruct(&rdata, &kd, NULL);
   10155 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10156 
   10157 			/* Removal timer expired? */
   10158 			if (kd.removehd != 0 && kd.removehd < now) {
   10159 				CHECK(update_one_rr(db, ver, &diff,
   10160 						    DNS_DIFFOP_DEL, name, ttl,
   10161 						    &rdata));
   10162 				continue;
   10163 			}
   10164 
   10165 			/* Acceptance timer expired? */
   10166 			if (kd.addhd <= now) {
   10167 				timer = kd.addhd;
   10168 			}
   10169 
   10170 			/* Or do we just need to refresh the keyset? */
   10171 			if (timer > kd.refresh) {
   10172 				timer = kd.refresh;
   10173 			}
   10174 
   10175 			set_refreshkeytimer(zone, &kd, now, false);
   10176 			timerset = true;
   10177 		}
   10178 
   10179 		if (timer > now) {
   10180 			continue;
   10181 		}
   10182 
   10183 		kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
   10184 		if (kfetch == NULL) {
   10185 			fetch_err = true;
   10186 			goto failure;
   10187 		}
   10188 
   10189 		zone->refreshkeycount++;
   10190 		kfetch->zone = zone;
   10191 		zone->irefs++;
   10192 		INSIST(zone->irefs != 0);
   10193 		kname = dns_fixedname_initname(&kfetch->name);
   10194 		dns_name_dup(name, zone->mctx, kname);
   10195 		dns_rdataset_init(&kfetch->dnskeyset);
   10196 		dns_rdataset_init(&kfetch->dnskeysigset);
   10197 		dns_rdataset_init(&kfetch->keydataset);
   10198 		dns_rdataset_clone(kdset, &kfetch->keydataset);
   10199 		kfetch->db = NULL;
   10200 		dns_db_attach(db, &kfetch->db);
   10201 		kfetch->fetch = NULL;
   10202 
   10203 		if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   10204 			char namebuf[DNS_NAME_FORMATSIZE];
   10205 			dns_name_format(kname, namebuf,
   10206 					sizeof(namebuf));
   10207 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   10208 				   "Creating key fetch in "
   10209 				   "zone_refreshkeys() for '%s'",
   10210 				   namebuf);
   10211 		}
   10212 
   10213 		/*
   10214 		 * Use of DNS_FETCHOPT_NOCACHED is essential here.  If it is
   10215 		 * not set and the cache still holds a non-expired, validated
   10216 		 * version of the RRset being queried for by the time the
   10217 		 * response is received, the cached RRset will be passed to
   10218 		 * keyfetch_done() instead of the one received in the response
   10219 		 * as the latter will have a lower trust level due to not being
   10220 		 * validated until keyfetch_done() is called.
   10221 		 */
   10222 
   10223 #ifdef ENABLE_AFL
   10224 		if (dns_fuzzing_resolver == false) {
   10225 #endif
   10226 		result = dns_resolver_createfetch(zone->view->resolver,
   10227 						  kname, dns_rdatatype_dnskey,
   10228 						  NULL, NULL, NULL, NULL, 0,
   10229 						  DNS_FETCHOPT_NOVALIDATE |
   10230 						  DNS_FETCHOPT_UNSHARED |
   10231 						  DNS_FETCHOPT_NOCACHED,
   10232 						  0, NULL, zone->task,
   10233 						  keyfetch_done, kfetch,
   10234 						  &kfetch->dnskeyset,
   10235 						  &kfetch->dnskeysigset,
   10236 						  &kfetch->fetch);
   10237 #ifdef ENABLE_AFL
   10238 		} else {
   10239 			result = ISC_R_FAILURE;
   10240 		}
   10241 #endif
   10242 		if (result == ISC_R_SUCCESS) {
   10243 			fetching = true;
   10244 		} else {
   10245 			zone->refreshkeycount--;
   10246 			zone->irefs--;
   10247 			dns_db_detach(&kfetch->db);
   10248 			dns_rdataset_disassociate(&kfetch->keydataset);
   10249 			dns_name_free(kname, zone->mctx);
   10250 			isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
   10251 			dnssec_log(zone, ISC_LOG_WARNING,
   10252 				   "Failed to create fetch for DNSKEY update");
   10253 			fetch_err = true;
   10254 		}
   10255 	}
   10256 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10257 		CHECK(update_soa_serial(db, ver, &diff, zone->mctx,
   10258 					zone->updatemethod));
   10259 		CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
   10260 		commit = true;
   10261 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   10262 		zone_needdump(zone, 30);
   10263 	}
   10264 
   10265   failure:
   10266 	if (fetch_err) {
   10267 		/*
   10268 		 * Error during a key fetch; retry in an hour.
   10269 		 */
   10270 		isc_time_t timenow, timethen;
   10271 		char timebuf[80];
   10272 
   10273 		TIME_NOW(&timenow);
   10274 		DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
   10275 		zone->refreshkeytime = timethen;
   10276 		zone_settimer(zone, &timenow);
   10277 
   10278 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   10279 		dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
   10280 			   timebuf);
   10281 	} else if (!timerset) {
   10282 		isc_time_settoepoch(&zone->refreshkeytime);
   10283 	}
   10284 
   10285 	if (!fetching) {
   10286 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10287 	}
   10288 
   10289 	dns_diff_clear(&diff);
   10290 	if (ver != NULL) {
   10291 		dns_rriterator_destroy(&rrit);
   10292 		dns_db_closeversion(db, &ver, commit);
   10293 	}
   10294 	dns_db_detach(&db);
   10295 
   10296 	UNLOCK_ZONE(zone);
   10297 
   10298 	INSIST(ver == NULL);
   10299 }
   10300 
   10301 static void
   10302 zone_maintenance(dns_zone_t *zone) {
   10303 	const char me[] = "zone_maintenance";
   10304 	isc_time_t now;
   10305 	isc_result_t result;
   10306 	bool dumping, load_pending;
   10307 
   10308 	REQUIRE(DNS_ZONE_VALID(zone));
   10309 	ENTER;
   10310 
   10311 	/*
   10312 	 * Are we pending load/reload?
   10313 	 */
   10314 	LOCK_ZONE(zone);
   10315 	load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
   10316 	UNLOCK_ZONE(zone);
   10317 
   10318 	if (load_pending) {
   10319 		return;
   10320 	}
   10321 
   10322 	/*
   10323 	 * Configuring the view of this zone may have
   10324 	 * failed, for example because the config file
   10325 	 * had a syntax error.	In that case, the view
   10326 	 * adb or resolver will be NULL, and we had better not try
   10327 	 * to do further maintenance on it.
   10328 	 */
   10329 	if (zone->view == NULL || zone->view->adb == NULL)
   10330 		return;
   10331 
   10332 	TIME_NOW(&now);
   10333 
   10334 	/*
   10335 	 * Expire check.
   10336 	 */
   10337 	switch (zone->type) {
   10338 	case dns_zone_redirect:
   10339 		if (zone->masters == NULL)
   10340 			break;
   10341 		/* FALLTHROUGH */
   10342 	case dns_zone_slave:
   10343 	case dns_zone_mirror:
   10344 	case dns_zone_stub:
   10345 		LOCK_ZONE(zone);
   10346 		if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
   10347 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   10348 			zone_expire(zone);
   10349 			zone->refreshtime = now;
   10350 		}
   10351 		UNLOCK_ZONE(zone);
   10352 		break;
   10353 	default:
   10354 		break;
   10355 	}
   10356 
   10357 	/*
   10358 	 * Up to date check.
   10359 	 */
   10360 	switch (zone->type) {
   10361 	case dns_zone_redirect:
   10362 		if (zone->masters == NULL)
   10363 			break;
   10364 		/* FALLTHROUGH */
   10365 	case dns_zone_slave:
   10366 	case dns_zone_mirror:
   10367 	case dns_zone_stub:
   10368 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
   10369 		    isc_time_compare(&now, &zone->refreshtime) >= 0)
   10370 			dns_zone_refresh(zone);
   10371 		break;
   10372 	default:
   10373 		break;
   10374 	}
   10375 
   10376 	/*
   10377 	 * Slaves send notifies before backing up to disk, masters after.
   10378 	 */
   10379 	if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror) &&
   10380 	    (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   10381 	     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   10382 	    isc_time_compare(&now, &zone->notifytime) >= 0)
   10383 		zone_notify(zone, &now);
   10384 
   10385 	/*
   10386 	 * Do we need to consolidate the backing store?
   10387 	 */
   10388 	switch (zone->type) {
   10389 	case dns_zone_master:
   10390 	case dns_zone_slave:
   10391 	case dns_zone_mirror:
   10392 	case dns_zone_key:
   10393 	case dns_zone_redirect:
   10394 	case dns_zone_stub:
   10395 		LOCK_ZONE(zone);
   10396 		if (zone->masterfile != NULL &&
   10397 		    isc_time_compare(&now, &zone->dumptime) >= 0 &&
   10398 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   10399 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
   10400 			dumping = was_dumping(zone);
   10401 		} else
   10402 			dumping = true;
   10403 		UNLOCK_ZONE(zone);
   10404 		if (!dumping) {
   10405 			result = zone_dump(zone, true); /* task locked */
   10406 			if (result != ISC_R_SUCCESS)
   10407 				dns_zone_log(zone, ISC_LOG_WARNING,
   10408 					     "dump failed: %s",
   10409 					     dns_result_totext(result));
   10410 		}
   10411 		break;
   10412 	default:
   10413 		break;
   10414 	}
   10415 
   10416 	/*
   10417 	 * Master/redirect zones send notifies now, if needed
   10418 	 */
   10419 	switch (zone->type) {
   10420 	case dns_zone_master:
   10421 	case dns_zone_redirect:
   10422 		if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   10423 		     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))&&
   10424 		    isc_time_compare(&now, &zone->notifytime) >= 0)
   10425 			zone_notify(zone, &now);
   10426 	default:
   10427 		break;
   10428 	}
   10429 
   10430 	/*
   10431 	 * Do we need to refresh keys?
   10432 	 */
   10433 	switch (zone->type) {
   10434 	case dns_zone_key:
   10435 		if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
   10436 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   10437 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
   10438 				zone_refreshkeys(zone);
   10439 			}
   10440 		}
   10441 		break;
   10442 	case dns_zone_master:
   10443 		if (!isc_time_isepoch(&zone->refreshkeytime) &&
   10444 		    isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
   10445 		    zone->rss_event == NULL)
   10446 			zone_rekey(zone);
   10447 	default:
   10448 		break;
   10449 	}
   10450 
   10451 	switch (zone->type) {
   10452 	case dns_zone_master:
   10453 	case dns_zone_redirect:
   10454 	case dns_zone_slave:
   10455 		/*
   10456 		 * Do we need to sign/resign some RRsets?
   10457 		 */
   10458 		if (zone->rss_event != NULL)
   10459 			break;
   10460 		if (!isc_time_isepoch(&zone->signingtime) &&
   10461 		    isc_time_compare(&now, &zone->signingtime) >= 0)
   10462 			zone_sign(zone);
   10463 		else if (!isc_time_isepoch(&zone->resigntime) &&
   10464 		    isc_time_compare(&now, &zone->resigntime) >= 0)
   10465 			zone_resigninc(zone);
   10466 		else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
   10467 			isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
   10468 			zone_nsec3chain(zone);
   10469 		/*
   10470 		 * Do we need to issue a key expiry warning?
   10471 		 */
   10472 		if (!isc_time_isepoch(&zone->keywarntime) &&
   10473 		    isc_time_compare(&now, &zone->keywarntime) >= 0)
   10474 			set_key_expiry_warning(zone, zone->key_expiry,
   10475 					       isc_time_seconds(&now));
   10476 		break;
   10477 
   10478 	default:
   10479 		break;
   10480 	}
   10481 	zone_settimer(zone, &now);
   10482 }
   10483 
   10484 void
   10485 dns_zone_markdirty(dns_zone_t *zone) {
   10486 	uint32_t serial;
   10487 	isc_result_t result = ISC_R_SUCCESS;
   10488 	dns_zone_t *secure = NULL;
   10489 
   10490 	/*
   10491 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   10492 	 * could result in a deadlock due to a LOR so we will spin if we
   10493 	 * can't obtain the both locks.
   10494 	 */
   10495  again:
   10496 	LOCK_ZONE(zone);
   10497 	if (zone->type == dns_zone_master) {
   10498 		if (inline_raw(zone)) {
   10499 			unsigned int soacount;
   10500 			secure = zone->secure;
   10501 			INSIST(secure != zone);
   10502 			TRYLOCK_ZONE(result, secure);
   10503 			if (result != ISC_R_SUCCESS) {
   10504 				UNLOCK_ZONE(zone);
   10505 				secure = NULL;
   10506 				isc_thread_yield();
   10507 				goto again;
   10508 			}
   10509 
   10510 			ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   10511 			if (zone->db != NULL) {
   10512 				result = zone_get_from_db(zone, zone->db, NULL,
   10513 							  &soacount, &serial,
   10514 							  NULL, NULL, NULL,
   10515 							  NULL, NULL);
   10516 			} else
   10517 				result = DNS_R_NOTLOADED;
   10518 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   10519 			if (result == ISC_R_SUCCESS && soacount > 0U)
   10520 				zone_send_secureserial(zone, serial);
   10521 		}
   10522 
   10523 		/* XXXMPA make separate call back */
   10524 		if (result == ISC_R_SUCCESS)
   10525 			set_resigntime(zone);
   10526 	}
   10527 	if (secure != NULL)
   10528 		UNLOCK_ZONE(secure);
   10529 	zone_needdump(zone, DNS_DUMP_DELAY);
   10530 	UNLOCK_ZONE(zone);
   10531 }
   10532 
   10533 void
   10534 dns_zone_expire(dns_zone_t *zone) {
   10535 	REQUIRE(DNS_ZONE_VALID(zone));
   10536 
   10537 	LOCK_ZONE(zone);
   10538 	zone_expire(zone);
   10539 	UNLOCK_ZONE(zone);
   10540 }
   10541 
   10542 static void
   10543 zone_expire(dns_zone_t *zone) {
   10544 	/*
   10545 	 * 'zone' locked by caller.
   10546 	 */
   10547 
   10548 	REQUIRE(LOCKED_ZONE(zone));
   10549 
   10550 	dns_zone_log(zone, ISC_LOG_WARNING, "expired");
   10551 
   10552 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
   10553 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   10554 	zone->retry = DNS_ZONE_DEFAULTRETRY;
   10555 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   10556 	zone_unload(zone);
   10557 }
   10558 
   10559 void
   10560 dns_zone_refresh(dns_zone_t *zone) {
   10561 	isc_interval_t i;
   10562 	uint32_t oldflags;
   10563 	unsigned int j;
   10564 	isc_result_t result;
   10565 
   10566 	REQUIRE(DNS_ZONE_VALID(zone));
   10567 
   10568 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
   10569 		return;
   10570 
   10571 	/*
   10572 	 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
   10573 	 * in progress at a time.
   10574 	 */
   10575 
   10576 	LOCK_ZONE(zone);
   10577 	oldflags = zone->flags;
   10578 	if (zone->masterscnt == 0) {
   10579 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   10580 		if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
   10581 			dns_zone_log(zone, ISC_LOG_ERROR,
   10582 				     "cannot refresh: no masters");
   10583 		goto unlock;
   10584 	}
   10585 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   10586 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   10587 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   10588 	if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
   10589 		goto unlock;
   10590 
   10591 	/*
   10592 	 * Set the next refresh time as if refresh check has failed.
   10593 	 * Setting this to the retry time will do that.  XXXMLG
   10594 	 * If we are successful it will be reset using zone->refresh.
   10595 	 */
   10596 	isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4),
   10597 			 0);
   10598 	result = isc_time_nowplusinterval(&zone->refreshtime, &i);
   10599 	if (result != ISC_R_SUCCESS)
   10600 		dns_zone_log(zone, ISC_LOG_WARNING,
   10601 			     "isc_time_nowplusinterval() failed: %s",
   10602 			     dns_result_totext(result));
   10603 
   10604 	/*
   10605 	 * When lacking user-specified timer values from the SOA,
   10606 	 * do exponential backoff of the retry time up to a
   10607 	 * maximum of six hours.
   10608 	 */
   10609 	if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   10610 		zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
   10611 
   10612 	zone->curmaster = 0;
   10613 	for (j = 0; j < zone->masterscnt; j++)
   10614 		zone->mastersok[j] = false;
   10615 	/* initiate soa query */
   10616 	queue_soa_query(zone);
   10617  unlock:
   10618 	UNLOCK_ZONE(zone);
   10619 }
   10620 
   10621 static void
   10622 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) {
   10623 	isc_result_t result;
   10624 	int32_t journalsize;
   10625 	dns_dbversion_t *ver = NULL;
   10626 	uint64_t dbsize;
   10627 
   10628 	INSIST(LOCKED_ZONE(zone));
   10629 	if (inline_raw(zone))
   10630 		INSIST(LOCKED_ZONE(zone->secure));
   10631 
   10632 	journalsize = zone->journalsize;
   10633 	if (journalsize == -1) {
   10634 		journalsize = DNS_JOURNAL_SIZE_MAX;
   10635 		dns_db_currentversion(db, &ver);
   10636 		result = dns_db_getsize(db, ver, NULL, &dbsize);
   10637 		dns_db_closeversion(db, &ver, false);
   10638 		if (result != ISC_R_SUCCESS) {
   10639 			dns_zone_log(zone, ISC_LOG_ERROR,
   10640 				     "zone_journal_compact: "
   10641 				     "could not get zone size: %s",
   10642 				     isc_result_totext(result));
   10643 		} else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) {
   10644 			journalsize = (int32_t)dbsize * 2;
   10645 		}
   10646 	}
   10647 	zone_debuglog(zone, "zone_journal_compact", 1,
   10648 		      "target journal size %d", journalsize);
   10649 	result = dns_journal_compact(zone->mctx, zone->journal,
   10650 				     serial, journalsize);
   10651 	switch (result) {
   10652 	case ISC_R_SUCCESS:
   10653 	case ISC_R_NOSPACE:
   10654 	case ISC_R_NOTFOUND:
   10655 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   10656 			     "dns_journal_compact: %s",
   10657 			     dns_result_totext(result));
   10658 		break;
   10659 	default:
   10660 		dns_zone_log(zone, ISC_LOG_ERROR,
   10661 			     "dns_journal_compact failed: %s",
   10662 			     dns_result_totext(result));
   10663 		break;
   10664 	}
   10665 }
   10666 
   10667 isc_result_t
   10668 dns_zone_flush(dns_zone_t *zone) {
   10669 	isc_result_t result = ISC_R_SUCCESS;
   10670 	bool dumping;
   10671 
   10672 	REQUIRE(DNS_ZONE_VALID(zone));
   10673 
   10674 	LOCK_ZONE(zone);
   10675 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
   10676 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   10677 	    zone->masterfile != NULL) {
   10678 		result = ISC_R_ALREADYRUNNING;
   10679 		dumping = was_dumping(zone);
   10680 	} else
   10681 		dumping = true;
   10682 	UNLOCK_ZONE(zone);
   10683 	if (!dumping)
   10684 		result = zone_dump(zone, true);	/* Unknown task. */
   10685 	return (result);
   10686 }
   10687 
   10688 isc_result_t
   10689 dns_zone_dump(dns_zone_t *zone) {
   10690 	isc_result_t result = ISC_R_ALREADYRUNNING;
   10691 	bool dumping;
   10692 
   10693 	REQUIRE(DNS_ZONE_VALID(zone));
   10694 
   10695 	LOCK_ZONE(zone);
   10696 	dumping = was_dumping(zone);
   10697 	UNLOCK_ZONE(zone);
   10698 	if (!dumping)
   10699 		result = zone_dump(zone, false);	/* Unknown task. */
   10700 	return (result);
   10701 }
   10702 
   10703 static void
   10704 zone_needdump(dns_zone_t *zone, unsigned int delay) {
   10705 	const char me[] = "zone_needdump";
   10706 	isc_time_t dumptime;
   10707 	isc_time_t now;
   10708 
   10709 	/*
   10710 	 * 'zone' locked by caller
   10711 	 */
   10712 
   10713 	REQUIRE(DNS_ZONE_VALID(zone));
   10714 	REQUIRE(LOCKED_ZONE(zone));
   10715 	ENTER;
   10716 
   10717 	/*
   10718 	 * Do we have a place to dump to and are we loaded?
   10719 	 */
   10720 	if (zone->masterfile == NULL ||
   10721 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
   10722 		return;
   10723 
   10724 	TIME_NOW(&now);
   10725 	/* add some noise */
   10726 	DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
   10727 
   10728 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   10729 	if (isc_time_isepoch(&zone->dumptime) ||
   10730 	    isc_time_compare(&zone->dumptime, &dumptime) > 0)
   10731 		zone->dumptime = dumptime;
   10732 	if (zone->task != NULL)
   10733 		zone_settimer(zone, &now);
   10734 }
   10735 
   10736 static void
   10737 dump_done(void *arg, isc_result_t result) {
   10738 	const char me[] = "dump_done";
   10739 	dns_zone_t *zone = arg;
   10740 	dns_zone_t *secure = NULL;
   10741 	dns_db_t *db;
   10742 	dns_dbversion_t *version;
   10743 	bool again = false;
   10744 	bool compact = false;
   10745 	uint32_t serial;
   10746 	isc_result_t tresult;
   10747 
   10748 	REQUIRE(DNS_ZONE_VALID(zone));
   10749 
   10750 	ENTER;
   10751 
   10752 	if (result == ISC_R_SUCCESS && zone->journal != NULL) {
   10753 		/*
   10754 		 * We don't own these, zone->dctx must stay valid.
   10755 		 */
   10756 		db = dns_dumpctx_db(zone->dctx);
   10757 		version = dns_dumpctx_version(zone->dctx);
   10758 		tresult = dns_db_getsoaserial(db, version, &serial);
   10759 
   10760 		/*
   10761 		 * Handle lock order inversion.
   10762 		 */
   10763  again:
   10764 		LOCK_ZONE(zone);
   10765 		if (inline_raw(zone)) {
   10766 			secure = zone->secure;
   10767 			INSIST(secure != zone);
   10768 			TRYLOCK_ZONE(result, secure);
   10769 			if (result != ISC_R_SUCCESS) {
   10770 				UNLOCK_ZONE(zone);
   10771 				secure = NULL;
   10772 				isc_thread_yield();
   10773 				goto again;
   10774 			}
   10775 		}
   10776 
   10777 		/*
   10778 		 * If there is a secure version of this zone
   10779 		 * use its serial if it is less than ours.
   10780 		 */
   10781 		if (tresult == ISC_R_SUCCESS && secure != NULL) {
   10782 			uint32_t sserial;
   10783 			isc_result_t mresult;
   10784 
   10785 			ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
   10786 			if (secure->db != NULL) {
   10787 				mresult = dns_db_getsoaserial(zone->secure->db,
   10788 							      NULL, &sserial);
   10789 				if (mresult == ISC_R_SUCCESS &&
   10790 				    isc_serial_lt(sserial, serial))
   10791 					serial = sserial;
   10792 			}
   10793 			ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
   10794 		}
   10795 		if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
   10796 			dns_db_t *zdb = NULL;
   10797 			if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) {
   10798 				zone_journal_compact(zone, zdb, serial);
   10799 				dns_db_detach(&zdb);
   10800 			}
   10801 		} else if (tresult == ISC_R_SUCCESS) {
   10802 			compact = true;
   10803 			zone->compact_serial = serial;
   10804 		}
   10805 		if (secure != NULL)
   10806 			UNLOCK_ZONE(secure);
   10807 		UNLOCK_ZONE(zone);
   10808 	}
   10809 
   10810 	LOCK_ZONE(zone);
   10811 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   10812 	if (compact)
   10813 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   10814 	if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
   10815 		/*
   10816 		 * Try again in a short while.
   10817 		 */
   10818 		zone_needdump(zone, DNS_DUMP_DELAY);
   10819 	} else if (result == ISC_R_SUCCESS &&
   10820 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   10821 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   10822 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   10823 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   10824 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   10825 		isc_time_settoepoch(&zone->dumptime);
   10826 		again = true;
   10827 	} else if (result == ISC_R_SUCCESS)
   10828 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   10829 
   10830 	if (zone->dctx != NULL)
   10831 		dns_dumpctx_detach(&zone->dctx);
   10832 	zonemgr_putio(&zone->writeio);
   10833 	UNLOCK_ZONE(zone);
   10834 	if (again)
   10835 		(void)zone_dump(zone, false);
   10836 	dns_zone_idetach(&zone);
   10837 }
   10838 
   10839 static isc_result_t
   10840 zone_dump(dns_zone_t *zone, bool compact) {
   10841 	const char me[] = "zone_dump";
   10842 	isc_result_t result;
   10843 	dns_dbversion_t *version = NULL;
   10844 	bool again;
   10845 	dns_db_t *db = NULL;
   10846 	char *masterfile = NULL;
   10847 	dns_masterformat_t masterformat = dns_masterformat_none;
   10848 
   10849 /*
   10850  * 'compact' MUST only be set if we are task locked.
   10851  */
   10852 
   10853 	REQUIRE(DNS_ZONE_VALID(zone));
   10854 	ENTER;
   10855 
   10856  redo:
   10857 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   10858 	if (zone->db != NULL)
   10859 		dns_db_attach(zone->db, &db);
   10860 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   10861 	LOCK_ZONE(zone);
   10862 	if (zone->masterfile != NULL) {
   10863 		masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
   10864 		masterformat = zone->masterformat;
   10865 	}
   10866 	UNLOCK_ZONE(zone);
   10867 	if (db == NULL) {
   10868 		result = DNS_R_NOTLOADED;
   10869 		goto fail;
   10870 	}
   10871 	if (masterfile == NULL) {
   10872 		result = DNS_R_NOMASTERFILE;
   10873 		goto fail;
   10874 	}
   10875 
   10876 	if (compact && zone->type != dns_zone_stub) {
   10877 		dns_zone_t *dummy = NULL;
   10878 		LOCK_ZONE(zone);
   10879 		zone_iattach(zone, &dummy);
   10880 		result = zonemgr_getio(zone->zmgr, false, zone->task,
   10881 				       zone_gotwritehandle, zone,
   10882 				       &zone->writeio);
   10883 		if (result != ISC_R_SUCCESS)
   10884 			zone_idetach(&dummy);
   10885 		else
   10886 			result = DNS_R_CONTINUE;
   10887 		UNLOCK_ZONE(zone);
   10888 	} else {
   10889 		const dns_master_style_t *output_style;
   10890 
   10891 		dns_masterrawheader_t rawdata;
   10892 		dns_db_currentversion(db, &version);
   10893 		dns_master_initrawheader(&rawdata);
   10894 		if (inline_secure(zone))
   10895 			get_raw_serial(zone->raw, &rawdata);
   10896 		if (zone->type == dns_zone_key)
   10897 			output_style = &dns_master_style_keyzone;
   10898 		else
   10899 			output_style = &dns_master_style_default;
   10900 		result = dns_master_dump(zone->mctx, db, version,
   10901 					 output_style, masterfile,
   10902 					 masterformat, &rawdata);
   10903 		dns_db_closeversion(db, &version, false);
   10904 	}
   10905  fail:
   10906 	if (db != NULL)
   10907 		dns_db_detach(&db);
   10908 	if (masterfile != NULL)
   10909 		isc_mem_free(zone->mctx, masterfile);
   10910 	masterfile = NULL;
   10911 
   10912 	if (result == DNS_R_CONTINUE)
   10913 		return (ISC_R_SUCCESS); /* XXXMPA */
   10914 
   10915 	again = false;
   10916 	LOCK_ZONE(zone);
   10917 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   10918 	if (result != ISC_R_SUCCESS) {
   10919 		/*
   10920 		 * Try again in a short while.
   10921 		 */
   10922 		zone_needdump(zone, DNS_DUMP_DELAY);
   10923 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   10924 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   10925 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   10926 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   10927 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   10928 		isc_time_settoepoch(&zone->dumptime);
   10929 		again = true;
   10930 	} else
   10931 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   10932 	UNLOCK_ZONE(zone);
   10933 	if (again)
   10934 		goto redo;
   10935 
   10936 	return (result);
   10937 }
   10938 
   10939 static isc_result_t
   10940 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
   10941 	     dns_masterformat_t format, const uint32_t rawversion)
   10942 {
   10943 	isc_result_t result;
   10944 	dns_dbversion_t *version = NULL;
   10945 	dns_db_t *db = NULL;
   10946 	dns_masterrawheader_t rawdata;
   10947 
   10948 	REQUIRE(DNS_ZONE_VALID(zone));
   10949 
   10950 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   10951 	if (zone->db != NULL)
   10952 		dns_db_attach(zone->db, &db);
   10953 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   10954 	if (db == NULL)
   10955 		return (DNS_R_NOTLOADED);
   10956 
   10957 	dns_db_currentversion(db, &version);
   10958 	dns_master_initrawheader(&rawdata);
   10959 	if (rawversion == 0)
   10960 		rawdata.flags |= DNS_MASTERRAW_COMPAT;
   10961 	else if (inline_secure(zone))
   10962 		get_raw_serial(zone->raw, &rawdata);
   10963 	else if (zone->sourceserialset) {
   10964 		rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
   10965 		rawdata.sourceserial = zone->sourceserial;
   10966 	}
   10967 	result = dns_master_dumptostream(zone->mctx, db, version, style,
   10968 					 format, &rawdata, fd);
   10969 	dns_db_closeversion(db, &version, false);
   10970 	dns_db_detach(&db);
   10971 	return (result);
   10972 }
   10973 
   10974 isc_result_t
   10975 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
   10976 		      const dns_master_style_t *style,
   10977 		      const uint32_t rawversion)
   10978 {
   10979 	return (dumptostream(zone, fd, style, format, rawversion));
   10980 }
   10981 
   10982 void
   10983 dns_zone_unload(dns_zone_t *zone) {
   10984 	REQUIRE(DNS_ZONE_VALID(zone));
   10985 
   10986 	LOCK_ZONE(zone);
   10987 	zone_unload(zone);
   10988 	UNLOCK_ZONE(zone);
   10989 }
   10990 
   10991 static void
   10992 notify_cancel(dns_zone_t *zone) {
   10993 	dns_notify_t *notify;
   10994 
   10995 	/*
   10996 	 * 'zone' locked by caller.
   10997 	 */
   10998 
   10999 	REQUIRE(LOCKED_ZONE(zone));
   11000 
   11001 	for (notify = ISC_LIST_HEAD(zone->notifies);
   11002 	     notify != NULL;
   11003 	     notify = ISC_LIST_NEXT(notify, link)) {
   11004 		if (notify->find != NULL)
   11005 			dns_adb_cancelfind(notify->find);
   11006 		if (notify->request != NULL)
   11007 			dns_request_cancel(notify->request);
   11008 	}
   11009 }
   11010 
   11011 static void
   11012 forward_cancel(dns_zone_t *zone) {
   11013 	dns_forward_t *forward;
   11014 
   11015 	/*
   11016 	 * 'zone' locked by caller.
   11017 	 */
   11018 
   11019 	REQUIRE(LOCKED_ZONE(zone));
   11020 
   11021 	for (forward = ISC_LIST_HEAD(zone->forwards);
   11022 	     forward != NULL;
   11023 	     forward = ISC_LIST_NEXT(forward, link)) {
   11024 		if (forward->request != NULL)
   11025 			dns_request_cancel(forward->request);
   11026 	}
   11027 }
   11028 
   11029 static void
   11030 zone_unload(dns_zone_t *zone) {
   11031 	/*
   11032 	 * 'zone' locked by caller.
   11033 	 */
   11034 
   11035 	REQUIRE(LOCKED_ZONE(zone));
   11036 
   11037 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   11038 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   11039 		if (zone->writeio != NULL)
   11040 			zonemgr_cancelio(zone->writeio);
   11041 
   11042 		if (zone->dctx != NULL)
   11043 			dns_dumpctx_cancel(zone->dctx);
   11044 	}
   11045 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   11046 	zone_detachdb(zone);
   11047 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   11048 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
   11049 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11050 
   11051 	if (zone->type == dns_zone_mirror) {
   11052 		dns_zone_log(zone, ISC_LOG_INFO,
   11053 			     "mirror zone is no longer in use; "
   11054 			     "reverting to normal recursion");
   11055 	}
   11056 }
   11057 
   11058 void
   11059 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
   11060 	REQUIRE(DNS_ZONE_VALID(zone));
   11061 	REQUIRE(val > 0);
   11062 
   11063 	zone->minrefresh = val;
   11064 }
   11065 
   11066 void
   11067 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
   11068 	REQUIRE(DNS_ZONE_VALID(zone));
   11069 	REQUIRE(val > 0);
   11070 
   11071 	zone->maxrefresh = val;
   11072 }
   11073 
   11074 void
   11075 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
   11076 	REQUIRE(DNS_ZONE_VALID(zone));
   11077 	REQUIRE(val > 0);
   11078 
   11079 	zone->minretry = val;
   11080 }
   11081 
   11082 void
   11083 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
   11084 	REQUIRE(DNS_ZONE_VALID(zone));
   11085 	REQUIRE(val > 0);
   11086 
   11087 	zone->maxretry = val;
   11088 }
   11089 
   11090 uint32_t
   11091 dns_zone_getmaxrecords(dns_zone_t *zone) {
   11092 	REQUIRE(DNS_ZONE_VALID(zone));
   11093 
   11094 	return (zone->maxrecords);
   11095 }
   11096 
   11097 void
   11098 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
   11099 	REQUIRE(DNS_ZONE_VALID(zone));
   11100 
   11101 	zone->maxrecords = val;
   11102 }
   11103 
   11104 static bool
   11105 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
   11106 		isc_sockaddr_t *addr, dns_tsigkey_t *key)
   11107 {
   11108 	dns_notify_t *notify;
   11109 	dns_zonemgr_t *zmgr;
   11110 	isc_result_t result;
   11111 
   11112 	for (notify = ISC_LIST_HEAD(zone->notifies);
   11113 	     notify != NULL;
   11114 	     notify = ISC_LIST_NEXT(notify, link)) {
   11115 		if (notify->request != NULL)
   11116 			continue;
   11117 		if (name != NULL && dns_name_dynamic(&notify->ns) &&
   11118 		    dns_name_equal(name, &notify->ns))
   11119 			goto requeue;
   11120 		if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
   11121 		    notify->key == key)
   11122 			goto requeue;
   11123 	}
   11124 	return (false);
   11125 
   11126 requeue:
   11127 	/*
   11128 	 * If we are enqueued on the startup ratelimiter and this is
   11129 	 * not a startup notify, re-enqueue on the normal notify
   11130 	 * ratelimiter.
   11131 	 */
   11132 	if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
   11133 	    (notify->flags & DNS_NOTIFY_STARTUP) != 0) {
   11134 		zmgr = notify->zone->zmgr;
   11135 		result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
   11136 						 notify->event);
   11137 		if (result != ISC_R_SUCCESS)
   11138 			return (true);
   11139 
   11140 		notify->flags &= ~DNS_NOTIFY_STARTUP;
   11141 		result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
   11142 						 notify->zone->task,
   11143 						 &notify->event);
   11144 		if (result != ISC_R_SUCCESS) {
   11145 			isc_event_free(&notify->event);
   11146 			return (false);
   11147 		}
   11148 	}
   11149 
   11150 	return (true);
   11151 }
   11152 
   11153 static bool
   11154 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
   11155 	dns_tsigkey_t *key = NULL;
   11156 	isc_sockaddr_t src;
   11157 	isc_sockaddr_t any;
   11158 	bool isself;
   11159 	isc_netaddr_t dstaddr;
   11160 	isc_result_t result;
   11161 
   11162 	if (zone->view == NULL || zone->isself == NULL)
   11163 		return (false);
   11164 
   11165 	switch (isc_sockaddr_pf(dst)) {
   11166 	case PF_INET:
   11167 		src = zone->notifysrc4;
   11168 		isc_sockaddr_any(&any);
   11169 		break;
   11170 	case PF_INET6:
   11171 		src = zone->notifysrc6;
   11172 		isc_sockaddr_any6(&any);
   11173 		break;
   11174 	default:
   11175 		return (false);
   11176 	}
   11177 
   11178 	/*
   11179 	 * When sending from any the kernel will assign a source address
   11180 	 * that matches the destination address.
   11181 	 */
   11182 	if (isc_sockaddr_eqaddr(&any, &src))
   11183 		src = *dst;
   11184 
   11185 	isc_netaddr_fromsockaddr(&dstaddr, dst);
   11186 	result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
   11187 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
   11188 		return (false);
   11189 	isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
   11190 				zone->isselfarg);
   11191 	if (key != NULL)
   11192 		dns_tsigkey_detach(&key);
   11193 	return (isself);
   11194 }
   11195 
   11196 static void
   11197 notify_destroy(dns_notify_t *notify, bool locked) {
   11198 	isc_mem_t *mctx;
   11199 
   11200 	REQUIRE(DNS_NOTIFY_VALID(notify));
   11201 
   11202 	if (notify->zone != NULL) {
   11203 		if (!locked)
   11204 			LOCK_ZONE(notify->zone);
   11205 		REQUIRE(LOCKED_ZONE(notify->zone));
   11206 		if (ISC_LINK_LINKED(notify, link))
   11207 			ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
   11208 		if (!locked)
   11209 			UNLOCK_ZONE(notify->zone);
   11210 		if (locked)
   11211 			zone_idetach(&notify->zone);
   11212 		else
   11213 			dns_zone_idetach(&notify->zone);
   11214 	}
   11215 	if (notify->find != NULL)
   11216 		dns_adb_destroyfind(&notify->find);
   11217 	if (notify->request != NULL)
   11218 		dns_request_destroy(&notify->request);
   11219 	if (dns_name_dynamic(&notify->ns))
   11220 		dns_name_free(&notify->ns, notify->mctx);
   11221 	if (notify->key != NULL)
   11222 		dns_tsigkey_detach(&notify->key);
   11223 	mctx = notify->mctx;
   11224 	isc_mem_put(notify->mctx, notify, sizeof(*notify));
   11225 	isc_mem_detach(&mctx);
   11226 }
   11227 
   11228 static isc_result_t
   11229 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
   11230 	dns_notify_t *notify;
   11231 
   11232 	REQUIRE(notifyp != NULL && *notifyp == NULL);
   11233 
   11234 	notify = isc_mem_get(mctx, sizeof(*notify));
   11235 	if (notify == NULL)
   11236 		return (ISC_R_NOMEMORY);
   11237 
   11238 	notify->mctx = NULL;
   11239 	isc_mem_attach(mctx, &notify->mctx);
   11240 	notify->flags = flags;
   11241 	notify->zone = NULL;
   11242 	notify->find = NULL;
   11243 	notify->request = NULL;
   11244 	notify->key = NULL;
   11245 	notify->event = NULL;
   11246 	isc_sockaddr_any(&notify->dst);
   11247 	dns_name_init(&notify->ns, NULL);
   11248 	ISC_LINK_INIT(notify, link);
   11249 	notify->magic = NOTIFY_MAGIC;
   11250 	*notifyp = notify;
   11251 	return (ISC_R_SUCCESS);
   11252 }
   11253 
   11254 /*
   11255  * XXXAG should check for DNS_ZONEFLG_EXITING
   11256  */
   11257 static void
   11258 process_adb_event(isc_task_t *task, isc_event_t *ev) {
   11259 	dns_notify_t *notify;
   11260 	isc_eventtype_t result;
   11261 
   11262 	UNUSED(task);
   11263 
   11264 	notify = ev->ev_arg;
   11265 	REQUIRE(DNS_NOTIFY_VALID(notify));
   11266 	INSIST(task == notify->zone->task);
   11267 	result = ev->ev_type;
   11268 	isc_event_free(&ev);
   11269 	if (result == DNS_EVENT_ADBMOREADDRESSES) {
   11270 		dns_adb_destroyfind(&notify->find);
   11271 		notify_find_address(notify);
   11272 		return;
   11273 	}
   11274 	if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
   11275 		LOCK_ZONE(notify->zone);
   11276 		notify_send(notify);
   11277 		UNLOCK_ZONE(notify->zone);
   11278 	}
   11279 	notify_destroy(notify, false);
   11280 }
   11281 
   11282 static void
   11283 notify_find_address(dns_notify_t *notify) {
   11284 	isc_result_t result;
   11285 	unsigned int options;
   11286 
   11287 	REQUIRE(DNS_NOTIFY_VALID(notify));
   11288 	options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
   11289 		  DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
   11290 
   11291 	if (notify->zone->view->adb == NULL)
   11292 		goto destroy;
   11293 
   11294 	result = dns_adb_createfind(notify->zone->view->adb,
   11295 				    notify->zone->task,
   11296 				    process_adb_event, notify,
   11297 				    &notify->ns, dns_rootname, 0,
   11298 				    options, 0, NULL,
   11299 				    notify->zone->view->dstport,
   11300 				    0, NULL, &notify->find);
   11301 
   11302 	/* Something failed? */
   11303 	if (result != ISC_R_SUCCESS)
   11304 		goto destroy;
   11305 
   11306 	/* More addresses pending? */
   11307 	if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
   11308 		return;
   11309 
   11310 	/* We have as many addresses as we can get. */
   11311 	LOCK_ZONE(notify->zone);
   11312 	notify_send(notify);
   11313 	UNLOCK_ZONE(notify->zone);
   11314 
   11315  destroy:
   11316 	notify_destroy(notify, false);
   11317 }
   11318 
   11319 
   11320 static isc_result_t
   11321 notify_send_queue(dns_notify_t *notify, bool startup) {
   11322 	isc_event_t *e;
   11323 	isc_result_t result;
   11324 
   11325 	INSIST(notify->event == NULL);
   11326 	e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
   11327 			       notify_send_toaddr, notify, sizeof(isc_event_t));
   11328 	if (e == NULL)
   11329 		return (ISC_R_NOMEMORY);
   11330 	if (startup)
   11331 		notify->event = e;
   11332 	e->ev_arg = notify;
   11333 	e->ev_sender = NULL;
   11334 	result = isc_ratelimiter_enqueue(startup
   11335 					  ? notify->zone->zmgr->startupnotifyrl
   11336 					  : notify->zone->zmgr->notifyrl,
   11337 					 notify->zone->task, &e);
   11338 	if (result != ISC_R_SUCCESS) {
   11339 		isc_event_free(&e);
   11340 		notify->event = NULL;
   11341 	}
   11342 	return (result);
   11343 }
   11344 
   11345 static void
   11346 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
   11347 	dns_notify_t *notify;
   11348 	isc_result_t result;
   11349 	dns_message_t *message = NULL;
   11350 	isc_netaddr_t dstip;
   11351 	dns_tsigkey_t *key = NULL;
   11352 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   11353 	isc_sockaddr_t src;
   11354 	unsigned int options, timeout;
   11355 	bool have_notifysource = false;
   11356 	bool have_notifydscp = false;
   11357 	isc_dscp_t dscp = -1;
   11358 
   11359 	notify = event->ev_arg;
   11360 	REQUIRE(DNS_NOTIFY_VALID(notify));
   11361 
   11362 	UNUSED(task);
   11363 
   11364 	LOCK_ZONE(notify->zone);
   11365 
   11366 	notify->event = NULL;
   11367 
   11368 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
   11369 		result = ISC_R_CANCELED;
   11370 		goto cleanup;
   11371 	}
   11372 
   11373 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
   11374 	    DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
   11375 	    notify->zone->view->requestmgr == NULL ||
   11376 	    notify->zone->db == NULL) {
   11377 		result = ISC_R_CANCELED;
   11378 		goto cleanup;
   11379 	}
   11380 
   11381 	/*
   11382 	 * The raw IPv4 address should also exist.  Don't send to the
   11383 	 * mapped form.
   11384 	 */
   11385 	if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
   11386 	    IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr)) {
   11387 		isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   11388 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   11389 			   "notify: ignoring IPv6 mapped IPV4 address: %s",
   11390 			   addrbuf);
   11391 		result = ISC_R_CANCELED;
   11392 		goto cleanup;
   11393 	}
   11394 
   11395 	result = notify_createmessage(notify->zone, notify->flags, &message);
   11396 	if (result != ISC_R_SUCCESS)
   11397 		goto cleanup;
   11398 
   11399 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   11400 	if (notify->key != NULL) {
   11401 		/* Transfer ownership of key */
   11402 		key = notify->key;
   11403 		notify->key = NULL;
   11404 	} else {
   11405 		isc_netaddr_fromsockaddr(&dstip, &notify->dst);
   11406 		result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
   11407 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   11408 			notify_log(notify->zone, ISC_LOG_ERROR,
   11409 				   "NOTIFY to %s not sent. "
   11410 				   "Peer TSIG key lookup failure.", addrbuf);
   11411 			goto cleanup_message;
   11412 		}
   11413 	}
   11414 
   11415 	/* XXX: should we log the tsig key too? */
   11416 	notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
   11417 		   addrbuf);
   11418 	options = 0;
   11419 	if (notify->zone->view->peers != NULL) {
   11420 		dns_peer_t *peer = NULL;
   11421 		bool usetcp = false;
   11422 		result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
   11423 						 &dstip, &peer);
   11424 		if (result == ISC_R_SUCCESS) {
   11425 			result = dns_peer_getnotifysource(peer, &src);
   11426 			if (result == ISC_R_SUCCESS)
   11427 				have_notifysource = true;
   11428 			dns_peer_getnotifydscp(peer, &dscp);
   11429 			if (dscp != -1)
   11430 				have_notifydscp = true;
   11431 			result = dns_peer_getforcetcp(peer, &usetcp);
   11432 			if (result == ISC_R_SUCCESS && usetcp)
   11433 				options |= DNS_FETCHOPT_TCP;
   11434 		}
   11435 	}
   11436 	switch (isc_sockaddr_pf(&notify->dst)) {
   11437 	case PF_INET:
   11438 		if (!have_notifysource)
   11439 			src = notify->zone->notifysrc4;
   11440 		if (!have_notifydscp)
   11441 			dscp = notify->zone->notifysrc4dscp;
   11442 		break;
   11443 	case PF_INET6:
   11444 		if (!have_notifysource)
   11445 			src = notify->zone->notifysrc6;
   11446 		if (!have_notifydscp)
   11447 			dscp = notify->zone->notifysrc6dscp;
   11448 		break;
   11449 	default:
   11450 		result = ISC_R_NOTIMPLEMENTED;
   11451 		goto cleanup_key;
   11452 	}
   11453 	timeout = 15;
   11454 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
   11455 		timeout = 30;
   11456 	result = dns_request_createvia(notify->zone->view->requestmgr,
   11457 				       message, &src, &notify->dst, dscp,
   11458 				       options, key, timeout * 3, timeout,
   11459 				       0, notify->zone->task, notify_done,
   11460 				       notify, &notify->request);
   11461 	if (result == ISC_R_SUCCESS) {
   11462 		if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
   11463 			inc_stats(notify->zone,
   11464 				  dns_zonestatscounter_notifyoutv4);
   11465 		} else {
   11466 			inc_stats(notify->zone,
   11467 				  dns_zonestatscounter_notifyoutv6);
   11468 		}
   11469 	}
   11470 
   11471  cleanup_key:
   11472 	if (key != NULL)
   11473 		dns_tsigkey_detach(&key);
   11474  cleanup_message:
   11475 	dns_message_destroy(&message);
   11476  cleanup:
   11477 	UNLOCK_ZONE(notify->zone);
   11478 	isc_event_free(&event);
   11479 	if (result != ISC_R_SUCCESS)
   11480 		notify_destroy(notify, false);
   11481 }
   11482 
   11483 static void
   11484 notify_send(dns_notify_t *notify) {
   11485 	dns_adbaddrinfo_t *ai;
   11486 	isc_sockaddr_t dst;
   11487 	isc_result_t result;
   11488 	dns_notify_t *newnotify = NULL;
   11489 	unsigned int flags;
   11490 	bool startup;
   11491 
   11492 	/*
   11493 	 * Zone lock held by caller.
   11494 	 */
   11495 	REQUIRE(DNS_NOTIFY_VALID(notify));
   11496 	REQUIRE(LOCKED_ZONE(notify->zone));
   11497 
   11498 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING))
   11499 		return;
   11500 
   11501 	for (ai = ISC_LIST_HEAD(notify->find->list);
   11502 	     ai != NULL;
   11503 	     ai = ISC_LIST_NEXT(ai, publink)) {
   11504 		dst = ai->sockaddr;
   11505 		if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
   11506 				    NULL))
   11507 			continue;
   11508 		if (notify_isself(notify->zone, &dst))
   11509 			continue;
   11510 		newnotify = NULL;
   11511 		flags = notify->flags & DNS_NOTIFY_NOSOA;
   11512 		result = notify_create(notify->mctx, flags, &newnotify);
   11513 		if (result != ISC_R_SUCCESS)
   11514 			goto cleanup;
   11515 		zone_iattach(notify->zone, &newnotify->zone);
   11516 		ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link);
   11517 		newnotify->dst = dst;
   11518 		startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0);
   11519 		result = notify_send_queue(newnotify, startup);
   11520 		if (result != ISC_R_SUCCESS)
   11521 			goto cleanup;
   11522 		newnotify = NULL;
   11523 	}
   11524 
   11525  cleanup:
   11526 	if (newnotify != NULL)
   11527 		notify_destroy(newnotify, true);
   11528 }
   11529 
   11530 void
   11531 dns_zone_notify(dns_zone_t *zone) {
   11532 	isc_time_t now;
   11533 
   11534 	REQUIRE(DNS_ZONE_VALID(zone));
   11535 
   11536 	LOCK_ZONE(zone);
   11537 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   11538 
   11539 	TIME_NOW(&now);
   11540 	zone_settimer(zone, &now);
   11541 	UNLOCK_ZONE(zone);
   11542 }
   11543 
   11544 static void
   11545 zone_notify(dns_zone_t *zone, isc_time_t *now) {
   11546 	dns_dbnode_t *node = NULL;
   11547 	dns_db_t *zonedb = NULL;
   11548 	dns_dbversion_t *version = NULL;
   11549 	dns_name_t *origin = NULL;
   11550 	dns_name_t master;
   11551 	dns_rdata_ns_t ns;
   11552 	dns_rdata_soa_t soa;
   11553 	uint32_t serial;
   11554 	dns_rdata_t rdata = DNS_RDATA_INIT;
   11555 	dns_rdataset_t nsrdset;
   11556 	dns_rdataset_t soardset;
   11557 	isc_result_t result;
   11558 	unsigned int i;
   11559 	isc_sockaddr_t dst;
   11560 	bool isqueued;
   11561 	dns_notifytype_t notifytype;
   11562 	unsigned int flags = 0;
   11563 	bool loggednotify = false;
   11564 	bool startup;
   11565 
   11566 	REQUIRE(DNS_ZONE_VALID(zone));
   11567 
   11568 	LOCK_ZONE(zone);
   11569 	startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   11570 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   11571 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   11572 	notifytype = zone->notifytype;
   11573 	DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
   11574 	UNLOCK_ZONE(zone);
   11575 
   11576 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   11577 	    ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11578 		return;
   11579 
   11580 	if (notifytype == dns_notifytype_no)
   11581 		return;
   11582 
   11583 	if (notifytype == dns_notifytype_masteronly &&
   11584 	    zone->type != dns_zone_master)
   11585 		return;
   11586 
   11587 	origin = &zone->origin;
   11588 
   11589 	/*
   11590 	 * If the zone is dialup we are done as we don't want to send
   11591 	 * the current soa so as to force a refresh query.
   11592 	 */
   11593 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
   11594 		flags |= DNS_NOTIFY_NOSOA;
   11595 
   11596 	/*
   11597 	 * Record that this was a notify due to starting up.
   11598 	 */
   11599 	if (startup)
   11600 		flags |= DNS_NOTIFY_STARTUP;
   11601 
   11602 	/*
   11603 	 * Get SOA RRset.
   11604 	 */
   11605 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11606 	if (zone->db != NULL)
   11607 		dns_db_attach(zone->db, &zonedb);
   11608 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11609 	if (zonedb == NULL)
   11610 		return;
   11611 	dns_db_currentversion(zonedb, &version);
   11612 	result = dns_db_findnode(zonedb, origin, false, &node);
   11613 	if (result != ISC_R_SUCCESS)
   11614 		goto cleanup1;
   11615 
   11616 	dns_rdataset_init(&soardset);
   11617 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   11618 				     dns_rdatatype_none, 0, &soardset, NULL);
   11619 	if (result != ISC_R_SUCCESS)
   11620 		goto cleanup2;
   11621 
   11622 	/*
   11623 	 * Find serial and master server's name.
   11624 	 */
   11625 	dns_name_init(&master, NULL);
   11626 	result = dns_rdataset_first(&soardset);
   11627 	if (result != ISC_R_SUCCESS)
   11628 		goto cleanup3;
   11629 	dns_rdataset_current(&soardset, &rdata);
   11630 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   11631 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   11632 	dns_rdata_reset(&rdata);
   11633 	result = dns_name_dup(&soa.origin, zone->mctx, &master);
   11634 	serial = soa.serial;
   11635 	dns_rdataset_disassociate(&soardset);
   11636 	if (result != ISC_R_SUCCESS)
   11637 		goto cleanup3;
   11638 
   11639 	/*
   11640 	 * Enqueue notify requests for 'also-notify' servers.
   11641 	 */
   11642 	LOCK_ZONE(zone);
   11643 	for (i = 0; i < zone->notifycnt; i++) {
   11644 		dns_tsigkey_t *key = NULL;
   11645 		dns_notify_t *notify = NULL;
   11646 
   11647 		if ((zone->notifykeynames != NULL) &&
   11648 		    (zone->notifykeynames[i] != NULL)) {
   11649 			dns_view_t *view = dns_zone_getview(zone);
   11650 			dns_name_t *keyname = zone->notifykeynames[i];
   11651 			(void)dns_view_gettsig(view, keyname, &key);
   11652 		}
   11653 
   11654 		dst = zone->notify[i];
   11655 		if (notify_isqueued(zone, flags, NULL, &dst, key)) {
   11656 			if (key != NULL)
   11657 				dns_tsigkey_detach(&key);
   11658 			continue;
   11659 		}
   11660 
   11661 		result = notify_create(zone->mctx, flags, &notify);
   11662 		if (result != ISC_R_SUCCESS) {
   11663 			if (key != NULL)
   11664 				dns_tsigkey_detach(&key);
   11665 			continue;
   11666 		}
   11667 
   11668 		zone_iattach(zone, &notify->zone);
   11669 		notify->dst = dst;
   11670 
   11671 		INSIST(notify->key == NULL);
   11672 
   11673 		if (key != NULL) {
   11674 			notify->key = key;
   11675 			key = NULL;
   11676 		}
   11677 
   11678 		ISC_LIST_APPEND(zone->notifies, notify, link);
   11679 		result = notify_send_queue(notify, startup);
   11680 		if (result != ISC_R_SUCCESS)
   11681 			notify_destroy(notify, true);
   11682 		if (!loggednotify) {
   11683 			notify_log(zone, ISC_LOG_INFO,
   11684 				   "sending notifies (serial %u)",
   11685 				   serial);
   11686 			loggednotify = true;
   11687 		}
   11688 	}
   11689 	UNLOCK_ZONE(zone);
   11690 
   11691 	if (notifytype == dns_notifytype_explicit)
   11692 		goto cleanup3;
   11693 
   11694 	/*
   11695 	 * Process NS RRset to generate notifies.
   11696 	 */
   11697 
   11698 	dns_rdataset_init(&nsrdset);
   11699 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
   11700 				     dns_rdatatype_none, 0, &nsrdset, NULL);
   11701 	if (result != ISC_R_SUCCESS)
   11702 		goto cleanup3;
   11703 
   11704 	result = dns_rdataset_first(&nsrdset);
   11705 	while (result == ISC_R_SUCCESS) {
   11706 		dns_notify_t *notify = NULL;
   11707 
   11708 		dns_rdataset_current(&nsrdset, &rdata);
   11709 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   11710 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   11711 		dns_rdata_reset(&rdata);
   11712 		/*
   11713 		 * Don't notify the master server unless explicitly
   11714 		 * configured to do so.
   11715 		 */
   11716 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
   11717 		    dns_name_compare(&master, &ns.name) == 0) {
   11718 			result = dns_rdataset_next(&nsrdset);
   11719 			continue;
   11720 		}
   11721 
   11722 		if (!loggednotify) {
   11723 			notify_log(zone, ISC_LOG_INFO,
   11724 				   "sending notifies (serial %u)",
   11725 				   serial);
   11726 			loggednotify = true;
   11727 		}
   11728 
   11729 		LOCK_ZONE(zone);
   11730 		isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
   11731 		UNLOCK_ZONE(zone);
   11732 		if (isqueued) {
   11733 			result = dns_rdataset_next(&nsrdset);
   11734 			continue;
   11735 		}
   11736 		result = notify_create(zone->mctx, flags, &notify);
   11737 		if (result != ISC_R_SUCCESS)
   11738 			continue;
   11739 		dns_zone_iattach(zone, &notify->zone);
   11740 		result = dns_name_dup(&ns.name, zone->mctx, &notify->ns);
   11741 		if (result != ISC_R_SUCCESS) {
   11742 			LOCK_ZONE(zone);
   11743 			notify_destroy(notify, true);
   11744 			UNLOCK_ZONE(zone);
   11745 			continue;
   11746 		}
   11747 		LOCK_ZONE(zone);
   11748 		ISC_LIST_APPEND(zone->notifies, notify, link);
   11749 		UNLOCK_ZONE(zone);
   11750 		notify_find_address(notify);
   11751 		result = dns_rdataset_next(&nsrdset);
   11752 	}
   11753 	dns_rdataset_disassociate(&nsrdset);
   11754 
   11755  cleanup3:
   11756 	if (dns_name_dynamic(&master))
   11757 		dns_name_free(&master, zone->mctx);
   11758  cleanup2:
   11759 	dns_db_detachnode(zonedb, &node);
   11760  cleanup1:
   11761 	dns_db_closeversion(zonedb, &version, false);
   11762 	dns_db_detach(&zonedb);
   11763 }
   11764 
   11765 /***
   11766  *** Private
   11767  ***/
   11768 
   11769 static inline isc_result_t
   11770 save_nsrrset(dns_message_t *message, dns_name_t *name,
   11771 	     dns_db_t *db, dns_dbversion_t *version)
   11772 {
   11773 	dns_rdataset_t *nsrdataset = NULL;
   11774 	dns_rdataset_t *rdataset = NULL;
   11775 	dns_dbnode_t *node = NULL;
   11776 	dns_rdata_ns_t ns;
   11777 	isc_result_t result;
   11778 	dns_rdata_t rdata = DNS_RDATA_INIT;
   11779 
   11780 	/*
   11781 	 * Extract NS RRset from message.
   11782 	 */
   11783 	result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
   11784 				      dns_rdatatype_ns, dns_rdatatype_none,
   11785 				      NULL, &nsrdataset);
   11786 	if (result != ISC_R_SUCCESS)
   11787 		goto fail;
   11788 
   11789 	/*
   11790 	 * Add NS rdataset.
   11791 	 */
   11792 	result = dns_db_findnode(db, name, true, &node);
   11793 	if (result != ISC_R_SUCCESS)
   11794 		goto fail;
   11795 	result = dns_db_addrdataset(db, node, version, 0,
   11796 				    nsrdataset, 0, NULL);
   11797 	dns_db_detachnode(db, &node);
   11798 	if (result != ISC_R_SUCCESS)
   11799 		goto fail;
   11800 	/*
   11801 	 * Add glue rdatasets.
   11802 	 */
   11803 	for (result = dns_rdataset_first(nsrdataset);
   11804 	     result == ISC_R_SUCCESS;
   11805 	     result = dns_rdataset_next(nsrdataset)) {
   11806 		dns_rdataset_current(nsrdataset, &rdata);
   11807 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   11808 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   11809 		dns_rdata_reset(&rdata);
   11810 		if (!dns_name_issubdomain(&ns.name, name))
   11811 			continue;
   11812 		rdataset = NULL;
   11813 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
   11814 					      &ns.name, dns_rdatatype_aaaa,
   11815 					      dns_rdatatype_none, NULL,
   11816 					      &rdataset);
   11817 		if (result == ISC_R_SUCCESS) {
   11818 			result = dns_db_findnode(db, &ns.name,
   11819 						 true, &node);
   11820 			if (result != ISC_R_SUCCESS)
   11821 				goto fail;
   11822 			result = dns_db_addrdataset(db, node, version, 0,
   11823 						    rdataset, 0, NULL);
   11824 			dns_db_detachnode(db, &node);
   11825 			if (result != ISC_R_SUCCESS)
   11826 				goto fail;
   11827 		}
   11828 		rdataset = NULL;
   11829 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
   11830 					      &ns.name, dns_rdatatype_a,
   11831 					      dns_rdatatype_none, NULL,
   11832 					      &rdataset);
   11833 		if (result == ISC_R_SUCCESS) {
   11834 			result = dns_db_findnode(db, &ns.name,
   11835 						 true, &node);
   11836 			if (result != ISC_R_SUCCESS)
   11837 				goto fail;
   11838 			result = dns_db_addrdataset(db, node, version, 0,
   11839 						    rdataset, 0, NULL);
   11840 			dns_db_detachnode(db, &node);
   11841 			if (result != ISC_R_SUCCESS)
   11842 				goto fail;
   11843 		}
   11844 	}
   11845 	if (result != ISC_R_NOMORE)
   11846 		goto fail;
   11847 
   11848 	return (ISC_R_SUCCESS);
   11849 
   11850 fail:
   11851 	return (result);
   11852 }
   11853 
   11854 static void
   11855 stub_callback(isc_task_t *task, isc_event_t *event) {
   11856 	const char me[] = "stub_callback";
   11857 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   11858 	dns_stub_t *stub = NULL;
   11859 	dns_message_t *msg = NULL;
   11860 	dns_zone_t *zone = NULL;
   11861 	char master[ISC_SOCKADDR_FORMATSIZE];
   11862 	char source[ISC_SOCKADDR_FORMATSIZE];
   11863 	uint32_t nscnt, cnamecnt, refresh, retry, expire;
   11864 	isc_result_t result;
   11865 	isc_time_t now;
   11866 	bool exiting = false;
   11867 	isc_interval_t i;
   11868 	unsigned int j, soacount;
   11869 
   11870 	stub = revent->ev_arg;
   11871 	INSIST(DNS_STUB_VALID(stub));
   11872 
   11873 	UNUSED(task);
   11874 
   11875 	zone = stub->zone;
   11876 
   11877 	ENTER;
   11878 
   11879 	TIME_NOW(&now);
   11880 
   11881 	LOCK_ZONE(zone);
   11882 
   11883 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11884 		zone_debuglog(zone, me, 1, "exiting");
   11885 		exiting = true;
   11886 		goto next_master;
   11887 	}
   11888 
   11889 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   11890 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   11891 
   11892 	if (revent->result != ISC_R_SUCCESS) {
   11893 		if (revent->result == ISC_R_TIMEDOUT &&
   11894 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   11895 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   11896 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   11897 				     "refreshing stub: timeout retrying "
   11898 				     " without EDNS master %s (source %s)",
   11899 				     master, source);
   11900 			goto same_master;
   11901 		}
   11902 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
   11903 					   &zone->sourceaddr, &now);
   11904 		dns_zone_log(zone, ISC_LOG_INFO,
   11905 			     "could not refresh stub from master %s"
   11906 			     " (source %s): %s", master, source,
   11907 			     dns_result_totext(revent->result));
   11908 		goto next_master;
   11909 	}
   11910 
   11911 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   11912 	if (result != ISC_R_SUCCESS)
   11913 		goto next_master;
   11914 
   11915 	result = dns_request_getresponse(revent->request, msg, 0);
   11916 	if (result != ISC_R_SUCCESS)
   11917 		goto next_master;
   11918 
   11919 	/*
   11920 	 * Unexpected rcode.
   11921 	 */
   11922 	if (msg->rcode != dns_rcode_noerror) {
   11923 		char rcode[128];
   11924 		isc_buffer_t rb;
   11925 
   11926 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   11927 		(void)dns_rcode_totext(msg->rcode, &rb);
   11928 
   11929 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   11930 		    (msg->rcode == dns_rcode_servfail ||
   11931 		     msg->rcode == dns_rcode_notimp ||
   11932 		     msg->rcode == dns_rcode_formerr)) {
   11933 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   11934 				     "refreshing stub: rcode (%.*s) retrying "
   11935 				     "without EDNS master %s (source %s)",
   11936 				     (int)rb.used, rcode, master, source);
   11937 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   11938 			goto same_master;
   11939 		}
   11940 
   11941 		dns_zone_log(zone, ISC_LOG_INFO,
   11942 			     "refreshing stub: "
   11943 			     "unexpected rcode (%.*s) from %s (source %s)",
   11944 			     (int)rb.used, rcode, master, source);
   11945 		goto next_master;
   11946 	}
   11947 
   11948 	/*
   11949 	 * We need complete messages.
   11950 	 */
   11951 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   11952 		if (dns_request_usedtcp(revent->request)) {
   11953 			dns_zone_log(zone, ISC_LOG_INFO,
   11954 				     "refreshing stub: truncated TCP "
   11955 				     "response from master %s (source %s)",
   11956 				     master, source);
   11957 			goto next_master;
   11958 		}
   11959 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   11960 		goto same_master;
   11961 	}
   11962 
   11963 	/*
   11964 	 * If non-auth log and next master.
   11965 	 */
   11966 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   11967 		dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
   11968 			     "non-authoritative answer from "
   11969 			     "master %s (source %s)", master, source);
   11970 		goto next_master;
   11971 	}
   11972 
   11973 	/*
   11974 	 * Sanity checks.
   11975 	 */
   11976 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   11977 	nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
   11978 
   11979 	if (cnamecnt != 0) {
   11980 		dns_zone_log(zone, ISC_LOG_INFO,
   11981 			     "refreshing stub: unexpected CNAME response "
   11982 			     "from master %s (source %s)", master, source);
   11983 		goto next_master;
   11984 	}
   11985 
   11986 	if (nscnt == 0) {
   11987 		dns_zone_log(zone, ISC_LOG_INFO,
   11988 			     "refreshing stub: no NS records in response "
   11989 			     "from master %s (source %s)", master, source);
   11990 		goto next_master;
   11991 	}
   11992 
   11993 	/*
   11994 	 * Save answer.
   11995 	 */
   11996 	result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
   11997 	if (result != ISC_R_SUCCESS) {
   11998 		dns_zone_log(zone, ISC_LOG_INFO,
   11999 			     "refreshing stub: unable to save NS records "
   12000 			     "from master %s (source %s)", master, source);
   12001 		goto next_master;
   12002 	}
   12003 
   12004 	/*
   12005 	 * Tidy up.
   12006 	 */
   12007 	dns_db_closeversion(stub->db, &stub->version, true);
   12008 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   12009 	if (zone->db == NULL)
   12010 		zone_attachdb(zone, stub->db);
   12011 	result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
   12012 				  &refresh, &retry, &expire, NULL, NULL);
   12013 	if (result == ISC_R_SUCCESS && soacount > 0U) {
   12014 		zone->refresh = RANGE(refresh, zone->minrefresh,
   12015 				      zone->maxrefresh);
   12016 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   12017 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   12018 				     DNS_MAX_EXPIRE);
   12019 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   12020 	}
   12021 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   12022 	dns_db_detach(&stub->db);
   12023 
   12024 	dns_message_destroy(&msg);
   12025 	isc_event_free(&event);
   12026 	dns_request_destroy(&zone->request);
   12027 
   12028 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   12029 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   12030 	DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   12031 	isc_interval_set(&i, zone->expire, 0);
   12032 	DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
   12033 
   12034 	if (zone->masterfile != NULL)
   12035 		zone_needdump(zone, 0);
   12036 
   12037 	zone_settimer(zone, &now);
   12038 	goto free_stub;
   12039 
   12040  next_master:
   12041 	if (stub->version != NULL)
   12042 		dns_db_closeversion(stub->db, &stub->version, false);
   12043 	if (stub->db != NULL)
   12044 		dns_db_detach(&stub->db);
   12045 	if (msg != NULL)
   12046 		dns_message_destroy(&msg);
   12047 	isc_event_free(&event);
   12048 	dns_request_destroy(&zone->request);
   12049 	/*
   12050 	 * Skip to next failed / untried master.
   12051 	 */
   12052 	do {
   12053 		zone->curmaster++;
   12054 	} while (zone->curmaster < zone->masterscnt &&
   12055 		 zone->mastersok[zone->curmaster]);
   12056 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   12057 	if (exiting || zone->curmaster >= zone->masterscnt) {
   12058 		bool done = true;
   12059 		if (!exiting &&
   12060 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   12061 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   12062 			/*
   12063 			 * Did we get a good answer from all the masters?
   12064 			 */
   12065 			for (j = 0; j < zone->masterscnt; j++)
   12066 				if (zone->mastersok[j] == false) {
   12067 					done = false;
   12068 					break;
   12069 				}
   12070 		} else
   12071 			done = true;
   12072 		if (!done) {
   12073 			zone->curmaster = 0;
   12074 			/*
   12075 			 * Find the next failed master.
   12076 			 */
   12077 			while (zone->curmaster < zone->masterscnt &&
   12078 			       zone->mastersok[zone->curmaster])
   12079 				zone->curmaster++;
   12080 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   12081 		} else {
   12082 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   12083 
   12084 			zone_settimer(zone, &now);
   12085 			goto free_stub;
   12086 		}
   12087 	}
   12088 	queue_soa_query(zone);
   12089 	goto free_stub;
   12090 
   12091  same_master:
   12092 	if (msg != NULL)
   12093 		dns_message_destroy(&msg);
   12094 	isc_event_free(&event);
   12095 	dns_request_destroy(&zone->request);
   12096 	ns_query(zone, NULL, stub);
   12097 	UNLOCK_ZONE(zone);
   12098 	goto done;
   12099 
   12100  free_stub:
   12101 	UNLOCK_ZONE(zone);
   12102 	stub->magic = 0;
   12103 	dns_zone_idetach(&stub->zone);
   12104 	INSIST(stub->db == NULL);
   12105 	INSIST(stub->version == NULL);
   12106 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   12107 
   12108  done:
   12109 	INSIST(event == NULL);
   12110 	return;
   12111 }
   12112 
   12113 /*
   12114  * Get the EDNS EXPIRE option from the response and if it exists trim
   12115  * expire to be not more than it.
   12116  */
   12117 static void
   12118 get_edns_expire(dns_zone_t * zone, dns_message_t *message,
   12119 		uint32_t *expirep)
   12120 {
   12121 	isc_result_t result;
   12122 	uint32_t expire;
   12123 	dns_rdata_t rdata = DNS_RDATA_INIT;
   12124 	isc_buffer_t optbuf;
   12125 	uint16_t optcode;
   12126 	uint16_t optlen;
   12127 
   12128 	REQUIRE(expirep != NULL);
   12129 	REQUIRE(message != NULL);
   12130 
   12131 	if (message->opt == NULL)
   12132 		return;
   12133 
   12134 	result = dns_rdataset_first(message->opt);
   12135 	if (result == ISC_R_SUCCESS) {
   12136 		dns_rdataset_current(message->opt, &rdata);
   12137 		isc_buffer_init(&optbuf, rdata.data, rdata.length);
   12138 		isc_buffer_add(&optbuf, rdata.length);
   12139 		while (isc_buffer_remaininglength(&optbuf) >= 4) {
   12140 			optcode = isc_buffer_getuint16(&optbuf);
   12141 			optlen = isc_buffer_getuint16(&optbuf);
   12142 			/*
   12143 			 * A EDNS EXPIRE response has a length of 4.
   12144 			 */
   12145 			if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
   12146 				isc_buffer_forward(&optbuf, optlen);
   12147 				continue;
   12148 			}
   12149 			expire = isc_buffer_getuint32(&optbuf);
   12150 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   12151 				     "got EDNS EXPIRE of %u", expire);
   12152 			/*
   12153 			 * Trim *expirep?
   12154 			 */
   12155 			if (expire < *expirep)
   12156 				*expirep = expire;
   12157 			break;
   12158 		}
   12159 	}
   12160 }
   12161 
   12162 /*
   12163  * Set the file modification time zone->expire seconds before expiretime.
   12164  */
   12165 static void
   12166 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
   12167 	isc_result_t result;
   12168 	isc_time_t when;
   12169 	isc_interval_t i;
   12170 
   12171 	isc_interval_set(&i, zone->expire, 0);
   12172 	result = isc_time_subtract(expiretime, &i, &when);
   12173 	if (result != ISC_R_SUCCESS)
   12174 		return;
   12175 
   12176 	result = ISC_R_FAILURE;
   12177 	if (zone->journal != NULL)
   12178 		result = isc_file_settime(zone->journal, &when);
   12179 	if (result == ISC_R_SUCCESS &&
   12180 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   12181 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
   12182 		result = isc_file_settime(zone->masterfile, &when);
   12183 	else if (result != ISC_R_SUCCESS)
   12184 		result = isc_file_settime(zone->masterfile, &when);
   12185 
   12186 	/*
   12187 	 * Someone removed the file from underneath us!
   12188 	 */
   12189 	if (result == ISC_R_FILENOTFOUND) {
   12190 		zone_needdump(zone, DNS_DUMP_DELAY);
   12191 	} else if (result != ISC_R_SUCCESS)
   12192 		dns_zone_log(zone, ISC_LOG_ERROR, "refresh: could not set "
   12193 			     "file modification time of '%s': %s",
   12194 			     zone->masterfile, dns_result_totext(result));
   12195 }
   12196 
   12197 /*
   12198  * An SOA query has finished (successfully or not).
   12199  */
   12200 static void
   12201 refresh_callback(isc_task_t *task, isc_event_t *event) {
   12202 	const char me[] = "refresh_callback";
   12203 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   12204 	dns_zone_t *zone;
   12205 	dns_message_t *msg = NULL;
   12206 	uint32_t soacnt, cnamecnt, soacount, nscount;
   12207 	isc_time_t now;
   12208 	char master[ISC_SOCKADDR_FORMATSIZE];
   12209 	char source[ISC_SOCKADDR_FORMATSIZE];
   12210 	dns_rdataset_t *rdataset = NULL;
   12211 	dns_rdata_t rdata = DNS_RDATA_INIT;
   12212 	dns_rdata_soa_t soa;
   12213 	isc_result_t result;
   12214 	uint32_t serial, oldserial = 0;
   12215 	unsigned int j;
   12216 	bool do_queue_xfrin = false;
   12217 
   12218 	zone = revent->ev_arg;
   12219 	INSIST(DNS_ZONE_VALID(zone));
   12220 
   12221 	UNUSED(task);
   12222 
   12223 	ENTER;
   12224 
   12225 	TIME_NOW(&now);
   12226 
   12227 	LOCK_ZONE(zone);
   12228 
   12229 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   12230 		isc_event_free(&event);
   12231 		dns_request_destroy(&zone->request);
   12232 		goto detach;
   12233 	}
   12234 
   12235 	/*
   12236 	 * if timeout log and next master;
   12237 	 */
   12238 
   12239 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   12240 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   12241 
   12242 	if (revent->result != ISC_R_SUCCESS) {
   12243 		if (revent->result == ISC_R_TIMEDOUT &&
   12244 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   12245 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   12246 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   12247 				     "refresh: timeout retrying without EDNS "
   12248 				     "master %s (source %s)", master, source);
   12249 			goto same_master;
   12250 		}
   12251 		if (revent->result == ISC_R_TIMEDOUT &&
   12252 		    !dns_request_usedtcp(revent->request)) {
   12253 			dns_zone_log(zone, ISC_LOG_INFO,
   12254 				     "refresh: retry limit for "
   12255 				     "master %s exceeded (source %s)",
   12256 				     master, source);
   12257 			/* Try with slave with TCP. */
   12258 			if ((zone->type == dns_zone_slave ||
   12259 			     zone->type == dns_zone_mirror ||
   12260 			     zone->type == dns_zone_redirect) &&
   12261 			    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
   12262 			{
   12263 				if (!dns_zonemgr_unreachable(zone->zmgr,
   12264 							     &zone->masteraddr,
   12265 							     &zone->sourceaddr,
   12266 							     &now))
   12267 				{
   12268 					DNS_ZONE_SETFLAG(zone,
   12269 						     DNS_ZONEFLG_SOABEFOREAXFR);
   12270 					goto tcp_transfer;
   12271 				}
   12272 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
   12273 					     "refresh: skipped tcp fallback "
   12274 					     "as master %s (source %s) is "
   12275 					     "unreachable (cached)",
   12276 					      master, source);
   12277 			}
   12278 		} else
   12279 			dns_zone_log(zone, ISC_LOG_INFO,
   12280 				     "refresh: failure trying master "
   12281 				     "%s (source %s): %s", master, source,
   12282 				     dns_result_totext(revent->result));
   12283 		goto next_master;
   12284 	}
   12285 
   12286 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   12287 	if (result != ISC_R_SUCCESS)
   12288 		goto next_master;
   12289 	result = dns_request_getresponse(revent->request, msg, 0);
   12290 	if (result != ISC_R_SUCCESS) {
   12291 		dns_zone_log(zone, ISC_LOG_INFO,
   12292 			     "refresh: failure trying master "
   12293 			     "%s (source %s): %s", master, source,
   12294 			     dns_result_totext(result));
   12295 		goto next_master;
   12296 	}
   12297 
   12298 	/*
   12299 	 * Unexpected rcode.
   12300 	 */
   12301 	if (msg->rcode != dns_rcode_noerror) {
   12302 		char rcode[128];
   12303 		isc_buffer_t rb;
   12304 
   12305 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   12306 		(void)dns_rcode_totext(msg->rcode, &rb);
   12307 
   12308 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   12309 		    (msg->rcode == dns_rcode_servfail ||
   12310 		     msg->rcode == dns_rcode_notimp ||
   12311 		     msg->rcode == dns_rcode_formerr)) {
   12312 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   12313 				     "refresh: rcode (%.*s) retrying without "
   12314 				     "EDNS master %s (source %s)",
   12315 				     (int)rb.used, rcode, master, source);
   12316 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   12317 			goto same_master;
   12318 		}
   12319 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   12320 		    msg->rcode == dns_rcode_badvers) {
   12321 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   12322 				     "refresh: rcode (%.*s) retrying without "
   12323 				     "EDNS EXPIRE OPTION master %s (source %s)",
   12324 				     (int)rb.used, rcode, master, source);
   12325 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   12326 			goto same_master;
   12327 		}
   12328 		dns_zone_log(zone, ISC_LOG_INFO,
   12329 			     "refresh: unexpected rcode (%.*s) from "
   12330 			     "master %s (source %s)", (int)rb.used, rcode,
   12331 			     master, source);
   12332 		/*
   12333 		 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
   12334 		 */
   12335 		if (msg->rcode == dns_rcode_refused &&
   12336 		    (zone->type == dns_zone_slave ||
   12337 		     zone->type == dns_zone_mirror ||
   12338 		     zone->type == dns_zone_redirect))
   12339 		{
   12340 			goto tcp_transfer;
   12341 		}
   12342 		goto next_master;
   12343 	}
   12344 
   12345 	/*
   12346 	 * If truncated punt to zone transfer which will query again.
   12347 	 */
   12348 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   12349 		if (zone->type == dns_zone_slave ||
   12350 		    zone->type == dns_zone_mirror ||
   12351 		    zone->type == dns_zone_redirect)
   12352 		{
   12353 			dns_zone_log(zone, ISC_LOG_INFO,
   12354 				     "refresh: truncated UDP answer, "
   12355 				     "initiating TCP zone xfer "
   12356 				     "for master %s (source %s)",
   12357 				     master, source);
   12358 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   12359 			goto tcp_transfer;
   12360 		} else {
   12361 			INSIST(zone->type == dns_zone_stub);
   12362 			if (dns_request_usedtcp(revent->request)) {
   12363 				dns_zone_log(zone, ISC_LOG_INFO,
   12364 					     "refresh: truncated TCP response "
   12365 					     "from master %s (source %s)",
   12366 					     master, source);
   12367 				goto next_master;
   12368 			}
   12369 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   12370 			goto same_master;
   12371 		}
   12372 	}
   12373 
   12374 	/*
   12375 	 * if non-auth log and next master;
   12376 	 */
   12377 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   12378 		dns_zone_log(zone, ISC_LOG_INFO,
   12379 			     "refresh: non-authoritative answer from "
   12380 			     "master %s (source %s)", master, source);
   12381 		goto next_master;
   12382 	}
   12383 
   12384 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   12385 	soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
   12386 	nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
   12387 	soacount = message_count(msg, DNS_SECTION_AUTHORITY,
   12388 				 dns_rdatatype_soa);
   12389 
   12390 	/*
   12391 	 * There should not be a CNAME record at top of zone.
   12392 	 */
   12393 	if (cnamecnt != 0) {
   12394 		dns_zone_log(zone, ISC_LOG_INFO,
   12395 			     "refresh: CNAME at top of zone "
   12396 			     "in master %s (source %s)", master, source);
   12397 		goto next_master;
   12398 	}
   12399 
   12400 	/*
   12401 	 * if referral log and next master;
   12402 	 */
   12403 	if (soacnt == 0 && soacount == 0 && nscount != 0) {
   12404 		dns_zone_log(zone, ISC_LOG_INFO,
   12405 			     "refresh: referral response "
   12406 			     "from master %s (source %s)", master, source);
   12407 		goto next_master;
   12408 	}
   12409 
   12410 	/*
   12411 	 * if nodata log and next master;
   12412 	 */
   12413 	if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
   12414 		dns_zone_log(zone, ISC_LOG_INFO,
   12415 			     "refresh: NODATA response "
   12416 			     "from master %s (source %s)", master, source);
   12417 		goto next_master;
   12418 	}
   12419 
   12420 	/*
   12421 	 * Only one soa at top of zone.
   12422 	 */
   12423 	if (soacnt != 1) {
   12424 		dns_zone_log(zone, ISC_LOG_INFO,
   12425 			     "refresh: answer SOA count (%d) != 1 "
   12426 			     "from master %s (source %s)",
   12427 			     soacnt, master, source);
   12428 		goto next_master;
   12429 	}
   12430 
   12431 	/*
   12432 	 * Extract serial
   12433 	 */
   12434 	rdataset = NULL;
   12435 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
   12436 				      dns_rdatatype_soa, dns_rdatatype_none,
   12437 				      NULL, &rdataset);
   12438 	if (result != ISC_R_SUCCESS) {
   12439 		dns_zone_log(zone, ISC_LOG_INFO,
   12440 			     "refresh: unable to get SOA record "
   12441 			     "from master %s (source %s)", master, source);
   12442 		goto next_master;
   12443 	}
   12444 
   12445 	result = dns_rdataset_first(rdataset);
   12446 	if (result != ISC_R_SUCCESS) {
   12447 		dns_zone_log(zone, ISC_LOG_INFO,
   12448 			     "refresh: dns_rdataset_first() failed");
   12449 		goto next_master;
   12450 	}
   12451 
   12452 	dns_rdataset_current(rdataset, &rdata);
   12453 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   12454 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12455 
   12456 	serial = soa.serial;
   12457 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   12458 		unsigned int dbsoacount;
   12459 		result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
   12460 					  &oldserial, NULL, NULL, NULL, NULL,
   12461 					  NULL);
   12462 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12463 		RUNTIME_CHECK(dbsoacount > 0U);
   12464 		zone_debuglog(zone, me, 1, "serial: new %u, old %u",
   12465 			      serial, oldserial);
   12466 	} else
   12467 		zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
   12468 			      serial);
   12469 
   12470 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
   12471 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
   12472 	    isc_serial_gt(serial, oldserial)) {
   12473 		if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   12474 					    &zone->sourceaddr, &now))
   12475 		{
   12476 			dns_zone_log(zone, ISC_LOG_INFO,
   12477 				     "refresh: skipping %s as master %s "
   12478 				     "(source %s) is unreachable (cached)",
   12479 				     (zone->type == dns_zone_slave ||
   12480 				      zone->type == dns_zone_mirror ||
   12481 				      zone->type == dns_zone_redirect) ?
   12482 				     "zone transfer" : "NS query",
   12483 				     master, source);
   12484 			goto next_master;
   12485 		}
   12486  tcp_transfer:
   12487 		isc_event_free(&event);
   12488 		dns_request_destroy(&zone->request);
   12489 		if (zone->type == dns_zone_slave ||
   12490 		    zone->type == dns_zone_mirror ||
   12491 		    zone->type == dns_zone_redirect)
   12492 		{
   12493 			do_queue_xfrin = true;
   12494 		} else {
   12495 			INSIST(zone->type == dns_zone_stub);
   12496 			ns_query(zone, rdataset, NULL);
   12497 		}
   12498 		if (msg != NULL)
   12499 			dns_message_destroy(&msg);
   12500 	} else if (isc_serial_eq(soa.serial, oldserial)) {
   12501 		isc_time_t expiretime;
   12502 		uint32_t expire;
   12503 
   12504 		/*
   12505 		 * Compute the new expire time based on this response.
   12506 		 */
   12507 		expire = zone->expire;
   12508 		get_edns_expire(zone, msg, &expire);
   12509 		DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
   12510 
   12511 		/*
   12512 		 * Has the expire time improved?
   12513 		 */
   12514 		if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
   12515 			zone->expiretime = expiretime;
   12516 			if (zone->masterfile != NULL)
   12517 				setmodtime(zone, &expiretime);
   12518 		}
   12519 
   12520 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   12521 		zone->mastersok[zone->curmaster] = true;
   12522 		goto next_master;
   12523 	} else {
   12524 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
   12525 			dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
   12526 				     "received from master %s < ours (%u)",
   12527 				     soa.serial, master, oldserial);
   12528 		else
   12529 			zone_debuglog(zone, me, 1, "ahead");
   12530 		zone->mastersok[zone->curmaster] = true;
   12531 		goto next_master;
   12532 	}
   12533 	if (msg != NULL)
   12534 		dns_message_destroy(&msg);
   12535 	goto detach;
   12536 
   12537  next_master:
   12538 	if (msg != NULL)
   12539 		dns_message_destroy(&msg);
   12540 	isc_event_free(&event);
   12541 	dns_request_destroy(&zone->request);
   12542 	/*
   12543 	 * Skip to next failed / untried master.
   12544 	 */
   12545 	do {
   12546 		zone->curmaster++;
   12547 	} while (zone->curmaster < zone->masterscnt &&
   12548 		 zone->mastersok[zone->curmaster]);
   12549 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   12550 	if (zone->curmaster >= zone->masterscnt) {
   12551 		bool done = true;
   12552 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   12553 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   12554 			/*
   12555 			 * Did we get a good answer from all the masters?
   12556 			 */
   12557 			for (j = 0; j < zone->masterscnt; j++)
   12558 				if (zone->mastersok[j] == false) {
   12559 					done = false;
   12560 					break;
   12561 				}
   12562 		} else
   12563 			done = true;
   12564 		if (!done) {
   12565 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   12566 			zone->curmaster = 0;
   12567 			/*
   12568 			 * Find the next failed master.
   12569 			 */
   12570 			while (zone->curmaster < zone->masterscnt &&
   12571 			       zone->mastersok[zone->curmaster])
   12572 				zone->curmaster++;
   12573 			goto requeue;
   12574 		}
   12575 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   12576 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   12577 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   12578 			zone->refreshtime = now;
   12579 		}
   12580 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   12581 		zone_settimer(zone, &now);
   12582 		goto detach;
   12583 	}
   12584 
   12585  requeue:
   12586 	queue_soa_query(zone);
   12587 	goto detach;
   12588 
   12589  same_master:
   12590 	if (msg != NULL)
   12591 		dns_message_destroy(&msg);
   12592 	isc_event_free(&event);
   12593 	dns_request_destroy(&zone->request);
   12594 	queue_soa_query(zone);
   12595 
   12596  detach:
   12597 	UNLOCK_ZONE(zone);
   12598 	if (do_queue_xfrin)
   12599 		queue_xfrin(zone);
   12600 	dns_zone_idetach(&zone);
   12601 	return;
   12602 }
   12603 
   12604 static void
   12605 queue_soa_query(dns_zone_t *zone) {
   12606 	const char me[] = "queue_soa_query";
   12607 	isc_event_t *e;
   12608 	dns_zone_t *dummy = NULL;
   12609 	isc_result_t result;
   12610 
   12611 	ENTER;
   12612 	/*
   12613 	 * Locked by caller
   12614 	 */
   12615 	REQUIRE(LOCKED_ZONE(zone));
   12616 
   12617 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   12618 		cancel_refresh(zone);
   12619 		return;
   12620 	}
   12621 
   12622 	e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
   12623 			       soa_query, zone, sizeof(isc_event_t));
   12624 	if (e == NULL) {
   12625 		cancel_refresh(zone);
   12626 		return;
   12627 	}
   12628 
   12629 	/*
   12630 	 * Attach so that we won't clean up
   12631 	 * until the event is delivered.
   12632 	 */
   12633 	zone_iattach(zone, &dummy);
   12634 
   12635 	e->ev_arg = zone;
   12636 	e->ev_sender = NULL;
   12637 	result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
   12638 	if (result != ISC_R_SUCCESS) {
   12639 		zone_idetach(&dummy);
   12640 		isc_event_free(&e);
   12641 		cancel_refresh(zone);
   12642 	}
   12643 }
   12644 
   12645 static inline isc_result_t
   12646 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
   12647 	     dns_message_t **messagep)
   12648 {
   12649 	dns_message_t *message = NULL;
   12650 	dns_name_t *qname = NULL;
   12651 	dns_rdataset_t *qrdataset = NULL;
   12652 	isc_result_t result;
   12653 
   12654 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
   12655 				    &message);
   12656 	if (result != ISC_R_SUCCESS)
   12657 		goto cleanup;
   12658 
   12659 	message->opcode = dns_opcode_query;
   12660 	message->rdclass = zone->rdclass;
   12661 
   12662 	result = dns_message_gettempname(message, &qname);
   12663 	if (result != ISC_R_SUCCESS)
   12664 		goto cleanup;
   12665 
   12666 	result = dns_message_gettemprdataset(message, &qrdataset);
   12667 	if (result != ISC_R_SUCCESS)
   12668 		goto cleanup;
   12669 
   12670 	/*
   12671 	 * Make question.
   12672 	 */
   12673 	dns_name_init(qname, NULL);
   12674 	dns_name_clone(&zone->origin, qname);
   12675 	dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
   12676 	ISC_LIST_APPEND(qname->list, qrdataset, link);
   12677 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
   12678 
   12679 	*messagep = message;
   12680 	return (ISC_R_SUCCESS);
   12681 
   12682  cleanup:
   12683 	if (qname != NULL)
   12684 		dns_message_puttempname(message, &qname);
   12685 	if (qrdataset != NULL)
   12686 		dns_message_puttemprdataset(message, &qrdataset);
   12687 	if (message != NULL)
   12688 		dns_message_destroy(&message);
   12689 	return (result);
   12690 }
   12691 
   12692 static isc_result_t
   12693 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
   12694 	bool reqexpire)
   12695 {
   12696 	isc_result_t result;
   12697 	dns_rdataset_t *rdataset = NULL;
   12698 	dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
   12699 	int count = 0;
   12700 
   12701 	/* Set EDNS options if applicable */
   12702 	if (reqnsid) {
   12703 		INSIST(count < DNS_EDNSOPTIONS);
   12704 		ednsopts[count].code = DNS_OPT_NSID;
   12705 		ednsopts[count].length = 0;
   12706 		ednsopts[count].value = NULL;
   12707 		count++;
   12708 	}
   12709 	if (reqexpire) {
   12710 		INSIST(count < DNS_EDNSOPTIONS);
   12711 		ednsopts[count].code = DNS_OPT_EXPIRE;
   12712 		ednsopts[count].length = 0;
   12713 		ednsopts[count].value = NULL;
   12714 		count++;
   12715 	}
   12716 	result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
   12717 				      ednsopts, count);
   12718 	if (result != ISC_R_SUCCESS)
   12719 		return (result);
   12720 
   12721 	return (dns_message_setopt(message, rdataset));
   12722 }
   12723 
   12724 static void
   12725 soa_query(isc_task_t *task, isc_event_t *event) {
   12726 	const char me[] = "soa_query";
   12727 	isc_result_t result = ISC_R_FAILURE;
   12728 	dns_message_t *message = NULL;
   12729 	dns_zone_t *zone = event->ev_arg;
   12730 	dns_zone_t *dummy = NULL;
   12731 	isc_netaddr_t masterip;
   12732 	dns_tsigkey_t *key = NULL;
   12733 	uint32_t options;
   12734 	bool cancel = true;
   12735 	int timeout;
   12736 	bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
   12737 	uint16_t udpsize = SEND_BUFFER_SIZE;
   12738 	isc_dscp_t dscp = -1;
   12739 
   12740 	REQUIRE(DNS_ZONE_VALID(zone));
   12741 
   12742 	UNUSED(task);
   12743 
   12744 	ENTER;
   12745 
   12746 	LOCK_ZONE(zone);
   12747 	if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
   12748 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   12749 	    zone->view->requestmgr == NULL) {
   12750 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
   12751 			cancel = false;
   12752 		goto cleanup;
   12753 	}
   12754 
   12755  again:
   12756 	result = create_query(zone, dns_rdatatype_soa, &message);
   12757 	if (result != ISC_R_SUCCESS)
   12758 		goto cleanup;
   12759 
   12760 	INSIST(zone->masterscnt > 0);
   12761 	INSIST(zone->curmaster < zone->masterscnt);
   12762 
   12763 	zone->masteraddr = zone->masters[zone->curmaster];
   12764 
   12765 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   12766 	/*
   12767 	 * First, look for a tsig key in the master statement, then
   12768 	 * try for a server key.
   12769 	 */
   12770 	if ((zone->masterkeynames != NULL) &&
   12771 	    (zone->masterkeynames[zone->curmaster] != NULL)) {
   12772 		dns_view_t *view = dns_zone_getview(zone);
   12773 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   12774 		result = dns_view_gettsig(view, keyname, &key);
   12775 		if (result != ISC_R_SUCCESS) {
   12776 			char namebuf[DNS_NAME_FORMATSIZE];
   12777 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   12778 			dns_zone_log(zone, ISC_LOG_ERROR,
   12779 				     "unable to find key: %s", namebuf);
   12780 			goto skip_master;
   12781 		}
   12782 	}
   12783 	if (key == NULL) {
   12784 		result = dns_view_getpeertsig(zone->view, &masterip, &key);
   12785 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12786 			char addrbuf[ISC_NETADDR_FORMATSIZE];
   12787 			isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
   12788 			dns_zone_log(zone, ISC_LOG_ERROR,
   12789 				     "unable to find TSIG key for %s", addrbuf);
   12790 			goto skip_master;
   12791 		}
   12792 	}
   12793 
   12794 	options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
   12795 		  DNS_REQUESTOPT_TCP : 0;
   12796 	have_xfrsource = have_xfrdscp = false;
   12797 	reqnsid = zone->view->requestnsid;
   12798 	reqexpire = zone->requestexpire;
   12799 	if (zone->view->peers != NULL) {
   12800 		dns_peer_t *peer = NULL;
   12801 		bool edns, usetcp;
   12802 		result = dns_peerlist_peerbyaddr(zone->view->peers,
   12803 						 &masterip, &peer);
   12804 		if (result == ISC_R_SUCCESS) {
   12805 			result = dns_peer_getsupportedns(peer, &edns);
   12806 			if (result == ISC_R_SUCCESS && !edns)
   12807 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   12808 			result = dns_peer_gettransfersource(peer,
   12809 							    &zone->sourceaddr);
   12810 			if (result == ISC_R_SUCCESS)
   12811 				have_xfrsource = true;
   12812 			(void)dns_peer_gettransferdscp(peer, &dscp);
   12813 			if (dscp != -1)
   12814 				have_xfrdscp = true;
   12815 			if (zone->view->resolver != NULL)
   12816 				udpsize =
   12817 				  dns_resolver_getudpsize(zone->view->resolver);
   12818 			(void)dns_peer_getudpsize(peer, &udpsize);
   12819 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   12820 			(void)dns_peer_getrequestexpire(peer, &reqexpire);
   12821 			result = dns_peer_getforcetcp(peer, &usetcp);
   12822 			if (result == ISC_R_SUCCESS && usetcp)
   12823 				options |= DNS_REQUESTOPT_TCP;
   12824 		}
   12825 	}
   12826 
   12827 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   12828 	case PF_INET:
   12829 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   12830 			if (isc_sockaddr_equal(&zone->altxfrsource4,
   12831 					       &zone->xfrsource4))
   12832 				goto skip_master;
   12833 			zone->sourceaddr = zone->altxfrsource4;
   12834 			if (!have_xfrdscp)
   12835 				dscp = zone->altxfrsource4dscp;
   12836 		} else if (!have_xfrsource) {
   12837 			zone->sourceaddr = zone->xfrsource4;
   12838 			if (!have_xfrdscp)
   12839 				dscp = zone->xfrsource4dscp;
   12840 		}
   12841 		break;
   12842 	case PF_INET6:
   12843 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   12844 			if (isc_sockaddr_equal(&zone->altxfrsource6,
   12845 					       &zone->xfrsource6))
   12846 				goto skip_master;
   12847 			zone->sourceaddr = zone->altxfrsource6;
   12848 			if (!have_xfrdscp)
   12849 				dscp = zone->altxfrsource6dscp;
   12850 		} else if (!have_xfrsource) {
   12851 			zone->sourceaddr = zone->xfrsource6;
   12852 			if (!have_xfrdscp)
   12853 				dscp = zone->xfrsource6dscp;
   12854 		}
   12855 		break;
   12856 	default:
   12857 		result = ISC_R_NOTIMPLEMENTED;
   12858 		goto cleanup;
   12859 	}
   12860 
   12861 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   12862 		result = add_opt(message, udpsize, reqnsid, reqexpire);
   12863 		if (result != ISC_R_SUCCESS)
   12864 			zone_debuglog(zone, me, 1,
   12865 				      "unable to add opt record: %s",
   12866 				      dns_result_totext(result));
   12867 	}
   12868 
   12869 	zone_iattach(zone, &dummy);
   12870 	timeout = 15;
   12871 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
   12872 		timeout = 30;
   12873 	result = dns_request_createvia(zone->view->requestmgr, message,
   12874 				       &zone->sourceaddr, &zone->masteraddr,
   12875 				       dscp, options, key, timeout * 3,
   12876 				       timeout, 0, zone->task,
   12877 				       refresh_callback, zone, &zone->request);
   12878 	if (result != ISC_R_SUCCESS) {
   12879 		zone_idetach(&dummy);
   12880 		zone_debuglog(zone, me, 1,
   12881 			      "dns_request_createvia4() failed: %s",
   12882 			      dns_result_totext(result));
   12883 		goto skip_master;
   12884 	} else {
   12885 		if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
   12886 			inc_stats(zone, dns_zonestatscounter_soaoutv4);
   12887 		else
   12888 			inc_stats(zone, dns_zonestatscounter_soaoutv6);
   12889 	}
   12890 	cancel = false;
   12891 
   12892  cleanup:
   12893 	if (key != NULL)
   12894 		dns_tsigkey_detach(&key);
   12895 	if (result != ISC_R_SUCCESS)
   12896 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   12897 	if (message != NULL)
   12898 		dns_message_destroy(&message);
   12899 	if (cancel)
   12900 		cancel_refresh(zone);
   12901 	isc_event_free(&event);
   12902 	UNLOCK_ZONE(zone);
   12903 	dns_zone_idetach(&zone);
   12904 	return;
   12905 
   12906  skip_master:
   12907 	if (key != NULL)
   12908 		dns_tsigkey_detach(&key);
   12909 	dns_message_destroy(&message);
   12910 	/*
   12911 	 * Skip to next failed / untried master.
   12912 	 */
   12913 	do {
   12914 		zone->curmaster++;
   12915 	} while (zone->curmaster < zone->masterscnt &&
   12916 		 zone->mastersok[zone->curmaster]);
   12917 	if (zone->curmaster < zone->masterscnt)
   12918 		goto again;
   12919 	zone->curmaster = 0;
   12920 	goto cleanup;
   12921 }
   12922 
   12923 static void
   12924 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
   12925 	const char me[] = "ns_query";
   12926 	isc_result_t result;
   12927 	dns_message_t *message = NULL;
   12928 	isc_netaddr_t masterip;
   12929 	dns_tsigkey_t *key = NULL;
   12930 	dns_dbnode_t *node = NULL;
   12931 	int timeout;
   12932 	bool have_xfrsource = false, have_xfrdscp = false;
   12933 	bool reqnsid;
   12934 	uint16_t udpsize = SEND_BUFFER_SIZE;
   12935 	isc_dscp_t dscp = -1;
   12936 
   12937 	REQUIRE(DNS_ZONE_VALID(zone));
   12938 	REQUIRE(LOCKED_ZONE(zone));
   12939 	REQUIRE((soardataset != NULL && stub == NULL) ||
   12940 		(soardataset == NULL && stub != NULL));
   12941 	REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
   12942 
   12943 	ENTER;
   12944 
   12945 	if (stub == NULL) {
   12946 		stub = isc_mem_get(zone->mctx, sizeof(*stub));
   12947 		if (stub == NULL)
   12948 			goto cleanup;
   12949 		stub->magic = STUB_MAGIC;
   12950 		stub->mctx = zone->mctx;
   12951 		stub->zone = NULL;
   12952 		stub->db = NULL;
   12953 		stub->version = NULL;
   12954 
   12955 		/*
   12956 		 * Attach so that the zone won't disappear from under us.
   12957 		 */
   12958 		zone_iattach(zone, &stub->zone);
   12959 
   12960 		/*
   12961 		 * If a db exists we will update it, otherwise we create a
   12962 		 * new one and attach it to the zone once we have the NS
   12963 		 * RRset and glue.
   12964 		 */
   12965 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12966 		if (zone->db != NULL) {
   12967 			dns_db_attach(zone->db, &stub->db);
   12968 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12969 		} else {
   12970 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12971 
   12972 			INSIST(zone->db_argc >= 1);
   12973 			result = dns_db_create(zone->mctx, zone->db_argv[0],
   12974 					       &zone->origin, dns_dbtype_stub,
   12975 					       zone->rdclass,
   12976 					       zone->db_argc - 1,
   12977 					       zone->db_argv + 1,
   12978 					       &stub->db);
   12979 			if (result != ISC_R_SUCCESS) {
   12980 				dns_zone_log(zone, ISC_LOG_ERROR,
   12981 					     "refreshing stub: "
   12982 					     "could not create "
   12983 					     "database: %s",
   12984 					     dns_result_totext(result));
   12985 				goto cleanup;
   12986 			}
   12987 			dns_db_settask(stub->db, zone->task);
   12988 		}
   12989 
   12990 		result = dns_db_newversion(stub->db, &stub->version);
   12991 		if (result != ISC_R_SUCCESS) {
   12992 			dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
   12993 				     "dns_db_newversion() failed: %s",
   12994 				     dns_result_totext(result));
   12995 			goto cleanup;
   12996 		}
   12997 
   12998 		/*
   12999 		 * Update SOA record.
   13000 		 */
   13001 		result = dns_db_findnode(stub->db, &zone->origin, true,
   13002 					 &node);
   13003 		if (result != ISC_R_SUCCESS) {
   13004 			dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
   13005 				     "dns_db_findnode() failed: %s",
   13006 				     dns_result_totext(result));
   13007 			goto cleanup;
   13008 		}
   13009 
   13010 		result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   13011 					    soardataset, 0, NULL);
   13012 		dns_db_detachnode(stub->db, &node);
   13013 		if (result != ISC_R_SUCCESS) {
   13014 			dns_zone_log(zone, ISC_LOG_INFO,
   13015 				     "refreshing stub: "
   13016 				     "dns_db_addrdataset() failed: %s",
   13017 				     dns_result_totext(result));
   13018 			goto cleanup;
   13019 		}
   13020 	}
   13021 
   13022 	/*
   13023 	 * XXX Optimisation: Create message when zone is setup and reuse.
   13024 	 */
   13025 	result = create_query(zone, dns_rdatatype_ns, &message);
   13026 	INSIST(result == ISC_R_SUCCESS);
   13027 
   13028 	INSIST(zone->masterscnt > 0);
   13029 	INSIST(zone->curmaster < zone->masterscnt);
   13030 	zone->masteraddr = zone->masters[zone->curmaster];
   13031 
   13032 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   13033 	/*
   13034 	 * First, look for a tsig key in the master statement, then
   13035 	 * try for a server key.
   13036 	 */
   13037 	if ((zone->masterkeynames != NULL) &&
   13038 	    (zone->masterkeynames[zone->curmaster] != NULL)) {
   13039 		dns_view_t *view = dns_zone_getview(zone);
   13040 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   13041 		result = dns_view_gettsig(view, keyname, &key);
   13042 		if (result != ISC_R_SUCCESS) {
   13043 			char namebuf[DNS_NAME_FORMATSIZE];
   13044 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   13045 			dns_zone_log(zone, ISC_LOG_ERROR,
   13046 				     "unable to find key: %s", namebuf);
   13047 		}
   13048 	}
   13049 	if (key == NULL)
   13050 		(void)dns_view_getpeertsig(zone->view, &masterip, &key);
   13051 
   13052 	reqnsid = zone->view->requestnsid;
   13053 	if (zone->view->peers != NULL) {
   13054 		dns_peer_t *peer = NULL;
   13055 		bool edns;
   13056 		result = dns_peerlist_peerbyaddr(zone->view->peers,
   13057 						 &masterip, &peer);
   13058 		if (result == ISC_R_SUCCESS) {
   13059 			result = dns_peer_getsupportedns(peer, &edns);
   13060 			if (result == ISC_R_SUCCESS && !edns)
   13061 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13062 			result = dns_peer_gettransfersource(peer,
   13063 							    &zone->sourceaddr);
   13064 			if (result == ISC_R_SUCCESS)
   13065 				have_xfrsource = true;
   13066 			result = dns_peer_gettransferdscp(peer, &dscp);
   13067 			if (result == ISC_R_SUCCESS && dscp != -1)
   13068 				have_xfrdscp = true;
   13069 			if (zone->view->resolver != NULL)
   13070 				udpsize =
   13071 				  dns_resolver_getudpsize(zone->view->resolver);
   13072 			(void)dns_peer_getudpsize(peer, &udpsize);
   13073 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   13074 		}
   13075 
   13076 	}
   13077 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   13078 		result = add_opt(message, udpsize, reqnsid, false);
   13079 		if (result != ISC_R_SUCCESS)
   13080 			zone_debuglog(zone, me, 1,
   13081 				      "unable to add opt record: %s",
   13082 				      dns_result_totext(result));
   13083 	}
   13084 
   13085 	/*
   13086 	 * Always use TCP so that we shouldn't truncate in additional section.
   13087 	 */
   13088 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   13089 	case PF_INET:
   13090 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   13091 			zone->sourceaddr = zone->altxfrsource4;
   13092 			if (!have_xfrdscp)
   13093 				dscp = zone->altxfrsource4dscp;
   13094 		} else if (!have_xfrsource) {
   13095 			zone->sourceaddr = zone->xfrsource4;
   13096 			if (!have_xfrdscp)
   13097 				dscp = zone->xfrsource4dscp;
   13098 		}
   13099 		break;
   13100 	case PF_INET6:
   13101 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   13102 			zone->sourceaddr = zone->altxfrsource6;
   13103 			if (!have_xfrdscp)
   13104 				dscp = zone->altxfrsource6dscp;
   13105 		} else if (!have_xfrsource) {
   13106 			zone->sourceaddr = zone->xfrsource6;
   13107 			if (!have_xfrdscp)
   13108 				dscp = zone->xfrsource6dscp;
   13109 		}
   13110 		break;
   13111 	default:
   13112 		result = ISC_R_NOTIMPLEMENTED;
   13113 		POST(result);
   13114 		goto cleanup;
   13115 	}
   13116 	timeout = 15;
   13117 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
   13118 		timeout = 30;
   13119 	result = dns_request_createvia(zone->view->requestmgr, message,
   13120 				       &zone->sourceaddr, &zone->masteraddr,
   13121 				       dscp, DNS_REQUESTOPT_TCP, key,
   13122 				       timeout * 3, timeout, 0, zone->task,
   13123 				       stub_callback, stub, &zone->request);
   13124 	if (result != ISC_R_SUCCESS) {
   13125 		zone_debuglog(zone, me, 1,
   13126 			      "dns_request_createvia() failed: %s",
   13127 			      dns_result_totext(result));
   13128 		goto cleanup;
   13129 	}
   13130 	dns_message_destroy(&message);
   13131 	goto unlock;
   13132 
   13133  cleanup:
   13134 	cancel_refresh(zone);
   13135 	if (stub != NULL) {
   13136 		stub->magic = 0;
   13137 		if (stub->version != NULL)
   13138 			dns_db_closeversion(stub->db, &stub->version,
   13139 					    false);
   13140 		if (stub->db != NULL)
   13141 			dns_db_detach(&stub->db);
   13142 		if (stub->zone != NULL)
   13143 			zone_idetach(&stub->zone);
   13144 		isc_mem_put(stub->mctx, stub, sizeof(*stub));
   13145 	}
   13146 	if (message != NULL)
   13147 		dns_message_destroy(&message);
   13148  unlock:
   13149 	if (key != NULL)
   13150 		dns_tsigkey_detach(&key);
   13151 	return;
   13152 }
   13153 
   13154 /*
   13155  * Handle the control event.  Note that although this event causes the zone
   13156  * to shut down, it is not a shutdown event in the sense of the task library.
   13157  */
   13158 static void
   13159 zone_shutdown(isc_task_t *task, isc_event_t *event) {
   13160 	dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
   13161 	bool free_needed, linked = false;
   13162 	dns_zone_t *raw = NULL, *secure = NULL;
   13163 
   13164 	UNUSED(task);
   13165 	REQUIRE(DNS_ZONE_VALID(zone));
   13166 	INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
   13167 	INSIST(isc_refcount_current(&zone->erefs) == 0);
   13168 
   13169 	zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
   13170 
   13171 	/*
   13172 	 * Stop things being restarted after we cancel them below.
   13173 	 */
   13174 	LOCK_ZONE(zone);
   13175 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
   13176 	UNLOCK_ZONE(zone);
   13177 
   13178 	/*
   13179 	 * If we were waiting for xfrin quota, step out of
   13180 	 * the queue.
   13181 	 * If there's no zone manager, we can't be waiting for the
   13182 	 * xfrin quota
   13183 	 */
   13184 	if (zone->zmgr != NULL) {
   13185 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   13186 		if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
   13187 			ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
   13188 					statelink);
   13189 			linked = true;
   13190 			zone->statelist = NULL;
   13191 		}
   13192 		if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
   13193 			ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
   13194 					statelink);
   13195 			zone->statelist = NULL;
   13196 			zmgr_resume_xfrs(zone->zmgr, false);
   13197 		}
   13198 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   13199 	}
   13200 
   13201 	/*
   13202 	 * In task context, no locking required.  See zone_xfrdone().
   13203 	 */
   13204 	if (zone->xfr != NULL)
   13205 		dns_xfrin_shutdown(zone->xfr);
   13206 
   13207 	/* Safe to release the zone now */
   13208 	if (zone->zmgr != NULL)
   13209 		dns_zonemgr_releasezone(zone->zmgr, zone);
   13210 
   13211 	LOCK_ZONE(zone);
   13212 	INSIST(zone != zone->raw);
   13213 	if (linked) {
   13214 		INSIST(zone->irefs > 0);
   13215 		zone->irefs--;
   13216 	}
   13217 	if (zone->request != NULL) {
   13218 		dns_request_cancel(zone->request);
   13219 	}
   13220 
   13221 	if (zone->readio != NULL)
   13222 		zonemgr_cancelio(zone->readio);
   13223 
   13224 	if (zone->lctx != NULL)
   13225 		dns_loadctx_cancel(zone->lctx);
   13226 
   13227 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   13228 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   13229 		if (zone->writeio != NULL)
   13230 			zonemgr_cancelio(zone->writeio);
   13231 
   13232 		if (zone->dctx != NULL)
   13233 			dns_dumpctx_cancel(zone->dctx);
   13234 	}
   13235 
   13236 	notify_cancel(zone);
   13237 
   13238 	forward_cancel(zone);
   13239 
   13240 	if (zone->timer != NULL) {
   13241 		isc_timer_detach(&zone->timer);
   13242 		INSIST(zone->irefs > 0);
   13243 		zone->irefs--;
   13244 	}
   13245 
   13246 	/*
   13247 	 * We have now canceled everything set the flag to allow exit_check()
   13248 	 * to succeed.	We must not unlock between setting this flag and
   13249 	 * calling exit_check().
   13250 	 */
   13251 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
   13252 	free_needed = exit_check(zone);
   13253 	if (inline_secure(zone)) {
   13254 		raw = zone->raw;
   13255 		zone->raw = NULL;
   13256 	}
   13257 	if (inline_raw(zone)) {
   13258 		secure = zone->secure;
   13259 		zone->secure = NULL;
   13260 	}
   13261 	UNLOCK_ZONE(zone);
   13262 	if (raw != NULL)
   13263 		dns_zone_detach(&raw);
   13264 	if (secure != NULL)
   13265 		dns_zone_idetach(&secure);
   13266 	if (free_needed)
   13267 		zone_free(zone);
   13268 }
   13269 
   13270 static void
   13271 zone_timer(isc_task_t *task, isc_event_t *event) {
   13272 	const char me[] = "zone_timer";
   13273 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   13274 
   13275 	UNUSED(task);
   13276 	REQUIRE(DNS_ZONE_VALID(zone));
   13277 
   13278 	ENTER;
   13279 
   13280 	zone_maintenance(zone);
   13281 
   13282 	isc_event_free(&event);
   13283 }
   13284 
   13285 static void
   13286 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
   13287 	const char me[] = "zone_settimer";
   13288 	isc_time_t next;
   13289 	isc_result_t result;
   13290 
   13291 	REQUIRE(DNS_ZONE_VALID(zone));
   13292 	ENTER;
   13293 
   13294 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
   13295 		return;
   13296 
   13297 	isc_time_settoepoch(&next);
   13298 
   13299 	switch (zone->type) {
   13300 	case dns_zone_redirect:
   13301 		if (zone->masters != NULL)
   13302 			goto treat_as_slave;
   13303 		/* FALLTHROUGH */
   13304 
   13305 	case dns_zone_master:
   13306 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   13307 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   13308 			next = zone->notifytime;
   13309 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   13310 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   13311 			INSIST(!isc_time_isepoch(&zone->dumptime));
   13312 			if (isc_time_isepoch(&next) ||
   13313 			    isc_time_compare(&zone->dumptime, &next) < 0)
   13314 				next = zone->dumptime;
   13315 		}
   13316 		if (zone->type == dns_zone_redirect)
   13317 			break;
   13318 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
   13319 		    !isc_time_isepoch(&zone->refreshkeytime)) {
   13320 			if (isc_time_isepoch(&next) ||
   13321 			    isc_time_compare(&zone->refreshkeytime, &next) < 0)
   13322 				next = zone->refreshkeytime;
   13323 		}
   13324 		if (!isc_time_isepoch(&zone->resigntime)) {
   13325 			if (isc_time_isepoch(&next) ||
   13326 			    isc_time_compare(&zone->resigntime, &next) < 0)
   13327 				next = zone->resigntime;
   13328 		}
   13329 		if (!isc_time_isepoch(&zone->keywarntime)) {
   13330 			if (isc_time_isepoch(&next) ||
   13331 			    isc_time_compare(&zone->keywarntime, &next) < 0)
   13332 				next = zone->keywarntime;
   13333 		}
   13334 		if (!isc_time_isepoch(&zone->signingtime)) {
   13335 			if (isc_time_isepoch(&next) ||
   13336 			    isc_time_compare(&zone->signingtime, &next) < 0)
   13337 				next = zone->signingtime;
   13338 		}
   13339 		if (!isc_time_isepoch(&zone->nsec3chaintime)) {
   13340 			if (isc_time_isepoch(&next) ||
   13341 			    isc_time_compare(&zone->nsec3chaintime, &next) < 0)
   13342 				next = zone->nsec3chaintime;
   13343 		}
   13344 		break;
   13345 
   13346 	case dns_zone_slave:
   13347 	case dns_zone_mirror:
   13348 	treat_as_slave:
   13349 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   13350 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   13351 			next = zone->notifytime;
   13352 		/* FALLTHROUGH */
   13353 
   13354 	case dns_zone_stub:
   13355 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
   13356 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
   13357 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
   13358 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
   13359 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
   13360 		    !isc_time_isepoch(&zone->refreshtime) &&
   13361 		    (isc_time_isepoch(&next) ||
   13362 		     isc_time_compare(&zone->refreshtime, &next) < 0))
   13363 			next = zone->refreshtime;
   13364 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   13365 		    !isc_time_isepoch(&zone->expiretime)) {
   13366 			if (isc_time_isepoch(&next) ||
   13367 			     isc_time_compare(&zone->expiretime, &next) < 0)
   13368 				next = zone->expiretime;
   13369 		}
   13370 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   13371 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   13372 			INSIST(!isc_time_isepoch(&zone->dumptime));
   13373 			if (isc_time_isepoch(&next) ||
   13374 			    isc_time_compare(&zone->dumptime, &next) < 0)
   13375 				next = zone->dumptime;
   13376 		}
   13377 		break;
   13378 
   13379 	case dns_zone_key:
   13380 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   13381 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   13382 			INSIST(!isc_time_isepoch(&zone->dumptime));
   13383 			if (isc_time_isepoch(&next) ||
   13384 			    isc_time_compare(&zone->dumptime, &next) < 0)
   13385 				next = zone->dumptime;
   13386 		}
   13387 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
   13388 			if (isc_time_isepoch(&next) ||
   13389 			    (!isc_time_isepoch(&zone->refreshkeytime) &&
   13390 			    isc_time_compare(&zone->refreshkeytime, &next) < 0))
   13391 				next = zone->refreshkeytime;
   13392 		}
   13393 		break;
   13394 
   13395 	default:
   13396 		break;
   13397 	}
   13398 
   13399 	if (isc_time_isepoch(&next)) {
   13400 		zone_debuglog(zone, me, 10, "settimer inactive");
   13401 		result = isc_timer_reset(zone->timer, isc_timertype_inactive,
   13402 					  NULL, NULL, true);
   13403 		if (result != ISC_R_SUCCESS)
   13404 			dns_zone_log(zone, ISC_LOG_ERROR,
   13405 				     "could not deactivate zone timer: %s",
   13406 				     isc_result_totext(result));
   13407 	} else {
   13408 		if (isc_time_compare(&next, now) <= 0)
   13409 			next = *now;
   13410 		result = isc_timer_reset(zone->timer, isc_timertype_once,
   13411 					 &next, NULL, true);
   13412 		if (result != ISC_R_SUCCESS)
   13413 			dns_zone_log(zone, ISC_LOG_ERROR,
   13414 				     "could not reset zone timer: %s",
   13415 				     isc_result_totext(result));
   13416 	}
   13417 }
   13418 
   13419 static void
   13420 cancel_refresh(dns_zone_t *zone) {
   13421 	const char me[] = "cancel_refresh";
   13422 	isc_time_t now;
   13423 
   13424 	/*
   13425 	 * 'zone' locked by caller.
   13426 	 */
   13427 
   13428 	REQUIRE(DNS_ZONE_VALID(zone));
   13429 	REQUIRE(LOCKED_ZONE(zone));
   13430 
   13431 	ENTER;
   13432 
   13433 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13434 	TIME_NOW(&now);
   13435 	zone_settimer(zone, &now);
   13436 }
   13437 
   13438 static isc_result_t
   13439 notify_createmessage(dns_zone_t *zone, unsigned int flags,
   13440 		     dns_message_t **messagep)
   13441 {
   13442 	dns_db_t *zonedb = NULL;
   13443 	dns_dbnode_t *node = NULL;
   13444 	dns_dbversion_t *version = NULL;
   13445 	dns_message_t *message = NULL;
   13446 	dns_rdataset_t rdataset;
   13447 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13448 
   13449 	dns_name_t *tempname = NULL;
   13450 	dns_rdata_t *temprdata = NULL;
   13451 	dns_rdatalist_t *temprdatalist = NULL;
   13452 	dns_rdataset_t *temprdataset = NULL;
   13453 
   13454 	isc_result_t result;
   13455 	isc_region_t r;
   13456 	isc_buffer_t *b = NULL;
   13457 
   13458 	REQUIRE(DNS_ZONE_VALID(zone));
   13459 	REQUIRE(messagep != NULL && *messagep == NULL);
   13460 
   13461 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
   13462 				    &message);
   13463 	if (result != ISC_R_SUCCESS)
   13464 		return (result);
   13465 
   13466 	message->opcode = dns_opcode_notify;
   13467 	message->flags |= DNS_MESSAGEFLAG_AA;
   13468 	message->rdclass = zone->rdclass;
   13469 
   13470 	result = dns_message_gettempname(message, &tempname);
   13471 	if (result != ISC_R_SUCCESS)
   13472 		goto cleanup;
   13473 
   13474 	result = dns_message_gettemprdataset(message, &temprdataset);
   13475 	if (result != ISC_R_SUCCESS)
   13476 		goto cleanup;
   13477 
   13478 	/*
   13479 	 * Make question.
   13480 	 */
   13481 	dns_name_init(tempname, NULL);
   13482 	dns_name_clone(&zone->origin, tempname);
   13483 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
   13484 				  dns_rdatatype_soa);
   13485 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   13486 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
   13487 	tempname = NULL;
   13488 	temprdataset = NULL;
   13489 
   13490 	if ((flags & DNS_NOTIFY_NOSOA) != 0)
   13491 		goto done;
   13492 
   13493 	result = dns_message_gettempname(message, &tempname);
   13494 	if (result != ISC_R_SUCCESS)
   13495 		goto soa_cleanup;
   13496 	result = dns_message_gettemprdata(message, &temprdata);
   13497 	if (result != ISC_R_SUCCESS)
   13498 		goto soa_cleanup;
   13499 	result = dns_message_gettemprdataset(message, &temprdataset);
   13500 	if (result != ISC_R_SUCCESS)
   13501 		goto soa_cleanup;
   13502 	result = dns_message_gettemprdatalist(message, &temprdatalist);
   13503 	if (result != ISC_R_SUCCESS)
   13504 		goto soa_cleanup;
   13505 
   13506 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   13507 	INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
   13508 	dns_db_attach(zone->db, &zonedb);
   13509 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   13510 
   13511 	dns_name_init(tempname, NULL);
   13512 	dns_name_clone(&zone->origin, tempname);
   13513 	dns_db_currentversion(zonedb, &version);
   13514 	result = dns_db_findnode(zonedb, tempname, false, &node);
   13515 	if (result != ISC_R_SUCCESS)
   13516 		goto soa_cleanup;
   13517 
   13518 	dns_rdataset_init(&rdataset);
   13519 	result = dns_db_findrdataset(zonedb, node, version,
   13520 				     dns_rdatatype_soa,
   13521 				     dns_rdatatype_none, 0, &rdataset,
   13522 				     NULL);
   13523 	if (result != ISC_R_SUCCESS)
   13524 		goto soa_cleanup;
   13525 	result = dns_rdataset_first(&rdataset);
   13526 	if (result != ISC_R_SUCCESS)
   13527 		goto soa_cleanup;
   13528 	dns_rdataset_current(&rdataset, &rdata);
   13529 	dns_rdata_toregion(&rdata, &r);
   13530 	result = isc_buffer_allocate(zone->mctx, &b, r.length);
   13531 	if (result != ISC_R_SUCCESS)
   13532 		goto soa_cleanup;
   13533 	isc_buffer_putmem(b, r.base, r.length);
   13534 	isc_buffer_usedregion(b, &r);
   13535 	dns_rdata_init(temprdata);
   13536 	dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
   13537 	dns_message_takebuffer(message, &b);
   13538 	result = dns_rdataset_next(&rdataset);
   13539 	dns_rdataset_disassociate(&rdataset);
   13540 	if (result != ISC_R_NOMORE)
   13541 		goto soa_cleanup;
   13542 	temprdatalist->rdclass = rdata.rdclass;
   13543 	temprdatalist->type = rdata.type;
   13544 	temprdatalist->ttl = rdataset.ttl;
   13545 	ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
   13546 
   13547 	result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
   13548 	if (result != ISC_R_SUCCESS)
   13549 		goto soa_cleanup;
   13550 
   13551 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   13552 	dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
   13553 	temprdatalist = NULL;
   13554 	temprdataset = NULL;
   13555 	temprdata = NULL;
   13556 	tempname = NULL;
   13557 
   13558  soa_cleanup:
   13559 	if (node != NULL)
   13560 		dns_db_detachnode(zonedb, &node);
   13561 	if (version != NULL)
   13562 		dns_db_closeversion(zonedb, &version, false);
   13563 	if (zonedb != NULL)
   13564 		dns_db_detach(&zonedb);
   13565 	if (tempname != NULL)
   13566 		dns_message_puttempname(message, &tempname);
   13567 	if (temprdata != NULL)
   13568 		dns_message_puttemprdata(message, &temprdata);
   13569 	if (temprdataset != NULL)
   13570 		dns_message_puttemprdataset(message, &temprdataset);
   13571 	if (temprdatalist != NULL)
   13572 		dns_message_puttemprdatalist(message, &temprdatalist);
   13573 
   13574  done:
   13575 	*messagep = message;
   13576 	return (ISC_R_SUCCESS);
   13577 
   13578  cleanup:
   13579 	if (tempname != NULL)
   13580 		dns_message_puttempname(message, &tempname);
   13581 	if (temprdataset != NULL)
   13582 		dns_message_puttemprdataset(message, &temprdataset);
   13583 	dns_message_destroy(&message);
   13584 	return (result);
   13585 }
   13586 
   13587 isc_result_t
   13588 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
   13589 		       isc_sockaddr_t *to, dns_message_t *msg)
   13590 {
   13591 	unsigned int i;
   13592 	dns_rdata_soa_t soa;
   13593 	dns_rdataset_t *rdataset = NULL;
   13594 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13595 	isc_result_t result;
   13596 	char fromtext[ISC_SOCKADDR_FORMATSIZE];
   13597 	int match = 0;
   13598 	isc_netaddr_t netaddr;
   13599 	uint32_t serial = 0;
   13600 	bool have_serial = false;
   13601 	dns_tsigkey_t *tsigkey;
   13602 	dns_name_t *tsig;
   13603 
   13604 	REQUIRE(DNS_ZONE_VALID(zone));
   13605 
   13606 	/*
   13607 	 * If type != T_SOA return DNS_R_NOTIMP.  We don't yet support
   13608 	 * ROLLOVER.
   13609 	 *
   13610 	 * SOA:	RFC1996
   13611 	 * Check that 'from' is a valid notify source, (zone->masters).
   13612 	 *	Return DNS_R_REFUSED if not.
   13613 	 *
   13614 	 * If the notify message contains a serial number check it
   13615 	 * against the zones serial and return if <= current serial
   13616 	 *
   13617 	 * If a refresh check is progress, if so just record the
   13618 	 * fact we received a NOTIFY and from where and return.
   13619 	 * We will perform a new refresh check when the current one
   13620 	 * completes. Return ISC_R_SUCCESS.
   13621 	 *
   13622 	 * Otherwise initiate a refresh check using 'from' as the
   13623 	 * first address to check.  Return ISC_R_SUCCESS.
   13624 	 */
   13625 
   13626 	isc_sockaddr_format(from, fromtext, sizeof(fromtext));
   13627 
   13628 	/*
   13629 	 * Notify messages are processed by the raw zone.
   13630 	 */
   13631 	LOCK_ZONE(zone);
   13632 	INSIST(zone != zone->raw);
   13633 	if (inline_secure(zone)) {
   13634 		result = dns_zone_notifyreceive(zone->raw, from, to, msg);
   13635 		UNLOCK_ZONE(zone);
   13636 		return (result);
   13637 	}
   13638 	/*
   13639 	 *  We only handle NOTIFY (SOA) at the present.
   13640 	 */
   13641 	if (isc_sockaddr_pf(from) == PF_INET)
   13642 		inc_stats(zone, dns_zonestatscounter_notifyinv4);
   13643 	else
   13644 		inc_stats(zone, dns_zonestatscounter_notifyinv6);
   13645 	if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
   13646 	    dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
   13647 				 dns_rdatatype_soa, dns_rdatatype_none,
   13648 				 NULL, NULL) != ISC_R_SUCCESS) {
   13649 		UNLOCK_ZONE(zone);
   13650 		if (msg->counts[DNS_SECTION_QUESTION] == 0) {
   13651 			dns_zone_log(zone, ISC_LOG_NOTICE,
   13652 				     "NOTIFY with no "
   13653 				     "question section from: %s", fromtext);
   13654 			return (DNS_R_FORMERR);
   13655 		}
   13656 		dns_zone_log(zone, ISC_LOG_NOTICE,
   13657 			     "NOTIFY zone does not match");
   13658 		return (DNS_R_NOTIMP);
   13659 	}
   13660 
   13661 	/*
   13662 	 * If we are a master zone just succeed.
   13663 	 */
   13664 	if (zone->type == dns_zone_master) {
   13665 		UNLOCK_ZONE(zone);
   13666 		return (ISC_R_SUCCESS);
   13667 	}
   13668 
   13669 	isc_netaddr_fromsockaddr(&netaddr, from);
   13670 	for (i = 0; i < zone->masterscnt; i++) {
   13671 		if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
   13672 			break;
   13673 		if (zone->view->aclenv.match_mapped &&
   13674 		    IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
   13675 		    isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
   13676 			isc_netaddr_t na1, na2;
   13677 			isc_netaddr_fromv4mapped(&na1, &netaddr);
   13678 			isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
   13679 			if (isc_netaddr_equal(&na1, &na2))
   13680 				break;
   13681 		}
   13682 	}
   13683 
   13684 	/*
   13685 	 * Accept notify requests from non masters if they are on
   13686 	 * 'zone->notify_acl'.
   13687 	 */
   13688 	tsigkey = dns_message_gettsigkey(msg);
   13689 	tsig = dns_tsigkey_identity(tsigkey);
   13690 	if (i >= zone->masterscnt && zone->notify_acl != NULL &&
   13691 	    (dns_acl_match(&netaddr, tsig, zone->notify_acl,
   13692 			   &zone->view->aclenv, &match,
   13693 			   NULL) == ISC_R_SUCCESS) &&
   13694 	    match > 0)
   13695 	{
   13696 		/* Accept notify. */
   13697 	} else if (i >= zone->masterscnt) {
   13698 		UNLOCK_ZONE(zone);
   13699 		dns_zone_log(zone, ISC_LOG_INFO,
   13700 			     "refused notify from non-master: %s", fromtext);
   13701 		inc_stats(zone, dns_zonestatscounter_notifyrej);
   13702 		return (DNS_R_REFUSED);
   13703 	}
   13704 
   13705 	/*
   13706 	 * If the zone is loaded and there are answers check the serial
   13707 	 * to see if we need to do a refresh.  Do not worry about this
   13708 	 * check if we are a dialup zone as we use the notify request
   13709 	 * to trigger a refresh check.
   13710 	 */
   13711 	if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
   13712 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   13713 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
   13714 		result = dns_message_findname(msg, DNS_SECTION_ANSWER,
   13715 					      &zone->origin,
   13716 					      dns_rdatatype_soa,
   13717 					      dns_rdatatype_none, NULL,
   13718 					      &rdataset);
   13719 		if (result == ISC_R_SUCCESS)
   13720 			result = dns_rdataset_first(rdataset);
   13721 		if (result == ISC_R_SUCCESS) {
   13722 			uint32_t oldserial;
   13723 			unsigned int soacount;
   13724 
   13725 			dns_rdataset_current(rdataset, &rdata);
   13726 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   13727 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13728 			serial = soa.serial;
   13729 			have_serial = true;
   13730 			/*
   13731 			 * The following should safely be performed without DB
   13732 			 * lock and succeed in this context.
   13733 			 */
   13734 			result = zone_get_from_db(zone, zone->db, NULL,
   13735 						  &soacount, &oldserial, NULL,
   13736 						  NULL, NULL, NULL, NULL);
   13737 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13738 			RUNTIME_CHECK(soacount > 0U);
   13739 			if (isc_serial_le(serial, oldserial)) {
   13740 				dns_zone_log(zone,
   13741 					     ISC_LOG_INFO,
   13742 					     "notify from %s: "
   13743 					     "zone is up to date",
   13744 					     fromtext);
   13745 				UNLOCK_ZONE(zone);
   13746 				return (ISC_R_SUCCESS);
   13747 			}
   13748 		}
   13749 	}
   13750 
   13751 	/*
   13752 	 * If we got this far and there was a refresh in progress just
   13753 	 * let it complete.  Record where we got the notify from so we
   13754 	 * can perform a refresh check when the current one completes
   13755 	 */
   13756 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   13757 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   13758 		zone->notifyfrom = *from;
   13759 		UNLOCK_ZONE(zone);
   13760 		if (have_serial)
   13761 			dns_zone_log(zone, ISC_LOG_INFO,
   13762 				     "notify from %s: serial %u: refresh in "
   13763 				     "progress, refresh check queued",
   13764 				      fromtext, serial);
   13765 		else
   13766 			dns_zone_log(zone, ISC_LOG_INFO,
   13767 				     "notify from %s: refresh in progress, "
   13768 				     "refresh check queued", fromtext);
   13769 		return (ISC_R_SUCCESS);
   13770 	}
   13771 	if (have_serial)
   13772 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
   13773 			     fromtext, serial);
   13774 	else
   13775 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
   13776 			     fromtext);
   13777 	zone->notifyfrom = *from;
   13778 	UNLOCK_ZONE(zone);
   13779 
   13780 	if (to != NULL) {
   13781 		dns_zonemgr_unreachabledel(zone->zmgr, from, to);
   13782 	}
   13783 	dns_zone_refresh(zone);
   13784 	return (ISC_R_SUCCESS);
   13785 }
   13786 
   13787 void
   13788 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
   13789 
   13790 	REQUIRE(DNS_ZONE_VALID(zone));
   13791 
   13792 	LOCK_ZONE(zone);
   13793 	if (zone->notify_acl != NULL)
   13794 		dns_acl_detach(&zone->notify_acl);
   13795 	dns_acl_attach(acl, &zone->notify_acl);
   13796 	UNLOCK_ZONE(zone);
   13797 }
   13798 
   13799 void
   13800 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
   13801 
   13802 	REQUIRE(DNS_ZONE_VALID(zone));
   13803 
   13804 	LOCK_ZONE(zone);
   13805 	if (zone->query_acl != NULL)
   13806 		dns_acl_detach(&zone->query_acl);
   13807 	dns_acl_attach(acl, &zone->query_acl);
   13808 	UNLOCK_ZONE(zone);
   13809 }
   13810 
   13811 void
   13812 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
   13813 
   13814 	REQUIRE(DNS_ZONE_VALID(zone));
   13815 
   13816 	LOCK_ZONE(zone);
   13817 	if (zone->queryon_acl != NULL)
   13818 		dns_acl_detach(&zone->queryon_acl);
   13819 	dns_acl_attach(acl, &zone->queryon_acl);
   13820 	UNLOCK_ZONE(zone);
   13821 }
   13822 
   13823 void
   13824 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
   13825 
   13826 	REQUIRE(DNS_ZONE_VALID(zone));
   13827 
   13828 	LOCK_ZONE(zone);
   13829 	if (zone->update_acl != NULL)
   13830 		dns_acl_detach(&zone->update_acl);
   13831 	dns_acl_attach(acl, &zone->update_acl);
   13832 	UNLOCK_ZONE(zone);
   13833 }
   13834 
   13835 void
   13836 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
   13837 
   13838 	REQUIRE(DNS_ZONE_VALID(zone));
   13839 
   13840 	LOCK_ZONE(zone);
   13841 	if (zone->forward_acl != NULL)
   13842 		dns_acl_detach(&zone->forward_acl);
   13843 	dns_acl_attach(acl, &zone->forward_acl);
   13844 	UNLOCK_ZONE(zone);
   13845 }
   13846 
   13847 void
   13848 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
   13849 
   13850 	REQUIRE(DNS_ZONE_VALID(zone));
   13851 
   13852 	LOCK_ZONE(zone);
   13853 	if (zone->xfr_acl != NULL)
   13854 		dns_acl_detach(&zone->xfr_acl);
   13855 	dns_acl_attach(acl, &zone->xfr_acl);
   13856 	UNLOCK_ZONE(zone);
   13857 }
   13858 
   13859 dns_acl_t *
   13860 dns_zone_getnotifyacl(dns_zone_t *zone) {
   13861 
   13862 	REQUIRE(DNS_ZONE_VALID(zone));
   13863 
   13864 	return (zone->notify_acl);
   13865 }
   13866 
   13867 dns_acl_t *
   13868 dns_zone_getqueryacl(dns_zone_t *zone) {
   13869 
   13870 	REQUIRE(DNS_ZONE_VALID(zone));
   13871 
   13872 	return (zone->query_acl);
   13873 }
   13874 
   13875 dns_acl_t *
   13876 dns_zone_getqueryonacl(dns_zone_t *zone) {
   13877 
   13878 	REQUIRE(DNS_ZONE_VALID(zone));
   13879 
   13880 	return (zone->queryon_acl);
   13881 }
   13882 
   13883 dns_acl_t *
   13884 dns_zone_getupdateacl(dns_zone_t *zone) {
   13885 
   13886 	REQUIRE(DNS_ZONE_VALID(zone));
   13887 
   13888 	return (zone->update_acl);
   13889 }
   13890 
   13891 dns_acl_t *
   13892 dns_zone_getforwardacl(dns_zone_t *zone) {
   13893 
   13894 	REQUIRE(DNS_ZONE_VALID(zone));
   13895 
   13896 	return (zone->forward_acl);
   13897 }
   13898 
   13899 dns_acl_t *
   13900 dns_zone_getxfracl(dns_zone_t *zone) {
   13901 
   13902 	REQUIRE(DNS_ZONE_VALID(zone));
   13903 
   13904 	return (zone->xfr_acl);
   13905 }
   13906 
   13907 void
   13908 dns_zone_clearupdateacl(dns_zone_t *zone) {
   13909 
   13910 	REQUIRE(DNS_ZONE_VALID(zone));
   13911 
   13912 	LOCK_ZONE(zone);
   13913 	if (zone->update_acl != NULL)
   13914 		dns_acl_detach(&zone->update_acl);
   13915 	UNLOCK_ZONE(zone);
   13916 }
   13917 
   13918 void
   13919 dns_zone_clearforwardacl(dns_zone_t *zone) {
   13920 
   13921 	REQUIRE(DNS_ZONE_VALID(zone));
   13922 
   13923 	LOCK_ZONE(zone);
   13924 	if (zone->forward_acl != NULL)
   13925 		dns_acl_detach(&zone->forward_acl);
   13926 	UNLOCK_ZONE(zone);
   13927 }
   13928 
   13929 void
   13930 dns_zone_clearnotifyacl(dns_zone_t *zone) {
   13931 
   13932 	REQUIRE(DNS_ZONE_VALID(zone));
   13933 
   13934 	LOCK_ZONE(zone);
   13935 	if (zone->notify_acl != NULL)
   13936 		dns_acl_detach(&zone->notify_acl);
   13937 	UNLOCK_ZONE(zone);
   13938 }
   13939 
   13940 void
   13941 dns_zone_clearqueryacl(dns_zone_t *zone) {
   13942 
   13943 	REQUIRE(DNS_ZONE_VALID(zone));
   13944 
   13945 	LOCK_ZONE(zone);
   13946 	if (zone->query_acl != NULL)
   13947 		dns_acl_detach(&zone->query_acl);
   13948 	UNLOCK_ZONE(zone);
   13949 }
   13950 
   13951 void
   13952 dns_zone_clearqueryonacl(dns_zone_t *zone) {
   13953 
   13954 	REQUIRE(DNS_ZONE_VALID(zone));
   13955 
   13956 	LOCK_ZONE(zone);
   13957 	if (zone->queryon_acl != NULL)
   13958 		dns_acl_detach(&zone->queryon_acl);
   13959 	UNLOCK_ZONE(zone);
   13960 }
   13961 
   13962 void
   13963 dns_zone_clearxfracl(dns_zone_t *zone) {
   13964 
   13965 	REQUIRE(DNS_ZONE_VALID(zone));
   13966 
   13967 	LOCK_ZONE(zone);
   13968 	if (zone->xfr_acl != NULL)
   13969 		dns_acl_detach(&zone->xfr_acl);
   13970 	UNLOCK_ZONE(zone);
   13971 }
   13972 
   13973 bool
   13974 dns_zone_getupdatedisabled(dns_zone_t *zone) {
   13975 	REQUIRE(DNS_ZONE_VALID(zone));
   13976 	return (zone->update_disabled);
   13977 
   13978 }
   13979 
   13980 void
   13981 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
   13982 	REQUIRE(DNS_ZONE_VALID(zone));
   13983 	zone->update_disabled = state;
   13984 }
   13985 
   13986 bool
   13987 dns_zone_getzeronosoattl(dns_zone_t *zone) {
   13988 	REQUIRE(DNS_ZONE_VALID(zone));
   13989 	return (zone->zero_no_soa_ttl);
   13990 
   13991 }
   13992 
   13993 void
   13994 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
   13995 	REQUIRE(DNS_ZONE_VALID(zone));
   13996 	zone->zero_no_soa_ttl = state;
   13997 }
   13998 
   13999 void
   14000 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
   14001 	REQUIRE(DNS_ZONE_VALID(zone));
   14002 
   14003 	zone->check_names = severity;
   14004 }
   14005 
   14006 dns_severity_t
   14007 dns_zone_getchecknames(dns_zone_t *zone) {
   14008 	REQUIRE(DNS_ZONE_VALID(zone));
   14009 
   14010 	return (zone->check_names);
   14011 }
   14012 
   14013 void
   14014 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
   14015 	REQUIRE(DNS_ZONE_VALID(zone));
   14016 
   14017 	zone->journalsize = size;
   14018 }
   14019 
   14020 int32_t
   14021 dns_zone_getjournalsize(dns_zone_t *zone) {
   14022 	REQUIRE(DNS_ZONE_VALID(zone));
   14023 
   14024 	return (zone->journalsize);
   14025 }
   14026 
   14027 static void
   14028 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
   14029 	isc_result_t result = ISC_R_FAILURE;
   14030 	isc_buffer_t buffer;
   14031 
   14032 	REQUIRE(buf != NULL);
   14033 	REQUIRE(length > 1U);
   14034 
   14035 	/*
   14036 	 * Leave space for terminating '\0'.
   14037 	 */
   14038 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   14039 	if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
   14040 		if (dns_name_dynamic(&zone->origin))
   14041 			result = dns_name_totext(&zone->origin, true, &buffer);
   14042 		if (result != ISC_R_SUCCESS &&
   14043 		    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
   14044 			isc_buffer_putstr(&buffer, "<UNKNOWN>");
   14045 
   14046 		if (isc_buffer_availablelength(&buffer) > 0)
   14047 			isc_buffer_putstr(&buffer, "/");
   14048 		(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   14049 	}
   14050 
   14051 	if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
   14052 	    strcmp(zone->view->name, "_default") != 0 &&
   14053 	    strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
   14054 		isc_buffer_putstr(&buffer, "/");
   14055 		isc_buffer_putstr(&buffer, zone->view->name);
   14056 	}
   14057 	if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer))
   14058 		isc_buffer_putstr(&buffer, " (signed)");
   14059 	if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer))
   14060 		isc_buffer_putstr(&buffer, " (unsigned)");
   14061 
   14062 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   14063 }
   14064 
   14065 static void
   14066 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
   14067 	isc_result_t result = ISC_R_FAILURE;
   14068 	isc_buffer_t buffer;
   14069 
   14070 	REQUIRE(buf != NULL);
   14071 	REQUIRE(length > 1U);
   14072 
   14073 	/*
   14074 	 * Leave space for terminating '\0'.
   14075 	 */
   14076 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   14077 	if (dns_name_dynamic(&zone->origin))
   14078 		result = dns_name_totext(&zone->origin, true, &buffer);
   14079 	if (result != ISC_R_SUCCESS &&
   14080 	    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
   14081 		isc_buffer_putstr(&buffer, "<UNKNOWN>");
   14082 
   14083 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   14084 }
   14085 
   14086 static void
   14087 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
   14088 	isc_buffer_t buffer;
   14089 
   14090 	REQUIRE(buf != NULL);
   14091 	REQUIRE(length > 1U);
   14092 
   14093 	/*
   14094 	 * Leave space for terminating '\0'.
   14095 	 */
   14096 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   14097 	(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   14098 
   14099 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   14100 }
   14101 
   14102 static void
   14103 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
   14104 	isc_buffer_t buffer;
   14105 
   14106 	REQUIRE(buf != NULL);
   14107 	REQUIRE(length > 1U);
   14108 
   14109 
   14110 	/*
   14111 	 * Leave space for terminating '\0'.
   14112 	 */
   14113 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   14114 
   14115 	if (zone->view == NULL) {
   14116 		isc_buffer_putstr(&buffer, "_none");
   14117 	} else if (strlen(zone->view->name)
   14118 		   < isc_buffer_availablelength(&buffer)) {
   14119 		isc_buffer_putstr(&buffer, zone->view->name);
   14120 	} else {
   14121 		isc_buffer_putstr(&buffer, "_toolong");
   14122 	}
   14123 
   14124 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   14125 }
   14126 
   14127 void
   14128 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
   14129 	REQUIRE(DNS_ZONE_VALID(zone));
   14130 	REQUIRE(buf != NULL);
   14131 	zone_namerd_tostr(zone, buf, length);
   14132 }
   14133 
   14134 void
   14135 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
   14136 	REQUIRE(DNS_ZONE_VALID(zone));
   14137 	REQUIRE(buf != NULL);
   14138 	zone_name_tostr(zone, buf, length);
   14139 }
   14140 
   14141 void
   14142 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level,
   14143 	      const char *prefix, const char *fmt, va_list ap)
   14144 {
   14145 	char message[4096];
   14146 	const char *zstr;
   14147 
   14148 	if (!isc_log_wouldlog(dns_lctx, level)) {
   14149 		return;
   14150 	}
   14151 
   14152 	vsnprintf(message, sizeof(message), fmt, ap);
   14153 
   14154 	switch (zone->type) {
   14155 	case dns_zone_key:
   14156 		zstr = "managed-keys-zone";
   14157 		break;
   14158 	case dns_zone_redirect:
   14159 		zstr = "redirect-zone";
   14160 		break;
   14161 	default:
   14162 		zstr = "zone ";
   14163 	}
   14164 
   14165 	isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level,
   14166 		      "%s%s%s%s: %s",
   14167 		      (prefix != NULL ? prefix : ""),
   14168 		      (prefix != NULL ? ": " : ""),
   14169 		      zstr, zone->strnamerd, message);
   14170 }
   14171 
   14172 static void
   14173 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   14174 	va_list ap;
   14175 
   14176 	va_start(ap, fmt);
   14177 	dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap);
   14178 	va_end(ap);
   14179 }
   14180 
   14181 void
   14182 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
   14183 	      int level, const char *fmt, ...)
   14184 {
   14185 	va_list ap;
   14186 
   14187 	va_start(ap, fmt);
   14188 	dns_zone_logv(zone, category, level, NULL, fmt, ap);
   14189 	va_end(ap);
   14190 }
   14191 
   14192 void
   14193 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   14194 	va_list ap;
   14195 
   14196 	va_start(ap, fmt);
   14197 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap);
   14198 	va_end(ap);
   14199 }
   14200 
   14201 static void
   14202 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
   14203 	      const char *fmt, ...)
   14204 {
   14205 	int level = ISC_LOG_DEBUG(debuglevel);
   14206 	va_list ap;
   14207 
   14208 	va_start(ap, fmt);
   14209 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap);
   14210 	va_end(ap);
   14211 }
   14212 
   14213 static void
   14214 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   14215 	va_list ap;
   14216 
   14217 	va_start(ap, fmt);
   14218 	dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap);
   14219 	va_end(ap);
   14220 }
   14221 
   14222 static int
   14223 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
   14224 {
   14225 	isc_result_t result;
   14226 	dns_name_t *name;
   14227 	dns_rdataset_t *curr;
   14228 	int count = 0;
   14229 
   14230 	result = dns_message_firstname(msg, section);
   14231 	while (result == ISC_R_SUCCESS) {
   14232 		name = NULL;
   14233 		dns_message_currentname(msg, section, &name);
   14234 
   14235 		for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
   14236 		     curr = ISC_LIST_PREV(curr, link)) {
   14237 			if (curr->type == type)
   14238 				count++;
   14239 		}
   14240 		result = dns_message_nextname(msg, section);
   14241 	}
   14242 
   14243 	return (count);
   14244 }
   14245 
   14246 void
   14247 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
   14248 	REQUIRE(DNS_ZONE_VALID(zone));
   14249 
   14250 	zone->maxxfrin = maxxfrin;
   14251 }
   14252 
   14253 uint32_t
   14254 dns_zone_getmaxxfrin(dns_zone_t *zone) {
   14255 	REQUIRE(DNS_ZONE_VALID(zone));
   14256 
   14257 	return (zone->maxxfrin);
   14258 }
   14259 
   14260 void
   14261 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
   14262 	REQUIRE(DNS_ZONE_VALID(zone));
   14263 	zone->maxxfrout = maxxfrout;
   14264 }
   14265 
   14266 uint32_t
   14267 dns_zone_getmaxxfrout(dns_zone_t *zone) {
   14268 	REQUIRE(DNS_ZONE_VALID(zone));
   14269 
   14270 	return (zone->maxxfrout);
   14271 }
   14272 
   14273 dns_zonetype_t
   14274 dns_zone_gettype(dns_zone_t *zone) {
   14275 	REQUIRE(DNS_ZONE_VALID(zone));
   14276 
   14277 	return (zone->type);
   14278 }
   14279 
   14280 dns_zonetype_t
   14281 dns_zone_getredirecttype(dns_zone_t *zone) {
   14282 	REQUIRE(DNS_ZONE_VALID(zone));
   14283 	REQUIRE(zone->type == dns_zone_redirect);
   14284 
   14285 	return (zone->masters == NULL ? dns_zone_master : dns_zone_slave);
   14286 }
   14287 
   14288 dns_name_t *
   14289 dns_zone_getorigin(dns_zone_t *zone) {
   14290 	REQUIRE(DNS_ZONE_VALID(zone));
   14291 
   14292 	return (&zone->origin);
   14293 }
   14294 
   14295 void
   14296 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
   14297 	REQUIRE(DNS_ZONE_VALID(zone));
   14298 
   14299 	LOCK_ZONE(zone);
   14300 	if (zone->task != NULL)
   14301 		isc_task_detach(&zone->task);
   14302 	isc_task_attach(task, &zone->task);
   14303 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14304 	if (zone->db != NULL)
   14305 		dns_db_settask(zone->db, zone->task);
   14306 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14307 	UNLOCK_ZONE(zone);
   14308 }
   14309 
   14310 void
   14311 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
   14312 	REQUIRE(DNS_ZONE_VALID(zone));
   14313 	isc_task_attach(zone->task, target);
   14314 }
   14315 
   14316 void
   14317 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
   14318 	REQUIRE(DNS_ZONE_VALID(zone));
   14319 
   14320 	if (idlein == 0)
   14321 		idlein = DNS_DEFAULT_IDLEIN;
   14322 	zone->idlein = idlein;
   14323 }
   14324 
   14325 uint32_t
   14326 dns_zone_getidlein(dns_zone_t *zone) {
   14327 	REQUIRE(DNS_ZONE_VALID(zone));
   14328 
   14329 	return (zone->idlein);
   14330 }
   14331 
   14332 void
   14333 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
   14334 	REQUIRE(DNS_ZONE_VALID(zone));
   14335 
   14336 	zone->idleout = idleout;
   14337 }
   14338 
   14339 uint32_t
   14340 dns_zone_getidleout(dns_zone_t *zone) {
   14341 	REQUIRE(DNS_ZONE_VALID(zone));
   14342 
   14343 	return (zone->idleout);
   14344 }
   14345 
   14346 static void
   14347 notify_done(isc_task_t *task, isc_event_t *event) {
   14348 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   14349 	dns_notify_t *notify;
   14350 	isc_result_t result;
   14351 	dns_message_t *message = NULL;
   14352 	isc_buffer_t buf;
   14353 	char rcode[128];
   14354 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   14355 
   14356 	UNUSED(task);
   14357 
   14358 	notify = event->ev_arg;
   14359 	REQUIRE(DNS_NOTIFY_VALID(notify));
   14360 	INSIST(task == notify->zone->task);
   14361 
   14362 	isc_buffer_init(&buf, rcode, sizeof(rcode));
   14363 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   14364 
   14365 	result = revent->result;
   14366 	if (result == ISC_R_SUCCESS)
   14367 		result = dns_message_create(notify->zone->mctx,
   14368 					    DNS_MESSAGE_INTENTPARSE, &message);
   14369 	if (result == ISC_R_SUCCESS)
   14370 		result = dns_request_getresponse(revent->request, message,
   14371 					DNS_MESSAGEPARSE_PRESERVEORDER);
   14372 	if (result == ISC_R_SUCCESS)
   14373 		result = dns_rcode_totext(message->rcode, &buf);
   14374 	if (result == ISC_R_SUCCESS)
   14375 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   14376 			   "notify response from %s: %.*s",
   14377 			   addrbuf, (int)buf.used, rcode);
   14378 	else
   14379 		notify_log(notify->zone, ISC_LOG_DEBUG(2),
   14380 			   "notify to %s failed: %s", addrbuf,
   14381 			   dns_result_totext(result));
   14382 
   14383 	/*
   14384 	 * Old bind's return formerr if they see a soa record.	Retry w/o
   14385 	 * the soa if we see a formerr and had sent a SOA.
   14386 	 */
   14387 	isc_event_free(&event);
   14388 	if (message != NULL && message->rcode == dns_rcode_formerr &&
   14389 	    (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
   14390 		bool startup;
   14391 
   14392 		notify->flags |= DNS_NOTIFY_NOSOA;
   14393 		dns_request_destroy(&notify->request);
   14394 		startup = (notify->flags & DNS_NOTIFY_STARTUP);
   14395 		result = notify_send_queue(notify, startup);
   14396 		if (result != ISC_R_SUCCESS)
   14397 			notify_destroy(notify, false);
   14398 	} else {
   14399 		if (result == ISC_R_TIMEDOUT)
   14400 			notify_log(notify->zone, ISC_LOG_DEBUG(1),
   14401 				   "notify to %s: retries exceeded", addrbuf);
   14402 		notify_destroy(notify, false);
   14403 	}
   14404 	if (message != NULL)
   14405 		dns_message_destroy(&message);
   14406 }
   14407 
   14408 struct secure_event {
   14409 	isc_event_t e;
   14410 	dns_db_t *db;
   14411 	uint32_t serial;
   14412 };
   14413 
   14414 static void
   14415 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
   14416 	UNUSED(arg);
   14417 	dns_zone_log(zone, level, "%s", message);
   14418 }
   14419 
   14420 static isc_result_t
   14421 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
   14422 		    uint32_t start, uint32_t end,
   14423 		    dns_difftuple_t **soatuplep, dns_diff_t *diff)
   14424 {
   14425 	isc_result_t result;
   14426 	dns_difftuple_t *tuple = NULL;
   14427 	dns_diffop_t op = DNS_DIFFOP_ADD;
   14428 	int n_soa = 0;
   14429 
   14430 	REQUIRE(soatuplep != NULL);
   14431 
   14432 	if (start == end)
   14433 		return (DNS_R_UNCHANGED);
   14434 
   14435 	CHECK(dns_journal_iter_init(journal, start, end));
   14436 	for (result = dns_journal_first_rr(journal);
   14437 	     result == ISC_R_SUCCESS;
   14438 	     result = dns_journal_next_rr(journal))
   14439 	{
   14440 		dns_name_t *name = NULL;
   14441 		uint32_t ttl;
   14442 		dns_rdata_t *rdata = NULL;
   14443 		dns_journal_current_rr(journal, &name, &ttl, &rdata);
   14444 
   14445 		if (rdata->type == dns_rdatatype_soa) {
   14446 			n_soa++;
   14447 			if (n_soa == 2) {
   14448 				/*
   14449 				 * Save the latest raw SOA record.
   14450 				 */
   14451 				if (*soatuplep != NULL)
   14452 					dns_difftuple_free(soatuplep);
   14453 				CHECK(dns_difftuple_create(diff->mctx,
   14454 							   DNS_DIFFOP_ADD,
   14455 							   name, ttl, rdata,
   14456 							   soatuplep));
   14457 			}
   14458 			if (n_soa == 3)
   14459 				n_soa = 1;
   14460 			continue;
   14461 		}
   14462 
   14463 		/* Sanity. */
   14464 		if (n_soa == 0) {
   14465 			dns_zone_log(raw, ISC_LOG_ERROR,
   14466 				     "corrupt journal file: '%s'\n",
   14467 				     raw->journal);
   14468 			return (ISC_R_FAILURE);
   14469 		}
   14470 
   14471 		if (zone->privatetype != 0 &&
   14472 		    rdata->type == zone->privatetype)
   14473 			continue;
   14474 
   14475 		if (rdata->type == dns_rdatatype_nsec ||
   14476 		    rdata->type == dns_rdatatype_rrsig ||
   14477 		    rdata->type == dns_rdatatype_nsec3 ||
   14478 		    rdata->type == dns_rdatatype_dnskey ||
   14479 		    rdata->type == dns_rdatatype_nsec3param)
   14480 			continue;
   14481 
   14482 		op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
   14483 
   14484 		CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
   14485 					   &tuple));
   14486 		dns_diff_appendminimal(diff, &tuple);
   14487 	}
   14488 	if (result == ISC_R_NOMORE)
   14489 		result = ISC_R_SUCCESS;
   14490 
   14491  failure:
   14492 	return(result);
   14493 }
   14494 
   14495 static isc_result_t
   14496 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
   14497 	       dns_dbversion_t *secver, dns_difftuple_t **soatuple,
   14498 	       dns_diff_t *diff)
   14499 {
   14500 	isc_result_t result;
   14501 	dns_db_t *rawdb = NULL;
   14502 	dns_dbversion_t *rawver = NULL;
   14503 	dns_difftuple_t *tuple = NULL, *next;
   14504 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   14505 	dns_rdata_soa_t oldsoa, newsoa;
   14506 
   14507 	REQUIRE(DNS_ZONE_VALID(seczone));
   14508 	REQUIRE(soatuple != NULL && *soatuple == NULL);
   14509 
   14510 	if (!seczone->sourceserialset)
   14511 		return (DNS_R_UNCHANGED);
   14512 
   14513 	dns_db_attach(raw->db, &rawdb);
   14514 	dns_db_currentversion(rawdb, &rawver);
   14515 	result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
   14516 	dns_db_closeversion(rawdb, &rawver, false);
   14517 	dns_db_detach(&rawdb);
   14518 
   14519 	if (result != ISC_R_SUCCESS)
   14520 		return (result);
   14521 
   14522 	for (tuple = ISC_LIST_HEAD(diff->tuples);
   14523 	     tuple != NULL;
   14524 	     tuple = next)
   14525 	{
   14526 		next = ISC_LIST_NEXT(tuple, link);
   14527 		if (tuple->rdata.type == dns_rdatatype_nsec ||
   14528 		    tuple->rdata.type == dns_rdatatype_rrsig ||
   14529 		    tuple->rdata.type == dns_rdatatype_dnskey ||
   14530 		    tuple->rdata.type == dns_rdatatype_nsec3 ||
   14531 		    tuple->rdata.type == dns_rdatatype_nsec3param)
   14532 		{
   14533 			ISC_LIST_UNLINK(diff->tuples, tuple, link);
   14534 			dns_difftuple_free(&tuple);
   14535 			continue;
   14536 		}
   14537 		if (tuple->rdata.type == dns_rdatatype_soa) {
   14538 			if (tuple->op == DNS_DIFFOP_DEL) {
   14539 				INSIST(oldtuple == NULL);
   14540 				oldtuple = tuple;
   14541 			}
   14542 			if (tuple->op == DNS_DIFFOP_ADD) {
   14543 				INSIST(newtuple == NULL);
   14544 				newtuple = tuple;
   14545 			}
   14546 		}
   14547 	}
   14548 
   14549 	if (oldtuple != NULL && newtuple != NULL) {
   14550 
   14551 		result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
   14552 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14553 
   14554 		result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
   14555 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14556 
   14557 		/*
   14558 		 * If the SOA records are the same except for the serial
   14559 		 * remove them from the diff.
   14560 		 */
   14561 		if (oldsoa.refresh == newsoa.refresh &&
   14562 		    oldsoa.retry == newsoa.retry &&
   14563 		    oldsoa.minimum == newsoa.minimum &&
   14564 		    oldsoa.expire == newsoa.expire &&
   14565 		    dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
   14566 		    dns_name_equal(&oldsoa.contact, &newsoa.contact)) {
   14567 			ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   14568 			dns_difftuple_free(&oldtuple);
   14569 			ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   14570 			dns_difftuple_free(&newtuple);
   14571 		}
   14572 	}
   14573 
   14574 	if (ISC_LIST_EMPTY(diff->tuples))
   14575 		return (DNS_R_UNCHANGED);
   14576 
   14577 	/*
   14578 	 * If there are still SOA records in the diff they can now be removed
   14579 	 * saving the new SOA record.
   14580 	 */
   14581 	if (oldtuple != NULL) {
   14582 		ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   14583 		dns_difftuple_free(&oldtuple);
   14584 	}
   14585 
   14586 	if (newtuple != NULL) {
   14587 		ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   14588 		*soatuple = newtuple;
   14589 	}
   14590 
   14591 	return (ISC_R_SUCCESS);
   14592 }
   14593 
   14594 static void
   14595 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
   14596 	static char me[] = "receive_secure_serial";
   14597 	isc_result_t result = ISC_R_SUCCESS;
   14598 	dns_journal_t *rjournal = NULL;
   14599 	dns_journal_t *sjournal = NULL;
   14600 	uint32_t start, end;
   14601 	dns_zone_t *zone;
   14602 	dns_difftuple_t *tuple = NULL, *soatuple = NULL;
   14603 	dns_update_log_t log = { update_log_cb, NULL };
   14604 	uint32_t newserial = 0, desired = 0;
   14605 	isc_time_t timenow;
   14606 
   14607 	UNUSED(task);
   14608 
   14609 	zone = event->ev_arg;
   14610 	end = ((struct secure_event *)event)->serial;
   14611 
   14612 	ENTER;
   14613 
   14614 	LOCK_ZONE(zone);
   14615 
   14616 	/*
   14617 	 * If we are already processing a receive secure serial event
   14618 	 * for the zone, just queue the new one and exit.
   14619 	 */
   14620 	if (zone->rss_event != NULL && zone->rss_event != event) {
   14621 		ISC_LIST_APPEND(zone->rss_events, event, ev_link);
   14622 		UNLOCK_ZONE(zone);
   14623 		return;
   14624 	}
   14625 
   14626  nextevent:
   14627 	if (zone->rss_event != NULL) {
   14628 		INSIST(zone->rss_event == event);
   14629 		UNLOCK_ZONE(zone);
   14630 	} else {
   14631 		zone->rss_event = event;
   14632 		dns_diff_init(zone->mctx, &zone->rss_diff);
   14633 
   14634 		/*
   14635 		 * zone->db may be NULL, if the load from disk failed.
   14636 		 */
   14637 		result = ISC_R_SUCCESS;
   14638 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14639 		if (zone->db != NULL)
   14640 			dns_db_attach(zone->db, &zone->rss_db);
   14641 		else
   14642 			result = ISC_R_FAILURE;
   14643 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14644 
   14645 		if (result == ISC_R_SUCCESS && zone->raw != NULL)
   14646 			dns_zone_attach(zone->raw, &zone->rss_raw);
   14647 		else
   14648 			result = ISC_R_FAILURE;
   14649 
   14650 		UNLOCK_ZONE(zone);
   14651 
   14652 		CHECK(result);
   14653 
   14654 		/*
   14655 		 * We first attempt to sync the raw zone to the secure zone
   14656 		 * by using the raw zone's journal, applying all the deltas
   14657 		 * from the latest source-serial of the secure zone up to
   14658 		 * the current serial number of the raw zone.
   14659 		 *
   14660 		 * If that fails, then we'll fall back to a direct comparison
   14661 		 * between raw and secure zones.
   14662 		 */
   14663 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   14664 				       zone->rss_raw->journal,
   14665 				       DNS_JOURNAL_WRITE, &rjournal));
   14666 
   14667 		result = dns_journal_open(zone->mctx, zone->journal,
   14668 					  DNS_JOURNAL_READ, &sjournal);
   14669 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
   14670 			goto failure;
   14671 
   14672 		if (!dns_journal_get_sourceserial(rjournal, &start)) {
   14673 			start = dns_journal_first_serial(rjournal);
   14674 			dns_journal_set_sourceserial(rjournal, start);
   14675 		}
   14676 		if (sjournal != NULL) {
   14677 			uint32_t serial;
   14678 			/*
   14679 			 * We read the secure journal first, if that
   14680 			 * exists use its value provided it is greater
   14681 			 * that from the raw journal.
   14682 			 */
   14683 			if (dns_journal_get_sourceserial(sjournal, &serial)) {
   14684 				if (isc_serial_gt(serial, start))
   14685 					start = serial;
   14686 			}
   14687 			dns_journal_destroy(&sjournal);
   14688 		}
   14689 
   14690 		dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
   14691 		CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
   14692 
   14693 		/*
   14694 		 * Try to apply diffs from the raw zone's journal to the secure
   14695 		 * zone.  If that fails, we recover by syncing up the databases
   14696 		 * directly.
   14697 		 */
   14698 		result = sync_secure_journal(zone, zone->rss_raw, rjournal,
   14699 					     start, end, &soatuple,
   14700 					     &zone->rss_diff);
   14701 		if (result == DNS_R_UNCHANGED)
   14702 			goto failure;
   14703 		else if (result != ISC_R_SUCCESS)
   14704 			CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
   14705 					     zone->rss_oldver, &soatuple,
   14706 					     &zone->rss_diff));
   14707 
   14708 		CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
   14709 				     zone->rss_newver));
   14710 
   14711 		if (soatuple != NULL) {
   14712 			uint32_t oldserial;
   14713 
   14714 			CHECK(dns_db_createsoatuple(zone->rss_db,
   14715 						    zone->rss_oldver,
   14716 						    zone->rss_diff.mctx,
   14717 						    DNS_DIFFOP_DEL, &tuple));
   14718 			oldserial = dns_soa_getserial(&tuple->rdata);
   14719 			newserial = desired =
   14720 				    dns_soa_getserial(&soatuple->rdata);
   14721 			if (!isc_serial_gt(newserial, oldserial)) {
   14722 				newserial = oldserial + 1;
   14723 				if (newserial == 0)
   14724 					newserial++;
   14725 				dns_soa_setserial(newserial, &soatuple->rdata);
   14726 			}
   14727 			CHECK(do_one_tuple(&tuple, zone->rss_db,
   14728 					   zone->rss_newver, &zone->rss_diff));
   14729 			CHECK(do_one_tuple(&soatuple, zone->rss_db,
   14730 					   zone->rss_newver, &zone->rss_diff));
   14731 		} else
   14732 			CHECK(update_soa_serial(zone->rss_db, zone->rss_newver,
   14733 						&zone->rss_diff, zone->mctx,
   14734 						zone->updatemethod));
   14735 
   14736 	}
   14737 	result = dns_update_signaturesinc(&log, zone, zone->rss_db,
   14738 					  zone->rss_oldver, zone->rss_newver,
   14739 					  &zone->rss_diff,
   14740 					  zone->sigvalidityinterval,
   14741 					  &zone->rss_state);
   14742 	if (result == DNS_R_CONTINUE) {
   14743 		if (rjournal != NULL)
   14744 			dns_journal_destroy(&rjournal);
   14745 		isc_task_send(task, &event);
   14746 		return;
   14747 	}
   14748 	/*
   14749 	 * If something went wrong while trying to update the secure zone and
   14750 	 * the latter was already signed before, do not apply raw zone deltas
   14751 	 * to it as that would break existing DNSSEC signatures.  However, if
   14752 	 * the secure zone was not yet signed (e.g. because no signing keys
   14753 	 * were created for it), commence applying raw zone deltas to it so
   14754 	 * that contents of the raw zone and the secure zone are kept in sync.
   14755 	 */
   14756 	if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
   14757 		goto failure;
   14758 	}
   14759 
   14760 	if (rjournal == NULL)
   14761 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   14762 				       zone->rss_raw->journal,
   14763 				       DNS_JOURNAL_WRITE, &rjournal));
   14764 	CHECK(zone_journal(zone, &zone->rss_diff, &end,
   14765 			   "receive_secure_serial"));
   14766 
   14767 	dns_journal_set_sourceserial(rjournal, end);
   14768 	dns_journal_commit(rjournal);
   14769 
   14770 	LOCK_ZONE(zone);
   14771 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   14772 
   14773 	zone->sourceserial = end;
   14774 	zone->sourceserialset = true;
   14775 	zone_needdump(zone, DNS_DUMP_DELAY);
   14776 
   14777 	TIME_NOW(&timenow);
   14778 	zone_settimer(zone, &timenow);
   14779 	UNLOCK_ZONE(zone);
   14780 
   14781 	dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false);
   14782 	dns_db_closeversion(zone->rss_db, &zone->rss_newver, true);
   14783 
   14784 	if (newserial != 0) {
   14785 		dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
   14786 			     newserial, desired);
   14787 	}
   14788 
   14789  failure:
   14790 	isc_event_free(&zone->rss_event);
   14791 	event = ISC_LIST_HEAD(zone->rss_events);
   14792 
   14793 	if (zone->rss_raw != NULL)
   14794 		dns_zone_detach(&zone->rss_raw);
   14795 	if (result != ISC_R_SUCCESS)
   14796 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_serial: %s",
   14797 			     dns_result_totext(result));
   14798 	if (tuple != NULL)
   14799 		dns_difftuple_free(&tuple);
   14800 	if (soatuple != NULL)
   14801 		dns_difftuple_free(&soatuple);
   14802 	if (zone->rss_db != NULL) {
   14803 		if (zone->rss_oldver != NULL)
   14804 			dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
   14805 					    false);
   14806 		if (zone->rss_newver != NULL)
   14807 			dns_db_closeversion(zone->rss_db, &zone->rss_newver,
   14808 					    false);
   14809 		dns_db_detach(&zone->rss_db);
   14810 	}
   14811 	INSIST(zone->rss_oldver == NULL);
   14812 	INSIST(zone->rss_newver == NULL);
   14813 	if (rjournal != NULL)
   14814 		dns_journal_destroy(&rjournal);
   14815 	dns_diff_clear(&zone->rss_diff);
   14816 
   14817 	if (event != NULL) {
   14818 		LOCK_ZONE(zone);
   14819 		INSIST(zone->irefs > 1);
   14820 		zone->irefs--;
   14821 		ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
   14822 		goto nextevent;
   14823 	}
   14824 	dns_zone_idetach(&zone);
   14825 }
   14826 
   14827 static isc_result_t
   14828 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) {
   14829 	isc_event_t *e;
   14830 	dns_zone_t *dummy = NULL;
   14831 
   14832 	e = isc_event_allocate(zone->secure->mctx, zone,
   14833 			       DNS_EVENT_ZONESECURESERIAL,
   14834 			       receive_secure_serial, zone->secure,
   14835 			       sizeof(struct secure_event));
   14836 	if (e == NULL)
   14837 		return (ISC_R_NOMEMORY);
   14838 	((struct secure_event *)e)->serial = serial;
   14839 	INSIST(LOCKED_ZONE(zone->secure));
   14840 	zone_iattach(zone->secure, &dummy);
   14841 	isc_task_send(zone->secure->task, &e);
   14842 
   14843 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   14844 	return (ISC_R_SUCCESS);
   14845 }
   14846 
   14847 static isc_result_t
   14848 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   14849 	       dns_rdataset_t *rdataset, uint32_t oldserial)
   14850 {
   14851 	dns_rdata_soa_t soa;
   14852 	dns_rdata_t rdata = DNS_RDATA_INIT;
   14853 	dns_rdatalist_t temprdatalist;
   14854 	dns_rdataset_t temprdataset;
   14855 	isc_buffer_t b;
   14856 	isc_result_t result;
   14857 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   14858 	dns_fixedname_t fixed;
   14859 	dns_name_t *name;
   14860 
   14861 	result = dns_rdataset_first(rdataset);
   14862 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14863 	dns_rdataset_current(rdataset, &rdata);
   14864 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   14865 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14866 
   14867 	if (isc_serial_gt(soa.serial, oldserial))
   14868 		return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
   14869 					   NULL));
   14870 	/*
   14871 	 * Always bump the serial.
   14872 	 */
   14873 	oldserial++;
   14874 	if (oldserial == 0)
   14875 		oldserial++;
   14876 	soa.serial = oldserial;
   14877 
   14878 	/*
   14879 	 * Construct a replacement rdataset.
   14880 	 */
   14881 	dns_rdata_reset(&rdata);
   14882 	isc_buffer_init(&b, buf, sizeof(buf));
   14883 	result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
   14884 				      dns_rdatatype_soa, &soa, &b);
   14885 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14886 	dns_rdatalist_init(&temprdatalist);
   14887 	temprdatalist.rdclass = rdata.rdclass;
   14888 	temprdatalist.type = rdata.type;
   14889 	temprdatalist.ttl = rdataset->ttl;
   14890 	ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
   14891 
   14892 	dns_rdataset_init(&temprdataset);
   14893 	result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
   14894 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14895 
   14896 	name = dns_fixedname_initname(&fixed);
   14897 	result = dns_db_nodefullname(db, node, name);
   14898 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14899 	dns_rdataset_getownercase(rdataset, name);
   14900 	dns_rdataset_setownercase(&temprdataset, name);
   14901 	return (dns_db_addrdataset(db, node, version, 0, &temprdataset,
   14902 				   0, NULL));
   14903 }
   14904 
   14905 /*
   14906  * This function should populate an nsec3paramlist_t with the
   14907  * nsecparam_t data from a zone.
   14908  */
   14909 static isc_result_t
   14910 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
   14911 	isc_result_t result;
   14912 	dns_dbnode_t *node = NULL;
   14913 	dns_rdataset_t rdataset, prdataset;
   14914 	dns_dbversion_t *version = NULL;
   14915 	nsec3param_t *nsec3param = NULL;
   14916 	nsec3param_t *nsec3p = NULL;
   14917 	nsec3param_t *next;
   14918 	dns_db_t *db = NULL;
   14919 	unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   14920 
   14921 	REQUIRE(DNS_ZONE_VALID(zone));
   14922 	REQUIRE(nsec3list != NULL);
   14923 	REQUIRE(ISC_LIST_EMPTY(*nsec3list));
   14924 
   14925 	dns_rdataset_init(&rdataset);
   14926 	dns_rdataset_init(&prdataset);
   14927 
   14928 	dns_db_attach(zone->db, &db);
   14929 	CHECK(dns_db_getoriginnode(db, &node));
   14930 
   14931 	dns_db_currentversion(db, &version);
   14932 	result = dns_db_findrdataset(db, node, version,
   14933 				     dns_rdatatype_nsec3param,
   14934 				     dns_rdatatype_none, 0, &rdataset, NULL);
   14935 
   14936 	if (result != ISC_R_SUCCESS)
   14937 		goto getprivate;
   14938 
   14939 	/*
   14940 	 * walk nsec3param rdataset making a list of parameters (note that
   14941 	 * multiple simultaneous nsec3 chains are annoyingly legal -- this
   14942 	 * is why we use an nsec3list, even tho we will usually only have
   14943 	 * one)
   14944 	 */
   14945 	for (result = dns_rdataset_first(&rdataset);
   14946 	     result == ISC_R_SUCCESS;
   14947 	     result = dns_rdataset_next(&rdataset))
   14948 	{
   14949 		dns_rdata_t rdata = DNS_RDATA_INIT;
   14950 		dns_rdata_t private = DNS_RDATA_INIT;
   14951 
   14952 		dns_rdataset_current(&rdataset, &rdata);
   14953 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   14954 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   14955 			      "looping through nsec3param data");
   14956 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   14957 		if (nsec3param == NULL)
   14958 			CHECK(ISC_R_NOMEMORY);
   14959 		ISC_LINK_INIT(nsec3param, link);
   14960 
   14961 		/*
   14962 		 * now transfer the data from the rdata to
   14963 		 * the nsec3param
   14964 		 */
   14965 		dns_nsec3param_toprivate(&rdata, &private,
   14966 					 zone->privatetype, nsec3param->data,
   14967 					 sizeof(nsec3param->data));
   14968 		nsec3param->length = private.length;
   14969 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   14970 	}
   14971 
   14972  getprivate:
   14973 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   14974 				     dns_rdatatype_none, 0, &prdataset, NULL);
   14975 	if (result != ISC_R_SUCCESS)
   14976 		goto done;
   14977 
   14978 	/*
   14979 	 * walk private type records, converting them to nsec3 parameters
   14980 	 * using dns_nsec3param_fromprivate(), do the right thing based on
   14981 	 * CREATE and REMOVE flags
   14982 	 */
   14983 	for (result = dns_rdataset_first(&prdataset);
   14984 	     result == ISC_R_SUCCESS;
   14985 	     result = dns_rdataset_next(&prdataset))
   14986 	{
   14987 		dns_rdata_t rdata = DNS_RDATA_INIT;
   14988 		dns_rdata_t private = DNS_RDATA_INIT;
   14989 
   14990 		dns_rdataset_current(&prdataset, &private);
   14991 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   14992 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   14993 			      "looping through nsec3param private data");
   14994 
   14995 		/*
   14996 		 * Do we have a valid private record?
   14997 		 */
   14998 		if (!dns_nsec3param_fromprivate(&private, &rdata,
   14999 						buf, sizeof(buf)))
   15000 			continue;
   15001 
   15002 		/*
   15003 		 * Remove any NSEC3PARAM records scheduled to be removed.
   15004 		 */
   15005 		if (NSEC3REMOVE(rdata.data[1])) {
   15006 			/*
   15007 			 * Zero out the flags.
   15008 			 */
   15009 			rdata.data[1] = 0;
   15010 
   15011 			for (nsec3p = ISC_LIST_HEAD(*nsec3list);
   15012 			     nsec3p != NULL;
   15013 			     nsec3p = next)
   15014 			{
   15015 				next = ISC_LIST_NEXT(nsec3p, link);
   15016 
   15017 				if (nsec3p->length == rdata.length + 1 &&
   15018 				    memcmp(rdata.data, nsec3p->data + 1,
   15019 					   nsec3p->length - 1) == 0) {
   15020 					ISC_LIST_UNLINK(*nsec3list,
   15021 							nsec3p, link);
   15022 					isc_mem_put(zone->mctx, nsec3p,
   15023 						    sizeof(nsec3param_t));
   15024 				}
   15025 			}
   15026 			continue;
   15027 		}
   15028 
   15029 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   15030 		if (nsec3param == NULL)
   15031 			CHECK(ISC_R_NOMEMORY);
   15032 		ISC_LINK_INIT(nsec3param, link);
   15033 
   15034 		/*
   15035 		 * Copy the remaining private records so the nsec/nsec3
   15036 		 * chain gets created.
   15037 		 */
   15038 		INSIST(private.length <= sizeof(nsec3param->data));
   15039 		memmove(nsec3param->data, private.data, private.length);
   15040 		nsec3param->length = private.length;
   15041 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   15042 	}
   15043 
   15044  done:
   15045 	if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND)
   15046 		result = ISC_R_SUCCESS;
   15047 
   15048  failure:
   15049 	if (node != NULL)
   15050 		dns_db_detachnode(db, &node);
   15051 	if (version != NULL)
   15052 		dns_db_closeversion(db, &version, false);
   15053 	if (db != NULL)
   15054 		dns_db_detach(&db);
   15055 	if (dns_rdataset_isassociated(&rdataset))
   15056 		dns_rdataset_disassociate(&rdataset);
   15057 	if (dns_rdataset_isassociated(&prdataset))
   15058 		dns_rdataset_disassociate(&prdataset);
   15059 	return (result);
   15060 }
   15061 
   15062 /*
   15063  * Populate new zone db with private type records found by save_nsec3param().
   15064  */
   15065 static isc_result_t
   15066 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   15067 		   nsec3paramlist_t *nsec3list)
   15068 {
   15069 	isc_result_t result;
   15070 	dns_diff_t diff;
   15071 	dns_rdata_t rdata;
   15072 	nsec3param_t *nsec3p = NULL;
   15073 	nsec3param_t *next;
   15074 
   15075 	REQUIRE(DNS_ZONE_VALID(zone));
   15076 	REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
   15077 
   15078 	dns_diff_init(zone->mctx, &diff);
   15079 
   15080 	/*
   15081 	 * Loop through the list of private-type records, set the INITIAL
   15082 	 * and CREATE flags, and the add the record to the apex of the tree
   15083 	 * in db.
   15084 	 */
   15085 	for (nsec3p = ISC_LIST_HEAD(*nsec3list);
   15086 	     nsec3p != NULL;
   15087 	     nsec3p = next)
   15088 	{
   15089 		next = ISC_LIST_NEXT(nsec3p, link);
   15090 		dns_rdata_init(&rdata);
   15091 		nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
   15092 		rdata.length = nsec3p->length;
   15093 		rdata.data = nsec3p->data;
   15094 		rdata.type = zone->privatetype;
   15095 		rdata.rdclass = zone->rdclass;
   15096 		result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
   15097 				       &zone->origin, 0, &rdata);
   15098 		if (result != ISC_R_SUCCESS) {
   15099 			break;
   15100 		}
   15101 	}
   15102 
   15103 	dns_diff_clear(&diff);
   15104 	return (result);
   15105 }
   15106 
   15107 static void
   15108 receive_secure_db(isc_task_t *task, isc_event_t *event) {
   15109 	isc_result_t result;
   15110 	dns_zone_t *zone;
   15111 	dns_db_t *rawdb, *db = NULL;
   15112 	dns_dbnode_t *rawnode = NULL, *node = NULL;
   15113 	dns_fixedname_t fname;
   15114 	dns_name_t *name;
   15115 	dns_dbiterator_t *dbiterator = NULL;
   15116 	dns_rdatasetiter_t *rdsit = NULL;
   15117 	dns_rdataset_t rdataset;
   15118 	dns_dbversion_t *version = NULL;
   15119 	isc_time_t loadtime;
   15120 	unsigned int oldserial = 0;
   15121 	bool have_oldserial = false;
   15122 	nsec3paramlist_t nsec3list;
   15123 	isc_event_t *setnsec3param_event;
   15124 	dns_zone_t *dummy;
   15125 
   15126 	UNUSED(task);
   15127 
   15128 	ISC_LIST_INIT(nsec3list);
   15129 
   15130 	zone = event->ev_arg;
   15131 	rawdb = ((struct secure_event *)event)->db;
   15132 	isc_event_free(&event);
   15133 
   15134 	name = dns_fixedname_initname(&fname);
   15135 	dns_rdataset_init(&rdataset);
   15136 
   15137 	LOCK_ZONE(zone);
   15138 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
   15139 		result = ISC_R_SHUTTINGDOWN;
   15140 		goto failure;
   15141 	}
   15142 
   15143 	TIME_NOW(&loadtime);
   15144 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   15145 	if (zone->db != NULL) {
   15146 		result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
   15147 		if (result == ISC_R_SUCCESS)
   15148 			have_oldserial = true;
   15149 
   15150 		/*
   15151 		 * assemble nsec3parameters from the old zone, and set a flag
   15152 		 * if any are found
   15153 		 */
   15154 		result = save_nsec3param(zone, &nsec3list);
   15155 		if (result != ISC_R_SUCCESS) {
   15156 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15157 			goto failure;
   15158 		}
   15159 	}
   15160 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15161 
   15162 	result = dns_db_create(zone->mctx, zone->db_argv[0],
   15163 			       &zone->origin, dns_dbtype_zone, zone->rdclass,
   15164 			       zone->db_argc - 1, zone->db_argv + 1, &db);
   15165 	if (result != ISC_R_SUCCESS)
   15166 		goto failure;
   15167 
   15168 	result = dns_db_setgluecachestats(db, zone->gluecachestats);
   15169 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
   15170 		goto failure;
   15171 	}
   15172 
   15173 	result = dns_db_newversion(db, &version);
   15174 	if (result != ISC_R_SUCCESS)
   15175 		goto failure;
   15176 
   15177 	result = dns_db_createiterator(rawdb, 0, &dbiterator);
   15178 	if (result != ISC_R_SUCCESS)
   15179 		goto failure;
   15180 
   15181 	for (result = dns_dbiterator_first(dbiterator);
   15182 	     result == ISC_R_SUCCESS;
   15183 	     result = dns_dbiterator_next(dbiterator)) {
   15184 		result = dns_dbiterator_current(dbiterator, &rawnode, name);
   15185 		if (result != ISC_R_SUCCESS)
   15186 			continue;
   15187 
   15188 		result = dns_db_findnode(db, name, true, &node);
   15189 		if (result != ISC_R_SUCCESS)
   15190 			goto failure;
   15191 
   15192 		result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
   15193 		if (result != ISC_R_SUCCESS)
   15194 			goto failure;
   15195 
   15196 		for (result = dns_rdatasetiter_first(rdsit);
   15197 		     result == ISC_R_SUCCESS;
   15198 		     result = dns_rdatasetiter_next(rdsit)) {
   15199 			dns_rdatasetiter_current(rdsit, &rdataset);
   15200 			if (rdataset.type == dns_rdatatype_nsec ||
   15201 			    rdataset.type == dns_rdatatype_rrsig ||
   15202 			    rdataset.type == dns_rdatatype_nsec3 ||
   15203 			    rdataset.type == dns_rdatatype_dnskey ||
   15204 			    rdataset.type == dns_rdatatype_nsec3param) {
   15205 				dns_rdataset_disassociate(&rdataset);
   15206 				continue;
   15207 			}
   15208 			if (rdataset.type == dns_rdatatype_soa &&
   15209 			    have_oldserial) {
   15210 				result = checkandaddsoa(db, node, version,
   15211 							&rdataset, oldserial);
   15212 			} else
   15213 				result = dns_db_addrdataset(db, node, version,
   15214 							    0, &rdataset, 0,
   15215 							    NULL);
   15216 			if (result != ISC_R_SUCCESS)
   15217 				goto failure;
   15218 
   15219 			dns_rdataset_disassociate(&rdataset);
   15220 		}
   15221 		dns_rdatasetiter_destroy(&rdsit);
   15222 		dns_db_detachnode(rawdb, &rawnode);
   15223 		dns_db_detachnode(db, &node);
   15224 	}
   15225 
   15226 	/*
   15227 	 * Call restore_nsec3param() to create private-type records from
   15228 	 * the old nsec3 parameters and insert them into db
   15229 	 */
   15230 	if (!ISC_LIST_EMPTY(nsec3list)) {
   15231 		result = restore_nsec3param(zone, db, version, &nsec3list);
   15232 		if (result != ISC_R_SUCCESS) {
   15233 			goto failure;
   15234 		}
   15235 	}
   15236 
   15237 	dns_db_closeversion(db, &version, true);
   15238 
   15239 	/*
   15240 	 * Lock hierarchy: zmgr, zone, raw.
   15241 	 */
   15242 	INSIST(zone != zone->raw);
   15243 	LOCK_ZONE(zone->raw);
   15244 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   15245 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   15246 	zone_needdump(zone, 0); /* XXXMPA */
   15247 	UNLOCK_ZONE(zone->raw);
   15248 
   15249 	/*
   15250 	 * Process any queued NSEC3PARAM change requests.
   15251 	 */
   15252 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   15253 		setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   15254 		ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
   15255 				ev_link);
   15256 		dummy = NULL;
   15257 		zone_iattach(zone, &dummy);
   15258 		isc_task_send(zone->task, &setnsec3param_event);
   15259 	}
   15260 
   15261  failure:
   15262 	UNLOCK_ZONE(zone);
   15263 	if (result != ISC_R_SUCCESS)
   15264 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
   15265 			     dns_result_totext(result));
   15266 
   15267 	while (!ISC_LIST_EMPTY(nsec3list)) {
   15268 		nsec3param_t *nsec3p;
   15269 		nsec3p = ISC_LIST_HEAD(nsec3list);
   15270 		ISC_LIST_UNLINK(nsec3list, nsec3p, link);
   15271 		isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
   15272 	}
   15273 	if (dns_rdataset_isassociated(&rdataset))
   15274 		dns_rdataset_disassociate(&rdataset);
   15275 	if (db != NULL) {
   15276 		if (node != NULL)
   15277 			dns_db_detachnode(db, &node);
   15278 		if (version != NULL)
   15279 			dns_db_closeversion(db, &version, false);
   15280 		dns_db_detach(&db);
   15281 	}
   15282 	if (rawnode != NULL)
   15283 		dns_db_detachnode(rawdb, &rawnode);
   15284 	dns_db_detach(&rawdb);
   15285 	if (dbiterator != NULL)
   15286 		dns_dbiterator_destroy(&dbiterator);
   15287 	dns_zone_idetach(&zone);
   15288 
   15289 	INSIST(version == NULL);
   15290 }
   15291 
   15292 static isc_result_t
   15293 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
   15294 	isc_event_t *e;
   15295 	dns_db_t *dummy = NULL;
   15296 	dns_zone_t *secure = NULL;
   15297 
   15298 	e = isc_event_allocate(zone->secure->mctx, zone,
   15299 			       DNS_EVENT_ZONESECUREDB,
   15300 			       receive_secure_db, zone->secure,
   15301 			       sizeof(struct secure_event));
   15302 	if (e == NULL)
   15303 		return (ISC_R_NOMEMORY);
   15304 	dns_db_attach(db, &dummy);
   15305 	((struct secure_event *)e)->db = dummy;
   15306 	INSIST(LOCKED_ZONE(zone->secure));
   15307 	zone_iattach(zone->secure, &secure);
   15308 	isc_task_send(zone->secure->task, &e);
   15309 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   15310 	return (ISC_R_SUCCESS);
   15311 }
   15312 
   15313 isc_result_t
   15314 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   15315 	isc_result_t result;
   15316 	dns_zone_t *secure = NULL;
   15317 
   15318 	REQUIRE(DNS_ZONE_VALID(zone));
   15319  again:
   15320 	LOCK_ZONE(zone);
   15321 	if (inline_raw(zone)) {
   15322 		secure = zone->secure;
   15323 		INSIST(secure != zone);
   15324 		TRYLOCK_ZONE(result, secure);
   15325 		if (result != ISC_R_SUCCESS) {
   15326 			UNLOCK_ZONE(zone);
   15327 			secure = NULL;
   15328 			isc_thread_yield();
   15329 			goto again;
   15330 		}
   15331 	}
   15332 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   15333 	result = zone_replacedb(zone, db, dump);
   15334 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   15335 	if (secure != NULL)
   15336 		UNLOCK_ZONE(secure);
   15337 	UNLOCK_ZONE(zone);
   15338 	return (result);
   15339 }
   15340 
   15341 static isc_result_t
   15342 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   15343 	dns_dbversion_t *ver;
   15344 	isc_result_t result;
   15345 	unsigned int soacount = 0;
   15346 	unsigned int nscount = 0;
   15347 
   15348 	/*
   15349 	 * 'zone' and 'zone->db' locked by caller.
   15350 	 */
   15351 	REQUIRE(DNS_ZONE_VALID(zone));
   15352 	REQUIRE(LOCKED_ZONE(zone));
   15353 	if (inline_raw(zone))
   15354 		REQUIRE(LOCKED_ZONE(zone->secure));
   15355 
   15356 	result = zone_get_from_db(zone, db, &nscount, &soacount,
   15357 				  NULL, NULL, NULL, NULL, NULL, NULL);
   15358 	if (result == ISC_R_SUCCESS) {
   15359 		if (soacount != 1) {
   15360 			dns_zone_log(zone, ISC_LOG_ERROR,
   15361 				     "has %d SOA records", soacount);
   15362 			result = DNS_R_BADZONE;
   15363 		}
   15364 		if (nscount == 0 && zone->type != dns_zone_key) {
   15365 			dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
   15366 			result = DNS_R_BADZONE;
   15367 		}
   15368 		if (result != ISC_R_SUCCESS)
   15369 			return (result);
   15370 	} else {
   15371 		dns_zone_log(zone, ISC_LOG_ERROR,
   15372 			    "retrieving SOA and NS records failed: %s",
   15373 			    dns_result_totext(result));
   15374 		return (result);
   15375 	}
   15376 
   15377 	result = check_nsec3param(zone, db);
   15378 	if (result != ISC_R_SUCCESS)
   15379 		return (result);
   15380 
   15381 	ver = NULL;
   15382 	dns_db_currentversion(db, &ver);
   15383 
   15384 	/*
   15385 	 * The initial version of a slave zone is always dumped;
   15386 	 * subsequent versions may be journaled instead if this
   15387 	 * is enabled in the configuration.
   15388 	 */
   15389 	if (zone->db != NULL && zone->journal != NULL &&
   15390 	    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   15391 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
   15392 	{
   15393 		uint32_t serial, oldserial;
   15394 
   15395 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
   15396 
   15397 		result = dns_db_getsoaserial(db, ver, &serial);
   15398 		if (result != ISC_R_SUCCESS) {
   15399 			dns_zone_log(zone, ISC_LOG_ERROR,
   15400 				     "ixfr-from-differences: unable to get "
   15401 				     "new serial");
   15402 			goto fail;
   15403 		}
   15404 
   15405 		/*
   15406 		 * This is checked in zone_postload() for master zones.
   15407 		 */
   15408 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
   15409 					  &oldserial, NULL, NULL, NULL, NULL,
   15410 					  NULL);
   15411 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15412 		RUNTIME_CHECK(soacount > 0U);
   15413 		if ((zone->type == dns_zone_slave ||
   15414 		     (zone->type == dns_zone_redirect &&
   15415 		      zone->masters != NULL))
   15416 		    && !isc_serial_gt(serial, oldserial)) {
   15417 			uint32_t serialmin, serialmax;
   15418 			serialmin = (oldserial + 1) & 0xffffffffU;
   15419 			serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
   15420 			dns_zone_log(zone, ISC_LOG_ERROR,
   15421 				     "ixfr-from-differences: failed: "
   15422 				     "new serial (%u) out of range [%u - %u]",
   15423 				     serial, serialmin, serialmax);
   15424 			result = ISC_R_RANGE;
   15425 			goto fail;
   15426 		}
   15427 
   15428 		result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
   15429 				     zone->journal);
   15430 		if (result != ISC_R_SUCCESS) {
   15431 			char strbuf[ISC_STRERRORSIZE];
   15432 			strerror_r(errno, strbuf, sizeof(strbuf));
   15433 			dns_zone_log(zone, ISC_LOG_ERROR,
   15434 				     "ixfr-from-differences: failed: "
   15435 				     "%s", strbuf);
   15436 			goto fallback;
   15437 		}
   15438 		if (dump)
   15439 			zone_needdump(zone, DNS_DUMP_DELAY);
   15440 		else
   15441 			zone_journal_compact(zone, zone->db, serial);
   15442 		if (zone->type == dns_zone_master && inline_raw(zone))
   15443 			zone_send_secureserial(zone, serial);
   15444 	} else {
   15445  fallback:
   15446 		if (dump && zone->masterfile != NULL) {
   15447 			/*
   15448 			 * If DNS_ZONEFLG_FORCEXFER was set we don't want
   15449 			 * to keep the old masterfile.
   15450 			 */
   15451 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
   15452 			    remove(zone->masterfile) < 0 && errno != ENOENT) {
   15453 				char strbuf[ISC_STRERRORSIZE];
   15454 				strerror_r(errno, strbuf, sizeof(strbuf));
   15455 				isc_log_write(dns_lctx,
   15456 					      DNS_LOGCATEGORY_GENERAL,
   15457 					      DNS_LOGMODULE_ZONE,
   15458 					      ISC_LOG_WARNING,
   15459 					      "unable to remove masterfile "
   15460 					      "'%s': '%s'",
   15461 					      zone->masterfile, strbuf);
   15462 			}
   15463 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
   15464 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
   15465 			else
   15466 				zone_needdump(zone, 0);
   15467 		}
   15468 		if (dump && zone->journal != NULL) {
   15469 			/*
   15470 			 * The in-memory database just changed, and
   15471 			 * because 'dump' is set, it didn't change by
   15472 			 * being loaded from disk.  Also, we have not
   15473 			 * journaled diffs for this change.
   15474 			 * Therefore, the on-disk journal is missing
   15475 			 * the deltas for this change.	Since it can
   15476 			 * no longer be used to bring the zone
   15477 			 * up-to-date, it is useless and should be
   15478 			 * removed.
   15479 			 */
   15480 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   15481 				      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   15482 				      "removing journal file");
   15483 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   15484 				char strbuf[ISC_STRERRORSIZE];
   15485 				strerror_r(errno, strbuf, sizeof(strbuf));
   15486 				isc_log_write(dns_lctx,
   15487 					      DNS_LOGCATEGORY_GENERAL,
   15488 					      DNS_LOGMODULE_ZONE,
   15489 					      ISC_LOG_WARNING,
   15490 					      "unable to remove journal "
   15491 					      "'%s': '%s'",
   15492 					      zone->journal, strbuf);
   15493 			}
   15494 		}
   15495 
   15496 		if (inline_raw(zone))
   15497 			zone_send_securedb(zone, db);
   15498 	}
   15499 
   15500 	dns_db_closeversion(db, &ver, false);
   15501 
   15502 	dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
   15503 
   15504 	if (zone->db != NULL)
   15505 		zone_detachdb(zone);
   15506 	zone_attachdb(zone, db);
   15507 	dns_db_settask(zone->db, zone->task);
   15508 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
   15509 	return (ISC_R_SUCCESS);
   15510 
   15511  fail:
   15512 	dns_db_closeversion(db, &ver, false);
   15513 	return (result);
   15514 }
   15515 
   15516 /* The caller must hold the dblock as a writer. */
   15517 static inline void
   15518 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
   15519 	REQUIRE(zone->db == NULL && db != NULL);
   15520 
   15521 	dns_db_attach(db, &zone->db);
   15522 }
   15523 
   15524 /* The caller must hold the dblock as a writer. */
   15525 static inline void
   15526 zone_detachdb(dns_zone_t *zone) {
   15527 	REQUIRE(zone->db != NULL);
   15528 
   15529 	dns_db_detach(&zone->db);
   15530 }
   15531 
   15532 static void
   15533 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
   15534 	isc_time_t now;
   15535 	bool again = false;
   15536 	unsigned int soacount;
   15537 	unsigned int nscount;
   15538 	uint32_t serial, refresh, retry, expire, minimum;
   15539 	isc_result_t xfrresult = result;
   15540 	bool free_needed;
   15541 	dns_zone_t *secure = NULL;
   15542 
   15543 	REQUIRE(DNS_ZONE_VALID(zone));
   15544 
   15545 	dns_zone_log(zone, ISC_LOG_DEBUG(1),
   15546 		     "zone transfer finished: %s", dns_result_totext(result));
   15547 
   15548 	/*
   15549 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   15550 	 * could result in a deadlock due to a LOR so we will spin if we
   15551 	 * can't obtain the both locks.
   15552 	 */
   15553  again:
   15554 	LOCK_ZONE(zone);
   15555 	if (inline_raw(zone)) {
   15556 		secure = zone->secure;
   15557 		INSIST(secure != zone);
   15558 		TRYLOCK_ZONE(result, secure);
   15559 		if (result != ISC_R_SUCCESS) {
   15560 			UNLOCK_ZONE(zone);
   15561 			secure = NULL;
   15562 			isc_thread_yield();
   15563 			goto again;
   15564 		}
   15565 	}
   15566 
   15567 	INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
   15568 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   15569 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   15570 
   15571 	TIME_NOW(&now);
   15572 	switch (xfrresult) {
   15573 	case ISC_R_SUCCESS:
   15574 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   15575 		/* FALLTHROUGH */
   15576 	case DNS_R_UPTODATE:
   15577 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   15578 		/*
   15579 		 * Has the zone expired underneath us?
   15580 		 */
   15581 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   15582 		if (zone->db == NULL) {
   15583 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15584 			goto same_master;
   15585 		}
   15586 
   15587 		/*
   15588 		 * Update the zone structure's data from the actual
   15589 		 * SOA received.
   15590 		 */
   15591 		nscount = 0;
   15592 		soacount = 0;
   15593 		INSIST(zone->db != NULL);
   15594 		result = zone_get_from_db(zone, zone->db, &nscount,
   15595 					  &soacount, &serial, &refresh,
   15596 					  &retry, &expire, &minimum, NULL);
   15597 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15598 		if (result == ISC_R_SUCCESS) {
   15599 			if (soacount != 1)
   15600 				dns_zone_log(zone, ISC_LOG_ERROR,
   15601 					     "transferred zone "
   15602 					     "has %d SOA record%s", soacount,
   15603 					     (soacount != 0) ? "s" : "");
   15604 			if (nscount == 0) {
   15605 				dns_zone_log(zone, ISC_LOG_ERROR,
   15606 					     "transferred zone "
   15607 					     "has no NS records");
   15608 				if (DNS_ZONE_FLAG(zone,
   15609 						  DNS_ZONEFLG_HAVETIMERS)) {
   15610 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   15611 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   15612 				}
   15613 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   15614 				zone_unload(zone);
   15615 				goto next_master;
   15616 			}
   15617 			zone->refresh = RANGE(refresh, zone->minrefresh,
   15618 					      zone->maxrefresh);
   15619 			zone->retry = RANGE(retry, zone->minretry,
   15620 					    zone->maxretry);
   15621 			zone->expire = RANGE(expire,
   15622 					     zone->refresh + zone->retry,
   15623 					     DNS_MAX_EXPIRE);
   15624 			zone->minimum = minimum;
   15625 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   15626 		}
   15627 
   15628 		/*
   15629 		 * Set our next update/expire times.
   15630 		 */
   15631 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   15632 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   15633 			zone->refreshtime = now;
   15634 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   15635 					  &zone->expiretime);
   15636 		} else {
   15637 			DNS_ZONE_JITTER_ADD(&now, zone->refresh,
   15638 					    &zone->refreshtime);
   15639 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   15640 					  &zone->expiretime);
   15641 		}
   15642 		if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
   15643 			char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
   15644 			if (zone->tsigkey != NULL) {
   15645 				char namebuf[DNS_NAME_FORMATSIZE];
   15646 				dns_name_format(&zone->tsigkey->name, namebuf,
   15647 						sizeof(namebuf));
   15648 				snprintf(buf, sizeof(buf), ": TSIG '%s'",
   15649 					 namebuf);
   15650 			} else
   15651 				buf[0] = '\0';
   15652 			dns_zone_log(zone, ISC_LOG_INFO,
   15653 				     "transferred serial %u%s",
   15654 				     serial, buf);
   15655 			if (inline_raw(zone))
   15656 				zone_send_secureserial(zone, serial);
   15657 		}
   15658 
   15659 		/*
   15660 		 * This is not necessary if we just performed a AXFR
   15661 		 * however it is necessary for an IXFR / UPTODATE and
   15662 		 * won't hurt with an AXFR.
   15663 		 */
   15664 		if (zone->masterfile != NULL || zone->journal != NULL) {
   15665 			unsigned int delay = DNS_DUMP_DELAY;
   15666 
   15667 			result = ISC_R_FAILURE;
   15668 			if (zone->journal != NULL)
   15669 				result = isc_file_settime(zone->journal, &now);
   15670 			if (result != ISC_R_SUCCESS &&
   15671 			    zone->masterfile != NULL)
   15672 				result = isc_file_settime(zone->masterfile,
   15673 							  &now);
   15674 
   15675 			if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
   15676 			    result == ISC_R_FILENOTFOUND)
   15677 				delay = 0;
   15678 
   15679 			if ((result == ISC_R_SUCCESS ||
   15680 			    result == ISC_R_FILENOTFOUND) &&
   15681 			    zone->masterfile != NULL)
   15682 				zone_needdump(zone, delay);
   15683 			else if (result != ISC_R_SUCCESS)
   15684 				dns_zone_log(zone, ISC_LOG_ERROR,
   15685 					     "transfer: could not set file "
   15686 					     "modification time of '%s': %s",
   15687 					     zone->masterfile,
   15688 					     dns_result_totext(result));
   15689 		}
   15690 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
   15691 		inc_stats(zone, dns_zonestatscounter_xfrsuccess);
   15692 		break;
   15693 
   15694 	case DNS_R_BADIXFR:
   15695 		/* Force retry with AXFR. */
   15696 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
   15697 		goto same_master;
   15698 
   15699 	case DNS_R_TOOMANYRECORDS:
   15700 	case DNS_R_VERIFYFAILURE:
   15701 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   15702 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   15703 		break;
   15704 
   15705 	default:
   15706 	next_master:
   15707 		/*
   15708 		 * Skip to next failed / untried master.
   15709 		 */
   15710 		do {
   15711 			zone->curmaster++;
   15712 		} while (zone->curmaster < zone->masterscnt &&
   15713 			 zone->mastersok[zone->curmaster]);
   15714 		/* FALLTHROUGH */
   15715 	same_master:
   15716 		if (zone->curmaster >= zone->masterscnt) {
   15717 			zone->curmaster = 0;
   15718 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   15719 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   15720 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   15721 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   15722 				while (zone->curmaster < zone->masterscnt &&
   15723 				       zone->mastersok[zone->curmaster])
   15724 					zone->curmaster++;
   15725 				again = true;
   15726 			} else
   15727 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   15728 		} else {
   15729 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   15730 			again = true;
   15731 		}
   15732 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   15733 		break;
   15734 	}
   15735 	zone_settimer(zone, &now);
   15736 
   15737 	/*
   15738 	 * If creating the transfer object failed, zone->xfr is NULL.
   15739 	 * Otherwise, we are called as the done callback of a zone
   15740 	 * transfer object that just entered its shutting-down
   15741 	 * state.  Since we are no longer responsible for shutting
   15742 	 * it down, we can detach our reference.
   15743 	 */
   15744 	if (zone->xfr != NULL)
   15745 		dns_xfrin_detach(&zone->xfr);
   15746 
   15747 	if (zone->tsigkey != NULL)
   15748 		dns_tsigkey_detach(&zone->tsigkey);
   15749 
   15750 	/*
   15751 	 * Handle any deferred journal compaction.
   15752 	 */
   15753 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
   15754 		dns_db_t *db = NULL;
   15755 		if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) {
   15756 			zone_journal_compact(zone, db, zone->compact_serial);
   15757 			dns_db_detach(&db);
   15758 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   15759 		}
   15760 	}
   15761 
   15762 	if (secure != NULL)
   15763 		UNLOCK_ZONE(secure);
   15764 	/*
   15765 	 * This transfer finishing freed up a transfer quota slot.
   15766 	 * Let any other zones waiting for quota have it.
   15767 	 */
   15768 	if (zone->zmgr != NULL &&
   15769 	    zone->statelist == &zone->zmgr->xfrin_in_progress) {
   15770 		UNLOCK_ZONE(zone);
   15771 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   15772 		ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
   15773 		zone->statelist = NULL;
   15774 		zmgr_resume_xfrs(zone->zmgr, false);
   15775 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   15776 		LOCK_ZONE(zone);
   15777 	}
   15778 
   15779 	/*
   15780 	 * Retry with a different server if necessary.
   15781 	 */
   15782 	if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
   15783 		queue_soa_query(zone);
   15784 
   15785 	INSIST(zone->irefs > 0);
   15786 	zone->irefs--;
   15787 	free_needed = exit_check(zone);
   15788 	UNLOCK_ZONE(zone);
   15789 	if (free_needed)
   15790 		zone_free(zone);
   15791 }
   15792 
   15793 static void
   15794 zone_loaddone(void *arg, isc_result_t result) {
   15795 	static char me[] = "zone_loaddone";
   15796 	dns_load_t *load = arg;
   15797 	dns_zone_t *zone;
   15798 	isc_result_t tresult;
   15799 	dns_zone_t *secure = NULL;
   15800 
   15801 	REQUIRE(DNS_LOAD_VALID(load));
   15802 	zone = load->zone;
   15803 
   15804 	ENTER;
   15805 
   15806 	tresult = dns_db_endload(load->db, &load->callbacks);
   15807 	if (tresult != ISC_R_SUCCESS &&
   15808 	    (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
   15809 		result = tresult;
   15810 
   15811 	/*
   15812 	 * Lock hierarchy: zmgr, zone, raw.
   15813 	 */
   15814  again:
   15815 	LOCK_ZONE(zone);
   15816 	INSIST(zone != zone->raw);
   15817 	if (inline_secure(zone))
   15818 		LOCK_ZONE(zone->raw);
   15819 	else if (inline_raw(zone)) {
   15820 		secure = zone->secure;
   15821 		TRYLOCK_ZONE(result, secure);
   15822 		if (result != ISC_R_SUCCESS) {
   15823 			UNLOCK_ZONE(zone);
   15824 			secure = NULL;
   15825 			isc_thread_yield();
   15826 			goto again;
   15827 		}
   15828 	}
   15829 	(void)zone_postload(zone, load->db, load->loadtime, result);
   15830 	zonemgr_putio(&zone->readio);
   15831 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
   15832 	zone_idetach(&load->callbacks.zone);
   15833 	/*
   15834 	 * Leave the zone frozen if the reload fails.
   15835 	 */
   15836 	if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
   15837 	     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
   15838 		zone->update_disabled = false;
   15839 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
   15840 	if (inline_secure(zone))
   15841 		UNLOCK_ZONE(zone->raw);
   15842 	else if (secure != NULL)
   15843 		UNLOCK_ZONE(secure);
   15844 	UNLOCK_ZONE(zone);
   15845 
   15846 	load->magic = 0;
   15847 	dns_db_detach(&load->db);
   15848 	if (load->zone->lctx != NULL)
   15849 		dns_loadctx_detach(&load->zone->lctx);
   15850 	dns_zone_idetach(&load->zone);
   15851 	isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
   15852 }
   15853 
   15854 void
   15855 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
   15856 	REQUIRE(DNS_ZONE_VALID(zone));
   15857 	REQUIRE(table != NULL);
   15858 	REQUIRE(*table == NULL);
   15859 
   15860 	LOCK_ZONE(zone);
   15861 	if (zone->ssutable != NULL)
   15862 		dns_ssutable_attach(zone->ssutable, table);
   15863 	UNLOCK_ZONE(zone);
   15864 }
   15865 
   15866 void
   15867 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
   15868 	REQUIRE(DNS_ZONE_VALID(zone));
   15869 
   15870 	LOCK_ZONE(zone);
   15871 	if (zone->ssutable != NULL)
   15872 		dns_ssutable_detach(&zone->ssutable);
   15873 	if (table != NULL)
   15874 		dns_ssutable_attach(table, &zone->ssutable);
   15875 	UNLOCK_ZONE(zone);
   15876 }
   15877 
   15878 void
   15879 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   15880 	REQUIRE(DNS_ZONE_VALID(zone));
   15881 
   15882 	zone->sigvalidityinterval = interval;
   15883 }
   15884 
   15885 uint32_t
   15886 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
   15887 	REQUIRE(DNS_ZONE_VALID(zone));
   15888 
   15889 	return (zone->sigvalidityinterval);
   15890 }
   15891 
   15892 void
   15893 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   15894 	REQUIRE(DNS_ZONE_VALID(zone));
   15895 
   15896 	zone->keyvalidityinterval = interval;
   15897 }
   15898 
   15899 uint32_t
   15900 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
   15901 	REQUIRE(DNS_ZONE_VALID(zone));
   15902 
   15903 	return (zone->keyvalidityinterval);
   15904 }
   15905 
   15906 void
   15907 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
   15908 	isc_time_t now;
   15909 
   15910 	REQUIRE(DNS_ZONE_VALID(zone));
   15911 
   15912 	LOCK_ZONE(zone);
   15913 	zone->sigresigninginterval = interval;
   15914 	set_resigntime(zone);
   15915 	if (zone->task != NULL) {
   15916 		TIME_NOW(&now);
   15917 		zone_settimer(zone, &now);
   15918 	}
   15919 	UNLOCK_ZONE(zone);
   15920 }
   15921 
   15922 uint32_t
   15923 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
   15924 	REQUIRE(DNS_ZONE_VALID(zone));
   15925 
   15926 	return (zone->sigresigninginterval);
   15927 }
   15928 
   15929 static void
   15930 queue_xfrin(dns_zone_t *zone) {
   15931 	const char me[] = "queue_xfrin";
   15932 	isc_result_t result;
   15933 	dns_zonemgr_t *zmgr = zone->zmgr;
   15934 
   15935 	ENTER;
   15936 
   15937 	INSIST(zone->statelist == NULL);
   15938 
   15939 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   15940 	ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
   15941 	LOCK_ZONE(zone);
   15942 	zone->irefs++;
   15943 	UNLOCK_ZONE(zone);
   15944 	zone->statelist = &zmgr->waiting_for_xfrin;
   15945 	result = zmgr_start_xfrin_ifquota(zmgr, zone);
   15946 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   15947 
   15948 	if (result == ISC_R_QUOTA) {
   15949 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   15950 			      "zone transfer deferred due to quota");
   15951 	} else if (result != ISC_R_SUCCESS) {
   15952 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   15953 			      "starting zone transfer: %s",
   15954 			      isc_result_totext(result));
   15955 	}
   15956 }
   15957 
   15958 /*
   15959  * This event callback is called when a zone has received
   15960  * any necessary zone transfer quota.  This is the time
   15961  * to go ahead and start the transfer.
   15962  */
   15963 static void
   15964 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
   15965 	isc_result_t result = ISC_R_SUCCESS;
   15966 	dns_peer_t *peer = NULL;
   15967 	char master[ISC_SOCKADDR_FORMATSIZE];
   15968 	char source[ISC_SOCKADDR_FORMATSIZE];
   15969 	dns_rdatatype_t xfrtype;
   15970 	dns_zone_t *zone = event->ev_arg;
   15971 	isc_netaddr_t masterip;
   15972 	isc_sockaddr_t sourceaddr;
   15973 	isc_sockaddr_t masteraddr;
   15974 	isc_time_t now;
   15975 	const char *soa_before = "";
   15976 	isc_dscp_t dscp = -1;
   15977 	bool loaded;
   15978 
   15979 	UNUSED(task);
   15980 
   15981 	INSIST(task == zone->task);
   15982 
   15983 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   15984 		result = ISC_R_CANCELED;
   15985 		goto cleanup;
   15986 	}
   15987 
   15988 	TIME_NOW(&now);
   15989 
   15990 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   15991 	if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   15992 				    &zone->sourceaddr, &now))
   15993 	{
   15994 		isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   15995 		dns_zone_log(zone, ISC_LOG_INFO,
   15996 			     "got_transfer_quota: skipping zone transfer as "
   15997 			     "master %s (source %s) is unreachable (cached)",
   15998 			     master, source);
   15999 		result = ISC_R_CANCELED;
   16000 		goto cleanup;
   16001 	}
   16002 
   16003 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   16004 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   16005 
   16006 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
   16007 		soa_before = "SOA before ";
   16008 	/*
   16009 	 * Decide whether we should request IXFR or AXFR.
   16010 	 */
   16011 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16012 	loaded = (zone->db != NULL);
   16013 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16014 
   16015 	if (!loaded) {
   16016 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
   16017 			     "no database exists yet, requesting AXFR of "
   16018 			     "initial version from %s", master);
   16019 		xfrtype = dns_rdatatype_axfr;
   16020 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
   16021 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
   16022 			     "forced reload, requesting AXFR of "
   16023 			     "initial version from %s", master);
   16024 		xfrtype = dns_rdatatype_axfr;
   16025 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
   16026 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
   16027 			     "retrying with AXFR from %s due to "
   16028 			     "previous IXFR failure", master);
   16029 		xfrtype = dns_rdatatype_axfr;
   16030 		LOCK_ZONE(zone);
   16031 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
   16032 		UNLOCK_ZONE(zone);
   16033 	} else {
   16034 		bool use_ixfr = true;
   16035 		if (peer != NULL)
   16036 			result = dns_peer_getrequestixfr(peer, &use_ixfr);
   16037 		if (peer == NULL || result != ISC_R_SUCCESS)
   16038 			use_ixfr = zone->requestixfr;
   16039 		if (use_ixfr == false) {
   16040 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   16041 				     "IXFR disabled, requesting %sAXFR from %s",
   16042 				     soa_before, master);
   16043 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
   16044 				xfrtype = dns_rdatatype_soa;
   16045 			else
   16046 				xfrtype = dns_rdatatype_axfr;
   16047 		} else {
   16048 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   16049 				     "requesting IXFR from %s", master);
   16050 			xfrtype = dns_rdatatype_ixfr;
   16051 		}
   16052 	}
   16053 
   16054 	/*
   16055 	 * Determine if we should attempt to sign the request with TSIG.
   16056 	 */
   16057 	result = ISC_R_NOTFOUND;
   16058 
   16059 	/*
   16060 	 * First, look for a tsig key in the master statement, then
   16061 	 * try for a server key.
   16062 	 */
   16063 	if ((zone->masterkeynames != NULL) &&
   16064 	    (zone->masterkeynames[zone->curmaster] != NULL)) {
   16065 		dns_view_t *view = dns_zone_getview(zone);
   16066 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   16067 		result = dns_view_gettsig(view, keyname, &zone->tsigkey);
   16068 	}
   16069 	if (zone->tsigkey == NULL)
   16070 		result = dns_view_getpeertsig(zone->view, &masterip,
   16071 					      &zone->tsigkey);
   16072 
   16073 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   16074 		dns_zone_log(zone, ISC_LOG_ERROR,
   16075 			     "could not get TSIG key for zone transfer: %s",
   16076 			     isc_result_totext(result));
   16077 	}
   16078 
   16079 	if (zone->masterdscps != NULL)
   16080 	    dscp = zone->masterdscps[zone->curmaster];
   16081 
   16082 	LOCK_ZONE(zone);
   16083 	masteraddr = zone->masteraddr;
   16084 	sourceaddr = zone->sourceaddr;
   16085 	switch (isc_sockaddr_pf(&masteraddr)) {
   16086 	case PF_INET:
   16087 		if (dscp == -1)
   16088 			dscp = zone->xfrsource4dscp;
   16089 		break;
   16090 	case PF_INET6:
   16091 		if (dscp == -1)
   16092 			dscp = zone->xfrsource6dscp;
   16093 		break;
   16094 	default:
   16095 		INSIST(0);
   16096 		ISC_UNREACHABLE();
   16097 	}
   16098 	UNLOCK_ZONE(zone);
   16099 	INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
   16100 	result = dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr,
   16101 				  dscp, zone->tsigkey, zone->mctx,
   16102 				  zone->zmgr->timermgr, zone->zmgr->socketmgr,
   16103 				  zone->task, zone_xfrdone, &zone->xfr);
   16104 	if (result == ISC_R_SUCCESS) {
   16105 		LOCK_ZONE(zone);
   16106 		if (xfrtype == dns_rdatatype_axfr) {
   16107 			if (isc_sockaddr_pf(&masteraddr) == PF_INET)
   16108 				inc_stats(zone, dns_zonestatscounter_axfrreqv4);
   16109 			else
   16110 				inc_stats(zone, dns_zonestatscounter_axfrreqv6);
   16111 		} else if (xfrtype == dns_rdatatype_ixfr) {
   16112 			if (isc_sockaddr_pf(&masteraddr) == PF_INET)
   16113 				inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
   16114 			else
   16115 				inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
   16116 		}
   16117 		UNLOCK_ZONE(zone);
   16118 	}
   16119  cleanup:
   16120 	/*
   16121 	 * Any failure in this function is handled like a failed
   16122 	 * zone transfer.  This ensures that we get removed from
   16123 	 * zmgr->xfrin_in_progress.
   16124 	 */
   16125 	if (result != ISC_R_SUCCESS)
   16126 		zone_xfrdone(zone, result);
   16127 
   16128 	isc_event_free(&event);
   16129 }
   16130 
   16131 /*
   16132  * Update forwarding support.
   16133  */
   16134 
   16135 static void
   16136 forward_destroy(dns_forward_t *forward) {
   16137 
   16138 	forward->magic = 0;
   16139 	if (forward->request != NULL)
   16140 		dns_request_destroy(&forward->request);
   16141 	if (forward->msgbuf != NULL)
   16142 		isc_buffer_free(&forward->msgbuf);
   16143 	if (forward->zone != NULL) {
   16144 		LOCK(&forward->zone->lock);
   16145 		if (ISC_LINK_LINKED(forward, link))
   16146 			ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
   16147 		UNLOCK(&forward->zone->lock);
   16148 		dns_zone_idetach(&forward->zone);
   16149 	}
   16150 	isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
   16151 }
   16152 
   16153 static isc_result_t
   16154 sendtomaster(dns_forward_t *forward) {
   16155 	isc_result_t result;
   16156 	isc_sockaddr_t src;
   16157 	isc_dscp_t dscp = -1;
   16158 
   16159 	LOCK_ZONE(forward->zone);
   16160 
   16161 	if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
   16162 		UNLOCK_ZONE(forward->zone);
   16163 		return (ISC_R_CANCELED);
   16164 	}
   16165 
   16166 	if (forward->which >= forward->zone->masterscnt) {
   16167 		UNLOCK_ZONE(forward->zone);
   16168 		return (ISC_R_NOMORE);
   16169 	}
   16170 
   16171 	forward->addr = forward->zone->masters[forward->which];
   16172 	/*
   16173 	 * Always use TCP regardless of whether the original update
   16174 	 * used TCP.
   16175 	 * XXX The timeout may but a bit small if we are far down a
   16176 	 * transfer graph and the master has to try several masters.
   16177 	 */
   16178 	switch (isc_sockaddr_pf(&forward->addr)) {
   16179 	case PF_INET:
   16180 		src = forward->zone->xfrsource4;
   16181 		dscp = forward->zone->xfrsource4dscp;
   16182 		break;
   16183 	case PF_INET6:
   16184 		src = forward->zone->xfrsource6;
   16185 		dscp = forward->zone->xfrsource6dscp;
   16186 		break;
   16187 	default:
   16188 		result = ISC_R_NOTIMPLEMENTED;
   16189 		goto unlock;
   16190 	}
   16191 	result = dns_request_createraw(forward->zone->view->requestmgr,
   16192 				       forward->msgbuf,
   16193 				       &src, &forward->addr, dscp,
   16194 				       forward->options, 15 /* XXX */,
   16195 				       0, 0, forward->zone->task,
   16196 				       forward_callback, forward,
   16197 				       &forward->request);
   16198 	if (result == ISC_R_SUCCESS) {
   16199 		if (!ISC_LINK_LINKED(forward, link))
   16200 			ISC_LIST_APPEND(forward->zone->forwards, forward, link);
   16201 	}
   16202 
   16203  unlock:
   16204 	UNLOCK_ZONE(forward->zone);
   16205 	return (result);
   16206 }
   16207 
   16208 static void
   16209 forward_callback(isc_task_t *task, isc_event_t *event) {
   16210 	const char me[] = "forward_callback";
   16211 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   16212 	dns_message_t *msg = NULL;
   16213 	char master[ISC_SOCKADDR_FORMATSIZE];
   16214 	isc_result_t result;
   16215 	dns_forward_t *forward;
   16216 	dns_zone_t *zone;
   16217 
   16218 	UNUSED(task);
   16219 
   16220 	forward = revent->ev_arg;
   16221 	INSIST(DNS_FORWARD_VALID(forward));
   16222 	zone = forward->zone;
   16223 	INSIST(DNS_ZONE_VALID(zone));
   16224 
   16225 	ENTER;
   16226 
   16227 	isc_sockaddr_format(&forward->addr, master, sizeof(master));
   16228 
   16229 	if (revent->result != ISC_R_SUCCESS) {
   16230 		dns_zone_log(zone, ISC_LOG_INFO,
   16231 			     "could not forward dynamic update to %s: %s",
   16232 			     master, dns_result_totext(revent->result));
   16233 		goto next_master;
   16234 	}
   16235 
   16236 	result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   16237 	if (result != ISC_R_SUCCESS)
   16238 		goto next_master;
   16239 
   16240 	result = dns_request_getresponse(revent->request, msg,
   16241 					 DNS_MESSAGEPARSE_PRESERVEORDER |
   16242 					 DNS_MESSAGEPARSE_CLONEBUFFER);
   16243 	if (result != ISC_R_SUCCESS)
   16244 		goto next_master;
   16245 
   16246 	switch (msg->rcode) {
   16247 	/*
   16248 	 * Pass these rcodes back to client.
   16249 	 */
   16250 	case dns_rcode_noerror:
   16251 	case dns_rcode_yxdomain:
   16252 	case dns_rcode_yxrrset:
   16253 	case dns_rcode_nxrrset:
   16254 	case dns_rcode_refused:
   16255 	case dns_rcode_nxdomain: {
   16256 		char rcode[128];
   16257 		isc_buffer_t rb;
   16258 
   16259 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   16260 		(void)dns_rcode_totext(msg->rcode, &rb);
   16261 		dns_zone_log(zone, ISC_LOG_INFO,
   16262 			     "forwarded dynamic update: "
   16263 			     "master %s returned: %.*s",
   16264 			     master, (int)rb.used, rcode);
   16265 		break;
   16266 	}
   16267 
   16268 	/* These should not occur if the masters/zone are valid. */
   16269 	case dns_rcode_notzone:
   16270 	case dns_rcode_notauth: {
   16271 		char rcode[128];
   16272 		isc_buffer_t rb;
   16273 
   16274 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   16275 		(void)dns_rcode_totext(msg->rcode, &rb);
   16276 		dns_zone_log(zone, ISC_LOG_WARNING,
   16277 			     "forwarding dynamic update: "
   16278 			     "unexpected response: master %s returned: %.*s",
   16279 			     master, (int)rb.used, rcode);
   16280 		goto next_master;
   16281 	}
   16282 
   16283 	/* Try another server for these rcodes. */
   16284 	case dns_rcode_formerr:
   16285 	case dns_rcode_servfail:
   16286 	case dns_rcode_notimp:
   16287 	case dns_rcode_badvers:
   16288 	default:
   16289 		goto next_master;
   16290 	}
   16291 
   16292 	/* call callback */
   16293 	(forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
   16294 	msg = NULL;
   16295 	dns_request_destroy(&forward->request);
   16296 	forward_destroy(forward);
   16297 	isc_event_free(&event);
   16298 	return;
   16299 
   16300  next_master:
   16301 	if (msg != NULL)
   16302 		dns_message_destroy(&msg);
   16303 	isc_event_free(&event);
   16304 	forward->which++;
   16305 	dns_request_destroy(&forward->request);
   16306 	result = sendtomaster(forward);
   16307 	if (result != ISC_R_SUCCESS) {
   16308 		/* call callback */
   16309 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   16310 			     "exhausted dynamic update forwarder list");
   16311 		(forward->callback)(forward->callback_arg, result, NULL);
   16312 		forward_destroy(forward);
   16313 	}
   16314 }
   16315 
   16316 isc_result_t
   16317 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
   16318 		       dns_updatecallback_t callback, void *callback_arg)
   16319 {
   16320 	dns_forward_t *forward;
   16321 	isc_result_t result;
   16322 	isc_region_t *mr;
   16323 
   16324 	REQUIRE(DNS_ZONE_VALID(zone));
   16325 	REQUIRE(msg != NULL);
   16326 	REQUIRE(callback != NULL);
   16327 
   16328 	forward = isc_mem_get(zone->mctx, sizeof(*forward));
   16329 	if (forward == NULL)
   16330 		return (ISC_R_NOMEMORY);
   16331 
   16332 	forward->request = NULL;
   16333 	forward->zone = NULL;
   16334 	forward->msgbuf = NULL;
   16335 	forward->which = 0;
   16336 	forward->mctx = 0;
   16337 	forward->callback = callback;
   16338 	forward->callback_arg = callback_arg;
   16339 	ISC_LINK_INIT(forward, link);
   16340 	forward->magic = FORWARD_MAGIC;
   16341 	forward->options = DNS_REQUESTOPT_TCP;
   16342 	/*
   16343 	 * If we have a SIG(0) signed message we need to preserve the
   16344 	 * query id as that is included in the SIG(0) computation.
   16345 	 */
   16346 	if (msg->sig0 != NULL)
   16347 		forward->options |= DNS_REQUESTOPT_FIXEDID;
   16348 
   16349 	mr = dns_message_getrawmessage(msg);
   16350 	if (mr == NULL) {
   16351 		result = ISC_R_UNEXPECTEDEND;
   16352 		goto cleanup;
   16353 	}
   16354 
   16355 	result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
   16356 	if (result != ISC_R_SUCCESS)
   16357 		goto cleanup;
   16358 	result = isc_buffer_copyregion(forward->msgbuf, mr);
   16359 	if (result != ISC_R_SUCCESS)
   16360 		goto cleanup;
   16361 
   16362 	isc_mem_attach(zone->mctx, &forward->mctx);
   16363 	dns_zone_iattach(zone, &forward->zone);
   16364 	result = sendtomaster(forward);
   16365 
   16366  cleanup:
   16367 	if (result != ISC_R_SUCCESS) {
   16368 		forward_destroy(forward);
   16369 	}
   16370 	return (result);
   16371 }
   16372 
   16373 isc_result_t
   16374 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
   16375 	REQUIRE(DNS_ZONE_VALID(zone));
   16376 	REQUIRE(next != NULL && *next == NULL);
   16377 
   16378 	*next = ISC_LIST_NEXT(zone, link);
   16379 	if (*next == NULL)
   16380 		return (ISC_R_NOMORE);
   16381 	else
   16382 		return (ISC_R_SUCCESS);
   16383 }
   16384 
   16385 isc_result_t
   16386 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
   16387 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16388 	REQUIRE(first != NULL && *first == NULL);
   16389 
   16390 	*first = ISC_LIST_HEAD(zmgr->zones);
   16391 	if (*first == NULL)
   16392 		return (ISC_R_NOMORE);
   16393 	else
   16394 		return (ISC_R_SUCCESS);
   16395 }
   16396 
   16397 /***
   16398  ***	Zone manager.
   16399  ***/
   16400 
   16401 isc_result_t
   16402 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
   16403 		   isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
   16404 		   dns_zonemgr_t **zmgrp)
   16405 {
   16406 	dns_zonemgr_t *zmgr;
   16407 	isc_result_t result;
   16408 
   16409 	zmgr = isc_mem_get(mctx, sizeof(*zmgr));
   16410 	if (zmgr == NULL)
   16411 		return (ISC_R_NOMEMORY);
   16412 	zmgr->mctx = NULL;
   16413 	zmgr->refs = 1;
   16414 	isc_mem_attach(mctx, &zmgr->mctx);
   16415 	zmgr->taskmgr = taskmgr;
   16416 	zmgr->timermgr = timermgr;
   16417 	zmgr->socketmgr = socketmgr;
   16418 	zmgr->zonetasks = NULL;
   16419 	zmgr->loadtasks = NULL;
   16420 	zmgr->mctxpool = NULL;
   16421 	zmgr->task = NULL;
   16422 	zmgr->notifyrl = NULL;
   16423 	zmgr->refreshrl = NULL;
   16424 	zmgr->startupnotifyrl = NULL;
   16425 	zmgr->startuprefreshrl = NULL;
   16426 	ISC_LIST_INIT(zmgr->zones);
   16427 	ISC_LIST_INIT(zmgr->waiting_for_xfrin);
   16428 	ISC_LIST_INIT(zmgr->xfrin_in_progress);
   16429 	memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
   16430 	result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
   16431 	if (result != ISC_R_SUCCESS)
   16432 		goto free_mem;
   16433 
   16434 	zmgr->transfersin = 10;
   16435 	zmgr->transfersperns = 2;
   16436 
   16437 	/* Unreachable lock. */
   16438 	result = isc_rwlock_init(&zmgr->urlock, 0, 0);
   16439 	if (result != ISC_R_SUCCESS)
   16440 		goto free_rwlock;
   16441 
   16442 	/* Create a single task for queueing of SOA queries. */
   16443 	result = isc_task_create(taskmgr, 1, &zmgr->task);
   16444 	if (result != ISC_R_SUCCESS)
   16445 		goto free_urlock;
   16446 
   16447 	isc_task_setname(zmgr->task, "zmgr", zmgr);
   16448 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   16449 					&zmgr->notifyrl);
   16450 	if (result != ISC_R_SUCCESS)
   16451 		goto free_task;
   16452 
   16453 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   16454 					&zmgr->refreshrl);
   16455 	if (result != ISC_R_SUCCESS)
   16456 		goto free_notifyrl;
   16457 
   16458 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   16459 					&zmgr->startupnotifyrl);
   16460 	if (result != ISC_R_SUCCESS)
   16461 		goto free_refreshrl;
   16462 
   16463 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   16464 					&zmgr->startuprefreshrl);
   16465 	if (result != ISC_R_SUCCESS)
   16466 		goto free_startupnotifyrl;
   16467 
   16468 	/* default to 20 refresh queries / notifies per second. */
   16469 	setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
   16470 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
   16471 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
   16472 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
   16473 	isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true);
   16474 	isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true);
   16475 
   16476 	zmgr->iolimit = 1;
   16477 	zmgr->ioactive = 0;
   16478 	ISC_LIST_INIT(zmgr->high);
   16479 	ISC_LIST_INIT(zmgr->low);
   16480 
   16481 	isc_mutex_init(&zmgr->iolock);
   16482 
   16483 	zmgr->magic = ZONEMGR_MAGIC;
   16484 
   16485 	*zmgrp = zmgr;
   16486 	return (ISC_R_SUCCESS);
   16487 
   16488 #if 0
   16489  free_iolock:
   16490 	isc_mutex_destroy(&zmgr->iolock);
   16491 #endif
   16492  free_startupnotifyrl:
   16493 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   16494  free_refreshrl:
   16495 	isc_ratelimiter_detach(&zmgr->refreshrl);
   16496  free_notifyrl:
   16497 	isc_ratelimiter_detach(&zmgr->notifyrl);
   16498  free_task:
   16499 	isc_task_detach(&zmgr->task);
   16500  free_urlock:
   16501 	isc_rwlock_destroy(&zmgr->urlock);
   16502  free_rwlock:
   16503 	isc_rwlock_destroy(&zmgr->rwlock);
   16504  free_mem:
   16505 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   16506 	isc_mem_detach(&mctx);
   16507 	return (result);
   16508 }
   16509 
   16510 isc_result_t
   16511 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
   16512 	isc_result_t result;
   16513 	isc_mem_t *mctx = NULL;
   16514 	dns_zone_t *zone = NULL;
   16515 	void *item;
   16516 
   16517 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16518 	REQUIRE(zonep != NULL && *zonep == NULL);
   16519 
   16520 	if (zmgr->mctxpool == NULL)
   16521 		return (ISC_R_FAILURE);
   16522 
   16523 	item = isc_pool_get(zmgr->mctxpool);
   16524 	if (item == NULL)
   16525 		return (ISC_R_FAILURE);
   16526 
   16527 	isc_mem_attach((isc_mem_t *) item, &mctx);
   16528 	result = dns_zone_create(&zone, mctx);
   16529 	isc_mem_detach(&mctx);
   16530 
   16531 	if (result == ISC_R_SUCCESS)
   16532 		*zonep = zone;
   16533 
   16534 	return (result);
   16535 }
   16536 
   16537 isc_result_t
   16538 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   16539 	isc_result_t result;
   16540 
   16541 	REQUIRE(DNS_ZONE_VALID(zone));
   16542 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16543 
   16544 	if (zmgr->zonetasks == NULL)
   16545 		return (ISC_R_FAILURE);
   16546 
   16547 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16548 	LOCK_ZONE(zone);
   16549 	REQUIRE(zone->task == NULL);
   16550 	REQUIRE(zone->timer == NULL);
   16551 	REQUIRE(zone->zmgr == NULL);
   16552 
   16553 	isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
   16554 	isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
   16555 
   16556 	/*
   16557 	 * Set the task name.  The tag will arbitrarily point to one
   16558 	 * of the zones sharing the task (in practice, the one
   16559 	 * to be managed last).
   16560 	 */
   16561 	isc_task_setname(zone->task, "zone", zone);
   16562 	isc_task_setname(zone->loadtask, "loadzone", zone);
   16563 
   16564 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
   16565 				  NULL, NULL,
   16566 				  zone->task, zone_timer, zone,
   16567 				  &zone->timer);
   16568 
   16569 	if (result != ISC_R_SUCCESS)
   16570 		goto cleanup_tasks;
   16571 
   16572 	/*
   16573 	 * The timer "holds" a iref.
   16574 	 */
   16575 	zone->irefs++;
   16576 	INSIST(zone->irefs != 0);
   16577 
   16578 	ISC_LIST_APPEND(zmgr->zones, zone, link);
   16579 	zone->zmgr = zmgr;
   16580 	zmgr->refs++;
   16581 
   16582 	goto unlock;
   16583 
   16584  cleanup_tasks:
   16585 	isc_task_detach(&zone->loadtask);
   16586 	isc_task_detach(&zone->task);
   16587 
   16588  unlock:
   16589 	UNLOCK_ZONE(zone);
   16590 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16591 	return (result);
   16592 }
   16593 
   16594 void
   16595 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   16596 	bool free_now = false;
   16597 
   16598 	REQUIRE(DNS_ZONE_VALID(zone));
   16599 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16600 	REQUIRE(zone->zmgr == zmgr);
   16601 
   16602 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16603 	LOCK_ZONE(zone);
   16604 
   16605 	ISC_LIST_UNLINK(zmgr->zones, zone, link);
   16606 	zone->zmgr = NULL;
   16607 	zmgr->refs--;
   16608 	if (zmgr->refs == 0)
   16609 		free_now = true;
   16610 
   16611 	UNLOCK_ZONE(zone);
   16612 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16613 
   16614 	if (free_now)
   16615 		zonemgr_free(zmgr);
   16616 	ENSURE(zone->zmgr == NULL);
   16617 }
   16618 
   16619 void
   16620 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
   16621 	REQUIRE(DNS_ZONEMGR_VALID(source));
   16622 	REQUIRE(target != NULL && *target == NULL);
   16623 
   16624 	RWLOCK(&source->rwlock, isc_rwlocktype_write);
   16625 	REQUIRE(source->refs > 0);
   16626 	source->refs++;
   16627 	INSIST(source->refs > 0);
   16628 	RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
   16629 	*target = source;
   16630 }
   16631 
   16632 void
   16633 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
   16634 	dns_zonemgr_t *zmgr;
   16635 	bool free_now = false;
   16636 
   16637 	REQUIRE(zmgrp != NULL);
   16638 	zmgr = *zmgrp;
   16639 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16640 
   16641 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16642 	zmgr->refs--;
   16643 	if (zmgr->refs == 0)
   16644 		free_now = true;
   16645 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16646 
   16647 	if (free_now)
   16648 		zonemgr_free(zmgr);
   16649 	*zmgrp = NULL;
   16650 }
   16651 
   16652 isc_result_t
   16653 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
   16654 	dns_zone_t *p;
   16655 
   16656 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16657 
   16658 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   16659 	for (p = ISC_LIST_HEAD(zmgr->zones);
   16660 	     p != NULL;
   16661 	     p = ISC_LIST_NEXT(p, link))
   16662 	{
   16663 		dns_zone_maintenance(p);
   16664 	}
   16665 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   16666 
   16667 	/*
   16668 	 * Recent configuration changes may have increased the
   16669 	 * amount of available transfers quota.  Make sure any
   16670 	 * transfers currently blocked on quota get started if
   16671 	 * possible.
   16672 	 */
   16673 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16674 	zmgr_resume_xfrs(zmgr, true);
   16675 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16676 	return (ISC_R_SUCCESS);
   16677 }
   16678 
   16679 void
   16680 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
   16681 
   16682 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16683 
   16684 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16685 	zmgr_resume_xfrs(zmgr, true);
   16686 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   16687 }
   16688 
   16689 void
   16690 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
   16691 	dns_zone_t *zone;
   16692 
   16693 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16694 
   16695 	isc_ratelimiter_shutdown(zmgr->notifyrl);
   16696 	isc_ratelimiter_shutdown(zmgr->refreshrl);
   16697 	isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
   16698 	isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
   16699 
   16700 	if (zmgr->task != NULL)
   16701 		isc_task_destroy(&zmgr->task);
   16702 	if (zmgr->zonetasks != NULL)
   16703 		isc_taskpool_destroy(&zmgr->zonetasks);
   16704 	if (zmgr->loadtasks != NULL)
   16705 		isc_taskpool_destroy(&zmgr->loadtasks);
   16706 	if (zmgr->mctxpool != NULL)
   16707 		isc_pool_destroy(&zmgr->mctxpool);
   16708 
   16709 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   16710 	for (zone = ISC_LIST_HEAD(zmgr->zones);
   16711 	     zone != NULL;
   16712 	     zone = ISC_LIST_NEXT(zone, link))
   16713 	{
   16714 		LOCK_ZONE(zone);
   16715 		forward_cancel(zone);
   16716 		UNLOCK_ZONE(zone);
   16717 	}
   16718 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   16719 }
   16720 
   16721 static isc_result_t
   16722 mctxinit(void **target, void *arg) {
   16723 	isc_result_t result;
   16724 	isc_mem_t *mctx = NULL;
   16725 
   16726 	UNUSED(arg);
   16727 
   16728 	REQUIRE(target != NULL && *target == NULL);
   16729 
   16730 	result = isc_mem_create(0, 0, &mctx);
   16731 	if (result != ISC_R_SUCCESS)
   16732 		return (result);
   16733 	isc_mem_setname(mctx, "zonemgr-pool", NULL);
   16734 
   16735 	*target = mctx;
   16736 	return (ISC_R_SUCCESS);
   16737 }
   16738 
   16739 static void
   16740 mctxfree(void **target) {
   16741 	isc_mem_t *mctx = *(isc_mem_t **) target;
   16742 	isc_mem_detach(&mctx);
   16743 	*target = NULL;
   16744 }
   16745 
   16746 #define ZONES_PER_TASK 100
   16747 #define ZONES_PER_MCTX 1000
   16748 
   16749 isc_result_t
   16750 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
   16751 	isc_result_t result;
   16752 	int ntasks = num_zones / ZONES_PER_TASK;
   16753 	int nmctx = num_zones / ZONES_PER_MCTX;
   16754 	isc_taskpool_t *pool = NULL;
   16755 	isc_pool_t *mctxpool = NULL;
   16756 
   16757 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16758 
   16759 	/*
   16760 	 * For anything fewer than 1000 zones we use 10 tasks in
   16761 	 * the task pools.  More than that, and we'll scale at one
   16762 	 * task per 100 zones.  Similarly, for anything smaller than
   16763 	 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
   16764 	 */
   16765 	if (ntasks < 10)
   16766 		ntasks = 10;
   16767 	if (nmctx < 2)
   16768 		nmctx = 2;
   16769 
   16770 	/* Create or resize the zone task pools. */
   16771 	if (zmgr->zonetasks == NULL)
   16772 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
   16773 					     ntasks, 2, &pool);
   16774 	else
   16775 		result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
   16776 
   16777 	if (result == ISC_R_SUCCESS)
   16778 		zmgr->zonetasks = pool;
   16779 
   16780 	pool = NULL;
   16781 	if (zmgr->loadtasks == NULL)
   16782 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
   16783 					     ntasks, 2, &pool);
   16784 	else
   16785 		result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
   16786 
   16787 	if (result == ISC_R_SUCCESS)
   16788 		zmgr->loadtasks = pool;
   16789 
   16790 	/*
   16791 	 * We always set all tasks in the zone-load task pool to
   16792 	 * privileged.  This prevents other tasks in the system from
   16793 	 * running while the server task manager is in privileged
   16794 	 * mode.
   16795 	 *
   16796 	 * NOTE: If we start using task privileges for any other
   16797 	 * part of the system than zone tasks, then this will need to be
   16798 	 * revisted.  In that case we'd want to turn on privileges for
   16799 	 * zone tasks only when we were loading, and turn them off the
   16800 	 * rest of the time.  For now, however, it's okay to just
   16801 	 * set it and forget it.
   16802 	 */
   16803 	isc_taskpool_setprivilege(zmgr->loadtasks, true);
   16804 
   16805 	/* Create or resize the zone memory context pool. */
   16806 	if (zmgr->mctxpool == NULL)
   16807 		result = isc_pool_create(zmgr->mctx, nmctx, mctxfree,
   16808 					 mctxinit, NULL, &mctxpool);
   16809 	else
   16810 		result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
   16811 
   16812 	if (result == ISC_R_SUCCESS)
   16813 		zmgr->mctxpool = mctxpool;
   16814 
   16815 	return (result);
   16816 }
   16817 
   16818 static void
   16819 zonemgr_free(dns_zonemgr_t *zmgr) {
   16820 	isc_mem_t *mctx;
   16821 
   16822 	INSIST(zmgr->refs == 0);
   16823 	INSIST(ISC_LIST_EMPTY(zmgr->zones));
   16824 
   16825 	zmgr->magic = 0;
   16826 
   16827 	isc_mutex_destroy(&zmgr->iolock);
   16828 	isc_ratelimiter_detach(&zmgr->notifyrl);
   16829 	isc_ratelimiter_detach(&zmgr->refreshrl);
   16830 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   16831 	isc_ratelimiter_detach(&zmgr->startuprefreshrl);
   16832 
   16833 	isc_rwlock_destroy(&zmgr->urlock);
   16834 	isc_rwlock_destroy(&zmgr->rwlock);
   16835 	mctx = zmgr->mctx;
   16836 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   16837 	isc_mem_detach(&mctx);
   16838 }
   16839 
   16840 void
   16841 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
   16842 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16843 
   16844 	zmgr->transfersin = value;
   16845 }
   16846 
   16847 uint32_t
   16848 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
   16849 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16850 
   16851 	return (zmgr->transfersin);
   16852 }
   16853 
   16854 void
   16855 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
   16856 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16857 
   16858 	zmgr->transfersperns = value;
   16859 }
   16860 
   16861 uint32_t
   16862 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
   16863 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   16864 
   16865 	return (zmgr->transfersperns);
   16866 }
   16867 
   16868 /*
   16869  * Try to start a new incoming zone transfer to fill a quota
   16870  * slot that was just vacated.
   16871  *
   16872  * Requires:
   16873  *	The zone manager is locked by the caller.
   16874  */
   16875 static void
   16876 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) {
   16877 	dns_zone_t *zone;
   16878 	dns_zone_t *next;
   16879 
   16880 	for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
   16881 	     zone != NULL;
   16882 	     zone = next)
   16883 	{
   16884 		isc_result_t result;
   16885 		next = ISC_LIST_NEXT(zone, statelink);
   16886 		result = zmgr_start_xfrin_ifquota(zmgr, zone);
   16887 		if (result == ISC_R_SUCCESS) {
   16888 			if (multi)
   16889 				continue;
   16890 			/*
   16891 			 * We successfully filled the slot.  We're done.
   16892 			 */
   16893 			break;
   16894 		} else if (result == ISC_R_QUOTA) {
   16895 			/*
   16896 			 * Not enough quota.  This is probably the per-server
   16897 			 * quota, because we usually get called when a unit of
   16898 			 * global quota has just been freed.  Try the next
   16899 			 * zone, it may succeed if it uses another master.
   16900 			 */
   16901 			continue;
   16902 		} else {
   16903 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   16904 				     "starting zone transfer: %s",
   16905 				     isc_result_totext(result));
   16906 			break;
   16907 		}
   16908 	}
   16909 }
   16910 
   16911 /*
   16912  * Try to start an incoming zone transfer for 'zone', quota permitting.
   16913  *
   16914  * Requires:
   16915  *	The zone manager is locked by the caller.
   16916  *
   16917  * Returns:
   16918  *	ISC_R_SUCCESS	There was enough quota and we attempted to
   16919  *			start a transfer.  zone_xfrdone() has been or will
   16920  *			be called.
   16921  *	ISC_R_QUOTA	Not enough quota.
   16922  *	Others		Failure.
   16923  */
   16924 static isc_result_t
   16925 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   16926 	dns_peer_t *peer = NULL;
   16927 	isc_netaddr_t masterip;
   16928 	uint32_t nxfrsin, nxfrsperns;
   16929 	dns_zone_t *x;
   16930 	uint32_t maxtransfersin, maxtransfersperns;
   16931 	isc_event_t *e;
   16932 
   16933 	/*
   16934 	 * If we are exiting just pretend we got quota so the zone will
   16935 	 * be cleaned up in the zone's task context.
   16936 	 */
   16937 	LOCK_ZONE(zone);
   16938 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   16939 		UNLOCK_ZONE(zone);
   16940 		goto gotquota;
   16941 	}
   16942 
   16943 	/*
   16944 	 * Find any configured information about the server we'd
   16945 	 * like to transfer this zone from.
   16946 	 */
   16947 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   16948 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   16949 	UNLOCK_ZONE(zone);
   16950 
   16951 	/*
   16952 	 * Determine the total maximum number of simultaneous
   16953 	 * transfers allowed, and the maximum for this specific
   16954 	 * master.
   16955 	 */
   16956 	maxtransfersin = zmgr->transfersin;
   16957 	maxtransfersperns = zmgr->transfersperns;
   16958 	if (peer != NULL)
   16959 		(void)dns_peer_gettransfers(peer, &maxtransfersperns);
   16960 
   16961 	/*
   16962 	 * Count the total number of transfers that are in progress,
   16963 	 * and the number of transfers in progress from this master.
   16964 	 * We linearly scan a list of all transfers; if this turns
   16965 	 * out to be too slow, we could hash on the master address.
   16966 	 */
   16967 	nxfrsin = nxfrsperns = 0;
   16968 	for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
   16969 	     x != NULL;
   16970 	     x = ISC_LIST_NEXT(x, statelink))
   16971 	{
   16972 		isc_netaddr_t xip;
   16973 
   16974 		LOCK_ZONE(x);
   16975 		isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
   16976 		UNLOCK_ZONE(x);
   16977 
   16978 		nxfrsin++;
   16979 		if (isc_netaddr_equal(&xip, &masterip))
   16980 			nxfrsperns++;
   16981 	}
   16982 
   16983 	/* Enforce quota. */
   16984 	if (nxfrsin >= maxtransfersin)
   16985 		return (ISC_R_QUOTA);
   16986 
   16987 	if (nxfrsperns >= maxtransfersperns)
   16988 		return (ISC_R_QUOTA);
   16989 
   16990  gotquota:
   16991 	/*
   16992 	 * We have sufficient quota.  Move the zone to the "xfrin_in_progress"
   16993 	 * list and send it an event to let it start the actual transfer in the
   16994 	 * context of its own task.
   16995 	 */
   16996 	e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
   16997 			       got_transfer_quota, zone, sizeof(isc_event_t));
   16998 	if (e == NULL)
   16999 		return (ISC_R_NOMEMORY);
   17000 
   17001 	LOCK_ZONE(zone);
   17002 	INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
   17003 	ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
   17004 	ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
   17005 	zone->statelist = &zmgr->xfrin_in_progress;
   17006 	isc_task_send(zone->task, &e);
   17007 	dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
   17008 	UNLOCK_ZONE(zone);
   17009 
   17010 	return (ISC_R_SUCCESS);
   17011 }
   17012 
   17013 void
   17014 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) {
   17015 
   17016 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17017 	REQUIRE(iolimit > 0);
   17018 
   17019 	zmgr->iolimit = iolimit;
   17020 }
   17021 
   17022 uint32_t
   17023 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
   17024 
   17025 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17026 
   17027 	return (zmgr->iolimit);
   17028 }
   17029 
   17030 /*
   17031  * Get permission to request a file handle from the OS.
   17032  * An event will be sent to action when one is available.
   17033  * There are two queues available (high and low), the high
   17034  * queue will be serviced before the low one.
   17035  *
   17036  * zonemgr_putio() must be called after the event is delivered to
   17037  * 'action'.
   17038  */
   17039 
   17040 static isc_result_t
   17041 zonemgr_getio(dns_zonemgr_t *zmgr, bool high,
   17042 	      isc_task_t *task, isc_taskaction_t action, void *arg,
   17043 	      dns_io_t **iop)
   17044 {
   17045 	dns_io_t *io;
   17046 	bool queue;
   17047 
   17048 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17049 	REQUIRE(iop != NULL && *iop == NULL);
   17050 
   17051 	io = isc_mem_get(zmgr->mctx, sizeof(*io));
   17052 	if (io == NULL)
   17053 		return (ISC_R_NOMEMORY);
   17054 
   17055 	io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
   17056 				       action, arg, sizeof(*io->event));
   17057 	if (io->event == NULL) {
   17058 		isc_mem_put(zmgr->mctx, io, sizeof(*io));
   17059 		return (ISC_R_NOMEMORY);
   17060 	}
   17061 
   17062 	io->zmgr = zmgr;
   17063 	io->high = high;
   17064 	io->task = NULL;
   17065 	isc_task_attach(task, &io->task);
   17066 	ISC_LINK_INIT(io, link);
   17067 	io->magic = IO_MAGIC;
   17068 
   17069 	LOCK(&zmgr->iolock);
   17070 	zmgr->ioactive++;
   17071 	queue = (zmgr->ioactive > zmgr->iolimit);
   17072 	if (queue) {
   17073 		if (io->high)
   17074 			ISC_LIST_APPEND(zmgr->high, io, link);
   17075 		else
   17076 			ISC_LIST_APPEND(zmgr->low, io, link);
   17077 	}
   17078 	UNLOCK(&zmgr->iolock);
   17079 	*iop = io;
   17080 
   17081 	if (!queue)
   17082 		isc_task_send(io->task, &io->event);
   17083 	return (ISC_R_SUCCESS);
   17084 }
   17085 
   17086 static void
   17087 zonemgr_putio(dns_io_t **iop) {
   17088 	dns_io_t *io;
   17089 	dns_io_t *next;
   17090 	dns_zonemgr_t *zmgr;
   17091 
   17092 	REQUIRE(iop != NULL);
   17093 	io = *iop;
   17094 	REQUIRE(DNS_IO_VALID(io));
   17095 
   17096 	*iop = NULL;
   17097 
   17098 	INSIST(!ISC_LINK_LINKED(io, link));
   17099 	INSIST(io->event == NULL);
   17100 
   17101 	zmgr = io->zmgr;
   17102 	isc_task_detach(&io->task);
   17103 	io->magic = 0;
   17104 	isc_mem_put(zmgr->mctx, io, sizeof(*io));
   17105 
   17106 	LOCK(&zmgr->iolock);
   17107 	INSIST(zmgr->ioactive > 0);
   17108 	zmgr->ioactive--;
   17109 	next = HEAD(zmgr->high);
   17110 	if (next == NULL)
   17111 		next = HEAD(zmgr->low);
   17112 	if (next != NULL) {
   17113 		if (next->high)
   17114 			ISC_LIST_UNLINK(zmgr->high, next, link);
   17115 		else
   17116 			ISC_LIST_UNLINK(zmgr->low, next, link);
   17117 		INSIST(next->event != NULL);
   17118 	}
   17119 	UNLOCK(&zmgr->iolock);
   17120 	if (next != NULL)
   17121 		isc_task_send(next->task, &next->event);
   17122 }
   17123 
   17124 static void
   17125 zonemgr_cancelio(dns_io_t *io) {
   17126 	bool send_event = false;
   17127 
   17128 	REQUIRE(DNS_IO_VALID(io));
   17129 
   17130 	/*
   17131 	 * If we are queued to be run then dequeue.
   17132 	 */
   17133 	LOCK(&io->zmgr->iolock);
   17134 	if (ISC_LINK_LINKED(io, link)) {
   17135 		if (io->high)
   17136 			ISC_LIST_UNLINK(io->zmgr->high, io, link);
   17137 		else
   17138 			ISC_LIST_UNLINK(io->zmgr->low, io, link);
   17139 
   17140 		send_event = true;
   17141 		INSIST(io->event != NULL);
   17142 	}
   17143 	UNLOCK(&io->zmgr->iolock);
   17144 	if (send_event) {
   17145 		io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
   17146 		isc_task_send(io->task, &io->event);
   17147 	}
   17148 }
   17149 
   17150 static void
   17151 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
   17152 	char *buf;
   17153 	int buflen;
   17154 	isc_result_t result;
   17155 
   17156 	buflen = strlen(path) + strlen(templat) + 2;
   17157 
   17158 	buf = isc_mem_get(zone->mctx, buflen);
   17159 	if (buf == NULL)
   17160 		return;
   17161 
   17162 	result = isc_file_template(path, templat, buf, buflen);
   17163 	if (result != ISC_R_SUCCESS)
   17164 		goto cleanup;
   17165 
   17166 	result = isc_file_renameunique(path, buf);
   17167 	if (result != ISC_R_SUCCESS)
   17168 		goto cleanup;
   17169 
   17170 	dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
   17171 		     "renaming file to '%s' for failure analysis and "
   17172 		     "retransferring.", path, buf);
   17173 
   17174  cleanup:
   17175 	isc_mem_put(zone->mctx, buf, buflen);
   17176 }
   17177 
   17178 static void
   17179 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
   17180 	isc_interval_t interval;
   17181 	uint32_t s, ns;
   17182 	uint32_t pertic;
   17183 	isc_result_t result;
   17184 
   17185 	if (value == 0)
   17186 		value = 1;
   17187 
   17188 	if (value == 1) {
   17189 		s = 1;
   17190 		ns = 0;
   17191 		pertic = 1;
   17192 	} else if (value <= 10) {
   17193 		s = 0;
   17194 		ns = 1000000000 / value;
   17195 		pertic = 1;
   17196 	} else {
   17197 		s = 0;
   17198 		ns = (1000000000 / value) * 10;
   17199 		pertic = 10;
   17200 	}
   17201 
   17202 	isc_interval_set(&interval, s, ns);
   17203 
   17204 	result = isc_ratelimiter_setinterval(rl, &interval);
   17205 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   17206 	isc_ratelimiter_setpertic(rl, pertic);
   17207 
   17208 	*rate = value;
   17209 }
   17210 
   17211 void
   17212 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   17213 
   17214 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17215 
   17216 	setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
   17217 }
   17218 
   17219 void
   17220 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   17221 
   17222 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17223 
   17224 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
   17225 }
   17226 
   17227 void
   17228 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
   17229 
   17230 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17231 
   17232 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
   17233 	/* XXXMPA seperate out once we have the code to support this. */
   17234 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
   17235 }
   17236 
   17237 unsigned int
   17238 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
   17239 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17240 
   17241 	return (zmgr->notifyrate);
   17242 }
   17243 
   17244 unsigned int
   17245 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
   17246 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17247 
   17248 	return (zmgr->startupnotifyrate);
   17249 }
   17250 
   17251 unsigned int
   17252 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
   17253 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17254 
   17255 	return (zmgr->serialqueryrate);
   17256 }
   17257 
   17258 bool
   17259 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   17260 			isc_sockaddr_t *local, isc_time_t *now)
   17261 {
   17262 	unsigned int i;
   17263 	isc_rwlocktype_t locktype;
   17264 	isc_result_t result;
   17265 	uint32_t seconds = isc_time_seconds(now);
   17266 	uint32_t count = 0;
   17267 
   17268 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17269 
   17270 	locktype = isc_rwlocktype_read;
   17271 	RWLOCK(&zmgr->urlock, locktype);
   17272 	for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
   17273 		if (zmgr->unreachable[i].expire >= seconds &&
   17274 		    isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   17275 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
   17276 			result = isc_rwlock_tryupgrade(&zmgr->urlock);
   17277 			if (result == ISC_R_SUCCESS) {
   17278 				locktype = isc_rwlocktype_write;
   17279 				zmgr->unreachable[i].last = seconds;
   17280 				count = zmgr->unreachable[i].count;
   17281 			}
   17282 			break;
   17283 		}
   17284 	}
   17285 	RWUNLOCK(&zmgr->urlock, locktype);
   17286 	return (i < UNREACH_CHACHE_SIZE && count > 1U);
   17287 }
   17288 
   17289 void
   17290 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   17291 			   isc_sockaddr_t *local)
   17292 {
   17293 	unsigned int i;
   17294 	isc_rwlocktype_t locktype;
   17295 	isc_result_t result;
   17296 
   17297 	char master[ISC_SOCKADDR_FORMATSIZE];
   17298 	char source[ISC_SOCKADDR_FORMATSIZE];
   17299 
   17300 	isc_sockaddr_format(remote, master, sizeof(master));
   17301 	isc_sockaddr_format(local, source, sizeof(source));
   17302 
   17303 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17304 
   17305 	locktype = isc_rwlocktype_read;
   17306 	RWLOCK(&zmgr->urlock, locktype);
   17307 	for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
   17308 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   17309 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
   17310 			if (zmgr->unreachable[i].expire == 0)
   17311 				break;
   17312 			result = isc_rwlock_tryupgrade(&zmgr->urlock);
   17313 			if (result == ISC_R_SUCCESS) {
   17314 				locktype = isc_rwlocktype_write;
   17315 				zmgr->unreachable[i].expire = 0;
   17316 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17317 					      DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
   17318 					      "master %s (source %s) deleted "
   17319 					      "from unreachable cache",
   17320 					      master, source);
   17321 			}
   17322 			break;
   17323 		}
   17324 	}
   17325 	RWUNLOCK(&zmgr->urlock, locktype);
   17326 }
   17327 
   17328 void
   17329 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   17330 			   isc_sockaddr_t *local, isc_time_t *now)
   17331 {
   17332 	uint32_t seconds = isc_time_seconds(now);
   17333 	uint32_t last = seconds;
   17334 	unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
   17335 
   17336 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17337 
   17338 	RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
   17339 	for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
   17340 		/* Existing entry? */
   17341 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   17342 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   17343 			break;
   17344 		/* Empty slot? */
   17345 		if (zmgr->unreachable[i].expire < seconds)
   17346 			slot = i;
   17347 		/* Least recently used slot? */
   17348 		if (zmgr->unreachable[i].last < last) {
   17349 			last = zmgr->unreachable[i].last;
   17350 			oldest = i;
   17351 		}
   17352 	}
   17353 	if (i < UNREACH_CHACHE_SIZE) {
   17354 		/*
   17355 		 * Found a existing entry.  Update the expire timer and
   17356 		 * last usage timestamps.
   17357 		 */
   17358 		zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
   17359 		zmgr->unreachable[i].last = seconds;
   17360 		if (zmgr->unreachable[i].expire < seconds)
   17361 			zmgr->unreachable[i].count = 1;
   17362 		else
   17363 			zmgr->unreachable[i].count++;
   17364 	} else if (slot != UNREACH_CHACHE_SIZE) {
   17365 		/*
   17366 		 * Found a empty slot. Add a new entry to the cache.
   17367 		 */
   17368 		zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
   17369 		zmgr->unreachable[slot].last = seconds;
   17370 		zmgr->unreachable[slot].remote = *remote;
   17371 		zmgr->unreachable[slot].local = *local;
   17372 		zmgr->unreachable[slot].count = 1;
   17373 	} else {
   17374 		/*
   17375 		 * Replace the least recently used entry in the cache.
   17376 		 */
   17377 		zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
   17378 		zmgr->unreachable[oldest].last = seconds;
   17379 		zmgr->unreachable[oldest].remote = *remote;
   17380 		zmgr->unreachable[oldest].local = *local;
   17381 		zmgr->unreachable[oldest].count = 1;
   17382 	}
   17383 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
   17384 }
   17385 
   17386 void
   17387 dns_zone_forcereload(dns_zone_t *zone) {
   17388 	REQUIRE(DNS_ZONE_VALID(zone));
   17389 
   17390 	if (zone->type == dns_zone_master ||
   17391 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   17392 		return;
   17393 
   17394 	LOCK_ZONE(zone);
   17395 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   17396 	UNLOCK_ZONE(zone);
   17397 	dns_zone_refresh(zone);
   17398 }
   17399 
   17400 bool
   17401 dns_zone_isforced(dns_zone_t *zone) {
   17402 	REQUIRE(DNS_ZONE_VALID(zone));
   17403 
   17404 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
   17405 }
   17406 
   17407 isc_result_t
   17408 dns_zone_setstatistics(dns_zone_t *zone, bool on) {
   17409 	/*
   17410 	 * This function is obsoleted.
   17411 	 */
   17412 	UNUSED(zone);
   17413 	UNUSED(on);
   17414 	return (ISC_R_NOTIMPLEMENTED);
   17415 }
   17416 
   17417 uint64_t *
   17418 dns_zone_getstatscounters(dns_zone_t *zone) {
   17419 	/*
   17420 	 * This function is obsoleted.
   17421 	 */
   17422 	UNUSED(zone);
   17423 	return (NULL);
   17424 }
   17425 
   17426 void
   17427 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
   17428 	REQUIRE(DNS_ZONE_VALID(zone));
   17429 	REQUIRE(zone->stats == NULL);
   17430 
   17431 	LOCK_ZONE(zone);
   17432 	zone->stats = NULL;
   17433 	isc_stats_attach(stats, &zone->stats);
   17434 	UNLOCK_ZONE(zone);
   17435 }
   17436 
   17437 void
   17438 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
   17439 
   17440 	REQUIRE(DNS_ZONE_VALID(zone));
   17441 
   17442 	LOCK_ZONE(zone);
   17443 	if (zone->requeststats_on && stats == NULL)
   17444 		zone->requeststats_on = false;
   17445 	else if (!zone->requeststats_on && stats != NULL) {
   17446 		if (zone->requeststats == NULL) {
   17447 			isc_stats_attach(stats, &zone->requeststats);
   17448 			zone->requeststats_on = true;
   17449 		}
   17450 	}
   17451 	UNLOCK_ZONE(zone);
   17452 }
   17453 
   17454 void
   17455 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
   17456 
   17457 	REQUIRE(DNS_ZONE_VALID(zone));
   17458 
   17459 	LOCK_ZONE(zone);
   17460 	if (zone->requeststats_on && stats != NULL) {
   17461 		if (zone->rcvquerystats == NULL) {
   17462 			dns_stats_attach(stats, &zone->rcvquerystats);
   17463 			zone->requeststats_on = true;
   17464 		}
   17465 	}
   17466 	UNLOCK_ZONE(zone);
   17467 }
   17468 
   17469 isc_stats_t *
   17470 dns_zone_getrequeststats(dns_zone_t *zone) {
   17471 	/*
   17472 	 * We don't lock zone for efficiency reason.  This is not catastrophic
   17473 	 * because requeststats must always be valid when requeststats_on is
   17474 	 * true.
   17475 	 * Some counters may be incremented while requeststats_on is becoming
   17476 	 * false, or some cannot be incremented just after the statistics are
   17477 	 * installed, but it shouldn't matter much in practice.
   17478 	 */
   17479 	if (zone->requeststats_on)
   17480 		return (zone->requeststats);
   17481 	else
   17482 		return (NULL);
   17483 }
   17484 
   17485 /*
   17486  * Return the received query stats bucket
   17487  * see note from dns_zone_getrequeststats()
   17488  */
   17489 dns_stats_t *
   17490 dns_zone_getrcvquerystats(dns_zone_t *zone) {
   17491 	if (zone->requeststats_on)
   17492 		return (zone->rcvquerystats);
   17493 	else
   17494 		return (NULL);
   17495 }
   17496 
   17497 void
   17498 dns_zone_dialup(dns_zone_t *zone) {
   17499 
   17500 	REQUIRE(DNS_ZONE_VALID(zone));
   17501 
   17502 	zone_debuglog(zone, "dns_zone_dialup", 3,
   17503 		      "notify = %d, refresh = %d",
   17504 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
   17505 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
   17506 
   17507 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
   17508 		dns_zone_notify(zone);
   17509 	if (zone->type != dns_zone_master && zone->masters != NULL &&
   17510 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
   17511 		dns_zone_refresh(zone);
   17512 }
   17513 
   17514 void
   17515 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
   17516 	REQUIRE(DNS_ZONE_VALID(zone));
   17517 
   17518 	LOCK_ZONE(zone);
   17519 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
   17520 			 DNS_ZONEFLG_DIALREFRESH |
   17521 			 DNS_ZONEFLG_NOREFRESH);
   17522 	switch (dialup) {
   17523 	case dns_dialuptype_no:
   17524 		break;
   17525 	case dns_dialuptype_yes:
   17526 		DNS_ZONE_SETFLAG(zone,	(DNS_ZONEFLG_DIALNOTIFY |
   17527 				 DNS_ZONEFLG_DIALREFRESH |
   17528 				 DNS_ZONEFLG_NOREFRESH));
   17529 		break;
   17530 	case dns_dialuptype_notify:
   17531 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   17532 		break;
   17533 	case dns_dialuptype_notifypassive:
   17534 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   17535 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   17536 		break;
   17537 	case dns_dialuptype_refresh:
   17538 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
   17539 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   17540 		break;
   17541 	case dns_dialuptype_passive:
   17542 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   17543 		break;
   17544 	default:
   17545 		INSIST(0);
   17546 		ISC_UNREACHABLE();
   17547 	}
   17548 	UNLOCK_ZONE(zone);
   17549 }
   17550 
   17551 isc_result_t
   17552 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
   17553 	isc_result_t result = ISC_R_SUCCESS;
   17554 
   17555 	REQUIRE(DNS_ZONE_VALID(zone));
   17556 
   17557 	LOCK_ZONE(zone);
   17558 	result = dns_zone_setstring(zone, &zone->keydirectory, directory);
   17559 	UNLOCK_ZONE(zone);
   17560 
   17561 	return (result);
   17562 }
   17563 
   17564 const char *
   17565 dns_zone_getkeydirectory(dns_zone_t *zone) {
   17566 	REQUIRE(DNS_ZONE_VALID(zone));
   17567 
   17568 	return (zone->keydirectory);
   17569 }
   17570 
   17571 unsigned int
   17572 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
   17573 	dns_zone_t *zone;
   17574 	unsigned int count = 0;
   17575 
   17576 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17577 
   17578 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   17579 	switch (state) {
   17580 	case DNS_ZONESTATE_XFERRUNNING:
   17581 		for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
   17582 		     zone != NULL;
   17583 		     zone = ISC_LIST_NEXT(zone, statelink))
   17584 			count++;
   17585 		break;
   17586 	case DNS_ZONESTATE_XFERDEFERRED:
   17587 		for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
   17588 		     zone != NULL;
   17589 		     zone = ISC_LIST_NEXT(zone, statelink))
   17590 			count++;
   17591 		break;
   17592 	case DNS_ZONESTATE_SOAQUERY:
   17593 		for (zone = ISC_LIST_HEAD(zmgr->zones);
   17594 		     zone != NULL;
   17595 		     zone = ISC_LIST_NEXT(zone, link))
   17596 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
   17597 				count++;
   17598 		break;
   17599 	case DNS_ZONESTATE_ANY:
   17600 		for (zone = ISC_LIST_HEAD(zmgr->zones);
   17601 		     zone != NULL;
   17602 		     zone = ISC_LIST_NEXT(zone, link)) {
   17603 			dns_view_t *view = zone->view;
   17604 			if (view != NULL && strcmp(view->name, "_bind") == 0)
   17605 				continue;
   17606 			count++;
   17607 		}
   17608 		break;
   17609 	case DNS_ZONESTATE_AUTOMATIC:
   17610 		for (zone = ISC_LIST_HEAD(zmgr->zones);
   17611 		     zone != NULL;
   17612 		     zone = ISC_LIST_NEXT(zone, link)) {
   17613 			dns_view_t *view = zone->view;
   17614 			if (view != NULL && strcmp(view->name, "_bind") == 0)
   17615 				continue;
   17616 			if (zone->automatic)
   17617 				count++;
   17618 		}
   17619 		break;
   17620 	default:
   17621 		INSIST(0);
   17622 		ISC_UNREACHABLE();
   17623 	}
   17624 
   17625 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   17626 
   17627 	return (count);
   17628 }
   17629 
   17630 isc_result_t
   17631 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
   17632 		    dns_rdata_t *rdata)
   17633 {
   17634 	bool ok = true;
   17635 	bool fail = false;
   17636 	char namebuf[DNS_NAME_FORMATSIZE];
   17637 	char namebuf2[DNS_NAME_FORMATSIZE];
   17638 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   17639 	int level = ISC_LOG_WARNING;
   17640 	dns_name_t bad;
   17641 
   17642 	REQUIRE(DNS_ZONE_VALID(zone));
   17643 
   17644 	if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
   17645 	    rdata->type != dns_rdatatype_nsec3)
   17646 		return (ISC_R_SUCCESS);
   17647 
   17648 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
   17649 	    rdata->type == dns_rdatatype_nsec3) {
   17650 		level = ISC_LOG_ERROR;
   17651 		fail = true;
   17652 	}
   17653 
   17654 	ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true);
   17655 	if (!ok) {
   17656 		dns_name_format(name, namebuf, sizeof(namebuf));
   17657 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   17658 		dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
   17659 			     dns_result_totext(DNS_R_BADOWNERNAME));
   17660 		if (fail)
   17661 			return (DNS_R_BADOWNERNAME);
   17662 	}
   17663 
   17664 	dns_name_init(&bad, NULL);
   17665 	ok = dns_rdata_checknames(rdata, name, &bad);
   17666 	if (!ok) {
   17667 		dns_name_format(name, namebuf, sizeof(namebuf));
   17668 		dns_name_format(&bad, namebuf2, sizeof(namebuf2));
   17669 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   17670 		dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
   17671 			     namebuf2, dns_result_totext(DNS_R_BADNAME));
   17672 		if (fail)
   17673 			return (DNS_R_BADNAME);
   17674 	}
   17675 
   17676 	return (ISC_R_SUCCESS);
   17677 }
   17678 
   17679 void
   17680 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
   17681 	REQUIRE(DNS_ZONE_VALID(zone));
   17682 	zone->checkmx = checkmx;
   17683 }
   17684 
   17685 void
   17686 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
   17687 	REQUIRE(DNS_ZONE_VALID(zone));
   17688 	zone->checksrv = checksrv;
   17689 }
   17690 
   17691 void
   17692 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
   17693 	REQUIRE(DNS_ZONE_VALID(zone));
   17694 	zone->checkns = checkns;
   17695 }
   17696 
   17697 void
   17698 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
   17699 	REQUIRE(DNS_ZONE_VALID(zone));
   17700 
   17701 	LOCK_ZONE(zone);
   17702 	zone->isself = isself;
   17703 	zone->isselfarg = arg;
   17704 	UNLOCK_ZONE(zone);
   17705 }
   17706 
   17707 void
   17708 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
   17709 	REQUIRE(DNS_ZONE_VALID(zone));
   17710 
   17711 	LOCK_ZONE(zone);
   17712 	zone->notifydelay = delay;
   17713 	UNLOCK_ZONE(zone);
   17714 }
   17715 
   17716 uint32_t
   17717 dns_zone_getnotifydelay(dns_zone_t *zone) {
   17718 	REQUIRE(DNS_ZONE_VALID(zone));
   17719 
   17720 	return (zone->notifydelay);
   17721 }
   17722 
   17723 isc_result_t
   17724 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
   17725 		     uint16_t keyid, bool deleteit)
   17726 {
   17727 	isc_result_t result;
   17728 	REQUIRE(DNS_ZONE_VALID(zone));
   17729 
   17730 	dnssec_log(zone, ISC_LOG_NOTICE,
   17731 		   "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
   17732 		   algorithm, keyid);
   17733 	LOCK_ZONE(zone);
   17734 	result = zone_signwithkey(zone, algorithm, keyid, deleteit);
   17735 	UNLOCK_ZONE(zone);
   17736 
   17737 	return (result);
   17738 }
   17739 
   17740 /*
   17741  * Called when a dynamic update for an NSEC3PARAM record is received.
   17742  *
   17743  * If set, transform the NSEC3 salt into human-readable form so that it can be
   17744  * logged.  Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it.
   17745  */
   17746 isc_result_t
   17747 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   17748 	isc_result_t result;
   17749 	char salt[255*2+1];
   17750 
   17751 	REQUIRE(DNS_ZONE_VALID(zone));
   17752 
   17753 	result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
   17754 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   17755 	dnssec_log(zone, ISC_LOG_NOTICE,
   17756 		   "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
   17757 		   nsec3param->hash, nsec3param->iterations, salt);
   17758 	LOCK_ZONE(zone);
   17759 	result = zone_addnsec3chain(zone, nsec3param);
   17760 	UNLOCK_ZONE(zone);
   17761 
   17762 	return (result);
   17763 }
   17764 
   17765 void
   17766 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
   17767 	REQUIRE(DNS_ZONE_VALID(zone));
   17768 
   17769 	if (nodes == 0)
   17770 		nodes = 1;
   17771 	zone->nodes = nodes;
   17772 }
   17773 
   17774 void
   17775 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
   17776 	REQUIRE(DNS_ZONE_VALID(zone));
   17777 
   17778 	/*
   17779 	 * We treat signatures as a signed value so explicitly
   17780 	 * limit its range here.
   17781 	 */
   17782 	if (signatures > INT32_MAX)
   17783 		signatures = INT32_MAX;
   17784 	else if (signatures == 0)
   17785 		signatures = 1;
   17786 	zone->signatures = signatures;
   17787 }
   17788 
   17789 uint32_t
   17790 dns_zone_getsignatures(dns_zone_t *zone) {
   17791 	REQUIRE(DNS_ZONE_VALID(zone));
   17792 	return (zone->signatures);
   17793 }
   17794 
   17795 void
   17796 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
   17797 	REQUIRE(DNS_ZONE_VALID(zone));
   17798 	zone->privatetype = type;
   17799 }
   17800 
   17801 dns_rdatatype_t
   17802 dns_zone_getprivatetype(dns_zone_t *zone) {
   17803 	REQUIRE(DNS_ZONE_VALID(zone));
   17804 	return (zone->privatetype);
   17805 }
   17806 
   17807 static isc_result_t
   17808 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   17809 		 bool deleteit)
   17810 {
   17811 	dns_signing_t *signing;
   17812 	dns_signing_t *current;
   17813 	isc_result_t result = ISC_R_SUCCESS;
   17814 	isc_time_t now;
   17815 	dns_db_t *db = NULL;
   17816 
   17817 	signing = isc_mem_get(zone->mctx, sizeof *signing);
   17818 	if (signing == NULL)
   17819 		return (ISC_R_NOMEMORY);
   17820 
   17821 	signing->magic = 0;
   17822 	signing->db  = NULL;
   17823 	signing->dbiterator = NULL;
   17824 	signing->algorithm = algorithm;
   17825 	signing->keyid = keyid;
   17826 	signing->deleteit = deleteit;
   17827 	signing->done = false;
   17828 
   17829 	TIME_NOW(&now);
   17830 
   17831 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17832 	if (zone->db != NULL)
   17833 		dns_db_attach(zone->db, &db);
   17834 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17835 
   17836 	if (db == NULL) {
   17837 		result = ISC_R_NOTFOUND;
   17838 		goto cleanup;
   17839 	}
   17840 
   17841 	dns_db_attach(db, &signing->db);
   17842 
   17843 	for (current = ISC_LIST_HEAD(zone->signing);
   17844 	     current != NULL;
   17845 	     current = ISC_LIST_NEXT(current, link)) {
   17846 		if (current->db == signing->db &&
   17847 		    current->algorithm == signing->algorithm &&
   17848 		    current->keyid == signing->keyid) {
   17849 			if (current->deleteit != signing->deleteit)
   17850 				current->done = true;
   17851 			else
   17852 				goto cleanup;
   17853 		}
   17854 	}
   17855 
   17856 	result = dns_db_createiterator(signing->db, 0,
   17857 				       &signing->dbiterator);
   17858 
   17859 	if (result == ISC_R_SUCCESS)
   17860 		result = dns_dbiterator_first(signing->dbiterator);
   17861 	if (result == ISC_R_SUCCESS) {
   17862 		dns_dbiterator_pause(signing->dbiterator);
   17863 		ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
   17864 		signing = NULL;
   17865 		if (isc_time_isepoch(&zone->signingtime)) {
   17866 			zone->signingtime = now;
   17867 			if (zone->task != NULL)
   17868 				zone_settimer(zone, &now);
   17869 		}
   17870 	}
   17871 
   17872  cleanup:
   17873 	if (signing != NULL) {
   17874 		if (signing->db != NULL)
   17875 			dns_db_detach(&signing->db);
   17876 		if (signing->dbiterator != NULL)
   17877 			dns_dbiterator_destroy(&signing->dbiterator);
   17878 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   17879 	}
   17880 	if (db != NULL)
   17881 		dns_db_detach(&db);
   17882 	return (result);
   17883 }
   17884 
   17885 static void
   17886 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
   17887 	dns_dnsseckey_t *key;
   17888 	while (!ISC_LIST_EMPTY(*list)) {
   17889 		key = ISC_LIST_HEAD(*list);
   17890 		ISC_LIST_UNLINK(*list, key, link);
   17891 		dns_dnsseckey_destroy(mctx, &key);
   17892 	}
   17893 }
   17894 
   17895 /* Called once; *timep should be set to the current time. */
   17896 static isc_result_t
   17897 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
   17898 	isc_result_t result;
   17899 	isc_stdtime_t now, then = 0, event;
   17900 	int i;
   17901 
   17902 	now = *timep;
   17903 
   17904 	for (i = 0; i <= DST_MAX_TIMES; i++) {
   17905 		result = dst_key_gettime(key, i, &event);
   17906 		if (result == ISC_R_SUCCESS && event > now &&
   17907 		    (then == 0 || event < then))
   17908 			then = event;
   17909 	}
   17910 
   17911 	if (then != 0) {
   17912 		*timep = then;
   17913 		return (ISC_R_SUCCESS);
   17914 	}
   17915 
   17916 	return (ISC_R_NOTFOUND);
   17917 }
   17918 
   17919 static isc_result_t
   17920 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   17921 	  const dns_rdata_t *rdata, bool *flag)
   17922 {
   17923 	dns_rdataset_t rdataset;
   17924 	dns_dbnode_t *node = NULL;
   17925 	isc_result_t result;
   17926 
   17927 	dns_rdataset_init(&rdataset);
   17928 	if (rdata->type == dns_rdatatype_nsec3)
   17929 		CHECK(dns_db_findnsec3node(db, name, false, &node));
   17930 	else
   17931 		CHECK(dns_db_findnode(db, name, false, &node));
   17932 	result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
   17933 				     (isc_stdtime_t) 0, &rdataset, NULL);
   17934 	if (result == ISC_R_NOTFOUND) {
   17935 		*flag = false;
   17936 		result = ISC_R_SUCCESS;
   17937 		goto failure;
   17938 	}
   17939 
   17940 	for (result = dns_rdataset_first(&rdataset);
   17941 	     result == ISC_R_SUCCESS;
   17942 	     result = dns_rdataset_next(&rdataset)) {
   17943 		dns_rdata_t myrdata = DNS_RDATA_INIT;
   17944 		dns_rdataset_current(&rdataset, &myrdata);
   17945 		if (!dns_rdata_compare(&myrdata, rdata))
   17946 			break;
   17947 	}
   17948 	dns_rdataset_disassociate(&rdataset);
   17949 	if (result == ISC_R_SUCCESS) {
   17950 		*flag = true;
   17951 	} else if (result == ISC_R_NOMORE) {
   17952 		*flag = false;
   17953 		result = ISC_R_SUCCESS;
   17954 	}
   17955 
   17956  failure:
   17957 	if (node != NULL)
   17958 		dns_db_detachnode(db, &node);
   17959 	return (result);
   17960 }
   17961 
   17962 /*
   17963  * Add records to signal the state of signing or of key removal.
   17964  */
   17965 static isc_result_t
   17966 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
   17967 		    dns_dbversion_t *ver, dns_diff_t *diff,
   17968 		    bool sign_all)
   17969 {
   17970 	dns_difftuple_t *tuple, *newtuple = NULL;
   17971 	dns_rdata_dnskey_t dnskey;
   17972 	dns_rdata_t rdata = DNS_RDATA_INIT;
   17973 	bool flag;
   17974 	isc_region_t r;
   17975 	isc_result_t result = ISC_R_SUCCESS;
   17976 	uint16_t keyid;
   17977 	unsigned char buf[5];
   17978 	dns_name_t *name = dns_db_origin(db);
   17979 
   17980 	for (tuple = ISC_LIST_HEAD(diff->tuples);
   17981 	     tuple != NULL;
   17982 	     tuple = ISC_LIST_NEXT(tuple, link)) {
   17983 		if (tuple->rdata.type != dns_rdatatype_dnskey)
   17984 			continue;
   17985 
   17986 		result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
   17987 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   17988 		if ((dnskey.flags &
   17989 		     (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
   17990 			 != DNS_KEYOWNER_ZONE)
   17991 			continue;
   17992 
   17993 		dns_rdata_toregion(&tuple->rdata, &r);
   17994 
   17995 		keyid = dst_region_computeid(&r);
   17996 
   17997 		buf[0] = dnskey.algorithm;
   17998 		buf[1] = (keyid & 0xff00) >> 8;
   17999 		buf[2] = (keyid & 0xff);
   18000 		buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
   18001 		buf[4] = 0;
   18002 		rdata.data = buf;
   18003 		rdata.length = sizeof(buf);
   18004 		rdata.type = privatetype;
   18005 		rdata.rdclass = tuple->rdata.rdclass;
   18006 
   18007 		if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
   18008 			CHECK(rr_exists(db, ver, name, &rdata, &flag));
   18009 			if (flag)
   18010 				continue;
   18011 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   18012 						   name, 0, &rdata, &newtuple));
   18013 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   18014 			INSIST(newtuple == NULL);
   18015 		}
   18016 
   18017 		/*
   18018 		 * Remove any record which says this operation has already
   18019 		 * completed.
   18020 		 */
   18021 		buf[4] = 1;
   18022 		CHECK(rr_exists(db, ver, name, &rdata, &flag));
   18023 		if (flag) {
   18024 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
   18025 						   name, 0, &rdata, &newtuple));
   18026 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   18027 			INSIST(newtuple == NULL);
   18028 		}
   18029 	}
   18030  failure:
   18031 	return (result);
   18032 }
   18033 
   18034 static isc_result_t
   18035 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   18036 	  isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff)
   18037 {
   18038 	isc_result_t result;
   18039 	isc_stdtime_t inception, soaexpire, keyexpire;
   18040 	bool check_ksk, keyset_kskonly;
   18041 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   18042 	unsigned int nkeys = 0, i;
   18043 	dns_difftuple_t *tuple;
   18044 
   18045 	result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
   18046 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   18047 	if (result != ISC_R_SUCCESS) {
   18048 		dnssec_log(zone, ISC_LOG_ERROR,
   18049 			   "sign_apex:dns__zone_findkeys -> %s",
   18050 			   dns_result_totext(result));
   18051 		return (result);
   18052 	}
   18053 
   18054 	inception = now - 3600;	/* Allow for clock skew. */
   18055 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
   18056 
   18057 	keyexpire = dns_zone_getkeyvalidityinterval(zone);
   18058 	if (keyexpire == 0) {
   18059 		keyexpire = soaexpire - 1;
   18060 	} else {
   18061 		keyexpire += now;
   18062 	}
   18063 
   18064 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   18065 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   18066 
   18067 	/*
   18068 	 * See if dns__zone_updatesigs() will update DNSKEY signature and if
   18069 	 * not cause them to sign so that newly activated keys are used.
   18070 	 */
   18071 	for (tuple = ISC_LIST_HEAD(diff->tuples);
   18072 	     tuple != NULL;
   18073 	     tuple = ISC_LIST_NEXT(tuple, link))
   18074 	{
   18075 		if (tuple->rdata.type == dns_rdatatype_dnskey &&
   18076 		    dns_name_equal(&tuple->name, &zone->origin))
   18077 		{
   18078 			break;
   18079 		}
   18080 	}
   18081 
   18082 	if (tuple == NULL) {
   18083 		result = del_sigs(zone, db, ver, &zone->origin,
   18084 				  dns_rdatatype_dnskey, zonediff,
   18085 				  zone_keys, nkeys, now, false);
   18086 		if (result != ISC_R_SUCCESS) {
   18087 			dnssec_log(zone, ISC_LOG_ERROR,
   18088 				   "sign_apex:del_sigs -> %s",
   18089 				   dns_result_totext(result));
   18090 			goto failure;
   18091 		}
   18092 		result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
   18093 				  zonediff->diff, zone_keys, nkeys, zone->mctx,
   18094 				  inception, keyexpire, check_ksk,
   18095 				  keyset_kskonly);
   18096 		if (result != ISC_R_SUCCESS) {
   18097 			dnssec_log(zone, ISC_LOG_ERROR,
   18098 				   "sign_apex:add_sigs -> %s",
   18099 				   dns_result_totext(result));
   18100 			goto failure;
   18101 		}
   18102 	}
   18103 
   18104 	result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
   18105 				      inception, soaexpire, keyexpire, now,
   18106 				      check_ksk, keyset_kskonly, zonediff);
   18107 
   18108 	if (result != ISC_R_SUCCESS) {
   18109 		dnssec_log(zone, ISC_LOG_ERROR,
   18110 			   "sign_apex:dns__zone_updatesigs -> %s",
   18111 			   dns_result_totext(result));
   18112 		goto failure;
   18113 	}
   18114 
   18115  failure:
   18116 	for (i = 0; i < nkeys; i++) {
   18117 		dst_key_free(&zone_keys[i]);
   18118 	}
   18119 	return (result);
   18120 }
   18121 
   18122 /*
   18123  * Prevent the zone entering a inconsistent state where
   18124  * NSEC only DNSKEYs are present with NSEC3 chains.
   18125  * See update.c:check_dnssec()
   18126  */
   18127 static bool
   18128 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   18129 	    dns_diff_t *diff)
   18130 {
   18131 	isc_result_t result;
   18132 	dns_difftuple_t *tuple;
   18133 	bool nseconly = false, nsec3 = false;
   18134 	dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
   18135 
   18136 	/* Scan the tuples for an NSEC-only DNSKEY */
   18137 	for (tuple = ISC_LIST_HEAD(diff->tuples);
   18138 	     tuple != NULL;
   18139 	     tuple = ISC_LIST_NEXT(tuple, link))
   18140 	{
   18141 		uint8_t alg;
   18142 		if (tuple->rdata.type != dns_rdatatype_dnskey ||
   18143 		    tuple->op != DNS_DIFFOP_ADD)
   18144 		{
   18145 			continue;
   18146 		}
   18147 
   18148 		alg = tuple->rdata.data[3];
   18149 		if (alg == DST_ALG_RSASHA1) {
   18150 			nseconly = true;
   18151 			break;
   18152 		}
   18153 	}
   18154 
   18155 	/* Check existing DB for NSEC-only DNSKEY */
   18156 	if (!nseconly) {
   18157 		result = dns_nsec_nseconly(db, ver, &nseconly);
   18158 		if (result == ISC_R_NOTFOUND) {
   18159 			result = ISC_R_SUCCESS;
   18160 		}
   18161 		CHECK(result);
   18162 	}
   18163 
   18164 	/* Check existing DB for NSEC3 */
   18165 	if (!nsec3) {
   18166 		CHECK(dns_nsec3_activex(db, ver, false,
   18167 					privatetype, &nsec3));
   18168 	}
   18169 
   18170 	/* Refuse to allow NSEC3 with NSEC-only keys */
   18171 	if (nseconly && nsec3) {
   18172 		dnssec_log(zone, ISC_LOG_ERROR,
   18173 			   "NSEC only DNSKEYs and NSEC3 chains not allowed");
   18174 		goto failure;
   18175 	}
   18176 
   18177 	return (true);
   18178 
   18179  failure:
   18180 	return (false);
   18181 }
   18182 
   18183 static isc_result_t
   18184 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   18185 		 dns_diff_t *diff)
   18186 {
   18187 	isc_result_t result;
   18188 	dns_dbnode_t *node = NULL;
   18189 	dns_rdataset_t rdataset;
   18190 
   18191 	dns_rdataset_init(&rdataset);
   18192 	CHECK(dns_db_getoriginnode(db, &node));
   18193 
   18194 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   18195 				     dns_rdatatype_none, 0, &rdataset, NULL);
   18196 	if (dns_rdataset_isassociated(&rdataset))
   18197 		dns_rdataset_disassociate(&rdataset);
   18198 	if (result != ISC_R_NOTFOUND)
   18199 		goto failure;
   18200 
   18201 	result = dns_nsec3param_deletechains(db, ver, zone, true, diff);
   18202 
   18203  failure:
   18204 	if (node != NULL)
   18205 		dns_db_detachnode(db, &node);
   18206 	return (result);
   18207 }
   18208 
   18209 /*
   18210  * Given an RRSIG rdataset and an algorithm, determine whether there
   18211  * are any signatures using that algorithm.
   18212  */
   18213 static bool
   18214 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
   18215 	dns_rdata_t rdata = DNS_RDATA_INIT;
   18216 	dns_rdata_rrsig_t rrsig;
   18217 	isc_result_t result;
   18218 
   18219 	REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
   18220 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
   18221 		return (false);
   18222 	}
   18223 
   18224 	for (result = dns_rdataset_first(rdataset);
   18225 	     result == ISC_R_SUCCESS;
   18226 	     result = dns_rdataset_next(rdataset))
   18227 	{
   18228 		dns_rdataset_current(rdataset, &rdata);
   18229 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   18230 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   18231 		dns_rdata_reset(&rdata);
   18232 		if (rrsig.algorithm == alg)
   18233 			return (true);
   18234 	}
   18235 
   18236 	return (false);
   18237 }
   18238 
   18239 static isc_result_t
   18240 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   18241 	   dns_diff_t *diff)
   18242 {
   18243 	dns_name_t *origin;
   18244 	bool build_nsec3;
   18245 	isc_result_t result;
   18246 
   18247 	origin = dns_db_origin(db);
   18248 	CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
   18249 				 &build_nsec3));
   18250 	if (build_nsec3)
   18251 		CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
   18252 					   false, zone->privatetype, diff));
   18253 	CHECK(updatesecure(db, ver, origin, zone->minimum, true, diff));
   18254 
   18255  failure:
   18256 	return (result);
   18257 }
   18258 
   18259 static void
   18260 dnssec_report(const char *format, ...) {
   18261 	va_list args;
   18262 	va_start(args, format);
   18263 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE,
   18264 		       ISC_LOG_INFO, format, args);
   18265 	va_end(args);
   18266 }
   18267 
   18268 static void
   18269 zone_rekey(dns_zone_t *zone) {
   18270 	isc_result_t result;
   18271 	dns_db_t *db = NULL;
   18272 	dns_dbnode_t *node = NULL;
   18273 	dns_dbversion_t *ver = NULL;
   18274 	dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset;
   18275 	dns_dnsseckeylist_t dnskeys, keys, rmkeys;
   18276 	dns_dnsseckey_t *key = NULL;
   18277 	dns_diff_t diff, _sig_diff;
   18278 	dns__zonediff_t zonediff;
   18279 	bool commit = false, newactive = false;
   18280 	bool newalg = false;
   18281 	bool fullsign;
   18282 	dns_ttl_t ttl = 3600;
   18283 	const char *dir = NULL;
   18284 	isc_mem_t *mctx = NULL;
   18285 	isc_stdtime_t now;
   18286 	isc_time_t timenow;
   18287 	isc_interval_t ival;
   18288 	char timebuf[80];
   18289 
   18290 	REQUIRE(DNS_ZONE_VALID(zone));
   18291 
   18292 	ISC_LIST_INIT(dnskeys);
   18293 	ISC_LIST_INIT(keys);
   18294 	ISC_LIST_INIT(rmkeys);
   18295 	dns_rdataset_init(&soaset);
   18296 	dns_rdataset_init(&soasigs);
   18297 	dns_rdataset_init(&keyset);
   18298 	dns_rdataset_init(&keysigs);
   18299 	dns_rdataset_init(&cdsset);
   18300 	dns_rdataset_init(&cdnskeyset);
   18301 	dir = dns_zone_getkeydirectory(zone);
   18302 	mctx = zone->mctx;
   18303 	dns_diff_init(mctx, &diff);
   18304 	dns_diff_init(mctx, &_sig_diff);
   18305 	zonediff_init(&zonediff, &_sig_diff);
   18306 
   18307 	CHECK(dns_zone_getdb(zone, &db));
   18308 	CHECK(dns_db_newversion(db, &ver));
   18309 	CHECK(dns_db_getoriginnode(db, &node));
   18310 
   18311 	TIME_NOW(&timenow);
   18312 	now = isc_time_seconds(&timenow);
   18313 
   18314 	dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
   18315 
   18316 	/* Get the SOA record's TTL */
   18317 	CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
   18318 				  dns_rdatatype_none, 0, &soaset, &soasigs));
   18319 	ttl = soaset.ttl;
   18320 	dns_rdataset_disassociate(&soaset);
   18321 
   18322 	/* Get the DNSKEY rdataset */
   18323 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   18324 				     dns_rdatatype_none, 0, &keyset, &keysigs);
   18325 	if (result == ISC_R_SUCCESS) {
   18326 		ttl = keyset.ttl;
   18327 		CHECK(dns_dnssec_keylistfromrdataset(&zone->origin, dir,
   18328 						     mctx, &keyset,
   18329 						     &keysigs, &soasigs,
   18330 						     false, false,
   18331 						     &dnskeys));
   18332 	} else if (result != ISC_R_NOTFOUND) {
   18333 		goto failure;
   18334 	}
   18335 
   18336 
   18337 	/* Get the CDS rdataset */
   18338 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds,
   18339 				     dns_rdatatype_none, 0, &cdsset, NULL);
   18340 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset))
   18341 		dns_rdataset_disassociate(&cdsset);
   18342 
   18343 	/* Get the CDNSKEY rdataset */
   18344 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey,
   18345 				     dns_rdatatype_none, 0, &cdnskeyset, NULL);
   18346 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset))
   18347 	{
   18348 		dns_rdataset_disassociate(&cdnskeyset);
   18349 	}
   18350 
   18351 	/*
   18352 	 * True when called from "rndc sign".  Indicates the zone should be
   18353 	 * fully signed now.
   18354 	 */
   18355 	fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
   18356 
   18357 	result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
   18358 					     &keys);
   18359 	if (result == ISC_R_SUCCESS) {
   18360 		bool check_ksk;
   18361 		check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   18362 
   18363 		result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
   18364 					       &zone->origin, ttl, &diff,
   18365 					       !check_ksk, mctx,
   18366 					       dnssec_report);
   18367 		/*
   18368 		 * Keys couldn't be updated for some reason;
   18369 		 * try again later.
   18370 		 */
   18371 		if (result != ISC_R_SUCCESS) {
   18372 			dnssec_log(zone, ISC_LOG_ERROR,
   18373 				   "zone_rekey:couldn't update zone keys: %s",
   18374 				   isc_result_totext(result));
   18375 			goto failure;
   18376 		}
   18377 
   18378 		/*
   18379 		 * Update CDS / CDNSKEY records.
   18380 		 */
   18381 		result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset,
   18382 					       &cdnskeyset, now, ttl,
   18383 					       &diff, mctx);
   18384 		if (result != ISC_R_SUCCESS) {
   18385 			dnssec_log(zone, ISC_LOG_ERROR,
   18386 				   "zone_rekey:couldn't update CDS/CDNSKEY: %s",
   18387 				   isc_result_totext(result));
   18388 			goto failure;
   18389 		}
   18390 
   18391 		/*
   18392 		 * See if any pre-existing keys have newly become active;
   18393 		 * also, see if any new key is for a new algorithm, as in that
   18394 		 * event, we need to sign the zone fully.  (If there's a new
   18395 		 * key, but it's for an already-existing algorithm, then
   18396 		 * the zone signing can be handled incrementally.)
   18397 		 */
   18398 		for (key = ISC_LIST_HEAD(dnskeys);
   18399 		     key != NULL;
   18400 		     key = ISC_LIST_NEXT(key, link))
   18401 		{
   18402 			if (!key->first_sign) {
   18403 				continue;
   18404 			}
   18405 
   18406 			newactive = true;
   18407 
   18408 			if (!dns_rdataset_isassociated(&keysigs)) {
   18409 				newalg = true;
   18410 				break;
   18411 			}
   18412 
   18413 			if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
   18414 				/*
   18415 				 * This isn't a new algorithm; clear
   18416 				 * first_sign so we won't sign the
   18417 				 * whole zone with this key later
   18418 				 */
   18419 				key->first_sign = false;
   18420 			} else {
   18421 				newalg = true;
   18422 				break;
   18423 			}
   18424 		}
   18425 
   18426 		if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
   18427 		    dnskey_sane(zone, db, ver, &diff))
   18428 		{
   18429 			CHECK(dns_diff_apply(&diff, db, ver));
   18430 			CHECK(clean_nsec3param(zone, db, ver, &diff));
   18431 			CHECK(add_signing_records(db, zone->privatetype,
   18432 						  ver, &diff,
   18433 						  (newalg || fullsign)));
   18434 			CHECK(update_soa_serial(db, ver, &diff, mctx,
   18435 						zone->updatemethod));
   18436 			CHECK(add_chains(zone, db, ver, &diff));
   18437 			CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff));
   18438 			CHECK(zone_journal(zone, zonediff.diff, NULL,
   18439 					   "zone_rekey"));
   18440 			commit = true;
   18441 		}
   18442 	}
   18443 
   18444 	dns_db_closeversion(db, &ver, true);
   18445 
   18446 	if (commit) {
   18447 		dns_difftuple_t *tuple;
   18448 
   18449 		LOCK_ZONE(zone);
   18450 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   18451 
   18452 		zone_needdump(zone, DNS_DUMP_DELAY);
   18453 
   18454 		zone_settimer(zone, &timenow);
   18455 
   18456 		/* Remove any signatures from removed keys.  */
   18457 		if (!ISC_LIST_EMPTY(rmkeys)) {
   18458 			for (key = ISC_LIST_HEAD(rmkeys);
   18459 			     key != NULL;
   18460 			     key = ISC_LIST_NEXT(key, link))
   18461 			{
   18462 				result = zone_signwithkey(zone,
   18463 							  dst_key_alg(key->key),
   18464 							  dst_key_id(key->key),
   18465 							  true);
   18466 				if (result != ISC_R_SUCCESS) {
   18467 					dnssec_log(zone, ISC_LOG_ERROR,
   18468 					   "zone_signwithkey failed: %s",
   18469 					   dns_result_totext(result));
   18470 				}
   18471 			}
   18472 		}
   18473 
   18474 		if (fullsign) {
   18475 			/*
   18476 			 * "rndc sign" was called, so we now sign the zone
   18477 			 * with all active keys, whether they're new or not.
   18478 			 */
   18479 			for (key = ISC_LIST_HEAD(dnskeys);
   18480 			     key != NULL;
   18481 			     key = ISC_LIST_NEXT(key, link))
   18482 			{
   18483 				if (!key->force_sign && !key->hint_sign) {
   18484 					continue;
   18485 				}
   18486 
   18487 				result = zone_signwithkey(zone,
   18488 							  dst_key_alg(key->key),
   18489 							  dst_key_id(key->key),
   18490 							  false);
   18491 				if (result != ISC_R_SUCCESS) {
   18492 					dnssec_log(zone, ISC_LOG_ERROR,
   18493 					   "zone_signwithkey failed: %s",
   18494 					   dns_result_totext(result));
   18495 				}
   18496 			}
   18497 		} else if (newalg) {
   18498 			/*
   18499 			 * We haven't been told to sign fully, but a new
   18500 			 * algorithm was added to the DNSKEY.  We sign
   18501 			 * the full zone, but only with newly active
   18502 			 * keys.
   18503 			 */
   18504 			for (key = ISC_LIST_HEAD(dnskeys);
   18505 			     key != NULL;
   18506 			     key = ISC_LIST_NEXT(key, link))
   18507 			{
   18508 				if (!key->first_sign) {
   18509 					continue;
   18510 				}
   18511 
   18512 				result = zone_signwithkey(zone,
   18513 							  dst_key_alg(key->key),
   18514 							  dst_key_id(key->key),
   18515 							  false);
   18516 				if (result != ISC_R_SUCCESS) {
   18517 					dnssec_log(zone, ISC_LOG_ERROR,
   18518 					   "zone_signwithkey failed: %s",
   18519 					   dns_result_totext(result));
   18520 				}
   18521 			}
   18522 		}
   18523 
   18524 		/*
   18525 		 * Clear fullsign flag, if it was set, so we don't do
   18526 		 * another full signing next time
   18527 		 */
   18528 		zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
   18529 
   18530 		/*
   18531 		 * Cause the zone to add/delete NSEC3 chains for the
   18532 		 * deferred NSEC3PARAM changes.
   18533 		 */
   18534 		for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
   18535 		     tuple != NULL;
   18536 		     tuple = ISC_LIST_NEXT(tuple, link))
   18537 		{
   18538 			unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   18539 			dns_rdata_t rdata = DNS_RDATA_INIT;
   18540 			dns_rdata_nsec3param_t nsec3param;
   18541 
   18542 			if (tuple->rdata.type != zone->privatetype ||
   18543 			    tuple->op != DNS_DIFFOP_ADD)
   18544 			{
   18545 				continue;
   18546 			}
   18547 
   18548 			if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
   18549 							buf, sizeof(buf)))
   18550 			{
   18551 				continue;
   18552 			}
   18553 
   18554 			result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   18555 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   18556 			if (nsec3param.flags == 0) {
   18557 				continue;
   18558 			}
   18559 
   18560 			result = zone_addnsec3chain(zone, &nsec3param);
   18561 			if (result != ISC_R_SUCCESS) {
   18562 				dnssec_log(zone, ISC_LOG_ERROR,
   18563 					   "zone_addnsec3chain failed: %s",
   18564 					   dns_result_totext(result));
   18565 			}
   18566 		}
   18567 
   18568 		/*
   18569 		 * Activate any NSEC3 chain updates that may have
   18570 		 * been scheduled before this rekey.
   18571 		 */
   18572 		if (fullsign || newalg) {
   18573 			resume_addnsec3chain(zone);
   18574 		}
   18575 
   18576 		/*
   18577 		 * Schedule the next resigning event
   18578 		 */
   18579 		set_resigntime(zone);
   18580 		UNLOCK_ZONE(zone);
   18581 	}
   18582 
   18583 	isc_time_settoepoch(&zone->refreshkeytime);
   18584 
   18585 	/*
   18586 	 * If we're doing key maintenance, set the key refresh timer to
   18587 	 * the next scheduled key event or to 'dnssec-loadkeys-interval'
   18588 	 * seconds in the future, whichever is sooner.
   18589 	 */
   18590 	if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
   18591 		isc_time_t timethen;
   18592 		isc_stdtime_t then;
   18593 
   18594 		LOCK_ZONE(zone);
   18595 		DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
   18596 				  &timethen);
   18597 		zone->refreshkeytime = timethen;
   18598 		UNLOCK_ZONE(zone);
   18599 
   18600 		for (key = ISC_LIST_HEAD(dnskeys);
   18601 		     key != NULL;
   18602 		     key = ISC_LIST_NEXT(key, link))
   18603 		{
   18604 			then = now;
   18605 			result = next_keyevent(key->key, &then);
   18606 			if (result != ISC_R_SUCCESS) {
   18607 				continue;
   18608 			}
   18609 
   18610 			DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   18611 			LOCK_ZONE(zone);
   18612 			if (isc_time_compare(&timethen,
   18613 					     &zone->refreshkeytime) < 0)
   18614 			{
   18615 				zone->refreshkeytime = timethen;
   18616 			}
   18617 			UNLOCK_ZONE(zone);
   18618 		}
   18619 
   18620 		zone_settimer(zone, &timenow);
   18621 
   18622 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   18623 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   18624 	}
   18625 
   18626 	result = ISC_R_SUCCESS;
   18627 
   18628  failure:
   18629 	if (result != ISC_R_SUCCESS) {
   18630 		/*
   18631 		 * Something went wrong; try again in ten minutes or
   18632 		 * after a key refresh interval, whichever is shorter.
   18633 		 */
   18634 		isc_interval_set(&ival,
   18635 				 ISC_MIN(zone->refreshkeyinterval, 600), 0);
   18636 		isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
   18637 	}
   18638 
   18639 	dns_diff_clear(&diff);
   18640 	dns_diff_clear(&_sig_diff);
   18641 
   18642 	clear_keylist(&dnskeys, mctx);
   18643 	clear_keylist(&keys, mctx);
   18644 	clear_keylist(&rmkeys, mctx);
   18645 
   18646 	if (ver != NULL) {
   18647 		dns_db_closeversion(db, &ver, false);
   18648 	}
   18649 	if (dns_rdataset_isassociated(&cdsset)) {
   18650 		dns_rdataset_disassociate(&cdsset);
   18651 	}
   18652 	if (dns_rdataset_isassociated(&keyset)) {
   18653 		dns_rdataset_disassociate(&keyset);
   18654 	}
   18655 	if (dns_rdataset_isassociated(&keysigs)) {
   18656 		dns_rdataset_disassociate(&keysigs);
   18657 	}
   18658 	if (dns_rdataset_isassociated(&soasigs)) {
   18659 		dns_rdataset_disassociate(&soasigs);
   18660 	}
   18661 	if (dns_rdataset_isassociated(&cdnskeyset)) {
   18662 		dns_rdataset_disassociate(&cdnskeyset);
   18663 	}
   18664 	if (node != NULL) {
   18665 		dns_db_detachnode(db, &node);
   18666 	}
   18667 	if (db != NULL) {
   18668 		dns_db_detach(&db);
   18669 	}
   18670 
   18671 	INSIST(ver == NULL);
   18672 }
   18673 
   18674 void
   18675 dns_zone_rekey(dns_zone_t *zone, bool fullsign) {
   18676 	isc_time_t now;
   18677 
   18678 	if (zone->type == dns_zone_master && zone->task != NULL) {
   18679 		LOCK_ZONE(zone);
   18680 
   18681 		if (fullsign)
   18682 			zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
   18683 
   18684 		TIME_NOW(&now);
   18685 		zone->refreshkeytime = now;
   18686 		zone_settimer(zone, &now);
   18687 
   18688 		UNLOCK_ZONE(zone);
   18689 	}
   18690 }
   18691 
   18692 isc_result_t
   18693 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   18694 		 unsigned int *errors)
   18695 {
   18696 	isc_result_t result;
   18697 	dns_dbnode_t *node = NULL;
   18698 
   18699 	REQUIRE(DNS_ZONE_VALID(zone));
   18700 	REQUIRE(errors != NULL);
   18701 
   18702 	result = dns_db_getoriginnode(db, &node);
   18703 	if (result != ISC_R_SUCCESS)
   18704 		return (result);
   18705 	result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
   18706 				  false);
   18707 	dns_db_detachnode(db, &node);
   18708 	return (result);
   18709 }
   18710 
   18711 isc_result_t
   18712 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
   18713 	isc_result_t result;
   18714 	dns_dbnode_t *node = NULL;
   18715 	dns_rdataset_t dnskey, cds, cdnskey;
   18716 	unsigned char buffer[DNS_DS_BUFFERSIZE];
   18717 	unsigned char algorithms[256];
   18718 	unsigned int i;
   18719 
   18720 	REQUIRE(DNS_ZONE_VALID(zone));
   18721 
   18722 	result = dns_db_getoriginnode(db, &node);
   18723 	if (result != ISC_R_SUCCESS)
   18724 		return (result);
   18725 
   18726 	dns_rdataset_init(&cds);
   18727 	dns_rdataset_init(&dnskey);
   18728 	dns_rdataset_init(&cdnskey);
   18729 
   18730 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
   18731 				     dns_rdatatype_none, 0, &cds, NULL);
   18732 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
   18733 		goto failure;
   18734 
   18735 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
   18736 				     dns_rdatatype_none, 0, &cdnskey, NULL);
   18737 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
   18738 		goto failure;
   18739 
   18740 	if (!dns_rdataset_isassociated(&cds) &&
   18741 	    !dns_rdataset_isassociated(&cdnskey)) {
   18742 		result = ISC_R_SUCCESS;
   18743 		goto failure;
   18744 	}
   18745 
   18746 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   18747 				     dns_rdatatype_none, 0, &dnskey, NULL);
   18748 	if (result == ISC_R_NOTFOUND) {
   18749 		if (dns_rdataset_isassociated(&cds))
   18750 			result = DNS_R_BADCDS;
   18751 		else
   18752 			result = DNS_R_BADCDNSKEY;
   18753 		goto failure;
   18754 	}
   18755 	if (result != ISC_R_SUCCESS)
   18756 		goto failure;
   18757 
   18758 	/*
   18759 	 * For each DNSSEC algorithm in the CDS RRset there must be
   18760 	 * a matching DNSKEY record.
   18761 	 */
   18762 	if (dns_rdataset_isassociated(&cds)) {
   18763 		memset(algorithms, 0, sizeof(algorithms));
   18764 		for (result = dns_rdataset_first(&cds);
   18765 		     result == ISC_R_SUCCESS;
   18766 		     result = dns_rdataset_next(&cds)) {
   18767 			dns_rdata_t crdata = DNS_RDATA_INIT;
   18768 			dns_rdata_cds_t structcds;
   18769 
   18770 			dns_rdataset_current(&cds, &crdata);
   18771 			CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
   18772 			if (algorithms[structcds.algorithm] == 0)
   18773 				algorithms[structcds.algorithm] = 1;
   18774 			for (result = dns_rdataset_first(&dnskey);
   18775 			     result == ISC_R_SUCCESS;
   18776 			     result = dns_rdataset_next(&dnskey)) {
   18777 				dns_rdata_t rdata = DNS_RDATA_INIT;
   18778 				dns_rdata_t dsrdata = DNS_RDATA_INIT;
   18779 
   18780 				dns_rdataset_current(&dnskey, &rdata);
   18781 				CHECK(dns_ds_buildrdata(&zone->origin, &rdata,
   18782 							structcds.digest_type,
   18783 							buffer, &dsrdata));
   18784 				if (crdata.length == dsrdata.length &&
   18785 				    memcmp(crdata.data, dsrdata.data,
   18786 					   dsrdata.length) == 0) {
   18787 					algorithms[structcds.algorithm] = 2;
   18788 				}
   18789 			}
   18790 			if (result != ISC_R_NOMORE)
   18791 				goto failure;
   18792 		}
   18793 		for (i = 0; i < sizeof(algorithms); i++) {
   18794 			if (algorithms[i] == 1) {
   18795 				result = DNS_R_BADCDNSKEY;
   18796 				goto failure;
   18797 			}
   18798 		}
   18799 	}
   18800 
   18801 	/*
   18802 	 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
   18803 	 * a matching DNSKEY record.
   18804 	 */
   18805 	if (dns_rdataset_isassociated(&cdnskey)) {
   18806 		memset(algorithms, 0, sizeof(algorithms));
   18807 		for (result = dns_rdataset_first(&cdnskey);
   18808 		     result == ISC_R_SUCCESS;
   18809 		     result = dns_rdataset_next(&cdnskey)) {
   18810 			dns_rdata_t crdata = DNS_RDATA_INIT;
   18811 			dns_rdata_cdnskey_t structcdnskey;
   18812 
   18813 			dns_rdataset_current(&cdnskey, &crdata);
   18814 			CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
   18815 						 NULL));
   18816 			if (algorithms[structcdnskey.algorithm] == 0)
   18817 				algorithms[structcdnskey.algorithm] = 1;
   18818 			for (result = dns_rdataset_first(&dnskey);
   18819 			     result == ISC_R_SUCCESS;
   18820 			     result = dns_rdataset_next(&dnskey)) {
   18821 				dns_rdata_t rdata = DNS_RDATA_INIT;
   18822 
   18823 				dns_rdataset_current(&dnskey, &rdata);
   18824 				if (crdata.length == rdata.length &&
   18825 				    memcmp(crdata.data, rdata.data,
   18826 					   rdata.length) == 0) {
   18827 					algorithms[structcdnskey.algorithm] = 2;
   18828 				}
   18829 			}
   18830 			if (result != ISC_R_NOMORE)
   18831 				goto failure;
   18832 		}
   18833 		for (i = 0; i < sizeof(algorithms); i++) {
   18834 			if (algorithms[i] == 1) {
   18835 				result = DNS_R_BADCDS;
   18836 				goto failure;
   18837 			}
   18838 		}
   18839 	}
   18840 	result = ISC_R_SUCCESS;
   18841 
   18842  failure:
   18843 	if (dns_rdataset_isassociated(&cds))
   18844 		dns_rdataset_disassociate(&cds);
   18845 	if (dns_rdataset_isassociated(&dnskey))
   18846 		dns_rdataset_disassociate(&dnskey);
   18847 	if (dns_rdataset_isassociated(&cdnskey))
   18848 		dns_rdataset_disassociate(&cdnskey);
   18849 	dns_db_detachnode(db, &node);
   18850 	return (result);
   18851 }
   18852 
   18853 void
   18854 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
   18855 	REQUIRE(DNS_ZONE_VALID(zone));
   18856 
   18857 	LOCK_ZONE(zone);
   18858 	zone->automatic = automatic;
   18859 	UNLOCK_ZONE(zone);
   18860 }
   18861 
   18862 bool
   18863 dns_zone_getautomatic(dns_zone_t *zone) {
   18864 	REQUIRE(DNS_ZONE_VALID(zone));
   18865 	return (zone->automatic);
   18866 }
   18867 
   18868 void
   18869 dns_zone_setadded(dns_zone_t *zone, bool added) {
   18870 	REQUIRE(DNS_ZONE_VALID(zone));
   18871 
   18872 	LOCK_ZONE(zone);
   18873 	zone->added = added;
   18874 	UNLOCK_ZONE(zone);
   18875 }
   18876 
   18877 bool
   18878 dns_zone_getadded(dns_zone_t *zone) {
   18879 	REQUIRE(DNS_ZONE_VALID(zone));
   18880 	return (zone->added);
   18881 }
   18882 
   18883 isc_result_t
   18884 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
   18885 {
   18886 	isc_time_t loadtime;
   18887 	isc_result_t result;
   18888 	dns_zone_t *secure = NULL;
   18889 
   18890 	TIME_NOW(&loadtime);
   18891 
   18892 	/*
   18893 	 * Lock hierarchy: zmgr, zone, raw.
   18894 	 */
   18895  again:
   18896 	LOCK_ZONE(zone);
   18897 	INSIST(zone != zone->raw);
   18898 	if (inline_secure(zone))
   18899 		LOCK_ZONE(zone->raw);
   18900 	else if (inline_raw(zone)) {
   18901 		secure = zone->secure;
   18902 		TRYLOCK_ZONE(result, secure);
   18903 		if (result != ISC_R_SUCCESS) {
   18904 			UNLOCK_ZONE(zone);
   18905 			secure = NULL;
   18906 			isc_thread_yield();
   18907 			goto again;
   18908 		}
   18909 	}
   18910 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   18911 	if (inline_secure(zone))
   18912 		UNLOCK_ZONE(zone->raw);
   18913 	else if (secure != NULL)
   18914 		UNLOCK_ZONE(secure);
   18915 	UNLOCK_ZONE(zone);
   18916 	return result;
   18917 }
   18918 
   18919 isc_result_t
   18920 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
   18921 	REQUIRE(DNS_ZONE_VALID(zone));
   18922 	if (interval == 0)
   18923 		return (ISC_R_RANGE);
   18924 	/* Maximum value: 24 hours (3600 minutes) */
   18925 	if (interval > (24 * 60))
   18926 		interval = (24 * 60);
   18927 	/* Multiply by 60 for seconds */
   18928 	zone->refreshkeyinterval = interval * 60;
   18929 	return (ISC_R_SUCCESS);
   18930 }
   18931 
   18932 void
   18933 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
   18934 	REQUIRE(DNS_ZONE_VALID(zone));
   18935 	zone->requestixfr = flag;
   18936 }
   18937 
   18938 bool
   18939 dns_zone_getrequestixfr(dns_zone_t *zone) {
   18940 	REQUIRE(DNS_ZONE_VALID(zone));
   18941 	return (zone->requestixfr);
   18942 }
   18943 
   18944 void
   18945 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
   18946 	REQUIRE(DNS_ZONE_VALID(zone));
   18947 	zone->requestexpire = flag;
   18948 }
   18949 
   18950 bool
   18951 dns_zone_getrequestexpire(dns_zone_t *zone) {
   18952 	REQUIRE(DNS_ZONE_VALID(zone));
   18953 	return (zone->requestexpire);
   18954 }
   18955 
   18956 void
   18957 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
   18958 	REQUIRE(DNS_ZONE_VALID(zone));
   18959 	zone->updatemethod = method;
   18960 }
   18961 
   18962 dns_updatemethod_t
   18963 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
   18964 	REQUIRE(DNS_ZONE_VALID(zone));
   18965 	return(zone->updatemethod);
   18966 }
   18967 
   18968 /*
   18969  * Lock hierarchy: zmgr, zone, raw.
   18970  */
   18971 isc_result_t
   18972 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
   18973 	isc_result_t result;
   18974 	dns_zonemgr_t *zmgr;
   18975 
   18976 	REQUIRE(DNS_ZONE_VALID(zone));
   18977 	REQUIRE(zone->zmgr != NULL);
   18978 	REQUIRE(zone->task != NULL);
   18979 	REQUIRE(zone->loadtask != NULL);
   18980 	REQUIRE(zone->raw == NULL);
   18981 
   18982 	REQUIRE(DNS_ZONE_VALID(raw));
   18983 	REQUIRE(raw->zmgr == NULL);
   18984 	REQUIRE(raw->task == NULL);
   18985 	REQUIRE(raw->loadtask == NULL);
   18986 	REQUIRE(raw->secure == NULL);
   18987 
   18988 	REQUIRE(zone != raw);
   18989 
   18990 	/*
   18991 	 * Lock hierarchy: zmgr, zone, raw.
   18992 	 */
   18993 	zmgr = zone->zmgr;
   18994 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18995 	LOCK_ZONE(zone);
   18996 	LOCK_ZONE(raw);
   18997 
   18998 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
   18999 				  NULL, NULL, zone->task, zone_timer, raw,
   19000 				  &raw->timer);
   19001 	if (result != ISC_R_SUCCESS)
   19002 		goto unlock;
   19003 
   19004 	/*
   19005 	 * The timer "holds" a iref.
   19006 	 */
   19007 	raw->irefs++;
   19008 	INSIST(raw->irefs != 0);
   19009 
   19010 
   19011 	/* dns_zone_attach(raw, &zone->raw); */
   19012 	isc_refcount_increment(&raw->erefs);
   19013 	zone->raw = raw;
   19014 
   19015 	/* dns_zone_iattach(zone,  &raw->secure); */
   19016 	zone_iattach(zone, &raw->secure);
   19017 
   19018 	isc_task_attach(zone->task, &raw->task);
   19019 	isc_task_attach(zone->loadtask, &raw->loadtask);
   19020 
   19021 	ISC_LIST_APPEND(zmgr->zones, raw, link);
   19022 	raw->zmgr = zmgr;
   19023 	zmgr->refs++;
   19024 
   19025  unlock:
   19026 	UNLOCK_ZONE(raw);
   19027 	UNLOCK_ZONE(zone);
   19028 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   19029 	return (result);
   19030 }
   19031 
   19032 void
   19033 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
   19034 	REQUIRE(DNS_ZONE_VALID(zone));
   19035 	REQUIRE(raw != NULL && *raw == NULL);
   19036 
   19037 	LOCK(&zone->lock);
   19038 	INSIST(zone != zone->raw);
   19039 	if (zone->raw != NULL)
   19040 		dns_zone_attach(zone->raw, raw);
   19041 	UNLOCK(&zone->lock);
   19042 }
   19043 
   19044 struct keydone {
   19045 	isc_event_t event;
   19046 	bool all;
   19047 	unsigned char data[5];
   19048 };
   19049 
   19050 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE|DNS_NSEC3FLAG_INITIAL)
   19051 
   19052 static void
   19053 keydone(isc_task_t *task, isc_event_t *event) {
   19054 	const char *me = "keydone";
   19055 	bool commit = false;
   19056 	isc_result_t result;
   19057 	dns_rdata_t rdata = DNS_RDATA_INIT;
   19058 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   19059 	dns_zone_t *zone;
   19060 	dns_db_t *db = NULL;
   19061 	dns_dbnode_t *node = NULL;
   19062 	dns_rdataset_t rdataset;
   19063 	dns_diff_t diff;
   19064 	struct keydone *kd = (struct keydone *)event;
   19065 	dns_update_log_t log = { update_log_cb, NULL };
   19066 	bool clear_pending = false;
   19067 
   19068 	UNUSED(task);
   19069 
   19070 	zone = event->ev_arg;
   19071 	INSIST(DNS_ZONE_VALID(zone));
   19072 
   19073 	ENTER;
   19074 
   19075 	dns_rdataset_init(&rdataset);
   19076 	dns_diff_init(zone->mctx, &diff);
   19077 
   19078 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   19079 	if (zone->db != NULL) {
   19080 		dns_db_attach(zone->db, &db);
   19081 	}
   19082 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   19083 	if (db == NULL) {
   19084 		goto failure;
   19085 	}
   19086 
   19087 	dns_db_currentversion(db, &oldver);
   19088 	result = dns_db_newversion(db, &newver);
   19089 	if (result != ISC_R_SUCCESS) {
   19090 		dnssec_log(zone, ISC_LOG_ERROR,
   19091 			   "keydone:dns_db_newversion -> %s",
   19092 			   dns_result_totext(result));
   19093 		goto failure;
   19094 	}
   19095 
   19096 	result = dns_db_getoriginnode(db, &node);
   19097 	if (result != ISC_R_SUCCESS) {
   19098 		goto failure;
   19099 	}
   19100 
   19101 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   19102 				     dns_rdatatype_none, 0, &rdataset, NULL);
   19103 	if (result == ISC_R_NOTFOUND) {
   19104 		INSIST(!dns_rdataset_isassociated(&rdataset));
   19105 		goto failure;
   19106 	}
   19107 	if (result != ISC_R_SUCCESS) {
   19108 		INSIST(!dns_rdataset_isassociated(&rdataset));
   19109 		goto failure;
   19110 	}
   19111 
   19112 	for (result = dns_rdataset_first(&rdataset);
   19113 	     result == ISC_R_SUCCESS;
   19114 	     result = dns_rdataset_next(&rdataset))
   19115 	{
   19116 		bool found = false;
   19117 
   19118 		dns_rdataset_current(&rdataset, &rdata);
   19119 
   19120 		if (kd->all) {
   19121 			if (rdata.length == 5 && rdata.data[0] != 0 &&
   19122 			       rdata.data[3] == 0 && rdata.data[4] == 1)
   19123 			{
   19124 				found = true;
   19125 			} else if (rdata.data[0] == 0 &&
   19126 				   (rdata.data[2] & PENDINGFLAGS) != 0)
   19127 			{
   19128 				found = true;
   19129 				clear_pending = true;
   19130 			}
   19131 		} else if (rdata.length == 5 &&
   19132 			   memcmp(rdata.data, kd->data, 5) == 0)
   19133 		{
   19134 			found = true;
   19135 		}
   19136 
   19137 		if (found) {
   19138 			CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
   19139 					    &zone->origin, rdataset.ttl,
   19140 					    &rdata));
   19141 		}
   19142 		dns_rdata_reset(&rdata);
   19143 	}
   19144 
   19145 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   19146 		/* Write changes to journal file. */
   19147 		CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
   19148 					zone->updatemethod));
   19149 
   19150 		result = dns_update_signatures(&log, zone, db,
   19151 					       oldver, newver, &diff,
   19152 					       zone->sigvalidityinterval);
   19153 		if (!clear_pending) {
   19154 			CHECK(result);
   19155 		}
   19156 
   19157 		CHECK(zone_journal(zone, &diff, NULL, "keydone"));
   19158 		commit = true;
   19159 
   19160 		LOCK_ZONE(zone);
   19161 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   19162 		zone_needdump(zone, 30);
   19163 		UNLOCK_ZONE(zone);
   19164 	}
   19165 
   19166  failure:
   19167 	if (dns_rdataset_isassociated(&rdataset)) {
   19168 		dns_rdataset_disassociate(&rdataset);
   19169 	}
   19170 	if (db != NULL) {
   19171 		if (node != NULL) {
   19172 			dns_db_detachnode(db, &node);
   19173 		}
   19174 		if (oldver != NULL) {
   19175 			dns_db_closeversion(db, &oldver, false);
   19176 		}
   19177 		if (newver != NULL) {
   19178 			dns_db_closeversion(db, &newver, commit);
   19179 		}
   19180 		dns_db_detach(&db);
   19181 	}
   19182 	dns_diff_clear(&diff);
   19183 	isc_event_free(&event);
   19184 	dns_zone_idetach(&zone);
   19185 
   19186 	INSIST(oldver == NULL);
   19187 	INSIST(newver == NULL);
   19188 }
   19189 
   19190 isc_result_t
   19191 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
   19192 	isc_result_t result = ISC_R_SUCCESS;
   19193 	isc_event_t *e;
   19194 	isc_buffer_t b;
   19195 	dns_zone_t *dummy = NULL;
   19196 	struct keydone *kd;
   19197 
   19198 	REQUIRE(DNS_ZONE_VALID(zone));
   19199 
   19200 	LOCK_ZONE(zone);
   19201 
   19202 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
   19203 			       zone, sizeof(struct keydone));
   19204 	if (e == NULL) {
   19205 		result = ISC_R_NOMEMORY;
   19206 		goto failure;
   19207 	}
   19208 
   19209 	kd = (struct keydone *) e;
   19210 	if (strcasecmp(keystr, "all") == 0) {
   19211 		kd->all = true;
   19212 	} else {
   19213 		isc_textregion_t r;
   19214 		const char *algstr;
   19215 		dns_keytag_t keyid;
   19216 		dns_secalg_t alg;
   19217 		size_t n;
   19218 
   19219 		kd->all = false;
   19220 
   19221 		n = sscanf(keystr, "%hu/", &keyid);
   19222 		if (n == 0U) {
   19223 			CHECK(ISC_R_FAILURE);
   19224 		}
   19225 
   19226 		algstr = strchr(keystr, '/');
   19227 		if (algstr != NULL) {
   19228 			algstr++;
   19229 		} else {
   19230 			CHECK(ISC_R_FAILURE);
   19231 		}
   19232 
   19233 		n = sscanf(algstr, "%hhu", &alg);
   19234 		if (n == 0U) {
   19235 			DE_CONST(algstr, r.base);
   19236 			r.length = strlen(algstr);
   19237 			CHECK(dns_secalg_fromtext(&alg, &r));
   19238 		}
   19239 
   19240 		/* construct a private-type rdata */
   19241 		isc_buffer_init(&b, kd->data, sizeof(kd->data));
   19242 		isc_buffer_putuint8(&b, alg);
   19243 		isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
   19244 		isc_buffer_putuint8(&b, (keyid & 0xff));
   19245 		isc_buffer_putuint8(&b, 0);
   19246 		isc_buffer_putuint8(&b, 1);
   19247 	}
   19248 
   19249 	zone_iattach(zone, &dummy);
   19250 	isc_task_send(zone->task, &e);
   19251 
   19252  failure:
   19253 	if (e != NULL) {
   19254 		isc_event_free(&e);
   19255 	}
   19256 	UNLOCK_ZONE(zone);
   19257 	return (result);
   19258 }
   19259 
   19260 /*
   19261  * Called from the zone task's queue after the relevant event is posted by
   19262  * dns_zone_setnsec3param().
   19263  *
   19264  * Check whether NSEC3 chain addition or removal specified by the private-type
   19265  * record passed with the event was already queued (or even fully performed).
   19266  * If not, modify the relevant private-type records at the zone apex and call
   19267  * resume_addnsec3chain().
   19268  */
   19269 static void
   19270 setnsec3param(isc_task_t *task, isc_event_t *event) {
   19271 	const char *me = "setnsec3param";
   19272 	bool commit = false;
   19273 	isc_result_t result;
   19274 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   19275 	dns_zone_t *zone;
   19276 	dns_db_t *db = NULL;
   19277 	dns_dbnode_t *node = NULL;
   19278 	dns_rdataset_t prdataset, nrdataset;
   19279 	dns_diff_t diff;
   19280 	struct np3event *npe = (struct np3event *)event;
   19281 	nsec3param_t *np;
   19282 	dns_update_log_t log = { update_log_cb, NULL };
   19283 	dns_rdata_t rdata;
   19284 	bool nseconly;
   19285 	bool exists = false;
   19286 
   19287 	UNUSED(task);
   19288 
   19289 	zone = event->ev_arg;
   19290 	INSIST(DNS_ZONE_VALID(zone));
   19291 
   19292 	ENTER;
   19293 
   19294 	np = &npe->params;
   19295 
   19296 	dns_rdataset_init(&prdataset);
   19297 	dns_rdataset_init(&nrdataset);
   19298 	dns_diff_init(zone->mctx, &diff);
   19299 
   19300 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   19301 	if (zone->db != NULL) {
   19302 		dns_db_attach(zone->db, &db);
   19303 	}
   19304 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   19305 	if (db == NULL) {
   19306 		goto failure;
   19307 	}
   19308 
   19309 	dns_db_currentversion(db, &oldver);
   19310 	result = dns_db_newversion(db, &newver);
   19311 	if (result != ISC_R_SUCCESS) {
   19312 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   19313 		dnssec_log(zone, ISC_LOG_ERROR,
   19314 			   "setnsec3param:dns_db_newversion -> %s",
   19315 			   dns_result_totext(result));
   19316 		goto failure;
   19317 	}
   19318 
   19319 	CHECK(dns_db_getoriginnode(db, &node));
   19320 
   19321 	/*
   19322 	 * Does a private-type record already exist for this chain?
   19323 	 */
   19324 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   19325 				     dns_rdatatype_none, 0, &prdataset, NULL);
   19326 	if (result == ISC_R_SUCCESS) {
   19327 		for (result = dns_rdataset_first(&prdataset);
   19328 		     result == ISC_R_SUCCESS;
   19329 		     result = dns_rdataset_next(&prdataset))
   19330 		{
   19331 			dns_rdata_init(&rdata);
   19332 			dns_rdataset_current(&prdataset, &rdata);
   19333 
   19334 			if (np->length == rdata.length &&
   19335 			    memcmp(rdata.data, np->data, np->length) == 0)
   19336 			{
   19337 				exists = true;
   19338 				break;
   19339 			}
   19340 		}
   19341 	} else if (result != ISC_R_NOTFOUND) {
   19342 		INSIST(!dns_rdataset_isassociated(&prdataset));
   19343 		goto failure;
   19344 	}
   19345 
   19346 	/*
   19347 	 * Does the chain already exist?
   19348 	 */
   19349 	result = dns_db_findrdataset(db, node, newver,
   19350 				     dns_rdatatype_nsec3param,
   19351 				     dns_rdatatype_none, 0, &nrdataset, NULL);
   19352 	if (result == ISC_R_SUCCESS) {
   19353 		for (result = dns_rdataset_first(&nrdataset);
   19354 		     result == ISC_R_SUCCESS;
   19355 		     result = dns_rdataset_next(&nrdataset))
   19356 		{
   19357 			dns_rdata_init(&rdata);
   19358 			dns_rdataset_current(&nrdataset, &rdata);
   19359 
   19360 			if (np->length == (rdata.length + 1) &&
   19361 			    memcmp(rdata.data, np->data + 1,
   19362 				   np->length - 1) == 0)
   19363 			{
   19364 				exists = true;
   19365 				break;
   19366 			}
   19367 		}
   19368 	} else if (result != ISC_R_NOTFOUND) {
   19369 		INSIST(!dns_rdataset_isassociated(&nrdataset));
   19370 		goto failure;
   19371 	}
   19372 
   19373 
   19374 	/*
   19375 	 * We need to remove any existing NSEC3 chains if the supplied NSEC3
   19376 	 * parameters are supposed to replace the current ones or if we are
   19377 	 * switching to NSEC.
   19378 	 */
   19379 	if (!exists && np->replace && (np->length != 0 || np->nsec)) {
   19380 		CHECK(dns_nsec3param_deletechains(db, newver, zone,
   19381 						  !np->nsec, &diff));
   19382 	}
   19383 
   19384 	if (!exists && np->length != 0) {
   19385 		/*
   19386 		 * We're creating an NSEC3 chain.  Add the private-type record
   19387 		 * passed in the event handler's argument to the zone apex.
   19388 		 *
   19389 		 * If the zone is not currently capable of supporting an NSEC3
   19390 		 * chain (due to the DNSKEY RRset at the zone apex not existing
   19391 		 * or containing at least one key using an NSEC-only
   19392 		 * algorithm), add the INITIAL flag, so these parameters can be
   19393 		 * used later when NSEC3 becomes available.
   19394 		 */
   19395 		dns_rdata_init(&rdata);
   19396 
   19397 		np->data[2] |= DNS_NSEC3FLAG_CREATE;
   19398 		result = dns_nsec_nseconly(db, newver, &nseconly);
   19399 		if (result == ISC_R_NOTFOUND || nseconly) {
   19400 			np->data[2] |= DNS_NSEC3FLAG_INITIAL;
   19401 		}
   19402 
   19403 		rdata.length = np->length;
   19404 		rdata.data = np->data;
   19405 		rdata.type = zone->privatetype;
   19406 		rdata.rdclass = zone->rdclass;
   19407 		CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
   19408 				    &zone->origin, 0, &rdata));
   19409 	}
   19410 
   19411 	/*
   19412 	 * If we changed anything in the zone, write changes to journal file
   19413 	 * and set commit to true so that resume_addnsec3chain() will be
   19414 	 * called below in order to kick off adding/removing relevant NSEC3
   19415 	 * records.
   19416 	 */
   19417 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   19418 		CHECK(update_soa_serial(db, newver, &diff, zone->mctx,
   19419 					zone->updatemethod));
   19420 		result = dns_update_signatures(&log, zone, db,
   19421 					       oldver, newver, &diff,
   19422 					       zone->sigvalidityinterval);
   19423 		if (result != ISC_R_NOTFOUND) {
   19424 			CHECK(result);
   19425 		}
   19426 		CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
   19427 		commit = true;
   19428 
   19429 		LOCK_ZONE(zone);
   19430 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   19431 		zone_needdump(zone, 30);
   19432 		UNLOCK_ZONE(zone);
   19433 	}
   19434 
   19435  failure:
   19436 	if (dns_rdataset_isassociated(&prdataset)) {
   19437 		dns_rdataset_disassociate(&prdataset);
   19438 	}
   19439 	if (dns_rdataset_isassociated(&nrdataset)) {
   19440 		dns_rdataset_disassociate(&nrdataset);
   19441 	}
   19442 	if (node != NULL) {
   19443 		dns_db_detachnode(db, &node);
   19444 	}
   19445 	if (oldver != NULL) {
   19446 		dns_db_closeversion(db, &oldver, false);
   19447 	}
   19448 	if (newver != NULL) {
   19449 		dns_db_closeversion(db, &newver, commit);
   19450 	}
   19451 	if (db != NULL) {
   19452 		dns_db_detach(&db);
   19453 	}
   19454 	if (commit) {
   19455 		LOCK_ZONE(zone);
   19456 		resume_addnsec3chain(zone);
   19457 		UNLOCK_ZONE(zone);
   19458 	}
   19459 	dns_diff_clear(&diff);
   19460 	isc_event_free(&event);
   19461 	dns_zone_idetach(&zone);
   19462 
   19463 	INSIST(oldver == NULL);
   19464 	INSIST(newver == NULL);
   19465 }
   19466 
   19467 /*
   19468  * Called when an "rndc signing -nsec3param ..." command is received.
   19469  *
   19470  * Allocate and prepare an nsec3param_t structure which holds information about
   19471  * the NSEC3 changes requested for the zone:
   19472  *
   19473  *   - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec"
   19474  *     field of the structure to true and the "replace" field to the value
   19475  *     of the "replace" argument, leaving other fields initialized to zeros, to
   19476  *     signal that the zone should be signed using NSEC instead of NSEC3,
   19477  *
   19478  *   - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at
   19479  *     the zone apex, convert it to a private-type record and store the latter
   19480  *     in the "data" field of the nsec3param_t structure.
   19481  *
   19482  * Once the nsec3param_t structure is prepared, post an event to the zone's
   19483  * task which will cause setnsec3param() to be called with the prepared
   19484  * structure passed as an argument.
   19485  */
   19486 isc_result_t
   19487 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags,
   19488 		       uint16_t iter, uint8_t saltlen,
   19489 		       unsigned char *salt, bool replace)
   19490 {
   19491 	isc_result_t result = ISC_R_SUCCESS;
   19492 	dns_rdata_nsec3param_t param;
   19493 	dns_rdata_t nrdata = DNS_RDATA_INIT;
   19494 	dns_rdata_t prdata = DNS_RDATA_INIT;
   19495 	unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
   19496 	struct np3event *npe;
   19497 	nsec3param_t *np;
   19498 	dns_zone_t *dummy = NULL;
   19499 	isc_buffer_t b;
   19500 	isc_event_t *e;
   19501 
   19502 	REQUIRE(DNS_ZONE_VALID(zone));
   19503 	REQUIRE(salt != NULL);
   19504 
   19505 	LOCK_ZONE(zone);
   19506 
   19507 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
   19508 			       setnsec3param, zone, sizeof(struct np3event));
   19509 	if (e == NULL) {
   19510 		result = ISC_R_NOMEMORY;
   19511 		goto failure;
   19512 	}
   19513 
   19514 	npe = (struct np3event *) e;
   19515 	np = &npe->params;
   19516 
   19517 	np->replace = replace;
   19518 	if (hash == 0) {
   19519 		np->length = 0;
   19520 		np->nsec = true;
   19521 	} else {
   19522 		param.common.rdclass = zone->rdclass;
   19523 		param.common.rdtype = dns_rdatatype_nsec3param;
   19524 		ISC_LINK_INIT(&param.common, link);
   19525 		param.mctx = NULL;
   19526 		param.hash = hash;
   19527 		param.flags = flags;
   19528 		param.iterations = iter;
   19529 		param.salt_length = saltlen;
   19530 		param.salt = salt;
   19531 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
   19532 		CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
   19533 					   dns_rdatatype_nsec3param,
   19534 					   &param, &b));
   19535 		dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
   19536 					 np->data, sizeof(np->data));
   19537 		np->length = prdata.length;
   19538 		np->nsec = false;
   19539 	}
   19540 
   19541 	/*
   19542 	 * setnsec3param() will silently return early if the zone does not yet
   19543 	 * have a database.  Prevent that by queueing the event up if zone->db
   19544 	 * is NULL.  All events queued here are subsequently processed by
   19545 	 * receive_secure_db() if it ever gets called or simply freed by
   19546 	 * zone_free() otherwise.
   19547 	 */
   19548 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   19549 	if (zone->db != NULL) {
   19550 		zone_iattach(zone, &dummy);
   19551 		isc_task_send(zone->task, &e);
   19552 	} else {
   19553 		ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link);
   19554 		e = NULL;
   19555 	}
   19556 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   19557 
   19558  failure:
   19559 	if (e != NULL) {
   19560 		isc_event_free(&e);
   19561 	}
   19562 	UNLOCK_ZONE(zone);
   19563 	return (result);
   19564 }
   19565 
   19566 isc_result_t
   19567 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
   19568 	REQUIRE(DNS_ZONE_VALID(zone));
   19569 	REQUIRE(loadtime != NULL);
   19570 
   19571 	LOCK_ZONE(zone);
   19572 	*loadtime = zone->loadtime;
   19573 	UNLOCK_ZONE(zone);
   19574 	return (ISC_R_SUCCESS);
   19575 }
   19576 
   19577 isc_result_t
   19578 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
   19579 	REQUIRE(DNS_ZONE_VALID(zone));
   19580 	REQUIRE(expiretime != NULL);
   19581 
   19582 	LOCK_ZONE(zone);
   19583 	*expiretime = zone->expiretime;
   19584 	UNLOCK_ZONE(zone);
   19585 	return (ISC_R_SUCCESS);
   19586 }
   19587 
   19588 isc_result_t
   19589 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
   19590 	REQUIRE(DNS_ZONE_VALID(zone));
   19591 	REQUIRE(refreshtime != NULL);
   19592 
   19593 	LOCK_ZONE(zone);
   19594 	*refreshtime = zone->refreshtime;
   19595 	UNLOCK_ZONE(zone);
   19596 	return (ISC_R_SUCCESS);
   19597 }
   19598 
   19599 isc_result_t
   19600 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
   19601 	REQUIRE(DNS_ZONE_VALID(zone));
   19602 	REQUIRE(refreshkeytime != NULL);
   19603 
   19604 	LOCK_ZONE(zone);
   19605 	*refreshkeytime = zone->refreshkeytime;
   19606 	UNLOCK_ZONE(zone);
   19607 	return (ISC_R_SUCCESS);
   19608 }
   19609 
   19610 unsigned int
   19611 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
   19612 	dns_include_t *include;
   19613 	char **array = NULL;
   19614 	unsigned int n = 0;
   19615 
   19616 	REQUIRE(DNS_ZONE_VALID(zone));
   19617 	REQUIRE(includesp != NULL && *includesp == NULL);
   19618 
   19619 	LOCK_ZONE(zone);
   19620 	if (zone->nincludes == 0)
   19621 		goto done;
   19622 
   19623 	array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
   19624 	if (array == NULL)
   19625 		goto done;
   19626 	for (include = ISC_LIST_HEAD(zone->includes);
   19627 	     include != NULL;
   19628 	     include = ISC_LIST_NEXT(include, link)) {
   19629 		INSIST(n < zone->nincludes);
   19630 		array[n++] = isc_mem_strdup(zone->mctx, include->name);
   19631 	}
   19632 	INSIST(n == zone->nincludes);
   19633 	*includesp = array;
   19634 
   19635  done:
   19636 	UNLOCK_ZONE(zone);
   19637 	return (n);
   19638 }
   19639 
   19640 void
   19641 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
   19642 	REQUIRE(DNS_ZONE_VALID(zone));
   19643 
   19644 	zone->statlevel = level;
   19645 }
   19646 
   19647 dns_zonestat_level_t
   19648 dns_zone_getstatlevel(dns_zone_t *zone) {
   19649 	REQUIRE(DNS_ZONE_VALID(zone));
   19650 
   19651 	return (zone->statlevel);
   19652 }
   19653 
   19654 static void
   19655 setserial(isc_task_t *task, isc_event_t *event) {
   19656 	uint32_t oldserial, desired;
   19657 	const char *me = "setserial";
   19658 	bool commit = false;
   19659 	isc_result_t result;
   19660 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   19661 	dns_zone_t *zone;
   19662 	dns_db_t *db = NULL;
   19663 	dns_diff_t diff;
   19664 	struct ssevent *sse = (struct ssevent *)event;
   19665 	dns_update_log_t log = { update_log_cb, NULL };
   19666 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   19667 
   19668 	UNUSED(task);
   19669 
   19670 	zone = event->ev_arg;
   19671 	INSIST(DNS_ZONE_VALID(zone));
   19672 
   19673 	ENTER;
   19674 
   19675 	if (zone->update_disabled)
   19676 		goto failure;
   19677 
   19678 	desired = sse->serial;
   19679 
   19680 	dns_diff_init(zone->mctx, &diff);
   19681 
   19682 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   19683 	if (zone->db != NULL)
   19684 		dns_db_attach(zone->db, &db);
   19685 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   19686 	if (db == NULL)
   19687 		goto failure;
   19688 
   19689 	dns_db_currentversion(db, &oldver);
   19690 	result = dns_db_newversion(db, &newver);
   19691 	if (result != ISC_R_SUCCESS) {
   19692 		dns_zone_log(zone, ISC_LOG_ERROR,
   19693 			     "setserial:dns_db_newversion -> %s",
   19694 			     dns_result_totext(result));
   19695 		goto failure;
   19696 	}
   19697 
   19698 	CHECK(dns_db_createsoatuple(db, oldver, diff.mctx,
   19699 				    DNS_DIFFOP_DEL, &oldtuple));
   19700 	CHECK(dns_difftuple_copy(oldtuple, &newtuple));
   19701 	newtuple->op = DNS_DIFFOP_ADD;
   19702 
   19703 	oldserial = dns_soa_getserial(&oldtuple->rdata);
   19704 	if (desired == 0U)
   19705 		desired = 1;
   19706 	if (!isc_serial_gt(desired, oldserial)) {
   19707 		if (desired != oldserial)
   19708 			dns_zone_log(zone, ISC_LOG_INFO,
   19709 				     "setserial: desired serial (%u) "
   19710 				     "out of range (%u-%u)", desired,
   19711 				     oldserial + 1, (oldserial + 0x7fffffff));
   19712 		goto failure;
   19713 	}
   19714 
   19715 	dns_soa_setserial(desired, &newtuple->rdata);
   19716 	CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
   19717 	CHECK(do_one_tuple(&newtuple, db, newver, &diff));
   19718 	result = dns_update_signatures(&log, zone, db,
   19719 				       oldver, newver, &diff,
   19720 				       zone->sigvalidityinterval);
   19721 	if (result != ISC_R_NOTFOUND)
   19722 		CHECK(result);
   19723 
   19724 	/* Write changes to journal file. */
   19725 	CHECK(zone_journal(zone, &diff, NULL, "setserial"));
   19726 	commit = true;
   19727 
   19728 	LOCK_ZONE(zone);
   19729 	zone_needdump(zone, 30);
   19730 	UNLOCK_ZONE(zone);
   19731 
   19732  failure:
   19733 	if (oldtuple != NULL)
   19734 		dns_difftuple_free(&oldtuple);
   19735 	if (newtuple != NULL)
   19736 		dns_difftuple_free(&newtuple);
   19737 	if (oldver != NULL)
   19738 		dns_db_closeversion(db, &oldver, false);
   19739 	if (newver != NULL)
   19740 		dns_db_closeversion(db, &newver, commit);
   19741 	if (db != NULL)
   19742 		dns_db_detach(&db);
   19743 	dns_diff_clear(&diff);
   19744 	isc_event_free(&event);
   19745 	dns_zone_idetach(&zone);
   19746 
   19747 	INSIST(oldver == NULL);
   19748 	INSIST(newver == NULL);
   19749 }
   19750 
   19751 isc_result_t
   19752 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
   19753 	isc_result_t result = ISC_R_SUCCESS;
   19754 	dns_zone_t *dummy = NULL;
   19755 	isc_event_t *e = NULL;
   19756 	struct ssevent *sse;
   19757 
   19758 	REQUIRE(DNS_ZONE_VALID(zone));
   19759 
   19760 	LOCK_ZONE(zone);
   19761 
   19762 	if (!inline_secure(zone)) {
   19763 		if (!dns_zone_isdynamic(zone, true)) {
   19764 			result = DNS_R_NOTDYNAMIC;
   19765 			goto failure;
   19766 		}
   19767 	}
   19768 
   19769 	if (zone->update_disabled) {
   19770 		result = DNS_R_FROZEN;
   19771 		goto failure;
   19772 	}
   19773 
   19774 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL,
   19775 			       setserial, zone, sizeof(struct ssevent));
   19776 	if (e == NULL) {
   19777 		result = ISC_R_NOMEMORY;
   19778 		goto failure;
   19779 	}
   19780 
   19781 	sse = (struct ssevent *)e;
   19782 	sse->serial = serial;
   19783 
   19784 	zone_iattach(zone, &dummy);
   19785 	isc_task_send(zone->task, &e);
   19786 
   19787  failure:
   19788 	if (e != NULL)
   19789 		isc_event_free(&e);
   19790 	UNLOCK_ZONE(zone);
   19791 	return (result);
   19792 }
   19793 
   19794 isc_stats_t *
   19795 dns_zone_getgluecachestats(dns_zone_t *zone) {
   19796 	REQUIRE(DNS_ZONE_VALID(zone));
   19797 
   19798 	return (zone->gluecachestats);
   19799 }
   19800 
   19801 bool
   19802 dns_zone_isloaded(const dns_zone_t *zone) {
   19803 	REQUIRE(DNS_ZONE_VALID(zone));
   19804 
   19805 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
   19806 }
   19807 
   19808 isc_result_t
   19809 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
   19810 	dns_dbversion_t *version = NULL;
   19811 	dns_keytable_t *secroots = NULL;
   19812 	isc_result_t result;
   19813 	dns_name_t *origin;
   19814 
   19815 	const char me[] = "dns_zone_verifydb";
   19816 	ENTER;
   19817 
   19818 	REQUIRE(DNS_ZONE_VALID(zone));
   19819 	REQUIRE(db != NULL);
   19820 
   19821 	if (dns_zone_gettype(zone) != dns_zone_mirror) {
   19822 		return (ISC_R_SUCCESS);
   19823 	}
   19824 
   19825 	if (ver == NULL) {
   19826 		dns_db_currentversion(db, &version);
   19827 	} else {
   19828 		version = ver;
   19829 	}
   19830 
   19831 	if (zone->view != NULL) {
   19832 		result = dns_view_getsecroots(zone->view, &secroots);
   19833 		if (result != ISC_R_SUCCESS) {
   19834 			goto done;
   19835 		}
   19836 	}
   19837 
   19838 	origin = dns_db_origin(db);
   19839 	result = dns_zoneverify_dnssec(zone, db, version, origin, secroots,
   19840 				       zone->mctx, true, false);
   19841 
   19842  done:
   19843 	if (secroots != NULL) {
   19844 		dns_keytable_detach(&secroots);
   19845 	}
   19846 
   19847 	if (ver == NULL) {
   19848 		dns_db_closeversion(db, &version, false);
   19849 	}
   19850 
   19851 	if (result != ISC_R_SUCCESS) {
   19852 		dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s",
   19853 			   isc_result_totext(result));
   19854 		result = DNS_R_VERIFYFAILURE;
   19855 	}
   19856 
   19857 	return (result);
   19858 }
   19859