Home | History | Annotate | Line # | Download | only in dns
zone.c revision 1.17
      1 /*	$NetBSD: zone.c,v 1.17 2023/01/25 21:43:30 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * SPDX-License-Identifier: MPL-2.0
      7  *
      8  * This Source Code Form is subject to the terms of the Mozilla Public
      9  * License, v. 2.0. If a copy of the MPL was not distributed with this
     10  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
     11  *
     12  * See the COPYRIGHT file distributed with this work for additional
     13  * information regarding copyright ownership.
     14  */
     15 
     16 /*! \file */
     17 
     18 #include <errno.h>
     19 #include <inttypes.h>
     20 #include <stdbool.h>
     21 
     22 #include <isc/atomic.h>
     23 #include <isc/file.h>
     24 #include <isc/hex.h>
     25 #include <isc/md.h>
     26 #include <isc/mutex.h>
     27 #include <isc/pool.h>
     28 #include <isc/print.h>
     29 #include <isc/random.h>
     30 #include <isc/ratelimiter.h>
     31 #include <isc/refcount.h>
     32 #include <isc/rwlock.h>
     33 #include <isc/serial.h>
     34 #include <isc/stats.h>
     35 #include <isc/stdtime.h>
     36 #include <isc/strerr.h>
     37 #include <isc/string.h>
     38 #include <isc/taskpool.h>
     39 #include <isc/thread.h>
     40 #include <isc/timer.h>
     41 #include <isc/util.h>
     42 
     43 #include <dns/acl.h>
     44 #include <dns/adb.h>
     45 #include <dns/callbacks.h>
     46 #include <dns/catz.h>
     47 #include <dns/db.h>
     48 #include <dns/dbiterator.h>
     49 #include <dns/dlz.h>
     50 #include <dns/dnssec.h>
     51 #include <dns/events.h>
     52 #include <dns/journal.h>
     53 #include <dns/kasp.h>
     54 #include <dns/keydata.h>
     55 #include <dns/keymgr.h>
     56 #include <dns/keytable.h>
     57 #include <dns/keyvalues.h>
     58 #include <dns/log.h>
     59 #include <dns/master.h>
     60 #include <dns/masterdump.h>
     61 #include <dns/message.h>
     62 #include <dns/name.h>
     63 #include <dns/nsec.h>
     64 #include <dns/nsec3.h>
     65 #include <dns/opcode.h>
     66 #include <dns/peer.h>
     67 #include <dns/private.h>
     68 #include <dns/rcode.h>
     69 #include <dns/rdata.h>
     70 #include <dns/rdataclass.h>
     71 #include <dns/rdatalist.h>
     72 #include <dns/rdataset.h>
     73 #include <dns/rdatasetiter.h>
     74 #include <dns/rdatastruct.h>
     75 #include <dns/rdatatype.h>
     76 #include <dns/request.h>
     77 #include <dns/resolver.h>
     78 #include <dns/result.h>
     79 #include <dns/rriterator.h>
     80 #include <dns/soa.h>
     81 #include <dns/ssu.h>
     82 #include <dns/stats.h>
     83 #include <dns/time.h>
     84 #include <dns/tsig.h>
     85 #include <dns/update.h>
     86 #include <dns/xfrin.h>
     87 #include <dns/zone.h>
     88 #include <dns/zoneverify.h>
     89 #include <dns/zt.h>
     90 
     91 #include <dst/dst.h>
     92 
     93 #include "zone_p.h"
     94 
     95 #define ZONE_MAGIC	     ISC_MAGIC('Z', 'O', 'N', 'E')
     96 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
     97 
     98 #define NOTIFY_MAGIC		 ISC_MAGIC('N', 't', 'f', 'y')
     99 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
    100 
    101 #define CHECKDS_MAGIC		   ISC_MAGIC('C', 'h', 'D', 'S')
    102 #define DNS_CHECKDS_VALID(checkds) ISC_MAGIC_VALID(checkds, CHECKDS_MAGIC)
    103 
    104 #define STUB_MAGIC	     ISC_MAGIC('S', 't', 'u', 'b')
    105 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
    106 
    107 #define ZONEMGR_MAGIC		ISC_MAGIC('Z', 'm', 'g', 'r')
    108 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
    109 
    110 #define LOAD_MAGIC	     ISC_MAGIC('L', 'o', 'a', 'd')
    111 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
    112 
    113 #define FORWARD_MAGIC		ISC_MAGIC('F', 'o', 'r', 'w')
    114 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
    115 
    116 #define IO_MAGIC	   ISC_MAGIC('Z', 'm', 'I', 'O')
    117 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
    118 
    119 #define KEYMGMT_MAGIC		ISC_MAGIC('M', 'g', 'm', 't')
    120 #define DNS_KEYMGMT_VALID(load) ISC_MAGIC_VALID(load, KEYMGMT_MAGIC)
    121 
    122 #define KEYFILEIO_MAGIC		  ISC_MAGIC('K', 'y', 'I', 'O')
    123 #define DNS_KEYFILEIO_VALID(kfio) ISC_MAGIC_VALID(kfio, KEYFILEIO_MAGIC)
    124 
    125 /*%
    126  * Ensure 'a' is at least 'min' but not more than 'max'.
    127  */
    128 #define RANGE(a, min, max) (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
    129 
    130 #define NSEC3REMOVE(x) (((x)&DNS_NSEC3FLAG_REMOVE) != 0)
    131 
    132 /*%
    133  * Key flags
    134  */
    135 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
    136 #define KSK(x)	  ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
    137 #define ID(x)	  dst_key_id(x)
    138 #define ALG(x)	  dst_key_alg(x)
    139 
    140 /*%
    141  * KASP flags
    142  */
    143 #define KASP_LOCK(k)                  \
    144 	if ((k) != NULL) {            \
    145 		LOCK((&((k)->lock))); \
    146 	}
    147 
    148 #define KASP_UNLOCK(k)                  \
    149 	if ((k) != NULL) {              \
    150 		UNLOCK((&((k)->lock))); \
    151 	}
    152 
    153 /*
    154  * Default values.
    155  */
    156 #define DNS_DEFAULT_IDLEIN  3600       /*%< 1 hour */
    157 #define DNS_DEFAULT_IDLEOUT 3600       /*%< 1 hour */
    158 #define MAX_XFER_TIME	    (2 * 3600) /*%< Documented default is 2 hours */
    159 #define RESIGN_DELAY	    3600       /*%< 1 hour */
    160 
    161 #ifndef DNS_MAX_EXPIRE
    162 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
    163 #endif				/* ifndef DNS_MAX_EXPIRE */
    164 
    165 #ifndef DNS_DUMP_DELAY
    166 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
    167 #endif			   /* ifndef DNS_DUMP_DELAY */
    168 
    169 typedef struct dns_notify dns_notify_t;
    170 typedef struct dns_checkds dns_checkds_t;
    171 typedef struct dns_stub dns_stub_t;
    172 typedef struct dns_load dns_load_t;
    173 typedef struct dns_forward dns_forward_t;
    174 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
    175 typedef struct dns_io dns_io_t;
    176 typedef ISC_LIST(dns_io_t) dns_iolist_t;
    177 typedef struct dns_keymgmt dns_keymgmt_t;
    178 typedef struct dns_signing dns_signing_t;
    179 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
    180 typedef struct dns_nsec3chain dns_nsec3chain_t;
    181 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
    182 typedef struct dns_keyfetch dns_keyfetch_t;
    183 typedef struct dns_asyncload dns_asyncload_t;
    184 typedef struct dns_include dns_include_t;
    185 
    186 #define DNS_ZONE_CHECKLOCK
    187 #ifdef DNS_ZONE_CHECKLOCK
    188 #define LOCK_ZONE(z)                  \
    189 	do {                          \
    190 		LOCK(&(z)->lock);     \
    191 		INSIST(!(z)->locked); \
    192 		(z)->locked = true;   \
    193 	} while (0)
    194 #define UNLOCK_ZONE(z)               \
    195 	do {                         \
    196 		(z)->locked = false; \
    197 		UNLOCK(&(z)->lock);  \
    198 	} while (0)
    199 #define LOCKED_ZONE(z) ((z)->locked)
    200 #define TRYLOCK_ZONE(result, z)                         \
    201 	do {                                            \
    202 		result = isc_mutex_trylock(&(z)->lock); \
    203 		if (result == ISC_R_SUCCESS) {          \
    204 			INSIST(!(z)->locked);           \
    205 			(z)->locked = true;             \
    206 		}                                       \
    207 	} while (0)
    208 #else /* ifdef DNS_ZONE_CHECKLOCK */
    209 #define LOCK_ZONE(z)   LOCK(&(z)->lock)
    210 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
    211 #define LOCKED_ZONE(z) true
    212 #define TRYLOCK_ZONE(result, z)                         \
    213 	do {                                            \
    214 		result = isc_mutex_trylock(&(z)->lock); \
    215 	} while (0)
    216 #endif /* ifdef DNS_ZONE_CHECKLOCK */
    217 
    218 #define ZONEDB_INITLOCK(l)    isc_rwlock_init((l), 0, 0)
    219 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
    220 #define ZONEDB_LOCK(l, t)     RWLOCK((l), (t))
    221 #define ZONEDB_UNLOCK(l, t)   RWUNLOCK((l), (t))
    222 
    223 #ifdef ENABLE_AFL
    224 extern bool dns_fuzzing_resolver;
    225 #endif /* ifdef ENABLE_AFL */
    226 
    227 /*%
    228  *	Hold key file IO locks.
    229  */
    230 typedef struct dns_keyfileio {
    231 	unsigned int magic;
    232 	struct dns_keyfileio *next;
    233 	uint32_t hashval;
    234 	dns_fixedname_t fname;
    235 	dns_name_t *name;
    236 	isc_refcount_t references;
    237 	isc_mutex_t lock;
    238 } dns_keyfileio_t;
    239 
    240 struct dns_keymgmt {
    241 	unsigned int magic;
    242 	isc_rwlock_t lock;
    243 	isc_mem_t *mctx;
    244 
    245 	dns_keyfileio_t **table;
    246 
    247 	atomic_uint_fast32_t count;
    248 
    249 	uint32_t bits;
    250 };
    251 
    252 struct dns_zone {
    253 	/* Unlocked */
    254 	unsigned int magic;
    255 	isc_mutex_t lock;
    256 #ifdef DNS_ZONE_CHECKLOCK
    257 	bool locked;
    258 #endif /* ifdef DNS_ZONE_CHECKLOCK */
    259 	isc_mem_t *mctx;
    260 	isc_refcount_t erefs;
    261 
    262 	isc_rwlock_t dblock;
    263 	dns_db_t *db; /* Locked by dblock */
    264 
    265 	/* Locked */
    266 	dns_zonemgr_t *zmgr;
    267 	ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
    268 	isc_timer_t *timer;
    269 	isc_refcount_t irefs;
    270 	dns_name_t origin;
    271 	char *masterfile;
    272 	ISC_LIST(dns_include_t) includes;    /* Include files */
    273 	ISC_LIST(dns_include_t) newincludes; /* Loading */
    274 	unsigned int nincludes;
    275 	dns_masterformat_t masterformat;
    276 	const dns_master_style_t *masterstyle;
    277 	char *journal;
    278 	int32_t journalsize;
    279 	dns_rdataclass_t rdclass;
    280 	dns_zonetype_t type;
    281 #ifdef __NetBSD__
    282 	atomic_uint_fast32_t flags;
    283 	atomic_uint_fast32_t options;
    284 #else
    285 	atomic_uint_fast64_t flags;
    286 	atomic_uint_fast64_t options;
    287 #endif
    288 	unsigned int db_argc;
    289 	char **db_argv;
    290 	isc_time_t expiretime;
    291 	isc_time_t refreshtime;
    292 	isc_time_t dumptime;
    293 	isc_time_t loadtime;
    294 	isc_time_t notifytime;
    295 	isc_time_t resigntime;
    296 	isc_time_t keywarntime;
    297 	isc_time_t signingtime;
    298 	isc_time_t nsec3chaintime;
    299 	isc_time_t refreshkeytime;
    300 	uint32_t refreshkeyinterval;
    301 	uint32_t refreshkeycount;
    302 	uint32_t refresh;
    303 	uint32_t retry;
    304 	uint32_t expire;
    305 	uint32_t minimum;
    306 	isc_stdtime_t key_expiry;
    307 	isc_stdtime_t log_key_expired_timer;
    308 	char *keydirectory;
    309 	dns_keyfileio_t *kfio;
    310 
    311 	uint32_t maxrefresh;
    312 	uint32_t minrefresh;
    313 	uint32_t maxretry;
    314 	uint32_t minretry;
    315 
    316 	uint32_t maxrecords;
    317 
    318 	isc_sockaddr_t *masters;
    319 	isc_dscp_t *masterdscps;
    320 	dns_name_t **masterkeynames;
    321 	bool *mastersok;
    322 	unsigned int masterscnt;
    323 	unsigned int curmaster;
    324 	isc_sockaddr_t masteraddr;
    325 
    326 	isc_sockaddr_t *parentals;
    327 	isc_dscp_t *parentaldscps;
    328 	dns_name_t **parentalkeynames;
    329 	dns_dnsseckeylist_t checkds_ok;
    330 	unsigned int parentalscnt;
    331 	isc_sockaddr_t parentaladdr;
    332 
    333 	dns_notifytype_t notifytype;
    334 	isc_sockaddr_t *notify;
    335 	dns_name_t **notifykeynames;
    336 	isc_dscp_t *notifydscp;
    337 	unsigned int notifycnt;
    338 	isc_sockaddr_t notifyfrom;
    339 	isc_task_t *task;
    340 	isc_task_t *loadtask;
    341 	isc_sockaddr_t notifysrc4;
    342 	isc_sockaddr_t notifysrc6;
    343 	isc_sockaddr_t parentalsrc4;
    344 	isc_sockaddr_t parentalsrc6;
    345 	isc_sockaddr_t xfrsource4;
    346 	isc_sockaddr_t xfrsource6;
    347 	isc_sockaddr_t altxfrsource4;
    348 	isc_sockaddr_t altxfrsource6;
    349 	isc_sockaddr_t sourceaddr;
    350 	isc_dscp_t notifysrc4dscp;
    351 	isc_dscp_t notifysrc6dscp;
    352 	isc_dscp_t parentalsrc4dscp;
    353 	isc_dscp_t parentalsrc6dscp;
    354 	isc_dscp_t xfrsource4dscp;
    355 	isc_dscp_t xfrsource6dscp;
    356 	isc_dscp_t altxfrsource4dscp;
    357 	isc_dscp_t altxfrsource6dscp;
    358 	dns_xfrin_ctx_t *xfr;	/* task locked */
    359 	dns_tsigkey_t *tsigkey; /* key used for xfr */
    360 	/* Access Control Lists */
    361 	dns_acl_t *update_acl;
    362 	dns_acl_t *forward_acl;
    363 	dns_acl_t *notify_acl;
    364 	dns_acl_t *query_acl;
    365 	dns_acl_t *queryon_acl;
    366 	dns_acl_t *xfr_acl;
    367 	bool update_disabled;
    368 	bool zero_no_soa_ttl;
    369 	dns_severity_t check_names;
    370 	ISC_LIST(dns_notify_t) notifies;
    371 	ISC_LIST(dns_checkds_t) checkds_requests;
    372 	dns_request_t *request;
    373 	dns_loadctx_t *lctx;
    374 	dns_io_t *readio;
    375 	dns_dumpctx_t *dctx;
    376 	dns_io_t *writeio;
    377 	uint32_t maxxfrin;
    378 	uint32_t maxxfrout;
    379 	uint32_t idlein;
    380 	uint32_t idleout;
    381 	isc_event_t ctlevent;
    382 	dns_ssutable_t *ssutable;
    383 	uint32_t sigvalidityinterval;
    384 	uint32_t keyvalidityinterval;
    385 	uint32_t sigresigninginterval;
    386 	dns_view_t *view;
    387 	dns_view_t *prev_view;
    388 	dns_kasp_t *kasp;
    389 	dns_checkmxfunc_t checkmx;
    390 	dns_checksrvfunc_t checksrv;
    391 	dns_checknsfunc_t checkns;
    392 	/*%
    393 	 * Zones in certain states such as "waiting for zone transfer"
    394 	 * or "zone transfer in progress" are kept on per-state linked lists
    395 	 * in the zone manager using the 'statelink' field.  The 'statelist'
    396 	 * field points at the list the zone is currently on.  It the zone
    397 	 * is not on any such list, statelist is NULL.
    398 	 */
    399 	ISC_LINK(dns_zone_t) statelink;
    400 	dns_zonelist_t *statelist;
    401 	/*%
    402 	 * Statistics counters about zone management.
    403 	 */
    404 	isc_stats_t *stats;
    405 	/*%
    406 	 * Optional per-zone statistics counters.  Counted outside of this
    407 	 * module.
    408 	 */
    409 	dns_zonestat_level_t statlevel;
    410 	bool requeststats_on;
    411 	isc_stats_t *requeststats;
    412 	dns_stats_t *rcvquerystats;
    413 	dns_stats_t *dnssecsignstats;
    414 	uint32_t notifydelay;
    415 	dns_isselffunc_t isself;
    416 	void *isselfarg;
    417 
    418 	char *strnamerd;
    419 	char *strname;
    420 	char *strrdclass;
    421 	char *strviewname;
    422 
    423 	/*%
    424 	 * Serial number for deferred journal compaction.
    425 	 */
    426 	uint32_t compact_serial;
    427 	/*%
    428 	 * Keys that are signing the zone for the first time.
    429 	 */
    430 	dns_signinglist_t signing;
    431 	dns_nsec3chainlist_t nsec3chain;
    432 	/*%
    433 	 * List of outstanding NSEC3PARAM change requests.
    434 	 */
    435 	isc_eventlist_t setnsec3param_queue;
    436 	/*%
    437 	 * Signing / re-signing quantum stopping parameters.
    438 	 */
    439 	uint32_t signatures;
    440 	uint32_t nodes;
    441 	dns_rdatatype_t privatetype;
    442 
    443 	/*%
    444 	 * Autosigning/key-maintenance options
    445 	 */
    446 #ifdef __NetBSD__
    447 	atomic_uint_fast32_t keyopts;
    448 #else
    449 	atomic_uint_fast64_t keyopts;
    450 #endif
    451 
    452 	/*%
    453 	 * True if added by "rndc addzone"
    454 	 */
    455 	bool added;
    456 
    457 	/*%
    458 	 * True if added by automatically by named.
    459 	 */
    460 	bool automatic;
    461 
    462 	/*%
    463 	 * response policy data to be relayed to the database
    464 	 */
    465 	dns_rpz_zones_t *rpzs;
    466 	dns_rpz_num_t rpz_num;
    467 
    468 	/*%
    469 	 * catalog zone data
    470 	 */
    471 	dns_catz_zones_t *catzs;
    472 
    473 	/*%
    474 	 * parent catalog zone
    475 	 */
    476 	dns_catz_zone_t *parentcatz;
    477 
    478 	/*%
    479 	 * Serial number update method.
    480 	 */
    481 	dns_updatemethod_t updatemethod;
    482 
    483 	/*%
    484 	 * whether ixfr is requested
    485 	 */
    486 	bool requestixfr;
    487 	uint32_t ixfr_ratio;
    488 
    489 	/*%
    490 	 * whether EDNS EXPIRE is requested
    491 	 */
    492 	bool requestexpire;
    493 
    494 	/*%
    495 	 * Outstanding forwarded UPDATE requests.
    496 	 */
    497 	dns_forwardlist_t forwards;
    498 
    499 	dns_zone_t *raw;
    500 	dns_zone_t *secure;
    501 
    502 	bool sourceserialset;
    503 	uint32_t sourceserial;
    504 
    505 	/*%
    506 	 * soa and maximum zone ttl
    507 	 */
    508 	dns_ttl_t soattl;
    509 	dns_ttl_t maxttl;
    510 
    511 	/*
    512 	 * Inline zone signing state.
    513 	 */
    514 	dns_diff_t rss_diff;
    515 	isc_eventlist_t rss_events;
    516 	isc_eventlist_t rss_post;
    517 	dns_dbversion_t *rss_newver;
    518 	dns_dbversion_t *rss_oldver;
    519 	dns_db_t *rss_db;
    520 	dns_zone_t *rss_raw;
    521 	isc_event_t *rss_event;
    522 	dns_update_state_t *rss_state;
    523 
    524 	isc_stats_t *gluecachestats;
    525 };
    526 
    527 #define zonediff_init(z, d)                \
    528 	do {                               \
    529 		dns__zonediff_t *_z = (z); \
    530 		(_z)->diff = (d);          \
    531 		(_z)->offline = false;     \
    532 	} while (0)
    533 
    534 #define DNS_ZONE_FLAG(z, f)    ((atomic_load_relaxed(&(z)->flags) & (f)) != 0)
    535 #define DNS_ZONE_SETFLAG(z, f) atomic_fetch_or(&(z)->flags, (f))
    536 #define DNS_ZONE_CLRFLAG(z, f) atomic_fetch_and(&(z)->flags, ~(f))
    537 typedef enum {
    538 	DNS_ZONEFLG_REFRESH = 0x00000001U,     /*%< refresh check in progress */
    539 	DNS_ZONEFLG_NEEDDUMP = 0x00000002U,    /*%< zone need consolidation */
    540 	DNS_ZONEFLG_USEVC = 0x00000004U,       /*%< use tcp for refresh query */
    541 	DNS_ZONEFLG_DUMPING = 0x00000008U,     /*%< a dump is in progress */
    542 	DNS_ZONEFLG_HASINCLUDE = 0x00000010U,  /*%< $INCLUDE in zone file */
    543 	DNS_ZONEFLG_LOADED = 0x00000020U,      /*%< database has loaded */
    544 	DNS_ZONEFLG_EXITING = 0x00000040U,     /*%< zone is being destroyed */
    545 	DNS_ZONEFLG_EXPIRED = 0x00000080U,     /*%< zone has expired */
    546 	DNS_ZONEFLG_NEEDREFRESH = 0x00000100U, /*%< refresh check needed */
    547 	DNS_ZONEFLG_UPTODATE = 0x00000200U,    /*%< zone contents are
    548 						* up-to-date */
    549 	DNS_ZONEFLG_NEEDNOTIFY = 0x00000400U,  /*%< need to send out notify
    550 						* messages */
    551 	DNS_ZONEFLG_FIXJOURNAL = 0x00000800U,  /*%< journal file had
    552 						* recoverable error,
    553 						* needs rewriting */
    554 	DNS_ZONEFLG_NOMASTERS = 0x00001000U,   /*%< an attempt to refresh a
    555 						* zone with no primaries
    556 						* occurred */
    557 	DNS_ZONEFLG_LOADING = 0x00002000U,     /*%< load from disk in progress*/
    558 	DNS_ZONEFLG_HAVETIMERS = 0x00004000U,  /*%< timer values have been set
    559 						* from SOA (if not set, we
    560 						* are still using
    561 						* default timer values) */
    562 	DNS_ZONEFLG_FORCEXFER = 0x00008000U,   /*%< Force a zone xfer */
    563 	DNS_ZONEFLG_NOREFRESH = 0x00010000U,
    564 	DNS_ZONEFLG_DIALNOTIFY = 0x00020000U,
    565 	DNS_ZONEFLG_DIALREFRESH = 0x00040000U,
    566 	DNS_ZONEFLG_SHUTDOWN = 0x00080000U,
    567 	DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */
    568 	DNS_ZONEFLG_FLUSH = 0x00200000U,
    569 	DNS_ZONEFLG_NOEDNS = 0x00400000U,
    570 	DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U,
    571 	DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U,
    572 	DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U,
    573 	DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */
    574 	DNS_ZONEFLG_THAW = 0x08000000U,
    575 	DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */
    576 	DNS_ZONEFLG_NODELAY = 0x20000000U,
    577 	DNS_ZONEFLG_SENDSECURE = 0x40000000U,
    578 	DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out
    579 						      * notify due to the zone
    580 						      * just being loaded for
    581 						      * the first time. */
    582 #ifndef __NetBSD__
    583 	/*
    584 	 * DO NOT add any new zone flags here until all platforms
    585 	 * support 64-bit enum values. Currently they fail on
    586 	 * Windows.
    587 	 */
    588 	DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */
    589 #endif
    590 } dns_zoneflg_t;
    591 
    592 #define DNS_ZONE_OPTION(z, o)	 ((atomic_load_relaxed(&(z)->options) & (o)) != 0)
    593 #define DNS_ZONE_SETOPTION(z, o) atomic_fetch_or(&(z)->options, (o))
    594 #define DNS_ZONE_CLROPTION(z, o) atomic_fetch_and(&(z)->options, ~(o))
    595 
    596 #define DNS_ZONEKEY_OPTION(z, o) \
    597 	((atomic_load_relaxed(&(z)->keyopts) & (o)) != 0)
    598 #define DNS_ZONEKEY_SETOPTION(z, o) atomic_fetch_or(&(z)->keyopts, (o))
    599 #define DNS_ZONEKEY_CLROPTION(z, o) atomic_fetch_and(&(z)->keyopts, ~(o))
    600 
    601 /* Flags for zone_load() */
    602 typedef enum {
    603 	DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */
    604 	DNS_ZONELOADFLAG_THAW = 0x00000002U,   /* Thaw the zone on successful
    605 						* load. */
    606 } dns_zoneloadflag_t;
    607 
    608 #define UNREACH_CACHE_SIZE 10U
    609 #define UNREACH_HOLD_TIME  600 /* 10 minutes */
    610 
    611 #define CHECK(op)                            \
    612 	do {                                 \
    613 		result = (op);               \
    614 		if (result != ISC_R_SUCCESS) \
    615 			goto failure;        \
    616 	} while (0)
    617 
    618 struct dns_unreachable {
    619 	isc_sockaddr_t remote;
    620 	isc_sockaddr_t local;
    621 	atomic_uint_fast32_t expire;
    622 	atomic_uint_fast32_t last;
    623 	uint32_t count;
    624 };
    625 
    626 struct dns_zonemgr {
    627 	unsigned int magic;
    628 	isc_mem_t *mctx;
    629 	isc_refcount_t refs;
    630 	isc_taskmgr_t *taskmgr;
    631 	isc_timermgr_t *timermgr;
    632 	isc_socketmgr_t *socketmgr;
    633 	isc_taskpool_t *zonetasks;
    634 	isc_taskpool_t *loadtasks;
    635 	isc_task_t *task;
    636 	isc_pool_t *mctxpool;
    637 	isc_ratelimiter_t *checkdsrl;
    638 	isc_ratelimiter_t *notifyrl;
    639 	isc_ratelimiter_t *refreshrl;
    640 	isc_ratelimiter_t *startupnotifyrl;
    641 	isc_ratelimiter_t *startuprefreshrl;
    642 	isc_rwlock_t rwlock;
    643 	isc_mutex_t iolock;
    644 	isc_rwlock_t urlock;
    645 
    646 	/* Locked by rwlock. */
    647 	dns_zonelist_t zones;
    648 	dns_zonelist_t waiting_for_xfrin;
    649 	dns_zonelist_t xfrin_in_progress;
    650 
    651 	/* Configuration data. */
    652 	uint32_t transfersin;
    653 	uint32_t transfersperns;
    654 	unsigned int checkdsrate;
    655 	unsigned int notifyrate;
    656 	unsigned int startupnotifyrate;
    657 	unsigned int serialqueryrate;
    658 	unsigned int startupserialqueryrate;
    659 
    660 	/* Locked by iolock */
    661 	uint32_t iolimit;
    662 	uint32_t ioactive;
    663 	dns_iolist_t high;
    664 	dns_iolist_t low;
    665 
    666 	/* Locked by urlock. */
    667 	/* LRU cache */
    668 	struct dns_unreachable unreachable[UNREACH_CACHE_SIZE];
    669 
    670 	dns_keymgmt_t *keymgmt;
    671 };
    672 
    673 /*%
    674  * Hold notify state.
    675  */
    676 struct dns_notify {
    677 	unsigned int magic;
    678 	unsigned int flags;
    679 	isc_mem_t *mctx;
    680 	dns_zone_t *zone;
    681 	dns_adbfind_t *find;
    682 	dns_request_t *request;
    683 	dns_name_t ns;
    684 	isc_sockaddr_t dst;
    685 	dns_tsigkey_t *key;
    686 	isc_dscp_t dscp;
    687 	ISC_LINK(dns_notify_t) link;
    688 	isc_event_t *event;
    689 };
    690 
    691 #define DNS_NOTIFY_NOSOA   0x0001U
    692 #define DNS_NOTIFY_STARTUP 0x0002U
    693 
    694 /*%
    695  * Hold checkds state.
    696  */
    697 struct dns_checkds {
    698 	unsigned int magic;
    699 	unsigned int flags;
    700 	isc_mem_t *mctx;
    701 	dns_zone_t *zone;
    702 	dns_request_t *request;
    703 	isc_sockaddr_t dst;
    704 	dns_tsigkey_t *key;
    705 	isc_dscp_t dscp;
    706 	ISC_LINK(dns_checkds_t) link;
    707 	isc_event_t *event;
    708 };
    709 
    710 /*%
    711  *	dns_stub holds state while performing a 'stub' transfer.
    712  *	'db' is the zone's 'db' or a new one if this is the initial
    713  *	transfer.
    714  */
    715 
    716 struct dns_stub {
    717 	unsigned int magic;
    718 	isc_mem_t *mctx;
    719 	dns_zone_t *zone;
    720 	dns_db_t *db;
    721 	dns_dbversion_t *version;
    722 	atomic_uint_fast32_t pending_requests;
    723 };
    724 
    725 /*%
    726  *	Hold load state.
    727  */
    728 struct dns_load {
    729 	unsigned int magic;
    730 	isc_mem_t *mctx;
    731 	dns_zone_t *zone;
    732 	dns_db_t *db;
    733 	isc_time_t loadtime;
    734 	dns_rdatacallbacks_t callbacks;
    735 };
    736 
    737 /*%
    738  *	Hold forward state.
    739  */
    740 struct dns_forward {
    741 	unsigned int magic;
    742 	isc_mem_t *mctx;
    743 	dns_zone_t *zone;
    744 	isc_buffer_t *msgbuf;
    745 	dns_request_t *request;
    746 	uint32_t which;
    747 	isc_sockaddr_t addr;
    748 	dns_updatecallback_t callback;
    749 	void *callback_arg;
    750 	unsigned int options;
    751 	ISC_LINK(dns_forward_t) link;
    752 };
    753 
    754 /*%
    755  *	Hold IO request state.
    756  */
    757 struct dns_io {
    758 	unsigned int magic;
    759 	dns_zonemgr_t *zmgr;
    760 	bool high;
    761 	isc_task_t *task;
    762 	ISC_LINK(dns_io_t) link;
    763 	isc_event_t *event;
    764 };
    765 
    766 /*%
    767  *	Hold state for when we are signing a zone with a new
    768  *	DNSKEY as result of an update.
    769  */
    770 struct dns_signing {
    771 	unsigned int magic;
    772 	dns_db_t *db;
    773 	dns_dbiterator_t *dbiterator;
    774 	dns_secalg_t algorithm;
    775 	uint16_t keyid;
    776 	bool deleteit;
    777 	bool done;
    778 	ISC_LINK(dns_signing_t) link;
    779 };
    780 
    781 struct dns_nsec3chain {
    782 	unsigned int magic;
    783 	dns_db_t *db;
    784 	dns_dbiterator_t *dbiterator;
    785 	dns_rdata_nsec3param_t nsec3param;
    786 	unsigned char salt[255];
    787 	bool done;
    788 	bool seen_nsec;
    789 	bool delete_nsec;
    790 	bool save_delete_nsec;
    791 	ISC_LINK(dns_nsec3chain_t) link;
    792 };
    793 
    794 /*%<
    795  * 'dbiterator' contains a iterator for the database.  If we are creating
    796  * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
    797  * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
    798  * iterated.
    799  *
    800  * 'nsec3param' contains the parameters of the NSEC3 chain being created
    801  * or removed.
    802  *
    803  * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
    804  *
    805  * 'seen_nsec' will be set to true if, while iterating the zone to create a
    806  * NSEC3 chain, a NSEC record is seen.
    807  *
    808  * 'delete_nsec' will be set to true if, at the completion of the creation
    809  * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
    810  * are in the process of deleting the NSEC chain.
    811  *
    812  * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
    813  * so it can be recovered in the event of a error.
    814  */
    815 
    816 struct dns_keyfetch {
    817 	isc_mem_t *mctx;
    818 	dns_fixedname_t name;
    819 	dns_rdataset_t keydataset;
    820 	dns_rdataset_t dnskeyset;
    821 	dns_rdataset_t dnskeysigset;
    822 	dns_zone_t *zone;
    823 	dns_db_t *db;
    824 	dns_fetch_t *fetch;
    825 };
    826 
    827 /*%
    828  * Hold state for an asynchronous load
    829  */
    830 struct dns_asyncload {
    831 	dns_zone_t *zone;
    832 	unsigned int flags;
    833 	dns_zt_zoneloaded_t loaded;
    834 	void *loaded_arg;
    835 };
    836 
    837 /*%
    838  * Reference to an include file encountered during loading
    839  */
    840 struct dns_include {
    841 	char *name;
    842 	isc_time_t filetime;
    843 	ISC_LINK(dns_include_t) link;
    844 };
    845 
    846 /*
    847  * These can be overridden by the -T mkeytimers option on the command
    848  * line, so that we can test with shorter periods than specified in
    849  * RFC 5011.
    850  */
    851 #define HOUR  3600
    852 #define DAY   (24 * HOUR)
    853 #define MONTH (30 * DAY)
    854 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR;
    855 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY;
    856 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH;
    857 
    858 #define SEND_BUFFER_SIZE 2048
    859 
    860 static void
    861 zone_settimer(dns_zone_t *, isc_time_t *);
    862 static void
    863 cancel_refresh(dns_zone_t *);
    864 static void
    865 zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg,
    866 	      ...) ISC_FORMAT_PRINTF(4, 5);
    867 static void
    868 notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
    869 	ISC_FORMAT_PRINTF(3, 4);
    870 static void
    871 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...)
    872 	ISC_FORMAT_PRINTF(3, 4);
    873 static void
    874 queue_xfrin(dns_zone_t *zone);
    875 static isc_result_t
    876 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
    877 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
    878 	      dns_rdata_t *rdata);
    879 static void
    880 zone_unload(dns_zone_t *zone);
    881 static void
    882 zone_expire(dns_zone_t *zone);
    883 static void
    884 zone_iattach(dns_zone_t *source, dns_zone_t **target);
    885 static void
    886 zone_idetach(dns_zone_t **zonep);
    887 static isc_result_t
    888 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump);
    889 static void
    890 zone_attachdb(dns_zone_t *zone, dns_db_t *db);
    891 static void
    892 zone_detachdb(dns_zone_t *zone);
    893 static void
    894 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs);
    895 static void
    896 zone_catz_disable(dns_zone_t *zone);
    897 static isc_result_t
    898 default_journal(dns_zone_t *zone);
    899 static void
    900 zone_xfrdone(dns_zone_t *zone, isc_result_t result);
    901 static isc_result_t
    902 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
    903 	      isc_result_t result);
    904 static void
    905 zone_needdump(dns_zone_t *zone, unsigned int delay);
    906 static void
    907 zone_shutdown(isc_task_t *, isc_event_t *);
    908 static void
    909 zone_loaddone(void *arg, isc_result_t result);
    910 static isc_result_t
    911 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime);
    912 static void
    913 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
    914 static void
    915 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
    916 static void
    917 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
    918 static void
    919 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
    920 static isc_result_t
    921 zone_send_secureserial(dns_zone_t *zone, uint32_t serial);
    922 static void
    923 refresh_callback(isc_task_t *, isc_event_t *);
    924 static void
    925 stub_callback(isc_task_t *, isc_event_t *);
    926 static void
    927 queue_soa_query(dns_zone_t *zone);
    928 static void
    929 soa_query(isc_task_t *, isc_event_t *);
    930 static void
    931 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub);
    932 static int
    933 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type);
    934 static void
    935 checkds_cancel(dns_zone_t *zone);
    936 static void
    937 checkds_send(dns_zone_t *zone);
    938 static isc_result_t
    939 checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep);
    940 static void
    941 checkds_done(isc_task_t *task, isc_event_t *event);
    942 static void
    943 checkds_send_toaddr(isc_task_t *task, isc_event_t *event);
    944 static void
    945 notify_cancel(dns_zone_t *zone);
    946 static void
    947 notify_find_address(dns_notify_t *notify);
    948 static void
    949 notify_send(dns_notify_t *notify);
    950 static isc_result_t
    951 notify_createmessage(dns_zone_t *zone, unsigned int flags,
    952 		     dns_message_t **messagep);
    953 static void
    954 notify_done(isc_task_t *task, isc_event_t *event);
    955 static void
    956 notify_send_toaddr(isc_task_t *task, isc_event_t *event);
    957 static isc_result_t
    958 zone_dump(dns_zone_t *, bool);
    959 static void
    960 got_transfer_quota(isc_task_t *task, isc_event_t *event);
    961 static isc_result_t
    962 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone);
    963 static void
    964 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi);
    965 static void
    966 zonemgr_free(dns_zonemgr_t *zmgr);
    967 static isc_result_t
    968 zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task,
    969 	      isc_taskaction_t action, void *arg, dns_io_t **iop);
    970 static void
    971 zonemgr_putio(dns_io_t **iop);
    972 static void
    973 zonemgr_cancelio(dns_io_t *io);
    974 static void
    975 rss_post(dns_zone_t *, isc_event_t *);
    976 
    977 static isc_result_t
    978 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
    979 		 unsigned int *soacount, uint32_t *soattl, uint32_t *serial,
    980 		 uint32_t *refresh, uint32_t *retry, uint32_t *expire,
    981 		 uint32_t *minimum, unsigned int *errors);
    982 
    983 static void
    984 zone_freedbargs(dns_zone_t *zone);
    985 static void
    986 forward_callback(isc_task_t *task, isc_event_t *event);
    987 static void
    988 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat);
    989 static void
    990 zone_maintenance(dns_zone_t *zone);
    991 static void
    992 zone_notify(dns_zone_t *zone, isc_time_t *now);
    993 static void
    994 dump_done(void *arg, isc_result_t result);
    995 static isc_result_t
    996 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
    997 		 bool deleteit);
    998 static isc_result_t
    999 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   1000 	    dns_name_t *name, dns_diff_t *diff);
   1001 static void
   1002 zone_rekey(dns_zone_t *zone);
   1003 static isc_result_t
   1004 zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
   1005 static dns_ttl_t
   1006 zone_nsecttl(dns_zone_t *zone);
   1007 static void
   1008 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value);
   1009 static void
   1010 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial);
   1011 static isc_result_t
   1012 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump,
   1013 			 bool *fixjournal);
   1014 
   1015 #define ENTER zone_debuglog(zone, me, 1, "enter")
   1016 
   1017 static const unsigned int dbargc_default = 1;
   1018 static const char *dbargv_default[] = { "rbt" };
   1019 
   1020 #define DNS_ZONE_JITTER_ADD(a, b, c)                                         \
   1021 	do {                                                                 \
   1022 		isc_interval_t _i;                                           \
   1023 		uint32_t _j;                                                 \
   1024 		_j = (b)-isc_random_uniform((b) / 4);                        \
   1025 		isc_interval_set(&_i, _j, 0);                                \
   1026 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) {          \
   1027 			dns_zone_log(zone, ISC_LOG_WARNING,                  \
   1028 				     "epoch approaching: upgrade required: " \
   1029 				     "now + %s failed",                      \
   1030 				     #b);                                    \
   1031 			isc_interval_set(&_i, _j / 2, 0);                    \
   1032 			(void)isc_time_add((a), &_i, (c));                   \
   1033 		}                                                            \
   1034 	} while (0)
   1035 
   1036 #define DNS_ZONE_TIME_ADD(a, b, c)                                           \
   1037 	do {                                                                 \
   1038 		isc_interval_t _i;                                           \
   1039 		isc_interval_set(&_i, (b), 0);                               \
   1040 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) {          \
   1041 			dns_zone_log(zone, ISC_LOG_WARNING,                  \
   1042 				     "epoch approaching: upgrade required: " \
   1043 				     "now + %s failed",                      \
   1044 				     #b);                                    \
   1045 			isc_interval_set(&_i, (b) / 2, 0);                   \
   1046 			(void)isc_time_add((a), &_i, (c));                   \
   1047 		}                                                            \
   1048 	} while (0)
   1049 
   1050 typedef struct nsec3param nsec3param_t;
   1051 struct nsec3param {
   1052 	dns_rdata_nsec3param_t rdata;
   1053 	unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
   1054 	unsigned int length;
   1055 	bool nsec;
   1056 	bool replace;
   1057 	bool resalt;
   1058 	bool lookup;
   1059 	ISC_LINK(nsec3param_t) link;
   1060 };
   1061 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
   1062 struct np3event {
   1063 	isc_event_t event;
   1064 	nsec3param_t params;
   1065 };
   1066 
   1067 struct ssevent {
   1068 	isc_event_t event;
   1069 	uint32_t serial;
   1070 };
   1071 
   1072 struct stub_cb_args {
   1073 	dns_stub_t *stub;
   1074 	dns_tsigkey_t *tsig_key;
   1075 	isc_dscp_t dscp;
   1076 	uint16_t udpsize;
   1077 	int timeout;
   1078 	bool reqnsid;
   1079 };
   1080 
   1081 struct stub_glue_request {
   1082 	dns_request_t *request;
   1083 	dns_name_t name;
   1084 	struct stub_cb_args *args;
   1085 	bool ipv4;
   1086 };
   1087 
   1088 /*%
   1089  * Increment resolver-related statistics counters.  Zone must be locked.
   1090  */
   1091 static void
   1092 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
   1093 	if (zone->stats != NULL) {
   1094 		isc_stats_increment(zone->stats, counter);
   1095 	}
   1096 }
   1097 
   1098 /***
   1099  ***	Public functions.
   1100  ***/
   1101 
   1102 isc_result_t
   1103 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
   1104 	isc_result_t result;
   1105 	isc_time_t now;
   1106 	dns_zone_t *zone = NULL;
   1107 	dns_zone_t z = { .masterformat = dns_masterformat_none,
   1108 			 .journalsize = -1,
   1109 			 .rdclass = dns_rdataclass_none,
   1110 			 .type = dns_zone_none,
   1111 			 .refresh = DNS_ZONE_DEFAULTREFRESH,
   1112 			 .retry = DNS_ZONE_DEFAULTRETRY,
   1113 			 .maxrefresh = DNS_ZONE_MAXREFRESH,
   1114 			 .minrefresh = DNS_ZONE_MINREFRESH,
   1115 			 .maxretry = DNS_ZONE_MAXRETRY,
   1116 			 .minretry = DNS_ZONE_MINRETRY,
   1117 			 .notifytype = dns_notifytype_yes,
   1118 			 .zero_no_soa_ttl = true,
   1119 			 .check_names = dns_severity_ignore,
   1120 			 .idlein = DNS_DEFAULT_IDLEIN,
   1121 			 .idleout = DNS_DEFAULT_IDLEOUT,
   1122 			 .notifysrc4dscp = -1,
   1123 			 .notifysrc6dscp = -1,
   1124 			 .parentalsrc4dscp = -1,
   1125 			 .parentalsrc6dscp = -1,
   1126 			 .xfrsource4dscp = -1,
   1127 			 .xfrsource6dscp = -1,
   1128 			 .altxfrsource4dscp = -1,
   1129 			 .altxfrsource6dscp = -1,
   1130 			 .maxxfrin = MAX_XFER_TIME,
   1131 			 .maxxfrout = MAX_XFER_TIME,
   1132 			 .sigvalidityinterval = 30 * 24 * 3600,
   1133 			 .sigresigninginterval = 7 * 24 * 3600,
   1134 			 .statlevel = dns_zonestat_none,
   1135 			 .notifydelay = 5,
   1136 			 .signatures = 10,
   1137 			 .nodes = 100,
   1138 			 .privatetype = (dns_rdatatype_t)0xffffU,
   1139 			 .rpz_num = DNS_RPZ_INVALID_NUM,
   1140 			 .requestixfr = true,
   1141 			 .ixfr_ratio = 100,
   1142 			 .requestexpire = true,
   1143 			 .updatemethod = dns_updatemethod_increment,
   1144 			 .magic = ZONE_MAGIC };
   1145 
   1146 	REQUIRE(zonep != NULL && *zonep == NULL);
   1147 	REQUIRE(mctx != NULL);
   1148 
   1149 	TIME_NOW(&now);
   1150 	zone = isc_mem_get(mctx, sizeof(*zone));
   1151 	*zone = z;
   1152 
   1153 	zone->mctx = NULL;
   1154 	isc_mem_attach(mctx, &zone->mctx);
   1155 	isc_mutex_init(&zone->lock);
   1156 	ZONEDB_INITLOCK(&zone->dblock);
   1157 	/* XXX MPA check that all elements are initialised */
   1158 #ifdef DNS_ZONE_CHECKLOCK
   1159 	zone->locked = false;
   1160 #endif /* ifdef DNS_ZONE_CHECKLOCK */
   1161 
   1162 	zone->notifytime = now;
   1163 
   1164 	ISC_LINK_INIT(zone, link);
   1165 	isc_refcount_init(&zone->erefs, 1);
   1166 	isc_refcount_init(&zone->irefs, 0);
   1167 	dns_name_init(&zone->origin, NULL);
   1168 	ISC_LIST_INIT(zone->includes);
   1169 	ISC_LIST_INIT(zone->newincludes);
   1170 	atomic_init(&zone->flags, 0);
   1171 	atomic_init(&zone->options, 0);
   1172 	atomic_init(&zone->keyopts, 0);
   1173 	isc_time_settoepoch(&zone->expiretime);
   1174 	isc_time_settoepoch(&zone->refreshtime);
   1175 	isc_time_settoepoch(&zone->dumptime);
   1176 	isc_time_settoepoch(&zone->loadtime);
   1177 	isc_time_settoepoch(&zone->resigntime);
   1178 	isc_time_settoepoch(&zone->keywarntime);
   1179 	isc_time_settoepoch(&zone->signingtime);
   1180 	isc_time_settoepoch(&zone->nsec3chaintime);
   1181 	isc_time_settoepoch(&zone->refreshkeytime);
   1182 	ISC_LIST_INIT(zone->notifies);
   1183 	ISC_LIST_INIT(zone->checkds_requests);
   1184 	isc_sockaddr_any(&zone->notifysrc4);
   1185 	isc_sockaddr_any6(&zone->notifysrc6);
   1186 	isc_sockaddr_any(&zone->parentalsrc4);
   1187 	isc_sockaddr_any6(&zone->parentalsrc6);
   1188 	isc_sockaddr_any(&zone->xfrsource4);
   1189 	isc_sockaddr_any6(&zone->xfrsource6);
   1190 	isc_sockaddr_any(&zone->altxfrsource4);
   1191 	isc_sockaddr_any6(&zone->altxfrsource6);
   1192 	ISC_LINK_INIT(zone, statelink);
   1193 	ISC_LIST_INIT(zone->signing);
   1194 	ISC_LIST_INIT(zone->nsec3chain);
   1195 	ISC_LIST_INIT(zone->setnsec3param_queue);
   1196 	ISC_LIST_INIT(zone->forwards);
   1197 	ISC_LIST_INIT(zone->rss_events);
   1198 	ISC_LIST_INIT(zone->rss_post);
   1199 
   1200 	result = isc_stats_create(mctx, &zone->gluecachestats,
   1201 				  dns_gluecachestatscounter_max);
   1202 	if (result != ISC_R_SUCCESS) {
   1203 		goto free_refs;
   1204 	}
   1205 
   1206 	/* Must be after magic is set. */
   1207 	dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
   1208 
   1209 	ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
   1210 		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL,
   1211 		       NULL);
   1212 	*zonep = zone;
   1213 	return (ISC_R_SUCCESS);
   1214 
   1215 free_refs:
   1216 	isc_refcount_decrement0(&zone->erefs);
   1217 	isc_refcount_destroy(&zone->erefs);
   1218 	isc_refcount_destroy(&zone->irefs);
   1219 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1220 	isc_mutex_destroy(&zone->lock);
   1221 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1222 	return (result);
   1223 }
   1224 
   1225 static void
   1226 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
   1227 	dns_dnsseckey_t *key;
   1228 	while (!ISC_LIST_EMPTY(*list)) {
   1229 		key = ISC_LIST_HEAD(*list);
   1230 		ISC_LIST_UNLINK(*list, key, link);
   1231 		dns_dnsseckey_destroy(mctx, &key);
   1232 	}
   1233 }
   1234 
   1235 /*
   1236  * Free a zone.  Because we require that there be no more
   1237  * outstanding events or references, no locking is necessary.
   1238  */
   1239 static void
   1240 zone_free(dns_zone_t *zone) {
   1241 	dns_signing_t *signing;
   1242 	dns_nsec3chain_t *nsec3chain;
   1243 	isc_event_t *event;
   1244 	dns_include_t *include;
   1245 
   1246 	REQUIRE(DNS_ZONE_VALID(zone));
   1247 	isc_refcount_destroy(&zone->erefs);
   1248 	isc_refcount_destroy(&zone->irefs);
   1249 	REQUIRE(!LOCKED_ZONE(zone));
   1250 	REQUIRE(zone->timer == NULL);
   1251 	REQUIRE(zone->zmgr == NULL);
   1252 
   1253 	/*
   1254 	 * Managed objects.  Order is important.
   1255 	 */
   1256 	if (zone->request != NULL) {
   1257 		dns_request_destroy(&zone->request); /* XXXMPA */
   1258 	}
   1259 	INSIST(zone->readio == NULL);
   1260 	INSIST(zone->statelist == NULL);
   1261 	INSIST(zone->writeio == NULL);
   1262 
   1263 	if (zone->task != NULL) {
   1264 		isc_task_detach(&zone->task);
   1265 	}
   1266 	if (zone->loadtask != NULL) {
   1267 		isc_task_detach(&zone->loadtask);
   1268 	}
   1269 	if (zone->view != NULL) {
   1270 		dns_view_weakdetach(&zone->view);
   1271 	}
   1272 	if (zone->prev_view != NULL) {
   1273 		dns_view_weakdetach(&zone->prev_view);
   1274 	}
   1275 
   1276 	/* Unmanaged objects */
   1277 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   1278 		event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   1279 		ISC_LIST_UNLINK(zone->setnsec3param_queue, event, ev_link);
   1280 		isc_event_free(&event);
   1281 	}
   1282 	while (!ISC_LIST_EMPTY(zone->rss_post)) {
   1283 		event = ISC_LIST_HEAD(zone->rss_post);
   1284 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   1285 		isc_event_free(&event);
   1286 	}
   1287 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   1288 	     signing = ISC_LIST_HEAD(zone->signing))
   1289 	{
   1290 		ISC_LIST_UNLINK(zone->signing, signing, link);
   1291 		dns_db_detach(&signing->db);
   1292 		dns_dbiterator_destroy(&signing->dbiterator);
   1293 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   1294 	}
   1295 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   1296 	     nsec3chain = ISC_LIST_HEAD(zone->nsec3chain))
   1297 	{
   1298 		ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   1299 		dns_db_detach(&nsec3chain->db);
   1300 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   1301 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   1302 	}
   1303 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   1304 	     include = ISC_LIST_HEAD(zone->includes))
   1305 	{
   1306 		ISC_LIST_UNLINK(zone->includes, include, link);
   1307 		isc_mem_free(zone->mctx, include->name);
   1308 		isc_mem_put(zone->mctx, include, sizeof *include);
   1309 	}
   1310 	for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL;
   1311 	     include = ISC_LIST_HEAD(zone->newincludes))
   1312 	{
   1313 		ISC_LIST_UNLINK(zone->newincludes, include, link);
   1314 		isc_mem_free(zone->mctx, include->name);
   1315 		isc_mem_put(zone->mctx, include, sizeof *include);
   1316 	}
   1317 	if (zone->masterfile != NULL) {
   1318 		isc_mem_free(zone->mctx, zone->masterfile);
   1319 	}
   1320 	zone->masterfile = NULL;
   1321 	if (zone->keydirectory != NULL) {
   1322 		isc_mem_free(zone->mctx, zone->keydirectory);
   1323 	}
   1324 	zone->keydirectory = NULL;
   1325 	if (zone->kasp != NULL) {
   1326 		dns_kasp_detach(&zone->kasp);
   1327 	}
   1328 	if (!ISC_LIST_EMPTY(zone->checkds_ok)) {
   1329 		clear_keylist(&zone->checkds_ok, zone->mctx);
   1330 	}
   1331 
   1332 	zone->journalsize = -1;
   1333 	if (zone->journal != NULL) {
   1334 		isc_mem_free(zone->mctx, zone->journal);
   1335 	}
   1336 	zone->journal = NULL;
   1337 	if (zone->stats != NULL) {
   1338 		isc_stats_detach(&zone->stats);
   1339 	}
   1340 	if (zone->requeststats != NULL) {
   1341 		isc_stats_detach(&zone->requeststats);
   1342 	}
   1343 	if (zone->rcvquerystats != NULL) {
   1344 		dns_stats_detach(&zone->rcvquerystats);
   1345 	}
   1346 	if (zone->dnssecsignstats != NULL) {
   1347 		dns_stats_detach(&zone->dnssecsignstats);
   1348 	}
   1349 	if (zone->db != NULL) {
   1350 		zone_detachdb(zone);
   1351 	}
   1352 	if (zone->rpzs != NULL) {
   1353 		REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
   1354 		dns_rpz_detach_rpzs(&zone->rpzs);
   1355 		zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1356 	}
   1357 	if (zone->catzs != NULL) {
   1358 		dns_catz_catzs_detach(&zone->catzs);
   1359 	}
   1360 	zone_freedbargs(zone);
   1361 
   1362 	RUNTIME_CHECK(dns_zone_setparentals(zone, NULL, NULL, 0) ==
   1363 		      ISC_R_SUCCESS);
   1364 	RUNTIME_CHECK(dns_zone_setprimarieswithkeys(zone, NULL, NULL, 0) ==
   1365 		      ISC_R_SUCCESS);
   1366 	RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
   1367 	zone->check_names = dns_severity_ignore;
   1368 	if (zone->update_acl != NULL) {
   1369 		dns_acl_detach(&zone->update_acl);
   1370 	}
   1371 	if (zone->forward_acl != NULL) {
   1372 		dns_acl_detach(&zone->forward_acl);
   1373 	}
   1374 	if (zone->notify_acl != NULL) {
   1375 		dns_acl_detach(&zone->notify_acl);
   1376 	}
   1377 	if (zone->query_acl != NULL) {
   1378 		dns_acl_detach(&zone->query_acl);
   1379 	}
   1380 	if (zone->queryon_acl != NULL) {
   1381 		dns_acl_detach(&zone->queryon_acl);
   1382 	}
   1383 	if (zone->xfr_acl != NULL) {
   1384 		dns_acl_detach(&zone->xfr_acl);
   1385 	}
   1386 	if (dns_name_dynamic(&zone->origin)) {
   1387 		dns_name_free(&zone->origin, zone->mctx);
   1388 	}
   1389 	if (zone->strnamerd != NULL) {
   1390 		isc_mem_free(zone->mctx, zone->strnamerd);
   1391 	}
   1392 	if (zone->strname != NULL) {
   1393 		isc_mem_free(zone->mctx, zone->strname);
   1394 	}
   1395 	if (zone->strrdclass != NULL) {
   1396 		isc_mem_free(zone->mctx, zone->strrdclass);
   1397 	}
   1398 	if (zone->strviewname != NULL) {
   1399 		isc_mem_free(zone->mctx, zone->strviewname);
   1400 	}
   1401 	if (zone->ssutable != NULL) {
   1402 		dns_ssutable_detach(&zone->ssutable);
   1403 	}
   1404 	if (zone->gluecachestats != NULL) {
   1405 		isc_stats_detach(&zone->gluecachestats);
   1406 	}
   1407 
   1408 	/* last stuff */
   1409 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1410 	isc_mutex_destroy(&zone->lock);
   1411 	zone->magic = 0;
   1412 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1413 }
   1414 
   1415 /*
   1416  * Returns true iff this the signed side of an inline-signing zone.
   1417  * Caller should hold zone lock.
   1418  */
   1419 static bool
   1420 inline_secure(dns_zone_t *zone) {
   1421 	REQUIRE(DNS_ZONE_VALID(zone));
   1422 	if (zone->raw != NULL) {
   1423 		return (true);
   1424 	}
   1425 	return (false);
   1426 }
   1427 
   1428 /*
   1429  * Returns true iff this the unsigned side of an inline-signing zone
   1430  * Caller should hold zone lock.
   1431  */
   1432 static bool
   1433 inline_raw(dns_zone_t *zone) {
   1434 	REQUIRE(DNS_ZONE_VALID(zone));
   1435 	if (zone->secure != NULL) {
   1436 		return (true);
   1437 	}
   1438 	return (false);
   1439 }
   1440 
   1441 /*
   1442  *	Single shot.
   1443  */
   1444 void
   1445 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
   1446 	char namebuf[1024];
   1447 
   1448 	REQUIRE(DNS_ZONE_VALID(zone));
   1449 	REQUIRE(rdclass != dns_rdataclass_none);
   1450 
   1451 	/*
   1452 	 * Test and set.
   1453 	 */
   1454 	LOCK_ZONE(zone);
   1455 	INSIST(zone != zone->raw);
   1456 	REQUIRE(zone->rdclass == dns_rdataclass_none ||
   1457 		zone->rdclass == rdclass);
   1458 	zone->rdclass = rdclass;
   1459 
   1460 	if (zone->strnamerd != NULL) {
   1461 		isc_mem_free(zone->mctx, zone->strnamerd);
   1462 	}
   1463 	if (zone->strrdclass != NULL) {
   1464 		isc_mem_free(zone->mctx, zone->strrdclass);
   1465 	}
   1466 
   1467 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1468 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1469 	zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
   1470 	zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
   1471 
   1472 	if (inline_secure(zone)) {
   1473 		dns_zone_setclass(zone->raw, rdclass);
   1474 	}
   1475 	UNLOCK_ZONE(zone);
   1476 }
   1477 
   1478 dns_rdataclass_t
   1479 dns_zone_getclass(dns_zone_t *zone) {
   1480 	REQUIRE(DNS_ZONE_VALID(zone));
   1481 
   1482 	return (zone->rdclass);
   1483 }
   1484 
   1485 void
   1486 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
   1487 	REQUIRE(DNS_ZONE_VALID(zone));
   1488 
   1489 	LOCK_ZONE(zone);
   1490 	zone->notifytype = notifytype;
   1491 	UNLOCK_ZONE(zone);
   1492 }
   1493 
   1494 isc_result_t
   1495 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
   1496 	isc_result_t result;
   1497 	unsigned int soacount;
   1498 
   1499 	REQUIRE(DNS_ZONE_VALID(zone));
   1500 	REQUIRE(serialp != NULL);
   1501 
   1502 	LOCK_ZONE(zone);
   1503 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   1504 	if (zone->db != NULL) {
   1505 		result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
   1506 					  serialp, NULL, NULL, NULL, NULL,
   1507 					  NULL);
   1508 		if (result == ISC_R_SUCCESS && soacount == 0) {
   1509 			result = ISC_R_FAILURE;
   1510 		}
   1511 	} else {
   1512 		result = DNS_R_NOTLOADED;
   1513 	}
   1514 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   1515 	UNLOCK_ZONE(zone);
   1516 
   1517 	return (result);
   1518 }
   1519 
   1520 /*
   1521  *	Single shot.
   1522  */
   1523 void
   1524 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
   1525 	char namebuf[1024];
   1526 
   1527 	REQUIRE(DNS_ZONE_VALID(zone));
   1528 	REQUIRE(type != dns_zone_none);
   1529 
   1530 	/*
   1531 	 * Test and set.
   1532 	 */
   1533 	LOCK_ZONE(zone);
   1534 	REQUIRE(zone->type == dns_zone_none || zone->type == type);
   1535 	zone->type = type;
   1536 
   1537 	if (zone->strnamerd != NULL) {
   1538 		isc_mem_free(zone->mctx, zone->strnamerd);
   1539 	}
   1540 
   1541 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1542 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1543 	UNLOCK_ZONE(zone);
   1544 }
   1545 
   1546 static void
   1547 zone_freedbargs(dns_zone_t *zone) {
   1548 	unsigned int i;
   1549 
   1550 	/* Free the old database argument list. */
   1551 	if (zone->db_argv != NULL) {
   1552 		for (i = 0; i < zone->db_argc; i++) {
   1553 			isc_mem_free(zone->mctx, zone->db_argv[i]);
   1554 		}
   1555 		isc_mem_put(zone->mctx, zone->db_argv,
   1556 			    zone->db_argc * sizeof(*zone->db_argv));
   1557 	}
   1558 	zone->db_argc = 0;
   1559 	zone->db_argv = NULL;
   1560 }
   1561 
   1562 isc_result_t
   1563 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
   1564 	size_t size = 0;
   1565 	unsigned int i;
   1566 	isc_result_t result = ISC_R_SUCCESS;
   1567 	void *mem;
   1568 	char **tmp, *tmp2, *base;
   1569 
   1570 	REQUIRE(DNS_ZONE_VALID(zone));
   1571 	REQUIRE(argv != NULL && *argv == NULL);
   1572 
   1573 	LOCK_ZONE(zone);
   1574 	size = (zone->db_argc + 1) * sizeof(char *);
   1575 	for (i = 0; i < zone->db_argc; i++) {
   1576 		size += strlen(zone->db_argv[i]) + 1;
   1577 	}
   1578 	mem = isc_mem_allocate(mctx, size);
   1579 	{
   1580 		tmp = mem;
   1581 		tmp2 = mem;
   1582 		base = mem;
   1583 		tmp2 += (zone->db_argc + 1) * sizeof(char *);
   1584 		for (i = 0; i < zone->db_argc; i++) {
   1585 			*tmp++ = tmp2;
   1586 			strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
   1587 			tmp2 += strlen(tmp2) + 1;
   1588 		}
   1589 		*tmp = NULL;
   1590 	}
   1591 	UNLOCK_ZONE(zone);
   1592 	*argv = mem;
   1593 	return (result);
   1594 }
   1595 
   1596 void
   1597 dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc,
   1598 		   const char *const *dbargv) {
   1599 	char **argv = NULL;
   1600 	unsigned int i;
   1601 
   1602 	REQUIRE(DNS_ZONE_VALID(zone));
   1603 	REQUIRE(dbargc >= 1);
   1604 	REQUIRE(dbargv != NULL);
   1605 
   1606 	LOCK_ZONE(zone);
   1607 
   1608 	/* Set up a new database argument list. */
   1609 	argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv));
   1610 	for (i = 0; i < dbargc; i++) {
   1611 		argv[i] = NULL;
   1612 	}
   1613 	for (i = 0; i < dbargc; i++) {
   1614 		argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
   1615 	}
   1616 
   1617 	/* Free the old list. */
   1618 	zone_freedbargs(zone);
   1619 
   1620 	zone->db_argc = dbargc;
   1621 	zone->db_argv = argv;
   1622 
   1623 	UNLOCK_ZONE(zone);
   1624 }
   1625 
   1626 static void
   1627 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
   1628 	char namebuf[1024];
   1629 
   1630 	if (zone->prev_view == NULL && zone->view != NULL) {
   1631 		dns_view_weakattach(zone->view, &zone->prev_view);
   1632 	}
   1633 
   1634 	INSIST(zone != zone->raw);
   1635 	if (zone->view != NULL) {
   1636 		dns_view_weakdetach(&zone->view);
   1637 	}
   1638 	dns_view_weakattach(view, &zone->view);
   1639 
   1640 	if (zone->strviewname != NULL) {
   1641 		isc_mem_free(zone->mctx, zone->strviewname);
   1642 	}
   1643 	if (zone->strnamerd != NULL) {
   1644 		isc_mem_free(zone->mctx, zone->strnamerd);
   1645 	}
   1646 
   1647 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1648 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1649 	zone_viewname_tostr(zone, namebuf, sizeof namebuf);
   1650 	zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
   1651 
   1652 	if (inline_secure(zone)) {
   1653 		dns_zone_setview(zone->raw, view);
   1654 	}
   1655 }
   1656 
   1657 void
   1658 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
   1659 	REQUIRE(DNS_ZONE_VALID(zone));
   1660 
   1661 	LOCK_ZONE(zone);
   1662 	dns_zone_setview_helper(zone, view);
   1663 	UNLOCK_ZONE(zone);
   1664 }
   1665 
   1666 dns_view_t *
   1667 dns_zone_getview(dns_zone_t *zone) {
   1668 	REQUIRE(DNS_ZONE_VALID(zone));
   1669 
   1670 	return (zone->view);
   1671 }
   1672 
   1673 void
   1674 dns_zone_setviewcommit(dns_zone_t *zone) {
   1675 	REQUIRE(DNS_ZONE_VALID(zone));
   1676 
   1677 	LOCK_ZONE(zone);
   1678 	if (zone->prev_view != NULL) {
   1679 		dns_view_weakdetach(&zone->prev_view);
   1680 	}
   1681 	if (inline_secure(zone)) {
   1682 		dns_zone_setviewcommit(zone->raw);
   1683 	}
   1684 	UNLOCK_ZONE(zone);
   1685 }
   1686 
   1687 void
   1688 dns_zone_setviewrevert(dns_zone_t *zone) {
   1689 	REQUIRE(DNS_ZONE_VALID(zone));
   1690 
   1691 	LOCK_ZONE(zone);
   1692 	if (zone->prev_view != NULL) {
   1693 		dns_zone_setview_helper(zone, zone->prev_view);
   1694 		dns_view_weakdetach(&zone->prev_view);
   1695 	}
   1696 	if (zone->catzs != NULL) {
   1697 		zone_catz_enable(zone, zone->catzs);
   1698 	}
   1699 	if (inline_secure(zone)) {
   1700 		dns_zone_setviewrevert(zone->raw);
   1701 	}
   1702 	UNLOCK_ZONE(zone);
   1703 }
   1704 
   1705 isc_result_t
   1706 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
   1707 	isc_result_t result = ISC_R_SUCCESS;
   1708 	char namebuf[1024];
   1709 
   1710 	REQUIRE(DNS_ZONE_VALID(zone));
   1711 	REQUIRE(origin != NULL);
   1712 
   1713 	LOCK_ZONE(zone);
   1714 	INSIST(zone != zone->raw);
   1715 	if (dns_name_dynamic(&zone->origin)) {
   1716 		dns_name_free(&zone->origin, zone->mctx);
   1717 		dns_name_init(&zone->origin, NULL);
   1718 	}
   1719 	dns_name_dup(origin, zone->mctx, &zone->origin);
   1720 
   1721 	if (zone->strnamerd != NULL) {
   1722 		isc_mem_free(zone->mctx, zone->strnamerd);
   1723 	}
   1724 	if (zone->strname != NULL) {
   1725 		isc_mem_free(zone->mctx, zone->strname);
   1726 	}
   1727 
   1728 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1729 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1730 	zone_name_tostr(zone, namebuf, sizeof namebuf);
   1731 	zone->strname = isc_mem_strdup(zone->mctx, namebuf);
   1732 
   1733 	if (inline_secure(zone)) {
   1734 		result = dns_zone_setorigin(zone->raw, origin);
   1735 	}
   1736 	UNLOCK_ZONE(zone);
   1737 	return (result);
   1738 }
   1739 
   1740 static isc_result_t
   1741 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
   1742 	char *copy;
   1743 
   1744 	if (value != NULL) {
   1745 		copy = isc_mem_strdup(zone->mctx, value);
   1746 	} else {
   1747 		copy = NULL;
   1748 	}
   1749 
   1750 	if (*field != NULL) {
   1751 		isc_mem_free(zone->mctx, *field);
   1752 	}
   1753 
   1754 	*field = copy;
   1755 	return (ISC_R_SUCCESS);
   1756 }
   1757 
   1758 isc_result_t
   1759 dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format,
   1760 		 const dns_master_style_t *style) {
   1761 	isc_result_t result = ISC_R_SUCCESS;
   1762 
   1763 	REQUIRE(DNS_ZONE_VALID(zone));
   1764 
   1765 	LOCK_ZONE(zone);
   1766 	result = dns_zone_setstring(zone, &zone->masterfile, file);
   1767 	if (result == ISC_R_SUCCESS) {
   1768 		zone->masterformat = format;
   1769 		if (format == dns_masterformat_text) {
   1770 			zone->masterstyle = style;
   1771 		}
   1772 		result = default_journal(zone);
   1773 	}
   1774 	UNLOCK_ZONE(zone);
   1775 
   1776 	return (result);
   1777 }
   1778 
   1779 const char *
   1780 dns_zone_getfile(dns_zone_t *zone) {
   1781 	REQUIRE(DNS_ZONE_VALID(zone));
   1782 
   1783 	return (zone->masterfile);
   1784 }
   1785 
   1786 dns_ttl_t
   1787 dns_zone_getmaxttl(dns_zone_t *zone) {
   1788 	REQUIRE(DNS_ZONE_VALID(zone));
   1789 
   1790 	return (zone->maxttl);
   1791 }
   1792 
   1793 void
   1794 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
   1795 	REQUIRE(DNS_ZONE_VALID(zone));
   1796 
   1797 	LOCK_ZONE(zone);
   1798 	if (maxttl != 0) {
   1799 		DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1800 	} else {
   1801 		DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1802 	}
   1803 	zone->maxttl = maxttl;
   1804 	UNLOCK_ZONE(zone);
   1805 
   1806 	return;
   1807 }
   1808 
   1809 static isc_result_t
   1810 default_journal(dns_zone_t *zone) {
   1811 	isc_result_t result;
   1812 	char *journal;
   1813 
   1814 	REQUIRE(DNS_ZONE_VALID(zone));
   1815 	REQUIRE(LOCKED_ZONE(zone));
   1816 
   1817 	if (zone->masterfile != NULL) {
   1818 		/* Calculate string length including '\0'. */
   1819 		int len = strlen(zone->masterfile) + sizeof(".jnl");
   1820 		journal = isc_mem_allocate(zone->mctx, len);
   1821 		strlcpy(journal, zone->masterfile, len);
   1822 		strlcat(journal, ".jnl", len);
   1823 	} else {
   1824 		journal = NULL;
   1825 	}
   1826 	result = dns_zone_setstring(zone, &zone->journal, journal);
   1827 	if (journal != NULL) {
   1828 		isc_mem_free(zone->mctx, journal);
   1829 	}
   1830 	return (result);
   1831 }
   1832 
   1833 isc_result_t
   1834 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
   1835 	isc_result_t result = ISC_R_SUCCESS;
   1836 
   1837 	REQUIRE(DNS_ZONE_VALID(zone));
   1838 
   1839 	LOCK_ZONE(zone);
   1840 	result = dns_zone_setstring(zone, &zone->journal, myjournal);
   1841 	UNLOCK_ZONE(zone);
   1842 
   1843 	return (result);
   1844 }
   1845 
   1846 char *
   1847 dns_zone_getjournal(dns_zone_t *zone) {
   1848 	REQUIRE(DNS_ZONE_VALID(zone));
   1849 
   1850 	return (zone->journal);
   1851 }
   1852 
   1853 /*
   1854  * Return true iff the zone is "dynamic", in the sense that the zone's
   1855  * master file (if any) is written by the server, rather than being
   1856  * updated manually and read by the server.
   1857  *
   1858  * This is true for slave zones, mirror zones, stub zones, key zones,
   1859  * and zones that allow dynamic updates either by having an update
   1860  * policy ("ssutable") or an "allow-update" ACL with a value other than
   1861  * exactly "{ none; }".
   1862  */
   1863 bool
   1864 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
   1865 	REQUIRE(DNS_ZONE_VALID(zone));
   1866 
   1867 	if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror ||
   1868 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   1869 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   1870 	{
   1871 		return (true);
   1872 	}
   1873 
   1874 	/* Inline zones are always dynamic. */
   1875 	if (zone->type == dns_zone_primary && zone->raw != NULL) {
   1876 		return (true);
   1877 	}
   1878 
   1879 	/* If !ignore_freeze, we need check whether updates are disabled.  */
   1880 	if (zone->type == dns_zone_primary &&
   1881 	    (!zone->update_disabled || ignore_freeze) &&
   1882 	    ((zone->ssutable != NULL) ||
   1883 	     (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
   1884 	{
   1885 		return (true);
   1886 	}
   1887 
   1888 	return (false);
   1889 }
   1890 
   1891 /*
   1892  * Set the response policy index and information for a zone.
   1893  */
   1894 isc_result_t
   1895 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
   1896 		    dns_rpz_num_t rpz_num) {
   1897 	/*
   1898 	 * Only RBTDB zones can be used for response policy zones,
   1899 	 * because only they have the code to create the summary data.
   1900 	 * Only zones that are loaded instead of mmap()ed create the
   1901 	 * summary data and so can be policy zones.
   1902 	 */
   1903 	if (strcmp(zone->db_argv[0], "rbt") != 0 &&
   1904 	    strcmp(zone->db_argv[0], "rbt64") != 0)
   1905 	{
   1906 		return (ISC_R_NOTIMPLEMENTED);
   1907 	}
   1908 	if (zone->masterformat == dns_masterformat_map) {
   1909 		return (ISC_R_NOTIMPLEMENTED);
   1910 	}
   1911 
   1912 	/*
   1913 	 * This must happen only once or be redundant.
   1914 	 */
   1915 	LOCK_ZONE(zone);
   1916 	if (zone->rpzs != NULL) {
   1917 		REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
   1918 	} else {
   1919 		REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
   1920 		dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
   1921 		zone->rpz_num = rpz_num;
   1922 	}
   1923 	rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
   1924 	UNLOCK_ZONE(zone);
   1925 
   1926 	return (ISC_R_SUCCESS);
   1927 }
   1928 
   1929 dns_rpz_num_t
   1930 dns_zone_get_rpz_num(dns_zone_t *zone) {
   1931 	return (zone->rpz_num);
   1932 }
   1933 
   1934 /*
   1935  * If a zone is a response policy zone, mark its new database.
   1936  */
   1937 void
   1938 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1939 	isc_result_t result;
   1940 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1941 		return;
   1942 	}
   1943 	REQUIRE(zone->rpzs != NULL);
   1944 	result = dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback,
   1945 					      zone->rpzs->zones[zone->rpz_num]);
   1946 	REQUIRE(result == ISC_R_SUCCESS);
   1947 }
   1948 
   1949 static void
   1950 dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1951 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1952 		return;
   1953 	}
   1954 	REQUIRE(zone->rpzs != NULL);
   1955 	(void)dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback,
   1956 					     zone->rpzs->zones[zone->rpz_num]);
   1957 }
   1958 
   1959 /*
   1960  * If a zone is a catalog zone, attach it to update notification in database.
   1961  */
   1962 void
   1963 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1964 	REQUIRE(DNS_ZONE_VALID(zone));
   1965 	REQUIRE(db != NULL);
   1966 
   1967 	if (zone->catzs != NULL) {
   1968 		dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
   1969 					     zone->catzs);
   1970 	}
   1971 }
   1972 
   1973 static void
   1974 dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1975 	REQUIRE(DNS_ZONE_VALID(zone));
   1976 	REQUIRE(db != NULL);
   1977 
   1978 	if (zone->catzs != NULL) {
   1979 		dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback,
   1980 					       zone->catzs);
   1981 	}
   1982 }
   1983 
   1984 static void
   1985 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
   1986 	REQUIRE(DNS_ZONE_VALID(zone));
   1987 	REQUIRE(catzs != NULL);
   1988 
   1989 	INSIST(zone->catzs == NULL || zone->catzs == catzs);
   1990 	dns_catz_catzs_set_view(catzs, zone->view);
   1991 	if (zone->catzs == NULL) {
   1992 		dns_catz_catzs_attach(catzs, &zone->catzs);
   1993 	}
   1994 }
   1995 
   1996 void
   1997 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
   1998 	REQUIRE(DNS_ZONE_VALID(zone));
   1999 
   2000 	LOCK_ZONE(zone);
   2001 	zone_catz_enable(zone, catzs);
   2002 	UNLOCK_ZONE(zone);
   2003 }
   2004 
   2005 static void
   2006 zone_catz_disable(dns_zone_t *zone) {
   2007 	REQUIRE(DNS_ZONE_VALID(zone));
   2008 
   2009 	if (zone->catzs != NULL) {
   2010 		if (zone->db != NULL) {
   2011 			dns_zone_catz_disable_db(zone, zone->db);
   2012 		}
   2013 		dns_catz_catzs_detach(&zone->catzs);
   2014 	}
   2015 }
   2016 
   2017 void
   2018 dns_zone_catz_disable(dns_zone_t *zone) {
   2019 	REQUIRE(DNS_ZONE_VALID(zone));
   2020 
   2021 	LOCK_ZONE(zone);
   2022 	zone_catz_disable(zone);
   2023 	UNLOCK_ZONE(zone);
   2024 }
   2025 
   2026 bool
   2027 dns_zone_catz_is_enabled(dns_zone_t *zone) {
   2028 	REQUIRE(DNS_ZONE_VALID(zone));
   2029 
   2030 	return (zone->catzs != NULL);
   2031 }
   2032 
   2033 /*
   2034  * Set catalog zone ownership of the zone
   2035  */
   2036 void
   2037 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) {
   2038 	REQUIRE(DNS_ZONE_VALID(zone));
   2039 	REQUIRE(catz != NULL);
   2040 	LOCK_ZONE(zone);
   2041 	INSIST(zone->parentcatz == NULL || zone->parentcatz == catz);
   2042 	zone->parentcatz = catz;
   2043 	UNLOCK_ZONE(zone);
   2044 }
   2045 
   2046 dns_catz_zone_t *
   2047 dns_zone_get_parentcatz(const dns_zone_t *zone) {
   2048 	REQUIRE(DNS_ZONE_VALID(zone));
   2049 	return (zone->parentcatz);
   2050 }
   2051 
   2052 static bool
   2053 zone_touched(dns_zone_t *zone) {
   2054 	isc_result_t result;
   2055 	isc_time_t modtime;
   2056 	dns_include_t *include;
   2057 
   2058 	REQUIRE(DNS_ZONE_VALID(zone));
   2059 
   2060 	result = isc_file_getmodtime(zone->masterfile, &modtime);
   2061 	if (result != ISC_R_SUCCESS ||
   2062 	    isc_time_compare(&modtime, &zone->loadtime) > 0)
   2063 	{
   2064 		return (true);
   2065 	}
   2066 
   2067 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   2068 	     include = ISC_LIST_NEXT(include, link))
   2069 	{
   2070 		result = isc_file_getmodtime(include->name, &modtime);
   2071 		if (result != ISC_R_SUCCESS ||
   2072 		    isc_time_compare(&modtime, &include->filetime) > 0)
   2073 		{
   2074 			return (true);
   2075 		}
   2076 	}
   2077 
   2078 	return (false);
   2079 }
   2080 
   2081 /*
   2082  * Note: when dealing with inline-signed zones, external callers will always
   2083  * call zone_load() for the secure zone; zone_load() calls itself recursively
   2084  * in order to load the raw zone.
   2085  */
   2086 static isc_result_t
   2087 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
   2088 	isc_result_t result;
   2089 	isc_time_t now;
   2090 	isc_time_t loadtime;
   2091 	dns_db_t *db = NULL;
   2092 	bool rbt, hasraw, is_dynamic;
   2093 
   2094 	REQUIRE(DNS_ZONE_VALID(zone));
   2095 
   2096 	if (!locked) {
   2097 		LOCK_ZONE(zone);
   2098 	}
   2099 
   2100 	INSIST(zone != zone->raw);
   2101 	hasraw = inline_secure(zone);
   2102 	if (hasraw) {
   2103 		/*
   2104 		 * We are trying to load an inline-signed zone.  First call
   2105 		 * self recursively to try loading the raw version of the zone.
   2106 		 * Assuming the raw zone file is readable, there are two
   2107 		 * possibilities:
   2108 		 *
   2109 		 *  a) the raw zone was not yet loaded and thus it will be
   2110 		 *     loaded now, synchronously; if this succeeds, a
   2111 		 *     subsequent attempt to load the signed zone file will
   2112 		 *     take place and thus zone_postload() will be called
   2113 		 *     twice: first for the raw zone and then for the secure
   2114 		 *     zone; the latter call will take care of syncing the raw
   2115 		 *     version with the secure version,
   2116 		 *
   2117 		 *  b) the raw zone was already loaded and we are trying to
   2118 		 *     reload it, which will happen asynchronously; this means
   2119 		 *     zone_postload() will only be called for the raw zone
   2120 		 *     because "result" returned by the zone_load() call below
   2121 		 *     will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE;
   2122 		 *     zone_postload() called for the raw zone will take care
   2123 		 *     of syncing the raw version with the secure version.
   2124 		 */
   2125 		result = zone_load(zone->raw, flags, false);
   2126 		if (result != ISC_R_SUCCESS) {
   2127 			if (!locked) {
   2128 				UNLOCK_ZONE(zone);
   2129 			}
   2130 			return (result);
   2131 		}
   2132 		LOCK_ZONE(zone->raw);
   2133 	}
   2134 
   2135 	TIME_NOW(&now);
   2136 
   2137 	INSIST(zone->type != dns_zone_none);
   2138 
   2139 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
   2140 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2141 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2142 		}
   2143 		result = DNS_R_CONTINUE;
   2144 		goto cleanup;
   2145 	}
   2146 
   2147 	INSIST(zone->db_argc >= 1);
   2148 
   2149 	rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
   2150 	      strcmp(zone->db_argv[0], "rbt64") == 0;
   2151 
   2152 	if (zone->db != NULL && zone->masterfile == NULL && rbt) {
   2153 		/*
   2154 		 * The zone has no master file configured.
   2155 		 */
   2156 		result = ISC_R_SUCCESS;
   2157 		goto cleanup;
   2158 	}
   2159 
   2160 	is_dynamic = dns_zone_isdynamic(zone, false);
   2161 	if (zone->db != NULL && is_dynamic) {
   2162 		/*
   2163 		 * This is a slave, stub, or dynamically updated zone being
   2164 		 * reloaded.  Do nothing - the database we already
   2165 		 * have is guaranteed to be up-to-date.
   2166 		 */
   2167 		if (zone->type == dns_zone_primary && !hasraw) {
   2168 			result = DNS_R_DYNAMIC;
   2169 		} else {
   2170 			result = ISC_R_SUCCESS;
   2171 		}
   2172 		goto cleanup;
   2173 	}
   2174 
   2175 	/*
   2176 	 * Store the current time before the zone is loaded, so that if the
   2177 	 * file changes between the time of the load and the time that
   2178 	 * zone->loadtime is set, then the file will still be reloaded
   2179 	 * the next time dns_zone_load is called.
   2180 	 */
   2181 	TIME_NOW(&loadtime);
   2182 
   2183 	/*
   2184 	 * Don't do the load if the file that stores the zone is older
   2185 	 * than the last time the zone was loaded.  If the zone has not
   2186 	 * been loaded yet, zone->loadtime will be the epoch.
   2187 	 */
   2188 	if (zone->masterfile != NULL) {
   2189 		isc_time_t filetime;
   2190 
   2191 		/*
   2192 		 * The file is already loaded.	If we are just doing a
   2193 		 * "rndc reconfig", we are done.
   2194 		 */
   2195 		if (!isc_time_isepoch(&zone->loadtime) &&
   2196 		    (flags & DNS_ZONELOADFLAG_NOSTAT) != 0)
   2197 		{
   2198 			result = ISC_R_SUCCESS;
   2199 			goto cleanup;
   2200 		}
   2201 
   2202 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   2203 		    !zone_touched(zone))
   2204 		{
   2205 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2206 				      ISC_LOG_DEBUG(1),
   2207 				      "skipping load: master file "
   2208 				      "older than last load");
   2209 			result = DNS_R_UPTODATE;
   2210 			goto cleanup;
   2211 		}
   2212 
   2213 		/*
   2214 		 * If the file modification time is in the past
   2215 		 * set loadtime to that value.
   2216 		 */
   2217 		result = isc_file_getmodtime(zone->masterfile, &filetime);
   2218 		if (result == ISC_R_SUCCESS &&
   2219 		    isc_time_compare(&loadtime, &filetime) > 0)
   2220 		{
   2221 			loadtime = filetime;
   2222 		}
   2223 	}
   2224 
   2225 	/*
   2226 	 * Built in zones (with the exception of empty zones) don't need
   2227 	 * to be reloaded.
   2228 	 */
   2229 	if (zone->type == dns_zone_primary &&
   2230 	    strcmp(zone->db_argv[0], "_builtin") == 0 &&
   2231 	    (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
   2232 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   2233 	{
   2234 		result = ISC_R_SUCCESS;
   2235 		goto cleanup;
   2236 	}
   2237 
   2238 	/*
   2239 	 * Zones associated with a DLZ don't need to be loaded either,
   2240 	 * but we need to associate the database with the zone object.
   2241 	 */
   2242 	if (strcmp(zone->db_argv[0], "dlz") == 0) {
   2243 		dns_dlzdb_t *dlzdb;
   2244 		dns_dlzfindzone_t findzone;
   2245 
   2246 		for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
   2247 		     dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link))
   2248 		{
   2249 			INSIST(DNS_DLZ_VALID(dlzdb));
   2250 			if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) {
   2251 				break;
   2252 			}
   2253 		}
   2254 
   2255 		if (dlzdb == NULL) {
   2256 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2257 				      ISC_LOG_ERROR,
   2258 				      "DLZ %s does not exist or is set "
   2259 				      "to 'search yes;'",
   2260 				      zone->db_argv[1]);
   2261 			result = ISC_R_NOTFOUND;
   2262 			goto cleanup;
   2263 		}
   2264 
   2265 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   2266 		/* ask SDLZ driver if the zone is supported */
   2267 		findzone = dlzdb->implementation->methods->findzone;
   2268 		result = (*findzone)(dlzdb->implementation->driverarg,
   2269 				     dlzdb->dbdata, dlzdb->mctx,
   2270 				     zone->view->rdclass, &zone->origin, NULL,
   2271 				     NULL, &db);
   2272 		if (result != ISC_R_NOTFOUND) {
   2273 			if (zone->db != NULL) {
   2274 				zone_detachdb(zone);
   2275 			}
   2276 			zone_attachdb(zone, db);
   2277 			dns_db_detach(&db);
   2278 			result = ISC_R_SUCCESS;
   2279 		}
   2280 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   2281 
   2282 		if (result == ISC_R_SUCCESS) {
   2283 			if (dlzdb->configure_callback == NULL) {
   2284 				goto cleanup;
   2285 			}
   2286 
   2287 			result = (*dlzdb->configure_callback)(zone->view, dlzdb,
   2288 							      zone);
   2289 			if (result != ISC_R_SUCCESS) {
   2290 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2291 					      ISC_LOG_ERROR,
   2292 					      "DLZ configuration callback: %s",
   2293 					      isc_result_totext(result));
   2294 			}
   2295 		}
   2296 		goto cleanup;
   2297 	}
   2298 
   2299 	if ((zone->type == dns_zone_secondary ||
   2300 	     zone->type == dns_zone_mirror || zone->type == dns_zone_stub ||
   2301 	     (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
   2302 	    rbt)
   2303 	{
   2304 		if (zone->masterfile == NULL ||
   2305 		    !isc_file_exists(zone->masterfile))
   2306 		{
   2307 			if (zone->masterfile != NULL) {
   2308 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2309 					      ISC_LOG_DEBUG(1),
   2310 					      "no master file");
   2311 			}
   2312 			zone->refreshtime = now;
   2313 			if (zone->task != NULL) {
   2314 				zone_settimer(zone, &now);
   2315 			}
   2316 			result = ISC_R_SUCCESS;
   2317 			goto cleanup;
   2318 		}
   2319 	}
   2320 
   2321 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   2322 		      "starting load");
   2323 
   2324 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   2325 			       (zone->type == dns_zone_stub) ? dns_dbtype_stub
   2326 							     : dns_dbtype_zone,
   2327 			       zone->rdclass, zone->db_argc - 1,
   2328 			       zone->db_argv + 1, &db);
   2329 
   2330 	if (result != ISC_R_SUCCESS) {
   2331 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   2332 			      "loading zone: creating database: %s",
   2333 			      isc_result_totext(result));
   2334 		goto cleanup;
   2335 	}
   2336 	dns_db_settask(db, zone->task);
   2337 
   2338 	if (zone->type == dns_zone_primary ||
   2339 	    zone->type == dns_zone_secondary || zone->type == dns_zone_mirror)
   2340 	{
   2341 		result = dns_db_setgluecachestats(db, zone->gluecachestats);
   2342 		if (result == ISC_R_NOTIMPLEMENTED) {
   2343 			result = ISC_R_SUCCESS;
   2344 		}
   2345 		if (result != ISC_R_SUCCESS) {
   2346 			goto cleanup;
   2347 		}
   2348 	}
   2349 
   2350 	if (!dns_db_ispersistent(db)) {
   2351 		if (zone->masterfile != NULL) {
   2352 			result = zone_startload(db, zone, loadtime);
   2353 		} else {
   2354 			result = DNS_R_NOMASTERFILE;
   2355 			if (zone->type == dns_zone_primary ||
   2356 			    (zone->type == dns_zone_redirect &&
   2357 			     zone->masters == NULL))
   2358 			{
   2359 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2360 					      ISC_LOG_ERROR,
   2361 					      "loading zone: "
   2362 					      "no master file configured");
   2363 				goto cleanup;
   2364 			}
   2365 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2366 				      ISC_LOG_INFO,
   2367 				      "loading zone: "
   2368 				      "no master file configured: continuing");
   2369 		}
   2370 	}
   2371 
   2372 	if (result == DNS_R_CONTINUE) {
   2373 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
   2374 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2375 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2376 		}
   2377 		goto cleanup;
   2378 	}
   2379 
   2380 	result = zone_postload(zone, db, loadtime, result);
   2381 
   2382 cleanup:
   2383 	if (hasraw) {
   2384 		UNLOCK_ZONE(zone->raw);
   2385 	}
   2386 	if (!locked) {
   2387 		UNLOCK_ZONE(zone);
   2388 	}
   2389 	if (db != NULL) {
   2390 		dns_db_detach(&db);
   2391 	}
   2392 	return (result);
   2393 }
   2394 
   2395 isc_result_t
   2396 dns_zone_load(dns_zone_t *zone, bool newonly) {
   2397 	return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
   2398 }
   2399 
   2400 static void
   2401 zone_asyncload(isc_task_t *task, isc_event_t *event) {
   2402 	dns_asyncload_t *asl = event->ev_arg;
   2403 	dns_zone_t *zone = asl->zone;
   2404 	isc_result_t result;
   2405 
   2406 	UNUSED(task);
   2407 
   2408 	REQUIRE(DNS_ZONE_VALID(zone));
   2409 
   2410 	isc_event_free(&event);
   2411 
   2412 	LOCK_ZONE(zone);
   2413 	result = zone_load(zone, asl->flags, true);
   2414 	if (result != DNS_R_CONTINUE) {
   2415 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2416 	}
   2417 	UNLOCK_ZONE(zone);
   2418 
   2419 	/* Inform the zone table we've finished loading */
   2420 	if (asl->loaded != NULL) {
   2421 		(asl->loaded)(asl->loaded_arg, zone, task);
   2422 	}
   2423 
   2424 	isc_mem_put(zone->mctx, asl, sizeof(*asl));
   2425 	dns_zone_idetach(&zone);
   2426 }
   2427 
   2428 isc_result_t
   2429 dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_zoneloaded_t done,
   2430 		   void *arg) {
   2431 	isc_event_t *e;
   2432 	dns_asyncload_t *asl = NULL;
   2433 
   2434 	REQUIRE(DNS_ZONE_VALID(zone));
   2435 
   2436 	if (zone->zmgr == NULL) {
   2437 		return (ISC_R_FAILURE);
   2438 	}
   2439 
   2440 	/* If we already have a load pending, stop now */
   2441 	LOCK_ZONE(zone);
   2442 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) {
   2443 		UNLOCK_ZONE(zone);
   2444 		return (ISC_R_ALREADYRUNNING);
   2445 	}
   2446 
   2447 	asl = isc_mem_get(zone->mctx, sizeof(*asl));
   2448 
   2449 	asl->zone = NULL;
   2450 	asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
   2451 	asl->loaded = done;
   2452 	asl->loaded_arg = arg;
   2453 
   2454 	e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, DNS_EVENT_ZONELOAD,
   2455 			       zone_asyncload, asl, sizeof(isc_event_t));
   2456 
   2457 	zone_iattach(zone, &asl->zone);
   2458 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2459 	isc_task_send(zone->loadtask, &e);
   2460 	UNLOCK_ZONE(zone);
   2461 
   2462 	return (ISC_R_SUCCESS);
   2463 }
   2464 
   2465 bool
   2466 dns__zone_loadpending(dns_zone_t *zone) {
   2467 	REQUIRE(DNS_ZONE_VALID(zone));
   2468 
   2469 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
   2470 }
   2471 
   2472 isc_result_t
   2473 dns_zone_loadandthaw(dns_zone_t *zone) {
   2474 	isc_result_t result;
   2475 
   2476 	if (inline_raw(zone)) {
   2477 		result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false);
   2478 	} else {
   2479 		/*
   2480 		 * When thawing a zone, we don't know what changes
   2481 		 * have been made. If we do DNSSEC maintenance on this
   2482 		 * zone, schedule a full sign for this zone.
   2483 		 */
   2484 		if (zone->type == dns_zone_primary &&
   2485 		    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   2486 		{
   2487 			DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN);
   2488 		}
   2489 		result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false);
   2490 	}
   2491 
   2492 	switch (result) {
   2493 	case DNS_R_CONTINUE:
   2494 		/* Deferred thaw. */
   2495 		break;
   2496 	case DNS_R_UPTODATE:
   2497 	case ISC_R_SUCCESS:
   2498 	case DNS_R_SEENINCLUDE:
   2499 		zone->update_disabled = false;
   2500 		break;
   2501 	case DNS_R_NOMASTERFILE:
   2502 		zone->update_disabled = false;
   2503 		break;
   2504 	default:
   2505 		/* Error, remain in disabled state. */
   2506 		break;
   2507 	}
   2508 	return (result);
   2509 }
   2510 
   2511 static unsigned int
   2512 get_master_options(dns_zone_t *zone) {
   2513 	unsigned int options;
   2514 
   2515 	options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
   2516 	if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror ||
   2517 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   2518 	{
   2519 		options |= DNS_MASTER_SLAVE;
   2520 	}
   2521 	if (zone->type == dns_zone_key) {
   2522 		options |= DNS_MASTER_KEY;
   2523 	}
   2524 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
   2525 		options |= DNS_MASTER_CHECKNS;
   2526 	}
   2527 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
   2528 		options |= DNS_MASTER_FATALNS;
   2529 	}
   2530 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
   2531 		options |= DNS_MASTER_CHECKNAMES;
   2532 	}
   2533 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
   2534 		options |= DNS_MASTER_CHECKNAMESFAIL;
   2535 	}
   2536 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
   2537 		options |= DNS_MASTER_CHECKMX;
   2538 	}
   2539 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2540 		options |= DNS_MASTER_CHECKMXFAIL;
   2541 	}
   2542 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
   2543 		options |= DNS_MASTER_CHECKWILDCARD;
   2544 	}
   2545 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
   2546 		options |= DNS_MASTER_CHECKTTL;
   2547 	}
   2548 
   2549 	return (options);
   2550 }
   2551 
   2552 static void
   2553 zone_registerinclude(const char *filename, void *arg) {
   2554 	isc_result_t result;
   2555 	dns_zone_t *zone = (dns_zone_t *)arg;
   2556 	dns_include_t *inc = NULL;
   2557 
   2558 	REQUIRE(DNS_ZONE_VALID(zone));
   2559 
   2560 	if (filename == NULL) {
   2561 		return;
   2562 	}
   2563 
   2564 	/*
   2565 	 * Suppress duplicates.
   2566 	 */
   2567 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   2568 	     inc = ISC_LIST_NEXT(inc, link))
   2569 	{
   2570 		if (strcmp(filename, inc->name) == 0) {
   2571 			return;
   2572 		}
   2573 	}
   2574 
   2575 	inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
   2576 	inc->name = isc_mem_strdup(zone->mctx, filename);
   2577 	ISC_LINK_INIT(inc, link);
   2578 
   2579 	result = isc_file_getmodtime(filename, &inc->filetime);
   2580 	if (result != ISC_R_SUCCESS) {
   2581 		isc_time_settoepoch(&inc->filetime);
   2582 	}
   2583 
   2584 	ISC_LIST_APPEND(zone->newincludes, inc, link);
   2585 }
   2586 
   2587 static void
   2588 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
   2589 	dns_load_t *load = event->ev_arg;
   2590 	isc_result_t result = ISC_R_SUCCESS;
   2591 	unsigned int options;
   2592 
   2593 	REQUIRE(DNS_LOAD_VALID(load));
   2594 
   2595 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2596 		result = ISC_R_CANCELED;
   2597 	}
   2598 	isc_event_free(&event);
   2599 	if (result == ISC_R_CANCELED) {
   2600 		goto fail;
   2601 	}
   2602 
   2603 	options = get_master_options(load->zone);
   2604 
   2605 	result = dns_master_loadfileinc(
   2606 		load->zone->masterfile, dns_db_origin(load->db),
   2607 		dns_db_origin(load->db), load->zone->rdclass, options, 0,
   2608 		&load->callbacks, task, zone_loaddone, load, &load->zone->lctx,
   2609 		zone_registerinclude, load->zone, load->zone->mctx,
   2610 		load->zone->masterformat, load->zone->maxttl);
   2611 	if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
   2612 	    result != DNS_R_SEENINCLUDE)
   2613 	{
   2614 		goto fail;
   2615 	}
   2616 	return;
   2617 
   2618 fail:
   2619 	zone_loaddone(load, result);
   2620 }
   2621 
   2622 static void
   2623 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
   2624 	isc_result_t result;
   2625 	unsigned int soacount;
   2626 
   2627 	LOCK(&raw->lock);
   2628 	if (raw->db != NULL) {
   2629 		result = zone_get_from_db(raw, raw->db, NULL, &soacount, NULL,
   2630 					  &rawdata->sourceserial, NULL, NULL,
   2631 					  NULL, NULL, NULL);
   2632 		if (result == ISC_R_SUCCESS && soacount > 0U) {
   2633 			rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
   2634 		}
   2635 	}
   2636 	UNLOCK(&raw->lock);
   2637 }
   2638 
   2639 static void
   2640 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
   2641 	const char me[] = "zone_gotwritehandle";
   2642 	dns_zone_t *zone = event->ev_arg;
   2643 	isc_result_t result = ISC_R_SUCCESS;
   2644 	dns_dbversion_t *version = NULL;
   2645 	dns_masterrawheader_t rawdata;
   2646 	dns_db_t *db = NULL;
   2647 
   2648 	REQUIRE(DNS_ZONE_VALID(zone));
   2649 	INSIST(task == zone->task);
   2650 	ENTER;
   2651 
   2652 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2653 		result = ISC_R_CANCELED;
   2654 	}
   2655 	isc_event_free(&event);
   2656 	if (result == ISC_R_CANCELED) {
   2657 		goto fail;
   2658 	}
   2659 
   2660 	LOCK_ZONE(zone);
   2661 	INSIST(zone != zone->raw);
   2662 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   2663 	if (zone->db != NULL) {
   2664 		dns_db_attach(zone->db, &db);
   2665 	}
   2666 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   2667 	if (db != NULL) {
   2668 		const dns_master_style_t *output_style;
   2669 		dns_db_currentversion(db, &version);
   2670 		dns_master_initrawheader(&rawdata);
   2671 		if (inline_secure(zone)) {
   2672 			get_raw_serial(zone->raw, &rawdata);
   2673 		}
   2674 		if (zone->type == dns_zone_key) {
   2675 			output_style = &dns_master_style_keyzone;
   2676 		} else if (zone->masterstyle != NULL) {
   2677 			output_style = zone->masterstyle;
   2678 		} else {
   2679 			output_style = &dns_master_style_default;
   2680 		}
   2681 		result = dns_master_dumpasync(
   2682 			zone->mctx, db, version, output_style, zone->masterfile,
   2683 			zone->task, dump_done, zone, &zone->dctx,
   2684 			zone->masterformat, &rawdata);
   2685 		dns_db_closeversion(db, &version, false);
   2686 	} else {
   2687 		result = ISC_R_CANCELED;
   2688 	}
   2689 	if (db != NULL) {
   2690 		dns_db_detach(&db);
   2691 	}
   2692 	UNLOCK_ZONE(zone);
   2693 	if (result != DNS_R_CONTINUE) {
   2694 		goto fail;
   2695 	}
   2696 	return;
   2697 
   2698 fail:
   2699 	dump_done(zone, result);
   2700 }
   2701 
   2702 /*
   2703  * Save the raw serial number for inline-signing zones.
   2704  * (XXX: Other information from the header will be used
   2705  * for other purposes in the future, but for now this is
   2706  * all we're interested in.)
   2707  */
   2708 static void
   2709 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2710 	if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) {
   2711 		return;
   2712 	}
   2713 
   2714 	zone->sourceserial = header->sourceserial;
   2715 	zone->sourceserialset = true;
   2716 }
   2717 
   2718 void
   2719 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2720 	if (zone == NULL) {
   2721 		return;
   2722 	}
   2723 
   2724 	LOCK_ZONE(zone);
   2725 	zone_setrawdata(zone, header);
   2726 	UNLOCK_ZONE(zone);
   2727 }
   2728 
   2729 static isc_result_t
   2730 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
   2731 	const char me[] = "zone_startload";
   2732 	dns_load_t *load;
   2733 	isc_result_t result;
   2734 	isc_result_t tresult;
   2735 	unsigned int options;
   2736 
   2737 	ENTER;
   2738 
   2739 	dns_zone_rpz_enable_db(zone, db);
   2740 	dns_zone_catz_enable_db(zone, db);
   2741 
   2742 	options = get_master_options(zone);
   2743 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) {
   2744 		options |= DNS_MASTER_MANYERRORS;
   2745 	}
   2746 
   2747 	if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
   2748 		load = isc_mem_get(zone->mctx, sizeof(*load));
   2749 
   2750 		load->mctx = NULL;
   2751 		load->zone = NULL;
   2752 		load->db = NULL;
   2753 		load->loadtime = loadtime;
   2754 		load->magic = LOAD_MAGIC;
   2755 
   2756 		isc_mem_attach(zone->mctx, &load->mctx);
   2757 		zone_iattach(zone, &load->zone);
   2758 		dns_db_attach(db, &load->db);
   2759 		dns_rdatacallbacks_init(&load->callbacks);
   2760 		load->callbacks.rawdata = zone_setrawdata;
   2761 		zone_iattach(zone, &load->callbacks.zone);
   2762 		result = dns_db_beginload(db, &load->callbacks);
   2763 		if (result != ISC_R_SUCCESS) {
   2764 			goto cleanup;
   2765 		}
   2766 		result = zonemgr_getio(zone->zmgr, true, zone->loadtask,
   2767 				       zone_gotreadhandle, load, &zone->readio);
   2768 		if (result != ISC_R_SUCCESS) {
   2769 			/*
   2770 			 * We can't report multiple errors so ignore
   2771 			 * the result of dns_db_endload().
   2772 			 */
   2773 			(void)dns_db_endload(load->db, &load->callbacks);
   2774 			goto cleanup;
   2775 		} else {
   2776 			result = DNS_R_CONTINUE;
   2777 		}
   2778 	} else {
   2779 		dns_rdatacallbacks_t callbacks;
   2780 
   2781 		dns_rdatacallbacks_init(&callbacks);
   2782 		callbacks.rawdata = zone_setrawdata;
   2783 		zone_iattach(zone, &callbacks.zone);
   2784 		result = dns_db_beginload(db, &callbacks);
   2785 		if (result != ISC_R_SUCCESS) {
   2786 			zone_idetach(&callbacks.zone);
   2787 			return (result);
   2788 		}
   2789 		result = dns_master_loadfile(
   2790 			zone->masterfile, &zone->origin, &zone->origin,
   2791 			zone->rdclass, options, 0, &callbacks,
   2792 			zone_registerinclude, zone, zone->mctx,
   2793 			zone->masterformat, zone->maxttl);
   2794 		tresult = dns_db_endload(db, &callbacks);
   2795 		if (result == ISC_R_SUCCESS) {
   2796 			result = tresult;
   2797 		}
   2798 		zone_idetach(&callbacks.zone);
   2799 	}
   2800 
   2801 	return (result);
   2802 
   2803 cleanup:
   2804 	load->magic = 0;
   2805 	dns_db_detach(&load->db);
   2806 	zone_idetach(&load->zone);
   2807 	zone_idetach(&load->callbacks.zone);
   2808 	isc_mem_detach(&load->mctx);
   2809 	isc_mem_put(zone->mctx, load, sizeof(*load));
   2810 	return (result);
   2811 }
   2812 
   2813 static bool
   2814 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2815 	      dns_name_t *owner) {
   2816 	isc_result_t result;
   2817 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2818 	char namebuf[DNS_NAME_FORMATSIZE];
   2819 	char altbuf[DNS_NAME_FORMATSIZE];
   2820 	dns_fixedname_t fixed;
   2821 	dns_name_t *foundname;
   2822 	int level;
   2823 
   2824 	/*
   2825 	 * "." means the services does not exist.
   2826 	 */
   2827 	if (dns_name_equal(name, dns_rootname)) {
   2828 		return (true);
   2829 	}
   2830 
   2831 	/*
   2832 	 * Outside of zone.
   2833 	 */
   2834 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2835 		if (zone->checkmx != NULL) {
   2836 			return ((zone->checkmx)(zone, name, owner));
   2837 		}
   2838 		return (true);
   2839 	}
   2840 
   2841 	if (zone->type == dns_zone_primary) {
   2842 		level = ISC_LOG_ERROR;
   2843 	} else {
   2844 		level = ISC_LOG_WARNING;
   2845 	}
   2846 
   2847 	foundname = dns_fixedname_initname(&fixed);
   2848 
   2849 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2850 			     foundname, NULL, NULL);
   2851 	if (result == ISC_R_SUCCESS) {
   2852 		return (true);
   2853 	}
   2854 
   2855 	if (result == DNS_R_NXRRSET) {
   2856 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2857 				     NULL, foundname, NULL, NULL);
   2858 		if (result == ISC_R_SUCCESS) {
   2859 			return (true);
   2860 		}
   2861 	}
   2862 
   2863 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2864 	dns_name_format(name, namebuf, sizeof namebuf);
   2865 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2866 	    result == DNS_R_EMPTYNAME)
   2867 	{
   2868 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2869 			level = ISC_LOG_WARNING;
   2870 		}
   2871 		dns_zone_log(zone, level,
   2872 			     "%s/MX '%s' has no address records (A or AAAA)",
   2873 			     ownerbuf, namebuf);
   2874 		return ((level == ISC_LOG_WARNING) ? true : false);
   2875 	}
   2876 
   2877 	if (result == DNS_R_CNAME) {
   2878 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2879 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2880 		{
   2881 			level = ISC_LOG_WARNING;
   2882 		}
   2883 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2884 			dns_zone_log(zone, level,
   2885 				     "%s/MX '%s' is a CNAME (illegal)",
   2886 				     ownerbuf, namebuf);
   2887 		}
   2888 		return ((level == ISC_LOG_WARNING) ? true : false);
   2889 	}
   2890 
   2891 	if (result == DNS_R_DNAME) {
   2892 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2893 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2894 		{
   2895 			level = ISC_LOG_WARNING;
   2896 		}
   2897 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2898 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2899 			dns_zone_log(zone, level,
   2900 				     "%s/MX '%s' is below a DNAME"
   2901 				     " '%s' (illegal)",
   2902 				     ownerbuf, namebuf, altbuf);
   2903 		}
   2904 		return ((level == ISC_LOG_WARNING) ? true : false);
   2905 	}
   2906 
   2907 	if (zone->checkmx != NULL && result == DNS_R_DELEGATION) {
   2908 		return ((zone->checkmx)(zone, name, owner));
   2909 	}
   2910 
   2911 	return (true);
   2912 }
   2913 
   2914 static bool
   2915 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2916 	       dns_name_t *owner) {
   2917 	isc_result_t result;
   2918 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2919 	char namebuf[DNS_NAME_FORMATSIZE];
   2920 	char altbuf[DNS_NAME_FORMATSIZE];
   2921 	dns_fixedname_t fixed;
   2922 	dns_name_t *foundname;
   2923 	int level;
   2924 
   2925 	/*
   2926 	 * "." means the services does not exist.
   2927 	 */
   2928 	if (dns_name_equal(name, dns_rootname)) {
   2929 		return (true);
   2930 	}
   2931 
   2932 	/*
   2933 	 * Outside of zone.
   2934 	 */
   2935 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2936 		if (zone->checksrv != NULL) {
   2937 			return ((zone->checksrv)(zone, name, owner));
   2938 		}
   2939 		return (true);
   2940 	}
   2941 
   2942 	if (zone->type == dns_zone_primary) {
   2943 		level = ISC_LOG_ERROR;
   2944 	} else {
   2945 		level = ISC_LOG_WARNING;
   2946 	}
   2947 
   2948 	foundname = dns_fixedname_initname(&fixed);
   2949 
   2950 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2951 			     foundname, NULL, NULL);
   2952 	if (result == ISC_R_SUCCESS) {
   2953 		return (true);
   2954 	}
   2955 
   2956 	if (result == DNS_R_NXRRSET) {
   2957 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2958 				     NULL, foundname, NULL, NULL);
   2959 		if (result == ISC_R_SUCCESS) {
   2960 			return (true);
   2961 		}
   2962 	}
   2963 
   2964 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2965 	dns_name_format(name, namebuf, sizeof namebuf);
   2966 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2967 	    result == DNS_R_EMPTYNAME)
   2968 	{
   2969 		dns_zone_log(zone, level,
   2970 			     "%s/SRV '%s' has no address records (A or AAAA)",
   2971 			     ownerbuf, namebuf);
   2972 		/* XXX950 make fatal for 9.5.0. */
   2973 		return (true);
   2974 	}
   2975 
   2976 	if (result == DNS_R_CNAME) {
   2977 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2978 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2979 		{
   2980 			level = ISC_LOG_WARNING;
   2981 		}
   2982 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   2983 			dns_zone_log(zone, level,
   2984 				     "%s/SRV '%s' is a CNAME (illegal)",
   2985 				     ownerbuf, namebuf);
   2986 		}
   2987 		return ((level == ISC_LOG_WARNING) ? true : false);
   2988 	}
   2989 
   2990 	if (result == DNS_R_DNAME) {
   2991 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2992 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2993 		{
   2994 			level = ISC_LOG_WARNING;
   2995 		}
   2996 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   2997 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2998 			dns_zone_log(zone, level,
   2999 				     "%s/SRV '%s' is below a "
   3000 				     "DNAME '%s' (illegal)",
   3001 				     ownerbuf, namebuf, altbuf);
   3002 		}
   3003 		return ((level == ISC_LOG_WARNING) ? true : false);
   3004 	}
   3005 
   3006 	if (zone->checksrv != NULL && result == DNS_R_DELEGATION) {
   3007 		return ((zone->checksrv)(zone, name, owner));
   3008 	}
   3009 
   3010 	return (true);
   3011 }
   3012 
   3013 static bool
   3014 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   3015 		dns_name_t *owner) {
   3016 	bool answer = true;
   3017 	isc_result_t result, tresult;
   3018 	char ownerbuf[DNS_NAME_FORMATSIZE];
   3019 	char namebuf[DNS_NAME_FORMATSIZE];
   3020 	char altbuf[DNS_NAME_FORMATSIZE];
   3021 	dns_fixedname_t fixed;
   3022 	dns_name_t *foundname;
   3023 	dns_rdataset_t a;
   3024 	dns_rdataset_t aaaa;
   3025 	int level;
   3026 
   3027 	/*
   3028 	 * Outside of zone.
   3029 	 */
   3030 	if (!dns_name_issubdomain(name, &zone->origin)) {
   3031 		if (zone->checkns != NULL) {
   3032 			return ((zone->checkns)(zone, name, owner, NULL, NULL));
   3033 		}
   3034 		return (true);
   3035 	}
   3036 
   3037 	if (zone->type == dns_zone_primary) {
   3038 		level = ISC_LOG_ERROR;
   3039 	} else {
   3040 		level = ISC_LOG_WARNING;
   3041 	}
   3042 
   3043 	foundname = dns_fixedname_initname(&fixed);
   3044 	dns_rdataset_init(&a);
   3045 	dns_rdataset_init(&aaaa);
   3046 
   3047 	/*
   3048 	 * Perform a regular lookup to catch DNAME records then look
   3049 	 * for glue.
   3050 	 */
   3051 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   3052 			     foundname, &a, NULL);
   3053 	switch (result) {
   3054 	case ISC_R_SUCCESS:
   3055 	case DNS_R_DNAME:
   3056 	case DNS_R_CNAME:
   3057 		break;
   3058 	default:
   3059 		if (dns_rdataset_isassociated(&a)) {
   3060 			dns_rdataset_disassociate(&a);
   3061 		}
   3062 		result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   3063 				     DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a,
   3064 				     NULL);
   3065 	}
   3066 	if (result == ISC_R_SUCCESS) {
   3067 		dns_rdataset_disassociate(&a);
   3068 		return (true);
   3069 	} else if (result == DNS_R_DELEGATION) {
   3070 		dns_rdataset_disassociate(&a);
   3071 	}
   3072 
   3073 	if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
   3074 	    result == DNS_R_GLUE)
   3075 	{
   3076 		tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
   3077 				      DNS_DBFIND_GLUEOK, 0, NULL, foundname,
   3078 				      &aaaa, NULL);
   3079 		if (tresult == ISC_R_SUCCESS) {
   3080 			if (dns_rdataset_isassociated(&a)) {
   3081 				dns_rdataset_disassociate(&a);
   3082 			}
   3083 			dns_rdataset_disassociate(&aaaa);
   3084 			return (true);
   3085 		}
   3086 		if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) {
   3087 			dns_rdataset_disassociate(&aaaa);
   3088 		}
   3089 		if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
   3090 			/*
   3091 			 * Check glue against child zone.
   3092 			 */
   3093 			if (zone->checkns != NULL) {
   3094 				answer = (zone->checkns)(zone, name, owner, &a,
   3095 							 &aaaa);
   3096 			}
   3097 			if (dns_rdataset_isassociated(&a)) {
   3098 				dns_rdataset_disassociate(&a);
   3099 			}
   3100 			if (dns_rdataset_isassociated(&aaaa)) {
   3101 				dns_rdataset_disassociate(&aaaa);
   3102 			}
   3103 			return (answer);
   3104 		}
   3105 	}
   3106 
   3107 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   3108 	dns_name_format(name, namebuf, sizeof namebuf);
   3109 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   3110 	    result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION)
   3111 	{
   3112 		const char *what;
   3113 		bool required = false;
   3114 		if (dns_name_issubdomain(name, owner)) {
   3115 			what = "REQUIRED GLUE ";
   3116 			required = true;
   3117 		} else if (result == DNS_R_DELEGATION) {
   3118 			what = "SIBLING GLUE ";
   3119 		} else {
   3120 			what = "";
   3121 		}
   3122 
   3123 		if (result != DNS_R_DELEGATION || required ||
   3124 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING))
   3125 		{
   3126 			dns_zone_log(zone, level,
   3127 				     "%s/NS '%s' has no %s"
   3128 				     "address records (A or AAAA)",
   3129 				     ownerbuf, namebuf, what);
   3130 			/*
   3131 			 * Log missing address record.
   3132 			 */
   3133 			if (result == DNS_R_DELEGATION && zone->checkns != NULL)
   3134 			{
   3135 				(void)(zone->checkns)(zone, name, owner, &a,
   3136 						      &aaaa);
   3137 			}
   3138 			/* XXX950 make fatal for 9.5.0. */
   3139 			/* answer = false; */
   3140 		}
   3141 	} else if (result == DNS_R_CNAME) {
   3142 		dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
   3143 			     ownerbuf, namebuf);
   3144 		/* XXX950 make fatal for 9.5.0. */
   3145 		/* answer = false; */
   3146 	} else if (result == DNS_R_DNAME) {
   3147 		dns_name_format(foundname, altbuf, sizeof altbuf);
   3148 		dns_zone_log(zone, level,
   3149 			     "%s/NS '%s' is below a DNAME '%s' (illegal)",
   3150 			     ownerbuf, namebuf, altbuf);
   3151 		/* XXX950 make fatal for 9.5.0. */
   3152 		/* answer = false; */
   3153 	}
   3154 
   3155 	if (dns_rdataset_isassociated(&a)) {
   3156 		dns_rdataset_disassociate(&a);
   3157 	}
   3158 	if (dns_rdataset_isassociated(&aaaa)) {
   3159 		dns_rdataset_disassociate(&aaaa);
   3160 	}
   3161 	return (answer);
   3162 }
   3163 
   3164 static bool
   3165 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
   3166 		     dns_rdataset_t *rdataset) {
   3167 	dns_rdataset_t tmprdataset;
   3168 	isc_result_t result;
   3169 	bool answer = true;
   3170 	bool format = true;
   3171 	int level = ISC_LOG_WARNING;
   3172 	char ownerbuf[DNS_NAME_FORMATSIZE];
   3173 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   3174 	unsigned int count1 = 0;
   3175 
   3176 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) {
   3177 		level = ISC_LOG_ERROR;
   3178 	}
   3179 
   3180 	dns_rdataset_init(&tmprdataset);
   3181 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   3182 	     result = dns_rdataset_next(rdataset))
   3183 	{
   3184 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   3185 		unsigned int count2 = 0;
   3186 
   3187 		count1++;
   3188 		dns_rdataset_current(rdataset, &rdata1);
   3189 		dns_rdataset_clone(rdataset, &tmprdataset);
   3190 		for (result = dns_rdataset_first(&tmprdataset);
   3191 		     result == ISC_R_SUCCESS;
   3192 		     result = dns_rdataset_next(&tmprdataset))
   3193 		{
   3194 			dns_rdata_t rdata2 = DNS_RDATA_INIT;
   3195 			count2++;
   3196 			if (count1 >= count2) {
   3197 				continue;
   3198 			}
   3199 			dns_rdataset_current(&tmprdataset, &rdata2);
   3200 			if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
   3201 				if (format) {
   3202 					dns_name_format(owner, ownerbuf,
   3203 							sizeof ownerbuf);
   3204 					dns_rdatatype_format(rdata1.type,
   3205 							     typebuf,
   3206 							     sizeof(typebuf));
   3207 					format = false;
   3208 				}
   3209 				dns_zone_log(zone, level,
   3210 					     "%s/%s has "
   3211 					     "semantically identical records",
   3212 					     ownerbuf, typebuf);
   3213 				if (level == ISC_LOG_ERROR) {
   3214 					answer = false;
   3215 				}
   3216 				break;
   3217 			}
   3218 		}
   3219 		dns_rdataset_disassociate(&tmprdataset);
   3220 		if (!format) {
   3221 			break;
   3222 		}
   3223 	}
   3224 	return (answer);
   3225 }
   3226 
   3227 static bool
   3228 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
   3229 	dns_dbiterator_t *dbiterator = NULL;
   3230 	dns_dbnode_t *node = NULL;
   3231 	dns_fixedname_t fixed;
   3232 	dns_name_t *name;
   3233 	dns_rdataset_t rdataset;
   3234 	dns_rdatasetiter_t *rdsit = NULL;
   3235 	bool ok = true;
   3236 	isc_result_t result;
   3237 
   3238 	name = dns_fixedname_initname(&fixed);
   3239 	dns_rdataset_init(&rdataset);
   3240 
   3241 	result = dns_db_createiterator(db, 0, &dbiterator);
   3242 	if (result != ISC_R_SUCCESS) {
   3243 		return (true);
   3244 	}
   3245 
   3246 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   3247 	     result = dns_dbiterator_next(dbiterator))
   3248 	{
   3249 		result = dns_dbiterator_current(dbiterator, &node, name);
   3250 		if (result != ISC_R_SUCCESS) {
   3251 			continue;
   3252 		}
   3253 
   3254 		result = dns_db_allrdatasets(db, node, NULL, 0, 0, &rdsit);
   3255 		if (result != ISC_R_SUCCESS) {
   3256 			continue;
   3257 		}
   3258 
   3259 		for (result = dns_rdatasetiter_first(rdsit);
   3260 		     result == ISC_R_SUCCESS;
   3261 		     result = dns_rdatasetiter_next(rdsit))
   3262 		{
   3263 			dns_rdatasetiter_current(rdsit, &rdataset);
   3264 			if (!zone_rrset_check_dup(zone, name, &rdataset)) {
   3265 				ok = false;
   3266 			}
   3267 			dns_rdataset_disassociate(&rdataset);
   3268 		}
   3269 		dns_rdatasetiter_destroy(&rdsit);
   3270 		dns_db_detachnode(db, &node);
   3271 	}
   3272 
   3273 	if (node != NULL) {
   3274 		dns_db_detachnode(db, &node);
   3275 	}
   3276 	dns_dbiterator_destroy(&dbiterator);
   3277 
   3278 	return (ok);
   3279 }
   3280 
   3281 static bool
   3282 isspf(const dns_rdata_t *rdata) {
   3283 	char buf[1024];
   3284 	const unsigned char *data = rdata->data;
   3285 	unsigned int rdl = rdata->length, i = 0, tl, len;
   3286 
   3287 	while (rdl > 0U) {
   3288 		len = tl = *data;
   3289 		++data;
   3290 		--rdl;
   3291 		INSIST(tl <= rdl);
   3292 		if (len > sizeof(buf) - i - 1) {
   3293 			len = sizeof(buf) - i - 1;
   3294 		}
   3295 		memmove(buf + i, data, len);
   3296 		i += len;
   3297 		data += tl;
   3298 		rdl -= tl;
   3299 	}
   3300 
   3301 	if (i < 6U) {
   3302 		return (false);
   3303 	}
   3304 
   3305 	buf[i] = 0;
   3306 	if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) {
   3307 		return (true);
   3308 	}
   3309 	return (false);
   3310 }
   3311 
   3312 static bool
   3313 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
   3314 	dns_dbiterator_t *dbiterator = NULL;
   3315 	dns_dbnode_t *node = NULL;
   3316 	dns_rdataset_t rdataset;
   3317 	dns_fixedname_t fixed;
   3318 	dns_fixedname_t fixedbottom;
   3319 	dns_rdata_mx_t mx;
   3320 	dns_rdata_ns_t ns;
   3321 	dns_rdata_in_srv_t srv;
   3322 	dns_rdata_t rdata;
   3323 	dns_name_t *name;
   3324 	dns_name_t *bottom;
   3325 	isc_result_t result;
   3326 	bool ok = true, have_spf, have_txt;
   3327 
   3328 	name = dns_fixedname_initname(&fixed);
   3329 	bottom = dns_fixedname_initname(&fixedbottom);
   3330 	dns_rdataset_init(&rdataset);
   3331 	dns_rdata_init(&rdata);
   3332 
   3333 	result = dns_db_createiterator(db, 0, &dbiterator);
   3334 	if (result != ISC_R_SUCCESS) {
   3335 		return (true);
   3336 	}
   3337 
   3338 	result = dns_dbiterator_first(dbiterator);
   3339 	while (result == ISC_R_SUCCESS) {
   3340 		result = dns_dbiterator_current(dbiterator, &node, name);
   3341 		if (result != ISC_R_SUCCESS) {
   3342 			goto cleanup;
   3343 		}
   3344 
   3345 		/*
   3346 		 * Is this name visible in the zone?
   3347 		 */
   3348 		if (!dns_name_issubdomain(name, &zone->origin) ||
   3349 		    (dns_name_countlabels(bottom) > 0 &&
   3350 		     dns_name_issubdomain(name, bottom)))
   3351 		{
   3352 			goto next;
   3353 		}
   3354 
   3355 		dns_dbiterator_pause(dbiterator);
   3356 
   3357 		/*
   3358 		 * Don't check the NS records at the origin.
   3359 		 */
   3360 		if (dns_name_equal(name, &zone->origin)) {
   3361 			goto checkfordname;
   3362 		}
   3363 
   3364 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
   3365 					     0, 0, &rdataset, NULL);
   3366 		if (result != ISC_R_SUCCESS) {
   3367 			goto checkfordname;
   3368 		}
   3369 		/*
   3370 		 * Remember bottom of zone due to NS.
   3371 		 */
   3372 		dns_name_copynf(name, bottom);
   3373 
   3374 		result = dns_rdataset_first(&rdataset);
   3375 		while (result == ISC_R_SUCCESS) {
   3376 			dns_rdataset_current(&rdataset, &rdata);
   3377 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   3378 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3379 			if (!zone_check_glue(zone, db, &ns.name, name)) {
   3380 				ok = false;
   3381 			}
   3382 			dns_rdata_reset(&rdata);
   3383 			result = dns_rdataset_next(&rdataset);
   3384 		}
   3385 		dns_rdataset_disassociate(&rdataset);
   3386 		goto next;
   3387 
   3388 	checkfordname:
   3389 		result = dns_db_findrdataset(db, node, NULL,
   3390 					     dns_rdatatype_dname, 0, 0,
   3391 					     &rdataset, NULL);
   3392 		if (result == ISC_R_SUCCESS) {
   3393 			/*
   3394 			 * Remember bottom of zone due to DNAME.
   3395 			 */
   3396 			dns_name_copynf(name, bottom);
   3397 			dns_rdataset_disassociate(&rdataset);
   3398 		}
   3399 
   3400 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
   3401 					     0, 0, &rdataset, NULL);
   3402 		if (result != ISC_R_SUCCESS) {
   3403 			goto checksrv;
   3404 		}
   3405 		result = dns_rdataset_first(&rdataset);
   3406 		while (result == ISC_R_SUCCESS) {
   3407 			dns_rdataset_current(&rdataset, &rdata);
   3408 			result = dns_rdata_tostruct(&rdata, &mx, NULL);
   3409 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3410 			if (!zone_check_mx(zone, db, &mx.mx, name)) {
   3411 				ok = false;
   3412 			}
   3413 			dns_rdata_reset(&rdata);
   3414 			result = dns_rdataset_next(&rdataset);
   3415 		}
   3416 		dns_rdataset_disassociate(&rdataset);
   3417 
   3418 	checksrv:
   3419 		if (zone->rdclass != dns_rdataclass_in) {
   3420 			goto next;
   3421 		}
   3422 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
   3423 					     0, 0, &rdataset, NULL);
   3424 		if (result != ISC_R_SUCCESS) {
   3425 			goto checkspf;
   3426 		}
   3427 		result = dns_rdataset_first(&rdataset);
   3428 		while (result == ISC_R_SUCCESS) {
   3429 			dns_rdataset_current(&rdataset, &rdata);
   3430 			result = dns_rdata_tostruct(&rdata, &srv, NULL);
   3431 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3432 			if (!zone_check_srv(zone, db, &srv.target, name)) {
   3433 				ok = false;
   3434 			}
   3435 			dns_rdata_reset(&rdata);
   3436 			result = dns_rdataset_next(&rdataset);
   3437 		}
   3438 		dns_rdataset_disassociate(&rdataset);
   3439 
   3440 	checkspf:
   3441 		/*
   3442 		 * Check if there is a type SPF record without an
   3443 		 * SPF-formatted type TXT record also being present.
   3444 		 */
   3445 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) {
   3446 			goto next;
   3447 		}
   3448 		if (zone->rdclass != dns_rdataclass_in) {
   3449 			goto next;
   3450 		}
   3451 		have_spf = have_txt = false;
   3452 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
   3453 					     0, 0, &rdataset, NULL);
   3454 		if (result == ISC_R_SUCCESS) {
   3455 			dns_rdataset_disassociate(&rdataset);
   3456 			have_spf = true;
   3457 		}
   3458 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
   3459 					     0, 0, &rdataset, NULL);
   3460 		if (result != ISC_R_SUCCESS) {
   3461 			goto notxt;
   3462 		}
   3463 		result = dns_rdataset_first(&rdataset);
   3464 		while (result == ISC_R_SUCCESS) {
   3465 			dns_rdataset_current(&rdataset, &rdata);
   3466 			have_txt = isspf(&rdata);
   3467 			dns_rdata_reset(&rdata);
   3468 			if (have_txt) {
   3469 				break;
   3470 			}
   3471 			result = dns_rdataset_next(&rdataset);
   3472 		}
   3473 		dns_rdataset_disassociate(&rdataset);
   3474 
   3475 	notxt:
   3476 		if (have_spf && !have_txt) {
   3477 			char namebuf[DNS_NAME_FORMATSIZE];
   3478 
   3479 			dns_name_format(name, namebuf, sizeof(namebuf));
   3480 			dns_zone_log(zone, ISC_LOG_WARNING,
   3481 				     "'%s' found type "
   3482 				     "SPF record but no SPF TXT record found, "
   3483 				     "add matching type TXT record",
   3484 				     namebuf);
   3485 		}
   3486 
   3487 	next:
   3488 		dns_db_detachnode(db, &node);
   3489 		result = dns_dbiterator_next(dbiterator);
   3490 	}
   3491 
   3492 cleanup:
   3493 	if (node != NULL) {
   3494 		dns_db_detachnode(db, &node);
   3495 	}
   3496 	dns_dbiterator_destroy(&dbiterator);
   3497 
   3498 	return (ok);
   3499 }
   3500 
   3501 /*
   3502  * OpenSSL verification of RSA keys with exponent 3 is known to be
   3503  * broken prior OpenSSL 0.9.8c/0.9.7k.	Look for such keys and warn
   3504  * if they are in use.
   3505  */
   3506 static void
   3507 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
   3508 	dns_dbnode_t *node = NULL;
   3509 	dns_dbversion_t *version = NULL;
   3510 	dns_rdata_dnskey_t dnskey;
   3511 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3512 	dns_rdataset_t rdataset;
   3513 	isc_result_t result;
   3514 
   3515 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3516 	if (result != ISC_R_SUCCESS) {
   3517 		goto cleanup;
   3518 	}
   3519 
   3520 	dns_db_currentversion(db, &version);
   3521 	dns_rdataset_init(&rdataset);
   3522 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   3523 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3524 	if (result != ISC_R_SUCCESS) {
   3525 		goto cleanup;
   3526 	}
   3527 
   3528 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3529 	     result = dns_rdataset_next(&rdataset))
   3530 	{
   3531 		dns_rdataset_current(&rdataset, &rdata);
   3532 		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
   3533 		INSIST(result == ISC_R_SUCCESS);
   3534 
   3535 		/*
   3536 		 * RFC 3110, section 4: Performance Considerations:
   3537 		 *
   3538 		 * A public exponent of 3 minimizes the effort needed to verify
   3539 		 * a signature.  Use of 3 as the public exponent is weak for
   3540 		 * confidentiality uses since, if the same data can be collected
   3541 		 * encrypted under three different keys with an exponent of 3
   3542 		 * then, using the Chinese Remainder Theorem [NETSEC], the
   3543 		 * original plain text can be easily recovered.  If a key is
   3544 		 * known to be used only for authentication, as is the case with
   3545 		 * DNSSEC, then an exponent of 3 is acceptable.  However other
   3546 		 * applications in the future may wish to leverage DNS
   3547 		 * distributed keys for applications that do require
   3548 		 * confidentiality.  For keys which might have such other uses,
   3549 		 * a more conservative choice would be 65537 (F4, the fourth
   3550 		 * fermat number).
   3551 		 */
   3552 		if (dnskey.datalen > 1 && dnskey.data[0] == 1 &&
   3553 		    dnskey.data[1] == 3 &&
   3554 		    (dnskey.algorithm == DNS_KEYALG_RSAMD5 ||
   3555 		     dnskey.algorithm == DNS_KEYALG_RSASHA1 ||
   3556 		     dnskey.algorithm == DNS_KEYALG_NSEC3RSASHA1 ||
   3557 		     dnskey.algorithm == DNS_KEYALG_RSASHA256 ||
   3558 		     dnskey.algorithm == DNS_KEYALG_RSASHA512))
   3559 		{
   3560 			char algorithm[DNS_SECALG_FORMATSIZE];
   3561 			isc_region_t r;
   3562 
   3563 			dns_rdata_toregion(&rdata, &r);
   3564 			dns_secalg_format(dnskey.algorithm, algorithm,
   3565 					  sizeof(algorithm));
   3566 
   3567 			dnssec_log(zone, ISC_LOG_WARNING,
   3568 				   "weak %s (%u) key found (exponent=3, id=%u)",
   3569 				   algorithm, dnskey.algorithm,
   3570 				   dst_region_computeid(&r));
   3571 		}
   3572 		dns_rdata_reset(&rdata);
   3573 	}
   3574 	dns_rdataset_disassociate(&rdataset);
   3575 
   3576 cleanup:
   3577 	if (node != NULL) {
   3578 		dns_db_detachnode(db, &node);
   3579 	}
   3580 	if (version != NULL) {
   3581 		dns_db_closeversion(db, &version, false);
   3582 	}
   3583 }
   3584 
   3585 static void
   3586 resume_signingwithkey(dns_zone_t *zone) {
   3587 	dns_dbnode_t *node = NULL;
   3588 	dns_dbversion_t *version = NULL;
   3589 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3590 	dns_rdataset_t rdataset;
   3591 	isc_result_t result;
   3592 	dns_db_t *db = NULL;
   3593 
   3594 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3595 	if (zone->db != NULL) {
   3596 		dns_db_attach(zone->db, &db);
   3597 	}
   3598 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3599 	if (db == NULL) {
   3600 		goto cleanup;
   3601 	}
   3602 
   3603 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3604 	if (result != ISC_R_SUCCESS) {
   3605 		goto cleanup;
   3606 	}
   3607 
   3608 	dns_db_currentversion(db, &version);
   3609 	dns_rdataset_init(&rdataset);
   3610 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3611 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3612 	if (result != ISC_R_SUCCESS) {
   3613 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3614 		goto cleanup;
   3615 	}
   3616 
   3617 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3618 	     result = dns_rdataset_next(&rdataset))
   3619 	{
   3620 		dns_rdataset_current(&rdataset, &rdata);
   3621 		if (rdata.length != 5 || rdata.data[0] == 0 ||
   3622 		    rdata.data[4] != 0)
   3623 		{
   3624 			dns_rdata_reset(&rdata);
   3625 			continue;
   3626 		}
   3627 
   3628 		result = zone_signwithkey(zone, rdata.data[0],
   3629 					  (rdata.data[1] << 8) | rdata.data[2],
   3630 					  rdata.data[3]);
   3631 		if (result != ISC_R_SUCCESS) {
   3632 			dnssec_log(zone, ISC_LOG_ERROR,
   3633 				   "zone_signwithkey failed: %s",
   3634 				   dns_result_totext(result));
   3635 		}
   3636 		dns_rdata_reset(&rdata);
   3637 	}
   3638 	dns_rdataset_disassociate(&rdataset);
   3639 
   3640 cleanup:
   3641 	if (db != NULL) {
   3642 		if (node != NULL) {
   3643 			dns_db_detachnode(db, &node);
   3644 		}
   3645 		if (version != NULL) {
   3646 			dns_db_closeversion(db, &version, false);
   3647 		}
   3648 		dns_db_detach(&db);
   3649 	}
   3650 }
   3651 
   3652 /*
   3653  * Initiate adding/removing NSEC3 records belonging to the chain defined by the
   3654  * supplied NSEC3PARAM RDATA.
   3655  *
   3656  * Zone must be locked by caller.
   3657  */
   3658 static isc_result_t
   3659 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   3660 	dns_nsec3chain_t *nsec3chain, *current;
   3661 	dns_dbversion_t *version = NULL;
   3662 	bool nseconly = false, nsec3ok = false;
   3663 	isc_result_t result;
   3664 	isc_time_t now;
   3665 	unsigned int options = 0;
   3666 	char saltbuf[255 * 2 + 1];
   3667 	char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
   3668 	dns_db_t *db = NULL;
   3669 
   3670 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3671 	if (zone->db != NULL) {
   3672 		dns_db_attach(zone->db, &db);
   3673 	}
   3674 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3675 
   3676 	if (db == NULL) {
   3677 		result = ISC_R_SUCCESS;
   3678 		goto cleanup;
   3679 	}
   3680 
   3681 	/*
   3682 	 * If this zone is not NSEC3-capable, attempting to remove any NSEC3
   3683 	 * chain from it is pointless as it would not be possible for the
   3684 	 * latter to exist in the first place.
   3685 	 */
   3686 	dns_db_currentversion(db, &version);
   3687 	result = dns_nsec_nseconly(db, version, &nseconly);
   3688 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3689 	dns_db_closeversion(db, &version, false);
   3690 	if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
   3691 		result = ISC_R_SUCCESS;
   3692 		goto cleanup;
   3693 	}
   3694 
   3695 	/*
   3696 	 * Allocate and initialize structure preserving state of
   3697 	 * adding/removing records belonging to this NSEC3 chain between
   3698 	 * separate zone_nsec3chain() calls.
   3699 	 */
   3700 	nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
   3701 
   3702 	nsec3chain->magic = 0;
   3703 	nsec3chain->done = false;
   3704 	nsec3chain->db = NULL;
   3705 	nsec3chain->dbiterator = NULL;
   3706 	nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
   3707 	nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
   3708 	nsec3chain->nsec3param.hash = nsec3param->hash;
   3709 	nsec3chain->nsec3param.iterations = nsec3param->iterations;
   3710 	nsec3chain->nsec3param.flags = nsec3param->flags;
   3711 	nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
   3712 	memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
   3713 	nsec3chain->nsec3param.salt = nsec3chain->salt;
   3714 	nsec3chain->seen_nsec = false;
   3715 	nsec3chain->delete_nsec = false;
   3716 	nsec3chain->save_delete_nsec = false;
   3717 
   3718 	/*
   3719 	 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA.
   3720 	 */
   3721 	if (nsec3param->flags == 0) {
   3722 		strlcpy(flags, "NONE", sizeof(flags));
   3723 	} else {
   3724 		flags[0] = '\0';
   3725 		if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   3726 			strlcat(flags, "REMOVE", sizeof(flags));
   3727 		}
   3728 		if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) {
   3729 			if (flags[0] == '\0') {
   3730 				strlcpy(flags, "INITIAL", sizeof(flags));
   3731 			} else {
   3732 				strlcat(flags, "|INITIAL", sizeof(flags));
   3733 			}
   3734 		}
   3735 		if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3736 			if (flags[0] == '\0') {
   3737 				strlcpy(flags, "CREATE", sizeof(flags));
   3738 			} else {
   3739 				strlcat(flags, "|CREATE", sizeof(flags));
   3740 			}
   3741 		}
   3742 		if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) {
   3743 			if (flags[0] == '\0') {
   3744 				strlcpy(flags, "NONSEC", sizeof(flags));
   3745 			} else {
   3746 				strlcat(flags, "|NONSEC", sizeof(flags));
   3747 			}
   3748 		}
   3749 		if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) {
   3750 			if (flags[0] == '\0') {
   3751 				strlcpy(flags, "OPTOUT", sizeof(flags));
   3752 			} else {
   3753 				strlcat(flags, "|OPTOUT", sizeof(flags));
   3754 			}
   3755 		}
   3756 	}
   3757 	result = dns_nsec3param_salttotext(nsec3param, saltbuf,
   3758 					   sizeof(saltbuf));
   3759 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3760 	dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)",
   3761 		   nsec3param->hash, flags, nsec3param->iterations, saltbuf);
   3762 
   3763 	/*
   3764 	 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is
   3765 	 * currently being processed, interrupt its processing to avoid
   3766 	 * simultaneously adding and removing records for the same NSEC3 chain.
   3767 	 */
   3768 	for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL;
   3769 	     current = ISC_LIST_NEXT(current, link))
   3770 	{
   3771 		if ((current->db == db) &&
   3772 		    (current->nsec3param.hash == nsec3param->hash) &&
   3773 		    (current->nsec3param.iterations ==
   3774 		     nsec3param->iterations) &&
   3775 		    (current->nsec3param.salt_length ==
   3776 		     nsec3param->salt_length) &&
   3777 		    memcmp(current->nsec3param.salt, nsec3param->salt,
   3778 			   nsec3param->salt_length) == 0)
   3779 		{
   3780 			current->done = true;
   3781 		}
   3782 	}
   3783 
   3784 	/*
   3785 	 * Attach zone database to the structure initialized above and create
   3786 	 * an iterator for it with appropriate options in order to avoid
   3787 	 * creating NSEC3 records for NSEC3 records.
   3788 	 */
   3789 	dns_db_attach(db, &nsec3chain->db);
   3790 	if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3791 		options = DNS_DB_NONSEC3;
   3792 	}
   3793 	result = dns_db_createiterator(nsec3chain->db, options,
   3794 				       &nsec3chain->dbiterator);
   3795 	if (result == ISC_R_SUCCESS) {
   3796 		result = dns_dbiterator_first(nsec3chain->dbiterator);
   3797 	}
   3798 	if (result == ISC_R_SUCCESS) {
   3799 		/*
   3800 		 * Database iterator initialization succeeded.  We are now
   3801 		 * ready to kick off adding/removing records belonging to this
   3802 		 * NSEC3 chain.  Append the structure initialized above to the
   3803 		 * "nsec3chain" list for the zone and set the appropriate zone
   3804 		 * timer so that zone_nsec3chain() is called as soon as
   3805 		 * possible.
   3806 		 */
   3807 		dns_dbiterator_pause(nsec3chain->dbiterator);
   3808 		ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link);
   3809 		nsec3chain = NULL;
   3810 		if (isc_time_isepoch(&zone->nsec3chaintime)) {
   3811 			TIME_NOW(&now);
   3812 			zone->nsec3chaintime = now;
   3813 			if (zone->task != NULL) {
   3814 				zone_settimer(zone, &now);
   3815 			}
   3816 		}
   3817 	}
   3818 
   3819 	if (nsec3chain != NULL) {
   3820 		if (nsec3chain->db != NULL) {
   3821 			dns_db_detach(&nsec3chain->db);
   3822 		}
   3823 		if (nsec3chain->dbiterator != NULL) {
   3824 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   3825 		}
   3826 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   3827 	}
   3828 
   3829 cleanup:
   3830 	if (db != NULL) {
   3831 		dns_db_detach(&db);
   3832 	}
   3833 	return (result);
   3834 }
   3835 
   3836 /*
   3837  * Find private-type records at the zone apex which signal that an NSEC3 chain
   3838  * should be added or removed.  For each such record, extract NSEC3PARAM RDATA
   3839  * and pass it to zone_addnsec3chain().
   3840  *
   3841  * Zone must be locked by caller.
   3842  */
   3843 static void
   3844 resume_addnsec3chain(dns_zone_t *zone) {
   3845 	dns_dbnode_t *node = NULL;
   3846 	dns_dbversion_t *version = NULL;
   3847 	dns_rdataset_t rdataset;
   3848 	isc_result_t result;
   3849 	dns_rdata_nsec3param_t nsec3param;
   3850 	bool nseconly = false, nsec3ok = false;
   3851 	dns_db_t *db = NULL;
   3852 
   3853 	INSIST(LOCKED_ZONE(zone));
   3854 
   3855 	if (zone->privatetype == 0) {
   3856 		return;
   3857 	}
   3858 
   3859 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3860 	if (zone->db != NULL) {
   3861 		dns_db_attach(zone->db, &db);
   3862 	}
   3863 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3864 	if (db == NULL) {
   3865 		goto cleanup;
   3866 	}
   3867 
   3868 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3869 	if (result != ISC_R_SUCCESS) {
   3870 		goto cleanup;
   3871 	}
   3872 
   3873 	dns_db_currentversion(db, &version);
   3874 
   3875 	/*
   3876 	 * In order to create NSEC3 chains we need the DNSKEY RRset at zone
   3877 	 * apex to exist and contain no keys using NSEC-only algorithms.
   3878 	 */
   3879 	result = dns_nsec_nseconly(db, version, &nseconly);
   3880 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3881 
   3882 	/*
   3883 	 * Get the RRset containing all private-type records at the zone apex.
   3884 	 */
   3885 	dns_rdataset_init(&rdataset);
   3886 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3887 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3888 	if (result != ISC_R_SUCCESS) {
   3889 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3890 		goto cleanup;
   3891 	}
   3892 
   3893 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3894 	     result = dns_rdataset_next(&rdataset))
   3895 	{
   3896 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   3897 		dns_rdata_t rdata = DNS_RDATA_INIT;
   3898 		dns_rdata_t private = DNS_RDATA_INIT;
   3899 
   3900 		dns_rdataset_current(&rdataset, &private);
   3901 		/*
   3902 		 * Try extracting NSEC3PARAM RDATA from this private-type
   3903 		 * record.  Failure means this private-type record does not
   3904 		 * represent an NSEC3PARAM record, so skip it.
   3905 		 */
   3906 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   3907 						sizeof(buf)))
   3908 		{
   3909 			continue;
   3910 		}
   3911 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3912 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3913 		if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
   3914 		    ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
   3915 		{
   3916 			/*
   3917 			 * Pass the NSEC3PARAM RDATA contained in this
   3918 			 * private-type record to zone_addnsec3chain() so that
   3919 			 * it can kick off adding or removing NSEC3 records.
   3920 			 */
   3921 			result = zone_addnsec3chain(zone, &nsec3param);
   3922 			if (result != ISC_R_SUCCESS) {
   3923 				dnssec_log(zone, ISC_LOG_ERROR,
   3924 					   "zone_addnsec3chain failed: %s",
   3925 					   dns_result_totext(result));
   3926 			}
   3927 		}
   3928 	}
   3929 	dns_rdataset_disassociate(&rdataset);
   3930 
   3931 cleanup:
   3932 	if (db != NULL) {
   3933 		if (node != NULL) {
   3934 			dns_db_detachnode(db, &node);
   3935 		}
   3936 		if (version != NULL) {
   3937 			dns_db_closeversion(db, &version, false);
   3938 		}
   3939 		dns_db_detach(&db);
   3940 	}
   3941 }
   3942 
   3943 static void
   3944 set_resigntime(dns_zone_t *zone) {
   3945 	dns_rdataset_t rdataset;
   3946 	dns_fixedname_t fixed;
   3947 	unsigned int resign;
   3948 	isc_result_t result;
   3949 	uint32_t nanosecs;
   3950 	dns_db_t *db = NULL;
   3951 
   3952 	INSIST(LOCKED_ZONE(zone));
   3953 
   3954 	/* We only re-sign zones that can be dynamically updated */
   3955 	if (zone->update_disabled) {
   3956 		return;
   3957 	}
   3958 
   3959 	if (!inline_secure(zone) &&
   3960 	    (zone->type != dns_zone_primary ||
   3961 	     (zone->ssutable == NULL &&
   3962 	      (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
   3963 	{
   3964 		return;
   3965 	}
   3966 
   3967 	dns_rdataset_init(&rdataset);
   3968 	dns_fixedname_init(&fixed);
   3969 
   3970 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3971 	if (zone->db != NULL) {
   3972 		dns_db_attach(zone->db, &db);
   3973 	}
   3974 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3975 	if (db == NULL) {
   3976 		isc_time_settoepoch(&zone->resigntime);
   3977 		return;
   3978 	}
   3979 
   3980 	result = dns_db_getsigningtime(db, &rdataset,
   3981 				       dns_fixedname_name(&fixed));
   3982 	if (result != ISC_R_SUCCESS) {
   3983 		isc_time_settoepoch(&zone->resigntime);
   3984 		goto cleanup;
   3985 	}
   3986 
   3987 	resign = rdataset.resign - dns_zone_getsigresigninginterval(zone);
   3988 	dns_rdataset_disassociate(&rdataset);
   3989 	nanosecs = isc_random_uniform(1000000000);
   3990 	isc_time_set(&zone->resigntime, resign, nanosecs);
   3991 
   3992 cleanup:
   3993 	dns_db_detach(&db);
   3994 	return;
   3995 }
   3996 
   3997 static isc_result_t
   3998 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
   3999 	bool ok = false;
   4000 	dns_dbnode_t *node = NULL;
   4001 	dns_dbversion_t *version = NULL;
   4002 	dns_rdata_nsec3param_t nsec3param;
   4003 	dns_rdataset_t rdataset;
   4004 	isc_result_t result;
   4005 	bool dynamic = (zone->type == dns_zone_primary)
   4006 			       ? dns_zone_isdynamic(zone, false)
   4007 			       : false;
   4008 
   4009 	dns_rdataset_init(&rdataset);
   4010 	result = dns_db_findnode(db, &zone->origin, false, &node);
   4011 	if (result != ISC_R_SUCCESS) {
   4012 		dns_zone_log(zone, ISC_LOG_ERROR,
   4013 			     "nsec3param lookup failure: %s",
   4014 			     dns_result_totext(result));
   4015 		return (result);
   4016 	}
   4017 	dns_db_currentversion(db, &version);
   4018 
   4019 	result = dns_db_findrdataset(db, node, version,
   4020 				     dns_rdatatype_nsec3param,
   4021 				     dns_rdatatype_none, 0, &rdataset, NULL);
   4022 	if (result == ISC_R_NOTFOUND) {
   4023 		INSIST(!dns_rdataset_isassociated(&rdataset));
   4024 		result = ISC_R_SUCCESS;
   4025 		goto cleanup;
   4026 	}
   4027 	if (result != ISC_R_SUCCESS) {
   4028 		INSIST(!dns_rdataset_isassociated(&rdataset));
   4029 		dns_zone_log(zone, ISC_LOG_ERROR,
   4030 			     "nsec3param lookup failure: %s",
   4031 			     dns_result_totext(result));
   4032 		goto cleanup;
   4033 	}
   4034 
   4035 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   4036 	     result = dns_rdataset_next(&rdataset))
   4037 	{
   4038 		dns_rdata_t rdata = DNS_RDATA_INIT;
   4039 
   4040 		dns_rdataset_current(&rdataset, &rdata);
   4041 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   4042 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4043 
   4044 		/*
   4045 		 * For dynamic zones we must support every algorithm so we
   4046 		 * can regenerate all the NSEC3 chains.
   4047 		 * For non-dynamic zones we only need to find a supported
   4048 		 * algorithm.
   4049 		 */
   4050 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
   4051 		    nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
   4052 		{
   4053 			dns_zone_log(zone, ISC_LOG_WARNING,
   4054 				     "nsec3 test \"unknown\" hash algorithm "
   4055 				     "found: %u",
   4056 				     nsec3param.hash);
   4057 			ok = true;
   4058 		} else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
   4059 			if (dynamic) {
   4060 				dns_zone_log(zone, ISC_LOG_ERROR,
   4061 					     "unsupported nsec3 hash algorithm"
   4062 					     " in dynamic zone: %u",
   4063 					     nsec3param.hash);
   4064 				result = DNS_R_BADZONE;
   4065 				/* Stop second error message. */
   4066 				ok = true;
   4067 				break;
   4068 			} else {
   4069 				dns_zone_log(zone, ISC_LOG_WARNING,
   4070 					     "unsupported nsec3 hash "
   4071 					     "algorithm: %u",
   4072 					     nsec3param.hash);
   4073 			}
   4074 		} else {
   4075 			ok = true;
   4076 		}
   4077 
   4078 		/*
   4079 		 * Warn if the zone has excessive NSEC3 iterations.
   4080 		 */
   4081 		if (nsec3param.iterations > dns_nsec3_maxiterations()) {
   4082 			dnssec_log(zone, ISC_LOG_WARNING,
   4083 				   "excessive NSEC3PARAM iterations %u > %u",
   4084 				   nsec3param.iterations,
   4085 				   dns_nsec3_maxiterations());
   4086 		}
   4087 	}
   4088 	if (result == ISC_R_NOMORE) {
   4089 		result = ISC_R_SUCCESS;
   4090 	}
   4091 
   4092 	if (!ok) {
   4093 		result = DNS_R_BADZONE;
   4094 		dns_zone_log(zone, ISC_LOG_ERROR,
   4095 			     "no supported nsec3 hash algorithm");
   4096 	}
   4097 
   4098 cleanup:
   4099 	if (dns_rdataset_isassociated(&rdataset)) {
   4100 		dns_rdataset_disassociate(&rdataset);
   4101 	}
   4102 	dns_db_closeversion(db, &version, false);
   4103 	dns_db_detachnode(db, &node);
   4104 	return (result);
   4105 }
   4106 
   4107 /*
   4108  * Set the timer for refreshing the key zone to the soonest future time
   4109  * of the set (current timer, keydata->refresh, keydata->addhd,
   4110  * keydata->removehd).
   4111  */
   4112 static void
   4113 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
   4114 		    isc_stdtime_t now, bool force) {
   4115 	const char me[] = "set_refreshkeytimer";
   4116 	isc_stdtime_t then;
   4117 	isc_time_t timenow, timethen;
   4118 	char timebuf[80];
   4119 
   4120 	ENTER;
   4121 	then = key->refresh;
   4122 	if (force) {
   4123 		then = now;
   4124 	}
   4125 	if (key->addhd > now && key->addhd < then) {
   4126 		then = key->addhd;
   4127 	}
   4128 	if (key->removehd > now && key->removehd < then) {
   4129 		then = key->removehd;
   4130 	}
   4131 
   4132 	TIME_NOW(&timenow);
   4133 	if (then > now) {
   4134 		DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   4135 	} else {
   4136 		timethen = timenow;
   4137 	}
   4138 	if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
   4139 	    isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
   4140 	{
   4141 		zone->refreshkeytime = timethen;
   4142 	}
   4143 
   4144 	isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   4145 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
   4146 	zone_settimer(zone, &timenow);
   4147 }
   4148 
   4149 /*
   4150  * If keynode references a key or a DS rdataset, and if the key
   4151  * zone does not contain a KEYDATA record for the corresponding name,
   4152  * then create an empty KEYDATA and push it into the zone as a placeholder,
   4153  * then schedule a key refresh immediately. This new KEYDATA record will be
   4154  * updated during the refresh.
   4155  *
   4156  * If the key zone is changed, set '*changed' to true.
   4157  */
   4158 static isc_result_t
   4159 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4160 	       dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname,
   4161 	       bool *changed) {
   4162 	const char me[] = "create_keydata";
   4163 	isc_result_t result = ISC_R_SUCCESS;
   4164 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4165 	dns_rdata_keydata_t kd;
   4166 	unsigned char rrdata[4096];
   4167 	isc_buffer_t rrdatabuf;
   4168 	isc_stdtime_t now;
   4169 
   4170 	REQUIRE(keynode != NULL);
   4171 
   4172 	ENTER;
   4173 	isc_stdtime_get(&now);
   4174 
   4175 	/*
   4176 	 * If the keynode has no trust anchor set, we shouldn't be here.
   4177 	 */
   4178 	if (!dns_keynode_dsset(keynode, NULL)) {
   4179 		return (ISC_R_FAILURE);
   4180 	}
   4181 
   4182 	memset(&kd, 0, sizeof(kd));
   4183 	kd.common.rdclass = zone->rdclass;
   4184 	kd.common.rdtype = dns_rdatatype_keydata;
   4185 	ISC_LINK_INIT(&kd.common, link);
   4186 
   4187 	isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
   4188 
   4189 	CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata,
   4190 				   &kd, &rrdatabuf));
   4191 	/* Add rdata to zone. */
   4192 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata));
   4193 	*changed = true;
   4194 
   4195 	/* Refresh new keys from the zone apex as soon as possible. */
   4196 	set_refreshkeytimer(zone, &kd, now, true);
   4197 	return (ISC_R_SUCCESS);
   4198 
   4199 failure:
   4200 	return (result);
   4201 }
   4202 
   4203 /*
   4204  * Remove from the key zone all the KEYDATA records found in rdataset.
   4205  */
   4206 static isc_result_t
   4207 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4208 	       dns_name_t *name, dns_rdataset_t *rdataset) {
   4209 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4210 	isc_result_t result, uresult;
   4211 
   4212 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4213 	     result = dns_rdataset_next(rdataset))
   4214 	{
   4215 		dns_rdata_reset(&rdata);
   4216 		dns_rdataset_current(rdataset, &rdata);
   4217 		uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0,
   4218 					&rdata);
   4219 		if (uresult != ISC_R_SUCCESS) {
   4220 			return (uresult);
   4221 		}
   4222 	}
   4223 	if (result == ISC_R_NOMORE) {
   4224 		result = ISC_R_SUCCESS;
   4225 	}
   4226 	return (result);
   4227 }
   4228 
   4229 /*
   4230  * Compute the DNSSEC key ID for a DNSKEY record.
   4231  */
   4232 static isc_result_t
   4233 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
   4234 	    dns_keytag_t *tag) {
   4235 	isc_result_t result;
   4236 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4237 	unsigned char data[4096];
   4238 	isc_buffer_t buffer;
   4239 	dst_key_t *dstkey = NULL;
   4240 
   4241 	isc_buffer_init(&buffer, data, sizeof(data));
   4242 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4243 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4244 
   4245 	result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
   4246 	if (result == ISC_R_SUCCESS) {
   4247 		*tag = dst_key_id(dstkey);
   4248 		dst_key_free(&dstkey);
   4249 	}
   4250 
   4251 	return (result);
   4252 }
   4253 
   4254 /*
   4255  * Add key to the security roots.
   4256  */
   4257 static void
   4258 trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey,
   4259 	  bool initial) {
   4260 	isc_result_t result;
   4261 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4262 	unsigned char data[4096], digest[ISC_MAX_MD_SIZE];
   4263 	isc_buffer_t buffer;
   4264 	dns_keytable_t *sr = NULL;
   4265 	dns_rdata_ds_t ds;
   4266 
   4267 	result = dns_view_getsecroots(zone->view, &sr);
   4268 	if (result != ISC_R_SUCCESS) {
   4269 		return;
   4270 	}
   4271 
   4272 	/* Build DS record for key. */
   4273 	isc_buffer_init(&buffer, data, sizeof(data));
   4274 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4275 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4276 	CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest,
   4277 				  &ds));
   4278 	CHECK(dns_keytable_add(sr, true, initial, keyname, &ds));
   4279 
   4280 	dns_keytable_detach(&sr);
   4281 
   4282 failure:
   4283 	if (sr != NULL) {
   4284 		dns_keytable_detach(&sr);
   4285 	}
   4286 	return;
   4287 }
   4288 
   4289 /*
   4290  * Add a null key to the security roots for so that all queries
   4291  * to the zone will fail.
   4292  */
   4293 static void
   4294 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
   4295 	isc_result_t result;
   4296 	dns_keytable_t *sr = NULL;
   4297 
   4298 	result = dns_view_getsecroots(zone->view, &sr);
   4299 	if (result == ISC_R_SUCCESS) {
   4300 		dns_keytable_marksecure(sr, keyname);
   4301 		dns_keytable_detach(&sr);
   4302 	}
   4303 }
   4304 
   4305 /*
   4306  * Scan a set of KEYDATA records from the key zone.  The ones that are
   4307  * valid (i.e., the add holddown timer has expired) become trusted keys.
   4308  */
   4309 static void
   4310 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
   4311 	isc_result_t result;
   4312 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4313 	dns_rdata_keydata_t keydata;
   4314 	dns_rdata_dnskey_t dnskey;
   4315 	int trusted = 0, revoked = 0, pending = 0;
   4316 	isc_stdtime_t now;
   4317 	dns_keytable_t *sr = NULL;
   4318 
   4319 	isc_stdtime_get(&now);
   4320 
   4321 	result = dns_view_getsecroots(zone->view, &sr);
   4322 	if (result == ISC_R_SUCCESS) {
   4323 		dns_keytable_delete(sr, name);
   4324 		dns_keytable_detach(&sr);
   4325 	}
   4326 
   4327 	/* Now insert all the accepted trust anchors from this keydata set. */
   4328 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4329 	     result = dns_rdataset_next(rdataset))
   4330 	{
   4331 		dns_rdata_reset(&rdata);
   4332 		dns_rdataset_current(rdataset, &rdata);
   4333 
   4334 		/* Convert rdata to keydata. */
   4335 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   4336 		if (result == ISC_R_UNEXPECTEDEND) {
   4337 			continue;
   4338 		}
   4339 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4340 
   4341 		/* Set the key refresh timer to force a fast refresh. */
   4342 		set_refreshkeytimer(zone, &keydata, now, true);
   4343 
   4344 		/* If the removal timer is nonzero, this key was revoked. */
   4345 		if (keydata.removehd != 0) {
   4346 			revoked++;
   4347 			continue;
   4348 		}
   4349 
   4350 		/*
   4351 		 * If the add timer is still pending, this key is not
   4352 		 * trusted yet.
   4353 		 */
   4354 		if (now < keydata.addhd) {
   4355 			pending++;
   4356 			continue;
   4357 		}
   4358 
   4359 		/* Convert keydata to dnskey. */
   4360 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   4361 
   4362 		/* Add to keytables. */
   4363 		trusted++;
   4364 		trust_key(zone, name, &dnskey, (keydata.addhd == 0));
   4365 	}
   4366 
   4367 	if (trusted == 0 && pending != 0) {
   4368 		char namebuf[DNS_NAME_FORMATSIZE];
   4369 		dns_name_format(name, namebuf, sizeof namebuf);
   4370 		dnssec_log(zone, ISC_LOG_ERROR,
   4371 			   "No valid trust anchors for '%s'!", namebuf);
   4372 		dnssec_log(zone, ISC_LOG_ERROR,
   4373 			   "%d key(s) revoked, %d still pending", revoked,
   4374 			   pending);
   4375 		dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail",
   4376 			   namebuf);
   4377 		fail_secure(zone, name);
   4378 	}
   4379 }
   4380 
   4381 static isc_result_t
   4382 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
   4383 	     dns_diff_t *diff) {
   4384 	dns_diff_t temp_diff;
   4385 	isc_result_t result;
   4386 
   4387 	/*
   4388 	 * Create a singleton diff.
   4389 	 */
   4390 	dns_diff_init(diff->mctx, &temp_diff);
   4391 	ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
   4392 
   4393 	/*
   4394 	 * Apply it to the database.
   4395 	 */
   4396 	result = dns_diff_apply(&temp_diff, db, ver);
   4397 	ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
   4398 	if (result != ISC_R_SUCCESS) {
   4399 		dns_difftuple_free(tuple);
   4400 		return (result);
   4401 	}
   4402 
   4403 	/*
   4404 	 * Merge it into the current pending journal entry.
   4405 	 */
   4406 	dns_diff_appendminimal(diff, tuple);
   4407 
   4408 	/*
   4409 	 * Do not clear temp_diff.
   4410 	 */
   4411 	return (ISC_R_SUCCESS);
   4412 }
   4413 
   4414 static isc_result_t
   4415 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4416 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
   4417 	      dns_rdata_t *rdata) {
   4418 	dns_difftuple_t *tuple = NULL;
   4419 	isc_result_t result;
   4420 	result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple);
   4421 	if (result != ISC_R_SUCCESS) {
   4422 		return (result);
   4423 	}
   4424 	return (do_one_tuple(&tuple, db, ver, diff));
   4425 }
   4426 
   4427 static isc_result_t
   4428 update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4429 		  dns_diff_t *diff, isc_mem_t *mctx,
   4430 		  dns_updatemethod_t method) {
   4431 	dns_difftuple_t *deltuple = NULL;
   4432 	dns_difftuple_t *addtuple = NULL;
   4433 	uint32_t serial;
   4434 	isc_result_t result;
   4435 	dns_updatemethod_t used = dns_updatemethod_none;
   4436 
   4437 	INSIST(method != dns_updatemethod_none);
   4438 
   4439 	CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
   4440 	CHECK(dns_difftuple_copy(deltuple, &addtuple));
   4441 	addtuple->op = DNS_DIFFOP_ADD;
   4442 
   4443 	serial = dns_soa_getserial(&addtuple->rdata);
   4444 	serial = dns_update_soaserial(serial, method, &used);
   4445 	if (method != used) {
   4446 		dns_zone_log(zone, ISC_LOG_WARNING,
   4447 			     "update_soa_serial:new serial would be lower than "
   4448 			     "old serial, using increment method instead");
   4449 	}
   4450 	dns_soa_setserial(serial, &addtuple->rdata);
   4451 	CHECK(do_one_tuple(&deltuple, db, ver, diff));
   4452 	CHECK(do_one_tuple(&addtuple, db, ver, diff));
   4453 	result = ISC_R_SUCCESS;
   4454 
   4455 failure:
   4456 	if (addtuple != NULL) {
   4457 		dns_difftuple_free(&addtuple);
   4458 	}
   4459 	if (deltuple != NULL) {
   4460 		dns_difftuple_free(&deltuple);
   4461 	}
   4462 	return (result);
   4463 }
   4464 
   4465 /*
   4466  * Write all transactions in 'diff' to the zone journal file.
   4467  */
   4468 static isc_result_t
   4469 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial,
   4470 	     const char *caller) {
   4471 	const char me[] = "zone_journal";
   4472 	const char *journalfile;
   4473 	isc_result_t result = ISC_R_SUCCESS;
   4474 	dns_journal_t *journal = NULL;
   4475 	unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE;
   4476 
   4477 	ENTER;
   4478 	journalfile = dns_zone_getjournal(zone);
   4479 	if (journalfile != NULL) {
   4480 		result = dns_journal_open(zone->mctx, journalfile, mode,
   4481 					  &journal);
   4482 		if (result != ISC_R_SUCCESS) {
   4483 			dns_zone_log(zone, ISC_LOG_ERROR,
   4484 				     "%s:dns_journal_open -> %s", caller,
   4485 				     dns_result_totext(result));
   4486 			return (result);
   4487 		}
   4488 
   4489 		if (sourceserial != NULL) {
   4490 			dns_journal_set_sourceserial(journal, *sourceserial);
   4491 		}
   4492 
   4493 		result = dns_journal_write_transaction(journal, diff);
   4494 		if (result != ISC_R_SUCCESS) {
   4495 			dns_zone_log(zone, ISC_LOG_ERROR,
   4496 				     "%s:dns_journal_write_transaction -> %s",
   4497 				     caller, dns_result_totext(result));
   4498 		}
   4499 		dns_journal_destroy(&journal);
   4500 	}
   4501 
   4502 	return (result);
   4503 }
   4504 
   4505 /*
   4506  * Create an SOA record for a newly-created zone
   4507  */
   4508 static isc_result_t
   4509 add_soa(dns_zone_t *zone, dns_db_t *db) {
   4510 	isc_result_t result;
   4511 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4512 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   4513 	dns_dbversion_t *ver = NULL;
   4514 	dns_diff_t diff;
   4515 
   4516 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
   4517 
   4518 	dns_diff_init(zone->mctx, &diff);
   4519 	result = dns_db_newversion(db, &ver);
   4520 	if (result != ISC_R_SUCCESS) {
   4521 		dns_zone_log(zone, ISC_LOG_ERROR,
   4522 			     "add_soa:dns_db_newversion -> %s",
   4523 			     dns_result_totext(result));
   4524 		goto failure;
   4525 	}
   4526 
   4527 	/* Build SOA record */
   4528 	result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
   4529 				    0, 0, 0, 0, 0, buf, &rdata);
   4530 	if (result != ISC_R_SUCCESS) {
   4531 		dns_zone_log(zone, ISC_LOG_ERROR,
   4532 			     "add_soa:dns_soa_buildrdata -> %s",
   4533 			     dns_result_totext(result));
   4534 		goto failure;
   4535 	}
   4536 
   4537 	result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0,
   4538 			       &rdata);
   4539 
   4540 failure:
   4541 	dns_diff_clear(&diff);
   4542 	if (ver != NULL) {
   4543 		dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS));
   4544 	}
   4545 
   4546 	INSIST(ver == NULL);
   4547 
   4548 	return (result);
   4549 }
   4550 
   4551 struct addifmissing_arg {
   4552 	dns_db_t *db;
   4553 	dns_dbversion_t *ver;
   4554 	dns_diff_t *diff;
   4555 	dns_zone_t *zone;
   4556 	bool *changed;
   4557 	isc_result_t result;
   4558 };
   4559 
   4560 static void
   4561 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode,
   4562 	     dns_name_t *keyname, void *arg) {
   4563 	dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
   4564 	dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
   4565 	dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
   4566 	dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
   4567 	bool *changed = ((struct addifmissing_arg *)arg)->changed;
   4568 	isc_result_t result;
   4569 	dns_fixedname_t fname;
   4570 
   4571 	UNUSED(keytable);
   4572 
   4573 	if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) {
   4574 		return;
   4575 	}
   4576 
   4577 	if (!dns_keynode_managed(keynode)) {
   4578 		return;
   4579 	}
   4580 
   4581 	/*
   4582 	 * If the keynode has no trust anchor set, return.
   4583 	 */
   4584 	if (!dns_keynode_dsset(keynode, NULL)) {
   4585 		return;
   4586 	}
   4587 
   4588 	/*
   4589 	 * Check whether there's already a KEYDATA entry for this name;
   4590 	 * if so, we don't need to add another.
   4591 	 */
   4592 	dns_fixedname_init(&fname);
   4593 	result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata,
   4594 			     DNS_DBFIND_NOWILD, 0, NULL,
   4595 			     dns_fixedname_name(&fname), NULL, NULL);
   4596 	if (result == ISC_R_SUCCESS) {
   4597 		return;
   4598 	}
   4599 
   4600 	/*
   4601 	 * Create the keydata.
   4602 	 */
   4603 	result = create_keydata(zone, db, ver, diff, keynode, keyname, changed);
   4604 	if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
   4605 		((struct addifmissing_arg *)arg)->result = result;
   4606 	}
   4607 }
   4608 
   4609 /*
   4610  * Synchronize the set of initializing keys found in managed-keys {}
   4611  * statements with the set of trust anchors found in the managed-keys.bind
   4612  * zone.  If a domain is no longer named in managed-keys, delete all keys
   4613  * from that domain from the key zone.	If a domain is configured as an
   4614  * initial-key in trust-anchors, but there are no references to it in the
   4615  * key zone, load the key zone with the initializing key(s) for that
   4616  * domain and schedule a key refresh. If a domain is configured as
   4617  * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key
   4618  * zone with the matching key, and schedule a key refresh.
   4619  */
   4620 static isc_result_t
   4621 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
   4622 	isc_result_t result = ISC_R_SUCCESS;
   4623 	bool changed = false;
   4624 	bool commit = false;
   4625 	dns_keynode_t *keynode = NULL;
   4626 	dns_view_t *view = zone->view;
   4627 	dns_keytable_t *sr = NULL;
   4628 	dns_dbversion_t *ver = NULL;
   4629 	dns_diff_t diff;
   4630 	dns_rriterator_t rrit;
   4631 	struct addifmissing_arg arg;
   4632 
   4633 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
   4634 
   4635 	dns_diff_init(zone->mctx, &diff);
   4636 
   4637 	CHECK(dns_view_getsecroots(view, &sr));
   4638 
   4639 	result = dns_db_newversion(db, &ver);
   4640 	if (result != ISC_R_SUCCESS) {
   4641 		dnssec_log(zone, ISC_LOG_ERROR,
   4642 			   "sync_keyzone:dns_db_newversion -> %s",
   4643 			   dns_result_totext(result));
   4644 		goto failure;
   4645 	}
   4646 
   4647 	/*
   4648 	 * Walk the zone DB.  If we find any keys whose names are no longer
   4649 	 * in trust-anchors, or which have been changed from initial to static,
   4650 	 * (meaning they are permanent and not RFC5011-maintained), delete
   4651 	 * them from the zone.  Otherwise call load_secroots(), which
   4652 	 * loads keys into secroots as appropriate.
   4653 	 */
   4654 	dns_rriterator_init(&rrit, db, ver, 0);
   4655 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   4656 	     result = dns_rriterator_nextrrset(&rrit))
   4657 	{
   4658 		dns_rdataset_t *rdataset = NULL;
   4659 		dns_rdata_t rdata = DNS_RDATA_INIT;
   4660 		dns_rdata_keydata_t keydata;
   4661 		isc_stdtime_t now;
   4662 		bool load = true;
   4663 		dns_name_t *rrname = NULL;
   4664 		uint32_t ttl;
   4665 
   4666 		isc_stdtime_get(&now);
   4667 
   4668 		dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL);
   4669 		if (!dns_rdataset_isassociated(rdataset)) {
   4670 			dns_rriterator_destroy(&rrit);
   4671 			goto failure;
   4672 		}
   4673 
   4674 		if (rdataset->type != dns_rdatatype_keydata) {
   4675 			continue;
   4676 		}
   4677 
   4678 		/*
   4679 		 * The managed-keys zone can contain a placeholder instead of
   4680 		 * legitimate data, in which case we will not use it, and we
   4681 		 * will try to refresh it.
   4682 		 */
   4683 		for (result = dns_rdataset_first(rdataset);
   4684 		     result == ISC_R_SUCCESS;
   4685 		     result = dns_rdataset_next(rdataset))
   4686 		{
   4687 			isc_result_t iresult;
   4688 
   4689 			dns_rdata_reset(&rdata);
   4690 			dns_rdataset_current(rdataset, &rdata);
   4691 
   4692 			iresult = dns_rdata_tostruct(&rdata, &keydata, NULL);
   4693 			/* Do we have a valid placeholder KEYDATA record? */
   4694 			if (iresult == ISC_R_SUCCESS && keydata.flags == 0 &&
   4695 			    keydata.protocol == 0 && keydata.algorithm == 0)
   4696 			{
   4697 				set_refreshkeytimer(zone, &keydata, now, true);
   4698 				load = false;
   4699 			}
   4700 		}
   4701 
   4702 		/*
   4703 		 * Release db wrlock to prevent LOR reports against
   4704 		 * dns_keytable_forall() call below.
   4705 		 */
   4706 		dns_rriterator_pause(&rrit);
   4707 		result = dns_keytable_find(sr, rrname, &keynode);
   4708 		if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) {
   4709 			CHECK(delete_keydata(db, ver, &diff, rrname, rdataset));
   4710 			changed = true;
   4711 		} else if (load) {
   4712 			load_secroots(zone, rrname, rdataset);
   4713 		}
   4714 
   4715 		if (keynode != NULL) {
   4716 			dns_keytable_detachkeynode(sr, &keynode);
   4717 		}
   4718 	}
   4719 	dns_rriterator_destroy(&rrit);
   4720 
   4721 	/*
   4722 	 * Walk secroots to find any initial keys that aren't in
   4723 	 * the zone.  If we find any, add them to the zone directly.
   4724 	 * If any DS-style initial keys are found, refresh the key
   4725 	 * zone so that they'll be looked up.
   4726 	 */
   4727 	arg.db = db;
   4728 	arg.ver = ver;
   4729 	arg.result = ISC_R_SUCCESS;
   4730 	arg.diff = &diff;
   4731 	arg.zone = zone;
   4732 	arg.changed = &changed;
   4733 	dns_keytable_forall(sr, addifmissing, &arg);
   4734 	result = arg.result;
   4735 	if (changed) {
   4736 		/* Write changes to journal file. */
   4737 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   4738 					zone->updatemethod));
   4739 		CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
   4740 
   4741 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   4742 		zone_needdump(zone, 30);
   4743 		commit = true;
   4744 	}
   4745 
   4746 failure:
   4747 	if (result != ISC_R_SUCCESS && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4748 	{
   4749 		dnssec_log(zone, ISC_LOG_ERROR,
   4750 			   "unable to synchronize managed keys: %s",
   4751 			   dns_result_totext(result));
   4752 		isc_time_settoepoch(&zone->refreshkeytime);
   4753 	}
   4754 	if (keynode != NULL) {
   4755 		dns_keytable_detachkeynode(sr, &keynode);
   4756 	}
   4757 	if (sr != NULL) {
   4758 		dns_keytable_detach(&sr);
   4759 	}
   4760 	if (ver != NULL) {
   4761 		dns_db_closeversion(db, &ver, commit);
   4762 	}
   4763 	dns_diff_clear(&diff);
   4764 
   4765 	INSIST(ver == NULL);
   4766 
   4767 	return (result);
   4768 }
   4769 
   4770 isc_result_t
   4771 dns_zone_synckeyzone(dns_zone_t *zone) {
   4772 	isc_result_t result;
   4773 	dns_db_t *db = NULL;
   4774 
   4775 	if (zone->type != dns_zone_key) {
   4776 		return (DNS_R_BADZONE);
   4777 	}
   4778 
   4779 	CHECK(dns_zone_getdb(zone, &db));
   4780 
   4781 	LOCK_ZONE(zone);
   4782 	result = sync_keyzone(zone, db);
   4783 	UNLOCK_ZONE(zone);
   4784 
   4785 failure:
   4786 	if (db != NULL) {
   4787 		dns_db_detach(&db);
   4788 	}
   4789 	return (result);
   4790 }
   4791 
   4792 static void
   4793 maybe_send_secure(dns_zone_t *zone) {
   4794 	isc_result_t result;
   4795 
   4796 	/*
   4797 	 * We've finished loading, or else failed to load, an inline-signing
   4798 	 * 'secure' zone.  We now need information about the status of the
   4799 	 * 'raw' zone.  If we failed to load, then we need it to send a
   4800 	 * copy of its database; if we succeeded, we need it to send its
   4801 	 * serial number so that we can sync with it.  If it has not yet
   4802 	 * loaded, we set a flag so that it will send the necessary
   4803 	 * information when it has finished loading.
   4804 	 */
   4805 	if (zone->raw->db != NULL) {
   4806 		if (zone->db != NULL) {
   4807 			uint32_t serial;
   4808 			unsigned int soacount;
   4809 
   4810 			result = zone_get_from_db(
   4811 				zone->raw, zone->raw->db, NULL, &soacount, NULL,
   4812 				&serial, NULL, NULL, NULL, NULL, NULL);
   4813 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   4814 				zone_send_secureserial(zone->raw, serial);
   4815 			}
   4816 		} else {
   4817 			zone_send_securedb(zone->raw, zone->raw->db);
   4818 		}
   4819 	} else {
   4820 		DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
   4821 	}
   4822 }
   4823 
   4824 static bool
   4825 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
   4826 	isc_result_t result;
   4827 	bool answer = false;
   4828 	dns_diff_t diff;
   4829 
   4830 	dns_diff_init(mctx, &diff);
   4831 	result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
   4832 	if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) {
   4833 		answer = true;
   4834 	}
   4835 	dns_diff_clear(&diff);
   4836 	return (answer);
   4837 }
   4838 
   4839 /*
   4840  * The zone is presumed to be locked.
   4841  * If this is a inline_raw zone the secure version is also locked.
   4842  */
   4843 static isc_result_t
   4844 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
   4845 	      isc_result_t result) {
   4846 	unsigned int soacount = 0;
   4847 	unsigned int nscount = 0;
   4848 	unsigned int errors = 0;
   4849 	uint32_t serial, oldserial, refresh, retry, expire, minimum, soattl;
   4850 	isc_time_t now;
   4851 	bool needdump = false;
   4852 	bool fixjournal = false;
   4853 	bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4854 	bool nomaster = false;
   4855 	bool had_db = false;
   4856 	dns_include_t *inc;
   4857 	bool is_dynamic = false;
   4858 
   4859 	INSIST(LOCKED_ZONE(zone));
   4860 	if (inline_raw(zone)) {
   4861 		INSIST(LOCKED_ZONE(zone->secure));
   4862 	}
   4863 
   4864 	TIME_NOW(&now);
   4865 
   4866 	/*
   4867 	 * Initiate zone transfer?  We may need a error code that
   4868 	 * indicates that the "permanent" form does not exist.
   4869 	 * XXX better error feedback to log.
   4870 	 */
   4871 	if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
   4872 		if (zone->type == dns_zone_secondary ||
   4873 		    zone->type == dns_zone_mirror ||
   4874 		    zone->type == dns_zone_stub ||
   4875 		    (zone->type == dns_zone_redirect && zone->masters == NULL))
   4876 		{
   4877 			if (result == ISC_R_FILENOTFOUND) {
   4878 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4879 					      ISC_LOG_DEBUG(1),
   4880 					      "no master file");
   4881 			} else if (result != DNS_R_NOMASTERFILE) {
   4882 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4883 					      ISC_LOG_ERROR,
   4884 					      "loading from master file %s "
   4885 					      "failed: %s",
   4886 					      zone->masterfile,
   4887 					      dns_result_totext(result));
   4888 			}
   4889 		} else if (zone->type == dns_zone_primary &&
   4890 			   inline_secure(zone) && result == ISC_R_FILENOTFOUND)
   4891 		{
   4892 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4893 				      ISC_LOG_DEBUG(1),
   4894 				      "no master file, requesting db");
   4895 			maybe_send_secure(zone);
   4896 		} else {
   4897 			int level = ISC_LOG_ERROR;
   4898 			if (zone->type == dns_zone_key &&
   4899 			    result == ISC_R_FILENOTFOUND)
   4900 			{
   4901 				level = ISC_LOG_DEBUG(1);
   4902 			}
   4903 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level,
   4904 				      "loading from master file %s failed: %s",
   4905 				      zone->masterfile,
   4906 				      dns_result_totext(result));
   4907 			nomaster = true;
   4908 		}
   4909 
   4910 		if (zone->type != dns_zone_key) {
   4911 			goto cleanup;
   4912 		}
   4913 	}
   4914 
   4915 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
   4916 		      "number of nodes in database: %u", dns_db_nodecount(db));
   4917 
   4918 	if (result == DNS_R_SEENINCLUDE) {
   4919 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4920 	} else {
   4921 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4922 	}
   4923 
   4924 	/*
   4925 	 * If there's no master file for a key zone, then the zone is new:
   4926 	 * create an SOA record.  (We do this now, instead of later, so that
   4927 	 * if there happens to be a journal file, we can roll forward from
   4928 	 * a sane starting point.)
   4929 	 */
   4930 	if (nomaster && zone->type == dns_zone_key) {
   4931 		result = add_soa(zone, db);
   4932 		if (result != ISC_R_SUCCESS) {
   4933 			goto cleanup;
   4934 		}
   4935 	}
   4936 
   4937 	/*
   4938 	 * Apply update log, if any, on initial load.
   4939 	 */
   4940 	if (zone->journal != NULL &&
   4941 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
   4942 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4943 	{
   4944 		result = zone_journal_rollforward(zone, db, &needdump,
   4945 						  &fixjournal);
   4946 		if (result != ISC_R_SUCCESS) {
   4947 			goto cleanup;
   4948 		}
   4949 	}
   4950 
   4951 	/*
   4952 	 * Obtain ns, soa and cname counts for top of zone.
   4953 	 */
   4954 	INSIST(db != NULL);
   4955 	result = zone_get_from_db(zone, db, &nscount, &soacount, &soattl,
   4956 				  &serial, &refresh, &retry, &expire, &minimum,
   4957 				  &errors);
   4958 	if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
   4959 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   4960 			      "could not find NS and/or SOA records");
   4961 	}
   4962 
   4963 	/*
   4964 	 * Process any queued NSEC3PARAM change requests. Only for dynamic
   4965 	 * zones, an inline-signing zone will perform this action when
   4966 	 * receiving the secure db (receive_secure_db).
   4967 	 */
   4968 	is_dynamic = dns_zone_isdynamic(zone, true);
   4969 	if (is_dynamic) {
   4970 		isc_event_t *setnsec3param_event;
   4971 		dns_zone_t *dummy;
   4972 
   4973 		while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   4974 			setnsec3param_event =
   4975 				ISC_LIST_HEAD(zone->setnsec3param_queue);
   4976 			ISC_LIST_UNLINK(zone->setnsec3param_queue,
   4977 					setnsec3param_event, ev_link);
   4978 			dummy = NULL;
   4979 			zone_iattach(zone, &dummy);
   4980 			isc_task_send(zone->task, &setnsec3param_event);
   4981 		}
   4982 	}
   4983 
   4984 	/*
   4985 	 * Check to make sure the journal is up to date, and remove the
   4986 	 * journal file if it isn't, as we wouldn't be able to apply
   4987 	 * updates otherwise.
   4988 	 */
   4989 	if (zone->journal != NULL && is_dynamic &&
   4990 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
   4991 	{
   4992 		uint32_t jserial;
   4993 		dns_journal_t *journal = NULL;
   4994 		bool empty = false;
   4995 
   4996 		result = dns_journal_open(zone->mctx, zone->journal,
   4997 					  DNS_JOURNAL_READ, &journal);
   4998 		if (result == ISC_R_SUCCESS) {
   4999 			jserial = dns_journal_last_serial(journal);
   5000 			empty = dns_journal_empty(journal);
   5001 			dns_journal_destroy(&journal);
   5002 		} else {
   5003 			jserial = serial;
   5004 			result = ISC_R_SUCCESS;
   5005 		}
   5006 
   5007 		if (jserial != serial) {
   5008 			if (!empty) {
   5009 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5010 					      ISC_LOG_INFO,
   5011 					      "journal file is out of date: "
   5012 					      "removing journal file");
   5013 			}
   5014 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   5015 				char strbuf[ISC_STRERRORSIZE];
   5016 				strerror_r(errno, strbuf, sizeof(strbuf));
   5017 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   5018 					      DNS_LOGMODULE_ZONE,
   5019 					      ISC_LOG_WARNING,
   5020 					      "unable to remove journal "
   5021 					      "'%s': '%s'",
   5022 					      zone->journal, strbuf);
   5023 			}
   5024 		}
   5025 	}
   5026 
   5027 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   5028 		      "loaded; checking validity");
   5029 
   5030 	/*
   5031 	 * Master / Slave / Mirror / Stub zones require both NS and SOA records
   5032 	 * at the top of the zone.
   5033 	 */
   5034 
   5035 	switch (zone->type) {
   5036 	case dns_zone_dlz:
   5037 	case dns_zone_primary:
   5038 	case dns_zone_secondary:
   5039 	case dns_zone_mirror:
   5040 	case dns_zone_stub:
   5041 	case dns_zone_redirect:
   5042 		if (soacount != 1) {
   5043 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5044 				      ISC_LOG_ERROR, "has %d SOA records",
   5045 				      soacount);
   5046 			result = DNS_R_BADZONE;
   5047 		}
   5048 		if (nscount == 0) {
   5049 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5050 				      ISC_LOG_ERROR, "has no NS records");
   5051 			result = DNS_R_BADZONE;
   5052 		}
   5053 		if (result != ISC_R_SUCCESS) {
   5054 			goto cleanup;
   5055 		}
   5056 		if (zone->type == dns_zone_primary && errors != 0) {
   5057 			result = DNS_R_BADZONE;
   5058 			goto cleanup;
   5059 		}
   5060 		if (zone->type != dns_zone_stub &&
   5061 		    zone->type != dns_zone_redirect)
   5062 		{
   5063 			result = check_nsec3param(zone, db);
   5064 			if (result != ISC_R_SUCCESS) {
   5065 				goto cleanup;
   5066 			}
   5067 		}
   5068 		if (zone->type == dns_zone_primary &&
   5069 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
   5070 		    !integrity_checks(zone, db))
   5071 		{
   5072 			result = DNS_R_BADZONE;
   5073 			goto cleanup;
   5074 		}
   5075 		if (zone->type == dns_zone_primary &&
   5076 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
   5077 		    !zone_check_dup(zone, db))
   5078 		{
   5079 			result = DNS_R_BADZONE;
   5080 			goto cleanup;
   5081 		}
   5082 
   5083 		if (zone->type == dns_zone_primary) {
   5084 			result = dns_zone_cdscheck(zone, db, NULL);
   5085 			if (result != ISC_R_SUCCESS) {
   5086 				dns_zone_log(zone, ISC_LOG_ERROR,
   5087 					     "CDS/CDNSKEY consistency checks "
   5088 					     "failed");
   5089 				goto cleanup;
   5090 			}
   5091 		}
   5092 
   5093 		result = dns_zone_verifydb(zone, db, NULL);
   5094 		if (result != ISC_R_SUCCESS) {
   5095 			goto cleanup;
   5096 		}
   5097 
   5098 		if (zone->db != NULL) {
   5099 			unsigned int oldsoacount;
   5100 
   5101 			/*
   5102 			 * This is checked in zone_replacedb() for slave zones
   5103 			 * as they don't reload from disk.
   5104 			 */
   5105 			result = zone_get_from_db(
   5106 				zone, zone->db, NULL, &oldsoacount, NULL,
   5107 				&oldserial, NULL, NULL, NULL, NULL, NULL);
   5108 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5109 			RUNTIME_CHECK(oldsoacount > 0U);
   5110 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   5111 			    !isc_serial_gt(serial, oldserial))
   5112 			{
   5113 				uint32_t serialmin, serialmax;
   5114 
   5115 				INSIST(zone->type == dns_zone_primary);
   5116 				INSIST(zone->raw == NULL);
   5117 
   5118 				if (serial == oldserial &&
   5119 				    zone_unchanged(zone->db, db, zone->mctx))
   5120 				{
   5121 					dns_zone_logc(zone,
   5122 						      DNS_LOGCATEGORY_ZONELOAD,
   5123 						      ISC_LOG_INFO,
   5124 						      "ixfr-from-differences: "
   5125 						      "unchanged");
   5126 					zone->loadtime = loadtime;
   5127 					goto done;
   5128 				}
   5129 
   5130 				serialmin = (oldserial + 1) & 0xffffffffU;
   5131 				serialmax = (oldserial + 0x7fffffffU) &
   5132 					    0xffffffffU;
   5133 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5134 					      ISC_LOG_ERROR,
   5135 					      "ixfr-from-differences: "
   5136 					      "new serial (%u) out of range "
   5137 					      "[%u - %u]",
   5138 					      serial, serialmin, serialmax);
   5139 				result = DNS_R_BADZONE;
   5140 				goto cleanup;
   5141 			} else if (!isc_serial_ge(serial, oldserial)) {
   5142 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5143 					      ISC_LOG_ERROR,
   5144 					      "zone serial (%u/%u) has gone "
   5145 					      "backwards",
   5146 					      serial, oldserial);
   5147 			} else if (serial == oldserial && !hasinclude &&
   5148 				   strcmp(zone->db_argv[0], "_builtin") != 0)
   5149 			{
   5150 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5151 					      ISC_LOG_ERROR,
   5152 					      "zone serial (%u) unchanged. "
   5153 					      "zone may fail to transfer "
   5154 					      "to slaves.",
   5155 					      serial);
   5156 			}
   5157 		}
   5158 
   5159 		if (zone->type == dns_zone_primary &&
   5160 		    (zone->update_acl != NULL || zone->ssutable != NULL) &&
   5161 		    dns_zone_getsigresigninginterval(zone) < (3 * refresh) &&
   5162 		    dns_db_issecure(db))
   5163 		{
   5164 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5165 				      ISC_LOG_WARNING,
   5166 				      "sig-re-signing-interval less than "
   5167 				      "3 * refresh.");
   5168 		}
   5169 
   5170 		zone->refresh = RANGE(refresh, zone->minrefresh,
   5171 				      zone->maxrefresh);
   5172 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   5173 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   5174 				     DNS_MAX_EXPIRE);
   5175 		zone->soattl = soattl;
   5176 		zone->minimum = minimum;
   5177 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   5178 
   5179 		if (zone->type == dns_zone_secondary ||
   5180 		    zone->type == dns_zone_mirror ||
   5181 		    zone->type == dns_zone_stub ||
   5182 		    (zone->type == dns_zone_redirect && zone->masters != NULL))
   5183 		{
   5184 			isc_time_t t;
   5185 			uint32_t delay;
   5186 
   5187 			result = isc_file_getmodtime(zone->journal, &t);
   5188 			if (result != ISC_R_SUCCESS) {
   5189 				result = isc_file_getmodtime(zone->masterfile,
   5190 							     &t);
   5191 			}
   5192 			if (result == ISC_R_SUCCESS) {
   5193 				DNS_ZONE_TIME_ADD(&t, zone->expire,
   5194 						  &zone->expiretime);
   5195 			} else {
   5196 				DNS_ZONE_TIME_ADD(&now, zone->retry,
   5197 						  &zone->expiretime);
   5198 			}
   5199 
   5200 			delay = (zone->retry -
   5201 				 isc_random_uniform((zone->retry * 3) / 4));
   5202 			DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
   5203 			if (isc_time_compare(&zone->refreshtime,
   5204 					     &zone->expiretime) >= 0)
   5205 			{
   5206 				zone->refreshtime = now;
   5207 			}
   5208 		}
   5209 
   5210 		break;
   5211 
   5212 	case dns_zone_key:
   5213 		result = sync_keyzone(zone, db);
   5214 		if (result != ISC_R_SUCCESS) {
   5215 			goto cleanup;
   5216 		}
   5217 		break;
   5218 
   5219 	default:
   5220 		UNEXPECTED_ERROR(__FILE__, __LINE__, "unexpected zone type %d",
   5221 				 zone->type);
   5222 		result = ISC_R_UNEXPECTED;
   5223 		goto cleanup;
   5224 	}
   5225 
   5226 	/*
   5227 	 * Check for weak DNSKEY's.
   5228 	 */
   5229 	if (zone->type == dns_zone_primary) {
   5230 		zone_check_dnskeys(zone, db);
   5231 	}
   5232 
   5233 	/*
   5234 	 * Schedule DNSSEC key refresh.
   5235 	 */
   5236 	if (zone->type == dns_zone_primary &&
   5237 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   5238 	{
   5239 		zone->refreshkeytime = now;
   5240 	}
   5241 
   5242 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   5243 	if (zone->db != NULL) {
   5244 		had_db = true;
   5245 		result = zone_replacedb(zone, db, false);
   5246 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5247 		if (result != ISC_R_SUCCESS) {
   5248 			goto cleanup;
   5249 		}
   5250 	} else {
   5251 		zone_attachdb(zone, db);
   5252 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5253 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED |
   5254 					       DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   5255 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
   5256 		    inline_raw(zone))
   5257 		{
   5258 			if (zone->secure->db == NULL) {
   5259 				zone_send_securedb(zone, db);
   5260 			} else {
   5261 				zone_send_secureserial(zone, serial);
   5262 			}
   5263 		}
   5264 	}
   5265 
   5266 	/*
   5267 	 * Finished loading inline-signing zone; need to get status
   5268 	 * from the raw side now.
   5269 	 */
   5270 	if (zone->type == dns_zone_primary && inline_secure(zone)) {
   5271 		maybe_send_secure(zone);
   5272 	}
   5273 
   5274 	result = ISC_R_SUCCESS;
   5275 
   5276 	if (fixjournal) {
   5277 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIXJOURNAL);
   5278 		zone_journal_compact(zone, zone->db, 0);
   5279 	}
   5280 	if (needdump) {
   5281 		if (zone->type == dns_zone_key) {
   5282 			zone_needdump(zone, 30);
   5283 		} else {
   5284 			zone_needdump(zone, DNS_DUMP_DELAY);
   5285 		}
   5286 	}
   5287 
   5288 	if (zone->task != NULL) {
   5289 		if (zone->type == dns_zone_primary) {
   5290 			set_resigntime(zone);
   5291 			resume_signingwithkey(zone);
   5292 			resume_addnsec3chain(zone);
   5293 		}
   5294 
   5295 		is_dynamic = dns_zone_isdynamic(zone, false);
   5296 		if (zone->type == dns_zone_primary &&
   5297 		    !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
   5298 		    is_dynamic && dns_db_issecure(db))
   5299 		{
   5300 			dns_name_t *name;
   5301 			dns_fixedname_t fixed;
   5302 			dns_rdataset_t next;
   5303 
   5304 			dns_rdataset_init(&next);
   5305 			name = dns_fixedname_initname(&fixed);
   5306 
   5307 			result = dns_db_getsigningtime(db, &next, name);
   5308 			if (result == ISC_R_SUCCESS) {
   5309 				isc_stdtime_t timenow;
   5310 				char namebuf[DNS_NAME_FORMATSIZE];
   5311 				char typebuf[DNS_RDATATYPE_FORMATSIZE];
   5312 
   5313 				isc_stdtime_get(&timenow);
   5314 				dns_name_format(name, namebuf, sizeof(namebuf));
   5315 				dns_rdatatype_format(next.covers, typebuf,
   5316 						     sizeof(typebuf));
   5317 				dnssec_log(
   5318 					zone, ISC_LOG_DEBUG(3),
   5319 					"next resign: %s/%s "
   5320 					"in %d seconds",
   5321 					namebuf, typebuf,
   5322 					next.resign - timenow -
   5323 						dns_zone_getsigresigninginterval(
   5324 							zone));
   5325 				dns_rdataset_disassociate(&next);
   5326 			} else {
   5327 				dnssec_log(zone, ISC_LOG_WARNING,
   5328 					   "signed dynamic zone has no "
   5329 					   "resign event scheduled");
   5330 			}
   5331 		}
   5332 
   5333 		zone_settimer(zone, &now);
   5334 	}
   5335 
   5336 	/*
   5337 	 * Clear old include list.
   5338 	 */
   5339 	for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL;
   5340 	     inc = ISC_LIST_HEAD(zone->includes))
   5341 	{
   5342 		ISC_LIST_UNLINK(zone->includes, inc, link);
   5343 		isc_mem_free(zone->mctx, inc->name);
   5344 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5345 	}
   5346 	zone->nincludes = 0;
   5347 
   5348 	/*
   5349 	 * Transfer new include list.
   5350 	 */
   5351 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5352 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5353 	{
   5354 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5355 		ISC_LIST_APPEND(zone->includes, inc, link);
   5356 		zone->nincludes++;
   5357 	}
   5358 
   5359 	if (!dns_db_ispersistent(db)) {
   5360 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5361 			      "loaded serial %u%s", serial,
   5362 			      dns_db_issecure(db) ? " (DNSSEC signed)" : "");
   5363 	}
   5364 
   5365 	if (!had_db && zone->type == dns_zone_mirror) {
   5366 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5367 			      "mirror zone is now in use");
   5368 	}
   5369 
   5370 	zone->loadtime = loadtime;
   5371 	goto done;
   5372 
   5373 cleanup:
   5374 	if (zone->type == dns_zone_key && result != ISC_R_SUCCESS) {
   5375 		dnssec_log(zone, ISC_LOG_ERROR,
   5376 			   "failed to initialize managed-keys (%s): "
   5377 			   "DNSSEC validation is at risk",
   5378 			   isc_result_totext(result));
   5379 	}
   5380 
   5381 	if (result != ISC_R_SUCCESS) {
   5382 		dns_zone_rpz_disable_db(zone, db);
   5383 		dns_zone_catz_disable_db(zone, db);
   5384 	}
   5385 
   5386 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5387 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5388 	{
   5389 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5390 		isc_mem_free(zone->mctx, inc->name);
   5391 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5392 	}
   5393 	if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror ||
   5394 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   5395 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   5396 	{
   5397 		if (result != ISC_R_NOMEMORY) {
   5398 			if (zone->journal != NULL) {
   5399 				zone_saveunique(zone, zone->journal,
   5400 						"jn-XXXXXXXX");
   5401 			}
   5402 			if (zone->masterfile != NULL) {
   5403 				zone_saveunique(zone, zone->masterfile,
   5404 						"db-XXXXXXXX");
   5405 			}
   5406 		}
   5407 
   5408 		/* Mark the zone for immediate refresh. */
   5409 		zone->refreshtime = now;
   5410 		if (zone->task != NULL) {
   5411 			zone_settimer(zone, &now);
   5412 		}
   5413 		result = ISC_R_SUCCESS;
   5414 	} else if (zone->type == dns_zone_primary ||
   5415 		   zone->type == dns_zone_redirect)
   5416 	{
   5417 		if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
   5418 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5419 				      ISC_LOG_ERROR,
   5420 				      "not loaded due to errors.");
   5421 		} else if (zone->type == dns_zone_primary) {
   5422 			result = ISC_R_SUCCESS;
   5423 		}
   5424 	}
   5425 
   5426 done:
   5427 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   5428 	/*
   5429 	 * If this is an inline-signed zone and we were called for the raw
   5430 	 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone
   5431 	 * as well, but only if this is a reload, not an initial zone load: in
   5432 	 * the former case, zone_postload() will not be run for the secure
   5433 	 * zone; in the latter case, it will be.  Check which case we are
   5434 	 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the
   5435 	 * secure zone: if it is set, this must be a reload.
   5436 	 */
   5437 	if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
   5438 	{
   5439 		DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
   5440 		/*
   5441 		 * Re-start zone maintenance if it had been stalled
   5442 		 * due to DNS_ZONEFLG_LOADPENDING being set when
   5443 		 * zone_maintenance was called.
   5444 		 */
   5445 		if (zone->secure->task != NULL) {
   5446 			zone_settimer(zone->secure, &now);
   5447 		}
   5448 	}
   5449 
   5450 	zone_debuglog(zone, "zone_postload", 99, "done");
   5451 
   5452 	return (result);
   5453 }
   5454 
   5455 static bool
   5456 exit_check(dns_zone_t *zone) {
   5457 	REQUIRE(LOCKED_ZONE(zone));
   5458 
   5459 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
   5460 	    isc_refcount_current(&zone->irefs) == 0)
   5461 	{
   5462 		/*
   5463 		 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
   5464 		 */
   5465 		INSIST(isc_refcount_current(&zone->erefs) == 0);
   5466 		return (true);
   5467 	}
   5468 	return (false);
   5469 }
   5470 
   5471 static bool
   5472 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   5473 	      dns_name_t *name, bool logit) {
   5474 	isc_result_t result;
   5475 	char namebuf[DNS_NAME_FORMATSIZE];
   5476 	char altbuf[DNS_NAME_FORMATSIZE];
   5477 	dns_fixedname_t fixed;
   5478 	dns_name_t *foundname;
   5479 	int level;
   5480 
   5481 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) {
   5482 		return (true);
   5483 	}
   5484 
   5485 	if (zone->type == dns_zone_primary) {
   5486 		level = ISC_LOG_ERROR;
   5487 	} else {
   5488 		level = ISC_LOG_WARNING;
   5489 	}
   5490 
   5491 	foundname = dns_fixedname_initname(&fixed);
   5492 
   5493 	result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL,
   5494 			     foundname, NULL, NULL);
   5495 	if (result == ISC_R_SUCCESS) {
   5496 		return (true);
   5497 	}
   5498 
   5499 	if (result == DNS_R_NXRRSET) {
   5500 		result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0,
   5501 				     0, NULL, foundname, NULL, NULL);
   5502 		if (result == ISC_R_SUCCESS) {
   5503 			return (true);
   5504 		}
   5505 	}
   5506 
   5507 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   5508 	    result == DNS_R_EMPTYNAME)
   5509 	{
   5510 		if (logit) {
   5511 			dns_name_format(name, namebuf, sizeof namebuf);
   5512 			dns_zone_log(zone, level,
   5513 				     "NS '%s' has no address "
   5514 				     "records (A or AAAA)",
   5515 				     namebuf);
   5516 		}
   5517 		return (false);
   5518 	}
   5519 
   5520 	if (result == DNS_R_CNAME) {
   5521 		if (logit) {
   5522 			dns_name_format(name, namebuf, sizeof namebuf);
   5523 			dns_zone_log(zone, level,
   5524 				     "NS '%s' is a CNAME "
   5525 				     "(illegal)",
   5526 				     namebuf);
   5527 		}
   5528 		return (false);
   5529 	}
   5530 
   5531 	if (result == DNS_R_DNAME) {
   5532 		if (logit) {
   5533 			dns_name_format(name, namebuf, sizeof namebuf);
   5534 			dns_name_format(foundname, altbuf, sizeof altbuf);
   5535 			dns_zone_log(zone, level,
   5536 				     "NS '%s' is below a DNAME "
   5537 				     "'%s' (illegal)",
   5538 				     namebuf, altbuf);
   5539 		}
   5540 		return (false);
   5541 	}
   5542 
   5543 	return (true);
   5544 }
   5545 
   5546 static isc_result_t
   5547 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   5548 		 dns_dbversion_t *version, unsigned int *nscount,
   5549 		 unsigned int *errors, bool logit) {
   5550 	isc_result_t result;
   5551 	unsigned int count = 0;
   5552 	unsigned int ecount = 0;
   5553 	dns_rdataset_t rdataset;
   5554 	dns_rdata_t rdata;
   5555 	dns_rdata_ns_t ns;
   5556 
   5557 	dns_rdataset_init(&rdataset);
   5558 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
   5559 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5560 	if (result == ISC_R_NOTFOUND) {
   5561 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5562 		goto success;
   5563 	}
   5564 	if (result != ISC_R_SUCCESS) {
   5565 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5566 		goto invalidate_rdataset;
   5567 	}
   5568 
   5569 	result = dns_rdataset_first(&rdataset);
   5570 	while (result == ISC_R_SUCCESS) {
   5571 		if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
   5572 		    (zone->type == dns_zone_primary ||
   5573 		     zone->type == dns_zone_secondary ||
   5574 		     zone->type == dns_zone_mirror))
   5575 		{
   5576 			dns_rdata_init(&rdata);
   5577 			dns_rdataset_current(&rdataset, &rdata);
   5578 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   5579 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5580 			if (dns_name_issubdomain(&ns.name, &zone->origin) &&
   5581 			    !zone_check_ns(zone, db, version, &ns.name, logit))
   5582 			{
   5583 				ecount++;
   5584 			}
   5585 		}
   5586 		count++;
   5587 		result = dns_rdataset_next(&rdataset);
   5588 	}
   5589 	dns_rdataset_disassociate(&rdataset);
   5590 
   5591 success:
   5592 	if (nscount != NULL) {
   5593 		*nscount = count;
   5594 	}
   5595 	if (errors != NULL) {
   5596 		*errors = ecount;
   5597 	}
   5598 
   5599 	result = ISC_R_SUCCESS;
   5600 
   5601 invalidate_rdataset:
   5602 	dns_rdataset_invalidate(&rdataset);
   5603 
   5604 	return (result);
   5605 }
   5606 
   5607 #define SET_IF_NOT_NULL(obj, val) \
   5608 	if (obj != NULL) {        \
   5609 		*obj = val;       \
   5610 	}
   5611 
   5612 #define SET_SOA_VALUES(soattl_v, serial_v, refresh_v, retry_v, expire_v, \
   5613 		       minimum_v)                                        \
   5614 	{                                                                \
   5615 		SET_IF_NOT_NULL(soattl, soattl_v);                       \
   5616 		SET_IF_NOT_NULL(serial, serial_v);                       \
   5617 		SET_IF_NOT_NULL(refresh, refresh_v);                     \
   5618 		SET_IF_NOT_NULL(retry, retry_v);                         \
   5619 		SET_IF_NOT_NULL(expire, expire_v);                       \
   5620 		SET_IF_NOT_NULL(minimum, minimum_v);                     \
   5621 	}
   5622 
   5623 #define CLR_SOA_VALUES()                          \
   5624 	{                                         \
   5625 		SET_SOA_VALUES(0, 0, 0, 0, 0, 0); \
   5626 	}
   5627 
   5628 static isc_result_t
   5629 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   5630 		 unsigned int *soacount, uint32_t *soattl, uint32_t *serial,
   5631 		 uint32_t *refresh, uint32_t *retry, uint32_t *expire,
   5632 		 uint32_t *minimum) {
   5633 	isc_result_t result;
   5634 	unsigned int count = 0;
   5635 	dns_rdataset_t rdataset;
   5636 	dns_rdata_t rdata = DNS_RDATA_INIT;
   5637 
   5638 	dns_rdataset_init(&rdataset);
   5639 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
   5640 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5641 	if (result == ISC_R_NOTFOUND) {
   5642 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5643 		result = ISC_R_SUCCESS;
   5644 		goto invalidate_rdataset;
   5645 	}
   5646 	if (result != ISC_R_SUCCESS) {
   5647 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5648 		goto invalidate_rdataset;
   5649 	}
   5650 
   5651 	result = dns_rdataset_first(&rdataset);
   5652 	while (result == ISC_R_SUCCESS) {
   5653 		dns_rdata_init(&rdata);
   5654 		dns_rdataset_current(&rdataset, &rdata);
   5655 		count++;
   5656 		if (count == 1) {
   5657 			dns_rdata_soa_t soa;
   5658 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   5659 			SET_SOA_VALUES(rdataset.ttl, soa.serial, soa.refresh,
   5660 				       soa.retry, soa.expire, soa.minimum);
   5661 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5662 		}
   5663 
   5664 		result = dns_rdataset_next(&rdataset);
   5665 		dns_rdata_reset(&rdata);
   5666 	}
   5667 	dns_rdataset_disassociate(&rdataset);
   5668 
   5669 	result = ISC_R_SUCCESS;
   5670 
   5671 invalidate_rdataset:
   5672 	SET_IF_NOT_NULL(soacount, count);
   5673 	if (count == 0) {
   5674 		CLR_SOA_VALUES();
   5675 	}
   5676 
   5677 	dns_rdataset_invalidate(&rdataset);
   5678 
   5679 	return (result);
   5680 }
   5681 
   5682 /*
   5683  * zone must be locked.
   5684  */
   5685 static isc_result_t
   5686 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
   5687 		 unsigned int *soacount, uint32_t *soattl, uint32_t *serial,
   5688 		 uint32_t *refresh, uint32_t *retry, uint32_t *expire,
   5689 		 uint32_t *minimum, unsigned int *errors) {
   5690 	isc_result_t result;
   5691 	isc_result_t answer = ISC_R_SUCCESS;
   5692 	dns_dbversion_t *version = NULL;
   5693 	dns_dbnode_t *node;
   5694 
   5695 	REQUIRE(db != NULL);
   5696 	REQUIRE(zone != NULL);
   5697 
   5698 	dns_db_currentversion(db, &version);
   5699 
   5700 	SET_IF_NOT_NULL(nscount, 0);
   5701 	SET_IF_NOT_NULL(soacount, 0);
   5702 	SET_IF_NOT_NULL(errors, 0);
   5703 	CLR_SOA_VALUES();
   5704 
   5705 	node = NULL;
   5706 	result = dns_db_findnode(db, &zone->origin, false, &node);
   5707 	if (result != ISC_R_SUCCESS) {
   5708 		answer = result;
   5709 		goto closeversion;
   5710 	}
   5711 
   5712 	if (nscount != NULL || errors != NULL) {
   5713 		result = zone_count_ns_rr(zone, db, node, version, nscount,
   5714 					  errors, true);
   5715 		if (result != ISC_R_SUCCESS) {
   5716 			answer = result;
   5717 		}
   5718 	}
   5719 
   5720 	if (soacount != NULL || soattl != NULL || serial != NULL ||
   5721 	    refresh != NULL || retry != NULL || expire != NULL ||
   5722 	    minimum != NULL)
   5723 	{
   5724 		result = zone_load_soa_rr(db, node, version, soacount, soattl,
   5725 					  serial, refresh, retry, expire,
   5726 					  minimum);
   5727 		if (result != ISC_R_SUCCESS) {
   5728 			answer = result;
   5729 		}
   5730 	}
   5731 
   5732 	dns_db_detachnode(db, &node);
   5733 closeversion:
   5734 	dns_db_closeversion(db, &version, false);
   5735 
   5736 	return (answer);
   5737 }
   5738 
   5739 void
   5740 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
   5741 	REQUIRE(DNS_ZONE_VALID(source));
   5742 	REQUIRE(target != NULL && *target == NULL);
   5743 	isc_refcount_increment(&source->erefs);
   5744 	*target = source;
   5745 }
   5746 
   5747 void
   5748 dns_zone_detach(dns_zone_t **zonep) {
   5749 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5750 
   5751 	dns_zone_t *zone = *zonep;
   5752 	*zonep = NULL;
   5753 
   5754 	if (isc_refcount_decrement(&zone->erefs) == 1) {
   5755 		isc_event_t *ev = &zone->ctlevent;
   5756 
   5757 		isc_refcount_destroy(&zone->erefs);
   5758 
   5759 		/*
   5760 		 * Stop things being restarted after we cancel them below.
   5761 		 */
   5762 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
   5763 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
   5764 			     "final reference detached");
   5765 		if (zone->task != NULL) {
   5766 			/*
   5767 			 * This zone has a task; it can clean
   5768 			 * itself up asynchronously.
   5769 			 */
   5770 			isc_task_send(zone->task, &ev);
   5771 			return;
   5772 		}
   5773 
   5774 		/*
   5775 		 * This zone is unmanaged; we're probably running in
   5776 		 * named-checkzone or a unit test. There's no task,
   5777 		 * so we need to free it immediately.
   5778 		 *
   5779 		 * Unmanaged zones must not have null views; we have no way
   5780 		 * of detaching from the view here without causing deadlock
   5781 		 * because this code is called with the view already
   5782 		 * locked.
   5783 		 */
   5784 		INSIST(zone->view == NULL);
   5785 
   5786 		zone_shutdown(zone->task, ev);
   5787 		ev = NULL;
   5788 	}
   5789 }
   5790 
   5791 void
   5792 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5793 	REQUIRE(DNS_ZONE_VALID(source));
   5794 
   5795 	LOCK_ZONE(source);
   5796 	zone_iattach(source, target);
   5797 	UNLOCK_ZONE(source);
   5798 }
   5799 
   5800 static void
   5801 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5802 	REQUIRE(DNS_ZONE_VALID(source));
   5803 	REQUIRE(LOCKED_ZONE(source));
   5804 	REQUIRE(target != NULL && *target == NULL);
   5805 	INSIST(isc_refcount_increment0(&source->irefs) +
   5806 		       isc_refcount_current(&source->erefs) >
   5807 	       0);
   5808 	*target = source;
   5809 }
   5810 
   5811 static void
   5812 zone_idetach(dns_zone_t **zonep) {
   5813 	dns_zone_t *zone;
   5814 
   5815 	/*
   5816 	 * 'zone' locked by caller.
   5817 	 */
   5818 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5819 	REQUIRE(LOCKED_ZONE(*zonep));
   5820 
   5821 	zone = *zonep;
   5822 	*zonep = NULL;
   5823 
   5824 	INSIST(isc_refcount_decrement(&zone->irefs) - 1 +
   5825 		       isc_refcount_current(&zone->erefs) >
   5826 	       0);
   5827 }
   5828 
   5829 void
   5830 dns_zone_idetach(dns_zone_t **zonep) {
   5831 	dns_zone_t *zone;
   5832 
   5833 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5834 
   5835 	zone = *zonep;
   5836 	*zonep = NULL;
   5837 
   5838 	if (isc_refcount_decrement(&zone->irefs) == 1) {
   5839 		bool free_needed;
   5840 		LOCK_ZONE(zone);
   5841 		free_needed = exit_check(zone);
   5842 		UNLOCK_ZONE(zone);
   5843 		if (free_needed) {
   5844 			zone_free(zone);
   5845 		}
   5846 	}
   5847 }
   5848 
   5849 isc_mem_t *
   5850 dns_zone_getmctx(dns_zone_t *zone) {
   5851 	REQUIRE(DNS_ZONE_VALID(zone));
   5852 
   5853 	return (zone->mctx);
   5854 }
   5855 
   5856 dns_zonemgr_t *
   5857 dns_zone_getmgr(dns_zone_t *zone) {
   5858 	REQUIRE(DNS_ZONE_VALID(zone));
   5859 
   5860 	return (zone->zmgr);
   5861 }
   5862 
   5863 void
   5864 dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) {
   5865 	REQUIRE(DNS_ZONE_VALID(zone));
   5866 
   5867 	LOCK_ZONE(zone);
   5868 	if (zone->kasp != NULL) {
   5869 		dns_kasp_t *oldkasp = zone->kasp;
   5870 		zone->kasp = NULL;
   5871 		dns_kasp_detach(&oldkasp);
   5872 	}
   5873 	zone->kasp = kasp;
   5874 	UNLOCK_ZONE(zone);
   5875 }
   5876 
   5877 dns_kasp_t *
   5878 dns_zone_getkasp(dns_zone_t *zone) {
   5879 	REQUIRE(DNS_ZONE_VALID(zone));
   5880 
   5881 	return (zone->kasp);
   5882 }
   5883 
   5884 void
   5885 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) {
   5886 	REQUIRE(DNS_ZONE_VALID(zone));
   5887 
   5888 	if (value) {
   5889 		DNS_ZONE_SETOPTION(zone, option);
   5890 	} else {
   5891 		DNS_ZONE_CLROPTION(zone, option);
   5892 	}
   5893 }
   5894 
   5895 dns_zoneopt_t
   5896 dns_zone_getoptions(dns_zone_t *zone) {
   5897 	REQUIRE(DNS_ZONE_VALID(zone));
   5898 
   5899 	return (atomic_load_relaxed(&zone->options));
   5900 }
   5901 
   5902 void
   5903 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) {
   5904 	REQUIRE(DNS_ZONE_VALID(zone));
   5905 
   5906 	if (value) {
   5907 		DNS_ZONEKEY_SETOPTION(zone, keyopt);
   5908 	} else {
   5909 		DNS_ZONEKEY_CLROPTION(zone, keyopt);
   5910 	}
   5911 }
   5912 
   5913 unsigned int
   5914 dns_zone_getkeyopts(dns_zone_t *zone) {
   5915 	REQUIRE(DNS_ZONE_VALID(zone));
   5916 
   5917 	return (atomic_load_relaxed(&zone->keyopts));
   5918 }
   5919 
   5920 isc_result_t
   5921 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5922 	REQUIRE(DNS_ZONE_VALID(zone));
   5923 
   5924 	LOCK_ZONE(zone);
   5925 	zone->xfrsource4 = *xfrsource;
   5926 	UNLOCK_ZONE(zone);
   5927 
   5928 	return (ISC_R_SUCCESS);
   5929 }
   5930 
   5931 isc_sockaddr_t *
   5932 dns_zone_getxfrsource4(dns_zone_t *zone) {
   5933 	REQUIRE(DNS_ZONE_VALID(zone));
   5934 	return (&zone->xfrsource4);
   5935 }
   5936 
   5937 isc_result_t
   5938 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5939 	REQUIRE(DNS_ZONE_VALID(zone));
   5940 
   5941 	LOCK_ZONE(zone);
   5942 	zone->xfrsource4dscp = dscp;
   5943 	UNLOCK_ZONE(zone);
   5944 
   5945 	return (ISC_R_SUCCESS);
   5946 }
   5947 
   5948 isc_dscp_t
   5949 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
   5950 	REQUIRE(DNS_ZONE_VALID(zone));
   5951 	return (zone->xfrsource4dscp);
   5952 }
   5953 
   5954 isc_result_t
   5955 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5956 	REQUIRE(DNS_ZONE_VALID(zone));
   5957 
   5958 	LOCK_ZONE(zone);
   5959 	zone->xfrsource6 = *xfrsource;
   5960 	UNLOCK_ZONE(zone);
   5961 
   5962 	return (ISC_R_SUCCESS);
   5963 }
   5964 
   5965 isc_sockaddr_t *
   5966 dns_zone_getxfrsource6(dns_zone_t *zone) {
   5967 	REQUIRE(DNS_ZONE_VALID(zone));
   5968 	return (&zone->xfrsource6);
   5969 }
   5970 
   5971 isc_dscp_t
   5972 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
   5973 	REQUIRE(DNS_ZONE_VALID(zone));
   5974 	return (zone->xfrsource6dscp);
   5975 }
   5976 
   5977 isc_result_t
   5978 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5979 	REQUIRE(DNS_ZONE_VALID(zone));
   5980 
   5981 	LOCK_ZONE(zone);
   5982 	zone->xfrsource6dscp = dscp;
   5983 	UNLOCK_ZONE(zone);
   5984 
   5985 	return (ISC_R_SUCCESS);
   5986 }
   5987 
   5988 isc_result_t
   5989 dns_zone_setaltxfrsource4(dns_zone_t *zone,
   5990 			  const isc_sockaddr_t *altxfrsource) {
   5991 	REQUIRE(DNS_ZONE_VALID(zone));
   5992 
   5993 	LOCK_ZONE(zone);
   5994 	zone->altxfrsource4 = *altxfrsource;
   5995 	UNLOCK_ZONE(zone);
   5996 
   5997 	return (ISC_R_SUCCESS);
   5998 }
   5999 
   6000 isc_sockaddr_t *
   6001 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
   6002 	REQUIRE(DNS_ZONE_VALID(zone));
   6003 	return (&zone->altxfrsource4);
   6004 }
   6005 
   6006 isc_result_t
   6007 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6008 	REQUIRE(DNS_ZONE_VALID(zone));
   6009 
   6010 	LOCK_ZONE(zone);
   6011 	zone->altxfrsource4dscp = dscp;
   6012 	UNLOCK_ZONE(zone);
   6013 
   6014 	return (ISC_R_SUCCESS);
   6015 }
   6016 
   6017 isc_dscp_t
   6018 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
   6019 	REQUIRE(DNS_ZONE_VALID(zone));
   6020 	return (zone->altxfrsource4dscp);
   6021 }
   6022 
   6023 isc_result_t
   6024 dns_zone_setaltxfrsource6(dns_zone_t *zone,
   6025 			  const isc_sockaddr_t *altxfrsource) {
   6026 	REQUIRE(DNS_ZONE_VALID(zone));
   6027 
   6028 	LOCK_ZONE(zone);
   6029 	zone->altxfrsource6 = *altxfrsource;
   6030 	UNLOCK_ZONE(zone);
   6031 
   6032 	return (ISC_R_SUCCESS);
   6033 }
   6034 
   6035 isc_sockaddr_t *
   6036 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
   6037 	REQUIRE(DNS_ZONE_VALID(zone));
   6038 	return (&zone->altxfrsource6);
   6039 }
   6040 
   6041 isc_result_t
   6042 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6043 	REQUIRE(DNS_ZONE_VALID(zone));
   6044 
   6045 	LOCK_ZONE(zone);
   6046 	zone->altxfrsource6dscp = dscp;
   6047 	UNLOCK_ZONE(zone);
   6048 
   6049 	return (ISC_R_SUCCESS);
   6050 }
   6051 
   6052 isc_dscp_t
   6053 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
   6054 	REQUIRE(DNS_ZONE_VALID(zone));
   6055 	return (zone->altxfrsource6dscp);
   6056 }
   6057 
   6058 isc_result_t
   6059 dns_zone_setparentalsrc4(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) {
   6060 	REQUIRE(DNS_ZONE_VALID(zone));
   6061 
   6062 	LOCK_ZONE(zone);
   6063 	zone->parentalsrc4 = *parentalsrc;
   6064 	UNLOCK_ZONE(zone);
   6065 
   6066 	return (ISC_R_SUCCESS);
   6067 }
   6068 
   6069 isc_sockaddr_t *
   6070 dns_zone_getparentalsrc4(dns_zone_t *zone) {
   6071 	REQUIRE(DNS_ZONE_VALID(zone));
   6072 	return (&zone->parentalsrc4);
   6073 }
   6074 
   6075 isc_result_t
   6076 dns_zone_setparentalsrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6077 	REQUIRE(DNS_ZONE_VALID(zone));
   6078 
   6079 	LOCK_ZONE(zone);
   6080 	zone->parentalsrc4dscp = dscp;
   6081 	UNLOCK_ZONE(zone);
   6082 
   6083 	return (ISC_R_SUCCESS);
   6084 }
   6085 
   6086 isc_dscp_t
   6087 dns_zone_getparentalsrc4dscp(dns_zone_t *zone) {
   6088 	REQUIRE(DNS_ZONE_VALID(zone));
   6089 	return (zone->parentalsrc4dscp);
   6090 }
   6091 
   6092 isc_result_t
   6093 dns_zone_setparentalsrc6(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) {
   6094 	REQUIRE(DNS_ZONE_VALID(zone));
   6095 
   6096 	LOCK_ZONE(zone);
   6097 	zone->parentalsrc6 = *parentalsrc;
   6098 	UNLOCK_ZONE(zone);
   6099 
   6100 	return (ISC_R_SUCCESS);
   6101 }
   6102 
   6103 isc_sockaddr_t *
   6104 dns_zone_getparentalsrc6(dns_zone_t *zone) {
   6105 	REQUIRE(DNS_ZONE_VALID(zone));
   6106 	return (&zone->parentalsrc6);
   6107 }
   6108 
   6109 isc_result_t
   6110 dns_zone_setparentalsrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6111 	REQUIRE(DNS_ZONE_VALID(zone));
   6112 
   6113 	LOCK_ZONE(zone);
   6114 	zone->parentalsrc6dscp = dscp;
   6115 	UNLOCK_ZONE(zone);
   6116 
   6117 	return (ISC_R_SUCCESS);
   6118 }
   6119 
   6120 isc_dscp_t
   6121 dns_zone_getparentalsrc6dscp(dns_zone_t *zone) {
   6122 	REQUIRE(DNS_ZONE_VALID(zone));
   6123 	return (zone->parentalsrc6dscp);
   6124 }
   6125 
   6126 isc_result_t
   6127 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6128 	REQUIRE(DNS_ZONE_VALID(zone));
   6129 
   6130 	LOCK_ZONE(zone);
   6131 	zone->notifysrc4 = *notifysrc;
   6132 	UNLOCK_ZONE(zone);
   6133 
   6134 	return (ISC_R_SUCCESS);
   6135 }
   6136 
   6137 isc_sockaddr_t *
   6138 dns_zone_getnotifysrc4(dns_zone_t *zone) {
   6139 	REQUIRE(DNS_ZONE_VALID(zone));
   6140 	return (&zone->notifysrc4);
   6141 }
   6142 
   6143 isc_result_t
   6144 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6145 	REQUIRE(DNS_ZONE_VALID(zone));
   6146 
   6147 	LOCK_ZONE(zone);
   6148 	zone->notifysrc4dscp = dscp;
   6149 	UNLOCK_ZONE(zone);
   6150 
   6151 	return (ISC_R_SUCCESS);
   6152 }
   6153 
   6154 isc_dscp_t
   6155 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
   6156 	REQUIRE(DNS_ZONE_VALID(zone));
   6157 	return (zone->notifysrc4dscp);
   6158 }
   6159 
   6160 isc_result_t
   6161 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6162 	REQUIRE(DNS_ZONE_VALID(zone));
   6163 
   6164 	LOCK_ZONE(zone);
   6165 	zone->notifysrc6 = *notifysrc;
   6166 	UNLOCK_ZONE(zone);
   6167 
   6168 	return (ISC_R_SUCCESS);
   6169 }
   6170 
   6171 isc_sockaddr_t *
   6172 dns_zone_getnotifysrc6(dns_zone_t *zone) {
   6173 	REQUIRE(DNS_ZONE_VALID(zone));
   6174 	return (&zone->notifysrc6);
   6175 }
   6176 
   6177 isc_result_t
   6178 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6179 	REQUIRE(DNS_ZONE_VALID(zone));
   6180 
   6181 	LOCK_ZONE(zone);
   6182 	zone->notifysrc6dscp = dscp;
   6183 	UNLOCK_ZONE(zone);
   6184 
   6185 	return (ISC_R_SUCCESS);
   6186 }
   6187 
   6188 isc_dscp_t
   6189 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
   6190 	REQUIRE(DNS_ZONE_VALID(zone));
   6191 	return (zone->notifysrc6dscp);
   6192 }
   6193 
   6194 static bool
   6195 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
   6196 	   uint32_t count) {
   6197 	unsigned int i;
   6198 
   6199 	for (i = 0; i < count; i++) {
   6200 		if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) {
   6201 			return (false);
   6202 		}
   6203 	}
   6204 	return (true);
   6205 }
   6206 
   6207 static bool
   6208 same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist,
   6209 	      uint32_t count) {
   6210 	unsigned int i;
   6211 
   6212 	if (oldlist == NULL && newlist == NULL) {
   6213 		return (true);
   6214 	}
   6215 	if (oldlist == NULL || newlist == NULL) {
   6216 		return (false);
   6217 	}
   6218 
   6219 	for (i = 0; i < count; i++) {
   6220 		if (oldlist[i] == NULL && newlist[i] == NULL) {
   6221 			continue;
   6222 		}
   6223 		if (oldlist[i] == NULL || newlist[i] == NULL ||
   6224 		    !dns_name_equal(oldlist[i], newlist[i]))
   6225 		{
   6226 			return (false);
   6227 		}
   6228 	}
   6229 	return (true);
   6230 }
   6231 
   6232 static void
   6233 clear_serverslist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
   6234 		  dns_name_t ***keynamesp, unsigned int *countp,
   6235 		  isc_mem_t *mctx) {
   6236 	unsigned int count;
   6237 	isc_sockaddr_t *addrs;
   6238 	isc_dscp_t *dscps;
   6239 	dns_name_t **keynames;
   6240 
   6241 	REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
   6242 		keynamesp != NULL);
   6243 
   6244 	count = *countp;
   6245 	*countp = 0;
   6246 	addrs = *addrsp;
   6247 	*addrsp = NULL;
   6248 	dscps = *dscpsp;
   6249 	*dscpsp = NULL;
   6250 	keynames = *keynamesp;
   6251 	*keynamesp = NULL;
   6252 
   6253 	if (addrs != NULL) {
   6254 		isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
   6255 	}
   6256 
   6257 	if (dscps != NULL) {
   6258 		isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
   6259 	}
   6260 
   6261 	if (keynames != NULL) {
   6262 		unsigned int i;
   6263 		for (i = 0; i < count; i++) {
   6264 			if (keynames[i] != NULL) {
   6265 				dns_name_free(keynames[i], mctx);
   6266 				isc_mem_put(mctx, keynames[i],
   6267 					    sizeof(dns_name_t));
   6268 				keynames[i] = NULL;
   6269 			}
   6270 		}
   6271 		isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
   6272 	}
   6273 }
   6274 
   6275 static isc_result_t
   6276 set_serverslist(unsigned int count, const isc_sockaddr_t *addrs,
   6277 		isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp,
   6278 		isc_dscp_t **newdscpp, dns_name_t **names,
   6279 		dns_name_t ***newnamesp, isc_mem_t *mctx) {
   6280 	isc_sockaddr_t *newaddrs = NULL;
   6281 	isc_dscp_t *newdscp = NULL;
   6282 	dns_name_t **newnames = NULL;
   6283 	unsigned int i;
   6284 
   6285 	REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
   6286 	REQUIRE(newdscpp != NULL && *newdscpp == NULL);
   6287 	REQUIRE(newnamesp != NULL && *newnamesp == NULL);
   6288 
   6289 	newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
   6290 	memmove(newaddrs, addrs, count * sizeof(*newaddrs));
   6291 
   6292 	if (dscp != NULL) {
   6293 		newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
   6294 		memmove(newdscp, dscp, count * sizeof(*newdscp));
   6295 	} else {
   6296 		newdscp = NULL;
   6297 	}
   6298 
   6299 	if (names != NULL) {
   6300 		newnames = isc_mem_get(mctx, count * sizeof(*newnames));
   6301 		for (i = 0; i < count; i++) {
   6302 			newnames[i] = NULL;
   6303 		}
   6304 		for (i = 0; i < count; i++) {
   6305 			if (names[i] != NULL) {
   6306 				newnames[i] = isc_mem_get(mctx,
   6307 							  sizeof(dns_name_t));
   6308 				dns_name_init(newnames[i], NULL);
   6309 				dns_name_dup(names[i], mctx, newnames[i]);
   6310 			}
   6311 		}
   6312 	} else {
   6313 		newnames = NULL;
   6314 	}
   6315 
   6316 	*newdscpp = newdscp;
   6317 	*newaddrsp = newaddrs;
   6318 	*newnamesp = newnames;
   6319 	return (ISC_R_SUCCESS);
   6320 }
   6321 
   6322 isc_result_t
   6323 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6324 		       uint32_t count) {
   6325 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
   6326 					       count));
   6327 }
   6328 
   6329 isc_result_t
   6330 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6331 			       dns_name_t **keynames, uint32_t count) {
   6332 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
   6333 					       count));
   6334 }
   6335 
   6336 isc_result_t
   6337 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6338 			       const isc_dscp_t *dscps, dns_name_t **keynames,
   6339 			       uint32_t count) {
   6340 	isc_result_t result;
   6341 	isc_sockaddr_t *newaddrs = NULL;
   6342 	isc_dscp_t *newdscps = NULL;
   6343 	dns_name_t **newnames = NULL;
   6344 
   6345 	REQUIRE(DNS_ZONE_VALID(zone));
   6346 	REQUIRE(count == 0 || notify != NULL);
   6347 	if (keynames != NULL) {
   6348 		REQUIRE(count != 0);
   6349 	}
   6350 
   6351 	LOCK_ZONE(zone);
   6352 
   6353 	if (count == zone->notifycnt &&
   6354 	    same_addrs(zone->notify, notify, count) &&
   6355 	    same_keynames(zone->notifykeynames, keynames, count))
   6356 	{
   6357 		goto unlock;
   6358 	}
   6359 
   6360 	clear_serverslist(&zone->notify, &zone->notifydscp,
   6361 			  &zone->notifykeynames, &zone->notifycnt, zone->mctx);
   6362 
   6363 	if (count == 0) {
   6364 		goto unlock;
   6365 	}
   6366 
   6367 	/*
   6368 	 * Set up the notify and notifykey lists
   6369 	 */
   6370 	result = set_serverslist(count, notify, &newaddrs, dscps, &newdscps,
   6371 				 keynames, &newnames, zone->mctx);
   6372 	if (result != ISC_R_SUCCESS) {
   6373 		goto unlock;
   6374 	}
   6375 
   6376 	/*
   6377 	 * Everything is ok so attach to the zone.
   6378 	 */
   6379 	zone->notify = newaddrs;
   6380 	zone->notifydscp = newdscps;
   6381 	zone->notifykeynames = newnames;
   6382 	zone->notifycnt = count;
   6383 unlock:
   6384 	UNLOCK_ZONE(zone);
   6385 	return (ISC_R_SUCCESS);
   6386 }
   6387 
   6388 isc_result_t
   6389 dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *masters,
   6390 		      uint32_t count) {
   6391 	isc_result_t result;
   6392 
   6393 	result = dns_zone_setprimarieswithkeys(zone, masters, NULL, count);
   6394 	return (result);
   6395 }
   6396 
   6397 isc_result_t
   6398 dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
   6399 			      dns_name_t **keynames, uint32_t count) {
   6400 	isc_result_t result = ISC_R_SUCCESS;
   6401 	isc_sockaddr_t *newaddrs = NULL;
   6402 	isc_dscp_t *newdscps = NULL;
   6403 	dns_name_t **newnames = NULL;
   6404 	bool *newok;
   6405 	unsigned int i;
   6406 
   6407 	REQUIRE(DNS_ZONE_VALID(zone));
   6408 	REQUIRE(count == 0 || masters != NULL);
   6409 	if (keynames != NULL) {
   6410 		REQUIRE(count != 0);
   6411 	}
   6412 
   6413 	LOCK_ZONE(zone);
   6414 	/*
   6415 	 * The refresh code assumes that 'primaries' wouldn't change under it.
   6416 	 * If it will change then kill off any current refresh in progress
   6417 	 * and update the primaries info.  If it won't change then we can just
   6418 	 * unlock and exit.
   6419 	 */
   6420 	if (count != zone->masterscnt ||
   6421 	    !same_addrs(zone->masters, masters, count) ||
   6422 	    !same_keynames(zone->masterkeynames, keynames, count))
   6423 	{
   6424 		if (zone->request != NULL) {
   6425 			dns_request_cancel(zone->request);
   6426 		}
   6427 	} else {
   6428 		goto unlock;
   6429 	}
   6430 
   6431 	/*
   6432 	 * This needs to happen before clear_addresskeylist() sets
   6433 	 * zone->masterscnt to 0:
   6434 	 */
   6435 	if (zone->mastersok != NULL) {
   6436 		isc_mem_put(zone->mctx, zone->mastersok,
   6437 			    zone->masterscnt * sizeof(bool));
   6438 		zone->mastersok = NULL;
   6439 	}
   6440 	clear_serverslist(&zone->masters, &zone->masterdscps,
   6441 			  &zone->masterkeynames, &zone->masterscnt, zone->mctx);
   6442 	/*
   6443 	 * If count == 0, don't allocate any space for masters, mastersok or
   6444 	 * keynames so internally, those pointers are NULL if count == 0
   6445 	 */
   6446 	if (count == 0) {
   6447 		goto unlock;
   6448 	}
   6449 
   6450 	/*
   6451 	 * mastersok must contain count elements
   6452 	 */
   6453 	newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
   6454 	for (i = 0; i < count; i++) {
   6455 		newok[i] = false;
   6456 	}
   6457 
   6458 	/*
   6459 	 * Now set up the primaries and primary key lists
   6460 	 */
   6461 	result = set_serverslist(count, masters, &newaddrs, NULL, &newdscps,
   6462 				 keynames, &newnames, zone->mctx);
   6463 	INSIST(newdscps == NULL);
   6464 	if (result != ISC_R_SUCCESS) {
   6465 		isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
   6466 		goto unlock;
   6467 	}
   6468 
   6469 	/*
   6470 	 * Everything is ok so attach to the zone.
   6471 	 */
   6472 	zone->curmaster = 0;
   6473 	zone->mastersok = newok;
   6474 	zone->masters = newaddrs;
   6475 	zone->masterdscps = newdscps;
   6476 	zone->masterkeynames = newnames;
   6477 	zone->masterscnt = count;
   6478 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   6479 
   6480 unlock:
   6481 	UNLOCK_ZONE(zone);
   6482 	return (result);
   6483 }
   6484 
   6485 isc_result_t
   6486 dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
   6487 		      dns_name_t **keynames, uint32_t count) {
   6488 	isc_result_t result = ISC_R_SUCCESS;
   6489 	isc_sockaddr_t *newaddrs = NULL;
   6490 	isc_dscp_t *newdscps = NULL;
   6491 	dns_name_t **newkeynames = NULL;
   6492 
   6493 	REQUIRE(DNS_ZONE_VALID(zone));
   6494 	REQUIRE(count == 0 || parentals != NULL);
   6495 	if (keynames != NULL) {
   6496 		REQUIRE(count != 0);
   6497 	}
   6498 
   6499 	LOCK_ZONE(zone);
   6500 
   6501 	clear_serverslist(&zone->parentals, &zone->parentaldscps,
   6502 			  &zone->parentalkeynames, &zone->parentalscnt,
   6503 			  zone->mctx);
   6504 	/*
   6505 	 * If count == 0, don't allocate any space for parentals, or keynames
   6506 	 * so internally, those pointers are NULL if count == 0
   6507 	 */
   6508 	if (count == 0) {
   6509 		goto unlock;
   6510 	}
   6511 
   6512 	/*
   6513 	 * Now set up the parentals and parental key lists
   6514 	 */
   6515 	result = set_serverslist(count, parentals, &newaddrs, NULL, &newdscps,
   6516 				 keynames, &newkeynames, zone->mctx);
   6517 	INSIST(newdscps == NULL);
   6518 	if (result != ISC_R_SUCCESS) {
   6519 		goto unlock;
   6520 	}
   6521 
   6522 	/*
   6523 	 * Everything is ok so attach to the zone.
   6524 	 */
   6525 	zone->parentals = newaddrs;
   6526 	zone->parentaldscps = newdscps;
   6527 	zone->parentalkeynames = newkeynames;
   6528 	zone->parentalscnt = count;
   6529 
   6530 	dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count);
   6531 
   6532 unlock:
   6533 	UNLOCK_ZONE(zone);
   6534 	return (result);
   6535 }
   6536 
   6537 isc_result_t
   6538 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
   6539 	isc_result_t result = ISC_R_SUCCESS;
   6540 
   6541 	REQUIRE(DNS_ZONE_VALID(zone));
   6542 
   6543 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   6544 	if (zone->db == NULL) {
   6545 		result = DNS_R_NOTLOADED;
   6546 	} else {
   6547 		dns_db_attach(zone->db, dpb);
   6548 	}
   6549 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   6550 
   6551 	return (result);
   6552 }
   6553 
   6554 void
   6555 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
   6556 	REQUIRE(DNS_ZONE_VALID(zone));
   6557 	REQUIRE(zone->type == dns_zone_staticstub);
   6558 
   6559 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   6560 	REQUIRE(zone->db == NULL);
   6561 	dns_db_attach(db, &zone->db);
   6562 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   6563 }
   6564 
   6565 /*
   6566  * Coordinates the starting of routine jobs.
   6567  */
   6568 void
   6569 dns_zone_maintenance(dns_zone_t *zone) {
   6570 	const char me[] = "dns_zone_maintenance";
   6571 	isc_time_t now;
   6572 
   6573 	REQUIRE(DNS_ZONE_VALID(zone));
   6574 	ENTER;
   6575 
   6576 	LOCK_ZONE(zone);
   6577 	TIME_NOW(&now);
   6578 	zone_settimer(zone, &now);
   6579 	UNLOCK_ZONE(zone);
   6580 }
   6581 
   6582 static bool
   6583 was_dumping(dns_zone_t *zone) {
   6584 	REQUIRE(LOCKED_ZONE(zone));
   6585 
   6586 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   6587 		return (true);
   6588 	}
   6589 
   6590 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   6591 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   6592 	isc_time_settoepoch(&zone->dumptime);
   6593 	return (false);
   6594 }
   6595 
   6596 /*%
   6597  * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database
   6598  * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'.
   6599  * Only load the public part of a given key if it is not active at timestamp
   6600  * 'now'.  Store the number of keys found in 'nkeys'.
   6601  */
   6602 isc_result_t
   6603 dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   6604 		   isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys,
   6605 		   dst_key_t **keys, unsigned int *nkeys) {
   6606 	isc_result_t result;
   6607 	dns_dbnode_t *node = NULL;
   6608 	const char *directory = dns_zone_getkeydirectory(zone);
   6609 
   6610 	CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
   6611 	memset(keys, 0, sizeof(*keys) * maxkeys);
   6612 
   6613 	dns_zone_lock_keyfiles(zone);
   6614 
   6615 	result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
   6616 					 directory, now, mctx, maxkeys, keys,
   6617 					 nkeys);
   6618 
   6619 	dns_zone_unlock_keyfiles(zone);
   6620 
   6621 	if (result == ISC_R_NOTFOUND) {
   6622 		result = ISC_R_SUCCESS;
   6623 	}
   6624 
   6625 failure:
   6626 
   6627 	if (node != NULL) {
   6628 		dns_db_detachnode(db, &node);
   6629 	}
   6630 	return (result);
   6631 }
   6632 
   6633 /*%
   6634  * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys
   6635  * into 'keys'. Requires KASP to be locked.
   6636  */
   6637 isc_result_t
   6638 dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   6639 		       isc_stdtime_t now, dns_dnsseckeylist_t *keys) {
   6640 	isc_result_t result;
   6641 	const char *dir = dns_zone_getkeydirectory(zone);
   6642 	dns_dbnode_t *node = NULL;
   6643 	dns_dnsseckey_t *key, *key_next;
   6644 	dns_dnsseckeylist_t dnskeys;
   6645 	dns_name_t *origin = dns_zone_getorigin(zone);
   6646 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   6647 	dns_rdataset_t keyset;
   6648 
   6649 	REQUIRE(DNS_ZONE_VALID(zone));
   6650 	REQUIRE(kasp != NULL);
   6651 
   6652 	ISC_LIST_INIT(dnskeys);
   6653 
   6654 	dns_rdataset_init(&keyset);
   6655 
   6656 	CHECK(dns_db_findnode(db, origin, false, &node));
   6657 
   6658 	/* Get keys from private key files. */
   6659 	dns_zone_lock_keyfiles(zone);
   6660 	result = dns_dnssec_findmatchingkeys(origin, dir, now,
   6661 					     dns_zone_getmctx(zone), keys);
   6662 	dns_zone_unlock_keyfiles(zone);
   6663 
   6664 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   6665 		goto failure;
   6666 	}
   6667 
   6668 	/* Get public keys (dnskeys). */
   6669 	dns_rdataset_init(&keyset);
   6670 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   6671 				     dns_rdatatype_none, 0, &keyset, NULL);
   6672 	if (result == ISC_R_SUCCESS) {
   6673 		CHECK(dns_dnssec_keylistfromrdataset(
   6674 			origin, dir, dns_zone_getmctx(zone), &keyset, NULL,
   6675 			NULL, false, false, &dnskeys));
   6676 	} else if (result != ISC_R_NOTFOUND) {
   6677 		CHECK(result);
   6678 	}
   6679 
   6680 	/* Add new 'dnskeys' to 'keys'. */
   6681 	for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL;
   6682 	     k1 = key_next)
   6683 	{
   6684 		dns_dnsseckey_t *k2 = NULL;
   6685 		key_next = ISC_LIST_NEXT(k1, link);
   6686 
   6687 		for (k2 = ISC_LIST_HEAD(*keys); k2 != NULL;
   6688 		     k2 = ISC_LIST_NEXT(k2, link))
   6689 		{
   6690 			if (dst_key_compare(k1->key, k2->key)) {
   6691 				break;
   6692 			}
   6693 		}
   6694 		/* No match found, add the new key. */
   6695 		if (k2 == NULL) {
   6696 			ISC_LIST_UNLINK(dnskeys, k1, link);
   6697 			ISC_LIST_APPEND(*keys, k1, link);
   6698 		}
   6699 	}
   6700 
   6701 failure:
   6702 	if (dns_rdataset_isassociated(&keyset)) {
   6703 		dns_rdataset_disassociate(&keyset);
   6704 	}
   6705 	if (node != NULL) {
   6706 		dns_db_detachnode(db, &node);
   6707 	}
   6708 	while (!ISC_LIST_EMPTY(dnskeys)) {
   6709 		key = ISC_LIST_HEAD(dnskeys);
   6710 		ISC_LIST_UNLINK(dnskeys, key, link);
   6711 		dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key);
   6712 	}
   6713 	return (result);
   6714 }
   6715 
   6716 static isc_result_t
   6717 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff,
   6718 	dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) {
   6719 	isc_result_t result;
   6720 
   6721 	if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) {
   6722 		return (ISC_R_SUCCESS);
   6723 	}
   6724 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
   6725 			       name, ttl, rdata);
   6726 	if (result != ISC_R_SUCCESS) {
   6727 		return (result);
   6728 	}
   6729 	rdata->flags |= DNS_RDATA_OFFLINE;
   6730 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
   6731 			       name, ttl, rdata);
   6732 	zonediff->offline = true;
   6733 	return (result);
   6734 }
   6735 
   6736 static void
   6737 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when,
   6738 		       isc_stdtime_t now) {
   6739 	unsigned int delta;
   6740 	char timebuf[80];
   6741 
   6742 	LOCK_ZONE(zone);
   6743 	zone->key_expiry = when;
   6744 	if (when <= now) {
   6745 		dns_zone_log(zone, ISC_LOG_ERROR,
   6746 			     "DNSKEY RRSIG(s) have expired");
   6747 		isc_time_settoepoch(&zone->keywarntime);
   6748 	} else if (when < now + 7 * 24 * 3600) {
   6749 		isc_time_t t;
   6750 		isc_time_set(&t, when, 0);
   6751 		isc_time_formattimestamp(&t, timebuf, 80);
   6752 		dns_zone_log(zone, ISC_LOG_WARNING,
   6753 			     "DNSKEY RRSIG(s) will expire within 7 days: %s",
   6754 			     timebuf);
   6755 		delta = when - now;
   6756 		delta--;	    /* loop prevention */
   6757 		delta /= 24 * 3600; /* to whole days */
   6758 		delta *= 24 * 3600; /* to seconds */
   6759 		isc_time_set(&zone->keywarntime, when - delta, 0);
   6760 	} else {
   6761 		isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
   6762 		isc_time_formattimestamp(&zone->keywarntime, timebuf, 80);
   6763 		dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s",
   6764 			     timebuf);
   6765 	}
   6766 	UNLOCK_ZONE(zone);
   6767 }
   6768 
   6769 /*
   6770  * Helper function to del_sigs(). We don't want to delete RRSIGs that
   6771  * have no new key.
   6772  */
   6773 static bool
   6774 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
   6775 	  bool kasp, bool *warn) {
   6776 	unsigned int i = 0;
   6777 	isc_result_t ret;
   6778 	bool have_ksk = false, have_zsk = false;
   6779 	bool have_pksk = false, have_pzsk = false;
   6780 
   6781 	for (i = 0; i < nkeys; i++) {
   6782 		bool ksk, zsk;
   6783 
   6784 		if (have_pksk && have_ksk && have_pzsk && have_zsk) {
   6785 			break;
   6786 		}
   6787 
   6788 		if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) {
   6789 			continue;
   6790 		}
   6791 
   6792 		ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   6793 		if (ret != ISC_R_SUCCESS) {
   6794 			ksk = KSK(keys[i]);
   6795 		}
   6796 		ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   6797 		if (ret != ISC_R_SUCCESS) {
   6798 			zsk = !KSK(keys[i]);
   6799 		}
   6800 
   6801 		if (ksk) {
   6802 			have_ksk = true;
   6803 			if (dst_key_isprivate(keys[i])) {
   6804 				have_pksk = true;
   6805 			}
   6806 		}
   6807 		if (zsk) {
   6808 			have_zsk = true;
   6809 			if (dst_key_isprivate(keys[i])) {
   6810 				have_pzsk = true;
   6811 			}
   6812 		}
   6813 	}
   6814 
   6815 	if (have_zsk && have_ksk && !have_pzsk) {
   6816 		*warn = true;
   6817 	}
   6818 
   6819 	if (have_pksk && have_pzsk) {
   6820 		return (true);
   6821 	}
   6822 
   6823 	/*
   6824 	 * Deleting the SOA RRSIG is always okay.
   6825 	 */
   6826 	if (rrsig_ptr->covered == dns_rdatatype_soa) {
   6827 		return (true);
   6828 	}
   6829 
   6830 	/*
   6831 	 * It's okay to delete a signature if there is an active key with the
   6832 	 * same algorithm to replace it, unless that violates the DNSSEC
   6833 	 * policy.
   6834 	 */
   6835 	if (have_pksk || have_pzsk) {
   6836 		if (kasp && have_pzsk) {
   6837 			return (true);
   6838 		}
   6839 		return (!kasp);
   6840 	}
   6841 
   6842 	/*
   6843 	 * Failing that, it is *not* okay to delete a signature
   6844 	 * if the associated public key is still in the DNSKEY RRset
   6845 	 */
   6846 	for (i = 0; i < nkeys; i++) {
   6847 		if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
   6848 		    (rrsig_ptr->keyid == dst_key_id(keys[i])))
   6849 		{
   6850 			return (false);
   6851 		}
   6852 	}
   6853 
   6854 	/*
   6855 	 * But if the key is gone, then go ahead.
   6856 	 */
   6857 	return (true);
   6858 }
   6859 
   6860 /*
   6861  * Delete expired RRsigs and any RRsigs we are about to re-sign.
   6862  * See also update.c:del_keysigs().
   6863  */
   6864 static isc_result_t
   6865 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   6866 	 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys,
   6867 	 unsigned int nkeys, isc_stdtime_t now, bool incremental) {
   6868 	isc_result_t result;
   6869 	dns_dbnode_t *node = NULL;
   6870 	dns_rdataset_t rdataset;
   6871 	unsigned int i;
   6872 	dns_rdata_rrsig_t rrsig;
   6873 	bool kasp = (dns_zone_getkasp(zone) != NULL);
   6874 	bool found;
   6875 	int64_t timewarn = 0, timemaybe = 0;
   6876 
   6877 	dns_rdataset_init(&rdataset);
   6878 
   6879 	if (type == dns_rdatatype_nsec3) {
   6880 		result = dns_db_findnsec3node(db, name, false, &node);
   6881 	} else {
   6882 		result = dns_db_findnode(db, name, false, &node);
   6883 	}
   6884 	if (result == ISC_R_NOTFOUND) {
   6885 		return (ISC_R_SUCCESS);
   6886 	}
   6887 	if (result != ISC_R_SUCCESS) {
   6888 		goto failure;
   6889 	}
   6890 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
   6891 				     (isc_stdtime_t)0, &rdataset, NULL);
   6892 	dns_db_detachnode(db, &node);
   6893 
   6894 	if (result == ISC_R_NOTFOUND) {
   6895 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6896 		return (ISC_R_SUCCESS);
   6897 	}
   6898 	if (result != ISC_R_SUCCESS) {
   6899 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6900 		goto failure;
   6901 	}
   6902 
   6903 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   6904 	     result = dns_rdataset_next(&rdataset))
   6905 	{
   6906 		dns_rdata_t rdata = DNS_RDATA_INIT;
   6907 
   6908 		dns_rdataset_current(&rdataset, &rdata);
   6909 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   6910 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6911 
   6912 		if (type != dns_rdatatype_dnskey && type != dns_rdatatype_cds &&
   6913 		    type != dns_rdatatype_cdnskey)
   6914 		{
   6915 			bool warn = false, deleted = false;
   6916 			if (delsig_ok(&rrsig, keys, nkeys, kasp, &warn)) {
   6917 				result = update_one_rr(db, ver, zonediff->diff,
   6918 						       DNS_DIFFOP_DELRESIGN,
   6919 						       name, rdataset.ttl,
   6920 						       &rdata);
   6921 				if (result != ISC_R_SUCCESS) {
   6922 					break;
   6923 				}
   6924 				deleted = true;
   6925 			}
   6926 			if (warn && !deleted) {
   6927 				/*
   6928 				 * At this point, we've got an RRSIG,
   6929 				 * which is signed by an inactive key.
   6930 				 * An administrator needs to provide a new
   6931 				 * key/alg, but until that time, we want to
   6932 				 * keep the old RRSIG.  Marking the key as
   6933 				 * offline will prevent us spinning waiting
   6934 				 * for the private part.
   6935 				 */
   6936 				if (incremental) {
   6937 					result = offline(db, ver, zonediff,
   6938 							 name, rdataset.ttl,
   6939 							 &rdata);
   6940 					if (result != ISC_R_SUCCESS) {
   6941 						break;
   6942 					}
   6943 				}
   6944 
   6945 				/*
   6946 				 * Log the key id and algorithm of
   6947 				 * the inactive key with no replacement
   6948 				 */
   6949 				if (zone->log_key_expired_timer <= now) {
   6950 					char origin[DNS_NAME_FORMATSIZE];
   6951 					char algbuf[DNS_NAME_FORMATSIZE];
   6952 					dns_name_format(&zone->origin, origin,
   6953 							sizeof(origin));
   6954 					dns_secalg_format(rrsig.algorithm,
   6955 							  algbuf,
   6956 							  sizeof(algbuf));
   6957 					dns_zone_log(zone, ISC_LOG_WARNING,
   6958 						     "Key %s/%s/%d "
   6959 						     "missing or inactive "
   6960 						     "and has no replacement: "
   6961 						     "retaining signatures.",
   6962 						     origin, algbuf,
   6963 						     rrsig.keyid);
   6964 					zone->log_key_expired_timer = now +
   6965 								      3600;
   6966 				}
   6967 			}
   6968 			continue;
   6969 		}
   6970 
   6971 		/*
   6972 		 * KSK RRSIGs requires special processing.
   6973 		 */
   6974 		found = false;
   6975 		for (i = 0; i < nkeys; i++) {
   6976 			if (rrsig.algorithm == dst_key_alg(keys[i]) &&
   6977 			    rrsig.keyid == dst_key_id(keys[i]))
   6978 			{
   6979 				found = true;
   6980 				/*
   6981 				 * Mark offline DNSKEY.
   6982 				 * We want the earliest offline expire time
   6983 				 * iff there is a new offline signature.
   6984 				 */
   6985 				if (!dst_key_inactive(keys[i]) &&
   6986 				    !dst_key_isprivate(keys[i]))
   6987 				{
   6988 					int64_t timeexpire = dns_time64_from32(
   6989 						rrsig.timeexpire);
   6990 					if (timewarn != 0 &&
   6991 					    timewarn > timeexpire)
   6992 					{
   6993 						timewarn = timeexpire;
   6994 					}
   6995 					if (rdata.flags & DNS_RDATA_OFFLINE) {
   6996 						if (timemaybe == 0 ||
   6997 						    timemaybe > timeexpire)
   6998 						{
   6999 							timemaybe = timeexpire;
   7000 						}
   7001 						break;
   7002 					}
   7003 					if (timewarn == 0) {
   7004 						timewarn = timemaybe;
   7005 					}
   7006 					if (timewarn == 0 ||
   7007 					    timewarn > timeexpire)
   7008 					{
   7009 						timewarn = timeexpire;
   7010 					}
   7011 					result = offline(db, ver, zonediff,
   7012 							 name, rdataset.ttl,
   7013 							 &rdata);
   7014 					break;
   7015 				}
   7016 				result = update_one_rr(db, ver, zonediff->diff,
   7017 						       DNS_DIFFOP_DELRESIGN,
   7018 						       name, rdataset.ttl,
   7019 						       &rdata);
   7020 				break;
   7021 			}
   7022 		}
   7023 
   7024 		/*
   7025 		 * If there is not a matching DNSKEY then
   7026 		 * delete the RRSIG.
   7027 		 */
   7028 		if (!found) {
   7029 			result = update_one_rr(db, ver, zonediff->diff,
   7030 					       DNS_DIFFOP_DELRESIGN, name,
   7031 					       rdataset.ttl, &rdata);
   7032 		}
   7033 		if (result != ISC_R_SUCCESS) {
   7034 			break;
   7035 		}
   7036 	}
   7037 
   7038 	dns_rdataset_disassociate(&rdataset);
   7039 	if (result == ISC_R_NOMORE) {
   7040 		result = ISC_R_SUCCESS;
   7041 	}
   7042 	if (timewarn > 0) {
   7043 		isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
   7044 		if (timewarn == stdwarn) {
   7045 			set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
   7046 					       now);
   7047 		} else {
   7048 			dns_zone_log(zone, ISC_LOG_ERROR,
   7049 				     "key expiry warning time out of range");
   7050 		}
   7051 	}
   7052 failure:
   7053 	if (node != NULL) {
   7054 		dns_db_detachnode(db, &node);
   7055 	}
   7056 	return (result);
   7057 }
   7058 
   7059 static isc_result_t
   7060 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone,
   7061 	 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
   7062 	 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
   7063 	 isc_stdtime_t expire, bool check_ksk, bool keyset_kskonly) {
   7064 	isc_result_t result;
   7065 	dns_dbnode_t *node = NULL;
   7066 	dns_stats_t *dnssecsignstats;
   7067 	dns_rdataset_t rdataset;
   7068 	dns_rdata_t sig_rdata = DNS_RDATA_INIT;
   7069 	unsigned char data[1024]; /* XXX */
   7070 	isc_buffer_t buffer;
   7071 	unsigned int i, j;
   7072 	bool use_kasp = false;
   7073 
   7074 	if (dns_zone_getkasp(zone) != NULL) {
   7075 		check_ksk = false;
   7076 		keyset_kskonly = true;
   7077 		use_kasp = true;
   7078 	}
   7079 
   7080 	dns_rdataset_init(&rdataset);
   7081 	isc_buffer_init(&buffer, data, sizeof(data));
   7082 
   7083 	if (type == dns_rdatatype_nsec3) {
   7084 		result = dns_db_findnsec3node(db, name, false, &node);
   7085 	} else {
   7086 		result = dns_db_findnode(db, name, false, &node);
   7087 	}
   7088 	if (result == ISC_R_NOTFOUND) {
   7089 		return (ISC_R_SUCCESS);
   7090 	}
   7091 	if (result != ISC_R_SUCCESS) {
   7092 		goto failure;
   7093 	}
   7094 	result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0,
   7095 				     &rdataset, NULL);
   7096 	dns_db_detachnode(db, &node);
   7097 	if (result == ISC_R_NOTFOUND) {
   7098 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7099 		return (ISC_R_SUCCESS);
   7100 	}
   7101 	if (result != ISC_R_SUCCESS) {
   7102 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7103 		goto failure;
   7104 	}
   7105 
   7106 	for (i = 0; i < nkeys; i++) {
   7107 		bool both = false;
   7108 
   7109 		/* Don't add signatures for offline or inactive keys */
   7110 		if (!dst_key_isprivate(keys[i])) {
   7111 			continue;
   7112 		}
   7113 		if (dst_key_inactive(keys[i])) {
   7114 			continue;
   7115 		}
   7116 
   7117 		if (check_ksk && !REVOKE(keys[i])) {
   7118 			bool have_ksk, have_nonksk;
   7119 			if (KSK(keys[i])) {
   7120 				have_ksk = true;
   7121 				have_nonksk = false;
   7122 			} else {
   7123 				have_ksk = false;
   7124 				have_nonksk = true;
   7125 			}
   7126 
   7127 			for (j = 0; j < nkeys; j++) {
   7128 				if (j == i || ALG(keys[i]) != ALG(keys[j])) {
   7129 					continue;
   7130 				}
   7131 
   7132 				/*
   7133 				 * Don't consider inactive keys, however
   7134 				 * the KSK may be temporary offline, so do
   7135 				 * consider keys which private key files are
   7136 				 * unavailable.
   7137 				 */
   7138 				if (dst_key_inactive(keys[j])) {
   7139 					continue;
   7140 				}
   7141 
   7142 				if (REVOKE(keys[j])) {
   7143 					continue;
   7144 				}
   7145 				if (KSK(keys[j])) {
   7146 					have_ksk = true;
   7147 				} else if (dst_key_isprivate(keys[j])) {
   7148 					have_nonksk = true;
   7149 				}
   7150 				both = have_ksk && have_nonksk;
   7151 				if (both) {
   7152 					break;
   7153 				}
   7154 			}
   7155 		}
   7156 		if (use_kasp) {
   7157 			/*
   7158 			 * A dnssec-policy is found. Check what RRsets this
   7159 			 * key should sign.
   7160 			 */
   7161 			isc_result_t kresult;
   7162 			isc_stdtime_t when;
   7163 			bool ksk = false;
   7164 			bool zsk = false;
   7165 			bool have_ksk = false;
   7166 			bool have_zsk = false;
   7167 
   7168 			kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   7169 			if (kresult != ISC_R_SUCCESS) {
   7170 				if (KSK(keys[i])) {
   7171 					ksk = true;
   7172 				}
   7173 			}
   7174 			kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   7175 			if (kresult != ISC_R_SUCCESS) {
   7176 				if (!KSK(keys[i])) {
   7177 					zsk = true;
   7178 				}
   7179 			}
   7180 
   7181 			have_ksk = ksk;
   7182 			have_zsk = zsk;
   7183 			both = have_ksk && have_zsk;
   7184 
   7185 			for (j = 0; j < nkeys; j++) {
   7186 				if (both) {
   7187 					break;
   7188 				}
   7189 
   7190 				if (j == i || ALG(keys[i]) != ALG(keys[j])) {
   7191 					continue;
   7192 				}
   7193 
   7194 				/*
   7195 				 * Don't consider inactive keys or offline keys.
   7196 				 */
   7197 				if (!dst_key_isprivate(keys[j])) {
   7198 					continue;
   7199 				}
   7200 				if (dst_key_inactive(keys[j])) {
   7201 					continue;
   7202 				}
   7203 
   7204 				if (REVOKE(keys[j])) {
   7205 					continue;
   7206 				}
   7207 
   7208 				if (!have_ksk) {
   7209 					kresult = dst_key_getbool(keys[j],
   7210 								  DST_BOOL_KSK,
   7211 								  &have_ksk);
   7212 					if (kresult != ISC_R_SUCCESS) {
   7213 						if (KSK(keys[j])) {
   7214 							have_ksk = true;
   7215 						}
   7216 					}
   7217 				}
   7218 				if (!have_zsk) {
   7219 					kresult = dst_key_getbool(keys[j],
   7220 								  DST_BOOL_ZSK,
   7221 								  &have_zsk);
   7222 					if (kresult != ISC_R_SUCCESS) {
   7223 						if (!KSK(keys[j])) {
   7224 							have_zsk = true;
   7225 						}
   7226 					}
   7227 				}
   7228 				both = have_ksk && have_zsk;
   7229 			}
   7230 
   7231 			if (type == dns_rdatatype_dnskey ||
   7232 			    type == dns_rdatatype_cdnskey ||
   7233 			    type == dns_rdatatype_cds)
   7234 			{
   7235 				/*
   7236 				 * DNSKEY RRset is signed with KSK.
   7237 				 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1).
   7238 				 */
   7239 				if (!ksk) {
   7240 					continue;
   7241 				}
   7242 			} else if (!zsk) {
   7243 				/*
   7244 				 * Other RRsets are signed with ZSK.
   7245 				 */
   7246 				if (type != dns_rdatatype_soa &&
   7247 				    type != zone->privatetype)
   7248 				{
   7249 					continue;
   7250 				}
   7251 				if (have_zsk) {
   7252 					continue;
   7253 				}
   7254 			} else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK,
   7255 						       inception, &when))
   7256 			{
   7257 				/*
   7258 				 * This key is not active for zone-signing.
   7259 				 */
   7260 				continue;
   7261 			}
   7262 
   7263 			/*
   7264 			 * If this key is revoked, it may only sign the
   7265 			 * DNSKEY RRset.
   7266 			 */
   7267 			if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   7268 				continue;
   7269 			}
   7270 		} else if (both) {
   7271 			/*
   7272 			 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
   7273 			 */
   7274 			if (type == dns_rdatatype_dnskey ||
   7275 			    type == dns_rdatatype_cdnskey ||
   7276 			    type == dns_rdatatype_cds)
   7277 			{
   7278 				if (!KSK(keys[i]) && keyset_kskonly) {
   7279 					continue;
   7280 				}
   7281 			} else if (KSK(keys[i])) {
   7282 				continue;
   7283 			}
   7284 		} else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   7285 			continue;
   7286 		}
   7287 
   7288 		/* Calculate the signature, creating a RRSIG RDATA. */
   7289 		isc_buffer_clear(&buffer);
   7290 		CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception,
   7291 				      &expire, mctx, &buffer, &sig_rdata));
   7292 
   7293 		/* Update the database and journal with the RRSIG. */
   7294 		/* XXX inefficient - will cause dataset merging */
   7295 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name,
   7296 				    rdataset.ttl, &sig_rdata));
   7297 		dns_rdata_reset(&sig_rdata);
   7298 		isc_buffer_init(&buffer, data, sizeof(data));
   7299 
   7300 		/* Update DNSSEC sign statistics. */
   7301 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7302 		if (dnssecsignstats != NULL) {
   7303 			/* Generated a new signature. */
   7304 			dns_dnssecsignstats_increment(dnssecsignstats,
   7305 						      ID(keys[i]),
   7306 						      (uint8_t)ALG(keys[i]),
   7307 						      dns_dnssecsignstats_sign);
   7308 			/* This is a refresh. */
   7309 			dns_dnssecsignstats_increment(
   7310 				dnssecsignstats, ID(keys[i]),
   7311 				(uint8_t)ALG(keys[i]),
   7312 				dns_dnssecsignstats_refresh);
   7313 		}
   7314 	}
   7315 
   7316 failure:
   7317 	if (dns_rdataset_isassociated(&rdataset)) {
   7318 		dns_rdataset_disassociate(&rdataset);
   7319 	}
   7320 	if (node != NULL) {
   7321 		dns_db_detachnode(db, &node);
   7322 	}
   7323 	return (result);
   7324 }
   7325 
   7326 static void
   7327 zone_resigninc(dns_zone_t *zone) {
   7328 	const char *me = "zone_resigninc";
   7329 	dns_db_t *db = NULL;
   7330 	dns_dbversion_t *version = NULL;
   7331 	dns_diff_t _sig_diff;
   7332 	dns__zonediff_t zonediff;
   7333 	dns_fixedname_t fixed;
   7334 	dns_name_t *name;
   7335 	dns_rdataset_t rdataset;
   7336 	dns_rdatatype_t covers;
   7337 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   7338 	bool check_ksk, keyset_kskonly = false;
   7339 	isc_result_t result;
   7340 	isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop;
   7341 	uint32_t sigvalidityinterval, expiryinterval;
   7342 	unsigned int i;
   7343 	unsigned int nkeys = 0;
   7344 	unsigned int resign;
   7345 
   7346 	ENTER;
   7347 
   7348 	dns_rdataset_init(&rdataset);
   7349 	dns_diff_init(zone->mctx, &_sig_diff);
   7350 	zonediff_init(&zonediff, &_sig_diff);
   7351 
   7352 	/*
   7353 	 * Zone is frozen or automatic resigning is disabled.
   7354 	 * Pause for 5 minutes.
   7355 	 */
   7356 	if (zone->update_disabled ||
   7357 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
   7358 	{
   7359 		result = ISC_R_FAILURE;
   7360 		goto failure;
   7361 	}
   7362 
   7363 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   7364 	dns_db_attach(zone->db, &db);
   7365 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   7366 
   7367 	result = dns_db_newversion(db, &version);
   7368 	if (result != ISC_R_SUCCESS) {
   7369 		dns_zone_log(zone, ISC_LOG_ERROR,
   7370 			     "zone_resigninc:dns_db_newversion -> %s",
   7371 			     dns_result_totext(result));
   7372 		goto failure;
   7373 	}
   7374 
   7375 	isc_stdtime_get(&now);
   7376 
   7377 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   7378 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   7379 	if (result != ISC_R_SUCCESS) {
   7380 		dns_zone_log(zone, ISC_LOG_ERROR,
   7381 			     "zone_resigninc:dns__zone_findkeys -> %s",
   7382 			     dns_result_totext(result));
   7383 		goto failure;
   7384 	}
   7385 
   7386 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   7387 	inception = now - 3600; /* Allow for clock skew. */
   7388 	soaexpire = now + sigvalidityinterval;
   7389 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   7390 	if (expiryinterval > sigvalidityinterval) {
   7391 		expiryinterval = sigvalidityinterval;
   7392 	} else {
   7393 		expiryinterval = sigvalidityinterval - expiryinterval;
   7394 	}
   7395 
   7396 	/*
   7397 	 * Spread out signatures over time if they happen to be
   7398 	 * clumped.  We don't do this for each add_sigs() call as
   7399 	 * we still want some clustering to occur.  In normal operations
   7400 	 * the records should be re-signed as they fall due and they should
   7401 	 * already be spread out.  However if the server is off for a
   7402 	 * period we need to ensure that the clusters don't become
   7403 	 * synchronised by using the full jitter range.
   7404 	 */
   7405 	if (sigvalidityinterval >= 3600U) {
   7406 		uint32_t normaljitter, fulljitter;
   7407 		if (sigvalidityinterval > 7200U) {
   7408 			normaljitter = isc_random_uniform(3600);
   7409 			fulljitter = isc_random_uniform(expiryinterval);
   7410 		} else {
   7411 			normaljitter = fulljitter = isc_random_uniform(1200);
   7412 		}
   7413 		expire = soaexpire - normaljitter - 1;
   7414 		fullexpire = soaexpire - fulljitter - 1;
   7415 	} else {
   7416 		expire = fullexpire = soaexpire - 1;
   7417 	}
   7418 	stop = now + 5;
   7419 
   7420 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   7421 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   7422 
   7423 	name = dns_fixedname_initname(&fixed);
   7424 	result = dns_db_getsigningtime(db, &rdataset, name);
   7425 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   7426 		dns_zone_log(zone, ISC_LOG_ERROR,
   7427 			     "zone_resigninc:dns_db_getsigningtime -> %s",
   7428 			     dns_result_totext(result));
   7429 	}
   7430 
   7431 	i = 0;
   7432 	while (result == ISC_R_SUCCESS) {
   7433 		resign = rdataset.resign -
   7434 			 dns_zone_getsigresigninginterval(zone);
   7435 		covers = rdataset.covers;
   7436 		dns_rdataset_disassociate(&rdataset);
   7437 
   7438 		/*
   7439 		 * Stop if we hit the SOA as that means we have walked the
   7440 		 * entire zone.  The SOA record should always be the most
   7441 		 * recent signature.
   7442 		 */
   7443 		/* XXXMPA increase number of RRsets signed pre call */
   7444 		if ((covers == dns_rdatatype_soa &&
   7445 		     dns_name_equal(name, &zone->origin)) ||
   7446 		    i++ > zone->signatures || resign > stop)
   7447 		{
   7448 			break;
   7449 		}
   7450 
   7451 		result = del_sigs(zone, db, version, name, covers, &zonediff,
   7452 				  zone_keys, nkeys, now, true);
   7453 		if (result != ISC_R_SUCCESS) {
   7454 			dns_zone_log(zone, ISC_LOG_ERROR,
   7455 				     "zone_resigninc:del_sigs -> %s",
   7456 				     dns_result_totext(result));
   7457 			break;
   7458 		}
   7459 
   7460 		/*
   7461 		 * If re-signing is over 5 minutes late use 'fullexpire'
   7462 		 * to redistribute the signature over the complete
   7463 		 * re-signing window, otherwise only add a small amount
   7464 		 * of jitter.
   7465 		 */
   7466 		result = add_sigs(db, version, name, zone, covers,
   7467 				  zonediff.diff, zone_keys, nkeys, zone->mctx,
   7468 				  inception,
   7469 				  resign > (now - 300) ? expire : fullexpire,
   7470 				  check_ksk, keyset_kskonly);
   7471 		if (result != ISC_R_SUCCESS) {
   7472 			dns_zone_log(zone, ISC_LOG_ERROR,
   7473 				     "zone_resigninc:add_sigs -> %s",
   7474 				     dns_result_totext(result));
   7475 			break;
   7476 		}
   7477 		result = dns_db_getsigningtime(db, &rdataset, name);
   7478 		if (nkeys == 0 && result == ISC_R_NOTFOUND) {
   7479 			result = ISC_R_SUCCESS;
   7480 			break;
   7481 		}
   7482 		if (result != ISC_R_SUCCESS) {
   7483 			dns_zone_log(zone, ISC_LOG_ERROR,
   7484 				     "zone_resigninc:dns_db_getsigningtime -> "
   7485 				     "%s",
   7486 				     dns_result_totext(result));
   7487 		}
   7488 	}
   7489 
   7490 	if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) {
   7491 		goto failure;
   7492 	}
   7493 
   7494 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   7495 			  &zonediff, zone_keys, nkeys, now, true);
   7496 	if (result != ISC_R_SUCCESS) {
   7497 		dns_zone_log(zone, ISC_LOG_ERROR,
   7498 			     "zone_resigninc:del_sigs -> %s",
   7499 			     dns_result_totext(result));
   7500 		goto failure;
   7501 	}
   7502 
   7503 	/*
   7504 	 * Did we change anything in the zone?
   7505 	 */
   7506 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   7507 		/*
   7508 		 * Commit the changes if any key has been marked as offline.
   7509 		 */
   7510 		if (zonediff.offline) {
   7511 			dns_db_closeversion(db, &version, true);
   7512 		}
   7513 		goto failure;
   7514 	}
   7515 
   7516 	/* Increment SOA serial if we have made changes */
   7517 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   7518 				   zone->updatemethod);
   7519 	if (result != ISC_R_SUCCESS) {
   7520 		dns_zone_log(zone, ISC_LOG_ERROR,
   7521 			     "zone_resigninc:update_soa_serial -> %s",
   7522 			     dns_result_totext(result));
   7523 		goto failure;
   7524 	}
   7525 
   7526 	/*
   7527 	 * Generate maximum life time signatures so that the above loop
   7528 	 * termination is sensible.
   7529 	 */
   7530 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   7531 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   7532 			  inception, soaexpire, check_ksk, keyset_kskonly);
   7533 	if (result != ISC_R_SUCCESS) {
   7534 		dns_zone_log(zone, ISC_LOG_ERROR,
   7535 			     "zone_resigninc:add_sigs -> %s",
   7536 			     dns_result_totext(result));
   7537 		goto failure;
   7538 	}
   7539 
   7540 	/* Write changes to journal file. */
   7541 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
   7542 
   7543 	/* Everything has succeeded. Commit the changes. */
   7544 	dns_db_closeversion(db, &version, true);
   7545 
   7546 failure:
   7547 	dns_diff_clear(&_sig_diff);
   7548 	for (i = 0; i < nkeys; i++) {
   7549 		dst_key_free(&zone_keys[i]);
   7550 	}
   7551 	if (version != NULL) {
   7552 		dns_db_closeversion(db, &version, false);
   7553 		dns_db_detach(&db);
   7554 	} else if (db != NULL) {
   7555 		dns_db_detach(&db);
   7556 	}
   7557 
   7558 	LOCK_ZONE(zone);
   7559 	if (result == ISC_R_SUCCESS) {
   7560 		set_resigntime(zone);
   7561 		zone_needdump(zone, DNS_DUMP_DELAY);
   7562 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   7563 	} else {
   7564 		/*
   7565 		 * Something failed.  Retry in 5 minutes.
   7566 		 */
   7567 		isc_interval_t ival;
   7568 		isc_interval_set(&ival, 300, 0);
   7569 		isc_time_nowplusinterval(&zone->resigntime, &ival);
   7570 	}
   7571 	UNLOCK_ZONE(zone);
   7572 
   7573 	INSIST(version == NULL);
   7574 }
   7575 
   7576 static isc_result_t
   7577 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
   7578 	    dns_name_t *newname, bool bottom) {
   7579 	isc_result_t result;
   7580 	dns_dbiterator_t *dbit = NULL;
   7581 	dns_rdatasetiter_t *rdsit = NULL;
   7582 	dns_dbnode_t *node = NULL;
   7583 
   7584 	CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
   7585 	CHECK(dns_dbiterator_seek(dbit, oldname));
   7586 	do {
   7587 		result = dns_dbiterator_next(dbit);
   7588 		if (result == ISC_R_NOMORE) {
   7589 			CHECK(dns_dbiterator_first(dbit));
   7590 		}
   7591 		CHECK(dns_dbiterator_current(dbit, &node, newname));
   7592 		if (bottom && dns_name_issubdomain(newname, oldname) &&
   7593 		    !dns_name_equal(newname, oldname))
   7594 		{
   7595 			dns_db_detachnode(db, &node);
   7596 			continue;
   7597 		}
   7598 		/*
   7599 		 * Is this node empty?
   7600 		 */
   7601 		CHECK(dns_db_allrdatasets(db, node, version, 0, 0, &rdsit));
   7602 		result = dns_rdatasetiter_first(rdsit);
   7603 		dns_db_detachnode(db, &node);
   7604 		dns_rdatasetiter_destroy(&rdsit);
   7605 		if (result != ISC_R_NOMORE) {
   7606 			break;
   7607 		}
   7608 	} while (1);
   7609 failure:
   7610 	if (node != NULL) {
   7611 		dns_db_detachnode(db, &node);
   7612 	}
   7613 	if (dbit != NULL) {
   7614 		dns_dbiterator_destroy(&dbit);
   7615 	}
   7616 	return (result);
   7617 }
   7618 
   7619 static bool
   7620 signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   7621 		     dns_dbversion_t *version, dns_rdatatype_t type,
   7622 		     dst_key_t *key) {
   7623 	isc_result_t result;
   7624 	dns_rdataset_t rdataset;
   7625 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7626 	dns_rdata_rrsig_t rrsig;
   7627 	int count = 0;
   7628 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   7629 
   7630 	dns_rdataset_init(&rdataset);
   7631 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
   7632 				     type, 0, &rdataset, NULL);
   7633 	if (result != ISC_R_SUCCESS) {
   7634 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7635 		return (false);
   7636 	}
   7637 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7638 	     result = dns_rdataset_next(&rdataset))
   7639 	{
   7640 		dns_rdataset_current(&rdataset, &rdata);
   7641 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   7642 		INSIST(result == ISC_R_SUCCESS);
   7643 		if (rrsig.algorithm == dst_key_alg(key) &&
   7644 		    rrsig.keyid == dst_key_id(key))
   7645 		{
   7646 			dns_rdataset_disassociate(&rdataset);
   7647 			return (true);
   7648 		}
   7649 		if (rrsig.algorithm == dst_key_alg(key)) {
   7650 			count++;
   7651 		}
   7652 		dns_rdata_reset(&rdata);
   7653 	}
   7654 
   7655 	if (dns_zone_getkasp(zone) != NULL) {
   7656 		dns_kasp_key_t *kkey;
   7657 		int zsk_count = 0;
   7658 		bool approved;
   7659 
   7660 		KASP_LOCK(kasp);
   7661 		for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
   7662 		     kkey = ISC_LIST_NEXT(kkey, link))
   7663 		{
   7664 			if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) {
   7665 				continue;
   7666 			}
   7667 			if (dns_kasp_key_zsk(kkey)) {
   7668 				zsk_count++;
   7669 			}
   7670 		}
   7671 		KASP_UNLOCK(kasp);
   7672 
   7673 		if (type == dns_rdatatype_dnskey ||
   7674 		    type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds)
   7675 		{
   7676 			/*
   7677 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7678 			 * (RFC 7344, section 4.1 specifies that they must
   7679 			 * be signed with a key in the current DS RRset,
   7680 			 * which would only include KSK's.)
   7681 			 */
   7682 			approved = false;
   7683 		} else {
   7684 			approved = (zsk_count == count);
   7685 		}
   7686 
   7687 		dns_rdataset_disassociate(&rdataset);
   7688 		return (approved);
   7689 	}
   7690 
   7691 	dns_rdataset_disassociate(&rdataset);
   7692 	return (false);
   7693 }
   7694 
   7695 static isc_result_t
   7696 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7697 	 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) {
   7698 	dns_fixedname_t fixed;
   7699 	dns_name_t *next;
   7700 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7701 	isc_result_t result;
   7702 	unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
   7703 
   7704 	next = dns_fixedname_initname(&fixed);
   7705 
   7706 	CHECK(next_active(db, version, name, next, bottom));
   7707 	CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata));
   7708 	CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
   7709 			    &rdata));
   7710 failure:
   7711 	return (result);
   7712 }
   7713 
   7714 static isc_result_t
   7715 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node,
   7716 			dns_dbversion_t *version, bool *is_bottom_of_zone) {
   7717 	isc_result_t result;
   7718 	dns_rdatasetiter_t *iterator = NULL;
   7719 	dns_rdataset_t rdataset;
   7720 	bool seen_soa = false, seen_ns = false, seen_dname = false;
   7721 
   7722 	REQUIRE(is_bottom_of_zone != NULL);
   7723 
   7724 	result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator);
   7725 	if (result != ISC_R_SUCCESS) {
   7726 		if (result == ISC_R_NOTFOUND) {
   7727 			result = ISC_R_SUCCESS;
   7728 		}
   7729 		return (result);
   7730 	}
   7731 
   7732 	dns_rdataset_init(&rdataset);
   7733 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7734 	     result = dns_rdatasetiter_next(iterator))
   7735 	{
   7736 		dns_rdatasetiter_current(iterator, &rdataset);
   7737 		switch (rdataset.type) {
   7738 		case dns_rdatatype_soa:
   7739 			seen_soa = true;
   7740 			break;
   7741 		case dns_rdatatype_ns:
   7742 			seen_ns = true;
   7743 			break;
   7744 		case dns_rdatatype_dname:
   7745 			seen_dname = true;
   7746 			break;
   7747 		}
   7748 		dns_rdataset_disassociate(&rdataset);
   7749 	}
   7750 	if (result != ISC_R_NOMORE) {
   7751 		goto failure;
   7752 	}
   7753 	if ((seen_ns && !seen_soa) || seen_dname) {
   7754 		*is_bottom_of_zone = true;
   7755 	}
   7756 	result = ISC_R_SUCCESS;
   7757 
   7758 failure:
   7759 	dns_rdatasetiter_destroy(&iterator);
   7760 
   7761 	return (result);
   7762 }
   7763 
   7764 static isc_result_t
   7765 sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
   7766 	    dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3,
   7767 	    bool build_nsec, dst_key_t *key, isc_stdtime_t inception,
   7768 	    isc_stdtime_t expire, dns_ttl_t nsecttl, bool is_ksk, bool is_zsk,
   7769 	    bool keyset_kskonly, bool is_bottom_of_zone, dns_diff_t *diff,
   7770 	    int32_t *signatures, isc_mem_t *mctx) {
   7771 	isc_result_t result;
   7772 	dns_rdatasetiter_t *iterator = NULL;
   7773 	dns_rdataset_t rdataset;
   7774 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7775 	dns_stats_t *dnssecsignstats;
   7776 
   7777 	isc_buffer_t buffer;
   7778 	unsigned char data[1024];
   7779 	bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds;
   7780 
   7781 	result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator);
   7782 	if (result != ISC_R_SUCCESS) {
   7783 		if (result == ISC_R_NOTFOUND) {
   7784 			result = ISC_R_SUCCESS;
   7785 		}
   7786 		return (result);
   7787 	}
   7788 
   7789 	dns_rdataset_init(&rdataset);
   7790 	isc_buffer_init(&buffer, data, sizeof(data));
   7791 	seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false;
   7792 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7793 	     result = dns_rdatasetiter_next(iterator))
   7794 	{
   7795 		dns_rdatasetiter_current(iterator, &rdataset);
   7796 		if (rdataset.type == dns_rdatatype_soa) {
   7797 			seen_soa = true;
   7798 		} else if (rdataset.type == dns_rdatatype_ns) {
   7799 			seen_ns = true;
   7800 		} else if (rdataset.type == dns_rdatatype_ds) {
   7801 			seen_ds = true;
   7802 		} else if (rdataset.type == dns_rdatatype_nsec) {
   7803 			seen_nsec = true;
   7804 		} else if (rdataset.type == dns_rdatatype_nsec3) {
   7805 			seen_nsec3 = true;
   7806 		}
   7807 		if (rdataset.type != dns_rdatatype_rrsig) {
   7808 			seen_rr = true;
   7809 		}
   7810 		dns_rdataset_disassociate(&rdataset);
   7811 	}
   7812 	if (result != ISC_R_NOMORE) {
   7813 		goto failure;
   7814 	}
   7815 	/*
   7816 	 * Going from insecure to NSEC3.
   7817 	 * Don't generate NSEC3 records for NSEC3 records.
   7818 	 */
   7819 	if (build_nsec3 && !seen_nsec3 && seen_rr) {
   7820 		bool unsecure = !seen_ds && seen_ns && !seen_soa;
   7821 		CHECK(dns_nsec3_addnsec3s(db, version, name, nsecttl, unsecure,
   7822 					  diff));
   7823 		(*signatures)--;
   7824 	}
   7825 	/*
   7826 	 * Going from insecure to NSEC.
   7827 	 * Don't generate NSEC records for NSEC3 records.
   7828 	 */
   7829 	if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
   7830 		/*
   7831 		 * Build a NSEC record except at the origin.
   7832 		 */
   7833 		if (!dns_name_equal(name, dns_db_origin(db))) {
   7834 			CHECK(add_nsec(db, version, name, node, nsecttl,
   7835 				       is_bottom_of_zone, diff));
   7836 			/* Count a NSEC generation as a signature generation. */
   7837 			(*signatures)--;
   7838 		}
   7839 	}
   7840 	result = dns_rdatasetiter_first(iterator);
   7841 	while (result == ISC_R_SUCCESS) {
   7842 		isc_stdtime_t when;
   7843 
   7844 		dns_rdatasetiter_current(iterator, &rdataset);
   7845 		if (rdataset.type == dns_rdatatype_soa ||
   7846 		    rdataset.type == dns_rdatatype_rrsig)
   7847 		{
   7848 			goto next_rdataset;
   7849 		}
   7850 		if (rdataset.type == dns_rdatatype_dnskey ||
   7851 		    rdataset.type == dns_rdatatype_cdnskey ||
   7852 		    rdataset.type == dns_rdatatype_cds)
   7853 		{
   7854 			/*
   7855 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7856 			 * (RFC 7344, section 4.1 specifies that they must
   7857 			 * be signed with a key in the current DS RRset,
   7858 			 * which would only include KSK's.)
   7859 			 */
   7860 			if (!is_ksk && keyset_kskonly) {
   7861 				goto next_rdataset;
   7862 			}
   7863 		} else if (!is_zsk) {
   7864 			goto next_rdataset;
   7865 		} else if (is_zsk && !dst_key_is_signing(key, DST_BOOL_ZSK,
   7866 							 inception, &when))
   7867 		{
   7868 			/* Only applies to dnssec-policy. */
   7869 			if (dns_zone_getkasp(zone) != NULL) {
   7870 				goto next_rdataset;
   7871 			}
   7872 		}
   7873 
   7874 		if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds &&
   7875 		    rdataset.type != dns_rdatatype_nsec)
   7876 		{
   7877 			goto next_rdataset;
   7878 		}
   7879 		if (signed_with_good_key(zone, db, node, version, rdataset.type,
   7880 					 key))
   7881 		{
   7882 			goto next_rdataset;
   7883 		}
   7884 
   7885 		/* Calculate the signature, creating a RRSIG RDATA. */
   7886 		isc_buffer_clear(&buffer);
   7887 		CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, &expire,
   7888 				      mctx, &buffer, &rdata));
   7889 		/* Update the database and journal with the RRSIG. */
   7890 		/* XXX inefficient - will cause dataset merging */
   7891 		CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
   7892 				    name, rdataset.ttl, &rdata));
   7893 		dns_rdata_reset(&rdata);
   7894 
   7895 		/* Update DNSSEC sign statistics. */
   7896 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7897 		if (dnssecsignstats != NULL) {
   7898 			/* Generated a new signature. */
   7899 			dns_dnssecsignstats_increment(dnssecsignstats, ID(key),
   7900 						      ALG(key),
   7901 						      dns_dnssecsignstats_sign);
   7902 			/* This is a refresh. */
   7903 			dns_dnssecsignstats_increment(
   7904 				dnssecsignstats, ID(key), ALG(key),
   7905 				dns_dnssecsignstats_refresh);
   7906 		}
   7907 
   7908 		(*signatures)--;
   7909 	next_rdataset:
   7910 		dns_rdataset_disassociate(&rdataset);
   7911 		result = dns_rdatasetiter_next(iterator);
   7912 	}
   7913 	if (result == ISC_R_NOMORE) {
   7914 		result = ISC_R_SUCCESS;
   7915 	}
   7916 failure:
   7917 	if (dns_rdataset_isassociated(&rdataset)) {
   7918 		dns_rdataset_disassociate(&rdataset);
   7919 	}
   7920 	if (iterator != NULL) {
   7921 		dns_rdatasetiter_destroy(&iterator);
   7922 	}
   7923 	return (result);
   7924 }
   7925 
   7926 /*
   7927  * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
   7928  */
   7929 static isc_result_t
   7930 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7931 	     dns_ttl_t nsecttl, bool update_only, dns_diff_t *diff) {
   7932 	isc_result_t result;
   7933 	dns_rdataset_t rdataset;
   7934 	dns_dbnode_t *node = NULL;
   7935 
   7936 	CHECK(dns_db_getoriginnode(db, &node));
   7937 	if (update_only) {
   7938 		dns_rdataset_init(&rdataset);
   7939 		result = dns_db_findrdataset(
   7940 			db, node, version, dns_rdatatype_nsec,
   7941 			dns_rdatatype_none, 0, &rdataset, NULL);
   7942 		if (dns_rdataset_isassociated(&rdataset)) {
   7943 			dns_rdataset_disassociate(&rdataset);
   7944 		}
   7945 		if (result == ISC_R_NOTFOUND) {
   7946 			goto success;
   7947 		}
   7948 		if (result != ISC_R_SUCCESS) {
   7949 			goto failure;
   7950 		}
   7951 	}
   7952 	CHECK(delete_nsec(db, version, node, name, diff));
   7953 	CHECK(add_nsec(db, version, name, node, nsecttl, false, diff));
   7954 success:
   7955 	result = ISC_R_SUCCESS;
   7956 failure:
   7957 	if (node != NULL) {
   7958 		dns_db_detachnode(db, &node);
   7959 	}
   7960 	return (result);
   7961 }
   7962 
   7963 static isc_result_t
   7964 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
   7965 		  dns_dbversion_t *version, bool build_nsec3, dns_ttl_t nsecttl,
   7966 		  dns_diff_t *diff) {
   7967 	isc_result_t result;
   7968 	dns_dbnode_t *node = NULL;
   7969 	dns_rdataset_t rdataset;
   7970 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7971 	unsigned char data[5];
   7972 	bool seen_done = false;
   7973 	bool have_rr = false;
   7974 
   7975 	dns_rdataset_init(&rdataset);
   7976 	result = dns_db_getoriginnode(signing->db, &node);
   7977 	if (result != ISC_R_SUCCESS) {
   7978 		goto failure;
   7979 	}
   7980 
   7981 	result = dns_db_findrdataset(signing->db, node, version,
   7982 				     zone->privatetype, dns_rdatatype_none, 0,
   7983 				     &rdataset, NULL);
   7984 	if (result == ISC_R_NOTFOUND) {
   7985 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7986 		result = ISC_R_SUCCESS;
   7987 		goto failure;
   7988 	}
   7989 	if (result != ISC_R_SUCCESS) {
   7990 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7991 		goto failure;
   7992 	}
   7993 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7994 	     result = dns_rdataset_next(&rdataset))
   7995 	{
   7996 		dns_rdataset_current(&rdataset, &rdata);
   7997 		/*
   7998 		 * If we don't match the algorithm or keyid skip the record.
   7999 		 */
   8000 		if (rdata.length != 5 || rdata.data[0] != signing->algorithm ||
   8001 		    rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
   8002 		    rdata.data[2] != (signing->keyid & 0xff))
   8003 		{
   8004 			have_rr = true;
   8005 			dns_rdata_reset(&rdata);
   8006 			continue;
   8007 		}
   8008 		/*
   8009 		 * We have a match.  If we were signing (!signing->deleteit)
   8010 		 * and we already have a record indicating that we have
   8011 		 * finished signing (rdata.data[4] != 0) then keep it.
   8012 		 * Otherwise it needs to be deleted as we have removed all
   8013 		 * the signatures (signing->deleteit), so any record indicating
   8014 		 * completion is now out of date, or we have finished signing
   8015 		 * with the new record so we no longer need to remember that
   8016 		 * we need to sign the zone with the matching key across a
   8017 		 * nameserver re-start.
   8018 		 */
   8019 		if (!signing->deleteit && rdata.data[4] != 0) {
   8020 			seen_done = true;
   8021 			have_rr = true;
   8022 		} else {
   8023 			CHECK(update_one_rr(signing->db, version, diff,
   8024 					    DNS_DIFFOP_DEL, &zone->origin,
   8025 					    rdataset.ttl, &rdata));
   8026 		}
   8027 		dns_rdata_reset(&rdata);
   8028 	}
   8029 	if (result == ISC_R_NOMORE) {
   8030 		result = ISC_R_SUCCESS;
   8031 	}
   8032 	if (!signing->deleteit && !seen_done) {
   8033 		/*
   8034 		 * If we were signing then we need to indicate that we have
   8035 		 * finished signing the zone with this key.  If it is already
   8036 		 * there we don't need to add it a second time.
   8037 		 */
   8038 		data[0] = signing->algorithm;
   8039 		data[1] = (signing->keyid >> 8) & 0xff;
   8040 		data[2] = signing->keyid & 0xff;
   8041 		data[3] = 0;
   8042 		data[4] = 1;
   8043 		rdata.length = sizeof(data);
   8044 		rdata.data = data;
   8045 		rdata.type = zone->privatetype;
   8046 		rdata.rdclass = dns_db_class(signing->db);
   8047 		CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
   8048 				    &zone->origin, rdataset.ttl, &rdata));
   8049 	} else if (!have_rr) {
   8050 		dns_name_t *origin = dns_db_origin(signing->db);
   8051 		/*
   8052 		 * Rebuild the NSEC/NSEC3 record for the origin as we no
   8053 		 * longer have any private records.
   8054 		 */
   8055 		if (build_nsec3) {
   8056 			CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
   8057 						  nsecttl, false, diff));
   8058 		}
   8059 		CHECK(updatesecure(signing->db, version, origin, nsecttl, true,
   8060 				   diff));
   8061 	}
   8062 
   8063 failure:
   8064 	if (dns_rdataset_isassociated(&rdataset)) {
   8065 		dns_rdataset_disassociate(&rdataset);
   8066 	}
   8067 	if (node != NULL) {
   8068 		dns_db_detachnode(signing->db, &node);
   8069 	}
   8070 	return (result);
   8071 }
   8072 
   8073 /*
   8074  * Called from zone_nsec3chain() in order to update zone records indicating
   8075  * processing status of given NSEC3 chain:
   8076  *
   8077  *   - If the supplied dns_nsec3chain_t structure has been fully processed
   8078  *     (which is indicated by "active" being set to false):
   8079  *
   8080  *       - remove all NSEC3PARAM records matching the relevant NSEC3 chain,
   8081  *
   8082  *       - remove all private-type records containing NSEC3PARAM RDATA matching
   8083  *         the relevant NSEC3 chain.
   8084  *
   8085  *   - If the supplied dns_nsec3chain_t structure has not been fully processed
   8086  *     (which is indicated by "active" being set to true), only remove the
   8087  *     NSEC3PARAM record which matches the relevant NSEC3 chain and has the
   8088  *     "flags" field set to 0.
   8089  *
   8090  *   - If given NSEC3 chain is being added, add an NSEC3PARAM record contained
   8091  *     in the relevant private-type record, but with the "flags" field set to
   8092  *     0, indicating that this NSEC3 chain is now complete for this zone.
   8093  *
   8094  * Note that this function is called at different processing stages for NSEC3
   8095  * chain additions vs. removals and needs to handle all cases properly.
   8096  */
   8097 static isc_result_t
   8098 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
   8099 		 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) {
   8100 	dns_dbnode_t *node = NULL;
   8101 	dns_name_t *name = dns_db_origin(db);
   8102 	dns_rdata_t rdata = DNS_RDATA_INIT;
   8103 	dns_rdataset_t rdataset;
   8104 	dns_rdata_nsec3param_t nsec3param;
   8105 	isc_result_t result;
   8106 	isc_buffer_t buffer;
   8107 	unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
   8108 	dns_ttl_t ttl = 0;
   8109 	bool nseconly = false, nsec3ok = false;
   8110 
   8111 	dns_rdataset_init(&rdataset);
   8112 
   8113 	result = dns_db_getoriginnode(db, &node);
   8114 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8115 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   8116 				     0, &rdataset, NULL);
   8117 	if (result == ISC_R_NOTFOUND) {
   8118 		goto try_private;
   8119 	}
   8120 	if (result != ISC_R_SUCCESS) {
   8121 		goto failure;
   8122 	}
   8123 
   8124 	/*
   8125 	 * Preserve the existing ttl.
   8126 	 */
   8127 	ttl = rdataset.ttl;
   8128 
   8129 	/*
   8130 	 * Delete all NSEC3PARAM records which match that in nsec3chain.
   8131 	 */
   8132 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8133 	     result = dns_rdataset_next(&rdataset))
   8134 	{
   8135 		dns_rdataset_current(&rdataset, &rdata);
   8136 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   8137 
   8138 		if (nsec3param.hash != chain->nsec3param.hash ||
   8139 		    (active && nsec3param.flags != 0) ||
   8140 		    nsec3param.iterations != chain->nsec3param.iterations ||
   8141 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   8142 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   8143 			   nsec3param.salt_length))
   8144 		{
   8145 			dns_rdata_reset(&rdata);
   8146 			continue;
   8147 		}
   8148 
   8149 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8150 				    rdataset.ttl, &rdata));
   8151 		dns_rdata_reset(&rdata);
   8152 	}
   8153 	if (result != ISC_R_NOMORE) {
   8154 		goto failure;
   8155 	}
   8156 
   8157 	dns_rdataset_disassociate(&rdataset);
   8158 
   8159 try_private:
   8160 
   8161 	if (active) {
   8162 		goto add;
   8163 	}
   8164 
   8165 	result = dns_nsec_nseconly(db, ver, &nseconly);
   8166 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   8167 
   8168 	/*
   8169 	 * Delete all private records which match that in nsec3chain.
   8170 	 */
   8171 	result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0,
   8172 				     &rdataset, NULL);
   8173 	if (result == ISC_R_NOTFOUND) {
   8174 		goto add;
   8175 	}
   8176 	if (result != ISC_R_SUCCESS) {
   8177 		goto failure;
   8178 	}
   8179 
   8180 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8181 	     result = dns_rdataset_next(&rdataset))
   8182 	{
   8183 		dns_rdata_t private = DNS_RDATA_INIT;
   8184 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   8185 
   8186 		dns_rdataset_current(&rdataset, &private);
   8187 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   8188 						sizeof(buf)))
   8189 		{
   8190 			continue;
   8191 		}
   8192 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   8193 
   8194 		if ((!nsec3ok &&
   8195 		     (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
   8196 		    nsec3param.hash != chain->nsec3param.hash ||
   8197 		    nsec3param.iterations != chain->nsec3param.iterations ||
   8198 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   8199 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   8200 			   nsec3param.salt_length))
   8201 		{
   8202 			dns_rdata_reset(&rdata);
   8203 			continue;
   8204 		}
   8205 
   8206 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8207 				    rdataset.ttl, &private));
   8208 		dns_rdata_reset(&rdata);
   8209 	}
   8210 	if (result != ISC_R_NOMORE) {
   8211 		goto failure;
   8212 	}
   8213 
   8214 add:
   8215 	if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   8216 		result = ISC_R_SUCCESS;
   8217 		goto failure;
   8218 	}
   8219 
   8220 	/*
   8221 	 * Add a NSEC3PARAM record which matches that in nsec3chain but
   8222 	 * with all flags bits cleared.
   8223 	 *
   8224 	 * Note: we do not clear chain->nsec3param.flags as this change
   8225 	 * may be reversed.
   8226 	 */
   8227 	isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
   8228 	CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
   8229 				   dns_rdatatype_nsec3param, &chain->nsec3param,
   8230 				   &buffer));
   8231 	rdata.data[1] = 0; /* Clear flag bits. */
   8232 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
   8233 
   8234 failure:
   8235 	dns_db_detachnode(db, &node);
   8236 	if (dns_rdataset_isassociated(&rdataset)) {
   8237 		dns_rdataset_disassociate(&rdataset);
   8238 	}
   8239 	return (result);
   8240 }
   8241 
   8242 static isc_result_t
   8243 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   8244 	    dns_name_t *name, dns_diff_t *diff) {
   8245 	dns_rdataset_t rdataset;
   8246 	isc_result_t result;
   8247 
   8248 	dns_rdataset_init(&rdataset);
   8249 
   8250 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   8251 				     &rdataset, NULL);
   8252 	if (result == ISC_R_NOTFOUND) {
   8253 		return (ISC_R_SUCCESS);
   8254 	}
   8255 	if (result != ISC_R_SUCCESS) {
   8256 		return (result);
   8257 	}
   8258 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8259 	     result = dns_rdataset_next(&rdataset))
   8260 	{
   8261 		dns_rdata_t rdata = DNS_RDATA_INIT;
   8262 
   8263 		dns_rdataset_current(&rdataset, &rdata);
   8264 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8265 				    rdataset.ttl, &rdata));
   8266 	}
   8267 	if (result == ISC_R_NOMORE) {
   8268 		result = ISC_R_SUCCESS;
   8269 	}
   8270 failure:
   8271 	dns_rdataset_disassociate(&rdataset);
   8272 	return (result);
   8273 }
   8274 
   8275 static isc_result_t
   8276 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   8277 		    dns_name_t *name, const dns_rdata_nsec3param_t *param,
   8278 		    dns_diff_t *diff) {
   8279 	dns_rdataset_t rdataset;
   8280 	dns_rdata_nsec3_t nsec3;
   8281 	isc_result_t result;
   8282 
   8283 	dns_rdataset_init(&rdataset);
   8284 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0,
   8285 				     &rdataset, NULL);
   8286 	if (result == ISC_R_NOTFOUND) {
   8287 		return (ISC_R_SUCCESS);
   8288 	}
   8289 	if (result != ISC_R_SUCCESS) {
   8290 		return (result);
   8291 	}
   8292 
   8293 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8294 	     result = dns_rdataset_next(&rdataset))
   8295 	{
   8296 		dns_rdata_t rdata = DNS_RDATA_INIT;
   8297 
   8298 		dns_rdataset_current(&rdataset, &rdata);
   8299 		CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
   8300 		if (nsec3.hash != param->hash ||
   8301 		    nsec3.iterations != param->iterations ||
   8302 		    nsec3.salt_length != param->salt_length ||
   8303 		    memcmp(nsec3.salt, param->salt, nsec3.salt_length))
   8304 		{
   8305 			continue;
   8306 		}
   8307 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8308 				    rdataset.ttl, &rdata));
   8309 	}
   8310 	if (result == ISC_R_NOMORE) {
   8311 		result = ISC_R_SUCCESS;
   8312 	}
   8313 failure:
   8314 	dns_rdataset_disassociate(&rdataset);
   8315 	return (result);
   8316 }
   8317 
   8318 static isc_result_t
   8319 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
   8320 		const dns_rdata_nsec3param_t *param, bool *answer) {
   8321 	dns_dbnode_t *node = NULL;
   8322 	dns_rdata_t rdata = DNS_RDATA_INIT;
   8323 	dns_rdata_nsec3param_t myparam;
   8324 	dns_rdataset_t rdataset;
   8325 	isc_result_t result;
   8326 
   8327 	*answer = false;
   8328 
   8329 	result = dns_db_getoriginnode(db, &node);
   8330 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8331 
   8332 	dns_rdataset_init(&rdataset);
   8333 
   8334 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   8335 				     &rdataset, NULL);
   8336 	if (result == ISC_R_SUCCESS) {
   8337 		dns_rdataset_disassociate(&rdataset);
   8338 		dns_db_detachnode(db, &node);
   8339 		return (result);
   8340 	}
   8341 	if (result != ISC_R_NOTFOUND) {
   8342 		dns_db_detachnode(db, &node);
   8343 		return (result);
   8344 	}
   8345 
   8346 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   8347 				     0, &rdataset, NULL);
   8348 	if (result == ISC_R_NOTFOUND) {
   8349 		*answer = true;
   8350 		dns_db_detachnode(db, &node);
   8351 		return (ISC_R_SUCCESS);
   8352 	}
   8353 	if (result != ISC_R_SUCCESS) {
   8354 		dns_db_detachnode(db, &node);
   8355 		return (result);
   8356 	}
   8357 
   8358 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8359 	     result = dns_rdataset_next(&rdataset))
   8360 	{
   8361 		dns_rdataset_current(&rdataset, &rdata);
   8362 		CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
   8363 		dns_rdata_reset(&rdata);
   8364 		/*
   8365 		 * Ignore any NSEC3PARAM removals.
   8366 		 */
   8367 		if (NSEC3REMOVE(myparam.flags)) {
   8368 			continue;
   8369 		}
   8370 		/*
   8371 		 * Ignore the chain that we are in the process of deleting.
   8372 		 */
   8373 		if (myparam.hash == param->hash &&
   8374 		    myparam.iterations == param->iterations &&
   8375 		    myparam.salt_length == param->salt_length &&
   8376 		    !memcmp(myparam.salt, param->salt, myparam.salt_length))
   8377 		{
   8378 			continue;
   8379 		}
   8380 		/*
   8381 		 * Found an active NSEC3 chain.
   8382 		 */
   8383 		break;
   8384 	}
   8385 	if (result == ISC_R_NOMORE) {
   8386 		*answer = true;
   8387 		result = ISC_R_SUCCESS;
   8388 	}
   8389 
   8390 failure:
   8391 	if (dns_rdataset_isassociated(&rdataset)) {
   8392 		dns_rdataset_disassociate(&rdataset);
   8393 	}
   8394 	dns_db_detachnode(db, &node);
   8395 	return (result);
   8396 }
   8397 
   8398 /*%
   8399  * Given a tuple which is part of a diff, return a pointer to the next tuple in
   8400  * that diff which has the same name and type (or NULL if no such tuple is
   8401  * found).
   8402  */
   8403 static dns_difftuple_t *
   8404 find_next_matching_tuple(dns_difftuple_t *cur) {
   8405 	dns_difftuple_t *next = cur;
   8406 
   8407 	while ((next = ISC_LIST_NEXT(next, link)) != NULL) {
   8408 		if (cur->rdata.type == next->rdata.type &&
   8409 		    dns_name_equal(&cur->name, &next->name))
   8410 		{
   8411 			return (next);
   8412 		}
   8413 	}
   8414 
   8415 	return (NULL);
   8416 }
   8417 
   8418 /*%
   8419  * Remove all tuples with the same name and type as 'cur' from 'src' and append
   8420  * them to 'dst'.
   8421  */
   8422 static void
   8423 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) {
   8424 	do {
   8425 		dns_difftuple_t *next = find_next_matching_tuple(cur);
   8426 		ISC_LIST_UNLINK(src->tuples, cur, link);
   8427 		dns_diff_appendminimal(dst, &cur);
   8428 		cur = next;
   8429 	} while (cur != NULL);
   8430 }
   8431 
   8432 /*%
   8433  * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in
   8434  * 'diff'.  Gradually remove tuples from 'diff' and append them to 'zonediff'
   8435  * along with tuples representing relevant signature changes.
   8436  */
   8437 isc_result_t
   8438 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
   8439 		     dst_key_t *zone_keys[], unsigned int nkeys,
   8440 		     dns_zone_t *zone, isc_stdtime_t inception,
   8441 		     isc_stdtime_t expire, isc_stdtime_t keyexpire,
   8442 		     isc_stdtime_t now, bool check_ksk, bool keyset_kskonly,
   8443 		     dns__zonediff_t *zonediff) {
   8444 	dns_difftuple_t *tuple;
   8445 	isc_result_t result;
   8446 
   8447 	while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) {
   8448 		isc_stdtime_t exp = expire;
   8449 
   8450 		if (keyexpire != 0 &&
   8451 		    (tuple->rdata.type == dns_rdatatype_dnskey ||
   8452 		     tuple->rdata.type == dns_rdatatype_cdnskey ||
   8453 		     tuple->rdata.type == dns_rdatatype_cds))
   8454 		{
   8455 			exp = keyexpire;
   8456 		}
   8457 
   8458 		result = del_sigs(zone, db, version, &tuple->name,
   8459 				  tuple->rdata.type, zonediff, zone_keys, nkeys,
   8460 				  now, false);
   8461 		if (result != ISC_R_SUCCESS) {
   8462 			dns_zone_log(zone, ISC_LOG_ERROR,
   8463 				     "dns__zone_updatesigs:del_sigs -> %s",
   8464 				     dns_result_totext(result));
   8465 			return (result);
   8466 		}
   8467 		result = add_sigs(db, version, &tuple->name, zone,
   8468 				  tuple->rdata.type, zonediff->diff, zone_keys,
   8469 				  nkeys, zone->mctx, inception, exp, check_ksk,
   8470 				  keyset_kskonly);
   8471 		if (result != ISC_R_SUCCESS) {
   8472 			dns_zone_log(zone, ISC_LOG_ERROR,
   8473 				     "dns__zone_updatesigs:add_sigs -> %s",
   8474 				     dns_result_totext(result));
   8475 			return (result);
   8476 		}
   8477 
   8478 		/*
   8479 		 * Signature changes for all RRs with name tuple->name and type
   8480 		 * tuple->rdata.type were appended to zonediff->diff.  Now we
   8481 		 * remove all the "raw" changes with the same name and type
   8482 		 * from diff (so that they are not processed by this loop
   8483 		 * again) and append them to zonediff so that they get applied.
   8484 		 */
   8485 		move_matching_tuples(tuple, diff, zonediff->diff);
   8486 	}
   8487 	return (ISC_R_SUCCESS);
   8488 }
   8489 
   8490 /*
   8491  * Incrementally build and sign a new NSEC3 chain using the parameters
   8492  * requested.
   8493  */
   8494 static void
   8495 zone_nsec3chain(dns_zone_t *zone) {
   8496 	const char *me = "zone_nsec3chain";
   8497 	dns_db_t *db = NULL;
   8498 	dns_dbnode_t *node = NULL;
   8499 	dns_dbversion_t *version = NULL;
   8500 	dns_diff_t _sig_diff;
   8501 	dns_diff_t nsec_diff;
   8502 	dns_diff_t nsec3_diff;
   8503 	dns_diff_t param_diff;
   8504 	dns__zonediff_t zonediff;
   8505 	dns_fixedname_t fixed;
   8506 	dns_fixedname_t nextfixed;
   8507 	dns_name_t *name, *nextname;
   8508 	dns_rdataset_t rdataset;
   8509 	dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
   8510 	dns_nsec3chainlist_t cleanup;
   8511 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   8512 	int32_t signatures;
   8513 	bool check_ksk, keyset_kskonly;
   8514 	bool delegation;
   8515 	bool first;
   8516 	isc_result_t result;
   8517 	isc_stdtime_t now, inception, soaexpire, expire;
   8518 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   8519 	unsigned int i;
   8520 	unsigned int nkeys = 0;
   8521 	uint32_t nodes;
   8522 	bool unsecure = false;
   8523 	bool seen_soa, seen_ns, seen_dname, seen_ds;
   8524 	bool seen_nsec, seen_nsec3, seen_rr;
   8525 	dns_rdatasetiter_t *iterator = NULL;
   8526 	bool buildnsecchain;
   8527 	bool updatensec = false;
   8528 	dns_rdatatype_t privatetype = zone->privatetype;
   8529 
   8530 	ENTER;
   8531 
   8532 	dns_rdataset_init(&rdataset);
   8533 	name = dns_fixedname_initname(&fixed);
   8534 	nextname = dns_fixedname_initname(&nextfixed);
   8535 	dns_diff_init(zone->mctx, &param_diff);
   8536 	dns_diff_init(zone->mctx, &nsec3_diff);
   8537 	dns_diff_init(zone->mctx, &nsec_diff);
   8538 	dns_diff_init(zone->mctx, &_sig_diff);
   8539 	zonediff_init(&zonediff, &_sig_diff);
   8540 	ISC_LIST_INIT(cleanup);
   8541 
   8542 	/*
   8543 	 * Updates are disabled.  Pause for 5 minutes.
   8544 	 */
   8545 	if (zone->update_disabled) {
   8546 		result = ISC_R_FAILURE;
   8547 		goto failure;
   8548 	}
   8549 
   8550 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8551 	/*
   8552 	 * This function is called when zone timer fires, after the latter gets
   8553 	 * set by zone_addnsec3chain().  If the action triggering the call to
   8554 	 * zone_addnsec3chain() is closely followed by a zone deletion request,
   8555 	 * it might turn out that the timer thread will not be woken up until
   8556 	 * after the zone is deleted by rmzone(), which calls dns_db_detach()
   8557 	 * for zone->db, causing the latter to become NULL.  Return immediately
   8558 	 * if that happens.
   8559 	 */
   8560 	if (zone->db != NULL) {
   8561 		dns_db_attach(zone->db, &db);
   8562 	}
   8563 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8564 	if (db == NULL) {
   8565 		return;
   8566 	}
   8567 
   8568 	result = dns_db_newversion(db, &version);
   8569 	if (result != ISC_R_SUCCESS) {
   8570 		dnssec_log(zone, ISC_LOG_ERROR,
   8571 			   "zone_nsec3chain:dns_db_newversion -> %s",
   8572 			   dns_result_totext(result));
   8573 		goto failure;
   8574 	}
   8575 
   8576 	isc_stdtime_get(&now);
   8577 
   8578 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   8579 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   8580 	if (result != ISC_R_SUCCESS) {
   8581 		dnssec_log(zone, ISC_LOG_ERROR,
   8582 			   "zone_nsec3chain:dns__zone_findkeys -> %s",
   8583 			   dns_result_totext(result));
   8584 		goto failure;
   8585 	}
   8586 
   8587 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   8588 	inception = now - 3600; /* Allow for clock skew. */
   8589 	soaexpire = now + sigvalidityinterval;
   8590 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   8591 	if (expiryinterval > sigvalidityinterval) {
   8592 		expiryinterval = sigvalidityinterval;
   8593 	} else {
   8594 		expiryinterval = sigvalidityinterval - expiryinterval;
   8595 	}
   8596 
   8597 	/*
   8598 	 * Spread out signatures over time if they happen to be
   8599 	 * clumped.  We don't do this for each add_sigs() call as
   8600 	 * we still want some clustering to occur.
   8601 	 */
   8602 	if (sigvalidityinterval >= 3600U) {
   8603 		if (sigvalidityinterval > 7200U) {
   8604 			jitter = isc_random_uniform(expiryinterval);
   8605 		} else {
   8606 			jitter = isc_random_uniform(1200);
   8607 		}
   8608 		expire = soaexpire - jitter - 1;
   8609 	} else {
   8610 		expire = soaexpire - 1;
   8611 	}
   8612 
   8613 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   8614 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   8615 
   8616 	/*
   8617 	 * We keep pulling nodes off each iterator in turn until
   8618 	 * we have no more nodes to pull off or we reach the limits
   8619 	 * for this quantum.
   8620 	 */
   8621 	nodes = zone->nodes;
   8622 	signatures = zone->signatures;
   8623 	LOCK_ZONE(zone);
   8624 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8625 	UNLOCK_ZONE(zone);
   8626 	first = true;
   8627 
   8628 	if (nsec3chain != NULL) {
   8629 		nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8630 	}
   8631 	/*
   8632 	 * Generate new NSEC3 chains first.
   8633 	 *
   8634 	 * The following while loop iterates over nodes in the zone database,
   8635 	 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of
   8636 	 * them.  Once all nodes are processed, the "delete_nsec" field is
   8637 	 * consulted to check whether we are supposed to remove NSEC records
   8638 	 * from the zone database; if so, the database iterator is reset to
   8639 	 * point to the first node and the loop traverses all of them again,
   8640 	 * this time removing NSEC records.  If we hit a node which is obscured
   8641 	 * by a delegation or a DNAME, nodes are skipped over until we find one
   8642 	 * that is not obscured by the same obscuring name and then normal
   8643 	 * processing is resumed.
   8644 	 *
   8645 	 * The above is repeated until all requested NSEC3 chain changes are
   8646 	 * applied or when we reach the limits for this quantum, whichever
   8647 	 * happens first.
   8648 	 *
   8649 	 * Note that the "signatures" variable is only used here to limit the
   8650 	 * amount of work performed.  Actual DNSSEC signatures are only
   8651 	 * generated by dns__zone_updatesigs() calls later in this function.
   8652 	 */
   8653 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8654 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8655 
   8656 		LOCK_ZONE(zone);
   8657 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8658 
   8659 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8660 		if (nsec3chain->done || nsec3chain->db != zone->db) {
   8661 			ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   8662 			ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8663 		}
   8664 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8665 		UNLOCK_ZONE(zone);
   8666 		if (ISC_LIST_TAIL(cleanup) == nsec3chain) {
   8667 			goto next_addchain;
   8668 		}
   8669 
   8670 		/*
   8671 		 * Possible future db.
   8672 		 */
   8673 		if (nsec3chain->db != db) {
   8674 			goto next_addchain;
   8675 		}
   8676 
   8677 		if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8678 			goto next_addchain;
   8679 		}
   8680 
   8681 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8682 
   8683 		if (nsec3chain->delete_nsec) {
   8684 			delegation = false;
   8685 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8686 			CHECK(delete_nsec(db, version, node, name, &nsec_diff));
   8687 			goto next_addnode;
   8688 		}
   8689 		/*
   8690 		 * On the first pass we need to check if the current node
   8691 		 * has not been obscured.
   8692 		 */
   8693 		delegation = false;
   8694 		unsecure = false;
   8695 		if (first) {
   8696 			dns_fixedname_t ffound;
   8697 			dns_name_t *found;
   8698 			found = dns_fixedname_initname(&ffound);
   8699 			result = dns_db_find(
   8700 				db, name, version, dns_rdatatype_soa,
   8701 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8702 			if ((result == DNS_R_DELEGATION ||
   8703 			     result == DNS_R_DNAME) &&
   8704 			    !dns_name_equal(name, found))
   8705 			{
   8706 				/*
   8707 				 * Remember the obscuring name so that
   8708 				 * we skip all obscured names.
   8709 				 */
   8710 				dns_name_copynf(found, name);
   8711 				delegation = true;
   8712 				goto next_addnode;
   8713 			}
   8714 		}
   8715 
   8716 		/*
   8717 		 * Check to see if this is a bottom of zone node.
   8718 		 */
   8719 		result = dns_db_allrdatasets(db, node, version, 0, 0,
   8720 					     &iterator);
   8721 		if (result == ISC_R_NOTFOUND) {
   8722 			/* Empty node? */
   8723 			goto next_addnode;
   8724 		}
   8725 		if (result != ISC_R_SUCCESS) {
   8726 			goto failure;
   8727 		}
   8728 
   8729 		seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false;
   8730 		for (result = dns_rdatasetiter_first(iterator);
   8731 		     result == ISC_R_SUCCESS;
   8732 		     result = dns_rdatasetiter_next(iterator))
   8733 		{
   8734 			dns_rdatasetiter_current(iterator, &rdataset);
   8735 			INSIST(rdataset.type != dns_rdatatype_nsec3);
   8736 			if (rdataset.type == dns_rdatatype_soa) {
   8737 				seen_soa = true;
   8738 			} else if (rdataset.type == dns_rdatatype_ns) {
   8739 				seen_ns = true;
   8740 			} else if (rdataset.type == dns_rdatatype_dname) {
   8741 				seen_dname = true;
   8742 			} else if (rdataset.type == dns_rdatatype_ds) {
   8743 				seen_ds = true;
   8744 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8745 				seen_nsec = true;
   8746 			}
   8747 			dns_rdataset_disassociate(&rdataset);
   8748 		}
   8749 		dns_rdatasetiter_destroy(&iterator);
   8750 		/*
   8751 		 * Is there a NSEC chain than needs to be cleaned up?
   8752 		 */
   8753 		if (seen_nsec) {
   8754 			nsec3chain->seen_nsec = true;
   8755 		}
   8756 		if (seen_ns && !seen_soa && !seen_ds) {
   8757 			unsecure = true;
   8758 		}
   8759 		if ((seen_ns && !seen_soa) || seen_dname) {
   8760 			delegation = true;
   8761 		}
   8762 
   8763 		/*
   8764 		 * Process one node.
   8765 		 */
   8766 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8767 		result = dns_nsec3_addnsec3(
   8768 			db, version, name, &nsec3chain->nsec3param,
   8769 			zone_nsecttl(zone), unsecure, &nsec3_diff);
   8770 		if (result != ISC_R_SUCCESS) {
   8771 			dnssec_log(zone, ISC_LOG_ERROR,
   8772 				   "zone_nsec3chain:"
   8773 				   "dns_nsec3_addnsec3 -> %s",
   8774 				   dns_result_totext(result));
   8775 			goto failure;
   8776 		}
   8777 
   8778 		/*
   8779 		 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
   8780 		 * two signatures.  Additionally there will, in general, be
   8781 		 * two signature generated below.
   8782 		 *
   8783 		 * If we are only changing the optout flag the cost is half
   8784 		 * that of the cost of generating a completely new chain.
   8785 		 */
   8786 		signatures -= 4;
   8787 
   8788 		/*
   8789 		 * Go onto next node.
   8790 		 */
   8791 	next_addnode:
   8792 		first = false;
   8793 		dns_db_detachnode(db, &node);
   8794 		do {
   8795 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8796 
   8797 			if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
   8798 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8799 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8800 						       false, privatetype,
   8801 						       &param_diff));
   8802 				LOCK_ZONE(zone);
   8803 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8804 						link);
   8805 				UNLOCK_ZONE(zone);
   8806 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8807 				goto next_addchain;
   8808 			}
   8809 			if (result == ISC_R_NOMORE) {
   8810 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8811 				if (nsec3chain->seen_nsec) {
   8812 					CHECK(fixup_nsec3param(
   8813 						db, version, nsec3chain, true,
   8814 						privatetype, &param_diff));
   8815 					nsec3chain->delete_nsec = true;
   8816 					goto same_addchain;
   8817 				}
   8818 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8819 						       false, privatetype,
   8820 						       &param_diff));
   8821 				LOCK_ZONE(zone);
   8822 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8823 						link);
   8824 				UNLOCK_ZONE(zone);
   8825 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8826 				goto next_addchain;
   8827 			} else if (result != ISC_R_SUCCESS) {
   8828 				dnssec_log(zone, ISC_LOG_ERROR,
   8829 					   "zone_nsec3chain:"
   8830 					   "dns_dbiterator_next -> %s",
   8831 					   dns_result_totext(result));
   8832 				goto failure;
   8833 			} else if (delegation) {
   8834 				dns_dbiterator_current(nsec3chain->dbiterator,
   8835 						       &node, nextname);
   8836 				dns_db_detachnode(db, &node);
   8837 				if (!dns_name_issubdomain(nextname, name)) {
   8838 					break;
   8839 				}
   8840 			} else {
   8841 				break;
   8842 			}
   8843 		} while (1);
   8844 		continue;
   8845 
   8846 	same_addchain:
   8847 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8848 		first = true;
   8849 		continue;
   8850 
   8851 	next_addchain:
   8852 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8853 		nsec3chain = nextnsec3chain;
   8854 		first = true;
   8855 		if (nsec3chain != NULL) {
   8856 			nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8857 		}
   8858 	}
   8859 
   8860 	if (nsec3chain != NULL) {
   8861 		goto skip_removals;
   8862 	}
   8863 
   8864 	/*
   8865 	 * Process removals.
   8866 	 *
   8867 	 * This is a counterpart of the above while loop which takes care of
   8868 	 * removing an NSEC3 chain.  It starts with determining whether the
   8869 	 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an
   8870 	 * NSEC chain by iterating over all nodes in the zone database and only
   8871 	 * then goes on to remove NSEC3 records be iterating over all nodes
   8872 	 * again and calling deletematchingnsec3() for each of them; otherwise,
   8873 	 * it starts removing NSEC3 records immediately.  Rules for processing
   8874 	 * obscured nodes and interrupting work are the same as for the while
   8875 	 * loop above.
   8876 	 */
   8877 	LOCK_ZONE(zone);
   8878 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8879 	UNLOCK_ZONE(zone);
   8880 	first = true;
   8881 	buildnsecchain = false;
   8882 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8883 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8884 
   8885 		LOCK_ZONE(zone);
   8886 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8887 		UNLOCK_ZONE(zone);
   8888 
   8889 		if (nsec3chain->db != db) {
   8890 			goto next_removechain;
   8891 		}
   8892 
   8893 		if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8894 			goto next_removechain;
   8895 		}
   8896 
   8897 		/*
   8898 		 * Work out if we need to build a NSEC chain as a consequence
   8899 		 * of removing this NSEC3 chain.
   8900 		 */
   8901 		if (first && !updatensec &&
   8902 		    (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
   8903 		{
   8904 			result = need_nsec_chain(db, version,
   8905 						 &nsec3chain->nsec3param,
   8906 						 &buildnsecchain);
   8907 			if (result != ISC_R_SUCCESS) {
   8908 				dnssec_log(zone, ISC_LOG_ERROR,
   8909 					   "zone_nsec3chain:"
   8910 					   "need_nsec_chain -> %s",
   8911 					   dns_result_totext(result));
   8912 				goto failure;
   8913 			}
   8914 		}
   8915 
   8916 		if (first) {
   8917 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   8918 				   "zone_nsec3chain:buildnsecchain = %u\n",
   8919 				   buildnsecchain);
   8920 		}
   8921 
   8922 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8923 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8924 		delegation = false;
   8925 
   8926 		if (!buildnsecchain) {
   8927 			/*
   8928 			 * Delete the NSEC3PARAM record matching this chain.
   8929 			 */
   8930 			if (first) {
   8931 				result = fixup_nsec3param(
   8932 					db, version, nsec3chain, true,
   8933 					privatetype, &param_diff);
   8934 				if (result != ISC_R_SUCCESS) {
   8935 					dnssec_log(zone, ISC_LOG_ERROR,
   8936 						   "zone_nsec3chain:"
   8937 						   "fixup_nsec3param -> %s",
   8938 						   dns_result_totext(result));
   8939 					goto failure;
   8940 				}
   8941 			}
   8942 
   8943 			/*
   8944 			 * Delete the NSEC3 records.
   8945 			 */
   8946 			result = deletematchingnsec3(db, version, node, name,
   8947 						     &nsec3chain->nsec3param,
   8948 						     &nsec3_diff);
   8949 			if (result != ISC_R_SUCCESS) {
   8950 				dnssec_log(zone, ISC_LOG_ERROR,
   8951 					   "zone_nsec3chain:"
   8952 					   "deletematchingnsec3 -> %s",
   8953 					   dns_result_totext(result));
   8954 				goto failure;
   8955 			}
   8956 			goto next_removenode;
   8957 		}
   8958 
   8959 		if (first) {
   8960 			dns_fixedname_t ffound;
   8961 			dns_name_t *found;
   8962 			found = dns_fixedname_initname(&ffound);
   8963 			result = dns_db_find(
   8964 				db, name, version, dns_rdatatype_soa,
   8965 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8966 			if ((result == DNS_R_DELEGATION ||
   8967 			     result == DNS_R_DNAME) &&
   8968 			    !dns_name_equal(name, found))
   8969 			{
   8970 				/*
   8971 				 * Remember the obscuring name so that
   8972 				 * we skip all obscured names.
   8973 				 */
   8974 				dns_name_copynf(found, name);
   8975 				delegation = true;
   8976 				goto next_removenode;
   8977 			}
   8978 		}
   8979 
   8980 		/*
   8981 		 * Check to see if this is a bottom of zone node.
   8982 		 */
   8983 		result = dns_db_allrdatasets(db, node, version, 0, 0,
   8984 					     &iterator);
   8985 		if (result == ISC_R_NOTFOUND) {
   8986 			/* Empty node? */
   8987 			goto next_removenode;
   8988 		}
   8989 		if (result != ISC_R_SUCCESS) {
   8990 			goto failure;
   8991 		}
   8992 
   8993 		seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
   8994 			seen_rr = false;
   8995 		for (result = dns_rdatasetiter_first(iterator);
   8996 		     result == ISC_R_SUCCESS;
   8997 		     result = dns_rdatasetiter_next(iterator))
   8998 		{
   8999 			dns_rdatasetiter_current(iterator, &rdataset);
   9000 			if (rdataset.type == dns_rdatatype_soa) {
   9001 				seen_soa = true;
   9002 			} else if (rdataset.type == dns_rdatatype_ns) {
   9003 				seen_ns = true;
   9004 			} else if (rdataset.type == dns_rdatatype_dname) {
   9005 				seen_dname = true;
   9006 			} else if (rdataset.type == dns_rdatatype_nsec) {
   9007 				seen_nsec = true;
   9008 			} else if (rdataset.type == dns_rdatatype_nsec3) {
   9009 				seen_nsec3 = true;
   9010 			} else if (rdataset.type != dns_rdatatype_rrsig) {
   9011 				seen_rr = true;
   9012 			}
   9013 			dns_rdataset_disassociate(&rdataset);
   9014 		}
   9015 		dns_rdatasetiter_destroy(&iterator);
   9016 
   9017 		if (!seen_rr || seen_nsec3 || seen_nsec) {
   9018 			goto next_removenode;
   9019 		}
   9020 		if ((seen_ns && !seen_soa) || seen_dname) {
   9021 			delegation = true;
   9022 		}
   9023 
   9024 		/*
   9025 		 * Add a NSEC record except at the origin.
   9026 		 */
   9027 		if (!dns_name_equal(name, dns_db_origin(db))) {
   9028 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9029 			CHECK(add_nsec(db, version, name, node,
   9030 				       zone_nsecttl(zone), delegation,
   9031 				       &nsec_diff));
   9032 			signatures--;
   9033 		}
   9034 
   9035 	next_removenode:
   9036 		first = false;
   9037 		dns_db_detachnode(db, &node);
   9038 		do {
   9039 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   9040 			if (result == ISC_R_NOMORE && buildnsecchain) {
   9041 				/*
   9042 				 * The NSEC chain should now be built.
   9043 				 * We can now remove the NSEC3 chain.
   9044 				 */
   9045 				updatensec = true;
   9046 				goto same_removechain;
   9047 			}
   9048 			if (result == ISC_R_NOMORE) {
   9049 				dns_dbiterator_pause(nsec3chain->dbiterator);
   9050 				LOCK_ZONE(zone);
   9051 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   9052 						link);
   9053 				UNLOCK_ZONE(zone);
   9054 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   9055 				result = fixup_nsec3param(
   9056 					db, version, nsec3chain, false,
   9057 					privatetype, &param_diff);
   9058 				if (result != ISC_R_SUCCESS) {
   9059 					dnssec_log(zone, ISC_LOG_ERROR,
   9060 						   "zone_nsec3chain:"
   9061 						   "fixup_nsec3param -> %s",
   9062 						   dns_result_totext(result));
   9063 					goto failure;
   9064 				}
   9065 				goto next_removechain;
   9066 			} else if (result != ISC_R_SUCCESS) {
   9067 				dnssec_log(zone, ISC_LOG_ERROR,
   9068 					   "zone_nsec3chain:"
   9069 					   "dns_dbiterator_next -> %s",
   9070 					   dns_result_totext(result));
   9071 				goto failure;
   9072 			} else if (delegation) {
   9073 				dns_dbiterator_current(nsec3chain->dbiterator,
   9074 						       &node, nextname);
   9075 				dns_db_detachnode(db, &node);
   9076 				if (!dns_name_issubdomain(nextname, name)) {
   9077 					break;
   9078 				}
   9079 			} else {
   9080 				break;
   9081 			}
   9082 		} while (1);
   9083 		continue;
   9084 
   9085 	same_removechain:
   9086 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   9087 		buildnsecchain = false;
   9088 		first = true;
   9089 		continue;
   9090 
   9091 	next_removechain:
   9092 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9093 		nsec3chain = nextnsec3chain;
   9094 		first = true;
   9095 	}
   9096 
   9097 skip_removals:
   9098 	/*
   9099 	 * We may need to update the NSEC/NSEC3 records for the zone apex.
   9100 	 */
   9101 	if (!ISC_LIST_EMPTY(param_diff.tuples)) {
   9102 		bool rebuild_nsec = false, rebuild_nsec3 = false;
   9103 		result = dns_db_getoriginnode(db, &node);
   9104 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9105 		result = dns_db_allrdatasets(db, node, version, 0, 0,
   9106 					     &iterator);
   9107 		if (result != ISC_R_SUCCESS) {
   9108 			dnssec_log(zone, ISC_LOG_ERROR,
   9109 				   "zone_nsec3chain:dns_db_allrdatasets -> %s",
   9110 				   dns_result_totext(result));
   9111 			goto failure;
   9112 		}
   9113 		for (result = dns_rdatasetiter_first(iterator);
   9114 		     result == ISC_R_SUCCESS;
   9115 		     result = dns_rdatasetiter_next(iterator))
   9116 		{
   9117 			dns_rdatasetiter_current(iterator, &rdataset);
   9118 			if (rdataset.type == dns_rdatatype_nsec) {
   9119 				rebuild_nsec = true;
   9120 			} else if (rdataset.type == dns_rdatatype_nsec3param) {
   9121 				rebuild_nsec3 = true;
   9122 			}
   9123 			dns_rdataset_disassociate(&rdataset);
   9124 		}
   9125 		dns_rdatasetiter_destroy(&iterator);
   9126 		dns_db_detachnode(db, &node);
   9127 
   9128 		if (rebuild_nsec) {
   9129 			if (nsec3chain != NULL) {
   9130 				dns_dbiterator_pause(nsec3chain->dbiterator);
   9131 			}
   9132 
   9133 			result = updatesecure(db, version, &zone->origin,
   9134 					      zone_nsecttl(zone), true,
   9135 					      &nsec_diff);
   9136 			if (result != ISC_R_SUCCESS) {
   9137 				dnssec_log(zone, ISC_LOG_ERROR,
   9138 					   "zone_nsec3chain:updatesecure -> %s",
   9139 					   dns_result_totext(result));
   9140 				goto failure;
   9141 			}
   9142 		}
   9143 
   9144 		if (rebuild_nsec3) {
   9145 			if (nsec3chain != NULL) {
   9146 				dns_dbiterator_pause(nsec3chain->dbiterator);
   9147 			}
   9148 
   9149 			result = dns_nsec3_addnsec3s(
   9150 				db, version, dns_db_origin(db),
   9151 				zone_nsecttl(zone), false, &nsec3_diff);
   9152 			if (result != ISC_R_SUCCESS) {
   9153 				dnssec_log(zone, ISC_LOG_ERROR,
   9154 					   "zone_nsec3chain:"
   9155 					   "dns_nsec3_addnsec3s -> %s",
   9156 					   dns_result_totext(result));
   9157 				goto failure;
   9158 			}
   9159 		}
   9160 	}
   9161 
   9162 	/*
   9163 	 * Add / update signatures for the NSEC3 records.
   9164 	 */
   9165 	if (nsec3chain != NULL) {
   9166 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9167 	}
   9168 	result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys,
   9169 				      nkeys, zone, inception, expire, 0, now,
   9170 				      check_ksk, keyset_kskonly, &zonediff);
   9171 	if (result != ISC_R_SUCCESS) {
   9172 		dnssec_log(zone, ISC_LOG_ERROR,
   9173 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   9174 			   dns_result_totext(result));
   9175 		goto failure;
   9176 	}
   9177 
   9178 	/*
   9179 	 * We have changed the NSEC3PARAM or private RRsets
   9180 	 * above so we need to update the signatures.
   9181 	 */
   9182 	result = dns__zone_updatesigs(&param_diff, db, version, zone_keys,
   9183 				      nkeys, zone, inception, expire, 0, now,
   9184 				      check_ksk, keyset_kskonly, &zonediff);
   9185 	if (result != ISC_R_SUCCESS) {
   9186 		dnssec_log(zone, ISC_LOG_ERROR,
   9187 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   9188 			   dns_result_totext(result));
   9189 		goto failure;
   9190 	}
   9191 
   9192 	if (updatensec) {
   9193 		result = updatesecure(db, version, &zone->origin,
   9194 				      zone_nsecttl(zone), false, &nsec_diff);
   9195 		if (result != ISC_R_SUCCESS) {
   9196 			dnssec_log(zone, ISC_LOG_ERROR,
   9197 				   "zone_nsec3chain:updatesecure -> %s",
   9198 				   dns_result_totext(result));
   9199 			goto failure;
   9200 		}
   9201 	}
   9202 
   9203 	result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys,
   9204 				      zone, inception, expire, 0, now,
   9205 				      check_ksk, keyset_kskonly, &zonediff);
   9206 	if (result != ISC_R_SUCCESS) {
   9207 		dnssec_log(zone, ISC_LOG_ERROR,
   9208 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   9209 			   dns_result_totext(result));
   9210 		goto failure;
   9211 	}
   9212 
   9213 	/*
   9214 	 * If we made no effective changes to the zone then we can just
   9215 	 * cleanup otherwise we need to increment the serial.
   9216 	 */
   9217 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   9218 		/*
   9219 		 * No need to call dns_db_closeversion() here as it is
   9220 		 * called with commit = true below.
   9221 		 */
   9222 		goto done;
   9223 	}
   9224 
   9225 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   9226 			  &zonediff, zone_keys, nkeys, now, false);
   9227 	if (result != ISC_R_SUCCESS) {
   9228 		dnssec_log(zone, ISC_LOG_ERROR,
   9229 			   "zone_nsec3chain:del_sigs -> %s",
   9230 			   dns_result_totext(result));
   9231 		goto failure;
   9232 	}
   9233 
   9234 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   9235 				   zone->updatemethod);
   9236 	if (result != ISC_R_SUCCESS) {
   9237 		dnssec_log(zone, ISC_LOG_ERROR,
   9238 			   "zone_nsec3chain:update_soa_serial -> %s",
   9239 			   dns_result_totext(result));
   9240 		goto failure;
   9241 	}
   9242 
   9243 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   9244 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   9245 			  inception, soaexpire, check_ksk, keyset_kskonly);
   9246 	if (result != ISC_R_SUCCESS) {
   9247 		dnssec_log(zone, ISC_LOG_ERROR,
   9248 			   "zone_nsec3chain:add_sigs -> %s",
   9249 			   dns_result_totext(result));
   9250 		goto failure;
   9251 	}
   9252 
   9253 	/* Write changes to journal file. */
   9254 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
   9255 
   9256 	LOCK_ZONE(zone);
   9257 	zone_needdump(zone, DNS_DUMP_DELAY);
   9258 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   9259 	UNLOCK_ZONE(zone);
   9260 
   9261 done:
   9262 	/*
   9263 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   9264 	 */
   9265 	LOCK_ZONE(zone);
   9266 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   9267 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   9268 	{
   9269 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9270 	}
   9271 	UNLOCK_ZONE(zone);
   9272 
   9273 	/*
   9274 	 * Everything has succeeded. Commit the changes.
   9275 	 * Unconditionally commit as zonediff.offline not checked above.
   9276 	 */
   9277 	dns_db_closeversion(db, &version, true);
   9278 
   9279 	/*
   9280 	 * Everything succeeded so we can clean these up now.
   9281 	 */
   9282 	nsec3chain = ISC_LIST_HEAD(cleanup);
   9283 	while (nsec3chain != NULL) {
   9284 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   9285 		dns_db_detach(&nsec3chain->db);
   9286 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9287 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9288 		nsec3chain = ISC_LIST_HEAD(cleanup);
   9289 	}
   9290 
   9291 	LOCK_ZONE(zone);
   9292 	set_resigntime(zone);
   9293 	UNLOCK_ZONE(zone);
   9294 
   9295 failure:
   9296 	if (result != ISC_R_SUCCESS) {
   9297 		dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
   9298 			   dns_result_totext(result));
   9299 	}
   9300 
   9301 	/*
   9302 	 * On error roll back the current nsec3chain.
   9303 	 */
   9304 	if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
   9305 		if (nsec3chain->done) {
   9306 			dns_db_detach(&nsec3chain->db);
   9307 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9308 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9309 		} else {
   9310 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9311 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9312 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9313 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9314 		}
   9315 	}
   9316 
   9317 	/*
   9318 	 * Rollback the cleanup list.
   9319 	 */
   9320 	nsec3chain = ISC_LIST_TAIL(cleanup);
   9321 	while (nsec3chain != NULL) {
   9322 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   9323 		if (nsec3chain->done) {
   9324 			dns_db_detach(&nsec3chain->db);
   9325 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9326 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9327 		} else {
   9328 			LOCK_ZONE(zone);
   9329 			ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
   9330 			UNLOCK_ZONE(zone);
   9331 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9332 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9333 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9334 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9335 		}
   9336 		nsec3chain = ISC_LIST_TAIL(cleanup);
   9337 	}
   9338 
   9339 	LOCK_ZONE(zone);
   9340 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   9341 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   9342 	{
   9343 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9344 	}
   9345 	UNLOCK_ZONE(zone);
   9346 
   9347 	dns_diff_clear(&param_diff);
   9348 	dns_diff_clear(&nsec3_diff);
   9349 	dns_diff_clear(&nsec_diff);
   9350 	dns_diff_clear(&_sig_diff);
   9351 
   9352 	if (iterator != NULL) {
   9353 		dns_rdatasetiter_destroy(&iterator);
   9354 	}
   9355 
   9356 	for (i = 0; i < nkeys; i++) {
   9357 		dst_key_free(&zone_keys[i]);
   9358 	}
   9359 
   9360 	if (node != NULL) {
   9361 		dns_db_detachnode(db, &node);
   9362 	}
   9363 	if (version != NULL) {
   9364 		dns_db_closeversion(db, &version, false);
   9365 		dns_db_detach(&db);
   9366 	} else if (db != NULL) {
   9367 		dns_db_detach(&db);
   9368 	}
   9369 
   9370 	LOCK_ZONE(zone);
   9371 	if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
   9372 		isc_interval_t interval;
   9373 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   9374 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   9375 		} else {
   9376 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   9377 		}
   9378 		isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
   9379 	} else {
   9380 		isc_time_settoepoch(&zone->nsec3chaintime);
   9381 	}
   9382 	UNLOCK_ZONE(zone);
   9383 
   9384 	INSIST(version == NULL);
   9385 }
   9386 
   9387 /*%
   9388  * Delete all RRSIG records with the given algorithm and keyid.
   9389  * Remove the NSEC record and RRSIGs if nkeys is zero.
   9390  * If all remaining RRsets are signed with the given algorithm
   9391  * set *has_algp to true.
   9392  */
   9393 static isc_result_t
   9394 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   9395 	dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
   9396 	uint16_t keyid, bool *has_algp, dns_diff_t *diff) {
   9397 	dns_rdata_rrsig_t rrsig;
   9398 	dns_rdataset_t rdataset;
   9399 	dns_rdatasetiter_t *iterator = NULL;
   9400 	isc_result_t result;
   9401 	bool alg_missed = false;
   9402 	bool alg_found = false;
   9403 
   9404 	char namebuf[DNS_NAME_FORMATSIZE];
   9405 	dns_name_format(name, namebuf, sizeof(namebuf));
   9406 
   9407 	result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator);
   9408 	if (result != ISC_R_SUCCESS) {
   9409 		if (result == ISC_R_NOTFOUND) {
   9410 			result = ISC_R_SUCCESS;
   9411 		}
   9412 		return (result);
   9413 	}
   9414 
   9415 	dns_rdataset_init(&rdataset);
   9416 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   9417 	     result = dns_rdatasetiter_next(iterator))
   9418 	{
   9419 		bool has_alg = false;
   9420 		dns_rdatasetiter_current(iterator, &rdataset);
   9421 		if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
   9422 			for (result = dns_rdataset_first(&rdataset);
   9423 			     result == ISC_R_SUCCESS;
   9424 			     result = dns_rdataset_next(&rdataset))
   9425 			{
   9426 				dns_rdata_t rdata = DNS_RDATA_INIT;
   9427 				dns_rdataset_current(&rdataset, &rdata);
   9428 				CHECK(update_one_rr(db, version, diff,
   9429 						    DNS_DIFFOP_DEL, name,
   9430 						    rdataset.ttl, &rdata));
   9431 			}
   9432 			if (result != ISC_R_NOMORE) {
   9433 				goto failure;
   9434 			}
   9435 			dns_rdataset_disassociate(&rdataset);
   9436 			continue;
   9437 		}
   9438 		if (rdataset.type != dns_rdatatype_rrsig) {
   9439 			dns_rdataset_disassociate(&rdataset);
   9440 			continue;
   9441 		}
   9442 		for (result = dns_rdataset_first(&rdataset);
   9443 		     result == ISC_R_SUCCESS;
   9444 		     result = dns_rdataset_next(&rdataset))
   9445 		{
   9446 			dns_rdata_t rdata = DNS_RDATA_INIT;
   9447 			dns_rdataset_current(&rdataset, &rdata);
   9448 			CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
   9449 			if (nkeys != 0 && (rrsig.algorithm != algorithm ||
   9450 					   rrsig.keyid != keyid))
   9451 			{
   9452 				if (rrsig.algorithm == algorithm) {
   9453 					has_alg = true;
   9454 				}
   9455 				continue;
   9456 			}
   9457 			CHECK(update_one_rr(db, version, diff,
   9458 					    DNS_DIFFOP_DELRESIGN, name,
   9459 					    rdataset.ttl, &rdata));
   9460 		}
   9461 		dns_rdataset_disassociate(&rdataset);
   9462 		if (result != ISC_R_NOMORE) {
   9463 			break;
   9464 		}
   9465 
   9466 		/*
   9467 		 * After deleting, if there's still a signature for
   9468 		 * 'algorithm', set alg_found; if not, set alg_missed.
   9469 		 */
   9470 		if (has_alg) {
   9471 			alg_found = true;
   9472 		} else {
   9473 			alg_missed = true;
   9474 		}
   9475 	}
   9476 	if (result == ISC_R_NOMORE) {
   9477 		result = ISC_R_SUCCESS;
   9478 	}
   9479 
   9480 	/*
   9481 	 * Set `has_algp` if the algorithm was found in every RRset:
   9482 	 * i.e., found in at least one, and not missing from any.
   9483 	 */
   9484 	*has_algp = (alg_found && !alg_missed);
   9485 failure:
   9486 	if (dns_rdataset_isassociated(&rdataset)) {
   9487 		dns_rdataset_disassociate(&rdataset);
   9488 	}
   9489 	dns_rdatasetiter_destroy(&iterator);
   9490 	return (result);
   9491 }
   9492 
   9493 /*
   9494  * Incrementally sign the zone using the keys requested.
   9495  * Builds the NSEC chain if required.
   9496  */
   9497 static void
   9498 zone_sign(dns_zone_t *zone) {
   9499 	const char *me = "zone_sign";
   9500 	dns_db_t *db = NULL;
   9501 	dns_dbnode_t *node = NULL;
   9502 	dns_dbversion_t *version = NULL;
   9503 	dns_diff_t _sig_diff;
   9504 	dns_diff_t post_diff;
   9505 	dns__zonediff_t zonediff;
   9506 	dns_fixedname_t fixed;
   9507 	dns_fixedname_t nextfixed;
   9508 	dns_kasp_t *kasp;
   9509 	dns_name_t *name, *nextname;
   9510 	dns_rdataset_t rdataset;
   9511 	dns_signing_t *signing, *nextsigning;
   9512 	dns_signinglist_t cleanup;
   9513 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   9514 	int32_t signatures;
   9515 	bool check_ksk, keyset_kskonly, is_ksk, is_zsk;
   9516 	bool with_ksk, with_zsk;
   9517 	bool commit = false;
   9518 	bool is_bottom_of_zone;
   9519 	bool build_nsec = false;
   9520 	bool build_nsec3 = false;
   9521 	bool use_kasp = false;
   9522 	bool first;
   9523 	isc_result_t result;
   9524 	isc_stdtime_t now, inception, soaexpire, expire;
   9525 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   9526 	unsigned int i, j;
   9527 	unsigned int nkeys = 0;
   9528 	uint32_t nodes;
   9529 
   9530 	ENTER;
   9531 
   9532 	dns_rdataset_init(&rdataset);
   9533 	name = dns_fixedname_initname(&fixed);
   9534 	nextname = dns_fixedname_initname(&nextfixed);
   9535 	dns_diff_init(zone->mctx, &_sig_diff);
   9536 	dns_diff_init(zone->mctx, &post_diff);
   9537 	zonediff_init(&zonediff, &_sig_diff);
   9538 	ISC_LIST_INIT(cleanup);
   9539 
   9540 	/*
   9541 	 * Updates are disabled.  Pause for 1 minute.
   9542 	 */
   9543 	if (zone->update_disabled) {
   9544 		result = ISC_R_FAILURE;
   9545 		goto cleanup;
   9546 	}
   9547 
   9548 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9549 	if (zone->db != NULL) {
   9550 		dns_db_attach(zone->db, &db);
   9551 	}
   9552 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9553 	if (db == NULL) {
   9554 		result = ISC_R_FAILURE;
   9555 		goto cleanup;
   9556 	}
   9557 
   9558 	result = dns_db_newversion(db, &version);
   9559 	if (result != ISC_R_SUCCESS) {
   9560 		dnssec_log(zone, ISC_LOG_ERROR,
   9561 			   "zone_sign:dns_db_newversion -> %s",
   9562 			   dns_result_totext(result));
   9563 		goto cleanup;
   9564 	}
   9565 
   9566 	isc_stdtime_get(&now);
   9567 
   9568 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   9569 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   9570 	if (result != ISC_R_SUCCESS) {
   9571 		dnssec_log(zone, ISC_LOG_ERROR,
   9572 			   "zone_sign:dns__zone_findkeys -> %s",
   9573 			   dns_result_totext(result));
   9574 		goto cleanup;
   9575 	}
   9576 
   9577 	kasp = dns_zone_getkasp(zone);
   9578 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   9579 	inception = now - 3600; /* Allow for clock skew. */
   9580 	soaexpire = now + sigvalidityinterval;
   9581 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   9582 	if (expiryinterval > sigvalidityinterval) {
   9583 		expiryinterval = sigvalidityinterval;
   9584 	} else {
   9585 		expiryinterval = sigvalidityinterval - expiryinterval;
   9586 	}
   9587 
   9588 	/*
   9589 	 * Spread out signatures over time if they happen to be
   9590 	 * clumped.  We don't do this for each add_sigs() call as
   9591 	 * we still want some clustering to occur.
   9592 	 */
   9593 	if (sigvalidityinterval >= 3600U) {
   9594 		if (sigvalidityinterval > 7200U) {
   9595 			jitter = isc_random_uniform(expiryinterval);
   9596 		} else {
   9597 			jitter = isc_random_uniform(1200);
   9598 		}
   9599 		expire = soaexpire - jitter - 1;
   9600 	} else {
   9601 		expire = soaexpire - 1;
   9602 	}
   9603 
   9604 	/*
   9605 	 * We keep pulling nodes off each iterator in turn until
   9606 	 * we have no more nodes to pull off or we reach the limits
   9607 	 * for this quantum.
   9608 	 */
   9609 	nodes = zone->nodes;
   9610 	signatures = zone->signatures;
   9611 	signing = ISC_LIST_HEAD(zone->signing);
   9612 	first = true;
   9613 
   9614 	if (dns_zone_getkasp(zone) != NULL) {
   9615 		check_ksk = false;
   9616 		keyset_kskonly = true;
   9617 		use_kasp = true;
   9618 	} else {
   9619 		check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   9620 		keyset_kskonly = DNS_ZONE_OPTION(zone,
   9621 						 DNS_ZONEOPT_DNSKEYKSKONLY);
   9622 	}
   9623 	dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s",
   9624 		   use_kasp ? "yes" : "no");
   9625 
   9626 	/* Determine which type of chain to build */
   9627 	if (use_kasp) {
   9628 		build_nsec3 = dns_kasp_nsec3(kasp);
   9629 		build_nsec = !build_nsec3;
   9630 	} else {
   9631 		CHECK(dns_private_chains(db, version, zone->privatetype,
   9632 					 &build_nsec, &build_nsec3));
   9633 		/* If neither chain is found, default to NSEC */
   9634 		if (!build_nsec && !build_nsec3) {
   9635 			build_nsec = true;
   9636 		}
   9637 	}
   9638 
   9639 	while (signing != NULL && nodes-- > 0 && signatures > 0) {
   9640 		bool has_alg = false;
   9641 
   9642 		dns_dbiterator_pause(signing->dbiterator);
   9643 		nextsigning = ISC_LIST_NEXT(signing, link);
   9644 
   9645 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9646 		if (signing->done || signing->db != zone->db) {
   9647 			/*
   9648 			 * The zone has been reloaded.	We will have to
   9649 			 * created new signings as part of the reload
   9650 			 * process so we can destroy this one.
   9651 			 */
   9652 			ISC_LIST_UNLINK(zone->signing, signing, link);
   9653 			ISC_LIST_APPEND(cleanup, signing, link);
   9654 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9655 			goto next_signing;
   9656 		}
   9657 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9658 
   9659 		if (signing->db != db) {
   9660 			goto next_signing;
   9661 		}
   9662 
   9663 		is_bottom_of_zone = false;
   9664 
   9665 		if (first && signing->deleteit) {
   9666 			/*
   9667 			 * Remove the key we are deleting from consideration.
   9668 			 */
   9669 			for (i = 0, j = 0; i < nkeys; i++) {
   9670 				/*
   9671 				 * Find the key we want to remove.
   9672 				 */
   9673 				if (ALG(zone_keys[i]) == signing->algorithm &&
   9674 				    dst_key_id(zone_keys[i]) == signing->keyid)
   9675 				{
   9676 					bool ksk = false;
   9677 					isc_result_t ret = dst_key_getbool(
   9678 						zone_keys[i], DST_BOOL_KSK,
   9679 						&ksk);
   9680 					if (ret != ISC_R_SUCCESS) {
   9681 						ksk = KSK(zone_keys[i]);
   9682 					}
   9683 					if (ksk) {
   9684 						dst_key_free(&zone_keys[i]);
   9685 					}
   9686 					continue;
   9687 				}
   9688 				zone_keys[j] = zone_keys[i];
   9689 				j++;
   9690 			}
   9691 			for (i = j; i < nkeys; i++) {
   9692 				zone_keys[i] = NULL;
   9693 			}
   9694 			nkeys = j;
   9695 		}
   9696 
   9697 		dns_dbiterator_current(signing->dbiterator, &node, name);
   9698 
   9699 		if (signing->deleteit) {
   9700 			dns_dbiterator_pause(signing->dbiterator);
   9701 			CHECK(del_sig(db, version, name, node, nkeys,
   9702 				      signing->algorithm, signing->keyid,
   9703 				      &has_alg, zonediff.diff));
   9704 		}
   9705 
   9706 		/*
   9707 		 * On the first pass we need to check if the current node
   9708 		 * has not been obscured.
   9709 		 */
   9710 		if (first) {
   9711 			dns_fixedname_t ffound;
   9712 			dns_name_t *found;
   9713 			found = dns_fixedname_initname(&ffound);
   9714 			result = dns_db_find(
   9715 				db, name, version, dns_rdatatype_soa,
   9716 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   9717 			if ((result == DNS_R_DELEGATION ||
   9718 			     result == DNS_R_DNAME) &&
   9719 			    !dns_name_equal(name, found))
   9720 			{
   9721 				/*
   9722 				 * Remember the obscuring name so that
   9723 				 * we skip all obscured names.
   9724 				 */
   9725 				dns_name_copynf(found, name);
   9726 				is_bottom_of_zone = true;
   9727 				goto next_node;
   9728 			}
   9729 		}
   9730 
   9731 		/*
   9732 		 * Process one node.
   9733 		 */
   9734 		with_ksk = false;
   9735 		with_zsk = false;
   9736 		dns_dbiterator_pause(signing->dbiterator);
   9737 
   9738 		CHECK(check_if_bottom_of_zone(db, node, version,
   9739 					      &is_bottom_of_zone));
   9740 
   9741 		for (i = 0; !has_alg && i < nkeys; i++) {
   9742 			bool both = false;
   9743 
   9744 			/*
   9745 			 * Find the keys we want to sign with.
   9746 			 */
   9747 			if (!dst_key_isprivate(zone_keys[i])) {
   9748 				continue;
   9749 			}
   9750 			if (dst_key_inactive(zone_keys[i])) {
   9751 				continue;
   9752 			}
   9753 
   9754 			/*
   9755 			 * When adding look for the specific key.
   9756 			 */
   9757 			if (!signing->deleteit &&
   9758 			    (dst_key_alg(zone_keys[i]) != signing->algorithm ||
   9759 			     dst_key_id(zone_keys[i]) != signing->keyid))
   9760 			{
   9761 				continue;
   9762 			}
   9763 
   9764 			/*
   9765 			 * When deleting make sure we are properly signed
   9766 			 * with the algorithm that was being removed.
   9767 			 */
   9768 			if (signing->deleteit &&
   9769 			    ALG(zone_keys[i]) != signing->algorithm)
   9770 			{
   9771 				continue;
   9772 			}
   9773 
   9774 			/*
   9775 			 * Do we do KSK processing?
   9776 			 */
   9777 			if (check_ksk && !REVOKE(zone_keys[i])) {
   9778 				bool have_ksk, have_nonksk;
   9779 				if (KSK(zone_keys[i])) {
   9780 					have_ksk = true;
   9781 					have_nonksk = false;
   9782 				} else {
   9783 					have_ksk = false;
   9784 					have_nonksk = true;
   9785 				}
   9786 				for (j = 0; j < nkeys; j++) {
   9787 					if (j == i || (ALG(zone_keys[i]) !=
   9788 						       ALG(zone_keys[j])))
   9789 					{
   9790 						continue;
   9791 					}
   9792 					/*
   9793 					 * Don't consider inactive keys, however
   9794 					 * the key may be temporary offline, so
   9795 					 * do consider KSKs which private key
   9796 					 * files are unavailable.
   9797 					 */
   9798 					if (dst_key_inactive(zone_keys[j])) {
   9799 						continue;
   9800 					}
   9801 					if (REVOKE(zone_keys[j])) {
   9802 						continue;
   9803 					}
   9804 					if (KSK(zone_keys[j])) {
   9805 						have_ksk = true;
   9806 					} else if (dst_key_isprivate(
   9807 							   zone_keys[j]))
   9808 					{
   9809 						have_nonksk = true;
   9810 					}
   9811 					both = have_ksk && have_nonksk;
   9812 					if (both) {
   9813 						break;
   9814 					}
   9815 				}
   9816 			}
   9817 			if (use_kasp) {
   9818 				/*
   9819 				 * A dnssec-policy is found. Check what
   9820 				 * RRsets this key can sign.
   9821 				 */
   9822 				isc_result_t kresult;
   9823 				is_ksk = false;
   9824 				kresult = dst_key_getbool(
   9825 					zone_keys[i], DST_BOOL_KSK, &is_ksk);
   9826 				if (kresult != ISC_R_SUCCESS) {
   9827 					if (KSK(zone_keys[i])) {
   9828 						is_ksk = true;
   9829 					}
   9830 				}
   9831 
   9832 				is_zsk = false;
   9833 				kresult = dst_key_getbool(
   9834 					zone_keys[i], DST_BOOL_ZSK, &is_zsk);
   9835 				if (kresult != ISC_R_SUCCESS) {
   9836 					if (!KSK(zone_keys[i])) {
   9837 						is_zsk = true;
   9838 					}
   9839 				}
   9840 				/* Treat as if we have both KSK and ZSK. */
   9841 				both = true;
   9842 			} else if (both || REVOKE(zone_keys[i])) {
   9843 				is_ksk = KSK(zone_keys[i]);
   9844 				is_zsk = !KSK(zone_keys[i]);
   9845 			} else {
   9846 				is_ksk = false;
   9847 				is_zsk = true;
   9848 			}
   9849 
   9850 			/*
   9851 			 * If deleting signatures, we need to ensure that
   9852 			 * the RRset is still signed at least once by a
   9853 			 * KSK and a ZSK.
   9854 			 */
   9855 			if (signing->deleteit && is_zsk && with_zsk) {
   9856 				continue;
   9857 			}
   9858 
   9859 			if (signing->deleteit && is_ksk && with_ksk) {
   9860 				continue;
   9861 			}
   9862 
   9863 			CHECK(sign_a_node(
   9864 				db, zone, name, node, version, build_nsec3,
   9865 				build_nsec, zone_keys[i], inception, expire,
   9866 				zone_nsecttl(zone), is_ksk, is_zsk,
   9867 				(both && keyset_kskonly), is_bottom_of_zone,
   9868 				zonediff.diff, &signatures, zone->mctx));
   9869 			/*
   9870 			 * If we are adding we are done.  Look for other keys
   9871 			 * of the same algorithm if deleting.
   9872 			 */
   9873 			if (!signing->deleteit) {
   9874 				break;
   9875 			}
   9876 			if (is_zsk) {
   9877 				with_zsk = true;
   9878 			}
   9879 			if (is_ksk) {
   9880 				with_ksk = true;
   9881 			}
   9882 		}
   9883 
   9884 		/*
   9885 		 * Go onto next node.
   9886 		 */
   9887 	next_node:
   9888 		first = false;
   9889 		dns_db_detachnode(db, &node);
   9890 		do {
   9891 			result = dns_dbiterator_next(signing->dbiterator);
   9892 			if (result == ISC_R_NOMORE) {
   9893 				ISC_LIST_UNLINK(zone->signing, signing, link);
   9894 				ISC_LIST_APPEND(cleanup, signing, link);
   9895 				dns_dbiterator_pause(signing->dbiterator);
   9896 				if (nkeys != 0 && build_nsec) {
   9897 					/*
   9898 					 * We have finished regenerating the
   9899 					 * zone with a zone signing key.
   9900 					 * The NSEC chain is now complete and
   9901 					 * there is a full set of signatures
   9902 					 * for the zone.  We can now clear the
   9903 					 * OPT bit from the NSEC record.
   9904 					 */
   9905 					result = updatesecure(
   9906 						db, version, &zone->origin,
   9907 						zone_nsecttl(zone), false,
   9908 						&post_diff);
   9909 					if (result != ISC_R_SUCCESS) {
   9910 						dnssec_log(zone, ISC_LOG_ERROR,
   9911 							   "updatesecure -> %s",
   9912 							   dns_result_totext(
   9913 								   result));
   9914 						goto cleanup;
   9915 					}
   9916 				}
   9917 				result = updatesignwithkey(
   9918 					zone, signing, version, build_nsec3,
   9919 					zone_nsecttl(zone), &post_diff);
   9920 				if (result != ISC_R_SUCCESS) {
   9921 					dnssec_log(zone, ISC_LOG_ERROR,
   9922 						   "updatesignwithkey -> %s",
   9923 						   dns_result_totext(result));
   9924 					goto cleanup;
   9925 				}
   9926 				build_nsec = false;
   9927 				goto next_signing;
   9928 			} else if (result != ISC_R_SUCCESS) {
   9929 				dnssec_log(zone, ISC_LOG_ERROR,
   9930 					   "zone_sign:"
   9931 					   "dns_dbiterator_next -> %s",
   9932 					   dns_result_totext(result));
   9933 				goto cleanup;
   9934 			} else if (is_bottom_of_zone) {
   9935 				dns_dbiterator_current(signing->dbiterator,
   9936 						       &node, nextname);
   9937 				dns_db_detachnode(db, &node);
   9938 				if (!dns_name_issubdomain(nextname, name)) {
   9939 					break;
   9940 				}
   9941 			} else {
   9942 				break;
   9943 			}
   9944 		} while (1);
   9945 		continue;
   9946 
   9947 	next_signing:
   9948 		dns_dbiterator_pause(signing->dbiterator);
   9949 		signing = nextsigning;
   9950 		first = true;
   9951 	}
   9952 
   9953 	if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
   9954 		result = dns__zone_updatesigs(&post_diff, db, version,
   9955 					      zone_keys, nkeys, zone, inception,
   9956 					      expire, 0, now, check_ksk,
   9957 					      keyset_kskonly, &zonediff);
   9958 		if (result != ISC_R_SUCCESS) {
   9959 			dnssec_log(zone, ISC_LOG_ERROR,
   9960 				   "zone_sign:dns__zone_updatesigs -> %s",
   9961 				   dns_result_totext(result));
   9962 			goto cleanup;
   9963 		}
   9964 	}
   9965 
   9966 	/*
   9967 	 * Have we changed anything?
   9968 	 */
   9969 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   9970 		if (zonediff.offline) {
   9971 			commit = true;
   9972 		}
   9973 		result = ISC_R_SUCCESS;
   9974 		goto pauseall;
   9975 	}
   9976 
   9977 	commit = true;
   9978 
   9979 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   9980 			  &zonediff, zone_keys, nkeys, now, false);
   9981 	if (result != ISC_R_SUCCESS) {
   9982 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s",
   9983 			   dns_result_totext(result));
   9984 		goto cleanup;
   9985 	}
   9986 
   9987 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   9988 				   zone->updatemethod);
   9989 	if (result != ISC_R_SUCCESS) {
   9990 		dnssec_log(zone, ISC_LOG_ERROR,
   9991 			   "zone_sign:update_soa_serial -> %s",
   9992 			   dns_result_totext(result));
   9993 		goto cleanup;
   9994 	}
   9995 
   9996 	/*
   9997 	 * Generate maximum life time signatures so that the above loop
   9998 	 * termination is sensible.
   9999 	 */
   10000 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   10001 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   10002 			  inception, soaexpire, check_ksk, keyset_kskonly);
   10003 	if (result != ISC_R_SUCCESS) {
   10004 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s",
   10005 			   dns_result_totext(result));
   10006 		goto cleanup;
   10007 	}
   10008 
   10009 	/*
   10010 	 * Write changes to journal file.
   10011 	 */
   10012 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
   10013 
   10014 pauseall:
   10015 	/*
   10016 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   10017 	 */
   10018 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   10019 	     signing = ISC_LIST_NEXT(signing, link))
   10020 	{
   10021 		dns_dbiterator_pause(signing->dbiterator);
   10022 	}
   10023 
   10024 	for (signing = ISC_LIST_HEAD(cleanup); signing != NULL;
   10025 	     signing = ISC_LIST_NEXT(signing, link))
   10026 	{
   10027 		dns_dbiterator_pause(signing->dbiterator);
   10028 	}
   10029 
   10030 	/*
   10031 	 * Everything has succeeded. Commit the changes.
   10032 	 */
   10033 	dns_db_closeversion(db, &version, commit);
   10034 
   10035 	/*
   10036 	 * Everything succeeded so we can clean these up now.
   10037 	 */
   10038 	signing = ISC_LIST_HEAD(cleanup);
   10039 	while (signing != NULL) {
   10040 		ISC_LIST_UNLINK(cleanup, signing, link);
   10041 		dns_db_detach(&signing->db);
   10042 		dns_dbiterator_destroy(&signing->dbiterator);
   10043 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   10044 		signing = ISC_LIST_HEAD(cleanup);
   10045 	}
   10046 
   10047 	LOCK_ZONE(zone);
   10048 	set_resigntime(zone);
   10049 	if (commit) {
   10050 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   10051 		zone_needdump(zone, DNS_DUMP_DELAY);
   10052 	}
   10053 	UNLOCK_ZONE(zone);
   10054 
   10055 failure:
   10056 	if (result != ISC_R_SUCCESS) {
   10057 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s",
   10058 			   dns_result_totext(result));
   10059 	}
   10060 
   10061 cleanup:
   10062 	/*
   10063 	 * Pause all dbiterators.
   10064 	 */
   10065 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   10066 	     signing = ISC_LIST_NEXT(signing, link))
   10067 	{
   10068 		dns_dbiterator_pause(signing->dbiterator);
   10069 	}
   10070 
   10071 	/*
   10072 	 * Rollback the cleanup list.
   10073 	 */
   10074 	signing = ISC_LIST_HEAD(cleanup);
   10075 	while (signing != NULL) {
   10076 		ISC_LIST_UNLINK(cleanup, signing, link);
   10077 		ISC_LIST_PREPEND(zone->signing, signing, link);
   10078 		dns_dbiterator_first(signing->dbiterator);
   10079 		dns_dbiterator_pause(signing->dbiterator);
   10080 		signing = ISC_LIST_HEAD(cleanup);
   10081 	}
   10082 
   10083 	dns_diff_clear(&_sig_diff);
   10084 
   10085 	for (i = 0; i < nkeys; i++) {
   10086 		dst_key_free(&zone_keys[i]);
   10087 	}
   10088 
   10089 	if (node != NULL) {
   10090 		dns_db_detachnode(db, &node);
   10091 	}
   10092 
   10093 	if (version != NULL) {
   10094 		dns_db_closeversion(db, &version, false);
   10095 		dns_db_detach(&db);
   10096 	} else if (db != NULL) {
   10097 		dns_db_detach(&db);
   10098 	}
   10099 
   10100 	LOCK_ZONE(zone);
   10101 	if (ISC_LIST_HEAD(zone->signing) != NULL) {
   10102 		isc_interval_t interval;
   10103 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   10104 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   10105 		} else {
   10106 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   10107 		}
   10108 		isc_time_nowplusinterval(&zone->signingtime, &interval);
   10109 	} else {
   10110 		isc_time_settoepoch(&zone->signingtime);
   10111 	}
   10112 	UNLOCK_ZONE(zone);
   10113 
   10114 	INSIST(version == NULL);
   10115 }
   10116 
   10117 static isc_result_t
   10118 normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data,
   10119 	      int size) {
   10120 	dns_rdata_dnskey_t dnskey;
   10121 	dns_rdata_keydata_t keydata;
   10122 	isc_buffer_t buf;
   10123 	isc_result_t result;
   10124 
   10125 	dns_rdata_reset(target);
   10126 	isc_buffer_init(&buf, data, size);
   10127 
   10128 	switch (rr->type) {
   10129 	case dns_rdatatype_dnskey:
   10130 		result = dns_rdata_tostruct(rr, &dnskey, NULL);
   10131 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10132 		dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
   10133 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   10134 				     &dnskey, &buf);
   10135 		break;
   10136 	case dns_rdatatype_keydata:
   10137 		result = dns_rdata_tostruct(rr, &keydata, NULL);
   10138 		if (result == ISC_R_UNEXPECTEDEND) {
   10139 			return (result);
   10140 		}
   10141 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10142 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   10143 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   10144 				     &dnskey, &buf);
   10145 		break;
   10146 	default:
   10147 		UNREACHABLE();
   10148 	}
   10149 	return (ISC_R_SUCCESS);
   10150 }
   10151 
   10152 /*
   10153  * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
   10154  * a KEYDATA rdataset from the key zone.
   10155  *
   10156  * 'rr' contains either a DNSKEY record, or a KEYDATA record
   10157  *
   10158  * After normalizing keys to the same format (DNSKEY, with revoke bit
   10159  * cleared), return true if a key that matches 'rr' is found in
   10160  * 'rdset', or false if not.
   10161  */
   10162 
   10163 static bool
   10164 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
   10165 	unsigned char data1[4096], data2[4096];
   10166 	dns_rdata_t rdata, rdata1, rdata2;
   10167 	isc_result_t result;
   10168 
   10169 	dns_rdata_init(&rdata);
   10170 	dns_rdata_init(&rdata1);
   10171 	dns_rdata_init(&rdata2);
   10172 
   10173 	result = normalize_key(rr, &rdata1, data1, sizeof(data1));
   10174 	if (result != ISC_R_SUCCESS) {
   10175 		return (false);
   10176 	}
   10177 
   10178 	for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS;
   10179 	     result = dns_rdataset_next(rdset))
   10180 	{
   10181 		dns_rdata_reset(&rdata);
   10182 		dns_rdataset_current(rdset, &rdata);
   10183 		result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
   10184 		if (result != ISC_R_SUCCESS) {
   10185 			continue;
   10186 		}
   10187 		if (dns_rdata_compare(&rdata1, &rdata2) == 0) {
   10188 			return (true);
   10189 		}
   10190 	}
   10191 
   10192 	return (false);
   10193 }
   10194 
   10195 /*
   10196  * Calculate the refresh interval for a keydata zone, per
   10197  * RFC5011: MAX(1 hr,
   10198  *		MIN(15 days,
   10199  *		    1/2 * OrigTTL,
   10200  *		    1/2 * RRSigExpirationInterval))
   10201  * or for retries: MAX(1 hr,
   10202  *		       MIN(1 day,
   10203  *			   1/10 * OrigTTL,
   10204  *			   1/10 * RRSigExpirationInterval))
   10205  */
   10206 static isc_stdtime_t
   10207 refresh_time(dns_keyfetch_t *kfetch, bool retry) {
   10208 	isc_result_t result;
   10209 	uint32_t t;
   10210 	dns_rdataset_t *rdset;
   10211 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10212 	dns_rdata_sig_t sig;
   10213 	isc_stdtime_t now;
   10214 
   10215 	isc_stdtime_get(&now);
   10216 
   10217 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
   10218 		rdset = &kfetch->dnskeysigset;
   10219 	} else {
   10220 		return (now + dns_zone_mkey_hour);
   10221 	}
   10222 
   10223 	result = dns_rdataset_first(rdset);
   10224 	if (result != ISC_R_SUCCESS) {
   10225 		return (now + dns_zone_mkey_hour);
   10226 	}
   10227 
   10228 	dns_rdataset_current(rdset, &sigrr);
   10229 	result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10230 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10231 
   10232 	if (!retry) {
   10233 		t = sig.originalttl / 2;
   10234 
   10235 		if (isc_serial_gt(sig.timeexpire, now)) {
   10236 			uint32_t exp = (sig.timeexpire - now) / 2;
   10237 			if (t > exp) {
   10238 				t = exp;
   10239 			}
   10240 		}
   10241 
   10242 		if (t > (15 * dns_zone_mkey_day)) {
   10243 			t = (15 * dns_zone_mkey_day);
   10244 		}
   10245 
   10246 		if (t < dns_zone_mkey_hour) {
   10247 			t = dns_zone_mkey_hour;
   10248 		}
   10249 	} else {
   10250 		t = sig.originalttl / 10;
   10251 
   10252 		if (isc_serial_gt(sig.timeexpire, now)) {
   10253 			uint32_t exp = (sig.timeexpire - now) / 10;
   10254 			if (t > exp) {
   10255 				t = exp;
   10256 			}
   10257 		}
   10258 
   10259 		if (t > dns_zone_mkey_day) {
   10260 			t = dns_zone_mkey_day;
   10261 		}
   10262 
   10263 		if (t < dns_zone_mkey_hour) {
   10264 			t = dns_zone_mkey_hour;
   10265 		}
   10266 	}
   10267 
   10268 	return (now + t);
   10269 }
   10270 
   10271 /*
   10272  * This routine is called when no changes are needed in a KEYDATA
   10273  * record except to simply update the refresh timer.  Caller should
   10274  * hold zone lock.
   10275  */
   10276 static isc_result_t
   10277 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) {
   10278 	isc_result_t result;
   10279 	isc_buffer_t keyb;
   10280 	unsigned char key_buf[4096];
   10281 	dns_rdata_t rdata = DNS_RDATA_INIT;
   10282 	dns_rdata_keydata_t keydata;
   10283 	dns_name_t *name;
   10284 	dns_zone_t *zone = kfetch->zone;
   10285 	isc_stdtime_t now;
   10286 
   10287 	name = dns_fixedname_name(&kfetch->name);
   10288 	isc_stdtime_get(&now);
   10289 
   10290 	for (result = dns_rdataset_first(&kfetch->keydataset);
   10291 	     result == ISC_R_SUCCESS;
   10292 	     result = dns_rdataset_next(&kfetch->keydataset))
   10293 	{
   10294 		dns_rdata_reset(&rdata);
   10295 		dns_rdataset_current(&kfetch->keydataset, &rdata);
   10296 
   10297 		/* Delete old version */
   10298 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name,
   10299 				    0, &rdata));
   10300 
   10301 		/* Update refresh timer */
   10302 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   10303 		if (result == ISC_R_UNEXPECTEDEND) {
   10304 			continue;
   10305 		}
   10306 		if (result != ISC_R_SUCCESS) {
   10307 			goto failure;
   10308 		}
   10309 		keydata.refresh = refresh_time(kfetch, true);
   10310 		set_refreshkeytimer(zone, &keydata, now, false);
   10311 
   10312 		dns_rdata_reset(&rdata);
   10313 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10314 		CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass,
   10315 					   dns_rdatatype_keydata, &keydata,
   10316 					   &keyb));
   10317 
   10318 		/* Insert updated version */
   10319 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name,
   10320 				    0, &rdata));
   10321 	}
   10322 	result = ISC_R_SUCCESS;
   10323 failure:
   10324 	return (result);
   10325 }
   10326 
   10327 /*
   10328  * Verify that DNSKEY set is signed by the key specified in 'keydata'.
   10329  */
   10330 static bool
   10331 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
   10332 	isc_result_t result;
   10333 	dns_name_t *keyname;
   10334 	isc_mem_t *mctx;
   10335 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10336 	dns_rdata_t rr = DNS_RDATA_INIT;
   10337 	dns_rdata_rrsig_t sig;
   10338 	dns_rdata_dnskey_t dnskey;
   10339 	dst_key_t *dstkey = NULL;
   10340 	unsigned char key_buf[4096];
   10341 	isc_buffer_t keyb;
   10342 	bool answer = false;
   10343 
   10344 	REQUIRE(kfetch != NULL && keydata != NULL);
   10345 	REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
   10346 
   10347 	keyname = dns_fixedname_name(&kfetch->name);
   10348 	mctx = kfetch->zone->view->mctx;
   10349 
   10350 	/* Generate a key from keydata */
   10351 	isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10352 	dns_keydata_todnskey(keydata, &dnskey, NULL);
   10353 	dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
   10354 			     &dnskey, &keyb);
   10355 	result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
   10356 	if (result != ISC_R_SUCCESS) {
   10357 		return (false);
   10358 	}
   10359 
   10360 	/* See if that key generated any of the signatures */
   10361 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
   10362 	     result == ISC_R_SUCCESS;
   10363 	     result = dns_rdataset_next(&kfetch->dnskeysigset))
   10364 	{
   10365 		dns_fixedname_t fixed;
   10366 		dns_fixedname_init(&fixed);
   10367 
   10368 		dns_rdata_reset(&sigrr);
   10369 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
   10370 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10371 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10372 
   10373 		if (dst_key_alg(dstkey) == sig.algorithm &&
   10374 		    dst_key_rid(dstkey) == sig.keyid)
   10375 		{
   10376 			result = dns_dnssec_verify(
   10377 				keyname, &kfetch->dnskeyset, dstkey, false, 0,
   10378 				mctx, &sigrr, dns_fixedname_name(&fixed));
   10379 
   10380 			dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3),
   10381 				   "Confirm revoked DNSKEY is self-signed: %s",
   10382 				   dns_result_totext(result));
   10383 
   10384 			if (result == ISC_R_SUCCESS) {
   10385 				answer = true;
   10386 				break;
   10387 			}
   10388 		}
   10389 	}
   10390 
   10391 	dst_key_free(&dstkey);
   10392 	return (answer);
   10393 }
   10394 
   10395 /*
   10396  * A DNSKEY set has been fetched from the zone apex of a zone whose trust
   10397  * anchors are being managed; scan the keyset, and update the key zone and the
   10398  * local trust anchors according to RFC5011.
   10399  */
   10400 static void
   10401 keyfetch_done(isc_task_t *task, isc_event_t *event) {
   10402 	isc_result_t result, eresult;
   10403 	dns_fetchevent_t *devent;
   10404 	dns_keyfetch_t *kfetch;
   10405 	dns_zone_t *zone;
   10406 	isc_mem_t *mctx = NULL;
   10407 	dns_keytable_t *secroots = NULL;
   10408 	dns_dbversion_t *ver = NULL;
   10409 	dns_diff_t diff;
   10410 	bool alldone = false;
   10411 	bool commit = false;
   10412 	dns_name_t *keyname = NULL;
   10413 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10414 	dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
   10415 	dns_rdata_t keydatarr = DNS_RDATA_INIT;
   10416 	dns_rdata_rrsig_t sig;
   10417 	dns_rdata_dnskey_t dnskey;
   10418 	dns_rdata_keydata_t keydata;
   10419 	bool initializing;
   10420 	char namebuf[DNS_NAME_FORMATSIZE];
   10421 	unsigned char key_buf[4096];
   10422 	isc_buffer_t keyb;
   10423 	dst_key_t *dstkey = NULL;
   10424 	isc_stdtime_t now;
   10425 	int pending = 0;
   10426 	bool secure = false, initial = false;
   10427 	bool free_needed;
   10428 	dns_keynode_t *keynode = NULL;
   10429 	dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL;
   10430 	dns_rdataset_t *keydataset = NULL, dsset;
   10431 
   10432 	UNUSED(task);
   10433 	INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
   10434 	INSIST(event->ev_arg != NULL);
   10435 
   10436 	kfetch = event->ev_arg;
   10437 	zone = kfetch->zone;
   10438 	mctx = kfetch->mctx;
   10439 	keyname = dns_fixedname_name(&kfetch->name);
   10440 	dnskeys = &kfetch->dnskeyset;
   10441 	dnskeysigs = &kfetch->dnskeysigset;
   10442 	keydataset = &kfetch->keydataset;
   10443 
   10444 	devent = (dns_fetchevent_t *)event;
   10445 	eresult = devent->result;
   10446 
   10447 	/* Free resources which are not of interest */
   10448 	if (devent->node != NULL) {
   10449 		dns_db_detachnode(devent->db, &devent->node);
   10450 	}
   10451 	if (devent->db != NULL) {
   10452 		dns_db_detach(&devent->db);
   10453 	}
   10454 	isc_event_free(&event);
   10455 	dns_resolver_destroyfetch(&kfetch->fetch);
   10456 
   10457 	LOCK_ZONE(zone);
   10458 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) {
   10459 		goto cleanup;
   10460 	}
   10461 
   10462 	isc_stdtime_get(&now);
   10463 	dns_name_format(keyname, namebuf, sizeof(namebuf));
   10464 
   10465 	result = dns_view_getsecroots(zone->view, &secroots);
   10466 	INSIST(result == ISC_R_SUCCESS);
   10467 
   10468 	dns_diff_init(mctx, &diff);
   10469 
   10470 	CHECK(dns_db_newversion(kfetch->db, &ver));
   10471 
   10472 	zone->refreshkeycount--;
   10473 	alldone = (zone->refreshkeycount == 0);
   10474 
   10475 	if (alldone) {
   10476 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10477 	}
   10478 
   10479 	dnssec_log(zone, ISC_LOG_DEBUG(3),
   10480 		   "Returned from key fetch in keyfetch_done() for '%s': %s",
   10481 		   namebuf, dns_result_totext(eresult));
   10482 
   10483 	/* Fetch failed */
   10484 	if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) {
   10485 		dnssec_log(zone, ISC_LOG_WARNING,
   10486 			   "Unable to fetch DNSKEY set '%s': %s", namebuf,
   10487 			   dns_result_totext(eresult));
   10488 		CHECK(minimal_update(kfetch, ver, &diff));
   10489 		goto done;
   10490 	}
   10491 
   10492 	/* No RRSIGs found */
   10493 	if (!dns_rdataset_isassociated(dnskeysigs)) {
   10494 		dnssec_log(zone, ISC_LOG_WARNING,
   10495 			   "No DNSKEY RRSIGs found for '%s': %s", namebuf,
   10496 			   dns_result_totext(eresult));
   10497 		CHECK(minimal_update(kfetch, ver, &diff));
   10498 		goto done;
   10499 	}
   10500 
   10501 	/*
   10502 	 * Clear any cached trust level, as we need to run validation
   10503 	 * over again; trusted keys might have changed.
   10504 	 */
   10505 	dnskeys->trust = dnskeysigs->trust = dns_trust_none;
   10506 
   10507 	/* Look up the trust anchor */
   10508 	result = dns_keytable_find(secroots, keyname, &keynode);
   10509 	if (result != ISC_R_SUCCESS) {
   10510 		goto anchors_done;
   10511 	}
   10512 
   10513 	/*
   10514 	 * If the keynode has a DS trust anchor, use it for verification.
   10515 	 */
   10516 	dns_rdataset_init(&dsset);
   10517 	if (dns_keynode_dsset(keynode, &dsset)) {
   10518 		for (result = dns_rdataset_first(dnskeysigs);
   10519 		     result == ISC_R_SUCCESS;
   10520 		     result = dns_rdataset_next(dnskeysigs))
   10521 		{
   10522 			isc_result_t tresult;
   10523 			dns_rdata_t keyrdata = DNS_RDATA_INIT;
   10524 
   10525 			dns_rdata_reset(&sigrr);
   10526 			dns_rdataset_current(dnskeysigs, &sigrr);
   10527 			result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10528 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10529 
   10530 			for (tresult = dns_rdataset_first(&dsset);
   10531 			     tresult == ISC_R_SUCCESS;
   10532 			     tresult = dns_rdataset_next(&dsset))
   10533 			{
   10534 				dns_rdata_t dsrdata = DNS_RDATA_INIT;
   10535 				dns_rdata_ds_t ds;
   10536 
   10537 				dns_rdata_reset(&dsrdata);
   10538 				dns_rdataset_current(&dsset, &dsrdata);
   10539 				tresult = dns_rdata_tostruct(&dsrdata, &ds,
   10540 							     NULL);
   10541 				RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
   10542 
   10543 				if (ds.key_tag != sig.keyid ||
   10544 				    ds.algorithm != sig.algorithm)
   10545 				{
   10546 					continue;
   10547 				}
   10548 
   10549 				result = dns_dnssec_matchdskey(
   10550 					keyname, &dsrdata, dnskeys, &keyrdata);
   10551 				if (result == ISC_R_SUCCESS) {
   10552 					break;
   10553 				}
   10554 			}
   10555 
   10556 			if (tresult == ISC_R_NOMORE) {
   10557 				continue;
   10558 			}
   10559 
   10560 			result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
   10561 							 mctx, &dstkey);
   10562 			if (result != ISC_R_SUCCESS) {
   10563 				continue;
   10564 			}
   10565 
   10566 			result = dns_dnssec_verify(keyname, dnskeys, dstkey,
   10567 						   false, 0, mctx, &sigrr,
   10568 						   NULL);
   10569 			dst_key_free(&dstkey);
   10570 
   10571 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   10572 				   "Verifying DNSKEY set for zone "
   10573 				   "'%s' using DS %d/%d: %s",
   10574 				   namebuf, sig.keyid, sig.algorithm,
   10575 				   dns_result_totext(result));
   10576 
   10577 			if (result == ISC_R_SUCCESS) {
   10578 				dnskeys->trust = dns_trust_secure;
   10579 				dnskeysigs->trust = dns_trust_secure;
   10580 				initial = dns_keynode_initial(keynode);
   10581 				dns_keynode_trust(keynode);
   10582 				secure = true;
   10583 				break;
   10584 			}
   10585 		}
   10586 		dns_rdataset_disassociate(&dsset);
   10587 	}
   10588 
   10589 anchors_done:
   10590 	if (keynode != NULL) {
   10591 		dns_keytable_detachkeynode(secroots, &keynode);
   10592 	}
   10593 
   10594 	/*
   10595 	 * If we were not able to verify the answer using the current
   10596 	 * trusted keys then all we can do is look at any revoked keys.
   10597 	 */
   10598 	if (!secure) {
   10599 		dnssec_log(zone, ISC_LOG_INFO,
   10600 			   "DNSKEY set for zone '%s' could not be verified "
   10601 			   "with current keys",
   10602 			   namebuf);
   10603 	}
   10604 
   10605 	/*
   10606 	 * First scan keydataset to find keys that are not in dnskeyset
   10607 	 *   - Missing keys which are not scheduled for removal,
   10608 	 *     log a warning
   10609 	 *   - Missing keys which are scheduled for removal and
   10610 	 *     the remove hold-down timer has completed should
   10611 	 *     be removed from the key zone
   10612 	 *   - Missing keys whose acceptance timers have not yet
   10613 	 *     completed, log a warning and reset the acceptance
   10614 	 *     timer to 30 days in the future
   10615 	 *   - All keys not being removed have their refresh timers
   10616 	 *     updated
   10617 	 */
   10618 	initializing = true;
   10619 	for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS;
   10620 	     result = dns_rdataset_next(keydataset))
   10621 	{
   10622 		dns_keytag_t keytag;
   10623 
   10624 		dns_rdata_reset(&keydatarr);
   10625 		dns_rdataset_current(keydataset, &keydatarr);
   10626 		result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10627 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10628 
   10629 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   10630 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10631 		if (result != ISC_R_SUCCESS) {
   10632 			/*
   10633 			 * Skip if we cannot compute the key tag.
   10634 			 * This may happen if the algorithm is unsupported
   10635 			 */
   10636 			dns_zone_log(zone, ISC_LOG_ERROR,
   10637 				     "Cannot compute tag for key in zone %s: "
   10638 				     "%s "
   10639 				     "(skipping)",
   10640 				     namebuf, dns_result_totext(result));
   10641 			continue;
   10642 		}
   10643 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10644 
   10645 		/*
   10646 		 * If any keydata record has a nonzero add holddown, then
   10647 		 * there was a pre-existing trust anchor for this domain;
   10648 		 * that means we are *not* initializing it and shouldn't
   10649 		 * automatically trust all the keys we find at the zone apex.
   10650 		 */
   10651 		initializing = initializing && (keydata.addhd == 0);
   10652 
   10653 		if (!matchkey(dnskeys, &keydatarr)) {
   10654 			bool deletekey = false;
   10655 
   10656 			if (!secure) {
   10657 				if (keydata.removehd != 0 &&
   10658 				    keydata.removehd <= now)
   10659 				{
   10660 					deletekey = true;
   10661 				}
   10662 			} else if (keydata.addhd == 0) {
   10663 				deletekey = true;
   10664 			} else if (keydata.addhd > now) {
   10665 				dnssec_log(zone, ISC_LOG_INFO,
   10666 					   "Pending key %d for zone %s "
   10667 					   "unexpectedly missing "
   10668 					   "restarting 30-day acceptance "
   10669 					   "timer",
   10670 					   keytag, namebuf);
   10671 				if (keydata.addhd < now + dns_zone_mkey_month) {
   10672 					keydata.addhd = now +
   10673 							dns_zone_mkey_month;
   10674 				}
   10675 				keydata.refresh = refresh_time(kfetch, false);
   10676 			} else if (keydata.removehd == 0) {
   10677 				dnssec_log(zone, ISC_LOG_INFO,
   10678 					   "Active key %d for zone %s "
   10679 					   "unexpectedly missing",
   10680 					   keytag, namebuf);
   10681 				keydata.refresh = now + dns_zone_mkey_hour;
   10682 			} else if (keydata.removehd <= now) {
   10683 				deletekey = true;
   10684 				dnssec_log(zone, ISC_LOG_INFO,
   10685 					   "Revoked key %d for zone %s "
   10686 					   "missing: deleting from "
   10687 					   "managed keys database",
   10688 					   keytag, namebuf);
   10689 			} else {
   10690 				keydata.refresh = refresh_time(kfetch, false);
   10691 			}
   10692 
   10693 			if (secure || deletekey) {
   10694 				/* Delete old version */
   10695 				CHECK(update_one_rr(kfetch->db, ver, &diff,
   10696 						    DNS_DIFFOP_DEL, keyname, 0,
   10697 						    &keydatarr));
   10698 			}
   10699 
   10700 			if (!secure || deletekey) {
   10701 				continue;
   10702 			}
   10703 
   10704 			dns_rdata_reset(&keydatarr);
   10705 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10706 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10707 					     dns_rdatatype_keydata, &keydata,
   10708 					     &keyb);
   10709 
   10710 			/* Insert updated version */
   10711 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10712 					    DNS_DIFFOP_ADD, keyname, 0,
   10713 					    &keydatarr));
   10714 
   10715 			set_refreshkeytimer(zone, &keydata, now, false);
   10716 		}
   10717 	}
   10718 
   10719 	/*
   10720 	 * Next scan dnskeyset:
   10721 	 *   - If new keys are found (i.e., lacking a match in keydataset)
   10722 	 *     add them to the key zone and set the acceptance timer
   10723 	 *     to 30 days in the future (or to immediately if we've
   10724 	 *     determined that we're initializing the zone for the
   10725 	 *     first time)
   10726 	 *   - Previously-known keys that have been revoked
   10727 	 *     must be scheduled for removal from the key zone (or,
   10728 	 *     if they hadn't been accepted as trust anchors yet
   10729 	 *     anyway, removed at once)
   10730 	 *   - Previously-known unrevoked keys whose acceptance timers
   10731 	 *     have completed are promoted to trust anchors
   10732 	 *   - All keys not being removed have their refresh
   10733 	 *     timers updated
   10734 	 */
   10735 	for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS;
   10736 	     result = dns_rdataset_next(dnskeys))
   10737 	{
   10738 		bool revoked = false;
   10739 		bool newkey = false;
   10740 		bool updatekey = false;
   10741 		bool deletekey = false;
   10742 		bool trustkey = false;
   10743 		dns_keytag_t keytag;
   10744 
   10745 		dns_rdata_reset(&dnskeyrr);
   10746 		dns_rdataset_current(dnskeys, &dnskeyrr);
   10747 		result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10748 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10749 
   10750 		/* Skip ZSK's */
   10751 		if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
   10752 			continue;
   10753 		}
   10754 
   10755 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10756 		if (result != ISC_R_SUCCESS) {
   10757 			/*
   10758 			 * Skip if we cannot compute the key tag.
   10759 			 * This may happen if the algorithm is unsupported
   10760 			 */
   10761 			dns_zone_log(zone, ISC_LOG_ERROR,
   10762 				     "Cannot compute tag for key in zone %s: "
   10763 				     "%s "
   10764 				     "(skipping)",
   10765 				     namebuf, dns_result_totext(result));
   10766 			continue;
   10767 		}
   10768 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10769 
   10770 		revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
   10771 
   10772 		if (matchkey(keydataset, &dnskeyrr)) {
   10773 			dns_rdata_reset(&keydatarr);
   10774 			dns_rdataset_current(keydataset, &keydatarr);
   10775 			result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10776 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10777 
   10778 			if (revoked && revocable(kfetch, &keydata)) {
   10779 				if (keydata.addhd > now) {
   10780 					/*
   10781 					 * Key wasn't trusted yet, and now
   10782 					 * it's been revoked?  Just remove it
   10783 					 */
   10784 					deletekey = true;
   10785 					dnssec_log(zone, ISC_LOG_INFO,
   10786 						   "Pending key %d for "
   10787 						   "zone %s is now revoked: "
   10788 						   "deleting from the "
   10789 						   "managed keys database",
   10790 						   keytag, namebuf);
   10791 				} else if (keydata.removehd == 0) {
   10792 					/*
   10793 					 * Remove key from secroots.
   10794 					 */
   10795 					dns_view_untrust(zone->view, keyname,
   10796 							 &dnskey);
   10797 
   10798 					/* If initializing, delete now */
   10799 					if (keydata.addhd == 0) {
   10800 						deletekey = true;
   10801 					} else {
   10802 						keydata.removehd =
   10803 							now +
   10804 							dns_zone_mkey_month;
   10805 						keydata.flags |=
   10806 							DNS_KEYFLAG_REVOKE;
   10807 					}
   10808 
   10809 					dnssec_log(zone, ISC_LOG_INFO,
   10810 						   "Trusted key %d for "
   10811 						   "zone %s is now revoked",
   10812 						   keytag, namebuf);
   10813 				} else if (keydata.removehd < now) {
   10814 					/* Scheduled for removal */
   10815 					deletekey = true;
   10816 
   10817 					dnssec_log(zone, ISC_LOG_INFO,
   10818 						   "Revoked key %d for "
   10819 						   "zone %s removal timer "
   10820 						   "complete: deleting from "
   10821 						   "the managed keys database",
   10822 						   keytag, namebuf);
   10823 				}
   10824 			} else if (revoked && keydata.removehd == 0) {
   10825 				dnssec_log(zone, ISC_LOG_WARNING,
   10826 					   "Active key %d for zone "
   10827 					   "%s is revoked but "
   10828 					   "did not self-sign; "
   10829 					   "ignoring",
   10830 					   keytag, namebuf);
   10831 				continue;
   10832 			} else if (secure) {
   10833 				if (keydata.removehd != 0) {
   10834 					/*
   10835 					 * Key isn't revoked--but it
   10836 					 * seems it used to be.
   10837 					 * Remove it now and add it
   10838 					 * back as if it were a fresh key,
   10839 					 * with a 30-day acceptance timer.
   10840 					 */
   10841 					deletekey = true;
   10842 					newkey = true;
   10843 					keydata.removehd = 0;
   10844 					keydata.addhd = now +
   10845 							dns_zone_mkey_month;
   10846 
   10847 					dnssec_log(zone, ISC_LOG_INFO,
   10848 						   "Revoked key %d for "
   10849 						   "zone %s has returned: "
   10850 						   "starting 30-day "
   10851 						   "acceptance timer",
   10852 						   keytag, namebuf);
   10853 				} else if (keydata.addhd > now) {
   10854 					pending++;
   10855 				} else if (keydata.addhd == 0) {
   10856 					keydata.addhd = now;
   10857 				}
   10858 
   10859 				if (keydata.addhd <= now) {
   10860 					trustkey = true;
   10861 					dnssec_log(zone, ISC_LOG_INFO,
   10862 						   "Key %d for zone %s "
   10863 						   "is now trusted (%s)",
   10864 						   keytag, namebuf,
   10865 						   initial ? "initializing key "
   10866 							     "verified"
   10867 							   : "acceptance timer "
   10868 							     "complete");
   10869 				}
   10870 			} else if (keydata.addhd > now) {
   10871 				/*
   10872 				 * Not secure, and key is pending:
   10873 				 * reset the acceptance timer
   10874 				 */
   10875 				pending++;
   10876 				keydata.addhd = now + dns_zone_mkey_month;
   10877 				dnssec_log(zone, ISC_LOG_INFO,
   10878 					   "Pending key %d "
   10879 					   "for zone %s was "
   10880 					   "not validated: restarting "
   10881 					   "30-day acceptance timer",
   10882 					   keytag, namebuf);
   10883 			}
   10884 
   10885 			if (!deletekey && !newkey) {
   10886 				updatekey = true;
   10887 			}
   10888 		} else if (secure) {
   10889 			/*
   10890 			 * Key wasn't in the key zone but it's
   10891 			 * revoked now anyway, so just skip it
   10892 			 */
   10893 			if (revoked) {
   10894 				continue;
   10895 			}
   10896 
   10897 			/* Key wasn't in the key zone: add it */
   10898 			newkey = true;
   10899 
   10900 			if (initializing) {
   10901 				dnssec_log(zone, ISC_LOG_WARNING,
   10902 					   "Initializing automatic trust "
   10903 					   "anchor management for zone '%s'; "
   10904 					   "DNSKEY ID %d is now trusted, "
   10905 					   "waiving the normal 30-day "
   10906 					   "waiting period.",
   10907 					   namebuf, keytag);
   10908 				trustkey = true;
   10909 			} else {
   10910 				dnssec_log(zone, ISC_LOG_INFO,
   10911 					   "New key %d observed "
   10912 					   "for zone '%s': "
   10913 					   "starting 30-day "
   10914 					   "acceptance timer",
   10915 					   keytag, namebuf);
   10916 			}
   10917 		} else {
   10918 			/*
   10919 			 * No previously known key, and the key is not
   10920 			 * secure, so skip it.
   10921 			 */
   10922 			continue;
   10923 		}
   10924 
   10925 		/* Delete old version */
   10926 		if (deletekey || !newkey) {
   10927 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10928 					    DNS_DIFFOP_DEL, keyname, 0,
   10929 					    &keydatarr));
   10930 		}
   10931 
   10932 		if (updatekey) {
   10933 			/* Set refresh timer */
   10934 			keydata.refresh = refresh_time(kfetch, false);
   10935 			dns_rdata_reset(&keydatarr);
   10936 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10937 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10938 					     dns_rdatatype_keydata, &keydata,
   10939 					     &keyb);
   10940 
   10941 			/* Insert updated version */
   10942 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10943 					    DNS_DIFFOP_ADD, keyname, 0,
   10944 					    &keydatarr));
   10945 		} else if (newkey) {
   10946 			/* Convert DNSKEY to KEYDATA */
   10947 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10948 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10949 			dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
   10950 					       NULL);
   10951 			keydata.addhd = initializing
   10952 						? now
   10953 						: now + dns_zone_mkey_month;
   10954 			keydata.refresh = refresh_time(kfetch, false);
   10955 			dns_rdata_reset(&keydatarr);
   10956 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10957 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10958 					     dns_rdatatype_keydata, &keydata,
   10959 					     &keyb);
   10960 
   10961 			/* Insert into key zone */
   10962 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10963 					    DNS_DIFFOP_ADD, keyname, 0,
   10964 					    &keydatarr));
   10965 		}
   10966 
   10967 		if (trustkey) {
   10968 			/* Trust this key. */
   10969 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10970 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10971 			trust_key(zone, keyname, &dnskey, false);
   10972 		}
   10973 
   10974 		if (secure && !deletekey) {
   10975 			INSIST(newkey || updatekey);
   10976 			set_refreshkeytimer(zone, &keydata, now, false);
   10977 		}
   10978 	}
   10979 
   10980 	/*
   10981 	 * RFC5011 says, "A trust point that has all of its trust anchors
   10982 	 * revoked is considered deleted and is treated as if the trust
   10983 	 * point was never configured."  But if someone revoked their
   10984 	 * active key before the standby was trusted, that would mean the
   10985 	 * zone would suddenly be nonsecured.  We avoid this by checking to
   10986 	 * see if there's pending keydata.  If so, we put a null key in
   10987 	 * the security roots; then all queries to the zone will fail.
   10988 	 */
   10989 	if (pending != 0) {
   10990 		fail_secure(zone, keyname);
   10991 	}
   10992 
   10993 done:
   10994 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10995 		/* Write changes to journal file. */
   10996 		CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx,
   10997 					zone->updatemethod));
   10998 		CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
   10999 		commit = true;
   11000 
   11001 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   11002 		zone_needdump(zone, 30);
   11003 	} else if (result == ISC_R_NOMORE) {
   11004 		/*
   11005 		 * If "updatekey" was true for all keys found in the DNSKEY
   11006 		 * response and the previous update of those keys happened
   11007 		 * during the same second (only possible if a key refresh was
   11008 		 * externally triggered), it may happen that all relevant
   11009 		 * update_one_rr() calls will return ISC_R_SUCCESS, but
   11010 		 * diff.tuples will remain empty.  Reset result to
   11011 		 * ISC_R_SUCCESS to prevent a bogus warning from being logged.
   11012 		 */
   11013 		result = ISC_R_SUCCESS;
   11014 	}
   11015 
   11016 failure:
   11017 	if (result != ISC_R_SUCCESS) {
   11018 		dnssec_log(zone, ISC_LOG_ERROR,
   11019 			   "error during managed-keys processing (%s): "
   11020 			   "DNSSEC validation may be at risk",
   11021 			   isc_result_totext(result));
   11022 	}
   11023 	dns_diff_clear(&diff);
   11024 	if (ver != NULL) {
   11025 		dns_db_closeversion(kfetch->db, &ver, commit);
   11026 	}
   11027 
   11028 cleanup:
   11029 	dns_db_detach(&kfetch->db);
   11030 
   11031 	/* The zone must be managed */
   11032 	INSIST(kfetch->zone->task != NULL);
   11033 	isc_refcount_decrement(&zone->irefs);
   11034 
   11035 	if (dns_rdataset_isassociated(keydataset)) {
   11036 		dns_rdataset_disassociate(keydataset);
   11037 	}
   11038 	if (dns_rdataset_isassociated(dnskeys)) {
   11039 		dns_rdataset_disassociate(dnskeys);
   11040 	}
   11041 	if (dns_rdataset_isassociated(dnskeysigs)) {
   11042 		dns_rdataset_disassociate(dnskeysigs);
   11043 	}
   11044 
   11045 	dns_name_free(keyname, mctx);
   11046 	isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(dns_keyfetch_t));
   11047 
   11048 	if (secroots != NULL) {
   11049 		dns_keytable_detach(&secroots);
   11050 	}
   11051 
   11052 	free_needed = exit_check(zone);
   11053 	UNLOCK_ZONE(zone);
   11054 
   11055 	if (free_needed) {
   11056 		zone_free(zone);
   11057 	}
   11058 
   11059 	INSIST(ver == NULL);
   11060 }
   11061 
   11062 static void
   11063 retry_keyfetch(dns_keyfetch_t *kfetch, dns_name_t *kname) {
   11064 	isc_time_t timenow, timethen;
   11065 	dns_zone_t *zone = kfetch->zone;
   11066 	bool free_needed;
   11067 
   11068 	/*
   11069 	 * Error during a key fetch; cancel and retry in an hour.
   11070 	 */
   11071 	LOCK_ZONE(zone);
   11072 	zone->refreshkeycount--;
   11073 	isc_refcount_decrement(&zone->irefs);
   11074 	dns_db_detach(&kfetch->db);
   11075 	dns_rdataset_disassociate(&kfetch->keydataset);
   11076 	dns_name_free(kname, zone->mctx);
   11077 	isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(*kfetch));
   11078 	dnssec_log(zone, ISC_LOG_WARNING,
   11079 		   "Failed to create fetch for DNSKEY update");
   11080 
   11081 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11082 		/* Don't really retry if we are exiting */
   11083 		char timebuf[80];
   11084 
   11085 		TIME_NOW(&timenow);
   11086 		DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
   11087 		zone->refreshkeytime = timethen;
   11088 		zone_settimer(zone, &timenow);
   11089 
   11090 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   11091 		dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
   11092 			   timebuf);
   11093 	}
   11094 
   11095 	free_needed = exit_check(zone);
   11096 	UNLOCK_ZONE(zone);
   11097 
   11098 	if (free_needed) {
   11099 		zone_free(zone);
   11100 	}
   11101 }
   11102 
   11103 static void
   11104 do_keyfetch(isc_task_t *task, isc_event_t *event) {
   11105 	isc_result_t result;
   11106 	dns_keyfetch_t *kfetch = (dns_keyfetch_t *)event->ev_arg;
   11107 	dns_name_t *kname = dns_fixedname_name(&kfetch->name);
   11108 	dns_zone_t *zone = kfetch->zone;
   11109 
   11110 	UNUSED(task);
   11111 
   11112 	isc_event_free(&event);
   11113 
   11114 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11115 		retry_keyfetch(kfetch, kname);
   11116 		return;
   11117 	}
   11118 
   11119 	/*
   11120 	 * Use of DNS_FETCHOPT_NOCACHED is essential here.  If it is not
   11121 	 * set and the cache still holds a non-expired, validated version
   11122 	 * of the RRset being queried for by the time the response is
   11123 	 * received, the cached RRset will be passed to keyfetch_done()
   11124 	 * instead of the one received in the response as the latter will
   11125 	 * have a lower trust level due to not being validated until
   11126 	 * keyfetch_done() is called.
   11127 	 */
   11128 	result = dns_resolver_createfetch(
   11129 		zone->view->resolver, kname, dns_rdatatype_dnskey, NULL, NULL,
   11130 		NULL, NULL, 0,
   11131 		DNS_FETCHOPT_NOVALIDATE | DNS_FETCHOPT_UNSHARED |
   11132 			DNS_FETCHOPT_NOCACHED,
   11133 		0, NULL, zone->task, keyfetch_done, kfetch, &kfetch->dnskeyset,
   11134 		&kfetch->dnskeysigset, &kfetch->fetch);
   11135 
   11136 	if (result != ISC_R_SUCCESS) {
   11137 		retry_keyfetch(kfetch, kname);
   11138 	}
   11139 }
   11140 
   11141 /*
   11142  * Refresh the data in the key zone.  Initiate a fetch to look up
   11143  * DNSKEY records at the trust anchor name.
   11144  */
   11145 static void
   11146 zone_refreshkeys(dns_zone_t *zone) {
   11147 	const char me[] = "zone_refreshkeys";
   11148 	isc_result_t result;
   11149 	dns_rriterator_t rrit;
   11150 	dns_db_t *db = NULL;
   11151 	dns_dbversion_t *ver = NULL;
   11152 	dns_diff_t diff;
   11153 	dns_rdata_t rdata = DNS_RDATA_INIT;
   11154 	dns_rdata_keydata_t kd;
   11155 	isc_stdtime_t now;
   11156 	bool commit = false;
   11157 	bool fetching = false;
   11158 	bool timerset = false;
   11159 
   11160 	ENTER;
   11161 	REQUIRE(zone->db != NULL);
   11162 
   11163 	isc_stdtime_get(&now);
   11164 
   11165 	LOCK_ZONE(zone);
   11166 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11167 		isc_time_settoepoch(&zone->refreshkeytime);
   11168 		UNLOCK_ZONE(zone);
   11169 		return;
   11170 	}
   11171 
   11172 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11173 	dns_db_attach(zone->db, &db);
   11174 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11175 
   11176 	dns_diff_init(zone->mctx, &diff);
   11177 
   11178 	CHECK(dns_db_newversion(db, &ver));
   11179 
   11180 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
   11181 
   11182 	dns_rriterator_init(&rrit, db, ver, 0);
   11183 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   11184 	     result = dns_rriterator_nextrrset(&rrit))
   11185 	{
   11186 		isc_stdtime_t timer = 0xffffffff;
   11187 		dns_name_t *name = NULL, *kname = NULL;
   11188 		dns_rdataset_t *kdset = NULL;
   11189 		uint32_t ttl;
   11190 
   11191 		dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
   11192 		if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
   11193 		    !dns_rdataset_isassociated(kdset))
   11194 		{
   11195 			continue;
   11196 		}
   11197 
   11198 		/*
   11199 		 * Scan the stored keys looking for ones that need
   11200 		 * removal or refreshing
   11201 		 */
   11202 		for (result = dns_rdataset_first(kdset);
   11203 		     result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset))
   11204 		{
   11205 			dns_rdata_reset(&rdata);
   11206 			dns_rdataset_current(kdset, &rdata);
   11207 			result = dns_rdata_tostruct(&rdata, &kd, NULL);
   11208 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   11209 
   11210 			/* Removal timer expired? */
   11211 			if (kd.removehd != 0 && kd.removehd < now) {
   11212 				dns_rriterator_pause(&rrit);
   11213 				CHECK(update_one_rr(db, ver, &diff,
   11214 						    DNS_DIFFOP_DEL, name, ttl,
   11215 						    &rdata));
   11216 				continue;
   11217 			}
   11218 
   11219 			/* Acceptance timer expired? */
   11220 			if (kd.addhd <= now) {
   11221 				timer = kd.addhd;
   11222 			}
   11223 
   11224 			/* Or do we just need to refresh the keyset? */
   11225 			if (timer > kd.refresh) {
   11226 				timer = kd.refresh;
   11227 			}
   11228 
   11229 			dns_rriterator_pause(&rrit);
   11230 			set_refreshkeytimer(zone, &kd, now, false);
   11231 			timerset = true;
   11232 		}
   11233 
   11234 		if (timer > now) {
   11235 			continue;
   11236 		}
   11237 
   11238 		dns_rriterator_pause(&rrit);
   11239 
   11240 #ifdef ENABLE_AFL
   11241 		if (!dns_fuzzing_resolver) {
   11242 #endif /* ifdef ENABLE_AFL */
   11243 			dns_keyfetch_t *kfetch = NULL;
   11244 			isc_event_t *e;
   11245 
   11246 			kfetch = isc_mem_get(zone->mctx,
   11247 					     sizeof(dns_keyfetch_t));
   11248 			*kfetch = (dns_keyfetch_t){ .zone = zone };
   11249 			isc_mem_attach(zone->mctx, &kfetch->mctx);
   11250 
   11251 			zone->refreshkeycount++;
   11252 			isc_refcount_increment0(&zone->irefs);
   11253 			kname = dns_fixedname_initname(&kfetch->name);
   11254 			dns_name_dup(name, zone->mctx, kname);
   11255 			dns_rdataset_init(&kfetch->dnskeyset);
   11256 			dns_rdataset_init(&kfetch->dnskeysigset);
   11257 			dns_rdataset_init(&kfetch->keydataset);
   11258 			dns_rdataset_clone(kdset, &kfetch->keydataset);
   11259 			dns_db_attach(db, &kfetch->db);
   11260 
   11261 			if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   11262 				char namebuf[DNS_NAME_FORMATSIZE];
   11263 				dns_name_format(kname, namebuf,
   11264 						sizeof(namebuf));
   11265 				dnssec_log(zone, ISC_LOG_DEBUG(3),
   11266 					   "Creating key fetch in "
   11267 					   "zone_refreshkeys() for '%s'",
   11268 					   namebuf);
   11269 			}
   11270 
   11271 			e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
   11272 					       do_keyfetch, kfetch,
   11273 					       sizeof(isc_event_t));
   11274 			isc_task_send(zone->task, &e);
   11275 			fetching = true;
   11276 #ifdef ENABLE_AFL
   11277 		}
   11278 #endif /* ifdef ENABLE_AFL */
   11279 	}
   11280 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   11281 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   11282 					zone->updatemethod));
   11283 		CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
   11284 		commit = true;
   11285 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   11286 		zone_needdump(zone, 30);
   11287 	}
   11288 
   11289 failure:
   11290 	if (!timerset) {
   11291 		isc_time_settoepoch(&zone->refreshkeytime);
   11292 	}
   11293 
   11294 	if (!fetching) {
   11295 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   11296 	}
   11297 
   11298 	dns_diff_clear(&diff);
   11299 	if (ver != NULL) {
   11300 		dns_rriterator_destroy(&rrit);
   11301 		dns_db_closeversion(db, &ver, commit);
   11302 	}
   11303 	dns_db_detach(&db);
   11304 
   11305 	UNLOCK_ZONE(zone);
   11306 
   11307 	INSIST(ver == NULL);
   11308 }
   11309 
   11310 static void
   11311 zone_maintenance(dns_zone_t *zone) {
   11312 	const char me[] = "zone_maintenance";
   11313 	isc_time_t now;
   11314 	isc_result_t result;
   11315 	bool dumping, load_pending, exiting, viewok;
   11316 	bool need_notify;
   11317 
   11318 	REQUIRE(DNS_ZONE_VALID(zone));
   11319 	ENTER;
   11320 
   11321 	/*
   11322 	 * Are we pending load/reload, exiting, or unconfigured
   11323 	 * (e.g. because of a syntax failure in the config file)?
   11324 	 * If so, don't attempt maintenance.
   11325 	 */
   11326 	LOCK_ZONE(zone);
   11327 	load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
   11328 	exiting = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING);
   11329 	viewok = (zone->view != NULL && zone->view->adb != NULL);
   11330 	UNLOCK_ZONE(zone);
   11331 
   11332 	if (load_pending || exiting || !viewok) {
   11333 		return;
   11334 	}
   11335 
   11336 	TIME_NOW(&now);
   11337 
   11338 	/*
   11339 	 * Expire check.
   11340 	 */
   11341 	switch (zone->type) {
   11342 	case dns_zone_redirect:
   11343 		if (zone->masters == NULL) {
   11344 			break;
   11345 		}
   11346 		FALLTHROUGH;
   11347 	case dns_zone_secondary:
   11348 	case dns_zone_mirror:
   11349 	case dns_zone_stub:
   11350 		LOCK_ZONE(zone);
   11351 		if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
   11352 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11353 		{
   11354 			zone_expire(zone);
   11355 			zone->refreshtime = now;
   11356 		}
   11357 		UNLOCK_ZONE(zone);
   11358 		break;
   11359 	default:
   11360 		break;
   11361 	}
   11362 
   11363 	/*
   11364 	 * Up to date check.
   11365 	 */
   11366 	switch (zone->type) {
   11367 	case dns_zone_redirect:
   11368 		if (zone->masters == NULL) {
   11369 			break;
   11370 		}
   11371 		FALLTHROUGH;
   11372 	case dns_zone_secondary:
   11373 	case dns_zone_mirror:
   11374 	case dns_zone_stub:
   11375 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
   11376 		    isc_time_compare(&now, &zone->refreshtime) >= 0)
   11377 		{
   11378 			dns_zone_refresh(zone);
   11379 		}
   11380 		break;
   11381 	default:
   11382 		break;
   11383 	}
   11384 
   11385 	/*
   11386 	 * Secondaries send notifies before backing up to disk,
   11387 	 * primaries after.
   11388 	 */
   11389 	LOCK_ZONE(zone);
   11390 	need_notify = (zone->type == dns_zone_secondary ||
   11391 		       zone->type == dns_zone_mirror) &&
   11392 		      (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11393 		       DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11394 		      (isc_time_compare(&now, &zone->notifytime) >= 0);
   11395 	UNLOCK_ZONE(zone);
   11396 
   11397 	if (need_notify) {
   11398 		zone_notify(zone, &now);
   11399 	}
   11400 
   11401 	/*
   11402 	 * Do we need to consolidate the backing store?
   11403 	 */
   11404 	switch (zone->type) {
   11405 	case dns_zone_primary:
   11406 	case dns_zone_secondary:
   11407 	case dns_zone_mirror:
   11408 	case dns_zone_key:
   11409 	case dns_zone_redirect:
   11410 	case dns_zone_stub:
   11411 		LOCK_ZONE(zone);
   11412 		if (zone->masterfile != NULL &&
   11413 		    isc_time_compare(&now, &zone->dumptime) >= 0 &&
   11414 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11415 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
   11416 		{
   11417 			dumping = was_dumping(zone);
   11418 		} else {
   11419 			dumping = true;
   11420 		}
   11421 		UNLOCK_ZONE(zone);
   11422 		if (!dumping) {
   11423 			result = zone_dump(zone, true); /* task locked */
   11424 			if (result != ISC_R_SUCCESS) {
   11425 				dns_zone_log(zone, ISC_LOG_WARNING,
   11426 					     "dump failed: %s",
   11427 					     dns_result_totext(result));
   11428 			}
   11429 		}
   11430 		break;
   11431 	default:
   11432 		break;
   11433 	}
   11434 
   11435 	/*
   11436 	 * Master/redirect zones send notifies now, if needed
   11437 	 */
   11438 	switch (zone->type) {
   11439 	case dns_zone_primary:
   11440 	case dns_zone_redirect:
   11441 		if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11442 		     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11443 		    isc_time_compare(&now, &zone->notifytime) >= 0)
   11444 		{
   11445 			zone_notify(zone, &now);
   11446 		}
   11447 	default:
   11448 		break;
   11449 	}
   11450 
   11451 	/*
   11452 	 * Do we need to refresh keys?
   11453 	 */
   11454 	switch (zone->type) {
   11455 	case dns_zone_key:
   11456 		if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
   11457 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11458 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
   11459 			{
   11460 				zone_refreshkeys(zone);
   11461 			}
   11462 		}
   11463 		break;
   11464 	case dns_zone_primary:
   11465 		if (!isc_time_isepoch(&zone->refreshkeytime) &&
   11466 		    isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
   11467 		    zone->rss_event == NULL)
   11468 		{
   11469 			zone_rekey(zone);
   11470 		}
   11471 	default:
   11472 		break;
   11473 	}
   11474 
   11475 	switch (zone->type) {
   11476 	case dns_zone_primary:
   11477 	case dns_zone_redirect:
   11478 	case dns_zone_secondary:
   11479 		/*
   11480 		 * Do we need to sign/resign some RRsets?
   11481 		 */
   11482 		if (zone->rss_event != NULL) {
   11483 			break;
   11484 		}
   11485 		if (!isc_time_isepoch(&zone->signingtime) &&
   11486 		    isc_time_compare(&now, &zone->signingtime) >= 0)
   11487 		{
   11488 			zone_sign(zone);
   11489 		} else if (!isc_time_isepoch(&zone->resigntime) &&
   11490 			   isc_time_compare(&now, &zone->resigntime) >= 0)
   11491 		{
   11492 			zone_resigninc(zone);
   11493 		} else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
   11494 			   isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
   11495 		{
   11496 			zone_nsec3chain(zone);
   11497 		}
   11498 		/*
   11499 		 * Do we need to issue a key expiry warning?
   11500 		 */
   11501 		if (!isc_time_isepoch(&zone->keywarntime) &&
   11502 		    isc_time_compare(&now, &zone->keywarntime) >= 0)
   11503 		{
   11504 			set_key_expiry_warning(zone, zone->key_expiry,
   11505 					       isc_time_seconds(&now));
   11506 		}
   11507 		break;
   11508 
   11509 	default:
   11510 		break;
   11511 	}
   11512 	LOCK_ZONE(zone);
   11513 	zone_settimer(zone, &now);
   11514 	UNLOCK_ZONE(zone);
   11515 }
   11516 
   11517 void
   11518 dns_zone_markdirty(dns_zone_t *zone) {
   11519 	uint32_t serial;
   11520 	isc_result_t result = ISC_R_SUCCESS;
   11521 	dns_zone_t *secure = NULL;
   11522 
   11523 	/*
   11524 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   11525 	 * could result in a deadlock due to a LOR so we will spin if we
   11526 	 * can't obtain the both locks.
   11527 	 */
   11528 again:
   11529 	LOCK_ZONE(zone);
   11530 	if (zone->type == dns_zone_primary) {
   11531 		if (inline_raw(zone)) {
   11532 			unsigned int soacount;
   11533 			secure = zone->secure;
   11534 			INSIST(secure != zone);
   11535 			TRYLOCK_ZONE(result, secure);
   11536 			if (result != ISC_R_SUCCESS) {
   11537 				UNLOCK_ZONE(zone);
   11538 				secure = NULL;
   11539 				isc_thread_yield();
   11540 				goto again;
   11541 			}
   11542 
   11543 			ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11544 			if (zone->db != NULL) {
   11545 				result = zone_get_from_db(
   11546 					zone, zone->db, NULL, &soacount, NULL,
   11547 					&serial, NULL, NULL, NULL, NULL, NULL);
   11548 			} else {
   11549 				result = DNS_R_NOTLOADED;
   11550 			}
   11551 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11552 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   11553 				zone_send_secureserial(zone, serial);
   11554 			}
   11555 		}
   11556 
   11557 		/* XXXMPA make separate call back */
   11558 		if (result == ISC_R_SUCCESS) {
   11559 			set_resigntime(zone);
   11560 			if (zone->task != NULL) {
   11561 				isc_time_t now;
   11562 				TIME_NOW(&now);
   11563 				zone_settimer(zone, &now);
   11564 			}
   11565 		}
   11566 	}
   11567 	if (secure != NULL) {
   11568 		UNLOCK_ZONE(secure);
   11569 	}
   11570 	zone_needdump(zone, DNS_DUMP_DELAY);
   11571 	UNLOCK_ZONE(zone);
   11572 }
   11573 
   11574 void
   11575 dns_zone_expire(dns_zone_t *zone) {
   11576 	REQUIRE(DNS_ZONE_VALID(zone));
   11577 
   11578 	LOCK_ZONE(zone);
   11579 	zone_expire(zone);
   11580 	UNLOCK_ZONE(zone);
   11581 }
   11582 
   11583 static void
   11584 zone_expire(dns_zone_t *zone) {
   11585 	dns_db_t *db = NULL;
   11586 
   11587 	/*
   11588 	 * 'zone' locked by caller.
   11589 	 */
   11590 
   11591 	REQUIRE(LOCKED_ZONE(zone));
   11592 
   11593 	dns_zone_log(zone, ISC_LOG_WARNING, "expired");
   11594 
   11595 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
   11596 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   11597 	zone->retry = DNS_ZONE_DEFAULTRETRY;
   11598 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   11599 
   11600 	/*
   11601 	 * An RPZ zone has expired; before unloading it, we must
   11602 	 * first remove it from the RPZ summary database. The
   11603 	 * easiest way to do this is "update" it with an empty
   11604 	 * database so that the update callback synchronizes
   11605 	 * the diff automatically.
   11606 	 */
   11607 	if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) {
   11608 		isc_result_t result;
   11609 		dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num];
   11610 
   11611 		CHECK(dns_db_create(zone->mctx, "rbt", &zone->origin,
   11612 				    dns_dbtype_zone, zone->rdclass, 0, NULL,
   11613 				    &db));
   11614 		CHECK(dns_rpz_dbupdate_callback(db, rpz));
   11615 		dns_zone_log(zone, ISC_LOG_WARNING,
   11616 			     "response-policy zone expired; "
   11617 			     "policies unloaded");
   11618 	}
   11619 
   11620 failure:
   11621 	if (db != NULL) {
   11622 		dns_db_detach(&db);
   11623 	}
   11624 
   11625 	zone_unload(zone);
   11626 }
   11627 
   11628 void
   11629 dns_zone_refresh(dns_zone_t *zone) {
   11630 	isc_interval_t i;
   11631 	uint32_t oldflags;
   11632 	unsigned int j;
   11633 	isc_result_t result;
   11634 
   11635 	REQUIRE(DNS_ZONE_VALID(zone));
   11636 
   11637 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11638 		return;
   11639 	}
   11640 
   11641 	/*
   11642 	 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
   11643 	 * in progress at a time.
   11644 	 */
   11645 
   11646 	LOCK_ZONE(zone);
   11647 	oldflags = atomic_load(&zone->flags);
   11648 	if (zone->masterscnt == 0) {
   11649 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   11650 		if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) {
   11651 			dns_zone_log(zone, ISC_LOG_ERROR,
   11652 				     "cannot refresh: no primaries");
   11653 		}
   11654 		goto unlock;
   11655 	}
   11656 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   11657 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   11658 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   11659 	if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) {
   11660 		goto unlock;
   11661 	}
   11662 
   11663 	/*
   11664 	 * Set the next refresh time as if refresh check has failed.
   11665 	 * Setting this to the retry time will do that.  XXXMLG
   11666 	 * If we are successful it will be reset using zone->refresh.
   11667 	 */
   11668 	isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4),
   11669 			 0);
   11670 	result = isc_time_nowplusinterval(&zone->refreshtime, &i);
   11671 	if (result != ISC_R_SUCCESS) {
   11672 		dns_zone_log(zone, ISC_LOG_WARNING,
   11673 			     "isc_time_nowplusinterval() failed: %s",
   11674 			     dns_result_totext(result));
   11675 	}
   11676 
   11677 	/*
   11678 	 * When lacking user-specified timer values from the SOA,
   11679 	 * do exponential backoff of the retry time up to a
   11680 	 * maximum of six hours.
   11681 	 */
   11682 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) {
   11683 		zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
   11684 	}
   11685 
   11686 	zone->curmaster = 0;
   11687 	for (j = 0; j < zone->masterscnt; j++) {
   11688 		zone->mastersok[j] = false;
   11689 	}
   11690 	/* initiate soa query */
   11691 	queue_soa_query(zone);
   11692 unlock:
   11693 	UNLOCK_ZONE(zone);
   11694 }
   11695 
   11696 static isc_result_t
   11697 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump,
   11698 			 bool *fixjournal) {
   11699 	dns_journal_t *journal = NULL;
   11700 	unsigned int options;
   11701 	isc_result_t result;
   11702 
   11703 	if (zone->type == dns_zone_primary &&
   11704 	    (inline_secure(zone) ||
   11705 	     (zone->update_acl != NULL || zone->ssutable != NULL)))
   11706 	{
   11707 		options = DNS_JOURNALOPT_RESIGN;
   11708 	} else {
   11709 		options = 0;
   11710 	}
   11711 
   11712 	result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ,
   11713 				  &journal);
   11714 	if (result == ISC_R_NOTFOUND) {
   11715 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(3),
   11716 			      "no journal file, but that's OK ");
   11717 		return (ISC_R_SUCCESS);
   11718 	} else if (result != ISC_R_SUCCESS) {
   11719 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11720 			      "journal open failed: %s",
   11721 			      dns_result_totext(result));
   11722 		return (result);
   11723 	}
   11724 
   11725 	if (dns_journal_empty(journal)) {
   11726 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   11727 			      "journal empty");
   11728 		dns_journal_destroy(&journal);
   11729 		return (ISC_R_SUCCESS);
   11730 	}
   11731 
   11732 	result = dns_journal_rollforward(journal, db, options);
   11733 	switch (result) {
   11734 	case ISC_R_SUCCESS:
   11735 		*needdump = true;
   11736 		FALLTHROUGH;
   11737 	case DNS_R_UPTODATE:
   11738 		if (dns_journal_recovered(journal)) {
   11739 			*fixjournal = true;
   11740 			dns_zone_logc(
   11741 				zone, DNS_LOGCATEGORY_ZONELOAD,
   11742 				ISC_LOG_DEBUG(1),
   11743 				"journal rollforward completed successfully "
   11744 				"using old journal format: %s",
   11745 				dns_result_totext(result));
   11746 		} else {
   11747 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   11748 				      ISC_LOG_DEBUG(1),
   11749 				      "journal rollforward completed "
   11750 				      "successfully: %s",
   11751 				      dns_result_totext(result));
   11752 		}
   11753 
   11754 		dns_journal_destroy(&journal);
   11755 		return (ISC_R_SUCCESS);
   11756 	case ISC_R_NOTFOUND:
   11757 	case ISC_R_RANGE:
   11758 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11759 			      "journal rollforward failed: journal out of sync "
   11760 			      "with zone");
   11761 		dns_journal_destroy(&journal);
   11762 		return (result);
   11763 	default:
   11764 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11765 			      "journal rollforward failed: %s",
   11766 			      dns_result_totext(result));
   11767 		dns_journal_destroy(&journal);
   11768 		return (result);
   11769 	}
   11770 }
   11771 
   11772 static void
   11773 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) {
   11774 	isc_result_t result;
   11775 	int32_t journalsize;
   11776 	dns_dbversion_t *ver = NULL;
   11777 	uint64_t dbsize;
   11778 	uint32_t options = 0;
   11779 
   11780 	INSIST(LOCKED_ZONE(zone));
   11781 	if (inline_raw(zone)) {
   11782 		INSIST(LOCKED_ZONE(zone->secure));
   11783 	}
   11784 
   11785 	journalsize = zone->journalsize;
   11786 	if (journalsize == -1) {
   11787 		journalsize = DNS_JOURNAL_SIZE_MAX;
   11788 		dns_db_currentversion(db, &ver);
   11789 		result = dns_db_getsize(db, ver, NULL, &dbsize);
   11790 		dns_db_closeversion(db, &ver, false);
   11791 		if (result != ISC_R_SUCCESS) {
   11792 			dns_zone_log(zone, ISC_LOG_ERROR,
   11793 				     "zone_journal_compact: "
   11794 				     "could not get zone size: %s",
   11795 				     isc_result_totext(result));
   11796 		} else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) {
   11797 			journalsize = (int32_t)dbsize * 2;
   11798 		}
   11799 	}
   11800 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIXJOURNAL)) {
   11801 		options |= DNS_JOURNAL_COMPACTALL;
   11802 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FIXJOURNAL);
   11803 		zone_debuglog(zone, "zone_journal_compact", 1,
   11804 			      "repair full journal");
   11805 	} else {
   11806 		zone_debuglog(zone, "zone_journal_compact", 1,
   11807 			      "target journal size %d", journalsize);
   11808 	}
   11809 	result = dns_journal_compact(zone->mctx, zone->journal, serial, options,
   11810 				     journalsize);
   11811 	switch (result) {
   11812 	case ISC_R_SUCCESS:
   11813 	case ISC_R_NOSPACE:
   11814 	case ISC_R_NOTFOUND:
   11815 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s",
   11816 			     dns_result_totext(result));
   11817 		break;
   11818 	default:
   11819 		dns_zone_log(zone, ISC_LOG_ERROR,
   11820 			     "dns_journal_compact failed: %s",
   11821 			     dns_result_totext(result));
   11822 		break;
   11823 	}
   11824 }
   11825 
   11826 isc_result_t
   11827 dns_zone_flush(dns_zone_t *zone) {
   11828 	isc_result_t result = ISC_R_SUCCESS;
   11829 	bool dumping;
   11830 
   11831 	REQUIRE(DNS_ZONE_VALID(zone));
   11832 
   11833 	LOCK_ZONE(zone);
   11834 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
   11835 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11836 	    zone->masterfile != NULL)
   11837 	{
   11838 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   11839 		result = ISC_R_ALREADYRUNNING;
   11840 		dumping = was_dumping(zone);
   11841 	} else {
   11842 		dumping = true;
   11843 	}
   11844 	UNLOCK_ZONE(zone);
   11845 	if (!dumping) {
   11846 		result = zone_dump(zone, true); /* Unknown task. */
   11847 	}
   11848 	return (result);
   11849 }
   11850 
   11851 isc_result_t
   11852 dns_zone_dump(dns_zone_t *zone) {
   11853 	isc_result_t result = ISC_R_ALREADYRUNNING;
   11854 	bool dumping;
   11855 
   11856 	REQUIRE(DNS_ZONE_VALID(zone));
   11857 
   11858 	LOCK_ZONE(zone);
   11859 	dumping = was_dumping(zone);
   11860 	UNLOCK_ZONE(zone);
   11861 	if (!dumping) {
   11862 		result = zone_dump(zone, false); /* Unknown task. */
   11863 	}
   11864 	return (result);
   11865 }
   11866 
   11867 static void
   11868 zone_needdump(dns_zone_t *zone, unsigned int delay) {
   11869 	const char me[] = "zone_needdump";
   11870 	isc_time_t dumptime;
   11871 	isc_time_t now;
   11872 
   11873 	/*
   11874 	 * 'zone' locked by caller
   11875 	 */
   11876 
   11877 	REQUIRE(DNS_ZONE_VALID(zone));
   11878 	REQUIRE(LOCKED_ZONE(zone));
   11879 	ENTER;
   11880 
   11881 	/*
   11882 	 * Do we have a place to dump to and are we loaded?
   11883 	 */
   11884 	if (zone->masterfile == NULL ||
   11885 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
   11886 	{
   11887 		return;
   11888 	}
   11889 
   11890 	TIME_NOW(&now);
   11891 	/* add some noise */
   11892 	DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
   11893 
   11894 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11895 	if (isc_time_isepoch(&zone->dumptime) ||
   11896 	    isc_time_compare(&zone->dumptime, &dumptime) > 0)
   11897 	{
   11898 		zone->dumptime = dumptime;
   11899 	}
   11900 	if (zone->task != NULL) {
   11901 		zone_settimer(zone, &now);
   11902 	}
   11903 }
   11904 
   11905 static void
   11906 dump_done(void *arg, isc_result_t result) {
   11907 	const char me[] = "dump_done";
   11908 	dns_zone_t *zone = arg;
   11909 	dns_zone_t *secure = NULL;
   11910 	dns_db_t *db;
   11911 	dns_dbversion_t *version;
   11912 	bool again = false;
   11913 	bool compact = false;
   11914 	uint32_t serial;
   11915 	isc_result_t tresult;
   11916 
   11917 	REQUIRE(DNS_ZONE_VALID(zone));
   11918 
   11919 	ENTER;
   11920 
   11921 	if (result == ISC_R_SUCCESS && zone->journal != NULL) {
   11922 		/*
   11923 		 * We don't own these, zone->dctx must stay valid.
   11924 		 */
   11925 		db = dns_dumpctx_db(zone->dctx);
   11926 		version = dns_dumpctx_version(zone->dctx);
   11927 		tresult = dns_db_getsoaserial(db, version, &serial);
   11928 
   11929 		/*
   11930 		 * Handle lock order inversion.
   11931 		 */
   11932 	again:
   11933 		LOCK_ZONE(zone);
   11934 		if (inline_raw(zone)) {
   11935 			secure = zone->secure;
   11936 			INSIST(secure != zone);
   11937 			TRYLOCK_ZONE(result, secure);
   11938 			if (result != ISC_R_SUCCESS) {
   11939 				UNLOCK_ZONE(zone);
   11940 				secure = NULL;
   11941 				isc_thread_yield();
   11942 				goto again;
   11943 			}
   11944 		}
   11945 
   11946 		/*
   11947 		 * If there is a secure version of this zone
   11948 		 * use its serial if it is less than ours.
   11949 		 */
   11950 		if (tresult == ISC_R_SUCCESS && secure != NULL) {
   11951 			uint32_t sserial;
   11952 			isc_result_t mresult;
   11953 
   11954 			ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
   11955 			if (secure->db != NULL) {
   11956 				mresult = dns_db_getsoaserial(zone->secure->db,
   11957 							      NULL, &sserial);
   11958 				if (mresult == ISC_R_SUCCESS &&
   11959 				    isc_serial_lt(sserial, serial))
   11960 				{
   11961 					serial = sserial;
   11962 				}
   11963 			}
   11964 			ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
   11965 		}
   11966 		if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
   11967 			dns_db_t *zdb = NULL;
   11968 			if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) {
   11969 				zone_journal_compact(zone, zdb, serial);
   11970 				dns_db_detach(&zdb);
   11971 			}
   11972 		} else if (tresult == ISC_R_SUCCESS) {
   11973 			compact = true;
   11974 			zone->compact_serial = serial;
   11975 		}
   11976 		if (secure != NULL) {
   11977 			UNLOCK_ZONE(secure);
   11978 		}
   11979 		UNLOCK_ZONE(zone);
   11980 	}
   11981 
   11982 	LOCK_ZONE(zone);
   11983 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   11984 	if (compact) {
   11985 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   11986 	}
   11987 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN)) {
   11988 		/*
   11989 		 * If DNS_ZONEFLG_SHUTDOWN is set, all external references to
   11990 		 * the zone are gone, which means it is in the process of being
   11991 		 * cleaned up, so do not reschedule dumping.
   11992 		 *
   11993 		 * Detach from the raw version of the zone in case this
   11994 		 * operation has been deferred in zone_shutdown().
   11995 		 */
   11996 		if (zone->raw != NULL) {
   11997 			dns_zone_detach(&zone->raw);
   11998 		}
   11999 		if (result == ISC_R_SUCCESS) {
   12000 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   12001 		}
   12002 	} else if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
   12003 		/*
   12004 		 * Try again in a short while.
   12005 		 */
   12006 		zone_needdump(zone, DNS_DUMP_DELAY);
   12007 	} else if (result == ISC_R_SUCCESS &&
   12008 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   12009 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   12010 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12011 	{
   12012 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   12013 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   12014 		isc_time_settoepoch(&zone->dumptime);
   12015 		again = true;
   12016 	} else if (result == ISC_R_SUCCESS) {
   12017 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   12018 	}
   12019 
   12020 	if (zone->dctx != NULL) {
   12021 		dns_dumpctx_detach(&zone->dctx);
   12022 	}
   12023 	zonemgr_putio(&zone->writeio);
   12024 	UNLOCK_ZONE(zone);
   12025 	if (again) {
   12026 		(void)zone_dump(zone, false);
   12027 	}
   12028 	dns_zone_idetach(&zone);
   12029 }
   12030 
   12031 static isc_result_t
   12032 zone_dump(dns_zone_t *zone, bool compact) {
   12033 	const char me[] = "zone_dump";
   12034 	isc_result_t result;
   12035 	dns_dbversion_t *version = NULL;
   12036 	bool again;
   12037 	dns_db_t *db = NULL;
   12038 	char *masterfile = NULL;
   12039 	dns_masterformat_t masterformat = dns_masterformat_none;
   12040 
   12041 	/*
   12042 	 * 'compact' MUST only be set if we are task locked.
   12043 	 */
   12044 
   12045 	REQUIRE(DNS_ZONE_VALID(zone));
   12046 	ENTER;
   12047 
   12048 redo:
   12049 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12050 	if (zone->db != NULL) {
   12051 		dns_db_attach(zone->db, &db);
   12052 	}
   12053 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12054 	LOCK_ZONE(zone);
   12055 	if (zone->masterfile != NULL) {
   12056 		masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
   12057 		masterformat = zone->masterformat;
   12058 	}
   12059 	UNLOCK_ZONE(zone);
   12060 	if (db == NULL) {
   12061 		result = DNS_R_NOTLOADED;
   12062 		goto fail;
   12063 	}
   12064 	if (masterfile == NULL) {
   12065 		result = DNS_R_NOMASTERFILE;
   12066 		goto fail;
   12067 	}
   12068 
   12069 	if (compact && zone->type != dns_zone_stub) {
   12070 		dns_zone_t *dummy = NULL;
   12071 		LOCK_ZONE(zone);
   12072 		zone_iattach(zone, &dummy);
   12073 		result = zonemgr_getio(zone->zmgr, false, zone->task,
   12074 				       zone_gotwritehandle, zone,
   12075 				       &zone->writeio);
   12076 		if (result != ISC_R_SUCCESS) {
   12077 			zone_idetach(&dummy);
   12078 		} else {
   12079 			result = DNS_R_CONTINUE;
   12080 		}
   12081 		UNLOCK_ZONE(zone);
   12082 	} else {
   12083 		const dns_master_style_t *output_style;
   12084 
   12085 		dns_masterrawheader_t rawdata;
   12086 		dns_db_currentversion(db, &version);
   12087 		dns_master_initrawheader(&rawdata);
   12088 		if (inline_secure(zone)) {
   12089 			get_raw_serial(zone->raw, &rawdata);
   12090 		}
   12091 		if (zone->type == dns_zone_key) {
   12092 			output_style = &dns_master_style_keyzone;
   12093 		} else {
   12094 			output_style = &dns_master_style_default;
   12095 		}
   12096 		result = dns_master_dump(zone->mctx, db, version, output_style,
   12097 					 masterfile, masterformat, &rawdata);
   12098 		dns_db_closeversion(db, &version, false);
   12099 	}
   12100 fail:
   12101 	if (db != NULL) {
   12102 		dns_db_detach(&db);
   12103 	}
   12104 	if (masterfile != NULL) {
   12105 		isc_mem_free(zone->mctx, masterfile);
   12106 	}
   12107 	masterfile = NULL;
   12108 
   12109 	if (result == DNS_R_CONTINUE) {
   12110 		return (ISC_R_SUCCESS); /* XXXMPA */
   12111 	}
   12112 
   12113 	again = false;
   12114 	LOCK_ZONE(zone);
   12115 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   12116 	if (result != ISC_R_SUCCESS) {
   12117 		/*
   12118 		 * Try again in a short while.
   12119 		 */
   12120 		zone_needdump(zone, DNS_DUMP_DELAY);
   12121 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   12122 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   12123 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12124 	{
   12125 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   12126 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   12127 		isc_time_settoepoch(&zone->dumptime);
   12128 		again = true;
   12129 	} else {
   12130 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   12131 	}
   12132 	UNLOCK_ZONE(zone);
   12133 	if (again) {
   12134 		goto redo;
   12135 	}
   12136 
   12137 	return (result);
   12138 }
   12139 
   12140 static isc_result_t
   12141 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
   12142 	     dns_masterformat_t format, const uint32_t rawversion) {
   12143 	isc_result_t result;
   12144 	dns_dbversion_t *version = NULL;
   12145 	dns_db_t *db = NULL;
   12146 	dns_masterrawheader_t rawdata;
   12147 
   12148 	REQUIRE(DNS_ZONE_VALID(zone));
   12149 
   12150 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12151 	if (zone->db != NULL) {
   12152 		dns_db_attach(zone->db, &db);
   12153 	}
   12154 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12155 	if (db == NULL) {
   12156 		return (DNS_R_NOTLOADED);
   12157 	}
   12158 
   12159 	dns_db_currentversion(db, &version);
   12160 	dns_master_initrawheader(&rawdata);
   12161 	if (rawversion == 0) {
   12162 		rawdata.flags |= DNS_MASTERRAW_COMPAT;
   12163 	} else if (inline_secure(zone)) {
   12164 		get_raw_serial(zone->raw, &rawdata);
   12165 	} else if (zone->sourceserialset) {
   12166 		rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
   12167 		rawdata.sourceserial = zone->sourceserial;
   12168 	}
   12169 	result = dns_master_dumptostream(zone->mctx, db, version, style, format,
   12170 					 &rawdata, fd);
   12171 	dns_db_closeversion(db, &version, false);
   12172 	dns_db_detach(&db);
   12173 	return (result);
   12174 }
   12175 
   12176 isc_result_t
   12177 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
   12178 		      const dns_master_style_t *style,
   12179 		      const uint32_t rawversion) {
   12180 	return (dumptostream(zone, fd, style, format, rawversion));
   12181 }
   12182 
   12183 void
   12184 dns_zone_unload(dns_zone_t *zone) {
   12185 	REQUIRE(DNS_ZONE_VALID(zone));
   12186 
   12187 	LOCK_ZONE(zone);
   12188 	zone_unload(zone);
   12189 	UNLOCK_ZONE(zone);
   12190 }
   12191 
   12192 static void
   12193 notify_cancel(dns_zone_t *zone) {
   12194 	dns_notify_t *notify;
   12195 
   12196 	/*
   12197 	 * 'zone' locked by caller.
   12198 	 */
   12199 
   12200 	REQUIRE(LOCKED_ZONE(zone));
   12201 
   12202 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   12203 	     notify = ISC_LIST_NEXT(notify, link))
   12204 	{
   12205 		if (notify->find != NULL) {
   12206 			dns_adb_cancelfind(notify->find);
   12207 		}
   12208 		if (notify->request != NULL) {
   12209 			dns_request_cancel(notify->request);
   12210 		}
   12211 	}
   12212 }
   12213 
   12214 static void
   12215 checkds_cancel(dns_zone_t *zone) {
   12216 	dns_checkds_t *checkds;
   12217 
   12218 	/*
   12219 	 * 'zone' locked by caller.
   12220 	 */
   12221 
   12222 	REQUIRE(LOCKED_ZONE(zone));
   12223 
   12224 	for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL;
   12225 	     checkds = ISC_LIST_NEXT(checkds, link))
   12226 	{
   12227 		if (checkds->request != NULL) {
   12228 			dns_request_cancel(checkds->request);
   12229 		}
   12230 	}
   12231 }
   12232 
   12233 static void
   12234 forward_cancel(dns_zone_t *zone) {
   12235 	dns_forward_t *forward;
   12236 
   12237 	/*
   12238 	 * 'zone' locked by caller.
   12239 	 */
   12240 
   12241 	REQUIRE(LOCKED_ZONE(zone));
   12242 
   12243 	for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL;
   12244 	     forward = ISC_LIST_NEXT(forward, link))
   12245 	{
   12246 		if (forward->request != NULL) {
   12247 			dns_request_cancel(forward->request);
   12248 		}
   12249 	}
   12250 }
   12251 
   12252 static void
   12253 zone_unload(dns_zone_t *zone) {
   12254 	/*
   12255 	 * 'zone' locked by caller.
   12256 	 */
   12257 
   12258 	REQUIRE(LOCKED_ZONE(zone));
   12259 
   12260 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   12261 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   12262 	{
   12263 		if (zone->writeio != NULL) {
   12264 			zonemgr_cancelio(zone->writeio);
   12265 		}
   12266 
   12267 		if (zone->dctx != NULL) {
   12268 			dns_dumpctx_cancel(zone->dctx);
   12269 		}
   12270 	}
   12271 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   12272 	zone_detachdb(zone);
   12273 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   12274 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
   12275 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   12276 
   12277 	if (zone->type == dns_zone_mirror) {
   12278 		dns_zone_log(zone, ISC_LOG_INFO,
   12279 			     "mirror zone is no longer in use; "
   12280 			     "reverting to normal recursion");
   12281 	}
   12282 }
   12283 
   12284 void
   12285 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
   12286 	REQUIRE(DNS_ZONE_VALID(zone));
   12287 	REQUIRE(val > 0);
   12288 
   12289 	zone->minrefresh = val;
   12290 }
   12291 
   12292 void
   12293 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
   12294 	REQUIRE(DNS_ZONE_VALID(zone));
   12295 	REQUIRE(val > 0);
   12296 
   12297 	zone->maxrefresh = val;
   12298 }
   12299 
   12300 void
   12301 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
   12302 	REQUIRE(DNS_ZONE_VALID(zone));
   12303 	REQUIRE(val > 0);
   12304 
   12305 	zone->minretry = val;
   12306 }
   12307 
   12308 void
   12309 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
   12310 	REQUIRE(DNS_ZONE_VALID(zone));
   12311 	REQUIRE(val > 0);
   12312 
   12313 	zone->maxretry = val;
   12314 }
   12315 
   12316 uint32_t
   12317 dns_zone_getmaxrecords(dns_zone_t *zone) {
   12318 	REQUIRE(DNS_ZONE_VALID(zone));
   12319 
   12320 	return (zone->maxrecords);
   12321 }
   12322 
   12323 void
   12324 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
   12325 	REQUIRE(DNS_ZONE_VALID(zone));
   12326 
   12327 	zone->maxrecords = val;
   12328 }
   12329 
   12330 static bool
   12331 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
   12332 		isc_sockaddr_t *addr, dns_tsigkey_t *key) {
   12333 	dns_notify_t *notify;
   12334 	dns_zonemgr_t *zmgr;
   12335 	isc_result_t result;
   12336 
   12337 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   12338 	     notify = ISC_LIST_NEXT(notify, link))
   12339 	{
   12340 		if (notify->request != NULL) {
   12341 			continue;
   12342 		}
   12343 		if (name != NULL && dns_name_dynamic(&notify->ns) &&
   12344 		    dns_name_equal(name, &notify->ns))
   12345 		{
   12346 			goto requeue;
   12347 		}
   12348 		if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
   12349 		    notify->key == key)
   12350 		{
   12351 			goto requeue;
   12352 		}
   12353 	}
   12354 	return (false);
   12355 
   12356 requeue:
   12357 	/*
   12358 	 * If we are enqueued on the startup ratelimiter and this is
   12359 	 * not a startup notify, re-enqueue on the normal notify
   12360 	 * ratelimiter.
   12361 	 */
   12362 	if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
   12363 	    (notify->flags & DNS_NOTIFY_STARTUP) != 0)
   12364 	{
   12365 		zmgr = notify->zone->zmgr;
   12366 		result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
   12367 						 notify->event);
   12368 		if (result != ISC_R_SUCCESS) {
   12369 			return (true);
   12370 		}
   12371 
   12372 		notify->flags &= ~DNS_NOTIFY_STARTUP;
   12373 		result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
   12374 						 notify->zone->task,
   12375 						 &notify->event);
   12376 		if (result != ISC_R_SUCCESS) {
   12377 			isc_event_free(&notify->event);
   12378 			return (false);
   12379 		}
   12380 	}
   12381 
   12382 	return (true);
   12383 }
   12384 
   12385 static bool
   12386 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
   12387 	dns_tsigkey_t *key = NULL;
   12388 	isc_sockaddr_t src;
   12389 	isc_sockaddr_t any;
   12390 	bool isself;
   12391 	isc_netaddr_t dstaddr;
   12392 	isc_result_t result;
   12393 
   12394 	if (zone->view == NULL || zone->isself == NULL) {
   12395 		return (false);
   12396 	}
   12397 
   12398 	switch (isc_sockaddr_pf(dst)) {
   12399 	case PF_INET:
   12400 		src = zone->notifysrc4;
   12401 		isc_sockaddr_any(&any);
   12402 		break;
   12403 	case PF_INET6:
   12404 		src = zone->notifysrc6;
   12405 		isc_sockaddr_any6(&any);
   12406 		break;
   12407 	default:
   12408 		return (false);
   12409 	}
   12410 
   12411 	/*
   12412 	 * When sending from any the kernel will assign a source address
   12413 	 * that matches the destination address.
   12414 	 */
   12415 	if (isc_sockaddr_eqaddr(&any, &src)) {
   12416 		src = *dst;
   12417 	}
   12418 
   12419 	isc_netaddr_fromsockaddr(&dstaddr, dst);
   12420 	result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
   12421 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12422 		return (false);
   12423 	}
   12424 	isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
   12425 				zone->isselfarg);
   12426 	if (key != NULL) {
   12427 		dns_tsigkey_detach(&key);
   12428 	}
   12429 	return (isself);
   12430 }
   12431 
   12432 static void
   12433 notify_destroy(dns_notify_t *notify, bool locked) {
   12434 	isc_mem_t *mctx;
   12435 
   12436 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12437 
   12438 	if (notify->zone != NULL) {
   12439 		if (!locked) {
   12440 			LOCK_ZONE(notify->zone);
   12441 		}
   12442 		REQUIRE(LOCKED_ZONE(notify->zone));
   12443 		if (ISC_LINK_LINKED(notify, link)) {
   12444 			ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
   12445 		}
   12446 		if (!locked) {
   12447 			UNLOCK_ZONE(notify->zone);
   12448 		}
   12449 		if (locked) {
   12450 			zone_idetach(&notify->zone);
   12451 		} else {
   12452 			dns_zone_idetach(&notify->zone);
   12453 		}
   12454 	}
   12455 	if (notify->find != NULL) {
   12456 		dns_adb_destroyfind(&notify->find);
   12457 	}
   12458 	if (notify->request != NULL) {
   12459 		dns_request_destroy(&notify->request);
   12460 	}
   12461 	if (dns_name_dynamic(&notify->ns)) {
   12462 		dns_name_free(&notify->ns, notify->mctx);
   12463 	}
   12464 	if (notify->key != NULL) {
   12465 		dns_tsigkey_detach(&notify->key);
   12466 	}
   12467 	mctx = notify->mctx;
   12468 	isc_mem_put(notify->mctx, notify, sizeof(*notify));
   12469 	isc_mem_detach(&mctx);
   12470 }
   12471 
   12472 static isc_result_t
   12473 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
   12474 	dns_notify_t *notify;
   12475 
   12476 	REQUIRE(notifyp != NULL && *notifyp == NULL);
   12477 
   12478 	notify = isc_mem_get(mctx, sizeof(*notify));
   12479 
   12480 	notify->mctx = NULL;
   12481 	isc_mem_attach(mctx, &notify->mctx);
   12482 	notify->flags = flags;
   12483 	notify->zone = NULL;
   12484 	notify->find = NULL;
   12485 	notify->request = NULL;
   12486 	notify->key = NULL;
   12487 	notify->event = NULL;
   12488 	isc_sockaddr_any(&notify->dst);
   12489 	dns_name_init(&notify->ns, NULL);
   12490 	ISC_LINK_INIT(notify, link);
   12491 	notify->magic = NOTIFY_MAGIC;
   12492 	*notifyp = notify;
   12493 	return (ISC_R_SUCCESS);
   12494 }
   12495 
   12496 /*
   12497  * XXXAG should check for DNS_ZONEFLG_EXITING
   12498  */
   12499 static void
   12500 process_adb_event(isc_task_t *task, isc_event_t *ev) {
   12501 	dns_notify_t *notify;
   12502 	isc_eventtype_t result;
   12503 
   12504 	UNUSED(task);
   12505 
   12506 	notify = ev->ev_arg;
   12507 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12508 	INSIST(task == notify->zone->task);
   12509 	result = ev->ev_type;
   12510 	isc_event_free(&ev);
   12511 	if (result == DNS_EVENT_ADBMOREADDRESSES) {
   12512 		dns_adb_destroyfind(&notify->find);
   12513 		notify_find_address(notify);
   12514 		return;
   12515 	}
   12516 	if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
   12517 		LOCK_ZONE(notify->zone);
   12518 		notify_send(notify);
   12519 		UNLOCK_ZONE(notify->zone);
   12520 	}
   12521 	notify_destroy(notify, false);
   12522 }
   12523 
   12524 static void
   12525 notify_find_address(dns_notify_t *notify) {
   12526 	isc_result_t result;
   12527 	unsigned int options;
   12528 
   12529 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12530 	options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 |
   12531 		  DNS_ADBFIND_RETURNLAME;
   12532 
   12533 	if (notify->zone->view->adb == NULL) {
   12534 		goto destroy;
   12535 	}
   12536 
   12537 	result = dns_adb_createfind(
   12538 		notify->zone->view->adb, notify->zone->task, process_adb_event,
   12539 		notify, &notify->ns, dns_rootname, 0, options, 0, NULL,
   12540 		notify->zone->view->dstport, 0, NULL, &notify->find);
   12541 
   12542 	/* Something failed? */
   12543 	if (result != ISC_R_SUCCESS) {
   12544 		goto destroy;
   12545 	}
   12546 
   12547 	/* More addresses pending? */
   12548 	if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) {
   12549 		return;
   12550 	}
   12551 
   12552 	/* We have as many addresses as we can get. */
   12553 	LOCK_ZONE(notify->zone);
   12554 	notify_send(notify);
   12555 	UNLOCK_ZONE(notify->zone);
   12556 
   12557 destroy:
   12558 	notify_destroy(notify, false);
   12559 }
   12560 
   12561 static isc_result_t
   12562 notify_send_queue(dns_notify_t *notify, bool startup) {
   12563 	isc_event_t *e;
   12564 	isc_result_t result;
   12565 
   12566 	INSIST(notify->event == NULL);
   12567 	e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
   12568 			       notify_send_toaddr, notify, sizeof(isc_event_t));
   12569 	if (startup) {
   12570 		notify->event = e;
   12571 	}
   12572 	e->ev_arg = notify;
   12573 	e->ev_sender = NULL;
   12574 	result = isc_ratelimiter_enqueue(
   12575 		startup ? notify->zone->zmgr->startupnotifyrl
   12576 			: notify->zone->zmgr->notifyrl,
   12577 		notify->zone->task, &e);
   12578 	if (result != ISC_R_SUCCESS) {
   12579 		isc_event_free(&e);
   12580 		notify->event = NULL;
   12581 	}
   12582 	return (result);
   12583 }
   12584 
   12585 static void
   12586 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
   12587 	dns_notify_t *notify;
   12588 	isc_result_t result;
   12589 	dns_message_t *message = NULL;
   12590 	isc_netaddr_t dstip;
   12591 	dns_tsigkey_t *key = NULL;
   12592 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   12593 	isc_sockaddr_t src;
   12594 	unsigned int options, timeout;
   12595 	bool have_notifysource = false;
   12596 	bool have_notifydscp = false;
   12597 	isc_dscp_t dscp = -1;
   12598 
   12599 	notify = event->ev_arg;
   12600 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12601 
   12602 	UNUSED(task);
   12603 
   12604 	LOCK_ZONE(notify->zone);
   12605 
   12606 	notify->event = NULL;
   12607 
   12608 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
   12609 		result = ISC_R_CANCELED;
   12610 		goto cleanup;
   12611 	}
   12612 
   12613 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
   12614 	    DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
   12615 	    notify->zone->view->requestmgr == NULL || notify->zone->db == NULL)
   12616 	{
   12617 		result = ISC_R_CANCELED;
   12618 		goto cleanup;
   12619 	}
   12620 
   12621 	/*
   12622 	 * The raw IPv4 address should also exist.  Don't send to the
   12623 	 * mapped form.
   12624 	 */
   12625 	if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
   12626 	    IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr))
   12627 	{
   12628 		isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12629 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12630 			   "notify: ignoring IPv6 mapped IPV4 address: %s",
   12631 			   addrbuf);
   12632 		result = ISC_R_CANCELED;
   12633 		goto cleanup;
   12634 	}
   12635 
   12636 	result = notify_createmessage(notify->zone, notify->flags, &message);
   12637 	if (result != ISC_R_SUCCESS) {
   12638 		goto cleanup;
   12639 	}
   12640 
   12641 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12642 	if (notify->key != NULL) {
   12643 		/* Transfer ownership of key */
   12644 		key = notify->key;
   12645 		notify->key = NULL;
   12646 	} else {
   12647 		isc_netaddr_fromsockaddr(&dstip, &notify->dst);
   12648 		result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
   12649 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12650 			notify_log(notify->zone, ISC_LOG_ERROR,
   12651 				   "NOTIFY to %s not sent. "
   12652 				   "Peer TSIG key lookup failure.",
   12653 				   addrbuf);
   12654 			goto cleanup_message;
   12655 		}
   12656 	}
   12657 
   12658 	if (key != NULL) {
   12659 		char namebuf[DNS_NAME_FORMATSIZE];
   12660 
   12661 		dns_name_format(&key->name, namebuf, sizeof(namebuf));
   12662 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12663 			   "sending notify to %s : TSIG (%s)", addrbuf,
   12664 			   namebuf);
   12665 	} else {
   12666 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12667 			   "sending notify to %s", addrbuf);
   12668 	}
   12669 	options = 0;
   12670 	if (notify->zone->view->peers != NULL) {
   12671 		dns_peer_t *peer = NULL;
   12672 		bool usetcp = false;
   12673 		result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
   12674 						 &dstip, &peer);
   12675 		if (result == ISC_R_SUCCESS) {
   12676 			result = dns_peer_getnotifysource(peer, &src);
   12677 			if (result == ISC_R_SUCCESS) {
   12678 				have_notifysource = true;
   12679 			}
   12680 			dns_peer_getnotifydscp(peer, &dscp);
   12681 			if (dscp != -1) {
   12682 				have_notifydscp = true;
   12683 			}
   12684 			result = dns_peer_getforcetcp(peer, &usetcp);
   12685 			if (result == ISC_R_SUCCESS && usetcp) {
   12686 				options |= DNS_FETCHOPT_TCP;
   12687 			}
   12688 		}
   12689 	}
   12690 	switch (isc_sockaddr_pf(&notify->dst)) {
   12691 	case PF_INET:
   12692 		if (!have_notifysource) {
   12693 			src = notify->zone->notifysrc4;
   12694 		}
   12695 		if (!have_notifydscp) {
   12696 			dscp = notify->zone->notifysrc4dscp;
   12697 		}
   12698 		break;
   12699 	case PF_INET6:
   12700 		if (!have_notifysource) {
   12701 			src = notify->zone->notifysrc6;
   12702 		}
   12703 		if (!have_notifydscp) {
   12704 			dscp = notify->zone->notifysrc6dscp;
   12705 		}
   12706 		break;
   12707 	default:
   12708 		result = ISC_R_NOTIMPLEMENTED;
   12709 		goto cleanup_key;
   12710 	}
   12711 	timeout = 15;
   12712 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12713 		timeout = 30;
   12714 	}
   12715 	result = dns_request_createvia(
   12716 		notify->zone->view->requestmgr, message, &src, &notify->dst,
   12717 		dscp, options, key, timeout * 3, timeout, 0, notify->zone->task,
   12718 		notify_done, notify, &notify->request);
   12719 	if (result == ISC_R_SUCCESS) {
   12720 		if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
   12721 			inc_stats(notify->zone,
   12722 				  dns_zonestatscounter_notifyoutv4);
   12723 		} else {
   12724 			inc_stats(notify->zone,
   12725 				  dns_zonestatscounter_notifyoutv6);
   12726 		}
   12727 	}
   12728 
   12729 cleanup_key:
   12730 	if (key != NULL) {
   12731 		dns_tsigkey_detach(&key);
   12732 	}
   12733 cleanup_message:
   12734 	dns_message_detach(&message);
   12735 cleanup:
   12736 	UNLOCK_ZONE(notify->zone);
   12737 	isc_event_free(&event);
   12738 	if (result != ISC_R_SUCCESS) {
   12739 		notify_destroy(notify, false);
   12740 	}
   12741 }
   12742 
   12743 static void
   12744 notify_send(dns_notify_t *notify) {
   12745 	dns_adbaddrinfo_t *ai;
   12746 	isc_sockaddr_t dst;
   12747 	isc_result_t result;
   12748 	dns_notify_t *newnotify = NULL;
   12749 	unsigned int flags;
   12750 	bool startup;
   12751 
   12752 	/*
   12753 	 * Zone lock held by caller.
   12754 	 */
   12755 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12756 	REQUIRE(LOCKED_ZONE(notify->zone));
   12757 
   12758 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) {
   12759 		return;
   12760 	}
   12761 
   12762 	for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL;
   12763 	     ai = ISC_LIST_NEXT(ai, publink))
   12764 	{
   12765 		dst = ai->sockaddr;
   12766 		if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
   12767 				    NULL))
   12768 		{
   12769 			continue;
   12770 		}
   12771 		if (notify_isself(notify->zone, &dst)) {
   12772 			continue;
   12773 		}
   12774 		newnotify = NULL;
   12775 		flags = notify->flags & DNS_NOTIFY_NOSOA;
   12776 		result = notify_create(notify->mctx, flags, &newnotify);
   12777 		if (result != ISC_R_SUCCESS) {
   12778 			goto cleanup;
   12779 		}
   12780 		zone_iattach(notify->zone, &newnotify->zone);
   12781 		ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link);
   12782 		newnotify->dst = dst;
   12783 		startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0);
   12784 		result = notify_send_queue(newnotify, startup);
   12785 		if (result != ISC_R_SUCCESS) {
   12786 			goto cleanup;
   12787 		}
   12788 		newnotify = NULL;
   12789 	}
   12790 
   12791 cleanup:
   12792 	if (newnotify != NULL) {
   12793 		notify_destroy(newnotify, true);
   12794 	}
   12795 }
   12796 
   12797 void
   12798 dns_zone_notify(dns_zone_t *zone) {
   12799 	isc_time_t now;
   12800 
   12801 	REQUIRE(DNS_ZONE_VALID(zone));
   12802 
   12803 	LOCK_ZONE(zone);
   12804 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12805 
   12806 	TIME_NOW(&now);
   12807 	zone_settimer(zone, &now);
   12808 	UNLOCK_ZONE(zone);
   12809 }
   12810 
   12811 static void
   12812 zone_notify(dns_zone_t *zone, isc_time_t *now) {
   12813 	dns_dbnode_t *node = NULL;
   12814 	dns_db_t *zonedb = NULL;
   12815 	dns_dbversion_t *version = NULL;
   12816 	dns_name_t *origin = NULL;
   12817 	dns_name_t master;
   12818 	dns_rdata_ns_t ns;
   12819 	dns_rdata_soa_t soa;
   12820 	uint32_t serial;
   12821 	dns_rdata_t rdata = DNS_RDATA_INIT;
   12822 	dns_rdataset_t nsrdset;
   12823 	dns_rdataset_t soardset;
   12824 	isc_result_t result;
   12825 	unsigned int i;
   12826 	isc_sockaddr_t dst;
   12827 	bool isqueued;
   12828 	dns_notifytype_t notifytype;
   12829 	unsigned int flags = 0;
   12830 	bool loggednotify = false;
   12831 	bool startup;
   12832 
   12833 	REQUIRE(DNS_ZONE_VALID(zone));
   12834 
   12835 	LOCK_ZONE(zone);
   12836 	startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12837 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12838 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   12839 	notifytype = zone->notifytype;
   12840 	DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
   12841 	UNLOCK_ZONE(zone);
   12842 
   12843 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   12844 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12845 	{
   12846 		return;
   12847 	}
   12848 
   12849 	if (notifytype == dns_notifytype_no) {
   12850 		return;
   12851 	}
   12852 
   12853 	if (notifytype == dns_notifytype_masteronly &&
   12854 	    zone->type != dns_zone_primary)
   12855 	{
   12856 		return;
   12857 	}
   12858 
   12859 	origin = &zone->origin;
   12860 
   12861 	/*
   12862 	 * If the zone is dialup we are done as we don't want to send
   12863 	 * the current soa so as to force a refresh query.
   12864 	 */
   12865 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12866 		flags |= DNS_NOTIFY_NOSOA;
   12867 	}
   12868 
   12869 	/*
   12870 	 * Record that this was a notify due to starting up.
   12871 	 */
   12872 	if (startup) {
   12873 		flags |= DNS_NOTIFY_STARTUP;
   12874 	}
   12875 
   12876 	/*
   12877 	 * Get SOA RRset.
   12878 	 */
   12879 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12880 	if (zone->db != NULL) {
   12881 		dns_db_attach(zone->db, &zonedb);
   12882 	}
   12883 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12884 	if (zonedb == NULL) {
   12885 		return;
   12886 	}
   12887 	dns_db_currentversion(zonedb, &version);
   12888 	result = dns_db_findnode(zonedb, origin, false, &node);
   12889 	if (result != ISC_R_SUCCESS) {
   12890 		goto cleanup1;
   12891 	}
   12892 
   12893 	dns_rdataset_init(&soardset);
   12894 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   12895 				     dns_rdatatype_none, 0, &soardset, NULL);
   12896 	if (result != ISC_R_SUCCESS) {
   12897 		goto cleanup2;
   12898 	}
   12899 
   12900 	/*
   12901 	 * Find serial and master server's name.
   12902 	 */
   12903 	dns_name_init(&master, NULL);
   12904 	result = dns_rdataset_first(&soardset);
   12905 	if (result != ISC_R_SUCCESS) {
   12906 		goto cleanup3;
   12907 	}
   12908 	dns_rdataset_current(&soardset, &rdata);
   12909 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   12910 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12911 	dns_rdata_reset(&rdata);
   12912 	dns_name_dup(&soa.origin, zone->mctx, &master);
   12913 	serial = soa.serial;
   12914 	dns_rdataset_disassociate(&soardset);
   12915 
   12916 	/*
   12917 	 * Enqueue notify requests for 'also-notify' servers.
   12918 	 */
   12919 	LOCK_ZONE(zone);
   12920 	for (i = 0; i < zone->notifycnt; i++) {
   12921 		dns_tsigkey_t *key = NULL;
   12922 		dns_notify_t *notify = NULL;
   12923 
   12924 		if ((zone->notifykeynames != NULL) &&
   12925 		    (zone->notifykeynames[i] != NULL))
   12926 		{
   12927 			dns_view_t *view = dns_zone_getview(zone);
   12928 			dns_name_t *keyname = zone->notifykeynames[i];
   12929 			(void)dns_view_gettsig(view, keyname, &key);
   12930 		}
   12931 
   12932 		dst = zone->notify[i];
   12933 		if (notify_isqueued(zone, flags, NULL, &dst, key)) {
   12934 			if (key != NULL) {
   12935 				dns_tsigkey_detach(&key);
   12936 			}
   12937 			continue;
   12938 		}
   12939 
   12940 		result = notify_create(zone->mctx, flags, &notify);
   12941 		if (result != ISC_R_SUCCESS) {
   12942 			if (key != NULL) {
   12943 				dns_tsigkey_detach(&key);
   12944 			}
   12945 			continue;
   12946 		}
   12947 
   12948 		zone_iattach(zone, &notify->zone);
   12949 		notify->dst = dst;
   12950 
   12951 		INSIST(notify->key == NULL);
   12952 
   12953 		if (key != NULL) {
   12954 			notify->key = key;
   12955 			key = NULL;
   12956 		}
   12957 
   12958 		ISC_LIST_APPEND(zone->notifies, notify, link);
   12959 		result = notify_send_queue(notify, startup);
   12960 		if (result != ISC_R_SUCCESS) {
   12961 			notify_destroy(notify, true);
   12962 		}
   12963 		if (!loggednotify) {
   12964 			notify_log(zone, ISC_LOG_INFO,
   12965 				   "sending notifies (serial %u)", serial);
   12966 			loggednotify = true;
   12967 		}
   12968 	}
   12969 	UNLOCK_ZONE(zone);
   12970 
   12971 	if (notifytype == dns_notifytype_explicit) {
   12972 		goto cleanup3;
   12973 	}
   12974 
   12975 	/*
   12976 	 * Process NS RRset to generate notifies.
   12977 	 */
   12978 
   12979 	dns_rdataset_init(&nsrdset);
   12980 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
   12981 				     dns_rdatatype_none, 0, &nsrdset, NULL);
   12982 	if (result != ISC_R_SUCCESS) {
   12983 		goto cleanup3;
   12984 	}
   12985 
   12986 	result = dns_rdataset_first(&nsrdset);
   12987 	while (result == ISC_R_SUCCESS) {
   12988 		dns_notify_t *notify = NULL;
   12989 
   12990 		dns_rdataset_current(&nsrdset, &rdata);
   12991 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   12992 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12993 		dns_rdata_reset(&rdata);
   12994 		/*
   12995 		 * Don't notify the master server unless explicitly
   12996 		 * configured to do so.
   12997 		 */
   12998 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
   12999 		    dns_name_compare(&master, &ns.name) == 0)
   13000 		{
   13001 			result = dns_rdataset_next(&nsrdset);
   13002 			continue;
   13003 		}
   13004 
   13005 		if (!loggednotify) {
   13006 			notify_log(zone, ISC_LOG_INFO,
   13007 				   "sending notifies (serial %u)", serial);
   13008 			loggednotify = true;
   13009 		}
   13010 
   13011 		LOCK_ZONE(zone);
   13012 		isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
   13013 		UNLOCK_ZONE(zone);
   13014 		if (isqueued) {
   13015 			result = dns_rdataset_next(&nsrdset);
   13016 			continue;
   13017 		}
   13018 		result = notify_create(zone->mctx, flags, &notify);
   13019 		if (result != ISC_R_SUCCESS) {
   13020 			continue;
   13021 		}
   13022 		dns_zone_iattach(zone, &notify->zone);
   13023 		dns_name_dup(&ns.name, zone->mctx, &notify->ns);
   13024 		LOCK_ZONE(zone);
   13025 		ISC_LIST_APPEND(zone->notifies, notify, link);
   13026 		UNLOCK_ZONE(zone);
   13027 		notify_find_address(notify);
   13028 		result = dns_rdataset_next(&nsrdset);
   13029 	}
   13030 	dns_rdataset_disassociate(&nsrdset);
   13031 
   13032 cleanup3:
   13033 	if (dns_name_dynamic(&master)) {
   13034 		dns_name_free(&master, zone->mctx);
   13035 	}
   13036 cleanup2:
   13037 	dns_db_detachnode(zonedb, &node);
   13038 cleanup1:
   13039 	dns_db_closeversion(zonedb, &version, false);
   13040 	dns_db_detach(&zonedb);
   13041 }
   13042 
   13043 /***
   13044  *** Private
   13045  ***/
   13046 static isc_result_t
   13047 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name,
   13048 	     dns_message_t **messagep) {
   13049 	dns_message_t *message = NULL;
   13050 	dns_name_t *qname = NULL;
   13051 	dns_rdataset_t *qrdataset = NULL;
   13052 	isc_result_t result;
   13053 
   13054 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   13055 
   13056 	message->opcode = dns_opcode_query;
   13057 	message->rdclass = zone->rdclass;
   13058 
   13059 	result = dns_message_gettempname(message, &qname);
   13060 	if (result != ISC_R_SUCCESS) {
   13061 		goto cleanup;
   13062 	}
   13063 
   13064 	result = dns_message_gettemprdataset(message, &qrdataset);
   13065 	if (result != ISC_R_SUCCESS) {
   13066 		goto cleanup;
   13067 	}
   13068 
   13069 	/*
   13070 	 * Make question.
   13071 	 */
   13072 	dns_name_clone(name, qname);
   13073 	dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
   13074 	ISC_LIST_APPEND(qname->list, qrdataset, link);
   13075 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
   13076 
   13077 	*messagep = message;
   13078 	return (ISC_R_SUCCESS);
   13079 
   13080 cleanup:
   13081 	if (qname != NULL) {
   13082 		dns_message_puttempname(message, &qname);
   13083 	}
   13084 	if (qrdataset != NULL) {
   13085 		dns_message_puttemprdataset(message, &qrdataset);
   13086 	}
   13087 	dns_message_detach(&message);
   13088 	return (result);
   13089 }
   13090 
   13091 static isc_result_t
   13092 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
   13093 	bool reqexpire) {
   13094 	isc_result_t result;
   13095 	dns_rdataset_t *rdataset = NULL;
   13096 	dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
   13097 	int count = 0;
   13098 
   13099 	/* Set EDNS options if applicable. */
   13100 	if (reqnsid) {
   13101 		INSIST(count < DNS_EDNSOPTIONS);
   13102 		ednsopts[count].code = DNS_OPT_NSID;
   13103 		ednsopts[count].length = 0;
   13104 		ednsopts[count].value = NULL;
   13105 		count++;
   13106 	}
   13107 	if (reqexpire) {
   13108 		INSIST(count < DNS_EDNSOPTIONS);
   13109 		ednsopts[count].code = DNS_OPT_EXPIRE;
   13110 		ednsopts[count].length = 0;
   13111 		ednsopts[count].value = NULL;
   13112 		count++;
   13113 	}
   13114 	result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
   13115 				      ednsopts, count);
   13116 	if (result != ISC_R_SUCCESS) {
   13117 		return (result);
   13118 	}
   13119 
   13120 	return (dns_message_setopt(message, rdataset));
   13121 }
   13122 
   13123 /*
   13124  * Called when stub zone update is finished.
   13125  * Update zone refresh, retry, expire values accordingly with
   13126  * SOA received from master, sync database to file, restart
   13127  * zone management timer.
   13128  */
   13129 static void
   13130 stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) {
   13131 	uint32_t refresh, retry, expire;
   13132 	isc_result_t result;
   13133 	isc_interval_t i;
   13134 	unsigned int soacount;
   13135 	dns_zone_t *zone = stub->zone;
   13136 
   13137 	/*
   13138 	 * Tidy up.
   13139 	 */
   13140 	dns_db_closeversion(stub->db, &stub->version, true);
   13141 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   13142 	if (zone->db == NULL) {
   13143 		zone_attachdb(zone, stub->db);
   13144 	}
   13145 	result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, NULL,
   13146 				  &refresh, &retry, &expire, NULL, NULL);
   13147 	if (result == ISC_R_SUCCESS && soacount > 0U) {
   13148 		zone->refresh = RANGE(refresh, zone->minrefresh,
   13149 				      zone->maxrefresh);
   13150 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   13151 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   13152 				     DNS_MAX_EXPIRE);
   13153 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   13154 	}
   13155 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   13156 	dns_db_detach(&stub->db);
   13157 
   13158 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13159 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   13160 	DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   13161 	isc_interval_set(&i, zone->expire, 0);
   13162 	DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
   13163 
   13164 	if (zone->masterfile != NULL) {
   13165 		zone_needdump(zone, 0);
   13166 	}
   13167 
   13168 	zone_settimer(zone, &now);
   13169 }
   13170 
   13171 /*
   13172  * Process answers for A and AAAA queries when
   13173  * resolving nameserver addresses for which glue
   13174  * was missing in a previous answer for a NS query.
   13175  */
   13176 static void
   13177 stub_glue_response_cb(isc_task_t *task, isc_event_t *event) {
   13178 	const char me[] = "stub_glue_response_cb";
   13179 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13180 	dns_stub_t *stub = NULL;
   13181 	dns_message_t *msg = NULL;
   13182 	dns_zone_t *zone = NULL;
   13183 	char master[ISC_SOCKADDR_FORMATSIZE];
   13184 	char source[ISC_SOCKADDR_FORMATSIZE];
   13185 	uint32_t addr_count, cnamecnt;
   13186 	isc_result_t result;
   13187 	isc_time_t now;
   13188 	struct stub_glue_request *request;
   13189 	struct stub_cb_args *cb_args;
   13190 	dns_rdataset_t *addr_rdataset = NULL;
   13191 	dns_dbnode_t *node = NULL;
   13192 
   13193 	UNUSED(task);
   13194 
   13195 	request = revent->ev_arg;
   13196 	cb_args = request->args;
   13197 	stub = cb_args->stub;
   13198 	INSIST(DNS_STUB_VALID(stub));
   13199 
   13200 	zone = stub->zone;
   13201 
   13202 	ENTER;
   13203 
   13204 	TIME_NOW(&now);
   13205 
   13206 	LOCK_ZONE(zone);
   13207 
   13208 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13209 		zone_debuglog(zone, me, 1, "exiting");
   13210 		goto cleanup;
   13211 	}
   13212 
   13213 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   13214 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13215 
   13216 	if (revent->result != ISC_R_SUCCESS) {
   13217 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
   13218 					   &zone->sourceaddr, &now);
   13219 		dns_zone_log(zone, ISC_LOG_INFO,
   13220 			     "could not refresh stub from master %s"
   13221 			     " (source %s): %s",
   13222 			     master, source, dns_result_totext(revent->result));
   13223 		goto cleanup;
   13224 	}
   13225 
   13226 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13227 	result = dns_request_getresponse(revent->request, msg, 0);
   13228 	if (result != ISC_R_SUCCESS) {
   13229 		dns_zone_log(zone, ISC_LOG_INFO,
   13230 			     "refreshing stub: unable to parse response (%s)",
   13231 			     isc_result_totext(result));
   13232 		goto cleanup;
   13233 	}
   13234 
   13235 	/*
   13236 	 * Unexpected opcode.
   13237 	 */
   13238 	if (msg->opcode != dns_opcode_query) {
   13239 		char opcode[128];
   13240 		isc_buffer_t rb;
   13241 
   13242 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   13243 		(void)dns_opcode_totext(msg->opcode, &rb);
   13244 
   13245 		dns_zone_log(zone, ISC_LOG_INFO,
   13246 			     "refreshing stub: "
   13247 			     "unexpected opcode (%.*s) from %s (source %s)",
   13248 			     (int)rb.used, opcode, master, source);
   13249 		goto cleanup;
   13250 	}
   13251 
   13252 	/*
   13253 	 * Unexpected rcode.
   13254 	 */
   13255 	if (msg->rcode != dns_rcode_noerror) {
   13256 		char rcode[128];
   13257 		isc_buffer_t rb;
   13258 
   13259 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13260 		(void)dns_rcode_totext(msg->rcode, &rb);
   13261 
   13262 		dns_zone_log(zone, ISC_LOG_INFO,
   13263 			     "refreshing stub: "
   13264 			     "unexpected rcode (%.*s) from %s (source %s)",
   13265 			     (int)rb.used, rcode, master, source);
   13266 		goto cleanup;
   13267 	}
   13268 
   13269 	/*
   13270 	 * We need complete messages.
   13271 	 */
   13272 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13273 		if (dns_request_usedtcp(revent->request)) {
   13274 			dns_zone_log(zone, ISC_LOG_INFO,
   13275 				     "refreshing stub: truncated TCP "
   13276 				     "response from master %s (source %s)",
   13277 				     master, source);
   13278 		}
   13279 		goto cleanup;
   13280 	}
   13281 
   13282 	/*
   13283 	 * If non-auth log.
   13284 	 */
   13285 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13286 		dns_zone_log(zone, ISC_LOG_INFO,
   13287 			     "refreshing stub: "
   13288 			     "non-authoritative answer from "
   13289 			     "master %s (source %s)",
   13290 			     master, source);
   13291 		goto cleanup;
   13292 	}
   13293 
   13294 	/*
   13295 	 * Sanity checks.
   13296 	 */
   13297 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13298 	addr_count = message_count(msg, DNS_SECTION_ANSWER,
   13299 				   request->ipv4 ? dns_rdatatype_a
   13300 						 : dns_rdatatype_aaaa);
   13301 
   13302 	if (cnamecnt != 0) {
   13303 		dns_zone_log(zone, ISC_LOG_INFO,
   13304 			     "refreshing stub: unexpected CNAME response "
   13305 			     "from master %s (source %s)",
   13306 			     master, source);
   13307 		goto cleanup;
   13308 	}
   13309 
   13310 	if (addr_count == 0) {
   13311 		dns_zone_log(zone, ISC_LOG_INFO,
   13312 			     "refreshing stub: no %s records in response "
   13313 			     "from master %s (source %s)",
   13314 			     request->ipv4 ? "A" : "AAAA", master, source);
   13315 		goto cleanup;
   13316 	}
   13317 	/*
   13318 	 * Extract A or AAAA RRset from message.
   13319 	 */
   13320 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &request->name,
   13321 				      request->ipv4 ? dns_rdatatype_a
   13322 						    : dns_rdatatype_aaaa,
   13323 				      dns_rdatatype_none, NULL, &addr_rdataset);
   13324 	if (result != ISC_R_SUCCESS) {
   13325 		if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) {
   13326 			char namebuf[DNS_NAME_FORMATSIZE];
   13327 			dns_name_format(&request->name, namebuf,
   13328 					sizeof(namebuf));
   13329 			dns_zone_log(
   13330 				zone, ISC_LOG_INFO,
   13331 				"refreshing stub: dns_message_findname(%s/%s) "
   13332 				"failed (%s)",
   13333 				namebuf, request->ipv4 ? "A" : "AAAA",
   13334 				isc_result_totext(result));
   13335 		}
   13336 		goto cleanup;
   13337 	}
   13338 
   13339 	result = dns_db_findnode(stub->db, &request->name, true, &node);
   13340 	if (result != ISC_R_SUCCESS) {
   13341 		dns_zone_log(zone, ISC_LOG_INFO,
   13342 			     "refreshing stub: "
   13343 			     "dns_db_findnode() failed: %s",
   13344 			     dns_result_totext(result));
   13345 		goto cleanup;
   13346 	}
   13347 
   13348 	result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   13349 				    addr_rdataset, 0, NULL);
   13350 	if (result != ISC_R_SUCCESS) {
   13351 		dns_zone_log(zone, ISC_LOG_INFO,
   13352 			     "refreshing stub: "
   13353 			     "dns_db_addrdataset() failed: %s",
   13354 			     dns_result_totext(result));
   13355 	}
   13356 	dns_db_detachnode(stub->db, &node);
   13357 
   13358 cleanup:
   13359 	if (msg != NULL) {
   13360 		dns_message_detach(&msg);
   13361 	}
   13362 	isc_event_free(&event);
   13363 	dns_name_free(&request->name, zone->mctx);
   13364 	dns_request_destroy(&request->request);
   13365 	isc_mem_put(zone->mctx, request, sizeof(*request));
   13366 
   13367 	/* If last request, release all related resources */
   13368 	if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) {
   13369 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13370 		stub_finish_zone_update(stub, now);
   13371 		UNLOCK_ZONE(zone);
   13372 		stub->magic = 0;
   13373 		dns_zone_idetach(&stub->zone);
   13374 		INSIST(stub->db == NULL);
   13375 		INSIST(stub->version == NULL);
   13376 		isc_mem_put(stub->mctx, stub, sizeof(*stub));
   13377 	} else {
   13378 		UNLOCK_ZONE(zone);
   13379 	}
   13380 }
   13381 
   13382 /*
   13383  * Create and send an A or AAAA query to the master
   13384  * server of the stub zone given.
   13385  */
   13386 static isc_result_t
   13387 stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4,
   13388 				const dns_name_t *name) {
   13389 	dns_message_t *message = NULL;
   13390 	dns_zone_t *zone;
   13391 	isc_result_t result;
   13392 	struct stub_glue_request *request;
   13393 
   13394 	zone = args->stub->zone;
   13395 	request = isc_mem_get(zone->mctx, sizeof(*request));
   13396 	request->request = NULL;
   13397 	request->args = args;
   13398 	request->name = (dns_name_t)DNS_NAME_INITEMPTY;
   13399 	request->ipv4 = ipv4;
   13400 	dns_name_dup(name, zone->mctx, &request->name);
   13401 
   13402 	result = create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa,
   13403 			      &request->name, &message);
   13404 	INSIST(result == ISC_R_SUCCESS);
   13405 
   13406 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   13407 		result = add_opt(message, args->udpsize, args->reqnsid, false);
   13408 		if (result != ISC_R_SUCCESS) {
   13409 			zone_debuglog(zone, "stub_send_query", 1,
   13410 				      "unable to add opt record: %s",
   13411 				      dns_result_totext(result));
   13412 			goto fail;
   13413 		}
   13414 	}
   13415 
   13416 	atomic_fetch_add_release(&args->stub->pending_requests, 1);
   13417 
   13418 	result = dns_request_createvia(
   13419 		zone->view->requestmgr, message, &zone->sourceaddr,
   13420 		&zone->masteraddr, args->dscp, DNS_REQUESTOPT_TCP,
   13421 		args->tsig_key, args->timeout * 3, args->timeout, 0, zone->task,
   13422 		stub_glue_response_cb, request, &request->request);
   13423 
   13424 	if (result != ISC_R_SUCCESS) {
   13425 		INSIST(atomic_fetch_sub_release(&args->stub->pending_requests,
   13426 						1) > 1);
   13427 		zone_debuglog(zone, "stub_send_query", 1,
   13428 			      "dns_request_createvia() failed: %s",
   13429 			      dns_result_totext(result));
   13430 		goto fail;
   13431 	}
   13432 
   13433 	dns_message_detach(&message);
   13434 
   13435 	return (ISC_R_SUCCESS);
   13436 
   13437 fail:
   13438 	dns_name_free(&request->name, zone->mctx);
   13439 	isc_mem_put(zone->mctx, request, sizeof(*request));
   13440 
   13441 	if (message != NULL) {
   13442 		dns_message_detach(&message);
   13443 	}
   13444 
   13445 	return (result);
   13446 }
   13447 
   13448 static isc_result_t
   13449 save_nsrrset(dns_message_t *message, dns_name_t *name,
   13450 	     struct stub_cb_args *cb_args, dns_db_t *db,
   13451 	     dns_dbversion_t *version) {
   13452 	dns_rdataset_t *nsrdataset = NULL;
   13453 	dns_rdataset_t *rdataset = NULL;
   13454 	dns_dbnode_t *node = NULL;
   13455 	dns_rdata_ns_t ns;
   13456 	isc_result_t result;
   13457 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13458 	bool has_glue = false;
   13459 	dns_name_t *ns_name;
   13460 	/*
   13461 	 * List of NS entries in answer, keep names that will be used
   13462 	 * to resolve missing A/AAAA glue for each entry.
   13463 	 */
   13464 	dns_namelist_t ns_list;
   13465 	ISC_LIST_INIT(ns_list);
   13466 
   13467 	/*
   13468 	 * Extract NS RRset from message.
   13469 	 */
   13470 	result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
   13471 				      dns_rdatatype_ns, dns_rdatatype_none,
   13472 				      NULL, &nsrdataset);
   13473 	if (result != ISC_R_SUCCESS) {
   13474 		goto done;
   13475 	}
   13476 
   13477 	/*
   13478 	 * Add NS rdataset.
   13479 	 */
   13480 	result = dns_db_findnode(db, name, true, &node);
   13481 	if (result != ISC_R_SUCCESS) {
   13482 		goto done;
   13483 	}
   13484 	result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL);
   13485 	dns_db_detachnode(db, &node);
   13486 	if (result != ISC_R_SUCCESS) {
   13487 		goto done;
   13488 	}
   13489 	/*
   13490 	 * Add glue rdatasets.
   13491 	 */
   13492 	for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS;
   13493 	     result = dns_rdataset_next(nsrdataset))
   13494 	{
   13495 		dns_rdataset_current(nsrdataset, &rdata);
   13496 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   13497 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13498 		dns_rdata_reset(&rdata);
   13499 
   13500 		if (!dns_name_issubdomain(&ns.name, name)) {
   13501 			continue;
   13502 		}
   13503 		rdataset = NULL;
   13504 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
   13505 					      &ns.name, dns_rdatatype_aaaa,
   13506 					      dns_rdatatype_none, NULL,
   13507 					      &rdataset);
   13508 		if (result == ISC_R_SUCCESS) {
   13509 			has_glue = true;
   13510 			result = dns_db_findnode(db, &ns.name, true, &node);
   13511 			if (result != ISC_R_SUCCESS) {
   13512 				goto done;
   13513 			}
   13514 			result = dns_db_addrdataset(db, node, version, 0,
   13515 						    rdataset, 0, NULL);
   13516 			dns_db_detachnode(db, &node);
   13517 			if (result != ISC_R_SUCCESS) {
   13518 				goto done;
   13519 			}
   13520 		}
   13521 
   13522 		rdataset = NULL;
   13523 		result = dns_message_findname(
   13524 			message, DNS_SECTION_ADDITIONAL, &ns.name,
   13525 			dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset);
   13526 		if (result == ISC_R_SUCCESS) {
   13527 			has_glue = true;
   13528 			result = dns_db_findnode(db, &ns.name, true, &node);
   13529 			if (result != ISC_R_SUCCESS) {
   13530 				goto done;
   13531 			}
   13532 			result = dns_db_addrdataset(db, node, version, 0,
   13533 						    rdataset, 0, NULL);
   13534 			dns_db_detachnode(db, &node);
   13535 			if (result != ISC_R_SUCCESS) {
   13536 				goto done;
   13537 			}
   13538 		}
   13539 
   13540 		/*
   13541 		 * If no glue is found so far, we add the name to the list to
   13542 		 * resolve the A/AAAA glue later. If any glue is found in any
   13543 		 * iteration step, this list will be discarded and only the glue
   13544 		 * provided in this message will be used.
   13545 		 */
   13546 		if (!has_glue && dns_name_issubdomain(&ns.name, name)) {
   13547 			dns_name_t *tmp_name;
   13548 			tmp_name = isc_mem_get(cb_args->stub->mctx,
   13549 					       sizeof(*tmp_name));
   13550 			dns_name_init(tmp_name, NULL);
   13551 			dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name);
   13552 			ISC_LIST_APPEND(ns_list, tmp_name, link);
   13553 		}
   13554 	}
   13555 
   13556 	if (result != ISC_R_NOMORE) {
   13557 		goto done;
   13558 	}
   13559 
   13560 	/*
   13561 	 * If no glue records were found, we attempt to resolve A/AAAA
   13562 	 * for each NS entry found in the answer.
   13563 	 */
   13564 	if (!has_glue) {
   13565 		for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL;
   13566 		     ns_name = ISC_LIST_NEXT(ns_name, link))
   13567 		{
   13568 			/*
   13569 			 * Resolve NS IPv4 address/A.
   13570 			 */
   13571 			result = stub_request_nameserver_address(cb_args, true,
   13572 								 ns_name);
   13573 			if (result != ISC_R_SUCCESS) {
   13574 				goto done;
   13575 			}
   13576 			/*
   13577 			 * Resolve NS IPv6 address/AAAA.
   13578 			 */
   13579 			result = stub_request_nameserver_address(cb_args, false,
   13580 								 ns_name);
   13581 			if (result != ISC_R_SUCCESS) {
   13582 				goto done;
   13583 			}
   13584 		}
   13585 	}
   13586 
   13587 	result = ISC_R_SUCCESS;
   13588 
   13589 done:
   13590 	while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) {
   13591 		ISC_LIST_UNLINK(ns_list, ns_name, link);
   13592 		dns_name_free(ns_name, cb_args->stub->mctx);
   13593 		isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name));
   13594 	}
   13595 	return (result);
   13596 }
   13597 
   13598 static void
   13599 stub_callback(isc_task_t *task, isc_event_t *event) {
   13600 	const char me[] = "stub_callback";
   13601 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13602 	dns_stub_t *stub = NULL;
   13603 	dns_message_t *msg = NULL;
   13604 	dns_zone_t *zone = NULL;
   13605 	char master[ISC_SOCKADDR_FORMATSIZE];
   13606 	char source[ISC_SOCKADDR_FORMATSIZE];
   13607 	uint32_t nscnt, cnamecnt;
   13608 	isc_result_t result;
   13609 	isc_time_t now;
   13610 	bool exiting = false;
   13611 	unsigned int j;
   13612 	struct stub_cb_args *cb_args;
   13613 
   13614 	cb_args = revent->ev_arg;
   13615 	stub = cb_args->stub;
   13616 	INSIST(DNS_STUB_VALID(stub));
   13617 
   13618 	UNUSED(task);
   13619 
   13620 	zone = stub->zone;
   13621 
   13622 	ENTER;
   13623 
   13624 	TIME_NOW(&now);
   13625 
   13626 	LOCK_ZONE(zone);
   13627 
   13628 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13629 		zone_debuglog(zone, me, 1, "exiting");
   13630 		exiting = true;
   13631 		goto next_master;
   13632 	}
   13633 
   13634 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   13635 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13636 
   13637 	if (revent->result != ISC_R_SUCCESS) {
   13638 		if (revent->result == ISC_R_TIMEDOUT &&
   13639 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS))
   13640 		{
   13641 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13642 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13643 				     "refreshing stub: timeout retrying "
   13644 				     " without EDNS master %s (source %s)",
   13645 				     master, source);
   13646 			goto same_master;
   13647 		}
   13648 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
   13649 					   &zone->sourceaddr, &now);
   13650 		dns_zone_log(zone, ISC_LOG_INFO,
   13651 			     "could not refresh stub from master %s"
   13652 			     " (source %s): %s",
   13653 			     master, source, dns_result_totext(revent->result));
   13654 		goto next_master;
   13655 	}
   13656 
   13657 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13658 
   13659 	result = dns_request_getresponse(revent->request, msg, 0);
   13660 	if (result != ISC_R_SUCCESS) {
   13661 		goto next_master;
   13662 	}
   13663 
   13664 	/*
   13665 	 * Unexpected opcode.
   13666 	 */
   13667 	if (msg->opcode != dns_opcode_query) {
   13668 		char opcode[128];
   13669 		isc_buffer_t rb;
   13670 
   13671 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   13672 		(void)dns_opcode_totext(msg->opcode, &rb);
   13673 
   13674 		dns_zone_log(zone, ISC_LOG_INFO,
   13675 			     "refreshing stub: "
   13676 			     "unexpected opcode (%.*s) from %s (source %s)",
   13677 			     (int)rb.used, opcode, master, source);
   13678 		goto next_master;
   13679 	}
   13680 
   13681 	/*
   13682 	 * Unexpected rcode.
   13683 	 */
   13684 	if (msg->rcode != dns_rcode_noerror) {
   13685 		char rcode[128];
   13686 		isc_buffer_t rb;
   13687 
   13688 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13689 		(void)dns_rcode_totext(msg->rcode, &rb);
   13690 
   13691 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13692 		    (msg->rcode == dns_rcode_servfail ||
   13693 		     msg->rcode == dns_rcode_notimp ||
   13694 		     msg->rcode == dns_rcode_formerr))
   13695 		{
   13696 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13697 				     "refreshing stub: rcode (%.*s) retrying "
   13698 				     "without EDNS master %s (source %s)",
   13699 				     (int)rb.used, rcode, master, source);
   13700 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13701 			goto same_master;
   13702 		}
   13703 
   13704 		dns_zone_log(zone, ISC_LOG_INFO,
   13705 			     "refreshing stub: "
   13706 			     "unexpected rcode (%.*s) from %s (source %s)",
   13707 			     (int)rb.used, rcode, master, source);
   13708 		goto next_master;
   13709 	}
   13710 
   13711 	/*
   13712 	 * We need complete messages.
   13713 	 */
   13714 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13715 		if (dns_request_usedtcp(revent->request)) {
   13716 			dns_zone_log(zone, ISC_LOG_INFO,
   13717 				     "refreshing stub: truncated TCP "
   13718 				     "response from master %s (source %s)",
   13719 				     master, source);
   13720 			goto next_master;
   13721 		}
   13722 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   13723 		goto same_master;
   13724 	}
   13725 
   13726 	/*
   13727 	 * If non-auth log and next master.
   13728 	 */
   13729 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13730 		dns_zone_log(zone, ISC_LOG_INFO,
   13731 			     "refreshing stub: "
   13732 			     "non-authoritative answer from "
   13733 			     "master %s (source %s)",
   13734 			     master, source);
   13735 		goto next_master;
   13736 	}
   13737 
   13738 	/*
   13739 	 * Sanity checks.
   13740 	 */
   13741 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13742 	nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
   13743 
   13744 	if (cnamecnt != 0) {
   13745 		dns_zone_log(zone, ISC_LOG_INFO,
   13746 			     "refreshing stub: unexpected CNAME response "
   13747 			     "from master %s (source %s)",
   13748 			     master, source);
   13749 		goto next_master;
   13750 	}
   13751 
   13752 	if (nscnt == 0) {
   13753 		dns_zone_log(zone, ISC_LOG_INFO,
   13754 			     "refreshing stub: no NS records in response "
   13755 			     "from master %s (source %s)",
   13756 			     master, source);
   13757 		goto next_master;
   13758 	}
   13759 
   13760 	atomic_fetch_add(&stub->pending_requests, 1);
   13761 
   13762 	/*
   13763 	 * Save answer.
   13764 	 */
   13765 	result = save_nsrrset(msg, &zone->origin, cb_args, stub->db,
   13766 			      stub->version);
   13767 	if (result != ISC_R_SUCCESS) {
   13768 		dns_zone_log(zone, ISC_LOG_INFO,
   13769 			     "refreshing stub: unable to save NS records "
   13770 			     "from master %s (source %s)",
   13771 			     master, source);
   13772 		goto next_master;
   13773 	}
   13774 
   13775 	dns_message_detach(&msg);
   13776 	isc_event_free(&event);
   13777 	dns_request_destroy(&zone->request);
   13778 
   13779 	/*
   13780 	 * Check to see if there are no outstanding requests and
   13781 	 * finish off if that is so.
   13782 	 */
   13783 	if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) {
   13784 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13785 		stub_finish_zone_update(stub, now);
   13786 		goto free_stub;
   13787 	}
   13788 
   13789 	UNLOCK_ZONE(zone);
   13790 	return;
   13791 
   13792 next_master:
   13793 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13794 	if (stub->version != NULL) {
   13795 		dns_db_closeversion(stub->db, &stub->version, false);
   13796 	}
   13797 	if (stub->db != NULL) {
   13798 		dns_db_detach(&stub->db);
   13799 	}
   13800 	if (msg != NULL) {
   13801 		dns_message_detach(&msg);
   13802 	}
   13803 	isc_event_free(&event);
   13804 	dns_request_destroy(&zone->request);
   13805 	/*
   13806 	 * Skip to next failed / untried master.
   13807 	 */
   13808 	do {
   13809 		zone->curmaster++;
   13810 	} while (zone->curmaster < zone->masterscnt &&
   13811 		 zone->mastersok[zone->curmaster]);
   13812 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13813 	if (exiting || zone->curmaster >= zone->masterscnt) {
   13814 		bool done = true;
   13815 		if (!exiting &&
   13816 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   13817 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   13818 		{
   13819 			/*
   13820 			 * Did we get a good answer from all the primaries?
   13821 			 */
   13822 			for (j = 0; j < zone->masterscnt; j++) {
   13823 				if (!zone->mastersok[j]) {
   13824 					{
   13825 						done = false;
   13826 						break;
   13827 					}
   13828 				}
   13829 			}
   13830 		} else {
   13831 			done = true;
   13832 		}
   13833 		if (!done) {
   13834 			zone->curmaster = 0;
   13835 			/*
   13836 			 * Find the next failed master.
   13837 			 */
   13838 			while (zone->curmaster < zone->masterscnt &&
   13839 			       zone->mastersok[zone->curmaster])
   13840 			{
   13841 				zone->curmaster++;
   13842 			}
   13843 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13844 		} else {
   13845 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13846 
   13847 			zone_settimer(zone, &now);
   13848 			goto free_stub;
   13849 		}
   13850 	}
   13851 	queue_soa_query(zone);
   13852 	goto free_stub;
   13853 
   13854 same_master:
   13855 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13856 	if (msg != NULL) {
   13857 		dns_message_detach(&msg);
   13858 	}
   13859 	isc_event_free(&event);
   13860 	dns_request_destroy(&zone->request);
   13861 	ns_query(zone, NULL, stub);
   13862 	UNLOCK_ZONE(zone);
   13863 	goto done;
   13864 
   13865 free_stub:
   13866 	UNLOCK_ZONE(zone);
   13867 	stub->magic = 0;
   13868 	dns_zone_idetach(&stub->zone);
   13869 	INSIST(stub->db == NULL);
   13870 	INSIST(stub->version == NULL);
   13871 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   13872 
   13873 done:
   13874 	INSIST(event == NULL);
   13875 	return;
   13876 }
   13877 
   13878 /*
   13879  * Get the EDNS EXPIRE option from the response and if it exists trim
   13880  * expire to be not more than it.
   13881  */
   13882 static void
   13883 get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) {
   13884 	isc_result_t result;
   13885 	uint32_t expire;
   13886 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13887 	isc_buffer_t optbuf;
   13888 	uint16_t optcode;
   13889 	uint16_t optlen;
   13890 
   13891 	REQUIRE(expirep != NULL);
   13892 	REQUIRE(message != NULL);
   13893 
   13894 	if (message->opt == NULL) {
   13895 		return;
   13896 	}
   13897 
   13898 	result = dns_rdataset_first(message->opt);
   13899 	if (result == ISC_R_SUCCESS) {
   13900 		dns_rdataset_current(message->opt, &rdata);
   13901 		isc_buffer_init(&optbuf, rdata.data, rdata.length);
   13902 		isc_buffer_add(&optbuf, rdata.length);
   13903 		while (isc_buffer_remaininglength(&optbuf) >= 4) {
   13904 			optcode = isc_buffer_getuint16(&optbuf);
   13905 			optlen = isc_buffer_getuint16(&optbuf);
   13906 			/*
   13907 			 * A EDNS EXPIRE response has a length of 4.
   13908 			 */
   13909 			if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
   13910 				isc_buffer_forward(&optbuf, optlen);
   13911 				continue;
   13912 			}
   13913 			expire = isc_buffer_getuint32(&optbuf);
   13914 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13915 				     "got EDNS EXPIRE of %u", expire);
   13916 			/*
   13917 			 * Trim *expirep?
   13918 			 */
   13919 			if (expire < *expirep) {
   13920 				*expirep = expire;
   13921 			}
   13922 			break;
   13923 		}
   13924 	}
   13925 }
   13926 
   13927 /*
   13928  * Set the file modification time zone->expire seconds before expiretime.
   13929  */
   13930 static void
   13931 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
   13932 	isc_result_t result;
   13933 	isc_time_t when;
   13934 	isc_interval_t i;
   13935 
   13936 	isc_interval_set(&i, zone->expire, 0);
   13937 	result = isc_time_subtract(expiretime, &i, &when);
   13938 	if (result != ISC_R_SUCCESS) {
   13939 		return;
   13940 	}
   13941 
   13942 	result = ISC_R_FAILURE;
   13943 	if (zone->journal != NULL) {
   13944 		result = isc_file_settime(zone->journal, &when);
   13945 	}
   13946 	if (result == ISC_R_SUCCESS &&
   13947 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   13948 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   13949 	{
   13950 		result = isc_file_settime(zone->masterfile, &when);
   13951 	} else if (result != ISC_R_SUCCESS) {
   13952 		result = isc_file_settime(zone->masterfile, &when);
   13953 	}
   13954 
   13955 	/*
   13956 	 * Someone removed the file from underneath us!
   13957 	 */
   13958 	if (result == ISC_R_FILENOTFOUND) {
   13959 		zone_needdump(zone, DNS_DUMP_DELAY);
   13960 	} else if (result != ISC_R_SUCCESS) {
   13961 		dns_zone_log(zone, ISC_LOG_ERROR,
   13962 			     "refresh: could not set "
   13963 			     "file modification time of '%s': %s",
   13964 			     zone->masterfile, dns_result_totext(result));
   13965 	}
   13966 }
   13967 
   13968 /*
   13969  * An SOA query has finished (successfully or not).
   13970  */
   13971 static void
   13972 refresh_callback(isc_task_t *task, isc_event_t *event) {
   13973 	const char me[] = "refresh_callback";
   13974 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13975 	dns_zone_t *zone;
   13976 	dns_message_t *msg = NULL;
   13977 	uint32_t soacnt, cnamecnt, soacount, nscount;
   13978 	isc_time_t now;
   13979 	char master[ISC_SOCKADDR_FORMATSIZE];
   13980 	char source[ISC_SOCKADDR_FORMATSIZE];
   13981 	dns_rdataset_t *rdataset = NULL;
   13982 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13983 	dns_rdata_soa_t soa;
   13984 	isc_result_t result;
   13985 	uint32_t serial, oldserial = 0;
   13986 	unsigned int j;
   13987 	bool do_queue_xfrin = false;
   13988 
   13989 	zone = revent->ev_arg;
   13990 	INSIST(DNS_ZONE_VALID(zone));
   13991 
   13992 	UNUSED(task);
   13993 
   13994 	ENTER;
   13995 
   13996 	TIME_NOW(&now);
   13997 
   13998 	LOCK_ZONE(zone);
   13999 
   14000 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14001 		isc_event_free(&event);
   14002 		dns_request_destroy(&zone->request);
   14003 		goto detach;
   14004 	}
   14005 
   14006 	/*
   14007 	 * if timeout log and next master;
   14008 	 */
   14009 
   14010 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   14011 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   14012 
   14013 	if (revent->result != ISC_R_SUCCESS) {
   14014 		if (revent->result == ISC_R_TIMEDOUT &&
   14015 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS))
   14016 		{
   14017 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14018 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14019 				     "refresh: timeout retrying without EDNS "
   14020 				     "master %s (source %s)",
   14021 				     master, source);
   14022 			goto same_master;
   14023 		}
   14024 		if (revent->result == ISC_R_TIMEDOUT &&
   14025 		    !dns_request_usedtcp(revent->request))
   14026 		{
   14027 			dns_zone_log(zone, ISC_LOG_INFO,
   14028 				     "refresh: retry limit for "
   14029 				     "master %s exceeded (source %s)",
   14030 				     master, source);
   14031 			/* Try with slave with TCP. */
   14032 			if ((zone->type == dns_zone_secondary ||
   14033 			     zone->type == dns_zone_mirror ||
   14034 			     zone->type == dns_zone_redirect) &&
   14035 			    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
   14036 			{
   14037 				if (!dns_zonemgr_unreachable(
   14038 					    zone->zmgr, &zone->masteraddr,
   14039 					    &zone->sourceaddr, &now))
   14040 				{
   14041 					DNS_ZONE_SETFLAG(
   14042 						zone,
   14043 						DNS_ZONEFLG_SOABEFOREAXFR);
   14044 					goto tcp_transfer;
   14045 				}
   14046 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14047 					     "refresh: skipped tcp fallback "
   14048 					     "as master %s (source %s) is "
   14049 					     "unreachable (cached)",
   14050 					     master, source);
   14051 			}
   14052 		} else {
   14053 			dns_zone_log(zone, ISC_LOG_INFO,
   14054 				     "refresh: failure trying master "
   14055 				     "%s (source %s): %s",
   14056 				     master, source,
   14057 				     dns_result_totext(revent->result));
   14058 		}
   14059 		goto next_master;
   14060 	}
   14061 
   14062 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   14063 	result = dns_request_getresponse(revent->request, msg, 0);
   14064 	if (result != ISC_R_SUCCESS) {
   14065 		dns_zone_log(zone, ISC_LOG_INFO,
   14066 			     "refresh: failure trying master "
   14067 			     "%s (source %s): %s",
   14068 			     master, source, dns_result_totext(result));
   14069 		goto next_master;
   14070 	}
   14071 
   14072 	/*
   14073 	 * Unexpected opcode.
   14074 	 */
   14075 	if (msg->opcode != dns_opcode_query) {
   14076 		char opcode[128];
   14077 		isc_buffer_t rb;
   14078 
   14079 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   14080 		(void)dns_opcode_totext(msg->opcode, &rb);
   14081 
   14082 		dns_zone_log(zone, ISC_LOG_INFO,
   14083 			     "refresh: "
   14084 			     "unexpected opcode (%.*s) from %s (source %s)",
   14085 			     (int)rb.used, opcode, master, source);
   14086 		goto next_master;
   14087 	}
   14088 
   14089 	/*
   14090 	 * Unexpected rcode.
   14091 	 */
   14092 	if (msg->rcode != dns_rcode_noerror) {
   14093 		char rcode[128];
   14094 		isc_buffer_t rb;
   14095 
   14096 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   14097 		(void)dns_rcode_totext(msg->rcode, &rb);
   14098 
   14099 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   14100 		    (msg->rcode == dns_rcode_servfail ||
   14101 		     msg->rcode == dns_rcode_notimp ||
   14102 		     msg->rcode == dns_rcode_formerr))
   14103 		{
   14104 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14105 				     "refresh: rcode (%.*s) retrying without "
   14106 				     "EDNS master %s (source %s)",
   14107 				     (int)rb.used, rcode, master, source);
   14108 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14109 			goto same_master;
   14110 		}
   14111 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   14112 		    msg->rcode == dns_rcode_badvers)
   14113 		{
   14114 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14115 				     "refresh: rcode (%.*s) retrying without "
   14116 				     "EDNS EXPIRE OPTION master %s (source %s)",
   14117 				     (int)rb.used, rcode, master, source);
   14118 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14119 			goto same_master;
   14120 		}
   14121 		dns_zone_log(zone, ISC_LOG_INFO,
   14122 			     "refresh: unexpected rcode (%.*s) from "
   14123 			     "master %s (source %s)",
   14124 			     (int)rb.used, rcode, master, source);
   14125 		/*
   14126 		 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
   14127 		 */
   14128 		if (msg->rcode == dns_rcode_refused &&
   14129 		    (zone->type == dns_zone_secondary ||
   14130 		     zone->type == dns_zone_mirror ||
   14131 		     zone->type == dns_zone_redirect))
   14132 		{
   14133 			goto tcp_transfer;
   14134 		}
   14135 		goto next_master;
   14136 	}
   14137 
   14138 	/*
   14139 	 * If truncated punt to zone transfer which will query again.
   14140 	 */
   14141 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   14142 		if (zone->type == dns_zone_secondary ||
   14143 		    zone->type == dns_zone_mirror ||
   14144 		    zone->type == dns_zone_redirect)
   14145 		{
   14146 			dns_zone_log(zone, ISC_LOG_INFO,
   14147 				     "refresh: truncated UDP answer, "
   14148 				     "initiating TCP zone xfer "
   14149 				     "for master %s (source %s)",
   14150 				     master, source);
   14151 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   14152 			goto tcp_transfer;
   14153 		} else {
   14154 			INSIST(zone->type == dns_zone_stub);
   14155 			if (dns_request_usedtcp(revent->request)) {
   14156 				dns_zone_log(zone, ISC_LOG_INFO,
   14157 					     "refresh: truncated TCP response "
   14158 					     "from master %s (source %s)",
   14159 					     master, source);
   14160 				goto next_master;
   14161 			}
   14162 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   14163 			goto same_master;
   14164 		}
   14165 	}
   14166 
   14167 	/*
   14168 	 * if non-auth log and next master;
   14169 	 */
   14170 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   14171 		dns_zone_log(zone, ISC_LOG_INFO,
   14172 			     "refresh: non-authoritative answer from "
   14173 			     "master %s (source %s)",
   14174 			     master, source);
   14175 		goto next_master;
   14176 	}
   14177 
   14178 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   14179 	soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
   14180 	nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
   14181 	soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa);
   14182 
   14183 	/*
   14184 	 * There should not be a CNAME record at top of zone.
   14185 	 */
   14186 	if (cnamecnt != 0) {
   14187 		dns_zone_log(zone, ISC_LOG_INFO,
   14188 			     "refresh: CNAME at top of zone "
   14189 			     "in master %s (source %s)",
   14190 			     master, source);
   14191 		goto next_master;
   14192 	}
   14193 
   14194 	/*
   14195 	 * if referral log and next master;
   14196 	 */
   14197 	if (soacnt == 0 && soacount == 0 && nscount != 0) {
   14198 		dns_zone_log(zone, ISC_LOG_INFO,
   14199 			     "refresh: referral response "
   14200 			     "from master %s (source %s)",
   14201 			     master, source);
   14202 		goto next_master;
   14203 	}
   14204 
   14205 	/*
   14206 	 * if nodata log and next master;
   14207 	 */
   14208 	if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
   14209 		dns_zone_log(zone, ISC_LOG_INFO,
   14210 			     "refresh: NODATA response "
   14211 			     "from master %s (source %s)",
   14212 			     master, source);
   14213 		goto next_master;
   14214 	}
   14215 
   14216 	/*
   14217 	 * Only one soa at top of zone.
   14218 	 */
   14219 	if (soacnt != 1) {
   14220 		dns_zone_log(zone, ISC_LOG_INFO,
   14221 			     "refresh: answer SOA count (%d) != 1 "
   14222 			     "from master %s (source %s)",
   14223 			     soacnt, master, source);
   14224 		goto next_master;
   14225 	}
   14226 
   14227 	/*
   14228 	 * Extract serial
   14229 	 */
   14230 	rdataset = NULL;
   14231 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
   14232 				      dns_rdatatype_soa, dns_rdatatype_none,
   14233 				      NULL, &rdataset);
   14234 	if (result != ISC_R_SUCCESS) {
   14235 		dns_zone_log(zone, ISC_LOG_INFO,
   14236 			     "refresh: unable to get SOA record "
   14237 			     "from master %s (source %s)",
   14238 			     master, source);
   14239 		goto next_master;
   14240 	}
   14241 
   14242 	result = dns_rdataset_first(rdataset);
   14243 	if (result != ISC_R_SUCCESS) {
   14244 		dns_zone_log(zone, ISC_LOG_INFO,
   14245 			     "refresh: dns_rdataset_first() failed");
   14246 		goto next_master;
   14247 	}
   14248 
   14249 	dns_rdataset_current(rdataset, &rdata);
   14250 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   14251 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14252 
   14253 	serial = soa.serial;
   14254 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   14255 		unsigned int dbsoacount;
   14256 		result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
   14257 					  NULL, &oldserial, NULL, NULL, NULL,
   14258 					  NULL, NULL);
   14259 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14260 		RUNTIME_CHECK(dbsoacount > 0U);
   14261 		zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial,
   14262 			      oldserial);
   14263 	} else {
   14264 		zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
   14265 			      serial);
   14266 	}
   14267 
   14268 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
   14269 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
   14270 	    isc_serial_gt(serial, oldserial))
   14271 	{
   14272 		if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   14273 					    &zone->sourceaddr, &now))
   14274 		{
   14275 			dns_zone_log(zone, ISC_LOG_INFO,
   14276 				     "refresh: skipping %s as master %s "
   14277 				     "(source %s) is unreachable (cached)",
   14278 				     (zone->type == dns_zone_secondary ||
   14279 				      zone->type == dns_zone_mirror ||
   14280 				      zone->type == dns_zone_redirect)
   14281 					     ? "zone transfer"
   14282 					     : "NS query",
   14283 				     master, source);
   14284 			goto next_master;
   14285 		}
   14286 	tcp_transfer:
   14287 		isc_event_free(&event);
   14288 		dns_request_destroy(&zone->request);
   14289 		if (zone->type == dns_zone_secondary ||
   14290 		    zone->type == dns_zone_mirror ||
   14291 		    zone->type == dns_zone_redirect)
   14292 		{
   14293 			do_queue_xfrin = true;
   14294 		} else {
   14295 			INSIST(zone->type == dns_zone_stub);
   14296 			ns_query(zone, rdataset, NULL);
   14297 		}
   14298 		if (msg != NULL) {
   14299 			dns_message_detach(&msg);
   14300 		}
   14301 	} else if (isc_serial_eq(soa.serial, oldserial)) {
   14302 		isc_time_t expiretime;
   14303 		uint32_t expire;
   14304 
   14305 		/*
   14306 		 * Compute the new expire time based on this response.
   14307 		 */
   14308 		expire = zone->expire;
   14309 		get_edns_expire(zone, msg, &expire);
   14310 		DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
   14311 
   14312 		/*
   14313 		 * Has the expire time improved?
   14314 		 */
   14315 		if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
   14316 			zone->expiretime = expiretime;
   14317 			if (zone->masterfile != NULL) {
   14318 				setmodtime(zone, &expiretime);
   14319 			}
   14320 		}
   14321 
   14322 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   14323 		zone->mastersok[zone->curmaster] = true;
   14324 		goto next_master;
   14325 	} else {
   14326 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) {
   14327 			dns_zone_log(zone, ISC_LOG_INFO,
   14328 				     "serial number (%u) "
   14329 				     "received from master %s < ours (%u)",
   14330 				     soa.serial, master, oldserial);
   14331 		} else {
   14332 			zone_debuglog(zone, me, 1, "ahead");
   14333 		}
   14334 		zone->mastersok[zone->curmaster] = true;
   14335 		goto next_master;
   14336 	}
   14337 	if (msg != NULL) {
   14338 		dns_message_detach(&msg);
   14339 	}
   14340 	goto detach;
   14341 
   14342 next_master:
   14343 	if (msg != NULL) {
   14344 		dns_message_detach(&msg);
   14345 	}
   14346 	isc_event_free(&event);
   14347 	dns_request_destroy(&zone->request);
   14348 	/*
   14349 	 * Skip to next failed / untried master.
   14350 	 */
   14351 	do {
   14352 		zone->curmaster++;
   14353 	} while (zone->curmaster < zone->masterscnt &&
   14354 		 zone->mastersok[zone->curmaster]);
   14355 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14356 	if (zone->curmaster >= zone->masterscnt) {
   14357 		bool done = true;
   14358 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   14359 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   14360 		{
   14361 			/*
   14362 			 * Did we get a good answer from all the primaries?
   14363 			 */
   14364 			for (j = 0; j < zone->masterscnt; j++) {
   14365 				if (!zone->mastersok[j]) {
   14366 					{
   14367 						done = false;
   14368 						break;
   14369 					}
   14370 				}
   14371 			}
   14372 		} else {
   14373 			done = true;
   14374 		}
   14375 		if (!done) {
   14376 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   14377 			zone->curmaster = 0;
   14378 			/*
   14379 			 * Find the next failed master.
   14380 			 */
   14381 			while (zone->curmaster < zone->masterscnt &&
   14382 			       zone->mastersok[zone->curmaster])
   14383 			{
   14384 				zone->curmaster++;
   14385 			}
   14386 			goto requeue;
   14387 		}
   14388 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14389 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   14390 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   14391 			zone->refreshtime = now;
   14392 		}
   14393 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   14394 		zone_settimer(zone, &now);
   14395 		goto detach;
   14396 	}
   14397 
   14398 requeue:
   14399 	queue_soa_query(zone);
   14400 	goto detach;
   14401 
   14402 same_master:
   14403 	if (msg != NULL) {
   14404 		dns_message_detach(&msg);
   14405 	}
   14406 	isc_event_free(&event);
   14407 	dns_request_destroy(&zone->request);
   14408 	queue_soa_query(zone);
   14409 
   14410 detach:
   14411 	UNLOCK_ZONE(zone);
   14412 	if (do_queue_xfrin) {
   14413 		queue_xfrin(zone);
   14414 	}
   14415 	dns_zone_idetach(&zone);
   14416 	return;
   14417 }
   14418 
   14419 static void
   14420 queue_soa_query(dns_zone_t *zone) {
   14421 	const char me[] = "queue_soa_query";
   14422 	isc_event_t *e;
   14423 	dns_zone_t *dummy = NULL;
   14424 	isc_result_t result;
   14425 
   14426 	ENTER;
   14427 	/*
   14428 	 * Locked by caller
   14429 	 */
   14430 	REQUIRE(LOCKED_ZONE(zone));
   14431 
   14432 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14433 		cancel_refresh(zone);
   14434 		return;
   14435 	}
   14436 
   14437 	e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, soa_query,
   14438 			       zone, sizeof(isc_event_t));
   14439 
   14440 	/*
   14441 	 * Attach so that we won't clean up
   14442 	 * until the event is delivered.
   14443 	 */
   14444 	zone_iattach(zone, &dummy);
   14445 
   14446 	e->ev_arg = zone;
   14447 	e->ev_sender = NULL;
   14448 	result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
   14449 	if (result != ISC_R_SUCCESS) {
   14450 		zone_idetach(&dummy);
   14451 		isc_event_free(&e);
   14452 		cancel_refresh(zone);
   14453 	}
   14454 }
   14455 
   14456 static void
   14457 soa_query(isc_task_t *task, isc_event_t *event) {
   14458 	const char me[] = "soa_query";
   14459 	isc_result_t result = ISC_R_FAILURE;
   14460 	dns_message_t *message = NULL;
   14461 	dns_zone_t *zone = event->ev_arg;
   14462 	dns_zone_t *dummy = NULL;
   14463 	isc_netaddr_t masterip;
   14464 	dns_tsigkey_t *key = NULL;
   14465 	uint32_t options;
   14466 	bool cancel = true;
   14467 	int timeout;
   14468 	bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
   14469 	uint16_t udpsize = SEND_BUFFER_SIZE;
   14470 	isc_dscp_t dscp = -1;
   14471 
   14472 	REQUIRE(DNS_ZONE_VALID(zone));
   14473 
   14474 	UNUSED(task);
   14475 
   14476 	ENTER;
   14477 
   14478 	LOCK_ZONE(zone);
   14479 	if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
   14480 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   14481 	    zone->view->requestmgr == NULL)
   14482 	{
   14483 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14484 			cancel = false;
   14485 		}
   14486 		goto cleanup;
   14487 	}
   14488 
   14489 again:
   14490 	result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
   14491 	if (result != ISC_R_SUCCESS) {
   14492 		goto cleanup;
   14493 	}
   14494 
   14495 	INSIST(zone->masterscnt > 0);
   14496 	INSIST(zone->curmaster < zone->masterscnt);
   14497 
   14498 	zone->masteraddr = zone->masters[zone->curmaster];
   14499 
   14500 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   14501 	/*
   14502 	 * First, look for a tsig key in the master statement, then
   14503 	 * try for a server key.
   14504 	 */
   14505 	if ((zone->masterkeynames != NULL) &&
   14506 	    (zone->masterkeynames[zone->curmaster] != NULL))
   14507 	{
   14508 		dns_view_t *view = dns_zone_getview(zone);
   14509 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   14510 		result = dns_view_gettsig(view, keyname, &key);
   14511 		if (result != ISC_R_SUCCESS) {
   14512 			char namebuf[DNS_NAME_FORMATSIZE];
   14513 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   14514 			dns_zone_log(zone, ISC_LOG_ERROR,
   14515 				     "unable to find key: %s", namebuf);
   14516 			goto skip_master;
   14517 		}
   14518 	}
   14519 	if (key == NULL) {
   14520 		result = dns_view_getpeertsig(zone->view, &masterip, &key);
   14521 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   14522 			char addrbuf[ISC_NETADDR_FORMATSIZE];
   14523 			isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
   14524 			dns_zone_log(zone, ISC_LOG_ERROR,
   14525 				     "unable to find TSIG key for %s", addrbuf);
   14526 			goto skip_master;
   14527 		}
   14528 	}
   14529 
   14530 	options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP
   14531 							 : 0;
   14532 	have_xfrsource = have_xfrdscp = false;
   14533 	reqnsid = zone->view->requestnsid;
   14534 	reqexpire = zone->requestexpire;
   14535 	if (zone->view->peers != NULL) {
   14536 		dns_peer_t *peer = NULL;
   14537 		bool edns, usetcp;
   14538 		result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip,
   14539 						 &peer);
   14540 		if (result == ISC_R_SUCCESS) {
   14541 			result = dns_peer_getsupportedns(peer, &edns);
   14542 			if (result == ISC_R_SUCCESS && !edns) {
   14543 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14544 			}
   14545 			result = dns_peer_gettransfersource(peer,
   14546 							    &zone->sourceaddr);
   14547 			if (result == ISC_R_SUCCESS) {
   14548 				have_xfrsource = true;
   14549 			}
   14550 			(void)dns_peer_gettransferdscp(peer, &dscp);
   14551 			if (dscp != -1) {
   14552 				have_xfrdscp = true;
   14553 			}
   14554 			if (zone->view->resolver != NULL) {
   14555 				udpsize = dns_resolver_getudpsize(
   14556 					zone->view->resolver);
   14557 			}
   14558 			(void)dns_peer_getudpsize(peer, &udpsize);
   14559 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14560 			(void)dns_peer_getrequestexpire(peer, &reqexpire);
   14561 			result = dns_peer_getforcetcp(peer, &usetcp);
   14562 			if (result == ISC_R_SUCCESS && usetcp) {
   14563 				options |= DNS_REQUESTOPT_TCP;
   14564 			}
   14565 		}
   14566 	}
   14567 
   14568 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   14569 	case PF_INET:
   14570 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14571 			if (isc_sockaddr_equal(&zone->altxfrsource4,
   14572 					       &zone->xfrsource4))
   14573 			{
   14574 				goto skip_master;
   14575 			}
   14576 			zone->sourceaddr = zone->altxfrsource4;
   14577 			if (!have_xfrdscp) {
   14578 				dscp = zone->altxfrsource4dscp;
   14579 			}
   14580 		} else if (!have_xfrsource) {
   14581 			zone->sourceaddr = zone->xfrsource4;
   14582 			if (!have_xfrdscp) {
   14583 				dscp = zone->xfrsource4dscp;
   14584 			}
   14585 		}
   14586 		break;
   14587 	case PF_INET6:
   14588 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14589 			if (isc_sockaddr_equal(&zone->altxfrsource6,
   14590 					       &zone->xfrsource6))
   14591 			{
   14592 				goto skip_master;
   14593 			}
   14594 			zone->sourceaddr = zone->altxfrsource6;
   14595 			if (!have_xfrdscp) {
   14596 				dscp = zone->altxfrsource6dscp;
   14597 			}
   14598 		} else if (!have_xfrsource) {
   14599 			zone->sourceaddr = zone->xfrsource6;
   14600 			if (!have_xfrdscp) {
   14601 				dscp = zone->xfrsource6dscp;
   14602 			}
   14603 		}
   14604 		break;
   14605 	default:
   14606 		result = ISC_R_NOTIMPLEMENTED;
   14607 		goto cleanup;
   14608 	}
   14609 
   14610 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14611 		result = add_opt(message, udpsize, reqnsid, reqexpire);
   14612 		if (result != ISC_R_SUCCESS) {
   14613 			zone_debuglog(zone, me, 1,
   14614 				      "unable to add opt record: %s",
   14615 				      dns_result_totext(result));
   14616 		}
   14617 	}
   14618 
   14619 	zone_iattach(zone, &dummy);
   14620 	timeout = 15;
   14621 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14622 		timeout = 30;
   14623 	}
   14624 	result = dns_request_createvia(
   14625 		zone->view->requestmgr, message, &zone->sourceaddr,
   14626 		&zone->masteraddr, dscp, options, key, timeout * 3, timeout, 0,
   14627 		zone->task, refresh_callback, zone, &zone->request);
   14628 	if (result != ISC_R_SUCCESS) {
   14629 		zone_idetach(&dummy);
   14630 		zone_debuglog(zone, me, 1,
   14631 			      "dns_request_createvia4() failed: %s",
   14632 			      dns_result_totext(result));
   14633 		goto skip_master;
   14634 	} else {
   14635 		if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) {
   14636 			inc_stats(zone, dns_zonestatscounter_soaoutv4);
   14637 		} else {
   14638 			inc_stats(zone, dns_zonestatscounter_soaoutv6);
   14639 		}
   14640 	}
   14641 	cancel = false;
   14642 
   14643 cleanup:
   14644 	if (key != NULL) {
   14645 		dns_tsigkey_detach(&key);
   14646 	}
   14647 	if (result != ISC_R_SUCCESS) {
   14648 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14649 	}
   14650 	if (message != NULL) {
   14651 		dns_message_detach(&message);
   14652 	}
   14653 	if (cancel) {
   14654 		cancel_refresh(zone);
   14655 	}
   14656 	isc_event_free(&event);
   14657 	UNLOCK_ZONE(zone);
   14658 	dns_zone_idetach(&zone);
   14659 	return;
   14660 
   14661 skip_master:
   14662 	if (key != NULL) {
   14663 		dns_tsigkey_detach(&key);
   14664 	}
   14665 	dns_message_detach(&message);
   14666 	/*
   14667 	 * Skip to next failed / untried master.
   14668 	 */
   14669 	do {
   14670 		zone->curmaster++;
   14671 	} while (zone->curmaster < zone->masterscnt &&
   14672 		 zone->mastersok[zone->curmaster]);
   14673 	if (zone->curmaster < zone->masterscnt) {
   14674 		goto again;
   14675 	}
   14676 	zone->curmaster = 0;
   14677 	goto cleanup;
   14678 }
   14679 
   14680 static void
   14681 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
   14682 	const char me[] = "ns_query";
   14683 	isc_result_t result;
   14684 	dns_message_t *message = NULL;
   14685 	isc_netaddr_t masterip;
   14686 	dns_tsigkey_t *key = NULL;
   14687 	dns_dbnode_t *node = NULL;
   14688 	int timeout;
   14689 	bool have_xfrsource = false, have_xfrdscp = false;
   14690 	bool reqnsid;
   14691 	uint16_t udpsize = SEND_BUFFER_SIZE;
   14692 	isc_dscp_t dscp = -1;
   14693 	struct stub_cb_args *cb_args;
   14694 
   14695 	REQUIRE(DNS_ZONE_VALID(zone));
   14696 	REQUIRE(LOCKED_ZONE(zone));
   14697 	REQUIRE((soardataset != NULL && stub == NULL) ||
   14698 		(soardataset == NULL && stub != NULL));
   14699 	REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
   14700 
   14701 	ENTER;
   14702 
   14703 	if (stub == NULL) {
   14704 		stub = isc_mem_get(zone->mctx, sizeof(*stub));
   14705 		stub->magic = STUB_MAGIC;
   14706 		stub->mctx = zone->mctx;
   14707 		stub->zone = NULL;
   14708 		stub->db = NULL;
   14709 		stub->version = NULL;
   14710 		atomic_init(&stub->pending_requests, 0);
   14711 
   14712 		/*
   14713 		 * Attach so that the zone won't disappear from under us.
   14714 		 */
   14715 		zone_iattach(zone, &stub->zone);
   14716 
   14717 		/*
   14718 		 * If a db exists we will update it, otherwise we create a
   14719 		 * new one and attach it to the zone once we have the NS
   14720 		 * RRset and glue.
   14721 		 */
   14722 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14723 		if (zone->db != NULL) {
   14724 			dns_db_attach(zone->db, &stub->db);
   14725 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14726 		} else {
   14727 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14728 
   14729 			INSIST(zone->db_argc >= 1);
   14730 			result = dns_db_create(zone->mctx, zone->db_argv[0],
   14731 					       &zone->origin, dns_dbtype_stub,
   14732 					       zone->rdclass, zone->db_argc - 1,
   14733 					       zone->db_argv + 1, &stub->db);
   14734 			if (result != ISC_R_SUCCESS) {
   14735 				dns_zone_log(zone, ISC_LOG_ERROR,
   14736 					     "refreshing stub: "
   14737 					     "could not create "
   14738 					     "database: %s",
   14739 					     dns_result_totext(result));
   14740 				goto cleanup;
   14741 			}
   14742 			dns_db_settask(stub->db, zone->task);
   14743 		}
   14744 
   14745 		result = dns_db_newversion(stub->db, &stub->version);
   14746 		if (result != ISC_R_SUCCESS) {
   14747 			dns_zone_log(zone, ISC_LOG_INFO,
   14748 				     "refreshing stub: "
   14749 				     "dns_db_newversion() failed: %s",
   14750 				     dns_result_totext(result));
   14751 			goto cleanup;
   14752 		}
   14753 
   14754 		/*
   14755 		 * Update SOA record.
   14756 		 */
   14757 		result = dns_db_findnode(stub->db, &zone->origin, true, &node);
   14758 		if (result != ISC_R_SUCCESS) {
   14759 			dns_zone_log(zone, ISC_LOG_INFO,
   14760 				     "refreshing stub: "
   14761 				     "dns_db_findnode() failed: %s",
   14762 				     dns_result_totext(result));
   14763 			goto cleanup;
   14764 		}
   14765 
   14766 		result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   14767 					    soardataset, 0, NULL);
   14768 		dns_db_detachnode(stub->db, &node);
   14769 		if (result != ISC_R_SUCCESS) {
   14770 			dns_zone_log(zone, ISC_LOG_INFO,
   14771 				     "refreshing stub: "
   14772 				     "dns_db_addrdataset() failed: %s",
   14773 				     dns_result_totext(result));
   14774 			goto cleanup;
   14775 		}
   14776 	}
   14777 
   14778 	/*
   14779 	 * XXX Optimisation: Create message when zone is setup and reuse.
   14780 	 */
   14781 	result = create_query(zone, dns_rdatatype_ns, &zone->origin, &message);
   14782 	INSIST(result == ISC_R_SUCCESS);
   14783 
   14784 	INSIST(zone->masterscnt > 0);
   14785 	INSIST(zone->curmaster < zone->masterscnt);
   14786 	zone->masteraddr = zone->masters[zone->curmaster];
   14787 
   14788 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   14789 	/*
   14790 	 * First, look for a tsig key in the master statement, then
   14791 	 * try for a server key.
   14792 	 */
   14793 	if ((zone->masterkeynames != NULL) &&
   14794 	    (zone->masterkeynames[zone->curmaster] != NULL))
   14795 	{
   14796 		dns_view_t *view = dns_zone_getview(zone);
   14797 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   14798 		result = dns_view_gettsig(view, keyname, &key);
   14799 		if (result != ISC_R_SUCCESS) {
   14800 			char namebuf[DNS_NAME_FORMATSIZE];
   14801 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   14802 			dns_zone_log(zone, ISC_LOG_ERROR,
   14803 				     "unable to find key: %s", namebuf);
   14804 		}
   14805 	}
   14806 	if (key == NULL) {
   14807 		(void)dns_view_getpeertsig(zone->view, &masterip, &key);
   14808 	}
   14809 
   14810 	reqnsid = zone->view->requestnsid;
   14811 	if (zone->view->peers != NULL) {
   14812 		dns_peer_t *peer = NULL;
   14813 		bool edns;
   14814 		result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip,
   14815 						 &peer);
   14816 		if (result == ISC_R_SUCCESS) {
   14817 			result = dns_peer_getsupportedns(peer, &edns);
   14818 			if (result == ISC_R_SUCCESS && !edns) {
   14819 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14820 			}
   14821 			result = dns_peer_gettransfersource(peer,
   14822 							    &zone->sourceaddr);
   14823 			if (result == ISC_R_SUCCESS) {
   14824 				have_xfrsource = true;
   14825 			}
   14826 			result = dns_peer_gettransferdscp(peer, &dscp);
   14827 			if (result == ISC_R_SUCCESS && dscp != -1) {
   14828 				have_xfrdscp = true;
   14829 			}
   14830 			if (zone->view->resolver != NULL) {
   14831 				udpsize = dns_resolver_getudpsize(
   14832 					zone->view->resolver);
   14833 			}
   14834 			(void)dns_peer_getudpsize(peer, &udpsize);
   14835 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14836 		}
   14837 	}
   14838 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14839 		result = add_opt(message, udpsize, reqnsid, false);
   14840 		if (result != ISC_R_SUCCESS) {
   14841 			zone_debuglog(zone, me, 1,
   14842 				      "unable to add opt record: %s",
   14843 				      dns_result_totext(result));
   14844 		}
   14845 	}
   14846 
   14847 	/*
   14848 	 * Always use TCP so that we shouldn't truncate in additional section.
   14849 	 */
   14850 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   14851 	case PF_INET:
   14852 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14853 			zone->sourceaddr = zone->altxfrsource4;
   14854 			if (!have_xfrdscp) {
   14855 				dscp = zone->altxfrsource4dscp;
   14856 			}
   14857 		} else if (!have_xfrsource) {
   14858 			zone->sourceaddr = zone->xfrsource4;
   14859 			if (!have_xfrdscp) {
   14860 				dscp = zone->xfrsource4dscp;
   14861 			}
   14862 		}
   14863 		break;
   14864 	case PF_INET6:
   14865 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14866 			zone->sourceaddr = zone->altxfrsource6;
   14867 			if (!have_xfrdscp) {
   14868 				dscp = zone->altxfrsource6dscp;
   14869 			}
   14870 		} else if (!have_xfrsource) {
   14871 			zone->sourceaddr = zone->xfrsource6;
   14872 			if (!have_xfrdscp) {
   14873 				dscp = zone->xfrsource6dscp;
   14874 			}
   14875 		}
   14876 		break;
   14877 	default:
   14878 		result = ISC_R_NOTIMPLEMENTED;
   14879 		POST(result);
   14880 		goto cleanup;
   14881 	}
   14882 	timeout = 15;
   14883 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14884 		timeout = 30;
   14885 	}
   14886 
   14887 	/*
   14888 	 * Save request parameters so we can reuse them later on
   14889 	 * for resolving missing glue A/AAAA records.
   14890 	 */
   14891 	cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args));
   14892 	cb_args->stub = stub;
   14893 	cb_args->tsig_key = key;
   14894 	cb_args->dscp = dscp;
   14895 	cb_args->udpsize = udpsize;
   14896 	cb_args->timeout = timeout;
   14897 	cb_args->reqnsid = reqnsid;
   14898 
   14899 	result = dns_request_createvia(
   14900 		zone->view->requestmgr, message, &zone->sourceaddr,
   14901 		&zone->masteraddr, dscp, DNS_REQUESTOPT_TCP, key, timeout * 3,
   14902 		timeout, 0, zone->task, stub_callback, cb_args, &zone->request);
   14903 	if (result != ISC_R_SUCCESS) {
   14904 		zone_debuglog(zone, me, 1, "dns_request_createvia() failed: %s",
   14905 			      dns_result_totext(result));
   14906 		goto cleanup;
   14907 	}
   14908 	dns_message_detach(&message);
   14909 	goto unlock;
   14910 
   14911 cleanup:
   14912 	cancel_refresh(zone);
   14913 	stub->magic = 0;
   14914 	if (stub->version != NULL) {
   14915 		dns_db_closeversion(stub->db, &stub->version, false);
   14916 	}
   14917 	if (stub->db != NULL) {
   14918 		dns_db_detach(&stub->db);
   14919 	}
   14920 	if (stub->zone != NULL) {
   14921 		zone_idetach(&stub->zone);
   14922 	}
   14923 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   14924 	if (message != NULL) {
   14925 		dns_message_detach(&message);
   14926 	}
   14927 unlock:
   14928 	if (key != NULL) {
   14929 		dns_tsigkey_detach(&key);
   14930 	}
   14931 	return;
   14932 }
   14933 
   14934 /*
   14935  * Shut the zone down.
   14936  */
   14937 static void
   14938 zone_shutdown(isc_task_t *task, isc_event_t *event) {
   14939 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   14940 	bool free_needed, linked = false;
   14941 	dns_zone_t *raw = NULL, *secure = NULL;
   14942 
   14943 	UNUSED(task);
   14944 	REQUIRE(DNS_ZONE_VALID(zone));
   14945 	INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
   14946 	INSIST(isc_refcount_current(&zone->erefs) == 0);
   14947 
   14948 	zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
   14949 
   14950 	/*
   14951 	 * If we were waiting for xfrin quota, step out of
   14952 	 * the queue.
   14953 	 * If there's no zone manager, we can't be waiting for the
   14954 	 * xfrin quota
   14955 	 */
   14956 	if (zone->zmgr != NULL) {
   14957 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   14958 		if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
   14959 			ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
   14960 					statelink);
   14961 			linked = true;
   14962 			zone->statelist = NULL;
   14963 		}
   14964 		if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
   14965 			ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
   14966 					statelink);
   14967 			zone->statelist = NULL;
   14968 			zmgr_resume_xfrs(zone->zmgr, false);
   14969 		}
   14970 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   14971 	}
   14972 
   14973 	/*
   14974 	 * In task context, no locking required.  See zone_xfrdone().
   14975 	 */
   14976 	if (zone->xfr != NULL) {
   14977 		dns_xfrin_shutdown(zone->xfr);
   14978 	}
   14979 
   14980 	/* Safe to release the zone now */
   14981 	if (zone->zmgr != NULL) {
   14982 		dns_zonemgr_releasezone(zone->zmgr, zone);
   14983 	}
   14984 
   14985 	LOCK_ZONE(zone);
   14986 	INSIST(zone != zone->raw);
   14987 	if (linked) {
   14988 		isc_refcount_decrement(&zone->irefs);
   14989 	}
   14990 	if (zone->request != NULL) {
   14991 		dns_request_cancel(zone->request);
   14992 	}
   14993 
   14994 	if (zone->readio != NULL) {
   14995 		zonemgr_cancelio(zone->readio);
   14996 	}
   14997 
   14998 	if (zone->lctx != NULL) {
   14999 		dns_loadctx_cancel(zone->lctx);
   15000 	}
   15001 
   15002 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   15003 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15004 	{
   15005 		if (zone->writeio != NULL) {
   15006 			zonemgr_cancelio(zone->writeio);
   15007 		}
   15008 
   15009 		if (zone->dctx != NULL) {
   15010 			dns_dumpctx_cancel(zone->dctx);
   15011 		}
   15012 	}
   15013 
   15014 	checkds_cancel(zone);
   15015 
   15016 	notify_cancel(zone);
   15017 
   15018 	forward_cancel(zone);
   15019 
   15020 	if (zone->timer != NULL) {
   15021 		isc_timer_detach(&zone->timer);
   15022 		isc_refcount_decrement(&zone->irefs);
   15023 	}
   15024 
   15025 	/*
   15026 	 * We have now canceled everything set the flag to allow exit_check()
   15027 	 * to succeed.	We must not unlock between setting this flag and
   15028 	 * calling exit_check().
   15029 	 */
   15030 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
   15031 	free_needed = exit_check(zone);
   15032 	/*
   15033 	 * If a dump is in progress for the secure zone, defer detaching from
   15034 	 * the raw zone as it may prevent the unsigned serial number from being
   15035 	 * stored in the raw-format dump of the secure zone.  In this scenario,
   15036 	 * dump_done() takes care of cleaning up the zone->raw reference.
   15037 	 */
   15038 	if (inline_secure(zone) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   15039 		raw = zone->raw;
   15040 		zone->raw = NULL;
   15041 	}
   15042 	if (inline_raw(zone)) {
   15043 		secure = zone->secure;
   15044 		zone->secure = NULL;
   15045 	}
   15046 	UNLOCK_ZONE(zone);
   15047 	if (raw != NULL) {
   15048 		dns_zone_detach(&raw);
   15049 	}
   15050 	if (secure != NULL) {
   15051 		dns_zone_idetach(&secure);
   15052 	}
   15053 	if (free_needed) {
   15054 		zone_free(zone);
   15055 	}
   15056 }
   15057 
   15058 static void
   15059 zone_timer(isc_task_t *task, isc_event_t *event) {
   15060 	const char me[] = "zone_timer";
   15061 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   15062 
   15063 	UNUSED(task);
   15064 	REQUIRE(DNS_ZONE_VALID(zone));
   15065 
   15066 	ENTER;
   15067 
   15068 	zone_maintenance(zone);
   15069 
   15070 	isc_event_free(&event);
   15071 }
   15072 
   15073 static void
   15074 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
   15075 	const char me[] = "zone_settimer";
   15076 	isc_time_t next;
   15077 	isc_result_t result;
   15078 
   15079 	REQUIRE(DNS_ZONE_VALID(zone));
   15080 	REQUIRE(LOCKED_ZONE(zone));
   15081 	ENTER;
   15082 
   15083 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   15084 		return;
   15085 	}
   15086 
   15087 	isc_time_settoepoch(&next);
   15088 
   15089 	switch (zone->type) {
   15090 	case dns_zone_redirect:
   15091 		if (zone->masters != NULL) {
   15092 			goto treat_as_slave;
   15093 		}
   15094 		FALLTHROUGH;
   15095 	case dns_zone_primary:
   15096 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   15097 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   15098 		{
   15099 			next = zone->notifytime;
   15100 		}
   15101 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   15102 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15103 		{
   15104 			INSIST(!isc_time_isepoch(&zone->dumptime));
   15105 			if (isc_time_isepoch(&next) ||
   15106 			    isc_time_compare(&zone->dumptime, &next) < 0)
   15107 			{
   15108 				next = zone->dumptime;
   15109 			}
   15110 		}
   15111 		if (zone->type == dns_zone_redirect) {
   15112 			break;
   15113 		}
   15114 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
   15115 		    !isc_time_isepoch(&zone->refreshkeytime))
   15116 		{
   15117 			if (isc_time_isepoch(&next) ||
   15118 			    isc_time_compare(&zone->refreshkeytime, &next) < 0)
   15119 			{
   15120 				next = zone->refreshkeytime;
   15121 			}
   15122 		}
   15123 		if (!isc_time_isepoch(&zone->resigntime)) {
   15124 			if (isc_time_isepoch(&next) ||
   15125 			    isc_time_compare(&zone->resigntime, &next) < 0)
   15126 			{
   15127 				next = zone->resigntime;
   15128 			}
   15129 		}
   15130 		if (!isc_time_isepoch(&zone->keywarntime)) {
   15131 			if (isc_time_isepoch(&next) ||
   15132 			    isc_time_compare(&zone->keywarntime, &next) < 0)
   15133 			{
   15134 				next = zone->keywarntime;
   15135 			}
   15136 		}
   15137 		if (!isc_time_isepoch(&zone->signingtime)) {
   15138 			if (isc_time_isepoch(&next) ||
   15139 			    isc_time_compare(&zone->signingtime, &next) < 0)
   15140 			{
   15141 				next = zone->signingtime;
   15142 			}
   15143 		}
   15144 		if (!isc_time_isepoch(&zone->nsec3chaintime)) {
   15145 			if (isc_time_isepoch(&next) ||
   15146 			    isc_time_compare(&zone->nsec3chaintime, &next) < 0)
   15147 			{
   15148 				next = zone->nsec3chaintime;
   15149 			}
   15150 		}
   15151 		break;
   15152 
   15153 	case dns_zone_secondary:
   15154 	case dns_zone_mirror:
   15155 	treat_as_slave:
   15156 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   15157 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   15158 		{
   15159 			next = zone->notifytime;
   15160 		}
   15161 		FALLTHROUGH;
   15162 	case dns_zone_stub:
   15163 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
   15164 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
   15165 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
   15166 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
   15167 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
   15168 		    !isc_time_isepoch(&zone->refreshtime) &&
   15169 		    (isc_time_isepoch(&next) ||
   15170 		     isc_time_compare(&zone->refreshtime, &next) < 0))
   15171 		{
   15172 			next = zone->refreshtime;
   15173 		}
   15174 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   15175 		    !isc_time_isepoch(&zone->expiretime))
   15176 		{
   15177 			if (isc_time_isepoch(&next) ||
   15178 			    isc_time_compare(&zone->expiretime, &next) < 0)
   15179 			{
   15180 				next = zone->expiretime;
   15181 			}
   15182 		}
   15183 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   15184 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15185 		{
   15186 			INSIST(!isc_time_isepoch(&zone->dumptime));
   15187 			if (isc_time_isepoch(&next) ||
   15188 			    isc_time_compare(&zone->dumptime, &next) < 0)
   15189 			{
   15190 				next = zone->dumptime;
   15191 			}
   15192 		}
   15193 		break;
   15194 
   15195 	case dns_zone_key:
   15196 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   15197 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15198 		{
   15199 			INSIST(!isc_time_isepoch(&zone->dumptime));
   15200 			if (isc_time_isepoch(&next) ||
   15201 			    isc_time_compare(&zone->dumptime, &next) < 0)
   15202 			{
   15203 				next = zone->dumptime;
   15204 			}
   15205 		}
   15206 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
   15207 			if (isc_time_isepoch(&next) ||
   15208 			    (!isc_time_isepoch(&zone->refreshkeytime) &&
   15209 			     isc_time_compare(&zone->refreshkeytime, &next) <
   15210 				     0))
   15211 			{
   15212 				next = zone->refreshkeytime;
   15213 			}
   15214 		}
   15215 		break;
   15216 
   15217 	default:
   15218 		break;
   15219 	}
   15220 
   15221 	if (isc_time_isepoch(&next)) {
   15222 		zone_debuglog(zone, me, 10, "settimer inactive");
   15223 		result = isc_timer_reset(zone->timer, isc_timertype_inactive,
   15224 					 NULL, NULL, true);
   15225 		if (result != ISC_R_SUCCESS) {
   15226 			dns_zone_log(zone, ISC_LOG_ERROR,
   15227 				     "could not deactivate zone timer: %s",
   15228 				     isc_result_totext(result));
   15229 		}
   15230 	} else {
   15231 		if (isc_time_compare(&next, now) <= 0) {
   15232 			next = *now;
   15233 		}
   15234 		result = isc_timer_reset(zone->timer, isc_timertype_once, &next,
   15235 					 NULL, true);
   15236 		if (result != ISC_R_SUCCESS) {
   15237 			dns_zone_log(zone, ISC_LOG_ERROR,
   15238 				     "could not reset zone timer: %s",
   15239 				     isc_result_totext(result));
   15240 		}
   15241 	}
   15242 }
   15243 
   15244 static void
   15245 cancel_refresh(dns_zone_t *zone) {
   15246 	const char me[] = "cancel_refresh";
   15247 	isc_time_t now;
   15248 
   15249 	/*
   15250 	 * 'zone' locked by caller.
   15251 	 */
   15252 
   15253 	REQUIRE(DNS_ZONE_VALID(zone));
   15254 	REQUIRE(LOCKED_ZONE(zone));
   15255 
   15256 	ENTER;
   15257 
   15258 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   15259 	TIME_NOW(&now);
   15260 	zone_settimer(zone, &now);
   15261 }
   15262 
   15263 static isc_result_t
   15264 notify_createmessage(dns_zone_t *zone, unsigned int flags,
   15265 		     dns_message_t **messagep) {
   15266 	dns_db_t *zonedb = NULL;
   15267 	dns_dbnode_t *node = NULL;
   15268 	dns_dbversion_t *version = NULL;
   15269 	dns_message_t *message = NULL;
   15270 	dns_rdataset_t rdataset;
   15271 	dns_rdata_t rdata = DNS_RDATA_INIT;
   15272 
   15273 	dns_name_t *tempname = NULL;
   15274 	dns_rdata_t *temprdata = NULL;
   15275 	dns_rdatalist_t *temprdatalist = NULL;
   15276 	dns_rdataset_t *temprdataset = NULL;
   15277 
   15278 	isc_result_t result;
   15279 	isc_region_t r;
   15280 	isc_buffer_t *b = NULL;
   15281 
   15282 	REQUIRE(DNS_ZONE_VALID(zone));
   15283 	REQUIRE(messagep != NULL && *messagep == NULL);
   15284 
   15285 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   15286 
   15287 	message->opcode = dns_opcode_notify;
   15288 	message->flags |= DNS_MESSAGEFLAG_AA;
   15289 	message->rdclass = zone->rdclass;
   15290 
   15291 	result = dns_message_gettempname(message, &tempname);
   15292 	if (result != ISC_R_SUCCESS) {
   15293 		goto cleanup;
   15294 	}
   15295 
   15296 	result = dns_message_gettemprdataset(message, &temprdataset);
   15297 	if (result != ISC_R_SUCCESS) {
   15298 		goto cleanup;
   15299 	}
   15300 
   15301 	/*
   15302 	 * Make question.
   15303 	 */
   15304 	dns_name_clone(&zone->origin, tempname);
   15305 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
   15306 				  dns_rdatatype_soa);
   15307 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   15308 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
   15309 	tempname = NULL;
   15310 	temprdataset = NULL;
   15311 
   15312 	if ((flags & DNS_NOTIFY_NOSOA) != 0) {
   15313 		goto done;
   15314 	}
   15315 
   15316 	result = dns_message_gettempname(message, &tempname);
   15317 	if (result != ISC_R_SUCCESS) {
   15318 		goto soa_cleanup;
   15319 	}
   15320 	result = dns_message_gettemprdata(message, &temprdata);
   15321 	if (result != ISC_R_SUCCESS) {
   15322 		goto soa_cleanup;
   15323 	}
   15324 	result = dns_message_gettemprdataset(message, &temprdataset);
   15325 	if (result != ISC_R_SUCCESS) {
   15326 		goto soa_cleanup;
   15327 	}
   15328 	result = dns_message_gettemprdatalist(message, &temprdatalist);
   15329 	if (result != ISC_R_SUCCESS) {
   15330 		goto soa_cleanup;
   15331 	}
   15332 
   15333 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   15334 	INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
   15335 	dns_db_attach(zone->db, &zonedb);
   15336 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15337 
   15338 	dns_name_clone(&zone->origin, tempname);
   15339 	dns_db_currentversion(zonedb, &version);
   15340 	result = dns_db_findnode(zonedb, tempname, false, &node);
   15341 	if (result != ISC_R_SUCCESS) {
   15342 		goto soa_cleanup;
   15343 	}
   15344 
   15345 	dns_rdataset_init(&rdataset);
   15346 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   15347 				     dns_rdatatype_none, 0, &rdataset, NULL);
   15348 	if (result != ISC_R_SUCCESS) {
   15349 		goto soa_cleanup;
   15350 	}
   15351 	result = dns_rdataset_first(&rdataset);
   15352 	if (result != ISC_R_SUCCESS) {
   15353 		goto soa_cleanup;
   15354 	}
   15355 	dns_rdataset_current(&rdataset, &rdata);
   15356 	dns_rdata_toregion(&rdata, &r);
   15357 	isc_buffer_allocate(zone->mctx, &b, r.length);
   15358 	isc_buffer_putmem(b, r.base, r.length);
   15359 	isc_buffer_usedregion(b, &r);
   15360 	dns_rdata_init(temprdata);
   15361 	dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
   15362 	dns_message_takebuffer(message, &b);
   15363 	result = dns_rdataset_next(&rdataset);
   15364 	dns_rdataset_disassociate(&rdataset);
   15365 	if (result != ISC_R_NOMORE) {
   15366 		goto soa_cleanup;
   15367 	}
   15368 	temprdatalist->rdclass = rdata.rdclass;
   15369 	temprdatalist->type = rdata.type;
   15370 	temprdatalist->ttl = rdataset.ttl;
   15371 	ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
   15372 
   15373 	result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
   15374 	if (result != ISC_R_SUCCESS) {
   15375 		goto soa_cleanup;
   15376 	}
   15377 
   15378 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   15379 	dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
   15380 	temprdatalist = NULL;
   15381 	temprdataset = NULL;
   15382 	temprdata = NULL;
   15383 	tempname = NULL;
   15384 
   15385 soa_cleanup:
   15386 	if (node != NULL) {
   15387 		dns_db_detachnode(zonedb, &node);
   15388 	}
   15389 	if (version != NULL) {
   15390 		dns_db_closeversion(zonedb, &version, false);
   15391 	}
   15392 	if (zonedb != NULL) {
   15393 		dns_db_detach(&zonedb);
   15394 	}
   15395 	if (tempname != NULL) {
   15396 		dns_message_puttempname(message, &tempname);
   15397 	}
   15398 	if (temprdata != NULL) {
   15399 		dns_message_puttemprdata(message, &temprdata);
   15400 	}
   15401 	if (temprdataset != NULL) {
   15402 		dns_message_puttemprdataset(message, &temprdataset);
   15403 	}
   15404 	if (temprdatalist != NULL) {
   15405 		dns_message_puttemprdatalist(message, &temprdatalist);
   15406 	}
   15407 
   15408 done:
   15409 	*messagep = message;
   15410 	return (ISC_R_SUCCESS);
   15411 
   15412 cleanup:
   15413 	if (tempname != NULL) {
   15414 		dns_message_puttempname(message, &tempname);
   15415 	}
   15416 	if (temprdataset != NULL) {
   15417 		dns_message_puttemprdataset(message, &temprdataset);
   15418 	}
   15419 	dns_message_detach(&message);
   15420 	return (result);
   15421 }
   15422 
   15423 isc_result_t
   15424 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
   15425 		       isc_sockaddr_t *to, dns_message_t *msg) {
   15426 	unsigned int i;
   15427 	dns_rdata_soa_t soa;
   15428 	dns_rdataset_t *rdataset = NULL;
   15429 	dns_rdata_t rdata = DNS_RDATA_INIT;
   15430 	isc_result_t result;
   15431 	char fromtext[ISC_SOCKADDR_FORMATSIZE];
   15432 	int match = 0;
   15433 	isc_netaddr_t netaddr;
   15434 	uint32_t serial = 0;
   15435 	bool have_serial = false;
   15436 	dns_tsigkey_t *tsigkey;
   15437 	const dns_name_t *tsig;
   15438 
   15439 	REQUIRE(DNS_ZONE_VALID(zone));
   15440 
   15441 	/*
   15442 	 * If type != T_SOA return DNS_R_NOTIMP.  We don't yet support
   15443 	 * ROLLOVER.
   15444 	 *
   15445 	 * SOA:	RFC1996
   15446 	 * Check that 'from' is a valid notify source, (zone->masters).
   15447 	 *	Return DNS_R_REFUSED if not.
   15448 	 *
   15449 	 * If the notify message contains a serial number check it
   15450 	 * against the zones serial and return if <= current serial
   15451 	 *
   15452 	 * If a refresh check is progress, if so just record the
   15453 	 * fact we received a NOTIFY and from where and return.
   15454 	 * We will perform a new refresh check when the current one
   15455 	 * completes. Return ISC_R_SUCCESS.
   15456 	 *
   15457 	 * Otherwise initiate a refresh check using 'from' as the
   15458 	 * first address to check.  Return ISC_R_SUCCESS.
   15459 	 */
   15460 
   15461 	isc_sockaddr_format(from, fromtext, sizeof(fromtext));
   15462 
   15463 	/*
   15464 	 * Notify messages are processed by the raw zone.
   15465 	 */
   15466 	LOCK_ZONE(zone);
   15467 	INSIST(zone != zone->raw);
   15468 	if (inline_secure(zone)) {
   15469 		result = dns_zone_notifyreceive(zone->raw, from, to, msg);
   15470 		UNLOCK_ZONE(zone);
   15471 		return (result);
   15472 	}
   15473 	/*
   15474 	 *  We only handle NOTIFY (SOA) at the present.
   15475 	 */
   15476 	if (isc_sockaddr_pf(from) == PF_INET) {
   15477 		inc_stats(zone, dns_zonestatscounter_notifyinv4);
   15478 	} else {
   15479 		inc_stats(zone, dns_zonestatscounter_notifyinv6);
   15480 	}
   15481 	if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
   15482 	    dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
   15483 				 dns_rdatatype_soa, dns_rdatatype_none, NULL,
   15484 				 NULL) != ISC_R_SUCCESS)
   15485 	{
   15486 		UNLOCK_ZONE(zone);
   15487 		if (msg->counts[DNS_SECTION_QUESTION] == 0) {
   15488 			dns_zone_log(zone, ISC_LOG_NOTICE,
   15489 				     "NOTIFY with no "
   15490 				     "question section from: %s",
   15491 				     fromtext);
   15492 			return (DNS_R_FORMERR);
   15493 		}
   15494 		dns_zone_log(zone, ISC_LOG_NOTICE,
   15495 			     "NOTIFY zone does not match");
   15496 		return (DNS_R_NOTIMP);
   15497 	}
   15498 
   15499 	/*
   15500 	 * If we are a master zone just succeed.
   15501 	 */
   15502 	if (zone->type == dns_zone_primary) {
   15503 		UNLOCK_ZONE(zone);
   15504 		return (ISC_R_SUCCESS);
   15505 	}
   15506 
   15507 	isc_netaddr_fromsockaddr(&netaddr, from);
   15508 	for (i = 0; i < zone->masterscnt; i++) {
   15509 		if (isc_sockaddr_eqaddr(from, &zone->masters[i])) {
   15510 			break;
   15511 		}
   15512 		if (zone->view->aclenv.match_mapped &&
   15513 		    IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
   15514 		    isc_sockaddr_pf(&zone->masters[i]) == AF_INET)
   15515 		{
   15516 			isc_netaddr_t na1, na2;
   15517 			isc_netaddr_fromv4mapped(&na1, &netaddr);
   15518 			isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
   15519 			if (isc_netaddr_equal(&na1, &na2)) {
   15520 				break;
   15521 			}
   15522 		}
   15523 	}
   15524 
   15525 	/*
   15526 	 * Accept notify requests from non masters if they are on
   15527 	 * 'zone->notify_acl'.
   15528 	 */
   15529 	tsigkey = dns_message_gettsigkey(msg);
   15530 	tsig = dns_tsigkey_identity(tsigkey);
   15531 	if (i >= zone->masterscnt && zone->notify_acl != NULL &&
   15532 	    (dns_acl_match(&netaddr, tsig, zone->notify_acl,
   15533 			   &zone->view->aclenv, &match,
   15534 			   NULL) == ISC_R_SUCCESS) &&
   15535 	    match > 0)
   15536 	{
   15537 		/* Accept notify. */
   15538 	} else if (i >= zone->masterscnt) {
   15539 		UNLOCK_ZONE(zone);
   15540 		dns_zone_log(zone, ISC_LOG_INFO,
   15541 			     "refused notify from non-master: %s", fromtext);
   15542 		inc_stats(zone, dns_zonestatscounter_notifyrej);
   15543 		return (DNS_R_REFUSED);
   15544 	}
   15545 
   15546 	/*
   15547 	 * If the zone is loaded and there are answers check the serial
   15548 	 * to see if we need to do a refresh.  Do not worry about this
   15549 	 * check if we are a dialup zone as we use the notify request
   15550 	 * to trigger a refresh check.
   15551 	 */
   15552 	if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
   15553 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   15554 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH))
   15555 	{
   15556 		result = dns_message_findname(
   15557 			msg, DNS_SECTION_ANSWER, &zone->origin,
   15558 			dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset);
   15559 		if (result == ISC_R_SUCCESS) {
   15560 			result = dns_rdataset_first(rdataset);
   15561 		}
   15562 		if (result == ISC_R_SUCCESS) {
   15563 			uint32_t oldserial;
   15564 			unsigned int soacount;
   15565 
   15566 			dns_rdataset_current(rdataset, &rdata);
   15567 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   15568 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15569 			serial = soa.serial;
   15570 			have_serial = true;
   15571 			/*
   15572 			 * The following should safely be performed without DB
   15573 			 * lock and succeed in this context.
   15574 			 */
   15575 			result = zone_get_from_db(zone, zone->db, NULL,
   15576 						  &soacount, NULL, &oldserial,
   15577 						  NULL, NULL, NULL, NULL, NULL);
   15578 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15579 			RUNTIME_CHECK(soacount > 0U);
   15580 			if (isc_serial_le(serial, oldserial)) {
   15581 				dns_zone_log(zone, ISC_LOG_INFO,
   15582 					     "notify from %s: "
   15583 					     "zone is up to date",
   15584 					     fromtext);
   15585 				UNLOCK_ZONE(zone);
   15586 				return (ISC_R_SUCCESS);
   15587 			}
   15588 		}
   15589 	}
   15590 
   15591 	/*
   15592 	 * If we got this far and there was a refresh in progress just
   15593 	 * let it complete.  Record where we got the notify from so we
   15594 	 * can perform a refresh check when the current one completes
   15595 	 */
   15596 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   15597 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   15598 		zone->notifyfrom = *from;
   15599 		UNLOCK_ZONE(zone);
   15600 		if (have_serial) {
   15601 			dns_zone_log(zone, ISC_LOG_INFO,
   15602 				     "notify from %s: serial %u: refresh in "
   15603 				     "progress, refresh check queued",
   15604 				     fromtext, serial);
   15605 		} else {
   15606 			dns_zone_log(zone, ISC_LOG_INFO,
   15607 				     "notify from %s: refresh in progress, "
   15608 				     "refresh check queued",
   15609 				     fromtext);
   15610 		}
   15611 		return (ISC_R_SUCCESS);
   15612 	}
   15613 	if (have_serial) {
   15614 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
   15615 			     fromtext, serial);
   15616 	} else {
   15617 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
   15618 			     fromtext);
   15619 	}
   15620 	zone->notifyfrom = *from;
   15621 	UNLOCK_ZONE(zone);
   15622 
   15623 	if (to != NULL) {
   15624 		dns_zonemgr_unreachabledel(zone->zmgr, from, to);
   15625 	}
   15626 	dns_zone_refresh(zone);
   15627 	return (ISC_R_SUCCESS);
   15628 }
   15629 
   15630 void
   15631 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
   15632 	REQUIRE(DNS_ZONE_VALID(zone));
   15633 
   15634 	LOCK_ZONE(zone);
   15635 	if (zone->notify_acl != NULL) {
   15636 		dns_acl_detach(&zone->notify_acl);
   15637 	}
   15638 	dns_acl_attach(acl, &zone->notify_acl);
   15639 	UNLOCK_ZONE(zone);
   15640 }
   15641 
   15642 void
   15643 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
   15644 	REQUIRE(DNS_ZONE_VALID(zone));
   15645 
   15646 	LOCK_ZONE(zone);
   15647 	if (zone->query_acl != NULL) {
   15648 		dns_acl_detach(&zone->query_acl);
   15649 	}
   15650 	dns_acl_attach(acl, &zone->query_acl);
   15651 	UNLOCK_ZONE(zone);
   15652 }
   15653 
   15654 void
   15655 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
   15656 	REQUIRE(DNS_ZONE_VALID(zone));
   15657 
   15658 	LOCK_ZONE(zone);
   15659 	if (zone->queryon_acl != NULL) {
   15660 		dns_acl_detach(&zone->queryon_acl);
   15661 	}
   15662 	dns_acl_attach(acl, &zone->queryon_acl);
   15663 	UNLOCK_ZONE(zone);
   15664 }
   15665 
   15666 void
   15667 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
   15668 	REQUIRE(DNS_ZONE_VALID(zone));
   15669 
   15670 	LOCK_ZONE(zone);
   15671 	if (zone->update_acl != NULL) {
   15672 		dns_acl_detach(&zone->update_acl);
   15673 	}
   15674 	dns_acl_attach(acl, &zone->update_acl);
   15675 	UNLOCK_ZONE(zone);
   15676 }
   15677 
   15678 void
   15679 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
   15680 	REQUIRE(DNS_ZONE_VALID(zone));
   15681 
   15682 	LOCK_ZONE(zone);
   15683 	if (zone->forward_acl != NULL) {
   15684 		dns_acl_detach(&zone->forward_acl);
   15685 	}
   15686 	dns_acl_attach(acl, &zone->forward_acl);
   15687 	UNLOCK_ZONE(zone);
   15688 }
   15689 
   15690 void
   15691 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
   15692 	REQUIRE(DNS_ZONE_VALID(zone));
   15693 
   15694 	LOCK_ZONE(zone);
   15695 	if (zone->xfr_acl != NULL) {
   15696 		dns_acl_detach(&zone->xfr_acl);
   15697 	}
   15698 	dns_acl_attach(acl, &zone->xfr_acl);
   15699 	UNLOCK_ZONE(zone);
   15700 }
   15701 
   15702 dns_acl_t *
   15703 dns_zone_getnotifyacl(dns_zone_t *zone) {
   15704 	REQUIRE(DNS_ZONE_VALID(zone));
   15705 
   15706 	return (zone->notify_acl);
   15707 }
   15708 
   15709 dns_acl_t *
   15710 dns_zone_getqueryacl(dns_zone_t *zone) {
   15711 	REQUIRE(DNS_ZONE_VALID(zone));
   15712 
   15713 	return (zone->query_acl);
   15714 }
   15715 
   15716 dns_acl_t *
   15717 dns_zone_getqueryonacl(dns_zone_t *zone) {
   15718 	REQUIRE(DNS_ZONE_VALID(zone));
   15719 
   15720 	return (zone->queryon_acl);
   15721 }
   15722 
   15723 dns_acl_t *
   15724 dns_zone_getupdateacl(dns_zone_t *zone) {
   15725 	REQUIRE(DNS_ZONE_VALID(zone));
   15726 
   15727 	return (zone->update_acl);
   15728 }
   15729 
   15730 dns_acl_t *
   15731 dns_zone_getforwardacl(dns_zone_t *zone) {
   15732 	REQUIRE(DNS_ZONE_VALID(zone));
   15733 
   15734 	return (zone->forward_acl);
   15735 }
   15736 
   15737 dns_acl_t *
   15738 dns_zone_getxfracl(dns_zone_t *zone) {
   15739 	REQUIRE(DNS_ZONE_VALID(zone));
   15740 
   15741 	return (zone->xfr_acl);
   15742 }
   15743 
   15744 void
   15745 dns_zone_clearupdateacl(dns_zone_t *zone) {
   15746 	REQUIRE(DNS_ZONE_VALID(zone));
   15747 
   15748 	LOCK_ZONE(zone);
   15749 	if (zone->update_acl != NULL) {
   15750 		dns_acl_detach(&zone->update_acl);
   15751 	}
   15752 	UNLOCK_ZONE(zone);
   15753 }
   15754 
   15755 void
   15756 dns_zone_clearforwardacl(dns_zone_t *zone) {
   15757 	REQUIRE(DNS_ZONE_VALID(zone));
   15758 
   15759 	LOCK_ZONE(zone);
   15760 	if (zone->forward_acl != NULL) {
   15761 		dns_acl_detach(&zone->forward_acl);
   15762 	}
   15763 	UNLOCK_ZONE(zone);
   15764 }
   15765 
   15766 void
   15767 dns_zone_clearnotifyacl(dns_zone_t *zone) {
   15768 	REQUIRE(DNS_ZONE_VALID(zone));
   15769 
   15770 	LOCK_ZONE(zone);
   15771 	if (zone->notify_acl != NULL) {
   15772 		dns_acl_detach(&zone->notify_acl);
   15773 	}
   15774 	UNLOCK_ZONE(zone);
   15775 }
   15776 
   15777 void
   15778 dns_zone_clearqueryacl(dns_zone_t *zone) {
   15779 	REQUIRE(DNS_ZONE_VALID(zone));
   15780 
   15781 	LOCK_ZONE(zone);
   15782 	if (zone->query_acl != NULL) {
   15783 		dns_acl_detach(&zone->query_acl);
   15784 	}
   15785 	UNLOCK_ZONE(zone);
   15786 }
   15787 
   15788 void
   15789 dns_zone_clearqueryonacl(dns_zone_t *zone) {
   15790 	REQUIRE(DNS_ZONE_VALID(zone));
   15791 
   15792 	LOCK_ZONE(zone);
   15793 	if (zone->queryon_acl != NULL) {
   15794 		dns_acl_detach(&zone->queryon_acl);
   15795 	}
   15796 	UNLOCK_ZONE(zone);
   15797 }
   15798 
   15799 void
   15800 dns_zone_clearxfracl(dns_zone_t *zone) {
   15801 	REQUIRE(DNS_ZONE_VALID(zone));
   15802 
   15803 	LOCK_ZONE(zone);
   15804 	if (zone->xfr_acl != NULL) {
   15805 		dns_acl_detach(&zone->xfr_acl);
   15806 	}
   15807 	UNLOCK_ZONE(zone);
   15808 }
   15809 
   15810 bool
   15811 dns_zone_getupdatedisabled(dns_zone_t *zone) {
   15812 	REQUIRE(DNS_ZONE_VALID(zone));
   15813 	return (zone->update_disabled);
   15814 }
   15815 
   15816 void
   15817 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
   15818 	REQUIRE(DNS_ZONE_VALID(zone));
   15819 	zone->update_disabled = state;
   15820 }
   15821 
   15822 bool
   15823 dns_zone_getzeronosoattl(dns_zone_t *zone) {
   15824 	REQUIRE(DNS_ZONE_VALID(zone));
   15825 	return (zone->zero_no_soa_ttl);
   15826 }
   15827 
   15828 void
   15829 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
   15830 	REQUIRE(DNS_ZONE_VALID(zone));
   15831 	zone->zero_no_soa_ttl = state;
   15832 }
   15833 
   15834 void
   15835 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
   15836 	REQUIRE(DNS_ZONE_VALID(zone));
   15837 
   15838 	zone->check_names = severity;
   15839 }
   15840 
   15841 dns_severity_t
   15842 dns_zone_getchecknames(dns_zone_t *zone) {
   15843 	REQUIRE(DNS_ZONE_VALID(zone));
   15844 
   15845 	return (zone->check_names);
   15846 }
   15847 
   15848 void
   15849 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
   15850 	REQUIRE(DNS_ZONE_VALID(zone));
   15851 
   15852 	zone->journalsize = size;
   15853 }
   15854 
   15855 int32_t
   15856 dns_zone_getjournalsize(dns_zone_t *zone) {
   15857 	REQUIRE(DNS_ZONE_VALID(zone));
   15858 
   15859 	return (zone->journalsize);
   15860 }
   15861 
   15862 static void
   15863 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15864 	isc_result_t result = ISC_R_FAILURE;
   15865 	isc_buffer_t buffer;
   15866 
   15867 	REQUIRE(buf != NULL);
   15868 	REQUIRE(length > 1U);
   15869 
   15870 	/*
   15871 	 * Leave space for terminating '\0'.
   15872 	 */
   15873 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15874 	if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
   15875 		if (dns_name_dynamic(&zone->origin)) {
   15876 			result = dns_name_totext(&zone->origin, true, &buffer);
   15877 		}
   15878 		if (result != ISC_R_SUCCESS &&
   15879 		    isc_buffer_availablelength(&buffer) >=
   15880 			    (sizeof("<UNKNOWN>") - 1))
   15881 		{
   15882 			isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15883 		}
   15884 
   15885 		if (isc_buffer_availablelength(&buffer) > 0) {
   15886 			isc_buffer_putstr(&buffer, "/");
   15887 		}
   15888 		(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   15889 	}
   15890 
   15891 	if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
   15892 	    strcmp(zone->view->name, "_default") != 0 &&
   15893 	    strlen(zone->view->name) < isc_buffer_availablelength(&buffer))
   15894 	{
   15895 		isc_buffer_putstr(&buffer, "/");
   15896 		isc_buffer_putstr(&buffer, zone->view->name);
   15897 	}
   15898 	if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) {
   15899 		isc_buffer_putstr(&buffer, " (signed)");
   15900 	}
   15901 	if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) {
   15902 		isc_buffer_putstr(&buffer, " (unsigned)");
   15903 	}
   15904 
   15905 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15906 }
   15907 
   15908 static void
   15909 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15910 	isc_result_t result = ISC_R_FAILURE;
   15911 	isc_buffer_t buffer;
   15912 
   15913 	REQUIRE(buf != NULL);
   15914 	REQUIRE(length > 1U);
   15915 
   15916 	/*
   15917 	 * Leave space for terminating '\0'.
   15918 	 */
   15919 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15920 	if (dns_name_dynamic(&zone->origin)) {
   15921 		result = dns_name_totext(&zone->origin, true, &buffer);
   15922 	}
   15923 	if (result != ISC_R_SUCCESS &&
   15924 	    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
   15925 	{
   15926 		isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15927 	}
   15928 
   15929 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15930 }
   15931 
   15932 static void
   15933 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15934 	isc_buffer_t buffer;
   15935 
   15936 	REQUIRE(buf != NULL);
   15937 	REQUIRE(length > 1U);
   15938 
   15939 	/*
   15940 	 * Leave space for terminating '\0'.
   15941 	 */
   15942 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15943 	(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   15944 
   15945 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15946 }
   15947 
   15948 static void
   15949 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15950 	isc_buffer_t buffer;
   15951 
   15952 	REQUIRE(buf != NULL);
   15953 	REQUIRE(length > 1U);
   15954 
   15955 	/*
   15956 	 * Leave space for terminating '\0'.
   15957 	 */
   15958 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15959 
   15960 	if (zone->view == NULL) {
   15961 		isc_buffer_putstr(&buffer, "_none");
   15962 	} else if (strlen(zone->view->name) <
   15963 		   isc_buffer_availablelength(&buffer))
   15964 	{
   15965 		isc_buffer_putstr(&buffer, zone->view->name);
   15966 	} else {
   15967 		isc_buffer_putstr(&buffer, "_toolong");
   15968 	}
   15969 
   15970 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15971 }
   15972 
   15973 void
   15974 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
   15975 	REQUIRE(DNS_ZONE_VALID(zone));
   15976 	REQUIRE(buf != NULL);
   15977 
   15978 	LOCK_ZONE(zone);
   15979 	zone_namerd_tostr(zone, buf, length);
   15980 	UNLOCK_ZONE(zone);
   15981 }
   15982 
   15983 void
   15984 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
   15985 	REQUIRE(DNS_ZONE_VALID(zone));
   15986 	REQUIRE(buf != NULL);
   15987 	zone_name_tostr(zone, buf, length);
   15988 }
   15989 
   15990 void
   15991 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level,
   15992 	      const char *prefix, const char *fmt, va_list ap) {
   15993 	char message[4096];
   15994 	const char *zstr;
   15995 
   15996 	REQUIRE(DNS_ZONE_VALID(zone));
   15997 
   15998 	if (!isc_log_wouldlog(dns_lctx, level)) {
   15999 		return;
   16000 	}
   16001 
   16002 	vsnprintf(message, sizeof(message), fmt, ap);
   16003 
   16004 	switch (zone->type) {
   16005 	case dns_zone_key:
   16006 		zstr = "managed-keys-zone";
   16007 		break;
   16008 	case dns_zone_redirect:
   16009 		zstr = "redirect-zone";
   16010 		break;
   16011 	default:
   16012 		zstr = "zone ";
   16013 	}
   16014 
   16015 	isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level,
   16016 		      "%s%s%s%s: %s", (prefix != NULL ? prefix : ""),
   16017 		      (prefix != NULL ? ": " : ""), zstr, zone->strnamerd,
   16018 		      message);
   16019 }
   16020 
   16021 static void
   16022 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   16023 	va_list ap;
   16024 
   16025 	va_start(ap, fmt);
   16026 	dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap);
   16027 	va_end(ap);
   16028 }
   16029 
   16030 void
   16031 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level,
   16032 	      const char *fmt, ...) {
   16033 	va_list ap;
   16034 
   16035 	va_start(ap, fmt);
   16036 	dns_zone_logv(zone, category, level, NULL, fmt, ap);
   16037 	va_end(ap);
   16038 }
   16039 
   16040 void
   16041 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   16042 	va_list ap;
   16043 
   16044 	va_start(ap, fmt);
   16045 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap);
   16046 	va_end(ap);
   16047 }
   16048 
   16049 static void
   16050 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt,
   16051 	      ...) {
   16052 	int level = ISC_LOG_DEBUG(debuglevel);
   16053 	va_list ap;
   16054 
   16055 	va_start(ap, fmt);
   16056 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap);
   16057 	va_end(ap);
   16058 }
   16059 
   16060 static void
   16061 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   16062 	va_list ap;
   16063 
   16064 	va_start(ap, fmt);
   16065 	dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap);
   16066 	va_end(ap);
   16067 }
   16068 
   16069 static int
   16070 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) {
   16071 	isc_result_t result;
   16072 	dns_name_t *name;
   16073 	dns_rdataset_t *curr;
   16074 	int count = 0;
   16075 
   16076 	result = dns_message_firstname(msg, section);
   16077 	while (result == ISC_R_SUCCESS) {
   16078 		name = NULL;
   16079 		dns_message_currentname(msg, section, &name);
   16080 
   16081 		for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
   16082 		     curr = ISC_LIST_PREV(curr, link))
   16083 		{
   16084 			if (curr->type == type) {
   16085 				count++;
   16086 			}
   16087 		}
   16088 		result = dns_message_nextname(msg, section);
   16089 	}
   16090 
   16091 	return (count);
   16092 }
   16093 
   16094 void
   16095 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
   16096 	REQUIRE(DNS_ZONE_VALID(zone));
   16097 
   16098 	zone->maxxfrin = maxxfrin;
   16099 }
   16100 
   16101 uint32_t
   16102 dns_zone_getmaxxfrin(dns_zone_t *zone) {
   16103 	REQUIRE(DNS_ZONE_VALID(zone));
   16104 
   16105 	return (zone->maxxfrin);
   16106 }
   16107 
   16108 void
   16109 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
   16110 	REQUIRE(DNS_ZONE_VALID(zone));
   16111 	zone->maxxfrout = maxxfrout;
   16112 }
   16113 
   16114 uint32_t
   16115 dns_zone_getmaxxfrout(dns_zone_t *zone) {
   16116 	REQUIRE(DNS_ZONE_VALID(zone));
   16117 
   16118 	return (zone->maxxfrout);
   16119 }
   16120 
   16121 dns_zonetype_t
   16122 dns_zone_gettype(dns_zone_t *zone) {
   16123 	REQUIRE(DNS_ZONE_VALID(zone));
   16124 
   16125 	return (zone->type);
   16126 }
   16127 
   16128 const char *
   16129 dns_zonetype_name(dns_zonetype_t type) {
   16130 	switch (type) {
   16131 	case dns_zone_none:
   16132 		return ("none");
   16133 	case dns_zone_primary:
   16134 		return ("primary");
   16135 	case dns_zone_secondary:
   16136 		return ("secondary");
   16137 	case dns_zone_mirror:
   16138 		return ("mirror");
   16139 	case dns_zone_stub:
   16140 		return ("stub");
   16141 	case dns_zone_staticstub:
   16142 		return ("static-stub");
   16143 	case dns_zone_key:
   16144 		return ("key");
   16145 	case dns_zone_dlz:
   16146 		return ("dlz");
   16147 	case dns_zone_redirect:
   16148 		return ("redirect");
   16149 	default:
   16150 		return ("unknown");
   16151 	}
   16152 }
   16153 
   16154 dns_zonetype_t
   16155 dns_zone_getredirecttype(dns_zone_t *zone) {
   16156 	REQUIRE(DNS_ZONE_VALID(zone));
   16157 	REQUIRE(zone->type == dns_zone_redirect);
   16158 
   16159 	return (zone->masters == NULL ? dns_zone_primary : dns_zone_secondary);
   16160 }
   16161 
   16162 dns_name_t *
   16163 dns_zone_getorigin(dns_zone_t *zone) {
   16164 	REQUIRE(DNS_ZONE_VALID(zone));
   16165 
   16166 	return (&zone->origin);
   16167 }
   16168 
   16169 void
   16170 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
   16171 	REQUIRE(DNS_ZONE_VALID(zone));
   16172 
   16173 	LOCK_ZONE(zone);
   16174 	if (zone->task != NULL) {
   16175 		isc_task_detach(&zone->task);
   16176 	}
   16177 	isc_task_attach(task, &zone->task);
   16178 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16179 	if (zone->db != NULL) {
   16180 		dns_db_settask(zone->db, zone->task);
   16181 	}
   16182 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16183 	UNLOCK_ZONE(zone);
   16184 }
   16185 
   16186 void
   16187 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
   16188 	REQUIRE(DNS_ZONE_VALID(zone));
   16189 	isc_task_attach(zone->task, target);
   16190 }
   16191 
   16192 void
   16193 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
   16194 	REQUIRE(DNS_ZONE_VALID(zone));
   16195 
   16196 	if (idlein == 0) {
   16197 		idlein = DNS_DEFAULT_IDLEIN;
   16198 	}
   16199 	zone->idlein = idlein;
   16200 }
   16201 
   16202 uint32_t
   16203 dns_zone_getidlein(dns_zone_t *zone) {
   16204 	REQUIRE(DNS_ZONE_VALID(zone));
   16205 
   16206 	return (zone->idlein);
   16207 }
   16208 
   16209 void
   16210 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
   16211 	REQUIRE(DNS_ZONE_VALID(zone));
   16212 
   16213 	zone->idleout = idleout;
   16214 }
   16215 
   16216 uint32_t
   16217 dns_zone_getidleout(dns_zone_t *zone) {
   16218 	REQUIRE(DNS_ZONE_VALID(zone));
   16219 
   16220 	return (zone->idleout);
   16221 }
   16222 
   16223 static void
   16224 notify_done(isc_task_t *task, isc_event_t *event) {
   16225 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   16226 	dns_notify_t *notify;
   16227 	isc_result_t result;
   16228 	dns_message_t *message = NULL;
   16229 	isc_buffer_t buf;
   16230 	char rcode[128];
   16231 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   16232 
   16233 	UNUSED(task);
   16234 
   16235 	notify = event->ev_arg;
   16236 	REQUIRE(DNS_NOTIFY_VALID(notify));
   16237 	INSIST(task == notify->zone->task);
   16238 
   16239 	isc_buffer_init(&buf, rcode, sizeof(rcode));
   16240 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   16241 	dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE,
   16242 			   &message);
   16243 
   16244 	result = revent->result;
   16245 	if (result == ISC_R_SUCCESS) {
   16246 		result =
   16247 			dns_request_getresponse(revent->request, message,
   16248 						DNS_MESSAGEPARSE_PRESERVEORDER);
   16249 	}
   16250 	if (result == ISC_R_SUCCESS) {
   16251 		result = dns_rcode_totext(message->rcode, &buf);
   16252 	}
   16253 	if (result == ISC_R_SUCCESS) {
   16254 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   16255 			   "notify response from %s: %.*s", addrbuf,
   16256 			   (int)buf.used, rcode);
   16257 	} else {
   16258 		notify_log(notify->zone, ISC_LOG_DEBUG(2),
   16259 			   "notify to %s failed: %s", addrbuf,
   16260 			   dns_result_totext(result));
   16261 	}
   16262 
   16263 	/*
   16264 	 * Old bind's return formerr if they see a soa record.	Retry w/o
   16265 	 * the soa if we see a formerr and had sent a SOA.
   16266 	 */
   16267 	isc_event_free(&event);
   16268 	if (message->rcode == dns_rcode_formerr &&
   16269 	    (notify->flags & DNS_NOTIFY_NOSOA) == 0)
   16270 	{
   16271 		bool startup;
   16272 
   16273 		notify->flags |= DNS_NOTIFY_NOSOA;
   16274 		dns_request_destroy(&notify->request);
   16275 		startup = (notify->flags & DNS_NOTIFY_STARTUP);
   16276 		result = notify_send_queue(notify, startup);
   16277 		if (result != ISC_R_SUCCESS) {
   16278 			notify_destroy(notify, false);
   16279 		}
   16280 	} else {
   16281 		if (result == ISC_R_TIMEDOUT) {
   16282 			notify_log(notify->zone, ISC_LOG_DEBUG(1),
   16283 				   "notify to %s: retries exceeded", addrbuf);
   16284 		}
   16285 		notify_destroy(notify, false);
   16286 	}
   16287 	dns_message_detach(&message);
   16288 }
   16289 
   16290 struct secure_event {
   16291 	isc_event_t e;
   16292 	dns_db_t *db;
   16293 	uint32_t serial;
   16294 };
   16295 
   16296 static void
   16297 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
   16298 	UNUSED(arg);
   16299 	dns_zone_log(zone, level, "%s", message);
   16300 }
   16301 
   16302 static isc_result_t
   16303 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
   16304 		    uint32_t start, uint32_t end, dns_difftuple_t **soatuplep,
   16305 		    dns_diff_t *diff) {
   16306 	isc_result_t result;
   16307 	dns_difftuple_t *tuple = NULL;
   16308 	dns_diffop_t op = DNS_DIFFOP_ADD;
   16309 	int n_soa = 0;
   16310 
   16311 	REQUIRE(soatuplep != NULL);
   16312 
   16313 	if (start == end) {
   16314 		return (DNS_R_UNCHANGED);
   16315 	}
   16316 
   16317 	CHECK(dns_journal_iter_init(journal, start, end, NULL));
   16318 	for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS;
   16319 	     result = dns_journal_next_rr(journal))
   16320 	{
   16321 		dns_name_t *name = NULL;
   16322 		uint32_t ttl;
   16323 		dns_rdata_t *rdata = NULL;
   16324 		dns_journal_current_rr(journal, &name, &ttl, &rdata);
   16325 
   16326 		if (rdata->type == dns_rdatatype_soa) {
   16327 			n_soa++;
   16328 			if (n_soa == 2) {
   16329 				/*
   16330 				 * Save the latest raw SOA record.
   16331 				 */
   16332 				if (*soatuplep != NULL) {
   16333 					dns_difftuple_free(soatuplep);
   16334 				}
   16335 				CHECK(dns_difftuple_create(
   16336 					diff->mctx, DNS_DIFFOP_ADD, name, ttl,
   16337 					rdata, soatuplep));
   16338 			}
   16339 			if (n_soa == 3) {
   16340 				n_soa = 1;
   16341 			}
   16342 			continue;
   16343 		}
   16344 
   16345 		/* Sanity. */
   16346 		if (n_soa == 0) {
   16347 			dns_zone_log(raw, ISC_LOG_ERROR,
   16348 				     "corrupt journal file: '%s'\n",
   16349 				     raw->journal);
   16350 			return (ISC_R_FAILURE);
   16351 		}
   16352 
   16353 		if (zone->privatetype != 0 && rdata->type == zone->privatetype)
   16354 		{
   16355 			continue;
   16356 		}
   16357 
   16358 		if (rdata->type == dns_rdatatype_nsec ||
   16359 		    rdata->type == dns_rdatatype_rrsig ||
   16360 		    rdata->type == dns_rdatatype_nsec3 ||
   16361 		    rdata->type == dns_rdatatype_dnskey ||
   16362 		    rdata->type == dns_rdatatype_nsec3param)
   16363 		{
   16364 			continue;
   16365 		}
   16366 
   16367 		op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
   16368 
   16369 		CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
   16370 					   &tuple));
   16371 		dns_diff_appendminimal(diff, &tuple);
   16372 	}
   16373 	if (result == ISC_R_NOMORE) {
   16374 		result = ISC_R_SUCCESS;
   16375 	}
   16376 
   16377 failure:
   16378 	return (result);
   16379 }
   16380 
   16381 static isc_result_t
   16382 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
   16383 	       dns_dbversion_t *secver, dns_difftuple_t **soatuple,
   16384 	       dns_diff_t *diff) {
   16385 	isc_result_t result;
   16386 	dns_db_t *rawdb = NULL;
   16387 	dns_dbversion_t *rawver = NULL;
   16388 	dns_difftuple_t *tuple = NULL, *next;
   16389 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   16390 	dns_rdata_soa_t oldsoa, newsoa;
   16391 
   16392 	REQUIRE(DNS_ZONE_VALID(seczone));
   16393 	REQUIRE(soatuple != NULL && *soatuple == NULL);
   16394 
   16395 	if (!seczone->sourceserialset) {
   16396 		return (DNS_R_UNCHANGED);
   16397 	}
   16398 
   16399 	dns_db_attach(raw->db, &rawdb);
   16400 	dns_db_currentversion(rawdb, &rawver);
   16401 	result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
   16402 	dns_db_closeversion(rawdb, &rawver, false);
   16403 	dns_db_detach(&rawdb);
   16404 
   16405 	if (result != ISC_R_SUCCESS) {
   16406 		return (result);
   16407 	}
   16408 
   16409 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) {
   16410 		next = ISC_LIST_NEXT(tuple, link);
   16411 		if (tuple->rdata.type == dns_rdatatype_nsec ||
   16412 		    tuple->rdata.type == dns_rdatatype_rrsig ||
   16413 		    tuple->rdata.type == dns_rdatatype_dnskey ||
   16414 		    tuple->rdata.type == dns_rdatatype_nsec3 ||
   16415 		    tuple->rdata.type == dns_rdatatype_nsec3param)
   16416 		{
   16417 			ISC_LIST_UNLINK(diff->tuples, tuple, link);
   16418 			dns_difftuple_free(&tuple);
   16419 			continue;
   16420 		}
   16421 		if (tuple->rdata.type == dns_rdatatype_soa) {
   16422 			if (tuple->op == DNS_DIFFOP_DEL) {
   16423 				INSIST(oldtuple == NULL);
   16424 				oldtuple = tuple;
   16425 			}
   16426 			if (tuple->op == DNS_DIFFOP_ADD) {
   16427 				INSIST(newtuple == NULL);
   16428 				newtuple = tuple;
   16429 			}
   16430 		}
   16431 	}
   16432 
   16433 	if (oldtuple != NULL && newtuple != NULL) {
   16434 		result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
   16435 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16436 
   16437 		result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
   16438 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16439 
   16440 		/*
   16441 		 * If the SOA records are the same except for the serial
   16442 		 * remove them from the diff.
   16443 		 */
   16444 		if (oldtuple->ttl == newtuple->ttl &&
   16445 		    oldsoa.refresh == newsoa.refresh &&
   16446 		    oldsoa.retry == newsoa.retry &&
   16447 		    oldsoa.minimum == newsoa.minimum &&
   16448 		    oldsoa.expire == newsoa.expire &&
   16449 		    dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
   16450 		    dns_name_equal(&oldsoa.contact, &newsoa.contact))
   16451 		{
   16452 			ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   16453 			dns_difftuple_free(&oldtuple);
   16454 			ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   16455 			dns_difftuple_free(&newtuple);
   16456 		}
   16457 	}
   16458 
   16459 	if (ISC_LIST_EMPTY(diff->tuples)) {
   16460 		return (DNS_R_UNCHANGED);
   16461 	}
   16462 
   16463 	/*
   16464 	 * If there are still SOA records in the diff they can now be removed
   16465 	 * saving the new SOA record.
   16466 	 */
   16467 	if (oldtuple != NULL) {
   16468 		ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   16469 		dns_difftuple_free(&oldtuple);
   16470 	}
   16471 
   16472 	if (newtuple != NULL) {
   16473 		ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   16474 		*soatuple = newtuple;
   16475 	}
   16476 
   16477 	return (ISC_R_SUCCESS);
   16478 }
   16479 
   16480 static void
   16481 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
   16482 	static char me[] = "receive_secure_serial";
   16483 	isc_result_t result = ISC_R_SUCCESS;
   16484 	dns_journal_t *rjournal = NULL;
   16485 	dns_journal_t *sjournal = NULL;
   16486 	uint32_t start, end;
   16487 	dns_zone_t *zone;
   16488 	dns_difftuple_t *tuple = NULL, *soatuple = NULL;
   16489 	dns_update_log_t log = { update_log_cb, NULL };
   16490 	uint32_t newserial = 0, desired = 0;
   16491 	isc_time_t timenow;
   16492 	int level = ISC_LOG_ERROR;
   16493 
   16494 	UNUSED(task);
   16495 
   16496 	zone = event->ev_arg;
   16497 	end = ((struct secure_event *)event)->serial;
   16498 
   16499 	ENTER;
   16500 
   16501 	LOCK_ZONE(zone);
   16502 
   16503 	/*
   16504 	 * If we are already processing a receive secure serial event
   16505 	 * for the zone, just queue the new one and exit.
   16506 	 */
   16507 	if (zone->rss_event != NULL && zone->rss_event != event) {
   16508 		ISC_LIST_APPEND(zone->rss_events, event, ev_link);
   16509 		UNLOCK_ZONE(zone);
   16510 		return;
   16511 	}
   16512 
   16513 nextevent:
   16514 	if (zone->rss_event != NULL) {
   16515 		INSIST(zone->rss_event == event);
   16516 		UNLOCK_ZONE(zone);
   16517 	} else {
   16518 		zone->rss_event = event;
   16519 		dns_diff_init(zone->mctx, &zone->rss_diff);
   16520 
   16521 		/*
   16522 		 * zone->db may be NULL, if the load from disk failed.
   16523 		 */
   16524 		result = ISC_R_SUCCESS;
   16525 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16526 		if (zone->db != NULL) {
   16527 			dns_db_attach(zone->db, &zone->rss_db);
   16528 		} else {
   16529 			result = ISC_R_FAILURE;
   16530 		}
   16531 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16532 
   16533 		if (result == ISC_R_SUCCESS && zone->raw != NULL) {
   16534 			dns_zone_attach(zone->raw, &zone->rss_raw);
   16535 		} else {
   16536 			result = ISC_R_FAILURE;
   16537 		}
   16538 
   16539 		UNLOCK_ZONE(zone);
   16540 
   16541 		CHECK(result);
   16542 
   16543 		/*
   16544 		 * We first attempt to sync the raw zone to the secure zone
   16545 		 * by using the raw zone's journal, applying all the deltas
   16546 		 * from the latest source-serial of the secure zone up to
   16547 		 * the current serial number of the raw zone.
   16548 		 *
   16549 		 * If that fails, then we'll fall back to a direct comparison
   16550 		 * between raw and secure zones.
   16551 		 */
   16552 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16553 				       zone->rss_raw->journal,
   16554 				       DNS_JOURNAL_WRITE, &rjournal));
   16555 
   16556 		result = dns_journal_open(zone->mctx, zone->journal,
   16557 					  DNS_JOURNAL_READ, &sjournal);
   16558 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   16559 			goto failure;
   16560 		}
   16561 
   16562 		if (!dns_journal_get_sourceserial(rjournal, &start)) {
   16563 			start = dns_journal_first_serial(rjournal);
   16564 			dns_journal_set_sourceserial(rjournal, start);
   16565 		}
   16566 		if (sjournal != NULL) {
   16567 			uint32_t serial;
   16568 			/*
   16569 			 * We read the secure journal first, if that
   16570 			 * exists use its value provided it is greater
   16571 			 * that from the raw journal.
   16572 			 */
   16573 			if (dns_journal_get_sourceserial(sjournal, &serial)) {
   16574 				if (isc_serial_gt(serial, start)) {
   16575 					start = serial;
   16576 				}
   16577 			}
   16578 			dns_journal_destroy(&sjournal);
   16579 		}
   16580 
   16581 		dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
   16582 		CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
   16583 
   16584 		/*
   16585 		 * Try to apply diffs from the raw zone's journal to the secure
   16586 		 * zone.  If that fails, we recover by syncing up the databases
   16587 		 * directly.
   16588 		 */
   16589 		result = sync_secure_journal(zone, zone->rss_raw, rjournal,
   16590 					     start, end, &soatuple,
   16591 					     &zone->rss_diff);
   16592 		if (result == DNS_R_UNCHANGED) {
   16593 			level = ISC_LOG_INFO;
   16594 			goto failure;
   16595 		} else if (result != ISC_R_SUCCESS) {
   16596 			CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
   16597 					     zone->rss_oldver, &soatuple,
   16598 					     &zone->rss_diff));
   16599 		}
   16600 
   16601 		CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
   16602 				     zone->rss_newver));
   16603 
   16604 		if (soatuple != NULL) {
   16605 			uint32_t oldserial;
   16606 
   16607 			CHECK(dns_db_createsoatuple(
   16608 				zone->rss_db, zone->rss_oldver,
   16609 				zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple));
   16610 			oldserial = dns_soa_getserial(&tuple->rdata);
   16611 			newserial = desired =
   16612 				dns_soa_getserial(&soatuple->rdata);
   16613 			if (!isc_serial_gt(newserial, oldserial)) {
   16614 				newserial = oldserial + 1;
   16615 				if (newserial == 0) {
   16616 					newserial++;
   16617 				}
   16618 				dns_soa_setserial(newserial, &soatuple->rdata);
   16619 			}
   16620 			CHECK(do_one_tuple(&tuple, zone->rss_db,
   16621 					   zone->rss_newver, &zone->rss_diff));
   16622 			CHECK(do_one_tuple(&soatuple, zone->rss_db,
   16623 					   zone->rss_newver, &zone->rss_diff));
   16624 		} else {
   16625 			CHECK(update_soa_serial(zone, zone->rss_db,
   16626 						zone->rss_newver,
   16627 						&zone->rss_diff, zone->mctx,
   16628 						zone->updatemethod));
   16629 		}
   16630 	}
   16631 	result = dns_update_signaturesinc(
   16632 		&log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver,
   16633 		&zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state);
   16634 	if (result == DNS_R_CONTINUE) {
   16635 		if (rjournal != NULL) {
   16636 			dns_journal_destroy(&rjournal);
   16637 		}
   16638 		isc_task_send(task, &event);
   16639 		return;
   16640 	}
   16641 	/*
   16642 	 * If something went wrong while trying to update the secure zone and
   16643 	 * the latter was already signed before, do not apply raw zone deltas
   16644 	 * to it as that would break existing DNSSEC signatures.  However, if
   16645 	 * the secure zone was not yet signed (e.g. because no signing keys
   16646 	 * were created for it), commence applying raw zone deltas to it so
   16647 	 * that contents of the raw zone and the secure zone are kept in sync.
   16648 	 */
   16649 	if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
   16650 		goto failure;
   16651 	}
   16652 
   16653 	if (rjournal == NULL) {
   16654 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16655 				       zone->rss_raw->journal,
   16656 				       DNS_JOURNAL_WRITE, &rjournal));
   16657 	}
   16658 	CHECK(zone_journal(zone, &zone->rss_diff, &end,
   16659 			   "receive_secure_serial"));
   16660 
   16661 	dns_journal_set_sourceserial(rjournal, end);
   16662 	dns_journal_commit(rjournal);
   16663 
   16664 	LOCK_ZONE(zone);
   16665 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   16666 
   16667 	zone->sourceserial = end;
   16668 	zone->sourceserialset = true;
   16669 	zone_needdump(zone, DNS_DUMP_DELAY);
   16670 
   16671 	/*
   16672 	 * Set resign time to make sure it is set to the earliest
   16673 	 * signature expiration.
   16674 	 */
   16675 	set_resigntime(zone);
   16676 	TIME_NOW(&timenow);
   16677 	zone_settimer(zone, &timenow);
   16678 	UNLOCK_ZONE(zone);
   16679 
   16680 	dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false);
   16681 	dns_db_closeversion(zone->rss_db, &zone->rss_newver, true);
   16682 
   16683 	if (newserial != 0) {
   16684 		dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
   16685 			     newserial, desired);
   16686 	}
   16687 
   16688 failure:
   16689 	isc_event_free(&zone->rss_event);
   16690 	event = ISC_LIST_HEAD(zone->rss_events);
   16691 
   16692 	if (zone->rss_raw != NULL) {
   16693 		dns_zone_detach(&zone->rss_raw);
   16694 	}
   16695 	if (result != ISC_R_SUCCESS) {
   16696 		LOCK_ZONE(zone);
   16697 		set_resigntime(zone);
   16698 		TIME_NOW(&timenow);
   16699 		zone_settimer(zone, &timenow);
   16700 		UNLOCK_ZONE(zone);
   16701 		dns_zone_log(zone, level, "receive_secure_serial: %s",
   16702 			     dns_result_totext(result));
   16703 	}
   16704 	if (tuple != NULL) {
   16705 		dns_difftuple_free(&tuple);
   16706 	}
   16707 	if (soatuple != NULL) {
   16708 		dns_difftuple_free(&soatuple);
   16709 	}
   16710 	if (zone->rss_db != NULL) {
   16711 		if (zone->rss_oldver != NULL) {
   16712 			dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
   16713 					    false);
   16714 		}
   16715 		if (zone->rss_newver != NULL) {
   16716 			dns_db_closeversion(zone->rss_db, &zone->rss_newver,
   16717 					    false);
   16718 		}
   16719 		dns_db_detach(&zone->rss_db);
   16720 	}
   16721 	INSIST(zone->rss_oldver == NULL);
   16722 	INSIST(zone->rss_newver == NULL);
   16723 	if (rjournal != NULL) {
   16724 		dns_journal_destroy(&rjournal);
   16725 	}
   16726 	dns_diff_clear(&zone->rss_diff);
   16727 
   16728 	if (event != NULL) {
   16729 		LOCK_ZONE(zone);
   16730 		isc_refcount_decrement(&zone->irefs);
   16731 		ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
   16732 		goto nextevent;
   16733 	}
   16734 
   16735 	event = ISC_LIST_HEAD(zone->rss_post);
   16736 	while (event != NULL) {
   16737 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   16738 		rss_post(zone, event);
   16739 		event = ISC_LIST_HEAD(zone->rss_post);
   16740 	}
   16741 
   16742 	dns_zone_idetach(&zone);
   16743 }
   16744 
   16745 static isc_result_t
   16746 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) {
   16747 	isc_event_t *e;
   16748 	dns_zone_t *dummy = NULL;
   16749 
   16750 	e = isc_event_allocate(zone->secure->mctx, zone,
   16751 			       DNS_EVENT_ZONESECURESERIAL,
   16752 			       receive_secure_serial, zone->secure,
   16753 			       sizeof(struct secure_event));
   16754 	((struct secure_event *)e)->serial = serial;
   16755 	INSIST(LOCKED_ZONE(zone->secure));
   16756 	zone_iattach(zone->secure, &dummy);
   16757 	isc_task_send(zone->secure->task, &e);
   16758 
   16759 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   16760 	return (ISC_R_SUCCESS);
   16761 }
   16762 
   16763 static isc_result_t
   16764 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   16765 	       dns_rdataset_t *rdataset, uint32_t oldserial) {
   16766 	dns_rdata_soa_t soa;
   16767 	dns_rdata_t rdata = DNS_RDATA_INIT;
   16768 	dns_rdatalist_t temprdatalist;
   16769 	dns_rdataset_t temprdataset;
   16770 	isc_buffer_t b;
   16771 	isc_result_t result;
   16772 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   16773 	dns_fixedname_t fixed;
   16774 	dns_name_t *name;
   16775 
   16776 	result = dns_rdataset_first(rdataset);
   16777 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16778 	dns_rdataset_current(rdataset, &rdata);
   16779 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   16780 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16781 
   16782 	if (isc_serial_gt(soa.serial, oldserial)) {
   16783 		return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
   16784 					   NULL));
   16785 	}
   16786 	/*
   16787 	 * Always bump the serial.
   16788 	 */
   16789 	oldserial++;
   16790 	if (oldserial == 0) {
   16791 		oldserial++;
   16792 	}
   16793 	soa.serial = oldserial;
   16794 
   16795 	/*
   16796 	 * Construct a replacement rdataset.
   16797 	 */
   16798 	dns_rdata_reset(&rdata);
   16799 	isc_buffer_init(&b, buf, sizeof(buf));
   16800 	result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
   16801 				      dns_rdatatype_soa, &soa, &b);
   16802 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16803 	dns_rdatalist_init(&temprdatalist);
   16804 	temprdatalist.rdclass = rdata.rdclass;
   16805 	temprdatalist.type = rdata.type;
   16806 	temprdatalist.ttl = rdataset->ttl;
   16807 	ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
   16808 
   16809 	dns_rdataset_init(&temprdataset);
   16810 	result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
   16811 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16812 
   16813 	name = dns_fixedname_initname(&fixed);
   16814 	result = dns_db_nodefullname(db, node, name);
   16815 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16816 	dns_rdataset_getownercase(rdataset, name);
   16817 	dns_rdataset_setownercase(&temprdataset, name);
   16818 	return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 0,
   16819 				   NULL));
   16820 }
   16821 
   16822 /*
   16823  * This function should populate an nsec3paramlist_t with the
   16824  * nsecparam_t data from a zone.
   16825  */
   16826 static isc_result_t
   16827 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
   16828 	isc_result_t result;
   16829 	dns_dbnode_t *node = NULL;
   16830 	dns_rdataset_t rdataset, prdataset;
   16831 	dns_dbversion_t *version = NULL;
   16832 	nsec3param_t *nsec3param = NULL;
   16833 	nsec3param_t *nsec3p = NULL;
   16834 	nsec3param_t *next;
   16835 	dns_db_t *db = NULL;
   16836 	unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   16837 
   16838 	REQUIRE(DNS_ZONE_VALID(zone));
   16839 	REQUIRE(nsec3list != NULL);
   16840 	REQUIRE(ISC_LIST_EMPTY(*nsec3list));
   16841 
   16842 	dns_rdataset_init(&rdataset);
   16843 	dns_rdataset_init(&prdataset);
   16844 
   16845 	dns_db_attach(zone->db, &db);
   16846 	CHECK(dns_db_getoriginnode(db, &node));
   16847 
   16848 	dns_db_currentversion(db, &version);
   16849 	result = dns_db_findrdataset(db, node, version,
   16850 				     dns_rdatatype_nsec3param,
   16851 				     dns_rdatatype_none, 0, &rdataset, NULL);
   16852 
   16853 	if (result != ISC_R_SUCCESS) {
   16854 		goto getprivate;
   16855 	}
   16856 
   16857 	/*
   16858 	 * Walk nsec3param rdataset making a list of parameters (note that
   16859 	 * multiple simultaneous nsec3 chains are annoyingly legal -- this
   16860 	 * is why we use an nsec3list, even though we will usually only
   16861 	 * have one).
   16862 	 */
   16863 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   16864 	     result = dns_rdataset_next(&rdataset))
   16865 	{
   16866 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16867 		dns_rdata_t private = DNS_RDATA_INIT;
   16868 
   16869 		dns_rdataset_current(&rdataset, &rdata);
   16870 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16871 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16872 			      "looping through nsec3param data");
   16873 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   16874 		ISC_LINK_INIT(nsec3param, link);
   16875 
   16876 		/*
   16877 		 * now transfer the data from the rdata to
   16878 		 * the nsec3param
   16879 		 */
   16880 		dns_nsec3param_toprivate(&rdata, &private, zone->privatetype,
   16881 					 nsec3param->data,
   16882 					 sizeof(nsec3param->data));
   16883 		nsec3param->length = private.length;
   16884 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   16885 	}
   16886 
   16887 getprivate:
   16888 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   16889 				     dns_rdatatype_none, 0, &prdataset, NULL);
   16890 	if (result != ISC_R_SUCCESS) {
   16891 		goto done;
   16892 	}
   16893 
   16894 	/*
   16895 	 * walk private type records, converting them to nsec3 parameters
   16896 	 * using dns_nsec3param_fromprivate(), do the right thing based on
   16897 	 * CREATE and REMOVE flags
   16898 	 */
   16899 	for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS;
   16900 	     result = dns_rdataset_next(&prdataset))
   16901 	{
   16902 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16903 		dns_rdata_t private = DNS_RDATA_INIT;
   16904 
   16905 		dns_rdataset_current(&prdataset, &private);
   16906 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16907 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16908 			      "looping through nsec3param private data");
   16909 
   16910 		/*
   16911 		 * Do we have a valid private record?
   16912 		 */
   16913 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   16914 						sizeof(buf)))
   16915 		{
   16916 			continue;
   16917 		}
   16918 
   16919 		/*
   16920 		 * Remove any NSEC3PARAM records scheduled to be removed.
   16921 		 */
   16922 		if (NSEC3REMOVE(rdata.data[1])) {
   16923 			/*
   16924 			 * Zero out the flags.
   16925 			 */
   16926 			rdata.data[1] = 0;
   16927 
   16928 			for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL;
   16929 			     nsec3p = next)
   16930 			{
   16931 				next = ISC_LIST_NEXT(nsec3p, link);
   16932 
   16933 				if (nsec3p->length == rdata.length + 1 &&
   16934 				    memcmp(rdata.data, nsec3p->data + 1,
   16935 					   nsec3p->length - 1) == 0)
   16936 				{
   16937 					ISC_LIST_UNLINK(*nsec3list, nsec3p,
   16938 							link);
   16939 					isc_mem_put(zone->mctx, nsec3p,
   16940 						    sizeof(nsec3param_t));
   16941 				}
   16942 			}
   16943 			continue;
   16944 		}
   16945 
   16946 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   16947 		ISC_LINK_INIT(nsec3param, link);
   16948 
   16949 		/*
   16950 		 * Copy the remaining private records so the nsec/nsec3
   16951 		 * chain gets created.
   16952 		 */
   16953 		INSIST(private.length <= sizeof(nsec3param->data));
   16954 		memmove(nsec3param->data, private.data, private.length);
   16955 		nsec3param->length = private.length;
   16956 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   16957 	}
   16958 
   16959 done:
   16960 	if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) {
   16961 		result = ISC_R_SUCCESS;
   16962 	}
   16963 
   16964 failure:
   16965 	if (node != NULL) {
   16966 		dns_db_detachnode(db, &node);
   16967 	}
   16968 	if (version != NULL) {
   16969 		dns_db_closeversion(db, &version, false);
   16970 	}
   16971 	if (db != NULL) {
   16972 		dns_db_detach(&db);
   16973 	}
   16974 	if (dns_rdataset_isassociated(&rdataset)) {
   16975 		dns_rdataset_disassociate(&rdataset);
   16976 	}
   16977 	if (dns_rdataset_isassociated(&prdataset)) {
   16978 		dns_rdataset_disassociate(&prdataset);
   16979 	}
   16980 	return (result);
   16981 }
   16982 
   16983 /*
   16984  * Populate new zone db with private type records found by save_nsec3param().
   16985  */
   16986 static isc_result_t
   16987 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   16988 		   nsec3paramlist_t *nsec3list) {
   16989 	isc_result_t result = ISC_R_SUCCESS;
   16990 	dns_diff_t diff;
   16991 	dns_rdata_t rdata;
   16992 	nsec3param_t *nsec3p = NULL;
   16993 	nsec3param_t *next;
   16994 
   16995 	REQUIRE(DNS_ZONE_VALID(zone));
   16996 	REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
   16997 
   16998 	dns_diff_init(zone->mctx, &diff);
   16999 
   17000 	/*
   17001 	 * Loop through the list of private-type records, set the INITIAL
   17002 	 * and CREATE flags, and the add the record to the apex of the tree
   17003 	 * in db.
   17004 	 */
   17005 	for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next)
   17006 	{
   17007 		next = ISC_LIST_NEXT(nsec3p, link);
   17008 		dns_rdata_init(&rdata);
   17009 		nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
   17010 		rdata.length = nsec3p->length;
   17011 		rdata.data = nsec3p->data;
   17012 		rdata.type = zone->privatetype;
   17013 		rdata.rdclass = zone->rdclass;
   17014 		result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
   17015 				       &zone->origin, 0, &rdata);
   17016 		if (result != ISC_R_SUCCESS) {
   17017 			break;
   17018 		}
   17019 	}
   17020 
   17021 	dns_diff_clear(&diff);
   17022 	return (result);
   17023 }
   17024 
   17025 static isc_result_t
   17026 copy_non_dnssec_records(dns_db_t *db, dns_db_t *version, dns_db_t *rawdb,
   17027 			dns_dbiterator_t *dbiterator, unsigned int *oldserial) {
   17028 	dns_dbnode_t *rawnode = NULL, *node = NULL;
   17029 	dns_fixedname_t fixed;
   17030 	dns_name_t *name = dns_fixedname_initname(&fixed);
   17031 	dns_rdataset_t rdataset;
   17032 	dns_rdatasetiter_t *rdsit = NULL;
   17033 	isc_result_t result;
   17034 
   17035 	result = dns_dbiterator_current(dbiterator, &rawnode, name);
   17036 	if (result != ISC_R_SUCCESS) {
   17037 		return (ISC_R_SUCCESS);
   17038 	}
   17039 
   17040 	dns_dbiterator_pause(dbiterator);
   17041 
   17042 	result = dns_db_findnode(db, name, true, &node);
   17043 	if (result != ISC_R_SUCCESS) {
   17044 		goto cleanup;
   17045 	}
   17046 
   17047 	result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, 0, &rdsit);
   17048 	if (result != ISC_R_SUCCESS) {
   17049 		goto cleanup;
   17050 	}
   17051 
   17052 	dns_rdataset_init(&rdataset);
   17053 
   17054 	for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS;
   17055 	     result = dns_rdatasetiter_next(rdsit))
   17056 	{
   17057 		dns_rdatasetiter_current(rdsit, &rdataset);
   17058 		if (rdataset.type == dns_rdatatype_nsec ||
   17059 		    rdataset.type == dns_rdatatype_rrsig ||
   17060 		    rdataset.type == dns_rdatatype_nsec3 ||
   17061 		    rdataset.type == dns_rdatatype_dnskey ||
   17062 		    rdataset.type == dns_rdatatype_nsec3param)
   17063 		{
   17064 			dns_rdataset_disassociate(&rdataset);
   17065 			continue;
   17066 		}
   17067 		if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) {
   17068 			result = checkandaddsoa(db, node, version, &rdataset,
   17069 						*oldserial);
   17070 		} else {
   17071 			result = dns_db_addrdataset(db, node, version, 0,
   17072 						    &rdataset, 0, NULL);
   17073 		}
   17074 		dns_rdataset_disassociate(&rdataset);
   17075 		if (result != ISC_R_SUCCESS) {
   17076 			goto cleanup;
   17077 		}
   17078 	}
   17079 	if (result == ISC_R_NOMORE) {
   17080 		result = ISC_R_SUCCESS;
   17081 	}
   17082 
   17083 cleanup:
   17084 	if (rdsit != NULL) {
   17085 		dns_rdatasetiter_destroy(&rdsit);
   17086 	}
   17087 	if (rawnode) {
   17088 		dns_db_detachnode(rawdb, &rawnode);
   17089 	}
   17090 	if (node) {
   17091 		dns_db_detachnode(db, &node);
   17092 	}
   17093 	return (result);
   17094 }
   17095 
   17096 static void
   17097 receive_secure_db(isc_task_t *task, isc_event_t *event) {
   17098 	isc_result_t result;
   17099 	dns_zone_t *zone;
   17100 	dns_db_t *rawdb, *db = NULL;
   17101 	dns_dbiterator_t *dbiterator = NULL;
   17102 	dns_dbversion_t *version = NULL;
   17103 	isc_time_t loadtime;
   17104 	unsigned int oldserial = 0, *oldserialp = NULL;
   17105 	nsec3paramlist_t nsec3list;
   17106 	isc_event_t *setnsec3param_event;
   17107 	dns_zone_t *dummy;
   17108 
   17109 	UNUSED(task);
   17110 
   17111 	ISC_LIST_INIT(nsec3list);
   17112 
   17113 	zone = event->ev_arg;
   17114 	rawdb = ((struct secure_event *)event)->db;
   17115 	isc_event_free(&event);
   17116 
   17117 	LOCK_ZONE(zone);
   17118 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
   17119 		result = ISC_R_SHUTTINGDOWN;
   17120 		goto failure;
   17121 	}
   17122 
   17123 	TIME_NOW(&loadtime);
   17124 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17125 	if (zone->db != NULL) {
   17126 		result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
   17127 		if (result == ISC_R_SUCCESS) {
   17128 			oldserialp = &oldserial;
   17129 		}
   17130 
   17131 		/*
   17132 		 * assemble nsec3parameters from the old zone, and set a flag
   17133 		 * if any are found
   17134 		 */
   17135 		result = save_nsec3param(zone, &nsec3list);
   17136 		if (result != ISC_R_SUCCESS) {
   17137 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17138 			goto failure;
   17139 		}
   17140 	}
   17141 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17142 
   17143 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   17144 			       dns_dbtype_zone, zone->rdclass,
   17145 			       zone->db_argc - 1, zone->db_argv + 1, &db);
   17146 	if (result != ISC_R_SUCCESS) {
   17147 		goto failure;
   17148 	}
   17149 
   17150 	result = dns_db_setgluecachestats(db, zone->gluecachestats);
   17151 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
   17152 		goto failure;
   17153 	}
   17154 
   17155 	result = dns_db_newversion(db, &version);
   17156 	if (result != ISC_R_SUCCESS) {
   17157 		goto failure;
   17158 	}
   17159 
   17160 	result = dns_db_createiterator(rawdb, 0, &dbiterator);
   17161 	if (result != ISC_R_SUCCESS) {
   17162 		goto failure;
   17163 	}
   17164 
   17165 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   17166 	     result = dns_dbiterator_next(dbiterator))
   17167 	{
   17168 		result = copy_non_dnssec_records(db, version, rawdb, dbiterator,
   17169 						 oldserialp);
   17170 		if (result != ISC_R_SUCCESS) {
   17171 			goto failure;
   17172 		}
   17173 	}
   17174 	dns_dbiterator_destroy(&dbiterator);
   17175 	if (result != ISC_R_NOMORE) {
   17176 		goto failure;
   17177 	}
   17178 
   17179 	/*
   17180 	 * Call restore_nsec3param() to create private-type records from
   17181 	 * the old nsec3 parameters and insert them into db
   17182 	 */
   17183 	if (!ISC_LIST_EMPTY(nsec3list)) {
   17184 		result = restore_nsec3param(zone, db, version, &nsec3list);
   17185 		if (result != ISC_R_SUCCESS) {
   17186 			goto failure;
   17187 		}
   17188 	}
   17189 
   17190 	dns_db_closeversion(db, &version, true);
   17191 
   17192 	/*
   17193 	 * Lock hierarchy: zmgr, zone, raw.
   17194 	 */
   17195 	INSIST(zone != zone->raw);
   17196 	LOCK_ZONE(zone->raw);
   17197 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   17198 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   17199 	zone_needdump(zone, 0); /* XXXMPA */
   17200 	UNLOCK_ZONE(zone->raw);
   17201 
   17202 	/*
   17203 	 * Process any queued NSEC3PARAM change requests.
   17204 	 */
   17205 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   17206 		setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   17207 		ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
   17208 				ev_link);
   17209 		dummy = NULL;
   17210 		zone_iattach(zone, &dummy);
   17211 		isc_task_send(zone->task, &setnsec3param_event);
   17212 	}
   17213 
   17214 failure:
   17215 	UNLOCK_ZONE(zone);
   17216 	if (dbiterator != NULL) {
   17217 		dns_dbiterator_destroy(&dbiterator);
   17218 	}
   17219 	if (result != ISC_R_SUCCESS) {
   17220 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
   17221 			     dns_result_totext(result));
   17222 	}
   17223 
   17224 	while (!ISC_LIST_EMPTY(nsec3list)) {
   17225 		nsec3param_t *nsec3p;
   17226 		nsec3p = ISC_LIST_HEAD(nsec3list);
   17227 		ISC_LIST_UNLINK(nsec3list, nsec3p, link);
   17228 		isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
   17229 	}
   17230 	if (db != NULL) {
   17231 		if (version != NULL) {
   17232 			dns_db_closeversion(db, &version, false);
   17233 		}
   17234 		dns_db_detach(&db);
   17235 	}
   17236 	dns_db_detach(&rawdb);
   17237 	dns_zone_idetach(&zone);
   17238 
   17239 	INSIST(version == NULL);
   17240 }
   17241 
   17242 static isc_result_t
   17243 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
   17244 	isc_event_t *e;
   17245 	dns_db_t *dummy = NULL;
   17246 	dns_zone_t *secure = NULL;
   17247 
   17248 	e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECUREDB,
   17249 			       receive_secure_db, zone->secure,
   17250 			       sizeof(struct secure_event));
   17251 	dns_db_attach(db, &dummy);
   17252 	((struct secure_event *)e)->db = dummy;
   17253 	INSIST(LOCKED_ZONE(zone->secure));
   17254 	zone_iattach(zone->secure, &secure);
   17255 	isc_task_send(zone->secure->task, &e);
   17256 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   17257 	return (ISC_R_SUCCESS);
   17258 }
   17259 
   17260 isc_result_t
   17261 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   17262 	isc_result_t result;
   17263 	dns_zone_t *secure = NULL;
   17264 
   17265 	REQUIRE(DNS_ZONE_VALID(zone));
   17266 again:
   17267 	LOCK_ZONE(zone);
   17268 	if (inline_raw(zone)) {
   17269 		secure = zone->secure;
   17270 		INSIST(secure != zone);
   17271 		TRYLOCK_ZONE(result, secure);
   17272 		if (result != ISC_R_SUCCESS) {
   17273 			UNLOCK_ZONE(zone);
   17274 			secure = NULL;
   17275 			isc_thread_yield();
   17276 			goto again;
   17277 		}
   17278 	}
   17279 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   17280 	result = zone_replacedb(zone, db, dump);
   17281 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   17282 	if (secure != NULL) {
   17283 		UNLOCK_ZONE(secure);
   17284 	}
   17285 	UNLOCK_ZONE(zone);
   17286 	return (result);
   17287 }
   17288 
   17289 static isc_result_t
   17290 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   17291 	dns_dbversion_t *ver;
   17292 	isc_result_t result;
   17293 	unsigned int soacount = 0;
   17294 	unsigned int nscount = 0;
   17295 
   17296 	/*
   17297 	 * 'zone' and 'zone->db' locked by caller.
   17298 	 */
   17299 	REQUIRE(DNS_ZONE_VALID(zone));
   17300 	REQUIRE(LOCKED_ZONE(zone));
   17301 	if (inline_raw(zone)) {
   17302 		REQUIRE(LOCKED_ZONE(zone->secure));
   17303 	}
   17304 
   17305 	result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL,
   17306 				  NULL, NULL, NULL, NULL, NULL);
   17307 	if (result == ISC_R_SUCCESS) {
   17308 		if (soacount != 1) {
   17309 			dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records",
   17310 				     soacount);
   17311 			result = DNS_R_BADZONE;
   17312 		}
   17313 		if (nscount == 0 && zone->type != dns_zone_key) {
   17314 			dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
   17315 			result = DNS_R_BADZONE;
   17316 		}
   17317 		if (result != ISC_R_SUCCESS) {
   17318 			return (result);
   17319 		}
   17320 	} else {
   17321 		dns_zone_log(zone, ISC_LOG_ERROR,
   17322 			     "retrieving SOA and NS records failed: %s",
   17323 			     dns_result_totext(result));
   17324 		return (result);
   17325 	}
   17326 
   17327 	result = check_nsec3param(zone, db);
   17328 	if (result != ISC_R_SUCCESS) {
   17329 		return (result);
   17330 	}
   17331 
   17332 	ver = NULL;
   17333 	dns_db_currentversion(db, &ver);
   17334 
   17335 	/*
   17336 	 * The initial version of a slave zone is always dumped;
   17337 	 * subsequent versions may be journaled instead if this
   17338 	 * is enabled in the configuration.
   17339 	 */
   17340 	if (zone->db != NULL && zone->journal != NULL &&
   17341 	    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   17342 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
   17343 	{
   17344 		uint32_t serial, oldserial;
   17345 
   17346 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
   17347 
   17348 		result = dns_db_getsoaserial(db, ver, &serial);
   17349 		if (result != ISC_R_SUCCESS) {
   17350 			dns_zone_log(zone, ISC_LOG_ERROR,
   17351 				     "ixfr-from-differences: unable to get "
   17352 				     "new serial");
   17353 			goto fail;
   17354 		}
   17355 
   17356 		/*
   17357 		 * This is checked in zone_postload() for master zones.
   17358 		 */
   17359 		result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
   17360 					  &oldserial, NULL, NULL, NULL, NULL,
   17361 					  NULL);
   17362 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   17363 		RUNTIME_CHECK(soacount > 0U);
   17364 		if ((zone->type == dns_zone_secondary ||
   17365 		     (zone->type == dns_zone_redirect &&
   17366 		      zone->masters != NULL)) &&
   17367 		    !isc_serial_gt(serial, oldserial))
   17368 		{
   17369 			uint32_t serialmin, serialmax;
   17370 			serialmin = (oldserial + 1) & 0xffffffffU;
   17371 			serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
   17372 			dns_zone_log(zone, ISC_LOG_ERROR,
   17373 				     "ixfr-from-differences: failed: "
   17374 				     "new serial (%u) out of range [%u - %u]",
   17375 				     serial, serialmin, serialmax);
   17376 			result = ISC_R_RANGE;
   17377 			goto fail;
   17378 		}
   17379 
   17380 		result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
   17381 				     zone->journal);
   17382 		if (result != ISC_R_SUCCESS) {
   17383 			char strbuf[ISC_STRERRORSIZE];
   17384 			strerror_r(errno, strbuf, sizeof(strbuf));
   17385 			dns_zone_log(zone, ISC_LOG_ERROR,
   17386 				     "ixfr-from-differences: failed: "
   17387 				     "%s",
   17388 				     strbuf);
   17389 			goto fallback;
   17390 		}
   17391 		if (dump) {
   17392 			zone_needdump(zone, DNS_DUMP_DELAY);
   17393 		} else {
   17394 			zone_journal_compact(zone, zone->db, serial);
   17395 		}
   17396 		if (zone->type == dns_zone_primary && inline_raw(zone)) {
   17397 			zone_send_secureserial(zone, serial);
   17398 		}
   17399 	} else {
   17400 	fallback:
   17401 		if (dump && zone->masterfile != NULL) {
   17402 			/*
   17403 			 * If DNS_ZONEFLG_FORCEXFER was set we don't want
   17404 			 * to keep the old masterfile.
   17405 			 */
   17406 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
   17407 			    remove(zone->masterfile) < 0 && errno != ENOENT)
   17408 			{
   17409 				char strbuf[ISC_STRERRORSIZE];
   17410 				strerror_r(errno, strbuf, sizeof(strbuf));
   17411 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17412 					      DNS_LOGMODULE_ZONE,
   17413 					      ISC_LOG_WARNING,
   17414 					      "unable to remove masterfile "
   17415 					      "'%s': '%s'",
   17416 					      zone->masterfile, strbuf);
   17417 			}
   17418 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) {
   17419 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
   17420 			} else {
   17421 				zone_needdump(zone, 0);
   17422 			}
   17423 		}
   17424 		if (dump && zone->journal != NULL) {
   17425 			/*
   17426 			 * The in-memory database just changed, and
   17427 			 * because 'dump' is set, it didn't change by
   17428 			 * being loaded from disk.  Also, we have not
   17429 			 * journaled diffs for this change.
   17430 			 * Therefore, the on-disk journal is missing
   17431 			 * the deltas for this change.	Since it can
   17432 			 * no longer be used to bring the zone
   17433 			 * up-to-date, it is useless and should be
   17434 			 * removed.
   17435 			 */
   17436 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17437 				      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   17438 				      "removing journal file");
   17439 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   17440 				char strbuf[ISC_STRERRORSIZE];
   17441 				strerror_r(errno, strbuf, sizeof(strbuf));
   17442 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17443 					      DNS_LOGMODULE_ZONE,
   17444 					      ISC_LOG_WARNING,
   17445 					      "unable to remove journal "
   17446 					      "'%s': '%s'",
   17447 					      zone->journal, strbuf);
   17448 			}
   17449 		}
   17450 
   17451 		if (inline_raw(zone)) {
   17452 			zone_send_securedb(zone, db);
   17453 		}
   17454 	}
   17455 
   17456 	dns_db_closeversion(db, &ver, false);
   17457 
   17458 	dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
   17459 
   17460 	if (zone->db != NULL) {
   17461 		zone_detachdb(zone);
   17462 	}
   17463 	zone_attachdb(zone, db);
   17464 	dns_db_settask(zone->db, zone->task);
   17465 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   17466 	return (ISC_R_SUCCESS);
   17467 
   17468 fail:
   17469 	dns_db_closeversion(db, &ver, false);
   17470 	return (result);
   17471 }
   17472 
   17473 /* The caller must hold the dblock as a writer. */
   17474 static void
   17475 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
   17476 	REQUIRE(zone->db == NULL && db != NULL);
   17477 
   17478 	dns_db_attach(db, &zone->db);
   17479 }
   17480 
   17481 /* The caller must hold the dblock as a writer. */
   17482 static void
   17483 zone_detachdb(dns_zone_t *zone) {
   17484 	REQUIRE(zone->db != NULL);
   17485 
   17486 	dns_zone_rpz_disable_db(zone, zone->db);
   17487 	dns_zone_catz_disable_db(zone, zone->db);
   17488 	dns_db_detach(&zone->db);
   17489 }
   17490 
   17491 static void
   17492 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
   17493 	isc_time_t now;
   17494 	bool again = false;
   17495 	unsigned int soacount;
   17496 	unsigned int nscount;
   17497 	uint32_t serial, refresh, retry, expire, minimum, soattl;
   17498 	isc_result_t xfrresult = result;
   17499 	bool free_needed;
   17500 	dns_zone_t *secure = NULL;
   17501 
   17502 	REQUIRE(DNS_ZONE_VALID(zone));
   17503 
   17504 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17505 		      "zone transfer finished: %s", dns_result_totext(result));
   17506 
   17507 	/*
   17508 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   17509 	 * could result in a deadlock due to a LOR so we will spin if we
   17510 	 * can't obtain the both locks.
   17511 	 */
   17512 again:
   17513 	LOCK_ZONE(zone);
   17514 	if (inline_raw(zone)) {
   17515 		secure = zone->secure;
   17516 		INSIST(secure != zone);
   17517 		TRYLOCK_ZONE(result, secure);
   17518 		if (result != ISC_R_SUCCESS) {
   17519 			UNLOCK_ZONE(zone);
   17520 			secure = NULL;
   17521 			isc_thread_yield();
   17522 			goto again;
   17523 		}
   17524 	}
   17525 
   17526 	INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH));
   17527 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   17528 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   17529 
   17530 	TIME_NOW(&now);
   17531 	switch (xfrresult) {
   17532 	case ISC_R_SUCCESS:
   17533 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   17534 		FALLTHROUGH;
   17535 	case DNS_R_UPTODATE:
   17536 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   17537 		/*
   17538 		 * Has the zone expired underneath us?
   17539 		 */
   17540 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17541 		if (zone->db == NULL) {
   17542 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17543 			goto same_master;
   17544 		}
   17545 
   17546 		/*
   17547 		 * Update the zone structure's data from the actual
   17548 		 * SOA received.
   17549 		 */
   17550 		nscount = 0;
   17551 		soacount = 0;
   17552 		INSIST(zone->db != NULL);
   17553 		result = zone_get_from_db(zone, zone->db, &nscount, &soacount,
   17554 					  &soattl, &serial, &refresh, &retry,
   17555 					  &expire, &minimum, NULL);
   17556 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17557 		if (result == ISC_R_SUCCESS) {
   17558 			if (soacount != 1) {
   17559 				dns_zone_log(zone, ISC_LOG_ERROR,
   17560 					     "transferred zone "
   17561 					     "has %d SOA records",
   17562 					     soacount);
   17563 				if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   17564 				{
   17565 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   17566 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   17567 				}
   17568 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17569 				zone_unload(zone);
   17570 				goto next_master;
   17571 			}
   17572 			if (nscount == 0) {
   17573 				dns_zone_log(zone, ISC_LOG_ERROR,
   17574 					     "transferred zone "
   17575 					     "has no NS records");
   17576 				if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   17577 				{
   17578 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   17579 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   17580 				}
   17581 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17582 				zone_unload(zone);
   17583 				goto next_master;
   17584 			}
   17585 			zone->refresh = RANGE(refresh, zone->minrefresh,
   17586 					      zone->maxrefresh);
   17587 			zone->retry = RANGE(retry, zone->minretry,
   17588 					    zone->maxretry);
   17589 			zone->expire = RANGE(expire,
   17590 					     zone->refresh + zone->retry,
   17591 					     DNS_MAX_EXPIRE);
   17592 			zone->soattl = soattl;
   17593 			zone->minimum = minimum;
   17594 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17595 		}
   17596 
   17597 		/*
   17598 		 * Set our next update/expire times.
   17599 		 */
   17600 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   17601 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   17602 			zone->refreshtime = now;
   17603 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17604 					  &zone->expiretime);
   17605 		} else {
   17606 			DNS_ZONE_JITTER_ADD(&now, zone->refresh,
   17607 					    &zone->refreshtime);
   17608 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17609 					  &zone->expiretime);
   17610 		}
   17611 		if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
   17612 			char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
   17613 			if (zone->tsigkey != NULL) {
   17614 				char namebuf[DNS_NAME_FORMATSIZE];
   17615 				dns_name_format(&zone->tsigkey->name, namebuf,
   17616 						sizeof(namebuf));
   17617 				snprintf(buf, sizeof(buf), ": TSIG '%s'",
   17618 					 namebuf);
   17619 			} else {
   17620 				buf[0] = '\0';
   17621 			}
   17622 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17623 				      ISC_LOG_INFO, "transferred serial %u%s",
   17624 				      serial, buf);
   17625 			if (inline_raw(zone)) {
   17626 				zone_send_secureserial(zone, serial);
   17627 			}
   17628 		}
   17629 
   17630 		/*
   17631 		 * This is not necessary if we just performed a AXFR
   17632 		 * however it is necessary for an IXFR / UPTODATE and
   17633 		 * won't hurt with an AXFR.
   17634 		 */
   17635 		if (zone->masterfile != NULL || zone->journal != NULL) {
   17636 			unsigned int delay = DNS_DUMP_DELAY;
   17637 
   17638 			result = ISC_R_FAILURE;
   17639 			if (zone->journal != NULL) {
   17640 				result = isc_file_settime(zone->journal, &now);
   17641 			}
   17642 			if (result != ISC_R_SUCCESS && zone->masterfile != NULL)
   17643 			{
   17644 				result = isc_file_settime(zone->masterfile,
   17645 							  &now);
   17646 			}
   17647 
   17648 			if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
   17649 			    result == ISC_R_FILENOTFOUND)
   17650 			{
   17651 				delay = 0;
   17652 			}
   17653 
   17654 			if ((result == ISC_R_SUCCESS ||
   17655 			     result == ISC_R_FILENOTFOUND) &&
   17656 			    zone->masterfile != NULL)
   17657 			{
   17658 				zone_needdump(zone, delay);
   17659 			} else if (result != ISC_R_SUCCESS) {
   17660 				dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17661 					      ISC_LOG_ERROR,
   17662 					      "transfer: could not set file "
   17663 					      "modification time of '%s': %s",
   17664 					      zone->masterfile,
   17665 					      dns_result_totext(result));
   17666 			}
   17667 		}
   17668 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
   17669 		inc_stats(zone, dns_zonestatscounter_xfrsuccess);
   17670 		break;
   17671 
   17672 	case DNS_R_BADIXFR:
   17673 		/* Force retry with AXFR. */
   17674 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR);
   17675 		goto same_master;
   17676 
   17677 	case DNS_R_TOOMANYRECORDS:
   17678 	case DNS_R_VERIFYFAILURE:
   17679 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   17680 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17681 		break;
   17682 
   17683 	default:
   17684 	next_master:
   17685 		/*
   17686 		 * Skip to next failed / untried master.
   17687 		 */
   17688 		do {
   17689 			zone->curmaster++;
   17690 		} while (zone->curmaster < zone->masterscnt &&
   17691 			 zone->mastersok[zone->curmaster]);
   17692 	same_master:
   17693 		if (zone->curmaster >= zone->masterscnt) {
   17694 			zone->curmaster = 0;
   17695 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   17696 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   17697 			{
   17698 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17699 				DNS_ZONE_SETFLAG(zone,
   17700 						 DNS_ZONEFLG_USEALTXFRSRC);
   17701 				while (zone->curmaster < zone->masterscnt &&
   17702 				       zone->mastersok[zone->curmaster])
   17703 				{
   17704 					zone->curmaster++;
   17705 				}
   17706 				again = true;
   17707 			} else {
   17708 				DNS_ZONE_CLRFLAG(zone,
   17709 						 DNS_ZONEFLG_USEALTXFRSRC);
   17710 			}
   17711 		} else {
   17712 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17713 			again = true;
   17714 		}
   17715 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17716 		break;
   17717 	}
   17718 	zone_settimer(zone, &now);
   17719 
   17720 	/*
   17721 	 * If creating the transfer object failed, zone->xfr is NULL.
   17722 	 * Otherwise, we are called as the done callback of a zone
   17723 	 * transfer object that just entered its shutting-down
   17724 	 * state.  Since we are no longer responsible for shutting
   17725 	 * it down, we can detach our reference.
   17726 	 */
   17727 	if (zone->xfr != NULL) {
   17728 		dns_xfrin_detach(&zone->xfr);
   17729 	}
   17730 
   17731 	if (zone->tsigkey != NULL) {
   17732 		dns_tsigkey_detach(&zone->tsigkey);
   17733 	}
   17734 
   17735 	/*
   17736 	 * Handle any deferred journal compaction.
   17737 	 */
   17738 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
   17739 		dns_db_t *db = NULL;
   17740 		if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) {
   17741 			zone_journal_compact(zone, db, zone->compact_serial);
   17742 			dns_db_detach(&db);
   17743 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   17744 		}
   17745 	}
   17746 
   17747 	if (secure != NULL) {
   17748 		UNLOCK_ZONE(secure);
   17749 	}
   17750 	/*
   17751 	 * This transfer finishing freed up a transfer quota slot.
   17752 	 * Let any other zones waiting for quota have it.
   17753 	 */
   17754 	if (zone->zmgr != NULL &&
   17755 	    zone->statelist == &zone->zmgr->xfrin_in_progress)
   17756 	{
   17757 		UNLOCK_ZONE(zone);
   17758 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17759 		ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
   17760 		zone->statelist = NULL;
   17761 		zmgr_resume_xfrs(zone->zmgr, false);
   17762 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17763 		LOCK_ZONE(zone);
   17764 	}
   17765 
   17766 	/*
   17767 	 * Retry with a different server if necessary.
   17768 	 */
   17769 	if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   17770 		queue_soa_query(zone);
   17771 	}
   17772 
   17773 	isc_refcount_decrement(&zone->irefs);
   17774 	free_needed = exit_check(zone);
   17775 	UNLOCK_ZONE(zone);
   17776 	if (free_needed) {
   17777 		zone_free(zone);
   17778 	}
   17779 }
   17780 
   17781 static void
   17782 zone_loaddone(void *arg, isc_result_t result) {
   17783 	static char me[] = "zone_loaddone";
   17784 	dns_load_t *load = arg;
   17785 	dns_zone_t *zone;
   17786 	isc_result_t tresult;
   17787 	dns_zone_t *secure = NULL;
   17788 
   17789 	REQUIRE(DNS_LOAD_VALID(load));
   17790 	zone = load->zone;
   17791 
   17792 	ENTER;
   17793 
   17794 	/*
   17795 	 * If zone loading failed, remove the update db callbacks prior
   17796 	 * to calling the list of callbacks in the zone load structure.
   17797 	 */
   17798 	if (result != ISC_R_SUCCESS) {
   17799 		dns_zone_rpz_disable_db(zone, load->db);
   17800 		dns_zone_catz_disable_db(zone, load->db);
   17801 	}
   17802 
   17803 	tresult = dns_db_endload(load->db, &load->callbacks);
   17804 	if (tresult != ISC_R_SUCCESS &&
   17805 	    (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
   17806 	{
   17807 		result = tresult;
   17808 	}
   17809 
   17810 	/*
   17811 	 * Lock hierarchy: zmgr, zone, raw.
   17812 	 */
   17813 again:
   17814 	LOCK_ZONE(zone);
   17815 	INSIST(zone != zone->raw);
   17816 	if (inline_secure(zone)) {
   17817 		LOCK_ZONE(zone->raw);
   17818 	} else if (inline_raw(zone)) {
   17819 		secure = zone->secure;
   17820 		TRYLOCK_ZONE(tresult, secure);
   17821 		if (tresult != ISC_R_SUCCESS) {
   17822 			UNLOCK_ZONE(zone);
   17823 			secure = NULL;
   17824 			isc_thread_yield();
   17825 			goto again;
   17826 		}
   17827 	}
   17828 	(void)zone_postload(zone, load->db, load->loadtime, result);
   17829 	zonemgr_putio(&zone->readio);
   17830 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
   17831 	zone_idetach(&load->callbacks.zone);
   17832 	/*
   17833 	 * Leave the zone frozen if the reload fails.
   17834 	 */
   17835 	if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
   17836 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
   17837 	{
   17838 		zone->update_disabled = false;
   17839 	}
   17840 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
   17841 	if (inline_secure(zone)) {
   17842 		UNLOCK_ZONE(zone->raw);
   17843 	} else if (secure != NULL) {
   17844 		UNLOCK_ZONE(secure);
   17845 	}
   17846 	UNLOCK_ZONE(zone);
   17847 
   17848 	load->magic = 0;
   17849 	dns_db_detach(&load->db);
   17850 	if (load->zone->lctx != NULL) {
   17851 		dns_loadctx_detach(&load->zone->lctx);
   17852 	}
   17853 	dns_zone_idetach(&load->zone);
   17854 	isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
   17855 }
   17856 
   17857 void
   17858 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
   17859 	REQUIRE(DNS_ZONE_VALID(zone));
   17860 	REQUIRE(table != NULL);
   17861 	REQUIRE(*table == NULL);
   17862 
   17863 	LOCK_ZONE(zone);
   17864 	if (zone->ssutable != NULL) {
   17865 		dns_ssutable_attach(zone->ssutable, table);
   17866 	}
   17867 	UNLOCK_ZONE(zone);
   17868 }
   17869 
   17870 void
   17871 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
   17872 	REQUIRE(DNS_ZONE_VALID(zone));
   17873 
   17874 	LOCK_ZONE(zone);
   17875 	if (zone->ssutable != NULL) {
   17876 		dns_ssutable_detach(&zone->ssutable);
   17877 	}
   17878 	if (table != NULL) {
   17879 		dns_ssutable_attach(table, &zone->ssutable);
   17880 	}
   17881 	UNLOCK_ZONE(zone);
   17882 }
   17883 
   17884 void
   17885 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17886 	REQUIRE(DNS_ZONE_VALID(zone));
   17887 
   17888 	zone->sigvalidityinterval = interval;
   17889 }
   17890 
   17891 uint32_t
   17892 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
   17893 	REQUIRE(DNS_ZONE_VALID(zone));
   17894 
   17895 	return (zone->sigvalidityinterval);
   17896 }
   17897 
   17898 void
   17899 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17900 	REQUIRE(DNS_ZONE_VALID(zone));
   17901 
   17902 	zone->keyvalidityinterval = interval;
   17903 }
   17904 
   17905 uint32_t
   17906 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
   17907 	REQUIRE(DNS_ZONE_VALID(zone));
   17908 
   17909 	return (zone->keyvalidityinterval);
   17910 }
   17911 
   17912 void
   17913 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
   17914 	isc_time_t now;
   17915 
   17916 	REQUIRE(DNS_ZONE_VALID(zone));
   17917 
   17918 	LOCK_ZONE(zone);
   17919 	zone->sigresigninginterval = interval;
   17920 	set_resigntime(zone);
   17921 	if (zone->task != NULL) {
   17922 		TIME_NOW(&now);
   17923 		zone_settimer(zone, &now);
   17924 	}
   17925 	UNLOCK_ZONE(zone);
   17926 }
   17927 
   17928 uint32_t
   17929 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
   17930 	REQUIRE(DNS_ZONE_VALID(zone));
   17931 
   17932 	return (zone->sigresigninginterval);
   17933 }
   17934 
   17935 static void
   17936 queue_xfrin(dns_zone_t *zone) {
   17937 	const char me[] = "queue_xfrin";
   17938 	isc_result_t result;
   17939 	dns_zonemgr_t *zmgr = zone->zmgr;
   17940 
   17941 	ENTER;
   17942 
   17943 	INSIST(zone->statelist == NULL);
   17944 
   17945 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   17946 	ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
   17947 	isc_refcount_increment0(&zone->irefs);
   17948 	zone->statelist = &zmgr->waiting_for_xfrin;
   17949 	result = zmgr_start_xfrin_ifquota(zmgr, zone);
   17950 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   17951 
   17952 	if (result == ISC_R_QUOTA) {
   17953 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   17954 			      "zone transfer deferred due to quota");
   17955 	} else if (result != ISC_R_SUCCESS) {
   17956 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   17957 			      "starting zone transfer: %s",
   17958 			      isc_result_totext(result));
   17959 	}
   17960 }
   17961 
   17962 /*
   17963  * This event callback is called when a zone has received
   17964  * any necessary zone transfer quota.  This is the time
   17965  * to go ahead and start the transfer.
   17966  */
   17967 static void
   17968 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
   17969 	isc_result_t result = ISC_R_SUCCESS;
   17970 	dns_peer_t *peer = NULL;
   17971 	char master[ISC_SOCKADDR_FORMATSIZE];
   17972 	char source[ISC_SOCKADDR_FORMATSIZE];
   17973 	dns_rdatatype_t xfrtype;
   17974 	dns_zone_t *zone = event->ev_arg;
   17975 	isc_netaddr_t masterip;
   17976 	isc_sockaddr_t sourceaddr;
   17977 	isc_sockaddr_t masteraddr;
   17978 	isc_time_t now;
   17979 	const char *soa_before = "";
   17980 	isc_dscp_t dscp = -1;
   17981 	bool loaded;
   17982 
   17983 	UNUSED(task);
   17984 
   17985 	INSIST(task == zone->task);
   17986 
   17987 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   17988 		result = ISC_R_CANCELED;
   17989 		goto cleanup;
   17990 	}
   17991 
   17992 	TIME_NOW(&now);
   17993 
   17994 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   17995 	if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   17996 				    &zone->sourceaddr, &now))
   17997 	{
   17998 		isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   17999 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   18000 			      "got_transfer_quota: skipping zone transfer as "
   18001 			      "master %s (source %s) is unreachable (cached)",
   18002 			      master, source);
   18003 		result = ISC_R_CANCELED;
   18004 		goto cleanup;
   18005 	}
   18006 
   18007 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   18008 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   18009 
   18010 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   18011 		soa_before = "SOA before ";
   18012 	}
   18013 	/*
   18014 	 * Decide whether we should request IXFR or AXFR.
   18015 	 */
   18016 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   18017 	loaded = (zone->db != NULL);
   18018 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   18019 
   18020 	if (!loaded) {
   18021 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   18022 			      "no database exists yet, requesting AXFR of "
   18023 			      "initial version from %s",
   18024 			      master);
   18025 		xfrtype = dns_rdatatype_axfr;
   18026 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
   18027 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   18028 			      "forced reload, requesting AXFR of "
   18029 			      "initial version from %s",
   18030 			      master);
   18031 		xfrtype = dns_rdatatype_axfr;
   18032 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) {
   18033 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   18034 			      "retrying with AXFR from %s due to "
   18035 			      "previous IXFR failure",
   18036 			      master);
   18037 		xfrtype = dns_rdatatype_axfr;
   18038 		LOCK_ZONE(zone);
   18039 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR);
   18040 		UNLOCK_ZONE(zone);
   18041 	} else {
   18042 		bool use_ixfr = true;
   18043 		if (peer != NULL) {
   18044 			result = dns_peer_getrequestixfr(peer, &use_ixfr);
   18045 		}
   18046 		if (peer == NULL || result != ISC_R_SUCCESS) {
   18047 			use_ixfr = zone->requestixfr;
   18048 		}
   18049 		if (!use_ixfr) {
   18050 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   18051 				      ISC_LOG_DEBUG(1),
   18052 				      "IXFR disabled, "
   18053 				      "requesting %sAXFR from %s",
   18054 				      soa_before, master);
   18055 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   18056 				xfrtype = dns_rdatatype_soa;
   18057 			} else {
   18058 				xfrtype = dns_rdatatype_axfr;
   18059 			}
   18060 		} else {
   18061 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   18062 				      ISC_LOG_DEBUG(1),
   18063 				      "requesting IXFR from %s", master);
   18064 			xfrtype = dns_rdatatype_ixfr;
   18065 		}
   18066 	}
   18067 
   18068 	/*
   18069 	 * Determine if we should attempt to sign the request with TSIG.
   18070 	 */
   18071 	result = ISC_R_NOTFOUND;
   18072 
   18073 	/*
   18074 	 * First, look for a tsig key in the master statement, then
   18075 	 * try for a server key.
   18076 	 */
   18077 	if ((zone->masterkeynames != NULL) &&
   18078 	    (zone->masterkeynames[zone->curmaster] != NULL))
   18079 	{
   18080 		dns_view_t *view = dns_zone_getview(zone);
   18081 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   18082 		result = dns_view_gettsig(view, keyname, &zone->tsigkey);
   18083 	}
   18084 	if (zone->tsigkey == NULL) {
   18085 		result = dns_view_getpeertsig(zone->view, &masterip,
   18086 					      &zone->tsigkey);
   18087 	}
   18088 
   18089 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   18090 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   18091 			      "could not get TSIG key for zone transfer: %s",
   18092 			      isc_result_totext(result));
   18093 	}
   18094 
   18095 	if (zone->masterdscps != NULL) {
   18096 		dscp = zone->masterdscps[zone->curmaster];
   18097 	}
   18098 
   18099 	LOCK_ZONE(zone);
   18100 	masteraddr = zone->masteraddr;
   18101 	sourceaddr = zone->sourceaddr;
   18102 	switch (isc_sockaddr_pf(&masteraddr)) {
   18103 	case PF_INET:
   18104 		if (dscp == -1) {
   18105 			dscp = zone->xfrsource4dscp;
   18106 		}
   18107 		break;
   18108 	case PF_INET6:
   18109 		if (dscp == -1) {
   18110 			dscp = zone->xfrsource6dscp;
   18111 		}
   18112 		break;
   18113 	default:
   18114 		UNREACHABLE();
   18115 	}
   18116 	UNLOCK_ZONE(zone);
   18117 	INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
   18118 	result = dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr, dscp,
   18119 				  zone->tsigkey, zone->mctx,
   18120 				  zone->zmgr->timermgr, zone->zmgr->socketmgr,
   18121 				  zone->task, zone_xfrdone, &zone->xfr);
   18122 	if (result == ISC_R_SUCCESS) {
   18123 		LOCK_ZONE(zone);
   18124 		if (xfrtype == dns_rdatatype_axfr) {
   18125 			if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
   18126 				inc_stats(zone, dns_zonestatscounter_axfrreqv4);
   18127 			} else {
   18128 				inc_stats(zone, dns_zonestatscounter_axfrreqv6);
   18129 			}
   18130 		} else if (xfrtype == dns_rdatatype_ixfr) {
   18131 			if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
   18132 				inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
   18133 			} else {
   18134 				inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
   18135 			}
   18136 		}
   18137 		UNLOCK_ZONE(zone);
   18138 	}
   18139 cleanup:
   18140 	/*
   18141 	 * Any failure in this function is handled like a failed
   18142 	 * zone transfer.  This ensures that we get removed from
   18143 	 * zmgr->xfrin_in_progress.
   18144 	 */
   18145 	if (result != ISC_R_SUCCESS) {
   18146 		zone_xfrdone(zone, result);
   18147 	}
   18148 
   18149 	isc_event_free(&event);
   18150 }
   18151 
   18152 /*
   18153  * Update forwarding support.
   18154  */
   18155 
   18156 static void
   18157 forward_destroy(dns_forward_t *forward) {
   18158 	forward->magic = 0;
   18159 	if (forward->request != NULL) {
   18160 		dns_request_destroy(&forward->request);
   18161 	}
   18162 	if (forward->msgbuf != NULL) {
   18163 		isc_buffer_free(&forward->msgbuf);
   18164 	}
   18165 	if (forward->zone != NULL) {
   18166 		LOCK(&forward->zone->lock);
   18167 		if (ISC_LINK_LINKED(forward, link)) {
   18168 			ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
   18169 		}
   18170 		UNLOCK(&forward->zone->lock);
   18171 		dns_zone_idetach(&forward->zone);
   18172 	}
   18173 	isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
   18174 }
   18175 
   18176 static isc_result_t
   18177 sendtomaster(dns_forward_t *forward) {
   18178 	isc_result_t result;
   18179 	isc_sockaddr_t src;
   18180 	isc_dscp_t dscp = -1;
   18181 
   18182 	LOCK_ZONE(forward->zone);
   18183 
   18184 	if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
   18185 		UNLOCK_ZONE(forward->zone);
   18186 		return (ISC_R_CANCELED);
   18187 	}
   18188 
   18189 	if (forward->which >= forward->zone->masterscnt) {
   18190 		UNLOCK_ZONE(forward->zone);
   18191 		return (ISC_R_NOMORE);
   18192 	}
   18193 
   18194 	forward->addr = forward->zone->masters[forward->which];
   18195 	/*
   18196 	 * Always use TCP regardless of whether the original update
   18197 	 * used TCP.
   18198 	 * XXX The timeout may but a bit small if we are far down a
   18199 	 * transfer graph and the master has to try several masters.
   18200 	 */
   18201 	switch (isc_sockaddr_pf(&forward->addr)) {
   18202 	case PF_INET:
   18203 		src = forward->zone->xfrsource4;
   18204 		dscp = forward->zone->xfrsource4dscp;
   18205 		break;
   18206 	case PF_INET6:
   18207 		src = forward->zone->xfrsource6;
   18208 		dscp = forward->zone->xfrsource6dscp;
   18209 		break;
   18210 	default:
   18211 		result = ISC_R_NOTIMPLEMENTED;
   18212 		goto unlock;
   18213 	}
   18214 	result = dns_request_createraw(forward->zone->view->requestmgr,
   18215 				       forward->msgbuf, &src, &forward->addr,
   18216 				       dscp, forward->options, 15 /* XXX */, 0,
   18217 				       0, forward->zone->task, forward_callback,
   18218 				       forward, &forward->request);
   18219 	if (result == ISC_R_SUCCESS) {
   18220 		if (!ISC_LINK_LINKED(forward, link)) {
   18221 			ISC_LIST_APPEND(forward->zone->forwards, forward, link);
   18222 		}
   18223 	}
   18224 
   18225 unlock:
   18226 	UNLOCK_ZONE(forward->zone);
   18227 	return (result);
   18228 }
   18229 
   18230 static void
   18231 forward_callback(isc_task_t *task, isc_event_t *event) {
   18232 	const char me[] = "forward_callback";
   18233 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   18234 	dns_message_t *msg = NULL;
   18235 	char master[ISC_SOCKADDR_FORMATSIZE];
   18236 	isc_result_t result;
   18237 	dns_forward_t *forward;
   18238 	dns_zone_t *zone;
   18239 
   18240 	UNUSED(task);
   18241 
   18242 	forward = revent->ev_arg;
   18243 	INSIST(DNS_FORWARD_VALID(forward));
   18244 	zone = forward->zone;
   18245 	INSIST(DNS_ZONE_VALID(zone));
   18246 
   18247 	ENTER;
   18248 
   18249 	isc_sockaddr_format(&forward->addr, master, sizeof(master));
   18250 
   18251 	if (revent->result != ISC_R_SUCCESS) {
   18252 		dns_zone_log(zone, ISC_LOG_INFO,
   18253 			     "could not forward dynamic update to %s: %s",
   18254 			     master, dns_result_totext(revent->result));
   18255 		goto next_master;
   18256 	}
   18257 
   18258 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   18259 
   18260 	result = dns_request_getresponse(revent->request, msg,
   18261 					 DNS_MESSAGEPARSE_PRESERVEORDER |
   18262 						 DNS_MESSAGEPARSE_CLONEBUFFER);
   18263 	if (result != ISC_R_SUCCESS) {
   18264 		goto next_master;
   18265 	}
   18266 
   18267 	/*
   18268 	 * Unexpected opcode.
   18269 	 */
   18270 	if (msg->opcode != dns_opcode_update) {
   18271 		char opcode[128];
   18272 		isc_buffer_t rb;
   18273 
   18274 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   18275 		(void)dns_opcode_totext(msg->opcode, &rb);
   18276 
   18277 		dns_zone_log(zone, ISC_LOG_INFO,
   18278 			     "forwarding dynamic update: "
   18279 			     "unexpected opcode (%.*s) from %s",
   18280 			     (int)rb.used, opcode, master);
   18281 		goto next_master;
   18282 	}
   18283 
   18284 	switch (msg->rcode) {
   18285 	/*
   18286 	 * Pass these rcodes back to client.
   18287 	 */
   18288 	case dns_rcode_noerror:
   18289 	case dns_rcode_yxdomain:
   18290 	case dns_rcode_yxrrset:
   18291 	case dns_rcode_nxrrset:
   18292 	case dns_rcode_refused:
   18293 	case dns_rcode_nxdomain: {
   18294 		char rcode[128];
   18295 		isc_buffer_t rb;
   18296 
   18297 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   18298 		(void)dns_rcode_totext(msg->rcode, &rb);
   18299 		dns_zone_log(zone, ISC_LOG_INFO,
   18300 			     "forwarded dynamic update: "
   18301 			     "master %s returned: %.*s",
   18302 			     master, (int)rb.used, rcode);
   18303 		break;
   18304 	}
   18305 
   18306 	/* These should not occur if the primaries/zone are valid. */
   18307 	case dns_rcode_notzone:
   18308 	case dns_rcode_notauth: {
   18309 		char rcode[128];
   18310 		isc_buffer_t rb;
   18311 
   18312 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   18313 		(void)dns_rcode_totext(msg->rcode, &rb);
   18314 		dns_zone_log(zone, ISC_LOG_WARNING,
   18315 			     "forwarding dynamic update: "
   18316 			     "unexpected response: master %s returned: %.*s",
   18317 			     master, (int)rb.used, rcode);
   18318 		goto next_master;
   18319 	}
   18320 
   18321 	/* Try another server for these rcodes. */
   18322 	case dns_rcode_formerr:
   18323 	case dns_rcode_servfail:
   18324 	case dns_rcode_notimp:
   18325 	case dns_rcode_badvers:
   18326 	default:
   18327 		goto next_master;
   18328 	}
   18329 
   18330 	/* call callback */
   18331 	(forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
   18332 	msg = NULL;
   18333 	dns_request_destroy(&forward->request);
   18334 	forward_destroy(forward);
   18335 	isc_event_free(&event);
   18336 	return;
   18337 
   18338 next_master:
   18339 	if (msg != NULL) {
   18340 		dns_message_detach(&msg);
   18341 	}
   18342 	isc_event_free(&event);
   18343 	forward->which++;
   18344 	dns_request_destroy(&forward->request);
   18345 	result = sendtomaster(forward);
   18346 	if (result != ISC_R_SUCCESS) {
   18347 		/* call callback */
   18348 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   18349 			     "exhausted dynamic update forwarder list");
   18350 		(forward->callback)(forward->callback_arg, result, NULL);
   18351 		forward_destroy(forward);
   18352 	}
   18353 }
   18354 
   18355 isc_result_t
   18356 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
   18357 		       dns_updatecallback_t callback, void *callback_arg) {
   18358 	dns_forward_t *forward;
   18359 	isc_result_t result;
   18360 	isc_region_t *mr;
   18361 
   18362 	REQUIRE(DNS_ZONE_VALID(zone));
   18363 	REQUIRE(msg != NULL);
   18364 	REQUIRE(callback != NULL);
   18365 
   18366 	forward = isc_mem_get(zone->mctx, sizeof(*forward));
   18367 
   18368 	forward->request = NULL;
   18369 	forward->zone = NULL;
   18370 	forward->msgbuf = NULL;
   18371 	forward->which = 0;
   18372 	forward->mctx = 0;
   18373 	forward->callback = callback;
   18374 	forward->callback_arg = callback_arg;
   18375 	ISC_LINK_INIT(forward, link);
   18376 	forward->magic = FORWARD_MAGIC;
   18377 	forward->options = DNS_REQUESTOPT_TCP;
   18378 	/*
   18379 	 * If we have a SIG(0) signed message we need to preserve the
   18380 	 * query id as that is included in the SIG(0) computation.
   18381 	 */
   18382 	if (msg->sig0 != NULL) {
   18383 		forward->options |= DNS_REQUESTOPT_FIXEDID;
   18384 	}
   18385 
   18386 	mr = dns_message_getrawmessage(msg);
   18387 	if (mr == NULL) {
   18388 		result = ISC_R_UNEXPECTEDEND;
   18389 		goto cleanup;
   18390 	}
   18391 
   18392 	isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
   18393 	result = isc_buffer_copyregion(forward->msgbuf, mr);
   18394 	if (result != ISC_R_SUCCESS) {
   18395 		goto cleanup;
   18396 	}
   18397 
   18398 	isc_mem_attach(zone->mctx, &forward->mctx);
   18399 	dns_zone_iattach(zone, &forward->zone);
   18400 	result = sendtomaster(forward);
   18401 
   18402 cleanup:
   18403 	if (result != ISC_R_SUCCESS) {
   18404 		forward_destroy(forward);
   18405 	}
   18406 	return (result);
   18407 }
   18408 
   18409 isc_result_t
   18410 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
   18411 	REQUIRE(DNS_ZONE_VALID(zone));
   18412 	REQUIRE(next != NULL && *next == NULL);
   18413 
   18414 	*next = ISC_LIST_NEXT(zone, link);
   18415 	if (*next == NULL) {
   18416 		return (ISC_R_NOMORE);
   18417 	} else {
   18418 		return (ISC_R_SUCCESS);
   18419 	}
   18420 }
   18421 
   18422 isc_result_t
   18423 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
   18424 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18425 	REQUIRE(first != NULL && *first == NULL);
   18426 
   18427 	*first = ISC_LIST_HEAD(zmgr->zones);
   18428 	if (*first == NULL) {
   18429 		return (ISC_R_NOMORE);
   18430 	} else {
   18431 		return (ISC_R_SUCCESS);
   18432 	}
   18433 }
   18434 
   18435 /***
   18436  ***	Zone manager.
   18437  ***/
   18438 
   18439 #define KEYMGMT_OVERCOMMIT 3
   18440 #define KEYMGMT_BITS_MIN   2U
   18441 #define KEYMGMT_BITS_MAX   32U
   18442 
   18443 /*
   18444  * WMM: Static hash functions copied from lib/dns/rbtdb.c. Should be moved to
   18445  * lib/isc/hash.c when we refactor the hash table code.
   18446  */
   18447 #define GOLDEN_RATIO_32 0x61C88647
   18448 #define HASHSIZE(bits)	(UINT64_C(1) << (bits))
   18449 
   18450 static uint32_t
   18451 hash_index(uint32_t val, uint32_t bits) {
   18452 	return (val * GOLDEN_RATIO_32 >> (32 - bits));
   18453 }
   18454 
   18455 static uint32_t
   18456 hash_bits_grow(uint32_t bits, uint32_t count) {
   18457 	uint32_t newbits = bits;
   18458 	while (count >= HASHSIZE(newbits) && newbits < KEYMGMT_BITS_MAX) {
   18459 		newbits++;
   18460 	}
   18461 	return (newbits);
   18462 }
   18463 
   18464 static uint32_t
   18465 hash_bits_shrink(uint32_t bits, uint32_t count) {
   18466 	uint32_t newbits = bits;
   18467 	while (count <= HASHSIZE(newbits) && newbits > KEYMGMT_BITS_MIN) {
   18468 		newbits--;
   18469 	}
   18470 	return (newbits);
   18471 }
   18472 
   18473 static void
   18474 zonemgr_keymgmt_init(dns_zonemgr_t *zmgr) {
   18475 	dns_keymgmt_t *mgmt = isc_mem_get(zmgr->mctx, sizeof(*mgmt));
   18476 	uint32_t size;
   18477 
   18478 	*mgmt = (dns_keymgmt_t){
   18479 		.bits = KEYMGMT_BITS_MIN,
   18480 	};
   18481 	isc_mem_attach(zmgr->mctx, &mgmt->mctx);
   18482 	isc_rwlock_init(&mgmt->lock, 0, 0);
   18483 
   18484 	size = HASHSIZE(mgmt->bits);
   18485 	mgmt->table = isc_mem_get(mgmt->mctx, sizeof(*mgmt->table) * size);
   18486 	memset(mgmt->table, 0, size * sizeof(mgmt->table[0]));
   18487 
   18488 	atomic_init(&mgmt->count, 0);
   18489 	mgmt->magic = KEYMGMT_MAGIC;
   18490 
   18491 	zmgr->keymgmt = mgmt;
   18492 }
   18493 
   18494 static void
   18495 zonemgr_keymgmt_destroy(dns_zonemgr_t *zmgr) {
   18496 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18497 	uint32_t size;
   18498 
   18499 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18500 
   18501 	size = HASHSIZE(mgmt->bits);
   18502 
   18503 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18504 	INSIST(mgmt->count == 0);
   18505 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18506 
   18507 	mgmt->magic = 0;
   18508 	isc_rwlock_destroy(&mgmt->lock);
   18509 	isc_mem_put(mgmt->mctx, mgmt->table, size * sizeof(mgmt->table[0]));
   18510 	isc_mem_putanddetach(&mgmt->mctx, mgmt, sizeof(dns_keymgmt_t));
   18511 }
   18512 
   18513 static void
   18514 zonemgr_keymgmt_resize(dns_zonemgr_t *zmgr) {
   18515 	dns_keyfileio_t **newtable;
   18516 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18517 	uint32_t bits, newbits, count, size, newsize;
   18518 	bool grow;
   18519 
   18520 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18521 
   18522 	RWLOCK(&mgmt->lock, isc_rwlocktype_read);
   18523 	count = atomic_load_relaxed(&mgmt->count);
   18524 	bits = mgmt->bits;
   18525 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_read);
   18526 
   18527 	size = HASHSIZE(bits);
   18528 	INSIST(size > 0);
   18529 
   18530 	if (count >= (size * KEYMGMT_OVERCOMMIT)) {
   18531 		grow = true;
   18532 	} else if (count < (size / 2)) {
   18533 		grow = false;
   18534 	} else {
   18535 		/* No need to resize. */
   18536 		return;
   18537 	}
   18538 
   18539 	if (grow) {
   18540 		newbits = hash_bits_grow(bits, count);
   18541 	} else {
   18542 		newbits = hash_bits_shrink(bits, count);
   18543 	}
   18544 
   18545 	if (newbits == bits) {
   18546 		/*
   18547 		 * Bit values may stay the same if maximum or minimum is
   18548 		 * reached.
   18549 		 */
   18550 		return;
   18551 	}
   18552 
   18553 	newsize = HASHSIZE(newbits);
   18554 	INSIST(newsize > 0);
   18555 
   18556 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18557 
   18558 	newtable = isc_mem_get(mgmt->mctx, sizeof(dns_keyfileio_t *) * newsize);
   18559 	memset(newtable, 0, sizeof(dns_keyfileio_t *) * newsize);
   18560 
   18561 	for (unsigned int i = 0; i < size; i++) {
   18562 		dns_keyfileio_t *kfio, *next;
   18563 		for (kfio = mgmt->table[i]; kfio != NULL; kfio = next) {
   18564 			uint32_t hash = hash_index(kfio->hashval, newbits);
   18565 			next = kfio->next;
   18566 			kfio->next = newtable[hash];
   18567 			newtable[hash] = kfio;
   18568 		}
   18569 		mgmt->table[i] = NULL;
   18570 	}
   18571 
   18572 	isc_mem_put(mgmt->mctx, mgmt->table, sizeof(*mgmt->table) * size);
   18573 	mgmt->bits = newbits;
   18574 	mgmt->table = newtable;
   18575 
   18576 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18577 }
   18578 
   18579 static void
   18580 zonemgr_keymgmt_add(dns_zonemgr_t *zmgr, dns_zone_t *zone,
   18581 		    dns_keyfileio_t **added) {
   18582 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18583 	uint32_t hashval, hash;
   18584 	dns_keyfileio_t *kfio, *next;
   18585 
   18586 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18587 	REQUIRE(added != NULL && *added == NULL);
   18588 
   18589 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18590 
   18591 	hashval = dns_name_hash(&zone->origin, false);
   18592 	hash = hash_index(hashval, mgmt->bits);
   18593 
   18594 	for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) {
   18595 		next = kfio->next;
   18596 		if (dns_name_equal(kfio->name, &zone->origin)) {
   18597 			/* Already in table, increment the counter. */
   18598 			isc_refcount_increment(&kfio->references);
   18599 			break;
   18600 		}
   18601 	}
   18602 
   18603 	if (kfio == NULL) {
   18604 		/* No entry found, add it. */
   18605 		kfio = isc_mem_get(mgmt->mctx, sizeof(*kfio));
   18606 		*kfio = (dns_keyfileio_t){
   18607 			.hashval = hashval,
   18608 			.next = mgmt->table[hash],
   18609 			.magic = KEYFILEIO_MAGIC,
   18610 		};
   18611 
   18612 		isc_refcount_init(&kfio->references, 1);
   18613 
   18614 		kfio->name = dns_fixedname_initname(&kfio->fname);
   18615 		dns_name_copynf(&zone->origin, kfio->name);
   18616 
   18617 		isc_mutex_init(&kfio->lock);
   18618 
   18619 		mgmt->table[hash] = kfio;
   18620 
   18621 		atomic_fetch_add_relaxed(&mgmt->count, 1);
   18622 	}
   18623 
   18624 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18625 
   18626 	*added = kfio;
   18627 
   18628 	/*
   18629 	 * Call resize, that function will also check if resize is necessary.
   18630 	 */
   18631 	zonemgr_keymgmt_resize(zmgr);
   18632 }
   18633 
   18634 static void
   18635 zonemgr_keymgmt_delete(dns_zonemgr_t *zmgr, dns_zone_t *zone,
   18636 		       dns_keyfileio_t **deleted) {
   18637 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18638 	uint32_t hashval, hash;
   18639 	dns_keyfileio_t *kfio, *prev, *next;
   18640 
   18641 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18642 	REQUIRE(deleted != NULL && DNS_KEYFILEIO_VALID(*deleted));
   18643 
   18644 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18645 
   18646 	hashval = dns_name_hash(&zone->origin, false);
   18647 	hash = hash_index(hashval, mgmt->bits);
   18648 
   18649 	prev = NULL;
   18650 	for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) {
   18651 		next = kfio->next;
   18652 		if (dns_name_equal(kfio->name, &zone->origin)) {
   18653 			INSIST(kfio == *deleted);
   18654 			*deleted = NULL;
   18655 
   18656 			if (isc_refcount_decrement(&kfio->references) == 1) {
   18657 				if (prev == NULL) {
   18658 					mgmt->table[hash] = kfio->next;
   18659 				} else {
   18660 					prev->next = kfio->next;
   18661 				}
   18662 
   18663 				isc_refcount_destroy(&kfio->references);
   18664 				isc_mutex_destroy(&kfio->lock);
   18665 				isc_mem_put(mgmt->mctx, kfio, sizeof(*kfio));
   18666 
   18667 				atomic_fetch_sub_relaxed(&mgmt->count, 1);
   18668 			}
   18669 			break;
   18670 		}
   18671 
   18672 		prev = kfio;
   18673 	}
   18674 
   18675 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18676 
   18677 	/*
   18678 	 * Call resize, that function will also check if resize is necessary.
   18679 	 */
   18680 	zonemgr_keymgmt_resize(zmgr);
   18681 }
   18682 
   18683 isc_result_t
   18684 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
   18685 		   isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
   18686 		   dns_zonemgr_t **zmgrp) {
   18687 	dns_zonemgr_t *zmgr;
   18688 	isc_result_t result;
   18689 
   18690 	zmgr = isc_mem_get(mctx, sizeof(*zmgr));
   18691 	zmgr->mctx = NULL;
   18692 	isc_refcount_init(&zmgr->refs, 1);
   18693 	isc_mem_attach(mctx, &zmgr->mctx);
   18694 	zmgr->taskmgr = taskmgr;
   18695 	zmgr->timermgr = timermgr;
   18696 	zmgr->socketmgr = socketmgr;
   18697 	zmgr->zonetasks = NULL;
   18698 	zmgr->loadtasks = NULL;
   18699 	zmgr->mctxpool = NULL;
   18700 	zmgr->task = NULL;
   18701 	zmgr->checkdsrl = NULL;
   18702 	zmgr->notifyrl = NULL;
   18703 	zmgr->refreshrl = NULL;
   18704 	zmgr->startupnotifyrl = NULL;
   18705 	zmgr->startuprefreshrl = NULL;
   18706 	ISC_LIST_INIT(zmgr->zones);
   18707 	ISC_LIST_INIT(zmgr->waiting_for_xfrin);
   18708 	ISC_LIST_INIT(zmgr->xfrin_in_progress);
   18709 	memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
   18710 	for (size_t i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18711 		atomic_init(&zmgr->unreachable[i].expire, 0);
   18712 	}
   18713 	isc_rwlock_init(&zmgr->rwlock, 0, 0);
   18714 
   18715 	zmgr->transfersin = 10;
   18716 	zmgr->transfersperns = 2;
   18717 
   18718 	/* Unreachable lock. */
   18719 	isc_rwlock_init(&zmgr->urlock, 0, 0);
   18720 
   18721 	/* Create a single task for queueing of SOA queries. */
   18722 	result = isc_task_create(taskmgr, 1, &zmgr->task);
   18723 	if (result != ISC_R_SUCCESS) {
   18724 		goto free_urlock;
   18725 	}
   18726 
   18727 	isc_task_setname(zmgr->task, "zmgr", zmgr);
   18728 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18729 					&zmgr->checkdsrl);
   18730 	if (result != ISC_R_SUCCESS) {
   18731 		goto free_task;
   18732 	}
   18733 
   18734 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18735 					&zmgr->notifyrl);
   18736 	if (result != ISC_R_SUCCESS) {
   18737 		goto free_checkdsrl;
   18738 	}
   18739 
   18740 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18741 					&zmgr->refreshrl);
   18742 	if (result != ISC_R_SUCCESS) {
   18743 		goto free_notifyrl;
   18744 	}
   18745 
   18746 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18747 					&zmgr->startupnotifyrl);
   18748 	if (result != ISC_R_SUCCESS) {
   18749 		goto free_refreshrl;
   18750 	}
   18751 
   18752 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18753 					&zmgr->startuprefreshrl);
   18754 	if (result != ISC_R_SUCCESS) {
   18755 		goto free_startupnotifyrl;
   18756 	}
   18757 
   18758 	/* Key file I/O locks. */
   18759 	zonemgr_keymgmt_init(zmgr);
   18760 
   18761 	/* Default to 20 refresh queries / notifies / checkds per second. */
   18762 	setrl(zmgr->checkdsrl, &zmgr->checkdsrate, 20);
   18763 	setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
   18764 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
   18765 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
   18766 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
   18767 	isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true);
   18768 	isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true);
   18769 
   18770 	zmgr->iolimit = 1;
   18771 	zmgr->ioactive = 0;
   18772 	ISC_LIST_INIT(zmgr->high);
   18773 	ISC_LIST_INIT(zmgr->low);
   18774 
   18775 	isc_mutex_init(&zmgr->iolock);
   18776 
   18777 	zmgr->magic = ZONEMGR_MAGIC;
   18778 
   18779 	*zmgrp = zmgr;
   18780 	return (ISC_R_SUCCESS);
   18781 
   18782 #if 0
   18783  free_iolock:
   18784 	isc_mutex_destroy(&zmgr->iolock);
   18785 #endif /* if 0 */
   18786 free_startupnotifyrl:
   18787 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   18788 free_refreshrl:
   18789 	isc_ratelimiter_detach(&zmgr->refreshrl);
   18790 free_notifyrl:
   18791 	isc_ratelimiter_detach(&zmgr->notifyrl);
   18792 free_checkdsrl:
   18793 	isc_ratelimiter_detach(&zmgr->checkdsrl);
   18794 free_task:
   18795 	isc_task_detach(&zmgr->task);
   18796 free_urlock:
   18797 	isc_rwlock_destroy(&zmgr->urlock);
   18798 	isc_rwlock_destroy(&zmgr->rwlock);
   18799 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   18800 	isc_mem_detach(&mctx);
   18801 	return (result);
   18802 }
   18803 
   18804 isc_result_t
   18805 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
   18806 	isc_result_t result;
   18807 	isc_mem_t *mctx = NULL;
   18808 	dns_zone_t *zone = NULL;
   18809 	void *item;
   18810 
   18811 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18812 	REQUIRE(zonep != NULL && *zonep == NULL);
   18813 
   18814 	if (zmgr->mctxpool == NULL) {
   18815 		return (ISC_R_FAILURE);
   18816 	}
   18817 
   18818 	item = isc_pool_get(zmgr->mctxpool);
   18819 	if (item == NULL) {
   18820 		return (ISC_R_FAILURE);
   18821 	}
   18822 
   18823 	isc_mem_attach((isc_mem_t *)item, &mctx);
   18824 	result = dns_zone_create(&zone, mctx);
   18825 	isc_mem_detach(&mctx);
   18826 
   18827 	if (result == ISC_R_SUCCESS) {
   18828 		*zonep = zone;
   18829 	}
   18830 
   18831 	return (result);
   18832 }
   18833 
   18834 isc_result_t
   18835 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18836 	isc_result_t result;
   18837 
   18838 	REQUIRE(DNS_ZONE_VALID(zone));
   18839 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18840 
   18841 	if (zmgr->zonetasks == NULL) {
   18842 		return (ISC_R_FAILURE);
   18843 	}
   18844 
   18845 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18846 	LOCK_ZONE(zone);
   18847 	REQUIRE(zone->task == NULL);
   18848 	REQUIRE(zone->timer == NULL);
   18849 	REQUIRE(zone->zmgr == NULL);
   18850 
   18851 	isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
   18852 	isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
   18853 
   18854 	/*
   18855 	 * Set the task name.  The tag will arbitrarily point to one
   18856 	 * of the zones sharing the task (in practice, the one
   18857 	 * to be managed last).
   18858 	 */
   18859 	isc_task_setname(zone->task, "zone", zone);
   18860 	isc_task_setname(zone->loadtask, "loadzone", zone);
   18861 
   18862 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   18863 				  NULL, zone->task, zone_timer, zone,
   18864 				  &zone->timer);
   18865 
   18866 	if (result != ISC_R_SUCCESS) {
   18867 		goto cleanup_tasks;
   18868 	}
   18869 
   18870 	/*
   18871 	 * The timer "holds" a iref.
   18872 	 */
   18873 	isc_refcount_increment0(&zone->irefs);
   18874 
   18875 	zonemgr_keymgmt_add(zmgr, zone, &zone->kfio);
   18876 	INSIST(zone->kfio != NULL);
   18877 
   18878 	ISC_LIST_APPEND(zmgr->zones, zone, link);
   18879 	zone->zmgr = zmgr;
   18880 	isc_refcount_increment(&zmgr->refs);
   18881 
   18882 	goto unlock;
   18883 
   18884 cleanup_tasks:
   18885 	isc_task_detach(&zone->loadtask);
   18886 	isc_task_detach(&zone->task);
   18887 
   18888 unlock:
   18889 	UNLOCK_ZONE(zone);
   18890 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18891 	return (result);
   18892 }
   18893 
   18894 void
   18895 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18896 	REQUIRE(DNS_ZONE_VALID(zone));
   18897 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18898 	REQUIRE(zone->zmgr == zmgr);
   18899 
   18900 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18901 	LOCK_ZONE(zone);
   18902 
   18903 	ISC_LIST_UNLINK(zmgr->zones, zone, link);
   18904 
   18905 	if (zone->kfio != NULL) {
   18906 		zonemgr_keymgmt_delete(zmgr, zone, &zone->kfio);
   18907 		ENSURE(zone->kfio == NULL);
   18908 	}
   18909 
   18910 	/* Detach below, outside of the write lock. */
   18911 	zone->zmgr = NULL;
   18912 
   18913 	UNLOCK_ZONE(zone);
   18914 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18915 
   18916 	dns_zonemgr_detach(&zmgr);
   18917 }
   18918 
   18919 void
   18920 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
   18921 	REQUIRE(DNS_ZONEMGR_VALID(source));
   18922 	REQUIRE(target != NULL && *target == NULL);
   18923 
   18924 	isc_refcount_increment(&source->refs);
   18925 
   18926 	*target = source;
   18927 }
   18928 
   18929 void
   18930 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
   18931 	dns_zonemgr_t *zmgr;
   18932 
   18933 	REQUIRE(zmgrp != NULL);
   18934 	zmgr = *zmgrp;
   18935 	*zmgrp = NULL;
   18936 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18937 
   18938 	if (isc_refcount_decrement(&zmgr->refs) == 1) {
   18939 		zonemgr_free(zmgr);
   18940 	}
   18941 }
   18942 
   18943 isc_result_t
   18944 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
   18945 	dns_zone_t *p;
   18946 
   18947 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18948 
   18949 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18950 	for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL;
   18951 	     p = ISC_LIST_NEXT(p, link))
   18952 	{
   18953 		dns_zone_maintenance(p);
   18954 	}
   18955 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18956 
   18957 	/*
   18958 	 * Recent configuration changes may have increased the
   18959 	 * amount of available transfers quota.  Make sure any
   18960 	 * transfers currently blocked on quota get started if
   18961 	 * possible.
   18962 	 */
   18963 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18964 	zmgr_resume_xfrs(zmgr, true);
   18965 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18966 	return (ISC_R_SUCCESS);
   18967 }
   18968 
   18969 void
   18970 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
   18971 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18972 
   18973 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18974 	zmgr_resume_xfrs(zmgr, true);
   18975 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18976 }
   18977 
   18978 void
   18979 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
   18980 	dns_zone_t *zone;
   18981 
   18982 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18983 
   18984 	isc_ratelimiter_shutdown(zmgr->checkdsrl);
   18985 	isc_ratelimiter_shutdown(zmgr->notifyrl);
   18986 	isc_ratelimiter_shutdown(zmgr->refreshrl);
   18987 	isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
   18988 	isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
   18989 
   18990 	if (zmgr->task != NULL) {
   18991 		isc_task_destroy(&zmgr->task);
   18992 	}
   18993 	if (zmgr->zonetasks != NULL) {
   18994 		isc_taskpool_destroy(&zmgr->zonetasks);
   18995 	}
   18996 	if (zmgr->loadtasks != NULL) {
   18997 		isc_taskpool_destroy(&zmgr->loadtasks);
   18998 	}
   18999 	if (zmgr->mctxpool != NULL) {
   19000 		isc_pool_destroy(&zmgr->mctxpool);
   19001 	}
   19002 
   19003 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19004 	for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19005 	     zone = ISC_LIST_NEXT(zone, link))
   19006 	{
   19007 		LOCK_ZONE(zone);
   19008 		forward_cancel(zone);
   19009 		UNLOCK_ZONE(zone);
   19010 	}
   19011 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19012 }
   19013 
   19014 static isc_result_t
   19015 mctxinit(void **target, void *arg) {
   19016 	isc_mem_t *mctx = NULL;
   19017 
   19018 	UNUSED(arg);
   19019 
   19020 	REQUIRE(target != NULL && *target == NULL);
   19021 
   19022 	isc_mem_create(&mctx);
   19023 	isc_mem_setname(mctx, "zonemgr-pool", NULL);
   19024 
   19025 	*target = mctx;
   19026 	return (ISC_R_SUCCESS);
   19027 }
   19028 
   19029 static void
   19030 mctxfree(void **target) {
   19031 	isc_mem_t *mctx = *(isc_mem_t **)target;
   19032 	isc_mem_detach(&mctx);
   19033 	*target = NULL;
   19034 }
   19035 
   19036 #define ZONES_PER_TASK 100
   19037 #define ZONES_PER_MCTX 1000
   19038 
   19039 isc_result_t
   19040 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
   19041 	isc_result_t result;
   19042 	int ntasks = num_zones / ZONES_PER_TASK;
   19043 	int nmctx = num_zones / ZONES_PER_MCTX;
   19044 	isc_taskpool_t *pool = NULL;
   19045 	isc_pool_t *mctxpool = NULL;
   19046 
   19047 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19048 
   19049 	/*
   19050 	 * For anything fewer than 1000 zones we use 10 tasks in
   19051 	 * the task pools.  More than that, and we'll scale at one
   19052 	 * task per 100 zones.  Similarly, for anything smaller than
   19053 	 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
   19054 	 */
   19055 	if (ntasks < 10) {
   19056 		ntasks = 10;
   19057 	}
   19058 	if (nmctx < 2) {
   19059 		nmctx = 2;
   19060 	}
   19061 
   19062 	/* Create or resize the zone task pools. */
   19063 	if (zmgr->zonetasks == NULL) {
   19064 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   19065 					     2, false, &pool);
   19066 	} else {
   19067 		result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, false,
   19068 					     &pool);
   19069 	}
   19070 
   19071 	if (result == ISC_R_SUCCESS) {
   19072 		zmgr->zonetasks = pool;
   19073 	}
   19074 
   19075 	pool = NULL;
   19076 	if (zmgr->loadtasks == NULL) {
   19077 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   19078 					     2, true, &pool);
   19079 	} else {
   19080 		result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, true,
   19081 					     &pool);
   19082 	}
   19083 
   19084 	if (result == ISC_R_SUCCESS) {
   19085 		zmgr->loadtasks = pool;
   19086 	}
   19087 
   19088 	/* Create or resize the zone memory context pool. */
   19089 	if (zmgr->mctxpool == NULL) {
   19090 		result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit,
   19091 					 NULL, &mctxpool);
   19092 	} else {
   19093 		result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
   19094 	}
   19095 
   19096 	if (result == ISC_R_SUCCESS) {
   19097 		zmgr->mctxpool = mctxpool;
   19098 	}
   19099 
   19100 	return (result);
   19101 }
   19102 
   19103 static void
   19104 zonemgr_free(dns_zonemgr_t *zmgr) {
   19105 	isc_mem_t *mctx;
   19106 
   19107 	INSIST(ISC_LIST_EMPTY(zmgr->zones));
   19108 
   19109 	zmgr->magic = 0;
   19110 
   19111 	isc_refcount_destroy(&zmgr->refs);
   19112 	isc_mutex_destroy(&zmgr->iolock);
   19113 	isc_ratelimiter_detach(&zmgr->checkdsrl);
   19114 	isc_ratelimiter_detach(&zmgr->notifyrl);
   19115 	isc_ratelimiter_detach(&zmgr->refreshrl);
   19116 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   19117 	isc_ratelimiter_detach(&zmgr->startuprefreshrl);
   19118 
   19119 	isc_rwlock_destroy(&zmgr->urlock);
   19120 	isc_rwlock_destroy(&zmgr->rwlock);
   19121 
   19122 	zonemgr_keymgmt_destroy(zmgr);
   19123 
   19124 	mctx = zmgr->mctx;
   19125 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   19126 	isc_mem_detach(&mctx);
   19127 }
   19128 
   19129 void
   19130 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
   19131 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19132 
   19133 	zmgr->transfersin = value;
   19134 }
   19135 
   19136 uint32_t
   19137 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
   19138 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19139 
   19140 	return (zmgr->transfersin);
   19141 }
   19142 
   19143 void
   19144 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
   19145 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19146 
   19147 	zmgr->transfersperns = value;
   19148 }
   19149 
   19150 uint32_t
   19151 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
   19152 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19153 
   19154 	return (zmgr->transfersperns);
   19155 }
   19156 
   19157 isc_taskmgr_t *
   19158 dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr) {
   19159 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19160 
   19161 	return (zmgr->taskmgr);
   19162 }
   19163 
   19164 /*
   19165  * Try to start a new incoming zone transfer to fill a quota
   19166  * slot that was just vacated.
   19167  *
   19168  * Requires:
   19169  *	The zone manager is locked by the caller.
   19170  */
   19171 static void
   19172 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) {
   19173 	dns_zone_t *zone;
   19174 	dns_zone_t *next;
   19175 
   19176 	for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL;
   19177 	     zone = next)
   19178 	{
   19179 		isc_result_t result;
   19180 		next = ISC_LIST_NEXT(zone, statelink);
   19181 		result = zmgr_start_xfrin_ifquota(zmgr, zone);
   19182 		if (result == ISC_R_SUCCESS) {
   19183 			if (multi) {
   19184 				continue;
   19185 			}
   19186 			/*
   19187 			 * We successfully filled the slot.  We're done.
   19188 			 */
   19189 			break;
   19190 		} else if (result == ISC_R_QUOTA) {
   19191 			/*
   19192 			 * Not enough quota.  This is probably the per-server
   19193 			 * quota, because we usually get called when a unit of
   19194 			 * global quota has just been freed.  Try the next
   19195 			 * zone, it may succeed if it uses another master.
   19196 			 */
   19197 			continue;
   19198 		} else {
   19199 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   19200 				      ISC_LOG_DEBUG(1),
   19201 				      "starting zone transfer: %s",
   19202 				      isc_result_totext(result));
   19203 			break;
   19204 		}
   19205 	}
   19206 }
   19207 
   19208 /*
   19209  * Try to start an incoming zone transfer for 'zone', quota permitting.
   19210  *
   19211  * Requires:
   19212  *	The zone manager is locked by the caller.
   19213  *
   19214  * Returns:
   19215  *	ISC_R_SUCCESS	There was enough quota and we attempted to
   19216  *			start a transfer.  zone_xfrdone() has been or will
   19217  *			be called.
   19218  *	ISC_R_QUOTA	Not enough quota.
   19219  *	Others		Failure.
   19220  */
   19221 static isc_result_t
   19222 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   19223 	dns_peer_t *peer = NULL;
   19224 	isc_netaddr_t masterip;
   19225 	uint32_t nxfrsin, nxfrsperns;
   19226 	dns_zone_t *x;
   19227 	uint32_t maxtransfersin, maxtransfersperns;
   19228 	isc_event_t *e;
   19229 
   19230 	/*
   19231 	 * If we are exiting just pretend we got quota so the zone will
   19232 	 * be cleaned up in the zone's task context.
   19233 	 */
   19234 	LOCK_ZONE(zone);
   19235 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   19236 		UNLOCK_ZONE(zone);
   19237 		goto gotquota;
   19238 	}
   19239 
   19240 	/*
   19241 	 * Find any configured information about the server we'd
   19242 	 * like to transfer this zone from.
   19243 	 */
   19244 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   19245 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   19246 	UNLOCK_ZONE(zone);
   19247 
   19248 	/*
   19249 	 * Determine the total maximum number of simultaneous
   19250 	 * transfers allowed, and the maximum for this specific
   19251 	 * master.
   19252 	 */
   19253 	maxtransfersin = zmgr->transfersin;
   19254 	maxtransfersperns = zmgr->transfersperns;
   19255 	if (peer != NULL) {
   19256 		(void)dns_peer_gettransfers(peer, &maxtransfersperns);
   19257 	}
   19258 
   19259 	/*
   19260 	 * Count the total number of transfers that are in progress,
   19261 	 * and the number of transfers in progress from this master.
   19262 	 * We linearly scan a list of all transfers; if this turns
   19263 	 * out to be too slow, we could hash on the master address.
   19264 	 */
   19265 	nxfrsin = nxfrsperns = 0;
   19266 	for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL;
   19267 	     x = ISC_LIST_NEXT(x, statelink))
   19268 	{
   19269 		isc_netaddr_t xip;
   19270 
   19271 		LOCK_ZONE(x);
   19272 		isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
   19273 		UNLOCK_ZONE(x);
   19274 
   19275 		nxfrsin++;
   19276 		if (isc_netaddr_equal(&xip, &masterip)) {
   19277 			nxfrsperns++;
   19278 		}
   19279 	}
   19280 
   19281 	/* Enforce quota. */
   19282 	if (nxfrsin >= maxtransfersin) {
   19283 		return (ISC_R_QUOTA);
   19284 	}
   19285 
   19286 	if (nxfrsperns >= maxtransfersperns) {
   19287 		return (ISC_R_QUOTA);
   19288 	}
   19289 
   19290 gotquota:
   19291 	/*
   19292 	 * We have sufficient quota.  Move the zone to the "xfrin_in_progress"
   19293 	 * list and send it an event to let it start the actual transfer in the
   19294 	 * context of its own task.
   19295 	 */
   19296 	e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
   19297 			       got_transfer_quota, zone, sizeof(isc_event_t));
   19298 
   19299 	LOCK_ZONE(zone);
   19300 	INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
   19301 	ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
   19302 	ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
   19303 	zone->statelist = &zmgr->xfrin_in_progress;
   19304 	isc_task_send(zone->task, &e);
   19305 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   19306 		      "Transfer started.");
   19307 	UNLOCK_ZONE(zone);
   19308 
   19309 	return (ISC_R_SUCCESS);
   19310 }
   19311 
   19312 void
   19313 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) {
   19314 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19315 	REQUIRE(iolimit > 0);
   19316 
   19317 	zmgr->iolimit = iolimit;
   19318 }
   19319 
   19320 uint32_t
   19321 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
   19322 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19323 
   19324 	return (zmgr->iolimit);
   19325 }
   19326 
   19327 /*
   19328  * Get permission to request a file handle from the OS.
   19329  * An event will be sent to action when one is available.
   19330  * There are two queues available (high and low), the high
   19331  * queue will be serviced before the low one.
   19332  *
   19333  * zonemgr_putio() must be called after the event is delivered to
   19334  * 'action'.
   19335  */
   19336 
   19337 static isc_result_t
   19338 zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task,
   19339 	      isc_taskaction_t action, void *arg, dns_io_t **iop) {
   19340 	dns_io_t *io;
   19341 	bool queue;
   19342 
   19343 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19344 	REQUIRE(iop != NULL && *iop == NULL);
   19345 
   19346 	io = isc_mem_get(zmgr->mctx, sizeof(*io));
   19347 
   19348 	io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
   19349 				       action, arg, sizeof(*io->event));
   19350 
   19351 	io->zmgr = zmgr;
   19352 	io->high = high;
   19353 	io->task = NULL;
   19354 	isc_task_attach(task, &io->task);
   19355 	ISC_LINK_INIT(io, link);
   19356 	io->magic = IO_MAGIC;
   19357 
   19358 	LOCK(&zmgr->iolock);
   19359 	zmgr->ioactive++;
   19360 	queue = (zmgr->ioactive > zmgr->iolimit);
   19361 	if (queue) {
   19362 		if (io->high) {
   19363 			ISC_LIST_APPEND(zmgr->high, io, link);
   19364 		} else {
   19365 			ISC_LIST_APPEND(zmgr->low, io, link);
   19366 		}
   19367 	}
   19368 	UNLOCK(&zmgr->iolock);
   19369 	*iop = io;
   19370 
   19371 	if (!queue) {
   19372 		isc_task_send(io->task, &io->event);
   19373 	}
   19374 	return (ISC_R_SUCCESS);
   19375 }
   19376 
   19377 static void
   19378 zonemgr_putio(dns_io_t **iop) {
   19379 	dns_io_t *io;
   19380 	dns_io_t *next;
   19381 	dns_zonemgr_t *zmgr;
   19382 
   19383 	REQUIRE(iop != NULL);
   19384 	io = *iop;
   19385 	*iop = NULL;
   19386 	REQUIRE(DNS_IO_VALID(io));
   19387 
   19388 	INSIST(!ISC_LINK_LINKED(io, link));
   19389 	INSIST(io->event == NULL);
   19390 
   19391 	zmgr = io->zmgr;
   19392 	isc_task_detach(&io->task);
   19393 	io->magic = 0;
   19394 	isc_mem_put(zmgr->mctx, io, sizeof(*io));
   19395 
   19396 	LOCK(&zmgr->iolock);
   19397 	INSIST(zmgr->ioactive > 0);
   19398 	zmgr->ioactive--;
   19399 	next = HEAD(zmgr->high);
   19400 	if (next == NULL) {
   19401 		next = HEAD(zmgr->low);
   19402 	}
   19403 	if (next != NULL) {
   19404 		if (next->high) {
   19405 			ISC_LIST_UNLINK(zmgr->high, next, link);
   19406 		} else {
   19407 			ISC_LIST_UNLINK(zmgr->low, next, link);
   19408 		}
   19409 		INSIST(next->event != NULL);
   19410 	}
   19411 	UNLOCK(&zmgr->iolock);
   19412 	if (next != NULL) {
   19413 		isc_task_send(next->task, &next->event);
   19414 	}
   19415 }
   19416 
   19417 static void
   19418 zonemgr_cancelio(dns_io_t *io) {
   19419 	bool send_event = false;
   19420 
   19421 	REQUIRE(DNS_IO_VALID(io));
   19422 
   19423 	/*
   19424 	 * If we are queued to be run then dequeue.
   19425 	 */
   19426 	LOCK(&io->zmgr->iolock);
   19427 	if (ISC_LINK_LINKED(io, link)) {
   19428 		if (io->high) {
   19429 			ISC_LIST_UNLINK(io->zmgr->high, io, link);
   19430 		} else {
   19431 			ISC_LIST_UNLINK(io->zmgr->low, io, link);
   19432 		}
   19433 
   19434 		send_event = true;
   19435 		INSIST(io->event != NULL);
   19436 	}
   19437 	UNLOCK(&io->zmgr->iolock);
   19438 	if (send_event) {
   19439 		io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
   19440 		isc_task_send(io->task, &io->event);
   19441 	}
   19442 }
   19443 
   19444 static void
   19445 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
   19446 	char *buf;
   19447 	int buflen;
   19448 	isc_result_t result;
   19449 
   19450 	buflen = strlen(path) + strlen(templat) + 2;
   19451 
   19452 	buf = isc_mem_get(zone->mctx, buflen);
   19453 
   19454 	result = isc_file_template(path, templat, buf, buflen);
   19455 	if (result != ISC_R_SUCCESS) {
   19456 		goto cleanup;
   19457 	}
   19458 
   19459 	result = isc_file_renameunique(path, buf);
   19460 	if (result != ISC_R_SUCCESS) {
   19461 		goto cleanup;
   19462 	}
   19463 
   19464 	dns_zone_log(zone, ISC_LOG_WARNING,
   19465 		     "unable to load from '%s'; "
   19466 		     "renaming file to '%s' for failure analysis and "
   19467 		     "retransferring.",
   19468 		     path, buf);
   19469 
   19470 cleanup:
   19471 	isc_mem_put(zone->mctx, buf, buflen);
   19472 }
   19473 
   19474 static void
   19475 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
   19476 	isc_interval_t interval;
   19477 	uint32_t s, ns;
   19478 	uint32_t pertic;
   19479 	isc_result_t result;
   19480 
   19481 	if (value == 0) {
   19482 		value = 1;
   19483 	}
   19484 
   19485 	if (value == 1) {
   19486 		s = 1;
   19487 		ns = 0;
   19488 		pertic = 1;
   19489 	} else if (value <= 10) {
   19490 		s = 0;
   19491 		ns = 1000000000 / value;
   19492 		pertic = 1;
   19493 	} else {
   19494 		s = 0;
   19495 		ns = (1000000000 / value) * 10;
   19496 		pertic = 10;
   19497 	}
   19498 
   19499 	isc_interval_set(&interval, s, ns);
   19500 
   19501 	result = isc_ratelimiter_setinterval(rl, &interval);
   19502 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19503 	isc_ratelimiter_setpertic(rl, pertic);
   19504 
   19505 	*rate = value;
   19506 }
   19507 
   19508 void
   19509 dns_zonemgr_setcheckdsrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19510 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19511 
   19512 	setrl(zmgr->checkdsrl, &zmgr->checkdsrate, value);
   19513 }
   19514 
   19515 void
   19516 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19517 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19518 
   19519 	setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
   19520 }
   19521 
   19522 void
   19523 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19524 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19525 
   19526 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
   19527 }
   19528 
   19529 void
   19530 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19531 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19532 
   19533 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
   19534 	/* XXXMPA separate out once we have the code to support this. */
   19535 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
   19536 }
   19537 
   19538 unsigned int
   19539 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
   19540 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19541 
   19542 	return (zmgr->notifyrate);
   19543 }
   19544 
   19545 unsigned int
   19546 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
   19547 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19548 
   19549 	return (zmgr->startupnotifyrate);
   19550 }
   19551 
   19552 unsigned int
   19553 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
   19554 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19555 
   19556 	return (zmgr->serialqueryrate);
   19557 }
   19558 
   19559 bool
   19560 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   19561 			isc_sockaddr_t *local, isc_time_t *now) {
   19562 	unsigned int i;
   19563 	uint32_t seconds = isc_time_seconds(now);
   19564 	uint32_t count = 0;
   19565 
   19566 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19567 
   19568 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19569 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   19570 		if (atomic_load(&zmgr->unreachable[i].expire) >= seconds &&
   19571 		    isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   19572 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   19573 		{
   19574 			atomic_store_relaxed(&zmgr->unreachable[i].last,
   19575 					     seconds);
   19576 			count = zmgr->unreachable[i].count;
   19577 			break;
   19578 		}
   19579 	}
   19580 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19581 	return (i < UNREACH_CACHE_SIZE && count > 1U);
   19582 }
   19583 
   19584 void
   19585 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   19586 			   isc_sockaddr_t *local) {
   19587 	unsigned int i;
   19588 	char master[ISC_SOCKADDR_FORMATSIZE];
   19589 	char source[ISC_SOCKADDR_FORMATSIZE];
   19590 
   19591 	isc_sockaddr_format(remote, master, sizeof(master));
   19592 	isc_sockaddr_format(local, source, sizeof(source));
   19593 
   19594 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19595 
   19596 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19597 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   19598 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   19599 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   19600 		{
   19601 			atomic_store_relaxed(&zmgr->unreachable[i].expire, 0);
   19602 			break;
   19603 		}
   19604 	}
   19605 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19606 }
   19607 
   19608 void
   19609 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   19610 			   isc_sockaddr_t *local, isc_time_t *now) {
   19611 	uint32_t seconds = isc_time_seconds(now);
   19612 	uint32_t expire = 0, last = seconds;
   19613 	unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0;
   19614 	bool update_entry = true;
   19615 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19616 
   19617 	RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
   19618 	for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) {
   19619 		/* Existing entry? */
   19620 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   19621 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   19622 		{
   19623 			update_entry = false;
   19624 			slot = i;
   19625 			expire = atomic_load_relaxed(
   19626 				&zmgr->unreachable[i].expire);
   19627 			break;
   19628 		}
   19629 		/* Pick first empty slot? */
   19630 		if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds)
   19631 		{
   19632 			slot = i;
   19633 			break;
   19634 		}
   19635 		/* The worst case, least recently used slot? */
   19636 		if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) {
   19637 			last = atomic_load_relaxed(&zmgr->unreachable[i].last);
   19638 			oldest = i;
   19639 		}
   19640 	}
   19641 
   19642 	/* We haven't found any existing or free slots, use the oldest */
   19643 	if (slot == UNREACH_CACHE_SIZE) {
   19644 		slot = oldest;
   19645 	}
   19646 
   19647 	if (expire < seconds) {
   19648 		/* Expired or new entry, reset count to 1 */
   19649 		zmgr->unreachable[slot].count = 1;
   19650 	} else {
   19651 		zmgr->unreachable[slot].count++;
   19652 	}
   19653 	atomic_store_relaxed(&zmgr->unreachable[slot].expire,
   19654 			     seconds + UNREACH_HOLD_TIME);
   19655 	atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds);
   19656 	if (update_entry) {
   19657 		zmgr->unreachable[slot].remote = *remote;
   19658 		zmgr->unreachable[slot].local = *local;
   19659 	}
   19660 
   19661 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
   19662 }
   19663 
   19664 void
   19665 dns_zone_forcereload(dns_zone_t *zone) {
   19666 	REQUIRE(DNS_ZONE_VALID(zone));
   19667 
   19668 	if (zone->type == dns_zone_primary ||
   19669 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   19670 	{
   19671 		return;
   19672 	}
   19673 
   19674 	LOCK_ZONE(zone);
   19675 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   19676 	UNLOCK_ZONE(zone);
   19677 	dns_zone_refresh(zone);
   19678 }
   19679 
   19680 bool
   19681 dns_zone_isforced(dns_zone_t *zone) {
   19682 	REQUIRE(DNS_ZONE_VALID(zone));
   19683 
   19684 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
   19685 }
   19686 
   19687 isc_result_t
   19688 dns_zone_setstatistics(dns_zone_t *zone, bool on) {
   19689 	/*
   19690 	 * This function is obsoleted.
   19691 	 */
   19692 	UNUSED(zone);
   19693 	UNUSED(on);
   19694 	return (ISC_R_NOTIMPLEMENTED);
   19695 }
   19696 
   19697 uint64_t *
   19698 dns_zone_getstatscounters(dns_zone_t *zone) {
   19699 	/*
   19700 	 * This function is obsoleted.
   19701 	 */
   19702 	UNUSED(zone);
   19703 	return (NULL);
   19704 }
   19705 
   19706 void
   19707 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
   19708 	REQUIRE(DNS_ZONE_VALID(zone));
   19709 	REQUIRE(zone->stats == NULL);
   19710 
   19711 	LOCK_ZONE(zone);
   19712 	zone->stats = NULL;
   19713 	isc_stats_attach(stats, &zone->stats);
   19714 	UNLOCK_ZONE(zone);
   19715 }
   19716 
   19717 void
   19718 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
   19719 	REQUIRE(DNS_ZONE_VALID(zone));
   19720 
   19721 	LOCK_ZONE(zone);
   19722 	if (zone->requeststats_on && stats == NULL) {
   19723 		zone->requeststats_on = false;
   19724 	} else if (!zone->requeststats_on && stats != NULL) {
   19725 		if (zone->requeststats == NULL) {
   19726 			isc_stats_attach(stats, &zone->requeststats);
   19727 		}
   19728 		zone->requeststats_on = true;
   19729 	}
   19730 	UNLOCK_ZONE(zone);
   19731 }
   19732 
   19733 void
   19734 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
   19735 	REQUIRE(DNS_ZONE_VALID(zone));
   19736 
   19737 	LOCK_ZONE(zone);
   19738 	if (zone->requeststats_on && stats != NULL) {
   19739 		if (zone->rcvquerystats == NULL) {
   19740 			dns_stats_attach(stats, &zone->rcvquerystats);
   19741 			zone->requeststats_on = true;
   19742 		}
   19743 	}
   19744 	UNLOCK_ZONE(zone);
   19745 }
   19746 
   19747 void
   19748 dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
   19749 	REQUIRE(DNS_ZONE_VALID(zone));
   19750 
   19751 	LOCK_ZONE(zone);
   19752 	if (stats != NULL && zone->dnssecsignstats == NULL) {
   19753 		dns_stats_attach(stats, &zone->dnssecsignstats);
   19754 	}
   19755 	UNLOCK_ZONE(zone);
   19756 }
   19757 
   19758 dns_stats_t *
   19759 dns_zone_getdnssecsignstats(dns_zone_t *zone) {
   19760 	REQUIRE(DNS_ZONE_VALID(zone));
   19761 
   19762 	return (zone->dnssecsignstats);
   19763 }
   19764 
   19765 isc_stats_t *
   19766 dns_zone_getrequeststats(dns_zone_t *zone) {
   19767 	/*
   19768 	 * We don't lock zone for efficiency reason.  This is not catastrophic
   19769 	 * because requeststats must always be valid when requeststats_on is
   19770 	 * true.
   19771 	 * Some counters may be incremented while requeststats_on is becoming
   19772 	 * false, or some cannot be incremented just after the statistics are
   19773 	 * installed, but it shouldn't matter much in practice.
   19774 	 */
   19775 	if (zone->requeststats_on) {
   19776 		return (zone->requeststats);
   19777 	} else {
   19778 		return (NULL);
   19779 	}
   19780 }
   19781 
   19782 /*
   19783  * Return the received query stats bucket
   19784  * see note from dns_zone_getrequeststats()
   19785  */
   19786 dns_stats_t *
   19787 dns_zone_getrcvquerystats(dns_zone_t *zone) {
   19788 	if (zone->requeststats_on) {
   19789 		return (zone->rcvquerystats);
   19790 	} else {
   19791 		return (NULL);
   19792 	}
   19793 }
   19794 
   19795 void
   19796 dns_zone_dialup(dns_zone_t *zone) {
   19797 	REQUIRE(DNS_ZONE_VALID(zone));
   19798 
   19799 	zone_debuglog(zone, "dns_zone_dialup", 3, "notify = %d, refresh = %d",
   19800 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
   19801 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
   19802 
   19803 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   19804 		dns_zone_notify(zone);
   19805 	}
   19806 	if (zone->type != dns_zone_primary && zone->masters != NULL &&
   19807 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
   19808 	{
   19809 		dns_zone_refresh(zone);
   19810 	}
   19811 }
   19812 
   19813 void
   19814 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
   19815 	REQUIRE(DNS_ZONE_VALID(zone));
   19816 
   19817 	LOCK_ZONE(zone);
   19818 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
   19819 				       DNS_ZONEFLG_DIALREFRESH |
   19820 				       DNS_ZONEFLG_NOREFRESH);
   19821 	switch (dialup) {
   19822 	case dns_dialuptype_no:
   19823 		break;
   19824 	case dns_dialuptype_yes:
   19825 		DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
   19826 					DNS_ZONEFLG_DIALREFRESH |
   19827 					DNS_ZONEFLG_NOREFRESH));
   19828 		break;
   19829 	case dns_dialuptype_notify:
   19830 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19831 		break;
   19832 	case dns_dialuptype_notifypassive:
   19833 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19834 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19835 		break;
   19836 	case dns_dialuptype_refresh:
   19837 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
   19838 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19839 		break;
   19840 	case dns_dialuptype_passive:
   19841 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19842 		break;
   19843 	default:
   19844 		UNREACHABLE();
   19845 	}
   19846 	UNLOCK_ZONE(zone);
   19847 }
   19848 
   19849 isc_result_t
   19850 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
   19851 	isc_result_t result = ISC_R_SUCCESS;
   19852 
   19853 	REQUIRE(DNS_ZONE_VALID(zone));
   19854 
   19855 	LOCK_ZONE(zone);
   19856 	result = dns_zone_setstring(zone, &zone->keydirectory, directory);
   19857 	UNLOCK_ZONE(zone);
   19858 
   19859 	return (result);
   19860 }
   19861 
   19862 const char *
   19863 dns_zone_getkeydirectory(dns_zone_t *zone) {
   19864 	REQUIRE(DNS_ZONE_VALID(zone));
   19865 
   19866 	return (zone->keydirectory);
   19867 }
   19868 
   19869 unsigned int
   19870 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
   19871 	dns_zone_t *zone;
   19872 	unsigned int count = 0;
   19873 
   19874 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19875 
   19876 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19877 	switch (state) {
   19878 	case DNS_ZONESTATE_XFERRUNNING:
   19879 		for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
   19880 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19881 		{
   19882 			count++;
   19883 		}
   19884 		break;
   19885 	case DNS_ZONESTATE_XFERDEFERRED:
   19886 		for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
   19887 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19888 		{
   19889 			count++;
   19890 		}
   19891 		break;
   19892 	case DNS_ZONESTATE_SOAQUERY:
   19893 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19894 		     zone = ISC_LIST_NEXT(zone, link))
   19895 		{
   19896 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   19897 				count++;
   19898 			}
   19899 		}
   19900 		break;
   19901 	case DNS_ZONESTATE_ANY:
   19902 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19903 		     zone = ISC_LIST_NEXT(zone, link))
   19904 		{
   19905 			dns_view_t *view = zone->view;
   19906 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   19907 				continue;
   19908 			}
   19909 			count++;
   19910 		}
   19911 		break;
   19912 	case DNS_ZONESTATE_AUTOMATIC:
   19913 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19914 		     zone = ISC_LIST_NEXT(zone, link))
   19915 		{
   19916 			dns_view_t *view = zone->view;
   19917 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   19918 				continue;
   19919 			}
   19920 			if (zone->automatic) {
   19921 				count++;
   19922 			}
   19923 		}
   19924 		break;
   19925 	default:
   19926 		UNREACHABLE();
   19927 	}
   19928 
   19929 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19930 
   19931 	return (count);
   19932 }
   19933 
   19934 void
   19935 dns_zone_lock_keyfiles(dns_zone_t *zone) {
   19936 	REQUIRE(DNS_ZONE_VALID(zone));
   19937 
   19938 	if (zone->kasp == NULL) {
   19939 		/* No need to lock, nothing is writing key files. */
   19940 		return;
   19941 	}
   19942 
   19943 	REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio));
   19944 	isc_mutex_lock(&zone->kfio->lock);
   19945 }
   19946 
   19947 void
   19948 dns_zone_unlock_keyfiles(dns_zone_t *zone) {
   19949 	REQUIRE(DNS_ZONE_VALID(zone));
   19950 
   19951 	if (zone->kasp == NULL) {
   19952 		/* No need to lock, nothing is writing key files. */
   19953 		return;
   19954 	}
   19955 
   19956 	REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio));
   19957 	isc_mutex_unlock(&zone->kfio->lock);
   19958 }
   19959 
   19960 isc_result_t
   19961 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
   19962 		    dns_rdata_t *rdata) {
   19963 	bool ok = true;
   19964 	bool fail = false;
   19965 	char namebuf[DNS_NAME_FORMATSIZE];
   19966 	char namebuf2[DNS_NAME_FORMATSIZE];
   19967 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   19968 	int level = ISC_LOG_WARNING;
   19969 	dns_name_t bad;
   19970 
   19971 	REQUIRE(DNS_ZONE_VALID(zone));
   19972 
   19973 	if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
   19974 	    rdata->type != dns_rdatatype_nsec3)
   19975 	{
   19976 		return (ISC_R_SUCCESS);
   19977 	}
   19978 
   19979 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
   19980 	    rdata->type == dns_rdatatype_nsec3)
   19981 	{
   19982 		level = ISC_LOG_ERROR;
   19983 		fail = true;
   19984 	}
   19985 
   19986 	ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true);
   19987 	if (!ok) {
   19988 		dns_name_format(name, namebuf, sizeof(namebuf));
   19989 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   19990 		dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
   19991 			     dns_result_totext(DNS_R_BADOWNERNAME));
   19992 		if (fail) {
   19993 			return (DNS_R_BADOWNERNAME);
   19994 		}
   19995 	}
   19996 
   19997 	dns_name_init(&bad, NULL);
   19998 	ok = dns_rdata_checknames(rdata, name, &bad);
   19999 	if (!ok) {
   20000 		dns_name_format(name, namebuf, sizeof(namebuf));
   20001 		dns_name_format(&bad, namebuf2, sizeof(namebuf2));
   20002 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   20003 		dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
   20004 			     namebuf2, dns_result_totext(DNS_R_BADNAME));
   20005 		if (fail) {
   20006 			return (DNS_R_BADNAME);
   20007 		}
   20008 	}
   20009 
   20010 	return (ISC_R_SUCCESS);
   20011 }
   20012 
   20013 void
   20014 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
   20015 	REQUIRE(DNS_ZONE_VALID(zone));
   20016 	zone->checkmx = checkmx;
   20017 }
   20018 
   20019 void
   20020 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
   20021 	REQUIRE(DNS_ZONE_VALID(zone));
   20022 	zone->checksrv = checksrv;
   20023 }
   20024 
   20025 void
   20026 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
   20027 	REQUIRE(DNS_ZONE_VALID(zone));
   20028 	zone->checkns = checkns;
   20029 }
   20030 
   20031 void
   20032 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
   20033 	REQUIRE(DNS_ZONE_VALID(zone));
   20034 
   20035 	LOCK_ZONE(zone);
   20036 	zone->isself = isself;
   20037 	zone->isselfarg = arg;
   20038 	UNLOCK_ZONE(zone);
   20039 }
   20040 
   20041 void
   20042 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
   20043 	REQUIRE(DNS_ZONE_VALID(zone));
   20044 
   20045 	LOCK_ZONE(zone);
   20046 	zone->notifydelay = delay;
   20047 	UNLOCK_ZONE(zone);
   20048 }
   20049 
   20050 uint32_t
   20051 dns_zone_getnotifydelay(dns_zone_t *zone) {
   20052 	REQUIRE(DNS_ZONE_VALID(zone));
   20053 
   20054 	return (zone->notifydelay);
   20055 }
   20056 
   20057 isc_result_t
   20058 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   20059 		     bool deleteit) {
   20060 	isc_result_t result;
   20061 	REQUIRE(DNS_ZONE_VALID(zone));
   20062 
   20063 	dnssec_log(zone, ISC_LOG_NOTICE,
   20064 		   "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm,
   20065 		   keyid);
   20066 	LOCK_ZONE(zone);
   20067 	result = zone_signwithkey(zone, algorithm, keyid, deleteit);
   20068 	UNLOCK_ZONE(zone);
   20069 
   20070 	return (result);
   20071 }
   20072 
   20073 /*
   20074  * Called when a dynamic update for an NSEC3PARAM record is received.
   20075  *
   20076  * If set, transform the NSEC3 salt into human-readable form so that it can be
   20077  * logged.  Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it.
   20078  */
   20079 isc_result_t
   20080 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   20081 	isc_result_t result;
   20082 	char salt[255 * 2 + 1];
   20083 
   20084 	REQUIRE(DNS_ZONE_VALID(zone));
   20085 
   20086 	result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
   20087 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20088 	dnssec_log(zone, ISC_LOG_NOTICE,
   20089 		   "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
   20090 		   nsec3param->hash, nsec3param->iterations, salt);
   20091 	LOCK_ZONE(zone);
   20092 	result = zone_addnsec3chain(zone, nsec3param);
   20093 	UNLOCK_ZONE(zone);
   20094 
   20095 	return (result);
   20096 }
   20097 
   20098 void
   20099 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
   20100 	REQUIRE(DNS_ZONE_VALID(zone));
   20101 
   20102 	if (nodes == 0) {
   20103 		nodes = 1;
   20104 	}
   20105 	zone->nodes = nodes;
   20106 }
   20107 
   20108 void
   20109 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
   20110 	REQUIRE(DNS_ZONE_VALID(zone));
   20111 
   20112 	/*
   20113 	 * We treat signatures as a signed value so explicitly
   20114 	 * limit its range here.
   20115 	 */
   20116 	if (signatures > INT32_MAX) {
   20117 		signatures = INT32_MAX;
   20118 	} else if (signatures == 0) {
   20119 		signatures = 1;
   20120 	}
   20121 	zone->signatures = signatures;
   20122 }
   20123 
   20124 uint32_t
   20125 dns_zone_getsignatures(dns_zone_t *zone) {
   20126 	REQUIRE(DNS_ZONE_VALID(zone));
   20127 	return (zone->signatures);
   20128 }
   20129 
   20130 void
   20131 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
   20132 	REQUIRE(DNS_ZONE_VALID(zone));
   20133 	zone->privatetype = type;
   20134 }
   20135 
   20136 dns_rdatatype_t
   20137 dns_zone_getprivatetype(dns_zone_t *zone) {
   20138 	REQUIRE(DNS_ZONE_VALID(zone));
   20139 	return (zone->privatetype);
   20140 }
   20141 
   20142 static isc_result_t
   20143 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   20144 		 bool deleteit) {
   20145 	dns_signing_t *signing;
   20146 	dns_signing_t *current;
   20147 	isc_result_t result = ISC_R_SUCCESS;
   20148 	isc_time_t now;
   20149 	dns_db_t *db = NULL;
   20150 
   20151 	signing = isc_mem_get(zone->mctx, sizeof *signing);
   20152 
   20153 	signing->magic = 0;
   20154 	signing->db = NULL;
   20155 	signing->dbiterator = NULL;
   20156 	signing->algorithm = algorithm;
   20157 	signing->keyid = keyid;
   20158 	signing->deleteit = deleteit;
   20159 	signing->done = false;
   20160 
   20161 	TIME_NOW(&now);
   20162 
   20163 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   20164 	if (zone->db != NULL) {
   20165 		dns_db_attach(zone->db, &db);
   20166 	}
   20167 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   20168 
   20169 	if (db == NULL) {
   20170 		result = ISC_R_NOTFOUND;
   20171 		goto cleanup;
   20172 	}
   20173 
   20174 	dns_db_attach(db, &signing->db);
   20175 
   20176 	for (current = ISC_LIST_HEAD(zone->signing); current != NULL;
   20177 	     current = ISC_LIST_NEXT(current, link))
   20178 	{
   20179 		if (current->db == signing->db &&
   20180 		    current->algorithm == signing->algorithm &&
   20181 		    current->keyid == signing->keyid)
   20182 		{
   20183 			if (current->deleteit != signing->deleteit) {
   20184 				current->done = true;
   20185 			} else {
   20186 				goto cleanup;
   20187 			}
   20188 		}
   20189 	}
   20190 
   20191 	result = dns_db_createiterator(signing->db, 0, &signing->dbiterator);
   20192 
   20193 	if (result == ISC_R_SUCCESS) {
   20194 		result = dns_dbiterator_first(signing->dbiterator);
   20195 	}
   20196 	if (result == ISC_R_SUCCESS) {
   20197 		dns_dbiterator_pause(signing->dbiterator);
   20198 		ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
   20199 		signing = NULL;
   20200 		if (isc_time_isepoch(&zone->signingtime)) {
   20201 			zone->signingtime = now;
   20202 			if (zone->task != NULL) {
   20203 				zone_settimer(zone, &now);
   20204 			}
   20205 		}
   20206 	}
   20207 
   20208 cleanup:
   20209 	if (signing != NULL) {
   20210 		if (signing->db != NULL) {
   20211 			dns_db_detach(&signing->db);
   20212 		}
   20213 		if (signing->dbiterator != NULL) {
   20214 			dns_dbiterator_destroy(&signing->dbiterator);
   20215 		}
   20216 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   20217 	}
   20218 	if (db != NULL) {
   20219 		dns_db_detach(&db);
   20220 	}
   20221 	return (result);
   20222 }
   20223 
   20224 /* Called once; *timep should be set to the current time. */
   20225 static isc_result_t
   20226 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
   20227 	isc_result_t result;
   20228 	isc_stdtime_t now, then = 0, event;
   20229 	int i;
   20230 
   20231 	now = *timep;
   20232 
   20233 	for (i = 0; i <= DST_MAX_TIMES; i++) {
   20234 		result = dst_key_gettime(key, i, &event);
   20235 		if (result == ISC_R_SUCCESS && event > now &&
   20236 		    (then == 0 || event < then))
   20237 		{
   20238 			then = event;
   20239 		}
   20240 	}
   20241 
   20242 	if (then != 0) {
   20243 		*timep = then;
   20244 		return (ISC_R_SUCCESS);
   20245 	}
   20246 
   20247 	return (ISC_R_NOTFOUND);
   20248 }
   20249 
   20250 static isc_result_t
   20251 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   20252 	  const dns_rdata_t *rdata, bool *flag) {
   20253 	dns_rdataset_t rdataset;
   20254 	dns_dbnode_t *node = NULL;
   20255 	isc_result_t result;
   20256 
   20257 	dns_rdataset_init(&rdataset);
   20258 	if (rdata->type == dns_rdatatype_nsec3) {
   20259 		CHECK(dns_db_findnsec3node(db, name, false, &node));
   20260 	} else {
   20261 		CHECK(dns_db_findnode(db, name, false, &node));
   20262 	}
   20263 	result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
   20264 				     (isc_stdtime_t)0, &rdataset, NULL);
   20265 	if (result == ISC_R_NOTFOUND) {
   20266 		*flag = false;
   20267 		result = ISC_R_SUCCESS;
   20268 		goto failure;
   20269 	}
   20270 
   20271 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   20272 	     result = dns_rdataset_next(&rdataset))
   20273 	{
   20274 		dns_rdata_t myrdata = DNS_RDATA_INIT;
   20275 		dns_rdataset_current(&rdataset, &myrdata);
   20276 		if (!dns_rdata_compare(&myrdata, rdata)) {
   20277 			break;
   20278 		}
   20279 	}
   20280 	dns_rdataset_disassociate(&rdataset);
   20281 	if (result == ISC_R_SUCCESS) {
   20282 		*flag = true;
   20283 	} else if (result == ISC_R_NOMORE) {
   20284 		*flag = false;
   20285 		result = ISC_R_SUCCESS;
   20286 	}
   20287 
   20288 failure:
   20289 	if (node != NULL) {
   20290 		dns_db_detachnode(db, &node);
   20291 	}
   20292 	return (result);
   20293 }
   20294 
   20295 /*
   20296  * Add records to signal the state of signing or of key removal.
   20297  */
   20298 static isc_result_t
   20299 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
   20300 		    dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) {
   20301 	dns_difftuple_t *tuple, *newtuple = NULL;
   20302 	dns_rdata_dnskey_t dnskey;
   20303 	dns_rdata_t rdata = DNS_RDATA_INIT;
   20304 	bool flag;
   20305 	isc_region_t r;
   20306 	isc_result_t result = ISC_R_SUCCESS;
   20307 	uint16_t keyid;
   20308 	unsigned char buf[5];
   20309 	dns_name_t *name = dns_db_origin(db);
   20310 
   20311 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   20312 	     tuple = ISC_LIST_NEXT(tuple, link))
   20313 	{
   20314 		if (tuple->rdata.type != dns_rdatatype_dnskey) {
   20315 			continue;
   20316 		}
   20317 
   20318 		result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
   20319 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20320 		if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK |
   20321 				     DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE)
   20322 		{
   20323 			continue;
   20324 		}
   20325 
   20326 		dns_rdata_toregion(&tuple->rdata, &r);
   20327 
   20328 		keyid = dst_region_computeid(&r);
   20329 
   20330 		buf[0] = dnskey.algorithm;
   20331 		buf[1] = (keyid & 0xff00) >> 8;
   20332 		buf[2] = (keyid & 0xff);
   20333 		buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
   20334 		buf[4] = 0;
   20335 		rdata.data = buf;
   20336 		rdata.length = sizeof(buf);
   20337 		rdata.type = privatetype;
   20338 		rdata.rdclass = tuple->rdata.rdclass;
   20339 
   20340 		if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
   20341 			CHECK(rr_exists(db, ver, name, &rdata, &flag));
   20342 			if (flag) {
   20343 				continue;
   20344 			}
   20345 
   20346 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   20347 						   name, 0, &rdata, &newtuple));
   20348 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   20349 			INSIST(newtuple == NULL);
   20350 		}
   20351 
   20352 		/*
   20353 		 * Remove any record which says this operation has already
   20354 		 * completed.
   20355 		 */
   20356 		buf[4] = 1;
   20357 		CHECK(rr_exists(db, ver, name, &rdata, &flag));
   20358 		if (flag) {
   20359 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
   20360 						   name, 0, &rdata, &newtuple));
   20361 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   20362 			INSIST(newtuple == NULL);
   20363 		}
   20364 	}
   20365 failure:
   20366 	return (result);
   20367 }
   20368 
   20369 /*
   20370  * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at
   20371  * the apex, and if not tickle them and cause to sign so that newly activated
   20372  * keys are used.
   20373  */
   20374 static isc_result_t
   20375 tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db,
   20376 		  dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff,
   20377 		  dns__zonediff_t *zonediff, dst_key_t **keys,
   20378 		  unsigned int nkeys, isc_stdtime_t inception,
   20379 		  isc_stdtime_t keyexpire, bool check_ksk,
   20380 		  bool keyset_kskonly) {
   20381 	dns_difftuple_t *tuple;
   20382 	isc_result_t result;
   20383 
   20384 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   20385 	     tuple = ISC_LIST_NEXT(tuple, link))
   20386 	{
   20387 		if (tuple->rdata.type == rrtype &&
   20388 		    dns_name_equal(&tuple->name, &zone->origin))
   20389 		{
   20390 			break;
   20391 		}
   20392 	}
   20393 
   20394 	if (tuple == NULL) {
   20395 		result = del_sigs(zone, db, ver, &zone->origin, rrtype,
   20396 				  zonediff, keys, nkeys, now, false);
   20397 		if (result != ISC_R_SUCCESS) {
   20398 			dnssec_log(zone, ISC_LOG_ERROR,
   20399 				   "sign_apex:del_sigs -> %s",
   20400 				   dns_result_totext(result));
   20401 			return (result);
   20402 		}
   20403 		result = add_sigs(db, ver, &zone->origin, zone, rrtype,
   20404 				  zonediff->diff, keys, nkeys, zone->mctx,
   20405 				  inception, keyexpire, check_ksk,
   20406 				  keyset_kskonly);
   20407 		if (result != ISC_R_SUCCESS) {
   20408 			dnssec_log(zone, ISC_LOG_ERROR,
   20409 				   "sign_apex:add_sigs -> %s",
   20410 				   dns_result_totext(result));
   20411 			return (result);
   20412 		}
   20413 	}
   20414 
   20415 	return (ISC_R_SUCCESS);
   20416 }
   20417 
   20418 static isc_result_t
   20419 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   20420 	  isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) {
   20421 	isc_result_t result;
   20422 	isc_stdtime_t inception, soaexpire, keyexpire;
   20423 	bool check_ksk, keyset_kskonly;
   20424 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   20425 	unsigned int nkeys = 0, i;
   20426 
   20427 	result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
   20428 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   20429 	if (result != ISC_R_SUCCESS) {
   20430 		dnssec_log(zone, ISC_LOG_ERROR,
   20431 			   "sign_apex:dns__zone_findkeys -> %s",
   20432 			   dns_result_totext(result));
   20433 		return (result);
   20434 	}
   20435 
   20436 	inception = now - 3600; /* Allow for clock skew. */
   20437 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
   20438 
   20439 	keyexpire = dns_zone_getkeyvalidityinterval(zone);
   20440 	if (keyexpire == 0) {
   20441 		keyexpire = soaexpire - 1;
   20442 	} else {
   20443 		keyexpire += now;
   20444 	}
   20445 
   20446 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   20447 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   20448 
   20449 	/*
   20450 	 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY
   20451 	 * signature and if not cause them to sign so that newly activated
   20452 	 * keys are used.
   20453 	 */
   20454 	result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now,
   20455 				   diff, zonediff, zone_keys, nkeys, inception,
   20456 				   keyexpire, check_ksk, keyset_kskonly);
   20457 	if (result != ISC_R_SUCCESS) {
   20458 		goto failure;
   20459 	}
   20460 	result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff,
   20461 				   zonediff, zone_keys, nkeys, inception,
   20462 				   keyexpire, check_ksk, keyset_kskonly);
   20463 	if (result != ISC_R_SUCCESS) {
   20464 		goto failure;
   20465 	}
   20466 	result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now,
   20467 				   diff, zonediff, zone_keys, nkeys, inception,
   20468 				   keyexpire, check_ksk, keyset_kskonly);
   20469 	if (result != ISC_R_SUCCESS) {
   20470 		goto failure;
   20471 	}
   20472 
   20473 	result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
   20474 				      inception, soaexpire, keyexpire, now,
   20475 				      check_ksk, keyset_kskonly, zonediff);
   20476 
   20477 	if (result != ISC_R_SUCCESS) {
   20478 		dnssec_log(zone, ISC_LOG_ERROR,
   20479 			   "sign_apex:dns__zone_updatesigs -> %s",
   20480 			   dns_result_totext(result));
   20481 		goto failure;
   20482 	}
   20483 
   20484 failure:
   20485 	for (i = 0; i < nkeys; i++) {
   20486 		dst_key_free(&zone_keys[i]);
   20487 	}
   20488 	return (result);
   20489 }
   20490 
   20491 /*
   20492  * Prevent the zone entering a inconsistent state where
   20493  * NSEC only DNSKEYs are present with NSEC3 chains.
   20494  * See update.c:check_dnssec()
   20495  */
   20496 static bool
   20497 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   20498 	    dns_diff_t *diff) {
   20499 	isc_result_t result;
   20500 	dns_difftuple_t *tuple;
   20501 	bool nseconly = false, nsec3 = false;
   20502 	dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
   20503 
   20504 	/* Scan the tuples for an NSEC-only DNSKEY */
   20505 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   20506 	     tuple = ISC_LIST_NEXT(tuple, link))
   20507 	{
   20508 		uint8_t alg;
   20509 		if (tuple->rdata.type != dns_rdatatype_dnskey ||
   20510 		    tuple->op != DNS_DIFFOP_ADD)
   20511 		{
   20512 			continue;
   20513 		}
   20514 
   20515 		alg = tuple->rdata.data[3];
   20516 		if (alg == DST_ALG_RSASHA1) {
   20517 			nseconly = true;
   20518 			break;
   20519 		}
   20520 	}
   20521 
   20522 	/* Check existing DB for NSEC-only DNSKEY */
   20523 	if (!nseconly) {
   20524 		result = dns_nsec_nseconly(db, ver, &nseconly);
   20525 		if (result == ISC_R_NOTFOUND) {
   20526 			result = ISC_R_SUCCESS;
   20527 		}
   20528 		CHECK(result);
   20529 	}
   20530 
   20531 	/* Check existing DB for NSEC3 */
   20532 	if (!nsec3) {
   20533 		CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3));
   20534 	}
   20535 
   20536 	/* Refuse to allow NSEC3 with NSEC-only keys */
   20537 	if (nseconly && nsec3) {
   20538 		dnssec_log(zone, ISC_LOG_ERROR,
   20539 			   "NSEC only DNSKEYs and NSEC3 chains not allowed");
   20540 		goto failure;
   20541 	}
   20542 
   20543 	return (true);
   20544 
   20545 failure:
   20546 	return (false);
   20547 }
   20548 
   20549 static isc_result_t
   20550 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   20551 		 dns_diff_t *diff) {
   20552 	isc_result_t result;
   20553 	dns_dbnode_t *node = NULL;
   20554 	dns_rdataset_t rdataset;
   20555 
   20556 	dns_rdataset_init(&rdataset);
   20557 	CHECK(dns_db_getoriginnode(db, &node));
   20558 
   20559 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   20560 				     dns_rdatatype_none, 0, &rdataset, NULL);
   20561 	if (dns_rdataset_isassociated(&rdataset)) {
   20562 		dns_rdataset_disassociate(&rdataset);
   20563 	}
   20564 	if (result != ISC_R_NOTFOUND) {
   20565 		goto failure;
   20566 	}
   20567 
   20568 	result = dns_nsec3param_deletechains(db, ver, zone, true, diff);
   20569 
   20570 failure:
   20571 	if (node != NULL) {
   20572 		dns_db_detachnode(db, &node);
   20573 	}
   20574 	return (result);
   20575 }
   20576 
   20577 /*
   20578  * Given an RRSIG rdataset and an algorithm, determine whether there
   20579  * are any signatures using that algorithm.
   20580  */
   20581 static bool
   20582 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
   20583 	dns_rdata_t rdata = DNS_RDATA_INIT;
   20584 	dns_rdata_rrsig_t rrsig;
   20585 	isc_result_t result;
   20586 
   20587 	REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
   20588 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
   20589 		return (false);
   20590 	}
   20591 
   20592 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   20593 	     result = dns_rdataset_next(rdataset))
   20594 	{
   20595 		dns_rdataset_current(rdataset, &rdata);
   20596 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   20597 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20598 		dns_rdata_reset(&rdata);
   20599 		if (rrsig.algorithm == alg) {
   20600 			return (true);
   20601 		}
   20602 	}
   20603 
   20604 	return (false);
   20605 }
   20606 
   20607 static isc_result_t
   20608 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   20609 	   dns_diff_t *diff) {
   20610 	dns_name_t *origin;
   20611 	bool build_nsec3;
   20612 	isc_result_t result;
   20613 
   20614 	origin = dns_db_origin(db);
   20615 	CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
   20616 				 &build_nsec3));
   20617 	if (build_nsec3) {
   20618 		CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone_nsecttl(zone),
   20619 					   false, zone->privatetype, diff));
   20620 	}
   20621 	CHECK(updatesecure(db, ver, origin, zone_nsecttl(zone), true, diff));
   20622 
   20623 failure:
   20624 	return (result);
   20625 }
   20626 
   20627 static void
   20628 dnssec_report(const char *format, ...) {
   20629 	va_list args;
   20630 	va_start(args, format);
   20631 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE,
   20632 		       ISC_LOG_INFO, format, args);
   20633 	va_end(args);
   20634 }
   20635 
   20636 static void
   20637 checkds_destroy(dns_checkds_t *checkds, bool locked) {
   20638 	isc_mem_t *mctx;
   20639 
   20640 	REQUIRE(DNS_CHECKDS_VALID(checkds));
   20641 
   20642 	dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   20643 		     "checkds: destroy DS query");
   20644 
   20645 	if (checkds->zone != NULL) {
   20646 		if (!locked) {
   20647 			LOCK_ZONE(checkds->zone);
   20648 		}
   20649 		REQUIRE(LOCKED_ZONE(checkds->zone));
   20650 		if (ISC_LINK_LINKED(checkds, link)) {
   20651 			ISC_LIST_UNLINK(checkds->zone->checkds_requests,
   20652 					checkds, link);
   20653 		}
   20654 		if (!locked) {
   20655 			UNLOCK_ZONE(checkds->zone);
   20656 		}
   20657 		if (locked) {
   20658 			zone_idetach(&checkds->zone);
   20659 		} else {
   20660 			dns_zone_idetach(&checkds->zone);
   20661 		}
   20662 	}
   20663 	if (checkds->request != NULL) {
   20664 		dns_request_destroy(&checkds->request);
   20665 	}
   20666 	if (checkds->key != NULL) {
   20667 		dns_tsigkey_detach(&checkds->key);
   20668 	}
   20669 	mctx = checkds->mctx;
   20670 	isc_mem_put(checkds->mctx, checkds, sizeof(*checkds));
   20671 	isc_mem_detach(&mctx);
   20672 }
   20673 
   20674 static isc_result_t
   20675 make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize,
   20676 	    dns_rdata_t *target) {
   20677 	isc_result_t result;
   20678 	isc_buffer_t b;
   20679 	isc_region_t r;
   20680 
   20681 	isc_buffer_init(&b, buf, bufsize);
   20682 	result = dst_key_todns(key, &b);
   20683 	if (result != ISC_R_SUCCESS) {
   20684 		return (result);
   20685 	}
   20686 
   20687 	dns_rdata_reset(target);
   20688 	isc_buffer_usedregion(&b, &r);
   20689 	dns_rdata_fromregion(target, dst_key_class(key), dns_rdatatype_dnskey,
   20690 			     &r);
   20691 	return (ISC_R_SUCCESS);
   20692 }
   20693 
   20694 static bool
   20695 do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now,
   20696 	   bool dspublish) {
   20697 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   20698 	const char *dir = dns_zone_getkeydirectory(zone);
   20699 	isc_result_t result;
   20700 	uint32_t count = 0;
   20701 
   20702 	if (dspublish) {
   20703 		(void)dst_key_getnum(key, DST_NUM_DSPUBCOUNT, &count);
   20704 		count += 1;
   20705 		dst_key_setnum(key, DST_NUM_DSPUBCOUNT, count);
   20706 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20707 			     "checkds: %u DS published "
   20708 			     "for key %u",
   20709 			     count, dst_key_id(key));
   20710 
   20711 		if (count != zone->parentalscnt) {
   20712 			return false;
   20713 		}
   20714 	} else {
   20715 		(void)dst_key_getnum(key, DST_NUM_DSDELCOUNT, &count);
   20716 		count += 1;
   20717 		dst_key_setnum(key, DST_NUM_DSDELCOUNT, count);
   20718 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20719 			     "checkds: %u DS withdrawn "
   20720 			     "for key %u",
   20721 			     count, dst_key_id(key));
   20722 
   20723 		if (count != zone->parentalscnt) {
   20724 			return false;
   20725 		}
   20726 	}
   20727 
   20728 	dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20729 		     "checkds: checkds %s for key "
   20730 		     "%u",
   20731 		     dspublish ? "published" : "withdrawn", dst_key_id(key));
   20732 
   20733 	dns_zone_lock_keyfiles(zone);
   20734 	result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, dir, now, now,
   20735 				       dspublish, dst_key_id(key),
   20736 				       dst_key_alg(key));
   20737 	dns_zone_unlock_keyfiles(zone);
   20738 
   20739 	if (result != ISC_R_SUCCESS) {
   20740 		dns_zone_log(zone, ISC_LOG_WARNING,
   20741 			     "checkds: checkds for key %u failed: %s",
   20742 			     dst_key_id(key), isc_result_totext(result));
   20743 		return false;
   20744 	}
   20745 
   20746 	return true;
   20747 }
   20748 
   20749 static isc_result_t
   20750 validate_ds(dns_zone_t *zone, dns_message_t *message) {
   20751 	UNUSED(zone);
   20752 	UNUSED(message);
   20753 
   20754 	/* Get closest trust anchor */
   20755 
   20756 	/* Check that trust anchor is (grand)parent of zone. */
   20757 
   20758 	/* Find the DNSKEY signing the message. */
   20759 
   20760 	/* Check that DNSKEY is in chain of trust. */
   20761 
   20762 	/* Validate DS RRset. */
   20763 
   20764 	return (ISC_R_SUCCESS);
   20765 }
   20766 
   20767 static void
   20768 checkds_done(isc_task_t *task, isc_event_t *event) {
   20769 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   20770 	char rcode[128];
   20771 	dns_checkds_t *checkds;
   20772 	dns_zone_t *zone;
   20773 	dns_db_t *db = NULL;
   20774 	dns_dbversion_t *version = NULL;
   20775 	dns_dnsseckey_t *key;
   20776 	dns_dnsseckeylist_t keys;
   20777 	dns_kasp_t *kasp = NULL;
   20778 	dns_message_t *message = NULL;
   20779 	dns_rdataset_t *ds_rrset = NULL;
   20780 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   20781 	isc_buffer_t buf;
   20782 	isc_result_t result;
   20783 	isc_stdtime_t now;
   20784 	isc_time_t timenow;
   20785 	bool rekey = false;
   20786 	bool empty = false;
   20787 
   20788 	UNUSED(task);
   20789 
   20790 	checkds = event->ev_arg;
   20791 	REQUIRE(DNS_CHECKDS_VALID(checkds));
   20792 
   20793 	zone = checkds->zone;
   20794 	INSIST(task == zone->task);
   20795 
   20796 	ISC_LIST_INIT(keys);
   20797 
   20798 	kasp = zone->kasp;
   20799 	INSIST(kasp != NULL);
   20800 
   20801 	isc_buffer_init(&buf, rcode, sizeof(rcode));
   20802 	isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf));
   20803 
   20804 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "checkds: DS query to %s: done",
   20805 		     addrbuf);
   20806 
   20807 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &message);
   20808 	INSIST(message != NULL);
   20809 
   20810 	CHECK(revent->result);
   20811 	CHECK(dns_request_getresponse(revent->request, message,
   20812 				      DNS_MESSAGEPARSE_PRESERVEORDER));
   20813 	CHECK(dns_rcode_totext(message->rcode, &buf));
   20814 
   20815 	dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20816 		     "checkds: DS response from %s: %.*s", addrbuf,
   20817 		     (int)buf.used, rcode);
   20818 
   20819 	/* Validate response. */
   20820 	CHECK(validate_ds(zone, message));
   20821 
   20822 	if (message->rcode != dns_rcode_noerror) {
   20823 		dns_zone_log(zone, ISC_LOG_NOTICE,
   20824 			     "checkds: bad DS response from %s: %.*s", addrbuf,
   20825 			     (int)buf.used, rcode);
   20826 		goto failure;
   20827 	}
   20828 
   20829 	/* Lookup DS RRset. */
   20830 	result = dns_message_firstname(message, DNS_SECTION_ANSWER);
   20831 	while (result == ISC_R_SUCCESS) {
   20832 		dns_name_t *name = NULL;
   20833 		dns_rdataset_t *rdataset;
   20834 
   20835 		dns_message_currentname(message, DNS_SECTION_ANSWER, &name);
   20836 		if (dns_name_compare(&zone->origin, name) != 0) {
   20837 			goto next;
   20838 		}
   20839 
   20840 		for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
   20841 		     rdataset = ISC_LIST_NEXT(rdataset, link))
   20842 		{
   20843 			if (rdataset->type != dns_rdatatype_ds) {
   20844 				goto next;
   20845 			}
   20846 
   20847 			ds_rrset = rdataset;
   20848 			break;
   20849 		}
   20850 
   20851 		if (ds_rrset != NULL) {
   20852 			break;
   20853 		}
   20854 
   20855 	next:
   20856 		result = dns_message_nextname(message, DNS_SECTION_ANSWER);
   20857 	}
   20858 
   20859 	if (ds_rrset == NULL) {
   20860 		empty = true;
   20861 		dns_zone_log(zone, ISC_LOG_NOTICE,
   20862 			     "checkds: empty DS response from %s", addrbuf);
   20863 	}
   20864 
   20865 	TIME_NOW(&timenow);
   20866 	now = isc_time_seconds(&timenow);
   20867 
   20868 	CHECK(dns_zone_getdb(zone, &db));
   20869 	dns_db_currentversion(db, &version);
   20870 
   20871 	KASP_LOCK(kasp);
   20872 	LOCK_ZONE(zone);
   20873 	for (key = ISC_LIST_HEAD(zone->checkds_ok); key != NULL;
   20874 	     key = ISC_LIST_NEXT(key, link))
   20875 	{
   20876 		bool alldone = false, found = false;
   20877 		bool checkdspub = false, checkdsdel = false, ksk = false;
   20878 		dst_key_state_t ds_state = DST_KEY_STATE_NA;
   20879 		isc_stdtime_t published = 0, withdrawn = 0;
   20880 		isc_result_t ret = ISC_R_SUCCESS;
   20881 
   20882 		/* Is this key have the KSK role? */
   20883 		(void)dst_key_role(key->key, &ksk, NULL);
   20884 		if (!ksk) {
   20885 			continue;
   20886 		}
   20887 
   20888 		/* Do we need to check the DS RRset for this key? */
   20889 		(void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state);
   20890 		(void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published);
   20891 		(void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn);
   20892 
   20893 		if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) {
   20894 			checkdspub = true;
   20895 		} else if (ds_state == DST_KEY_STATE_UNRETENTIVE &&
   20896 			   withdrawn == 0)
   20897 		{
   20898 			checkdsdel = true;
   20899 		}
   20900 		if (!checkdspub && !checkdsdel) {
   20901 			continue;
   20902 		}
   20903 
   20904 		if (empty) {
   20905 			goto dswithdrawn;
   20906 		}
   20907 
   20908 		/* Find the appropriate DS record. */
   20909 		ret = dns_rdataset_first(ds_rrset);
   20910 		while (ret == ISC_R_SUCCESS) {
   20911 			dns_rdata_ds_t ds;
   20912 			dns_rdata_t dnskey = DNS_RDATA_INIT;
   20913 			dns_rdata_t dsrdata = DNS_RDATA_INIT;
   20914 			dns_rdata_t rdata = DNS_RDATA_INIT;
   20915 			isc_result_t r;
   20916 			unsigned char dsbuf[DNS_DS_BUFFERSIZE];
   20917 			unsigned char keybuf[DST_KEY_MAXSIZE];
   20918 
   20919 			dns_rdataset_current(ds_rrset, &rdata);
   20920 			r = dns_rdata_tostruct(&rdata, &ds, NULL);
   20921 			if (r != ISC_R_SUCCESS) {
   20922 				goto nextds;
   20923 			}
   20924 			/* Check key tag and algorithm. */
   20925 			if (dst_key_id(key->key) != ds.key_tag) {
   20926 				goto nextds;
   20927 			}
   20928 			if (dst_key_alg(key->key) != ds.algorithm) {
   20929 				goto nextds;
   20930 			}
   20931 			/* Derive DS from DNSKEY, see if the rdata is equal. */
   20932 			make_dnskey(key->key, keybuf, sizeof(keybuf), &dnskey);
   20933 			r = dns_ds_buildrdata(&zone->origin, &dnskey,
   20934 					      ds.digest_type, dsbuf, &dsrdata);
   20935 			if (r != ISC_R_SUCCESS) {
   20936 				goto nextds;
   20937 			}
   20938 			if (dns_rdata_compare(&rdata, &dsrdata) == 0) {
   20939 				found = true;
   20940 				if (checkdspub) {
   20941 					/* DS Published. */
   20942 					alldone = do_checkds(zone, key->key,
   20943 							     now, true);
   20944 					if (alldone) {
   20945 						rekey = true;
   20946 					}
   20947 				}
   20948 			}
   20949 
   20950 		nextds:
   20951 			ret = dns_rdataset_next(ds_rrset);
   20952 		}
   20953 
   20954 	dswithdrawn:
   20955 		/* DS withdrawn. */
   20956 		if (checkdsdel && !found) {
   20957 			alldone = do_checkds(zone, key->key, now, false);
   20958 			if (alldone) {
   20959 				rekey = true;
   20960 			}
   20961 		}
   20962 	}
   20963 	UNLOCK_ZONE(zone);
   20964 	KASP_UNLOCK(kasp);
   20965 
   20966 	/* Rekey after checkds. */
   20967 	if (rekey) {
   20968 		dns_zone_rekey(zone, false);
   20969 	}
   20970 
   20971 failure:
   20972 	if (result != ISC_R_SUCCESS) {
   20973 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20974 			     "checkds: DS request failed: %s",
   20975 			     isc_result_totext(result));
   20976 	}
   20977 
   20978 	if (version != NULL) {
   20979 		dns_db_closeversion(db, &version, false);
   20980 	}
   20981 	if (db != NULL) {
   20982 		dns_db_detach(&db);
   20983 	}
   20984 
   20985 	while (!ISC_LIST_EMPTY(keys)) {
   20986 		key = ISC_LIST_HEAD(keys);
   20987 		ISC_LIST_UNLINK(keys, key, link);
   20988 		dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key);
   20989 	}
   20990 
   20991 	isc_event_free(&event);
   20992 	checkds_destroy(checkds, false);
   20993 	dns_message_detach(&message);
   20994 }
   20995 
   20996 static bool
   20997 checkds_isqueued(dns_zone_t *zone, isc_sockaddr_t *addr, dns_tsigkey_t *key) {
   20998 	dns_checkds_t *checkds;
   20999 
   21000 	for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL;
   21001 	     checkds = ISC_LIST_NEXT(checkds, link))
   21002 	{
   21003 		if (checkds->request != NULL) {
   21004 			continue;
   21005 		}
   21006 		if (addr != NULL && isc_sockaddr_equal(addr, &checkds->dst) &&
   21007 		    checkds->key == key)
   21008 		{
   21009 			return (true);
   21010 		}
   21011 	}
   21012 	return (false);
   21013 }
   21014 
   21015 static isc_result_t
   21016 checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) {
   21017 	dns_checkds_t *checkds;
   21018 
   21019 	REQUIRE(checkdsp != NULL && *checkdsp == NULL);
   21020 
   21021 	checkds = isc_mem_get(mctx, sizeof(*checkds));
   21022 	*checkds = (dns_checkds_t){
   21023 		.flags = flags,
   21024 	};
   21025 
   21026 	isc_mem_attach(mctx, &checkds->mctx);
   21027 	isc_sockaddr_any(&checkds->dst);
   21028 	ISC_LINK_INIT(checkds, link);
   21029 	checkds->magic = CHECKDS_MAGIC;
   21030 	*checkdsp = checkds;
   21031 	return (ISC_R_SUCCESS);
   21032 }
   21033 
   21034 static isc_result_t
   21035 checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep) {
   21036 	dns_message_t *message = NULL;
   21037 
   21038 	dns_name_t *tempname = NULL;
   21039 	dns_rdataset_t *temprdataset = NULL;
   21040 
   21041 	isc_result_t result;
   21042 
   21043 	REQUIRE(DNS_ZONE_VALID(zone));
   21044 	REQUIRE(messagep != NULL && *messagep == NULL);
   21045 
   21046 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   21047 
   21048 	message->opcode = dns_opcode_query;
   21049 	message->rdclass = zone->rdclass;
   21050 
   21051 	result = dns_message_gettempname(message, &tempname);
   21052 	if (result != ISC_R_SUCCESS) {
   21053 		goto cleanup;
   21054 	}
   21055 
   21056 	result = dns_message_gettemprdataset(message, &temprdataset);
   21057 	if (result != ISC_R_SUCCESS) {
   21058 		goto cleanup;
   21059 	}
   21060 
   21061 	/*
   21062 	 * Make question.
   21063 	 */
   21064 	dns_name_init(tempname, NULL);
   21065 	dns_name_clone(&zone->origin, tempname);
   21066 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
   21067 				  dns_rdatatype_ds);
   21068 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   21069 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
   21070 	tempname = NULL;
   21071 	temprdataset = NULL;
   21072 
   21073 	*messagep = message;
   21074 	return (ISC_R_SUCCESS);
   21075 
   21076 cleanup:
   21077 	if (tempname != NULL) {
   21078 		dns_message_puttempname(message, &tempname);
   21079 	}
   21080 	if (temprdataset != NULL) {
   21081 		dns_message_puttemprdataset(message, &temprdataset);
   21082 	}
   21083 	dns_message_detach(&message);
   21084 	return (result);
   21085 }
   21086 
   21087 static void
   21088 checkds_send_toaddr(isc_task_t *task, isc_event_t *event) {
   21089 	dns_checkds_t *checkds;
   21090 	isc_result_t result;
   21091 	dns_message_t *message = NULL;
   21092 	isc_netaddr_t dstip;
   21093 	dns_tsigkey_t *key = NULL;
   21094 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   21095 	isc_sockaddr_t src;
   21096 	unsigned int options, timeout;
   21097 	bool have_checkdssource = false;
   21098 	bool have_checkdsdscp = false;
   21099 	isc_dscp_t dscp = -1;
   21100 
   21101 	checkds = event->ev_arg;
   21102 	REQUIRE(DNS_CHECKDS_VALID(checkds));
   21103 
   21104 	UNUSED(task);
   21105 
   21106 	LOCK_ZONE(checkds->zone);
   21107 
   21108 	checkds->event = NULL;
   21109 
   21110 	if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_LOADED) == 0) {
   21111 		result = ISC_R_CANCELED;
   21112 		goto cleanup;
   21113 	}
   21114 
   21115 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
   21116 	    DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING) ||
   21117 	    checkds->zone->view->requestmgr == NULL ||
   21118 	    checkds->zone->db == NULL)
   21119 	{
   21120 		result = ISC_R_CANCELED;
   21121 		goto cleanup;
   21122 	}
   21123 
   21124 	/*
   21125 	 * The raw IPv4 address should also exist.  Don't send to the
   21126 	 * mapped form.
   21127 	 */
   21128 	if (isc_sockaddr_pf(&checkds->dst) == PF_INET6 &&
   21129 	    IN6_IS_ADDR_V4MAPPED(&checkds->dst.type.sin6.sin6_addr))
   21130 	{
   21131 		isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf));
   21132 		dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21133 			     "checkds: ignoring IPv6 mapped IPV4 address: %s",
   21134 			     addrbuf);
   21135 		result = ISC_R_CANCELED;
   21136 		goto cleanup;
   21137 	}
   21138 
   21139 	result = checkds_createmessage(checkds->zone, &message);
   21140 	if (result != ISC_R_SUCCESS) {
   21141 		goto cleanup;
   21142 	}
   21143 
   21144 	isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf));
   21145 	if (checkds->key != NULL) {
   21146 		/* Transfer ownership of key */
   21147 		key = checkds->key;
   21148 		checkds->key = NULL;
   21149 	} else {
   21150 		isc_netaddr_fromsockaddr(&dstip, &checkds->dst);
   21151 		result = dns_view_getpeertsig(checkds->zone->view, &dstip,
   21152 					      &key);
   21153 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   21154 			dns_zone_log(checkds->zone, ISC_LOG_ERROR,
   21155 				     "checkds: DS query to %s not sent. "
   21156 				     "Peer TSIG key lookup failure.",
   21157 				     addrbuf);
   21158 			goto cleanup_message;
   21159 		}
   21160 	}
   21161 
   21162 	if (key != NULL) {
   21163 		char namebuf[DNS_NAME_FORMATSIZE];
   21164 
   21165 		dns_name_format(&key->name, namebuf, sizeof(namebuf));
   21166 		dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21167 			     "checkds: sending DS query to %s : TSIG (%s)",
   21168 			     addrbuf, namebuf);
   21169 	} else {
   21170 		dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21171 			     "checkds: sending DS query to %s", addrbuf);
   21172 	}
   21173 	options = 0;
   21174 	if (checkds->zone->view->peers != NULL) {
   21175 		dns_peer_t *peer = NULL;
   21176 		bool usetcp = false;
   21177 		result = dns_peerlist_peerbyaddr(checkds->zone->view->peers,
   21178 						 &dstip, &peer);
   21179 		if (result == ISC_R_SUCCESS) {
   21180 			result = dns_peer_getquerysource(peer, &src);
   21181 			if (result == ISC_R_SUCCESS) {
   21182 				have_checkdssource = true;
   21183 			}
   21184 			dns_peer_getquerydscp(peer, &dscp);
   21185 			if (dscp != -1) {
   21186 				have_checkdsdscp = true;
   21187 			}
   21188 			result = dns_peer_getforcetcp(peer, &usetcp);
   21189 			if (result == ISC_R_SUCCESS && usetcp) {
   21190 				options |= DNS_FETCHOPT_TCP;
   21191 			}
   21192 		}
   21193 	}
   21194 	switch (isc_sockaddr_pf(&checkds->dst)) {
   21195 	case PF_INET:
   21196 		if (!have_checkdssource) {
   21197 			src = checkds->zone->parentalsrc4;
   21198 		}
   21199 		if (!have_checkdsdscp) {
   21200 			dscp = checkds->zone->parentalsrc4dscp;
   21201 		}
   21202 		break;
   21203 	case PF_INET6:
   21204 		if (!have_checkdssource) {
   21205 			src = checkds->zone->parentalsrc6;
   21206 		}
   21207 		if (!have_checkdsdscp) {
   21208 			dscp = checkds->zone->parentalsrc6dscp;
   21209 		}
   21210 		break;
   21211 	default:
   21212 		result = ISC_R_NOTIMPLEMENTED;
   21213 		goto cleanup_key;
   21214 	}
   21215 
   21216 	dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21217 		     "checkds: create request for DS query to %s", addrbuf);
   21218 
   21219 	timeout = 15;
   21220 	options |= DNS_REQUESTOPT_TCP;
   21221 	result = dns_request_createvia(
   21222 		checkds->zone->view->requestmgr, message, &src, &checkds->dst,
   21223 		dscp, options, key, timeout * 3, timeout, 0,
   21224 		checkds->zone->task, checkds_done, checkds, &checkds->request);
   21225 	if (result != ISC_R_SUCCESS) {
   21226 		dns_zone_log(
   21227 			checkds->zone, ISC_LOG_DEBUG(3),
   21228 			"checkds: dns_request_createvia() to %s failed: %s",
   21229 			addrbuf, dns_result_totext(result));
   21230 	}
   21231 
   21232 cleanup_key:
   21233 	if (key != NULL) {
   21234 		dns_tsigkey_detach(&key);
   21235 	}
   21236 cleanup_message:
   21237 	dns_message_detach(&message);
   21238 cleanup:
   21239 	UNLOCK_ZONE(checkds->zone);
   21240 	isc_event_free(&event);
   21241 	if (result != ISC_R_SUCCESS) {
   21242 		checkds_destroy(checkds, false);
   21243 	}
   21244 }
   21245 
   21246 static isc_result_t
   21247 checkds_send_queue(dns_checkds_t *checkds) {
   21248 	isc_event_t *e;
   21249 	isc_result_t result;
   21250 
   21251 	INSIST(checkds->event == NULL);
   21252 	e = isc_event_allocate(checkds->mctx, NULL, DNS_EVENT_CHECKDSSENDTOADDR,
   21253 			       checkds_send_toaddr, checkds,
   21254 			       sizeof(isc_event_t));
   21255 	e->ev_arg = checkds;
   21256 	e->ev_sender = NULL;
   21257 	result = isc_ratelimiter_enqueue(checkds->zone->zmgr->checkdsrl,
   21258 					 checkds->zone->task, &e);
   21259 	if (result != ISC_R_SUCCESS) {
   21260 		isc_event_free(&e);
   21261 		checkds->event = NULL;
   21262 	}
   21263 	return (result);
   21264 }
   21265 
   21266 static void
   21267 checkds_send(dns_zone_t *zone) {
   21268 	dns_view_t *view = dns_zone_getview(zone);
   21269 	isc_result_t result;
   21270 	unsigned int flags = 0;
   21271 
   21272 	/*
   21273 	 * Zone lock held by caller.
   21274 	 */
   21275 	REQUIRE(LOCKED_ZONE(zone));
   21276 
   21277 	dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21278 		     "checkds: start sending DS queries to %u parentals",
   21279 		     zone->parentalscnt);
   21280 
   21281 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   21282 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21283 			     "checkds: abort, named exiting");
   21284 		return;
   21285 	}
   21286 
   21287 	for (unsigned int i = 0; i < zone->parentalscnt; i++) {
   21288 		dns_tsigkey_t *key = NULL;
   21289 		isc_sockaddr_t dst;
   21290 		dns_checkds_t *checkds = NULL;
   21291 
   21292 		if ((zone->parentalkeynames != NULL) &&
   21293 		    (zone->parentalkeynames[i] != NULL))
   21294 		{
   21295 			dns_name_t *keyname = zone->parentalkeynames[i];
   21296 			(void)dns_view_gettsig(view, keyname, &key);
   21297 		}
   21298 
   21299 		dst = zone->parentals[i];
   21300 
   21301 		if (checkds_isqueued(zone, &dst, key)) {
   21302 			dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21303 				     "checkds: DS query to parent "
   21304 				     "%d is queued",
   21305 				     i);
   21306 			if (key != NULL) {
   21307 				dns_tsigkey_detach(&key);
   21308 			}
   21309 			continue;
   21310 		}
   21311 
   21312 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21313 			     "checkds: create DS query for "
   21314 			     "parent %d",
   21315 			     i);
   21316 
   21317 		result = checkds_create(zone->mctx, flags, &checkds);
   21318 		if (result != ISC_R_SUCCESS) {
   21319 			dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21320 				     "checkds: create DS query for "
   21321 				     "parent %d failed",
   21322 				     i);
   21323 			continue;
   21324 		}
   21325 		zone_iattach(zone, &checkds->zone);
   21326 		checkds->dst = dst;
   21327 
   21328 		INSIST(checkds->key == NULL);
   21329 		if (key != NULL) {
   21330 			checkds->key = key;
   21331 			key = NULL;
   21332 		}
   21333 
   21334 		ISC_LIST_APPEND(zone->checkds_requests, checkds, link);
   21335 		result = checkds_send_queue(checkds);
   21336 		if (result != ISC_R_SUCCESS) {
   21337 			dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21338 				     "checkds: send DS query to "
   21339 				     "parent %d failed",
   21340 				     i);
   21341 			checkds_destroy(checkds, true);
   21342 		}
   21343 	}
   21344 }
   21345 
   21346 static void
   21347 zone_checkds(dns_zone_t *zone) {
   21348 	bool cdscheck = false;
   21349 
   21350 	for (dns_dnsseckey_t *key = ISC_LIST_HEAD(zone->checkds_ok);
   21351 	     key != NULL; key = ISC_LIST_NEXT(key, link))
   21352 	{
   21353 		dst_key_state_t ds_state = DST_KEY_STATE_NA;
   21354 		bool ksk = false;
   21355 		isc_stdtime_t published = 0, withdrawn = 0;
   21356 
   21357 		/* Is this key have the KSK role? */
   21358 		(void)dst_key_role(key->key, &ksk, NULL);
   21359 		if (!ksk) {
   21360 			continue;
   21361 		}
   21362 
   21363 		/* Do we need to check the DS RRset? */
   21364 		(void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state);
   21365 		(void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published);
   21366 		(void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn);
   21367 
   21368 		if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) {
   21369 			dst_key_setnum(key->key, DST_NUM_DSPUBCOUNT, 0);
   21370 			cdscheck = true;
   21371 		} else if (ds_state == DST_KEY_STATE_UNRETENTIVE &&
   21372 			   withdrawn == 0)
   21373 		{
   21374 			dst_key_setnum(key->key, DST_NUM_DSDELCOUNT, 0);
   21375 			cdscheck = true;
   21376 		}
   21377 	}
   21378 
   21379 	if (cdscheck) {
   21380 		/* Request the DS RRset. */
   21381 		LOCK_ZONE(zone);
   21382 		checkds_send(zone);
   21383 		UNLOCK_ZONE(zone);
   21384 	}
   21385 }
   21386 
   21387 static void
   21388 zone_rekey(dns_zone_t *zone) {
   21389 	isc_result_t result;
   21390 	dns_db_t *db = NULL;
   21391 	dns_dbnode_t *node = NULL;
   21392 	dns_dbversion_t *ver = NULL;
   21393 	dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset;
   21394 	dns_dnsseckeylist_t dnskeys, keys, rmkeys;
   21395 	dns_dnsseckey_t *key = NULL;
   21396 	dns_diff_t diff, _sig_diff;
   21397 	dns_kasp_t *kasp;
   21398 	dns__zonediff_t zonediff;
   21399 	bool commit = false, newactive = false;
   21400 	bool newalg = false;
   21401 	bool fullsign;
   21402 	dns_ttl_t ttl = 3600;
   21403 	const char *dir = NULL;
   21404 	isc_mem_t *mctx = NULL;
   21405 	isc_stdtime_t now, nexttime = 0;
   21406 	isc_time_t timenow;
   21407 	isc_interval_t ival;
   21408 	char timebuf[80];
   21409 
   21410 	REQUIRE(DNS_ZONE_VALID(zone));
   21411 
   21412 	ISC_LIST_INIT(dnskeys);
   21413 	ISC_LIST_INIT(keys);
   21414 	ISC_LIST_INIT(rmkeys);
   21415 	dns_rdataset_init(&soaset);
   21416 	dns_rdataset_init(&soasigs);
   21417 	dns_rdataset_init(&keyset);
   21418 	dns_rdataset_init(&keysigs);
   21419 	dns_rdataset_init(&cdsset);
   21420 	dns_rdataset_init(&cdnskeyset);
   21421 	dir = dns_zone_getkeydirectory(zone);
   21422 	mctx = zone->mctx;
   21423 	dns_diff_init(mctx, &diff);
   21424 	dns_diff_init(mctx, &_sig_diff);
   21425 	zonediff_init(&zonediff, &_sig_diff);
   21426 
   21427 	CHECK(dns_zone_getdb(zone, &db));
   21428 	CHECK(dns_db_newversion(db, &ver));
   21429 	CHECK(dns_db_getoriginnode(db, &node));
   21430 
   21431 	TIME_NOW(&timenow);
   21432 	now = isc_time_seconds(&timenow);
   21433 
   21434 	kasp = dns_zone_getkasp(zone);
   21435 
   21436 	dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
   21437 
   21438 	/* Get the SOA record's TTL */
   21439 	CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
   21440 				  dns_rdatatype_none, 0, &soaset, &soasigs));
   21441 	ttl = soaset.ttl;
   21442 	dns_rdataset_disassociate(&soaset);
   21443 
   21444 	/* Get the DNSKEY rdataset */
   21445 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   21446 				     dns_rdatatype_none, 0, &keyset, &keysigs);
   21447 	if (result == ISC_R_SUCCESS) {
   21448 		ttl = keyset.ttl;
   21449 
   21450 		dns_zone_lock_keyfiles(zone);
   21451 
   21452 		result = dns_dnssec_keylistfromrdataset(
   21453 			&zone->origin, dir, mctx, &keyset, &keysigs, &soasigs,
   21454 			false, false, &dnskeys);
   21455 
   21456 		dns_zone_unlock_keyfiles(zone);
   21457 
   21458 		if (result != ISC_R_SUCCESS) {
   21459 			goto failure;
   21460 		}
   21461 	} else if (result != ISC_R_NOTFOUND) {
   21462 		goto failure;
   21463 	}
   21464 
   21465 	/* Get the CDS rdataset */
   21466 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds,
   21467 				     dns_rdatatype_none, 0, &cdsset, NULL);
   21468 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) {
   21469 		dns_rdataset_disassociate(&cdsset);
   21470 	}
   21471 
   21472 	/* Get the CDNSKEY rdataset */
   21473 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey,
   21474 				     dns_rdatatype_none, 0, &cdnskeyset, NULL);
   21475 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) {
   21476 		dns_rdataset_disassociate(&cdnskeyset);
   21477 	}
   21478 
   21479 	/*
   21480 	 * True when called from "rndc sign".  Indicates the zone should be
   21481 	 * fully signed now.
   21482 	 */
   21483 	fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
   21484 
   21485 	KASP_LOCK(kasp);
   21486 
   21487 	dns_zone_lock_keyfiles(zone);
   21488 	result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
   21489 					     &keys);
   21490 	dns_zone_unlock_keyfiles(zone);
   21491 
   21492 	if (result != ISC_R_SUCCESS) {
   21493 		dnssec_log(zone, ISC_LOG_DEBUG(1),
   21494 			   "zone_rekey:dns_dnssec_findmatchingkeys failed: %s",
   21495 			   isc_result_totext(result));
   21496 	}
   21497 
   21498 	if (kasp != NULL) {
   21499 		/*
   21500 		 * Check DS at parental agents. Clear ongoing checks.
   21501 		 */
   21502 		LOCK_ZONE(zone);
   21503 		checkds_cancel(zone);
   21504 		clear_keylist(&zone->checkds_ok, zone->mctx);
   21505 		ISC_LIST_INIT(zone->checkds_ok);
   21506 		UNLOCK_ZONE(zone);
   21507 
   21508 		result = dns_zone_getdnsseckeys(zone, db, ver, now,
   21509 						&zone->checkds_ok);
   21510 
   21511 		if (result == ISC_R_SUCCESS) {
   21512 			zone_checkds(zone);
   21513 		} else {
   21514 			dnssec_log(zone,
   21515 				   (result == ISC_R_NOTFOUND) ? ISC_LOG_DEBUG(1)
   21516 							      : ISC_LOG_ERROR,
   21517 				   "zone_rekey:dns_zone_getdnsseckeys failed: "
   21518 				   "%s",
   21519 				   isc_result_totext(result));
   21520 		}
   21521 
   21522 		if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) {
   21523 			dns_zone_lock_keyfiles(zone);
   21524 			result = dns_keymgr_run(&zone->origin, zone->rdclass,
   21525 						dir, mctx, &keys, &dnskeys,
   21526 						kasp, now, &nexttime);
   21527 			dns_zone_unlock_keyfiles(zone);
   21528 
   21529 			if (result != ISC_R_SUCCESS) {
   21530 				dnssec_log(zone, ISC_LOG_ERROR,
   21531 					   "zone_rekey:dns_dnssec_keymgr "
   21532 					   "failed: %s",
   21533 					   isc_result_totext(result));
   21534 				KASP_UNLOCK(kasp);
   21535 				goto failure;
   21536 			}
   21537 		}
   21538 	}
   21539 
   21540 	KASP_UNLOCK(kasp);
   21541 
   21542 	if (result == ISC_R_SUCCESS) {
   21543 		bool cdsdel = false;
   21544 		bool cdnskeydel = false;
   21545 		isc_stdtime_t when;
   21546 
   21547 		/*
   21548 		 * Publish CDS/CDNSKEY DELETE records if the zone is
   21549 		 * transitioning from secure to insecure.
   21550 		 */
   21551 		if (kasp != NULL) {
   21552 			if (strcmp(dns_kasp_getname(kasp), "insecure") == 0) {
   21553 				cdsdel = true;
   21554 				cdnskeydel = true;
   21555 			}
   21556 		} else {
   21557 			/* Check if there is a CDS DELETE record. */
   21558 			if (dns_rdataset_isassociated(&cdsset)) {
   21559 				for (result = dns_rdataset_first(&cdsset);
   21560 				     result == ISC_R_SUCCESS;
   21561 				     result = dns_rdataset_next(&cdsset))
   21562 				{
   21563 					dns_rdata_t crdata = DNS_RDATA_INIT;
   21564 					dns_rdataset_current(&cdsset, &crdata);
   21565 					/*
   21566 					 * CDS deletion record has this form
   21567 					 * "0 0 0 00" which is 5 zero octets.
   21568 					 */
   21569 					if (crdata.length == 5U &&
   21570 					    memcmp(crdata.data,
   21571 						   (unsigned char[5]){ 0, 0, 0,
   21572 								       0, 0 },
   21573 						   5) == 0)
   21574 					{
   21575 						cdsdel = true;
   21576 						break;
   21577 					}
   21578 				}
   21579 			}
   21580 
   21581 			/* Check if there is a CDNSKEY DELETE record. */
   21582 			if (dns_rdataset_isassociated(&cdnskeyset)) {
   21583 				for (result = dns_rdataset_first(&cdnskeyset);
   21584 				     result == ISC_R_SUCCESS;
   21585 				     result = dns_rdataset_next(&cdnskeyset))
   21586 				{
   21587 					dns_rdata_t crdata = DNS_RDATA_INIT;
   21588 					dns_rdataset_current(&cdnskeyset,
   21589 							     &crdata);
   21590 					/*
   21591 					 * CDNSKEY deletion record has this form
   21592 					 * "0 3 0 AA==" which is 2 zero octets,
   21593 					 * a 3, and 2 zero octets.
   21594 					 */
   21595 					if (crdata.length == 5U &&
   21596 					    memcmp(crdata.data,
   21597 						   (unsigned char[5]){ 0, 0, 3,
   21598 								       0, 0 },
   21599 						   5) == 0)
   21600 					{
   21601 						cdnskeydel = true;
   21602 						break;
   21603 					}
   21604 				}
   21605 			}
   21606 		}
   21607 
   21608 		/*
   21609 		 * Only update DNSKEY TTL if we have a policy.
   21610 		 */
   21611 		if (kasp != NULL) {
   21612 			ttl = dns_kasp_dnskeyttl(kasp);
   21613 		}
   21614 
   21615 		result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
   21616 					       &zone->origin, ttl, &diff, mctx,
   21617 					       dnssec_report);
   21618 		/*
   21619 		 * Keys couldn't be updated for some reason;
   21620 		 * try again later.
   21621 		 */
   21622 		if (result != ISC_R_SUCCESS) {
   21623 			dnssec_log(zone, ISC_LOG_ERROR,
   21624 				   "zone_rekey:couldn't update zone keys: %s",
   21625 				   isc_result_totext(result));
   21626 			goto failure;
   21627 		}
   21628 
   21629 		/*
   21630 		 * Update CDS / CDNSKEY records.
   21631 		 */
   21632 		result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset,
   21633 					       &cdnskeyset, now, ttl, &diff,
   21634 					       mctx);
   21635 		if (result != ISC_R_SUCCESS) {
   21636 			dnssec_log(zone, ISC_LOG_ERROR,
   21637 				   "zone_rekey:couldn't update CDS/CDNSKEY: %s",
   21638 				   isc_result_totext(result));
   21639 			goto failure;
   21640 		}
   21641 
   21642 		if (cdsdel || cdnskeydel) {
   21643 			/*
   21644 			 * Only publish CDS/CDNSKEY DELETE records if there is
   21645 			 * a KSK that can be used to verify the RRset. This
   21646 			 * means there must be a key with the KSK role that is
   21647 			 * published and is used for signing.
   21648 			 */
   21649 			bool allow = false;
   21650 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21651 			     key = ISC_LIST_NEXT(key, link))
   21652 			{
   21653 				dst_key_t *dstk = key->key;
   21654 
   21655 				if (dst_key_is_published(dstk, now, &when) &&
   21656 				    dst_key_is_signing(dstk, DST_BOOL_KSK, now,
   21657 						       &when))
   21658 				{
   21659 					allow = true;
   21660 					break;
   21661 				}
   21662 			}
   21663 			if (cdsdel) {
   21664 				cdsdel = allow;
   21665 			}
   21666 			if (cdnskeydel) {
   21667 				cdnskeydel = allow;
   21668 			}
   21669 		}
   21670 		result = dns_dnssec_syncdelete(
   21671 			&cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl,
   21672 			&diff, mctx, cdsdel, cdnskeydel);
   21673 		if (result != ISC_R_SUCCESS) {
   21674 			dnssec_log(zone, ISC_LOG_ERROR,
   21675 				   "zone_rekey:couldn't update CDS/CDNSKEY "
   21676 				   "DELETE records: %s",
   21677 				   isc_result_totext(result));
   21678 			goto failure;
   21679 		}
   21680 
   21681 		/*
   21682 		 * See if any pre-existing keys have newly become active;
   21683 		 * also, see if any new key is for a new algorithm, as in that
   21684 		 * event, we need to sign the zone fully.  (If there's a new
   21685 		 * key, but it's for an already-existing algorithm, then
   21686 		 * the zone signing can be handled incrementally.)
   21687 		 */
   21688 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21689 		     key = ISC_LIST_NEXT(key, link))
   21690 		{
   21691 			if (!key->first_sign) {
   21692 				continue;
   21693 			}
   21694 
   21695 			newactive = true;
   21696 
   21697 			if (!dns_rdataset_isassociated(&keysigs)) {
   21698 				newalg = true;
   21699 				break;
   21700 			}
   21701 
   21702 			if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
   21703 				/*
   21704 				 * This isn't a new algorithm; clear
   21705 				 * first_sign so we won't sign the
   21706 				 * whole zone with this key later.
   21707 				 */
   21708 				key->first_sign = false;
   21709 			} else {
   21710 				newalg = true;
   21711 				break;
   21712 			}
   21713 		}
   21714 
   21715 		if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
   21716 		    dnskey_sane(zone, db, ver, &diff))
   21717 		{
   21718 			CHECK(dns_diff_apply(&diff, db, ver));
   21719 			CHECK(clean_nsec3param(zone, db, ver, &diff));
   21720 			CHECK(add_signing_records(db, zone->privatetype, ver,
   21721 						  &diff, (newalg || fullsign)));
   21722 			CHECK(update_soa_serial(zone, db, ver, &diff, mctx,
   21723 						zone->updatemethod));
   21724 			CHECK(add_chains(zone, db, ver, &diff));
   21725 			CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff));
   21726 			CHECK(zone_journal(zone, zonediff.diff, NULL,
   21727 					   "zone_rekey"));
   21728 			commit = true;
   21729 		}
   21730 	}
   21731 
   21732 	dns_db_closeversion(db, &ver, true);
   21733 
   21734 	LOCK_ZONE(zone);
   21735 
   21736 	if (commit) {
   21737 		dns_difftuple_t *tuple;
   21738 		dns_stats_t *dnssecsignstats =
   21739 			dns_zone_getdnssecsignstats(zone);
   21740 
   21741 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   21742 
   21743 		zone_needdump(zone, DNS_DUMP_DELAY);
   21744 
   21745 		zone_settimer(zone, &timenow);
   21746 
   21747 		/* Remove any signatures from removed keys.  */
   21748 		if (!ISC_LIST_EMPTY(rmkeys)) {
   21749 			for (key = ISC_LIST_HEAD(rmkeys); key != NULL;
   21750 			     key = ISC_LIST_NEXT(key, link))
   21751 			{
   21752 				result = zone_signwithkey(
   21753 					zone, dst_key_alg(key->key),
   21754 					dst_key_id(key->key), true);
   21755 				if (result != ISC_R_SUCCESS) {
   21756 					dnssec_log(zone, ISC_LOG_ERROR,
   21757 						   "zone_signwithkey failed: "
   21758 						   "%s",
   21759 						   dns_result_totext(result));
   21760 				}
   21761 
   21762 				/* Clear DNSSEC sign statistics. */
   21763 				if (dnssecsignstats != NULL) {
   21764 					dns_dnssecsignstats_clear(
   21765 						dnssecsignstats,
   21766 						dst_key_id(key->key),
   21767 						dst_key_alg(key->key));
   21768 					/*
   21769 					 * Also clear the dnssec-sign
   21770 					 * statistics of the revoked key id.
   21771 					 */
   21772 					dns_dnssecsignstats_clear(
   21773 						dnssecsignstats,
   21774 						dst_key_rid(key->key),
   21775 						dst_key_alg(key->key));
   21776 				}
   21777 			}
   21778 		}
   21779 
   21780 		if (fullsign) {
   21781 			/*
   21782 			 * "rndc sign" was called, so we now sign the zone
   21783 			 * with all active keys, whether they're new or not.
   21784 			 */
   21785 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21786 			     key = ISC_LIST_NEXT(key, link))
   21787 			{
   21788 				if (!key->force_sign && !key->hint_sign) {
   21789 					continue;
   21790 				}
   21791 
   21792 				result = zone_signwithkey(
   21793 					zone, dst_key_alg(key->key),
   21794 					dst_key_id(key->key), false);
   21795 				if (result != ISC_R_SUCCESS) {
   21796 					dnssec_log(zone, ISC_LOG_ERROR,
   21797 						   "zone_signwithkey failed: "
   21798 						   "%s",
   21799 						   dns_result_totext(result));
   21800 				}
   21801 			}
   21802 		} else if (newalg) {
   21803 			/*
   21804 			 * We haven't been told to sign fully, but a new
   21805 			 * algorithm was added to the DNSKEY.  We sign
   21806 			 * the full zone, but only with newly active
   21807 			 * keys.
   21808 			 */
   21809 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21810 			     key = ISC_LIST_NEXT(key, link))
   21811 			{
   21812 				if (!key->first_sign) {
   21813 					continue;
   21814 				}
   21815 
   21816 				result = zone_signwithkey(
   21817 					zone, dst_key_alg(key->key),
   21818 					dst_key_id(key->key), false);
   21819 				if (result != ISC_R_SUCCESS) {
   21820 					dnssec_log(zone, ISC_LOG_ERROR,
   21821 						   "zone_signwithkey failed: "
   21822 						   "%s",
   21823 						   dns_result_totext(result));
   21824 				}
   21825 			}
   21826 		}
   21827 
   21828 		/*
   21829 		 * Clear fullsign flag, if it was set, so we don't do
   21830 		 * another full signing next time.
   21831 		 */
   21832 		DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN);
   21833 
   21834 		/*
   21835 		 * Cause the zone to add/delete NSEC3 chains for the
   21836 		 * deferred NSEC3PARAM changes.
   21837 		 */
   21838 		for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
   21839 		     tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link))
   21840 		{
   21841 			unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   21842 			dns_rdata_t rdata = DNS_RDATA_INIT;
   21843 			dns_rdata_nsec3param_t nsec3param;
   21844 
   21845 			if (tuple->rdata.type != zone->privatetype ||
   21846 			    tuple->op != DNS_DIFFOP_ADD)
   21847 			{
   21848 				continue;
   21849 			}
   21850 
   21851 			if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
   21852 							buf, sizeof(buf)))
   21853 			{
   21854 				continue;
   21855 			}
   21856 
   21857 			result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   21858 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   21859 			if (nsec3param.flags == 0) {
   21860 				continue;
   21861 			}
   21862 
   21863 			result = zone_addnsec3chain(zone, &nsec3param);
   21864 			if (result != ISC_R_SUCCESS) {
   21865 				dnssec_log(zone, ISC_LOG_ERROR,
   21866 					   "zone_addnsec3chain failed: %s",
   21867 					   dns_result_totext(result));
   21868 			}
   21869 		}
   21870 
   21871 		/*
   21872 		 * Activate any NSEC3 chain updates that may have
   21873 		 * been scheduled before this rekey.
   21874 		 */
   21875 		if (fullsign || newalg) {
   21876 			resume_addnsec3chain(zone);
   21877 		}
   21878 
   21879 		/*
   21880 		 * Schedule the next resigning event
   21881 		 */
   21882 		set_resigntime(zone);
   21883 	}
   21884 
   21885 	isc_time_settoepoch(&zone->refreshkeytime);
   21886 
   21887 	/*
   21888 	 * If keymgr provided a next time, use the calculated next rekey time.
   21889 	 */
   21890 	if (kasp != NULL) {
   21891 		isc_time_t timenext;
   21892 		uint32_t nexttime_seconds;
   21893 
   21894 		/*
   21895 		 * Set the key refresh timer to the next scheduled key event
   21896 		 * or to 'dnssec-loadkeys-interval' seconds in the future
   21897 		 * if no next key event is scheduled (nexttime == 0).
   21898 		 */
   21899 		if (nexttime > 0) {
   21900 			nexttime_seconds = nexttime - now;
   21901 		} else {
   21902 			nexttime_seconds = zone->refreshkeyinterval;
   21903 		}
   21904 
   21905 		DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext);
   21906 		zone->refreshkeytime = timenext;
   21907 		zone_settimer(zone, &timenow);
   21908 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   21909 
   21910 		dnssec_log(zone, ISC_LOG_DEBUG(3),
   21911 			   "next key event in %u seconds", nexttime_seconds);
   21912 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   21913 	}
   21914 	/*
   21915 	 * If we're doing key maintenance, set the key refresh timer to
   21916 	 * the next scheduled key event or to 'dnssec-loadkeys-interval'
   21917 	 * seconds in the future, whichever is sooner.
   21918 	 */
   21919 	else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   21920 	{
   21921 		isc_time_t timethen;
   21922 		isc_stdtime_t then;
   21923 
   21924 		DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
   21925 				  &timethen);
   21926 		zone->refreshkeytime = timethen;
   21927 
   21928 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21929 		     key = ISC_LIST_NEXT(key, link))
   21930 		{
   21931 			then = now;
   21932 			result = next_keyevent(key->key, &then);
   21933 			if (result != ISC_R_SUCCESS) {
   21934 				continue;
   21935 			}
   21936 
   21937 			DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   21938 			if (isc_time_compare(&timethen, &zone->refreshkeytime) <
   21939 			    0)
   21940 			{
   21941 				zone->refreshkeytime = timethen;
   21942 			}
   21943 		}
   21944 
   21945 		zone_settimer(zone, &timenow);
   21946 
   21947 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   21948 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   21949 	}
   21950 	UNLOCK_ZONE(zone);
   21951 
   21952 	if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   21953 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21954 		     key = ISC_LIST_NEXT(key, link))
   21955 		{
   21956 			/* This debug log is used in the kasp system test */
   21957 			char algbuf[DNS_SECALG_FORMATSIZE];
   21958 			dns_secalg_format(dst_key_alg(key->key), algbuf,
   21959 					  sizeof(algbuf));
   21960 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   21961 				   "zone_rekey done: key %d/%s",
   21962 				   dst_key_id(key->key), algbuf);
   21963 		}
   21964 	}
   21965 
   21966 	result = ISC_R_SUCCESS;
   21967 
   21968 failure:
   21969 	LOCK_ZONE(zone);
   21970 	if (result != ISC_R_SUCCESS) {
   21971 		/*
   21972 		 * Something went wrong; try again in ten minutes or
   21973 		 * after a key refresh interval, whichever is shorter.
   21974 		 */
   21975 		dnssec_log(zone, ISC_LOG_DEBUG(3),
   21976 			   "zone_rekey failure: %s (retry in %u seconds)",
   21977 			   isc_result_totext(result),
   21978 			   ISC_MIN(zone->refreshkeyinterval, 600));
   21979 		isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600),
   21980 				 0);
   21981 		isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
   21982 	}
   21983 	UNLOCK_ZONE(zone);
   21984 
   21985 	dns_diff_clear(&diff);
   21986 	dns_diff_clear(&_sig_diff);
   21987 
   21988 	clear_keylist(&dnskeys, mctx);
   21989 	clear_keylist(&keys, mctx);
   21990 	clear_keylist(&rmkeys, mctx);
   21991 
   21992 	if (ver != NULL) {
   21993 		dns_db_closeversion(db, &ver, false);
   21994 	}
   21995 	if (dns_rdataset_isassociated(&cdsset)) {
   21996 		dns_rdataset_disassociate(&cdsset);
   21997 	}
   21998 	if (dns_rdataset_isassociated(&keyset)) {
   21999 		dns_rdataset_disassociate(&keyset);
   22000 	}
   22001 	if (dns_rdataset_isassociated(&keysigs)) {
   22002 		dns_rdataset_disassociate(&keysigs);
   22003 	}
   22004 	if (dns_rdataset_isassociated(&soasigs)) {
   22005 		dns_rdataset_disassociate(&soasigs);
   22006 	}
   22007 	if (dns_rdataset_isassociated(&cdnskeyset)) {
   22008 		dns_rdataset_disassociate(&cdnskeyset);
   22009 	}
   22010 	if (node != NULL) {
   22011 		dns_db_detachnode(db, &node);
   22012 	}
   22013 	if (db != NULL) {
   22014 		dns_db_detach(&db);
   22015 	}
   22016 
   22017 	INSIST(ver == NULL);
   22018 }
   22019 
   22020 void
   22021 dns_zone_rekey(dns_zone_t *zone, bool fullsign) {
   22022 	isc_time_t now;
   22023 
   22024 	if (zone->type == dns_zone_primary && zone->task != NULL) {
   22025 		LOCK_ZONE(zone);
   22026 
   22027 		if (fullsign) {
   22028 			DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN);
   22029 		}
   22030 
   22031 		TIME_NOW(&now);
   22032 		zone->refreshkeytime = now;
   22033 		zone_settimer(zone, &now);
   22034 
   22035 		UNLOCK_ZONE(zone);
   22036 	}
   22037 }
   22038 
   22039 isc_result_t
   22040 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   22041 		 unsigned int *errors) {
   22042 	isc_result_t result;
   22043 	dns_dbnode_t *node = NULL;
   22044 
   22045 	REQUIRE(DNS_ZONE_VALID(zone));
   22046 	REQUIRE(errors != NULL);
   22047 
   22048 	result = dns_db_getoriginnode(db, &node);
   22049 	if (result != ISC_R_SUCCESS) {
   22050 		return (result);
   22051 	}
   22052 	result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false);
   22053 	dns_db_detachnode(db, &node);
   22054 	return (result);
   22055 }
   22056 
   22057 isc_result_t
   22058 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
   22059 	isc_result_t result;
   22060 	dns_dbnode_t *node = NULL;
   22061 	dns_rdataset_t dnskey, cds, cdnskey;
   22062 	unsigned char algorithms[256];
   22063 	unsigned int i;
   22064 	bool empty = false;
   22065 
   22066 	enum { notexpected = 0, expected = 1, found = 2 };
   22067 
   22068 	REQUIRE(DNS_ZONE_VALID(zone));
   22069 
   22070 	result = dns_db_getoriginnode(db, &node);
   22071 	if (result != ISC_R_SUCCESS) {
   22072 		return (result);
   22073 	}
   22074 
   22075 	dns_rdataset_init(&cds);
   22076 	dns_rdataset_init(&dnskey);
   22077 	dns_rdataset_init(&cdnskey);
   22078 
   22079 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
   22080 				     dns_rdatatype_none, 0, &cds, NULL);
   22081 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   22082 		goto failure;
   22083 	}
   22084 
   22085 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
   22086 				     dns_rdatatype_none, 0, &cdnskey, NULL);
   22087 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   22088 		goto failure;
   22089 	}
   22090 
   22091 	if (!dns_rdataset_isassociated(&cds) &&
   22092 	    !dns_rdataset_isassociated(&cdnskey))
   22093 	{
   22094 		result = ISC_R_SUCCESS;
   22095 		goto failure;
   22096 	}
   22097 
   22098 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   22099 				     dns_rdatatype_none, 0, &dnskey, NULL);
   22100 	if (result == ISC_R_NOTFOUND) {
   22101 		empty = true;
   22102 	} else if (result != ISC_R_SUCCESS) {
   22103 		goto failure;
   22104 	}
   22105 
   22106 	/*
   22107 	 * For each DNSSEC algorithm in the CDS RRset there must be
   22108 	 * a matching DNSKEY record with the exception of a CDS deletion
   22109 	 * record which must be by itself.
   22110 	 */
   22111 	if (dns_rdataset_isassociated(&cds)) {
   22112 		bool delete = false;
   22113 		memset(algorithms, notexpected, sizeof(algorithms));
   22114 		for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS;
   22115 		     result = dns_rdataset_next(&cds))
   22116 		{
   22117 			dns_rdata_t crdata = DNS_RDATA_INIT;
   22118 			dns_rdata_cds_t structcds;
   22119 
   22120 			dns_rdataset_current(&cds, &crdata);
   22121 			/*
   22122 			 * CDS deletion record has this form "0 0 0 00" which
   22123 			 * is 5 zero octets.
   22124 			 */
   22125 			if (crdata.length == 5U &&
   22126 			    memcmp(crdata.data,
   22127 				   (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0)
   22128 			{
   22129 				delete = true;
   22130 				continue;
   22131 			}
   22132 
   22133 			if (empty) {
   22134 				result = DNS_R_BADCDS;
   22135 				goto failure;
   22136 			}
   22137 
   22138 			CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
   22139 			if (algorithms[structcds.algorithm] == 0) {
   22140 				algorithms[structcds.algorithm] = expected;
   22141 			}
   22142 			for (result = dns_rdataset_first(&dnskey);
   22143 			     result == ISC_R_SUCCESS;
   22144 			     result = dns_rdataset_next(&dnskey))
   22145 			{
   22146 				dns_rdata_t rdata = DNS_RDATA_INIT;
   22147 				dns_rdata_dnskey_t structdnskey;
   22148 
   22149 				dns_rdataset_current(&dnskey, &rdata);
   22150 				CHECK(dns_rdata_tostruct(&rdata, &structdnskey,
   22151 							 NULL));
   22152 
   22153 				if (structdnskey.algorithm ==
   22154 				    structcds.algorithm)
   22155 				{
   22156 					algorithms[structcds.algorithm] = found;
   22157 				}
   22158 			}
   22159 			if (result != ISC_R_NOMORE) {
   22160 				goto failure;
   22161 			}
   22162 		}
   22163 		for (i = 0; i < sizeof(algorithms); i++) {
   22164 			if (delete) {
   22165 				if (algorithms[i] != notexpected) {
   22166 					result = DNS_R_BADCDS;
   22167 					goto failure;
   22168 				}
   22169 			} else if (algorithms[i] == expected) {
   22170 				result = DNS_R_BADCDS;
   22171 				goto failure;
   22172 			}
   22173 		}
   22174 	}
   22175 
   22176 	/*
   22177 	 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
   22178 	 * a matching DNSKEY record with the exception of a CDNSKEY deletion
   22179 	 * record which must be by itself.
   22180 	 */
   22181 	if (dns_rdataset_isassociated(&cdnskey)) {
   22182 		bool delete = false;
   22183 		memset(algorithms, notexpected, sizeof(algorithms));
   22184 		for (result = dns_rdataset_first(&cdnskey);
   22185 		     result == ISC_R_SUCCESS;
   22186 		     result = dns_rdataset_next(&cdnskey))
   22187 		{
   22188 			dns_rdata_t crdata = DNS_RDATA_INIT;
   22189 			dns_rdata_cdnskey_t structcdnskey;
   22190 
   22191 			dns_rdataset_current(&cdnskey, &crdata);
   22192 			/*
   22193 			 * CDNSKEY deletion record has this form
   22194 			 * "0 3 0 AA==" which is 2 zero octets, a 3,
   22195 			 * and 2 zero octets.
   22196 			 */
   22197 			if (crdata.length == 5U &&
   22198 			    memcmp(crdata.data,
   22199 				   (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0)
   22200 			{
   22201 				delete = true;
   22202 				continue;
   22203 			}
   22204 
   22205 			if (empty) {
   22206 				result = DNS_R_BADCDNSKEY;
   22207 				goto failure;
   22208 			}
   22209 
   22210 			CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
   22211 						 NULL));
   22212 			if (algorithms[structcdnskey.algorithm] == 0) {
   22213 				algorithms[structcdnskey.algorithm] = expected;
   22214 			}
   22215 			for (result = dns_rdataset_first(&dnskey);
   22216 			     result == ISC_R_SUCCESS;
   22217 			     result = dns_rdataset_next(&dnskey))
   22218 			{
   22219 				dns_rdata_t rdata = DNS_RDATA_INIT;
   22220 				dns_rdata_dnskey_t structdnskey;
   22221 
   22222 				dns_rdataset_current(&dnskey, &rdata);
   22223 				CHECK(dns_rdata_tostruct(&rdata, &structdnskey,
   22224 							 NULL));
   22225 
   22226 				if (structdnskey.algorithm ==
   22227 				    structcdnskey.algorithm)
   22228 				{
   22229 					algorithms[structcdnskey.algorithm] =
   22230 						found;
   22231 				}
   22232 			}
   22233 			if (result != ISC_R_NOMORE) {
   22234 				goto failure;
   22235 			}
   22236 		}
   22237 		for (i = 0; i < sizeof(algorithms); i++) {
   22238 			if (delete) {
   22239 				if (algorithms[i] != notexpected) {
   22240 					result = DNS_R_BADCDNSKEY;
   22241 					goto failure;
   22242 				}
   22243 			} else if (algorithms[i] == expected) {
   22244 				result = DNS_R_BADCDNSKEY;
   22245 				goto failure;
   22246 			}
   22247 		}
   22248 	}
   22249 	result = ISC_R_SUCCESS;
   22250 
   22251 failure:
   22252 	if (dns_rdataset_isassociated(&cds)) {
   22253 		dns_rdataset_disassociate(&cds);
   22254 	}
   22255 	if (dns_rdataset_isassociated(&dnskey)) {
   22256 		dns_rdataset_disassociate(&dnskey);
   22257 	}
   22258 	if (dns_rdataset_isassociated(&cdnskey)) {
   22259 		dns_rdataset_disassociate(&cdnskey);
   22260 	}
   22261 	dns_db_detachnode(db, &node);
   22262 	return (result);
   22263 }
   22264 
   22265 void
   22266 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
   22267 	REQUIRE(DNS_ZONE_VALID(zone));
   22268 
   22269 	LOCK_ZONE(zone);
   22270 	zone->automatic = automatic;
   22271 	UNLOCK_ZONE(zone);
   22272 }
   22273 
   22274 bool
   22275 dns_zone_getautomatic(dns_zone_t *zone) {
   22276 	REQUIRE(DNS_ZONE_VALID(zone));
   22277 	return (zone->automatic);
   22278 }
   22279 
   22280 void
   22281 dns_zone_setadded(dns_zone_t *zone, bool added) {
   22282 	REQUIRE(DNS_ZONE_VALID(zone));
   22283 
   22284 	LOCK_ZONE(zone);
   22285 	zone->added = added;
   22286 	UNLOCK_ZONE(zone);
   22287 }
   22288 
   22289 bool
   22290 dns_zone_getadded(dns_zone_t *zone) {
   22291 	REQUIRE(DNS_ZONE_VALID(zone));
   22292 	return (zone->added);
   22293 }
   22294 
   22295 isc_result_t
   22296 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) {
   22297 	isc_time_t loadtime;
   22298 	isc_result_t result;
   22299 	dns_zone_t *secure = NULL;
   22300 
   22301 	TIME_NOW(&loadtime);
   22302 
   22303 	/*
   22304 	 * Lock hierarchy: zmgr, zone, raw.
   22305 	 */
   22306 again:
   22307 	LOCK_ZONE(zone);
   22308 	INSIST(zone != zone->raw);
   22309 	if (inline_secure(zone)) {
   22310 		LOCK_ZONE(zone->raw);
   22311 	} else if (inline_raw(zone)) {
   22312 		secure = zone->secure;
   22313 		TRYLOCK_ZONE(result, secure);
   22314 		if (result != ISC_R_SUCCESS) {
   22315 			UNLOCK_ZONE(zone);
   22316 			secure = NULL;
   22317 			isc_thread_yield();
   22318 			goto again;
   22319 		}
   22320 	}
   22321 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   22322 	if (inline_secure(zone)) {
   22323 		UNLOCK_ZONE(zone->raw);
   22324 	} else if (secure != NULL) {
   22325 		UNLOCK_ZONE(secure);
   22326 	}
   22327 	UNLOCK_ZONE(zone);
   22328 	return (result);
   22329 }
   22330 
   22331 isc_result_t
   22332 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
   22333 	REQUIRE(DNS_ZONE_VALID(zone));
   22334 	if (interval == 0) {
   22335 		return (ISC_R_RANGE);
   22336 	}
   22337 	/* Maximum value: 24 hours (3600 minutes) */
   22338 	if (interval > (24 * 60)) {
   22339 		interval = (24 * 60);
   22340 	}
   22341 	/* Multiply by 60 for seconds */
   22342 	zone->refreshkeyinterval = interval * 60;
   22343 	return (ISC_R_SUCCESS);
   22344 }
   22345 
   22346 void
   22347 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
   22348 	REQUIRE(DNS_ZONE_VALID(zone));
   22349 	zone->requestixfr = flag;
   22350 }
   22351 
   22352 bool
   22353 dns_zone_getrequestixfr(dns_zone_t *zone) {
   22354 	REQUIRE(DNS_ZONE_VALID(zone));
   22355 	return (zone->requestixfr);
   22356 }
   22357 
   22358 void
   22359 dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) {
   22360 	REQUIRE(DNS_ZONE_VALID(zone));
   22361 	zone->ixfr_ratio = ratio;
   22362 }
   22363 
   22364 uint32_t
   22365 dns_zone_getixfrratio(dns_zone_t *zone) {
   22366 	REQUIRE(DNS_ZONE_VALID(zone));
   22367 	return (zone->ixfr_ratio);
   22368 }
   22369 
   22370 void
   22371 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
   22372 	REQUIRE(DNS_ZONE_VALID(zone));
   22373 	zone->requestexpire = flag;
   22374 }
   22375 
   22376 bool
   22377 dns_zone_getrequestexpire(dns_zone_t *zone) {
   22378 	REQUIRE(DNS_ZONE_VALID(zone));
   22379 	return (zone->requestexpire);
   22380 }
   22381 
   22382 void
   22383 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
   22384 	REQUIRE(DNS_ZONE_VALID(zone));
   22385 	zone->updatemethod = method;
   22386 }
   22387 
   22388 dns_updatemethod_t
   22389 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
   22390 	REQUIRE(DNS_ZONE_VALID(zone));
   22391 	return (zone->updatemethod);
   22392 }
   22393 
   22394 /*
   22395  * Lock hierarchy: zmgr, zone, raw.
   22396  */
   22397 isc_result_t
   22398 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
   22399 	isc_result_t result;
   22400 	dns_zonemgr_t *zmgr;
   22401 
   22402 	REQUIRE(DNS_ZONE_VALID(zone));
   22403 	REQUIRE(zone->zmgr != NULL);
   22404 	REQUIRE(zone->task != NULL);
   22405 	REQUIRE(zone->loadtask != NULL);
   22406 	REQUIRE(zone->raw == NULL);
   22407 
   22408 	REQUIRE(DNS_ZONE_VALID(raw));
   22409 	REQUIRE(raw->zmgr == NULL);
   22410 	REQUIRE(raw->task == NULL);
   22411 	REQUIRE(raw->loadtask == NULL);
   22412 	REQUIRE(raw->secure == NULL);
   22413 
   22414 	REQUIRE(zone != raw);
   22415 
   22416 	/*
   22417 	 * Lock hierarchy: zmgr, zone, raw.
   22418 	 */
   22419 	zmgr = zone->zmgr;
   22420 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   22421 	LOCK_ZONE(zone);
   22422 	LOCK_ZONE(raw);
   22423 
   22424 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   22425 				  NULL, zone->task, zone_timer, raw,
   22426 				  &raw->timer);
   22427 	if (result != ISC_R_SUCCESS) {
   22428 		goto unlock;
   22429 	}
   22430 
   22431 	/*
   22432 	 * The timer "holds" a iref.
   22433 	 */
   22434 	isc_refcount_increment0(&raw->irefs);
   22435 
   22436 	/* dns_zone_attach(raw, &zone->raw); */
   22437 	isc_refcount_increment(&raw->erefs);
   22438 	zone->raw = raw;
   22439 
   22440 	/* dns_zone_iattach(zone,  &raw->secure); */
   22441 	zone_iattach(zone, &raw->secure);
   22442 
   22443 	isc_task_attach(zone->task, &raw->task);
   22444 	isc_task_attach(zone->loadtask, &raw->loadtask);
   22445 
   22446 	ISC_LIST_APPEND(zmgr->zones, raw, link);
   22447 	raw->zmgr = zmgr;
   22448 	isc_refcount_increment(&zmgr->refs);
   22449 
   22450 unlock:
   22451 	UNLOCK_ZONE(raw);
   22452 	UNLOCK_ZONE(zone);
   22453 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   22454 	return (result);
   22455 }
   22456 
   22457 void
   22458 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
   22459 	REQUIRE(DNS_ZONE_VALID(zone));
   22460 	REQUIRE(raw != NULL && *raw == NULL);
   22461 
   22462 	LOCK(&zone->lock);
   22463 	INSIST(zone != zone->raw);
   22464 	if (zone->raw != NULL) {
   22465 		dns_zone_attach(zone->raw, raw);
   22466 	}
   22467 	UNLOCK(&zone->lock);
   22468 }
   22469 
   22470 struct keydone {
   22471 	isc_event_t event;
   22472 	bool all;
   22473 	unsigned char data[5];
   22474 };
   22475 
   22476 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL)
   22477 
   22478 static void
   22479 keydone(isc_task_t *task, isc_event_t *event) {
   22480 	const char *me = "keydone";
   22481 	bool commit = false;
   22482 	isc_result_t result;
   22483 	dns_rdata_t rdata = DNS_RDATA_INIT;
   22484 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   22485 	dns_zone_t *zone;
   22486 	dns_db_t *db = NULL;
   22487 	dns_dbnode_t *node = NULL;
   22488 	dns_rdataset_t rdataset;
   22489 	dns_diff_t diff;
   22490 	struct keydone *kd = (struct keydone *)event;
   22491 	dns_update_log_t log = { update_log_cb, NULL };
   22492 	bool clear_pending = false;
   22493 
   22494 	UNUSED(task);
   22495 
   22496 	zone = event->ev_arg;
   22497 	INSIST(DNS_ZONE_VALID(zone));
   22498 
   22499 	ENTER;
   22500 
   22501 	dns_rdataset_init(&rdataset);
   22502 	dns_diff_init(zone->mctx, &diff);
   22503 
   22504 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   22505 	if (zone->db != NULL) {
   22506 		dns_db_attach(zone->db, &db);
   22507 	}
   22508 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   22509 	if (db == NULL) {
   22510 		goto failure;
   22511 	}
   22512 
   22513 	dns_db_currentversion(db, &oldver);
   22514 	result = dns_db_newversion(db, &newver);
   22515 	if (result != ISC_R_SUCCESS) {
   22516 		dnssec_log(zone, ISC_LOG_ERROR,
   22517 			   "keydone:dns_db_newversion -> %s",
   22518 			   dns_result_totext(result));
   22519 		goto failure;
   22520 	}
   22521 
   22522 	result = dns_db_getoriginnode(db, &node);
   22523 	if (result != ISC_R_SUCCESS) {
   22524 		goto failure;
   22525 	}
   22526 
   22527 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   22528 				     dns_rdatatype_none, 0, &rdataset, NULL);
   22529 	if (result == ISC_R_NOTFOUND) {
   22530 		INSIST(!dns_rdataset_isassociated(&rdataset));
   22531 		goto failure;
   22532 	}
   22533 	if (result != ISC_R_SUCCESS) {
   22534 		INSIST(!dns_rdataset_isassociated(&rdataset));
   22535 		goto failure;
   22536 	}
   22537 
   22538 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   22539 	     result = dns_rdataset_next(&rdataset))
   22540 	{
   22541 		bool found = false;
   22542 
   22543 		dns_rdataset_current(&rdataset, &rdata);
   22544 
   22545 		if (kd->all) {
   22546 			if (rdata.length == 5 && rdata.data[0] != 0 &&
   22547 			    rdata.data[3] == 0 && rdata.data[4] == 1)
   22548 			{
   22549 				found = true;
   22550 			} else if (rdata.data[0] == 0 &&
   22551 				   (rdata.data[2] & PENDINGFLAGS) != 0)
   22552 			{
   22553 				found = true;
   22554 				clear_pending = true;
   22555 			}
   22556 		} else if (rdata.length == 5 &&
   22557 			   memcmp(rdata.data, kd->data, 5) == 0)
   22558 		{
   22559 			found = true;
   22560 		}
   22561 
   22562 		if (found) {
   22563 			CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
   22564 					    &zone->origin, rdataset.ttl,
   22565 					    &rdata));
   22566 		}
   22567 		dns_rdata_reset(&rdata);
   22568 	}
   22569 
   22570 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   22571 		/* Write changes to journal file. */
   22572 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   22573 					zone->updatemethod));
   22574 
   22575 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   22576 					       &diff,
   22577 					       zone->sigvalidityinterval);
   22578 		if (!clear_pending) {
   22579 			CHECK(result);
   22580 		}
   22581 
   22582 		CHECK(zone_journal(zone, &diff, NULL, "keydone"));
   22583 		commit = true;
   22584 
   22585 		LOCK_ZONE(zone);
   22586 		DNS_ZONE_SETFLAG(zone,
   22587 				 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   22588 		zone_needdump(zone, 30);
   22589 		UNLOCK_ZONE(zone);
   22590 	}
   22591 
   22592 failure:
   22593 	if (dns_rdataset_isassociated(&rdataset)) {
   22594 		dns_rdataset_disassociate(&rdataset);
   22595 	}
   22596 	if (db != NULL) {
   22597 		if (node != NULL) {
   22598 			dns_db_detachnode(db, &node);
   22599 		}
   22600 		if (oldver != NULL) {
   22601 			dns_db_closeversion(db, &oldver, false);
   22602 		}
   22603 		if (newver != NULL) {
   22604 			dns_db_closeversion(db, &newver, commit);
   22605 		}
   22606 		dns_db_detach(&db);
   22607 	}
   22608 	dns_diff_clear(&diff);
   22609 	isc_event_free(&event);
   22610 	dns_zone_idetach(&zone);
   22611 
   22612 	INSIST(oldver == NULL);
   22613 	INSIST(newver == NULL);
   22614 }
   22615 
   22616 isc_result_t
   22617 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
   22618 	isc_result_t result = ISC_R_SUCCESS;
   22619 	isc_event_t *e;
   22620 	isc_buffer_t b;
   22621 	dns_zone_t *dummy = NULL;
   22622 	struct keydone *kd;
   22623 
   22624 	REQUIRE(DNS_ZONE_VALID(zone));
   22625 
   22626 	LOCK_ZONE(zone);
   22627 
   22628 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
   22629 			       zone, sizeof(struct keydone));
   22630 
   22631 	kd = (struct keydone *)e;
   22632 	if (strcasecmp(keystr, "all") == 0) {
   22633 		kd->all = true;
   22634 	} else {
   22635 		isc_textregion_t r;
   22636 		const char *algstr;
   22637 		dns_keytag_t keyid;
   22638 		dns_secalg_t alg;
   22639 		size_t n;
   22640 
   22641 		kd->all = false;
   22642 
   22643 		n = sscanf(keystr, "%hu/", &keyid);
   22644 		if (n == 0U) {
   22645 			CHECK(ISC_R_FAILURE);
   22646 		}
   22647 
   22648 		algstr = strchr(keystr, '/');
   22649 		if (algstr != NULL) {
   22650 			algstr++;
   22651 		} else {
   22652 			CHECK(ISC_R_FAILURE);
   22653 		}
   22654 
   22655 		n = sscanf(algstr, "%hhu", &alg);
   22656 		if (n == 0U) {
   22657 			DE_CONST(algstr, r.base);
   22658 			r.length = strlen(algstr);
   22659 			CHECK(dns_secalg_fromtext(&alg, &r));
   22660 		}
   22661 
   22662 		/* construct a private-type rdata */
   22663 		isc_buffer_init(&b, kd->data, sizeof(kd->data));
   22664 		isc_buffer_putuint8(&b, alg);
   22665 		isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
   22666 		isc_buffer_putuint8(&b, (keyid & 0xff));
   22667 		isc_buffer_putuint8(&b, 0);
   22668 		isc_buffer_putuint8(&b, 1);
   22669 	}
   22670 
   22671 	zone_iattach(zone, &dummy);
   22672 	isc_task_send(zone->task, &e);
   22673 
   22674 failure:
   22675 	if (e != NULL) {
   22676 		isc_event_free(&e);
   22677 	}
   22678 	UNLOCK_ZONE(zone);
   22679 	return (result);
   22680 }
   22681 
   22682 /*
   22683  * Called from the zone task's queue after the relevant event is posted by
   22684  * dns_zone_setnsec3param().
   22685  */
   22686 static void
   22687 setnsec3param(isc_task_t *task, isc_event_t *event) {
   22688 	const char *me = "setnsec3param";
   22689 	dns_zone_t *zone = event->ev_arg;
   22690 	bool loadpending;
   22691 
   22692 	INSIST(DNS_ZONE_VALID(zone));
   22693 
   22694 	UNUSED(task);
   22695 
   22696 	ENTER;
   22697 
   22698 	LOCK_ZONE(zone);
   22699 	loadpending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
   22700 	UNLOCK_ZONE(zone);
   22701 
   22702 	/*
   22703 	 * If receive_secure_serial is still processing or we have a
   22704 	 * queued event append rss_post queue.
   22705 	 */
   22706 	if (zone->rss_newver != NULL || ISC_LIST_HEAD(zone->rss_post) != NULL) {
   22707 		/*
   22708 		 * Wait for receive_secure_serial() to finish processing.
   22709 		 */
   22710 		ISC_LIST_APPEND(zone->rss_post, event, ev_link);
   22711 	} else {
   22712 		bool rescheduled = false;
   22713 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   22714 		/*
   22715 		 * The zone is not yet fully loaded. Reschedule the event to
   22716 		 * be picked up later. This turns this function into a busy
   22717 		 * wait, but it only happens at startup.
   22718 		 */
   22719 		if (zone->db == NULL && loadpending) {
   22720 			rescheduled = true;
   22721 			isc_task_send(task, &event);
   22722 		}
   22723 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   22724 		if (rescheduled) {
   22725 			return;
   22726 		}
   22727 
   22728 		rss_post(zone, event);
   22729 	}
   22730 	dns_zone_idetach(&zone);
   22731 }
   22732 
   22733 static void
   22734 salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text,
   22735 	  unsigned int textlen) {
   22736 	isc_region_t r;
   22737 	isc_buffer_t buf;
   22738 	isc_result_t result;
   22739 
   22740 	r.base = salt;
   22741 	r.length = (unsigned int)saltlen;
   22742 
   22743 	isc_buffer_init(&buf, text, textlen);
   22744 	result = isc_hex_totext(&r, 2, "", &buf);
   22745 	if (result == ISC_R_SUCCESS) {
   22746 		text[saltlen * 2] = 0;
   22747 	} else {
   22748 		text[0] = 0;
   22749 	}
   22750 }
   22751 
   22752 /*
   22753  * Check whether NSEC3 chain addition or removal specified by the private-type
   22754  * record passed with the event was already queued (or even fully performed).
   22755  * If not, modify the relevant private-type records at the zone apex and call
   22756  * resume_addnsec3chain().
   22757  */
   22758 static void
   22759 rss_post(dns_zone_t *zone, isc_event_t *event) {
   22760 	const char *me = "rss_post";
   22761 	bool commit = false;
   22762 	isc_result_t result;
   22763 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   22764 	dns_db_t *db = NULL;
   22765 	dns_dbnode_t *node = NULL;
   22766 	dns_rdataset_t prdataset, nrdataset;
   22767 	dns_diff_t diff;
   22768 	struct np3event *npe = (struct np3event *)event;
   22769 	nsec3param_t *np;
   22770 	dns_update_log_t log = { update_log_cb, NULL };
   22771 	dns_rdata_t rdata;
   22772 	bool nseconly;
   22773 	bool exists = false;
   22774 
   22775 	ENTER;
   22776 
   22777 	np = &npe->params;
   22778 
   22779 	dns_rdataset_init(&prdataset);
   22780 	dns_rdataset_init(&nrdataset);
   22781 	dns_diff_init(zone->mctx, &diff);
   22782 
   22783 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   22784 	if (zone->db != NULL) {
   22785 		dns_db_attach(zone->db, &db);
   22786 	}
   22787 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   22788 	if (db == NULL) {
   22789 		goto failure;
   22790 	}
   22791 
   22792 	dns_db_currentversion(db, &oldver);
   22793 	result = dns_db_newversion(db, &newver);
   22794 	if (result != ISC_R_SUCCESS) {
   22795 		dnssec_log(zone, ISC_LOG_ERROR,
   22796 			   "setnsec3param:dns_db_newversion -> %s",
   22797 			   dns_result_totext(result));
   22798 		goto failure;
   22799 	}
   22800 
   22801 	CHECK(dns_db_getoriginnode(db, &node));
   22802 
   22803 	/*
   22804 	 * Do we need to look up the NSEC3 parameters?
   22805 	 */
   22806 	if (np->lookup) {
   22807 		dns_rdata_nsec3param_t param;
   22808 		dns_rdata_t nrdata = DNS_RDATA_INIT;
   22809 		dns_rdata_t prdata = DNS_RDATA_INIT;
   22810 		unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
   22811 		unsigned char saltbuf[255];
   22812 		isc_buffer_t b;
   22813 
   22814 		param.salt = NULL;
   22815 		result = dns__zone_lookup_nsec3param(zone, &np->rdata, &param,
   22816 						     saltbuf, np->resalt);
   22817 		if (result == ISC_R_SUCCESS) {
   22818 			/*
   22819 			 * Success because the NSEC3PARAM already exists, but
   22820 			 * function returns void, so goto failure to clean up.
   22821 			 */
   22822 			goto failure;
   22823 		}
   22824 		if (result != DNS_R_NSEC3RESALT && result != ISC_R_NOTFOUND) {
   22825 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   22826 				   "setnsec3param:lookup nsec3param -> %s",
   22827 				   isc_result_totext(result));
   22828 			goto failure;
   22829 		}
   22830 
   22831 		INSIST(param.salt != NULL);
   22832 
   22833 		/* Update NSEC3 parameters. */
   22834 		np->rdata.hash = param.hash;
   22835 		np->rdata.flags = param.flags;
   22836 		np->rdata.iterations = param.iterations;
   22837 		np->rdata.salt_length = param.salt_length;
   22838 		np->rdata.salt = param.salt;
   22839 
   22840 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
   22841 		CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
   22842 					   dns_rdatatype_nsec3param, &np->rdata,
   22843 					   &b));
   22844 		dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
   22845 					 np->data, sizeof(np->data));
   22846 		np->length = prdata.length;
   22847 		np->nsec = false;
   22848 	}
   22849 
   22850 	/*
   22851 	 * Does a private-type record already exist for this chain?
   22852 	 */
   22853 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   22854 				     dns_rdatatype_none, 0, &prdataset, NULL);
   22855 	if (result == ISC_R_SUCCESS) {
   22856 		for (result = dns_rdataset_first(&prdataset);
   22857 		     result == ISC_R_SUCCESS;
   22858 		     result = dns_rdataset_next(&prdataset))
   22859 		{
   22860 			dns_rdata_init(&rdata);
   22861 			dns_rdataset_current(&prdataset, &rdata);
   22862 
   22863 			if (np->length == rdata.length &&
   22864 			    memcmp(rdata.data, np->data, np->length) == 0)
   22865 			{
   22866 				exists = true;
   22867 				break;
   22868 			}
   22869 		}
   22870 	} else if (result != ISC_R_NOTFOUND) {
   22871 		INSIST(!dns_rdataset_isassociated(&prdataset));
   22872 		goto failure;
   22873 	}
   22874 
   22875 	/*
   22876 	 * Does the chain already exist?
   22877 	 */
   22878 	result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param,
   22879 				     dns_rdatatype_none, 0, &nrdataset, NULL);
   22880 	if (result == ISC_R_SUCCESS) {
   22881 		for (result = dns_rdataset_first(&nrdataset);
   22882 		     result == ISC_R_SUCCESS;
   22883 		     result = dns_rdataset_next(&nrdataset))
   22884 		{
   22885 			dns_rdata_init(&rdata);
   22886 			dns_rdataset_current(&nrdataset, &rdata);
   22887 
   22888 			if (np->length == (rdata.length + 1) &&
   22889 			    memcmp(rdata.data, np->data + 1, np->length - 1) ==
   22890 				    0)
   22891 			{
   22892 				exists = true;
   22893 				break;
   22894 			}
   22895 		}
   22896 	} else if (result != ISC_R_NOTFOUND) {
   22897 		INSIST(!dns_rdataset_isassociated(&nrdataset));
   22898 		goto failure;
   22899 	}
   22900 
   22901 	/*
   22902 	 * We need to remove any existing NSEC3 chains if the supplied NSEC3
   22903 	 * parameters are supposed to replace the current ones or if we are
   22904 	 * switching to NSEC.
   22905 	 */
   22906 	if (!exists && np->replace && (np->length != 0 || np->nsec)) {
   22907 		CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec,
   22908 						  &diff));
   22909 	}
   22910 
   22911 	if (!exists && np->length != 0) {
   22912 		/*
   22913 		 * We're creating an NSEC3 chain.  Add the private-type record
   22914 		 * passed in the event handler's argument to the zone apex.
   22915 		 *
   22916 		 * If the zone is not currently capable of supporting an NSEC3
   22917 		 * chain (due to the DNSKEY RRset at the zone apex not existing
   22918 		 * or containing at least one key using an NSEC-only
   22919 		 * algorithm), add the INITIAL flag, so these parameters can be
   22920 		 * used later when NSEC3 becomes available.
   22921 		 */
   22922 		dns_rdata_init(&rdata);
   22923 
   22924 		np->data[2] |= DNS_NSEC3FLAG_CREATE;
   22925 		result = dns_nsec_nseconly(db, newver, &nseconly);
   22926 		if (result == ISC_R_NOTFOUND || nseconly) {
   22927 			np->data[2] |= DNS_NSEC3FLAG_INITIAL;
   22928 		}
   22929 
   22930 		rdata.length = np->length;
   22931 		rdata.data = np->data;
   22932 		rdata.type = zone->privatetype;
   22933 		rdata.rdclass = zone->rdclass;
   22934 		CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
   22935 				    &zone->origin, 0, &rdata));
   22936 	}
   22937 
   22938 	/*
   22939 	 * If we changed anything in the zone, write changes to journal file
   22940 	 * and set commit to true so that resume_addnsec3chain() will be
   22941 	 * called below in order to kick off adding/removing relevant NSEC3
   22942 	 * records.
   22943 	 */
   22944 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   22945 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   22946 					zone->updatemethod));
   22947 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   22948 					       &diff,
   22949 					       zone->sigvalidityinterval);
   22950 		if (result != ISC_R_NOTFOUND) {
   22951 			CHECK(result);
   22952 		}
   22953 		CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
   22954 		commit = true;
   22955 
   22956 		LOCK_ZONE(zone);
   22957 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   22958 		zone_needdump(zone, 30);
   22959 		UNLOCK_ZONE(zone);
   22960 	}
   22961 
   22962 failure:
   22963 	if (dns_rdataset_isassociated(&prdataset)) {
   22964 		dns_rdataset_disassociate(&prdataset);
   22965 	}
   22966 	if (dns_rdataset_isassociated(&nrdataset)) {
   22967 		dns_rdataset_disassociate(&nrdataset);
   22968 	}
   22969 	if (node != NULL) {
   22970 		dns_db_detachnode(db, &node);
   22971 	}
   22972 	if (oldver != NULL) {
   22973 		dns_db_closeversion(db, &oldver, false);
   22974 	}
   22975 	if (newver != NULL) {
   22976 		dns_db_closeversion(db, &newver, commit);
   22977 	}
   22978 	if (db != NULL) {
   22979 		dns_db_detach(&db);
   22980 	}
   22981 	if (commit) {
   22982 		LOCK_ZONE(zone);
   22983 		resume_addnsec3chain(zone);
   22984 		UNLOCK_ZONE(zone);
   22985 	}
   22986 	dns_diff_clear(&diff);
   22987 	isc_event_free(&event);
   22988 
   22989 	INSIST(oldver == NULL);
   22990 	INSIST(newver == NULL);
   22991 }
   22992 
   22993 /*
   22994  * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters.
   22995  *
   22996  * If 'salt' is NULL, a match is found if the salt has the requested length,
   22997  * otherwise the NSEC3 salt must match the requested salt value too.
   22998  *
   22999  * Returns  ISC_R_SUCCESS, if a match is found, or an error if no match is
   23000  * found, or if the db lookup failed.
   23001  */
   23002 isc_result_t
   23003 dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup,
   23004 			    dns_rdata_nsec3param_t *param,
   23005 			    unsigned char saltbuf[255], bool resalt) {
   23006 	isc_result_t result = ISC_R_UNEXPECTED;
   23007 	dns_dbnode_t *node = NULL;
   23008 	dns_db_t *db = NULL;
   23009 	dns_dbversion_t *version = NULL;
   23010 	dns_rdataset_t rdataset;
   23011 	dns_rdata_nsec3param_t nsec3param;
   23012 	dns_rdata_t rdata = DNS_RDATA_INIT;
   23013 
   23014 	REQUIRE(DNS_ZONE_VALID(zone));
   23015 
   23016 	dns_rdataset_init(&rdataset);
   23017 
   23018 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   23019 	if (zone->db != NULL) {
   23020 		dns_db_attach(zone->db, &db);
   23021 	}
   23022 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   23023 	if (db == NULL) {
   23024 		result = ISC_R_FAILURE;
   23025 		goto setparam;
   23026 	}
   23027 
   23028 	result = dns_db_findnode(db, &zone->origin, false, &node);
   23029 	if (result != ISC_R_SUCCESS) {
   23030 		dns_zone_log(zone, ISC_LOG_ERROR,
   23031 			     "dns__zone_lookup_nsec3param:"
   23032 			     "dns_db_findnode -> %s",
   23033 			     dns_result_totext(result));
   23034 		result = ISC_R_FAILURE;
   23035 		goto setparam;
   23036 	}
   23037 	dns_db_currentversion(db, &version);
   23038 
   23039 	result = dns_db_findrdataset(db, node, version,
   23040 				     dns_rdatatype_nsec3param,
   23041 				     dns_rdatatype_none, 0, &rdataset, NULL);
   23042 	if (result != ISC_R_SUCCESS) {
   23043 		INSIST(!dns_rdataset_isassociated(&rdataset));
   23044 		if (result != ISC_R_NOTFOUND) {
   23045 			dns_zone_log(zone, ISC_LOG_ERROR,
   23046 				     "dns__zone_lookup_nsec3param:"
   23047 				     "dns_db_findrdataset -> %s",
   23048 				     dns_result_totext(result));
   23049 		}
   23050 		goto setparam;
   23051 	}
   23052 
   23053 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   23054 	     result = dns_rdataset_next(&rdataset))
   23055 	{
   23056 		dns_rdataset_current(&rdataset, &rdata);
   23057 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   23058 		INSIST(result == ISC_R_SUCCESS);
   23059 		dns_rdata_reset(&rdata);
   23060 
   23061 		/* Check parameters. */
   23062 		if (nsec3param.hash != lookup->hash) {
   23063 			continue;
   23064 		}
   23065 		if (nsec3param.iterations != lookup->iterations) {
   23066 			continue;
   23067 		}
   23068 		if (nsec3param.salt_length != lookup->salt_length) {
   23069 			continue;
   23070 		}
   23071 		if (lookup->salt != NULL) {
   23072 			if (memcmp(nsec3param.salt, lookup->salt,
   23073 				   lookup->salt_length) != 0)
   23074 			{
   23075 				continue;
   23076 			}
   23077 		}
   23078 		/* Found a match. */
   23079 		result = ISC_R_SUCCESS;
   23080 		param->hash = nsec3param.hash;
   23081 		param->flags = nsec3param.flags;
   23082 		param->iterations = nsec3param.iterations;
   23083 		param->salt_length = nsec3param.salt_length;
   23084 		param->salt = nsec3param.salt;
   23085 		break;
   23086 	}
   23087 
   23088 	if (result == ISC_R_NOMORE) {
   23089 		result = ISC_R_NOTFOUND;
   23090 	}
   23091 
   23092 setparam:
   23093 	if (result != ISC_R_SUCCESS) {
   23094 		/* Found no match. */
   23095 		param->hash = lookup->hash;
   23096 		param->flags = lookup->flags;
   23097 		param->iterations = lookup->iterations;
   23098 		param->salt_length = lookup->salt_length;
   23099 		param->salt = lookup->salt;
   23100 	}
   23101 
   23102 	if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) {
   23103 		goto failure;
   23104 	}
   23105 
   23106 	if (param->salt_length == 0) {
   23107 		DE_CONST("-", param->salt);
   23108 	} else if (resalt || param->salt == NULL) {
   23109 		unsigned char *newsalt;
   23110 		unsigned char salttext[255 * 2 + 1];
   23111 		do {
   23112 			/* Generate a new salt. */
   23113 			result = dns_nsec3_generate_salt(saltbuf,
   23114 							 param->salt_length);
   23115 			if (result != ISC_R_SUCCESS) {
   23116 				break;
   23117 			}
   23118 			newsalt = saltbuf;
   23119 			salt2text(newsalt, param->salt_length, salttext,
   23120 				  sizeof(salttext));
   23121 			dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s",
   23122 				   salttext);
   23123 			/* Check for salt conflict. */
   23124 			if (param->salt != NULL &&
   23125 			    memcmp(newsalt, param->salt, param->salt_length) ==
   23126 				    0)
   23127 			{
   23128 				result = ISC_R_SUCCESS;
   23129 			} else {
   23130 				param->salt = newsalt;
   23131 				result = DNS_R_NSEC3RESALT;
   23132 			}
   23133 		} while (result == ISC_R_SUCCESS);
   23134 
   23135 		INSIST(result != ISC_R_SUCCESS);
   23136 	}
   23137 
   23138 failure:
   23139 	if (dns_rdataset_isassociated(&rdataset)) {
   23140 		dns_rdataset_disassociate(&rdataset);
   23141 	}
   23142 	if (node != NULL) {
   23143 		dns_db_detachnode(db, &node);
   23144 	}
   23145 	if (version != NULL) {
   23146 		dns_db_closeversion(db, &version, false);
   23147 	}
   23148 	if (db != NULL) {
   23149 		dns_db_detach(&db);
   23150 	}
   23151 
   23152 	return (result);
   23153 }
   23154 
   23155 /*
   23156  * Called when an "rndc signing -nsec3param ..." command is received, or the
   23157  * 'dnssec-policy' has changed.
   23158  *
   23159  * Allocate and prepare an nsec3param_t structure which holds information about
   23160  * the NSEC3 changes requested for the zone:
   23161  *
   23162  *   - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec"
   23163  *     field of the structure to true and the "replace" field to the value
   23164  *     of the "replace" argument, leaving other fields initialized to zeros, to
   23165  *     signal that the zone should be signed using NSEC instead of NSEC3,
   23166  *
   23167  *   - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at
   23168  *     the zone apex, convert it to a private-type record and store the latter
   23169  *     in the "data" field of the nsec3param_t structure.
   23170  *
   23171  * Once the nsec3param_t structure is prepared, post an event to the zone's
   23172  * task which will cause setnsec3param() to be called with the prepared
   23173  * structure passed as an argument.
   23174  */
   23175 isc_result_t
   23176 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags,
   23177 		       uint16_t iter, uint8_t saltlen, unsigned char *salt,
   23178 		       bool replace, bool resalt) {
   23179 	isc_result_t result = ISC_R_SUCCESS;
   23180 	dns_rdata_nsec3param_t param, lookup;
   23181 	dns_rdata_t nrdata = DNS_RDATA_INIT;
   23182 	dns_rdata_t prdata = DNS_RDATA_INIT;
   23183 	unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
   23184 	unsigned char saltbuf[255];
   23185 	struct np3event *npe;
   23186 	nsec3param_t *np;
   23187 	dns_zone_t *dummy = NULL;
   23188 	isc_buffer_t b;
   23189 	isc_event_t *e = NULL;
   23190 	bool do_lookup = false;
   23191 
   23192 	REQUIRE(DNS_ZONE_VALID(zone));
   23193 
   23194 	LOCK_ZONE(zone);
   23195 
   23196 	/*
   23197 	 * First check if the requested NSEC3 parameters are already set,
   23198 	 * if so, no need to set again.
   23199 	 */
   23200 	if (hash != 0) {
   23201 		lookup.hash = hash;
   23202 		lookup.flags = flags;
   23203 		lookup.iterations = iter;
   23204 		lookup.salt_length = saltlen;
   23205 		lookup.salt = salt;
   23206 		param.salt = NULL;
   23207 		result = dns__zone_lookup_nsec3param(zone, &lookup, &param,
   23208 						     saltbuf, resalt);
   23209 		if (result == ISC_R_SUCCESS) {
   23210 			UNLOCK_ZONE(zone);
   23211 			return (ISC_R_SUCCESS);
   23212 		}
   23213 		/*
   23214 		 * Schedule lookup if lookup above failed (may happen if zone
   23215 		 * db is NULL for example).
   23216 		 */
   23217 		do_lookup = (param.salt == NULL) ? true : false;
   23218 	}
   23219 
   23220 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
   23221 			       setnsec3param, zone, sizeof(struct np3event));
   23222 
   23223 	npe = (struct np3event *)e;
   23224 	np = &npe->params;
   23225 	np->replace = replace;
   23226 	np->resalt = resalt;
   23227 	np->lookup = do_lookup;
   23228 	if (hash == 0) {
   23229 		np->length = 0;
   23230 		np->nsec = true;
   23231 		dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec");
   23232 	} else {
   23233 		param.common.rdclass = zone->rdclass;
   23234 		param.common.rdtype = dns_rdatatype_nsec3param;
   23235 		ISC_LINK_INIT(&param.common, link);
   23236 		param.mctx = NULL;
   23237 		/* nsec3 specific param set in dns__zone_lookup_nsec3param() */
   23238 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
   23239 
   23240 		if (param.salt != NULL) {
   23241 			CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
   23242 						   dns_rdatatype_nsec3param,
   23243 						   &param, &b));
   23244 			dns_nsec3param_toprivate(&nrdata, &prdata,
   23245 						 zone->privatetype, np->data,
   23246 						 sizeof(np->data));
   23247 			np->length = prdata.length;
   23248 		}
   23249 
   23250 		np->rdata = param;
   23251 		np->nsec = false;
   23252 
   23253 		if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   23254 			unsigned char salttext[255 * 2 + 1];
   23255 			if (param.salt != NULL) {
   23256 				salt2text(param.salt, param.salt_length,
   23257 					  salttext, sizeof(salttext));
   23258 			}
   23259 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   23260 				   "setnsec3param:nsec3 %u %u %u %u:%s",
   23261 				   param.hash, param.flags, param.iterations,
   23262 				   param.salt_length,
   23263 				   param.salt == NULL ? "unknown"
   23264 						      : (char *)salttext);
   23265 		}
   23266 	}
   23267 
   23268 	/*
   23269 	 * setnsec3param() will silently return early if the zone does not yet
   23270 	 * have a database.  Prevent that by queueing the event up if zone->db
   23271 	 * is NULL.  All events queued here are subsequently processed by
   23272 	 * receive_secure_db() if it ever gets called or simply freed by
   23273 	 * zone_free() otherwise.
   23274 	 */
   23275 
   23276 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   23277 	if (zone->db != NULL) {
   23278 		zone_iattach(zone, &dummy);
   23279 		isc_task_send(zone->task, &e);
   23280 	} else {
   23281 		ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link);
   23282 		e = NULL;
   23283 	}
   23284 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   23285 
   23286 	result = ISC_R_SUCCESS;
   23287 
   23288 failure:
   23289 	if (e != NULL) {
   23290 		isc_event_free(&e);
   23291 	}
   23292 	UNLOCK_ZONE(zone);
   23293 	return (result);
   23294 }
   23295 
   23296 isc_result_t
   23297 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
   23298 	REQUIRE(DNS_ZONE_VALID(zone));
   23299 	REQUIRE(loadtime != NULL);
   23300 
   23301 	LOCK_ZONE(zone);
   23302 	*loadtime = zone->loadtime;
   23303 	UNLOCK_ZONE(zone);
   23304 	return (ISC_R_SUCCESS);
   23305 }
   23306 
   23307 isc_result_t
   23308 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
   23309 	REQUIRE(DNS_ZONE_VALID(zone));
   23310 	REQUIRE(expiretime != NULL);
   23311 
   23312 	LOCK_ZONE(zone);
   23313 	*expiretime = zone->expiretime;
   23314 	UNLOCK_ZONE(zone);
   23315 	return (ISC_R_SUCCESS);
   23316 }
   23317 
   23318 isc_result_t
   23319 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
   23320 	REQUIRE(DNS_ZONE_VALID(zone));
   23321 	REQUIRE(refreshtime != NULL);
   23322 
   23323 	LOCK_ZONE(zone);
   23324 	*refreshtime = zone->refreshtime;
   23325 	UNLOCK_ZONE(zone);
   23326 	return (ISC_R_SUCCESS);
   23327 }
   23328 
   23329 isc_result_t
   23330 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
   23331 	REQUIRE(DNS_ZONE_VALID(zone));
   23332 	REQUIRE(refreshkeytime != NULL);
   23333 
   23334 	LOCK_ZONE(zone);
   23335 	*refreshkeytime = zone->refreshkeytime;
   23336 	UNLOCK_ZONE(zone);
   23337 	return (ISC_R_SUCCESS);
   23338 }
   23339 
   23340 unsigned int
   23341 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
   23342 	dns_include_t *include;
   23343 	char **array = NULL;
   23344 	unsigned int n = 0;
   23345 
   23346 	REQUIRE(DNS_ZONE_VALID(zone));
   23347 	REQUIRE(includesp != NULL && *includesp == NULL);
   23348 
   23349 	LOCK_ZONE(zone);
   23350 	if (zone->nincludes == 0) {
   23351 		goto done;
   23352 	}
   23353 
   23354 	array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
   23355 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   23356 	     include = ISC_LIST_NEXT(include, link))
   23357 	{
   23358 		INSIST(n < zone->nincludes);
   23359 		array[n++] = isc_mem_strdup(zone->mctx, include->name);
   23360 	}
   23361 	INSIST(n == zone->nincludes);
   23362 	*includesp = array;
   23363 
   23364 done:
   23365 	UNLOCK_ZONE(zone);
   23366 	return (n);
   23367 }
   23368 
   23369 void
   23370 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
   23371 	REQUIRE(DNS_ZONE_VALID(zone));
   23372 
   23373 	zone->statlevel = level;
   23374 }
   23375 
   23376 dns_zonestat_level_t
   23377 dns_zone_getstatlevel(dns_zone_t *zone) {
   23378 	REQUIRE(DNS_ZONE_VALID(zone));
   23379 
   23380 	return (zone->statlevel);
   23381 }
   23382 
   23383 static void
   23384 setserial(isc_task_t *task, isc_event_t *event) {
   23385 	uint32_t oldserial, desired;
   23386 	const char *me = "setserial";
   23387 	bool commit = false;
   23388 	isc_result_t result;
   23389 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   23390 	dns_zone_t *zone;
   23391 	dns_db_t *db = NULL;
   23392 	dns_diff_t diff;
   23393 	struct ssevent *sse = (struct ssevent *)event;
   23394 	dns_update_log_t log = { update_log_cb, NULL };
   23395 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   23396 
   23397 	UNUSED(task);
   23398 
   23399 	zone = event->ev_arg;
   23400 	INSIST(DNS_ZONE_VALID(zone));
   23401 
   23402 	ENTER;
   23403 
   23404 	if (zone->update_disabled) {
   23405 		goto disabled;
   23406 	}
   23407 
   23408 	desired = sse->serial;
   23409 
   23410 	dns_diff_init(zone->mctx, &diff);
   23411 
   23412 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   23413 	if (zone->db != NULL) {
   23414 		dns_db_attach(zone->db, &db);
   23415 	}
   23416 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   23417 	if (db == NULL) {
   23418 		goto failure;
   23419 	}
   23420 
   23421 	dns_db_currentversion(db, &oldver);
   23422 	result = dns_db_newversion(db, &newver);
   23423 	if (result != ISC_R_SUCCESS) {
   23424 		dns_zone_log(zone, ISC_LOG_ERROR,
   23425 			     "setserial:dns_db_newversion -> %s",
   23426 			     dns_result_totext(result));
   23427 		goto failure;
   23428 	}
   23429 
   23430 	CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL,
   23431 				    &oldtuple));
   23432 	CHECK(dns_difftuple_copy(oldtuple, &newtuple));
   23433 	newtuple->op = DNS_DIFFOP_ADD;
   23434 
   23435 	oldserial = dns_soa_getserial(&oldtuple->rdata);
   23436 	if (desired == 0U) {
   23437 		desired = 1;
   23438 	}
   23439 	if (!isc_serial_gt(desired, oldserial)) {
   23440 		if (desired != oldserial) {
   23441 			dns_zone_log(zone, ISC_LOG_INFO,
   23442 				     "setserial: desired serial (%u) "
   23443 				     "out of range (%u-%u)",
   23444 				     desired, oldserial + 1,
   23445 				     (oldserial + 0x7fffffff));
   23446 		}
   23447 		goto failure;
   23448 	}
   23449 
   23450 	dns_soa_setserial(desired, &newtuple->rdata);
   23451 	CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
   23452 	CHECK(do_one_tuple(&newtuple, db, newver, &diff));
   23453 	result = dns_update_signatures(&log, zone, db, oldver, newver, &diff,
   23454 				       zone->sigvalidityinterval);
   23455 	if (result != ISC_R_NOTFOUND) {
   23456 		CHECK(result);
   23457 	}
   23458 
   23459 	/* Write changes to journal file. */
   23460 	CHECK(zone_journal(zone, &diff, NULL, "setserial"));
   23461 	commit = true;
   23462 
   23463 	LOCK_ZONE(zone);
   23464 	zone_needdump(zone, 30);
   23465 	UNLOCK_ZONE(zone);
   23466 
   23467 failure:
   23468 	if (oldtuple != NULL) {
   23469 		dns_difftuple_free(&oldtuple);
   23470 	}
   23471 	if (newtuple != NULL) {
   23472 		dns_difftuple_free(&newtuple);
   23473 	}
   23474 	if (oldver != NULL) {
   23475 		dns_db_closeversion(db, &oldver, false);
   23476 	}
   23477 	if (newver != NULL) {
   23478 		dns_db_closeversion(db, &newver, commit);
   23479 	}
   23480 	if (db != NULL) {
   23481 		dns_db_detach(&db);
   23482 	}
   23483 	dns_diff_clear(&diff);
   23484 
   23485 disabled:
   23486 	isc_event_free(&event);
   23487 	dns_zone_idetach(&zone);
   23488 
   23489 	INSIST(oldver == NULL);
   23490 	INSIST(newver == NULL);
   23491 }
   23492 
   23493 isc_result_t
   23494 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
   23495 	isc_result_t result = ISC_R_SUCCESS;
   23496 	dns_zone_t *dummy = NULL;
   23497 	isc_event_t *e = NULL;
   23498 	struct ssevent *sse;
   23499 
   23500 	REQUIRE(DNS_ZONE_VALID(zone));
   23501 
   23502 	LOCK_ZONE(zone);
   23503 
   23504 	if (!inline_secure(zone)) {
   23505 		if (!dns_zone_isdynamic(zone, true)) {
   23506 			result = DNS_R_NOTDYNAMIC;
   23507 			goto failure;
   23508 		}
   23509 	}
   23510 
   23511 	if (zone->update_disabled) {
   23512 		result = DNS_R_FROZEN;
   23513 		goto failure;
   23514 	}
   23515 
   23516 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL, setserial,
   23517 			       zone, sizeof(struct ssevent));
   23518 
   23519 	sse = (struct ssevent *)e;
   23520 	sse->serial = serial;
   23521 
   23522 	zone_iattach(zone, &dummy);
   23523 	isc_task_send(zone->task, &e);
   23524 
   23525 failure:
   23526 	if (e != NULL) {
   23527 		isc_event_free(&e);
   23528 	}
   23529 	UNLOCK_ZONE(zone);
   23530 	return (result);
   23531 }
   23532 
   23533 isc_stats_t *
   23534 dns_zone_getgluecachestats(dns_zone_t *zone) {
   23535 	REQUIRE(DNS_ZONE_VALID(zone));
   23536 
   23537 	return (zone->gluecachestats);
   23538 }
   23539 
   23540 bool
   23541 dns_zone_isloaded(dns_zone_t *zone) {
   23542 	REQUIRE(DNS_ZONE_VALID(zone));
   23543 
   23544 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
   23545 }
   23546 
   23547 isc_result_t
   23548 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
   23549 	dns_dbversion_t *version = NULL;
   23550 	dns_keytable_t *secroots = NULL;
   23551 	isc_result_t result;
   23552 	dns_name_t *origin;
   23553 
   23554 	const char me[] = "dns_zone_verifydb";
   23555 
   23556 	REQUIRE(DNS_ZONE_VALID(zone));
   23557 	REQUIRE(db != NULL);
   23558 
   23559 	ENTER;
   23560 
   23561 	if (dns_zone_gettype(zone) != dns_zone_mirror) {
   23562 		return (ISC_R_SUCCESS);
   23563 	}
   23564 
   23565 	if (ver == NULL) {
   23566 		dns_db_currentversion(db, &version);
   23567 	} else {
   23568 		version = ver;
   23569 	}
   23570 
   23571 	if (zone->view != NULL) {
   23572 		result = dns_view_getsecroots(zone->view, &secroots);
   23573 		if (result != ISC_R_SUCCESS) {
   23574 			goto done;
   23575 		}
   23576 	}
   23577 
   23578 	origin = dns_db_origin(db);
   23579 	result = dns_zoneverify_dnssec(zone, db, version, origin, secroots,
   23580 				       zone->mctx, true, false, dnssec_report);
   23581 
   23582 done:
   23583 	if (secroots != NULL) {
   23584 		dns_keytable_detach(&secroots);
   23585 	}
   23586 
   23587 	if (ver == NULL) {
   23588 		dns_db_closeversion(db, &version, false);
   23589 	}
   23590 
   23591 	if (result != ISC_R_SUCCESS) {
   23592 		dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s",
   23593 			   isc_result_totext(result));
   23594 		result = DNS_R_VERIFYFAILURE;
   23595 	}
   23596 
   23597 	return (result);
   23598 }
   23599 
   23600 static dns_ttl_t
   23601 zone_nsecttl(dns_zone_t *zone) {
   23602 	REQUIRE(DNS_ZONE_VALID(zone));
   23603 
   23604 	return (ISC_MIN(zone->minimum, zone->soattl));
   23605 }
   23606