Home | History | Annotate | Line # | Download | only in dns
zone.c revision 1.16.2.2
      1 /*	$NetBSD: zone.c,v 1.16.2.2 2024/02/25 15:46:54 martin 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/result.h>
     33 #include <isc/rwlock.h>
     34 #include <isc/serial.h>
     35 #include <isc/stats.h>
     36 #include <isc/stdtime.h>
     37 #include <isc/strerr.h>
     38 #include <isc/string.h>
     39 #include <isc/taskpool.h>
     40 #include <isc/thread.h>
     41 #include <isc/timer.h>
     42 #include <isc/tls.h>
     43 #include <isc/util.h>
     44 
     45 #include <dns/acl.h>
     46 #include <dns/adb.h>
     47 #include <dns/callbacks.h>
     48 #include <dns/catz.h>
     49 #include <dns/db.h>
     50 #include <dns/dbiterator.h>
     51 #include <dns/dlz.h>
     52 #include <dns/dnssec.h>
     53 #include <dns/events.h>
     54 #include <dns/journal.h>
     55 #include <dns/kasp.h>
     56 #include <dns/keydata.h>
     57 #include <dns/keymgr.h>
     58 #include <dns/keytable.h>
     59 #include <dns/keyvalues.h>
     60 #include <dns/log.h>
     61 #include <dns/master.h>
     62 #include <dns/masterdump.h>
     63 #include <dns/message.h>
     64 #include <dns/name.h>
     65 #include <dns/nsec.h>
     66 #include <dns/nsec3.h>
     67 #include <dns/opcode.h>
     68 #include <dns/peer.h>
     69 #include <dns/private.h>
     70 #include <dns/rcode.h>
     71 #include <dns/rdata.h>
     72 #include <dns/rdataclass.h>
     73 #include <dns/rdatalist.h>
     74 #include <dns/rdataset.h>
     75 #include <dns/rdatasetiter.h>
     76 #include <dns/rdatastruct.h>
     77 #include <dns/rdatatype.h>
     78 #include <dns/request.h>
     79 #include <dns/resolver.h>
     80 #include <dns/rriterator.h>
     81 #include <dns/soa.h>
     82 #include <dns/ssu.h>
     83 #include <dns/stats.h>
     84 #include <dns/time.h>
     85 #include <dns/tsig.h>
     86 #include <dns/update.h>
     87 #include <dns/xfrin.h>
     88 #include <dns/zone.h>
     89 #include <dns/zoneverify.h>
     90 #include <dns/zt.h>
     91 
     92 #include <dst/dst.h>
     93 
     94 #include "zone_p.h"
     95 
     96 #define ZONE_MAGIC	     ISC_MAGIC('Z', 'O', 'N', 'E')
     97 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
     98 
     99 #define NOTIFY_MAGIC		 ISC_MAGIC('N', 't', 'f', 'y')
    100 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
    101 
    102 #define CHECKDS_MAGIC		   ISC_MAGIC('C', 'h', 'D', 'S')
    103 #define DNS_CHECKDS_VALID(checkds) ISC_MAGIC_VALID(checkds, CHECKDS_MAGIC)
    104 
    105 #define STUB_MAGIC	     ISC_MAGIC('S', 't', 'u', 'b')
    106 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
    107 
    108 #define ZONEMGR_MAGIC		ISC_MAGIC('Z', 'm', 'g', 'r')
    109 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
    110 
    111 #define LOAD_MAGIC	     ISC_MAGIC('L', 'o', 'a', 'd')
    112 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
    113 
    114 #define FORWARD_MAGIC		ISC_MAGIC('F', 'o', 'r', 'w')
    115 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
    116 
    117 #define IO_MAGIC	   ISC_MAGIC('Z', 'm', 'I', 'O')
    118 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
    119 
    120 #define KEYMGMT_MAGIC		ISC_MAGIC('M', 'g', 'm', 't')
    121 #define DNS_KEYMGMT_VALID(load) ISC_MAGIC_VALID(load, KEYMGMT_MAGIC)
    122 
    123 #define KEYFILEIO_MAGIC		  ISC_MAGIC('K', 'y', 'I', 'O')
    124 #define DNS_KEYFILEIO_VALID(kfio) ISC_MAGIC_VALID(kfio, KEYFILEIO_MAGIC)
    125 
    126 /*%
    127  * Ensure 'a' is at least 'min' but not more than 'max'.
    128  */
    129 #define RANGE(a, min, max) (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
    130 
    131 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
    132 
    133 /*%
    134  * Key flags
    135  */
    136 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
    137 #define KSK(x)	  ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
    138 #define ID(x)	  dst_key_id(x)
    139 #define ALG(x)	  dst_key_alg(x)
    140 
    141 /*%
    142  * KASP flags
    143  */
    144 #define KASP_LOCK(k)                  \
    145 	if ((k) != NULL) {            \
    146 		LOCK((&((k)->lock))); \
    147 	}
    148 
    149 #define KASP_UNLOCK(k)                  \
    150 	if ((k) != NULL) {              \
    151 		UNLOCK((&((k)->lock))); \
    152 	}
    153 
    154 /*
    155  * Default values.
    156  */
    157 #define DNS_DEFAULT_IDLEIN  3600       /*%< 1 hour */
    158 #define DNS_DEFAULT_IDLEOUT 3600       /*%< 1 hour */
    159 #define MAX_XFER_TIME	    (2 * 3600) /*%< Documented default is 2 hours */
    160 #define RESIGN_DELAY	    3600       /*%< 1 hour */
    161 
    162 #ifndef DNS_MAX_EXPIRE
    163 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
    164 #endif				/* ifndef DNS_MAX_EXPIRE */
    165 
    166 #ifndef DNS_DUMP_DELAY
    167 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
    168 #endif			   /* ifndef DNS_DUMP_DELAY */
    169 
    170 typedef struct dns_notify dns_notify_t;
    171 typedef struct dns_checkds dns_checkds_t;
    172 typedef struct dns_stub dns_stub_t;
    173 typedef struct dns_load dns_load_t;
    174 typedef struct dns_forward dns_forward_t;
    175 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
    176 typedef struct dns_io dns_io_t;
    177 typedef ISC_LIST(dns_io_t) dns_iolist_t;
    178 typedef struct dns_keymgmt dns_keymgmt_t;
    179 typedef struct dns_signing dns_signing_t;
    180 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
    181 typedef struct dns_nsec3chain dns_nsec3chain_t;
    182 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
    183 typedef struct dns_keyfetch dns_keyfetch_t;
    184 typedef struct dns_asyncload dns_asyncload_t;
    185 typedef struct dns_include dns_include_t;
    186 
    187 #define DNS_ZONE_CHECKLOCK
    188 #ifdef DNS_ZONE_CHECKLOCK
    189 #define LOCK_ZONE(z)                  \
    190 	do {                          \
    191 		LOCK(&(z)->lock);     \
    192 		INSIST(!(z)->locked); \
    193 		(z)->locked = true;   \
    194 	} while (0)
    195 #define UNLOCK_ZONE(z)               \
    196 	do {                         \
    197 		(z)->locked = false; \
    198 		UNLOCK(&(z)->lock);  \
    199 	} while (0)
    200 #define LOCKED_ZONE(z) ((z)->locked)
    201 #define TRYLOCK_ZONE(result, z)                         \
    202 	do {                                            \
    203 		result = isc_mutex_trylock(&(z)->lock); \
    204 		if (result == ISC_R_SUCCESS) {          \
    205 			INSIST(!(z)->locked);           \
    206 			(z)->locked = true;             \
    207 		}                                       \
    208 	} while (0)
    209 #else /* ifdef DNS_ZONE_CHECKLOCK */
    210 #define LOCK_ZONE(z)   LOCK(&(z)->lock)
    211 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
    212 #define LOCKED_ZONE(z) true
    213 #define TRYLOCK_ZONE(result, z)                         \
    214 	do {                                            \
    215 		result = isc_mutex_trylock(&(z)->lock); \
    216 	} while (0)
    217 #endif /* ifdef DNS_ZONE_CHECKLOCK */
    218 
    219 #define ZONEDB_INITLOCK(l)    isc_rwlock_init((l), 0, 0)
    220 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
    221 #define ZONEDB_LOCK(l, t)     RWLOCK((l), (t))
    222 #define ZONEDB_UNLOCK(l, t)   RWUNLOCK((l), (t))
    223 
    224 #ifdef ENABLE_AFL
    225 extern bool dns_fuzzing_resolver;
    226 #endif /* ifdef ENABLE_AFL */
    227 
    228 /*%
    229  *	Hold key file IO locks.
    230  */
    231 typedef struct dns_keyfileio {
    232 	unsigned int magic;
    233 	struct dns_keyfileio *next;
    234 	uint32_t hashval;
    235 	dns_fixedname_t fname;
    236 	dns_name_t *name;
    237 	isc_refcount_t references;
    238 	isc_mutex_t lock;
    239 } dns_keyfileio_t;
    240 
    241 struct dns_keymgmt {
    242 	unsigned int magic;
    243 	isc_rwlock_t lock;
    244 	isc_mem_t *mctx;
    245 
    246 	dns_keyfileio_t **table;
    247 
    248 	atomic_uint_fast32_t count;
    249 
    250 	uint32_t bits;
    251 };
    252 
    253 struct dns_zone {
    254 	/* Unlocked */
    255 	unsigned int magic;
    256 	isc_mutex_t lock;
    257 #ifdef DNS_ZONE_CHECKLOCK
    258 	bool locked;
    259 #endif /* ifdef DNS_ZONE_CHECKLOCK */
    260 	isc_mem_t *mctx;
    261 	isc_refcount_t erefs;
    262 
    263 	isc_rwlock_t dblock;
    264 	dns_db_t *db; /* Locked by dblock */
    265 
    266 	/* Locked */
    267 	dns_zonemgr_t *zmgr;
    268 	ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
    269 	isc_timer_t *timer;
    270 	isc_refcount_t irefs;
    271 	dns_name_t origin;
    272 	char *masterfile;
    273 	const FILE *stream;		     /* loading from a stream? */
    274 	ISC_LIST(dns_include_t) includes;    /* Include files */
    275 	ISC_LIST(dns_include_t) newincludes; /* Loading */
    276 	unsigned int nincludes;
    277 	dns_masterformat_t masterformat;
    278 	const dns_master_style_t *masterstyle;
    279 	char *journal;
    280 	int32_t journalsize;
    281 	dns_rdataclass_t rdclass;
    282 	dns_zonetype_t type;
    283 #ifdef __NetBSD__
    284 	atomic_uint_fast32_t flags;
    285 	atomic_uint_fast32_t options;
    286 #else
    287 	atomic_uint_fast64_t flags;
    288 	atomic_uint_fast64_t options;
    289 #endif
    290 	unsigned int db_argc;
    291 	char **db_argv;
    292 	isc_time_t expiretime;
    293 	isc_time_t refreshtime;
    294 	isc_time_t dumptime;
    295 	isc_time_t loadtime;
    296 	isc_time_t notifytime;
    297 	isc_time_t resigntime;
    298 	isc_time_t keywarntime;
    299 	isc_time_t signingtime;
    300 	isc_time_t nsec3chaintime;
    301 	isc_time_t refreshkeytime;
    302 	uint32_t refreshkeyinterval;
    303 	uint32_t refreshkeycount;
    304 	uint32_t refresh;
    305 	uint32_t retry;
    306 	uint32_t expire;
    307 	uint32_t minimum;
    308 	isc_stdtime_t key_expiry;
    309 	isc_stdtime_t log_key_expired_timer;
    310 	char *keydirectory;
    311 	dns_keyfileio_t *kfio;
    312 
    313 	uint32_t maxrefresh;
    314 	uint32_t minrefresh;
    315 	uint32_t maxretry;
    316 	uint32_t minretry;
    317 
    318 	uint32_t maxrecords;
    319 
    320 	isc_sockaddr_t *primaries;
    321 	dns_name_t **primarykeynames;
    322 	dns_name_t **primarytlsnames;
    323 	bool *primariesok;
    324 	unsigned int primariescnt;
    325 	unsigned int curprimary;
    326 	isc_sockaddr_t primaryaddr;
    327 
    328 	isc_sockaddr_t *parentals;
    329 	dns_name_t **parentalkeynames;
    330 	dns_name_t **parentaltlsnames;
    331 	dns_dnsseckeylist_t checkds_ok;
    332 	unsigned int parentalscnt;
    333 	isc_sockaddr_t parentaladdr;
    334 
    335 	dns_notifytype_t notifytype;
    336 	isc_sockaddr_t *notify;
    337 	dns_name_t **notifykeynames;
    338 	dns_name_t **notifytlsnames;
    339 	unsigned int notifycnt;
    340 	isc_sockaddr_t notifyfrom;
    341 	isc_task_t *task;
    342 	isc_task_t *loadtask;
    343 	isc_sockaddr_t notifysrc4;
    344 	isc_sockaddr_t notifysrc6;
    345 	isc_sockaddr_t parentalsrc4;
    346 	isc_sockaddr_t parentalsrc6;
    347 	isc_sockaddr_t xfrsource4;
    348 	isc_sockaddr_t xfrsource6;
    349 	isc_sockaddr_t altxfrsource4;
    350 	isc_sockaddr_t altxfrsource6;
    351 	isc_sockaddr_t sourceaddr;
    352 	dns_xfrin_ctx_t *xfr;	    /* task locked */
    353 	dns_tsigkey_t *tsigkey;	    /* key used for xfr */
    354 	dns_transport_t *transport; /* transport used for xfr */
    355 	/* Access Control Lists */
    356 	dns_acl_t *update_acl;
    357 	dns_acl_t *forward_acl;
    358 	dns_acl_t *notify_acl;
    359 	dns_acl_t *query_acl;
    360 	dns_acl_t *queryon_acl;
    361 	dns_acl_t *xfr_acl;
    362 	bool update_disabled;
    363 	bool zero_no_soa_ttl;
    364 	dns_severity_t check_names;
    365 	ISC_LIST(dns_notify_t) notifies;
    366 	ISC_LIST(dns_checkds_t) checkds_requests;
    367 	dns_request_t *request;
    368 	dns_loadctx_t *lctx;
    369 	dns_io_t *readio;
    370 	dns_dumpctx_t *dctx;
    371 	dns_io_t *writeio;
    372 	uint32_t maxxfrin;
    373 	uint32_t maxxfrout;
    374 	uint32_t idlein;
    375 	uint32_t idleout;
    376 	isc_event_t ctlevent;
    377 	dns_ssutable_t *ssutable;
    378 	uint32_t sigvalidityinterval;
    379 	uint32_t keyvalidityinterval;
    380 	uint32_t sigresigninginterval;
    381 	dns_view_t *view;
    382 	dns_view_t *prev_view;
    383 	dns_kasp_t *kasp;
    384 	dns_checkmxfunc_t checkmx;
    385 	dns_checksrvfunc_t checksrv;
    386 	dns_checknsfunc_t checkns;
    387 	/*%
    388 	 * Zones in certain states such as "waiting for zone transfer"
    389 	 * or "zone transfer in progress" are kept on per-state linked lists
    390 	 * in the zone manager using the 'statelink' field.  The 'statelist'
    391 	 * field points at the list the zone is currently on.  It the zone
    392 	 * is not on any such list, statelist is NULL.
    393 	 */
    394 	ISC_LINK(dns_zone_t) statelink;
    395 	dns_zonelist_t *statelist;
    396 	/*%
    397 	 * Statistics counters about zone management.
    398 	 */
    399 	isc_stats_t *stats;
    400 	/*%
    401 	 * Optional per-zone statistics counters.  Counted outside of this
    402 	 * module.
    403 	 */
    404 	dns_zonestat_level_t statlevel;
    405 	bool requeststats_on;
    406 	isc_stats_t *requeststats;
    407 	dns_stats_t *rcvquerystats;
    408 	dns_stats_t *dnssecsignstats;
    409 	uint32_t notifydelay;
    410 	dns_isselffunc_t isself;
    411 	void *isselfarg;
    412 
    413 	char *strnamerd;
    414 	char *strname;
    415 	char *strrdclass;
    416 	char *strviewname;
    417 
    418 	/*%
    419 	 * Serial number for deferred journal compaction.
    420 	 */
    421 	uint32_t compact_serial;
    422 	/*%
    423 	 * Keys that are signing the zone for the first time.
    424 	 */
    425 	dns_signinglist_t signing;
    426 	dns_nsec3chainlist_t nsec3chain;
    427 	/*%
    428 	 * List of outstanding NSEC3PARAM change requests.
    429 	 */
    430 	isc_eventlist_t setnsec3param_queue;
    431 	/*%
    432 	 * Signing / re-signing quantum stopping parameters.
    433 	 */
    434 	uint32_t signatures;
    435 	uint32_t nodes;
    436 	dns_rdatatype_t privatetype;
    437 
    438 	/*%
    439 	 * Autosigning/key-maintenance options
    440 	 */
    441 #ifdef __NetBSD__
    442 	atomic_uint_fast32_t keyopts;
    443 #else
    444 	atomic_uint_fast64_t keyopts;
    445 #endif
    446 
    447 	/*%
    448 	 * True if added by "rndc addzone"
    449 	 */
    450 	bool added;
    451 
    452 	/*%
    453 	 * True if added by automatically by named.
    454 	 */
    455 	bool automatic;
    456 
    457 	/*%
    458 	 * response policy data to be relayed to the database
    459 	 */
    460 	dns_rpz_zones_t *rpzs;
    461 	dns_rpz_num_t rpz_num;
    462 
    463 	/*%
    464 	 * catalog zone data
    465 	 */
    466 	dns_catz_zones_t *catzs;
    467 
    468 	/*%
    469 	 * parent catalog zone
    470 	 */
    471 	dns_catz_zone_t *parentcatz;
    472 
    473 	/*%
    474 	 * Serial number update method.
    475 	 */
    476 	dns_updatemethod_t updatemethod;
    477 
    478 	/*%
    479 	 * whether ixfr is requested
    480 	 */
    481 	bool requestixfr;
    482 	uint32_t ixfr_ratio;
    483 
    484 	/*%
    485 	 * whether EDNS EXPIRE is requested
    486 	 */
    487 	bool requestexpire;
    488 
    489 	/*%
    490 	 * Outstanding forwarded UPDATE requests.
    491 	 */
    492 	dns_forwardlist_t forwards;
    493 
    494 	dns_zone_t *raw;
    495 	dns_zone_t *secure;
    496 
    497 	bool sourceserialset;
    498 	uint32_t sourceserial;
    499 
    500 	/*%
    501 	 * soa and maximum zone ttl
    502 	 */
    503 	dns_ttl_t soattl;
    504 	dns_ttl_t maxttl;
    505 
    506 	/*
    507 	 * Inline zone signing state.
    508 	 */
    509 	dns_diff_t rss_diff;
    510 	isc_eventlist_t rss_events;
    511 	isc_eventlist_t rss_post;
    512 	dns_dbversion_t *rss_newver;
    513 	dns_dbversion_t *rss_oldver;
    514 	dns_db_t *rss_db;
    515 	dns_zone_t *rss_raw;
    516 	isc_event_t *rss_event;
    517 	dns_update_state_t *rss_state;
    518 
    519 	isc_stats_t *gluecachestats;
    520 };
    521 
    522 #define zonediff_init(z, d)                \
    523 	do {                               \
    524 		dns__zonediff_t *_z = (z); \
    525 		(_z)->diff = (d);          \
    526 		(_z)->offline = false;     \
    527 	} while (0)
    528 
    529 #define DNS_ZONE_FLAG(z, f)    ((atomic_load_relaxed(&(z)->flags) & (f)) != 0)
    530 #define DNS_ZONE_SETFLAG(z, f) atomic_fetch_or(&(z)->flags, (f))
    531 #define DNS_ZONE_CLRFLAG(z, f) atomic_fetch_and(&(z)->flags, ~(f))
    532 typedef enum {
    533 	DNS_ZONEFLG_REFRESH = 0x00000001U,     /*%< refresh check in progress */
    534 	DNS_ZONEFLG_NEEDDUMP = 0x00000002U,    /*%< zone need consolidation */
    535 	DNS_ZONEFLG_USEVC = 0x00000004U,       /*%< use tcp for refresh query */
    536 	DNS_ZONEFLG_DUMPING = 0x00000008U,     /*%< a dump is in progress */
    537 	DNS_ZONEFLG_HASINCLUDE = 0x00000010U,  /*%< $INCLUDE in zone file */
    538 	DNS_ZONEFLG_LOADED = 0x00000020U,      /*%< database has loaded */
    539 	DNS_ZONEFLG_EXITING = 0x00000040U,     /*%< zone is being destroyed */
    540 	DNS_ZONEFLG_EXPIRED = 0x00000080U,     /*%< zone has expired */
    541 	DNS_ZONEFLG_NEEDREFRESH = 0x00000100U, /*%< refresh check needed */
    542 	DNS_ZONEFLG_UPTODATE = 0x00000200U,    /*%< zone contents are
    543 						* up-to-date */
    544 	DNS_ZONEFLG_NEEDNOTIFY = 0x00000400U,  /*%< need to send out notify
    545 						* messages */
    546 	DNS_ZONEFLG_FIXJOURNAL = 0x00000800U,  /*%< journal file had
    547 						* recoverable error,
    548 						* needs rewriting */
    549 	DNS_ZONEFLG_NOPRIMARIES = 0x00001000U, /*%< an attempt to refresh a
    550 						* zone with no primaries
    551 						* occurred */
    552 	DNS_ZONEFLG_LOADING = 0x00002000U,     /*%< load from disk in progress*/
    553 	DNS_ZONEFLG_HAVETIMERS = 0x00004000U,  /*%< timer values have been set
    554 						* from SOA (if not set, we
    555 						* are still using
    556 						* default timer values) */
    557 	DNS_ZONEFLG_FORCEXFER = 0x00008000U,   /*%< Force a zone xfer */
    558 	DNS_ZONEFLG_NOREFRESH = 0x00010000U,
    559 	DNS_ZONEFLG_DIALNOTIFY = 0x00020000U,
    560 	DNS_ZONEFLG_DIALREFRESH = 0x00040000U,
    561 	DNS_ZONEFLG_SHUTDOWN = 0x00080000U,
    562 	DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */
    563 	DNS_ZONEFLG_FLUSH = 0x00200000U,
    564 	DNS_ZONEFLG_NOEDNS = 0x00400000U,
    565 	DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U,
    566 	DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U,
    567 	DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U,
    568 	DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */
    569 	DNS_ZONEFLG_THAW = 0x08000000U,
    570 	DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */
    571 	DNS_ZONEFLG_NODELAY = 0x20000000U,
    572 	DNS_ZONEFLG_SENDSECURE = 0x40000000U,
    573 	DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out
    574 						      * notify due to the zone
    575 						      * just being loaded for
    576 						      * the first time. */
    577 #ifndef __NetBSD__
    578 	/*
    579 	 * DO NOT add any new zone flags here until all platforms
    580 	 * support 64-bit enum values. Currently they fail on
    581 	 * Windows.
    582 	 */
    583 	DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */
    584 #endif
    585 } dns_zoneflg_t;
    586 
    587 #define DNS_ZONE_OPTION(z, o)	 ((atomic_load_relaxed(&(z)->options) & (o)) != 0)
    588 #define DNS_ZONE_SETOPTION(z, o) atomic_fetch_or(&(z)->options, (o))
    589 #define DNS_ZONE_CLROPTION(z, o) atomic_fetch_and(&(z)->options, ~(o))
    590 
    591 #define DNS_ZONEKEY_OPTION(z, o) \
    592 	((atomic_load_relaxed(&(z)->keyopts) & (o)) != 0)
    593 #define DNS_ZONEKEY_SETOPTION(z, o) atomic_fetch_or(&(z)->keyopts, (o))
    594 #define DNS_ZONEKEY_CLROPTION(z, o) atomic_fetch_and(&(z)->keyopts, ~(o))
    595 
    596 /* Flags for zone_load() */
    597 typedef enum {
    598 	DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */
    599 	DNS_ZONELOADFLAG_THAW = 0x00000002U,   /* Thaw the zone on successful
    600 						* load. */
    601 } dns_zoneloadflag_t;
    602 
    603 #define UNREACH_CACHE_SIZE 10U
    604 #define UNREACH_HOLD_TIME  600 /* 10 minutes */
    605 
    606 #define CHECK(op)                            \
    607 	do {                                 \
    608 		result = (op);               \
    609 		if (result != ISC_R_SUCCESS) \
    610 			goto failure;        \
    611 	} while (0)
    612 
    613 struct dns_unreachable {
    614 	isc_sockaddr_t remote;
    615 	isc_sockaddr_t local;
    616 	atomic_uint_fast32_t expire;
    617 	atomic_uint_fast32_t last;
    618 	uint32_t count;
    619 };
    620 
    621 struct dns_zonemgr {
    622 	unsigned int magic;
    623 	isc_mem_t *mctx;
    624 	isc_refcount_t refs;
    625 	isc_taskmgr_t *taskmgr;
    626 	isc_timermgr_t *timermgr;
    627 	isc_nm_t *netmgr;
    628 	isc_taskpool_t *zonetasks;
    629 	isc_taskpool_t *loadtasks;
    630 	isc_task_t *task;
    631 	isc_pool_t *mctxpool;
    632 	isc_ratelimiter_t *checkdsrl;
    633 	isc_ratelimiter_t *notifyrl;
    634 	isc_ratelimiter_t *refreshrl;
    635 	isc_ratelimiter_t *startupnotifyrl;
    636 	isc_ratelimiter_t *startuprefreshrl;
    637 	isc_rwlock_t rwlock;
    638 	isc_mutex_t iolock;
    639 	isc_rwlock_t urlock;
    640 
    641 	/* Locked by rwlock. */
    642 	dns_zonelist_t zones;
    643 	dns_zonelist_t waiting_for_xfrin;
    644 	dns_zonelist_t xfrin_in_progress;
    645 
    646 	/* Configuration data. */
    647 	uint32_t transfersin;
    648 	uint32_t transfersperns;
    649 	unsigned int checkdsrate;
    650 	unsigned int notifyrate;
    651 	unsigned int startupnotifyrate;
    652 	unsigned int serialqueryrate;
    653 	unsigned int startupserialqueryrate;
    654 
    655 	/* Locked by iolock */
    656 	uint32_t iolimit;
    657 	uint32_t ioactive;
    658 	dns_iolist_t high;
    659 	dns_iolist_t low;
    660 
    661 	/* Locked by urlock. */
    662 	/* LRU cache */
    663 	struct dns_unreachable unreachable[UNREACH_CACHE_SIZE];
    664 
    665 	dns_keymgmt_t *keymgmt;
    666 
    667 	isc_tlsctx_cache_t *tlsctx_cache;
    668 	isc_rwlock_t tlsctx_cache_rwlock;
    669 };
    670 
    671 /*%
    672  * Hold notify state.
    673  */
    674 struct dns_notify {
    675 	unsigned int magic;
    676 	unsigned int flags;
    677 	isc_mem_t *mctx;
    678 	dns_zone_t *zone;
    679 	dns_adbfind_t *find;
    680 	dns_request_t *request;
    681 	dns_name_t ns;
    682 	isc_sockaddr_t dst;
    683 	dns_tsigkey_t *key;
    684 	dns_transport_t *transport;
    685 	ISC_LINK(dns_notify_t) link;
    686 	isc_event_t *event;
    687 };
    688 
    689 #define DNS_NOTIFY_NOSOA   0x0001U
    690 #define DNS_NOTIFY_STARTUP 0x0002U
    691 
    692 /*%
    693  * Hold checkds state.
    694  */
    695 struct dns_checkds {
    696 	unsigned int magic;
    697 	unsigned int flags;
    698 	isc_mem_t *mctx;
    699 	dns_zone_t *zone;
    700 	dns_request_t *request;
    701 	isc_sockaddr_t dst;
    702 	dns_tsigkey_t *key;
    703 	dns_transport_t *transport;
    704 	ISC_LINK(dns_checkds_t) link;
    705 	isc_event_t *event;
    706 };
    707 
    708 /*%
    709  *	dns_stub holds state while performing a 'stub' transfer.
    710  *	'db' is the zone's 'db' or a new one if this is the initial
    711  *	transfer.
    712  */
    713 
    714 struct dns_stub {
    715 	unsigned int magic;
    716 	isc_mem_t *mctx;
    717 	dns_zone_t *zone;
    718 	dns_db_t *db;
    719 	dns_dbversion_t *version;
    720 	atomic_uint_fast32_t pending_requests;
    721 };
    722 
    723 /*%
    724  *	Hold load state.
    725  */
    726 struct dns_load {
    727 	unsigned int magic;
    728 	isc_mem_t *mctx;
    729 	dns_zone_t *zone;
    730 	dns_db_t *db;
    731 	isc_time_t loadtime;
    732 	dns_rdatacallbacks_t callbacks;
    733 };
    734 
    735 /*%
    736  *	Hold forward state.
    737  */
    738 struct dns_forward {
    739 	unsigned int magic;
    740 	isc_mem_t *mctx;
    741 	dns_zone_t *zone;
    742 	isc_buffer_t *msgbuf;
    743 	dns_request_t *request;
    744 	uint32_t which;
    745 	isc_sockaddr_t addr;
    746 	dns_updatecallback_t callback;
    747 	void *callback_arg;
    748 	unsigned int options;
    749 	ISC_LINK(dns_forward_t) link;
    750 };
    751 
    752 /*%
    753  *	Hold IO request state.
    754  */
    755 struct dns_io {
    756 	unsigned int magic;
    757 	dns_zonemgr_t *zmgr;
    758 	bool high;
    759 	isc_task_t *task;
    760 	ISC_LINK(dns_io_t) link;
    761 	isc_event_t *event;
    762 };
    763 
    764 /*%
    765  *	Hold state for when we are signing a zone with a new
    766  *	DNSKEY as result of an update.
    767  */
    768 struct dns_signing {
    769 	unsigned int magic;
    770 	dns_db_t *db;
    771 	dns_dbiterator_t *dbiterator;
    772 	dns_secalg_t algorithm;
    773 	uint16_t keyid;
    774 	bool deleteit;
    775 	bool done;
    776 	ISC_LINK(dns_signing_t) link;
    777 };
    778 
    779 struct dns_nsec3chain {
    780 	unsigned int magic;
    781 	dns_db_t *db;
    782 	dns_dbiterator_t *dbiterator;
    783 	dns_rdata_nsec3param_t nsec3param;
    784 	unsigned char salt[255];
    785 	bool done;
    786 	bool seen_nsec;
    787 	bool delete_nsec;
    788 	bool save_delete_nsec;
    789 	ISC_LINK(dns_nsec3chain_t) link;
    790 };
    791 
    792 /*%<
    793  * 'dbiterator' contains a iterator for the database.  If we are creating
    794  * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
    795  * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
    796  * iterated.
    797  *
    798  * 'nsec3param' contains the parameters of the NSEC3 chain being created
    799  * or removed.
    800  *
    801  * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
    802  *
    803  * 'seen_nsec' will be set to true if, while iterating the zone to create a
    804  * NSEC3 chain, a NSEC record is seen.
    805  *
    806  * 'delete_nsec' will be set to true if, at the completion of the creation
    807  * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
    808  * are in the process of deleting the NSEC chain.
    809  *
    810  * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
    811  * so it can be recovered in the event of a error.
    812  */
    813 
    814 struct dns_keyfetch {
    815 	isc_mem_t *mctx;
    816 	dns_fixedname_t name;
    817 	dns_rdataset_t keydataset;
    818 	dns_rdataset_t dnskeyset;
    819 	dns_rdataset_t dnskeysigset;
    820 	dns_zone_t *zone;
    821 	dns_db_t *db;
    822 	dns_fetch_t *fetch;
    823 };
    824 
    825 /*%
    826  * Hold state for an asynchronous load
    827  */
    828 struct dns_asyncload {
    829 	dns_zone_t *zone;
    830 	unsigned int flags;
    831 	dns_zt_zoneloaded_t loaded;
    832 	void *loaded_arg;
    833 };
    834 
    835 /*%
    836  * Reference to an include file encountered during loading
    837  */
    838 struct dns_include {
    839 	char *name;
    840 	isc_time_t filetime;
    841 	ISC_LINK(dns_include_t) link;
    842 };
    843 
    844 /*
    845  * These can be overridden by the -T mkeytimers option on the command
    846  * line, so that we can test with shorter periods than specified in
    847  * RFC 5011.
    848  */
    849 #define HOUR  3600
    850 #define DAY   (24 * HOUR)
    851 #define MONTH (30 * DAY)
    852 unsigned int dns_zone_mkey_hour = HOUR;
    853 unsigned int dns_zone_mkey_day = DAY;
    854 unsigned int dns_zone_mkey_month = MONTH;
    855 
    856 #define SEND_BUFFER_SIZE 2048
    857 
    858 static void
    859 zone_settimer(dns_zone_t *, isc_time_t *);
    860 static void
    861 cancel_refresh(dns_zone_t *);
    862 static void
    863 zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg,
    864 	      ...) ISC_FORMAT_PRINTF(4, 5);
    865 static void
    866 notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
    867 	ISC_FORMAT_PRINTF(3, 4);
    868 static void
    869 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...)
    870 	ISC_FORMAT_PRINTF(3, 4);
    871 static void
    872 queue_xfrin(dns_zone_t *zone);
    873 static isc_result_t
    874 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
    875 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
    876 	      dns_rdata_t *rdata);
    877 static void
    878 zone_unload(dns_zone_t *zone);
    879 static void
    880 zone_expire(dns_zone_t *zone);
    881 static void
    882 zone_refresh(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 void
   1018 zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache);
   1019 /*%<
   1020  *	Attach to TLS client context cache used for zone transfers via
   1021  *	encrypted transports (e.g. XoT).
   1022  *
   1023  * The obtained reference needs to be detached by a call to
   1024  * 'isc_tlsctx_cache_detach()' when not needed anymore.
   1025  *
   1026  * Requires:
   1027  *\li	'zmgr' is a valid zone manager.
   1028  *\li	'ptlsctx_cache' is not 'NULL' and points to 'NULL'.
   1029  */
   1030 
   1031 static const unsigned int dbargc_default = 1;
   1032 static const char *dbargv_default[] = { "rbt" };
   1033 
   1034 #define DNS_ZONE_JITTER_ADD(a, b, c)                                         \
   1035 	do {                                                                 \
   1036 		isc_interval_t _i;                                           \
   1037 		uint32_t _j;                                                 \
   1038 		_j = (b)-isc_random_uniform((b) / 4);                        \
   1039 		isc_interval_set(&_i, _j, 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, _j / 2, 0);                    \
   1046 			(void)isc_time_add((a), &_i, (c));                   \
   1047 		}                                                            \
   1048 	} while (0)
   1049 
   1050 #define DNS_ZONE_TIME_ADD(a, b, c)                                           \
   1051 	do {                                                                 \
   1052 		isc_interval_t _i;                                           \
   1053 		isc_interval_set(&_i, (b), 0);                               \
   1054 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) {          \
   1055 			dns_zone_log(zone, ISC_LOG_WARNING,                  \
   1056 				     "epoch approaching: upgrade required: " \
   1057 				     "now + %s failed",                      \
   1058 				     #b);                                    \
   1059 			isc_interval_set(&_i, (b) / 2, 0);                   \
   1060 			(void)isc_time_add((a), &_i, (c));                   \
   1061 		}                                                            \
   1062 	} while (0)
   1063 
   1064 typedef struct nsec3param nsec3param_t;
   1065 struct nsec3param {
   1066 	dns_rdata_nsec3param_t rdata;
   1067 	unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
   1068 	unsigned int length;
   1069 	bool nsec;
   1070 	bool replace;
   1071 	bool resalt;
   1072 	bool lookup;
   1073 	ISC_LINK(nsec3param_t) link;
   1074 };
   1075 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
   1076 struct np3event {
   1077 	isc_event_t event;
   1078 	nsec3param_t params;
   1079 };
   1080 
   1081 struct ssevent {
   1082 	isc_event_t event;
   1083 	uint32_t serial;
   1084 };
   1085 
   1086 struct stub_cb_args {
   1087 	dns_stub_t *stub;
   1088 	dns_tsigkey_t *tsig_key;
   1089 	uint16_t udpsize;
   1090 	int timeout;
   1091 	bool reqnsid;
   1092 };
   1093 
   1094 struct stub_glue_request {
   1095 	dns_request_t *request;
   1096 	dns_name_t name;
   1097 	struct stub_cb_args *args;
   1098 	bool ipv4;
   1099 };
   1100 
   1101 /*%
   1102  * Increment resolver-related statistics counters.  Zone must be locked.
   1103  */
   1104 static void
   1105 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
   1106 	if (zone->stats != NULL) {
   1107 		isc_stats_increment(zone->stats, counter);
   1108 	}
   1109 }
   1110 
   1111 /***
   1112  ***	Public functions.
   1113  ***/
   1114 
   1115 isc_result_t
   1116 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
   1117 	isc_result_t result;
   1118 	isc_time_t now;
   1119 	dns_zone_t *zone = NULL;
   1120 	dns_zone_t z = { .masterformat = dns_masterformat_none,
   1121 			 .journalsize = -1,
   1122 			 .rdclass = dns_rdataclass_none,
   1123 			 .type = dns_zone_none,
   1124 			 .refresh = DNS_ZONE_DEFAULTREFRESH,
   1125 			 .retry = DNS_ZONE_DEFAULTRETRY,
   1126 			 .maxrefresh = DNS_ZONE_MAXREFRESH,
   1127 			 .minrefresh = DNS_ZONE_MINREFRESH,
   1128 			 .maxretry = DNS_ZONE_MAXRETRY,
   1129 			 .minretry = DNS_ZONE_MINRETRY,
   1130 			 .notifytype = dns_notifytype_yes,
   1131 			 .zero_no_soa_ttl = true,
   1132 			 .check_names = dns_severity_ignore,
   1133 			 .idlein = DNS_DEFAULT_IDLEIN,
   1134 			 .idleout = DNS_DEFAULT_IDLEOUT,
   1135 			 .maxxfrin = MAX_XFER_TIME,
   1136 			 .maxxfrout = MAX_XFER_TIME,
   1137 			 .sigvalidityinterval = 30 * 24 * 3600,
   1138 			 .sigresigninginterval = 7 * 24 * 3600,
   1139 			 .statlevel = dns_zonestat_none,
   1140 			 .notifydelay = 5,
   1141 			 .signatures = 10,
   1142 			 .nodes = 100,
   1143 			 .privatetype = (dns_rdatatype_t)0xffffU,
   1144 			 .rpz_num = DNS_RPZ_INVALID_NUM,
   1145 			 .requestixfr = true,
   1146 			 .ixfr_ratio = 100,
   1147 			 .requestexpire = true,
   1148 			 .updatemethod = dns_updatemethod_increment,
   1149 			 .magic = ZONE_MAGIC };
   1150 
   1151 	REQUIRE(zonep != NULL && *zonep == NULL);
   1152 	REQUIRE(mctx != NULL);
   1153 
   1154 	TIME_NOW(&now);
   1155 	zone = isc_mem_get(mctx, sizeof(*zone));
   1156 	*zone = z;
   1157 
   1158 	zone->mctx = NULL;
   1159 	isc_mem_attach(mctx, &zone->mctx);
   1160 	isc_mutex_init(&zone->lock);
   1161 	ZONEDB_INITLOCK(&zone->dblock);
   1162 	/* XXX MPA check that all elements are initialised */
   1163 #ifdef DNS_ZONE_CHECKLOCK
   1164 	zone->locked = false;
   1165 #endif /* ifdef DNS_ZONE_CHECKLOCK */
   1166 
   1167 	zone->notifytime = now;
   1168 
   1169 	ISC_LINK_INIT(zone, link);
   1170 	isc_refcount_init(&zone->erefs, 1);
   1171 	isc_refcount_init(&zone->irefs, 0);
   1172 	dns_name_init(&zone->origin, NULL);
   1173 	ISC_LIST_INIT(zone->includes);
   1174 	ISC_LIST_INIT(zone->newincludes);
   1175 	atomic_init(&zone->flags, 0);
   1176 	atomic_init(&zone->options, 0);
   1177 	atomic_init(&zone->keyopts, 0);
   1178 	isc_time_settoepoch(&zone->expiretime);
   1179 	isc_time_settoepoch(&zone->refreshtime);
   1180 	isc_time_settoepoch(&zone->dumptime);
   1181 	isc_time_settoepoch(&zone->loadtime);
   1182 	isc_time_settoepoch(&zone->resigntime);
   1183 	isc_time_settoepoch(&zone->keywarntime);
   1184 	isc_time_settoepoch(&zone->signingtime);
   1185 	isc_time_settoepoch(&zone->nsec3chaintime);
   1186 	isc_time_settoepoch(&zone->refreshkeytime);
   1187 	ISC_LIST_INIT(zone->notifies);
   1188 	ISC_LIST_INIT(zone->checkds_requests);
   1189 	isc_sockaddr_any(&zone->notifysrc4);
   1190 	isc_sockaddr_any6(&zone->notifysrc6);
   1191 	isc_sockaddr_any(&zone->parentalsrc4);
   1192 	isc_sockaddr_any6(&zone->parentalsrc6);
   1193 	isc_sockaddr_any(&zone->xfrsource4);
   1194 	isc_sockaddr_any6(&zone->xfrsource6);
   1195 	isc_sockaddr_any(&zone->altxfrsource4);
   1196 	isc_sockaddr_any6(&zone->altxfrsource6);
   1197 	ISC_LINK_INIT(zone, statelink);
   1198 	ISC_LIST_INIT(zone->signing);
   1199 	ISC_LIST_INIT(zone->nsec3chain);
   1200 	ISC_LIST_INIT(zone->setnsec3param_queue);
   1201 	ISC_LIST_INIT(zone->forwards);
   1202 	ISC_LIST_INIT(zone->rss_events);
   1203 	ISC_LIST_INIT(zone->rss_post);
   1204 
   1205 	result = isc_stats_create(mctx, &zone->gluecachestats,
   1206 				  dns_gluecachestatscounter_max);
   1207 	if (result != ISC_R_SUCCESS) {
   1208 		goto free_refs;
   1209 	}
   1210 
   1211 	/* Must be after magic is set. */
   1212 	dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
   1213 
   1214 	ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
   1215 		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL,
   1216 		       NULL);
   1217 	*zonep = zone;
   1218 	return (ISC_R_SUCCESS);
   1219 
   1220 free_refs:
   1221 	isc_refcount_decrement0(&zone->erefs);
   1222 	isc_refcount_destroy(&zone->erefs);
   1223 	isc_refcount_destroy(&zone->irefs);
   1224 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1225 	isc_mutex_destroy(&zone->lock);
   1226 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1227 	return (result);
   1228 }
   1229 
   1230 static void
   1231 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
   1232 	dns_dnsseckey_t *key;
   1233 	while (!ISC_LIST_EMPTY(*list)) {
   1234 		key = ISC_LIST_HEAD(*list);
   1235 		ISC_LIST_UNLINK(*list, key, link);
   1236 		dns_dnsseckey_destroy(mctx, &key);
   1237 	}
   1238 }
   1239 
   1240 /*
   1241  * Free a zone.  Because we require that there be no more
   1242  * outstanding events or references, no locking is necessary.
   1243  */
   1244 static void
   1245 zone_free(dns_zone_t *zone) {
   1246 	dns_signing_t *signing;
   1247 	dns_nsec3chain_t *nsec3chain;
   1248 	isc_event_t *event;
   1249 	dns_include_t *include;
   1250 
   1251 	REQUIRE(DNS_ZONE_VALID(zone));
   1252 	isc_refcount_destroy(&zone->erefs);
   1253 	isc_refcount_destroy(&zone->irefs);
   1254 	REQUIRE(!LOCKED_ZONE(zone));
   1255 	REQUIRE(zone->timer == NULL);
   1256 	REQUIRE(zone->zmgr == NULL);
   1257 
   1258 	/*
   1259 	 * Managed objects.  Order is important.
   1260 	 */
   1261 	if (zone->request != NULL) {
   1262 		dns_request_destroy(&zone->request); /* XXXMPA */
   1263 	}
   1264 	INSIST(zone->readio == NULL);
   1265 	INSIST(zone->statelist == NULL);
   1266 	INSIST(zone->writeio == NULL);
   1267 	INSIST(zone->view == NULL);
   1268 	INSIST(zone->prev_view == NULL);
   1269 
   1270 	if (zone->task != NULL) {
   1271 		isc_task_detach(&zone->task);
   1272 	}
   1273 	if (zone->loadtask != NULL) {
   1274 		isc_task_detach(&zone->loadtask);
   1275 	}
   1276 
   1277 	/* Unmanaged objects */
   1278 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   1279 		event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   1280 		ISC_LIST_UNLINK(zone->setnsec3param_queue, event, ev_link);
   1281 		isc_event_free(&event);
   1282 	}
   1283 	while (!ISC_LIST_EMPTY(zone->rss_post)) {
   1284 		event = ISC_LIST_HEAD(zone->rss_post);
   1285 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   1286 		isc_event_free(&event);
   1287 	}
   1288 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   1289 	     signing = ISC_LIST_HEAD(zone->signing))
   1290 	{
   1291 		ISC_LIST_UNLINK(zone->signing, signing, link);
   1292 		dns_db_detach(&signing->db);
   1293 		dns_dbiterator_destroy(&signing->dbiterator);
   1294 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   1295 	}
   1296 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   1297 	     nsec3chain = ISC_LIST_HEAD(zone->nsec3chain))
   1298 	{
   1299 		ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   1300 		dns_db_detach(&nsec3chain->db);
   1301 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   1302 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   1303 	}
   1304 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   1305 	     include = ISC_LIST_HEAD(zone->includes))
   1306 	{
   1307 		ISC_LIST_UNLINK(zone->includes, include, link);
   1308 		isc_mem_free(zone->mctx, include->name);
   1309 		isc_mem_put(zone->mctx, include, sizeof *include);
   1310 	}
   1311 	for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL;
   1312 	     include = ISC_LIST_HEAD(zone->newincludes))
   1313 	{
   1314 		ISC_LIST_UNLINK(zone->newincludes, include, link);
   1315 		isc_mem_free(zone->mctx, include->name);
   1316 		isc_mem_put(zone->mctx, include, sizeof *include);
   1317 	}
   1318 	if (zone->masterfile != NULL) {
   1319 		isc_mem_free(zone->mctx, zone->masterfile);
   1320 	}
   1321 	zone->masterfile = NULL;
   1322 	if (zone->keydirectory != NULL) {
   1323 		isc_mem_free(zone->mctx, zone->keydirectory);
   1324 	}
   1325 	zone->keydirectory = NULL;
   1326 	if (zone->kasp != NULL) {
   1327 		dns_kasp_detach(&zone->kasp);
   1328 	}
   1329 	if (!ISC_LIST_EMPTY(zone->checkds_ok)) {
   1330 		clear_keylist(&zone->checkds_ok, zone->mctx);
   1331 	}
   1332 
   1333 	zone->journalsize = -1;
   1334 	if (zone->journal != NULL) {
   1335 		isc_mem_free(zone->mctx, zone->journal);
   1336 	}
   1337 	zone->journal = NULL;
   1338 	if (zone->stats != NULL) {
   1339 		isc_stats_detach(&zone->stats);
   1340 	}
   1341 	if (zone->requeststats != NULL) {
   1342 		isc_stats_detach(&zone->requeststats);
   1343 	}
   1344 	if (zone->rcvquerystats != NULL) {
   1345 		dns_stats_detach(&zone->rcvquerystats);
   1346 	}
   1347 	if (zone->dnssecsignstats != NULL) {
   1348 		dns_stats_detach(&zone->dnssecsignstats);
   1349 	}
   1350 	if (zone->db != NULL) {
   1351 		zone_detachdb(zone);
   1352 	}
   1353 	if (zone->rpzs != NULL) {
   1354 		REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
   1355 		dns_rpz_detach_rpzs(&zone->rpzs);
   1356 		zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1357 	}
   1358 	if (zone->catzs != NULL) {
   1359 		dns_catz_detach_catzs(&zone->catzs);
   1360 	}
   1361 	zone_freedbargs(zone);
   1362 	dns_zone_setparentals(zone, NULL, NULL, NULL, 0);
   1363 	dns_zone_setprimaries(zone, NULL, NULL, NULL, 0);
   1364 	dns_zone_setalsonotify(zone, NULL, NULL, NULL, 0);
   1365 
   1366 	zone->check_names = dns_severity_ignore;
   1367 	if (zone->update_acl != NULL) {
   1368 		dns_acl_detach(&zone->update_acl);
   1369 	}
   1370 	if (zone->forward_acl != NULL) {
   1371 		dns_acl_detach(&zone->forward_acl);
   1372 	}
   1373 	if (zone->notify_acl != NULL) {
   1374 		dns_acl_detach(&zone->notify_acl);
   1375 	}
   1376 	if (zone->query_acl != NULL) {
   1377 		dns_acl_detach(&zone->query_acl);
   1378 	}
   1379 	if (zone->queryon_acl != NULL) {
   1380 		dns_acl_detach(&zone->queryon_acl);
   1381 	}
   1382 	if (zone->xfr_acl != NULL) {
   1383 		dns_acl_detach(&zone->xfr_acl);
   1384 	}
   1385 	if (dns_name_dynamic(&zone->origin)) {
   1386 		dns_name_free(&zone->origin, zone->mctx);
   1387 	}
   1388 	if (zone->strnamerd != NULL) {
   1389 		isc_mem_free(zone->mctx, zone->strnamerd);
   1390 	}
   1391 	if (zone->strname != NULL) {
   1392 		isc_mem_free(zone->mctx, zone->strname);
   1393 	}
   1394 	if (zone->strrdclass != NULL) {
   1395 		isc_mem_free(zone->mctx, zone->strrdclass);
   1396 	}
   1397 	if (zone->strviewname != NULL) {
   1398 		isc_mem_free(zone->mctx, zone->strviewname);
   1399 	}
   1400 	if (zone->ssutable != NULL) {
   1401 		dns_ssutable_detach(&zone->ssutable);
   1402 	}
   1403 	if (zone->gluecachestats != NULL) {
   1404 		isc_stats_detach(&zone->gluecachestats);
   1405 	}
   1406 
   1407 	/* last stuff */
   1408 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1409 	isc_mutex_destroy(&zone->lock);
   1410 	zone->magic = 0;
   1411 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1412 }
   1413 
   1414 /*
   1415  * Returns true iff this the signed side of an inline-signing zone.
   1416  * Caller should hold zone lock.
   1417  */
   1418 static bool
   1419 inline_secure(dns_zone_t *zone) {
   1420 	REQUIRE(DNS_ZONE_VALID(zone));
   1421 	if (zone->raw != NULL) {
   1422 		return (true);
   1423 	}
   1424 	return (false);
   1425 }
   1426 
   1427 /*
   1428  * Returns true iff this the unsigned side of an inline-signing zone
   1429  * Caller should hold zone lock.
   1430  */
   1431 static bool
   1432 inline_raw(dns_zone_t *zone) {
   1433 	REQUIRE(DNS_ZONE_VALID(zone));
   1434 	if (zone->secure != NULL) {
   1435 		return (true);
   1436 	}
   1437 	return (false);
   1438 }
   1439 
   1440 /*
   1441  *	Single shot.
   1442  */
   1443 void
   1444 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
   1445 	char namebuf[1024];
   1446 
   1447 	REQUIRE(DNS_ZONE_VALID(zone));
   1448 	REQUIRE(rdclass != dns_rdataclass_none);
   1449 
   1450 	/*
   1451 	 * Test and set.
   1452 	 */
   1453 	LOCK_ZONE(zone);
   1454 	INSIST(zone != zone->raw);
   1455 	REQUIRE(zone->rdclass == dns_rdataclass_none ||
   1456 		zone->rdclass == rdclass);
   1457 	zone->rdclass = rdclass;
   1458 
   1459 	if (zone->strnamerd != NULL) {
   1460 		isc_mem_free(zone->mctx, zone->strnamerd);
   1461 	}
   1462 	if (zone->strrdclass != NULL) {
   1463 		isc_mem_free(zone->mctx, zone->strrdclass);
   1464 	}
   1465 
   1466 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1467 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1468 	zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
   1469 	zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
   1470 
   1471 	if (inline_secure(zone)) {
   1472 		dns_zone_setclass(zone->raw, rdclass);
   1473 	}
   1474 	UNLOCK_ZONE(zone);
   1475 }
   1476 
   1477 dns_rdataclass_t
   1478 dns_zone_getclass(dns_zone_t *zone) {
   1479 	REQUIRE(DNS_ZONE_VALID(zone));
   1480 
   1481 	return (zone->rdclass);
   1482 }
   1483 
   1484 void
   1485 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
   1486 	REQUIRE(DNS_ZONE_VALID(zone));
   1487 
   1488 	LOCK_ZONE(zone);
   1489 	zone->notifytype = notifytype;
   1490 	UNLOCK_ZONE(zone);
   1491 }
   1492 
   1493 isc_result_t
   1494 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
   1495 	isc_result_t result;
   1496 	unsigned int soacount;
   1497 
   1498 	REQUIRE(DNS_ZONE_VALID(zone));
   1499 	REQUIRE(serialp != NULL);
   1500 
   1501 	LOCK_ZONE(zone);
   1502 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   1503 	if (zone->db != NULL) {
   1504 		result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
   1505 					  serialp, NULL, NULL, NULL, NULL,
   1506 					  NULL);
   1507 		if (result == ISC_R_SUCCESS && soacount == 0) {
   1508 			result = ISC_R_FAILURE;
   1509 		}
   1510 	} else {
   1511 		result = DNS_R_NOTLOADED;
   1512 	}
   1513 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   1514 	UNLOCK_ZONE(zone);
   1515 
   1516 	return (result);
   1517 }
   1518 
   1519 /*
   1520  *	Single shot.
   1521  */
   1522 void
   1523 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
   1524 	char namebuf[1024];
   1525 
   1526 	REQUIRE(DNS_ZONE_VALID(zone));
   1527 	REQUIRE(type != dns_zone_none);
   1528 
   1529 	/*
   1530 	 * Test and set.
   1531 	 */
   1532 	LOCK_ZONE(zone);
   1533 	REQUIRE(zone->type == dns_zone_none || zone->type == type);
   1534 	zone->type = type;
   1535 
   1536 	if (zone->strnamerd != NULL) {
   1537 		isc_mem_free(zone->mctx, zone->strnamerd);
   1538 	}
   1539 
   1540 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1541 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1542 	UNLOCK_ZONE(zone);
   1543 }
   1544 
   1545 static void
   1546 zone_freedbargs(dns_zone_t *zone) {
   1547 	unsigned int i;
   1548 
   1549 	/* Free the old database argument list. */
   1550 	if (zone->db_argv != NULL) {
   1551 		for (i = 0; i < zone->db_argc; i++) {
   1552 			isc_mem_free(zone->mctx, zone->db_argv[i]);
   1553 		}
   1554 		isc_mem_put(zone->mctx, zone->db_argv,
   1555 			    zone->db_argc * sizeof(*zone->db_argv));
   1556 	}
   1557 	zone->db_argc = 0;
   1558 	zone->db_argv = NULL;
   1559 }
   1560 
   1561 isc_result_t
   1562 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
   1563 	size_t size = 0;
   1564 	unsigned int i;
   1565 	isc_result_t result = ISC_R_SUCCESS;
   1566 	void *mem;
   1567 	char **tmp, *tmp2, *base;
   1568 
   1569 	REQUIRE(DNS_ZONE_VALID(zone));
   1570 	REQUIRE(argv != NULL && *argv == NULL);
   1571 
   1572 	LOCK_ZONE(zone);
   1573 	size = (zone->db_argc + 1) * sizeof(char *);
   1574 	for (i = 0; i < zone->db_argc; i++) {
   1575 		size += strlen(zone->db_argv[i]) + 1;
   1576 	}
   1577 	mem = isc_mem_allocate(mctx, size);
   1578 	{
   1579 		tmp = mem;
   1580 		tmp2 = mem;
   1581 		base = mem;
   1582 		tmp2 += (zone->db_argc + 1) * sizeof(char *);
   1583 		for (i = 0; i < zone->db_argc; i++) {
   1584 			*tmp++ = tmp2;
   1585 			strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
   1586 			tmp2 += strlen(tmp2) + 1;
   1587 		}
   1588 		*tmp = NULL;
   1589 	}
   1590 	UNLOCK_ZONE(zone);
   1591 	*argv = mem;
   1592 	return (result);
   1593 }
   1594 
   1595 void
   1596 dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc,
   1597 		   const char *const *dbargv) {
   1598 	char **argv = NULL;
   1599 	unsigned int i;
   1600 
   1601 	REQUIRE(DNS_ZONE_VALID(zone));
   1602 	REQUIRE(dbargc >= 1);
   1603 	REQUIRE(dbargv != NULL);
   1604 
   1605 	LOCK_ZONE(zone);
   1606 
   1607 	/* Set up a new database argument list. */
   1608 	argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv));
   1609 	for (i = 0; i < dbargc; i++) {
   1610 		argv[i] = NULL;
   1611 	}
   1612 	for (i = 0; i < dbargc; i++) {
   1613 		argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
   1614 	}
   1615 
   1616 	/* Free the old list. */
   1617 	zone_freedbargs(zone);
   1618 
   1619 	zone->db_argc = dbargc;
   1620 	zone->db_argv = argv;
   1621 
   1622 	UNLOCK_ZONE(zone);
   1623 }
   1624 
   1625 static void
   1626 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
   1627 	char namebuf[1024];
   1628 
   1629 	if (zone->prev_view == NULL && zone->view != NULL) {
   1630 		dns_view_weakattach(zone->view, &zone->prev_view);
   1631 	}
   1632 
   1633 	INSIST(zone != zone->raw);
   1634 	if (zone->view != NULL) {
   1635 		dns_view_sfd_del(zone->view, &zone->origin);
   1636 		dns_view_weakdetach(&zone->view);
   1637 	}
   1638 	dns_view_weakattach(view, &zone->view);
   1639 	dns_view_sfd_add(view, &zone->origin);
   1640 
   1641 	if (zone->strviewname != NULL) {
   1642 		isc_mem_free(zone->mctx, zone->strviewname);
   1643 	}
   1644 	if (zone->strnamerd != NULL) {
   1645 		isc_mem_free(zone->mctx, zone->strnamerd);
   1646 	}
   1647 
   1648 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1649 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1650 	zone_viewname_tostr(zone, namebuf, sizeof namebuf);
   1651 	zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
   1652 
   1653 	if (inline_secure(zone)) {
   1654 		dns_zone_setview(zone->raw, view);
   1655 	}
   1656 }
   1657 
   1658 void
   1659 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
   1660 	REQUIRE(DNS_ZONE_VALID(zone));
   1661 
   1662 	LOCK_ZONE(zone);
   1663 	dns_zone_setview_helper(zone, view);
   1664 	UNLOCK_ZONE(zone);
   1665 }
   1666 
   1667 dns_view_t *
   1668 dns_zone_getview(dns_zone_t *zone) {
   1669 	REQUIRE(DNS_ZONE_VALID(zone));
   1670 
   1671 	return (zone->view);
   1672 }
   1673 
   1674 void
   1675 dns_zone_setviewcommit(dns_zone_t *zone) {
   1676 	REQUIRE(DNS_ZONE_VALID(zone));
   1677 
   1678 	LOCK_ZONE(zone);
   1679 	if (zone->prev_view != NULL) {
   1680 		dns_view_weakdetach(&zone->prev_view);
   1681 	}
   1682 	if (inline_secure(zone)) {
   1683 		dns_zone_setviewcommit(zone->raw);
   1684 	}
   1685 	UNLOCK_ZONE(zone);
   1686 }
   1687 
   1688 void
   1689 dns_zone_setviewrevert(dns_zone_t *zone) {
   1690 	REQUIRE(DNS_ZONE_VALID(zone));
   1691 
   1692 	LOCK_ZONE(zone);
   1693 	if (zone->prev_view != NULL) {
   1694 		dns_zone_setview_helper(zone, zone->prev_view);
   1695 		dns_view_weakdetach(&zone->prev_view);
   1696 	}
   1697 	if (zone->catzs != NULL) {
   1698 		zone_catz_enable(zone, zone->catzs);
   1699 	}
   1700 	if (inline_secure(zone)) {
   1701 		dns_zone_setviewrevert(zone->raw);
   1702 	}
   1703 	UNLOCK_ZONE(zone);
   1704 }
   1705 
   1706 isc_result_t
   1707 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
   1708 	isc_result_t result = ISC_R_SUCCESS;
   1709 	char namebuf[1024];
   1710 
   1711 	REQUIRE(DNS_ZONE_VALID(zone));
   1712 	REQUIRE(origin != NULL);
   1713 
   1714 	LOCK_ZONE(zone);
   1715 	INSIST(zone != zone->raw);
   1716 	if (dns_name_dynamic(&zone->origin)) {
   1717 		dns_name_free(&zone->origin, zone->mctx);
   1718 		dns_name_init(&zone->origin, NULL);
   1719 	}
   1720 	dns_name_dup(origin, zone->mctx, &zone->origin);
   1721 
   1722 	if (zone->strnamerd != NULL) {
   1723 		isc_mem_free(zone->mctx, zone->strnamerd);
   1724 	}
   1725 	if (zone->strname != NULL) {
   1726 		isc_mem_free(zone->mctx, zone->strname);
   1727 	}
   1728 
   1729 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1730 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1731 	zone_name_tostr(zone, namebuf, sizeof namebuf);
   1732 	zone->strname = isc_mem_strdup(zone->mctx, namebuf);
   1733 
   1734 	if (inline_secure(zone)) {
   1735 		result = dns_zone_setorigin(zone->raw, origin);
   1736 	}
   1737 	UNLOCK_ZONE(zone);
   1738 	return (result);
   1739 }
   1740 
   1741 static isc_result_t
   1742 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
   1743 	char *copy;
   1744 
   1745 	if (value != NULL) {
   1746 		copy = isc_mem_strdup(zone->mctx, value);
   1747 	} else {
   1748 		copy = NULL;
   1749 	}
   1750 
   1751 	if (*field != NULL) {
   1752 		isc_mem_free(zone->mctx, *field);
   1753 	}
   1754 
   1755 	*field = copy;
   1756 	return (ISC_R_SUCCESS);
   1757 }
   1758 
   1759 isc_result_t
   1760 dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format,
   1761 		 const dns_master_style_t *style) {
   1762 	isc_result_t result = ISC_R_SUCCESS;
   1763 
   1764 	REQUIRE(DNS_ZONE_VALID(zone));
   1765 	REQUIRE(zone->stream == NULL);
   1766 
   1767 	LOCK_ZONE(zone);
   1768 	result = dns_zone_setstring(zone, &zone->masterfile, file);
   1769 	if (result == ISC_R_SUCCESS) {
   1770 		zone->masterformat = format;
   1771 		if (format == dns_masterformat_text) {
   1772 			zone->masterstyle = style;
   1773 		}
   1774 		result = default_journal(zone);
   1775 	}
   1776 	UNLOCK_ZONE(zone);
   1777 
   1778 	return (result);
   1779 }
   1780 
   1781 const char *
   1782 dns_zone_getfile(dns_zone_t *zone) {
   1783 	REQUIRE(DNS_ZONE_VALID(zone));
   1784 
   1785 	return (zone->masterfile);
   1786 }
   1787 
   1788 isc_result_t
   1789 dns_zone_setstream(dns_zone_t *zone, const FILE *stream,
   1790 		   dns_masterformat_t format, const dns_master_style_t *style) {
   1791 	isc_result_t result = ISC_R_SUCCESS;
   1792 
   1793 	REQUIRE(DNS_ZONE_VALID(zone));
   1794 	REQUIRE(stream != NULL);
   1795 	REQUIRE(zone->masterfile == NULL);
   1796 
   1797 	LOCK_ZONE(zone);
   1798 	zone->stream = stream;
   1799 	zone->masterformat = format;
   1800 	if (format == dns_masterformat_text) {
   1801 		zone->masterstyle = style;
   1802 	}
   1803 	result = default_journal(zone);
   1804 	UNLOCK_ZONE(zone);
   1805 
   1806 	return (result);
   1807 }
   1808 
   1809 dns_ttl_t
   1810 dns_zone_getmaxttl(dns_zone_t *zone) {
   1811 	REQUIRE(DNS_ZONE_VALID(zone));
   1812 
   1813 	return (zone->maxttl);
   1814 }
   1815 
   1816 void
   1817 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
   1818 	REQUIRE(DNS_ZONE_VALID(zone));
   1819 
   1820 	LOCK_ZONE(zone);
   1821 	if (maxttl != 0) {
   1822 		DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1823 	} else {
   1824 		DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1825 	}
   1826 	zone->maxttl = maxttl;
   1827 	UNLOCK_ZONE(zone);
   1828 
   1829 	return;
   1830 }
   1831 
   1832 static isc_result_t
   1833 default_journal(dns_zone_t *zone) {
   1834 	isc_result_t result;
   1835 	char *journal;
   1836 
   1837 	REQUIRE(DNS_ZONE_VALID(zone));
   1838 	REQUIRE(LOCKED_ZONE(zone));
   1839 
   1840 	if (zone->masterfile != NULL) {
   1841 		/* Calculate string length including '\0'. */
   1842 		int len = strlen(zone->masterfile) + sizeof(".jnl");
   1843 		journal = isc_mem_allocate(zone->mctx, len);
   1844 		strlcpy(journal, zone->masterfile, len);
   1845 		strlcat(journal, ".jnl", len);
   1846 	} else {
   1847 		journal = NULL;
   1848 	}
   1849 	result = dns_zone_setstring(zone, &zone->journal, journal);
   1850 	if (journal != NULL) {
   1851 		isc_mem_free(zone->mctx, journal);
   1852 	}
   1853 	return (result);
   1854 }
   1855 
   1856 isc_result_t
   1857 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
   1858 	isc_result_t result = ISC_R_SUCCESS;
   1859 
   1860 	REQUIRE(DNS_ZONE_VALID(zone));
   1861 
   1862 	LOCK_ZONE(zone);
   1863 	result = dns_zone_setstring(zone, &zone->journal, myjournal);
   1864 	UNLOCK_ZONE(zone);
   1865 
   1866 	return (result);
   1867 }
   1868 
   1869 char *
   1870 dns_zone_getjournal(dns_zone_t *zone) {
   1871 	REQUIRE(DNS_ZONE_VALID(zone));
   1872 
   1873 	return (zone->journal);
   1874 }
   1875 
   1876 /*
   1877  * Return true iff the zone is "dynamic", in the sense that the zone's
   1878  * master file (if any) is written by the server, rather than being
   1879  * updated manually and read by the server.
   1880  *
   1881  * This is true for secondary zones, mirror zones, stub zones, key zones,
   1882  * and zones that allow dynamic updates either by having an update
   1883  * policy ("ssutable") or an "allow-update" ACL with a value other than
   1884  * exactly "{ none; }".
   1885  */
   1886 bool
   1887 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
   1888 	REQUIRE(DNS_ZONE_VALID(zone));
   1889 
   1890 	if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror ||
   1891 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   1892 	    (zone->type == dns_zone_redirect && zone->primaries != NULL))
   1893 	{
   1894 		return (true);
   1895 	}
   1896 
   1897 	/* Inline zones are always dynamic. */
   1898 	if (zone->type == dns_zone_primary && zone->raw != NULL) {
   1899 		return (true);
   1900 	}
   1901 
   1902 	/* If !ignore_freeze, we need check whether updates are disabled.  */
   1903 	if (zone->type == dns_zone_primary &&
   1904 	    (!zone->update_disabled || ignore_freeze) &&
   1905 	    ((zone->ssutable != NULL) ||
   1906 	     (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
   1907 	{
   1908 		return (true);
   1909 	}
   1910 
   1911 	return (false);
   1912 }
   1913 
   1914 /*
   1915  * Set the response policy index and information for a zone.
   1916  */
   1917 isc_result_t
   1918 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
   1919 		    dns_rpz_num_t rpz_num) {
   1920 	/*
   1921 	 * Only RBTDB zones can be used for response policy zones,
   1922 	 * because only they have the code to create the summary data.
   1923 	 * Only zones that are loaded instead of mmap()ed create the
   1924 	 * summary data and so can be policy zones.
   1925 	 */
   1926 	if (strcmp(zone->db_argv[0], "rbt") != 0 &&
   1927 	    strcmp(zone->db_argv[0], "rbt64") != 0)
   1928 	{
   1929 		return (ISC_R_NOTIMPLEMENTED);
   1930 	}
   1931 
   1932 	/*
   1933 	 * This must happen only once or be redundant.
   1934 	 */
   1935 	LOCK_ZONE(zone);
   1936 	if (zone->rpzs != NULL) {
   1937 		REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
   1938 	} else {
   1939 		REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
   1940 		dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
   1941 		zone->rpz_num = rpz_num;
   1942 	}
   1943 	rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
   1944 	UNLOCK_ZONE(zone);
   1945 
   1946 	return (ISC_R_SUCCESS);
   1947 }
   1948 
   1949 dns_rpz_num_t
   1950 dns_zone_get_rpz_num(dns_zone_t *zone) {
   1951 	return (zone->rpz_num);
   1952 }
   1953 
   1954 /*
   1955  * If a zone is a response policy zone, mark its new database.
   1956  */
   1957 void
   1958 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1959 	isc_result_t result;
   1960 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1961 		return;
   1962 	}
   1963 	REQUIRE(zone->rpzs != NULL);
   1964 	result = dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback,
   1965 					      zone->rpzs->zones[zone->rpz_num]);
   1966 	REQUIRE(result == ISC_R_SUCCESS);
   1967 }
   1968 
   1969 static void
   1970 dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1971 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1972 		return;
   1973 	}
   1974 	REQUIRE(zone->rpzs != NULL);
   1975 	(void)dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback,
   1976 					     zone->rpzs->zones[zone->rpz_num]);
   1977 }
   1978 
   1979 /*
   1980  * If a zone is a catalog zone, attach it to update notification in database.
   1981  */
   1982 void
   1983 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1984 	REQUIRE(DNS_ZONE_VALID(zone));
   1985 	REQUIRE(db != NULL);
   1986 
   1987 	if (zone->catzs != NULL) {
   1988 		dns_catz_dbupdate_register(db, zone->catzs);
   1989 	}
   1990 }
   1991 
   1992 static void
   1993 dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1994 	REQUIRE(DNS_ZONE_VALID(zone));
   1995 	REQUIRE(db != NULL);
   1996 
   1997 	if (zone->catzs != NULL) {
   1998 		dns_catz_dbupdate_unregister(db, zone->catzs);
   1999 	}
   2000 }
   2001 
   2002 static void
   2003 zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
   2004 	REQUIRE(DNS_ZONE_VALID(zone));
   2005 	REQUIRE(catzs != NULL);
   2006 
   2007 	INSIST(zone->catzs == NULL || zone->catzs == catzs);
   2008 	dns_catz_catzs_set_view(catzs, zone->view);
   2009 	if (zone->catzs == NULL) {
   2010 		dns_catz_attach_catzs(catzs, &zone->catzs);
   2011 	}
   2012 }
   2013 
   2014 void
   2015 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
   2016 	REQUIRE(DNS_ZONE_VALID(zone));
   2017 
   2018 	LOCK_ZONE(zone);
   2019 	zone_catz_enable(zone, catzs);
   2020 	UNLOCK_ZONE(zone);
   2021 }
   2022 
   2023 static void
   2024 zone_catz_disable(dns_zone_t *zone) {
   2025 	REQUIRE(DNS_ZONE_VALID(zone));
   2026 
   2027 	if (zone->catzs != NULL) {
   2028 		if (zone->db != NULL) {
   2029 			dns_zone_catz_disable_db(zone, zone->db);
   2030 		}
   2031 		dns_catz_detach_catzs(&zone->catzs);
   2032 	}
   2033 }
   2034 
   2035 void
   2036 dns_zone_catz_disable(dns_zone_t *zone) {
   2037 	REQUIRE(DNS_ZONE_VALID(zone));
   2038 
   2039 	LOCK_ZONE(zone);
   2040 	zone_catz_disable(zone);
   2041 	UNLOCK_ZONE(zone);
   2042 }
   2043 
   2044 bool
   2045 dns_zone_catz_is_enabled(dns_zone_t *zone) {
   2046 	REQUIRE(DNS_ZONE_VALID(zone));
   2047 
   2048 	return (zone->catzs != NULL);
   2049 }
   2050 
   2051 /*
   2052  * Set catalog zone ownership of the zone
   2053  */
   2054 void
   2055 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) {
   2056 	REQUIRE(DNS_ZONE_VALID(zone));
   2057 	REQUIRE(catz != NULL);
   2058 	LOCK_ZONE(zone);
   2059 	INSIST(zone->parentcatz == NULL || zone->parentcatz == catz);
   2060 	zone->parentcatz = catz;
   2061 	UNLOCK_ZONE(zone);
   2062 }
   2063 
   2064 dns_catz_zone_t *
   2065 dns_zone_get_parentcatz(const dns_zone_t *zone) {
   2066 	REQUIRE(DNS_ZONE_VALID(zone));
   2067 	return (zone->parentcatz);
   2068 }
   2069 
   2070 static bool
   2071 zone_touched(dns_zone_t *zone) {
   2072 	isc_result_t result;
   2073 	isc_time_t modtime;
   2074 	dns_include_t *include;
   2075 
   2076 	REQUIRE(DNS_ZONE_VALID(zone));
   2077 
   2078 	result = isc_file_getmodtime(zone->masterfile, &modtime);
   2079 	if (result != ISC_R_SUCCESS ||
   2080 	    isc_time_compare(&modtime, &zone->loadtime) > 0)
   2081 	{
   2082 		return (true);
   2083 	}
   2084 
   2085 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   2086 	     include = ISC_LIST_NEXT(include, link))
   2087 	{
   2088 		result = isc_file_getmodtime(include->name, &modtime);
   2089 		if (result != ISC_R_SUCCESS ||
   2090 		    isc_time_compare(&modtime, &include->filetime) > 0)
   2091 		{
   2092 			return (true);
   2093 		}
   2094 	}
   2095 
   2096 	return (false);
   2097 }
   2098 
   2099 /*
   2100  * Note: when dealing with inline-signed zones, external callers will always
   2101  * call zone_load() for the secure zone; zone_load() calls itself recursively
   2102  * in order to load the raw zone.
   2103  */
   2104 static isc_result_t
   2105 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
   2106 	isc_result_t result;
   2107 	isc_time_t now;
   2108 	isc_time_t loadtime;
   2109 	dns_db_t *db = NULL;
   2110 	bool rbt, hasraw, is_dynamic;
   2111 
   2112 	REQUIRE(DNS_ZONE_VALID(zone));
   2113 
   2114 	if (!locked) {
   2115 		LOCK_ZONE(zone);
   2116 	}
   2117 
   2118 	INSIST(zone != zone->raw);
   2119 	hasraw = inline_secure(zone);
   2120 	if (hasraw) {
   2121 		/*
   2122 		 * We are trying to load an inline-signed zone.  First call
   2123 		 * self recursively to try loading the raw version of the zone.
   2124 		 * Assuming the raw zone file is readable, there are two
   2125 		 * possibilities:
   2126 		 *
   2127 		 *  a) the raw zone was not yet loaded and thus it will be
   2128 		 *     loaded now, synchronously; if this succeeds, a
   2129 		 *     subsequent attempt to load the signed zone file will
   2130 		 *     take place and thus zone_postload() will be called
   2131 		 *     twice: first for the raw zone and then for the secure
   2132 		 *     zone; the latter call will take care of syncing the raw
   2133 		 *     version with the secure version,
   2134 		 *
   2135 		 *  b) the raw zone was already loaded and we are trying to
   2136 		 *     reload it, which will happen asynchronously; this means
   2137 		 *     zone_postload() will only be called for the raw zone
   2138 		 *     because "result" returned by the zone_load() call below
   2139 		 *     will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE;
   2140 		 *     zone_postload() called for the raw zone will take care
   2141 		 *     of syncing the raw version with the secure version.
   2142 		 */
   2143 		result = zone_load(zone->raw, flags, false);
   2144 		if (result != ISC_R_SUCCESS) {
   2145 			if (!locked) {
   2146 				UNLOCK_ZONE(zone);
   2147 			}
   2148 			return (result);
   2149 		}
   2150 		LOCK_ZONE(zone->raw);
   2151 	}
   2152 
   2153 	TIME_NOW(&now);
   2154 
   2155 	INSIST(zone->type != dns_zone_none);
   2156 
   2157 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
   2158 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2159 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2160 		}
   2161 		result = DNS_R_CONTINUE;
   2162 		goto cleanup;
   2163 	}
   2164 
   2165 	INSIST(zone->db_argc >= 1);
   2166 
   2167 	rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
   2168 	      strcmp(zone->db_argv[0], "rbt64") == 0;
   2169 
   2170 	if (zone->db != NULL && zone->masterfile == NULL && rbt) {
   2171 		/*
   2172 		 * The zone has no master file configured.
   2173 		 */
   2174 		result = ISC_R_SUCCESS;
   2175 		goto cleanup;
   2176 	}
   2177 
   2178 	is_dynamic = dns_zone_isdynamic(zone, false);
   2179 	if (zone->db != NULL && is_dynamic) {
   2180 		/*
   2181 		 * This is a secondary, stub, or dynamically updated zone
   2182 		 * being reloaded.  Do nothing - the database we already
   2183 		 * have is guaranteed to be up-to-date.
   2184 		 */
   2185 		if (zone->type == dns_zone_primary && !hasraw) {
   2186 			result = DNS_R_DYNAMIC;
   2187 		} else {
   2188 			result = ISC_R_SUCCESS;
   2189 		}
   2190 		goto cleanup;
   2191 	}
   2192 
   2193 	/*
   2194 	 * Store the current time before the zone is loaded, so that if the
   2195 	 * file changes between the time of the load and the time that
   2196 	 * zone->loadtime is set, then the file will still be reloaded
   2197 	 * the next time dns_zone_load is called.
   2198 	 */
   2199 	TIME_NOW(&loadtime);
   2200 
   2201 	/*
   2202 	 * Don't do the load if the file that stores the zone is older
   2203 	 * than the last time the zone was loaded.  If the zone has not
   2204 	 * been loaded yet, zone->loadtime will be the epoch.
   2205 	 */
   2206 	if (zone->masterfile != NULL) {
   2207 		isc_time_t filetime;
   2208 
   2209 		/*
   2210 		 * The file is already loaded.	If we are just doing a
   2211 		 * "rndc reconfig", we are done.
   2212 		 */
   2213 		if (!isc_time_isepoch(&zone->loadtime) &&
   2214 		    (flags & DNS_ZONELOADFLAG_NOSTAT) != 0)
   2215 		{
   2216 			result = ISC_R_SUCCESS;
   2217 			goto cleanup;
   2218 		}
   2219 
   2220 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   2221 		    !zone_touched(zone))
   2222 		{
   2223 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2224 				      ISC_LOG_DEBUG(1),
   2225 				      "skipping load: master file "
   2226 				      "older than last load");
   2227 			result = DNS_R_UPTODATE;
   2228 			goto cleanup;
   2229 		}
   2230 
   2231 		/*
   2232 		 * If the file modification time is in the past
   2233 		 * set loadtime to that value.
   2234 		 */
   2235 		result = isc_file_getmodtime(zone->masterfile, &filetime);
   2236 		if (result == ISC_R_SUCCESS &&
   2237 		    isc_time_compare(&loadtime, &filetime) > 0)
   2238 		{
   2239 			loadtime = filetime;
   2240 		}
   2241 	}
   2242 
   2243 	/*
   2244 	 * Built in zones (with the exception of empty zones) don't need
   2245 	 * to be reloaded.
   2246 	 */
   2247 	if (zone->type == dns_zone_primary &&
   2248 	    strcmp(zone->db_argv[0], "_builtin") == 0 &&
   2249 	    (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
   2250 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   2251 	{
   2252 		result = ISC_R_SUCCESS;
   2253 		goto cleanup;
   2254 	}
   2255 
   2256 	/*
   2257 	 * Zones associated with a DLZ don't need to be loaded either,
   2258 	 * but we need to associate the database with the zone object.
   2259 	 */
   2260 	if (strcmp(zone->db_argv[0], "dlz") == 0) {
   2261 		dns_dlzdb_t *dlzdb;
   2262 		dns_dlzfindzone_t findzone;
   2263 
   2264 		for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
   2265 		     dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link))
   2266 		{
   2267 			INSIST(DNS_DLZ_VALID(dlzdb));
   2268 			if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) {
   2269 				break;
   2270 			}
   2271 		}
   2272 
   2273 		if (dlzdb == NULL) {
   2274 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2275 				      ISC_LOG_ERROR,
   2276 				      "DLZ %s does not exist or is set "
   2277 				      "to 'search yes;'",
   2278 				      zone->db_argv[1]);
   2279 			result = ISC_R_NOTFOUND;
   2280 			goto cleanup;
   2281 		}
   2282 
   2283 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   2284 		/* ask SDLZ driver if the zone is supported */
   2285 		findzone = dlzdb->implementation->methods->findzone;
   2286 		result = (*findzone)(dlzdb->implementation->driverarg,
   2287 				     dlzdb->dbdata, dlzdb->mctx,
   2288 				     zone->view->rdclass, &zone->origin, NULL,
   2289 				     NULL, &db);
   2290 		if (result != ISC_R_NOTFOUND) {
   2291 			if (zone->db != NULL) {
   2292 				zone_detachdb(zone);
   2293 			}
   2294 			zone_attachdb(zone, db);
   2295 			dns_db_detach(&db);
   2296 			result = ISC_R_SUCCESS;
   2297 		}
   2298 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   2299 
   2300 		if (result == ISC_R_SUCCESS) {
   2301 			if (dlzdb->configure_callback == NULL) {
   2302 				goto cleanup;
   2303 			}
   2304 
   2305 			result = (*dlzdb->configure_callback)(zone->view, dlzdb,
   2306 							      zone);
   2307 			if (result != ISC_R_SUCCESS) {
   2308 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2309 					      ISC_LOG_ERROR,
   2310 					      "DLZ configuration callback: %s",
   2311 					      isc_result_totext(result));
   2312 			}
   2313 		}
   2314 		goto cleanup;
   2315 	}
   2316 
   2317 	if ((zone->type == dns_zone_secondary ||
   2318 	     zone->type == dns_zone_mirror || zone->type == dns_zone_stub ||
   2319 	     (zone->type == dns_zone_redirect && zone->primaries != NULL)) &&
   2320 	    rbt)
   2321 	{
   2322 		if (zone->stream == NULL &&
   2323 		    (zone->masterfile == NULL ||
   2324 		     !isc_file_exists(zone->masterfile)))
   2325 		{
   2326 			if (zone->masterfile != NULL) {
   2327 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2328 					      ISC_LOG_DEBUG(1),
   2329 					      "no master file");
   2330 			}
   2331 			zone->refreshtime = now;
   2332 			if (zone->task != NULL) {
   2333 				zone_settimer(zone, &now);
   2334 			}
   2335 			result = ISC_R_SUCCESS;
   2336 			goto cleanup;
   2337 		}
   2338 	}
   2339 
   2340 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   2341 		      "starting load");
   2342 
   2343 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   2344 			       (zone->type == dns_zone_stub) ? dns_dbtype_stub
   2345 							     : dns_dbtype_zone,
   2346 			       zone->rdclass, zone->db_argc - 1,
   2347 			       zone->db_argv + 1, &db);
   2348 
   2349 	if (result != ISC_R_SUCCESS) {
   2350 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   2351 			      "loading zone: creating database: %s",
   2352 			      isc_result_totext(result));
   2353 		goto cleanup;
   2354 	}
   2355 	dns_db_settask(db, zone->task);
   2356 
   2357 	if (zone->type == dns_zone_primary ||
   2358 	    zone->type == dns_zone_secondary || zone->type == dns_zone_mirror)
   2359 	{
   2360 		result = dns_db_setgluecachestats(db, zone->gluecachestats);
   2361 		if (result == ISC_R_NOTIMPLEMENTED) {
   2362 			result = ISC_R_SUCCESS;
   2363 		}
   2364 		if (result != ISC_R_SUCCESS) {
   2365 			goto cleanup;
   2366 		}
   2367 	}
   2368 
   2369 	if (!dns_db_ispersistent(db)) {
   2370 		if (zone->masterfile != NULL || zone->stream != NULL) {
   2371 			result = zone_startload(db, zone, loadtime);
   2372 		} else {
   2373 			result = DNS_R_NOMASTERFILE;
   2374 			if (zone->type == dns_zone_primary ||
   2375 			    (zone->type == dns_zone_redirect &&
   2376 			     zone->primaries == NULL))
   2377 			{
   2378 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2379 					      ISC_LOG_ERROR,
   2380 					      "loading zone: "
   2381 					      "no master file configured");
   2382 				goto cleanup;
   2383 			}
   2384 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2385 				      ISC_LOG_INFO,
   2386 				      "loading zone: "
   2387 				      "no master file configured: continuing");
   2388 		}
   2389 	}
   2390 
   2391 	if (result == DNS_R_CONTINUE) {
   2392 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
   2393 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2394 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2395 		}
   2396 		goto cleanup;
   2397 	}
   2398 
   2399 	result = zone_postload(zone, db, loadtime, result);
   2400 
   2401 cleanup:
   2402 	if (hasraw) {
   2403 		UNLOCK_ZONE(zone->raw);
   2404 	}
   2405 	if (!locked) {
   2406 		UNLOCK_ZONE(zone);
   2407 	}
   2408 	if (db != NULL) {
   2409 		dns_db_detach(&db);
   2410 	}
   2411 	return (result);
   2412 }
   2413 
   2414 isc_result_t
   2415 dns_zone_load(dns_zone_t *zone, bool newonly) {
   2416 	return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
   2417 }
   2418 
   2419 static void
   2420 zone_asyncload(isc_task_t *task, isc_event_t *event) {
   2421 	dns_asyncload_t *asl = event->ev_arg;
   2422 	dns_zone_t *zone = asl->zone;
   2423 	isc_result_t result;
   2424 
   2425 	UNUSED(task);
   2426 
   2427 	REQUIRE(DNS_ZONE_VALID(zone));
   2428 
   2429 	isc_event_free(&event);
   2430 
   2431 	LOCK_ZONE(zone);
   2432 	result = zone_load(zone, asl->flags, true);
   2433 	if (result != DNS_R_CONTINUE) {
   2434 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2435 	}
   2436 	UNLOCK_ZONE(zone);
   2437 
   2438 	/* Inform the zone table we've finished loading */
   2439 	if (asl->loaded != NULL) {
   2440 		(asl->loaded)(asl->loaded_arg, zone, task);
   2441 	}
   2442 
   2443 	/* Reduce the quantum */
   2444 	isc_task_setquantum(zone->loadtask, 1);
   2445 
   2446 	isc_mem_put(zone->mctx, asl, sizeof(*asl));
   2447 	dns_zone_idetach(&zone);
   2448 }
   2449 
   2450 isc_result_t
   2451 dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_zoneloaded_t done,
   2452 		   void *arg) {
   2453 	isc_event_t *e;
   2454 	dns_asyncload_t *asl = NULL;
   2455 
   2456 	REQUIRE(DNS_ZONE_VALID(zone));
   2457 
   2458 	if (zone->zmgr == NULL) {
   2459 		return (ISC_R_FAILURE);
   2460 	}
   2461 
   2462 	/* If we already have a load pending, stop now */
   2463 	LOCK_ZONE(zone);
   2464 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) {
   2465 		UNLOCK_ZONE(zone);
   2466 		return (ISC_R_ALREADYRUNNING);
   2467 	}
   2468 
   2469 	asl = isc_mem_get(zone->mctx, sizeof(*asl));
   2470 
   2471 	asl->zone = NULL;
   2472 	asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
   2473 	asl->loaded = done;
   2474 	asl->loaded_arg = arg;
   2475 
   2476 	e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, DNS_EVENT_ZONELOAD,
   2477 			       zone_asyncload, asl, sizeof(isc_event_t));
   2478 
   2479 	zone_iattach(zone, &asl->zone);
   2480 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2481 	isc_task_send(zone->loadtask, &e);
   2482 	UNLOCK_ZONE(zone);
   2483 
   2484 	return (ISC_R_SUCCESS);
   2485 }
   2486 
   2487 bool
   2488 dns__zone_loadpending(dns_zone_t *zone) {
   2489 	REQUIRE(DNS_ZONE_VALID(zone));
   2490 
   2491 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
   2492 }
   2493 
   2494 isc_result_t
   2495 dns_zone_loadandthaw(dns_zone_t *zone) {
   2496 	isc_result_t result;
   2497 
   2498 	if (inline_raw(zone)) {
   2499 		result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false);
   2500 	} else {
   2501 		/*
   2502 		 * When thawing a zone, we don't know what changes
   2503 		 * have been made. If we do DNSSEC maintenance on this
   2504 		 * zone, schedule a full sign for this zone.
   2505 		 */
   2506 		if (zone->type == dns_zone_primary &&
   2507 		    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   2508 		{
   2509 			DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN);
   2510 		}
   2511 		result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false);
   2512 	}
   2513 
   2514 	switch (result) {
   2515 	case DNS_R_CONTINUE:
   2516 		/* Deferred thaw. */
   2517 		break;
   2518 	case DNS_R_UPTODATE:
   2519 	case ISC_R_SUCCESS:
   2520 	case DNS_R_SEENINCLUDE:
   2521 		zone->update_disabled = false;
   2522 		break;
   2523 	case DNS_R_NOMASTERFILE:
   2524 		zone->update_disabled = false;
   2525 		break;
   2526 	default:
   2527 		/* Error, remain in disabled state. */
   2528 		break;
   2529 	}
   2530 	return (result);
   2531 }
   2532 
   2533 static unsigned int
   2534 get_primary_options(dns_zone_t *zone) {
   2535 	unsigned int options;
   2536 
   2537 	options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
   2538 	if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror ||
   2539 	    (zone->type == dns_zone_redirect && zone->primaries == NULL))
   2540 	{
   2541 		options |= DNS_MASTER_SECONDARY;
   2542 	}
   2543 	if (zone->type == dns_zone_key) {
   2544 		options |= DNS_MASTER_KEY;
   2545 	}
   2546 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
   2547 		options |= DNS_MASTER_CHECKNS;
   2548 	}
   2549 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
   2550 		options |= DNS_MASTER_FATALNS;
   2551 	}
   2552 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
   2553 		options |= DNS_MASTER_CHECKNAMES;
   2554 	}
   2555 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
   2556 		options |= DNS_MASTER_CHECKNAMESFAIL;
   2557 	}
   2558 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
   2559 		options |= DNS_MASTER_CHECKMX;
   2560 	}
   2561 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2562 		options |= DNS_MASTER_CHECKMXFAIL;
   2563 	}
   2564 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
   2565 		options |= DNS_MASTER_CHECKWILDCARD;
   2566 	}
   2567 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
   2568 		options |= DNS_MASTER_CHECKTTL;
   2569 	}
   2570 
   2571 	return (options);
   2572 }
   2573 
   2574 static void
   2575 zone_registerinclude(const char *filename, void *arg) {
   2576 	isc_result_t result;
   2577 	dns_zone_t *zone = (dns_zone_t *)arg;
   2578 	dns_include_t *inc = NULL;
   2579 
   2580 	REQUIRE(DNS_ZONE_VALID(zone));
   2581 
   2582 	if (filename == NULL) {
   2583 		return;
   2584 	}
   2585 
   2586 	/*
   2587 	 * Suppress duplicates.
   2588 	 */
   2589 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   2590 	     inc = ISC_LIST_NEXT(inc, link))
   2591 	{
   2592 		if (strcmp(filename, inc->name) == 0) {
   2593 			return;
   2594 		}
   2595 	}
   2596 
   2597 	inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
   2598 	inc->name = isc_mem_strdup(zone->mctx, filename);
   2599 	ISC_LINK_INIT(inc, link);
   2600 
   2601 	result = isc_file_getmodtime(filename, &inc->filetime);
   2602 	if (result != ISC_R_SUCCESS) {
   2603 		isc_time_settoepoch(&inc->filetime);
   2604 	}
   2605 
   2606 	ISC_LIST_APPEND(zone->newincludes, inc, link);
   2607 }
   2608 
   2609 static void
   2610 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
   2611 	dns_load_t *load = event->ev_arg;
   2612 	isc_result_t result = ISC_R_SUCCESS;
   2613 	unsigned int options;
   2614 
   2615 	REQUIRE(DNS_LOAD_VALID(load));
   2616 
   2617 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2618 		result = ISC_R_CANCELED;
   2619 	}
   2620 	isc_event_free(&event);
   2621 	if (result == ISC_R_CANCELED) {
   2622 		goto fail;
   2623 	}
   2624 
   2625 	options = get_primary_options(load->zone);
   2626 
   2627 	result = dns_master_loadfileinc(
   2628 		load->zone->masterfile, dns_db_origin(load->db),
   2629 		dns_db_origin(load->db), load->zone->rdclass, options, 0,
   2630 		&load->callbacks, task, zone_loaddone, load, &load->zone->lctx,
   2631 		zone_registerinclude, load->zone, load->zone->mctx,
   2632 		load->zone->masterformat, load->zone->maxttl);
   2633 	if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
   2634 	    result != DNS_R_SEENINCLUDE)
   2635 	{
   2636 		goto fail;
   2637 	}
   2638 	return;
   2639 
   2640 fail:
   2641 	zone_loaddone(load, result);
   2642 }
   2643 
   2644 static void
   2645 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
   2646 	isc_result_t result;
   2647 	unsigned int soacount;
   2648 
   2649 	LOCK(&raw->lock);
   2650 	if (raw->db != NULL) {
   2651 		result = zone_get_from_db(raw, raw->db, NULL, &soacount, NULL,
   2652 					  &rawdata->sourceserial, NULL, NULL,
   2653 					  NULL, NULL, NULL);
   2654 		if (result == ISC_R_SUCCESS && soacount > 0U) {
   2655 			rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
   2656 		}
   2657 	}
   2658 	UNLOCK(&raw->lock);
   2659 }
   2660 
   2661 static void
   2662 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
   2663 	const char me[] = "zone_gotwritehandle";
   2664 	dns_zone_t *zone = event->ev_arg;
   2665 	isc_result_t result = ISC_R_SUCCESS;
   2666 	dns_dbversion_t *version = NULL;
   2667 	dns_masterrawheader_t rawdata;
   2668 	dns_db_t *db = NULL;
   2669 
   2670 	REQUIRE(DNS_ZONE_VALID(zone));
   2671 	INSIST(task == zone->task);
   2672 	ENTER;
   2673 
   2674 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2675 		result = ISC_R_CANCELED;
   2676 	}
   2677 	isc_event_free(&event);
   2678 	if (result == ISC_R_CANCELED) {
   2679 		goto fail;
   2680 	}
   2681 
   2682 	LOCK_ZONE(zone);
   2683 	INSIST(zone != zone->raw);
   2684 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   2685 	if (zone->db != NULL) {
   2686 		dns_db_attach(zone->db, &db);
   2687 	}
   2688 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   2689 	if (db != NULL) {
   2690 		const dns_master_style_t *output_style;
   2691 		dns_db_currentversion(db, &version);
   2692 		dns_master_initrawheader(&rawdata);
   2693 		if (inline_secure(zone)) {
   2694 			get_raw_serial(zone->raw, &rawdata);
   2695 		}
   2696 		if (zone->type == dns_zone_key) {
   2697 			output_style = &dns_master_style_keyzone;
   2698 		} else if (zone->masterstyle != NULL) {
   2699 			output_style = zone->masterstyle;
   2700 		} else {
   2701 			output_style = &dns_master_style_default;
   2702 		}
   2703 		result = dns_master_dumpasync(
   2704 			zone->mctx, db, version, output_style, zone->masterfile,
   2705 			zone->task, dump_done, zone, &zone->dctx,
   2706 			zone->masterformat, &rawdata);
   2707 		dns_db_closeversion(db, &version, false);
   2708 	} else {
   2709 		result = ISC_R_CANCELED;
   2710 	}
   2711 	if (db != NULL) {
   2712 		dns_db_detach(&db);
   2713 	}
   2714 	UNLOCK_ZONE(zone);
   2715 	if (result != DNS_R_CONTINUE) {
   2716 		goto fail;
   2717 	}
   2718 	return;
   2719 
   2720 fail:
   2721 	dump_done(zone, result);
   2722 }
   2723 
   2724 /*
   2725  * Save the raw serial number for inline-signing zones.
   2726  * (XXX: Other information from the header will be used
   2727  * for other purposes in the future, but for now this is
   2728  * all we're interested in.)
   2729  */
   2730 static void
   2731 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2732 	if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) {
   2733 		return;
   2734 	}
   2735 
   2736 	zone->sourceserial = header->sourceserial;
   2737 	zone->sourceserialset = true;
   2738 }
   2739 
   2740 void
   2741 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2742 	if (zone == NULL) {
   2743 		return;
   2744 	}
   2745 
   2746 	LOCK_ZONE(zone);
   2747 	zone_setrawdata(zone, header);
   2748 	UNLOCK_ZONE(zone);
   2749 }
   2750 
   2751 static isc_result_t
   2752 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
   2753 	const char me[] = "zone_startload";
   2754 	dns_load_t *load;
   2755 	isc_result_t result;
   2756 	isc_result_t tresult;
   2757 	unsigned int options;
   2758 
   2759 	ENTER;
   2760 
   2761 	dns_zone_rpz_enable_db(zone, db);
   2762 	dns_zone_catz_enable_db(zone, db);
   2763 
   2764 	options = get_primary_options(zone);
   2765 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) {
   2766 		options |= DNS_MASTER_MANYERRORS;
   2767 	}
   2768 
   2769 	if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
   2770 		load = isc_mem_get(zone->mctx, sizeof(*load));
   2771 
   2772 		load->mctx = NULL;
   2773 		load->zone = NULL;
   2774 		load->db = NULL;
   2775 		load->loadtime = loadtime;
   2776 		load->magic = LOAD_MAGIC;
   2777 
   2778 		isc_mem_attach(zone->mctx, &load->mctx);
   2779 		zone_iattach(zone, &load->zone);
   2780 		dns_db_attach(db, &load->db);
   2781 		dns_rdatacallbacks_init(&load->callbacks);
   2782 		load->callbacks.rawdata = zone_setrawdata;
   2783 		zone_iattach(zone, &load->callbacks.zone);
   2784 		result = dns_db_beginload(db, &load->callbacks);
   2785 		if (result != ISC_R_SUCCESS) {
   2786 			goto cleanup;
   2787 		}
   2788 		result = zonemgr_getio(zone->zmgr, true, zone->loadtask,
   2789 				       zone_gotreadhandle, load, &zone->readio);
   2790 		if (result != ISC_R_SUCCESS) {
   2791 			/*
   2792 			 * We can't report multiple errors so ignore
   2793 			 * the result of dns_db_endload().
   2794 			 */
   2795 			(void)dns_db_endload(load->db, &load->callbacks);
   2796 			goto cleanup;
   2797 		} else {
   2798 			result = DNS_R_CONTINUE;
   2799 		}
   2800 	} else {
   2801 		dns_rdatacallbacks_t callbacks;
   2802 
   2803 		dns_rdatacallbacks_init(&callbacks);
   2804 		callbacks.rawdata = zone_setrawdata;
   2805 		zone_iattach(zone, &callbacks.zone);
   2806 		result = dns_db_beginload(db, &callbacks);
   2807 		if (result != ISC_R_SUCCESS) {
   2808 			zone_idetach(&callbacks.zone);
   2809 			return (result);
   2810 		}
   2811 
   2812 		if (zone->stream != NULL) {
   2813 			FILE *stream = NULL;
   2814 			DE_CONST(zone->stream, stream);
   2815 			result = dns_master_loadstream(
   2816 				stream, &zone->origin, &zone->origin,
   2817 				zone->rdclass, options, &callbacks, zone->mctx);
   2818 		} else {
   2819 			result = dns_master_loadfile(
   2820 				zone->masterfile, &zone->origin, &zone->origin,
   2821 				zone->rdclass, options, 0, &callbacks,
   2822 				zone_registerinclude, zone, zone->mctx,
   2823 				zone->masterformat, zone->maxttl);
   2824 		}
   2825 
   2826 		tresult = dns_db_endload(db, &callbacks);
   2827 		if (result == ISC_R_SUCCESS) {
   2828 			result = tresult;
   2829 		}
   2830 		zone_idetach(&callbacks.zone);
   2831 	}
   2832 
   2833 	return (result);
   2834 
   2835 cleanup:
   2836 	load->magic = 0;
   2837 	dns_db_detach(&load->db);
   2838 	zone_idetach(&load->zone);
   2839 	zone_idetach(&load->callbacks.zone);
   2840 	isc_mem_detach(&load->mctx);
   2841 	isc_mem_put(zone->mctx, load, sizeof(*load));
   2842 	return (result);
   2843 }
   2844 
   2845 static bool
   2846 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2847 	      dns_name_t *owner) {
   2848 	isc_result_t result;
   2849 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2850 	char namebuf[DNS_NAME_FORMATSIZE];
   2851 	char altbuf[DNS_NAME_FORMATSIZE];
   2852 	dns_fixedname_t fixed;
   2853 	dns_name_t *foundname;
   2854 	int level;
   2855 
   2856 	/*
   2857 	 * "." means the services does not exist.
   2858 	 */
   2859 	if (dns_name_equal(name, dns_rootname)) {
   2860 		return (true);
   2861 	}
   2862 
   2863 	/*
   2864 	 * Outside of zone.
   2865 	 */
   2866 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2867 		if (zone->checkmx != NULL) {
   2868 			return ((zone->checkmx)(zone, name, owner));
   2869 		}
   2870 		return (true);
   2871 	}
   2872 
   2873 	if (zone->type == dns_zone_primary) {
   2874 		level = ISC_LOG_ERROR;
   2875 	} else {
   2876 		level = ISC_LOG_WARNING;
   2877 	}
   2878 
   2879 	foundname = dns_fixedname_initname(&fixed);
   2880 
   2881 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2882 			     foundname, NULL, NULL);
   2883 	if (result == ISC_R_SUCCESS) {
   2884 		return (true);
   2885 	}
   2886 
   2887 	if (result == DNS_R_NXRRSET) {
   2888 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2889 				     NULL, foundname, NULL, NULL);
   2890 		if (result == ISC_R_SUCCESS) {
   2891 			return (true);
   2892 		}
   2893 	}
   2894 
   2895 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2896 	dns_name_format(name, namebuf, sizeof namebuf);
   2897 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2898 	    result == DNS_R_EMPTYNAME)
   2899 	{
   2900 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2901 			level = ISC_LOG_WARNING;
   2902 		}
   2903 		dns_zone_log(zone, level,
   2904 			     "%s/MX '%s' has no address records (A or AAAA)",
   2905 			     ownerbuf, namebuf);
   2906 		return ((level == ISC_LOG_WARNING) ? true : false);
   2907 	}
   2908 
   2909 	if (result == DNS_R_CNAME) {
   2910 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2911 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2912 		{
   2913 			level = ISC_LOG_WARNING;
   2914 		}
   2915 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2916 			dns_zone_log(zone, level,
   2917 				     "%s/MX '%s' is a CNAME (illegal)",
   2918 				     ownerbuf, namebuf);
   2919 		}
   2920 		return ((level == ISC_LOG_WARNING) ? true : false);
   2921 	}
   2922 
   2923 	if (result == DNS_R_DNAME) {
   2924 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2925 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2926 		{
   2927 			level = ISC_LOG_WARNING;
   2928 		}
   2929 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2930 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2931 			dns_zone_log(zone, level,
   2932 				     "%s/MX '%s' is below a DNAME"
   2933 				     " '%s' (illegal)",
   2934 				     ownerbuf, namebuf, altbuf);
   2935 		}
   2936 		return ((level == ISC_LOG_WARNING) ? true : false);
   2937 	}
   2938 
   2939 	if (zone->checkmx != NULL && result == DNS_R_DELEGATION) {
   2940 		return ((zone->checkmx)(zone, name, owner));
   2941 	}
   2942 
   2943 	return (true);
   2944 }
   2945 
   2946 static bool
   2947 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2948 	       dns_name_t *owner) {
   2949 	isc_result_t result;
   2950 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2951 	char namebuf[DNS_NAME_FORMATSIZE];
   2952 	char altbuf[DNS_NAME_FORMATSIZE];
   2953 	dns_fixedname_t fixed;
   2954 	dns_name_t *foundname;
   2955 	int level;
   2956 
   2957 	/*
   2958 	 * "." means the services does not exist.
   2959 	 */
   2960 	if (dns_name_equal(name, dns_rootname)) {
   2961 		return (true);
   2962 	}
   2963 
   2964 	/*
   2965 	 * Outside of zone.
   2966 	 */
   2967 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2968 		if (zone->checksrv != NULL) {
   2969 			return ((zone->checksrv)(zone, name, owner));
   2970 		}
   2971 		return (true);
   2972 	}
   2973 
   2974 	if (zone->type == dns_zone_primary) {
   2975 		level = ISC_LOG_ERROR;
   2976 	} else {
   2977 		level = ISC_LOG_WARNING;
   2978 	}
   2979 
   2980 	foundname = dns_fixedname_initname(&fixed);
   2981 
   2982 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2983 			     foundname, NULL, NULL);
   2984 	if (result == ISC_R_SUCCESS) {
   2985 		return (true);
   2986 	}
   2987 
   2988 	if (result == DNS_R_NXRRSET) {
   2989 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2990 				     NULL, foundname, NULL, NULL);
   2991 		if (result == ISC_R_SUCCESS) {
   2992 			return (true);
   2993 		}
   2994 	}
   2995 
   2996 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2997 	dns_name_format(name, namebuf, sizeof namebuf);
   2998 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2999 	    result == DNS_R_EMPTYNAME)
   3000 	{
   3001 		dns_zone_log(zone, level,
   3002 			     "%s/SRV '%s' has no address records (A or AAAA)",
   3003 			     ownerbuf, namebuf);
   3004 		/* XXX950 make fatal for 9.5.0. */
   3005 		return (true);
   3006 	}
   3007 
   3008 	if (result == DNS_R_CNAME) {
   3009 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   3010 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   3011 		{
   3012 			level = ISC_LOG_WARNING;
   3013 		}
   3014 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   3015 			dns_zone_log(zone, level,
   3016 				     "%s/SRV '%s' is a CNAME (illegal)",
   3017 				     ownerbuf, namebuf);
   3018 		}
   3019 		return ((level == ISC_LOG_WARNING) ? true : false);
   3020 	}
   3021 
   3022 	if (result == DNS_R_DNAME) {
   3023 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   3024 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   3025 		{
   3026 			level = ISC_LOG_WARNING;
   3027 		}
   3028 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   3029 			dns_name_format(foundname, altbuf, sizeof altbuf);
   3030 			dns_zone_log(zone, level,
   3031 				     "%s/SRV '%s' is below a "
   3032 				     "DNAME '%s' (illegal)",
   3033 				     ownerbuf, namebuf, altbuf);
   3034 		}
   3035 		return ((level == ISC_LOG_WARNING) ? true : false);
   3036 	}
   3037 
   3038 	if (zone->checksrv != NULL && result == DNS_R_DELEGATION) {
   3039 		return ((zone->checksrv)(zone, name, owner));
   3040 	}
   3041 
   3042 	return (true);
   3043 }
   3044 
   3045 static bool
   3046 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   3047 		dns_name_t *owner) {
   3048 	bool answer = true;
   3049 	isc_result_t result, tresult;
   3050 	char ownerbuf[DNS_NAME_FORMATSIZE];
   3051 	char namebuf[DNS_NAME_FORMATSIZE];
   3052 	char altbuf[DNS_NAME_FORMATSIZE];
   3053 	dns_fixedname_t fixed;
   3054 	dns_name_t *foundname;
   3055 	dns_rdataset_t a;
   3056 	dns_rdataset_t aaaa;
   3057 	int level;
   3058 
   3059 	/*
   3060 	 * Outside of zone.
   3061 	 */
   3062 	if (!dns_name_issubdomain(name, &zone->origin)) {
   3063 		if (zone->checkns != NULL) {
   3064 			return ((zone->checkns)(zone, name, owner, NULL, NULL));
   3065 		}
   3066 		return (true);
   3067 	}
   3068 
   3069 	if (zone->type == dns_zone_primary) {
   3070 		level = ISC_LOG_ERROR;
   3071 	} else {
   3072 		level = ISC_LOG_WARNING;
   3073 	}
   3074 
   3075 	foundname = dns_fixedname_initname(&fixed);
   3076 	dns_rdataset_init(&a);
   3077 	dns_rdataset_init(&aaaa);
   3078 
   3079 	/*
   3080 	 * Perform a regular lookup to catch DNAME records then look
   3081 	 * for glue.
   3082 	 */
   3083 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   3084 			     foundname, &a, NULL);
   3085 	switch (result) {
   3086 	case ISC_R_SUCCESS:
   3087 	case DNS_R_DNAME:
   3088 	case DNS_R_CNAME:
   3089 		break;
   3090 	default:
   3091 		if (dns_rdataset_isassociated(&a)) {
   3092 			dns_rdataset_disassociate(&a);
   3093 		}
   3094 		result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   3095 				     DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a,
   3096 				     NULL);
   3097 	}
   3098 	if (result == ISC_R_SUCCESS) {
   3099 		dns_rdataset_disassociate(&a);
   3100 		return (true);
   3101 	} else if (result == DNS_R_DELEGATION) {
   3102 		dns_rdataset_disassociate(&a);
   3103 	}
   3104 
   3105 	if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
   3106 	    result == DNS_R_GLUE)
   3107 	{
   3108 		tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
   3109 				      DNS_DBFIND_GLUEOK, 0, NULL, foundname,
   3110 				      &aaaa, NULL);
   3111 		if (tresult == ISC_R_SUCCESS) {
   3112 			if (dns_rdataset_isassociated(&a)) {
   3113 				dns_rdataset_disassociate(&a);
   3114 			}
   3115 			dns_rdataset_disassociate(&aaaa);
   3116 			return (true);
   3117 		}
   3118 		if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) {
   3119 			dns_rdataset_disassociate(&aaaa);
   3120 		}
   3121 		if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
   3122 			/*
   3123 			 * Check glue against child zone.
   3124 			 */
   3125 			if (zone->checkns != NULL) {
   3126 				answer = (zone->checkns)(zone, name, owner, &a,
   3127 							 &aaaa);
   3128 			}
   3129 			if (dns_rdataset_isassociated(&a)) {
   3130 				dns_rdataset_disassociate(&a);
   3131 			}
   3132 			if (dns_rdataset_isassociated(&aaaa)) {
   3133 				dns_rdataset_disassociate(&aaaa);
   3134 			}
   3135 			return (answer);
   3136 		}
   3137 	}
   3138 
   3139 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   3140 	dns_name_format(name, namebuf, sizeof namebuf);
   3141 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   3142 	    result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION)
   3143 	{
   3144 		const char *what;
   3145 		bool required = false;
   3146 		if (dns_name_issubdomain(name, owner)) {
   3147 			what = "REQUIRED GLUE ";
   3148 			required = true;
   3149 		} else if (result == DNS_R_DELEGATION) {
   3150 			what = "SIBLING GLUE ";
   3151 		} else {
   3152 			what = "";
   3153 		}
   3154 
   3155 		if (result != DNS_R_DELEGATION || required ||
   3156 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING))
   3157 		{
   3158 			dns_zone_log(zone, level,
   3159 				     "%s/NS '%s' has no %s"
   3160 				     "address records (A or AAAA)",
   3161 				     ownerbuf, namebuf, what);
   3162 			/*
   3163 			 * Log missing address record.
   3164 			 */
   3165 			if (result == DNS_R_DELEGATION && zone->checkns != NULL)
   3166 			{
   3167 				(void)(zone->checkns)(zone, name, owner, &a,
   3168 						      &aaaa);
   3169 			}
   3170 			/* XXX950 make fatal for 9.5.0. */
   3171 			/* answer = false; */
   3172 		}
   3173 	} else if (result == DNS_R_CNAME) {
   3174 		dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
   3175 			     ownerbuf, namebuf);
   3176 		/* XXX950 make fatal for 9.5.0. */
   3177 		/* answer = false; */
   3178 	} else if (result == DNS_R_DNAME) {
   3179 		dns_name_format(foundname, altbuf, sizeof altbuf);
   3180 		dns_zone_log(zone, level,
   3181 			     "%s/NS '%s' is below a DNAME '%s' (illegal)",
   3182 			     ownerbuf, namebuf, altbuf);
   3183 		/* XXX950 make fatal for 9.5.0. */
   3184 		/* answer = false; */
   3185 	}
   3186 
   3187 	if (dns_rdataset_isassociated(&a)) {
   3188 		dns_rdataset_disassociate(&a);
   3189 	}
   3190 	if (dns_rdataset_isassociated(&aaaa)) {
   3191 		dns_rdataset_disassociate(&aaaa);
   3192 	}
   3193 	return (answer);
   3194 }
   3195 
   3196 static bool
   3197 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
   3198 		     dns_rdataset_t *rdataset) {
   3199 	dns_rdataset_t tmprdataset;
   3200 	isc_result_t result;
   3201 	bool answer = true;
   3202 	bool format = true;
   3203 	int level = ISC_LOG_WARNING;
   3204 	char ownerbuf[DNS_NAME_FORMATSIZE];
   3205 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   3206 	unsigned int count1 = 0;
   3207 
   3208 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) {
   3209 		level = ISC_LOG_ERROR;
   3210 	}
   3211 
   3212 	dns_rdataset_init(&tmprdataset);
   3213 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   3214 	     result = dns_rdataset_next(rdataset))
   3215 	{
   3216 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   3217 		unsigned int count2 = 0;
   3218 
   3219 		count1++;
   3220 		dns_rdataset_current(rdataset, &rdata1);
   3221 		dns_rdataset_clone(rdataset, &tmprdataset);
   3222 		for (result = dns_rdataset_first(&tmprdataset);
   3223 		     result == ISC_R_SUCCESS;
   3224 		     result = dns_rdataset_next(&tmprdataset))
   3225 		{
   3226 			dns_rdata_t rdata2 = DNS_RDATA_INIT;
   3227 			count2++;
   3228 			if (count1 >= count2) {
   3229 				continue;
   3230 			}
   3231 			dns_rdataset_current(&tmprdataset, &rdata2);
   3232 			if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
   3233 				if (format) {
   3234 					dns_name_format(owner, ownerbuf,
   3235 							sizeof ownerbuf);
   3236 					dns_rdatatype_format(rdata1.type,
   3237 							     typebuf,
   3238 							     sizeof(typebuf));
   3239 					format = false;
   3240 				}
   3241 				dns_zone_log(zone, level,
   3242 					     "%s/%s has "
   3243 					     "semantically identical records",
   3244 					     ownerbuf, typebuf);
   3245 				if (level == ISC_LOG_ERROR) {
   3246 					answer = false;
   3247 				}
   3248 				break;
   3249 			}
   3250 		}
   3251 		dns_rdataset_disassociate(&tmprdataset);
   3252 		if (!format) {
   3253 			break;
   3254 		}
   3255 	}
   3256 	return (answer);
   3257 }
   3258 
   3259 static bool
   3260 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
   3261 	dns_dbiterator_t *dbiterator = NULL;
   3262 	dns_dbnode_t *node = NULL;
   3263 	dns_fixedname_t fixed;
   3264 	dns_name_t *name;
   3265 	dns_rdataset_t rdataset;
   3266 	dns_rdatasetiter_t *rdsit = NULL;
   3267 	bool ok = true;
   3268 	isc_result_t result;
   3269 
   3270 	name = dns_fixedname_initname(&fixed);
   3271 	dns_rdataset_init(&rdataset);
   3272 
   3273 	result = dns_db_createiterator(db, 0, &dbiterator);
   3274 	if (result != ISC_R_SUCCESS) {
   3275 		return (true);
   3276 	}
   3277 
   3278 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   3279 	     result = dns_dbiterator_next(dbiterator))
   3280 	{
   3281 		result = dns_dbiterator_current(dbiterator, &node, name);
   3282 		if (result != ISC_R_SUCCESS) {
   3283 			continue;
   3284 		}
   3285 
   3286 		result = dns_db_allrdatasets(db, node, NULL, 0, 0, &rdsit);
   3287 		if (result != ISC_R_SUCCESS) {
   3288 			continue;
   3289 		}
   3290 
   3291 		for (result = dns_rdatasetiter_first(rdsit);
   3292 		     result == ISC_R_SUCCESS;
   3293 		     result = dns_rdatasetiter_next(rdsit))
   3294 		{
   3295 			dns_rdatasetiter_current(rdsit, &rdataset);
   3296 			if (!zone_rrset_check_dup(zone, name, &rdataset)) {
   3297 				ok = false;
   3298 			}
   3299 			dns_rdataset_disassociate(&rdataset);
   3300 		}
   3301 		dns_rdatasetiter_destroy(&rdsit);
   3302 		dns_db_detachnode(db, &node);
   3303 	}
   3304 
   3305 	if (node != NULL) {
   3306 		dns_db_detachnode(db, &node);
   3307 	}
   3308 	dns_dbiterator_destroy(&dbiterator);
   3309 
   3310 	return (ok);
   3311 }
   3312 
   3313 static bool
   3314 isspf(const dns_rdata_t *rdata) {
   3315 	char buf[1024];
   3316 	const unsigned char *data = rdata->data;
   3317 	unsigned int rdl = rdata->length, i = 0, tl, len;
   3318 
   3319 	while (rdl > 0U) {
   3320 		len = tl = *data;
   3321 		++data;
   3322 		--rdl;
   3323 		INSIST(tl <= rdl);
   3324 		if (len > sizeof(buf) - i - 1) {
   3325 			len = sizeof(buf) - i - 1;
   3326 		}
   3327 		memmove(buf + i, data, len);
   3328 		i += len;
   3329 		data += tl;
   3330 		rdl -= tl;
   3331 	}
   3332 
   3333 	if (i < 6U) {
   3334 		return (false);
   3335 	}
   3336 
   3337 	buf[i] = 0;
   3338 	if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) {
   3339 		return (true);
   3340 	}
   3341 	return (false);
   3342 }
   3343 
   3344 static bool
   3345 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
   3346 	dns_dbiterator_t *dbiterator = NULL;
   3347 	dns_dbnode_t *node = NULL;
   3348 	dns_rdataset_t rdataset;
   3349 	dns_fixedname_t fixed;
   3350 	dns_fixedname_t fixedbottom;
   3351 	dns_rdata_mx_t mx;
   3352 	dns_rdata_ns_t ns;
   3353 	dns_rdata_in_srv_t srv;
   3354 	dns_rdata_t rdata;
   3355 	dns_name_t *name;
   3356 	dns_name_t *bottom;
   3357 	isc_result_t result;
   3358 	bool ok = true, have_spf, have_txt;
   3359 
   3360 	name = dns_fixedname_initname(&fixed);
   3361 	bottom = dns_fixedname_initname(&fixedbottom);
   3362 	dns_rdataset_init(&rdataset);
   3363 	dns_rdata_init(&rdata);
   3364 
   3365 	result = dns_db_createiterator(db, 0, &dbiterator);
   3366 	if (result != ISC_R_SUCCESS) {
   3367 		return (true);
   3368 	}
   3369 
   3370 	result = dns_dbiterator_first(dbiterator);
   3371 	while (result == ISC_R_SUCCESS) {
   3372 		result = dns_dbiterator_current(dbiterator, &node, name);
   3373 		if (result != ISC_R_SUCCESS) {
   3374 			goto cleanup;
   3375 		}
   3376 
   3377 		/*
   3378 		 * Is this name visible in the zone?
   3379 		 */
   3380 		if (!dns_name_issubdomain(name, &zone->origin) ||
   3381 		    (dns_name_countlabels(bottom) > 0 &&
   3382 		     dns_name_issubdomain(name, bottom)))
   3383 		{
   3384 			goto next;
   3385 		}
   3386 
   3387 		dns_dbiterator_pause(dbiterator);
   3388 
   3389 		/*
   3390 		 * Don't check the NS records at the origin.
   3391 		 */
   3392 		if (dns_name_equal(name, &zone->origin)) {
   3393 			goto checkfordname;
   3394 		}
   3395 
   3396 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
   3397 					     0, 0, &rdataset, NULL);
   3398 		if (result != ISC_R_SUCCESS) {
   3399 			goto checkfordname;
   3400 		}
   3401 		/*
   3402 		 * Remember bottom of zone due to NS.
   3403 		 */
   3404 		dns_name_copy(name, bottom);
   3405 
   3406 		result = dns_rdataset_first(&rdataset);
   3407 		while (result == ISC_R_SUCCESS) {
   3408 			dns_rdataset_current(&rdataset, &rdata);
   3409 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   3410 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3411 			if (!zone_check_glue(zone, db, &ns.name, name)) {
   3412 				ok = false;
   3413 			}
   3414 			dns_rdata_reset(&rdata);
   3415 			result = dns_rdataset_next(&rdataset);
   3416 		}
   3417 		dns_rdataset_disassociate(&rdataset);
   3418 		goto next;
   3419 
   3420 	checkfordname:
   3421 		result = dns_db_findrdataset(db, node, NULL,
   3422 					     dns_rdatatype_dname, 0, 0,
   3423 					     &rdataset, NULL);
   3424 		if (result == ISC_R_SUCCESS) {
   3425 			/*
   3426 			 * Remember bottom of zone due to DNAME.
   3427 			 */
   3428 			dns_name_copy(name, bottom);
   3429 			dns_rdataset_disassociate(&rdataset);
   3430 		}
   3431 
   3432 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
   3433 					     0, 0, &rdataset, NULL);
   3434 		if (result != ISC_R_SUCCESS) {
   3435 			goto checksrv;
   3436 		}
   3437 		result = dns_rdataset_first(&rdataset);
   3438 		while (result == ISC_R_SUCCESS) {
   3439 			dns_rdataset_current(&rdataset, &rdata);
   3440 			result = dns_rdata_tostruct(&rdata, &mx, NULL);
   3441 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3442 			if (!zone_check_mx(zone, db, &mx.mx, name)) {
   3443 				ok = false;
   3444 			}
   3445 			dns_rdata_reset(&rdata);
   3446 			result = dns_rdataset_next(&rdataset);
   3447 		}
   3448 		dns_rdataset_disassociate(&rdataset);
   3449 
   3450 	checksrv:
   3451 		if (zone->rdclass != dns_rdataclass_in) {
   3452 			goto next;
   3453 		}
   3454 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
   3455 					     0, 0, &rdataset, NULL);
   3456 		if (result != ISC_R_SUCCESS) {
   3457 			goto checkspf;
   3458 		}
   3459 		result = dns_rdataset_first(&rdataset);
   3460 		while (result == ISC_R_SUCCESS) {
   3461 			dns_rdataset_current(&rdataset, &rdata);
   3462 			result = dns_rdata_tostruct(&rdata, &srv, NULL);
   3463 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3464 			if (!zone_check_srv(zone, db, &srv.target, name)) {
   3465 				ok = false;
   3466 			}
   3467 			dns_rdata_reset(&rdata);
   3468 			result = dns_rdataset_next(&rdataset);
   3469 		}
   3470 		dns_rdataset_disassociate(&rdataset);
   3471 
   3472 	checkspf:
   3473 		/*
   3474 		 * Check if there is a type SPF record without an
   3475 		 * SPF-formatted type TXT record also being present.
   3476 		 */
   3477 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) {
   3478 			goto next;
   3479 		}
   3480 		if (zone->rdclass != dns_rdataclass_in) {
   3481 			goto next;
   3482 		}
   3483 		have_spf = have_txt = false;
   3484 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
   3485 					     0, 0, &rdataset, NULL);
   3486 		if (result == ISC_R_SUCCESS) {
   3487 			dns_rdataset_disassociate(&rdataset);
   3488 			have_spf = true;
   3489 		}
   3490 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
   3491 					     0, 0, &rdataset, NULL);
   3492 		if (result != ISC_R_SUCCESS) {
   3493 			goto notxt;
   3494 		}
   3495 		result = dns_rdataset_first(&rdataset);
   3496 		while (result == ISC_R_SUCCESS) {
   3497 			dns_rdataset_current(&rdataset, &rdata);
   3498 			have_txt = isspf(&rdata);
   3499 			dns_rdata_reset(&rdata);
   3500 			if (have_txt) {
   3501 				break;
   3502 			}
   3503 			result = dns_rdataset_next(&rdataset);
   3504 		}
   3505 		dns_rdataset_disassociate(&rdataset);
   3506 
   3507 	notxt:
   3508 		if (have_spf && !have_txt) {
   3509 			char namebuf[DNS_NAME_FORMATSIZE];
   3510 
   3511 			dns_name_format(name, namebuf, sizeof(namebuf));
   3512 			dns_zone_log(zone, ISC_LOG_WARNING,
   3513 				     "'%s' found type "
   3514 				     "SPF record but no SPF TXT record found, "
   3515 				     "add matching type TXT record",
   3516 				     namebuf);
   3517 		}
   3518 
   3519 	next:
   3520 		dns_db_detachnode(db, &node);
   3521 		result = dns_dbiterator_next(dbiterator);
   3522 	}
   3523 
   3524 cleanup:
   3525 	if (node != NULL) {
   3526 		dns_db_detachnode(db, &node);
   3527 	}
   3528 	dns_dbiterator_destroy(&dbiterator);
   3529 
   3530 	return (ok);
   3531 }
   3532 
   3533 /*
   3534  * OpenSSL verification of RSA keys with exponent 3 is known to be
   3535  * broken prior OpenSSL 0.9.8c/0.9.7k.	Look for such keys and warn
   3536  * if they are in use.
   3537  */
   3538 static void
   3539 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
   3540 	dns_dbnode_t *node = NULL;
   3541 	dns_dbversion_t *version = NULL;
   3542 	dns_rdata_dnskey_t dnskey;
   3543 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3544 	dns_rdataset_t rdataset;
   3545 	isc_result_t result;
   3546 
   3547 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3548 	if (result != ISC_R_SUCCESS) {
   3549 		goto cleanup;
   3550 	}
   3551 
   3552 	dns_db_currentversion(db, &version);
   3553 	dns_rdataset_init(&rdataset);
   3554 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   3555 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3556 	if (result != ISC_R_SUCCESS) {
   3557 		goto cleanup;
   3558 	}
   3559 
   3560 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3561 	     result = dns_rdataset_next(&rdataset))
   3562 	{
   3563 		dns_rdataset_current(&rdataset, &rdata);
   3564 		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
   3565 		INSIST(result == ISC_R_SUCCESS);
   3566 
   3567 		/*
   3568 		 * RFC 3110, section 4: Performance Considerations:
   3569 		 *
   3570 		 * A public exponent of 3 minimizes the effort needed to verify
   3571 		 * a signature.  Use of 3 as the public exponent is weak for
   3572 		 * confidentiality uses since, if the same data can be collected
   3573 		 * encrypted under three different keys with an exponent of 3
   3574 		 * then, using the Chinese Remainder Theorem [NETSEC], the
   3575 		 * original plain text can be easily recovered.  If a key is
   3576 		 * known to be used only for authentication, as is the case with
   3577 		 * DNSSEC, then an exponent of 3 is acceptable.  However other
   3578 		 * applications in the future may wish to leverage DNS
   3579 		 * distributed keys for applications that do require
   3580 		 * confidentiality.  For keys which might have such other uses,
   3581 		 * a more conservative choice would be 65537 (F4, the fourth
   3582 		 * fermat number).
   3583 		 */
   3584 		if (dnskey.datalen > 1 && dnskey.data[0] == 1 &&
   3585 		    dnskey.data[1] == 3 &&
   3586 		    (dnskey.algorithm == DNS_KEYALG_RSAMD5 ||
   3587 		     dnskey.algorithm == DNS_KEYALG_RSASHA1 ||
   3588 		     dnskey.algorithm == DNS_KEYALG_NSEC3RSASHA1 ||
   3589 		     dnskey.algorithm == DNS_KEYALG_RSASHA256 ||
   3590 		     dnskey.algorithm == DNS_KEYALG_RSASHA512))
   3591 		{
   3592 			char algorithm[DNS_SECALG_FORMATSIZE];
   3593 			isc_region_t r;
   3594 
   3595 			dns_rdata_toregion(&rdata, &r);
   3596 			dns_secalg_format(dnskey.algorithm, algorithm,
   3597 					  sizeof(algorithm));
   3598 
   3599 			dnssec_log(zone, ISC_LOG_WARNING,
   3600 				   "weak %s (%u) key found (exponent=3, id=%u)",
   3601 				   algorithm, dnskey.algorithm,
   3602 				   dst_region_computeid(&r));
   3603 		}
   3604 		dns_rdata_reset(&rdata);
   3605 	}
   3606 	dns_rdataset_disassociate(&rdataset);
   3607 
   3608 cleanup:
   3609 	if (node != NULL) {
   3610 		dns_db_detachnode(db, &node);
   3611 	}
   3612 	if (version != NULL) {
   3613 		dns_db_closeversion(db, &version, false);
   3614 	}
   3615 }
   3616 
   3617 static void
   3618 resume_signingwithkey(dns_zone_t *zone) {
   3619 	dns_dbnode_t *node = NULL;
   3620 	dns_dbversion_t *version = NULL;
   3621 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3622 	dns_rdataset_t rdataset;
   3623 	isc_result_t result;
   3624 	dns_db_t *db = NULL;
   3625 
   3626 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3627 	if (zone->db != NULL) {
   3628 		dns_db_attach(zone->db, &db);
   3629 	}
   3630 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3631 	if (db == NULL) {
   3632 		goto cleanup;
   3633 	}
   3634 
   3635 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3636 	if (result != ISC_R_SUCCESS) {
   3637 		goto cleanup;
   3638 	}
   3639 
   3640 	dns_db_currentversion(db, &version);
   3641 	dns_rdataset_init(&rdataset);
   3642 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3643 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3644 	if (result != ISC_R_SUCCESS) {
   3645 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3646 		goto cleanup;
   3647 	}
   3648 
   3649 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3650 	     result = dns_rdataset_next(&rdataset))
   3651 	{
   3652 		dns_rdataset_current(&rdataset, &rdata);
   3653 		if (rdata.length != 5 || rdata.data[0] == 0 ||
   3654 		    rdata.data[4] != 0)
   3655 		{
   3656 			dns_rdata_reset(&rdata);
   3657 			continue;
   3658 		}
   3659 
   3660 		result = zone_signwithkey(zone, rdata.data[0],
   3661 					  (rdata.data[1] << 8) | rdata.data[2],
   3662 					  rdata.data[3]);
   3663 		if (result != ISC_R_SUCCESS) {
   3664 			dnssec_log(zone, ISC_LOG_ERROR,
   3665 				   "zone_signwithkey failed: %s",
   3666 				   isc_result_totext(result));
   3667 		}
   3668 		dns_rdata_reset(&rdata);
   3669 	}
   3670 	dns_rdataset_disassociate(&rdataset);
   3671 
   3672 cleanup:
   3673 	if (db != NULL) {
   3674 		if (node != NULL) {
   3675 			dns_db_detachnode(db, &node);
   3676 		}
   3677 		if (version != NULL) {
   3678 			dns_db_closeversion(db, &version, false);
   3679 		}
   3680 		dns_db_detach(&db);
   3681 	}
   3682 }
   3683 
   3684 /*
   3685  * Initiate adding/removing NSEC3 records belonging to the chain defined by the
   3686  * supplied NSEC3PARAM RDATA.
   3687  *
   3688  * Zone must be locked by caller.
   3689  */
   3690 static isc_result_t
   3691 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   3692 	dns_nsec3chain_t *nsec3chain, *current;
   3693 	dns_dbversion_t *version = NULL;
   3694 	bool nseconly = false, nsec3ok = false;
   3695 	isc_result_t result;
   3696 	isc_time_t now;
   3697 	unsigned int options = 0;
   3698 	char saltbuf[255 * 2 + 1];
   3699 	char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
   3700 	dns_db_t *db = NULL;
   3701 
   3702 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3703 	if (zone->db != NULL) {
   3704 		dns_db_attach(zone->db, &db);
   3705 	}
   3706 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3707 
   3708 	if (db == NULL) {
   3709 		result = ISC_R_SUCCESS;
   3710 		goto cleanup;
   3711 	}
   3712 
   3713 	/*
   3714 	 * If this zone is not NSEC3-capable, attempting to remove any NSEC3
   3715 	 * chain from it is pointless as it would not be possible for the
   3716 	 * latter to exist in the first place.
   3717 	 */
   3718 	dns_db_currentversion(db, &version);
   3719 	result = dns_nsec_nseconly(db, version, NULL, &nseconly);
   3720 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3721 	dns_db_closeversion(db, &version, false);
   3722 	if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
   3723 		result = ISC_R_SUCCESS;
   3724 		goto cleanup;
   3725 	}
   3726 
   3727 	/*
   3728 	 * Allocate and initialize structure preserving state of
   3729 	 * adding/removing records belonging to this NSEC3 chain between
   3730 	 * separate zone_nsec3chain() calls.
   3731 	 */
   3732 	nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
   3733 
   3734 	nsec3chain->magic = 0;
   3735 	nsec3chain->done = false;
   3736 	nsec3chain->db = NULL;
   3737 	nsec3chain->dbiterator = NULL;
   3738 	nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
   3739 	nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
   3740 	nsec3chain->nsec3param.hash = nsec3param->hash;
   3741 	nsec3chain->nsec3param.iterations = nsec3param->iterations;
   3742 	nsec3chain->nsec3param.flags = nsec3param->flags;
   3743 	nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
   3744 	memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
   3745 	nsec3chain->nsec3param.salt = nsec3chain->salt;
   3746 	nsec3chain->seen_nsec = false;
   3747 	nsec3chain->delete_nsec = false;
   3748 	nsec3chain->save_delete_nsec = false;
   3749 
   3750 	/*
   3751 	 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA.
   3752 	 */
   3753 	if (nsec3param->flags == 0) {
   3754 		strlcpy(flags, "NONE", sizeof(flags));
   3755 	} else {
   3756 		flags[0] = '\0';
   3757 		if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   3758 			strlcat(flags, "REMOVE", sizeof(flags));
   3759 		}
   3760 		if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) {
   3761 			if (flags[0] == '\0') {
   3762 				strlcpy(flags, "INITIAL", sizeof(flags));
   3763 			} else {
   3764 				strlcat(flags, "|INITIAL", sizeof(flags));
   3765 			}
   3766 		}
   3767 		if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3768 			if (flags[0] == '\0') {
   3769 				strlcpy(flags, "CREATE", sizeof(flags));
   3770 			} else {
   3771 				strlcat(flags, "|CREATE", sizeof(flags));
   3772 			}
   3773 		}
   3774 		if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) {
   3775 			if (flags[0] == '\0') {
   3776 				strlcpy(flags, "NONSEC", sizeof(flags));
   3777 			} else {
   3778 				strlcat(flags, "|NONSEC", sizeof(flags));
   3779 			}
   3780 		}
   3781 		if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) {
   3782 			if (flags[0] == '\0') {
   3783 				strlcpy(flags, "OPTOUT", sizeof(flags));
   3784 			} else {
   3785 				strlcat(flags, "|OPTOUT", sizeof(flags));
   3786 			}
   3787 		}
   3788 	}
   3789 	result = dns_nsec3param_salttotext(nsec3param, saltbuf,
   3790 					   sizeof(saltbuf));
   3791 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3792 	dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)",
   3793 		   nsec3param->hash, flags, nsec3param->iterations, saltbuf);
   3794 
   3795 	/*
   3796 	 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is
   3797 	 * currently being processed, interrupt its processing to avoid
   3798 	 * simultaneously adding and removing records for the same NSEC3 chain.
   3799 	 */
   3800 	for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL;
   3801 	     current = ISC_LIST_NEXT(current, link))
   3802 	{
   3803 		if ((current->db == db) &&
   3804 		    (current->nsec3param.hash == nsec3param->hash) &&
   3805 		    (current->nsec3param.iterations ==
   3806 		     nsec3param->iterations) &&
   3807 		    (current->nsec3param.salt_length ==
   3808 		     nsec3param->salt_length) &&
   3809 		    memcmp(current->nsec3param.salt, nsec3param->salt,
   3810 			   nsec3param->salt_length) == 0)
   3811 		{
   3812 			current->done = true;
   3813 		}
   3814 	}
   3815 
   3816 	/*
   3817 	 * Attach zone database to the structure initialized above and create
   3818 	 * an iterator for it with appropriate options in order to avoid
   3819 	 * creating NSEC3 records for NSEC3 records.
   3820 	 */
   3821 	dns_db_attach(db, &nsec3chain->db);
   3822 	if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3823 		options = DNS_DB_NONSEC3;
   3824 	}
   3825 	result = dns_db_createiterator(nsec3chain->db, options,
   3826 				       &nsec3chain->dbiterator);
   3827 	if (result == ISC_R_SUCCESS) {
   3828 		result = dns_dbiterator_first(nsec3chain->dbiterator);
   3829 	}
   3830 	if (result == ISC_R_SUCCESS) {
   3831 		/*
   3832 		 * Database iterator initialization succeeded.  We are now
   3833 		 * ready to kick off adding/removing records belonging to this
   3834 		 * NSEC3 chain.  Append the structure initialized above to the
   3835 		 * "nsec3chain" list for the zone and set the appropriate zone
   3836 		 * timer so that zone_nsec3chain() is called as soon as
   3837 		 * possible.
   3838 		 */
   3839 		dns_dbiterator_pause(nsec3chain->dbiterator);
   3840 		ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link);
   3841 		nsec3chain = NULL;
   3842 		if (isc_time_isepoch(&zone->nsec3chaintime)) {
   3843 			TIME_NOW(&now);
   3844 			zone->nsec3chaintime = now;
   3845 			if (zone->task != NULL) {
   3846 				zone_settimer(zone, &now);
   3847 			}
   3848 		}
   3849 	}
   3850 
   3851 	if (nsec3chain != NULL) {
   3852 		if (nsec3chain->db != NULL) {
   3853 			dns_db_detach(&nsec3chain->db);
   3854 		}
   3855 		if (nsec3chain->dbiterator != NULL) {
   3856 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   3857 		}
   3858 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   3859 	}
   3860 
   3861 cleanup:
   3862 	if (db != NULL) {
   3863 		dns_db_detach(&db);
   3864 	}
   3865 	return (result);
   3866 }
   3867 
   3868 /*
   3869  * Find private-type records at the zone apex which signal that an NSEC3 chain
   3870  * should be added or removed.  For each such record, extract NSEC3PARAM RDATA
   3871  * and pass it to zone_addnsec3chain().
   3872  *
   3873  * Zone must be locked by caller.
   3874  */
   3875 static void
   3876 resume_addnsec3chain(dns_zone_t *zone) {
   3877 	dns_dbnode_t *node = NULL;
   3878 	dns_dbversion_t *version = NULL;
   3879 	dns_rdataset_t rdataset;
   3880 	isc_result_t result;
   3881 	dns_rdata_nsec3param_t nsec3param;
   3882 	bool nseconly = false, nsec3ok = false;
   3883 	dns_db_t *db = NULL;
   3884 
   3885 	INSIST(LOCKED_ZONE(zone));
   3886 
   3887 	if (zone->privatetype == 0) {
   3888 		return;
   3889 	}
   3890 
   3891 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3892 	if (zone->db != NULL) {
   3893 		dns_db_attach(zone->db, &db);
   3894 	}
   3895 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3896 	if (db == NULL) {
   3897 		goto cleanup;
   3898 	}
   3899 
   3900 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3901 	if (result != ISC_R_SUCCESS) {
   3902 		goto cleanup;
   3903 	}
   3904 
   3905 	dns_db_currentversion(db, &version);
   3906 
   3907 	/*
   3908 	 * In order to create NSEC3 chains we need the DNSKEY RRset at zone
   3909 	 * apex to exist and contain no keys using NSEC-only algorithms.
   3910 	 */
   3911 	result = dns_nsec_nseconly(db, version, NULL, &nseconly);
   3912 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3913 
   3914 	/*
   3915 	 * Get the RRset containing all private-type records at the zone apex.
   3916 	 */
   3917 	dns_rdataset_init(&rdataset);
   3918 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3919 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3920 	if (result != ISC_R_SUCCESS) {
   3921 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3922 		goto cleanup;
   3923 	}
   3924 
   3925 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3926 	     result = dns_rdataset_next(&rdataset))
   3927 	{
   3928 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   3929 		dns_rdata_t rdata = DNS_RDATA_INIT;
   3930 		dns_rdata_t private = DNS_RDATA_INIT;
   3931 
   3932 		dns_rdataset_current(&rdataset, &private);
   3933 		/*
   3934 		 * Try extracting NSEC3PARAM RDATA from this private-type
   3935 		 * record.  Failure means this private-type record does not
   3936 		 * represent an NSEC3PARAM record, so skip it.
   3937 		 */
   3938 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   3939 						sizeof(buf)))
   3940 		{
   3941 			continue;
   3942 		}
   3943 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3944 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3945 		if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
   3946 		    ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
   3947 		{
   3948 			/*
   3949 			 * Pass the NSEC3PARAM RDATA contained in this
   3950 			 * private-type record to zone_addnsec3chain() so that
   3951 			 * it can kick off adding or removing NSEC3 records.
   3952 			 */
   3953 			result = zone_addnsec3chain(zone, &nsec3param);
   3954 			if (result != ISC_R_SUCCESS) {
   3955 				dnssec_log(zone, ISC_LOG_ERROR,
   3956 					   "zone_addnsec3chain failed: %s",
   3957 					   isc_result_totext(result));
   3958 			}
   3959 		}
   3960 	}
   3961 	dns_rdataset_disassociate(&rdataset);
   3962 
   3963 cleanup:
   3964 	if (db != NULL) {
   3965 		if (node != NULL) {
   3966 			dns_db_detachnode(db, &node);
   3967 		}
   3968 		if (version != NULL) {
   3969 			dns_db_closeversion(db, &version, false);
   3970 		}
   3971 		dns_db_detach(&db);
   3972 	}
   3973 }
   3974 
   3975 static void
   3976 set_resigntime(dns_zone_t *zone) {
   3977 	dns_rdataset_t rdataset;
   3978 	dns_fixedname_t fixed;
   3979 	unsigned int resign;
   3980 	isc_result_t result;
   3981 	uint32_t nanosecs;
   3982 	dns_db_t *db = NULL;
   3983 
   3984 	INSIST(LOCKED_ZONE(zone));
   3985 
   3986 	/* We only re-sign zones that can be dynamically updated */
   3987 	if (!dns_zone_isdynamic(zone, false)) {
   3988 		return;
   3989 	}
   3990 
   3991 	if (inline_raw(zone)) {
   3992 		return;
   3993 	}
   3994 
   3995 	dns_rdataset_init(&rdataset);
   3996 	dns_fixedname_init(&fixed);
   3997 
   3998 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3999 	if (zone->db != NULL) {
   4000 		dns_db_attach(zone->db, &db);
   4001 	}
   4002 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   4003 	if (db == NULL) {
   4004 		isc_time_settoepoch(&zone->resigntime);
   4005 		return;
   4006 	}
   4007 
   4008 	result = dns_db_getsigningtime(db, &rdataset,
   4009 				       dns_fixedname_name(&fixed));
   4010 	if (result != ISC_R_SUCCESS) {
   4011 		isc_time_settoepoch(&zone->resigntime);
   4012 		goto cleanup;
   4013 	}
   4014 
   4015 	resign = rdataset.resign - dns_zone_getsigresigninginterval(zone);
   4016 	dns_rdataset_disassociate(&rdataset);
   4017 	nanosecs = isc_random_uniform(1000000000);
   4018 	isc_time_set(&zone->resigntime, resign, nanosecs);
   4019 
   4020 cleanup:
   4021 	dns_db_detach(&db);
   4022 	return;
   4023 }
   4024 
   4025 static isc_result_t
   4026 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
   4027 	bool ok = false;
   4028 	dns_dbnode_t *node = NULL;
   4029 	dns_dbversion_t *version = NULL;
   4030 	dns_rdata_nsec3param_t nsec3param;
   4031 	dns_rdataset_t rdataset;
   4032 	isc_result_t result;
   4033 	bool dynamic = (zone->type == dns_zone_primary)
   4034 			       ? dns_zone_isdynamic(zone, false)
   4035 			       : false;
   4036 
   4037 	dns_rdataset_init(&rdataset);
   4038 	result = dns_db_findnode(db, &zone->origin, false, &node);
   4039 	if (result != ISC_R_SUCCESS) {
   4040 		dns_zone_log(zone, ISC_LOG_ERROR,
   4041 			     "nsec3param lookup failure: %s",
   4042 			     isc_result_totext(result));
   4043 		return (result);
   4044 	}
   4045 	dns_db_currentversion(db, &version);
   4046 
   4047 	result = dns_db_findrdataset(db, node, version,
   4048 				     dns_rdatatype_nsec3param,
   4049 				     dns_rdatatype_none, 0, &rdataset, NULL);
   4050 	if (result == ISC_R_NOTFOUND) {
   4051 		INSIST(!dns_rdataset_isassociated(&rdataset));
   4052 		result = ISC_R_SUCCESS;
   4053 		goto cleanup;
   4054 	}
   4055 	if (result != ISC_R_SUCCESS) {
   4056 		INSIST(!dns_rdataset_isassociated(&rdataset));
   4057 		dns_zone_log(zone, ISC_LOG_ERROR,
   4058 			     "nsec3param lookup failure: %s",
   4059 			     isc_result_totext(result));
   4060 		goto cleanup;
   4061 	}
   4062 
   4063 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   4064 	     result = dns_rdataset_next(&rdataset))
   4065 	{
   4066 		dns_rdata_t rdata = DNS_RDATA_INIT;
   4067 
   4068 		dns_rdataset_current(&rdataset, &rdata);
   4069 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   4070 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4071 
   4072 		/*
   4073 		 * For dynamic zones we must support every algorithm so we
   4074 		 * can regenerate all the NSEC3 chains.
   4075 		 * For non-dynamic zones we only need to find a supported
   4076 		 * algorithm.
   4077 		 */
   4078 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
   4079 		    nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
   4080 		{
   4081 			dns_zone_log(zone, ISC_LOG_WARNING,
   4082 				     "nsec3 test \"unknown\" hash algorithm "
   4083 				     "found: %u",
   4084 				     nsec3param.hash);
   4085 			ok = true;
   4086 		} else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
   4087 			if (dynamic) {
   4088 				dns_zone_log(zone, ISC_LOG_ERROR,
   4089 					     "unsupported nsec3 hash algorithm"
   4090 					     " in dynamic zone: %u",
   4091 					     nsec3param.hash);
   4092 				result = DNS_R_BADZONE;
   4093 				/* Stop second error message. */
   4094 				ok = true;
   4095 				break;
   4096 			} else {
   4097 				dns_zone_log(zone, ISC_LOG_WARNING,
   4098 					     "unsupported nsec3 hash "
   4099 					     "algorithm: %u",
   4100 					     nsec3param.hash);
   4101 			}
   4102 		} else {
   4103 			ok = true;
   4104 		}
   4105 
   4106 		/*
   4107 		 * Warn if the zone has excessive NSEC3 iterations.
   4108 		 */
   4109 		if (nsec3param.iterations > dns_nsec3_maxiterations()) {
   4110 			dnssec_log(zone, ISC_LOG_WARNING,
   4111 				   "excessive NSEC3PARAM iterations %u > %u",
   4112 				   nsec3param.iterations,
   4113 				   dns_nsec3_maxiterations());
   4114 		}
   4115 	}
   4116 	if (result == ISC_R_NOMORE) {
   4117 		result = ISC_R_SUCCESS;
   4118 	}
   4119 
   4120 	if (!ok) {
   4121 		result = DNS_R_BADZONE;
   4122 		dns_zone_log(zone, ISC_LOG_ERROR,
   4123 			     "no supported nsec3 hash algorithm");
   4124 	}
   4125 
   4126 cleanup:
   4127 	if (dns_rdataset_isassociated(&rdataset)) {
   4128 		dns_rdataset_disassociate(&rdataset);
   4129 	}
   4130 	dns_db_closeversion(db, &version, false);
   4131 	dns_db_detachnode(db, &node);
   4132 	return (result);
   4133 }
   4134 
   4135 /*
   4136  * Set the timer for refreshing the key zone to the soonest future time
   4137  * of the set (current timer, keydata->refresh, keydata->addhd,
   4138  * keydata->removehd).
   4139  */
   4140 static void
   4141 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
   4142 		    isc_stdtime_t now, bool force) {
   4143 	const char me[] = "set_refreshkeytimer";
   4144 	isc_stdtime_t then;
   4145 	isc_time_t timenow, timethen;
   4146 	char timebuf[80];
   4147 
   4148 	ENTER;
   4149 	then = key->refresh;
   4150 	if (force) {
   4151 		then = now;
   4152 	}
   4153 	if (key->addhd > now && key->addhd < then) {
   4154 		then = key->addhd;
   4155 	}
   4156 	if (key->removehd > now && key->removehd < then) {
   4157 		then = key->removehd;
   4158 	}
   4159 
   4160 	TIME_NOW(&timenow);
   4161 	if (then > now) {
   4162 		DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   4163 	} else {
   4164 		timethen = timenow;
   4165 	}
   4166 	if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
   4167 	    isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
   4168 	{
   4169 		zone->refreshkeytime = timethen;
   4170 	}
   4171 
   4172 	isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   4173 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
   4174 	zone_settimer(zone, &timenow);
   4175 }
   4176 
   4177 /*
   4178  * If keynode references a key or a DS rdataset, and if the key
   4179  * zone does not contain a KEYDATA record for the corresponding name,
   4180  * then create an empty KEYDATA and push it into the zone as a placeholder,
   4181  * then schedule a key refresh immediately. This new KEYDATA record will be
   4182  * updated during the refresh.
   4183  *
   4184  * If the key zone is changed, set '*changed' to true.
   4185  */
   4186 static isc_result_t
   4187 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4188 	       dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname,
   4189 	       bool *changed) {
   4190 	const char me[] = "create_keydata";
   4191 	isc_result_t result = ISC_R_SUCCESS;
   4192 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4193 	dns_rdata_keydata_t kd;
   4194 	unsigned char rrdata[4096];
   4195 	isc_buffer_t rrdatabuf;
   4196 	isc_stdtime_t now;
   4197 
   4198 	REQUIRE(keynode != NULL);
   4199 
   4200 	ENTER;
   4201 	isc_stdtime_get(&now);
   4202 
   4203 	/*
   4204 	 * If the keynode has no trust anchor set, we shouldn't be here.
   4205 	 */
   4206 	if (!dns_keynode_dsset(keynode, NULL)) {
   4207 		return (ISC_R_FAILURE);
   4208 	}
   4209 
   4210 	memset(&kd, 0, sizeof(kd));
   4211 	kd.common.rdclass = zone->rdclass;
   4212 	kd.common.rdtype = dns_rdatatype_keydata;
   4213 	ISC_LINK_INIT(&kd.common, link);
   4214 
   4215 	isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
   4216 
   4217 	CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata,
   4218 				   &kd, &rrdatabuf));
   4219 	/* Add rdata to zone. */
   4220 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata));
   4221 	*changed = true;
   4222 
   4223 	/* Refresh new keys from the zone apex as soon as possible. */
   4224 	set_refreshkeytimer(zone, &kd, now, true);
   4225 	return (ISC_R_SUCCESS);
   4226 
   4227 failure:
   4228 	return (result);
   4229 }
   4230 
   4231 /*
   4232  * Remove from the key zone all the KEYDATA records found in rdataset.
   4233  */
   4234 static isc_result_t
   4235 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4236 	       dns_name_t *name, dns_rdataset_t *rdataset) {
   4237 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4238 	isc_result_t result, uresult;
   4239 
   4240 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4241 	     result = dns_rdataset_next(rdataset))
   4242 	{
   4243 		dns_rdata_reset(&rdata);
   4244 		dns_rdataset_current(rdataset, &rdata);
   4245 		uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0,
   4246 					&rdata);
   4247 		if (uresult != ISC_R_SUCCESS) {
   4248 			return (uresult);
   4249 		}
   4250 	}
   4251 	if (result == ISC_R_NOMORE) {
   4252 		result = ISC_R_SUCCESS;
   4253 	}
   4254 	return (result);
   4255 }
   4256 
   4257 /*
   4258  * Compute the DNSSEC key ID for a DNSKEY record.
   4259  */
   4260 static isc_result_t
   4261 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
   4262 	    dns_keytag_t *tag) {
   4263 	isc_result_t result;
   4264 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4265 	unsigned char data[4096];
   4266 	isc_buffer_t buffer;
   4267 	dst_key_t *dstkey = NULL;
   4268 
   4269 	isc_buffer_init(&buffer, data, sizeof(data));
   4270 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4271 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4272 
   4273 	result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
   4274 	if (result == ISC_R_SUCCESS) {
   4275 		*tag = dst_key_id(dstkey);
   4276 		dst_key_free(&dstkey);
   4277 	}
   4278 
   4279 	return (result);
   4280 }
   4281 
   4282 /*
   4283  * Synth-from-dnssec callbacks to add/delete names from namespace tree.
   4284  */
   4285 static void
   4286 sfd_add(const dns_name_t *name, void *arg) {
   4287 	if (arg != NULL) {
   4288 		dns_view_sfd_add(arg, name);
   4289 	}
   4290 }
   4291 
   4292 static void
   4293 sfd_del(const dns_name_t *name, void *arg) {
   4294 	if (arg != NULL) {
   4295 		dns_view_sfd_del(arg, name);
   4296 	}
   4297 }
   4298 
   4299 /*
   4300  * Add key to the security roots.
   4301  */
   4302 static void
   4303 trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey,
   4304 	  bool initial) {
   4305 	isc_result_t result;
   4306 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4307 	unsigned char data[4096], digest[ISC_MAX_MD_SIZE];
   4308 	isc_buffer_t buffer;
   4309 	dns_keytable_t *sr = NULL;
   4310 	dns_rdata_ds_t ds;
   4311 
   4312 	result = dns_view_getsecroots(zone->view, &sr);
   4313 	if (result != ISC_R_SUCCESS) {
   4314 		return;
   4315 	}
   4316 
   4317 	/* Build DS record for key. */
   4318 	isc_buffer_init(&buffer, data, sizeof(data));
   4319 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4320 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4321 	CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest,
   4322 				  &ds));
   4323 	CHECK(dns_keytable_add(sr, true, initial, keyname, &ds, sfd_add,
   4324 			       zone->view));
   4325 
   4326 	dns_keytable_detach(&sr);
   4327 
   4328 failure:
   4329 	if (sr != NULL) {
   4330 		dns_keytable_detach(&sr);
   4331 	}
   4332 	return;
   4333 }
   4334 
   4335 /*
   4336  * Add a null key to the security roots for so that all queries
   4337  * to the zone will fail.
   4338  */
   4339 static void
   4340 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
   4341 	isc_result_t result;
   4342 	dns_keytable_t *sr = NULL;
   4343 
   4344 	result = dns_view_getsecroots(zone->view, &sr);
   4345 	if (result == ISC_R_SUCCESS) {
   4346 		dns_keytable_marksecure(sr, keyname);
   4347 		dns_keytable_detach(&sr);
   4348 	}
   4349 }
   4350 
   4351 /*
   4352  * Scan a set of KEYDATA records from the key zone.  The ones that are
   4353  * valid (i.e., the add holddown timer has expired) become trusted keys.
   4354  */
   4355 static void
   4356 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
   4357 	isc_result_t result;
   4358 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4359 	dns_rdata_keydata_t keydata;
   4360 	dns_rdata_dnskey_t dnskey;
   4361 	int trusted = 0, revoked = 0, pending = 0;
   4362 	isc_stdtime_t now;
   4363 	dns_keytable_t *sr = NULL;
   4364 
   4365 	isc_stdtime_get(&now);
   4366 
   4367 	result = dns_view_getsecroots(zone->view, &sr);
   4368 	if (result == ISC_R_SUCCESS) {
   4369 		dns_keytable_delete(sr, name, sfd_del, zone->view);
   4370 		dns_keytable_detach(&sr);
   4371 	}
   4372 
   4373 	/* Now insert all the accepted trust anchors from this keydata set. */
   4374 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4375 	     result = dns_rdataset_next(rdataset))
   4376 	{
   4377 		dns_rdata_reset(&rdata);
   4378 		dns_rdataset_current(rdataset, &rdata);
   4379 
   4380 		/* Convert rdata to keydata. */
   4381 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   4382 		if (result == ISC_R_UNEXPECTEDEND) {
   4383 			continue;
   4384 		}
   4385 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4386 
   4387 		/* Set the key refresh timer to force a fast refresh. */
   4388 		set_refreshkeytimer(zone, &keydata, now, true);
   4389 
   4390 		/* If the removal timer is nonzero, this key was revoked. */
   4391 		if (keydata.removehd != 0) {
   4392 			revoked++;
   4393 			continue;
   4394 		}
   4395 
   4396 		/*
   4397 		 * If the add timer is still pending, this key is not
   4398 		 * trusted yet.
   4399 		 */
   4400 		if (now < keydata.addhd) {
   4401 			pending++;
   4402 			continue;
   4403 		}
   4404 
   4405 		/* Convert keydata to dnskey. */
   4406 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   4407 
   4408 		/* Add to keytables. */
   4409 		trusted++;
   4410 		trust_key(zone, name, &dnskey, (keydata.addhd == 0));
   4411 	}
   4412 
   4413 	if (trusted == 0 && pending != 0) {
   4414 		char namebuf[DNS_NAME_FORMATSIZE];
   4415 		dns_name_format(name, namebuf, sizeof namebuf);
   4416 		dnssec_log(zone, ISC_LOG_ERROR,
   4417 			   "No valid trust anchors for '%s'!", namebuf);
   4418 		dnssec_log(zone, ISC_LOG_ERROR,
   4419 			   "%d key(s) revoked, %d still pending", revoked,
   4420 			   pending);
   4421 		dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail",
   4422 			   namebuf);
   4423 		fail_secure(zone, name);
   4424 	}
   4425 }
   4426 
   4427 static isc_result_t
   4428 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
   4429 	     dns_diff_t *diff) {
   4430 	dns_diff_t temp_diff;
   4431 	isc_result_t result;
   4432 
   4433 	/*
   4434 	 * Create a singleton diff.
   4435 	 */
   4436 	dns_diff_init(diff->mctx, &temp_diff);
   4437 	ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
   4438 
   4439 	/*
   4440 	 * Apply it to the database.
   4441 	 */
   4442 	result = dns_diff_apply(&temp_diff, db, ver);
   4443 	ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
   4444 	if (result != ISC_R_SUCCESS) {
   4445 		dns_difftuple_free(tuple);
   4446 		return (result);
   4447 	}
   4448 
   4449 	/*
   4450 	 * Merge it into the current pending journal entry.
   4451 	 */
   4452 	dns_diff_appendminimal(diff, tuple);
   4453 
   4454 	/*
   4455 	 * Do not clear temp_diff.
   4456 	 */
   4457 	return (ISC_R_SUCCESS);
   4458 }
   4459 
   4460 static isc_result_t
   4461 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4462 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
   4463 	      dns_rdata_t *rdata) {
   4464 	dns_difftuple_t *tuple = NULL;
   4465 	isc_result_t result;
   4466 	result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple);
   4467 	if (result != ISC_R_SUCCESS) {
   4468 		return (result);
   4469 	}
   4470 	return (do_one_tuple(&tuple, db, ver, diff));
   4471 }
   4472 
   4473 static isc_result_t
   4474 update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4475 		  dns_diff_t *diff, isc_mem_t *mctx,
   4476 		  dns_updatemethod_t method) {
   4477 	dns_difftuple_t *deltuple = NULL;
   4478 	dns_difftuple_t *addtuple = NULL;
   4479 	uint32_t serial;
   4480 	isc_result_t result;
   4481 	dns_updatemethod_t used = dns_updatemethod_none;
   4482 
   4483 	INSIST(method != dns_updatemethod_none);
   4484 
   4485 	CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
   4486 	CHECK(dns_difftuple_copy(deltuple, &addtuple));
   4487 	addtuple->op = DNS_DIFFOP_ADD;
   4488 
   4489 	serial = dns_soa_getserial(&addtuple->rdata);
   4490 	serial = dns_update_soaserial(serial, method, &used);
   4491 	if (method != used) {
   4492 		dns_zone_log(zone, ISC_LOG_WARNING,
   4493 			     "update_soa_serial:new serial would be lower than "
   4494 			     "old serial, using increment method instead");
   4495 	}
   4496 	dns_soa_setserial(serial, &addtuple->rdata);
   4497 	CHECK(do_one_tuple(&deltuple, db, ver, diff));
   4498 	CHECK(do_one_tuple(&addtuple, db, ver, diff));
   4499 	result = ISC_R_SUCCESS;
   4500 
   4501 failure:
   4502 	if (addtuple != NULL) {
   4503 		dns_difftuple_free(&addtuple);
   4504 	}
   4505 	if (deltuple != NULL) {
   4506 		dns_difftuple_free(&deltuple);
   4507 	}
   4508 	return (result);
   4509 }
   4510 
   4511 /*
   4512  * Write all transactions in 'diff' to the zone journal file.
   4513  */
   4514 static isc_result_t
   4515 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial,
   4516 	     const char *caller) {
   4517 	const char me[] = "zone_journal";
   4518 	const char *journalfile;
   4519 	isc_result_t result = ISC_R_SUCCESS;
   4520 	dns_journal_t *journal = NULL;
   4521 	unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE;
   4522 
   4523 	ENTER;
   4524 	journalfile = dns_zone_getjournal(zone);
   4525 	if (journalfile != NULL) {
   4526 		result = dns_journal_open(zone->mctx, journalfile, mode,
   4527 					  &journal);
   4528 		if (result != ISC_R_SUCCESS) {
   4529 			dns_zone_log(zone, ISC_LOG_ERROR,
   4530 				     "%s:dns_journal_open -> %s", caller,
   4531 				     isc_result_totext(result));
   4532 			return (result);
   4533 		}
   4534 
   4535 		if (sourceserial != NULL) {
   4536 			dns_journal_set_sourceserial(journal, *sourceserial);
   4537 		}
   4538 
   4539 		result = dns_journal_write_transaction(journal, diff);
   4540 		if (result != ISC_R_SUCCESS) {
   4541 			dns_zone_log(zone, ISC_LOG_ERROR,
   4542 				     "%s:dns_journal_write_transaction -> %s",
   4543 				     caller, isc_result_totext(result));
   4544 		}
   4545 		dns_journal_destroy(&journal);
   4546 	}
   4547 
   4548 	return (result);
   4549 }
   4550 
   4551 /*
   4552  * Create an SOA record for a newly-created zone
   4553  */
   4554 static isc_result_t
   4555 add_soa(dns_zone_t *zone, dns_db_t *db) {
   4556 	isc_result_t result;
   4557 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4558 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   4559 	dns_dbversion_t *ver = NULL;
   4560 	dns_diff_t diff;
   4561 
   4562 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
   4563 
   4564 	dns_diff_init(zone->mctx, &diff);
   4565 	result = dns_db_newversion(db, &ver);
   4566 	if (result != ISC_R_SUCCESS) {
   4567 		dns_zone_log(zone, ISC_LOG_ERROR,
   4568 			     "add_soa:dns_db_newversion -> %s",
   4569 			     isc_result_totext(result));
   4570 		goto failure;
   4571 	}
   4572 
   4573 	/* Build SOA record */
   4574 	result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
   4575 				    0, 0, 0, 0, 0, buf, &rdata);
   4576 	if (result != ISC_R_SUCCESS) {
   4577 		dns_zone_log(zone, ISC_LOG_ERROR,
   4578 			     "add_soa:dns_soa_buildrdata -> %s",
   4579 			     isc_result_totext(result));
   4580 		goto failure;
   4581 	}
   4582 
   4583 	result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0,
   4584 			       &rdata);
   4585 
   4586 failure:
   4587 	dns_diff_clear(&diff);
   4588 	if (ver != NULL) {
   4589 		dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS));
   4590 	}
   4591 
   4592 	INSIST(ver == NULL);
   4593 
   4594 	return (result);
   4595 }
   4596 
   4597 struct addifmissing_arg {
   4598 	dns_db_t *db;
   4599 	dns_dbversion_t *ver;
   4600 	dns_diff_t *diff;
   4601 	dns_zone_t *zone;
   4602 	bool *changed;
   4603 	isc_result_t result;
   4604 };
   4605 
   4606 static void
   4607 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode,
   4608 	     dns_name_t *keyname, void *arg) {
   4609 	dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
   4610 	dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
   4611 	dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
   4612 	dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
   4613 	bool *changed = ((struct addifmissing_arg *)arg)->changed;
   4614 	isc_result_t result;
   4615 	dns_fixedname_t fname;
   4616 
   4617 	UNUSED(keytable);
   4618 
   4619 	if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) {
   4620 		return;
   4621 	}
   4622 
   4623 	if (!dns_keynode_managed(keynode)) {
   4624 		return;
   4625 	}
   4626 
   4627 	/*
   4628 	 * If the keynode has no trust anchor set, return.
   4629 	 */
   4630 	if (!dns_keynode_dsset(keynode, NULL)) {
   4631 		return;
   4632 	}
   4633 
   4634 	/*
   4635 	 * Check whether there's already a KEYDATA entry for this name;
   4636 	 * if so, we don't need to add another.
   4637 	 */
   4638 	dns_fixedname_init(&fname);
   4639 	result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata,
   4640 			     DNS_DBFIND_NOWILD, 0, NULL,
   4641 			     dns_fixedname_name(&fname), NULL, NULL);
   4642 	if (result == ISC_R_SUCCESS) {
   4643 		return;
   4644 	}
   4645 
   4646 	/*
   4647 	 * Create the keydata.
   4648 	 */
   4649 	result = create_keydata(zone, db, ver, diff, keynode, keyname, changed);
   4650 	if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
   4651 		((struct addifmissing_arg *)arg)->result = result;
   4652 	}
   4653 }
   4654 
   4655 /*
   4656  * Synchronize the set of initializing keys found in managed-keys {}
   4657  * statements with the set of trust anchors found in the managed-keys.bind
   4658  * zone.  If a domain is no longer named in managed-keys, delete all keys
   4659  * from that domain from the key zone.	If a domain is configured as an
   4660  * initial-key in trust-anchors, but there are no references to it in the
   4661  * key zone, load the key zone with the initializing key(s) for that
   4662  * domain and schedule a key refresh. If a domain is configured as
   4663  * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key
   4664  * zone with the matching key, and schedule a key refresh.
   4665  */
   4666 static isc_result_t
   4667 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
   4668 	isc_result_t result = ISC_R_SUCCESS;
   4669 	bool changed = false;
   4670 	bool commit = false;
   4671 	dns_keynode_t *keynode = NULL;
   4672 	dns_view_t *view = zone->view;
   4673 	dns_keytable_t *sr = NULL;
   4674 	dns_dbversion_t *ver = NULL;
   4675 	dns_diff_t diff;
   4676 	dns_rriterator_t rrit;
   4677 	struct addifmissing_arg arg;
   4678 
   4679 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
   4680 
   4681 	dns_diff_init(zone->mctx, &diff);
   4682 
   4683 	CHECK(dns_view_getsecroots(view, &sr));
   4684 
   4685 	result = dns_db_newversion(db, &ver);
   4686 	if (result != ISC_R_SUCCESS) {
   4687 		dnssec_log(zone, ISC_LOG_ERROR,
   4688 			   "sync_keyzone:dns_db_newversion -> %s",
   4689 			   isc_result_totext(result));
   4690 		goto failure;
   4691 	}
   4692 
   4693 	/*
   4694 	 * Walk the zone DB.  If we find any keys whose names are no longer
   4695 	 * in trust-anchors, or which have been changed from initial to static,
   4696 	 * (meaning they are permanent and not RFC5011-maintained), delete
   4697 	 * them from the zone.  Otherwise call load_secroots(), which
   4698 	 * loads keys into secroots as appropriate.
   4699 	 */
   4700 	dns_rriterator_init(&rrit, db, ver, 0);
   4701 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   4702 	     result = dns_rriterator_nextrrset(&rrit))
   4703 	{
   4704 		dns_rdataset_t *rdataset = NULL;
   4705 		dns_rdata_t rdata = DNS_RDATA_INIT;
   4706 		dns_rdata_keydata_t keydata;
   4707 		isc_stdtime_t now;
   4708 		bool load = true;
   4709 		dns_name_t *rrname = NULL;
   4710 		uint32_t ttl;
   4711 
   4712 		isc_stdtime_get(&now);
   4713 
   4714 		dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL);
   4715 		if (!dns_rdataset_isassociated(rdataset)) {
   4716 			dns_rriterator_destroy(&rrit);
   4717 			goto failure;
   4718 		}
   4719 
   4720 		if (rdataset->type != dns_rdatatype_keydata) {
   4721 			continue;
   4722 		}
   4723 
   4724 		/*
   4725 		 * The managed-keys zone can contain a placeholder instead of
   4726 		 * legitimate data, in which case we will not use it, and we
   4727 		 * will try to refresh it.
   4728 		 */
   4729 		for (result = dns_rdataset_first(rdataset);
   4730 		     result == ISC_R_SUCCESS;
   4731 		     result = dns_rdataset_next(rdataset))
   4732 		{
   4733 			isc_result_t iresult;
   4734 
   4735 			dns_rdata_reset(&rdata);
   4736 			dns_rdataset_current(rdataset, &rdata);
   4737 
   4738 			iresult = dns_rdata_tostruct(&rdata, &keydata, NULL);
   4739 			/* Do we have a valid placeholder KEYDATA record? */
   4740 			if (iresult == ISC_R_SUCCESS && keydata.flags == 0 &&
   4741 			    keydata.protocol == 0 && keydata.algorithm == 0)
   4742 			{
   4743 				set_refreshkeytimer(zone, &keydata, now, true);
   4744 				load = false;
   4745 			}
   4746 		}
   4747 
   4748 		/*
   4749 		 * Release db wrlock to prevent LOR reports against
   4750 		 * dns_keytable_forall() call below.
   4751 		 */
   4752 		dns_rriterator_pause(&rrit);
   4753 		result = dns_keytable_find(sr, rrname, &keynode);
   4754 		if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) {
   4755 			CHECK(delete_keydata(db, ver, &diff, rrname, rdataset));
   4756 			changed = true;
   4757 		} else if (load) {
   4758 			load_secroots(zone, rrname, rdataset);
   4759 		}
   4760 
   4761 		if (keynode != NULL) {
   4762 			dns_keytable_detachkeynode(sr, &keynode);
   4763 		}
   4764 	}
   4765 	dns_rriterator_destroy(&rrit);
   4766 
   4767 	/*
   4768 	 * Walk secroots to find any initial keys that aren't in
   4769 	 * the zone.  If we find any, add them to the zone directly.
   4770 	 * If any DS-style initial keys are found, refresh the key
   4771 	 * zone so that they'll be looked up.
   4772 	 */
   4773 	arg.db = db;
   4774 	arg.ver = ver;
   4775 	arg.result = ISC_R_SUCCESS;
   4776 	arg.diff = &diff;
   4777 	arg.zone = zone;
   4778 	arg.changed = &changed;
   4779 	dns_keytable_forall(sr, addifmissing, &arg);
   4780 	result = arg.result;
   4781 	if (changed) {
   4782 		/* Write changes to journal file. */
   4783 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   4784 					zone->updatemethod));
   4785 		CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
   4786 
   4787 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   4788 		zone_needdump(zone, 30);
   4789 		commit = true;
   4790 	}
   4791 
   4792 failure:
   4793 	if (result != ISC_R_SUCCESS) {
   4794 		dnssec_log(zone, ISC_LOG_ERROR,
   4795 			   "unable to synchronize managed keys: %s",
   4796 			   isc_result_totext(result));
   4797 		isc_time_settoepoch(&zone->refreshkeytime);
   4798 	}
   4799 	if (keynode != NULL) {
   4800 		dns_keytable_detachkeynode(sr, &keynode);
   4801 	}
   4802 	if (sr != NULL) {
   4803 		dns_keytable_detach(&sr);
   4804 	}
   4805 	if (ver != NULL) {
   4806 		dns_db_closeversion(db, &ver, commit);
   4807 	}
   4808 	dns_diff_clear(&diff);
   4809 
   4810 	INSIST(ver == NULL);
   4811 
   4812 	return (result);
   4813 }
   4814 
   4815 isc_result_t
   4816 dns_zone_synckeyzone(dns_zone_t *zone) {
   4817 	isc_result_t result;
   4818 	dns_db_t *db = NULL;
   4819 
   4820 	if (zone->type != dns_zone_key) {
   4821 		return (DNS_R_BADZONE);
   4822 	}
   4823 
   4824 	CHECK(dns_zone_getdb(zone, &db));
   4825 
   4826 	LOCK_ZONE(zone);
   4827 	result = sync_keyzone(zone, db);
   4828 	UNLOCK_ZONE(zone);
   4829 
   4830 failure:
   4831 	if (db != NULL) {
   4832 		dns_db_detach(&db);
   4833 	}
   4834 	return (result);
   4835 }
   4836 
   4837 static void
   4838 maybe_send_secure(dns_zone_t *zone) {
   4839 	isc_result_t result;
   4840 
   4841 	/*
   4842 	 * We've finished loading, or else failed to load, an inline-signing
   4843 	 * 'secure' zone.  We now need information about the status of the
   4844 	 * 'raw' zone.  If we failed to load, then we need it to send a
   4845 	 * copy of its database; if we succeeded, we need it to send its
   4846 	 * serial number so that we can sync with it.  If it has not yet
   4847 	 * loaded, we set a flag so that it will send the necessary
   4848 	 * information when it has finished loading.
   4849 	 */
   4850 	if (zone->raw->db != NULL) {
   4851 		if (zone->db != NULL) {
   4852 			uint32_t serial;
   4853 			unsigned int soacount;
   4854 
   4855 			result = zone_get_from_db(
   4856 				zone->raw, zone->raw->db, NULL, &soacount, NULL,
   4857 				&serial, NULL, NULL, NULL, NULL, NULL);
   4858 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   4859 				zone_send_secureserial(zone->raw, serial);
   4860 			}
   4861 		} else {
   4862 			zone_send_securedb(zone->raw, zone->raw->db);
   4863 		}
   4864 	} else {
   4865 		DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
   4866 	}
   4867 }
   4868 
   4869 static bool
   4870 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
   4871 	isc_result_t result;
   4872 	bool answer = false;
   4873 	dns_diff_t diff;
   4874 
   4875 	dns_diff_init(mctx, &diff);
   4876 	result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
   4877 	if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) {
   4878 		answer = true;
   4879 	}
   4880 	dns_diff_clear(&diff);
   4881 	return (answer);
   4882 }
   4883 
   4884 /*
   4885  * The zone is presumed to be locked.
   4886  * If this is a inline_raw zone the secure version is also locked.
   4887  */
   4888 static isc_result_t
   4889 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
   4890 	      isc_result_t result) {
   4891 	unsigned int soacount = 0;
   4892 	unsigned int nscount = 0;
   4893 	unsigned int errors = 0;
   4894 	uint32_t serial, oldserial, refresh, retry, expire, minimum, soattl;
   4895 	isc_time_t now;
   4896 	bool needdump = false;
   4897 	bool fixjournal = false;
   4898 	bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4899 	bool noprimary = false;
   4900 	bool had_db = false;
   4901 	dns_include_t *inc;
   4902 	bool is_dynamic = false;
   4903 
   4904 	INSIST(LOCKED_ZONE(zone));
   4905 	if (inline_raw(zone)) {
   4906 		INSIST(LOCKED_ZONE(zone->secure));
   4907 	}
   4908 
   4909 	TIME_NOW(&now);
   4910 
   4911 	/*
   4912 	 * Initiate zone transfer?  We may need a error code that
   4913 	 * indicates that the "permanent" form does not exist.
   4914 	 * XXX better error feedback to log.
   4915 	 */
   4916 	if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
   4917 		if (zone->type == dns_zone_secondary ||
   4918 		    zone->type == dns_zone_mirror ||
   4919 		    zone->type == dns_zone_stub ||
   4920 		    (zone->type == dns_zone_redirect &&
   4921 		     zone->primaries == NULL))
   4922 		{
   4923 			if (result == ISC_R_FILENOTFOUND) {
   4924 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4925 					      ISC_LOG_DEBUG(1),
   4926 					      "no master file");
   4927 			} else if (result != DNS_R_NOMASTERFILE) {
   4928 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4929 					      ISC_LOG_ERROR,
   4930 					      "loading from master file %s "
   4931 					      "failed: %s",
   4932 					      zone->masterfile,
   4933 					      isc_result_totext(result));
   4934 			}
   4935 		} else if (zone->type == dns_zone_primary &&
   4936 			   inline_secure(zone) && result == ISC_R_FILENOTFOUND)
   4937 		{
   4938 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4939 				      ISC_LOG_DEBUG(1),
   4940 				      "no master file, requesting db");
   4941 			maybe_send_secure(zone);
   4942 		} else {
   4943 			int level = ISC_LOG_ERROR;
   4944 			if (zone->type == dns_zone_key &&
   4945 			    result == ISC_R_FILENOTFOUND)
   4946 			{
   4947 				level = ISC_LOG_DEBUG(1);
   4948 			}
   4949 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level,
   4950 				      "loading from master file %s failed: %s",
   4951 				      zone->masterfile,
   4952 				      isc_result_totext(result));
   4953 			noprimary = true;
   4954 		}
   4955 
   4956 		if (zone->type != dns_zone_key) {
   4957 			goto cleanup;
   4958 		}
   4959 	}
   4960 
   4961 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
   4962 		      "number of nodes in database: %u",
   4963 		      dns_db_nodecount(db, dns_dbtree_main));
   4964 
   4965 	if (result == DNS_R_SEENINCLUDE) {
   4966 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4967 	} else {
   4968 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4969 	}
   4970 
   4971 	/*
   4972 	 * If there's no master file for a key zone, then the zone is new:
   4973 	 * create an SOA record.  (We do this now, instead of later, so that
   4974 	 * if there happens to be a journal file, we can roll forward from
   4975 	 * a sane starting point.)
   4976 	 */
   4977 	if (noprimary && zone->type == dns_zone_key) {
   4978 		result = add_soa(zone, db);
   4979 		if (result != ISC_R_SUCCESS) {
   4980 			goto cleanup;
   4981 		}
   4982 	}
   4983 
   4984 	/*
   4985 	 * Apply update log, if any, on initial load.
   4986 	 */
   4987 	if (zone->journal != NULL &&
   4988 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
   4989 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4990 	{
   4991 		result = zone_journal_rollforward(zone, db, &needdump,
   4992 						  &fixjournal);
   4993 		if (result != ISC_R_SUCCESS) {
   4994 			goto cleanup;
   4995 		}
   4996 	}
   4997 
   4998 	/*
   4999 	 * Obtain ns, soa and cname counts for top of zone.
   5000 	 */
   5001 	INSIST(db != NULL);
   5002 	result = zone_get_from_db(zone, db, &nscount, &soacount, &soattl,
   5003 				  &serial, &refresh, &retry, &expire, &minimum,
   5004 				  &errors);
   5005 	if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
   5006 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   5007 			      "could not find NS and/or SOA records");
   5008 	}
   5009 
   5010 	/*
   5011 	 * Process any queued NSEC3PARAM change requests. Only for dynamic
   5012 	 * zones, an inline-signing zone will perform this action when
   5013 	 * receiving the secure db (receive_secure_db).
   5014 	 */
   5015 	is_dynamic = dns_zone_isdynamic(zone, true);
   5016 	if (is_dynamic) {
   5017 		isc_event_t *setnsec3param_event;
   5018 		dns_zone_t *dummy;
   5019 
   5020 		while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   5021 			setnsec3param_event =
   5022 				ISC_LIST_HEAD(zone->setnsec3param_queue);
   5023 			ISC_LIST_UNLINK(zone->setnsec3param_queue,
   5024 					setnsec3param_event, ev_link);
   5025 			dummy = NULL;
   5026 			zone_iattach(zone, &dummy);
   5027 			isc_task_send(zone->task, &setnsec3param_event);
   5028 		}
   5029 	}
   5030 
   5031 	/*
   5032 	 * Check to make sure the journal is up to date, and remove the
   5033 	 * journal file if it isn't, as we wouldn't be able to apply
   5034 	 * updates otherwise.
   5035 	 */
   5036 	if (zone->journal != NULL && is_dynamic &&
   5037 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
   5038 	{
   5039 		uint32_t jserial;
   5040 		dns_journal_t *journal = NULL;
   5041 		bool empty = false;
   5042 
   5043 		result = dns_journal_open(zone->mctx, zone->journal,
   5044 					  DNS_JOURNAL_READ, &journal);
   5045 		if (result == ISC_R_SUCCESS) {
   5046 			jserial = dns_journal_last_serial(journal);
   5047 			empty = dns_journal_empty(journal);
   5048 			dns_journal_destroy(&journal);
   5049 		} else {
   5050 			jserial = serial;
   5051 			result = ISC_R_SUCCESS;
   5052 		}
   5053 
   5054 		if (jserial != serial) {
   5055 			if (!empty) {
   5056 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5057 					      ISC_LOG_INFO,
   5058 					      "journal file is out of date: "
   5059 					      "removing journal file");
   5060 			}
   5061 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   5062 				char strbuf[ISC_STRERRORSIZE];
   5063 				strerror_r(errno, strbuf, sizeof(strbuf));
   5064 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   5065 					      DNS_LOGMODULE_ZONE,
   5066 					      ISC_LOG_WARNING,
   5067 					      "unable to remove journal "
   5068 					      "'%s': '%s'",
   5069 					      zone->journal, strbuf);
   5070 			}
   5071 		}
   5072 	}
   5073 
   5074 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   5075 		      "loaded; checking validity");
   5076 
   5077 	/*
   5078 	 * Primary / Secondary / Mirror / Stub zones require both NS and SOA
   5079 	 * records at the top of the zone.
   5080 	 */
   5081 
   5082 	switch (zone->type) {
   5083 	case dns_zone_dlz:
   5084 	case dns_zone_primary:
   5085 	case dns_zone_secondary:
   5086 	case dns_zone_mirror:
   5087 	case dns_zone_stub:
   5088 	case dns_zone_redirect:
   5089 		if (soacount != 1) {
   5090 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5091 				      ISC_LOG_ERROR, "has %d SOA records",
   5092 				      soacount);
   5093 			result = DNS_R_BADZONE;
   5094 		}
   5095 		if (nscount == 0) {
   5096 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5097 				      ISC_LOG_ERROR, "has no NS records");
   5098 			result = DNS_R_BADZONE;
   5099 		}
   5100 		if (result != ISC_R_SUCCESS) {
   5101 			goto cleanup;
   5102 		}
   5103 		if (zone->type == dns_zone_primary && errors != 0) {
   5104 			result = DNS_R_BADZONE;
   5105 			goto cleanup;
   5106 		}
   5107 		if (zone->type != dns_zone_stub &&
   5108 		    zone->type != dns_zone_redirect)
   5109 		{
   5110 			result = check_nsec3param(zone, db);
   5111 			if (result != ISC_R_SUCCESS) {
   5112 				goto cleanup;
   5113 			}
   5114 		}
   5115 		if (zone->type == dns_zone_primary &&
   5116 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
   5117 		    !integrity_checks(zone, db))
   5118 		{
   5119 			result = DNS_R_BADZONE;
   5120 			goto cleanup;
   5121 		}
   5122 		if (zone->type == dns_zone_primary &&
   5123 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
   5124 		    !zone_check_dup(zone, db))
   5125 		{
   5126 			result = DNS_R_BADZONE;
   5127 			goto cleanup;
   5128 		}
   5129 
   5130 		if (zone->type == dns_zone_primary) {
   5131 			result = dns_zone_cdscheck(zone, db, NULL);
   5132 			if (result != ISC_R_SUCCESS) {
   5133 				dns_zone_log(zone, ISC_LOG_ERROR,
   5134 					     "CDS/CDNSKEY consistency checks "
   5135 					     "failed");
   5136 				goto cleanup;
   5137 			}
   5138 		}
   5139 
   5140 		result = dns_zone_verifydb(zone, db, NULL);
   5141 		if (result != ISC_R_SUCCESS) {
   5142 			goto cleanup;
   5143 		}
   5144 
   5145 		if (zone->db != NULL) {
   5146 			unsigned int oldsoacount;
   5147 
   5148 			/*
   5149 			 * This is checked in zone_replacedb() for
   5150 			 * secondary zones as they don't reload from disk.
   5151 			 */
   5152 			result = zone_get_from_db(
   5153 				zone, zone->db, NULL, &oldsoacount, NULL,
   5154 				&oldserial, NULL, NULL, NULL, NULL, NULL);
   5155 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5156 			RUNTIME_CHECK(oldsoacount > 0U);
   5157 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   5158 			    !isc_serial_gt(serial, oldserial))
   5159 			{
   5160 				uint32_t serialmin, serialmax;
   5161 
   5162 				INSIST(zone->type == dns_zone_primary);
   5163 				INSIST(zone->raw == NULL);
   5164 
   5165 				if (serial == oldserial &&
   5166 				    zone_unchanged(zone->db, db, zone->mctx))
   5167 				{
   5168 					dns_zone_logc(zone,
   5169 						      DNS_LOGCATEGORY_ZONELOAD,
   5170 						      ISC_LOG_INFO,
   5171 						      "ixfr-from-differences: "
   5172 						      "unchanged");
   5173 					zone->loadtime = loadtime;
   5174 					goto done;
   5175 				}
   5176 
   5177 				serialmin = (oldserial + 1) & 0xffffffffU;
   5178 				serialmax = (oldserial + 0x7fffffffU) &
   5179 					    0xffffffffU;
   5180 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5181 					      ISC_LOG_ERROR,
   5182 					      "ixfr-from-differences: "
   5183 					      "new serial (%u) out of range "
   5184 					      "[%u - %u]",
   5185 					      serial, serialmin, serialmax);
   5186 				result = DNS_R_BADZONE;
   5187 				goto cleanup;
   5188 			} else if (!isc_serial_ge(serial, oldserial)) {
   5189 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5190 					      ISC_LOG_ERROR,
   5191 					      "zone serial (%u/%u) has gone "
   5192 					      "backwards",
   5193 					      serial, oldserial);
   5194 			} else if (serial == oldserial && !hasinclude &&
   5195 				   strcmp(zone->db_argv[0], "_builtin") != 0)
   5196 			{
   5197 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5198 					      ISC_LOG_ERROR,
   5199 					      "zone serial (%u) unchanged. "
   5200 					      "zone may fail to transfer "
   5201 					      "to secondaries.",
   5202 					      serial);
   5203 			}
   5204 		}
   5205 
   5206 		if (zone->type == dns_zone_primary &&
   5207 		    (zone->update_acl != NULL || zone->ssutable != NULL) &&
   5208 		    dns_zone_getsigresigninginterval(zone) < (3 * refresh) &&
   5209 		    dns_db_issecure(db))
   5210 		{
   5211 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5212 				      ISC_LOG_WARNING,
   5213 				      "sig-re-signing-interval less than "
   5214 				      "3 * refresh.");
   5215 		}
   5216 
   5217 		zone->refresh = RANGE(refresh, zone->minrefresh,
   5218 				      zone->maxrefresh);
   5219 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   5220 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   5221 				     DNS_MAX_EXPIRE);
   5222 		zone->soattl = soattl;
   5223 		zone->minimum = minimum;
   5224 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   5225 
   5226 		if (zone->type == dns_zone_secondary ||
   5227 		    zone->type == dns_zone_mirror ||
   5228 		    zone->type == dns_zone_stub ||
   5229 		    (zone->type == dns_zone_redirect &&
   5230 		     zone->primaries != NULL))
   5231 		{
   5232 			isc_time_t t;
   5233 			uint32_t delay;
   5234 
   5235 			result = isc_file_getmodtime(zone->journal, &t);
   5236 			if (result != ISC_R_SUCCESS) {
   5237 				result = isc_file_getmodtime(zone->masterfile,
   5238 							     &t);
   5239 			}
   5240 			if (result == ISC_R_SUCCESS) {
   5241 				DNS_ZONE_TIME_ADD(&t, zone->expire,
   5242 						  &zone->expiretime);
   5243 			} else {
   5244 				DNS_ZONE_TIME_ADD(&now, zone->retry,
   5245 						  &zone->expiretime);
   5246 			}
   5247 
   5248 			delay = (zone->retry -
   5249 				 isc_random_uniform((zone->retry * 3) / 4));
   5250 			DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
   5251 			if (isc_time_compare(&zone->refreshtime,
   5252 					     &zone->expiretime) >= 0)
   5253 			{
   5254 				zone->refreshtime = now;
   5255 			}
   5256 		}
   5257 
   5258 		break;
   5259 
   5260 	case dns_zone_key:
   5261 		/* Nothing needs to be done now */
   5262 		break;
   5263 
   5264 	default:
   5265 		UNEXPECTED_ERROR("unexpected zone type %d", zone->type);
   5266 		result = ISC_R_UNEXPECTED;
   5267 		goto cleanup;
   5268 	}
   5269 
   5270 	/*
   5271 	 * Check for weak DNSKEY's.
   5272 	 */
   5273 	if (zone->type == dns_zone_primary) {
   5274 		zone_check_dnskeys(zone, db);
   5275 	}
   5276 
   5277 	/*
   5278 	 * Schedule DNSSEC key refresh.
   5279 	 */
   5280 	if (zone->type == dns_zone_primary &&
   5281 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   5282 	{
   5283 		zone->refreshkeytime = now;
   5284 	}
   5285 
   5286 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   5287 	if (zone->db != NULL) {
   5288 		had_db = true;
   5289 		result = zone_replacedb(zone, db, false);
   5290 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5291 		if (result != ISC_R_SUCCESS) {
   5292 			goto cleanup;
   5293 		}
   5294 	} else {
   5295 		zone_attachdb(zone, db);
   5296 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5297 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED |
   5298 					       DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   5299 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
   5300 		    inline_raw(zone))
   5301 		{
   5302 			if (zone->secure->db == NULL) {
   5303 				zone_send_securedb(zone, db);
   5304 			} else {
   5305 				zone_send_secureserial(zone, serial);
   5306 			}
   5307 		}
   5308 	}
   5309 
   5310 	/*
   5311 	 * Finished loading inline-signing zone; need to get status
   5312 	 * from the raw side now.
   5313 	 */
   5314 	if (zone->type == dns_zone_primary && inline_secure(zone)) {
   5315 		maybe_send_secure(zone);
   5316 	}
   5317 
   5318 	result = ISC_R_SUCCESS;
   5319 
   5320 	if (fixjournal) {
   5321 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIXJOURNAL);
   5322 		zone_journal_compact(zone, zone->db, 0);
   5323 	}
   5324 	if (needdump) {
   5325 		if (zone->type == dns_zone_key) {
   5326 			zone_needdump(zone, 30);
   5327 		} else {
   5328 			zone_needdump(zone, DNS_DUMP_DELAY);
   5329 		}
   5330 	}
   5331 
   5332 	if (zone->task != NULL) {
   5333 		if (zone->type == dns_zone_primary) {
   5334 			set_resigntime(zone);
   5335 			resume_signingwithkey(zone);
   5336 			resume_addnsec3chain(zone);
   5337 		}
   5338 
   5339 		is_dynamic = dns_zone_isdynamic(zone, false);
   5340 		if (zone->type == dns_zone_primary &&
   5341 		    !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
   5342 		    is_dynamic && dns_db_issecure(db) && !inline_raw(zone))
   5343 		{
   5344 			dns_name_t *name;
   5345 			dns_fixedname_t fixed;
   5346 			dns_rdataset_t next;
   5347 
   5348 			dns_rdataset_init(&next);
   5349 			name = dns_fixedname_initname(&fixed);
   5350 
   5351 			result = dns_db_getsigningtime(db, &next, name);
   5352 			if (result == ISC_R_SUCCESS) {
   5353 				isc_stdtime_t timenow;
   5354 				char namebuf[DNS_NAME_FORMATSIZE];
   5355 				char typebuf[DNS_RDATATYPE_FORMATSIZE];
   5356 
   5357 				isc_stdtime_get(&timenow);
   5358 				dns_name_format(name, namebuf, sizeof(namebuf));
   5359 				dns_rdatatype_format(next.covers, typebuf,
   5360 						     sizeof(typebuf));
   5361 				dnssec_log(
   5362 					zone, ISC_LOG_DEBUG(3),
   5363 					"next resign: %s/%s "
   5364 					"in %d seconds",
   5365 					namebuf, typebuf,
   5366 					next.resign - timenow -
   5367 						dns_zone_getsigresigninginterval(
   5368 							zone));
   5369 				dns_rdataset_disassociate(&next);
   5370 			} else {
   5371 				dnssec_log(zone, ISC_LOG_WARNING,
   5372 					   "signed dynamic zone has no "
   5373 					   "resign event scheduled");
   5374 			}
   5375 		}
   5376 
   5377 		zone_settimer(zone, &now);
   5378 	}
   5379 
   5380 	/*
   5381 	 * Clear old include list.
   5382 	 */
   5383 	for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL;
   5384 	     inc = ISC_LIST_HEAD(zone->includes))
   5385 	{
   5386 		ISC_LIST_UNLINK(zone->includes, inc, link);
   5387 		isc_mem_free(zone->mctx, inc->name);
   5388 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5389 	}
   5390 	zone->nincludes = 0;
   5391 
   5392 	/*
   5393 	 * Transfer new include list.
   5394 	 */
   5395 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5396 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5397 	{
   5398 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5399 		ISC_LIST_APPEND(zone->includes, inc, link);
   5400 		zone->nincludes++;
   5401 	}
   5402 
   5403 	if (!dns_db_ispersistent(db)) {
   5404 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5405 			      "loaded serial %u%s", serial,
   5406 			      dns_db_issecure(db) ? " (DNSSEC signed)" : "");
   5407 	}
   5408 
   5409 	if (!had_db && zone->type == dns_zone_mirror) {
   5410 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5411 			      "mirror zone is now in use");
   5412 	}
   5413 
   5414 	zone->loadtime = loadtime;
   5415 	goto done;
   5416 
   5417 cleanup:
   5418 	if (result != ISC_R_SUCCESS) {
   5419 		dns_zone_rpz_disable_db(zone, db);
   5420 		dns_zone_catz_disable_db(zone, db);
   5421 	}
   5422 
   5423 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5424 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5425 	{
   5426 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5427 		isc_mem_free(zone->mctx, inc->name);
   5428 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5429 	}
   5430 	if (zone->type == dns_zone_secondary || zone->type == dns_zone_mirror ||
   5431 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   5432 	    (zone->type == dns_zone_redirect && zone->primaries != NULL))
   5433 	{
   5434 		if (result != ISC_R_NOMEMORY) {
   5435 			if (zone->journal != NULL) {
   5436 				zone_saveunique(zone, zone->journal,
   5437 						"jn-XXXXXXXX");
   5438 			}
   5439 			if (zone->masterfile != NULL) {
   5440 				zone_saveunique(zone, zone->masterfile,
   5441 						"db-XXXXXXXX");
   5442 			}
   5443 		}
   5444 
   5445 		/* Mark the zone for immediate refresh. */
   5446 		zone->refreshtime = now;
   5447 		if (zone->task != NULL) {
   5448 			zone_settimer(zone, &now);
   5449 		}
   5450 		result = ISC_R_SUCCESS;
   5451 	} else if (zone->type == dns_zone_primary ||
   5452 		   zone->type == dns_zone_redirect)
   5453 	{
   5454 		if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
   5455 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5456 				      ISC_LOG_ERROR,
   5457 				      "not loaded due to errors.");
   5458 		} else if (zone->type == dns_zone_primary) {
   5459 			result = ISC_R_SUCCESS;
   5460 		}
   5461 	}
   5462 
   5463 done:
   5464 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   5465 	/*
   5466 	 * If this is an inline-signed zone and we were called for the raw
   5467 	 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone
   5468 	 * as well, but only if this is a reload, not an initial zone load: in
   5469 	 * the former case, zone_postload() will not be run for the secure
   5470 	 * zone; in the latter case, it will be.  Check which case we are
   5471 	 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the
   5472 	 * secure zone: if it is set, this must be a reload.
   5473 	 */
   5474 	if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
   5475 	{
   5476 		DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
   5477 		/*
   5478 		 * Re-start zone maintenance if it had been stalled
   5479 		 * due to DNS_ZONEFLG_LOADPENDING being set when
   5480 		 * zone_maintenance was called.
   5481 		 */
   5482 		if (zone->secure->task != NULL) {
   5483 			zone_settimer(zone->secure, &now);
   5484 		}
   5485 	}
   5486 
   5487 	zone_debuglog(zone, "zone_postload", 99, "done");
   5488 
   5489 	return (result);
   5490 }
   5491 
   5492 static bool
   5493 exit_check(dns_zone_t *zone) {
   5494 	REQUIRE(LOCKED_ZONE(zone));
   5495 
   5496 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
   5497 	    isc_refcount_current(&zone->irefs) == 0)
   5498 	{
   5499 		/*
   5500 		 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
   5501 		 */
   5502 		INSIST(isc_refcount_current(&zone->erefs) == 0);
   5503 		return (true);
   5504 	}
   5505 	return (false);
   5506 }
   5507 
   5508 static bool
   5509 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   5510 	      dns_name_t *name, bool logit) {
   5511 	isc_result_t result;
   5512 	char namebuf[DNS_NAME_FORMATSIZE];
   5513 	char altbuf[DNS_NAME_FORMATSIZE];
   5514 	dns_fixedname_t fixed;
   5515 	dns_name_t *foundname;
   5516 	int level;
   5517 
   5518 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) {
   5519 		return (true);
   5520 	}
   5521 
   5522 	if (zone->type == dns_zone_primary) {
   5523 		level = ISC_LOG_ERROR;
   5524 	} else {
   5525 		level = ISC_LOG_WARNING;
   5526 	}
   5527 
   5528 	foundname = dns_fixedname_initname(&fixed);
   5529 
   5530 	result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL,
   5531 			     foundname, NULL, NULL);
   5532 	if (result == ISC_R_SUCCESS) {
   5533 		return (true);
   5534 	}
   5535 
   5536 	if (result == DNS_R_NXRRSET) {
   5537 		result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0,
   5538 				     0, NULL, foundname, NULL, NULL);
   5539 		if (result == ISC_R_SUCCESS) {
   5540 			return (true);
   5541 		}
   5542 	}
   5543 
   5544 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   5545 	    result == DNS_R_EMPTYNAME)
   5546 	{
   5547 		if (logit) {
   5548 			dns_name_format(name, namebuf, sizeof namebuf);
   5549 			dns_zone_log(zone, level,
   5550 				     "NS '%s' has no address "
   5551 				     "records (A or AAAA)",
   5552 				     namebuf);
   5553 		}
   5554 		return (false);
   5555 	}
   5556 
   5557 	if (result == DNS_R_CNAME) {
   5558 		if (logit) {
   5559 			dns_name_format(name, namebuf, sizeof namebuf);
   5560 			dns_zone_log(zone, level,
   5561 				     "NS '%s' is a CNAME "
   5562 				     "(illegal)",
   5563 				     namebuf);
   5564 		}
   5565 		return (false);
   5566 	}
   5567 
   5568 	if (result == DNS_R_DNAME) {
   5569 		if (logit) {
   5570 			dns_name_format(name, namebuf, sizeof namebuf);
   5571 			dns_name_format(foundname, altbuf, sizeof altbuf);
   5572 			dns_zone_log(zone, level,
   5573 				     "NS '%s' is below a DNAME "
   5574 				     "'%s' (illegal)",
   5575 				     namebuf, altbuf);
   5576 		}
   5577 		return (false);
   5578 	}
   5579 
   5580 	return (true);
   5581 }
   5582 
   5583 static isc_result_t
   5584 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   5585 		 dns_dbversion_t *version, unsigned int *nscount,
   5586 		 unsigned int *errors, bool logit) {
   5587 	isc_result_t result;
   5588 	unsigned int count = 0;
   5589 	unsigned int ecount = 0;
   5590 	dns_rdataset_t rdataset;
   5591 	dns_rdata_t rdata;
   5592 	dns_rdata_ns_t ns;
   5593 
   5594 	dns_rdataset_init(&rdataset);
   5595 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
   5596 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5597 	if (result == ISC_R_NOTFOUND) {
   5598 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5599 		goto success;
   5600 	}
   5601 	if (result != ISC_R_SUCCESS) {
   5602 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5603 		goto invalidate_rdataset;
   5604 	}
   5605 
   5606 	result = dns_rdataset_first(&rdataset);
   5607 	while (result == ISC_R_SUCCESS) {
   5608 		if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
   5609 		    (zone->type == dns_zone_primary ||
   5610 		     zone->type == dns_zone_secondary ||
   5611 		     zone->type == dns_zone_mirror))
   5612 		{
   5613 			dns_rdata_init(&rdata);
   5614 			dns_rdataset_current(&rdataset, &rdata);
   5615 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   5616 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5617 			if (dns_name_issubdomain(&ns.name, &zone->origin) &&
   5618 			    !zone_check_ns(zone, db, version, &ns.name, logit))
   5619 			{
   5620 				ecount++;
   5621 			}
   5622 		}
   5623 		count++;
   5624 		result = dns_rdataset_next(&rdataset);
   5625 	}
   5626 	dns_rdataset_disassociate(&rdataset);
   5627 
   5628 success:
   5629 	if (nscount != NULL) {
   5630 		*nscount = count;
   5631 	}
   5632 	if (errors != NULL) {
   5633 		*errors = ecount;
   5634 	}
   5635 
   5636 	result = ISC_R_SUCCESS;
   5637 
   5638 invalidate_rdataset:
   5639 	dns_rdataset_invalidate(&rdataset);
   5640 
   5641 	return (result);
   5642 }
   5643 
   5644 #define SET_IF_NOT_NULL(obj, val) \
   5645 	if (obj != NULL) {        \
   5646 		*obj = val;       \
   5647 	}
   5648 
   5649 #define SET_SOA_VALUES(soattl_v, serial_v, refresh_v, retry_v, expire_v, \
   5650 		       minimum_v)                                        \
   5651 	{                                                                \
   5652 		SET_IF_NOT_NULL(soattl, soattl_v);                       \
   5653 		SET_IF_NOT_NULL(serial, serial_v);                       \
   5654 		SET_IF_NOT_NULL(refresh, refresh_v);                     \
   5655 		SET_IF_NOT_NULL(retry, retry_v);                         \
   5656 		SET_IF_NOT_NULL(expire, expire_v);                       \
   5657 		SET_IF_NOT_NULL(minimum, minimum_v);                     \
   5658 	}
   5659 
   5660 #define CLR_SOA_VALUES()                          \
   5661 	{                                         \
   5662 		SET_SOA_VALUES(0, 0, 0, 0, 0, 0); \
   5663 	}
   5664 
   5665 static isc_result_t
   5666 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   5667 		 unsigned int *soacount, uint32_t *soattl, uint32_t *serial,
   5668 		 uint32_t *refresh, uint32_t *retry, uint32_t *expire,
   5669 		 uint32_t *minimum) {
   5670 	isc_result_t result;
   5671 	unsigned int count = 0;
   5672 	dns_rdataset_t rdataset;
   5673 	dns_rdata_t rdata = DNS_RDATA_INIT;
   5674 
   5675 	dns_rdataset_init(&rdataset);
   5676 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
   5677 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5678 	if (result == ISC_R_NOTFOUND) {
   5679 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5680 		result = ISC_R_SUCCESS;
   5681 		goto invalidate_rdataset;
   5682 	}
   5683 	if (result != ISC_R_SUCCESS) {
   5684 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5685 		goto invalidate_rdataset;
   5686 	}
   5687 
   5688 	result = dns_rdataset_first(&rdataset);
   5689 	while (result == ISC_R_SUCCESS) {
   5690 		dns_rdata_init(&rdata);
   5691 		dns_rdataset_current(&rdataset, &rdata);
   5692 		count++;
   5693 		if (count == 1) {
   5694 			dns_rdata_soa_t soa;
   5695 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   5696 			SET_SOA_VALUES(rdataset.ttl, soa.serial, soa.refresh,
   5697 				       soa.retry, soa.expire, soa.minimum);
   5698 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5699 		}
   5700 
   5701 		result = dns_rdataset_next(&rdataset);
   5702 		dns_rdata_reset(&rdata);
   5703 	}
   5704 	dns_rdataset_disassociate(&rdataset);
   5705 
   5706 	result = ISC_R_SUCCESS;
   5707 
   5708 invalidate_rdataset:
   5709 	SET_IF_NOT_NULL(soacount, count);
   5710 	if (count == 0) {
   5711 		CLR_SOA_VALUES();
   5712 	}
   5713 
   5714 	dns_rdataset_invalidate(&rdataset);
   5715 
   5716 	return (result);
   5717 }
   5718 
   5719 /*
   5720  * zone must be locked.
   5721  */
   5722 static isc_result_t
   5723 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
   5724 		 unsigned int *soacount, uint32_t *soattl, uint32_t *serial,
   5725 		 uint32_t *refresh, uint32_t *retry, uint32_t *expire,
   5726 		 uint32_t *minimum, unsigned int *errors) {
   5727 	isc_result_t result;
   5728 	isc_result_t answer = ISC_R_SUCCESS;
   5729 	dns_dbversion_t *version = NULL;
   5730 	dns_dbnode_t *node;
   5731 
   5732 	REQUIRE(db != NULL);
   5733 	REQUIRE(zone != NULL);
   5734 
   5735 	dns_db_currentversion(db, &version);
   5736 
   5737 	SET_IF_NOT_NULL(nscount, 0);
   5738 	SET_IF_NOT_NULL(soacount, 0);
   5739 	SET_IF_NOT_NULL(errors, 0);
   5740 	CLR_SOA_VALUES();
   5741 
   5742 	node = NULL;
   5743 	result = dns_db_findnode(db, &zone->origin, false, &node);
   5744 	if (result != ISC_R_SUCCESS) {
   5745 		answer = result;
   5746 		goto closeversion;
   5747 	}
   5748 
   5749 	if (nscount != NULL || errors != NULL) {
   5750 		result = zone_count_ns_rr(zone, db, node, version, nscount,
   5751 					  errors, true);
   5752 		if (result != ISC_R_SUCCESS) {
   5753 			answer = result;
   5754 		}
   5755 	}
   5756 
   5757 	if (soacount != NULL || soattl != NULL || serial != NULL ||
   5758 	    refresh != NULL || retry != NULL || expire != NULL ||
   5759 	    minimum != NULL)
   5760 	{
   5761 		result = zone_load_soa_rr(db, node, version, soacount, soattl,
   5762 					  serial, refresh, retry, expire,
   5763 					  minimum);
   5764 		if (result != ISC_R_SUCCESS) {
   5765 			answer = result;
   5766 		}
   5767 	}
   5768 
   5769 	dns_db_detachnode(db, &node);
   5770 closeversion:
   5771 	dns_db_closeversion(db, &version, false);
   5772 
   5773 	return (answer);
   5774 }
   5775 
   5776 void
   5777 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
   5778 	REQUIRE(DNS_ZONE_VALID(source));
   5779 	REQUIRE(target != NULL && *target == NULL);
   5780 	isc_refcount_increment(&source->erefs);
   5781 	*target = source;
   5782 }
   5783 
   5784 void
   5785 dns_zone_detach(dns_zone_t **zonep) {
   5786 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5787 
   5788 	dns_zone_t *zone = *zonep;
   5789 	*zonep = NULL;
   5790 
   5791 	if (isc_refcount_decrement(&zone->erefs) == 1) {
   5792 		isc_event_t *ev = &zone->ctlevent;
   5793 
   5794 		isc_refcount_destroy(&zone->erefs);
   5795 
   5796 		/*
   5797 		 * Stop things being restarted after we cancel them below.
   5798 		 */
   5799 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
   5800 		dns_zone_log(zone, ISC_LOG_DEBUG(1),
   5801 			     "final reference detached");
   5802 		if (zone->task != NULL) {
   5803 			/*
   5804 			 * This zone has a task; it can clean
   5805 			 * itself up asynchronously.
   5806 			 */
   5807 			isc_task_send(zone->task, &ev);
   5808 			return;
   5809 		}
   5810 
   5811 		/*
   5812 		 * This zone is unmanaged; we're probably running in
   5813 		 * named-checkzone or a unit test. There's no task,
   5814 		 * so we need to free it immediately.
   5815 		 *
   5816 		 * Unmanaged zones must not have null views; we have no way
   5817 		 * of detaching from the view here without causing deadlock
   5818 		 * because this code is called with the view already
   5819 		 * locked.
   5820 		 */
   5821 		INSIST(zone->view == NULL);
   5822 
   5823 		zone_shutdown(zone->task, ev);
   5824 		ev = NULL;
   5825 	}
   5826 }
   5827 
   5828 void
   5829 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5830 	REQUIRE(DNS_ZONE_VALID(source));
   5831 
   5832 	LOCK_ZONE(source);
   5833 	zone_iattach(source, target);
   5834 	UNLOCK_ZONE(source);
   5835 }
   5836 
   5837 static void
   5838 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5839 	REQUIRE(DNS_ZONE_VALID(source));
   5840 	REQUIRE(LOCKED_ZONE(source));
   5841 	REQUIRE(target != NULL && *target == NULL);
   5842 	INSIST(isc_refcount_increment0(&source->irefs) +
   5843 		       isc_refcount_current(&source->erefs) >
   5844 	       0);
   5845 	*target = source;
   5846 }
   5847 
   5848 static void
   5849 zone_idetach(dns_zone_t **zonep) {
   5850 	dns_zone_t *zone;
   5851 
   5852 	/*
   5853 	 * 'zone' locked by caller.
   5854 	 */
   5855 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5856 	REQUIRE(LOCKED_ZONE(*zonep));
   5857 
   5858 	zone = *zonep;
   5859 	*zonep = NULL;
   5860 
   5861 	INSIST(isc_refcount_decrement(&zone->irefs) - 1 +
   5862 		       isc_refcount_current(&zone->erefs) >
   5863 	       0);
   5864 }
   5865 
   5866 void
   5867 dns_zone_idetach(dns_zone_t **zonep) {
   5868 	dns_zone_t *zone;
   5869 
   5870 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5871 
   5872 	zone = *zonep;
   5873 	*zonep = NULL;
   5874 
   5875 	if (isc_refcount_decrement(&zone->irefs) == 1) {
   5876 		bool free_needed;
   5877 		LOCK_ZONE(zone);
   5878 		free_needed = exit_check(zone);
   5879 		UNLOCK_ZONE(zone);
   5880 		if (free_needed) {
   5881 			zone_free(zone);
   5882 		}
   5883 	}
   5884 }
   5885 
   5886 isc_mem_t *
   5887 dns_zone_getmctx(dns_zone_t *zone) {
   5888 	REQUIRE(DNS_ZONE_VALID(zone));
   5889 
   5890 	return (zone->mctx);
   5891 }
   5892 
   5893 dns_zonemgr_t *
   5894 dns_zone_getmgr(dns_zone_t *zone) {
   5895 	REQUIRE(DNS_ZONE_VALID(zone));
   5896 
   5897 	return (zone->zmgr);
   5898 }
   5899 
   5900 void
   5901 dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) {
   5902 	REQUIRE(DNS_ZONE_VALID(zone));
   5903 
   5904 	LOCK_ZONE(zone);
   5905 	if (zone->kasp != NULL) {
   5906 		dns_kasp_detach(&zone->kasp);
   5907 	}
   5908 	if (kasp != NULL) {
   5909 		dns_kasp_attach(kasp, &zone->kasp);
   5910 	}
   5911 	UNLOCK_ZONE(zone);
   5912 }
   5913 
   5914 dns_kasp_t *
   5915 dns_zone_getkasp(dns_zone_t *zone) {
   5916 	REQUIRE(DNS_ZONE_VALID(zone));
   5917 
   5918 	return (zone->kasp);
   5919 }
   5920 
   5921 void
   5922 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) {
   5923 	REQUIRE(DNS_ZONE_VALID(zone));
   5924 
   5925 	if (value) {
   5926 		DNS_ZONE_SETOPTION(zone, option);
   5927 	} else {
   5928 		DNS_ZONE_CLROPTION(zone, option);
   5929 	}
   5930 }
   5931 
   5932 dns_zoneopt_t
   5933 dns_zone_getoptions(dns_zone_t *zone) {
   5934 	REQUIRE(DNS_ZONE_VALID(zone));
   5935 
   5936 	return (atomic_load_relaxed(&zone->options));
   5937 }
   5938 
   5939 void
   5940 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) {
   5941 	REQUIRE(DNS_ZONE_VALID(zone));
   5942 
   5943 	if (value) {
   5944 		DNS_ZONEKEY_SETOPTION(zone, keyopt);
   5945 	} else {
   5946 		DNS_ZONEKEY_CLROPTION(zone, keyopt);
   5947 	}
   5948 }
   5949 
   5950 unsigned int
   5951 dns_zone_getkeyopts(dns_zone_t *zone) {
   5952 	REQUIRE(DNS_ZONE_VALID(zone));
   5953 
   5954 	return (atomic_load_relaxed(&zone->keyopts));
   5955 }
   5956 
   5957 isc_result_t
   5958 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5959 	REQUIRE(DNS_ZONE_VALID(zone));
   5960 
   5961 	LOCK_ZONE(zone);
   5962 	zone->xfrsource4 = *xfrsource;
   5963 	UNLOCK_ZONE(zone);
   5964 
   5965 	return (ISC_R_SUCCESS);
   5966 }
   5967 
   5968 isc_sockaddr_t *
   5969 dns_zone_getxfrsource4(dns_zone_t *zone) {
   5970 	REQUIRE(DNS_ZONE_VALID(zone));
   5971 	return (&zone->xfrsource4);
   5972 }
   5973 
   5974 isc_result_t
   5975 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5976 	REQUIRE(DNS_ZONE_VALID(zone));
   5977 
   5978 	LOCK_ZONE(zone);
   5979 	zone->xfrsource6 = *xfrsource;
   5980 	UNLOCK_ZONE(zone);
   5981 
   5982 	return (ISC_R_SUCCESS);
   5983 }
   5984 
   5985 isc_sockaddr_t *
   5986 dns_zone_getxfrsource6(dns_zone_t *zone) {
   5987 	REQUIRE(DNS_ZONE_VALID(zone));
   5988 	return (&zone->xfrsource6);
   5989 }
   5990 
   5991 isc_result_t
   5992 dns_zone_setaltxfrsource4(dns_zone_t *zone,
   5993 			  const isc_sockaddr_t *altxfrsource) {
   5994 	REQUIRE(DNS_ZONE_VALID(zone));
   5995 
   5996 	LOCK_ZONE(zone);
   5997 	zone->altxfrsource4 = *altxfrsource;
   5998 	UNLOCK_ZONE(zone);
   5999 
   6000 	return (ISC_R_SUCCESS);
   6001 }
   6002 
   6003 isc_sockaddr_t *
   6004 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
   6005 	REQUIRE(DNS_ZONE_VALID(zone));
   6006 	return (&zone->altxfrsource4);
   6007 }
   6008 
   6009 isc_result_t
   6010 dns_zone_setaltxfrsource6(dns_zone_t *zone,
   6011 			  const isc_sockaddr_t *altxfrsource) {
   6012 	REQUIRE(DNS_ZONE_VALID(zone));
   6013 
   6014 	LOCK_ZONE(zone);
   6015 	zone->altxfrsource6 = *altxfrsource;
   6016 	UNLOCK_ZONE(zone);
   6017 
   6018 	return (ISC_R_SUCCESS);
   6019 }
   6020 
   6021 isc_sockaddr_t *
   6022 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
   6023 	REQUIRE(DNS_ZONE_VALID(zone));
   6024 	return (&zone->altxfrsource6);
   6025 }
   6026 
   6027 isc_result_t
   6028 dns_zone_setparentalsrc4(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) {
   6029 	REQUIRE(DNS_ZONE_VALID(zone));
   6030 
   6031 	LOCK_ZONE(zone);
   6032 	zone->parentalsrc4 = *parentalsrc;
   6033 	UNLOCK_ZONE(zone);
   6034 
   6035 	return (ISC_R_SUCCESS);
   6036 }
   6037 
   6038 isc_sockaddr_t *
   6039 dns_zone_getparentalsrc4(dns_zone_t *zone) {
   6040 	REQUIRE(DNS_ZONE_VALID(zone));
   6041 	return (&zone->parentalsrc4);
   6042 }
   6043 
   6044 isc_result_t
   6045 dns_zone_setparentalsrc6(dns_zone_t *zone, const isc_sockaddr_t *parentalsrc) {
   6046 	REQUIRE(DNS_ZONE_VALID(zone));
   6047 
   6048 	LOCK_ZONE(zone);
   6049 	zone->parentalsrc6 = *parentalsrc;
   6050 	UNLOCK_ZONE(zone);
   6051 
   6052 	return (ISC_R_SUCCESS);
   6053 }
   6054 
   6055 isc_sockaddr_t *
   6056 dns_zone_getparentalsrc6(dns_zone_t *zone) {
   6057 	REQUIRE(DNS_ZONE_VALID(zone));
   6058 	return (&zone->parentalsrc6);
   6059 }
   6060 
   6061 isc_result_t
   6062 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6063 	REQUIRE(DNS_ZONE_VALID(zone));
   6064 
   6065 	LOCK_ZONE(zone);
   6066 	zone->notifysrc4 = *notifysrc;
   6067 	UNLOCK_ZONE(zone);
   6068 
   6069 	return (ISC_R_SUCCESS);
   6070 }
   6071 
   6072 isc_sockaddr_t *
   6073 dns_zone_getnotifysrc4(dns_zone_t *zone) {
   6074 	REQUIRE(DNS_ZONE_VALID(zone));
   6075 	return (&zone->notifysrc4);
   6076 }
   6077 
   6078 isc_result_t
   6079 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6080 	REQUIRE(DNS_ZONE_VALID(zone));
   6081 
   6082 	LOCK_ZONE(zone);
   6083 	zone->notifysrc6 = *notifysrc;
   6084 	UNLOCK_ZONE(zone);
   6085 
   6086 	return (ISC_R_SUCCESS);
   6087 }
   6088 
   6089 isc_sockaddr_t *
   6090 dns_zone_getnotifysrc6(dns_zone_t *zone) {
   6091 	REQUIRE(DNS_ZONE_VALID(zone));
   6092 	return (&zone->notifysrc6);
   6093 }
   6094 
   6095 static bool
   6096 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
   6097 	   uint32_t count) {
   6098 	unsigned int i;
   6099 
   6100 	for (i = 0; i < count; i++) {
   6101 		if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) {
   6102 			return (false);
   6103 		}
   6104 	}
   6105 	return (true);
   6106 }
   6107 
   6108 static bool
   6109 same_names(dns_name_t *const *oldlist, dns_name_t *const *newlist,
   6110 	   uint32_t count) {
   6111 	unsigned int i;
   6112 
   6113 	if (oldlist == NULL && newlist == NULL) {
   6114 		return (true);
   6115 	}
   6116 	if (oldlist == NULL || newlist == NULL) {
   6117 		return (false);
   6118 	}
   6119 
   6120 	for (i = 0; i < count; i++) {
   6121 		if (oldlist[i] == NULL && newlist[i] == NULL) {
   6122 			continue;
   6123 		}
   6124 		if (oldlist[i] == NULL || newlist[i] == NULL ||
   6125 		    !dns_name_equal(oldlist[i], newlist[i]))
   6126 		{
   6127 			return (false);
   6128 		}
   6129 	}
   6130 	return (true);
   6131 }
   6132 
   6133 static void
   6134 clear_serverslist(isc_sockaddr_t **addrsp, dns_name_t ***keynamesp,
   6135 		  dns_name_t ***tlsnamesp, unsigned int *countp,
   6136 		  isc_mem_t *mctx) {
   6137 	unsigned int count;
   6138 	isc_sockaddr_t *addrs;
   6139 	dns_name_t **keynames;
   6140 	dns_name_t **tlsnames;
   6141 
   6142 	REQUIRE(countp != NULL);
   6143 	REQUIRE(addrsp != NULL);
   6144 	REQUIRE(keynamesp != NULL);
   6145 	REQUIRE(tlsnamesp != NULL);
   6146 
   6147 	count = *countp;
   6148 	*countp = 0;
   6149 	addrs = *addrsp;
   6150 	*addrsp = NULL;
   6151 	keynames = *keynamesp;
   6152 	*keynamesp = NULL;
   6153 	tlsnames = *tlsnamesp;
   6154 	*tlsnamesp = NULL;
   6155 
   6156 	if (addrs != NULL) {
   6157 		isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
   6158 	}
   6159 
   6160 	if (keynames != NULL) {
   6161 		unsigned int i;
   6162 		for (i = 0; i < count; i++) {
   6163 			if (keynames[i] != NULL) {
   6164 				dns_name_free(keynames[i], mctx);
   6165 				isc_mem_put(mctx, keynames[i],
   6166 					    sizeof(dns_name_t));
   6167 				keynames[i] = NULL;
   6168 			}
   6169 		}
   6170 		isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
   6171 	}
   6172 
   6173 	if (tlsnames != NULL) {
   6174 		unsigned int i;
   6175 		for (i = 0; i < count; i++) {
   6176 			if (tlsnames[i] != NULL) {
   6177 				dns_name_free(tlsnames[i], mctx);
   6178 				isc_mem_put(mctx, tlsnames[i],
   6179 					    sizeof(dns_name_t));
   6180 				tlsnames[i] = NULL;
   6181 			}
   6182 		}
   6183 		isc_mem_put(mctx, tlsnames, count * sizeof(dns_name_t *));
   6184 	}
   6185 }
   6186 
   6187 static void
   6188 set_serverslist(unsigned int count, const isc_sockaddr_t *addrs,
   6189 		isc_sockaddr_t **newaddrsp, dns_name_t **keynames,
   6190 		dns_name_t ***newkeynamesp, dns_name_t **tlsnames,
   6191 		dns_name_t ***newtlsnamesp, isc_mem_t *mctx) {
   6192 	isc_sockaddr_t *newaddrs = NULL;
   6193 	dns_name_t **newkeynames = NULL;
   6194 	dns_name_t **newtlsnames = NULL;
   6195 	unsigned int i;
   6196 
   6197 	REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
   6198 	REQUIRE(newkeynamesp != NULL && *newkeynamesp == NULL);
   6199 	REQUIRE(newtlsnamesp != NULL && *newtlsnamesp == NULL);
   6200 
   6201 	newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
   6202 	memmove(newaddrs, addrs, count * sizeof(*newaddrs));
   6203 
   6204 	if (keynames != NULL) {
   6205 		newkeynames = isc_mem_get(mctx, count * sizeof(*newkeynames));
   6206 		for (i = 0; i < count; i++) {
   6207 			newkeynames[i] = NULL;
   6208 		}
   6209 		for (i = 0; i < count; i++) {
   6210 			if (keynames[i] != NULL) {
   6211 				newkeynames[i] =
   6212 					isc_mem_get(mctx, sizeof(dns_name_t));
   6213 				dns_name_init(newkeynames[i], NULL);
   6214 				dns_name_dup(keynames[i], mctx, newkeynames[i]);
   6215 			}
   6216 		}
   6217 	}
   6218 
   6219 	if (tlsnames != NULL) {
   6220 		newtlsnames = isc_mem_get(mctx, count * sizeof(*newtlsnames));
   6221 		for (i = 0; i < count; i++) {
   6222 			newtlsnames[i] = NULL;
   6223 		}
   6224 		for (i = 0; i < count; i++) {
   6225 			if (tlsnames[i] != NULL) {
   6226 				newtlsnames[i] =
   6227 					isc_mem_get(mctx, sizeof(dns_name_t));
   6228 				dns_name_init(newtlsnames[i], NULL);
   6229 				dns_name_dup(tlsnames[i], mctx, newtlsnames[i]);
   6230 			}
   6231 		}
   6232 	}
   6233 
   6234 	*newaddrsp = newaddrs;
   6235 	*newkeynamesp = newkeynames;
   6236 	*newtlsnamesp = newtlsnames;
   6237 }
   6238 
   6239 void
   6240 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6241 		       dns_name_t **keynames, dns_name_t **tlsnames,
   6242 		       uint32_t count) {
   6243 	isc_sockaddr_t *newaddrs = NULL;
   6244 	dns_name_t **newkeynames = NULL;
   6245 	dns_name_t **newtlsnames = NULL;
   6246 
   6247 	REQUIRE(DNS_ZONE_VALID(zone));
   6248 	REQUIRE(count == 0 || notify != NULL);
   6249 	if (keynames != NULL) {
   6250 		REQUIRE(count != 0);
   6251 	}
   6252 
   6253 	LOCK_ZONE(zone);
   6254 
   6255 	if (count == zone->notifycnt &&
   6256 	    same_addrs(zone->notify, notify, count) &&
   6257 	    same_names(zone->notifykeynames, keynames, count) &&
   6258 	    same_names(zone->notifytlsnames, tlsnames, count))
   6259 	{
   6260 		goto unlock;
   6261 	}
   6262 
   6263 	clear_serverslist(&zone->notify, &zone->notifykeynames,
   6264 			  &zone->notifytlsnames, &zone->notifycnt, zone->mctx);
   6265 
   6266 	if (count == 0) {
   6267 		goto unlock;
   6268 	}
   6269 
   6270 	/*
   6271 	 * Set up the notify and notifykey lists
   6272 	 */
   6273 	set_serverslist(count, notify, &newaddrs, keynames, &newkeynames,
   6274 			tlsnames, &newtlsnames, zone->mctx);
   6275 
   6276 	/*
   6277 	 * Everything is ok so attach to the zone.
   6278 	 */
   6279 	zone->notify = newaddrs;
   6280 	zone->notifykeynames = newkeynames;
   6281 	zone->notifytlsnames = newtlsnames;
   6282 	zone->notifycnt = count;
   6283 unlock:
   6284 	UNLOCK_ZONE(zone);
   6285 }
   6286 
   6287 void
   6288 dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *primaries,
   6289 		      dns_name_t **keynames, dns_name_t **tlsnames,
   6290 		      uint32_t count) {
   6291 	isc_sockaddr_t *newaddrs = NULL;
   6292 	dns_name_t **newkeynames = NULL;
   6293 	dns_name_t **newtlsnames = NULL;
   6294 	bool *newok;
   6295 	unsigned int i;
   6296 
   6297 	REQUIRE(DNS_ZONE_VALID(zone));
   6298 	REQUIRE(count == 0 || primaries != NULL);
   6299 	if (keynames != NULL || tlsnames != NULL) {
   6300 		REQUIRE(count != 0);
   6301 	}
   6302 
   6303 	LOCK_ZONE(zone);
   6304 	/*
   6305 	 * The refresh code assumes that 'primaries' wouldn't change under it.
   6306 	 * If it will change then kill off any current refresh in progress
   6307 	 * and update the primaries info.  If it won't change then we can just
   6308 	 * unlock and exit.
   6309 	 */
   6310 	if (count != zone->primariescnt ||
   6311 	    !same_addrs(zone->primaries, primaries, count) ||
   6312 	    !same_names(zone->primarykeynames, keynames, count) ||
   6313 	    !same_names(zone->primarytlsnames, tlsnames, count))
   6314 	{
   6315 		if (zone->request != NULL) {
   6316 			dns_request_cancel(zone->request);
   6317 		}
   6318 	} else {
   6319 		goto unlock;
   6320 	}
   6321 
   6322 	/*
   6323 	 * This needs to happen before clear_addresskeylist() sets
   6324 	 * zone->primariescnt to 0:
   6325 	 */
   6326 	if (zone->primariesok != NULL) {
   6327 		isc_mem_put(zone->mctx, zone->primariesok,
   6328 			    zone->primariescnt * sizeof(bool));
   6329 		zone->primariesok = NULL;
   6330 	}
   6331 	clear_serverslist(&zone->primaries, &zone->primarykeynames,
   6332 			  &zone->primarytlsnames, &zone->primariescnt,
   6333 			  zone->mctx);
   6334 	/*
   6335 	 * If count == 0, don't allocate any space for primaries, primariesok or
   6336 	 * keynames so internally, those pointers are NULL if count == 0
   6337 	 */
   6338 	if (count == 0) {
   6339 		goto unlock;
   6340 	}
   6341 
   6342 	/*
   6343 	 * primariesok must contain count elements
   6344 	 */
   6345 	newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
   6346 	for (i = 0; i < count; i++) {
   6347 		newok[i] = false;
   6348 	}
   6349 
   6350 	/*
   6351 	 * Now set up the primaries and primary key lists
   6352 	 */
   6353 	set_serverslist(count, primaries, &newaddrs, keynames, &newkeynames,
   6354 			tlsnames, &newtlsnames, zone->mctx);
   6355 
   6356 	/*
   6357 	 * Everything is ok so attach to the zone.
   6358 	 */
   6359 	zone->curprimary = 0;
   6360 	zone->primariesok = newok;
   6361 	zone->primaries = newaddrs;
   6362 	zone->primarykeynames = newkeynames;
   6363 	zone->primarytlsnames = newtlsnames;
   6364 	zone->primariescnt = count;
   6365 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOPRIMARIES);
   6366 
   6367 unlock:
   6368 	UNLOCK_ZONE(zone);
   6369 }
   6370 
   6371 void
   6372 dns_zone_setparentals(dns_zone_t *zone, const isc_sockaddr_t *parentals,
   6373 		      dns_name_t **keynames, dns_name_t **tlsnames,
   6374 		      uint32_t count) {
   6375 	isc_sockaddr_t *newaddrs = NULL;
   6376 	dns_name_t **newkeynames = NULL;
   6377 	dns_name_t **newtlsnames = NULL;
   6378 
   6379 	REQUIRE(DNS_ZONE_VALID(zone));
   6380 	REQUIRE(count == 0 || parentals != NULL);
   6381 	if (keynames != NULL || tlsnames != NULL) {
   6382 		REQUIRE(count != 0);
   6383 	}
   6384 
   6385 	LOCK_ZONE(zone);
   6386 
   6387 	clear_serverslist(&zone->parentals, &zone->parentalkeynames,
   6388 			  &zone->parentaltlsnames, &zone->parentalscnt,
   6389 			  zone->mctx);
   6390 	/*
   6391 	 * If count == 0, don't allocate any space for parentals, or keynames
   6392 	 * so internally, those pointers are NULL if count == 0
   6393 	 */
   6394 	if (count == 0) {
   6395 		goto unlock;
   6396 	}
   6397 
   6398 	/*
   6399 	 * Now set up the parentals and parental key lists
   6400 	 */
   6401 	set_serverslist(count, parentals, &newaddrs, keynames, &newkeynames,
   6402 			tlsnames, &newtlsnames, zone->mctx);
   6403 
   6404 	/*
   6405 	 * Everything is ok so attach to the zone.
   6406 	 */
   6407 	zone->parentals = newaddrs;
   6408 	zone->parentalkeynames = newkeynames;
   6409 	zone->parentaltlsnames = newtlsnames;
   6410 	zone->parentalscnt = count;
   6411 
   6412 	dns_zone_log(zone, ISC_LOG_NOTICE, "checkds: set %u parentals", count);
   6413 
   6414 unlock:
   6415 	UNLOCK_ZONE(zone);
   6416 }
   6417 
   6418 isc_result_t
   6419 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
   6420 	isc_result_t result = ISC_R_SUCCESS;
   6421 
   6422 	REQUIRE(DNS_ZONE_VALID(zone));
   6423 
   6424 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   6425 	if (zone->db == NULL) {
   6426 		result = DNS_R_NOTLOADED;
   6427 	} else {
   6428 		dns_db_attach(zone->db, dpb);
   6429 	}
   6430 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   6431 
   6432 	return (result);
   6433 }
   6434 
   6435 void
   6436 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
   6437 	REQUIRE(DNS_ZONE_VALID(zone));
   6438 	REQUIRE(zone->type == dns_zone_staticstub);
   6439 
   6440 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   6441 	REQUIRE(zone->db == NULL);
   6442 	dns_db_attach(db, &zone->db);
   6443 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   6444 }
   6445 
   6446 /*
   6447  * Coordinates the starting of routine jobs.
   6448  */
   6449 void
   6450 dns_zone_maintenance(dns_zone_t *zone) {
   6451 	const char me[] = "dns_zone_maintenance";
   6452 	isc_time_t now;
   6453 
   6454 	REQUIRE(DNS_ZONE_VALID(zone));
   6455 	ENTER;
   6456 
   6457 	LOCK_ZONE(zone);
   6458 	TIME_NOW(&now);
   6459 	zone_settimer(zone, &now);
   6460 	UNLOCK_ZONE(zone);
   6461 }
   6462 
   6463 static bool
   6464 was_dumping(dns_zone_t *zone) {
   6465 	REQUIRE(LOCKED_ZONE(zone));
   6466 
   6467 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   6468 		return (true);
   6469 	}
   6470 
   6471 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   6472 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   6473 	isc_time_settoepoch(&zone->dumptime);
   6474 	return (false);
   6475 }
   6476 
   6477 /*%
   6478  * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database
   6479  * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'.
   6480  * Only load the public part of a given key if it is not active at timestamp
   6481  * 'now'.  Store the number of keys found in 'nkeys'.
   6482  */
   6483 isc_result_t
   6484 dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   6485 		   isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys,
   6486 		   dst_key_t **keys, unsigned int *nkeys) {
   6487 	isc_result_t result;
   6488 	dns_dbnode_t *node = NULL;
   6489 	const char *directory = dns_zone_getkeydirectory(zone);
   6490 
   6491 	CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
   6492 	memset(keys, 0, sizeof(*keys) * maxkeys);
   6493 
   6494 	dns_zone_lock_keyfiles(zone);
   6495 
   6496 	result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
   6497 					 directory, now, mctx, maxkeys, keys,
   6498 					 nkeys);
   6499 
   6500 	dns_zone_unlock_keyfiles(zone);
   6501 
   6502 	if (result == ISC_R_NOTFOUND) {
   6503 		result = ISC_R_SUCCESS;
   6504 	}
   6505 
   6506 failure:
   6507 
   6508 	if (node != NULL) {
   6509 		dns_db_detachnode(db, &node);
   6510 	}
   6511 	return (result);
   6512 }
   6513 
   6514 /*%
   6515  * Find DNSSEC keys used for signing zone with dnssec-policy. Load these keys
   6516  * into 'keys'. Requires KASP to be locked.
   6517  */
   6518 isc_result_t
   6519 dns_zone_getdnsseckeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   6520 		       isc_stdtime_t now, dns_dnsseckeylist_t *keys) {
   6521 	isc_result_t result;
   6522 	const char *dir = dns_zone_getkeydirectory(zone);
   6523 	dns_dbnode_t *node = NULL;
   6524 	dns_dnsseckey_t *key, *key_next;
   6525 	dns_dnsseckeylist_t dnskeys;
   6526 	dns_name_t *origin = dns_zone_getorigin(zone);
   6527 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   6528 	dns_rdataset_t keyset;
   6529 
   6530 	REQUIRE(DNS_ZONE_VALID(zone));
   6531 	REQUIRE(kasp != NULL);
   6532 
   6533 	ISC_LIST_INIT(dnskeys);
   6534 
   6535 	dns_rdataset_init(&keyset);
   6536 
   6537 	CHECK(dns_db_findnode(db, origin, false, &node));
   6538 
   6539 	/* Get keys from private key files. */
   6540 	dns_zone_lock_keyfiles(zone);
   6541 	result = dns_dnssec_findmatchingkeys(origin, dir, now,
   6542 					     dns_zone_getmctx(zone), keys);
   6543 	dns_zone_unlock_keyfiles(zone);
   6544 
   6545 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   6546 		goto failure;
   6547 	}
   6548 
   6549 	/* Get public keys (dnskeys). */
   6550 	dns_rdataset_init(&keyset);
   6551 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   6552 				     dns_rdatatype_none, 0, &keyset, NULL);
   6553 	if (result == ISC_R_SUCCESS) {
   6554 		CHECK(dns_dnssec_keylistfromrdataset(
   6555 			origin, dir, dns_zone_getmctx(zone), &keyset, NULL,
   6556 			NULL, false, false, &dnskeys));
   6557 	} else if (result != ISC_R_NOTFOUND) {
   6558 		CHECK(result);
   6559 	}
   6560 
   6561 	/* Add new 'dnskeys' to 'keys'. */
   6562 	for (dns_dnsseckey_t *k1 = ISC_LIST_HEAD(dnskeys); k1 != NULL;
   6563 	     k1 = key_next)
   6564 	{
   6565 		dns_dnsseckey_t *k2 = NULL;
   6566 		key_next = ISC_LIST_NEXT(k1, link);
   6567 
   6568 		for (k2 = ISC_LIST_HEAD(*keys); k2 != NULL;
   6569 		     k2 = ISC_LIST_NEXT(k2, link))
   6570 		{
   6571 			if (dst_key_compare(k1->key, k2->key)) {
   6572 				break;
   6573 			}
   6574 		}
   6575 		/* No match found, add the new key. */
   6576 		if (k2 == NULL) {
   6577 			ISC_LIST_UNLINK(dnskeys, k1, link);
   6578 			ISC_LIST_APPEND(*keys, k1, link);
   6579 		}
   6580 	}
   6581 
   6582 failure:
   6583 	if (dns_rdataset_isassociated(&keyset)) {
   6584 		dns_rdataset_disassociate(&keyset);
   6585 	}
   6586 	if (node != NULL) {
   6587 		dns_db_detachnode(db, &node);
   6588 	}
   6589 	while (!ISC_LIST_EMPTY(dnskeys)) {
   6590 		key = ISC_LIST_HEAD(dnskeys);
   6591 		ISC_LIST_UNLINK(dnskeys, key, link);
   6592 		dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key);
   6593 	}
   6594 	return (result);
   6595 }
   6596 
   6597 static isc_result_t
   6598 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff,
   6599 	dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) {
   6600 	isc_result_t result;
   6601 
   6602 	if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) {
   6603 		return (ISC_R_SUCCESS);
   6604 	}
   6605 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
   6606 			       name, ttl, rdata);
   6607 	if (result != ISC_R_SUCCESS) {
   6608 		return (result);
   6609 	}
   6610 	rdata->flags |= DNS_RDATA_OFFLINE;
   6611 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
   6612 			       name, ttl, rdata);
   6613 	zonediff->offline = true;
   6614 	return (result);
   6615 }
   6616 
   6617 static void
   6618 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when,
   6619 		       isc_stdtime_t now) {
   6620 	unsigned int delta;
   6621 	char timebuf[80];
   6622 
   6623 	LOCK_ZONE(zone);
   6624 	zone->key_expiry = when;
   6625 	if (when <= now) {
   6626 		dns_zone_log(zone, ISC_LOG_ERROR,
   6627 			     "DNSKEY RRSIG(s) have expired");
   6628 		isc_time_settoepoch(&zone->keywarntime);
   6629 	} else if (when < now + 7 * 24 * 3600) {
   6630 		isc_time_t t;
   6631 		isc_time_set(&t, when, 0);
   6632 		isc_time_formattimestamp(&t, timebuf, 80);
   6633 		dns_zone_log(zone, ISC_LOG_WARNING,
   6634 			     "DNSKEY RRSIG(s) will expire within 7 days: %s",
   6635 			     timebuf);
   6636 		delta = when - now;
   6637 		delta--;	    /* loop prevention */
   6638 		delta /= 24 * 3600; /* to whole days */
   6639 		delta *= 24 * 3600; /* to seconds */
   6640 		isc_time_set(&zone->keywarntime, when - delta, 0);
   6641 	} else {
   6642 		isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
   6643 		isc_time_formattimestamp(&zone->keywarntime, timebuf, 80);
   6644 		dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s",
   6645 			     timebuf);
   6646 	}
   6647 	UNLOCK_ZONE(zone);
   6648 }
   6649 
   6650 /*
   6651  * Helper function to del_sigs(). We don't want to delete RRSIGs that
   6652  * have no new key.
   6653  */
   6654 static bool
   6655 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
   6656 	  bool kasp, bool *warn) {
   6657 	unsigned int i = 0;
   6658 	isc_result_t ret;
   6659 	bool have_ksk = false, have_zsk = false;
   6660 	bool have_pksk = false, have_pzsk = false;
   6661 
   6662 	for (i = 0; i < nkeys; i++) {
   6663 		bool ksk, zsk;
   6664 
   6665 		if (have_pksk && have_ksk && have_pzsk && have_zsk) {
   6666 			break;
   6667 		}
   6668 
   6669 		if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) {
   6670 			continue;
   6671 		}
   6672 
   6673 		ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   6674 		if (ret != ISC_R_SUCCESS) {
   6675 			ksk = KSK(keys[i]);
   6676 		}
   6677 		ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   6678 		if (ret != ISC_R_SUCCESS) {
   6679 			zsk = !KSK(keys[i]);
   6680 		}
   6681 
   6682 		if (ksk) {
   6683 			have_ksk = true;
   6684 			if (dst_key_isprivate(keys[i])) {
   6685 				have_pksk = true;
   6686 			}
   6687 		}
   6688 		if (zsk) {
   6689 			have_zsk = true;
   6690 			if (dst_key_isprivate(keys[i])) {
   6691 				have_pzsk = true;
   6692 			}
   6693 		}
   6694 	}
   6695 
   6696 	if (have_zsk && have_ksk && !have_pzsk) {
   6697 		*warn = true;
   6698 	}
   6699 
   6700 	if (have_pksk && have_pzsk) {
   6701 		return (true);
   6702 	}
   6703 
   6704 	/*
   6705 	 * Deleting the SOA RRSIG is always okay.
   6706 	 */
   6707 	if (rrsig_ptr->covered == dns_rdatatype_soa) {
   6708 		return (true);
   6709 	}
   6710 
   6711 	/*
   6712 	 * It's okay to delete a signature if there is an active key with the
   6713 	 * same algorithm to replace it, unless that violates the DNSSEC
   6714 	 * policy.
   6715 	 */
   6716 	if (have_pksk || have_pzsk) {
   6717 		if (kasp && have_pzsk) {
   6718 			return (true);
   6719 		}
   6720 		return (!kasp);
   6721 	}
   6722 
   6723 	/*
   6724 	 * Failing that, it is *not* okay to delete a signature
   6725 	 * if the associated public key is still in the DNSKEY RRset
   6726 	 */
   6727 	for (i = 0; i < nkeys; i++) {
   6728 		if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
   6729 		    (rrsig_ptr->keyid == dst_key_id(keys[i])))
   6730 		{
   6731 			return (false);
   6732 		}
   6733 	}
   6734 
   6735 	/*
   6736 	 * But if the key is gone, then go ahead.
   6737 	 */
   6738 	return (true);
   6739 }
   6740 
   6741 /*
   6742  * Delete expired RRsigs and any RRsigs we are about to re-sign.
   6743  * See also update.c:del_keysigs().
   6744  */
   6745 static isc_result_t
   6746 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   6747 	 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys,
   6748 	 unsigned int nkeys, isc_stdtime_t now, bool incremental) {
   6749 	isc_result_t result;
   6750 	dns_dbnode_t *node = NULL;
   6751 	dns_rdataset_t rdataset;
   6752 	unsigned int i;
   6753 	dns_rdata_rrsig_t rrsig;
   6754 	bool kasp = (dns_zone_getkasp(zone) != NULL);
   6755 	bool found;
   6756 	int64_t timewarn = 0, timemaybe = 0;
   6757 
   6758 	dns_rdataset_init(&rdataset);
   6759 
   6760 	if (type == dns_rdatatype_nsec3) {
   6761 		result = dns_db_findnsec3node(db, name, false, &node);
   6762 	} else {
   6763 		result = dns_db_findnode(db, name, false, &node);
   6764 	}
   6765 	if (result == ISC_R_NOTFOUND) {
   6766 		return (ISC_R_SUCCESS);
   6767 	}
   6768 	if (result != ISC_R_SUCCESS) {
   6769 		goto failure;
   6770 	}
   6771 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
   6772 				     (isc_stdtime_t)0, &rdataset, NULL);
   6773 	dns_db_detachnode(db, &node);
   6774 
   6775 	if (result == ISC_R_NOTFOUND) {
   6776 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6777 		return (ISC_R_SUCCESS);
   6778 	}
   6779 	if (result != ISC_R_SUCCESS) {
   6780 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6781 		goto failure;
   6782 	}
   6783 
   6784 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   6785 	     result = dns_rdataset_next(&rdataset))
   6786 	{
   6787 		dns_rdata_t rdata = DNS_RDATA_INIT;
   6788 
   6789 		dns_rdataset_current(&rdataset, &rdata);
   6790 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   6791 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6792 
   6793 		if (type != dns_rdatatype_dnskey && type != dns_rdatatype_cds &&
   6794 		    type != dns_rdatatype_cdnskey)
   6795 		{
   6796 			bool warn = false, deleted = false;
   6797 			if (delsig_ok(&rrsig, keys, nkeys, kasp, &warn)) {
   6798 				result = update_one_rr(db, ver, zonediff->diff,
   6799 						       DNS_DIFFOP_DELRESIGN,
   6800 						       name, rdataset.ttl,
   6801 						       &rdata);
   6802 				if (result != ISC_R_SUCCESS) {
   6803 					break;
   6804 				}
   6805 				deleted = true;
   6806 			}
   6807 			if (warn && !deleted) {
   6808 				/*
   6809 				 * At this point, we've got an RRSIG,
   6810 				 * which is signed by an inactive key.
   6811 				 * An administrator needs to provide a new
   6812 				 * key/alg, but until that time, we want to
   6813 				 * keep the old RRSIG.  Marking the key as
   6814 				 * offline will prevent us spinning waiting
   6815 				 * for the private part.
   6816 				 */
   6817 				if (incremental) {
   6818 					result = offline(db, ver, zonediff,
   6819 							 name, rdataset.ttl,
   6820 							 &rdata);
   6821 					if (result != ISC_R_SUCCESS) {
   6822 						break;
   6823 					}
   6824 				}
   6825 
   6826 				/*
   6827 				 * Log the key id and algorithm of
   6828 				 * the inactive key with no replacement
   6829 				 */
   6830 				if (zone->log_key_expired_timer <= now) {
   6831 					char origin[DNS_NAME_FORMATSIZE];
   6832 					char algbuf[DNS_NAME_FORMATSIZE];
   6833 					dns_name_format(&zone->origin, origin,
   6834 							sizeof(origin));
   6835 					dns_secalg_format(rrsig.algorithm,
   6836 							  algbuf,
   6837 							  sizeof(algbuf));
   6838 					dns_zone_log(zone, ISC_LOG_WARNING,
   6839 						     "Key %s/%s/%d "
   6840 						     "missing or inactive "
   6841 						     "and has no replacement: "
   6842 						     "retaining signatures.",
   6843 						     origin, algbuf,
   6844 						     rrsig.keyid);
   6845 					zone->log_key_expired_timer = now +
   6846 								      3600;
   6847 				}
   6848 			}
   6849 			continue;
   6850 		}
   6851 
   6852 		/*
   6853 		 * KSK RRSIGs requires special processing.
   6854 		 */
   6855 		found = false;
   6856 		for (i = 0; i < nkeys; i++) {
   6857 			if (rrsig.algorithm == dst_key_alg(keys[i]) &&
   6858 			    rrsig.keyid == dst_key_id(keys[i]))
   6859 			{
   6860 				found = true;
   6861 				/*
   6862 				 * Mark offline DNSKEY.
   6863 				 * We want the earliest offline expire time
   6864 				 * iff there is a new offline signature.
   6865 				 */
   6866 				if (!dst_key_inactive(keys[i]) &&
   6867 				    !dst_key_isprivate(keys[i]))
   6868 				{
   6869 					int64_t timeexpire = dns_time64_from32(
   6870 						rrsig.timeexpire);
   6871 					if (timewarn != 0 &&
   6872 					    timewarn > timeexpire)
   6873 					{
   6874 						timewarn = timeexpire;
   6875 					}
   6876 					if (rdata.flags & DNS_RDATA_OFFLINE) {
   6877 						if (timemaybe == 0 ||
   6878 						    timemaybe > timeexpire)
   6879 						{
   6880 							timemaybe = timeexpire;
   6881 						}
   6882 						break;
   6883 					}
   6884 					if (timewarn == 0) {
   6885 						timewarn = timemaybe;
   6886 					}
   6887 					if (timewarn == 0 ||
   6888 					    timewarn > timeexpire)
   6889 					{
   6890 						timewarn = timeexpire;
   6891 					}
   6892 					result = offline(db, ver, zonediff,
   6893 							 name, rdataset.ttl,
   6894 							 &rdata);
   6895 					break;
   6896 				}
   6897 				result = update_one_rr(db, ver, zonediff->diff,
   6898 						       DNS_DIFFOP_DELRESIGN,
   6899 						       name, rdataset.ttl,
   6900 						       &rdata);
   6901 				break;
   6902 			}
   6903 		}
   6904 
   6905 		/*
   6906 		 * If there is not a matching DNSKEY then
   6907 		 * delete the RRSIG.
   6908 		 */
   6909 		if (!found) {
   6910 			result = update_one_rr(db, ver, zonediff->diff,
   6911 					       DNS_DIFFOP_DELRESIGN, name,
   6912 					       rdataset.ttl, &rdata);
   6913 		}
   6914 		if (result != ISC_R_SUCCESS) {
   6915 			break;
   6916 		}
   6917 	}
   6918 
   6919 	dns_rdataset_disassociate(&rdataset);
   6920 	if (result == ISC_R_NOMORE) {
   6921 		result = ISC_R_SUCCESS;
   6922 	}
   6923 	if (timewarn > 0) {
   6924 		isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
   6925 		if (timewarn == stdwarn) {
   6926 			set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
   6927 					       now);
   6928 		} else {
   6929 			dns_zone_log(zone, ISC_LOG_ERROR,
   6930 				     "key expiry warning time out of range");
   6931 		}
   6932 	}
   6933 failure:
   6934 	if (node != NULL) {
   6935 		dns_db_detachnode(db, &node);
   6936 	}
   6937 	return (result);
   6938 }
   6939 
   6940 static isc_result_t
   6941 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone,
   6942 	 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
   6943 	 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t now,
   6944 	 isc_stdtime_t inception, isc_stdtime_t expire, bool check_ksk,
   6945 	 bool keyset_kskonly) {
   6946 	isc_result_t result;
   6947 	dns_dbnode_t *node = NULL;
   6948 	dns_stats_t *dnssecsignstats;
   6949 	dns_rdataset_t rdataset;
   6950 	dns_rdata_t sig_rdata = DNS_RDATA_INIT;
   6951 	unsigned char data[1024]; /* XXX */
   6952 	isc_buffer_t buffer;
   6953 	unsigned int i, j;
   6954 	bool use_kasp = false;
   6955 
   6956 	if (dns_zone_getkasp(zone) != NULL) {
   6957 		check_ksk = false;
   6958 		keyset_kskonly = true;
   6959 		use_kasp = true;
   6960 	}
   6961 
   6962 	dns_rdataset_init(&rdataset);
   6963 	isc_buffer_init(&buffer, data, sizeof(data));
   6964 
   6965 	if (type == dns_rdatatype_nsec3) {
   6966 		result = dns_db_findnsec3node(db, name, false, &node);
   6967 	} else {
   6968 		result = dns_db_findnode(db, name, false, &node);
   6969 	}
   6970 	if (result == ISC_R_NOTFOUND) {
   6971 		return (ISC_R_SUCCESS);
   6972 	}
   6973 	if (result != ISC_R_SUCCESS) {
   6974 		goto failure;
   6975 	}
   6976 	result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0,
   6977 				     &rdataset, NULL);
   6978 	dns_db_detachnode(db, &node);
   6979 	if (result == ISC_R_NOTFOUND) {
   6980 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6981 		return (ISC_R_SUCCESS);
   6982 	}
   6983 	if (result != ISC_R_SUCCESS) {
   6984 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6985 		goto failure;
   6986 	}
   6987 
   6988 	for (i = 0; i < nkeys; i++) {
   6989 		bool both = false;
   6990 
   6991 		/* Don't add signatures for offline or inactive keys */
   6992 		if (!dst_key_isprivate(keys[i])) {
   6993 			continue;
   6994 		}
   6995 		if (dst_key_inactive(keys[i])) {
   6996 			continue;
   6997 		}
   6998 
   6999 		if (check_ksk && !REVOKE(keys[i])) {
   7000 			bool have_ksk, have_nonksk;
   7001 			if (KSK(keys[i])) {
   7002 				have_ksk = true;
   7003 				have_nonksk = false;
   7004 			} else {
   7005 				have_ksk = false;
   7006 				have_nonksk = true;
   7007 			}
   7008 
   7009 			for (j = 0; j < nkeys; j++) {
   7010 				if (j == i || ALG(keys[i]) != ALG(keys[j])) {
   7011 					continue;
   7012 				}
   7013 
   7014 				/*
   7015 				 * Don't consider inactive keys, however
   7016 				 * the KSK may be temporary offline, so do
   7017 				 * consider keys which private key files are
   7018 				 * unavailable.
   7019 				 */
   7020 				if (dst_key_inactive(keys[j])) {
   7021 					continue;
   7022 				}
   7023 
   7024 				if (REVOKE(keys[j])) {
   7025 					continue;
   7026 				}
   7027 				if (KSK(keys[j])) {
   7028 					have_ksk = true;
   7029 				} else if (dst_key_isprivate(keys[j])) {
   7030 					have_nonksk = true;
   7031 				}
   7032 				both = have_ksk && have_nonksk;
   7033 				if (both) {
   7034 					break;
   7035 				}
   7036 			}
   7037 		}
   7038 		if (use_kasp) {
   7039 			/*
   7040 			 * A dnssec-policy is found. Check what RRsets this
   7041 			 * key should sign.
   7042 			 */
   7043 			isc_result_t kresult;
   7044 			isc_stdtime_t when;
   7045 			bool ksk = false;
   7046 			bool zsk = false;
   7047 			bool have_ksk = false;
   7048 			bool have_zsk = false;
   7049 
   7050 			kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   7051 			if (kresult != ISC_R_SUCCESS) {
   7052 				if (KSK(keys[i])) {
   7053 					ksk = true;
   7054 				}
   7055 			}
   7056 			kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   7057 			if (kresult != ISC_R_SUCCESS) {
   7058 				if (!KSK(keys[i])) {
   7059 					zsk = true;
   7060 				}
   7061 			}
   7062 
   7063 			have_ksk = ksk;
   7064 			have_zsk = zsk;
   7065 			both = have_ksk && have_zsk;
   7066 
   7067 			for (j = 0; j < nkeys; j++) {
   7068 				if (both) {
   7069 					break;
   7070 				}
   7071 
   7072 				if (j == i || ALG(keys[i]) != ALG(keys[j])) {
   7073 					continue;
   7074 				}
   7075 
   7076 				/*
   7077 				 * Don't consider inactive keys or offline keys.
   7078 				 */
   7079 				if (!dst_key_isprivate(keys[j])) {
   7080 					continue;
   7081 				}
   7082 				if (dst_key_inactive(keys[j])) {
   7083 					continue;
   7084 				}
   7085 
   7086 				if (REVOKE(keys[j])) {
   7087 					continue;
   7088 				}
   7089 
   7090 				if (!have_ksk) {
   7091 					kresult = dst_key_getbool(keys[j],
   7092 								  DST_BOOL_KSK,
   7093 								  &have_ksk);
   7094 					if (kresult != ISC_R_SUCCESS) {
   7095 						if (KSK(keys[j])) {
   7096 							have_ksk = true;
   7097 						}
   7098 					}
   7099 				}
   7100 				if (!have_zsk) {
   7101 					kresult = dst_key_getbool(keys[j],
   7102 								  DST_BOOL_ZSK,
   7103 								  &have_zsk);
   7104 					if (kresult != ISC_R_SUCCESS) {
   7105 						if (!KSK(keys[j])) {
   7106 							have_zsk = true;
   7107 						}
   7108 					}
   7109 				}
   7110 				both = have_ksk && have_zsk;
   7111 			}
   7112 
   7113 			if (type == dns_rdatatype_dnskey ||
   7114 			    type == dns_rdatatype_cdnskey ||
   7115 			    type == dns_rdatatype_cds)
   7116 			{
   7117 				/*
   7118 				 * DNSKEY RRset is signed with KSK.
   7119 				 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1).
   7120 				 */
   7121 				if (!ksk) {
   7122 					continue;
   7123 				}
   7124 			} else if (!zsk) {
   7125 				/*
   7126 				 * Other RRsets are signed with ZSK.
   7127 				 */
   7128 				if (type != dns_rdatatype_soa &&
   7129 				    type != zone->privatetype)
   7130 				{
   7131 					continue;
   7132 				}
   7133 				if (have_zsk) {
   7134 					continue;
   7135 				}
   7136 			} else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK,
   7137 						       now, &when))
   7138 			{
   7139 				/*
   7140 				 * This key is not active for zone-signing.
   7141 				 */
   7142 				continue;
   7143 			}
   7144 
   7145 			/*
   7146 			 * If this key is revoked, it may only sign the
   7147 			 * DNSKEY RRset.
   7148 			 */
   7149 			if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   7150 				continue;
   7151 			}
   7152 		} else if (both) {
   7153 			/*
   7154 			 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
   7155 			 */
   7156 			if (type == dns_rdatatype_dnskey ||
   7157 			    type == dns_rdatatype_cdnskey ||
   7158 			    type == dns_rdatatype_cds)
   7159 			{
   7160 				if (!KSK(keys[i]) && keyset_kskonly) {
   7161 					continue;
   7162 				}
   7163 			} else if (KSK(keys[i])) {
   7164 				continue;
   7165 			}
   7166 		} else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   7167 			continue;
   7168 		}
   7169 
   7170 		/* Calculate the signature, creating a RRSIG RDATA. */
   7171 		isc_buffer_clear(&buffer);
   7172 		CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception,
   7173 				      &expire, mctx, &buffer, &sig_rdata));
   7174 
   7175 		/* Update the database and journal with the RRSIG. */
   7176 		/* XXX inefficient - will cause dataset merging */
   7177 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name,
   7178 				    rdataset.ttl, &sig_rdata));
   7179 		dns_rdata_reset(&sig_rdata);
   7180 		isc_buffer_init(&buffer, data, sizeof(data));
   7181 
   7182 		/* Update DNSSEC sign statistics. */
   7183 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7184 		if (dnssecsignstats != NULL) {
   7185 			/* Generated a new signature. */
   7186 			dns_dnssecsignstats_increment(dnssecsignstats,
   7187 						      ID(keys[i]),
   7188 						      (uint8_t)ALG(keys[i]),
   7189 						      dns_dnssecsignstats_sign);
   7190 			/* This is a refresh. */
   7191 			dns_dnssecsignstats_increment(
   7192 				dnssecsignstats, ID(keys[i]),
   7193 				(uint8_t)ALG(keys[i]),
   7194 				dns_dnssecsignstats_refresh);
   7195 		}
   7196 	}
   7197 
   7198 failure:
   7199 	if (dns_rdataset_isassociated(&rdataset)) {
   7200 		dns_rdataset_disassociate(&rdataset);
   7201 	}
   7202 	if (node != NULL) {
   7203 		dns_db_detachnode(db, &node);
   7204 	}
   7205 	return (result);
   7206 }
   7207 
   7208 static void
   7209 zone_resigninc(dns_zone_t *zone) {
   7210 	const char *me = "zone_resigninc";
   7211 	dns_db_t *db = NULL;
   7212 	dns_dbversion_t *version = NULL;
   7213 	dns_diff_t _sig_diff;
   7214 	dns__zonediff_t zonediff;
   7215 	dns_fixedname_t fixed;
   7216 	dns_name_t *name;
   7217 	dns_rdataset_t rdataset;
   7218 	dns_rdatatype_t covers;
   7219 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   7220 	bool check_ksk, keyset_kskonly = false;
   7221 	isc_result_t result;
   7222 	isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop;
   7223 	uint32_t sigvalidityinterval, expiryinterval;
   7224 	unsigned int i;
   7225 	unsigned int nkeys = 0;
   7226 	unsigned int resign;
   7227 
   7228 	ENTER;
   7229 
   7230 	dns_rdataset_init(&rdataset);
   7231 	dns_diff_init(zone->mctx, &_sig_diff);
   7232 	zonediff_init(&zonediff, &_sig_diff);
   7233 
   7234 	/*
   7235 	 * Zone is frozen or automatic resigning is disabled.
   7236 	 * Pause for 5 minutes.
   7237 	 */
   7238 	if (zone->update_disabled ||
   7239 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN))
   7240 	{
   7241 		result = ISC_R_FAILURE;
   7242 		goto failure;
   7243 	}
   7244 
   7245 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   7246 	if (zone->db != NULL) {
   7247 		dns_db_attach(zone->db, &db);
   7248 	}
   7249 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   7250 	if (db == NULL) {
   7251 		result = ISC_R_FAILURE;
   7252 		goto failure;
   7253 	}
   7254 
   7255 	result = dns_db_newversion(db, &version);
   7256 	if (result != ISC_R_SUCCESS) {
   7257 		dns_zone_log(zone, ISC_LOG_ERROR,
   7258 			     "zone_resigninc:dns_db_newversion -> %s",
   7259 			     isc_result_totext(result));
   7260 		goto failure;
   7261 	}
   7262 
   7263 	isc_stdtime_get(&now);
   7264 
   7265 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   7266 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   7267 	if (result != ISC_R_SUCCESS) {
   7268 		dns_zone_log(zone, ISC_LOG_ERROR,
   7269 			     "zone_resigninc:dns__zone_findkeys -> %s",
   7270 			     isc_result_totext(result));
   7271 		goto failure;
   7272 	}
   7273 
   7274 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   7275 	inception = now - 3600; /* Allow for clock skew. */
   7276 	soaexpire = now + sigvalidityinterval;
   7277 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   7278 	if (expiryinterval > sigvalidityinterval) {
   7279 		expiryinterval = sigvalidityinterval;
   7280 	} else {
   7281 		expiryinterval = sigvalidityinterval - expiryinterval;
   7282 	}
   7283 
   7284 	/*
   7285 	 * Spread out signatures over time if they happen to be
   7286 	 * clumped.  We don't do this for each add_sigs() call as
   7287 	 * we still want some clustering to occur.  In normal operations
   7288 	 * the records should be re-signed as they fall due and they should
   7289 	 * already be spread out.  However if the server is off for a
   7290 	 * period we need to ensure that the clusters don't become
   7291 	 * synchronised by using the full jitter range.
   7292 	 */
   7293 	if (sigvalidityinterval >= 3600U) {
   7294 		uint32_t normaljitter, fulljitter;
   7295 		if (sigvalidityinterval > 7200U) {
   7296 			normaljitter = isc_random_uniform(3600);
   7297 			fulljitter = isc_random_uniform(expiryinterval);
   7298 		} else {
   7299 			normaljitter = fulljitter = isc_random_uniform(1200);
   7300 		}
   7301 		expire = soaexpire - normaljitter - 1;
   7302 		fullexpire = soaexpire - fulljitter - 1;
   7303 	} else {
   7304 		expire = fullexpire = soaexpire - 1;
   7305 	}
   7306 	stop = now + 5;
   7307 
   7308 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   7309 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   7310 
   7311 	name = dns_fixedname_initname(&fixed);
   7312 	result = dns_db_getsigningtime(db, &rdataset, name);
   7313 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   7314 		dns_zone_log(zone, ISC_LOG_ERROR,
   7315 			     "zone_resigninc:dns_db_getsigningtime -> %s",
   7316 			     isc_result_totext(result));
   7317 	}
   7318 
   7319 	i = 0;
   7320 	while (result == ISC_R_SUCCESS) {
   7321 		resign = rdataset.resign -
   7322 			 dns_zone_getsigresigninginterval(zone);
   7323 		covers = rdataset.covers;
   7324 		dns_rdataset_disassociate(&rdataset);
   7325 
   7326 		/*
   7327 		 * Stop if we hit the SOA as that means we have walked the
   7328 		 * entire zone.  The SOA record should always be the most
   7329 		 * recent signature.
   7330 		 */
   7331 		/* XXXMPA increase number of RRsets signed pre call */
   7332 		if ((covers == dns_rdatatype_soa &&
   7333 		     dns_name_equal(name, &zone->origin)) ||
   7334 		    i++ > zone->signatures || resign > stop)
   7335 		{
   7336 			break;
   7337 		}
   7338 
   7339 		result = del_sigs(zone, db, version, name, covers, &zonediff,
   7340 				  zone_keys, nkeys, now, true);
   7341 		if (result != ISC_R_SUCCESS) {
   7342 			dns_zone_log(zone, ISC_LOG_ERROR,
   7343 				     "zone_resigninc:del_sigs -> %s",
   7344 				     isc_result_totext(result));
   7345 			break;
   7346 		}
   7347 
   7348 		/*
   7349 		 * If re-signing is over 5 minutes late use 'fullexpire'
   7350 		 * to redistribute the signature over the complete
   7351 		 * re-signing window, otherwise only add a small amount
   7352 		 * of jitter.
   7353 		 */
   7354 		result = add_sigs(db, version, name, zone, covers,
   7355 				  zonediff.diff, zone_keys, nkeys, zone->mctx,
   7356 				  now, inception,
   7357 				  resign > (now - 300) ? expire : fullexpire,
   7358 				  check_ksk, keyset_kskonly);
   7359 		if (result != ISC_R_SUCCESS) {
   7360 			dns_zone_log(zone, ISC_LOG_ERROR,
   7361 				     "zone_resigninc:add_sigs -> %s",
   7362 				     isc_result_totext(result));
   7363 			break;
   7364 		}
   7365 		result = dns_db_getsigningtime(db, &rdataset, name);
   7366 		if (nkeys == 0 && result == ISC_R_NOTFOUND) {
   7367 			result = ISC_R_SUCCESS;
   7368 			break;
   7369 		}
   7370 		if (result != ISC_R_SUCCESS) {
   7371 			dns_zone_log(zone, ISC_LOG_ERROR,
   7372 				     "zone_resigninc:dns_db_getsigningtime -> "
   7373 				     "%s",
   7374 				     isc_result_totext(result));
   7375 		}
   7376 	}
   7377 
   7378 	if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) {
   7379 		goto failure;
   7380 	}
   7381 
   7382 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   7383 			  &zonediff, zone_keys, nkeys, now, true);
   7384 	if (result != ISC_R_SUCCESS) {
   7385 		dns_zone_log(zone, ISC_LOG_ERROR,
   7386 			     "zone_resigninc:del_sigs -> %s",
   7387 			     isc_result_totext(result));
   7388 		goto failure;
   7389 	}
   7390 
   7391 	/*
   7392 	 * Did we change anything in the zone?
   7393 	 */
   7394 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   7395 		/*
   7396 		 * Commit the changes if any key has been marked as offline.
   7397 		 */
   7398 		if (zonediff.offline) {
   7399 			dns_db_closeversion(db, &version, true);
   7400 		}
   7401 		goto failure;
   7402 	}
   7403 
   7404 	/* Increment SOA serial if we have made changes */
   7405 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   7406 				   zone->updatemethod);
   7407 	if (result != ISC_R_SUCCESS) {
   7408 		dns_zone_log(zone, ISC_LOG_ERROR,
   7409 			     "zone_resigninc:update_soa_serial -> %s",
   7410 			     isc_result_totext(result));
   7411 		goto failure;
   7412 	}
   7413 
   7414 	/*
   7415 	 * Generate maximum life time signatures so that the above loop
   7416 	 * termination is sensible.
   7417 	 */
   7418 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   7419 			  zonediff.diff, zone_keys, nkeys, zone->mctx, now,
   7420 			  inception, soaexpire, check_ksk, keyset_kskonly);
   7421 	if (result != ISC_R_SUCCESS) {
   7422 		dns_zone_log(zone, ISC_LOG_ERROR,
   7423 			     "zone_resigninc:add_sigs -> %s",
   7424 			     isc_result_totext(result));
   7425 		goto failure;
   7426 	}
   7427 
   7428 	/* Write changes to journal file. */
   7429 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
   7430 
   7431 	/* Everything has succeeded. Commit the changes. */
   7432 	dns_db_closeversion(db, &version, true);
   7433 
   7434 failure:
   7435 	dns_diff_clear(&_sig_diff);
   7436 	for (i = 0; i < nkeys; i++) {
   7437 		dst_key_free(&zone_keys[i]);
   7438 	}
   7439 	if (version != NULL) {
   7440 		dns_db_closeversion(db, &version, false);
   7441 		dns_db_detach(&db);
   7442 	} else if (db != NULL) {
   7443 		dns_db_detach(&db);
   7444 	}
   7445 
   7446 	LOCK_ZONE(zone);
   7447 	if (result == ISC_R_SUCCESS) {
   7448 		set_resigntime(zone);
   7449 		zone_needdump(zone, DNS_DUMP_DELAY);
   7450 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   7451 	} else {
   7452 		/*
   7453 		 * Something failed.  Retry in 5 minutes.
   7454 		 */
   7455 		isc_interval_t ival;
   7456 		isc_interval_set(&ival, 300, 0);
   7457 		isc_time_nowplusinterval(&zone->resigntime, &ival);
   7458 	}
   7459 	UNLOCK_ZONE(zone);
   7460 
   7461 	INSIST(version == NULL);
   7462 }
   7463 
   7464 static isc_result_t
   7465 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
   7466 	    dns_name_t *newname, bool bottom) {
   7467 	isc_result_t result;
   7468 	dns_dbiterator_t *dbit = NULL;
   7469 	dns_rdatasetiter_t *rdsit = NULL;
   7470 	dns_dbnode_t *node = NULL;
   7471 
   7472 	CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
   7473 	CHECK(dns_dbiterator_seek(dbit, oldname));
   7474 	do {
   7475 		result = dns_dbiterator_next(dbit);
   7476 		if (result == ISC_R_NOMORE) {
   7477 			CHECK(dns_dbiterator_first(dbit));
   7478 		}
   7479 		CHECK(dns_dbiterator_current(dbit, &node, newname));
   7480 		if (bottom && dns_name_issubdomain(newname, oldname) &&
   7481 		    !dns_name_equal(newname, oldname))
   7482 		{
   7483 			dns_db_detachnode(db, &node);
   7484 			continue;
   7485 		}
   7486 		/*
   7487 		 * Is this node empty?
   7488 		 */
   7489 		CHECK(dns_db_allrdatasets(db, node, version, 0, 0, &rdsit));
   7490 		result = dns_rdatasetiter_first(rdsit);
   7491 		dns_db_detachnode(db, &node);
   7492 		dns_rdatasetiter_destroy(&rdsit);
   7493 		if (result != ISC_R_NOMORE) {
   7494 			break;
   7495 		}
   7496 	} while (1);
   7497 failure:
   7498 	if (node != NULL) {
   7499 		dns_db_detachnode(db, &node);
   7500 	}
   7501 	if (dbit != NULL) {
   7502 		dns_dbiterator_destroy(&dbit);
   7503 	}
   7504 	return (result);
   7505 }
   7506 
   7507 static bool
   7508 signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   7509 		     dns_dbversion_t *version, dns_rdatatype_t type,
   7510 		     dst_key_t *key) {
   7511 	isc_result_t result;
   7512 	dns_rdataset_t rdataset;
   7513 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7514 	dns_rdata_rrsig_t rrsig;
   7515 	int count = 0;
   7516 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   7517 
   7518 	dns_rdataset_init(&rdataset);
   7519 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
   7520 				     type, 0, &rdataset, NULL);
   7521 	if (result != ISC_R_SUCCESS) {
   7522 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7523 		return (false);
   7524 	}
   7525 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7526 	     result = dns_rdataset_next(&rdataset))
   7527 	{
   7528 		dns_rdataset_current(&rdataset, &rdata);
   7529 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   7530 		INSIST(result == ISC_R_SUCCESS);
   7531 		if (rrsig.algorithm == dst_key_alg(key) &&
   7532 		    rrsig.keyid == dst_key_id(key))
   7533 		{
   7534 			dns_rdataset_disassociate(&rdataset);
   7535 			return (true);
   7536 		}
   7537 		if (rrsig.algorithm == dst_key_alg(key)) {
   7538 			count++;
   7539 		}
   7540 		dns_rdata_reset(&rdata);
   7541 	}
   7542 
   7543 	if (dns_zone_getkasp(zone) != NULL) {
   7544 		dns_kasp_key_t *kkey;
   7545 		int zsk_count = 0;
   7546 		bool approved;
   7547 
   7548 		KASP_LOCK(kasp);
   7549 		for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
   7550 		     kkey = ISC_LIST_NEXT(kkey, link))
   7551 		{
   7552 			if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) {
   7553 				continue;
   7554 			}
   7555 			if (dns_kasp_key_zsk(kkey)) {
   7556 				zsk_count++;
   7557 			}
   7558 		}
   7559 		KASP_UNLOCK(kasp);
   7560 
   7561 		if (type == dns_rdatatype_dnskey ||
   7562 		    type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds)
   7563 		{
   7564 			/*
   7565 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7566 			 * (RFC 7344, section 4.1 specifies that they must
   7567 			 * be signed with a key in the current DS RRset,
   7568 			 * which would only include KSK's.)
   7569 			 */
   7570 			approved = false;
   7571 		} else {
   7572 			approved = (zsk_count == count);
   7573 		}
   7574 
   7575 		dns_rdataset_disassociate(&rdataset);
   7576 		return (approved);
   7577 	}
   7578 
   7579 	dns_rdataset_disassociate(&rdataset);
   7580 	return (false);
   7581 }
   7582 
   7583 static isc_result_t
   7584 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7585 	 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) {
   7586 	dns_fixedname_t fixed;
   7587 	dns_name_t *next;
   7588 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7589 	isc_result_t result;
   7590 	unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
   7591 
   7592 	next = dns_fixedname_initname(&fixed);
   7593 
   7594 	CHECK(next_active(db, version, name, next, bottom));
   7595 	CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata));
   7596 	CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
   7597 			    &rdata));
   7598 failure:
   7599 	return (result);
   7600 }
   7601 
   7602 static isc_result_t
   7603 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node,
   7604 			dns_dbversion_t *version, bool *is_bottom_of_zone) {
   7605 	isc_result_t result;
   7606 	dns_rdatasetiter_t *iterator = NULL;
   7607 	dns_rdataset_t rdataset;
   7608 	bool seen_soa = false, seen_ns = false, seen_dname = false;
   7609 
   7610 	REQUIRE(is_bottom_of_zone != NULL);
   7611 
   7612 	result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator);
   7613 	if (result != ISC_R_SUCCESS) {
   7614 		if (result == ISC_R_NOTFOUND) {
   7615 			result = ISC_R_SUCCESS;
   7616 		}
   7617 		return (result);
   7618 	}
   7619 
   7620 	dns_rdataset_init(&rdataset);
   7621 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7622 	     result = dns_rdatasetiter_next(iterator))
   7623 	{
   7624 		dns_rdatasetiter_current(iterator, &rdataset);
   7625 		switch (rdataset.type) {
   7626 		case dns_rdatatype_soa:
   7627 			seen_soa = true;
   7628 			break;
   7629 		case dns_rdatatype_ns:
   7630 			seen_ns = true;
   7631 			break;
   7632 		case dns_rdatatype_dname:
   7633 			seen_dname = true;
   7634 			break;
   7635 		}
   7636 		dns_rdataset_disassociate(&rdataset);
   7637 	}
   7638 	if (result != ISC_R_NOMORE) {
   7639 		goto failure;
   7640 	}
   7641 	if ((seen_ns && !seen_soa) || seen_dname) {
   7642 		*is_bottom_of_zone = true;
   7643 	}
   7644 	result = ISC_R_SUCCESS;
   7645 
   7646 failure:
   7647 	dns_rdatasetiter_destroy(&iterator);
   7648 
   7649 	return (result);
   7650 }
   7651 
   7652 static isc_result_t
   7653 sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
   7654 	    dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3,
   7655 	    bool build_nsec, dst_key_t *key, isc_stdtime_t now,
   7656 	    isc_stdtime_t inception, isc_stdtime_t expire, dns_ttl_t nsecttl,
   7657 	    bool is_ksk, bool is_zsk, bool keyset_kskonly,
   7658 	    bool is_bottom_of_zone, dns_diff_t *diff, int32_t *signatures,
   7659 	    isc_mem_t *mctx) {
   7660 	isc_result_t result;
   7661 	dns_rdatasetiter_t *iterator = NULL;
   7662 	dns_rdataset_t rdataset;
   7663 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7664 	dns_stats_t *dnssecsignstats;
   7665 
   7666 	isc_buffer_t buffer;
   7667 	unsigned char data[1024];
   7668 	bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds;
   7669 
   7670 	result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator);
   7671 	if (result != ISC_R_SUCCESS) {
   7672 		if (result == ISC_R_NOTFOUND) {
   7673 			result = ISC_R_SUCCESS;
   7674 		}
   7675 		return (result);
   7676 	}
   7677 
   7678 	dns_rdataset_init(&rdataset);
   7679 	isc_buffer_init(&buffer, data, sizeof(data));
   7680 	seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false;
   7681 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7682 	     result = dns_rdatasetiter_next(iterator))
   7683 	{
   7684 		dns_rdatasetiter_current(iterator, &rdataset);
   7685 		if (rdataset.type == dns_rdatatype_soa) {
   7686 			seen_soa = true;
   7687 		} else if (rdataset.type == dns_rdatatype_ns) {
   7688 			seen_ns = true;
   7689 		} else if (rdataset.type == dns_rdatatype_ds) {
   7690 			seen_ds = true;
   7691 		} else if (rdataset.type == dns_rdatatype_nsec) {
   7692 			seen_nsec = true;
   7693 		} else if (rdataset.type == dns_rdatatype_nsec3) {
   7694 			seen_nsec3 = true;
   7695 		}
   7696 		if (rdataset.type != dns_rdatatype_rrsig) {
   7697 			seen_rr = true;
   7698 		}
   7699 		dns_rdataset_disassociate(&rdataset);
   7700 	}
   7701 	if (result != ISC_R_NOMORE) {
   7702 		goto failure;
   7703 	}
   7704 	/*
   7705 	 * Going from insecure to NSEC3.
   7706 	 * Don't generate NSEC3 records for NSEC3 records.
   7707 	 */
   7708 	if (build_nsec3 && !seen_nsec3 && seen_rr) {
   7709 		bool unsecure = !seen_ds && seen_ns && !seen_soa;
   7710 		CHECK(dns_nsec3_addnsec3s(db, version, name, nsecttl, unsecure,
   7711 					  diff));
   7712 		(*signatures)--;
   7713 	}
   7714 	/*
   7715 	 * Going from insecure to NSEC.
   7716 	 * Don't generate NSEC records for NSEC3 records.
   7717 	 */
   7718 	if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
   7719 		/*
   7720 		 * Build a NSEC record except at the origin.
   7721 		 */
   7722 		if (!dns_name_equal(name, dns_db_origin(db))) {
   7723 			CHECK(add_nsec(db, version, name, node, nsecttl,
   7724 				       is_bottom_of_zone, diff));
   7725 			/* Count a NSEC generation as a signature generation. */
   7726 			(*signatures)--;
   7727 		}
   7728 	}
   7729 	result = dns_rdatasetiter_first(iterator);
   7730 	while (result == ISC_R_SUCCESS) {
   7731 		isc_stdtime_t when;
   7732 
   7733 		dns_rdatasetiter_current(iterator, &rdataset);
   7734 		if (rdataset.type == dns_rdatatype_soa ||
   7735 		    rdataset.type == dns_rdatatype_rrsig)
   7736 		{
   7737 			goto next_rdataset;
   7738 		}
   7739 		if (rdataset.type == dns_rdatatype_dnskey ||
   7740 		    rdataset.type == dns_rdatatype_cdnskey ||
   7741 		    rdataset.type == dns_rdatatype_cds)
   7742 		{
   7743 			/*
   7744 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7745 			 * (RFC 7344, section 4.1 specifies that they must
   7746 			 * be signed with a key in the current DS RRset,
   7747 			 * which would only include KSK's.)
   7748 			 */
   7749 			if (!is_ksk && keyset_kskonly) {
   7750 				goto next_rdataset;
   7751 			}
   7752 		} else if (!is_zsk) {
   7753 			goto next_rdataset;
   7754 		} else if (is_zsk &&
   7755 			   !dst_key_is_signing(key, DST_BOOL_ZSK, now, &when))
   7756 		{
   7757 			/* Only applies to dnssec-policy. */
   7758 			if (dns_zone_getkasp(zone) != NULL) {
   7759 				goto next_rdataset;
   7760 			}
   7761 		}
   7762 
   7763 		if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds &&
   7764 		    rdataset.type != dns_rdatatype_nsec)
   7765 		{
   7766 			goto next_rdataset;
   7767 		}
   7768 		if (signed_with_good_key(zone, db, node, version, rdataset.type,
   7769 					 key))
   7770 		{
   7771 			goto next_rdataset;
   7772 		}
   7773 
   7774 		/* Calculate the signature, creating a RRSIG RDATA. */
   7775 		isc_buffer_clear(&buffer);
   7776 		CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, &expire,
   7777 				      mctx, &buffer, &rdata));
   7778 		/* Update the database and journal with the RRSIG. */
   7779 		/* XXX inefficient - will cause dataset merging */
   7780 		CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
   7781 				    name, rdataset.ttl, &rdata));
   7782 		dns_rdata_reset(&rdata);
   7783 
   7784 		/* Update DNSSEC sign statistics. */
   7785 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7786 		if (dnssecsignstats != NULL) {
   7787 			/* Generated a new signature. */
   7788 			dns_dnssecsignstats_increment(dnssecsignstats, ID(key),
   7789 						      ALG(key),
   7790 						      dns_dnssecsignstats_sign);
   7791 			/* This is a refresh. */
   7792 			dns_dnssecsignstats_increment(
   7793 				dnssecsignstats, ID(key), ALG(key),
   7794 				dns_dnssecsignstats_refresh);
   7795 		}
   7796 
   7797 		(*signatures)--;
   7798 	next_rdataset:
   7799 		dns_rdataset_disassociate(&rdataset);
   7800 		result = dns_rdatasetiter_next(iterator);
   7801 	}
   7802 	if (result == ISC_R_NOMORE) {
   7803 		result = ISC_R_SUCCESS;
   7804 	}
   7805 failure:
   7806 	if (dns_rdataset_isassociated(&rdataset)) {
   7807 		dns_rdataset_disassociate(&rdataset);
   7808 	}
   7809 	if (iterator != NULL) {
   7810 		dns_rdatasetiter_destroy(&iterator);
   7811 	}
   7812 	return (result);
   7813 }
   7814 
   7815 /*
   7816  * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
   7817  */
   7818 static isc_result_t
   7819 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7820 	     dns_ttl_t nsecttl, bool update_only, dns_diff_t *diff) {
   7821 	isc_result_t result;
   7822 	dns_rdataset_t rdataset;
   7823 	dns_dbnode_t *node = NULL;
   7824 
   7825 	CHECK(dns_db_getoriginnode(db, &node));
   7826 	if (update_only) {
   7827 		dns_rdataset_init(&rdataset);
   7828 		result = dns_db_findrdataset(
   7829 			db, node, version, dns_rdatatype_nsec,
   7830 			dns_rdatatype_none, 0, &rdataset, NULL);
   7831 		if (dns_rdataset_isassociated(&rdataset)) {
   7832 			dns_rdataset_disassociate(&rdataset);
   7833 		}
   7834 		if (result == ISC_R_NOTFOUND) {
   7835 			goto success;
   7836 		}
   7837 		if (result != ISC_R_SUCCESS) {
   7838 			goto failure;
   7839 		}
   7840 	}
   7841 	CHECK(delete_nsec(db, version, node, name, diff));
   7842 	CHECK(add_nsec(db, version, name, node, nsecttl, false, diff));
   7843 success:
   7844 	result = ISC_R_SUCCESS;
   7845 failure:
   7846 	if (node != NULL) {
   7847 		dns_db_detachnode(db, &node);
   7848 	}
   7849 	return (result);
   7850 }
   7851 
   7852 static isc_result_t
   7853 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
   7854 		  dns_dbversion_t *version, bool build_nsec3, dns_ttl_t nsecttl,
   7855 		  dns_diff_t *diff) {
   7856 	isc_result_t result;
   7857 	dns_dbnode_t *node = NULL;
   7858 	dns_rdataset_t rdataset;
   7859 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7860 	unsigned char data[5];
   7861 	bool seen_done = false;
   7862 	bool have_rr = false;
   7863 
   7864 	dns_rdataset_init(&rdataset);
   7865 	result = dns_db_getoriginnode(signing->db, &node);
   7866 	if (result != ISC_R_SUCCESS) {
   7867 		goto failure;
   7868 	}
   7869 
   7870 	result = dns_db_findrdataset(signing->db, node, version,
   7871 				     zone->privatetype, dns_rdatatype_none, 0,
   7872 				     &rdataset, NULL);
   7873 	if (result == ISC_R_NOTFOUND) {
   7874 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7875 		result = ISC_R_SUCCESS;
   7876 		goto failure;
   7877 	}
   7878 	if (result != ISC_R_SUCCESS) {
   7879 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7880 		goto failure;
   7881 	}
   7882 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7883 	     result = dns_rdataset_next(&rdataset))
   7884 	{
   7885 		dns_rdataset_current(&rdataset, &rdata);
   7886 		/*
   7887 		 * If we don't match the algorithm or keyid skip the record.
   7888 		 */
   7889 		if (rdata.length != 5 || rdata.data[0] != signing->algorithm ||
   7890 		    rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
   7891 		    rdata.data[2] != (signing->keyid & 0xff))
   7892 		{
   7893 			have_rr = true;
   7894 			dns_rdata_reset(&rdata);
   7895 			continue;
   7896 		}
   7897 		/*
   7898 		 * We have a match.  If we were signing (!signing->deleteit)
   7899 		 * and we already have a record indicating that we have
   7900 		 * finished signing (rdata.data[4] != 0) then keep it.
   7901 		 * Otherwise it needs to be deleted as we have removed all
   7902 		 * the signatures (signing->deleteit), so any record indicating
   7903 		 * completion is now out of date, or we have finished signing
   7904 		 * with the new record so we no longer need to remember that
   7905 		 * we need to sign the zone with the matching key across a
   7906 		 * nameserver re-start.
   7907 		 */
   7908 		if (!signing->deleteit && rdata.data[4] != 0) {
   7909 			seen_done = true;
   7910 			have_rr = true;
   7911 		} else {
   7912 			CHECK(update_one_rr(signing->db, version, diff,
   7913 					    DNS_DIFFOP_DEL, &zone->origin,
   7914 					    rdataset.ttl, &rdata));
   7915 		}
   7916 		dns_rdata_reset(&rdata);
   7917 	}
   7918 	if (result == ISC_R_NOMORE) {
   7919 		result = ISC_R_SUCCESS;
   7920 	}
   7921 	if (!signing->deleteit && !seen_done) {
   7922 		/*
   7923 		 * If we were signing then we need to indicate that we have
   7924 		 * finished signing the zone with this key.  If it is already
   7925 		 * there we don't need to add it a second time.
   7926 		 */
   7927 		data[0] = signing->algorithm;
   7928 		data[1] = (signing->keyid >> 8) & 0xff;
   7929 		data[2] = signing->keyid & 0xff;
   7930 		data[3] = 0;
   7931 		data[4] = 1;
   7932 		rdata.length = sizeof(data);
   7933 		rdata.data = data;
   7934 		rdata.type = zone->privatetype;
   7935 		rdata.rdclass = dns_db_class(signing->db);
   7936 		CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
   7937 				    &zone->origin, rdataset.ttl, &rdata));
   7938 	} else if (!have_rr) {
   7939 		dns_name_t *origin = dns_db_origin(signing->db);
   7940 		/*
   7941 		 * Rebuild the NSEC/NSEC3 record for the origin as we no
   7942 		 * longer have any private records.
   7943 		 */
   7944 		if (build_nsec3) {
   7945 			CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
   7946 						  nsecttl, false, diff));
   7947 		}
   7948 		CHECK(updatesecure(signing->db, version, origin, nsecttl, true,
   7949 				   diff));
   7950 	}
   7951 
   7952 failure:
   7953 	if (dns_rdataset_isassociated(&rdataset)) {
   7954 		dns_rdataset_disassociate(&rdataset);
   7955 	}
   7956 	if (node != NULL) {
   7957 		dns_db_detachnode(signing->db, &node);
   7958 	}
   7959 	return (result);
   7960 }
   7961 
   7962 /*
   7963  * Called from zone_nsec3chain() in order to update zone records indicating
   7964  * processing status of given NSEC3 chain:
   7965  *
   7966  *   - If the supplied dns_nsec3chain_t structure has been fully processed
   7967  *     (which is indicated by "active" being set to false):
   7968  *
   7969  *       - remove all NSEC3PARAM records matching the relevant NSEC3 chain,
   7970  *
   7971  *       - remove all private-type records containing NSEC3PARAM RDATA matching
   7972  *         the relevant NSEC3 chain.
   7973  *
   7974  *   - If the supplied dns_nsec3chain_t structure has not been fully processed
   7975  *     (which is indicated by "active" being set to true), only remove the
   7976  *     NSEC3PARAM record which matches the relevant NSEC3 chain and has the
   7977  *     "flags" field set to 0.
   7978  *
   7979  *   - If given NSEC3 chain is being added, add an NSEC3PARAM record contained
   7980  *     in the relevant private-type record, but with the "flags" field set to
   7981  *     0, indicating that this NSEC3 chain is now complete for this zone.
   7982  *
   7983  * Note that this function is called at different processing stages for NSEC3
   7984  * chain additions vs. removals and needs to handle all cases properly.
   7985  */
   7986 static isc_result_t
   7987 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
   7988 		 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) {
   7989 	dns_dbnode_t *node = NULL;
   7990 	dns_name_t *name = dns_db_origin(db);
   7991 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7992 	dns_rdataset_t rdataset;
   7993 	dns_rdata_nsec3param_t nsec3param;
   7994 	isc_result_t result;
   7995 	isc_buffer_t buffer;
   7996 	unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
   7997 	dns_ttl_t ttl = 0;
   7998 	bool nseconly = false, nsec3ok = false;
   7999 
   8000 	dns_rdataset_init(&rdataset);
   8001 
   8002 	result = dns_db_getoriginnode(db, &node);
   8003 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8004 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   8005 				     0, &rdataset, NULL);
   8006 	if (result == ISC_R_NOTFOUND) {
   8007 		goto try_private;
   8008 	}
   8009 	if (result != ISC_R_SUCCESS) {
   8010 		goto failure;
   8011 	}
   8012 
   8013 	/*
   8014 	 * Preserve the existing ttl.
   8015 	 */
   8016 	ttl = rdataset.ttl;
   8017 
   8018 	/*
   8019 	 * Delete all NSEC3PARAM records which match that in nsec3chain.
   8020 	 */
   8021 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8022 	     result = dns_rdataset_next(&rdataset))
   8023 	{
   8024 		dns_rdataset_current(&rdataset, &rdata);
   8025 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   8026 
   8027 		if (nsec3param.hash != chain->nsec3param.hash ||
   8028 		    (active && nsec3param.flags != 0) ||
   8029 		    nsec3param.iterations != chain->nsec3param.iterations ||
   8030 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   8031 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   8032 			   nsec3param.salt_length))
   8033 		{
   8034 			dns_rdata_reset(&rdata);
   8035 			continue;
   8036 		}
   8037 
   8038 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8039 				    rdataset.ttl, &rdata));
   8040 		dns_rdata_reset(&rdata);
   8041 	}
   8042 	if (result != ISC_R_NOMORE) {
   8043 		goto failure;
   8044 	}
   8045 
   8046 	dns_rdataset_disassociate(&rdataset);
   8047 
   8048 try_private:
   8049 
   8050 	if (active) {
   8051 		goto add;
   8052 	}
   8053 
   8054 	result = dns_nsec_nseconly(db, ver, diff, &nseconly);
   8055 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   8056 
   8057 	/*
   8058 	 * Delete all private records which match that in nsec3chain.
   8059 	 */
   8060 	result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0,
   8061 				     &rdataset, NULL);
   8062 	if (result == ISC_R_NOTFOUND) {
   8063 		goto add;
   8064 	}
   8065 	if (result != ISC_R_SUCCESS) {
   8066 		goto failure;
   8067 	}
   8068 
   8069 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8070 	     result = dns_rdataset_next(&rdataset))
   8071 	{
   8072 		dns_rdata_t private = DNS_RDATA_INIT;
   8073 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   8074 
   8075 		dns_rdataset_current(&rdataset, &private);
   8076 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   8077 						sizeof(buf)))
   8078 		{
   8079 			continue;
   8080 		}
   8081 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   8082 
   8083 		if ((!nsec3ok &&
   8084 		     (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
   8085 		    nsec3param.hash != chain->nsec3param.hash ||
   8086 		    nsec3param.iterations != chain->nsec3param.iterations ||
   8087 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   8088 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   8089 			   nsec3param.salt_length))
   8090 		{
   8091 			dns_rdata_reset(&rdata);
   8092 			continue;
   8093 		}
   8094 
   8095 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8096 				    rdataset.ttl, &private));
   8097 		dns_rdata_reset(&rdata);
   8098 	}
   8099 	if (result != ISC_R_NOMORE) {
   8100 		goto failure;
   8101 	}
   8102 
   8103 add:
   8104 	if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   8105 		result = ISC_R_SUCCESS;
   8106 		goto failure;
   8107 	}
   8108 
   8109 	/*
   8110 	 * Add a NSEC3PARAM record which matches that in nsec3chain but
   8111 	 * with all flags bits cleared.
   8112 	 *
   8113 	 * Note: we do not clear chain->nsec3param.flags as this change
   8114 	 * may be reversed.
   8115 	 */
   8116 	isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
   8117 	CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
   8118 				   dns_rdatatype_nsec3param, &chain->nsec3param,
   8119 				   &buffer));
   8120 	rdata.data[1] = 0; /* Clear flag bits. */
   8121 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
   8122 
   8123 failure:
   8124 	dns_db_detachnode(db, &node);
   8125 	if (dns_rdataset_isassociated(&rdataset)) {
   8126 		dns_rdataset_disassociate(&rdataset);
   8127 	}
   8128 	return (result);
   8129 }
   8130 
   8131 static isc_result_t
   8132 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   8133 	    dns_name_t *name, dns_diff_t *diff) {
   8134 	dns_rdataset_t rdataset;
   8135 	isc_result_t result;
   8136 
   8137 	dns_rdataset_init(&rdataset);
   8138 
   8139 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   8140 				     &rdataset, NULL);
   8141 	if (result == ISC_R_NOTFOUND) {
   8142 		return (ISC_R_SUCCESS);
   8143 	}
   8144 	if (result != ISC_R_SUCCESS) {
   8145 		return (result);
   8146 	}
   8147 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8148 	     result = dns_rdataset_next(&rdataset))
   8149 	{
   8150 		dns_rdata_t rdata = DNS_RDATA_INIT;
   8151 
   8152 		dns_rdataset_current(&rdataset, &rdata);
   8153 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8154 				    rdataset.ttl, &rdata));
   8155 	}
   8156 	if (result == ISC_R_NOMORE) {
   8157 		result = ISC_R_SUCCESS;
   8158 	}
   8159 failure:
   8160 	dns_rdataset_disassociate(&rdataset);
   8161 	return (result);
   8162 }
   8163 
   8164 static isc_result_t
   8165 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   8166 		    dns_name_t *name, const dns_rdata_nsec3param_t *param,
   8167 		    dns_diff_t *diff) {
   8168 	dns_rdataset_t rdataset;
   8169 	dns_rdata_nsec3_t nsec3;
   8170 	isc_result_t result;
   8171 
   8172 	dns_rdataset_init(&rdataset);
   8173 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0,
   8174 				     &rdataset, NULL);
   8175 	if (result == ISC_R_NOTFOUND) {
   8176 		return (ISC_R_SUCCESS);
   8177 	}
   8178 	if (result != ISC_R_SUCCESS) {
   8179 		return (result);
   8180 	}
   8181 
   8182 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8183 	     result = dns_rdataset_next(&rdataset))
   8184 	{
   8185 		dns_rdata_t rdata = DNS_RDATA_INIT;
   8186 
   8187 		dns_rdataset_current(&rdataset, &rdata);
   8188 		CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
   8189 		if (nsec3.hash != param->hash ||
   8190 		    nsec3.iterations != param->iterations ||
   8191 		    nsec3.salt_length != param->salt_length ||
   8192 		    memcmp(nsec3.salt, param->salt, nsec3.salt_length))
   8193 		{
   8194 			continue;
   8195 		}
   8196 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8197 				    rdataset.ttl, &rdata));
   8198 	}
   8199 	if (result == ISC_R_NOMORE) {
   8200 		result = ISC_R_SUCCESS;
   8201 	}
   8202 failure:
   8203 	dns_rdataset_disassociate(&rdataset);
   8204 	return (result);
   8205 }
   8206 
   8207 static isc_result_t
   8208 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
   8209 		const dns_rdata_nsec3param_t *param, bool *answer) {
   8210 	dns_dbnode_t *node = NULL;
   8211 	dns_rdata_t rdata = DNS_RDATA_INIT;
   8212 	dns_rdata_nsec3param_t myparam;
   8213 	dns_rdataset_t rdataset;
   8214 	isc_result_t result;
   8215 
   8216 	*answer = false;
   8217 
   8218 	result = dns_db_getoriginnode(db, &node);
   8219 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8220 
   8221 	dns_rdataset_init(&rdataset);
   8222 
   8223 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   8224 				     &rdataset, NULL);
   8225 	if (result == ISC_R_SUCCESS) {
   8226 		dns_rdataset_disassociate(&rdataset);
   8227 		dns_db_detachnode(db, &node);
   8228 		return (result);
   8229 	}
   8230 	if (result != ISC_R_NOTFOUND) {
   8231 		dns_db_detachnode(db, &node);
   8232 		return (result);
   8233 	}
   8234 
   8235 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   8236 				     0, &rdataset, NULL);
   8237 	if (result == ISC_R_NOTFOUND) {
   8238 		*answer = true;
   8239 		dns_db_detachnode(db, &node);
   8240 		return (ISC_R_SUCCESS);
   8241 	}
   8242 	if (result != ISC_R_SUCCESS) {
   8243 		dns_db_detachnode(db, &node);
   8244 		return (result);
   8245 	}
   8246 
   8247 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8248 	     result = dns_rdataset_next(&rdataset))
   8249 	{
   8250 		dns_rdataset_current(&rdataset, &rdata);
   8251 		CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
   8252 		dns_rdata_reset(&rdata);
   8253 		/*
   8254 		 * Ignore any NSEC3PARAM removals.
   8255 		 */
   8256 		if (NSEC3REMOVE(myparam.flags)) {
   8257 			continue;
   8258 		}
   8259 		/*
   8260 		 * Ignore the chain that we are in the process of deleting.
   8261 		 */
   8262 		if (myparam.hash == param->hash &&
   8263 		    myparam.iterations == param->iterations &&
   8264 		    myparam.salt_length == param->salt_length &&
   8265 		    !memcmp(myparam.salt, param->salt, myparam.salt_length))
   8266 		{
   8267 			continue;
   8268 		}
   8269 		/*
   8270 		 * Found an active NSEC3 chain.
   8271 		 */
   8272 		break;
   8273 	}
   8274 	if (result == ISC_R_NOMORE) {
   8275 		*answer = true;
   8276 		result = ISC_R_SUCCESS;
   8277 	}
   8278 
   8279 failure:
   8280 	if (dns_rdataset_isassociated(&rdataset)) {
   8281 		dns_rdataset_disassociate(&rdataset);
   8282 	}
   8283 	dns_db_detachnode(db, &node);
   8284 	return (result);
   8285 }
   8286 
   8287 /*%
   8288  * Given a tuple which is part of a diff, return a pointer to the next tuple in
   8289  * that diff which has the same name and type (or NULL if no such tuple is
   8290  * found).
   8291  */
   8292 static dns_difftuple_t *
   8293 find_next_matching_tuple(dns_difftuple_t *cur) {
   8294 	dns_difftuple_t *next = cur;
   8295 
   8296 	while ((next = ISC_LIST_NEXT(next, link)) != NULL) {
   8297 		if (cur->rdata.type == next->rdata.type &&
   8298 		    dns_name_equal(&cur->name, &next->name))
   8299 		{
   8300 			return (next);
   8301 		}
   8302 	}
   8303 
   8304 	return (NULL);
   8305 }
   8306 
   8307 /*%
   8308  * Remove all tuples with the same name and type as 'cur' from 'src' and append
   8309  * them to 'dst'.
   8310  */
   8311 static void
   8312 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) {
   8313 	do {
   8314 		dns_difftuple_t *next = find_next_matching_tuple(cur);
   8315 		ISC_LIST_UNLINK(src->tuples, cur, link);
   8316 		dns_diff_appendminimal(dst, &cur);
   8317 		cur = next;
   8318 	} while (cur != NULL);
   8319 }
   8320 
   8321 /*%
   8322  * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in
   8323  * 'diff'.  Gradually remove tuples from 'diff' and append them to 'zonediff'
   8324  * along with tuples representing relevant signature changes.
   8325  */
   8326 isc_result_t
   8327 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
   8328 		     dst_key_t *zone_keys[], unsigned int nkeys,
   8329 		     dns_zone_t *zone, isc_stdtime_t inception,
   8330 		     isc_stdtime_t expire, isc_stdtime_t keyexpire,
   8331 		     isc_stdtime_t now, bool check_ksk, bool keyset_kskonly,
   8332 		     dns__zonediff_t *zonediff) {
   8333 	dns_difftuple_t *tuple;
   8334 	isc_result_t result;
   8335 
   8336 	while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) {
   8337 		isc_stdtime_t exp = expire;
   8338 
   8339 		if (keyexpire != 0 &&
   8340 		    (tuple->rdata.type == dns_rdatatype_dnskey ||
   8341 		     tuple->rdata.type == dns_rdatatype_cdnskey ||
   8342 		     tuple->rdata.type == dns_rdatatype_cds))
   8343 		{
   8344 			exp = keyexpire;
   8345 		}
   8346 
   8347 		result = del_sigs(zone, db, version, &tuple->name,
   8348 				  tuple->rdata.type, zonediff, zone_keys, nkeys,
   8349 				  now, false);
   8350 		if (result != ISC_R_SUCCESS) {
   8351 			dns_zone_log(zone, ISC_LOG_ERROR,
   8352 				     "dns__zone_updatesigs:del_sigs -> %s",
   8353 				     isc_result_totext(result));
   8354 			return (result);
   8355 		}
   8356 		result = add_sigs(db, version, &tuple->name, zone,
   8357 				  tuple->rdata.type, zonediff->diff, zone_keys,
   8358 				  nkeys, zone->mctx, now, inception, exp,
   8359 				  check_ksk, keyset_kskonly);
   8360 		if (result != ISC_R_SUCCESS) {
   8361 			dns_zone_log(zone, ISC_LOG_ERROR,
   8362 				     "dns__zone_updatesigs:add_sigs -> %s",
   8363 				     isc_result_totext(result));
   8364 			return (result);
   8365 		}
   8366 
   8367 		/*
   8368 		 * Signature changes for all RRs with name tuple->name and type
   8369 		 * tuple->rdata.type were appended to zonediff->diff.  Now we
   8370 		 * remove all the "raw" changes with the same name and type
   8371 		 * from diff (so that they are not processed by this loop
   8372 		 * again) and append them to zonediff so that they get applied.
   8373 		 */
   8374 		move_matching_tuples(tuple, diff, zonediff->diff);
   8375 	}
   8376 	return (ISC_R_SUCCESS);
   8377 }
   8378 
   8379 /*
   8380  * Incrementally build and sign a new NSEC3 chain using the parameters
   8381  * requested.
   8382  */
   8383 static void
   8384 zone_nsec3chain(dns_zone_t *zone) {
   8385 	const char *me = "zone_nsec3chain";
   8386 	dns_db_t *db = NULL;
   8387 	dns_dbnode_t *node = NULL;
   8388 	dns_dbversion_t *version = NULL;
   8389 	dns_diff_t _sig_diff;
   8390 	dns_diff_t nsec_diff;
   8391 	dns_diff_t nsec3_diff;
   8392 	dns_diff_t param_diff;
   8393 	dns__zonediff_t zonediff;
   8394 	dns_fixedname_t fixed;
   8395 	dns_fixedname_t nextfixed;
   8396 	dns_name_t *name, *nextname;
   8397 	dns_rdataset_t rdataset;
   8398 	dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
   8399 	dns_nsec3chainlist_t cleanup;
   8400 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   8401 	int32_t signatures;
   8402 	bool check_ksk, keyset_kskonly;
   8403 	bool delegation;
   8404 	bool first;
   8405 	isc_result_t result;
   8406 	isc_stdtime_t now, inception, soaexpire, expire;
   8407 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   8408 	unsigned int i;
   8409 	unsigned int nkeys = 0;
   8410 	uint32_t nodes;
   8411 	bool unsecure = false;
   8412 	bool seen_soa, seen_ns, seen_dname, seen_ds;
   8413 	bool seen_nsec, seen_nsec3, seen_rr;
   8414 	dns_rdatasetiter_t *iterator = NULL;
   8415 	bool buildnsecchain;
   8416 	bool updatensec = false;
   8417 	dns_rdatatype_t privatetype = zone->privatetype;
   8418 
   8419 	ENTER;
   8420 
   8421 	dns_rdataset_init(&rdataset);
   8422 	name = dns_fixedname_initname(&fixed);
   8423 	nextname = dns_fixedname_initname(&nextfixed);
   8424 	dns_diff_init(zone->mctx, &param_diff);
   8425 	dns_diff_init(zone->mctx, &nsec3_diff);
   8426 	dns_diff_init(zone->mctx, &nsec_diff);
   8427 	dns_diff_init(zone->mctx, &_sig_diff);
   8428 	zonediff_init(&zonediff, &_sig_diff);
   8429 	ISC_LIST_INIT(cleanup);
   8430 
   8431 	/*
   8432 	 * Updates are disabled.  Pause for 5 minutes.
   8433 	 */
   8434 	if (zone->update_disabled) {
   8435 		result = ISC_R_FAILURE;
   8436 		goto failure;
   8437 	}
   8438 
   8439 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8440 	/*
   8441 	 * This function is called when zone timer fires, after the latter gets
   8442 	 * set by zone_addnsec3chain().  If the action triggering the call to
   8443 	 * zone_addnsec3chain() is closely followed by a zone deletion request,
   8444 	 * it might turn out that the timer thread will not be woken up until
   8445 	 * after the zone is deleted by rmzone(), which calls dns_db_detach()
   8446 	 * for zone->db, causing the latter to become NULL.  Return immediately
   8447 	 * if that happens.
   8448 	 */
   8449 	if (zone->db != NULL) {
   8450 		dns_db_attach(zone->db, &db);
   8451 	}
   8452 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8453 	if (db == NULL) {
   8454 		return;
   8455 	}
   8456 
   8457 	result = dns_db_newversion(db, &version);
   8458 	if (result != ISC_R_SUCCESS) {
   8459 		dnssec_log(zone, ISC_LOG_ERROR,
   8460 			   "zone_nsec3chain:dns_db_newversion -> %s",
   8461 			   isc_result_totext(result));
   8462 		goto failure;
   8463 	}
   8464 
   8465 	isc_stdtime_get(&now);
   8466 
   8467 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   8468 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   8469 	if (result != ISC_R_SUCCESS) {
   8470 		dnssec_log(zone, ISC_LOG_ERROR,
   8471 			   "zone_nsec3chain:dns__zone_findkeys -> %s",
   8472 			   isc_result_totext(result));
   8473 		goto failure;
   8474 	}
   8475 
   8476 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   8477 	inception = now - 3600; /* Allow for clock skew. */
   8478 	soaexpire = now + sigvalidityinterval;
   8479 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   8480 	if (expiryinterval > sigvalidityinterval) {
   8481 		expiryinterval = sigvalidityinterval;
   8482 	} else {
   8483 		expiryinterval = sigvalidityinterval - expiryinterval;
   8484 	}
   8485 
   8486 	/*
   8487 	 * Spread out signatures over time if they happen to be
   8488 	 * clumped.  We don't do this for each add_sigs() call as
   8489 	 * we still want some clustering to occur.
   8490 	 */
   8491 	if (sigvalidityinterval >= 3600U) {
   8492 		if (sigvalidityinterval > 7200U) {
   8493 			jitter = isc_random_uniform(expiryinterval);
   8494 		} else {
   8495 			jitter = isc_random_uniform(1200);
   8496 		}
   8497 		expire = soaexpire - jitter - 1;
   8498 	} else {
   8499 		expire = soaexpire - 1;
   8500 	}
   8501 
   8502 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   8503 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   8504 
   8505 	/*
   8506 	 * We keep pulling nodes off each iterator in turn until
   8507 	 * we have no more nodes to pull off or we reach the limits
   8508 	 * for this quantum.
   8509 	 */
   8510 	nodes = zone->nodes;
   8511 	signatures = zone->signatures;
   8512 	LOCK_ZONE(zone);
   8513 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8514 	UNLOCK_ZONE(zone);
   8515 	first = true;
   8516 
   8517 	if (nsec3chain != NULL) {
   8518 		nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8519 	}
   8520 	/*
   8521 	 * Generate new NSEC3 chains first.
   8522 	 *
   8523 	 * The following while loop iterates over nodes in the zone database,
   8524 	 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of
   8525 	 * them.  Once all nodes are processed, the "delete_nsec" field is
   8526 	 * consulted to check whether we are supposed to remove NSEC records
   8527 	 * from the zone database; if so, the database iterator is reset to
   8528 	 * point to the first node and the loop traverses all of them again,
   8529 	 * this time removing NSEC records.  If we hit a node which is obscured
   8530 	 * by a delegation or a DNAME, nodes are skipped over until we find one
   8531 	 * that is not obscured by the same obscuring name and then normal
   8532 	 * processing is resumed.
   8533 	 *
   8534 	 * The above is repeated until all requested NSEC3 chain changes are
   8535 	 * applied or when we reach the limits for this quantum, whichever
   8536 	 * happens first.
   8537 	 *
   8538 	 * Note that the "signatures" variable is only used here to limit the
   8539 	 * amount of work performed.  Actual DNSSEC signatures are only
   8540 	 * generated by dns__zone_updatesigs() calls later in this function.
   8541 	 */
   8542 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8543 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8544 
   8545 		LOCK_ZONE(zone);
   8546 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8547 
   8548 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8549 		if (nsec3chain->done || nsec3chain->db != zone->db) {
   8550 			ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   8551 			ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8552 		}
   8553 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8554 		UNLOCK_ZONE(zone);
   8555 		if (ISC_LIST_TAIL(cleanup) == nsec3chain) {
   8556 			goto next_addchain;
   8557 		}
   8558 
   8559 		/*
   8560 		 * Possible future db.
   8561 		 */
   8562 		if (nsec3chain->db != db) {
   8563 			goto next_addchain;
   8564 		}
   8565 
   8566 		if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8567 			goto next_addchain;
   8568 		}
   8569 
   8570 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8571 
   8572 		if (nsec3chain->delete_nsec) {
   8573 			delegation = false;
   8574 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8575 			CHECK(delete_nsec(db, version, node, name, &nsec_diff));
   8576 			goto next_addnode;
   8577 		}
   8578 		/*
   8579 		 * On the first pass we need to check if the current node
   8580 		 * has not been obscured.
   8581 		 */
   8582 		delegation = false;
   8583 		unsecure = false;
   8584 		if (first) {
   8585 			dns_fixedname_t ffound;
   8586 			dns_name_t *found;
   8587 			found = dns_fixedname_initname(&ffound);
   8588 			result = dns_db_find(
   8589 				db, name, version, dns_rdatatype_soa,
   8590 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8591 			if ((result == DNS_R_DELEGATION ||
   8592 			     result == DNS_R_DNAME) &&
   8593 			    !dns_name_equal(name, found))
   8594 			{
   8595 				/*
   8596 				 * Remember the obscuring name so that
   8597 				 * we skip all obscured names.
   8598 				 */
   8599 				dns_name_copy(found, name);
   8600 				delegation = true;
   8601 				goto next_addnode;
   8602 			}
   8603 		}
   8604 
   8605 		/*
   8606 		 * Check to see if this is a bottom of zone node.
   8607 		 */
   8608 		result = dns_db_allrdatasets(db, node, version, 0, 0,
   8609 					     &iterator);
   8610 		if (result == ISC_R_NOTFOUND) {
   8611 			/* Empty node? */
   8612 			goto next_addnode;
   8613 		}
   8614 		if (result != ISC_R_SUCCESS) {
   8615 			goto failure;
   8616 		}
   8617 
   8618 		seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false;
   8619 		for (result = dns_rdatasetiter_first(iterator);
   8620 		     result == ISC_R_SUCCESS;
   8621 		     result = dns_rdatasetiter_next(iterator))
   8622 		{
   8623 			dns_rdatasetiter_current(iterator, &rdataset);
   8624 			INSIST(rdataset.type != dns_rdatatype_nsec3);
   8625 			if (rdataset.type == dns_rdatatype_soa) {
   8626 				seen_soa = true;
   8627 			} else if (rdataset.type == dns_rdatatype_ns) {
   8628 				seen_ns = true;
   8629 			} else if (rdataset.type == dns_rdatatype_dname) {
   8630 				seen_dname = true;
   8631 			} else if (rdataset.type == dns_rdatatype_ds) {
   8632 				seen_ds = true;
   8633 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8634 				seen_nsec = true;
   8635 			}
   8636 			dns_rdataset_disassociate(&rdataset);
   8637 		}
   8638 		dns_rdatasetiter_destroy(&iterator);
   8639 		/*
   8640 		 * Is there a NSEC chain than needs to be cleaned up?
   8641 		 */
   8642 		if (seen_nsec) {
   8643 			nsec3chain->seen_nsec = true;
   8644 		}
   8645 		if (seen_ns && !seen_soa && !seen_ds) {
   8646 			unsecure = true;
   8647 		}
   8648 		if ((seen_ns && !seen_soa) || seen_dname) {
   8649 			delegation = true;
   8650 		}
   8651 
   8652 		/*
   8653 		 * Process one node.
   8654 		 */
   8655 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8656 		result = dns_nsec3_addnsec3(
   8657 			db, version, name, &nsec3chain->nsec3param,
   8658 			zone_nsecttl(zone), unsecure, &nsec3_diff);
   8659 		if (result != ISC_R_SUCCESS) {
   8660 			dnssec_log(zone, ISC_LOG_ERROR,
   8661 				   "zone_nsec3chain:"
   8662 				   "dns_nsec3_addnsec3 -> %s",
   8663 				   isc_result_totext(result));
   8664 			goto failure;
   8665 		}
   8666 
   8667 		/*
   8668 		 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
   8669 		 * two signatures.  Additionally there will, in general, be
   8670 		 * two signature generated below.
   8671 		 *
   8672 		 * If we are only changing the optout flag the cost is half
   8673 		 * that of the cost of generating a completely new chain.
   8674 		 */
   8675 		signatures -= 4;
   8676 
   8677 		/*
   8678 		 * Go onto next node.
   8679 		 */
   8680 	next_addnode:
   8681 		first = false;
   8682 		dns_db_detachnode(db, &node);
   8683 		do {
   8684 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8685 
   8686 			if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
   8687 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8688 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8689 						       false, privatetype,
   8690 						       &param_diff));
   8691 				LOCK_ZONE(zone);
   8692 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8693 						link);
   8694 				UNLOCK_ZONE(zone);
   8695 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8696 				goto next_addchain;
   8697 			}
   8698 			if (result == ISC_R_NOMORE) {
   8699 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8700 				if (nsec3chain->seen_nsec) {
   8701 					CHECK(fixup_nsec3param(
   8702 						db, version, nsec3chain, true,
   8703 						privatetype, &param_diff));
   8704 					nsec3chain->delete_nsec = true;
   8705 					goto same_addchain;
   8706 				}
   8707 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8708 						       false, privatetype,
   8709 						       &param_diff));
   8710 				LOCK_ZONE(zone);
   8711 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8712 						link);
   8713 				UNLOCK_ZONE(zone);
   8714 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8715 				goto next_addchain;
   8716 			} else if (result != ISC_R_SUCCESS) {
   8717 				dnssec_log(zone, ISC_LOG_ERROR,
   8718 					   "zone_nsec3chain:"
   8719 					   "dns_dbiterator_next -> %s",
   8720 					   isc_result_totext(result));
   8721 				goto failure;
   8722 			} else if (delegation) {
   8723 				dns_dbiterator_current(nsec3chain->dbiterator,
   8724 						       &node, nextname);
   8725 				dns_db_detachnode(db, &node);
   8726 				if (!dns_name_issubdomain(nextname, name)) {
   8727 					break;
   8728 				}
   8729 			} else {
   8730 				break;
   8731 			}
   8732 		} while (1);
   8733 		continue;
   8734 
   8735 	same_addchain:
   8736 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8737 		first = true;
   8738 		continue;
   8739 
   8740 	next_addchain:
   8741 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8742 		nsec3chain = nextnsec3chain;
   8743 		first = true;
   8744 		if (nsec3chain != NULL) {
   8745 			nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8746 		}
   8747 	}
   8748 
   8749 	if (nsec3chain != NULL) {
   8750 		goto skip_removals;
   8751 	}
   8752 
   8753 	/*
   8754 	 * Process removals.
   8755 	 *
   8756 	 * This is a counterpart of the above while loop which takes care of
   8757 	 * removing an NSEC3 chain.  It starts with determining whether the
   8758 	 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an
   8759 	 * NSEC chain by iterating over all nodes in the zone database and only
   8760 	 * then goes on to remove NSEC3 records be iterating over all nodes
   8761 	 * again and calling deletematchingnsec3() for each of them; otherwise,
   8762 	 * it starts removing NSEC3 records immediately.  Rules for processing
   8763 	 * obscured nodes and interrupting work are the same as for the while
   8764 	 * loop above.
   8765 	 */
   8766 	LOCK_ZONE(zone);
   8767 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8768 	UNLOCK_ZONE(zone);
   8769 	first = true;
   8770 	buildnsecchain = false;
   8771 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8772 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8773 
   8774 		LOCK_ZONE(zone);
   8775 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8776 		UNLOCK_ZONE(zone);
   8777 
   8778 		if (nsec3chain->db != db) {
   8779 			goto next_removechain;
   8780 		}
   8781 
   8782 		if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8783 			goto next_removechain;
   8784 		}
   8785 
   8786 		/*
   8787 		 * Work out if we need to build a NSEC chain as a consequence
   8788 		 * of removing this NSEC3 chain.
   8789 		 */
   8790 		if (first && !updatensec &&
   8791 		    (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
   8792 		{
   8793 			result = need_nsec_chain(db, version,
   8794 						 &nsec3chain->nsec3param,
   8795 						 &buildnsecchain);
   8796 			if (result != ISC_R_SUCCESS) {
   8797 				dnssec_log(zone, ISC_LOG_ERROR,
   8798 					   "zone_nsec3chain:"
   8799 					   "need_nsec_chain -> %s",
   8800 					   isc_result_totext(result));
   8801 				goto failure;
   8802 			}
   8803 		}
   8804 
   8805 		if (first) {
   8806 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   8807 				   "zone_nsec3chain:buildnsecchain = %u\n",
   8808 				   buildnsecchain);
   8809 		}
   8810 
   8811 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8812 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8813 		delegation = false;
   8814 
   8815 		if (!buildnsecchain) {
   8816 			/*
   8817 			 * Delete the NSEC3PARAM record matching this chain.
   8818 			 */
   8819 			if (first) {
   8820 				result = fixup_nsec3param(
   8821 					db, version, nsec3chain, true,
   8822 					privatetype, &param_diff);
   8823 				if (result != ISC_R_SUCCESS) {
   8824 					dnssec_log(zone, ISC_LOG_ERROR,
   8825 						   "zone_nsec3chain:"
   8826 						   "fixup_nsec3param -> %s",
   8827 						   isc_result_totext(result));
   8828 					goto failure;
   8829 				}
   8830 			}
   8831 
   8832 			/*
   8833 			 * Delete the NSEC3 records.
   8834 			 */
   8835 			result = deletematchingnsec3(db, version, node, name,
   8836 						     &nsec3chain->nsec3param,
   8837 						     &nsec3_diff);
   8838 			if (result != ISC_R_SUCCESS) {
   8839 				dnssec_log(zone, ISC_LOG_ERROR,
   8840 					   "zone_nsec3chain:"
   8841 					   "deletematchingnsec3 -> %s",
   8842 					   isc_result_totext(result));
   8843 				goto failure;
   8844 			}
   8845 			goto next_removenode;
   8846 		}
   8847 
   8848 		if (first) {
   8849 			dns_fixedname_t ffound;
   8850 			dns_name_t *found;
   8851 			found = dns_fixedname_initname(&ffound);
   8852 			result = dns_db_find(
   8853 				db, name, version, dns_rdatatype_soa,
   8854 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8855 			if ((result == DNS_R_DELEGATION ||
   8856 			     result == DNS_R_DNAME) &&
   8857 			    !dns_name_equal(name, found))
   8858 			{
   8859 				/*
   8860 				 * Remember the obscuring name so that
   8861 				 * we skip all obscured names.
   8862 				 */
   8863 				dns_name_copy(found, name);
   8864 				delegation = true;
   8865 				goto next_removenode;
   8866 			}
   8867 		}
   8868 
   8869 		/*
   8870 		 * Check to see if this is a bottom of zone node.
   8871 		 */
   8872 		result = dns_db_allrdatasets(db, node, version, 0, 0,
   8873 					     &iterator);
   8874 		if (result == ISC_R_NOTFOUND) {
   8875 			/* Empty node? */
   8876 			goto next_removenode;
   8877 		}
   8878 		if (result != ISC_R_SUCCESS) {
   8879 			goto failure;
   8880 		}
   8881 
   8882 		seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
   8883 			seen_rr = false;
   8884 		for (result = dns_rdatasetiter_first(iterator);
   8885 		     result == ISC_R_SUCCESS;
   8886 		     result = dns_rdatasetiter_next(iterator))
   8887 		{
   8888 			dns_rdatasetiter_current(iterator, &rdataset);
   8889 			if (rdataset.type == dns_rdatatype_soa) {
   8890 				seen_soa = true;
   8891 			} else if (rdataset.type == dns_rdatatype_ns) {
   8892 				seen_ns = true;
   8893 			} else if (rdataset.type == dns_rdatatype_dname) {
   8894 				seen_dname = true;
   8895 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8896 				seen_nsec = true;
   8897 			} else if (rdataset.type == dns_rdatatype_nsec3) {
   8898 				seen_nsec3 = true;
   8899 			} else if (rdataset.type != dns_rdatatype_rrsig) {
   8900 				seen_rr = true;
   8901 			}
   8902 			dns_rdataset_disassociate(&rdataset);
   8903 		}
   8904 		dns_rdatasetiter_destroy(&iterator);
   8905 
   8906 		if (!seen_rr || seen_nsec3 || seen_nsec) {
   8907 			goto next_removenode;
   8908 		}
   8909 		if ((seen_ns && !seen_soa) || seen_dname) {
   8910 			delegation = true;
   8911 		}
   8912 
   8913 		/*
   8914 		 * Add a NSEC record except at the origin.
   8915 		 */
   8916 		if (!dns_name_equal(name, dns_db_origin(db))) {
   8917 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8918 			CHECK(add_nsec(db, version, name, node,
   8919 				       zone_nsecttl(zone), delegation,
   8920 				       &nsec_diff));
   8921 			signatures--;
   8922 		}
   8923 
   8924 	next_removenode:
   8925 		first = false;
   8926 		dns_db_detachnode(db, &node);
   8927 		do {
   8928 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8929 			if (result == ISC_R_NOMORE && buildnsecchain) {
   8930 				/*
   8931 				 * The NSEC chain should now be built.
   8932 				 * We can now remove the NSEC3 chain.
   8933 				 */
   8934 				updatensec = true;
   8935 				goto same_removechain;
   8936 			}
   8937 			if (result == ISC_R_NOMORE) {
   8938 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8939 				LOCK_ZONE(zone);
   8940 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8941 						link);
   8942 				UNLOCK_ZONE(zone);
   8943 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8944 				result = fixup_nsec3param(
   8945 					db, version, nsec3chain, false,
   8946 					privatetype, &param_diff);
   8947 				if (result != ISC_R_SUCCESS) {
   8948 					dnssec_log(zone, ISC_LOG_ERROR,
   8949 						   "zone_nsec3chain:"
   8950 						   "fixup_nsec3param -> %s",
   8951 						   isc_result_totext(result));
   8952 					goto failure;
   8953 				}
   8954 				goto next_removechain;
   8955 			} else if (result != ISC_R_SUCCESS) {
   8956 				dnssec_log(zone, ISC_LOG_ERROR,
   8957 					   "zone_nsec3chain:"
   8958 					   "dns_dbiterator_next -> %s",
   8959 					   isc_result_totext(result));
   8960 				goto failure;
   8961 			} else if (delegation) {
   8962 				dns_dbiterator_current(nsec3chain->dbiterator,
   8963 						       &node, nextname);
   8964 				dns_db_detachnode(db, &node);
   8965 				if (!dns_name_issubdomain(nextname, name)) {
   8966 					break;
   8967 				}
   8968 			} else {
   8969 				break;
   8970 			}
   8971 		} while (1);
   8972 		continue;
   8973 
   8974 	same_removechain:
   8975 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8976 		buildnsecchain = false;
   8977 		first = true;
   8978 		continue;
   8979 
   8980 	next_removechain:
   8981 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8982 		nsec3chain = nextnsec3chain;
   8983 		first = true;
   8984 	}
   8985 
   8986 skip_removals:
   8987 	/*
   8988 	 * We may need to update the NSEC/NSEC3 records for the zone apex.
   8989 	 */
   8990 	if (!ISC_LIST_EMPTY(param_diff.tuples)) {
   8991 		bool rebuild_nsec = false, rebuild_nsec3 = false;
   8992 		result = dns_db_getoriginnode(db, &node);
   8993 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8994 		result = dns_db_allrdatasets(db, node, version, 0, 0,
   8995 					     &iterator);
   8996 		if (result != ISC_R_SUCCESS) {
   8997 			dnssec_log(zone, ISC_LOG_ERROR,
   8998 				   "zone_nsec3chain:dns_db_allrdatasets -> %s",
   8999 				   isc_result_totext(result));
   9000 			goto failure;
   9001 		}
   9002 		for (result = dns_rdatasetiter_first(iterator);
   9003 		     result == ISC_R_SUCCESS;
   9004 		     result = dns_rdatasetiter_next(iterator))
   9005 		{
   9006 			dns_rdatasetiter_current(iterator, &rdataset);
   9007 			if (rdataset.type == dns_rdatatype_nsec) {
   9008 				rebuild_nsec = true;
   9009 			} else if (rdataset.type == dns_rdatatype_nsec3param) {
   9010 				rebuild_nsec3 = true;
   9011 			}
   9012 			dns_rdataset_disassociate(&rdataset);
   9013 		}
   9014 		dns_rdatasetiter_destroy(&iterator);
   9015 		dns_db_detachnode(db, &node);
   9016 
   9017 		if (rebuild_nsec) {
   9018 			if (nsec3chain != NULL) {
   9019 				dns_dbiterator_pause(nsec3chain->dbiterator);
   9020 			}
   9021 
   9022 			result = updatesecure(db, version, &zone->origin,
   9023 					      zone_nsecttl(zone), true,
   9024 					      &nsec_diff);
   9025 			if (result != ISC_R_SUCCESS) {
   9026 				dnssec_log(zone, ISC_LOG_ERROR,
   9027 					   "zone_nsec3chain:updatesecure -> %s",
   9028 					   isc_result_totext(result));
   9029 				goto failure;
   9030 			}
   9031 		}
   9032 
   9033 		if (rebuild_nsec3) {
   9034 			if (nsec3chain != NULL) {
   9035 				dns_dbiterator_pause(nsec3chain->dbiterator);
   9036 			}
   9037 
   9038 			result = dns_nsec3_addnsec3s(
   9039 				db, version, dns_db_origin(db),
   9040 				zone_nsecttl(zone), false, &nsec3_diff);
   9041 			if (result != ISC_R_SUCCESS) {
   9042 				dnssec_log(zone, ISC_LOG_ERROR,
   9043 					   "zone_nsec3chain:"
   9044 					   "dns_nsec3_addnsec3s -> %s",
   9045 					   isc_result_totext(result));
   9046 				goto failure;
   9047 			}
   9048 		}
   9049 	}
   9050 
   9051 	/*
   9052 	 * Add / update signatures for the NSEC3 records.
   9053 	 */
   9054 	if (nsec3chain != NULL) {
   9055 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9056 	}
   9057 	result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys,
   9058 				      nkeys, zone, inception, expire, 0, now,
   9059 				      check_ksk, keyset_kskonly, &zonediff);
   9060 	if (result != ISC_R_SUCCESS) {
   9061 		dnssec_log(zone, ISC_LOG_ERROR,
   9062 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   9063 			   isc_result_totext(result));
   9064 		goto failure;
   9065 	}
   9066 
   9067 	/*
   9068 	 * We have changed the NSEC3PARAM or private RRsets
   9069 	 * above so we need to update the signatures.
   9070 	 */
   9071 	result = dns__zone_updatesigs(&param_diff, db, version, zone_keys,
   9072 				      nkeys, zone, inception, expire, 0, now,
   9073 				      check_ksk, keyset_kskonly, &zonediff);
   9074 	if (result != ISC_R_SUCCESS) {
   9075 		dnssec_log(zone, ISC_LOG_ERROR,
   9076 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   9077 			   isc_result_totext(result));
   9078 		goto failure;
   9079 	}
   9080 
   9081 	if (updatensec) {
   9082 		result = updatesecure(db, version, &zone->origin,
   9083 				      zone_nsecttl(zone), false, &nsec_diff);
   9084 		if (result != ISC_R_SUCCESS) {
   9085 			dnssec_log(zone, ISC_LOG_ERROR,
   9086 				   "zone_nsec3chain:updatesecure -> %s",
   9087 				   isc_result_totext(result));
   9088 			goto failure;
   9089 		}
   9090 	}
   9091 
   9092 	result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys,
   9093 				      zone, inception, expire, 0, now,
   9094 				      check_ksk, keyset_kskonly, &zonediff);
   9095 	if (result != ISC_R_SUCCESS) {
   9096 		dnssec_log(zone, ISC_LOG_ERROR,
   9097 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   9098 			   isc_result_totext(result));
   9099 		goto failure;
   9100 	}
   9101 
   9102 	/*
   9103 	 * If we made no effective changes to the zone then we can just
   9104 	 * cleanup otherwise we need to increment the serial.
   9105 	 */
   9106 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   9107 		/*
   9108 		 * No need to call dns_db_closeversion() here as it is
   9109 		 * called with commit = true below.
   9110 		 */
   9111 		goto done;
   9112 	}
   9113 
   9114 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   9115 			  &zonediff, zone_keys, nkeys, now, false);
   9116 	if (result != ISC_R_SUCCESS) {
   9117 		dnssec_log(zone, ISC_LOG_ERROR,
   9118 			   "zone_nsec3chain:del_sigs -> %s",
   9119 			   isc_result_totext(result));
   9120 		goto failure;
   9121 	}
   9122 
   9123 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   9124 				   zone->updatemethod);
   9125 	if (result != ISC_R_SUCCESS) {
   9126 		dnssec_log(zone, ISC_LOG_ERROR,
   9127 			   "zone_nsec3chain:update_soa_serial -> %s",
   9128 			   isc_result_totext(result));
   9129 		goto failure;
   9130 	}
   9131 
   9132 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   9133 			  zonediff.diff, zone_keys, nkeys, zone->mctx, now,
   9134 			  inception, soaexpire, check_ksk, keyset_kskonly);
   9135 	if (result != ISC_R_SUCCESS) {
   9136 		dnssec_log(zone, ISC_LOG_ERROR,
   9137 			   "zone_nsec3chain:add_sigs -> %s",
   9138 			   isc_result_totext(result));
   9139 		goto failure;
   9140 	}
   9141 
   9142 	/* Write changes to journal file. */
   9143 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
   9144 
   9145 	LOCK_ZONE(zone);
   9146 	zone_needdump(zone, DNS_DUMP_DELAY);
   9147 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   9148 	UNLOCK_ZONE(zone);
   9149 
   9150 done:
   9151 	/*
   9152 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   9153 	 */
   9154 	LOCK_ZONE(zone);
   9155 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   9156 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   9157 	{
   9158 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9159 	}
   9160 	UNLOCK_ZONE(zone);
   9161 
   9162 	/*
   9163 	 * Everything has succeeded. Commit the changes.
   9164 	 * Unconditionally commit as zonediff.offline not checked above.
   9165 	 */
   9166 	dns_db_closeversion(db, &version, true);
   9167 
   9168 	/*
   9169 	 * Everything succeeded so we can clean these up now.
   9170 	 */
   9171 	nsec3chain = ISC_LIST_HEAD(cleanup);
   9172 	while (nsec3chain != NULL) {
   9173 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   9174 		dns_db_detach(&nsec3chain->db);
   9175 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9176 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9177 		nsec3chain = ISC_LIST_HEAD(cleanup);
   9178 	}
   9179 
   9180 	LOCK_ZONE(zone);
   9181 	set_resigntime(zone);
   9182 	UNLOCK_ZONE(zone);
   9183 
   9184 failure:
   9185 	if (result != ISC_R_SUCCESS) {
   9186 		dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
   9187 			   isc_result_totext(result));
   9188 	}
   9189 
   9190 	/*
   9191 	 * On error roll back the current nsec3chain.
   9192 	 */
   9193 	if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
   9194 		if (nsec3chain->done) {
   9195 			dns_db_detach(&nsec3chain->db);
   9196 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9197 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9198 		} else {
   9199 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9200 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9201 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9202 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9203 		}
   9204 	}
   9205 
   9206 	/*
   9207 	 * Rollback the cleanup list.
   9208 	 */
   9209 	nsec3chain = ISC_LIST_TAIL(cleanup);
   9210 	while (nsec3chain != NULL) {
   9211 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   9212 		if (nsec3chain->done) {
   9213 			dns_db_detach(&nsec3chain->db);
   9214 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9215 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9216 		} else {
   9217 			LOCK_ZONE(zone);
   9218 			ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
   9219 			UNLOCK_ZONE(zone);
   9220 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9221 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9222 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9223 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9224 		}
   9225 		nsec3chain = ISC_LIST_TAIL(cleanup);
   9226 	}
   9227 
   9228 	LOCK_ZONE(zone);
   9229 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   9230 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   9231 	{
   9232 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9233 	}
   9234 	UNLOCK_ZONE(zone);
   9235 
   9236 	dns_diff_clear(&param_diff);
   9237 	dns_diff_clear(&nsec3_diff);
   9238 	dns_diff_clear(&nsec_diff);
   9239 	dns_diff_clear(&_sig_diff);
   9240 
   9241 	if (iterator != NULL) {
   9242 		dns_rdatasetiter_destroy(&iterator);
   9243 	}
   9244 
   9245 	for (i = 0; i < nkeys; i++) {
   9246 		dst_key_free(&zone_keys[i]);
   9247 	}
   9248 
   9249 	if (node != NULL) {
   9250 		dns_db_detachnode(db, &node);
   9251 	}
   9252 	if (version != NULL) {
   9253 		dns_db_closeversion(db, &version, false);
   9254 		dns_db_detach(&db);
   9255 	} else if (db != NULL) {
   9256 		dns_db_detach(&db);
   9257 	}
   9258 
   9259 	LOCK_ZONE(zone);
   9260 	if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
   9261 		isc_interval_t interval;
   9262 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   9263 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   9264 		} else {
   9265 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   9266 		}
   9267 		isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
   9268 	} else {
   9269 		isc_time_settoepoch(&zone->nsec3chaintime);
   9270 	}
   9271 	UNLOCK_ZONE(zone);
   9272 
   9273 	INSIST(version == NULL);
   9274 }
   9275 
   9276 /*%
   9277  * Delete all RRSIG records with the given algorithm and keyid.
   9278  * Remove the NSEC record and RRSIGs if nkeys is zero.
   9279  * If all remaining RRsets are signed with the given algorithm
   9280  * set *has_algp to true.
   9281  */
   9282 static isc_result_t
   9283 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   9284 	dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
   9285 	uint16_t keyid, bool *has_algp, dns_diff_t *diff) {
   9286 	dns_rdata_rrsig_t rrsig;
   9287 	dns_rdataset_t rdataset;
   9288 	dns_rdatasetiter_t *iterator = NULL;
   9289 	isc_result_t result;
   9290 	bool alg_missed = false;
   9291 	bool alg_found = false;
   9292 
   9293 	char namebuf[DNS_NAME_FORMATSIZE];
   9294 	dns_name_format(name, namebuf, sizeof(namebuf));
   9295 
   9296 	result = dns_db_allrdatasets(db, node, version, 0, 0, &iterator);
   9297 	if (result != ISC_R_SUCCESS) {
   9298 		if (result == ISC_R_NOTFOUND) {
   9299 			result = ISC_R_SUCCESS;
   9300 		}
   9301 		return (result);
   9302 	}
   9303 
   9304 	dns_rdataset_init(&rdataset);
   9305 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   9306 	     result = dns_rdatasetiter_next(iterator))
   9307 	{
   9308 		bool has_alg = false;
   9309 		dns_rdatasetiter_current(iterator, &rdataset);
   9310 		if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
   9311 			for (result = dns_rdataset_first(&rdataset);
   9312 			     result == ISC_R_SUCCESS;
   9313 			     result = dns_rdataset_next(&rdataset))
   9314 			{
   9315 				dns_rdata_t rdata = DNS_RDATA_INIT;
   9316 				dns_rdataset_current(&rdataset, &rdata);
   9317 				CHECK(update_one_rr(db, version, diff,
   9318 						    DNS_DIFFOP_DEL, name,
   9319 						    rdataset.ttl, &rdata));
   9320 			}
   9321 			if (result != ISC_R_NOMORE) {
   9322 				goto failure;
   9323 			}
   9324 			dns_rdataset_disassociate(&rdataset);
   9325 			continue;
   9326 		}
   9327 		if (rdataset.type != dns_rdatatype_rrsig) {
   9328 			dns_rdataset_disassociate(&rdataset);
   9329 			continue;
   9330 		}
   9331 		for (result = dns_rdataset_first(&rdataset);
   9332 		     result == ISC_R_SUCCESS;
   9333 		     result = dns_rdataset_next(&rdataset))
   9334 		{
   9335 			dns_rdata_t rdata = DNS_RDATA_INIT;
   9336 			dns_rdataset_current(&rdataset, &rdata);
   9337 			CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
   9338 			if (nkeys != 0 && (rrsig.algorithm != algorithm ||
   9339 					   rrsig.keyid != keyid))
   9340 			{
   9341 				if (rrsig.algorithm == algorithm) {
   9342 					has_alg = true;
   9343 				}
   9344 				continue;
   9345 			}
   9346 			CHECK(update_one_rr(db, version, diff,
   9347 					    DNS_DIFFOP_DELRESIGN, name,
   9348 					    rdataset.ttl, &rdata));
   9349 		}
   9350 		dns_rdataset_disassociate(&rdataset);
   9351 		if (result != ISC_R_NOMORE) {
   9352 			break;
   9353 		}
   9354 
   9355 		/*
   9356 		 * After deleting, if there's still a signature for
   9357 		 * 'algorithm', set alg_found; if not, set alg_missed.
   9358 		 */
   9359 		if (has_alg) {
   9360 			alg_found = true;
   9361 		} else {
   9362 			alg_missed = true;
   9363 		}
   9364 	}
   9365 	if (result == ISC_R_NOMORE) {
   9366 		result = ISC_R_SUCCESS;
   9367 	}
   9368 
   9369 	/*
   9370 	 * Set `has_algp` if the algorithm was found in every RRset:
   9371 	 * i.e., found in at least one, and not missing from any.
   9372 	 */
   9373 	*has_algp = (alg_found && !alg_missed);
   9374 failure:
   9375 	if (dns_rdataset_isassociated(&rdataset)) {
   9376 		dns_rdataset_disassociate(&rdataset);
   9377 	}
   9378 	dns_rdatasetiter_destroy(&iterator);
   9379 	return (result);
   9380 }
   9381 
   9382 /*
   9383  * Prevent the zone entering a inconsistent state where
   9384  * NSEC only DNSKEYs are present with NSEC3 chains.
   9385  */
   9386 bool
   9387 dns_zone_check_dnskey_nsec3(dns_zone_t *zone, dns_db_t *db,
   9388 			    dns_dbversion_t *ver, dns_diff_t *diff,
   9389 			    dst_key_t **keys, unsigned int numkeys) {
   9390 	uint8_t alg;
   9391 	dns_rdatatype_t privatetype;
   9392 	;
   9393 	bool nseconly = false, nsec3 = false;
   9394 	isc_result_t result;
   9395 
   9396 	REQUIRE(DNS_ZONE_VALID(zone));
   9397 	REQUIRE(db != NULL);
   9398 
   9399 	privatetype = dns_zone_getprivatetype(zone);
   9400 
   9401 	/* Scan the tuples for an NSEC-only DNSKEY */
   9402 	if (diff != NULL) {
   9403 		for (dns_difftuple_t *tuple = ISC_LIST_HEAD(diff->tuples);
   9404 		     tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link))
   9405 		{
   9406 			if (nseconly && nsec3) {
   9407 				break;
   9408 			}
   9409 
   9410 			if (tuple->op != DNS_DIFFOP_ADD) {
   9411 				continue;
   9412 			}
   9413 
   9414 			if (tuple->rdata.type == dns_rdatatype_nsec3param) {
   9415 				nsec3 = true;
   9416 			}
   9417 
   9418 			if (tuple->rdata.type != dns_rdatatype_dnskey) {
   9419 				continue;
   9420 			}
   9421 
   9422 			alg = tuple->rdata.data[3];
   9423 			if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DH ||
   9424 			    alg == DNS_KEYALG_DSA || alg == DNS_KEYALG_RSASHA1)
   9425 			{
   9426 				nseconly = true;
   9427 			}
   9428 		}
   9429 	}
   9430 	/* Scan the zone keys for an NSEC-only DNSKEY */
   9431 	if (keys != NULL && !nseconly) {
   9432 		for (unsigned int i = 0; i < numkeys; i++) {
   9433 			alg = dst_key_alg(keys[i]);
   9434 			if (alg == DNS_KEYALG_RSAMD5 || alg == DNS_KEYALG_DH ||
   9435 			    alg == DNS_KEYALG_DSA || alg == DNS_KEYALG_RSASHA1)
   9436 			{
   9437 				nseconly = true;
   9438 				break;
   9439 			}
   9440 		}
   9441 	}
   9442 
   9443 	/* Check DB for NSEC-only DNSKEY */
   9444 	if (!nseconly) {
   9445 		result = dns_nsec_nseconly(db, ver, diff, &nseconly);
   9446 		/*
   9447 		 * Adding an NSEC3PARAM record can proceed without a
   9448 		 * DNSKEY (it will trigger a delayed change), so we can
   9449 		 * ignore ISC_R_NOTFOUND here.
   9450 		 */
   9451 		if (result == ISC_R_NOTFOUND) {
   9452 			result = ISC_R_SUCCESS;
   9453 		}
   9454 		CHECK(result);
   9455 	}
   9456 
   9457 	/* Check existing DB for NSEC3 */
   9458 	if (!nsec3) {
   9459 		CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3));
   9460 	}
   9461 
   9462 	/* Check kasp for NSEC3PARAM settings */
   9463 	if (!nsec3) {
   9464 		dns_kasp_t *kasp = dns_zone_getkasp(zone);
   9465 		if (kasp != NULL) {
   9466 			nsec3 = dns_kasp_nsec3(kasp);
   9467 		}
   9468 	}
   9469 
   9470 	/* Refuse to allow NSEC3 with NSEC-only keys */
   9471 	if (nseconly && nsec3) {
   9472 		goto failure;
   9473 	}
   9474 
   9475 	return (true);
   9476 
   9477 failure:
   9478 	return (false);
   9479 }
   9480 
   9481 /*
   9482  * Incrementally sign the zone using the keys requested.
   9483  * Builds the NSEC chain if required.
   9484  */
   9485 static void
   9486 zone_sign(dns_zone_t *zone) {
   9487 	const char *me = "zone_sign";
   9488 	dns_db_t *db = NULL;
   9489 	dns_dbnode_t *node = NULL;
   9490 	dns_dbversion_t *version = NULL;
   9491 	dns_diff_t _sig_diff;
   9492 	dns_diff_t post_diff;
   9493 	dns__zonediff_t zonediff;
   9494 	dns_fixedname_t fixed;
   9495 	dns_fixedname_t nextfixed;
   9496 	dns_kasp_t *kasp;
   9497 	dns_name_t *name, *nextname;
   9498 	dns_rdataset_t rdataset;
   9499 	dns_signing_t *signing, *nextsigning;
   9500 	dns_signinglist_t cleanup;
   9501 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   9502 	int32_t signatures;
   9503 	bool check_ksk, keyset_kskonly, is_ksk, is_zsk;
   9504 	bool with_ksk, with_zsk;
   9505 	bool commit = false;
   9506 	bool is_bottom_of_zone;
   9507 	bool build_nsec = false;
   9508 	bool build_nsec3 = false;
   9509 	bool use_kasp = false;
   9510 	bool first;
   9511 	isc_result_t result;
   9512 	isc_stdtime_t now, inception, soaexpire, expire;
   9513 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   9514 	unsigned int i, j;
   9515 	unsigned int nkeys = 0;
   9516 	uint32_t nodes;
   9517 
   9518 	ENTER;
   9519 
   9520 	dns_rdataset_init(&rdataset);
   9521 	name = dns_fixedname_initname(&fixed);
   9522 	nextname = dns_fixedname_initname(&nextfixed);
   9523 	dns_diff_init(zone->mctx, &_sig_diff);
   9524 	dns_diff_init(zone->mctx, &post_diff);
   9525 	zonediff_init(&zonediff, &_sig_diff);
   9526 	ISC_LIST_INIT(cleanup);
   9527 
   9528 	/*
   9529 	 * Updates are disabled.  Pause for 1 minute.
   9530 	 */
   9531 	if (zone->update_disabled) {
   9532 		result = ISC_R_FAILURE;
   9533 		goto cleanup;
   9534 	}
   9535 
   9536 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9537 	if (zone->db != NULL) {
   9538 		dns_db_attach(zone->db, &db);
   9539 	}
   9540 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9541 	if (db == NULL) {
   9542 		result = ISC_R_FAILURE;
   9543 		goto cleanup;
   9544 	}
   9545 
   9546 	result = dns_db_newversion(db, &version);
   9547 	if (result != ISC_R_SUCCESS) {
   9548 		dnssec_log(zone, ISC_LOG_ERROR,
   9549 			   "zone_sign:dns_db_newversion -> %s",
   9550 			   isc_result_totext(result));
   9551 		goto cleanup;
   9552 	}
   9553 
   9554 	isc_stdtime_get(&now);
   9555 
   9556 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   9557 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   9558 	if (result != ISC_R_SUCCESS) {
   9559 		dnssec_log(zone, ISC_LOG_ERROR,
   9560 			   "zone_sign:dns__zone_findkeys -> %s",
   9561 			   isc_result_totext(result));
   9562 		goto cleanup;
   9563 	}
   9564 
   9565 	kasp = dns_zone_getkasp(zone);
   9566 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   9567 	inception = now - 3600; /* Allow for clock skew. */
   9568 	soaexpire = now + sigvalidityinterval;
   9569 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   9570 	if (expiryinterval > sigvalidityinterval) {
   9571 		expiryinterval = sigvalidityinterval;
   9572 	} else {
   9573 		expiryinterval = sigvalidityinterval - expiryinterval;
   9574 	}
   9575 
   9576 	/*
   9577 	 * Spread out signatures over time if they happen to be
   9578 	 * clumped.  We don't do this for each add_sigs() call as
   9579 	 * we still want some clustering to occur.
   9580 	 */
   9581 	if (sigvalidityinterval >= 3600U) {
   9582 		if (sigvalidityinterval > 7200U) {
   9583 			jitter = isc_random_uniform(expiryinterval);
   9584 		} else {
   9585 			jitter = isc_random_uniform(1200);
   9586 		}
   9587 		expire = soaexpire - jitter - 1;
   9588 	} else {
   9589 		expire = soaexpire - 1;
   9590 	}
   9591 
   9592 	/*
   9593 	 * We keep pulling nodes off each iterator in turn until
   9594 	 * we have no more nodes to pull off or we reach the limits
   9595 	 * for this quantum.
   9596 	 */
   9597 	nodes = zone->nodes;
   9598 	signatures = zone->signatures;
   9599 	signing = ISC_LIST_HEAD(zone->signing);
   9600 	first = true;
   9601 
   9602 	if (dns_zone_getkasp(zone) != NULL) {
   9603 		check_ksk = false;
   9604 		keyset_kskonly = true;
   9605 		use_kasp = true;
   9606 	} else {
   9607 		check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   9608 		keyset_kskonly = DNS_ZONE_OPTION(zone,
   9609 						 DNS_ZONEOPT_DNSKEYKSKONLY);
   9610 	}
   9611 	dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s",
   9612 		   use_kasp ? "yes" : "no");
   9613 
   9614 	/* Determine which type of chain to build */
   9615 	CHECK(dns_private_chains(db, version, zone->privatetype, &build_nsec,
   9616 				 &build_nsec3));
   9617 	if (!build_nsec && !build_nsec3) {
   9618 		if (use_kasp) {
   9619 			build_nsec3 = dns_kasp_nsec3(kasp);
   9620 			if (!dns_zone_check_dnskey_nsec3(
   9621 				    zone, db, version, NULL,
   9622 				    (dst_key_t **)&zone_keys, nkeys))
   9623 			{
   9624 				dnssec_log(zone, ISC_LOG_INFO,
   9625 					   "wait building NSEC3 chain until "
   9626 					   "NSEC only DNSKEYs are removed");
   9627 				build_nsec3 = false;
   9628 			}
   9629 			build_nsec = !build_nsec3;
   9630 		} else {
   9631 			/* If neither chain is found, default to NSEC */
   9632 			build_nsec = true;
   9633 		}
   9634 	}
   9635 
   9636 	while (signing != NULL && nodes-- > 0 && signatures > 0) {
   9637 		bool has_alg = false;
   9638 
   9639 		dns_dbiterator_pause(signing->dbiterator);
   9640 		nextsigning = ISC_LIST_NEXT(signing, link);
   9641 
   9642 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9643 		if (signing->done || signing->db != zone->db) {
   9644 			/*
   9645 			 * The zone has been reloaded.	We will have to
   9646 			 * created new signings as part of the reload
   9647 			 * process so we can destroy this one.
   9648 			 */
   9649 			ISC_LIST_UNLINK(zone->signing, signing, link);
   9650 			ISC_LIST_APPEND(cleanup, signing, link);
   9651 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9652 			goto next_signing;
   9653 		}
   9654 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9655 
   9656 		if (signing->db != db) {
   9657 			goto next_signing;
   9658 		}
   9659 
   9660 		is_bottom_of_zone = false;
   9661 
   9662 		if (first && signing->deleteit) {
   9663 			/*
   9664 			 * Remove the key we are deleting from consideration.
   9665 			 */
   9666 			for (i = 0, j = 0; i < nkeys; i++) {
   9667 				/*
   9668 				 * Find the key we want to remove.
   9669 				 */
   9670 				if (ALG(zone_keys[i]) == signing->algorithm &&
   9671 				    dst_key_id(zone_keys[i]) == signing->keyid)
   9672 				{
   9673 					dst_key_free(&zone_keys[i]);
   9674 					continue;
   9675 				}
   9676 				zone_keys[j] = zone_keys[i];
   9677 				j++;
   9678 			}
   9679 			for (i = j; i < nkeys; i++) {
   9680 				zone_keys[i] = NULL;
   9681 			}
   9682 			nkeys = j;
   9683 		}
   9684 
   9685 		dns_dbiterator_current(signing->dbiterator, &node, name);
   9686 
   9687 		if (signing->deleteit) {
   9688 			dns_dbiterator_pause(signing->dbiterator);
   9689 			CHECK(del_sig(db, version, name, node, nkeys,
   9690 				      signing->algorithm, signing->keyid,
   9691 				      &has_alg, zonediff.diff));
   9692 		}
   9693 
   9694 		/*
   9695 		 * On the first pass we need to check if the current node
   9696 		 * has not been obscured.
   9697 		 */
   9698 		if (first) {
   9699 			dns_fixedname_t ffound;
   9700 			dns_name_t *found;
   9701 			found = dns_fixedname_initname(&ffound);
   9702 			result = dns_db_find(
   9703 				db, name, version, dns_rdatatype_soa,
   9704 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   9705 			if ((result == DNS_R_DELEGATION ||
   9706 			     result == DNS_R_DNAME) &&
   9707 			    !dns_name_equal(name, found))
   9708 			{
   9709 				/*
   9710 				 * Remember the obscuring name so that
   9711 				 * we skip all obscured names.
   9712 				 */
   9713 				dns_name_copy(found, name);
   9714 				is_bottom_of_zone = true;
   9715 				goto next_node;
   9716 			}
   9717 		}
   9718 
   9719 		/*
   9720 		 * Process one node.
   9721 		 */
   9722 		with_ksk = false;
   9723 		with_zsk = false;
   9724 		dns_dbiterator_pause(signing->dbiterator);
   9725 
   9726 		CHECK(check_if_bottom_of_zone(db, node, version,
   9727 					      &is_bottom_of_zone));
   9728 
   9729 		for (i = 0; !has_alg && i < nkeys; i++) {
   9730 			bool both = false;
   9731 
   9732 			/*
   9733 			 * Find the keys we want to sign with.
   9734 			 */
   9735 			if (!dst_key_isprivate(zone_keys[i])) {
   9736 				continue;
   9737 			}
   9738 			if (dst_key_inactive(zone_keys[i])) {
   9739 				continue;
   9740 			}
   9741 
   9742 			/*
   9743 			 * When adding look for the specific key.
   9744 			 */
   9745 			if (!signing->deleteit &&
   9746 			    (dst_key_alg(zone_keys[i]) != signing->algorithm ||
   9747 			     dst_key_id(zone_keys[i]) != signing->keyid))
   9748 			{
   9749 				continue;
   9750 			}
   9751 
   9752 			/*
   9753 			 * When deleting make sure we are properly signed
   9754 			 * with the algorithm that was being removed.
   9755 			 */
   9756 			if (signing->deleteit &&
   9757 			    ALG(zone_keys[i]) != signing->algorithm)
   9758 			{
   9759 				continue;
   9760 			}
   9761 
   9762 			/*
   9763 			 * Do we do KSK processing?
   9764 			 */
   9765 			if (check_ksk && !REVOKE(zone_keys[i])) {
   9766 				bool have_ksk, have_nonksk;
   9767 				if (KSK(zone_keys[i])) {
   9768 					have_ksk = true;
   9769 					have_nonksk = false;
   9770 				} else {
   9771 					have_ksk = false;
   9772 					have_nonksk = true;
   9773 				}
   9774 				for (j = 0; j < nkeys; j++) {
   9775 					if (j == i || (ALG(zone_keys[i]) !=
   9776 						       ALG(zone_keys[j])))
   9777 					{
   9778 						continue;
   9779 					}
   9780 					/*
   9781 					 * Don't consider inactive keys, however
   9782 					 * the key may be temporary offline, so
   9783 					 * do consider KSKs which private key
   9784 					 * files are unavailable.
   9785 					 */
   9786 					if (dst_key_inactive(zone_keys[j])) {
   9787 						continue;
   9788 					}
   9789 					if (REVOKE(zone_keys[j])) {
   9790 						continue;
   9791 					}
   9792 					if (KSK(zone_keys[j])) {
   9793 						have_ksk = true;
   9794 					} else if (dst_key_isprivate(
   9795 							   zone_keys[j]))
   9796 					{
   9797 						have_nonksk = true;
   9798 					}
   9799 					both = have_ksk && have_nonksk;
   9800 					if (both) {
   9801 						break;
   9802 					}
   9803 				}
   9804 			}
   9805 			if (use_kasp) {
   9806 				/*
   9807 				 * A dnssec-policy is found. Check what
   9808 				 * RRsets this key can sign.
   9809 				 */
   9810 				isc_result_t kresult;
   9811 				is_ksk = false;
   9812 				kresult = dst_key_getbool(
   9813 					zone_keys[i], DST_BOOL_KSK, &is_ksk);
   9814 				if (kresult != ISC_R_SUCCESS) {
   9815 					if (KSK(zone_keys[i])) {
   9816 						is_ksk = true;
   9817 					}
   9818 				}
   9819 
   9820 				is_zsk = false;
   9821 				kresult = dst_key_getbool(
   9822 					zone_keys[i], DST_BOOL_ZSK, &is_zsk);
   9823 				if (kresult != ISC_R_SUCCESS) {
   9824 					if (!KSK(zone_keys[i])) {
   9825 						is_zsk = true;
   9826 					}
   9827 				}
   9828 				/* Treat as if we have both KSK and ZSK. */
   9829 				both = true;
   9830 			} else if (both || REVOKE(zone_keys[i])) {
   9831 				is_ksk = KSK(zone_keys[i]);
   9832 				is_zsk = !KSK(zone_keys[i]);
   9833 			} else {
   9834 				is_ksk = false;
   9835 				is_zsk = true;
   9836 			}
   9837 
   9838 			/*
   9839 			 * If deleting signatures, we need to ensure that
   9840 			 * the RRset is still signed at least once by a
   9841 			 * KSK and a ZSK.
   9842 			 */
   9843 			if (signing->deleteit && is_zsk && with_zsk) {
   9844 				continue;
   9845 			}
   9846 
   9847 			if (signing->deleteit && is_ksk && with_ksk) {
   9848 				continue;
   9849 			}
   9850 
   9851 			CHECK(sign_a_node(
   9852 				db, zone, name, node, version, build_nsec3,
   9853 				build_nsec, zone_keys[i], now, inception,
   9854 				expire, zone_nsecttl(zone), is_ksk, is_zsk,
   9855 				(both && keyset_kskonly), is_bottom_of_zone,
   9856 				zonediff.diff, &signatures, zone->mctx));
   9857 			/*
   9858 			 * If we are adding we are done.  Look for other keys
   9859 			 * of the same algorithm if deleting.
   9860 			 */
   9861 			if (!signing->deleteit) {
   9862 				break;
   9863 			}
   9864 			if (is_zsk) {
   9865 				with_zsk = true;
   9866 			}
   9867 			if (is_ksk) {
   9868 				with_ksk = true;
   9869 			}
   9870 		}
   9871 
   9872 		/*
   9873 		 * Go onto next node.
   9874 		 */
   9875 	next_node:
   9876 		first = false;
   9877 		dns_db_detachnode(db, &node);
   9878 		do {
   9879 			result = dns_dbiterator_next(signing->dbiterator);
   9880 			if (result == ISC_R_NOMORE) {
   9881 				ISC_LIST_UNLINK(zone->signing, signing, link);
   9882 				ISC_LIST_APPEND(cleanup, signing, link);
   9883 				dns_dbiterator_pause(signing->dbiterator);
   9884 				if (nkeys != 0 && build_nsec) {
   9885 					/*
   9886 					 * We have finished regenerating the
   9887 					 * zone with a zone signing key.
   9888 					 * The NSEC chain is now complete and
   9889 					 * there is a full set of signatures
   9890 					 * for the zone.  We can now clear the
   9891 					 * OPT bit from the NSEC record.
   9892 					 */
   9893 					result = updatesecure(
   9894 						db, version, &zone->origin,
   9895 						zone_nsecttl(zone), false,
   9896 						&post_diff);
   9897 					if (result != ISC_R_SUCCESS) {
   9898 						dnssec_log(zone, ISC_LOG_ERROR,
   9899 							   "updatesecure -> %s",
   9900 							   isc_result_totext(
   9901 								   result));
   9902 						goto cleanup;
   9903 					}
   9904 				}
   9905 				result = updatesignwithkey(
   9906 					zone, signing, version, build_nsec3,
   9907 					zone_nsecttl(zone), &post_diff);
   9908 				if (result != ISC_R_SUCCESS) {
   9909 					dnssec_log(zone, ISC_LOG_ERROR,
   9910 						   "updatesignwithkey -> %s",
   9911 						   isc_result_totext(result));
   9912 					goto cleanup;
   9913 				}
   9914 				build_nsec = false;
   9915 				goto next_signing;
   9916 			} else if (result != ISC_R_SUCCESS) {
   9917 				dnssec_log(zone, ISC_LOG_ERROR,
   9918 					   "zone_sign:"
   9919 					   "dns_dbiterator_next -> %s",
   9920 					   isc_result_totext(result));
   9921 				goto cleanup;
   9922 			} else if (is_bottom_of_zone) {
   9923 				dns_dbiterator_current(signing->dbiterator,
   9924 						       &node, nextname);
   9925 				dns_db_detachnode(db, &node);
   9926 				if (!dns_name_issubdomain(nextname, name)) {
   9927 					break;
   9928 				}
   9929 			} else {
   9930 				break;
   9931 			}
   9932 		} while (1);
   9933 		continue;
   9934 
   9935 	next_signing:
   9936 		dns_dbiterator_pause(signing->dbiterator);
   9937 		signing = nextsigning;
   9938 		first = true;
   9939 	}
   9940 
   9941 	if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
   9942 		result = dns__zone_updatesigs(&post_diff, db, version,
   9943 					      zone_keys, nkeys, zone, inception,
   9944 					      expire, 0, now, check_ksk,
   9945 					      keyset_kskonly, &zonediff);
   9946 		if (result != ISC_R_SUCCESS) {
   9947 			dnssec_log(zone, ISC_LOG_ERROR,
   9948 				   "zone_sign:dns__zone_updatesigs -> %s",
   9949 				   isc_result_totext(result));
   9950 			goto cleanup;
   9951 		}
   9952 	}
   9953 
   9954 	/*
   9955 	 * Have we changed anything?
   9956 	 */
   9957 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   9958 		if (zonediff.offline) {
   9959 			commit = true;
   9960 		}
   9961 		result = ISC_R_SUCCESS;
   9962 		goto pauseall;
   9963 	}
   9964 
   9965 	commit = true;
   9966 
   9967 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   9968 			  &zonediff, zone_keys, nkeys, now, false);
   9969 	if (result != ISC_R_SUCCESS) {
   9970 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s",
   9971 			   isc_result_totext(result));
   9972 		goto cleanup;
   9973 	}
   9974 
   9975 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   9976 				   zone->updatemethod);
   9977 	if (result != ISC_R_SUCCESS) {
   9978 		dnssec_log(zone, ISC_LOG_ERROR,
   9979 			   "zone_sign:update_soa_serial -> %s",
   9980 			   isc_result_totext(result));
   9981 		goto cleanup;
   9982 	}
   9983 
   9984 	/*
   9985 	 * Generate maximum life time signatures so that the above loop
   9986 	 * termination is sensible.
   9987 	 */
   9988 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   9989 			  zonediff.diff, zone_keys, nkeys, zone->mctx, now,
   9990 			  inception, soaexpire, check_ksk, keyset_kskonly);
   9991 	if (result != ISC_R_SUCCESS) {
   9992 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s",
   9993 			   isc_result_totext(result));
   9994 		goto cleanup;
   9995 	}
   9996 
   9997 	/*
   9998 	 * Write changes to journal file.
   9999 	 */
   10000 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
   10001 
   10002 pauseall:
   10003 	/*
   10004 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   10005 	 */
   10006 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   10007 	     signing = ISC_LIST_NEXT(signing, link))
   10008 	{
   10009 		dns_dbiterator_pause(signing->dbiterator);
   10010 	}
   10011 
   10012 	for (signing = ISC_LIST_HEAD(cleanup); signing != NULL;
   10013 	     signing = ISC_LIST_NEXT(signing, link))
   10014 	{
   10015 		dns_dbiterator_pause(signing->dbiterator);
   10016 	}
   10017 
   10018 	/*
   10019 	 * Everything has succeeded. Commit the changes.
   10020 	 */
   10021 	dns_db_closeversion(db, &version, commit);
   10022 
   10023 	/*
   10024 	 * Everything succeeded so we can clean these up now.
   10025 	 */
   10026 	signing = ISC_LIST_HEAD(cleanup);
   10027 	while (signing != NULL) {
   10028 		ISC_LIST_UNLINK(cleanup, signing, link);
   10029 		dns_db_detach(&signing->db);
   10030 		dns_dbiterator_destroy(&signing->dbiterator);
   10031 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   10032 		signing = ISC_LIST_HEAD(cleanup);
   10033 	}
   10034 
   10035 	LOCK_ZONE(zone);
   10036 	set_resigntime(zone);
   10037 	if (commit) {
   10038 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   10039 		zone_needdump(zone, DNS_DUMP_DELAY);
   10040 	}
   10041 	UNLOCK_ZONE(zone);
   10042 
   10043 failure:
   10044 	if (result != ISC_R_SUCCESS) {
   10045 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s",
   10046 			   isc_result_totext(result));
   10047 	}
   10048 
   10049 cleanup:
   10050 	/*
   10051 	 * Pause all dbiterators.
   10052 	 */
   10053 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   10054 	     signing = ISC_LIST_NEXT(signing, link))
   10055 	{
   10056 		dns_dbiterator_pause(signing->dbiterator);
   10057 	}
   10058 
   10059 	/*
   10060 	 * Rollback the cleanup list.
   10061 	 */
   10062 	signing = ISC_LIST_HEAD(cleanup);
   10063 	while (signing != NULL) {
   10064 		ISC_LIST_UNLINK(cleanup, signing, link);
   10065 		ISC_LIST_PREPEND(zone->signing, signing, link);
   10066 		dns_dbiterator_first(signing->dbiterator);
   10067 		dns_dbiterator_pause(signing->dbiterator);
   10068 		signing = ISC_LIST_HEAD(cleanup);
   10069 	}
   10070 
   10071 	dns_diff_clear(&_sig_diff);
   10072 
   10073 	for (i = 0; i < nkeys; i++) {
   10074 		dst_key_free(&zone_keys[i]);
   10075 	}
   10076 
   10077 	if (node != NULL) {
   10078 		dns_db_detachnode(db, &node);
   10079 	}
   10080 
   10081 	if (version != NULL) {
   10082 		dns_db_closeversion(db, &version, false);
   10083 		dns_db_detach(&db);
   10084 	} else if (db != NULL) {
   10085 		dns_db_detach(&db);
   10086 	}
   10087 
   10088 	LOCK_ZONE(zone);
   10089 	if (ISC_LIST_HEAD(zone->signing) != NULL) {
   10090 		isc_interval_t interval;
   10091 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   10092 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   10093 		} else {
   10094 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   10095 		}
   10096 		isc_time_nowplusinterval(&zone->signingtime, &interval);
   10097 	} else {
   10098 		isc_time_settoepoch(&zone->signingtime);
   10099 	}
   10100 	UNLOCK_ZONE(zone);
   10101 
   10102 	INSIST(version == NULL);
   10103 }
   10104 
   10105 static isc_result_t
   10106 normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data,
   10107 	      int size) {
   10108 	dns_rdata_dnskey_t dnskey;
   10109 	dns_rdata_keydata_t keydata;
   10110 	isc_buffer_t buf;
   10111 	isc_result_t result;
   10112 
   10113 	dns_rdata_reset(target);
   10114 	isc_buffer_init(&buf, data, size);
   10115 
   10116 	switch (rr->type) {
   10117 	case dns_rdatatype_dnskey:
   10118 		result = dns_rdata_tostruct(rr, &dnskey, NULL);
   10119 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10120 		dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
   10121 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   10122 				     &dnskey, &buf);
   10123 		break;
   10124 	case dns_rdatatype_keydata:
   10125 		result = dns_rdata_tostruct(rr, &keydata, NULL);
   10126 		if (result == ISC_R_UNEXPECTEDEND) {
   10127 			return (result);
   10128 		}
   10129 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10130 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   10131 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   10132 				     &dnskey, &buf);
   10133 		break;
   10134 	default:
   10135 		UNREACHABLE();
   10136 	}
   10137 	return (ISC_R_SUCCESS);
   10138 }
   10139 
   10140 /*
   10141  * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
   10142  * a KEYDATA rdataset from the key zone.
   10143  *
   10144  * 'rr' contains either a DNSKEY record, or a KEYDATA record
   10145  *
   10146  * After normalizing keys to the same format (DNSKEY, with revoke bit
   10147  * cleared), return true if a key that matches 'rr' is found in
   10148  * 'rdset', or false if not.
   10149  */
   10150 
   10151 static bool
   10152 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
   10153 	unsigned char data1[4096], data2[4096];
   10154 	dns_rdata_t rdata, rdata1, rdata2;
   10155 	isc_result_t result;
   10156 
   10157 	dns_rdata_init(&rdata);
   10158 	dns_rdata_init(&rdata1);
   10159 	dns_rdata_init(&rdata2);
   10160 
   10161 	result = normalize_key(rr, &rdata1, data1, sizeof(data1));
   10162 	if (result != ISC_R_SUCCESS) {
   10163 		return (false);
   10164 	}
   10165 
   10166 	for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS;
   10167 	     result = dns_rdataset_next(rdset))
   10168 	{
   10169 		dns_rdata_reset(&rdata);
   10170 		dns_rdataset_current(rdset, &rdata);
   10171 		result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
   10172 		if (result != ISC_R_SUCCESS) {
   10173 			continue;
   10174 		}
   10175 		if (dns_rdata_compare(&rdata1, &rdata2) == 0) {
   10176 			return (true);
   10177 		}
   10178 	}
   10179 
   10180 	return (false);
   10181 }
   10182 
   10183 /*
   10184  * Calculate the refresh interval for a keydata zone, per
   10185  * RFC5011: MAX(1 hr,
   10186  *		MIN(15 days,
   10187  *		    1/2 * OrigTTL,
   10188  *		    1/2 * RRSigExpirationInterval))
   10189  * or for retries: MAX(1 hr,
   10190  *		       MIN(1 day,
   10191  *			   1/10 * OrigTTL,
   10192  *			   1/10 * RRSigExpirationInterval))
   10193  */
   10194 static isc_stdtime_t
   10195 refresh_time(dns_keyfetch_t *kfetch, bool retry) {
   10196 	isc_result_t result;
   10197 	uint32_t t;
   10198 	dns_rdataset_t *rdset;
   10199 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10200 	dns_rdata_sig_t sig;
   10201 	isc_stdtime_t now;
   10202 
   10203 	isc_stdtime_get(&now);
   10204 
   10205 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
   10206 		rdset = &kfetch->dnskeysigset;
   10207 	} else {
   10208 		return (now + dns_zone_mkey_hour);
   10209 	}
   10210 
   10211 	result = dns_rdataset_first(rdset);
   10212 	if (result != ISC_R_SUCCESS) {
   10213 		return (now + dns_zone_mkey_hour);
   10214 	}
   10215 
   10216 	dns_rdataset_current(rdset, &sigrr);
   10217 	result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10218 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10219 
   10220 	if (!retry) {
   10221 		t = sig.originalttl / 2;
   10222 
   10223 		if (isc_serial_gt(sig.timeexpire, now)) {
   10224 			uint32_t exp = (sig.timeexpire - now) / 2;
   10225 			if (t > exp) {
   10226 				t = exp;
   10227 			}
   10228 		}
   10229 
   10230 		if (t > (15 * dns_zone_mkey_day)) {
   10231 			t = (15 * dns_zone_mkey_day);
   10232 		}
   10233 
   10234 		if (t < dns_zone_mkey_hour) {
   10235 			t = dns_zone_mkey_hour;
   10236 		}
   10237 	} else {
   10238 		t = sig.originalttl / 10;
   10239 
   10240 		if (isc_serial_gt(sig.timeexpire, now)) {
   10241 			uint32_t exp = (sig.timeexpire - now) / 10;
   10242 			if (t > exp) {
   10243 				t = exp;
   10244 			}
   10245 		}
   10246 
   10247 		if (t > dns_zone_mkey_day) {
   10248 			t = dns_zone_mkey_day;
   10249 		}
   10250 
   10251 		if (t < dns_zone_mkey_hour) {
   10252 			t = dns_zone_mkey_hour;
   10253 		}
   10254 	}
   10255 
   10256 	return (now + t);
   10257 }
   10258 
   10259 /*
   10260  * This routine is called when no changes are needed in a KEYDATA
   10261  * record except to simply update the refresh timer.  Caller should
   10262  * hold zone lock.
   10263  */
   10264 static isc_result_t
   10265 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) {
   10266 	isc_result_t result;
   10267 	isc_buffer_t keyb;
   10268 	unsigned char key_buf[4096];
   10269 	dns_rdata_t rdata = DNS_RDATA_INIT;
   10270 	dns_rdata_keydata_t keydata;
   10271 	dns_name_t *name;
   10272 	dns_zone_t *zone = kfetch->zone;
   10273 	isc_stdtime_t now;
   10274 
   10275 	name = dns_fixedname_name(&kfetch->name);
   10276 	isc_stdtime_get(&now);
   10277 
   10278 	for (result = dns_rdataset_first(&kfetch->keydataset);
   10279 	     result == ISC_R_SUCCESS;
   10280 	     result = dns_rdataset_next(&kfetch->keydataset))
   10281 	{
   10282 		dns_rdata_reset(&rdata);
   10283 		dns_rdataset_current(&kfetch->keydataset, &rdata);
   10284 
   10285 		/* Delete old version */
   10286 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name,
   10287 				    0, &rdata));
   10288 
   10289 		/* Update refresh timer */
   10290 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   10291 		if (result == ISC_R_UNEXPECTEDEND) {
   10292 			continue;
   10293 		}
   10294 		if (result != ISC_R_SUCCESS) {
   10295 			goto failure;
   10296 		}
   10297 		keydata.refresh = refresh_time(kfetch, true);
   10298 		set_refreshkeytimer(zone, &keydata, now, false);
   10299 
   10300 		dns_rdata_reset(&rdata);
   10301 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10302 		CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass,
   10303 					   dns_rdatatype_keydata, &keydata,
   10304 					   &keyb));
   10305 
   10306 		/* Insert updated version */
   10307 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name,
   10308 				    0, &rdata));
   10309 	}
   10310 	result = ISC_R_SUCCESS;
   10311 failure:
   10312 	return (result);
   10313 }
   10314 
   10315 /*
   10316  * Verify that DNSKEY set is signed by the key specified in 'keydata'.
   10317  */
   10318 static bool
   10319 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
   10320 	isc_result_t result;
   10321 	dns_name_t *keyname;
   10322 	isc_mem_t *mctx;
   10323 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10324 	dns_rdata_t rr = DNS_RDATA_INIT;
   10325 	dns_rdata_rrsig_t sig;
   10326 	dns_rdata_dnskey_t dnskey;
   10327 	dst_key_t *dstkey = NULL;
   10328 	unsigned char key_buf[4096];
   10329 	isc_buffer_t keyb;
   10330 	bool answer = false;
   10331 
   10332 	REQUIRE(kfetch != NULL && keydata != NULL);
   10333 	REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
   10334 
   10335 	keyname = dns_fixedname_name(&kfetch->name);
   10336 	mctx = kfetch->zone->view->mctx;
   10337 
   10338 	/* Generate a key from keydata */
   10339 	isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10340 	dns_keydata_todnskey(keydata, &dnskey, NULL);
   10341 	dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
   10342 			     &dnskey, &keyb);
   10343 	result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
   10344 	if (result != ISC_R_SUCCESS) {
   10345 		return (false);
   10346 	}
   10347 
   10348 	/* See if that key generated any of the signatures */
   10349 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
   10350 	     result == ISC_R_SUCCESS;
   10351 	     result = dns_rdataset_next(&kfetch->dnskeysigset))
   10352 	{
   10353 		dns_fixedname_t fixed;
   10354 		dns_fixedname_init(&fixed);
   10355 
   10356 		dns_rdata_reset(&sigrr);
   10357 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
   10358 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10359 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10360 
   10361 		if (dst_key_alg(dstkey) == sig.algorithm &&
   10362 		    dst_key_rid(dstkey) == sig.keyid)
   10363 		{
   10364 			result = dns_dnssec_verify(
   10365 				keyname, &kfetch->dnskeyset, dstkey, false, 0,
   10366 				mctx, &sigrr, dns_fixedname_name(&fixed));
   10367 
   10368 			dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3),
   10369 				   "Confirm revoked DNSKEY is self-signed: %s",
   10370 				   isc_result_totext(result));
   10371 
   10372 			if (result == ISC_R_SUCCESS) {
   10373 				answer = true;
   10374 				break;
   10375 			}
   10376 		}
   10377 	}
   10378 
   10379 	dst_key_free(&dstkey);
   10380 	return (answer);
   10381 }
   10382 
   10383 /*
   10384  * A DNSKEY set has been fetched from the zone apex of a zone whose trust
   10385  * anchors are being managed; scan the keyset, and update the key zone and the
   10386  * local trust anchors according to RFC5011.
   10387  */
   10388 static void
   10389 keyfetch_done(isc_task_t *task, isc_event_t *event) {
   10390 	isc_result_t result, eresult;
   10391 	dns_fetchevent_t *devent;
   10392 	dns_keyfetch_t *kfetch;
   10393 	dns_zone_t *zone;
   10394 	isc_mem_t *mctx = NULL;
   10395 	dns_keytable_t *secroots = NULL;
   10396 	dns_dbversion_t *ver = NULL;
   10397 	dns_diff_t diff;
   10398 	bool alldone = false;
   10399 	bool commit = false;
   10400 	dns_name_t *keyname = NULL;
   10401 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10402 	dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
   10403 	dns_rdata_t keydatarr = DNS_RDATA_INIT;
   10404 	dns_rdata_rrsig_t sig;
   10405 	dns_rdata_dnskey_t dnskey;
   10406 	dns_rdata_keydata_t keydata;
   10407 	bool initializing;
   10408 	char namebuf[DNS_NAME_FORMATSIZE];
   10409 	unsigned char key_buf[4096];
   10410 	isc_buffer_t keyb;
   10411 	dst_key_t *dstkey = NULL;
   10412 	isc_stdtime_t now;
   10413 	int pending = 0;
   10414 	bool secure = false, initial = false;
   10415 	bool free_needed;
   10416 	dns_keynode_t *keynode = NULL;
   10417 	dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL;
   10418 	dns_rdataset_t *keydataset = NULL, dsset;
   10419 
   10420 	UNUSED(task);
   10421 	INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
   10422 	INSIST(event->ev_arg != NULL);
   10423 
   10424 	kfetch = event->ev_arg;
   10425 	zone = kfetch->zone;
   10426 	mctx = kfetch->mctx;
   10427 	keyname = dns_fixedname_name(&kfetch->name);
   10428 	dnskeys = &kfetch->dnskeyset;
   10429 	dnskeysigs = &kfetch->dnskeysigset;
   10430 	keydataset = &kfetch->keydataset;
   10431 
   10432 	devent = (dns_fetchevent_t *)event;
   10433 	eresult = devent->result;
   10434 
   10435 	/* Free resources which are not of interest */
   10436 	if (devent->node != NULL) {
   10437 		dns_db_detachnode(devent->db, &devent->node);
   10438 	}
   10439 	if (devent->db != NULL) {
   10440 		dns_db_detach(&devent->db);
   10441 	}
   10442 	isc_event_free(&event);
   10443 	dns_resolver_destroyfetch(&kfetch->fetch);
   10444 
   10445 	LOCK_ZONE(zone);
   10446 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) {
   10447 		goto cleanup;
   10448 	}
   10449 
   10450 	isc_stdtime_get(&now);
   10451 	dns_name_format(keyname, namebuf, sizeof(namebuf));
   10452 
   10453 	result = dns_view_getsecroots(zone->view, &secroots);
   10454 	INSIST(result == ISC_R_SUCCESS);
   10455 
   10456 	dns_diff_init(mctx, &diff);
   10457 
   10458 	CHECK(dns_db_newversion(kfetch->db, &ver));
   10459 
   10460 	zone->refreshkeycount--;
   10461 	alldone = (zone->refreshkeycount == 0);
   10462 
   10463 	if (alldone) {
   10464 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10465 	}
   10466 
   10467 	dnssec_log(zone, ISC_LOG_DEBUG(3),
   10468 		   "Returned from key fetch in keyfetch_done() for '%s': %s",
   10469 		   namebuf, isc_result_totext(eresult));
   10470 
   10471 	/* Fetch failed */
   10472 	if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) {
   10473 		dnssec_log(zone, ISC_LOG_WARNING,
   10474 			   "Unable to fetch DNSKEY set '%s': %s", namebuf,
   10475 			   isc_result_totext(eresult));
   10476 		CHECK(minimal_update(kfetch, ver, &diff));
   10477 		goto done;
   10478 	}
   10479 
   10480 	/* No RRSIGs found */
   10481 	if (!dns_rdataset_isassociated(dnskeysigs)) {
   10482 		dnssec_log(zone, ISC_LOG_WARNING,
   10483 			   "No DNSKEY RRSIGs found for '%s': %s", namebuf,
   10484 			   isc_result_totext(eresult));
   10485 		CHECK(minimal_update(kfetch, ver, &diff));
   10486 		goto done;
   10487 	}
   10488 
   10489 	/*
   10490 	 * Clear any cached trust level, as we need to run validation
   10491 	 * over again; trusted keys might have changed.
   10492 	 */
   10493 	dnskeys->trust = dnskeysigs->trust = dns_trust_none;
   10494 
   10495 	/* Look up the trust anchor */
   10496 	result = dns_keytable_find(secroots, keyname, &keynode);
   10497 	if (result != ISC_R_SUCCESS) {
   10498 		goto anchors_done;
   10499 	}
   10500 
   10501 	/*
   10502 	 * If the keynode has a DS trust anchor, use it for verification.
   10503 	 */
   10504 	dns_rdataset_init(&dsset);
   10505 	if (dns_keynode_dsset(keynode, &dsset)) {
   10506 		for (result = dns_rdataset_first(dnskeysigs);
   10507 		     result == ISC_R_SUCCESS;
   10508 		     result = dns_rdataset_next(dnskeysigs))
   10509 		{
   10510 			isc_result_t tresult;
   10511 			dns_rdata_t keyrdata = DNS_RDATA_INIT;
   10512 
   10513 			dns_rdata_reset(&sigrr);
   10514 			dns_rdataset_current(dnskeysigs, &sigrr);
   10515 			result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10516 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10517 
   10518 			for (tresult = dns_rdataset_first(&dsset);
   10519 			     tresult == ISC_R_SUCCESS;
   10520 			     tresult = dns_rdataset_next(&dsset))
   10521 			{
   10522 				dns_rdata_t dsrdata = DNS_RDATA_INIT;
   10523 				dns_rdata_ds_t ds;
   10524 
   10525 				dns_rdata_reset(&dsrdata);
   10526 				dns_rdataset_current(&dsset, &dsrdata);
   10527 				tresult = dns_rdata_tostruct(&dsrdata, &ds,
   10528 							     NULL);
   10529 				RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
   10530 
   10531 				if (ds.key_tag != sig.keyid ||
   10532 				    ds.algorithm != sig.algorithm)
   10533 				{
   10534 					continue;
   10535 				}
   10536 
   10537 				result = dns_dnssec_matchdskey(
   10538 					keyname, &dsrdata, dnskeys, &keyrdata);
   10539 				if (result == ISC_R_SUCCESS) {
   10540 					break;
   10541 				}
   10542 			}
   10543 
   10544 			if (tresult == ISC_R_NOMORE) {
   10545 				continue;
   10546 			}
   10547 
   10548 			result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
   10549 							 mctx, &dstkey);
   10550 			if (result != ISC_R_SUCCESS) {
   10551 				continue;
   10552 			}
   10553 
   10554 			result = dns_dnssec_verify(keyname, dnskeys, dstkey,
   10555 						   false, 0, mctx, &sigrr,
   10556 						   NULL);
   10557 			dst_key_free(&dstkey);
   10558 
   10559 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   10560 				   "Verifying DNSKEY set for zone "
   10561 				   "'%s' using DS %d/%d: %s",
   10562 				   namebuf, sig.keyid, sig.algorithm,
   10563 				   isc_result_totext(result));
   10564 
   10565 			if (result == ISC_R_SUCCESS) {
   10566 				dnskeys->trust = dns_trust_secure;
   10567 				dnskeysigs->trust = dns_trust_secure;
   10568 				initial = dns_keynode_initial(keynode);
   10569 				dns_keynode_trust(keynode);
   10570 				secure = true;
   10571 				break;
   10572 			}
   10573 		}
   10574 		dns_rdataset_disassociate(&dsset);
   10575 	}
   10576 
   10577 anchors_done:
   10578 	if (keynode != NULL) {
   10579 		dns_keytable_detachkeynode(secroots, &keynode);
   10580 	}
   10581 
   10582 	/*
   10583 	 * If we were not able to verify the answer using the current
   10584 	 * trusted keys then all we can do is look at any revoked keys.
   10585 	 */
   10586 	if (!secure) {
   10587 		dnssec_log(zone, ISC_LOG_INFO,
   10588 			   "DNSKEY set for zone '%s' could not be verified "
   10589 			   "with current keys",
   10590 			   namebuf);
   10591 	}
   10592 
   10593 	/*
   10594 	 * First scan keydataset to find keys that are not in dnskeyset
   10595 	 *   - Missing keys which are not scheduled for removal,
   10596 	 *     log a warning
   10597 	 *   - Missing keys which are scheduled for removal and
   10598 	 *     the remove hold-down timer has completed should
   10599 	 *     be removed from the key zone
   10600 	 *   - Missing keys whose acceptance timers have not yet
   10601 	 *     completed, log a warning and reset the acceptance
   10602 	 *     timer to 30 days in the future
   10603 	 *   - All keys not being removed have their refresh timers
   10604 	 *     updated
   10605 	 */
   10606 	initializing = true;
   10607 	for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS;
   10608 	     result = dns_rdataset_next(keydataset))
   10609 	{
   10610 		dns_keytag_t keytag;
   10611 
   10612 		dns_rdata_reset(&keydatarr);
   10613 		dns_rdataset_current(keydataset, &keydatarr);
   10614 		result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10615 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10616 
   10617 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   10618 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10619 		if (result != ISC_R_SUCCESS) {
   10620 			/*
   10621 			 * Skip if we cannot compute the key tag.
   10622 			 * This may happen if the algorithm is unsupported
   10623 			 */
   10624 			dns_zone_log(zone, ISC_LOG_ERROR,
   10625 				     "Cannot compute tag for key in zone %s: "
   10626 				     "%s "
   10627 				     "(skipping)",
   10628 				     namebuf, isc_result_totext(result));
   10629 			continue;
   10630 		}
   10631 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10632 
   10633 		/*
   10634 		 * If any keydata record has a nonzero add holddown, then
   10635 		 * there was a pre-existing trust anchor for this domain;
   10636 		 * that means we are *not* initializing it and shouldn't
   10637 		 * automatically trust all the keys we find at the zone apex.
   10638 		 */
   10639 		initializing = initializing && (keydata.addhd == 0);
   10640 
   10641 		if (!matchkey(dnskeys, &keydatarr)) {
   10642 			bool deletekey = false;
   10643 
   10644 			if (!secure) {
   10645 				if (keydata.removehd != 0 &&
   10646 				    keydata.removehd <= now)
   10647 				{
   10648 					deletekey = true;
   10649 				}
   10650 			} else if (keydata.addhd == 0) {
   10651 				deletekey = true;
   10652 			} else if (keydata.addhd > now) {
   10653 				dnssec_log(zone, ISC_LOG_INFO,
   10654 					   "Pending key %d for zone %s "
   10655 					   "unexpectedly missing from DNSKEY "
   10656 					   "RRset: restarting 30-day "
   10657 					   "acceptance timer",
   10658 					   keytag, namebuf);
   10659 				if (keydata.addhd < now + dns_zone_mkey_month) {
   10660 					keydata.addhd = now +
   10661 							dns_zone_mkey_month;
   10662 				}
   10663 				keydata.refresh = refresh_time(kfetch, false);
   10664 			} else if (keydata.removehd == 0) {
   10665 				dnssec_log(zone, ISC_LOG_INFO,
   10666 					   "Active key %d for zone %s "
   10667 					   "unexpectedly missing from DNSKEY "
   10668 					   "RRset",
   10669 					   keytag, namebuf);
   10670 				keydata.refresh = now + dns_zone_mkey_hour;
   10671 			} else if (keydata.removehd <= now) {
   10672 				deletekey = true;
   10673 				dnssec_log(
   10674 					zone, ISC_LOG_INFO,
   10675 					"Revoked key %d for zone %s no longer "
   10676 					"present in DNSKEY RRset: deleting "
   10677 					"from managed keys database",
   10678 					keytag, namebuf);
   10679 			} else {
   10680 				keydata.refresh = refresh_time(kfetch, false);
   10681 			}
   10682 
   10683 			if (secure || deletekey) {
   10684 				/* Delete old version */
   10685 				CHECK(update_one_rr(kfetch->db, ver, &diff,
   10686 						    DNS_DIFFOP_DEL, keyname, 0,
   10687 						    &keydatarr));
   10688 			}
   10689 
   10690 			if (!secure || deletekey) {
   10691 				continue;
   10692 			}
   10693 
   10694 			dns_rdata_reset(&keydatarr);
   10695 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10696 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10697 					     dns_rdatatype_keydata, &keydata,
   10698 					     &keyb);
   10699 
   10700 			/* Insert updated version */
   10701 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10702 					    DNS_DIFFOP_ADD, keyname, 0,
   10703 					    &keydatarr));
   10704 
   10705 			set_refreshkeytimer(zone, &keydata, now, false);
   10706 		}
   10707 	}
   10708 
   10709 	/*
   10710 	 * Next scan dnskeyset:
   10711 	 *   - If new keys are found (i.e., lacking a match in keydataset)
   10712 	 *     add them to the key zone and set the acceptance timer
   10713 	 *     to 30 days in the future (or to immediately if we've
   10714 	 *     determined that we're initializing the zone for the
   10715 	 *     first time)
   10716 	 *   - Previously-known keys that have been revoked
   10717 	 *     must be scheduled for removal from the key zone (or,
   10718 	 *     if they hadn't been accepted as trust anchors yet
   10719 	 *     anyway, removed at once)
   10720 	 *   - Previously-known unrevoked keys whose acceptance timers
   10721 	 *     have completed are promoted to trust anchors
   10722 	 *   - All keys not being removed have their refresh
   10723 	 *     timers updated
   10724 	 */
   10725 	for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS;
   10726 	     result = dns_rdataset_next(dnskeys))
   10727 	{
   10728 		bool revoked = false;
   10729 		bool newkey = false;
   10730 		bool updatekey = false;
   10731 		bool deletekey = false;
   10732 		bool trustkey = false;
   10733 		dns_keytag_t keytag;
   10734 
   10735 		dns_rdata_reset(&dnskeyrr);
   10736 		dns_rdataset_current(dnskeys, &dnskeyrr);
   10737 		result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10738 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10739 
   10740 		/* Skip ZSK's */
   10741 		if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
   10742 			continue;
   10743 		}
   10744 
   10745 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10746 		if (result != ISC_R_SUCCESS) {
   10747 			/*
   10748 			 * Skip if we cannot compute the key tag.
   10749 			 * This may happen if the algorithm is unsupported
   10750 			 */
   10751 			dns_zone_log(zone, ISC_LOG_ERROR,
   10752 				     "Cannot compute tag for key in zone %s: "
   10753 				     "%s "
   10754 				     "(skipping)",
   10755 				     namebuf, isc_result_totext(result));
   10756 			continue;
   10757 		}
   10758 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10759 
   10760 		revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
   10761 
   10762 		if (matchkey(keydataset, &dnskeyrr)) {
   10763 			dns_rdata_reset(&keydatarr);
   10764 			dns_rdataset_current(keydataset, &keydatarr);
   10765 			result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10766 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10767 
   10768 			if (revoked && revocable(kfetch, &keydata)) {
   10769 				if (keydata.addhd > now) {
   10770 					/*
   10771 					 * Key wasn't trusted yet, and now
   10772 					 * it's been revoked?  Just remove it
   10773 					 */
   10774 					deletekey = true;
   10775 					dnssec_log(zone, ISC_LOG_INFO,
   10776 						   "Pending key %d for "
   10777 						   "zone %s is now revoked: "
   10778 						   "deleting from the "
   10779 						   "managed keys database",
   10780 						   keytag, namebuf);
   10781 				} else if (keydata.removehd == 0) {
   10782 					/*
   10783 					 * Remove key from secroots.
   10784 					 */
   10785 					dns_view_untrust(zone->view, keyname,
   10786 							 &dnskey);
   10787 
   10788 					/* If initializing, delete now */
   10789 					if (keydata.addhd == 0) {
   10790 						deletekey = true;
   10791 					} else {
   10792 						keydata.removehd =
   10793 							now +
   10794 							dns_zone_mkey_month;
   10795 						keydata.flags |=
   10796 							DNS_KEYFLAG_REVOKE;
   10797 					}
   10798 
   10799 					dnssec_log(zone, ISC_LOG_INFO,
   10800 						   "Trusted key %d for "
   10801 						   "zone %s is now revoked",
   10802 						   keytag, namebuf);
   10803 				} else if (keydata.removehd < now) {
   10804 					/* Scheduled for removal */
   10805 					deletekey = true;
   10806 
   10807 					dnssec_log(zone, ISC_LOG_INFO,
   10808 						   "Revoked key %d for "
   10809 						   "zone %s removal timer "
   10810 						   "complete: deleting from "
   10811 						   "the managed keys database",
   10812 						   keytag, namebuf);
   10813 				}
   10814 			} else if (revoked && keydata.removehd == 0) {
   10815 				dnssec_log(zone, ISC_LOG_WARNING,
   10816 					   "Active key %d for zone "
   10817 					   "%s is revoked but "
   10818 					   "did not self-sign; "
   10819 					   "ignoring",
   10820 					   keytag, namebuf);
   10821 				continue;
   10822 			} else if (secure) {
   10823 				if (keydata.removehd != 0) {
   10824 					/*
   10825 					 * Key isn't revoked--but it
   10826 					 * seems it used to be.
   10827 					 * Remove it now and add it
   10828 					 * back as if it were a fresh key,
   10829 					 * with a 30-day acceptance timer.
   10830 					 */
   10831 					deletekey = true;
   10832 					newkey = true;
   10833 					keydata.removehd = 0;
   10834 					keydata.addhd = now +
   10835 							dns_zone_mkey_month;
   10836 
   10837 					dnssec_log(zone, ISC_LOG_INFO,
   10838 						   "Revoked key %d for "
   10839 						   "zone %s has returned: "
   10840 						   "starting 30-day "
   10841 						   "acceptance timer",
   10842 						   keytag, namebuf);
   10843 				} else if (keydata.addhd > now) {
   10844 					pending++;
   10845 				} else if (keydata.addhd == 0) {
   10846 					keydata.addhd = now;
   10847 				}
   10848 
   10849 				if (keydata.addhd <= now) {
   10850 					trustkey = true;
   10851 					dnssec_log(zone, ISC_LOG_INFO,
   10852 						   "Key %d for zone %s "
   10853 						   "is now trusted (%s)",
   10854 						   keytag, namebuf,
   10855 						   initial ? "initializing key "
   10856 							     "verified"
   10857 							   : "acceptance timer "
   10858 							     "complete");
   10859 				}
   10860 			} else if (keydata.addhd > now) {
   10861 				/*
   10862 				 * Not secure, and key is pending:
   10863 				 * reset the acceptance timer
   10864 				 */
   10865 				pending++;
   10866 				keydata.addhd = now + dns_zone_mkey_month;
   10867 				dnssec_log(zone, ISC_LOG_INFO,
   10868 					   "Pending key %d "
   10869 					   "for zone %s was "
   10870 					   "not validated: restarting "
   10871 					   "30-day acceptance timer",
   10872 					   keytag, namebuf);
   10873 			}
   10874 
   10875 			if (!deletekey && !newkey) {
   10876 				updatekey = true;
   10877 			}
   10878 		} else if (secure) {
   10879 			/*
   10880 			 * Key wasn't in the key zone but it's
   10881 			 * revoked now anyway, so just skip it
   10882 			 */
   10883 			if (revoked) {
   10884 				continue;
   10885 			}
   10886 
   10887 			/* Key wasn't in the key zone: add it */
   10888 			newkey = true;
   10889 
   10890 			if (initializing) {
   10891 				dnssec_log(zone, ISC_LOG_WARNING,
   10892 					   "Initializing automatic trust "
   10893 					   "anchor management for zone '%s'; "
   10894 					   "DNSKEY ID %d is now trusted, "
   10895 					   "waiving the normal 30-day "
   10896 					   "waiting period.",
   10897 					   namebuf, keytag);
   10898 				trustkey = true;
   10899 			} else {
   10900 				dnssec_log(zone, ISC_LOG_INFO,
   10901 					   "New key %d observed "
   10902 					   "for zone '%s': "
   10903 					   "starting 30-day "
   10904 					   "acceptance timer",
   10905 					   keytag, namebuf);
   10906 			}
   10907 		} else {
   10908 			/*
   10909 			 * No previously known key, and the key is not
   10910 			 * secure, so skip it.
   10911 			 */
   10912 			continue;
   10913 		}
   10914 
   10915 		/* Delete old version */
   10916 		if (deletekey || !newkey) {
   10917 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10918 					    DNS_DIFFOP_DEL, keyname, 0,
   10919 					    &keydatarr));
   10920 		}
   10921 
   10922 		if (updatekey) {
   10923 			/* Set refresh timer */
   10924 			keydata.refresh = refresh_time(kfetch, false);
   10925 			dns_rdata_reset(&keydatarr);
   10926 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10927 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10928 					     dns_rdatatype_keydata, &keydata,
   10929 					     &keyb);
   10930 
   10931 			/* Insert updated version */
   10932 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10933 					    DNS_DIFFOP_ADD, keyname, 0,
   10934 					    &keydatarr));
   10935 		} else if (newkey) {
   10936 			/* Convert DNSKEY to KEYDATA */
   10937 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10938 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10939 			dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
   10940 					       NULL);
   10941 			keydata.addhd = initializing
   10942 						? now
   10943 						: now + dns_zone_mkey_month;
   10944 			keydata.refresh = refresh_time(kfetch, false);
   10945 			dns_rdata_reset(&keydatarr);
   10946 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10947 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10948 					     dns_rdatatype_keydata, &keydata,
   10949 					     &keyb);
   10950 
   10951 			/* Insert into key zone */
   10952 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10953 					    DNS_DIFFOP_ADD, keyname, 0,
   10954 					    &keydatarr));
   10955 		}
   10956 
   10957 		if (trustkey) {
   10958 			/* Trust this key. */
   10959 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10960 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10961 			trust_key(zone, keyname, &dnskey, false);
   10962 		}
   10963 
   10964 		if (secure && !deletekey) {
   10965 			INSIST(newkey || updatekey);
   10966 			set_refreshkeytimer(zone, &keydata, now, false);
   10967 		}
   10968 	}
   10969 
   10970 	/*
   10971 	 * RFC5011 says, "A trust point that has all of its trust anchors
   10972 	 * revoked is considered deleted and is treated as if the trust
   10973 	 * point was never configured."  But if someone revoked their
   10974 	 * active key before the standby was trusted, that would mean the
   10975 	 * zone would suddenly be nonsecured.  We avoid this by checking to
   10976 	 * see if there's pending keydata.  If so, we put a null key in
   10977 	 * the security roots; then all queries to the zone will fail.
   10978 	 */
   10979 	if (pending != 0) {
   10980 		fail_secure(zone, keyname);
   10981 	}
   10982 
   10983 done:
   10984 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10985 		/* Write changes to journal file. */
   10986 		CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx,
   10987 					zone->updatemethod));
   10988 		CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
   10989 		commit = true;
   10990 
   10991 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   10992 		zone_needdump(zone, 30);
   10993 	} else if (result == ISC_R_NOMORE) {
   10994 		/*
   10995 		 * If "updatekey" was true for all keys found in the DNSKEY
   10996 		 * response and the previous update of those keys happened
   10997 		 * during the same second (only possible if a key refresh was
   10998 		 * externally triggered), it may happen that all relevant
   10999 		 * update_one_rr() calls will return ISC_R_SUCCESS, but
   11000 		 * diff.tuples will remain empty.  Reset result to
   11001 		 * ISC_R_SUCCESS to prevent a bogus warning from being logged.
   11002 		 */
   11003 		result = ISC_R_SUCCESS;
   11004 	}
   11005 
   11006 failure:
   11007 	if (result != ISC_R_SUCCESS) {
   11008 		dnssec_log(zone, ISC_LOG_ERROR,
   11009 			   "error during managed-keys processing (%s): "
   11010 			   "DNSSEC validation may be at risk",
   11011 			   isc_result_totext(result));
   11012 	}
   11013 	dns_diff_clear(&diff);
   11014 	if (ver != NULL) {
   11015 		dns_db_closeversion(kfetch->db, &ver, commit);
   11016 	}
   11017 
   11018 cleanup:
   11019 	dns_db_detach(&kfetch->db);
   11020 
   11021 	/* The zone must be managed */
   11022 	INSIST(kfetch->zone->task != NULL);
   11023 	isc_refcount_decrement(&zone->irefs);
   11024 
   11025 	if (dns_rdataset_isassociated(keydataset)) {
   11026 		dns_rdataset_disassociate(keydataset);
   11027 	}
   11028 	if (dns_rdataset_isassociated(dnskeys)) {
   11029 		dns_rdataset_disassociate(dnskeys);
   11030 	}
   11031 	if (dns_rdataset_isassociated(dnskeysigs)) {
   11032 		dns_rdataset_disassociate(dnskeysigs);
   11033 	}
   11034 
   11035 	dns_name_free(keyname, mctx);
   11036 	isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(dns_keyfetch_t));
   11037 
   11038 	if (secroots != NULL) {
   11039 		dns_keytable_detach(&secroots);
   11040 	}
   11041 
   11042 	free_needed = exit_check(zone);
   11043 	UNLOCK_ZONE(zone);
   11044 
   11045 	if (free_needed) {
   11046 		zone_free(zone);
   11047 	}
   11048 
   11049 	INSIST(ver == NULL);
   11050 }
   11051 
   11052 static void
   11053 retry_keyfetch(dns_keyfetch_t *kfetch, dns_name_t *kname) {
   11054 	isc_time_t timenow, timethen;
   11055 	dns_zone_t *zone = kfetch->zone;
   11056 	bool free_needed;
   11057 	char namebuf[DNS_NAME_FORMATSIZE];
   11058 
   11059 	dns_name_format(kname, namebuf, sizeof(namebuf));
   11060 	dnssec_log(zone, ISC_LOG_WARNING,
   11061 		   "Failed to create fetch for %s DNSKEY update", namebuf);
   11062 
   11063 	/*
   11064 	 * Error during a key fetch; cancel and retry in an hour.
   11065 	 */
   11066 	LOCK_ZONE(zone);
   11067 	zone->refreshkeycount--;
   11068 	isc_refcount_decrement(&zone->irefs);
   11069 	dns_db_detach(&kfetch->db);
   11070 	dns_rdataset_disassociate(&kfetch->keydataset);
   11071 	dns_name_free(kname, zone->mctx);
   11072 	isc_mem_putanddetach(&kfetch->mctx, kfetch, sizeof(*kfetch));
   11073 
   11074 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11075 		/* Don't really retry if we are exiting */
   11076 		char timebuf[80];
   11077 
   11078 		TIME_NOW(&timenow);
   11079 		DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
   11080 		zone->refreshkeytime = timethen;
   11081 		zone_settimer(zone, &timenow);
   11082 
   11083 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   11084 		dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
   11085 			   timebuf);
   11086 	}
   11087 
   11088 	free_needed = exit_check(zone);
   11089 	UNLOCK_ZONE(zone);
   11090 
   11091 	if (free_needed) {
   11092 		zone_free(zone);
   11093 	}
   11094 }
   11095 
   11096 static void
   11097 do_keyfetch(isc_task_t *task, isc_event_t *event) {
   11098 	isc_result_t result;
   11099 	dns_keyfetch_t *kfetch = (dns_keyfetch_t *)event->ev_arg;
   11100 	dns_name_t *kname = dns_fixedname_name(&kfetch->name);
   11101 	dns_zone_t *zone = kfetch->zone;
   11102 
   11103 	UNUSED(task);
   11104 
   11105 	isc_event_free(&event);
   11106 
   11107 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11108 		retry_keyfetch(kfetch, kname);
   11109 		return;
   11110 	}
   11111 
   11112 	/*
   11113 	 * Use of DNS_FETCHOPT_NOCACHED is essential here.  If it is not
   11114 	 * set and the cache still holds a non-expired, validated version
   11115 	 * of the RRset being queried for by the time the response is
   11116 	 * received, the cached RRset will be passed to keyfetch_done()
   11117 	 * instead of the one received in the response as the latter will
   11118 	 * have a lower trust level due to not being validated until
   11119 	 * keyfetch_done() is called.
   11120 	 */
   11121 	result = dns_resolver_createfetch(
   11122 		zone->view->resolver, kname, dns_rdatatype_dnskey, NULL, NULL,
   11123 		NULL, NULL, 0,
   11124 		DNS_FETCHOPT_NOVALIDATE | DNS_FETCHOPT_UNSHARED |
   11125 			DNS_FETCHOPT_NOCACHED,
   11126 		0, NULL, zone->task, keyfetch_done, kfetch, &kfetch->dnskeyset,
   11127 		&kfetch->dnskeysigset, &kfetch->fetch);
   11128 
   11129 	if (result != ISC_R_SUCCESS) {
   11130 		retry_keyfetch(kfetch, kname);
   11131 	}
   11132 }
   11133 
   11134 /*
   11135  * Refresh the data in the key zone.  Initiate a fetch to look up
   11136  * DNSKEY records at the trust anchor name.
   11137  */
   11138 static void
   11139 zone_refreshkeys(dns_zone_t *zone) {
   11140 	const char me[] = "zone_refreshkeys";
   11141 	isc_result_t result;
   11142 	dns_rriterator_t rrit;
   11143 	dns_db_t *db = NULL;
   11144 	dns_dbversion_t *ver = NULL;
   11145 	dns_diff_t diff;
   11146 	dns_rdata_t rdata = DNS_RDATA_INIT;
   11147 	dns_rdata_keydata_t kd;
   11148 	isc_stdtime_t now;
   11149 	bool commit = false;
   11150 	bool fetching = false;
   11151 	bool timerset = false;
   11152 
   11153 	ENTER;
   11154 	REQUIRE(zone->db != NULL);
   11155 
   11156 	isc_stdtime_get(&now);
   11157 
   11158 	LOCK_ZONE(zone);
   11159 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11160 		isc_time_settoepoch(&zone->refreshkeytime);
   11161 		UNLOCK_ZONE(zone);
   11162 		return;
   11163 	}
   11164 
   11165 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11166 	dns_db_attach(zone->db, &db);
   11167 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11168 
   11169 	dns_diff_init(zone->mctx, &diff);
   11170 
   11171 	CHECK(dns_db_newversion(db, &ver));
   11172 
   11173 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
   11174 
   11175 	dns_rriterator_init(&rrit, db, ver, 0);
   11176 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   11177 	     result = dns_rriterator_nextrrset(&rrit))
   11178 	{
   11179 		isc_stdtime_t timer = 0xffffffff;
   11180 		dns_name_t *name = NULL, *kname = NULL;
   11181 		dns_rdataset_t *kdset = NULL;
   11182 		uint32_t ttl;
   11183 
   11184 		dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
   11185 		if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
   11186 		    !dns_rdataset_isassociated(kdset))
   11187 		{
   11188 			continue;
   11189 		}
   11190 
   11191 		/*
   11192 		 * Scan the stored keys looking for ones that need
   11193 		 * removal or refreshing
   11194 		 */
   11195 		for (result = dns_rdataset_first(kdset);
   11196 		     result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset))
   11197 		{
   11198 			dns_rdata_reset(&rdata);
   11199 			dns_rdataset_current(kdset, &rdata);
   11200 			result = dns_rdata_tostruct(&rdata, &kd, NULL);
   11201 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   11202 
   11203 			/* Removal timer expired? */
   11204 			if (kd.removehd != 0 && kd.removehd < now) {
   11205 				dns_rriterator_pause(&rrit);
   11206 				CHECK(update_one_rr(db, ver, &diff,
   11207 						    DNS_DIFFOP_DEL, name, ttl,
   11208 						    &rdata));
   11209 				continue;
   11210 			}
   11211 
   11212 			/* Acceptance timer expired? */
   11213 			if (kd.addhd <= now) {
   11214 				timer = kd.addhd;
   11215 			}
   11216 
   11217 			/* Or do we just need to refresh the keyset? */
   11218 			if (timer > kd.refresh) {
   11219 				timer = kd.refresh;
   11220 			}
   11221 
   11222 			dns_rriterator_pause(&rrit);
   11223 			set_refreshkeytimer(zone, &kd, now, false);
   11224 			timerset = true;
   11225 		}
   11226 
   11227 		if (timer > now) {
   11228 			continue;
   11229 		}
   11230 
   11231 		dns_rriterator_pause(&rrit);
   11232 
   11233 #ifdef ENABLE_AFL
   11234 		if (!dns_fuzzing_resolver) {
   11235 #endif /* ifdef ENABLE_AFL */
   11236 			dns_keyfetch_t *kfetch = NULL;
   11237 			isc_event_t *e;
   11238 
   11239 			kfetch = isc_mem_get(zone->mctx,
   11240 					     sizeof(dns_keyfetch_t));
   11241 			*kfetch = (dns_keyfetch_t){ .zone = zone };
   11242 			isc_mem_attach(zone->mctx, &kfetch->mctx);
   11243 
   11244 			zone->refreshkeycount++;
   11245 			isc_refcount_increment0(&zone->irefs);
   11246 			kname = dns_fixedname_initname(&kfetch->name);
   11247 			dns_name_dup(name, zone->mctx, kname);
   11248 			dns_rdataset_init(&kfetch->dnskeyset);
   11249 			dns_rdataset_init(&kfetch->dnskeysigset);
   11250 			dns_rdataset_init(&kfetch->keydataset);
   11251 			dns_rdataset_clone(kdset, &kfetch->keydataset);
   11252 			dns_db_attach(db, &kfetch->db);
   11253 
   11254 			if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   11255 				char namebuf[DNS_NAME_FORMATSIZE];
   11256 				dns_name_format(kname, namebuf,
   11257 						sizeof(namebuf));
   11258 				dnssec_log(zone, ISC_LOG_DEBUG(3),
   11259 					   "Creating key fetch in "
   11260 					   "zone_refreshkeys() for '%s'",
   11261 					   namebuf);
   11262 			}
   11263 
   11264 			e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
   11265 					       do_keyfetch, kfetch,
   11266 					       sizeof(isc_event_t));
   11267 			isc_task_send(zone->task, &e);
   11268 			fetching = true;
   11269 #ifdef ENABLE_AFL
   11270 		}
   11271 #endif /* ifdef ENABLE_AFL */
   11272 	}
   11273 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   11274 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   11275 					zone->updatemethod));
   11276 		CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
   11277 		commit = true;
   11278 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   11279 		zone_needdump(zone, 30);
   11280 	}
   11281 
   11282 failure:
   11283 	if (!timerset) {
   11284 		isc_time_settoepoch(&zone->refreshkeytime);
   11285 	}
   11286 
   11287 	if (!fetching) {
   11288 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   11289 	}
   11290 
   11291 	dns_diff_clear(&diff);
   11292 	if (ver != NULL) {
   11293 		dns_rriterator_destroy(&rrit);
   11294 		dns_db_closeversion(db, &ver, commit);
   11295 	}
   11296 	dns_db_detach(&db);
   11297 
   11298 	UNLOCK_ZONE(zone);
   11299 
   11300 	INSIST(ver == NULL);
   11301 }
   11302 
   11303 static void
   11304 zone_maintenance(dns_zone_t *zone) {
   11305 	const char me[] = "zone_maintenance";
   11306 	isc_time_t now;
   11307 	isc_result_t result;
   11308 	bool load_pending, exiting, dumping, viewok, notify;
   11309 	bool refreshkeys, sign, resign, rekey, chain, warn_expire;
   11310 
   11311 	REQUIRE(DNS_ZONE_VALID(zone));
   11312 	ENTER;
   11313 
   11314 	/*
   11315 	 * Are we pending load/reload, exiting, or unconfigured
   11316 	 * (e.g. because of a syntax failure in the config file)?
   11317 	 * If so, don't attempt maintenance.
   11318 	 */
   11319 	LOCK_ZONE(zone);
   11320 	load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
   11321 	exiting = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING);
   11322 	viewok = (zone->view != NULL && zone->view->adb != NULL);
   11323 	UNLOCK_ZONE(zone);
   11324 
   11325 	if (load_pending || exiting || !viewok) {
   11326 		return;
   11327 	}
   11328 
   11329 	TIME_NOW(&now);
   11330 
   11331 	/*
   11332 	 * Expire check.
   11333 	 */
   11334 	switch (zone->type) {
   11335 	case dns_zone_redirect:
   11336 		if (zone->primaries == NULL) {
   11337 			break;
   11338 		}
   11339 		FALLTHROUGH;
   11340 	case dns_zone_secondary:
   11341 	case dns_zone_mirror:
   11342 	case dns_zone_stub:
   11343 		LOCK_ZONE(zone);
   11344 		if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
   11345 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11346 		{
   11347 			zone_expire(zone);
   11348 			zone->refreshtime = now;
   11349 		}
   11350 		UNLOCK_ZONE(zone);
   11351 		break;
   11352 	default:
   11353 		break;
   11354 	}
   11355 
   11356 	/*
   11357 	 * Up to date check.
   11358 	 */
   11359 	switch (zone->type) {
   11360 	case dns_zone_redirect:
   11361 		if (zone->primaries == NULL) {
   11362 			break;
   11363 		}
   11364 		FALLTHROUGH;
   11365 	case dns_zone_secondary:
   11366 	case dns_zone_mirror:
   11367 	case dns_zone_stub:
   11368 		LOCK_ZONE(zone);
   11369 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
   11370 		    isc_time_compare(&now, &zone->refreshtime) >= 0)
   11371 		{
   11372 			zone_refresh(zone);
   11373 		}
   11374 		UNLOCK_ZONE(zone);
   11375 		break;
   11376 	default:
   11377 		break;
   11378 	}
   11379 
   11380 	/*
   11381 	 * Secondaries send notifies before backing up to disk,
   11382 	 * primaries after.
   11383 	 */
   11384 	LOCK_ZONE(zone);
   11385 	notify = (zone->type == dns_zone_secondary ||
   11386 		  zone->type == dns_zone_mirror) &&
   11387 		 (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11388 		  DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11389 		 isc_time_compare(&now, &zone->notifytime) >= 0;
   11390 	UNLOCK_ZONE(zone);
   11391 
   11392 	if (notify) {
   11393 		zone_notify(zone, &now);
   11394 	}
   11395 
   11396 	/*
   11397 	 * Do we need to consolidate the backing store?
   11398 	 */
   11399 	switch (zone->type) {
   11400 	case dns_zone_primary:
   11401 	case dns_zone_secondary:
   11402 	case dns_zone_mirror:
   11403 	case dns_zone_key:
   11404 	case dns_zone_redirect:
   11405 	case dns_zone_stub:
   11406 		LOCK_ZONE(zone);
   11407 		if (zone->masterfile != NULL &&
   11408 		    isc_time_compare(&now, &zone->dumptime) >= 0 &&
   11409 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11410 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
   11411 		{
   11412 			dumping = was_dumping(zone);
   11413 		} else {
   11414 			dumping = true;
   11415 		}
   11416 		UNLOCK_ZONE(zone);
   11417 		if (!dumping) {
   11418 			result = zone_dump(zone, true); /* task locked */
   11419 			if (result != ISC_R_SUCCESS) {
   11420 				dns_zone_log(zone, ISC_LOG_WARNING,
   11421 					     "dump failed: %s",
   11422 					     isc_result_totext(result));
   11423 			}
   11424 		}
   11425 		break;
   11426 	default:
   11427 		break;
   11428 	}
   11429 
   11430 	/*
   11431 	 * Primary/redirect zones send notifies now, if needed
   11432 	 */
   11433 	switch (zone->type) {
   11434 	case dns_zone_primary:
   11435 	case dns_zone_redirect:
   11436 		LOCK_ZONE(zone);
   11437 		notify = (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11438 			  DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11439 			 isc_time_compare(&now, &zone->notifytime) >= 0;
   11440 		UNLOCK_ZONE(zone);
   11441 		if (notify) {
   11442 			zone_notify(zone, &now);
   11443 		}
   11444 	default:
   11445 		break;
   11446 	}
   11447 
   11448 	/*
   11449 	 * Do we need to refresh keys?
   11450 	 */
   11451 	switch (zone->type) {
   11452 	case dns_zone_key:
   11453 		LOCK_ZONE(zone);
   11454 		refreshkeys = isc_time_compare(&now, &zone->refreshkeytime) >=
   11455 				      0 &&
   11456 			      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11457 			      !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING);
   11458 		UNLOCK_ZONE(zone);
   11459 		if (refreshkeys) {
   11460 			zone_refreshkeys(zone);
   11461 		}
   11462 		break;
   11463 	case dns_zone_primary:
   11464 		LOCK_ZONE(zone);
   11465 		rekey = (!isc_time_isepoch(&zone->refreshkeytime) &&
   11466 			 isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
   11467 			 zone->rss_event == NULL);
   11468 		UNLOCK_ZONE(zone);
   11469 		if (rekey) {
   11470 			zone_rekey(zone);
   11471 		}
   11472 	default:
   11473 		break;
   11474 	}
   11475 
   11476 	switch (zone->type) {
   11477 	case dns_zone_primary:
   11478 	case dns_zone_redirect:
   11479 	case dns_zone_secondary:
   11480 		/*
   11481 		 * Do we need to sign/resign some RRsets?
   11482 		 */
   11483 		LOCK_ZONE(zone);
   11484 		if (zone->rss_event != NULL) {
   11485 			UNLOCK_ZONE(zone);
   11486 			break;
   11487 		}
   11488 		sign = !isc_time_isepoch(&zone->signingtime) &&
   11489 		       isc_time_compare(&now, &zone->signingtime) >= 0;
   11490 		resign = !isc_time_isepoch(&zone->resigntime) &&
   11491 			 isc_time_compare(&now, &zone->resigntime) >= 0;
   11492 		chain = !isc_time_isepoch(&zone->nsec3chaintime) &&
   11493 			isc_time_compare(&now, &zone->nsec3chaintime) >= 0;
   11494 		warn_expire = !isc_time_isepoch(&zone->keywarntime) &&
   11495 			      isc_time_compare(&now, &zone->keywarntime) >= 0;
   11496 		UNLOCK_ZONE(zone);
   11497 
   11498 		if (sign) {
   11499 			zone_sign(zone);
   11500 		} else if (resign) {
   11501 			zone_resigninc(zone);
   11502 		} else if (chain) {
   11503 			zone_nsec3chain(zone);
   11504 		}
   11505 
   11506 		/*
   11507 		 * Do we need to issue a key expiry warning?
   11508 		 */
   11509 		if (warn_expire) {
   11510 			set_key_expiry_warning(zone, zone->key_expiry,
   11511 					       isc_time_seconds(&now));
   11512 		}
   11513 		break;
   11514 
   11515 	default:
   11516 		break;
   11517 	}
   11518 	LOCK_ZONE(zone);
   11519 	zone_settimer(zone, &now);
   11520 	UNLOCK_ZONE(zone);
   11521 }
   11522 
   11523 void
   11524 dns_zone_markdirty(dns_zone_t *zone) {
   11525 	uint32_t serial;
   11526 	isc_result_t result = ISC_R_SUCCESS;
   11527 	dns_zone_t *secure = NULL;
   11528 
   11529 	/*
   11530 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   11531 	 * could result in a deadlock due to a LOR so we will spin if we
   11532 	 * can't obtain the both locks.
   11533 	 */
   11534 again:
   11535 	LOCK_ZONE(zone);
   11536 	if (zone->type == dns_zone_primary) {
   11537 		if (inline_raw(zone)) {
   11538 			unsigned int soacount;
   11539 			secure = zone->secure;
   11540 			INSIST(secure != zone);
   11541 			TRYLOCK_ZONE(result, secure);
   11542 			if (result != ISC_R_SUCCESS) {
   11543 				UNLOCK_ZONE(zone);
   11544 				secure = NULL;
   11545 				isc_thread_yield();
   11546 				goto again;
   11547 			}
   11548 
   11549 			ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11550 			if (zone->db != NULL) {
   11551 				result = zone_get_from_db(
   11552 					zone, zone->db, NULL, &soacount, NULL,
   11553 					&serial, NULL, NULL, NULL, NULL, NULL);
   11554 			} else {
   11555 				result = DNS_R_NOTLOADED;
   11556 			}
   11557 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11558 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   11559 				zone_send_secureserial(zone, serial);
   11560 			}
   11561 		}
   11562 
   11563 		/* XXXMPA make separate call back */
   11564 		if (result == ISC_R_SUCCESS) {
   11565 			set_resigntime(zone);
   11566 			if (zone->task != NULL) {
   11567 				isc_time_t now;
   11568 				TIME_NOW(&now);
   11569 				zone_settimer(zone, &now);
   11570 			}
   11571 		}
   11572 	}
   11573 	if (secure != NULL) {
   11574 		UNLOCK_ZONE(secure);
   11575 	}
   11576 	zone_needdump(zone, DNS_DUMP_DELAY);
   11577 	UNLOCK_ZONE(zone);
   11578 }
   11579 
   11580 void
   11581 dns_zone_expire(dns_zone_t *zone) {
   11582 	REQUIRE(DNS_ZONE_VALID(zone));
   11583 
   11584 	LOCK_ZONE(zone);
   11585 	zone_expire(zone);
   11586 	UNLOCK_ZONE(zone);
   11587 }
   11588 
   11589 static void
   11590 zone_expire(dns_zone_t *zone) {
   11591 	dns_db_t *db = NULL;
   11592 
   11593 	/*
   11594 	 * 'zone' locked by caller.
   11595 	 */
   11596 
   11597 	REQUIRE(LOCKED_ZONE(zone));
   11598 
   11599 	dns_zone_log(zone, ISC_LOG_WARNING, "expired");
   11600 
   11601 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
   11602 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   11603 	zone->retry = DNS_ZONE_DEFAULTRETRY;
   11604 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   11605 
   11606 	/*
   11607 	 * An RPZ zone has expired; before unloading it, we must
   11608 	 * first remove it from the RPZ summary database. The
   11609 	 * easiest way to do this is "update" it with an empty
   11610 	 * database so that the update callback synchronizes
   11611 	 * the diff automatically.
   11612 	 */
   11613 	if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) {
   11614 		isc_result_t result;
   11615 		dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num];
   11616 
   11617 		CHECK(dns_db_create(zone->mctx, "rbt", &zone->origin,
   11618 				    dns_dbtype_zone, zone->rdclass, 0, NULL,
   11619 				    &db));
   11620 		CHECK(dns_rpz_dbupdate_callback(db, rpz));
   11621 		dns_zone_log(zone, ISC_LOG_WARNING,
   11622 			     "response-policy zone expired; "
   11623 			     "policies unloaded");
   11624 	}
   11625 
   11626 failure:
   11627 	if (db != NULL) {
   11628 		dns_db_detach(&db);
   11629 	}
   11630 
   11631 	zone_unload(zone);
   11632 }
   11633 
   11634 static void
   11635 zone_refresh(dns_zone_t *zone) {
   11636 	isc_interval_t i;
   11637 	uint32_t oldflags;
   11638 	unsigned int j;
   11639 	isc_result_t result;
   11640 
   11641 	REQUIRE(DNS_ZONE_VALID(zone));
   11642 	REQUIRE(LOCKED_ZONE(zone));
   11643 
   11644 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11645 		return;
   11646 	}
   11647 
   11648 	/*
   11649 	 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
   11650 	 * in progress at a time.
   11651 	 */
   11652 
   11653 	oldflags = atomic_load(&zone->flags);
   11654 	if (zone->primariescnt == 0) {
   11655 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOPRIMARIES);
   11656 		if ((oldflags & DNS_ZONEFLG_NOPRIMARIES) == 0) {
   11657 			dns_zone_log(zone, ISC_LOG_ERROR,
   11658 				     "cannot refresh: no primaries");
   11659 		}
   11660 		return;
   11661 	}
   11662 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   11663 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   11664 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   11665 	if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) {
   11666 		return;
   11667 	}
   11668 
   11669 	/*
   11670 	 * Set the next refresh time as if refresh check has failed.
   11671 	 * Setting this to the retry time will do that.  XXXMLG
   11672 	 * If we are successful it will be reset using zone->refresh.
   11673 	 */
   11674 	isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4),
   11675 			 0);
   11676 	result = isc_time_nowplusinterval(&zone->refreshtime, &i);
   11677 	if (result != ISC_R_SUCCESS) {
   11678 		dns_zone_log(zone, ISC_LOG_WARNING,
   11679 			     "isc_time_nowplusinterval() failed: %s",
   11680 			     isc_result_totext(result));
   11681 	}
   11682 
   11683 	/*
   11684 	 * When lacking user-specified timer values from the SOA,
   11685 	 * do exponential backoff of the retry time up to a
   11686 	 * maximum of six hours.
   11687 	 */
   11688 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) {
   11689 		zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
   11690 	}
   11691 
   11692 	zone->curprimary = 0;
   11693 	for (j = 0; j < zone->primariescnt; j++) {
   11694 		zone->primariesok[j] = false;
   11695 	}
   11696 	/* initiate soa query */
   11697 	queue_soa_query(zone);
   11698 }
   11699 
   11700 void
   11701 dns_zone_refresh(dns_zone_t *zone) {
   11702 	LOCK_ZONE(zone);
   11703 	zone_refresh(zone);
   11704 	UNLOCK_ZONE(zone);
   11705 }
   11706 
   11707 static isc_result_t
   11708 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump,
   11709 			 bool *fixjournal) {
   11710 	dns_journal_t *journal = NULL;
   11711 	unsigned int options;
   11712 	isc_result_t result;
   11713 
   11714 	if (zone->type == dns_zone_primary &&
   11715 	    (inline_secure(zone) ||
   11716 	     (zone->update_acl != NULL || zone->ssutable != NULL)))
   11717 	{
   11718 		options = DNS_JOURNALOPT_RESIGN;
   11719 	} else {
   11720 		options = 0;
   11721 	}
   11722 
   11723 	result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ,
   11724 				  &journal);
   11725 	if (result == ISC_R_NOTFOUND) {
   11726 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(3),
   11727 			      "no journal file, but that's OK ");
   11728 		return (ISC_R_SUCCESS);
   11729 	} else if (result != ISC_R_SUCCESS) {
   11730 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11731 			      "journal open failed: %s",
   11732 			      isc_result_totext(result));
   11733 		return (result);
   11734 	}
   11735 
   11736 	if (dns_journal_empty(journal)) {
   11737 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   11738 			      "journal empty");
   11739 		dns_journal_destroy(&journal);
   11740 		return (ISC_R_SUCCESS);
   11741 	}
   11742 
   11743 	result = dns_journal_rollforward(journal, db, options);
   11744 	switch (result) {
   11745 	case ISC_R_SUCCESS:
   11746 		*needdump = true;
   11747 		FALLTHROUGH;
   11748 	case DNS_R_UPTODATE:
   11749 		if (dns_journal_recovered(journal)) {
   11750 			*fixjournal = true;
   11751 			dns_zone_logc(
   11752 				zone, DNS_LOGCATEGORY_ZONELOAD,
   11753 				ISC_LOG_DEBUG(1),
   11754 				"journal rollforward completed successfully "
   11755 				"using old journal format: %s",
   11756 				isc_result_totext(result));
   11757 		} else {
   11758 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   11759 				      ISC_LOG_DEBUG(1),
   11760 				      "journal rollforward completed "
   11761 				      "successfully: %s",
   11762 				      isc_result_totext(result));
   11763 		}
   11764 
   11765 		dns_journal_destroy(&journal);
   11766 		return (ISC_R_SUCCESS);
   11767 	case ISC_R_NOTFOUND:
   11768 	case ISC_R_RANGE:
   11769 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11770 			      "journal rollforward failed: journal out of sync "
   11771 			      "with zone");
   11772 		dns_journal_destroy(&journal);
   11773 		return (result);
   11774 	default:
   11775 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11776 			      "journal rollforward failed: %s",
   11777 			      isc_result_totext(result));
   11778 		dns_journal_destroy(&journal);
   11779 		return (result);
   11780 	}
   11781 }
   11782 
   11783 static void
   11784 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) {
   11785 	isc_result_t result;
   11786 	int32_t journalsize;
   11787 	dns_dbversion_t *ver = NULL;
   11788 	uint64_t dbsize;
   11789 	uint32_t options = 0;
   11790 
   11791 	INSIST(LOCKED_ZONE(zone));
   11792 	if (inline_raw(zone)) {
   11793 		INSIST(LOCKED_ZONE(zone->secure));
   11794 	}
   11795 
   11796 	journalsize = zone->journalsize;
   11797 	if (journalsize == -1) {
   11798 		journalsize = DNS_JOURNAL_SIZE_MAX;
   11799 		dns_db_currentversion(db, &ver);
   11800 		result = dns_db_getsize(db, ver, NULL, &dbsize);
   11801 		dns_db_closeversion(db, &ver, false);
   11802 		if (result != ISC_R_SUCCESS) {
   11803 			dns_zone_log(zone, ISC_LOG_ERROR,
   11804 				     "zone_journal_compact: "
   11805 				     "could not get zone size: %s",
   11806 				     isc_result_totext(result));
   11807 		} else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) {
   11808 			journalsize = (int32_t)dbsize * 2;
   11809 		}
   11810 	}
   11811 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIXJOURNAL)) {
   11812 		options |= DNS_JOURNAL_COMPACTALL;
   11813 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FIXJOURNAL);
   11814 		zone_debuglog(zone, "zone_journal_compact", 1,
   11815 			      "repair full journal");
   11816 	} else {
   11817 		zone_debuglog(zone, "zone_journal_compact", 1,
   11818 			      "target journal size %d", journalsize);
   11819 	}
   11820 	result = dns_journal_compact(zone->mctx, zone->journal, serial, options,
   11821 				     journalsize);
   11822 	switch (result) {
   11823 	case ISC_R_SUCCESS:
   11824 	case ISC_R_NOSPACE:
   11825 	case ISC_R_NOTFOUND:
   11826 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s",
   11827 			     isc_result_totext(result));
   11828 		break;
   11829 	default:
   11830 		dns_zone_log(zone, ISC_LOG_ERROR,
   11831 			     "dns_journal_compact failed: %s",
   11832 			     isc_result_totext(result));
   11833 		break;
   11834 	}
   11835 }
   11836 
   11837 isc_result_t
   11838 dns_zone_flush(dns_zone_t *zone) {
   11839 	isc_result_t result = ISC_R_SUCCESS;
   11840 	bool dumping;
   11841 
   11842 	REQUIRE(DNS_ZONE_VALID(zone));
   11843 
   11844 	LOCK_ZONE(zone);
   11845 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
   11846 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11847 	    zone->masterfile != NULL)
   11848 	{
   11849 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   11850 		result = ISC_R_ALREADYRUNNING;
   11851 		dumping = was_dumping(zone);
   11852 	} else {
   11853 		dumping = true;
   11854 	}
   11855 	UNLOCK_ZONE(zone);
   11856 	if (!dumping) {
   11857 		result = zone_dump(zone, true); /* Unknown task. */
   11858 	}
   11859 	return (result);
   11860 }
   11861 
   11862 isc_result_t
   11863 dns_zone_dump(dns_zone_t *zone) {
   11864 	isc_result_t result = ISC_R_ALREADYRUNNING;
   11865 	bool dumping;
   11866 
   11867 	REQUIRE(DNS_ZONE_VALID(zone));
   11868 
   11869 	LOCK_ZONE(zone);
   11870 	dumping = was_dumping(zone);
   11871 	UNLOCK_ZONE(zone);
   11872 	if (!dumping) {
   11873 		result = zone_dump(zone, false); /* Unknown task. */
   11874 	}
   11875 	return (result);
   11876 }
   11877 
   11878 static void
   11879 zone_needdump(dns_zone_t *zone, unsigned int delay) {
   11880 	const char me[] = "zone_needdump";
   11881 	isc_time_t dumptime;
   11882 	isc_time_t now;
   11883 
   11884 	/*
   11885 	 * 'zone' locked by caller
   11886 	 */
   11887 
   11888 	REQUIRE(DNS_ZONE_VALID(zone));
   11889 	REQUIRE(LOCKED_ZONE(zone));
   11890 	ENTER;
   11891 
   11892 	/*
   11893 	 * Do we have a place to dump to and are we loaded?
   11894 	 */
   11895 	if (zone->masterfile == NULL ||
   11896 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
   11897 	{
   11898 		return;
   11899 	}
   11900 
   11901 	TIME_NOW(&now);
   11902 	/* add some noise */
   11903 	DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
   11904 
   11905 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11906 	if (isc_time_isepoch(&zone->dumptime) ||
   11907 	    isc_time_compare(&zone->dumptime, &dumptime) > 0)
   11908 	{
   11909 		zone->dumptime = dumptime;
   11910 	}
   11911 	if (zone->task != NULL) {
   11912 		zone_settimer(zone, &now);
   11913 	}
   11914 }
   11915 
   11916 static void
   11917 dump_done(void *arg, isc_result_t result) {
   11918 	const char me[] = "dump_done";
   11919 	dns_zone_t *zone = arg;
   11920 	dns_zone_t *secure = NULL;
   11921 	dns_db_t *db;
   11922 	dns_dbversion_t *version;
   11923 	bool again = false;
   11924 	bool compact = false;
   11925 	uint32_t serial;
   11926 	isc_result_t tresult;
   11927 
   11928 	REQUIRE(DNS_ZONE_VALID(zone));
   11929 
   11930 	ENTER;
   11931 
   11932 	if (result == ISC_R_SUCCESS && zone->journal != NULL) {
   11933 		/*
   11934 		 * We don't own these, zone->dctx must stay valid.
   11935 		 */
   11936 		db = dns_dumpctx_db(zone->dctx);
   11937 		version = dns_dumpctx_version(zone->dctx);
   11938 		tresult = dns_db_getsoaserial(db, version, &serial);
   11939 
   11940 		/*
   11941 		 * Handle lock order inversion.
   11942 		 */
   11943 	again:
   11944 		LOCK_ZONE(zone);
   11945 		if (inline_raw(zone)) {
   11946 			secure = zone->secure;
   11947 			INSIST(secure != zone);
   11948 			TRYLOCK_ZONE(result, secure);
   11949 			if (result != ISC_R_SUCCESS) {
   11950 				UNLOCK_ZONE(zone);
   11951 				secure = NULL;
   11952 				isc_thread_yield();
   11953 				goto again;
   11954 			}
   11955 		}
   11956 
   11957 		/*
   11958 		 * If there is a secure version of this zone
   11959 		 * use its serial if it is less than ours.
   11960 		 */
   11961 		if (tresult == ISC_R_SUCCESS && secure != NULL) {
   11962 			uint32_t sserial;
   11963 			isc_result_t mresult;
   11964 
   11965 			ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
   11966 			if (secure->db != NULL) {
   11967 				mresult = dns_db_getsoaserial(zone->secure->db,
   11968 							      NULL, &sserial);
   11969 				if (mresult == ISC_R_SUCCESS &&
   11970 				    isc_serial_lt(sserial, serial))
   11971 				{
   11972 					serial = sserial;
   11973 				}
   11974 			}
   11975 			ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
   11976 		}
   11977 		if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
   11978 			dns_db_t *zdb = NULL;
   11979 			if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) {
   11980 				zone_journal_compact(zone, zdb, serial);
   11981 				dns_db_detach(&zdb);
   11982 			}
   11983 		} else if (tresult == ISC_R_SUCCESS) {
   11984 			compact = true;
   11985 			zone->compact_serial = serial;
   11986 		}
   11987 		if (secure != NULL) {
   11988 			UNLOCK_ZONE(secure);
   11989 		}
   11990 		UNLOCK_ZONE(zone);
   11991 	}
   11992 
   11993 	LOCK_ZONE(zone);
   11994 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   11995 	if (compact) {
   11996 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   11997 	}
   11998 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN)) {
   11999 		/*
   12000 		 * If DNS_ZONEFLG_SHUTDOWN is set, all external references to
   12001 		 * the zone are gone, which means it is in the process of being
   12002 		 * cleaned up, so do not reschedule dumping.
   12003 		 *
   12004 		 * Detach from the raw version of the zone in case this
   12005 		 * operation has been deferred in zone_shutdown().
   12006 		 */
   12007 		if (zone->raw != NULL) {
   12008 			dns_zone_detach(&zone->raw);
   12009 		}
   12010 		if (result == ISC_R_SUCCESS) {
   12011 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   12012 		}
   12013 	} else if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
   12014 		/*
   12015 		 * Try again in a short while.
   12016 		 */
   12017 		zone_needdump(zone, DNS_DUMP_DELAY);
   12018 	} else if (result == ISC_R_SUCCESS &&
   12019 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   12020 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   12021 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12022 	{
   12023 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   12024 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   12025 		isc_time_settoepoch(&zone->dumptime);
   12026 		again = true;
   12027 	} else if (result == ISC_R_SUCCESS) {
   12028 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   12029 	}
   12030 
   12031 	if (zone->dctx != NULL) {
   12032 		dns_dumpctx_detach(&zone->dctx);
   12033 	}
   12034 	zonemgr_putio(&zone->writeio);
   12035 	UNLOCK_ZONE(zone);
   12036 	if (again) {
   12037 		(void)zone_dump(zone, false);
   12038 	}
   12039 	dns_zone_idetach(&zone);
   12040 }
   12041 
   12042 static isc_result_t
   12043 zone_dump(dns_zone_t *zone, bool compact) {
   12044 	const char me[] = "zone_dump";
   12045 	isc_result_t result;
   12046 	dns_dbversion_t *version = NULL;
   12047 	bool again;
   12048 	dns_db_t *db = NULL;
   12049 	char *masterfile = NULL;
   12050 	dns_masterformat_t masterformat = dns_masterformat_none;
   12051 
   12052 	/*
   12053 	 * 'compact' MUST only be set if we are task locked.
   12054 	 */
   12055 
   12056 	REQUIRE(DNS_ZONE_VALID(zone));
   12057 	ENTER;
   12058 
   12059 redo:
   12060 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12061 	if (zone->db != NULL) {
   12062 		dns_db_attach(zone->db, &db);
   12063 	}
   12064 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12065 	LOCK_ZONE(zone);
   12066 	if (zone->masterfile != NULL) {
   12067 		masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
   12068 		masterformat = zone->masterformat;
   12069 	}
   12070 	UNLOCK_ZONE(zone);
   12071 	if (db == NULL) {
   12072 		result = DNS_R_NOTLOADED;
   12073 		goto fail;
   12074 	}
   12075 	if (masterfile == NULL) {
   12076 		result = DNS_R_NOMASTERFILE;
   12077 		goto fail;
   12078 	}
   12079 
   12080 	if (compact && zone->type != dns_zone_stub) {
   12081 		dns_zone_t *dummy = NULL;
   12082 		LOCK_ZONE(zone);
   12083 		zone_iattach(zone, &dummy);
   12084 		result = zonemgr_getio(zone->zmgr, false, zone->task,
   12085 				       zone_gotwritehandle, zone,
   12086 				       &zone->writeio);
   12087 		if (result != ISC_R_SUCCESS) {
   12088 			zone_idetach(&dummy);
   12089 		} else {
   12090 			result = DNS_R_CONTINUE;
   12091 		}
   12092 		UNLOCK_ZONE(zone);
   12093 	} else {
   12094 		const dns_master_style_t *output_style;
   12095 
   12096 		dns_masterrawheader_t rawdata;
   12097 		dns_db_currentversion(db, &version);
   12098 		dns_master_initrawheader(&rawdata);
   12099 		if (inline_secure(zone)) {
   12100 			get_raw_serial(zone->raw, &rawdata);
   12101 		}
   12102 		if (zone->type == dns_zone_key) {
   12103 			output_style = &dns_master_style_keyzone;
   12104 		} else {
   12105 			output_style = &dns_master_style_default;
   12106 		}
   12107 		result = dns_master_dump(zone->mctx, db, version, output_style,
   12108 					 masterfile, masterformat, &rawdata);
   12109 		dns_db_closeversion(db, &version, false);
   12110 	}
   12111 fail:
   12112 	if (db != NULL) {
   12113 		dns_db_detach(&db);
   12114 	}
   12115 	if (masterfile != NULL) {
   12116 		isc_mem_free(zone->mctx, masterfile);
   12117 	}
   12118 	masterfile = NULL;
   12119 
   12120 	if (result == DNS_R_CONTINUE) {
   12121 		return (ISC_R_SUCCESS); /* XXXMPA */
   12122 	}
   12123 
   12124 	again = false;
   12125 	LOCK_ZONE(zone);
   12126 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   12127 	if (result != ISC_R_SUCCESS) {
   12128 		/*
   12129 		 * Try again in a short while.
   12130 		 */
   12131 		zone_needdump(zone, DNS_DUMP_DELAY);
   12132 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   12133 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   12134 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12135 	{
   12136 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   12137 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   12138 		isc_time_settoepoch(&zone->dumptime);
   12139 		again = true;
   12140 	} else {
   12141 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   12142 	}
   12143 	UNLOCK_ZONE(zone);
   12144 	if (again) {
   12145 		goto redo;
   12146 	}
   12147 
   12148 	return (result);
   12149 }
   12150 
   12151 static isc_result_t
   12152 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
   12153 	     dns_masterformat_t format, const uint32_t rawversion) {
   12154 	isc_result_t result;
   12155 	dns_dbversion_t *version = NULL;
   12156 	dns_db_t *db = NULL;
   12157 	dns_masterrawheader_t rawdata;
   12158 
   12159 	REQUIRE(DNS_ZONE_VALID(zone));
   12160 
   12161 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12162 	if (zone->db != NULL) {
   12163 		dns_db_attach(zone->db, &db);
   12164 	}
   12165 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12166 	if (db == NULL) {
   12167 		return (DNS_R_NOTLOADED);
   12168 	}
   12169 
   12170 	dns_db_currentversion(db, &version);
   12171 	dns_master_initrawheader(&rawdata);
   12172 	if (rawversion == 0) {
   12173 		rawdata.flags |= DNS_MASTERRAW_COMPAT;
   12174 	} else if (inline_secure(zone)) {
   12175 		get_raw_serial(zone->raw, &rawdata);
   12176 	} else if (zone->sourceserialset) {
   12177 		rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
   12178 		rawdata.sourceserial = zone->sourceserial;
   12179 	}
   12180 	result = dns_master_dumptostream(zone->mctx, db, version, style, format,
   12181 					 &rawdata, fd);
   12182 	dns_db_closeversion(db, &version, false);
   12183 	dns_db_detach(&db);
   12184 	return (result);
   12185 }
   12186 
   12187 isc_result_t
   12188 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
   12189 		      const dns_master_style_t *style,
   12190 		      const uint32_t rawversion) {
   12191 	return (dumptostream(zone, fd, style, format, rawversion));
   12192 }
   12193 
   12194 void
   12195 dns_zone_unload(dns_zone_t *zone) {
   12196 	REQUIRE(DNS_ZONE_VALID(zone));
   12197 
   12198 	LOCK_ZONE(zone);
   12199 	zone_unload(zone);
   12200 	UNLOCK_ZONE(zone);
   12201 }
   12202 
   12203 static void
   12204 notify_cancel(dns_zone_t *zone) {
   12205 	dns_notify_t *notify;
   12206 
   12207 	/*
   12208 	 * 'zone' locked by caller.
   12209 	 */
   12210 
   12211 	REQUIRE(LOCKED_ZONE(zone));
   12212 
   12213 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   12214 	     notify = ISC_LIST_NEXT(notify, link))
   12215 	{
   12216 		if (notify->find != NULL) {
   12217 			dns_adb_cancelfind(notify->find);
   12218 		}
   12219 		if (notify->request != NULL) {
   12220 			dns_request_cancel(notify->request);
   12221 		}
   12222 	}
   12223 }
   12224 
   12225 static void
   12226 checkds_cancel(dns_zone_t *zone) {
   12227 	dns_checkds_t *checkds;
   12228 
   12229 	/*
   12230 	 * 'zone' locked by caller.
   12231 	 */
   12232 
   12233 	REQUIRE(LOCKED_ZONE(zone));
   12234 
   12235 	for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL;
   12236 	     checkds = ISC_LIST_NEXT(checkds, link))
   12237 	{
   12238 		if (checkds->request != NULL) {
   12239 			dns_request_cancel(checkds->request);
   12240 		}
   12241 	}
   12242 }
   12243 
   12244 static void
   12245 forward_cancel(dns_zone_t *zone) {
   12246 	dns_forward_t *forward;
   12247 
   12248 	/*
   12249 	 * 'zone' locked by caller.
   12250 	 */
   12251 
   12252 	REQUIRE(LOCKED_ZONE(zone));
   12253 
   12254 	for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL;
   12255 	     forward = ISC_LIST_NEXT(forward, link))
   12256 	{
   12257 		if (forward->request != NULL) {
   12258 			dns_request_cancel(forward->request);
   12259 		}
   12260 	}
   12261 }
   12262 
   12263 static void
   12264 zone_unload(dns_zone_t *zone) {
   12265 	/*
   12266 	 * 'zone' locked by caller.
   12267 	 */
   12268 
   12269 	REQUIRE(LOCKED_ZONE(zone));
   12270 
   12271 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   12272 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   12273 	{
   12274 		if (zone->writeio != NULL) {
   12275 			zonemgr_cancelio(zone->writeio);
   12276 		}
   12277 
   12278 		if (zone->dctx != NULL) {
   12279 			dns_dumpctx_cancel(zone->dctx);
   12280 		}
   12281 	}
   12282 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   12283 	zone_detachdb(zone);
   12284 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   12285 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
   12286 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   12287 
   12288 	if (zone->type == dns_zone_mirror) {
   12289 		dns_zone_log(zone, ISC_LOG_INFO,
   12290 			     "mirror zone is no longer in use; "
   12291 			     "reverting to normal recursion");
   12292 	}
   12293 }
   12294 
   12295 void
   12296 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
   12297 	REQUIRE(DNS_ZONE_VALID(zone));
   12298 	REQUIRE(val > 0);
   12299 
   12300 	zone->minrefresh = val;
   12301 }
   12302 
   12303 void
   12304 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
   12305 	REQUIRE(DNS_ZONE_VALID(zone));
   12306 	REQUIRE(val > 0);
   12307 
   12308 	zone->maxrefresh = val;
   12309 }
   12310 
   12311 void
   12312 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
   12313 	REQUIRE(DNS_ZONE_VALID(zone));
   12314 	REQUIRE(val > 0);
   12315 
   12316 	zone->minretry = val;
   12317 }
   12318 
   12319 void
   12320 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
   12321 	REQUIRE(DNS_ZONE_VALID(zone));
   12322 	REQUIRE(val > 0);
   12323 
   12324 	zone->maxretry = val;
   12325 }
   12326 
   12327 uint32_t
   12328 dns_zone_getmaxrecords(dns_zone_t *zone) {
   12329 	REQUIRE(DNS_ZONE_VALID(zone));
   12330 
   12331 	return (zone->maxrecords);
   12332 }
   12333 
   12334 void
   12335 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
   12336 	REQUIRE(DNS_ZONE_VALID(zone));
   12337 
   12338 	zone->maxrecords = val;
   12339 }
   12340 
   12341 static bool
   12342 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
   12343 		isc_sockaddr_t *addr, dns_tsigkey_t *key,
   12344 		dns_transport_t *transport) {
   12345 	dns_notify_t *notify;
   12346 	dns_zonemgr_t *zmgr;
   12347 	isc_result_t result;
   12348 
   12349 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   12350 	     notify = ISC_LIST_NEXT(notify, link))
   12351 	{
   12352 		if (notify->request != NULL) {
   12353 			continue;
   12354 		}
   12355 		if (name != NULL && dns_name_dynamic(&notify->ns) &&
   12356 		    dns_name_equal(name, &notify->ns))
   12357 		{
   12358 			goto requeue;
   12359 		}
   12360 		if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
   12361 		    notify->key == key && notify->transport == transport)
   12362 		{
   12363 			goto requeue;
   12364 		}
   12365 	}
   12366 	return (false);
   12367 
   12368 requeue:
   12369 	/*
   12370 	 * If we are enqueued on the startup ratelimiter and this is
   12371 	 * not a startup notify, re-enqueue on the normal notify
   12372 	 * ratelimiter.
   12373 	 */
   12374 	if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
   12375 	    (notify->flags & DNS_NOTIFY_STARTUP) != 0)
   12376 	{
   12377 		zmgr = notify->zone->zmgr;
   12378 		result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
   12379 						 notify->event);
   12380 		if (result != ISC_R_SUCCESS) {
   12381 			return (true);
   12382 		}
   12383 
   12384 		notify->flags &= ~DNS_NOTIFY_STARTUP;
   12385 		result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
   12386 						 notify->zone->task,
   12387 						 &notify->event);
   12388 		if (result != ISC_R_SUCCESS) {
   12389 			isc_event_free(&notify->event);
   12390 			return (false);
   12391 		}
   12392 	}
   12393 
   12394 	return (true);
   12395 }
   12396 
   12397 static bool
   12398 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
   12399 	dns_tsigkey_t *key = NULL;
   12400 	isc_sockaddr_t src;
   12401 	isc_sockaddr_t any;
   12402 	bool isself;
   12403 	isc_netaddr_t dstaddr;
   12404 	isc_result_t result;
   12405 
   12406 	if (zone->view == NULL || zone->isself == NULL) {
   12407 		return (false);
   12408 	}
   12409 
   12410 	switch (isc_sockaddr_pf(dst)) {
   12411 	case PF_INET:
   12412 		src = zone->notifysrc4;
   12413 		isc_sockaddr_any(&any);
   12414 		break;
   12415 	case PF_INET6:
   12416 		src = zone->notifysrc6;
   12417 		isc_sockaddr_any6(&any);
   12418 		break;
   12419 	default:
   12420 		return (false);
   12421 	}
   12422 
   12423 	/*
   12424 	 * When sending from any the kernel will assign a source address
   12425 	 * that matches the destination address.
   12426 	 */
   12427 	if (isc_sockaddr_eqaddr(&any, &src)) {
   12428 		src = *dst;
   12429 	}
   12430 
   12431 	isc_netaddr_fromsockaddr(&dstaddr, dst);
   12432 	result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
   12433 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12434 		return (false);
   12435 	}
   12436 	isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
   12437 				zone->isselfarg);
   12438 	if (key != NULL) {
   12439 		dns_tsigkey_detach(&key);
   12440 	}
   12441 	return (isself);
   12442 }
   12443 
   12444 static void
   12445 notify_destroy(dns_notify_t *notify, bool locked) {
   12446 	isc_mem_t *mctx;
   12447 
   12448 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12449 
   12450 	if (notify->zone != NULL) {
   12451 		if (!locked) {
   12452 			LOCK_ZONE(notify->zone);
   12453 		}
   12454 		REQUIRE(LOCKED_ZONE(notify->zone));
   12455 		if (ISC_LINK_LINKED(notify, link)) {
   12456 			ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
   12457 		}
   12458 		if (!locked) {
   12459 			UNLOCK_ZONE(notify->zone);
   12460 		}
   12461 		if (locked) {
   12462 			zone_idetach(&notify->zone);
   12463 		} else {
   12464 			dns_zone_idetach(&notify->zone);
   12465 		}
   12466 	}
   12467 	if (notify->find != NULL) {
   12468 		dns_adb_destroyfind(&notify->find);
   12469 	}
   12470 	if (notify->request != NULL) {
   12471 		dns_request_destroy(&notify->request);
   12472 	}
   12473 	if (dns_name_dynamic(&notify->ns)) {
   12474 		dns_name_free(&notify->ns, notify->mctx);
   12475 	}
   12476 	if (notify->key != NULL) {
   12477 		dns_tsigkey_detach(&notify->key);
   12478 	}
   12479 	if (notify->transport != NULL) {
   12480 		dns_transport_detach(&notify->transport);
   12481 	}
   12482 	mctx = notify->mctx;
   12483 	isc_mem_put(notify->mctx, notify, sizeof(*notify));
   12484 	isc_mem_detach(&mctx);
   12485 }
   12486 
   12487 static isc_result_t
   12488 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
   12489 	dns_notify_t *notify;
   12490 
   12491 	REQUIRE(notifyp != NULL && *notifyp == NULL);
   12492 
   12493 	notify = isc_mem_get(mctx, sizeof(*notify));
   12494 	*notify = (dns_notify_t){
   12495 		.flags = flags,
   12496 	};
   12497 
   12498 	isc_mem_attach(mctx, &notify->mctx);
   12499 	isc_sockaddr_any(&notify->dst);
   12500 	dns_name_init(&notify->ns, NULL);
   12501 	ISC_LINK_INIT(notify, link);
   12502 	notify->magic = NOTIFY_MAGIC;
   12503 	*notifyp = notify;
   12504 	return (ISC_R_SUCCESS);
   12505 }
   12506 
   12507 /*
   12508  * XXXAG should check for DNS_ZONEFLG_EXITING
   12509  */
   12510 static void
   12511 process_adb_event(isc_task_t *task, isc_event_t *ev) {
   12512 	dns_notify_t *notify;
   12513 	isc_eventtype_t result;
   12514 
   12515 	UNUSED(task);
   12516 
   12517 	notify = ev->ev_arg;
   12518 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12519 	INSIST(task == notify->zone->task);
   12520 	result = ev->ev_type;
   12521 	isc_event_free(&ev);
   12522 	if (result == DNS_EVENT_ADBMOREADDRESSES) {
   12523 		dns_adb_destroyfind(&notify->find);
   12524 		notify_find_address(notify);
   12525 		return;
   12526 	}
   12527 	if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
   12528 		LOCK_ZONE(notify->zone);
   12529 		notify_send(notify);
   12530 		UNLOCK_ZONE(notify->zone);
   12531 	}
   12532 	notify_destroy(notify, false);
   12533 }
   12534 
   12535 static void
   12536 notify_find_address(dns_notify_t *notify) {
   12537 	isc_result_t result;
   12538 	unsigned int options;
   12539 
   12540 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12541 	options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 |
   12542 		  DNS_ADBFIND_RETURNLAME;
   12543 
   12544 	if (notify->zone->view->adb == NULL) {
   12545 		goto destroy;
   12546 	}
   12547 
   12548 	result = dns_adb_createfind(
   12549 		notify->zone->view->adb, notify->zone->task, process_adb_event,
   12550 		notify, &notify->ns, dns_rootname, 0, options, 0, NULL,
   12551 		notify->zone->view->dstport, 0, NULL, &notify->find);
   12552 
   12553 	/* Something failed? */
   12554 	if (result != ISC_R_SUCCESS) {
   12555 		goto destroy;
   12556 	}
   12557 
   12558 	/* More addresses pending? */
   12559 	if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) {
   12560 		return;
   12561 	}
   12562 
   12563 	/* We have as many addresses as we can get. */
   12564 	LOCK_ZONE(notify->zone);
   12565 	notify_send(notify);
   12566 	UNLOCK_ZONE(notify->zone);
   12567 
   12568 destroy:
   12569 	notify_destroy(notify, false);
   12570 }
   12571 
   12572 static isc_result_t
   12573 notify_send_queue(dns_notify_t *notify, bool startup) {
   12574 	isc_event_t *e;
   12575 	isc_result_t result;
   12576 
   12577 	INSIST(notify->event == NULL);
   12578 	e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
   12579 			       notify_send_toaddr, notify, sizeof(isc_event_t));
   12580 	if (startup) {
   12581 		notify->event = e;
   12582 	}
   12583 	e->ev_arg = notify;
   12584 	e->ev_sender = NULL;
   12585 	result = isc_ratelimiter_enqueue(
   12586 		startup ? notify->zone->zmgr->startupnotifyrl
   12587 			: notify->zone->zmgr->notifyrl,
   12588 		notify->zone->task, &e);
   12589 	if (result != ISC_R_SUCCESS) {
   12590 		isc_event_free(&e);
   12591 		notify->event = NULL;
   12592 	}
   12593 	return (result);
   12594 }
   12595 
   12596 static void
   12597 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
   12598 	dns_notify_t *notify;
   12599 	isc_result_t result;
   12600 	dns_message_t *message = NULL;
   12601 	isc_netaddr_t dstip;
   12602 	dns_tsigkey_t *key = NULL;
   12603 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   12604 	isc_sockaddr_t src;
   12605 	unsigned int options, timeout;
   12606 	bool have_notifysource = false;
   12607 
   12608 	notify = event->ev_arg;
   12609 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12610 
   12611 	UNUSED(task);
   12612 
   12613 	LOCK_ZONE(notify->zone);
   12614 
   12615 	notify->event = NULL;
   12616 
   12617 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
   12618 		result = ISC_R_CANCELED;
   12619 		goto cleanup;
   12620 	}
   12621 
   12622 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
   12623 	    DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
   12624 	    notify->zone->view->requestmgr == NULL || notify->zone->db == NULL)
   12625 	{
   12626 		result = ISC_R_CANCELED;
   12627 		goto cleanup;
   12628 	}
   12629 
   12630 	/*
   12631 	 * The raw IPv4 address should also exist.  Don't send to the
   12632 	 * mapped form.
   12633 	 */
   12634 	if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
   12635 	    IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr))
   12636 	{
   12637 		isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12638 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12639 			   "notify: ignoring IPv6 mapped IPV4 address: %s",
   12640 			   addrbuf);
   12641 		result = ISC_R_CANCELED;
   12642 		goto cleanup;
   12643 	}
   12644 
   12645 	result = notify_createmessage(notify->zone, notify->flags, &message);
   12646 	if (result != ISC_R_SUCCESS) {
   12647 		goto cleanup;
   12648 	}
   12649 
   12650 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12651 	if (notify->key != NULL) {
   12652 		/* Transfer ownership of key */
   12653 		key = notify->key;
   12654 		notify->key = NULL;
   12655 	} else {
   12656 		isc_netaddr_fromsockaddr(&dstip, &notify->dst);
   12657 		result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
   12658 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12659 			notify_log(notify->zone, ISC_LOG_ERROR,
   12660 				   "NOTIFY to %s not sent. "
   12661 				   "Peer TSIG key lookup failure.",
   12662 				   addrbuf);
   12663 			goto cleanup_message;
   12664 		}
   12665 	}
   12666 
   12667 	if (key != NULL) {
   12668 		char namebuf[DNS_NAME_FORMATSIZE];
   12669 
   12670 		dns_name_format(&key->name, namebuf, sizeof(namebuf));
   12671 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12672 			   "sending notify to %s : TSIG (%s)", addrbuf,
   12673 			   namebuf);
   12674 	} else {
   12675 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12676 			   "sending notify to %s", addrbuf);
   12677 	}
   12678 	options = 0;
   12679 	if (notify->zone->view->peers != NULL) {
   12680 		dns_peer_t *peer = NULL;
   12681 		bool usetcp = false;
   12682 		result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
   12683 						 &dstip, &peer);
   12684 		if (result == ISC_R_SUCCESS) {
   12685 			result = dns_peer_getnotifysource(peer, &src);
   12686 			if (result == ISC_R_SUCCESS) {
   12687 				have_notifysource = true;
   12688 			}
   12689 			result = dns_peer_getforcetcp(peer, &usetcp);
   12690 			if (result == ISC_R_SUCCESS && usetcp) {
   12691 				options |= DNS_FETCHOPT_TCP;
   12692 			}
   12693 		}
   12694 	}
   12695 	switch (isc_sockaddr_pf(&notify->dst)) {
   12696 	case PF_INET:
   12697 		if (!have_notifysource) {
   12698 			src = notify->zone->notifysrc4;
   12699 		}
   12700 		break;
   12701 	case PF_INET6:
   12702 		if (!have_notifysource) {
   12703 			src = notify->zone->notifysrc6;
   12704 		}
   12705 		break;
   12706 	default:
   12707 		result = ISC_R_NOTIMPLEMENTED;
   12708 		goto cleanup_key;
   12709 	}
   12710 	timeout = 5;
   12711 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12712 		timeout = 30;
   12713 	}
   12714 	result = dns_request_create(
   12715 		notify->zone->view->requestmgr, message, &src, &notify->dst,
   12716 		options, key, timeout * 3 + 1, timeout, 2, notify->zone->task,
   12717 		notify_done, notify, &notify->request);
   12718 	if (result == ISC_R_SUCCESS) {
   12719 		if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
   12720 			inc_stats(notify->zone,
   12721 				  dns_zonestatscounter_notifyoutv4);
   12722 		} else {
   12723 			inc_stats(notify->zone,
   12724 				  dns_zonestatscounter_notifyoutv6);
   12725 		}
   12726 	}
   12727 
   12728 cleanup_key:
   12729 	if (key != NULL) {
   12730 		dns_tsigkey_detach(&key);
   12731 	}
   12732 cleanup_message:
   12733 	dns_message_detach(&message);
   12734 cleanup:
   12735 	UNLOCK_ZONE(notify->zone);
   12736 	isc_event_free(&event);
   12737 	if (result != ISC_R_SUCCESS) {
   12738 		notify_destroy(notify, false);
   12739 	}
   12740 }
   12741 
   12742 static void
   12743 notify_send(dns_notify_t *notify) {
   12744 	dns_adbaddrinfo_t *ai;
   12745 	isc_sockaddr_t dst;
   12746 	isc_result_t result;
   12747 	dns_notify_t *newnotify = NULL;
   12748 	unsigned int flags;
   12749 	bool startup;
   12750 
   12751 	/*
   12752 	 * Zone lock held by caller.
   12753 	 */
   12754 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12755 	REQUIRE(LOCKED_ZONE(notify->zone));
   12756 
   12757 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) {
   12758 		return;
   12759 	}
   12760 
   12761 	for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL;
   12762 	     ai = ISC_LIST_NEXT(ai, publink))
   12763 	{
   12764 		dst = ai->sockaddr;
   12765 		if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
   12766 				    NULL, NULL))
   12767 		{
   12768 			continue;
   12769 		}
   12770 		if (notify_isself(notify->zone, &dst)) {
   12771 			continue;
   12772 		}
   12773 		newnotify = NULL;
   12774 		flags = notify->flags & DNS_NOTIFY_NOSOA;
   12775 		result = notify_create(notify->mctx, flags, &newnotify);
   12776 		if (result != ISC_R_SUCCESS) {
   12777 			goto cleanup;
   12778 		}
   12779 		zone_iattach(notify->zone, &newnotify->zone);
   12780 		ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link);
   12781 		newnotify->dst = dst;
   12782 		startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0);
   12783 		result = notify_send_queue(newnotify, startup);
   12784 		if (result != ISC_R_SUCCESS) {
   12785 			goto cleanup;
   12786 		}
   12787 		newnotify = NULL;
   12788 	}
   12789 
   12790 cleanup:
   12791 	if (newnotify != NULL) {
   12792 		notify_destroy(newnotify, true);
   12793 	}
   12794 }
   12795 
   12796 void
   12797 dns_zone_notify(dns_zone_t *zone) {
   12798 	isc_time_t now;
   12799 
   12800 	REQUIRE(DNS_ZONE_VALID(zone));
   12801 
   12802 	LOCK_ZONE(zone);
   12803 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12804 
   12805 	TIME_NOW(&now);
   12806 	zone_settimer(zone, &now);
   12807 	UNLOCK_ZONE(zone);
   12808 }
   12809 
   12810 static void
   12811 zone_notify(dns_zone_t *zone, isc_time_t *now) {
   12812 	dns_dbnode_t *node = NULL;
   12813 	dns_db_t *zonedb = NULL;
   12814 	dns_dbversion_t *version = NULL;
   12815 	dns_name_t *origin = NULL;
   12816 	dns_name_t primary;
   12817 	dns_rdata_ns_t ns;
   12818 	dns_rdata_soa_t soa;
   12819 	uint32_t serial;
   12820 	dns_rdata_t rdata = DNS_RDATA_INIT;
   12821 	dns_rdataset_t nsrdset;
   12822 	dns_rdataset_t soardset;
   12823 	isc_result_t result;
   12824 	unsigned int i;
   12825 	isc_sockaddr_t dst;
   12826 	bool isqueued;
   12827 	dns_notifytype_t notifytype;
   12828 	unsigned int flags = 0;
   12829 	bool loggednotify = false;
   12830 	bool startup;
   12831 
   12832 	REQUIRE(DNS_ZONE_VALID(zone));
   12833 
   12834 	LOCK_ZONE(zone);
   12835 	startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12836 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12837 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   12838 	notifytype = zone->notifytype;
   12839 	DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
   12840 	UNLOCK_ZONE(zone);
   12841 
   12842 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   12843 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12844 	{
   12845 		return;
   12846 	}
   12847 
   12848 	if (notifytype == dns_notifytype_no) {
   12849 		return;
   12850 	}
   12851 
   12852 	if (notifytype == dns_notifytype_masteronly &&
   12853 	    zone->type != dns_zone_primary)
   12854 	{
   12855 		return;
   12856 	}
   12857 
   12858 	origin = &zone->origin;
   12859 
   12860 	/*
   12861 	 * If the zone is dialup we are done as we don't want to send
   12862 	 * the current soa so as to force a refresh query.
   12863 	 */
   12864 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12865 		flags |= DNS_NOTIFY_NOSOA;
   12866 	}
   12867 
   12868 	/*
   12869 	 * Record that this was a notify due to starting up.
   12870 	 */
   12871 	if (startup) {
   12872 		flags |= DNS_NOTIFY_STARTUP;
   12873 	}
   12874 
   12875 	/*
   12876 	 * Get SOA RRset.
   12877 	 */
   12878 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12879 	if (zone->db != NULL) {
   12880 		dns_db_attach(zone->db, &zonedb);
   12881 	}
   12882 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12883 	if (zonedb == NULL) {
   12884 		return;
   12885 	}
   12886 	dns_db_currentversion(zonedb, &version);
   12887 	result = dns_db_findnode(zonedb, origin, false, &node);
   12888 	if (result != ISC_R_SUCCESS) {
   12889 		goto cleanup1;
   12890 	}
   12891 
   12892 	dns_rdataset_init(&soardset);
   12893 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   12894 				     dns_rdatatype_none, 0, &soardset, NULL);
   12895 	if (result != ISC_R_SUCCESS) {
   12896 		goto cleanup2;
   12897 	}
   12898 
   12899 	/*
   12900 	 * Find serial and primary server's name.
   12901 	 */
   12902 	dns_name_init(&primary, NULL);
   12903 	result = dns_rdataset_first(&soardset);
   12904 	if (result != ISC_R_SUCCESS) {
   12905 		goto cleanup3;
   12906 	}
   12907 	dns_rdataset_current(&soardset, &rdata);
   12908 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   12909 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12910 	dns_rdata_reset(&rdata);
   12911 	dns_name_dup(&soa.origin, zone->mctx, &primary);
   12912 	serial = soa.serial;
   12913 	dns_rdataset_disassociate(&soardset);
   12914 
   12915 	/*
   12916 	 * Enqueue notify requests for 'also-notify' servers.
   12917 	 */
   12918 	LOCK_ZONE(zone);
   12919 	for (i = 0; i < zone->notifycnt; i++) {
   12920 		dns_tsigkey_t *key = NULL;
   12921 		dns_transport_t *transport = NULL;
   12922 		dns_notify_t *notify = NULL;
   12923 		dns_view_t *view = dns_zone_getview(zone);
   12924 
   12925 		if ((zone->notifykeynames != NULL) &&
   12926 		    (zone->notifykeynames[i] != NULL))
   12927 		{
   12928 			dns_name_t *keyname = zone->notifykeynames[i];
   12929 			(void)dns_view_gettsig(view, keyname, &key);
   12930 		}
   12931 
   12932 		if ((zone->notifytlsnames != NULL) &&
   12933 		    (zone->notifytlsnames[i] != NULL))
   12934 		{
   12935 			dns_name_t *tlsname = zone->notifytlsnames[i];
   12936 			(void)dns_view_gettransport(view, DNS_TRANSPORT_TLS,
   12937 						    tlsname, &transport);
   12938 
   12939 			dns_zone_logc(
   12940 				zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   12941 				"got TLS configuration for zone transfer");
   12942 		}
   12943 
   12944 		/* TODO: glue the transport to the notify */
   12945 
   12946 		dst = zone->notify[i];
   12947 		if (notify_isqueued(zone, flags, NULL, &dst, key, transport)) {
   12948 			if (key != NULL) {
   12949 				dns_tsigkey_detach(&key);
   12950 			}
   12951 			if (transport != NULL) {
   12952 				dns_transport_detach(&transport);
   12953 			}
   12954 			continue;
   12955 		}
   12956 
   12957 		result = notify_create(zone->mctx, flags, &notify);
   12958 		if (result != ISC_R_SUCCESS) {
   12959 			if (key != NULL) {
   12960 				dns_tsigkey_detach(&key);
   12961 			}
   12962 			if (transport != NULL) {
   12963 				dns_transport_detach(&transport);
   12964 			}
   12965 			continue;
   12966 		}
   12967 
   12968 		zone_iattach(zone, &notify->zone);
   12969 		notify->dst = dst;
   12970 
   12971 		INSIST(notify->key == NULL);
   12972 
   12973 		if (key != NULL) {
   12974 			notify->key = key;
   12975 			key = NULL;
   12976 		}
   12977 
   12978 		INSIST(notify->transport == NULL);
   12979 		if (transport != NULL) {
   12980 			notify->transport = transport;
   12981 			transport = NULL;
   12982 		}
   12983 
   12984 		ISC_LIST_APPEND(zone->notifies, notify, link);
   12985 		result = notify_send_queue(notify, startup);
   12986 		if (result != ISC_R_SUCCESS) {
   12987 			notify_destroy(notify, true);
   12988 		}
   12989 		if (!loggednotify) {
   12990 			notify_log(zone, ISC_LOG_INFO,
   12991 				   "sending notifies (serial %u)", serial);
   12992 			loggednotify = true;
   12993 		}
   12994 	}
   12995 	UNLOCK_ZONE(zone);
   12996 
   12997 	if (notifytype == dns_notifytype_explicit) {
   12998 		goto cleanup3;
   12999 	}
   13000 
   13001 	/*
   13002 	 * Process NS RRset to generate notifies.
   13003 	 */
   13004 
   13005 	dns_rdataset_init(&nsrdset);
   13006 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
   13007 				     dns_rdatatype_none, 0, &nsrdset, NULL);
   13008 	if (result != ISC_R_SUCCESS) {
   13009 		goto cleanup3;
   13010 	}
   13011 
   13012 	result = dns_rdataset_first(&nsrdset);
   13013 	while (result == ISC_R_SUCCESS) {
   13014 		dns_notify_t *notify = NULL;
   13015 
   13016 		dns_rdataset_current(&nsrdset, &rdata);
   13017 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   13018 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13019 		dns_rdata_reset(&rdata);
   13020 		/*
   13021 		 * Don't notify the primary server unless explicitly
   13022 		 * configured to do so.
   13023 		 */
   13024 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
   13025 		    dns_name_compare(&primary, &ns.name) == 0)
   13026 		{
   13027 			result = dns_rdataset_next(&nsrdset);
   13028 			continue;
   13029 		}
   13030 
   13031 		if (!loggednotify) {
   13032 			notify_log(zone, ISC_LOG_INFO,
   13033 				   "sending notifies (serial %u)", serial);
   13034 			loggednotify = true;
   13035 		}
   13036 
   13037 		LOCK_ZONE(zone);
   13038 		isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL,
   13039 					   NULL);
   13040 		UNLOCK_ZONE(zone);
   13041 		if (isqueued) {
   13042 			result = dns_rdataset_next(&nsrdset);
   13043 			continue;
   13044 		}
   13045 		result = notify_create(zone->mctx, flags, &notify);
   13046 		if (result != ISC_R_SUCCESS) {
   13047 			continue;
   13048 		}
   13049 		dns_zone_iattach(zone, &notify->zone);
   13050 		dns_name_dup(&ns.name, zone->mctx, &notify->ns);
   13051 		LOCK_ZONE(zone);
   13052 		ISC_LIST_APPEND(zone->notifies, notify, link);
   13053 		UNLOCK_ZONE(zone);
   13054 		notify_find_address(notify);
   13055 		result = dns_rdataset_next(&nsrdset);
   13056 	}
   13057 	dns_rdataset_disassociate(&nsrdset);
   13058 
   13059 cleanup3:
   13060 	if (dns_name_dynamic(&primary)) {
   13061 		dns_name_free(&primary, zone->mctx);
   13062 	}
   13063 cleanup2:
   13064 	dns_db_detachnode(zonedb, &node);
   13065 cleanup1:
   13066 	dns_db_closeversion(zonedb, &version, false);
   13067 	dns_db_detach(&zonedb);
   13068 }
   13069 
   13070 /***
   13071  *** Private
   13072  ***/
   13073 static isc_result_t
   13074 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name,
   13075 	     dns_message_t **messagep) {
   13076 	dns_message_t *message = NULL;
   13077 	dns_name_t *qname = NULL;
   13078 	dns_rdataset_t *qrdataset = NULL;
   13079 	isc_result_t result;
   13080 
   13081 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   13082 
   13083 	message->opcode = dns_opcode_query;
   13084 	message->rdclass = zone->rdclass;
   13085 
   13086 	result = dns_message_gettempname(message, &qname);
   13087 	if (result != ISC_R_SUCCESS) {
   13088 		goto cleanup;
   13089 	}
   13090 
   13091 	result = dns_message_gettemprdataset(message, &qrdataset);
   13092 	if (result != ISC_R_SUCCESS) {
   13093 		goto cleanup;
   13094 	}
   13095 
   13096 	/*
   13097 	 * Make question.
   13098 	 */
   13099 	dns_name_clone(name, qname);
   13100 	dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
   13101 	ISC_LIST_APPEND(qname->list, qrdataset, link);
   13102 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
   13103 
   13104 	*messagep = message;
   13105 	return (ISC_R_SUCCESS);
   13106 
   13107 cleanup:
   13108 	if (qname != NULL) {
   13109 		dns_message_puttempname(message, &qname);
   13110 	}
   13111 	if (qrdataset != NULL) {
   13112 		dns_message_puttemprdataset(message, &qrdataset);
   13113 	}
   13114 	dns_message_detach(&message);
   13115 	return (result);
   13116 }
   13117 
   13118 static isc_result_t
   13119 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
   13120 	bool reqexpire) {
   13121 	isc_result_t result;
   13122 	dns_rdataset_t *rdataset = NULL;
   13123 	dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
   13124 	int count = 0;
   13125 
   13126 	/* Set EDNS options if applicable. */
   13127 	if (reqnsid) {
   13128 		INSIST(count < DNS_EDNSOPTIONS);
   13129 		ednsopts[count].code = DNS_OPT_NSID;
   13130 		ednsopts[count].length = 0;
   13131 		ednsopts[count].value = NULL;
   13132 		count++;
   13133 	}
   13134 	if (reqexpire) {
   13135 		INSIST(count < DNS_EDNSOPTIONS);
   13136 		ednsopts[count].code = DNS_OPT_EXPIRE;
   13137 		ednsopts[count].length = 0;
   13138 		ednsopts[count].value = NULL;
   13139 		count++;
   13140 	}
   13141 	result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
   13142 				      ednsopts, count);
   13143 	if (result != ISC_R_SUCCESS) {
   13144 		return (result);
   13145 	}
   13146 
   13147 	return (dns_message_setopt(message, rdataset));
   13148 }
   13149 
   13150 /*
   13151  * Called when stub zone update is finished.
   13152  * Update zone refresh, retry, expire values accordingly with
   13153  * SOA received from primary, sync database to file, restart
   13154  * zone management timer.
   13155  */
   13156 static void
   13157 stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) {
   13158 	uint32_t refresh, retry, expire;
   13159 	isc_result_t result;
   13160 	isc_interval_t i;
   13161 	unsigned int soacount;
   13162 	dns_zone_t *zone = stub->zone;
   13163 
   13164 	/*
   13165 	 * Tidy up.
   13166 	 */
   13167 	dns_db_closeversion(stub->db, &stub->version, true);
   13168 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   13169 	if (zone->db == NULL) {
   13170 		zone_attachdb(zone, stub->db);
   13171 	}
   13172 	result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL, NULL,
   13173 				  &refresh, &retry, &expire, NULL, NULL);
   13174 	if (result == ISC_R_SUCCESS && soacount > 0U) {
   13175 		zone->refresh = RANGE(refresh, zone->minrefresh,
   13176 				      zone->maxrefresh);
   13177 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   13178 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   13179 				     DNS_MAX_EXPIRE);
   13180 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   13181 	}
   13182 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   13183 	dns_db_detach(&stub->db);
   13184 
   13185 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13186 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   13187 	DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   13188 	isc_interval_set(&i, zone->expire, 0);
   13189 	DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
   13190 
   13191 	if (zone->masterfile != NULL) {
   13192 		zone_needdump(zone, 0);
   13193 	}
   13194 
   13195 	zone_settimer(zone, &now);
   13196 }
   13197 
   13198 /*
   13199  * Process answers for A and AAAA queries when
   13200  * resolving nameserver addresses for which glue
   13201  * was missing in a previous answer for a NS query.
   13202  */
   13203 static void
   13204 stub_glue_response_cb(isc_task_t *task, isc_event_t *event) {
   13205 	const char me[] = "stub_glue_response_cb";
   13206 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13207 	dns_stub_t *stub = NULL;
   13208 	dns_message_t *msg = NULL;
   13209 	dns_zone_t *zone = NULL;
   13210 	char primary[ISC_SOCKADDR_FORMATSIZE];
   13211 	char source[ISC_SOCKADDR_FORMATSIZE];
   13212 	uint32_t addr_count, cnamecnt;
   13213 	isc_result_t result;
   13214 	isc_time_t now;
   13215 	struct stub_glue_request *request;
   13216 	struct stub_cb_args *cb_args;
   13217 	dns_rdataset_t *addr_rdataset = NULL;
   13218 	dns_dbnode_t *node = NULL;
   13219 
   13220 	UNUSED(task);
   13221 
   13222 	request = revent->ev_arg;
   13223 	cb_args = request->args;
   13224 	stub = cb_args->stub;
   13225 	INSIST(DNS_STUB_VALID(stub));
   13226 
   13227 	zone = stub->zone;
   13228 
   13229 	ENTER;
   13230 
   13231 	TIME_NOW(&now);
   13232 
   13233 	LOCK_ZONE(zone);
   13234 
   13235 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13236 		zone_debuglog(zone, me, 1, "exiting");
   13237 		goto cleanup;
   13238 	}
   13239 
   13240 	isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary));
   13241 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13242 
   13243 	if (revent->result != ISC_R_SUCCESS) {
   13244 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->primaryaddr,
   13245 					   &zone->sourceaddr, &now);
   13246 		dns_zone_log(zone, ISC_LOG_INFO,
   13247 			     "could not refresh stub from primary %s"
   13248 			     " (source %s): %s",
   13249 			     primary, source,
   13250 			     isc_result_totext(revent->result));
   13251 		goto cleanup;
   13252 	}
   13253 
   13254 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13255 	result = dns_request_getresponse(revent->request, msg, 0);
   13256 	if (result != ISC_R_SUCCESS) {
   13257 		dns_zone_log(zone, ISC_LOG_INFO,
   13258 			     "refreshing stub: unable to parse response (%s)",
   13259 			     isc_result_totext(result));
   13260 		goto cleanup;
   13261 	}
   13262 
   13263 	/*
   13264 	 * Unexpected opcode.
   13265 	 */
   13266 	if (msg->opcode != dns_opcode_query) {
   13267 		char opcode[128];
   13268 		isc_buffer_t rb;
   13269 
   13270 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   13271 		(void)dns_opcode_totext(msg->opcode, &rb);
   13272 
   13273 		dns_zone_log(zone, ISC_LOG_INFO,
   13274 			     "refreshing stub: "
   13275 			     "unexpected opcode (%.*s) from %s (source %s)",
   13276 			     (int)rb.used, opcode, primary, source);
   13277 		goto cleanup;
   13278 	}
   13279 
   13280 	/*
   13281 	 * Unexpected rcode.
   13282 	 */
   13283 	if (msg->rcode != dns_rcode_noerror) {
   13284 		char rcode[128];
   13285 		isc_buffer_t rb;
   13286 
   13287 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13288 		(void)dns_rcode_totext(msg->rcode, &rb);
   13289 
   13290 		dns_zone_log(zone, ISC_LOG_INFO,
   13291 			     "refreshing stub: "
   13292 			     "unexpected rcode (%.*s) from %s (source %s)",
   13293 			     (int)rb.used, rcode, primary, source);
   13294 		goto cleanup;
   13295 	}
   13296 
   13297 	/*
   13298 	 * We need complete messages.
   13299 	 */
   13300 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13301 		if (dns_request_usedtcp(revent->request)) {
   13302 			dns_zone_log(zone, ISC_LOG_INFO,
   13303 				     "refreshing stub: truncated TCP "
   13304 				     "response from primary %s (source %s)",
   13305 				     primary, source);
   13306 		}
   13307 		goto cleanup;
   13308 	}
   13309 
   13310 	/*
   13311 	 * If non-auth log.
   13312 	 */
   13313 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13314 		dns_zone_log(zone, ISC_LOG_INFO,
   13315 			     "refreshing stub: "
   13316 			     "non-authoritative answer from "
   13317 			     "primary %s (source %s)",
   13318 			     primary, source);
   13319 		goto cleanup;
   13320 	}
   13321 
   13322 	/*
   13323 	 * Sanity checks.
   13324 	 */
   13325 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13326 	addr_count = message_count(msg, DNS_SECTION_ANSWER,
   13327 				   request->ipv4 ? dns_rdatatype_a
   13328 						 : dns_rdatatype_aaaa);
   13329 
   13330 	if (cnamecnt != 0) {
   13331 		dns_zone_log(zone, ISC_LOG_INFO,
   13332 			     "refreshing stub: unexpected CNAME response "
   13333 			     "from primary %s (source %s)",
   13334 			     primary, source);
   13335 		goto cleanup;
   13336 	}
   13337 
   13338 	if (addr_count == 0) {
   13339 		dns_zone_log(zone, ISC_LOG_INFO,
   13340 			     "refreshing stub: no %s records in response "
   13341 			     "from primary %s (source %s)",
   13342 			     request->ipv4 ? "A" : "AAAA", primary, source);
   13343 		goto cleanup;
   13344 	}
   13345 	/*
   13346 	 * Extract A or AAAA RRset from message.
   13347 	 */
   13348 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &request->name,
   13349 				      request->ipv4 ? dns_rdatatype_a
   13350 						    : dns_rdatatype_aaaa,
   13351 				      dns_rdatatype_none, NULL, &addr_rdataset);
   13352 	if (result != ISC_R_SUCCESS) {
   13353 		if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) {
   13354 			char namebuf[DNS_NAME_FORMATSIZE];
   13355 			dns_name_format(&request->name, namebuf,
   13356 					sizeof(namebuf));
   13357 			dns_zone_log(
   13358 				zone, ISC_LOG_INFO,
   13359 				"refreshing stub: dns_message_findname(%s/%s) "
   13360 				"failed (%s)",
   13361 				namebuf, request->ipv4 ? "A" : "AAAA",
   13362 				isc_result_totext(result));
   13363 		}
   13364 		goto cleanup;
   13365 	}
   13366 
   13367 	result = dns_db_findnode(stub->db, &request->name, true, &node);
   13368 	if (result != ISC_R_SUCCESS) {
   13369 		dns_zone_log(zone, ISC_LOG_INFO,
   13370 			     "refreshing stub: "
   13371 			     "dns_db_findnode() failed: %s",
   13372 			     isc_result_totext(result));
   13373 		goto cleanup;
   13374 	}
   13375 
   13376 	result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   13377 				    addr_rdataset, 0, NULL);
   13378 	if (result != ISC_R_SUCCESS) {
   13379 		dns_zone_log(zone, ISC_LOG_INFO,
   13380 			     "refreshing stub: "
   13381 			     "dns_db_addrdataset() failed: %s",
   13382 			     isc_result_totext(result));
   13383 	}
   13384 	dns_db_detachnode(stub->db, &node);
   13385 
   13386 cleanup:
   13387 	if (msg != NULL) {
   13388 		dns_message_detach(&msg);
   13389 	}
   13390 	isc_event_free(&event);
   13391 	dns_name_free(&request->name, zone->mctx);
   13392 	dns_request_destroy(&request->request);
   13393 	isc_mem_put(zone->mctx, request, sizeof(*request));
   13394 
   13395 	/* If last request, release all related resources */
   13396 	if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) {
   13397 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13398 		stub_finish_zone_update(stub, now);
   13399 		UNLOCK_ZONE(zone);
   13400 		stub->magic = 0;
   13401 		dns_zone_idetach(&stub->zone);
   13402 		INSIST(stub->db == NULL);
   13403 		INSIST(stub->version == NULL);
   13404 		isc_mem_put(stub->mctx, stub, sizeof(*stub));
   13405 	} else {
   13406 		UNLOCK_ZONE(zone);
   13407 	}
   13408 }
   13409 
   13410 /*
   13411  * Create and send an A or AAAA query to the primary
   13412  * server of the stub zone given.
   13413  */
   13414 static isc_result_t
   13415 stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4,
   13416 				const dns_name_t *name) {
   13417 	dns_message_t *message = NULL;
   13418 	dns_zone_t *zone;
   13419 	isc_result_t result;
   13420 	struct stub_glue_request *request;
   13421 
   13422 	zone = args->stub->zone;
   13423 	request = isc_mem_get(zone->mctx, sizeof(*request));
   13424 	request->request = NULL;
   13425 	request->args = args;
   13426 	request->name = (dns_name_t)DNS_NAME_INITEMPTY;
   13427 	request->ipv4 = ipv4;
   13428 	dns_name_dup(name, zone->mctx, &request->name);
   13429 
   13430 	result = create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa,
   13431 			      &request->name, &message);
   13432 	INSIST(result == ISC_R_SUCCESS);
   13433 
   13434 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   13435 		result = add_opt(message, args->udpsize, args->reqnsid, false);
   13436 		if (result != ISC_R_SUCCESS) {
   13437 			zone_debuglog(zone, "stub_send_query", 1,
   13438 				      "unable to add opt record: %s",
   13439 				      isc_result_totext(result));
   13440 			goto fail;
   13441 		}
   13442 	}
   13443 
   13444 	atomic_fetch_add_release(&args->stub->pending_requests, 1);
   13445 
   13446 	result = dns_request_create(
   13447 		zone->view->requestmgr, message, &zone->sourceaddr,
   13448 		&zone->primaryaddr, DNS_REQUESTOPT_TCP, args->tsig_key,
   13449 		args->timeout * 3, args->timeout, 2, zone->task,
   13450 		stub_glue_response_cb, request, &request->request);
   13451 
   13452 	if (result != ISC_R_SUCCESS) {
   13453 		uint_fast32_t pr;
   13454 		pr = atomic_fetch_sub_release(&args->stub->pending_requests, 1);
   13455 		INSIST(pr > 1);
   13456 		zone_debuglog(zone, "stub_send_query", 1,
   13457 			      "dns_request_create() failed: %s",
   13458 			      isc_result_totext(result));
   13459 		goto fail;
   13460 	}
   13461 
   13462 	dns_message_detach(&message);
   13463 
   13464 	return (ISC_R_SUCCESS);
   13465 
   13466 fail:
   13467 	dns_name_free(&request->name, zone->mctx);
   13468 	isc_mem_put(zone->mctx, request, sizeof(*request));
   13469 
   13470 	if (message != NULL) {
   13471 		dns_message_detach(&message);
   13472 	}
   13473 
   13474 	return (result);
   13475 }
   13476 
   13477 static isc_result_t
   13478 save_nsrrset(dns_message_t *message, dns_name_t *name,
   13479 	     struct stub_cb_args *cb_args, dns_db_t *db,
   13480 	     dns_dbversion_t *version) {
   13481 	dns_rdataset_t *nsrdataset = NULL;
   13482 	dns_rdataset_t *rdataset = NULL;
   13483 	dns_dbnode_t *node = NULL;
   13484 	dns_rdata_ns_t ns;
   13485 	isc_result_t result;
   13486 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13487 	bool has_glue = false;
   13488 	dns_name_t *ns_name;
   13489 	/*
   13490 	 * List of NS entries in answer, keep names that will be used
   13491 	 * to resolve missing A/AAAA glue for each entry.
   13492 	 */
   13493 	dns_namelist_t ns_list;
   13494 	ISC_LIST_INIT(ns_list);
   13495 
   13496 	/*
   13497 	 * Extract NS RRset from message.
   13498 	 */
   13499 	result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
   13500 				      dns_rdatatype_ns, dns_rdatatype_none,
   13501 				      NULL, &nsrdataset);
   13502 	if (result != ISC_R_SUCCESS) {
   13503 		goto done;
   13504 	}
   13505 
   13506 	/*
   13507 	 * Add NS rdataset.
   13508 	 */
   13509 	result = dns_db_findnode(db, name, true, &node);
   13510 	if (result != ISC_R_SUCCESS) {
   13511 		goto done;
   13512 	}
   13513 	result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL);
   13514 	dns_db_detachnode(db, &node);
   13515 	if (result != ISC_R_SUCCESS) {
   13516 		goto done;
   13517 	}
   13518 	/*
   13519 	 * Add glue rdatasets.
   13520 	 */
   13521 	for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS;
   13522 	     result = dns_rdataset_next(nsrdataset))
   13523 	{
   13524 		dns_rdataset_current(nsrdataset, &rdata);
   13525 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   13526 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13527 		dns_rdata_reset(&rdata);
   13528 
   13529 		if (!dns_name_issubdomain(&ns.name, name)) {
   13530 			continue;
   13531 		}
   13532 		rdataset = NULL;
   13533 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
   13534 					      &ns.name, dns_rdatatype_aaaa,
   13535 					      dns_rdatatype_none, NULL,
   13536 					      &rdataset);
   13537 		if (result == ISC_R_SUCCESS) {
   13538 			has_glue = true;
   13539 			result = dns_db_findnode(db, &ns.name, true, &node);
   13540 			if (result != ISC_R_SUCCESS) {
   13541 				goto done;
   13542 			}
   13543 			result = dns_db_addrdataset(db, node, version, 0,
   13544 						    rdataset, 0, NULL);
   13545 			dns_db_detachnode(db, &node);
   13546 			if (result != ISC_R_SUCCESS) {
   13547 				goto done;
   13548 			}
   13549 		}
   13550 
   13551 		rdataset = NULL;
   13552 		result = dns_message_findname(
   13553 			message, DNS_SECTION_ADDITIONAL, &ns.name,
   13554 			dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset);
   13555 		if (result == ISC_R_SUCCESS) {
   13556 			has_glue = true;
   13557 			result = dns_db_findnode(db, &ns.name, true, &node);
   13558 			if (result != ISC_R_SUCCESS) {
   13559 				goto done;
   13560 			}
   13561 			result = dns_db_addrdataset(db, node, version, 0,
   13562 						    rdataset, 0, NULL);
   13563 			dns_db_detachnode(db, &node);
   13564 			if (result != ISC_R_SUCCESS) {
   13565 				goto done;
   13566 			}
   13567 		}
   13568 
   13569 		/*
   13570 		 * If no glue is found so far, we add the name to the list to
   13571 		 * resolve the A/AAAA glue later. If any glue is found in any
   13572 		 * iteration step, this list will be discarded and only the glue
   13573 		 * provided in this message will be used.
   13574 		 */
   13575 		if (!has_glue && dns_name_issubdomain(&ns.name, name)) {
   13576 			dns_name_t *tmp_name;
   13577 			tmp_name = isc_mem_get(cb_args->stub->mctx,
   13578 					       sizeof(*tmp_name));
   13579 			dns_name_init(tmp_name, NULL);
   13580 			dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name);
   13581 			ISC_LIST_APPEND(ns_list, tmp_name, link);
   13582 		}
   13583 	}
   13584 
   13585 	if (result != ISC_R_NOMORE) {
   13586 		goto done;
   13587 	}
   13588 
   13589 	/*
   13590 	 * If no glue records were found, we attempt to resolve A/AAAA
   13591 	 * for each NS entry found in the answer.
   13592 	 */
   13593 	if (!has_glue) {
   13594 		for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL;
   13595 		     ns_name = ISC_LIST_NEXT(ns_name, link))
   13596 		{
   13597 			/*
   13598 			 * Resolve NS IPv4 address/A.
   13599 			 */
   13600 			result = stub_request_nameserver_address(cb_args, true,
   13601 								 ns_name);
   13602 			if (result != ISC_R_SUCCESS) {
   13603 				goto done;
   13604 			}
   13605 			/*
   13606 			 * Resolve NS IPv6 address/AAAA.
   13607 			 */
   13608 			result = stub_request_nameserver_address(cb_args, false,
   13609 								 ns_name);
   13610 			if (result != ISC_R_SUCCESS) {
   13611 				goto done;
   13612 			}
   13613 		}
   13614 	}
   13615 
   13616 	result = ISC_R_SUCCESS;
   13617 
   13618 done:
   13619 	while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) {
   13620 		ISC_LIST_UNLINK(ns_list, ns_name, link);
   13621 		dns_name_free(ns_name, cb_args->stub->mctx);
   13622 		isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name));
   13623 	}
   13624 	return (result);
   13625 }
   13626 
   13627 static void
   13628 stub_callback(isc_task_t *task, isc_event_t *event) {
   13629 	const char me[] = "stub_callback";
   13630 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13631 	dns_stub_t *stub = NULL;
   13632 	dns_message_t *msg = NULL;
   13633 	dns_zone_t *zone = NULL;
   13634 	char primary[ISC_SOCKADDR_FORMATSIZE];
   13635 	char source[ISC_SOCKADDR_FORMATSIZE];
   13636 	uint32_t nscnt, cnamecnt;
   13637 	isc_result_t result;
   13638 	isc_time_t now;
   13639 	bool exiting = false;
   13640 	unsigned int j;
   13641 	struct stub_cb_args *cb_args;
   13642 
   13643 	cb_args = revent->ev_arg;
   13644 	stub = cb_args->stub;
   13645 	INSIST(DNS_STUB_VALID(stub));
   13646 
   13647 	UNUSED(task);
   13648 
   13649 	zone = stub->zone;
   13650 
   13651 	ENTER;
   13652 
   13653 	TIME_NOW(&now);
   13654 
   13655 	LOCK_ZONE(zone);
   13656 
   13657 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13658 		goto exiting;
   13659 	}
   13660 
   13661 	isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary));
   13662 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13663 
   13664 	switch (revent->result) {
   13665 	case ISC_R_SUCCESS:
   13666 		break;
   13667 	case ISC_R_SHUTTINGDOWN:
   13668 		goto exiting;
   13669 	case ISC_R_TIMEDOUT:
   13670 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   13671 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13672 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13673 				     "refreshing stub: timeout retrying "
   13674 				     "without EDNS primary %s (source %s)",
   13675 				     primary, source);
   13676 			goto same_primary;
   13677 		}
   13678 		FALLTHROUGH;
   13679 	default:
   13680 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->primaryaddr,
   13681 					   &zone->sourceaddr, &now);
   13682 		dns_zone_log(zone, ISC_LOG_INFO,
   13683 			     "could not refresh stub from primary "
   13684 			     "%s (source %s): %s",
   13685 			     primary, source,
   13686 			     isc_result_totext(revent->result));
   13687 		goto next_primary;
   13688 	}
   13689 
   13690 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13691 
   13692 	result = dns_request_getresponse(revent->request, msg, 0);
   13693 	if (result != ISC_R_SUCCESS) {
   13694 		goto next_primary;
   13695 	}
   13696 
   13697 	/*
   13698 	 * Unexpected opcode.
   13699 	 */
   13700 	if (msg->opcode != dns_opcode_query) {
   13701 		char opcode[128];
   13702 		isc_buffer_t rb;
   13703 
   13704 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   13705 		(void)dns_opcode_totext(msg->opcode, &rb);
   13706 
   13707 		dns_zone_log(zone, ISC_LOG_INFO,
   13708 			     "refreshing stub: "
   13709 			     "unexpected opcode (%.*s) from %s (source %s)",
   13710 			     (int)rb.used, opcode, primary, source);
   13711 		goto next_primary;
   13712 	}
   13713 
   13714 	/*
   13715 	 * Unexpected rcode.
   13716 	 */
   13717 	if (msg->rcode != dns_rcode_noerror) {
   13718 		char rcode[128];
   13719 		isc_buffer_t rb;
   13720 
   13721 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13722 		(void)dns_rcode_totext(msg->rcode, &rb);
   13723 
   13724 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13725 		    (msg->rcode == dns_rcode_servfail ||
   13726 		     msg->rcode == dns_rcode_notimp ||
   13727 		     (msg->rcode == dns_rcode_formerr && msg->opt == NULL)))
   13728 		{
   13729 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13730 				     "refreshing stub: rcode (%.*s) retrying "
   13731 				     "without EDNS primary %s (source %s)",
   13732 				     (int)rb.used, rcode, primary, source);
   13733 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13734 			goto same_primary;
   13735 		}
   13736 
   13737 		dns_zone_log(zone, ISC_LOG_INFO,
   13738 			     "refreshing stub: "
   13739 			     "unexpected rcode (%.*s) from %s (source %s)",
   13740 			     (int)rb.used, rcode, primary, source);
   13741 		goto next_primary;
   13742 	}
   13743 
   13744 	/*
   13745 	 * We need complete messages.
   13746 	 */
   13747 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13748 		if (dns_request_usedtcp(revent->request)) {
   13749 			dns_zone_log(zone, ISC_LOG_INFO,
   13750 				     "refreshing stub: truncated TCP "
   13751 				     "response from primary %s (source %s)",
   13752 				     primary, source);
   13753 			goto next_primary;
   13754 		}
   13755 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   13756 		goto same_primary;
   13757 	}
   13758 
   13759 	/*
   13760 	 * If non-auth log and next primary.
   13761 	 */
   13762 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13763 		dns_zone_log(zone, ISC_LOG_INFO,
   13764 			     "refreshing stub: "
   13765 			     "non-authoritative answer from "
   13766 			     "primary %s (source %s)",
   13767 			     primary, source);
   13768 		goto next_primary;
   13769 	}
   13770 
   13771 	/*
   13772 	 * Sanity checks.
   13773 	 */
   13774 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13775 	nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
   13776 
   13777 	if (cnamecnt != 0) {
   13778 		dns_zone_log(zone, ISC_LOG_INFO,
   13779 			     "refreshing stub: unexpected CNAME response "
   13780 			     "from primary %s (source %s)",
   13781 			     primary, source);
   13782 		goto next_primary;
   13783 	}
   13784 
   13785 	if (nscnt == 0) {
   13786 		dns_zone_log(zone, ISC_LOG_INFO,
   13787 			     "refreshing stub: no NS records in response "
   13788 			     "from primary %s (source %s)",
   13789 			     primary, source);
   13790 		goto next_primary;
   13791 	}
   13792 
   13793 	atomic_fetch_add(&stub->pending_requests, 1);
   13794 
   13795 	/*
   13796 	 * Save answer.
   13797 	 */
   13798 	result = save_nsrrset(msg, &zone->origin, cb_args, stub->db,
   13799 			      stub->version);
   13800 	if (result != ISC_R_SUCCESS) {
   13801 		dns_zone_log(zone, ISC_LOG_INFO,
   13802 			     "refreshing stub: unable to save NS records "
   13803 			     "from primary %s (source %s)",
   13804 			     primary, source);
   13805 		goto next_primary;
   13806 	}
   13807 
   13808 	dns_message_detach(&msg);
   13809 	isc_event_free(&event);
   13810 	dns_request_destroy(&zone->request);
   13811 
   13812 	/*
   13813 	 * Check to see if there are no outstanding requests and
   13814 	 * finish off if that is so.
   13815 	 */
   13816 	if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) {
   13817 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13818 		stub_finish_zone_update(stub, now);
   13819 		goto free_stub;
   13820 	}
   13821 
   13822 	UNLOCK_ZONE(zone);
   13823 	return;
   13824 
   13825 exiting:
   13826 	zone_debuglog(zone, me, 1, "exiting");
   13827 	exiting = true;
   13828 
   13829 next_primary:
   13830 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13831 	if (stub->version != NULL) {
   13832 		dns_db_closeversion(stub->db, &stub->version, false);
   13833 	}
   13834 	if (stub->db != NULL) {
   13835 		dns_db_detach(&stub->db);
   13836 	}
   13837 	if (msg != NULL) {
   13838 		dns_message_detach(&msg);
   13839 	}
   13840 	isc_event_free(&event);
   13841 	dns_request_destroy(&zone->request);
   13842 	/*
   13843 	 * Skip to next failed / untried primary.
   13844 	 */
   13845 	do {
   13846 		zone->curprimary++;
   13847 	} while (zone->curprimary < zone->primariescnt &&
   13848 		 zone->primariesok[zone->curprimary]);
   13849 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13850 	if (exiting || zone->curprimary >= zone->primariescnt) {
   13851 		bool done = true;
   13852 		if (!exiting &&
   13853 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   13854 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   13855 		{
   13856 			/*
   13857 			 * Did we get a good answer from all the primaries?
   13858 			 */
   13859 			for (j = 0; j < zone->primariescnt; j++) {
   13860 				if (!zone->primariesok[j]) {
   13861 					{
   13862 						done = false;
   13863 						break;
   13864 					}
   13865 				}
   13866 			}
   13867 		} else {
   13868 			done = true;
   13869 		}
   13870 		if (!done) {
   13871 			zone->curprimary = 0;
   13872 			/*
   13873 			 * Find the next failed primary.
   13874 			 */
   13875 			while (zone->curprimary < zone->primariescnt &&
   13876 			       zone->primariesok[zone->curprimary])
   13877 			{
   13878 				zone->curprimary++;
   13879 			}
   13880 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13881 		} else {
   13882 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13883 
   13884 			zone_settimer(zone, &now);
   13885 			goto free_stub;
   13886 		}
   13887 	}
   13888 	queue_soa_query(zone);
   13889 	goto free_stub;
   13890 
   13891 same_primary:
   13892 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13893 	if (msg != NULL) {
   13894 		dns_message_detach(&msg);
   13895 	}
   13896 	isc_event_free(&event);
   13897 	dns_request_destroy(&zone->request);
   13898 	ns_query(zone, NULL, stub);
   13899 	UNLOCK_ZONE(zone);
   13900 	goto done;
   13901 
   13902 free_stub:
   13903 	UNLOCK_ZONE(zone);
   13904 	stub->magic = 0;
   13905 	dns_zone_idetach(&stub->zone);
   13906 	INSIST(stub->db == NULL);
   13907 	INSIST(stub->version == NULL);
   13908 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   13909 
   13910 done:
   13911 	INSIST(event == NULL);
   13912 	return;
   13913 }
   13914 
   13915 /*
   13916  * Get the EDNS EXPIRE option from the response and if it exists trim
   13917  * expire to be not more than it.
   13918  */
   13919 static void
   13920 get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) {
   13921 	isc_result_t result;
   13922 	uint32_t expire;
   13923 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13924 	isc_buffer_t optbuf;
   13925 	uint16_t optcode;
   13926 	uint16_t optlen;
   13927 
   13928 	REQUIRE(expirep != NULL);
   13929 	REQUIRE(message != NULL);
   13930 
   13931 	if (message->opt == NULL) {
   13932 		return;
   13933 	}
   13934 
   13935 	result = dns_rdataset_first(message->opt);
   13936 	if (result == ISC_R_SUCCESS) {
   13937 		dns_rdataset_current(message->opt, &rdata);
   13938 		isc_buffer_init(&optbuf, rdata.data, rdata.length);
   13939 		isc_buffer_add(&optbuf, rdata.length);
   13940 		while (isc_buffer_remaininglength(&optbuf) >= 4) {
   13941 			optcode = isc_buffer_getuint16(&optbuf);
   13942 			optlen = isc_buffer_getuint16(&optbuf);
   13943 			/*
   13944 			 * A EDNS EXPIRE response has a length of 4.
   13945 			 */
   13946 			if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
   13947 				isc_buffer_forward(&optbuf, optlen);
   13948 				continue;
   13949 			}
   13950 			expire = isc_buffer_getuint32(&optbuf);
   13951 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13952 				     "got EDNS EXPIRE of %u", expire);
   13953 			/*
   13954 			 * Trim *expirep?
   13955 			 */
   13956 			if (expire < *expirep) {
   13957 				*expirep = expire;
   13958 			}
   13959 			break;
   13960 		}
   13961 	}
   13962 }
   13963 
   13964 /*
   13965  * Set the file modification time zone->expire seconds before expiretime.
   13966  */
   13967 static void
   13968 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
   13969 	isc_result_t result;
   13970 	isc_time_t when;
   13971 	isc_interval_t i;
   13972 
   13973 	isc_interval_set(&i, zone->expire, 0);
   13974 	result = isc_time_subtract(expiretime, &i, &when);
   13975 	if (result != ISC_R_SUCCESS) {
   13976 		return;
   13977 	}
   13978 
   13979 	result = ISC_R_FAILURE;
   13980 	if (zone->journal != NULL) {
   13981 		result = isc_file_settime(zone->journal, &when);
   13982 	}
   13983 	if (result == ISC_R_SUCCESS &&
   13984 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   13985 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   13986 	{
   13987 		result = isc_file_settime(zone->masterfile, &when);
   13988 	} else if (result != ISC_R_SUCCESS) {
   13989 		result = isc_file_settime(zone->masterfile, &when);
   13990 	}
   13991 
   13992 	/*
   13993 	 * Someone removed the file from underneath us!
   13994 	 */
   13995 	if (result == ISC_R_FILENOTFOUND) {
   13996 		zone_needdump(zone, DNS_DUMP_DELAY);
   13997 	} else if (result != ISC_R_SUCCESS) {
   13998 		dns_zone_log(zone, ISC_LOG_ERROR,
   13999 			     "refresh: could not set "
   14000 			     "file modification time of '%s': %s",
   14001 			     zone->masterfile, isc_result_totext(result));
   14002 	}
   14003 }
   14004 
   14005 /*
   14006  * An SOA query has finished (successfully or not).
   14007  */
   14008 static void
   14009 refresh_callback(isc_task_t *task, isc_event_t *event) {
   14010 	const char me[] = "refresh_callback";
   14011 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   14012 	dns_zone_t *zone;
   14013 	dns_message_t *msg = NULL;
   14014 	uint32_t soacnt, cnamecnt, soacount, nscount;
   14015 	isc_time_t now;
   14016 	char primary[ISC_SOCKADDR_FORMATSIZE];
   14017 	char source[ISC_SOCKADDR_FORMATSIZE];
   14018 	dns_rdataset_t *rdataset = NULL;
   14019 	dns_rdata_t rdata = DNS_RDATA_INIT;
   14020 	dns_rdata_soa_t soa;
   14021 	isc_result_t result;
   14022 	uint32_t serial, oldserial = 0;
   14023 	unsigned int j;
   14024 	bool do_queue_xfrin = false;
   14025 
   14026 	zone = revent->ev_arg;
   14027 	INSIST(DNS_ZONE_VALID(zone));
   14028 
   14029 	UNUSED(task);
   14030 
   14031 	ENTER;
   14032 
   14033 	TIME_NOW(&now);
   14034 
   14035 	LOCK_ZONE(zone);
   14036 
   14037 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14038 		goto exiting;
   14039 	}
   14040 
   14041 	/*
   14042 	 * If timeout, log and try the next primary
   14043 	 */
   14044 	isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary));
   14045 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   14046 
   14047 	switch (revent->result) {
   14048 	case ISC_R_SUCCESS:
   14049 		break;
   14050 	case ISC_R_SHUTTINGDOWN:
   14051 		goto exiting;
   14052 	case ISC_R_TIMEDOUT:
   14053 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14054 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14055 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14056 				     "refresh: timeout retrying without EDNS "
   14057 				     "primary %s (source %s)",
   14058 				     primary, source);
   14059 			goto same_primary;
   14060 		} else if (!dns_request_usedtcp(revent->request)) {
   14061 			dns_zone_log(zone, ISC_LOG_INFO,
   14062 				     "refresh: retry limit for "
   14063 				     "primary %s exceeded (source %s)",
   14064 				     primary, source);
   14065 			/* Try with secondary with TCP. */
   14066 			if ((zone->type == dns_zone_secondary ||
   14067 			     zone->type == dns_zone_mirror ||
   14068 			     zone->type == dns_zone_redirect) &&
   14069 			    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
   14070 			{
   14071 				if (!dns_zonemgr_unreachable(
   14072 					    zone->zmgr, &zone->primaryaddr,
   14073 					    &zone->sourceaddr, &now))
   14074 				{
   14075 					DNS_ZONE_SETFLAG(
   14076 						zone,
   14077 						DNS_ZONEFLG_SOABEFOREAXFR);
   14078 					goto tcp_transfer;
   14079 				}
   14080 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14081 					     "refresh: skipped tcp fallback "
   14082 					     "as primary %s (source %s) is "
   14083 					     "unreachable (cached)",
   14084 					     primary, source);
   14085 			}
   14086 			goto next_primary;
   14087 		}
   14088 		FALLTHROUGH;
   14089 	default:
   14090 		dns_zone_log(zone, ISC_LOG_INFO,
   14091 			     "refresh: failure trying primary "
   14092 			     "%s (source %s): %s",
   14093 			     primary, source,
   14094 			     isc_result_totext(revent->result));
   14095 		goto next_primary;
   14096 	}
   14097 
   14098 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   14099 	result = dns_request_getresponse(revent->request, msg, 0);
   14100 	if (result != ISC_R_SUCCESS) {
   14101 		dns_zone_log(zone, ISC_LOG_INFO,
   14102 			     "refresh: failure trying primary "
   14103 			     "%s (source %s): %s",
   14104 			     primary, source, isc_result_totext(result));
   14105 		goto next_primary;
   14106 	}
   14107 
   14108 	/*
   14109 	 * Unexpected opcode.
   14110 	 */
   14111 	if (msg->opcode != dns_opcode_query) {
   14112 		char opcode[128];
   14113 		isc_buffer_t rb;
   14114 
   14115 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   14116 		(void)dns_opcode_totext(msg->opcode, &rb);
   14117 
   14118 		dns_zone_log(zone, ISC_LOG_INFO,
   14119 			     "refresh: "
   14120 			     "unexpected opcode (%.*s) from %s (source %s)",
   14121 			     (int)rb.used, opcode, primary, source);
   14122 		goto next_primary;
   14123 	}
   14124 
   14125 	/*
   14126 	 * Unexpected rcode.
   14127 	 */
   14128 	if (msg->rcode != dns_rcode_noerror) {
   14129 		char rcode[128];
   14130 		isc_buffer_t rb;
   14131 
   14132 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   14133 		(void)dns_rcode_totext(msg->rcode, &rb);
   14134 
   14135 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   14136 		    (msg->rcode == dns_rcode_servfail ||
   14137 		     msg->rcode == dns_rcode_notimp ||
   14138 		     (msg->rcode == dns_rcode_formerr && msg->opt == NULL)))
   14139 		{
   14140 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14141 				     "refresh: rcode (%.*s) retrying without "
   14142 				     "EDNS primary %s (source %s)",
   14143 				     (int)rb.used, rcode, primary, source);
   14144 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14145 			goto same_primary;
   14146 		}
   14147 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   14148 		    msg->rcode == dns_rcode_badvers)
   14149 		{
   14150 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   14151 				     "refresh: rcode (%.*s) retrying without "
   14152 				     "EDNS EXPIRE OPTION primary %s "
   14153 				     "(source %s)",
   14154 				     (int)rb.used, rcode, primary, source);
   14155 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14156 			goto same_primary;
   14157 		}
   14158 		dns_zone_log(zone, ISC_LOG_INFO,
   14159 			     "refresh: unexpected rcode (%.*s) from "
   14160 			     "primary %s (source %s)",
   14161 			     (int)rb.used, rcode, primary, source);
   14162 		/*
   14163 		 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
   14164 		 */
   14165 		if (msg->rcode == dns_rcode_refused &&
   14166 		    (zone->type == dns_zone_secondary ||
   14167 		     zone->type == dns_zone_mirror ||
   14168 		     zone->type == dns_zone_redirect))
   14169 		{
   14170 			goto tcp_transfer;
   14171 		}
   14172 		goto next_primary;
   14173 	}
   14174 
   14175 	/*
   14176 	 * If truncated punt to zone transfer which will query again.
   14177 	 */
   14178 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   14179 		if (zone->type == dns_zone_secondary ||
   14180 		    zone->type == dns_zone_mirror ||
   14181 		    zone->type == dns_zone_redirect)
   14182 		{
   14183 			dns_zone_log(zone, ISC_LOG_INFO,
   14184 				     "refresh: truncated UDP answer, "
   14185 				     "initiating TCP zone xfer "
   14186 				     "for primary %s (source %s)",
   14187 				     primary, source);
   14188 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   14189 			goto tcp_transfer;
   14190 		} else {
   14191 			INSIST(zone->type == dns_zone_stub);
   14192 			if (dns_request_usedtcp(revent->request)) {
   14193 				dns_zone_log(zone, ISC_LOG_INFO,
   14194 					     "refresh: truncated TCP response "
   14195 					     "from primary %s (source %s)",
   14196 					     primary, source);
   14197 				goto next_primary;
   14198 			}
   14199 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   14200 			goto same_primary;
   14201 		}
   14202 	}
   14203 
   14204 	/*
   14205 	 * If non-auth, log and try the next primary
   14206 	 */
   14207 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   14208 		dns_zone_log(zone, ISC_LOG_INFO,
   14209 			     "refresh: non-authoritative answer from "
   14210 			     "primary %s (source %s)",
   14211 			     primary, source);
   14212 		goto next_primary;
   14213 	}
   14214 
   14215 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   14216 	soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
   14217 	nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
   14218 	soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa);
   14219 
   14220 	/*
   14221 	 * There should not be a CNAME record at top of zone.
   14222 	 */
   14223 	if (cnamecnt != 0) {
   14224 		dns_zone_log(zone, ISC_LOG_INFO,
   14225 			     "refresh: CNAME at top of zone "
   14226 			     "in primary %s (source %s)",
   14227 			     primary, source);
   14228 		goto next_primary;
   14229 	}
   14230 
   14231 	/*
   14232 	 * If referral, log and try the next primary;
   14233 	 */
   14234 	if (soacnt == 0 && soacount == 0 && nscount != 0) {
   14235 		dns_zone_log(zone, ISC_LOG_INFO,
   14236 			     "refresh: referral response "
   14237 			     "from primary %s (source %s)",
   14238 			     primary, source);
   14239 		goto next_primary;
   14240 	}
   14241 
   14242 	/*
   14243 	 * If nodata, log and try the next primary;
   14244 	 */
   14245 	if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
   14246 		dns_zone_log(zone, ISC_LOG_INFO,
   14247 			     "refresh: NODATA response "
   14248 			     "from primary %s (source %s)",
   14249 			     primary, source);
   14250 		goto next_primary;
   14251 	}
   14252 
   14253 	/*
   14254 	 * Only one soa at top of zone.
   14255 	 */
   14256 	if (soacnt != 1) {
   14257 		dns_zone_log(zone, ISC_LOG_INFO,
   14258 			     "refresh: answer SOA count (%d) != 1 "
   14259 			     "from primary %s (source %s)",
   14260 			     soacnt, primary, source);
   14261 		goto next_primary;
   14262 	}
   14263 
   14264 	/*
   14265 	 * Extract serial
   14266 	 */
   14267 	rdataset = NULL;
   14268 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
   14269 				      dns_rdatatype_soa, dns_rdatatype_none,
   14270 				      NULL, &rdataset);
   14271 	if (result != ISC_R_SUCCESS) {
   14272 		dns_zone_log(zone, ISC_LOG_INFO,
   14273 			     "refresh: unable to get SOA record "
   14274 			     "from primary %s (source %s)",
   14275 			     primary, source);
   14276 		goto next_primary;
   14277 	}
   14278 
   14279 	result = dns_rdataset_first(rdataset);
   14280 	if (result != ISC_R_SUCCESS) {
   14281 		dns_zone_log(zone, ISC_LOG_INFO,
   14282 			     "refresh: dns_rdataset_first() failed");
   14283 		goto next_primary;
   14284 	}
   14285 
   14286 	dns_rdataset_current(rdataset, &rdata);
   14287 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   14288 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14289 
   14290 	serial = soa.serial;
   14291 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   14292 		unsigned int dbsoacount;
   14293 		result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
   14294 					  NULL, &oldserial, NULL, NULL, NULL,
   14295 					  NULL, NULL);
   14296 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   14297 		RUNTIME_CHECK(dbsoacount > 0U);
   14298 		zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial,
   14299 			      oldserial);
   14300 	} else {
   14301 		zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
   14302 			      serial);
   14303 	}
   14304 
   14305 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
   14306 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
   14307 	    isc_serial_gt(serial, oldserial))
   14308 	{
   14309 		if (dns_zonemgr_unreachable(zone->zmgr, &zone->primaryaddr,
   14310 					    &zone->sourceaddr, &now))
   14311 		{
   14312 			dns_zone_log(zone, ISC_LOG_INFO,
   14313 				     "refresh: skipping %s as primary %s "
   14314 				     "(source %s) is unreachable (cached)",
   14315 				     (zone->type == dns_zone_secondary ||
   14316 				      zone->type == dns_zone_mirror ||
   14317 				      zone->type == dns_zone_redirect)
   14318 					     ? "zone transfer"
   14319 					     : "NS query",
   14320 				     primary, source);
   14321 			goto next_primary;
   14322 		}
   14323 	tcp_transfer:
   14324 		isc_event_free(&event);
   14325 		dns_request_destroy(&zone->request);
   14326 		if (zone->type == dns_zone_secondary ||
   14327 		    zone->type == dns_zone_mirror ||
   14328 		    zone->type == dns_zone_redirect)
   14329 		{
   14330 			do_queue_xfrin = true;
   14331 		} else {
   14332 			INSIST(zone->type == dns_zone_stub);
   14333 			ns_query(zone, rdataset, NULL);
   14334 		}
   14335 		if (msg != NULL) {
   14336 			dns_message_detach(&msg);
   14337 		}
   14338 	} else if (isc_serial_eq(soa.serial, oldserial)) {
   14339 		isc_time_t expiretime;
   14340 		uint32_t expire;
   14341 
   14342 		/*
   14343 		 * Compute the new expire time based on this response.
   14344 		 */
   14345 		expire = zone->expire;
   14346 		get_edns_expire(zone, msg, &expire);
   14347 		DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
   14348 
   14349 		/*
   14350 		 * Has the expire time improved?
   14351 		 */
   14352 		if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
   14353 			zone->expiretime = expiretime;
   14354 			if (zone->masterfile != NULL) {
   14355 				setmodtime(zone, &expiretime);
   14356 			}
   14357 		}
   14358 
   14359 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   14360 		zone->primariesok[zone->curprimary] = true;
   14361 		goto next_primary;
   14362 	} else {
   14363 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) {
   14364 			dns_zone_log(zone, ISC_LOG_INFO,
   14365 				     "serial number (%u) "
   14366 				     "received from primary %s < ours (%u)",
   14367 				     soa.serial, primary, oldserial);
   14368 		} else {
   14369 			zone_debuglog(zone, me, 1, "ahead");
   14370 		}
   14371 		zone->primariesok[zone->curprimary] = true;
   14372 		goto next_primary;
   14373 	}
   14374 	if (msg != NULL) {
   14375 		dns_message_detach(&msg);
   14376 	}
   14377 	goto detach;
   14378 
   14379 next_primary:
   14380 	if (msg != NULL) {
   14381 		dns_message_detach(&msg);
   14382 	}
   14383 	isc_event_free(&event);
   14384 	dns_request_destroy(&zone->request);
   14385 	/*
   14386 	 * Skip to next failed / untried primary.
   14387 	 */
   14388 	do {
   14389 		zone->curprimary++;
   14390 	} while (zone->curprimary < zone->primariescnt &&
   14391 		 zone->primariesok[zone->curprimary]);
   14392 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14393 	if (zone->curprimary >= zone->primariescnt) {
   14394 		bool done = true;
   14395 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   14396 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   14397 		{
   14398 			/*
   14399 			 * Did we get a good answer from all the primaries?
   14400 			 */
   14401 			for (j = 0; j < zone->primariescnt; j++) {
   14402 				if (!zone->primariesok[j]) {
   14403 					{
   14404 						done = false;
   14405 						break;
   14406 					}
   14407 				}
   14408 			}
   14409 		} else {
   14410 			done = true;
   14411 		}
   14412 		if (!done) {
   14413 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   14414 			zone->curprimary = 0;
   14415 			/*
   14416 			 * Find the next failed primary.
   14417 			 */
   14418 			while (zone->curprimary < zone->primariescnt &&
   14419 			       zone->primariesok[zone->curprimary])
   14420 			{
   14421 				zone->curprimary++;
   14422 			}
   14423 			goto requeue;
   14424 		}
   14425 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14426 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   14427 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   14428 			zone->refreshtime = now;
   14429 		}
   14430 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   14431 		zone_settimer(zone, &now);
   14432 		goto detach;
   14433 	}
   14434 
   14435 requeue:
   14436 	queue_soa_query(zone);
   14437 	goto detach;
   14438 
   14439 exiting:
   14440 	isc_event_free(&event);
   14441 	dns_request_destroy(&zone->request);
   14442 	goto detach;
   14443 
   14444 same_primary:
   14445 	if (msg != NULL) {
   14446 		dns_message_detach(&msg);
   14447 	}
   14448 	isc_event_free(&event);
   14449 	dns_request_destroy(&zone->request);
   14450 	queue_soa_query(zone);
   14451 
   14452 detach:
   14453 	UNLOCK_ZONE(zone);
   14454 	if (do_queue_xfrin) {
   14455 		queue_xfrin(zone);
   14456 	}
   14457 	dns_zone_idetach(&zone);
   14458 	return;
   14459 }
   14460 
   14461 static void
   14462 queue_soa_query(dns_zone_t *zone) {
   14463 	const char me[] = "queue_soa_query";
   14464 	isc_event_t *e;
   14465 	dns_zone_t *dummy = NULL;
   14466 	isc_result_t result;
   14467 
   14468 	ENTER;
   14469 	/*
   14470 	 * Locked by caller
   14471 	 */
   14472 	REQUIRE(LOCKED_ZONE(zone));
   14473 
   14474 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14475 		cancel_refresh(zone);
   14476 		return;
   14477 	}
   14478 
   14479 	e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, soa_query,
   14480 			       zone, sizeof(isc_event_t));
   14481 
   14482 	/*
   14483 	 * Attach so that we won't clean up
   14484 	 * until the event is delivered.
   14485 	 */
   14486 	zone_iattach(zone, &dummy);
   14487 
   14488 	e->ev_arg = zone;
   14489 	e->ev_sender = NULL;
   14490 	result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
   14491 	if (result != ISC_R_SUCCESS) {
   14492 		zone_idetach(&dummy);
   14493 		isc_event_free(&e);
   14494 		cancel_refresh(zone);
   14495 	}
   14496 }
   14497 
   14498 static void
   14499 soa_query(isc_task_t *task, isc_event_t *event) {
   14500 	const char me[] = "soa_query";
   14501 	isc_result_t result = ISC_R_FAILURE;
   14502 	dns_message_t *message = NULL;
   14503 	dns_zone_t *zone = event->ev_arg;
   14504 	dns_zone_t *dummy = NULL;
   14505 	isc_netaddr_t primaryip;
   14506 	dns_tsigkey_t *key = NULL;
   14507 	dns_transport_t *transport = NULL;
   14508 	uint32_t options;
   14509 	bool cancel = true;
   14510 	int timeout;
   14511 	bool have_xfrsource = false, reqnsid, reqexpire;
   14512 	uint16_t udpsize = SEND_BUFFER_SIZE;
   14513 	bool do_queue_xfrin = false;
   14514 
   14515 	REQUIRE(DNS_ZONE_VALID(zone));
   14516 
   14517 	UNUSED(task);
   14518 
   14519 	ENTER;
   14520 
   14521 	LOCK_ZONE(zone);
   14522 	if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
   14523 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   14524 	    zone->view->requestmgr == NULL)
   14525 	{
   14526 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14527 			cancel = false;
   14528 		}
   14529 		goto cleanup;
   14530 	}
   14531 
   14532 again:
   14533 	INSIST(zone->primariescnt > 0);
   14534 	INSIST(zone->curprimary < zone->primariescnt);
   14535 
   14536 	zone->primaryaddr = zone->primaries[zone->curprimary];
   14537 
   14538 	isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr);
   14539 	/*
   14540 	 * First, look for a tsig key in the primaries statement, then
   14541 	 * try for a server key.
   14542 	 */
   14543 	if ((zone->primarykeynames != NULL) &&
   14544 	    (zone->primarykeynames[zone->curprimary] != NULL))
   14545 	{
   14546 		dns_view_t *view = dns_zone_getview(zone);
   14547 		dns_name_t *keyname = zone->primarykeynames[zone->curprimary];
   14548 		result = dns_view_gettsig(view, keyname, &key);
   14549 		if (result != ISC_R_SUCCESS) {
   14550 			char namebuf[DNS_NAME_FORMATSIZE];
   14551 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   14552 			dns_zone_log(zone, ISC_LOG_ERROR,
   14553 				     "unable to find key: %s", namebuf);
   14554 			goto skip_primary;
   14555 		}
   14556 	}
   14557 	if (key == NULL) {
   14558 		result = dns_view_getpeertsig(zone->view, &primaryip, &key);
   14559 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   14560 			char addrbuf[ISC_NETADDR_FORMATSIZE];
   14561 			isc_netaddr_format(&primaryip, addrbuf,
   14562 					   sizeof(addrbuf));
   14563 			dns_zone_log(zone, ISC_LOG_ERROR,
   14564 				     "unable to find TSIG key for %s", addrbuf);
   14565 			goto skip_primary;
   14566 		}
   14567 	}
   14568 
   14569 	if ((zone->primarytlsnames != NULL) &&
   14570 	    (zone->primarytlsnames[zone->curprimary] != NULL))
   14571 	{
   14572 		dns_view_t *view = dns_zone_getview(zone);
   14573 		dns_name_t *tlsname = zone->primarytlsnames[zone->curprimary];
   14574 		result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname,
   14575 					       &transport);
   14576 		if (result != ISC_R_SUCCESS) {
   14577 			char namebuf[DNS_NAME_FORMATSIZE];
   14578 			dns_name_format(tlsname, namebuf, sizeof(namebuf));
   14579 			dns_zone_log(zone, ISC_LOG_ERROR,
   14580 				     "unable to find TLS configuration: %s",
   14581 				     namebuf);
   14582 			goto skip_primary;
   14583 		}
   14584 	}
   14585 
   14586 	options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP
   14587 							 : 0;
   14588 	reqnsid = zone->view->requestnsid;
   14589 	reqexpire = zone->requestexpire;
   14590 	if (zone->view->peers != NULL) {
   14591 		dns_peer_t *peer = NULL;
   14592 		bool edns, usetcp;
   14593 		result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip,
   14594 						 &peer);
   14595 		if (result == ISC_R_SUCCESS) {
   14596 			result = dns_peer_getsupportedns(peer, &edns);
   14597 			if (result == ISC_R_SUCCESS && !edns) {
   14598 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14599 			}
   14600 			result = dns_peer_gettransfersource(peer,
   14601 							    &zone->sourceaddr);
   14602 			if (result == ISC_R_SUCCESS) {
   14603 				have_xfrsource = true;
   14604 			}
   14605 			if (zone->view->resolver != NULL) {
   14606 				udpsize = dns_resolver_getudpsize(
   14607 					zone->view->resolver);
   14608 			}
   14609 			(void)dns_peer_getudpsize(peer, &udpsize);
   14610 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14611 			(void)dns_peer_getrequestexpire(peer, &reqexpire);
   14612 			result = dns_peer_getforcetcp(peer, &usetcp);
   14613 			if (result == ISC_R_SUCCESS && usetcp) {
   14614 				options |= DNS_REQUESTOPT_TCP;
   14615 			}
   14616 		}
   14617 	}
   14618 
   14619 	switch (isc_sockaddr_pf(&zone->primaryaddr)) {
   14620 	case PF_INET:
   14621 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14622 			if (isc_sockaddr_equal(&zone->altxfrsource4,
   14623 					       &zone->xfrsource4))
   14624 			{
   14625 				goto skip_primary;
   14626 			}
   14627 			zone->sourceaddr = zone->altxfrsource4;
   14628 		} else if (!have_xfrsource) {
   14629 			zone->sourceaddr = zone->xfrsource4;
   14630 		}
   14631 		break;
   14632 	case PF_INET6:
   14633 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14634 			if (isc_sockaddr_equal(&zone->altxfrsource6,
   14635 					       &zone->xfrsource6))
   14636 			{
   14637 				goto skip_primary;
   14638 			}
   14639 			zone->sourceaddr = zone->altxfrsource6;
   14640 		} else if (!have_xfrsource) {
   14641 			zone->sourceaddr = zone->xfrsource6;
   14642 		}
   14643 		break;
   14644 	default:
   14645 		result = ISC_R_NOTIMPLEMENTED;
   14646 		goto cleanup;
   14647 	}
   14648 
   14649 	/*
   14650 	 * FIXME(OS): This is a bit hackish, but it enforces the SOA query to go
   14651 	 * through the XFR channel instead of doing dns_request that doesn't
   14652 	 * have DoT support yet.
   14653 	 */
   14654 	if (transport != NULL) {
   14655 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   14656 		do_queue_xfrin = true;
   14657 		cancel = false;
   14658 		result = ISC_R_SUCCESS;
   14659 		goto cleanup;
   14660 	}
   14661 
   14662 	result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
   14663 	if (result != ISC_R_SUCCESS) {
   14664 		goto cleanup;
   14665 	}
   14666 
   14667 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14668 		result = add_opt(message, udpsize, reqnsid, reqexpire);
   14669 		if (result != ISC_R_SUCCESS) {
   14670 			zone_debuglog(zone, me, 1,
   14671 				      "unable to add opt record: %s",
   14672 				      isc_result_totext(result));
   14673 		}
   14674 	}
   14675 
   14676 	zone_iattach(zone, &dummy);
   14677 	timeout = 5;
   14678 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14679 		timeout = 30;
   14680 	}
   14681 	result = dns_request_create(
   14682 		zone->view->requestmgr, message, &zone->sourceaddr,
   14683 		&zone->primaryaddr, options, key, timeout * 3 + 1, timeout, 2,
   14684 		zone->task, refresh_callback, zone, &zone->request);
   14685 	if (result != ISC_R_SUCCESS) {
   14686 		zone_idetach(&dummy);
   14687 		zone_debuglog(zone, me, 1, "dns_request_create() failed: %s",
   14688 			      isc_result_totext(result));
   14689 		goto skip_primary;
   14690 	} else {
   14691 		if (isc_sockaddr_pf(&zone->primaryaddr) == PF_INET) {
   14692 			inc_stats(zone, dns_zonestatscounter_soaoutv4);
   14693 		} else {
   14694 			inc_stats(zone, dns_zonestatscounter_soaoutv6);
   14695 		}
   14696 	}
   14697 	cancel = false;
   14698 cleanup:
   14699 	if (transport != NULL) {
   14700 		dns_transport_detach(&transport);
   14701 	}
   14702 	if (key != NULL) {
   14703 		dns_tsigkey_detach(&key);
   14704 	}
   14705 	if (result != ISC_R_SUCCESS) {
   14706 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14707 	}
   14708 	if (message != NULL) {
   14709 		dns_message_detach(&message);
   14710 	}
   14711 	if (cancel) {
   14712 		cancel_refresh(zone);
   14713 	}
   14714 	isc_event_free(&event);
   14715 	UNLOCK_ZONE(zone);
   14716 	if (do_queue_xfrin) {
   14717 		queue_xfrin(zone);
   14718 	}
   14719 	dns_zone_idetach(&zone);
   14720 	return;
   14721 
   14722 skip_primary:
   14723 	if (transport != NULL) {
   14724 		dns_transport_detach(&transport);
   14725 	}
   14726 	if (key != NULL) {
   14727 		dns_tsigkey_detach(&key);
   14728 	}
   14729 	if (message != NULL) {
   14730 		dns_message_detach(&message);
   14731 	}
   14732 	/*
   14733 	 * Skip to next failed / untried primary.
   14734 	 */
   14735 	do {
   14736 		zone->curprimary++;
   14737 	} while (zone->curprimary < zone->primariescnt &&
   14738 		 zone->primariesok[zone->curprimary]);
   14739 	if (zone->curprimary < zone->primariescnt) {
   14740 		goto again;
   14741 	}
   14742 	zone->curprimary = 0;
   14743 	goto cleanup;
   14744 }
   14745 
   14746 static void
   14747 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
   14748 	const char me[] = "ns_query";
   14749 	isc_result_t result;
   14750 	dns_message_t *message = NULL;
   14751 	isc_netaddr_t primaryip;
   14752 	dns_tsigkey_t *key = NULL;
   14753 	dns_dbnode_t *node = NULL;
   14754 	int timeout;
   14755 	bool have_xfrsource = false;
   14756 	bool reqnsid;
   14757 	uint16_t udpsize = SEND_BUFFER_SIZE;
   14758 	struct stub_cb_args *cb_args;
   14759 
   14760 	REQUIRE(DNS_ZONE_VALID(zone));
   14761 	REQUIRE(LOCKED_ZONE(zone));
   14762 	REQUIRE((soardataset != NULL && stub == NULL) ||
   14763 		(soardataset == NULL && stub != NULL));
   14764 	REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
   14765 
   14766 	ENTER;
   14767 
   14768 	if (stub == NULL) {
   14769 		stub = isc_mem_get(zone->mctx, sizeof(*stub));
   14770 		stub->magic = STUB_MAGIC;
   14771 		stub->mctx = zone->mctx;
   14772 		stub->zone = NULL;
   14773 		stub->db = NULL;
   14774 		stub->version = NULL;
   14775 		atomic_init(&stub->pending_requests, 0);
   14776 
   14777 		/*
   14778 		 * Attach so that the zone won't disappear from under us.
   14779 		 */
   14780 		zone_iattach(zone, &stub->zone);
   14781 
   14782 		/*
   14783 		 * If a db exists we will update it, otherwise we create a
   14784 		 * new one and attach it to the zone once we have the NS
   14785 		 * RRset and glue.
   14786 		 */
   14787 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14788 		if (zone->db != NULL) {
   14789 			dns_db_attach(zone->db, &stub->db);
   14790 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14791 		} else {
   14792 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14793 
   14794 			INSIST(zone->db_argc >= 1);
   14795 			result = dns_db_create(zone->mctx, zone->db_argv[0],
   14796 					       &zone->origin, dns_dbtype_stub,
   14797 					       zone->rdclass, zone->db_argc - 1,
   14798 					       zone->db_argv + 1, &stub->db);
   14799 			if (result != ISC_R_SUCCESS) {
   14800 				dns_zone_log(zone, ISC_LOG_ERROR,
   14801 					     "refreshing stub: "
   14802 					     "could not create "
   14803 					     "database: %s",
   14804 					     isc_result_totext(result));
   14805 				goto cleanup;
   14806 			}
   14807 			dns_db_settask(stub->db, zone->task);
   14808 		}
   14809 
   14810 		result = dns_db_newversion(stub->db, &stub->version);
   14811 		if (result != ISC_R_SUCCESS) {
   14812 			dns_zone_log(zone, ISC_LOG_INFO,
   14813 				     "refreshing stub: "
   14814 				     "dns_db_newversion() failed: %s",
   14815 				     isc_result_totext(result));
   14816 			goto cleanup;
   14817 		}
   14818 
   14819 		/*
   14820 		 * Update SOA record.
   14821 		 */
   14822 		result = dns_db_findnode(stub->db, &zone->origin, true, &node);
   14823 		if (result != ISC_R_SUCCESS) {
   14824 			dns_zone_log(zone, ISC_LOG_INFO,
   14825 				     "refreshing stub: "
   14826 				     "dns_db_findnode() failed: %s",
   14827 				     isc_result_totext(result));
   14828 			goto cleanup;
   14829 		}
   14830 
   14831 		result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   14832 					    soardataset, 0, NULL);
   14833 		dns_db_detachnode(stub->db, &node);
   14834 		if (result != ISC_R_SUCCESS) {
   14835 			dns_zone_log(zone, ISC_LOG_INFO,
   14836 				     "refreshing stub: "
   14837 				     "dns_db_addrdataset() failed: %s",
   14838 				     isc_result_totext(result));
   14839 			goto cleanup;
   14840 		}
   14841 	}
   14842 
   14843 	/*
   14844 	 * XXX Optimisation: Create message when zone is setup and reuse.
   14845 	 */
   14846 	result = create_query(zone, dns_rdatatype_ns, &zone->origin, &message);
   14847 	INSIST(result == ISC_R_SUCCESS);
   14848 
   14849 	INSIST(zone->primariescnt > 0);
   14850 	INSIST(zone->curprimary < zone->primariescnt);
   14851 	zone->primaryaddr = zone->primaries[zone->curprimary];
   14852 
   14853 	isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr);
   14854 	/*
   14855 	 * First, look for a tsig key in the primaries statement, then
   14856 	 * try for a server key.
   14857 	 */
   14858 	if ((zone->primarykeynames != NULL) &&
   14859 	    (zone->primarykeynames[zone->curprimary] != NULL))
   14860 	{
   14861 		dns_view_t *view = dns_zone_getview(zone);
   14862 		dns_name_t *keyname = zone->primarykeynames[zone->curprimary];
   14863 		result = dns_view_gettsig(view, keyname, &key);
   14864 		if (result != ISC_R_SUCCESS) {
   14865 			char namebuf[DNS_NAME_FORMATSIZE];
   14866 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   14867 			dns_zone_log(zone, ISC_LOG_ERROR,
   14868 				     "unable to find key: %s", namebuf);
   14869 		}
   14870 	}
   14871 	if (key == NULL) {
   14872 		(void)dns_view_getpeertsig(zone->view, &primaryip, &key);
   14873 	}
   14874 
   14875 	/* FIXME(OS): Do we need the transport here too? Most probably yes */
   14876 
   14877 	reqnsid = zone->view->requestnsid;
   14878 	if (zone->view->peers != NULL) {
   14879 		dns_peer_t *peer = NULL;
   14880 		bool edns;
   14881 		result = dns_peerlist_peerbyaddr(zone->view->peers, &primaryip,
   14882 						 &peer);
   14883 		if (result == ISC_R_SUCCESS) {
   14884 			result = dns_peer_getsupportedns(peer, &edns);
   14885 			if (result == ISC_R_SUCCESS && !edns) {
   14886 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14887 			}
   14888 			result = dns_peer_gettransfersource(peer,
   14889 							    &zone->sourceaddr);
   14890 			if (result == ISC_R_SUCCESS) {
   14891 				have_xfrsource = true;
   14892 			}
   14893 			if (zone->view->resolver != NULL) {
   14894 				udpsize = dns_resolver_getudpsize(
   14895 					zone->view->resolver);
   14896 			}
   14897 			(void)dns_peer_getudpsize(peer, &udpsize);
   14898 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14899 		}
   14900 	}
   14901 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14902 		result = add_opt(message, udpsize, reqnsid, false);
   14903 		if (result != ISC_R_SUCCESS) {
   14904 			zone_debuglog(zone, me, 1,
   14905 				      "unable to add opt record: %s",
   14906 				      isc_result_totext(result));
   14907 		}
   14908 	}
   14909 
   14910 	/*
   14911 	 * Always use TCP so that we shouldn't truncate in additional section.
   14912 	 */
   14913 	switch (isc_sockaddr_pf(&zone->primaryaddr)) {
   14914 	case PF_INET:
   14915 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14916 			zone->sourceaddr = zone->altxfrsource4;
   14917 		} else if (!have_xfrsource) {
   14918 			zone->sourceaddr = zone->xfrsource4;
   14919 		}
   14920 		break;
   14921 	case PF_INET6:
   14922 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14923 			zone->sourceaddr = zone->altxfrsource6;
   14924 		} else if (!have_xfrsource) {
   14925 			zone->sourceaddr = zone->xfrsource6;
   14926 		}
   14927 		break;
   14928 	default:
   14929 		result = ISC_R_NOTIMPLEMENTED;
   14930 		POST(result);
   14931 		goto cleanup;
   14932 	}
   14933 	timeout = 5;
   14934 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14935 		timeout = 30;
   14936 	}
   14937 
   14938 	/*
   14939 	 * Save request parameters so we can reuse them later on
   14940 	 * for resolving missing glue A/AAAA records.
   14941 	 */
   14942 	cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args));
   14943 	cb_args->stub = stub;
   14944 	cb_args->tsig_key = key;
   14945 	cb_args->udpsize = udpsize;
   14946 	cb_args->timeout = timeout;
   14947 	cb_args->reqnsid = reqnsid;
   14948 
   14949 	result = dns_request_create(
   14950 		zone->view->requestmgr, message, &zone->sourceaddr,
   14951 		&zone->primaryaddr, DNS_REQUESTOPT_TCP, key, timeout * 3 + 1,
   14952 		timeout, 2, zone->task, stub_callback, cb_args, &zone->request);
   14953 	if (result != ISC_R_SUCCESS) {
   14954 		zone_debuglog(zone, me, 1, "dns_request_create() failed: %s",
   14955 			      isc_result_totext(result));
   14956 		goto cleanup;
   14957 	}
   14958 	dns_message_detach(&message);
   14959 	goto unlock;
   14960 
   14961 cleanup:
   14962 	cancel_refresh(zone);
   14963 	stub->magic = 0;
   14964 	if (stub->version != NULL) {
   14965 		dns_db_closeversion(stub->db, &stub->version, false);
   14966 	}
   14967 	if (stub->db != NULL) {
   14968 		dns_db_detach(&stub->db);
   14969 	}
   14970 	if (stub->zone != NULL) {
   14971 		zone_idetach(&stub->zone);
   14972 	}
   14973 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   14974 	if (message != NULL) {
   14975 		dns_message_detach(&message);
   14976 	}
   14977 unlock:
   14978 	if (key != NULL) {
   14979 		dns_tsigkey_detach(&key);
   14980 	}
   14981 	return;
   14982 }
   14983 
   14984 /*
   14985  * Shut the zone down.
   14986  */
   14987 static void
   14988 zone_shutdown(isc_task_t *task, isc_event_t *event) {
   14989 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   14990 	bool free_needed, linked = false;
   14991 	dns_zone_t *raw = NULL, *secure = NULL;
   14992 	dns_view_t *view = NULL, *prev_view = NULL;
   14993 
   14994 	UNUSED(task);
   14995 	REQUIRE(DNS_ZONE_VALID(zone));
   14996 	INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
   14997 	INSIST(isc_refcount_current(&zone->erefs) == 0);
   14998 
   14999 	zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
   15000 
   15001 	/*
   15002 	 * If we were waiting for xfrin quota, step out of
   15003 	 * the queue.
   15004 	 * If there's no zone manager, we can't be waiting for the
   15005 	 * xfrin quota
   15006 	 */
   15007 	if (zone->zmgr != NULL) {
   15008 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   15009 		if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
   15010 			ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
   15011 					statelink);
   15012 			linked = true;
   15013 			zone->statelist = NULL;
   15014 		}
   15015 		if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
   15016 			ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
   15017 					statelink);
   15018 			zone->statelist = NULL;
   15019 			zmgr_resume_xfrs(zone->zmgr, false);
   15020 		}
   15021 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   15022 	}
   15023 
   15024 	/*
   15025 	 * In task context, no locking required.  See zone_xfrdone().
   15026 	 */
   15027 	if (zone->xfr != NULL) {
   15028 		/* The final detach will happen in zone_xfrdone() */
   15029 		dns_xfrin_shutdown(zone->xfr);
   15030 	}
   15031 
   15032 	/* Safe to release the zone now */
   15033 	if (zone->zmgr != NULL) {
   15034 		dns_zonemgr_releasezone(zone->zmgr, zone);
   15035 	}
   15036 
   15037 	LOCK_ZONE(zone);
   15038 	INSIST(zone != zone->raw);
   15039 
   15040 	/*
   15041 	 * Detach the views early, we don't need them anymore.  However, we need
   15042 	 * to detach them outside of the zone lock to break the lock loop
   15043 	 * between view, adb and zone locks.
   15044 	 */
   15045 	view = zone->view;
   15046 	zone->view = NULL;
   15047 	prev_view = zone->prev_view;
   15048 	zone->prev_view = NULL;
   15049 
   15050 	if (linked) {
   15051 		isc_refcount_decrement(&zone->irefs);
   15052 	}
   15053 	if (zone->request != NULL) {
   15054 		dns_request_cancel(zone->request);
   15055 	}
   15056 
   15057 	if (zone->readio != NULL) {
   15058 		zonemgr_cancelio(zone->readio);
   15059 	}
   15060 
   15061 	if (zone->lctx != NULL) {
   15062 		dns_loadctx_cancel(zone->lctx);
   15063 	}
   15064 
   15065 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   15066 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15067 	{
   15068 		if (zone->writeio != NULL) {
   15069 			zonemgr_cancelio(zone->writeio);
   15070 		}
   15071 
   15072 		if (zone->dctx != NULL) {
   15073 			dns_dumpctx_cancel(zone->dctx);
   15074 		}
   15075 	}
   15076 
   15077 	checkds_cancel(zone);
   15078 
   15079 	notify_cancel(zone);
   15080 
   15081 	forward_cancel(zone);
   15082 
   15083 	if (zone->timer != NULL) {
   15084 		isc_timer_destroy(&zone->timer);
   15085 		isc_refcount_decrement(&zone->irefs);
   15086 	}
   15087 
   15088 	/*
   15089 	 * We have now canceled everything set the flag to allow exit_check()
   15090 	 * to succeed.	We must not unlock between setting this flag and
   15091 	 * calling exit_check().
   15092 	 */
   15093 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
   15094 	free_needed = exit_check(zone);
   15095 	/*
   15096 	 * If a dump is in progress for the secure zone, defer detaching from
   15097 	 * the raw zone as it may prevent the unsigned serial number from being
   15098 	 * stored in the raw-format dump of the secure zone.  In this scenario,
   15099 	 * dump_done() takes care of cleaning up the zone->raw reference.
   15100 	 */
   15101 	if (inline_secure(zone) && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   15102 		raw = zone->raw;
   15103 		zone->raw = NULL;
   15104 	}
   15105 	if (inline_raw(zone)) {
   15106 		secure = zone->secure;
   15107 		zone->secure = NULL;
   15108 	}
   15109 	UNLOCK_ZONE(zone);
   15110 
   15111 	if (view != NULL) {
   15112 		dns_view_weakdetach(&view);
   15113 	}
   15114 	if (prev_view != NULL) {
   15115 		dns_view_weakdetach(&prev_view);
   15116 	}
   15117 
   15118 	if (raw != NULL) {
   15119 		dns_zone_detach(&raw);
   15120 	}
   15121 	if (secure != NULL) {
   15122 		dns_zone_idetach(&secure);
   15123 	}
   15124 	if (free_needed) {
   15125 		zone_free(zone);
   15126 	}
   15127 }
   15128 
   15129 static void
   15130 zone_timer(isc_task_t *task, isc_event_t *event) {
   15131 	const char me[] = "zone_timer";
   15132 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   15133 
   15134 	UNUSED(task);
   15135 	REQUIRE(DNS_ZONE_VALID(zone));
   15136 
   15137 	ENTER;
   15138 
   15139 	zone_maintenance(zone);
   15140 
   15141 	isc_event_free(&event);
   15142 }
   15143 
   15144 static void
   15145 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
   15146 	const char me[] = "zone_settimer";
   15147 	isc_time_t next;
   15148 	isc_result_t result;
   15149 
   15150 	REQUIRE(DNS_ZONE_VALID(zone));
   15151 	REQUIRE(LOCKED_ZONE(zone));
   15152 	ENTER;
   15153 
   15154 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   15155 		return;
   15156 	}
   15157 
   15158 	isc_time_settoepoch(&next);
   15159 
   15160 	switch (zone->type) {
   15161 	case dns_zone_redirect:
   15162 		if (zone->primaries != NULL) {
   15163 			goto treat_as_secondary;
   15164 		}
   15165 		FALLTHROUGH;
   15166 	case dns_zone_primary:
   15167 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   15168 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   15169 		{
   15170 			next = zone->notifytime;
   15171 		}
   15172 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   15173 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15174 		{
   15175 			INSIST(!isc_time_isepoch(&zone->dumptime));
   15176 			if (isc_time_isepoch(&next) ||
   15177 			    isc_time_compare(&zone->dumptime, &next) < 0)
   15178 			{
   15179 				next = zone->dumptime;
   15180 			}
   15181 		}
   15182 		if (zone->type == dns_zone_redirect) {
   15183 			break;
   15184 		}
   15185 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
   15186 		    !isc_time_isepoch(&zone->refreshkeytime))
   15187 		{
   15188 			if (isc_time_isepoch(&next) ||
   15189 			    isc_time_compare(&zone->refreshkeytime, &next) < 0)
   15190 			{
   15191 				next = zone->refreshkeytime;
   15192 			}
   15193 		}
   15194 		if (!isc_time_isepoch(&zone->resigntime)) {
   15195 			if (isc_time_isepoch(&next) ||
   15196 			    isc_time_compare(&zone->resigntime, &next) < 0)
   15197 			{
   15198 				next = zone->resigntime;
   15199 			}
   15200 		}
   15201 		if (!isc_time_isepoch(&zone->keywarntime)) {
   15202 			if (isc_time_isepoch(&next) ||
   15203 			    isc_time_compare(&zone->keywarntime, &next) < 0)
   15204 			{
   15205 				next = zone->keywarntime;
   15206 			}
   15207 		}
   15208 		if (!isc_time_isepoch(&zone->signingtime)) {
   15209 			if (isc_time_isepoch(&next) ||
   15210 			    isc_time_compare(&zone->signingtime, &next) < 0)
   15211 			{
   15212 				next = zone->signingtime;
   15213 			}
   15214 		}
   15215 		if (!isc_time_isepoch(&zone->nsec3chaintime)) {
   15216 			if (isc_time_isepoch(&next) ||
   15217 			    isc_time_compare(&zone->nsec3chaintime, &next) < 0)
   15218 			{
   15219 				next = zone->nsec3chaintime;
   15220 			}
   15221 		}
   15222 		break;
   15223 
   15224 	case dns_zone_secondary:
   15225 	case dns_zone_mirror:
   15226 	treat_as_secondary:
   15227 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   15228 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   15229 		{
   15230 			next = zone->notifytime;
   15231 		}
   15232 		FALLTHROUGH;
   15233 	case dns_zone_stub:
   15234 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
   15235 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOPRIMARIES) &&
   15236 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
   15237 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
   15238 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
   15239 		    !isc_time_isepoch(&zone->refreshtime) &&
   15240 		    (isc_time_isepoch(&next) ||
   15241 		     isc_time_compare(&zone->refreshtime, &next) < 0))
   15242 		{
   15243 			next = zone->refreshtime;
   15244 		}
   15245 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   15246 		    !isc_time_isepoch(&zone->expiretime))
   15247 		{
   15248 			if (isc_time_isepoch(&next) ||
   15249 			    isc_time_compare(&zone->expiretime, &next) < 0)
   15250 			{
   15251 				next = zone->expiretime;
   15252 			}
   15253 		}
   15254 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   15255 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15256 		{
   15257 			INSIST(!isc_time_isepoch(&zone->dumptime));
   15258 			if (isc_time_isepoch(&next) ||
   15259 			    isc_time_compare(&zone->dumptime, &next) < 0)
   15260 			{
   15261 				next = zone->dumptime;
   15262 			}
   15263 		}
   15264 		break;
   15265 
   15266 	case dns_zone_key:
   15267 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   15268 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   15269 		{
   15270 			INSIST(!isc_time_isepoch(&zone->dumptime));
   15271 			if (isc_time_isepoch(&next) ||
   15272 			    isc_time_compare(&zone->dumptime, &next) < 0)
   15273 			{
   15274 				next = zone->dumptime;
   15275 			}
   15276 		}
   15277 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
   15278 			if (isc_time_isepoch(&next) ||
   15279 			    (!isc_time_isepoch(&zone->refreshkeytime) &&
   15280 			     isc_time_compare(&zone->refreshkeytime, &next) <
   15281 				     0))
   15282 			{
   15283 				next = zone->refreshkeytime;
   15284 			}
   15285 		}
   15286 		break;
   15287 
   15288 	default:
   15289 		break;
   15290 	}
   15291 
   15292 	if (isc_time_isepoch(&next)) {
   15293 		zone_debuglog(zone, me, 10, "settimer inactive");
   15294 		result = isc_timer_reset(zone->timer, isc_timertype_inactive,
   15295 					 NULL, NULL, true);
   15296 		if (result != ISC_R_SUCCESS) {
   15297 			dns_zone_log(zone, ISC_LOG_ERROR,
   15298 				     "could not deactivate zone timer: %s",
   15299 				     isc_result_totext(result));
   15300 		}
   15301 	} else {
   15302 		if (isc_time_compare(&next, now) <= 0) {
   15303 			next = *now;
   15304 		}
   15305 		result = isc_timer_reset(zone->timer, isc_timertype_once, &next,
   15306 					 NULL, true);
   15307 		if (result != ISC_R_SUCCESS) {
   15308 			dns_zone_log(zone, ISC_LOG_ERROR,
   15309 				     "could not reset zone timer: %s",
   15310 				     isc_result_totext(result));
   15311 		}
   15312 	}
   15313 }
   15314 
   15315 static void
   15316 cancel_refresh(dns_zone_t *zone) {
   15317 	const char me[] = "cancel_refresh";
   15318 	isc_time_t now;
   15319 
   15320 	/*
   15321 	 * 'zone' locked by caller.
   15322 	 */
   15323 
   15324 	REQUIRE(DNS_ZONE_VALID(zone));
   15325 	REQUIRE(LOCKED_ZONE(zone));
   15326 
   15327 	ENTER;
   15328 
   15329 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   15330 	TIME_NOW(&now);
   15331 	zone_settimer(zone, &now);
   15332 }
   15333 
   15334 static isc_result_t
   15335 notify_createmessage(dns_zone_t *zone, unsigned int flags,
   15336 		     dns_message_t **messagep) {
   15337 	dns_db_t *zonedb = NULL;
   15338 	dns_dbnode_t *node = NULL;
   15339 	dns_dbversion_t *version = NULL;
   15340 	dns_message_t *message = NULL;
   15341 	dns_rdataset_t rdataset;
   15342 	dns_rdata_t rdata = DNS_RDATA_INIT;
   15343 
   15344 	dns_name_t *tempname = NULL;
   15345 	dns_rdata_t *temprdata = NULL;
   15346 	dns_rdatalist_t *temprdatalist = NULL;
   15347 	dns_rdataset_t *temprdataset = NULL;
   15348 
   15349 	isc_result_t result;
   15350 	isc_region_t r;
   15351 	isc_buffer_t *b = NULL;
   15352 
   15353 	REQUIRE(DNS_ZONE_VALID(zone));
   15354 	REQUIRE(messagep != NULL && *messagep == NULL);
   15355 
   15356 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   15357 
   15358 	message->opcode = dns_opcode_notify;
   15359 	message->flags |= DNS_MESSAGEFLAG_AA;
   15360 	message->rdclass = zone->rdclass;
   15361 
   15362 	result = dns_message_gettempname(message, &tempname);
   15363 	if (result != ISC_R_SUCCESS) {
   15364 		goto cleanup;
   15365 	}
   15366 
   15367 	result = dns_message_gettemprdataset(message, &temprdataset);
   15368 	if (result != ISC_R_SUCCESS) {
   15369 		goto cleanup;
   15370 	}
   15371 
   15372 	/*
   15373 	 * Make question.
   15374 	 */
   15375 	dns_name_clone(&zone->origin, tempname);
   15376 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
   15377 				  dns_rdatatype_soa);
   15378 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   15379 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
   15380 	tempname = NULL;
   15381 	temprdataset = NULL;
   15382 
   15383 	if ((flags & DNS_NOTIFY_NOSOA) != 0) {
   15384 		goto done;
   15385 	}
   15386 
   15387 	result = dns_message_gettempname(message, &tempname);
   15388 	if (result != ISC_R_SUCCESS) {
   15389 		goto soa_cleanup;
   15390 	}
   15391 	result = dns_message_gettemprdata(message, &temprdata);
   15392 	if (result != ISC_R_SUCCESS) {
   15393 		goto soa_cleanup;
   15394 	}
   15395 	result = dns_message_gettemprdataset(message, &temprdataset);
   15396 	if (result != ISC_R_SUCCESS) {
   15397 		goto soa_cleanup;
   15398 	}
   15399 	result = dns_message_gettemprdatalist(message, &temprdatalist);
   15400 	if (result != ISC_R_SUCCESS) {
   15401 		goto soa_cleanup;
   15402 	}
   15403 
   15404 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   15405 	INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
   15406 	dns_db_attach(zone->db, &zonedb);
   15407 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15408 
   15409 	dns_name_clone(&zone->origin, tempname);
   15410 	dns_db_currentversion(zonedb, &version);
   15411 	result = dns_db_findnode(zonedb, tempname, false, &node);
   15412 	if (result != ISC_R_SUCCESS) {
   15413 		goto soa_cleanup;
   15414 	}
   15415 
   15416 	dns_rdataset_init(&rdataset);
   15417 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   15418 				     dns_rdatatype_none, 0, &rdataset, NULL);
   15419 	if (result != ISC_R_SUCCESS) {
   15420 		goto soa_cleanup;
   15421 	}
   15422 	result = dns_rdataset_first(&rdataset);
   15423 	if (result != ISC_R_SUCCESS) {
   15424 		goto soa_cleanup;
   15425 	}
   15426 	dns_rdataset_current(&rdataset, &rdata);
   15427 	dns_rdata_toregion(&rdata, &r);
   15428 	isc_buffer_allocate(zone->mctx, &b, r.length);
   15429 	isc_buffer_putmem(b, r.base, r.length);
   15430 	isc_buffer_usedregion(b, &r);
   15431 	dns_rdata_init(temprdata);
   15432 	dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
   15433 	dns_message_takebuffer(message, &b);
   15434 	result = dns_rdataset_next(&rdataset);
   15435 	dns_rdataset_disassociate(&rdataset);
   15436 	if (result != ISC_R_NOMORE) {
   15437 		goto soa_cleanup;
   15438 	}
   15439 	temprdatalist->rdclass = rdata.rdclass;
   15440 	temprdatalist->type = rdata.type;
   15441 	temprdatalist->ttl = rdataset.ttl;
   15442 	ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
   15443 
   15444 	result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
   15445 	if (result != ISC_R_SUCCESS) {
   15446 		goto soa_cleanup;
   15447 	}
   15448 
   15449 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   15450 	dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
   15451 	temprdatalist = NULL;
   15452 	temprdataset = NULL;
   15453 	temprdata = NULL;
   15454 	tempname = NULL;
   15455 
   15456 soa_cleanup:
   15457 	if (node != NULL) {
   15458 		dns_db_detachnode(zonedb, &node);
   15459 	}
   15460 	if (version != NULL) {
   15461 		dns_db_closeversion(zonedb, &version, false);
   15462 	}
   15463 	if (zonedb != NULL) {
   15464 		dns_db_detach(&zonedb);
   15465 	}
   15466 	if (tempname != NULL) {
   15467 		dns_message_puttempname(message, &tempname);
   15468 	}
   15469 	if (temprdata != NULL) {
   15470 		dns_message_puttemprdata(message, &temprdata);
   15471 	}
   15472 	if (temprdataset != NULL) {
   15473 		dns_message_puttemprdataset(message, &temprdataset);
   15474 	}
   15475 	if (temprdatalist != NULL) {
   15476 		dns_message_puttemprdatalist(message, &temprdatalist);
   15477 	}
   15478 
   15479 done:
   15480 	*messagep = message;
   15481 	return (ISC_R_SUCCESS);
   15482 
   15483 cleanup:
   15484 	if (tempname != NULL) {
   15485 		dns_message_puttempname(message, &tempname);
   15486 	}
   15487 	if (temprdataset != NULL) {
   15488 		dns_message_puttemprdataset(message, &temprdataset);
   15489 	}
   15490 	dns_message_detach(&message);
   15491 	return (result);
   15492 }
   15493 
   15494 isc_result_t
   15495 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
   15496 		       isc_sockaddr_t *to, dns_message_t *msg) {
   15497 	unsigned int i;
   15498 	dns_rdata_soa_t soa;
   15499 	dns_rdataset_t *rdataset = NULL;
   15500 	dns_rdata_t rdata = DNS_RDATA_INIT;
   15501 	isc_result_t result;
   15502 	char fromtext[ISC_SOCKADDR_FORMATSIZE];
   15503 	int match = 0;
   15504 	isc_netaddr_t netaddr;
   15505 	uint32_t serial = 0;
   15506 	bool have_serial = false;
   15507 	dns_tsigkey_t *tsigkey;
   15508 	const dns_name_t *tsig;
   15509 
   15510 	REQUIRE(DNS_ZONE_VALID(zone));
   15511 
   15512 	/*
   15513 	 * If type != T_SOA return DNS_R_NOTIMP.  We don't yet support
   15514 	 * ROLLOVER.
   15515 	 *
   15516 	 * SOA:	RFC1996
   15517 	 * Check that 'from' is a valid notify source, (zone->primaries).
   15518 	 *	Return DNS_R_REFUSED if not.
   15519 	 *
   15520 	 * If the notify message contains a serial number check it
   15521 	 * against the zones serial and return if <= current serial
   15522 	 *
   15523 	 * If a refresh check is progress, if so just record the
   15524 	 * fact we received a NOTIFY and from where and return.
   15525 	 * We will perform a new refresh check when the current one
   15526 	 * completes. Return ISC_R_SUCCESS.
   15527 	 *
   15528 	 * Otherwise initiate a refresh check using 'from' as the
   15529 	 * first address to check.  Return ISC_R_SUCCESS.
   15530 	 */
   15531 
   15532 	isc_sockaddr_format(from, fromtext, sizeof(fromtext));
   15533 
   15534 	/*
   15535 	 * Notify messages are processed by the raw zone.
   15536 	 */
   15537 	LOCK_ZONE(zone);
   15538 	INSIST(zone != zone->raw);
   15539 	if (inline_secure(zone)) {
   15540 		result = dns_zone_notifyreceive(zone->raw, from, to, msg);
   15541 		UNLOCK_ZONE(zone);
   15542 		return (result);
   15543 	}
   15544 	/*
   15545 	 *  We only handle NOTIFY (SOA) at the present.
   15546 	 */
   15547 	if (isc_sockaddr_pf(from) == PF_INET) {
   15548 		inc_stats(zone, dns_zonestatscounter_notifyinv4);
   15549 	} else {
   15550 		inc_stats(zone, dns_zonestatscounter_notifyinv6);
   15551 	}
   15552 	if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
   15553 	    dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
   15554 				 dns_rdatatype_soa, dns_rdatatype_none, NULL,
   15555 				 NULL) != ISC_R_SUCCESS)
   15556 	{
   15557 		UNLOCK_ZONE(zone);
   15558 		if (msg->counts[DNS_SECTION_QUESTION] == 0) {
   15559 			dns_zone_log(zone, ISC_LOG_NOTICE,
   15560 				     "NOTIFY with no "
   15561 				     "question section from: %s",
   15562 				     fromtext);
   15563 			return (DNS_R_FORMERR);
   15564 		}
   15565 		dns_zone_log(zone, ISC_LOG_NOTICE,
   15566 			     "NOTIFY zone does not match");
   15567 		return (DNS_R_NOTIMP);
   15568 	}
   15569 
   15570 	/*
   15571 	 * If we are a primary zone just succeed.
   15572 	 */
   15573 	if (zone->type == dns_zone_primary) {
   15574 		UNLOCK_ZONE(zone);
   15575 		return (ISC_R_SUCCESS);
   15576 	}
   15577 
   15578 	isc_netaddr_fromsockaddr(&netaddr, from);
   15579 	for (i = 0; i < zone->primariescnt; i++) {
   15580 		if (isc_sockaddr_eqaddr(from, &zone->primaries[i])) {
   15581 			break;
   15582 		}
   15583 		if (zone->view->aclenv->match_mapped &&
   15584 		    IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
   15585 		    isc_sockaddr_pf(&zone->primaries[i]) == AF_INET)
   15586 		{
   15587 			isc_netaddr_t na1, na2;
   15588 			isc_netaddr_fromv4mapped(&na1, &netaddr);
   15589 			isc_netaddr_fromsockaddr(&na2, &zone->primaries[i]);
   15590 			if (isc_netaddr_equal(&na1, &na2)) {
   15591 				break;
   15592 			}
   15593 		}
   15594 	}
   15595 
   15596 	/*
   15597 	 * Accept notify requests from non primaries if they are on
   15598 	 * 'zone->notify_acl'.
   15599 	 */
   15600 	tsigkey = dns_message_gettsigkey(msg);
   15601 	tsig = dns_tsigkey_identity(tsigkey);
   15602 	if (i >= zone->primariescnt && zone->notify_acl != NULL &&
   15603 	    (dns_acl_match(&netaddr, tsig, zone->notify_acl, zone->view->aclenv,
   15604 			   &match, NULL) == ISC_R_SUCCESS) &&
   15605 	    match > 0)
   15606 	{
   15607 		/* Accept notify. */
   15608 	} else if (i >= zone->primariescnt) {
   15609 		UNLOCK_ZONE(zone);
   15610 		dns_zone_log(zone, ISC_LOG_INFO,
   15611 			     "refused notify from non-primary: %s", fromtext);
   15612 		inc_stats(zone, dns_zonestatscounter_notifyrej);
   15613 		return (DNS_R_REFUSED);
   15614 	}
   15615 
   15616 	/*
   15617 	 * If the zone is loaded and there are answers check the serial
   15618 	 * to see if we need to do a refresh.  Do not worry about this
   15619 	 * check if we are a dialup zone as we use the notify request
   15620 	 * to trigger a refresh check.
   15621 	 */
   15622 	if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
   15623 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   15624 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH))
   15625 	{
   15626 		result = dns_message_findname(
   15627 			msg, DNS_SECTION_ANSWER, &zone->origin,
   15628 			dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset);
   15629 		if (result == ISC_R_SUCCESS) {
   15630 			result = dns_rdataset_first(rdataset);
   15631 		}
   15632 		if (result == ISC_R_SUCCESS) {
   15633 			uint32_t oldserial;
   15634 			unsigned int soacount;
   15635 
   15636 			dns_rdataset_current(rdataset, &rdata);
   15637 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   15638 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15639 			serial = soa.serial;
   15640 			have_serial = true;
   15641 			/*
   15642 			 * The following should safely be performed without DB
   15643 			 * lock and succeed in this context.
   15644 			 */
   15645 			result = zone_get_from_db(zone, zone->db, NULL,
   15646 						  &soacount, NULL, &oldserial,
   15647 						  NULL, NULL, NULL, NULL, NULL);
   15648 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15649 			RUNTIME_CHECK(soacount > 0U);
   15650 			if (isc_serial_le(serial, oldserial)) {
   15651 				dns_zone_log(zone, ISC_LOG_INFO,
   15652 					     "notify from %s: "
   15653 					     "zone is up to date",
   15654 					     fromtext);
   15655 				UNLOCK_ZONE(zone);
   15656 				return (ISC_R_SUCCESS);
   15657 			}
   15658 		}
   15659 	}
   15660 
   15661 	/*
   15662 	 * If we got this far and there was a refresh in progress just
   15663 	 * let it complete.  Record where we got the notify from so we
   15664 	 * can perform a refresh check when the current one completes
   15665 	 */
   15666 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   15667 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   15668 		zone->notifyfrom = *from;
   15669 		UNLOCK_ZONE(zone);
   15670 		if (have_serial) {
   15671 			dns_zone_log(zone, ISC_LOG_INFO,
   15672 				     "notify from %s: serial %u: refresh in "
   15673 				     "progress, refresh check queued",
   15674 				     fromtext, serial);
   15675 		} else {
   15676 			dns_zone_log(zone, ISC_LOG_INFO,
   15677 				     "notify from %s: refresh in progress, "
   15678 				     "refresh check queued",
   15679 				     fromtext);
   15680 		}
   15681 		return (ISC_R_SUCCESS);
   15682 	}
   15683 	if (have_serial) {
   15684 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
   15685 			     fromtext, serial);
   15686 	} else {
   15687 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
   15688 			     fromtext);
   15689 	}
   15690 	zone->notifyfrom = *from;
   15691 	UNLOCK_ZONE(zone);
   15692 
   15693 	if (to != NULL) {
   15694 		dns_zonemgr_unreachabledel(zone->zmgr, from, to);
   15695 	}
   15696 	dns_zone_refresh(zone);
   15697 	return (ISC_R_SUCCESS);
   15698 }
   15699 
   15700 void
   15701 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
   15702 	REQUIRE(DNS_ZONE_VALID(zone));
   15703 
   15704 	LOCK_ZONE(zone);
   15705 	if (zone->notify_acl != NULL) {
   15706 		dns_acl_detach(&zone->notify_acl);
   15707 	}
   15708 	dns_acl_attach(acl, &zone->notify_acl);
   15709 	UNLOCK_ZONE(zone);
   15710 }
   15711 
   15712 void
   15713 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
   15714 	REQUIRE(DNS_ZONE_VALID(zone));
   15715 
   15716 	LOCK_ZONE(zone);
   15717 	if (zone->query_acl != NULL) {
   15718 		dns_acl_detach(&zone->query_acl);
   15719 	}
   15720 	dns_acl_attach(acl, &zone->query_acl);
   15721 	UNLOCK_ZONE(zone);
   15722 }
   15723 
   15724 void
   15725 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
   15726 	REQUIRE(DNS_ZONE_VALID(zone));
   15727 
   15728 	LOCK_ZONE(zone);
   15729 	if (zone->queryon_acl != NULL) {
   15730 		dns_acl_detach(&zone->queryon_acl);
   15731 	}
   15732 	dns_acl_attach(acl, &zone->queryon_acl);
   15733 	UNLOCK_ZONE(zone);
   15734 }
   15735 
   15736 void
   15737 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
   15738 	REQUIRE(DNS_ZONE_VALID(zone));
   15739 
   15740 	LOCK_ZONE(zone);
   15741 	if (zone->update_acl != NULL) {
   15742 		dns_acl_detach(&zone->update_acl);
   15743 	}
   15744 	dns_acl_attach(acl, &zone->update_acl);
   15745 	UNLOCK_ZONE(zone);
   15746 }
   15747 
   15748 void
   15749 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
   15750 	REQUIRE(DNS_ZONE_VALID(zone));
   15751 
   15752 	LOCK_ZONE(zone);
   15753 	if (zone->forward_acl != NULL) {
   15754 		dns_acl_detach(&zone->forward_acl);
   15755 	}
   15756 	dns_acl_attach(acl, &zone->forward_acl);
   15757 	UNLOCK_ZONE(zone);
   15758 }
   15759 
   15760 void
   15761 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
   15762 	REQUIRE(DNS_ZONE_VALID(zone));
   15763 
   15764 	LOCK_ZONE(zone);
   15765 	if (zone->xfr_acl != NULL) {
   15766 		dns_acl_detach(&zone->xfr_acl);
   15767 	}
   15768 	dns_acl_attach(acl, &zone->xfr_acl);
   15769 	UNLOCK_ZONE(zone);
   15770 }
   15771 
   15772 dns_acl_t *
   15773 dns_zone_getnotifyacl(dns_zone_t *zone) {
   15774 	REQUIRE(DNS_ZONE_VALID(zone));
   15775 
   15776 	return (zone->notify_acl);
   15777 }
   15778 
   15779 dns_acl_t *
   15780 dns_zone_getqueryacl(dns_zone_t *zone) {
   15781 	REQUIRE(DNS_ZONE_VALID(zone));
   15782 
   15783 	return (zone->query_acl);
   15784 }
   15785 
   15786 dns_acl_t *
   15787 dns_zone_getqueryonacl(dns_zone_t *zone) {
   15788 	REQUIRE(DNS_ZONE_VALID(zone));
   15789 
   15790 	return (zone->queryon_acl);
   15791 }
   15792 
   15793 dns_acl_t *
   15794 dns_zone_getupdateacl(dns_zone_t *zone) {
   15795 	REQUIRE(DNS_ZONE_VALID(zone));
   15796 
   15797 	return (zone->update_acl);
   15798 }
   15799 
   15800 dns_acl_t *
   15801 dns_zone_getforwardacl(dns_zone_t *zone) {
   15802 	REQUIRE(DNS_ZONE_VALID(zone));
   15803 
   15804 	return (zone->forward_acl);
   15805 }
   15806 
   15807 dns_acl_t *
   15808 dns_zone_getxfracl(dns_zone_t *zone) {
   15809 	REQUIRE(DNS_ZONE_VALID(zone));
   15810 
   15811 	return (zone->xfr_acl);
   15812 }
   15813 
   15814 void
   15815 dns_zone_clearupdateacl(dns_zone_t *zone) {
   15816 	REQUIRE(DNS_ZONE_VALID(zone));
   15817 
   15818 	LOCK_ZONE(zone);
   15819 	if (zone->update_acl != NULL) {
   15820 		dns_acl_detach(&zone->update_acl);
   15821 	}
   15822 	UNLOCK_ZONE(zone);
   15823 }
   15824 
   15825 void
   15826 dns_zone_clearforwardacl(dns_zone_t *zone) {
   15827 	REQUIRE(DNS_ZONE_VALID(zone));
   15828 
   15829 	LOCK_ZONE(zone);
   15830 	if (zone->forward_acl != NULL) {
   15831 		dns_acl_detach(&zone->forward_acl);
   15832 	}
   15833 	UNLOCK_ZONE(zone);
   15834 }
   15835 
   15836 void
   15837 dns_zone_clearnotifyacl(dns_zone_t *zone) {
   15838 	REQUIRE(DNS_ZONE_VALID(zone));
   15839 
   15840 	LOCK_ZONE(zone);
   15841 	if (zone->notify_acl != NULL) {
   15842 		dns_acl_detach(&zone->notify_acl);
   15843 	}
   15844 	UNLOCK_ZONE(zone);
   15845 }
   15846 
   15847 void
   15848 dns_zone_clearqueryacl(dns_zone_t *zone) {
   15849 	REQUIRE(DNS_ZONE_VALID(zone));
   15850 
   15851 	LOCK_ZONE(zone);
   15852 	if (zone->query_acl != NULL) {
   15853 		dns_acl_detach(&zone->query_acl);
   15854 	}
   15855 	UNLOCK_ZONE(zone);
   15856 }
   15857 
   15858 void
   15859 dns_zone_clearqueryonacl(dns_zone_t *zone) {
   15860 	REQUIRE(DNS_ZONE_VALID(zone));
   15861 
   15862 	LOCK_ZONE(zone);
   15863 	if (zone->queryon_acl != NULL) {
   15864 		dns_acl_detach(&zone->queryon_acl);
   15865 	}
   15866 	UNLOCK_ZONE(zone);
   15867 }
   15868 
   15869 void
   15870 dns_zone_clearxfracl(dns_zone_t *zone) {
   15871 	REQUIRE(DNS_ZONE_VALID(zone));
   15872 
   15873 	LOCK_ZONE(zone);
   15874 	if (zone->xfr_acl != NULL) {
   15875 		dns_acl_detach(&zone->xfr_acl);
   15876 	}
   15877 	UNLOCK_ZONE(zone);
   15878 }
   15879 
   15880 bool
   15881 dns_zone_getupdatedisabled(dns_zone_t *zone) {
   15882 	REQUIRE(DNS_ZONE_VALID(zone));
   15883 	return (zone->update_disabled);
   15884 }
   15885 
   15886 void
   15887 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
   15888 	REQUIRE(DNS_ZONE_VALID(zone));
   15889 	zone->update_disabled = state;
   15890 }
   15891 
   15892 bool
   15893 dns_zone_getzeronosoattl(dns_zone_t *zone) {
   15894 	REQUIRE(DNS_ZONE_VALID(zone));
   15895 	return (zone->zero_no_soa_ttl);
   15896 }
   15897 
   15898 void
   15899 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
   15900 	REQUIRE(DNS_ZONE_VALID(zone));
   15901 	zone->zero_no_soa_ttl = state;
   15902 }
   15903 
   15904 void
   15905 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
   15906 	REQUIRE(DNS_ZONE_VALID(zone));
   15907 
   15908 	zone->check_names = severity;
   15909 }
   15910 
   15911 dns_severity_t
   15912 dns_zone_getchecknames(dns_zone_t *zone) {
   15913 	REQUIRE(DNS_ZONE_VALID(zone));
   15914 
   15915 	return (zone->check_names);
   15916 }
   15917 
   15918 void
   15919 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
   15920 	REQUIRE(DNS_ZONE_VALID(zone));
   15921 
   15922 	zone->journalsize = size;
   15923 }
   15924 
   15925 int32_t
   15926 dns_zone_getjournalsize(dns_zone_t *zone) {
   15927 	REQUIRE(DNS_ZONE_VALID(zone));
   15928 
   15929 	return (zone->journalsize);
   15930 }
   15931 
   15932 static void
   15933 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15934 	isc_result_t result = ISC_R_FAILURE;
   15935 	isc_buffer_t buffer;
   15936 
   15937 	REQUIRE(buf != NULL);
   15938 	REQUIRE(length > 1U);
   15939 
   15940 	/*
   15941 	 * Leave space for terminating '\0'.
   15942 	 */
   15943 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15944 	if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
   15945 		if (dns_name_dynamic(&zone->origin)) {
   15946 			result = dns_name_totext(&zone->origin, true, &buffer);
   15947 		}
   15948 		if (result != ISC_R_SUCCESS &&
   15949 		    isc_buffer_availablelength(&buffer) >=
   15950 			    (sizeof("<UNKNOWN>") - 1))
   15951 		{
   15952 			isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15953 		}
   15954 
   15955 		if (isc_buffer_availablelength(&buffer) > 0) {
   15956 			isc_buffer_putstr(&buffer, "/");
   15957 		}
   15958 		(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   15959 	}
   15960 
   15961 	if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
   15962 	    strcmp(zone->view->name, "_default") != 0 &&
   15963 	    strlen(zone->view->name) < isc_buffer_availablelength(&buffer))
   15964 	{
   15965 		isc_buffer_putstr(&buffer, "/");
   15966 		isc_buffer_putstr(&buffer, zone->view->name);
   15967 	}
   15968 	if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) {
   15969 		isc_buffer_putstr(&buffer, " (signed)");
   15970 	}
   15971 	if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) {
   15972 		isc_buffer_putstr(&buffer, " (unsigned)");
   15973 	}
   15974 
   15975 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15976 }
   15977 
   15978 static void
   15979 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15980 	isc_result_t result = ISC_R_FAILURE;
   15981 	isc_buffer_t buffer;
   15982 
   15983 	REQUIRE(buf != NULL);
   15984 	REQUIRE(length > 1U);
   15985 
   15986 	/*
   15987 	 * Leave space for terminating '\0'.
   15988 	 */
   15989 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15990 	if (dns_name_dynamic(&zone->origin)) {
   15991 		result = dns_name_totext(&zone->origin, true, &buffer);
   15992 	}
   15993 	if (result != ISC_R_SUCCESS &&
   15994 	    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
   15995 	{
   15996 		isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15997 	}
   15998 
   15999 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   16000 }
   16001 
   16002 static void
   16003 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
   16004 	isc_buffer_t buffer;
   16005 
   16006 	REQUIRE(buf != NULL);
   16007 	REQUIRE(length > 1U);
   16008 
   16009 	/*
   16010 	 * Leave space for terminating '\0'.
   16011 	 */
   16012 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   16013 	(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   16014 
   16015 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   16016 }
   16017 
   16018 static void
   16019 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
   16020 	isc_buffer_t buffer;
   16021 
   16022 	REQUIRE(buf != NULL);
   16023 	REQUIRE(length > 1U);
   16024 
   16025 	/*
   16026 	 * Leave space for terminating '\0'.
   16027 	 */
   16028 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   16029 
   16030 	if (zone->view == NULL) {
   16031 		isc_buffer_putstr(&buffer, "_none");
   16032 	} else if (strlen(zone->view->name) <
   16033 		   isc_buffer_availablelength(&buffer))
   16034 	{
   16035 		isc_buffer_putstr(&buffer, zone->view->name);
   16036 	} else {
   16037 		isc_buffer_putstr(&buffer, "_toolong");
   16038 	}
   16039 
   16040 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   16041 }
   16042 
   16043 void
   16044 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
   16045 	REQUIRE(DNS_ZONE_VALID(zone));
   16046 	REQUIRE(buf != NULL);
   16047 
   16048 	LOCK_ZONE(zone);
   16049 	zone_namerd_tostr(zone, buf, length);
   16050 	UNLOCK_ZONE(zone);
   16051 }
   16052 
   16053 void
   16054 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
   16055 	REQUIRE(DNS_ZONE_VALID(zone));
   16056 	REQUIRE(buf != NULL);
   16057 	zone_name_tostr(zone, buf, length);
   16058 }
   16059 
   16060 void
   16061 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level,
   16062 	      const char *prefix, const char *fmt, va_list ap) {
   16063 	char message[4096];
   16064 	const char *zstr;
   16065 
   16066 	REQUIRE(DNS_ZONE_VALID(zone));
   16067 
   16068 	if (!isc_log_wouldlog(dns_lctx, level)) {
   16069 		return;
   16070 	}
   16071 
   16072 	vsnprintf(message, sizeof(message), fmt, ap);
   16073 
   16074 	switch (zone->type) {
   16075 	case dns_zone_key:
   16076 		zstr = "managed-keys-zone";
   16077 		break;
   16078 	case dns_zone_redirect:
   16079 		zstr = "redirect-zone";
   16080 		break;
   16081 	default:
   16082 		zstr = "zone ";
   16083 	}
   16084 
   16085 	isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level,
   16086 		      "%s%s%s%s: %s", (prefix != NULL ? prefix : ""),
   16087 		      (prefix != NULL ? ": " : ""), zstr, zone->strnamerd,
   16088 		      message);
   16089 }
   16090 
   16091 static void
   16092 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   16093 	va_list ap;
   16094 
   16095 	va_start(ap, fmt);
   16096 	dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap);
   16097 	va_end(ap);
   16098 }
   16099 
   16100 void
   16101 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level,
   16102 	      const char *fmt, ...) {
   16103 	va_list ap;
   16104 
   16105 	va_start(ap, fmt);
   16106 	dns_zone_logv(zone, category, level, NULL, fmt, ap);
   16107 	va_end(ap);
   16108 }
   16109 
   16110 void
   16111 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   16112 	va_list ap;
   16113 
   16114 	va_start(ap, fmt);
   16115 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap);
   16116 	va_end(ap);
   16117 }
   16118 
   16119 static void
   16120 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt,
   16121 	      ...) {
   16122 	int level = ISC_LOG_DEBUG(debuglevel);
   16123 	va_list ap;
   16124 
   16125 	va_start(ap, fmt);
   16126 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap);
   16127 	va_end(ap);
   16128 }
   16129 
   16130 static void
   16131 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   16132 	va_list ap;
   16133 
   16134 	va_start(ap, fmt);
   16135 	dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap);
   16136 	va_end(ap);
   16137 }
   16138 
   16139 static int
   16140 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) {
   16141 	isc_result_t result;
   16142 	dns_name_t *name;
   16143 	dns_rdataset_t *curr;
   16144 	int count = 0;
   16145 
   16146 	result = dns_message_firstname(msg, section);
   16147 	while (result == ISC_R_SUCCESS) {
   16148 		name = NULL;
   16149 		dns_message_currentname(msg, section, &name);
   16150 
   16151 		for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
   16152 		     curr = ISC_LIST_PREV(curr, link))
   16153 		{
   16154 			if (curr->type == type) {
   16155 				count++;
   16156 			}
   16157 		}
   16158 		result = dns_message_nextname(msg, section);
   16159 	}
   16160 
   16161 	return (count);
   16162 }
   16163 
   16164 void
   16165 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
   16166 	REQUIRE(DNS_ZONE_VALID(zone));
   16167 
   16168 	zone->maxxfrin = maxxfrin;
   16169 }
   16170 
   16171 uint32_t
   16172 dns_zone_getmaxxfrin(dns_zone_t *zone) {
   16173 	REQUIRE(DNS_ZONE_VALID(zone));
   16174 
   16175 	return (zone->maxxfrin);
   16176 }
   16177 
   16178 void
   16179 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
   16180 	REQUIRE(DNS_ZONE_VALID(zone));
   16181 	zone->maxxfrout = maxxfrout;
   16182 }
   16183 
   16184 uint32_t
   16185 dns_zone_getmaxxfrout(dns_zone_t *zone) {
   16186 	REQUIRE(DNS_ZONE_VALID(zone));
   16187 
   16188 	return (zone->maxxfrout);
   16189 }
   16190 
   16191 dns_zonetype_t
   16192 dns_zone_gettype(dns_zone_t *zone) {
   16193 	REQUIRE(DNS_ZONE_VALID(zone));
   16194 
   16195 	return (zone->type);
   16196 }
   16197 
   16198 const char *
   16199 dns_zonetype_name(dns_zonetype_t type) {
   16200 	switch (type) {
   16201 	case dns_zone_none:
   16202 		return ("none");
   16203 	case dns_zone_primary:
   16204 		return ("primary");
   16205 	case dns_zone_secondary:
   16206 		return ("secondary");
   16207 	case dns_zone_mirror:
   16208 		return ("mirror");
   16209 	case dns_zone_stub:
   16210 		return ("stub");
   16211 	case dns_zone_staticstub:
   16212 		return ("static-stub");
   16213 	case dns_zone_key:
   16214 		return ("key");
   16215 	case dns_zone_dlz:
   16216 		return ("dlz");
   16217 	case dns_zone_redirect:
   16218 		return ("redirect");
   16219 	default:
   16220 		return ("unknown");
   16221 	}
   16222 }
   16223 
   16224 dns_zonetype_t
   16225 dns_zone_getredirecttype(dns_zone_t *zone) {
   16226 	REQUIRE(DNS_ZONE_VALID(zone));
   16227 	REQUIRE(zone->type == dns_zone_redirect);
   16228 
   16229 	return (zone->primaries == NULL ? dns_zone_primary
   16230 					: dns_zone_secondary);
   16231 }
   16232 
   16233 dns_name_t *
   16234 dns_zone_getorigin(dns_zone_t *zone) {
   16235 	REQUIRE(DNS_ZONE_VALID(zone));
   16236 
   16237 	return (&zone->origin);
   16238 }
   16239 
   16240 void
   16241 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
   16242 	REQUIRE(DNS_ZONE_VALID(zone));
   16243 
   16244 	LOCK_ZONE(zone);
   16245 	if (zone->task != NULL) {
   16246 		isc_task_detach(&zone->task);
   16247 	}
   16248 	isc_task_attach(task, &zone->task);
   16249 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16250 	if (zone->db != NULL) {
   16251 		dns_db_settask(zone->db, zone->task);
   16252 	}
   16253 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16254 	UNLOCK_ZONE(zone);
   16255 }
   16256 
   16257 void
   16258 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
   16259 	REQUIRE(DNS_ZONE_VALID(zone));
   16260 	isc_task_attach(zone->task, target);
   16261 }
   16262 
   16263 void
   16264 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
   16265 	REQUIRE(DNS_ZONE_VALID(zone));
   16266 
   16267 	if (idlein == 0) {
   16268 		idlein = DNS_DEFAULT_IDLEIN;
   16269 	}
   16270 	zone->idlein = idlein;
   16271 }
   16272 
   16273 uint32_t
   16274 dns_zone_getidlein(dns_zone_t *zone) {
   16275 	REQUIRE(DNS_ZONE_VALID(zone));
   16276 
   16277 	return (zone->idlein);
   16278 }
   16279 
   16280 void
   16281 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
   16282 	REQUIRE(DNS_ZONE_VALID(zone));
   16283 
   16284 	zone->idleout = idleout;
   16285 }
   16286 
   16287 uint32_t
   16288 dns_zone_getidleout(dns_zone_t *zone) {
   16289 	REQUIRE(DNS_ZONE_VALID(zone));
   16290 
   16291 	return (zone->idleout);
   16292 }
   16293 
   16294 static void
   16295 notify_done(isc_task_t *task, isc_event_t *event) {
   16296 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   16297 	dns_notify_t *notify;
   16298 	isc_result_t result;
   16299 	dns_message_t *message = NULL;
   16300 	isc_buffer_t buf;
   16301 	char rcode[128];
   16302 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   16303 
   16304 	UNUSED(task);
   16305 
   16306 	notify = event->ev_arg;
   16307 	REQUIRE(DNS_NOTIFY_VALID(notify));
   16308 	INSIST(task == notify->zone->task);
   16309 
   16310 	isc_buffer_init(&buf, rcode, sizeof(rcode));
   16311 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   16312 	dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE,
   16313 			   &message);
   16314 
   16315 	if (revent->result != ISC_R_SUCCESS) {
   16316 		result = revent->result;
   16317 		goto fail;
   16318 	}
   16319 
   16320 	result = dns_request_getresponse(revent->request, message,
   16321 					 DNS_MESSAGEPARSE_PRESERVEORDER);
   16322 	if (result != ISC_R_SUCCESS) {
   16323 		goto fail;
   16324 	}
   16325 
   16326 	result = dns_rcode_totext(message->rcode, &buf);
   16327 	if (result == ISC_R_SUCCESS) {
   16328 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   16329 			   "notify response from %s: %.*s", addrbuf,
   16330 			   (int)buf.used, rcode);
   16331 	}
   16332 
   16333 	goto done;
   16334 
   16335 fail:
   16336 	notify_log(notify->zone, ISC_LOG_DEBUG(2), "notify to %s failed: %s",
   16337 		   addrbuf, isc_result_totext(result));
   16338 	if (result == ISC_R_TIMEDOUT) {
   16339 		notify_log(notify->zone, ISC_LOG_DEBUG(1),
   16340 			   "notify to %s: retries exceeded", addrbuf);
   16341 	}
   16342 done:
   16343 	notify_destroy(notify, false);
   16344 	isc_event_free(&event);
   16345 	dns_message_detach(&message);
   16346 }
   16347 
   16348 struct secure_event {
   16349 	isc_event_t e;
   16350 	dns_db_t *db;
   16351 	uint32_t serial;
   16352 };
   16353 
   16354 static void
   16355 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
   16356 	UNUSED(arg);
   16357 	dns_zone_log(zone, level, "%s", message);
   16358 }
   16359 
   16360 static isc_result_t
   16361 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
   16362 		    uint32_t start, uint32_t end, dns_difftuple_t **soatuplep,
   16363 		    dns_diff_t *diff) {
   16364 	isc_result_t result;
   16365 	dns_difftuple_t *tuple = NULL;
   16366 	dns_diffop_t op = DNS_DIFFOP_ADD;
   16367 	int n_soa = 0;
   16368 
   16369 	REQUIRE(soatuplep != NULL);
   16370 
   16371 	if (start == end) {
   16372 		return (DNS_R_UNCHANGED);
   16373 	}
   16374 
   16375 	CHECK(dns_journal_iter_init(journal, start, end, NULL));
   16376 	for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS;
   16377 	     result = dns_journal_next_rr(journal))
   16378 	{
   16379 		dns_name_t *name = NULL;
   16380 		uint32_t ttl;
   16381 		dns_rdata_t *rdata = NULL;
   16382 		dns_journal_current_rr(journal, &name, &ttl, &rdata);
   16383 
   16384 		if (rdata->type == dns_rdatatype_soa) {
   16385 			n_soa++;
   16386 			if (n_soa == 2) {
   16387 				/*
   16388 				 * Save the latest raw SOA record.
   16389 				 */
   16390 				if (*soatuplep != NULL) {
   16391 					dns_difftuple_free(soatuplep);
   16392 				}
   16393 				CHECK(dns_difftuple_create(
   16394 					diff->mctx, DNS_DIFFOP_ADD, name, ttl,
   16395 					rdata, soatuplep));
   16396 			}
   16397 			if (n_soa == 3) {
   16398 				n_soa = 1;
   16399 			}
   16400 			continue;
   16401 		}
   16402 
   16403 		/* Sanity. */
   16404 		if (n_soa == 0) {
   16405 			dns_zone_log(raw, ISC_LOG_ERROR,
   16406 				     "corrupt journal file: '%s'\n",
   16407 				     raw->journal);
   16408 			return (ISC_R_FAILURE);
   16409 		}
   16410 
   16411 		if (zone->privatetype != 0 && rdata->type == zone->privatetype)
   16412 		{
   16413 			continue;
   16414 		}
   16415 
   16416 		if (rdata->type == dns_rdatatype_nsec ||
   16417 		    rdata->type == dns_rdatatype_rrsig ||
   16418 		    rdata->type == dns_rdatatype_nsec3 ||
   16419 		    rdata->type == dns_rdatatype_dnskey ||
   16420 		    rdata->type == dns_rdatatype_nsec3param)
   16421 		{
   16422 			continue;
   16423 		}
   16424 
   16425 		op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
   16426 
   16427 		CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
   16428 					   &tuple));
   16429 		dns_diff_appendminimal(diff, &tuple);
   16430 	}
   16431 	if (result == ISC_R_NOMORE) {
   16432 		result = ISC_R_SUCCESS;
   16433 	}
   16434 
   16435 failure:
   16436 	return (result);
   16437 }
   16438 
   16439 static isc_result_t
   16440 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
   16441 	       dns_dbversion_t *secver, dns_difftuple_t **soatuple,
   16442 	       dns_diff_t *diff) {
   16443 	isc_result_t result;
   16444 	dns_db_t *rawdb = NULL;
   16445 	dns_dbversion_t *rawver = NULL;
   16446 	dns_difftuple_t *tuple = NULL, *next;
   16447 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   16448 	dns_rdata_soa_t oldsoa, newsoa;
   16449 
   16450 	REQUIRE(DNS_ZONE_VALID(seczone));
   16451 	REQUIRE(soatuple != NULL && *soatuple == NULL);
   16452 
   16453 	if (!seczone->sourceserialset) {
   16454 		return (DNS_R_UNCHANGED);
   16455 	}
   16456 
   16457 	dns_db_attach(raw->db, &rawdb);
   16458 	dns_db_currentversion(rawdb, &rawver);
   16459 	result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
   16460 	dns_db_closeversion(rawdb, &rawver, false);
   16461 	dns_db_detach(&rawdb);
   16462 
   16463 	if (result != ISC_R_SUCCESS) {
   16464 		return (result);
   16465 	}
   16466 
   16467 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) {
   16468 		next = ISC_LIST_NEXT(tuple, link);
   16469 		if (tuple->rdata.type == dns_rdatatype_nsec ||
   16470 		    tuple->rdata.type == dns_rdatatype_rrsig ||
   16471 		    tuple->rdata.type == dns_rdatatype_dnskey ||
   16472 		    tuple->rdata.type == dns_rdatatype_nsec3 ||
   16473 		    tuple->rdata.type == dns_rdatatype_nsec3param)
   16474 		{
   16475 			ISC_LIST_UNLINK(diff->tuples, tuple, link);
   16476 			dns_difftuple_free(&tuple);
   16477 			continue;
   16478 		}
   16479 		if (tuple->rdata.type == dns_rdatatype_soa) {
   16480 			if (tuple->op == DNS_DIFFOP_DEL) {
   16481 				INSIST(oldtuple == NULL);
   16482 				oldtuple = tuple;
   16483 			}
   16484 			if (tuple->op == DNS_DIFFOP_ADD) {
   16485 				INSIST(newtuple == NULL);
   16486 				newtuple = tuple;
   16487 			}
   16488 		}
   16489 	}
   16490 
   16491 	if (oldtuple != NULL && newtuple != NULL) {
   16492 		result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
   16493 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16494 
   16495 		result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
   16496 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16497 
   16498 		/*
   16499 		 * If the SOA records are the same except for the serial
   16500 		 * remove them from the diff.
   16501 		 */
   16502 		if (oldtuple->ttl == newtuple->ttl &&
   16503 		    oldsoa.refresh == newsoa.refresh &&
   16504 		    oldsoa.retry == newsoa.retry &&
   16505 		    oldsoa.minimum == newsoa.minimum &&
   16506 		    oldsoa.expire == newsoa.expire &&
   16507 		    dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
   16508 		    dns_name_equal(&oldsoa.contact, &newsoa.contact))
   16509 		{
   16510 			ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   16511 			dns_difftuple_free(&oldtuple);
   16512 			ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   16513 			dns_difftuple_free(&newtuple);
   16514 		}
   16515 	}
   16516 
   16517 	if (ISC_LIST_EMPTY(diff->tuples)) {
   16518 		return (DNS_R_UNCHANGED);
   16519 	}
   16520 
   16521 	/*
   16522 	 * If there are still SOA records in the diff they can now be removed
   16523 	 * saving the new SOA record.
   16524 	 */
   16525 	if (oldtuple != NULL) {
   16526 		ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   16527 		dns_difftuple_free(&oldtuple);
   16528 	}
   16529 
   16530 	if (newtuple != NULL) {
   16531 		ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   16532 		*soatuple = newtuple;
   16533 	}
   16534 
   16535 	return (ISC_R_SUCCESS);
   16536 }
   16537 
   16538 static void
   16539 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
   16540 	static char me[] = "receive_secure_serial";
   16541 	isc_result_t result = ISC_R_SUCCESS;
   16542 	dns_journal_t *rjournal = NULL;
   16543 	dns_journal_t *sjournal = NULL;
   16544 	uint32_t start, end;
   16545 	dns_zone_t *zone;
   16546 	dns_difftuple_t *tuple = NULL, *soatuple = NULL;
   16547 	dns_update_log_t log = { update_log_cb, NULL };
   16548 	uint32_t newserial = 0, desired = 0;
   16549 	isc_time_t timenow;
   16550 	int level = ISC_LOG_ERROR;
   16551 
   16552 	UNUSED(task);
   16553 
   16554 	zone = event->ev_arg;
   16555 	end = ((struct secure_event *)event)->serial;
   16556 
   16557 	ENTER;
   16558 
   16559 	LOCK_ZONE(zone);
   16560 
   16561 	/*
   16562 	 * If we are already processing a receive secure serial event
   16563 	 * for the zone, just queue the new one and exit.
   16564 	 */
   16565 	if (zone->rss_event != NULL && zone->rss_event != event) {
   16566 		ISC_LIST_APPEND(zone->rss_events, event, ev_link);
   16567 		UNLOCK_ZONE(zone);
   16568 		return;
   16569 	}
   16570 
   16571 nextevent:
   16572 	if (zone->rss_event != NULL) {
   16573 		INSIST(zone->rss_event == event);
   16574 		UNLOCK_ZONE(zone);
   16575 	} else {
   16576 		zone->rss_event = event;
   16577 		dns_diff_init(zone->mctx, &zone->rss_diff);
   16578 
   16579 		/*
   16580 		 * zone->db may be NULL, if the load from disk failed.
   16581 		 */
   16582 		result = ISC_R_SUCCESS;
   16583 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16584 		if (zone->db != NULL) {
   16585 			dns_db_attach(zone->db, &zone->rss_db);
   16586 		} else {
   16587 			result = ISC_R_FAILURE;
   16588 		}
   16589 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16590 
   16591 		if (result == ISC_R_SUCCESS && zone->raw != NULL) {
   16592 			dns_zone_attach(zone->raw, &zone->rss_raw);
   16593 		} else {
   16594 			result = ISC_R_FAILURE;
   16595 		}
   16596 
   16597 		UNLOCK_ZONE(zone);
   16598 
   16599 		CHECK(result);
   16600 
   16601 		/*
   16602 		 * We first attempt to sync the raw zone to the secure zone
   16603 		 * by using the raw zone's journal, applying all the deltas
   16604 		 * from the latest source-serial of the secure zone up to
   16605 		 * the current serial number of the raw zone.
   16606 		 *
   16607 		 * If that fails, then we'll fall back to a direct comparison
   16608 		 * between raw and secure zones.
   16609 		 */
   16610 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16611 				       zone->rss_raw->journal,
   16612 				       DNS_JOURNAL_WRITE, &rjournal));
   16613 
   16614 		result = dns_journal_open(zone->mctx, zone->journal,
   16615 					  DNS_JOURNAL_READ, &sjournal);
   16616 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   16617 			goto failure;
   16618 		}
   16619 
   16620 		if (!dns_journal_get_sourceserial(rjournal, &start)) {
   16621 			start = dns_journal_first_serial(rjournal);
   16622 			dns_journal_set_sourceserial(rjournal, start);
   16623 		}
   16624 		if (sjournal != NULL) {
   16625 			uint32_t serial;
   16626 			/*
   16627 			 * We read the secure journal first, if that
   16628 			 * exists use its value provided it is greater
   16629 			 * that from the raw journal.
   16630 			 */
   16631 			if (dns_journal_get_sourceserial(sjournal, &serial)) {
   16632 				if (isc_serial_gt(serial, start)) {
   16633 					start = serial;
   16634 				}
   16635 			}
   16636 			dns_journal_destroy(&sjournal);
   16637 		}
   16638 
   16639 		dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
   16640 		CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
   16641 
   16642 		/*
   16643 		 * Try to apply diffs from the raw zone's journal to the secure
   16644 		 * zone.  If that fails, we recover by syncing up the databases
   16645 		 * directly.
   16646 		 */
   16647 		result = sync_secure_journal(zone, zone->rss_raw, rjournal,
   16648 					     start, end, &soatuple,
   16649 					     &zone->rss_diff);
   16650 		if (result == DNS_R_UNCHANGED) {
   16651 			goto failure;
   16652 		} else if (result != ISC_R_SUCCESS) {
   16653 			CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
   16654 					     zone->rss_oldver, &soatuple,
   16655 					     &zone->rss_diff));
   16656 		}
   16657 
   16658 		CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
   16659 				     zone->rss_newver));
   16660 
   16661 		if (soatuple != NULL) {
   16662 			uint32_t oldserial;
   16663 
   16664 			CHECK(dns_db_createsoatuple(
   16665 				zone->rss_db, zone->rss_oldver,
   16666 				zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple));
   16667 			oldserial = dns_soa_getserial(&tuple->rdata);
   16668 			newserial = desired =
   16669 				dns_soa_getserial(&soatuple->rdata);
   16670 			if (!isc_serial_gt(newserial, oldserial)) {
   16671 				newserial = oldserial + 1;
   16672 				if (newserial == 0) {
   16673 					newserial++;
   16674 				}
   16675 				dns_soa_setserial(newserial, &soatuple->rdata);
   16676 			}
   16677 			CHECK(do_one_tuple(&tuple, zone->rss_db,
   16678 					   zone->rss_newver, &zone->rss_diff));
   16679 			CHECK(do_one_tuple(&soatuple, zone->rss_db,
   16680 					   zone->rss_newver, &zone->rss_diff));
   16681 		} else {
   16682 			CHECK(update_soa_serial(zone, zone->rss_db,
   16683 						zone->rss_newver,
   16684 						&zone->rss_diff, zone->mctx,
   16685 						zone->updatemethod));
   16686 		}
   16687 	}
   16688 	result = dns_update_signaturesinc(
   16689 		&log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver,
   16690 		&zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state);
   16691 	if (result == DNS_R_CONTINUE) {
   16692 		if (rjournal != NULL) {
   16693 			dns_journal_destroy(&rjournal);
   16694 		}
   16695 		isc_task_send(task, &event);
   16696 		return;
   16697 	}
   16698 	/*
   16699 	 * If something went wrong while trying to update the secure zone and
   16700 	 * the latter was already signed before, do not apply raw zone deltas
   16701 	 * to it as that would break existing DNSSEC signatures.  However, if
   16702 	 * the secure zone was not yet signed (e.g. because no signing keys
   16703 	 * were created for it), commence applying raw zone deltas to it so
   16704 	 * that contents of the raw zone and the secure zone are kept in sync.
   16705 	 */
   16706 	if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
   16707 		goto failure;
   16708 	}
   16709 
   16710 	if (rjournal == NULL) {
   16711 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16712 				       zone->rss_raw->journal,
   16713 				       DNS_JOURNAL_WRITE, &rjournal));
   16714 	}
   16715 	CHECK(zone_journal(zone, &zone->rss_diff, &end,
   16716 			   "receive_secure_serial"));
   16717 
   16718 	dns_journal_set_sourceserial(rjournal, end);
   16719 	dns_journal_commit(rjournal);
   16720 
   16721 	LOCK_ZONE(zone);
   16722 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   16723 
   16724 	zone->sourceserial = end;
   16725 	zone->sourceserialset = true;
   16726 	zone_needdump(zone, DNS_DUMP_DELAY);
   16727 
   16728 	/*
   16729 	 * Set resign time to make sure it is set to the earliest
   16730 	 * signature expiration.
   16731 	 */
   16732 	set_resigntime(zone);
   16733 	TIME_NOW(&timenow);
   16734 	zone_settimer(zone, &timenow);
   16735 	UNLOCK_ZONE(zone);
   16736 
   16737 	dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false);
   16738 	dns_db_closeversion(zone->rss_db, &zone->rss_newver, true);
   16739 
   16740 	if (newserial != 0) {
   16741 		dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
   16742 			     newserial, desired);
   16743 	}
   16744 
   16745 failure:
   16746 	isc_event_free(&zone->rss_event);
   16747 	event = ISC_LIST_HEAD(zone->rss_events);
   16748 
   16749 	if (zone->rss_raw != NULL) {
   16750 		dns_zone_detach(&zone->rss_raw);
   16751 	}
   16752 	if (result != ISC_R_SUCCESS) {
   16753 		LOCK_ZONE(zone);
   16754 		set_resigntime(zone);
   16755 		TIME_NOW(&timenow);
   16756 		zone_settimer(zone, &timenow);
   16757 		UNLOCK_ZONE(zone);
   16758 		if (result == DNS_R_UNCHANGED) {
   16759 			level = ISC_LOG_INFO;
   16760 		}
   16761 		dns_zone_log(zone, level, "receive_secure_serial: %s",
   16762 			     isc_result_totext(result));
   16763 	}
   16764 	if (tuple != NULL) {
   16765 		dns_difftuple_free(&tuple);
   16766 	}
   16767 	if (soatuple != NULL) {
   16768 		dns_difftuple_free(&soatuple);
   16769 	}
   16770 	if (zone->rss_db != NULL) {
   16771 		if (zone->rss_oldver != NULL) {
   16772 			dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
   16773 					    false);
   16774 		}
   16775 		if (zone->rss_newver != NULL) {
   16776 			dns_db_closeversion(zone->rss_db, &zone->rss_newver,
   16777 					    false);
   16778 		}
   16779 		dns_db_detach(&zone->rss_db);
   16780 	}
   16781 	INSIST(zone->rss_oldver == NULL);
   16782 	INSIST(zone->rss_newver == NULL);
   16783 	if (rjournal != NULL) {
   16784 		dns_journal_destroy(&rjournal);
   16785 	}
   16786 	dns_diff_clear(&zone->rss_diff);
   16787 
   16788 	if (event != NULL) {
   16789 		LOCK_ZONE(zone);
   16790 		isc_refcount_decrement(&zone->irefs);
   16791 		ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
   16792 		goto nextevent;
   16793 	}
   16794 
   16795 	event = ISC_LIST_HEAD(zone->rss_post);
   16796 	while (event != NULL) {
   16797 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   16798 		rss_post(zone, event);
   16799 		event = ISC_LIST_HEAD(zone->rss_post);
   16800 	}
   16801 
   16802 	dns_zone_idetach(&zone);
   16803 }
   16804 
   16805 static isc_result_t
   16806 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) {
   16807 	isc_event_t *e;
   16808 	dns_zone_t *dummy = NULL;
   16809 
   16810 	e = isc_event_allocate(zone->secure->mctx, zone,
   16811 			       DNS_EVENT_ZONESECURESERIAL,
   16812 			       receive_secure_serial, zone->secure,
   16813 			       sizeof(struct secure_event));
   16814 	((struct secure_event *)e)->serial = serial;
   16815 	INSIST(LOCKED_ZONE(zone->secure));
   16816 	zone_iattach(zone->secure, &dummy);
   16817 	isc_task_send(zone->secure->task, &e);
   16818 
   16819 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   16820 	return (ISC_R_SUCCESS);
   16821 }
   16822 
   16823 static isc_result_t
   16824 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   16825 	       dns_rdataset_t *rdataset, uint32_t oldserial) {
   16826 	dns_rdata_soa_t soa;
   16827 	dns_rdata_t rdata = DNS_RDATA_INIT;
   16828 	dns_rdatalist_t temprdatalist;
   16829 	dns_rdataset_t temprdataset;
   16830 	isc_buffer_t b;
   16831 	isc_result_t result;
   16832 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   16833 	dns_fixedname_t fixed;
   16834 	dns_name_t *name;
   16835 
   16836 	result = dns_rdataset_first(rdataset);
   16837 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16838 	dns_rdataset_current(rdataset, &rdata);
   16839 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   16840 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16841 
   16842 	if (isc_serial_gt(soa.serial, oldserial)) {
   16843 		return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
   16844 					   NULL));
   16845 	}
   16846 	/*
   16847 	 * Always bump the serial.
   16848 	 */
   16849 	oldserial++;
   16850 	if (oldserial == 0) {
   16851 		oldserial++;
   16852 	}
   16853 	soa.serial = oldserial;
   16854 
   16855 	/*
   16856 	 * Construct a replacement rdataset.
   16857 	 */
   16858 	dns_rdata_reset(&rdata);
   16859 	isc_buffer_init(&b, buf, sizeof(buf));
   16860 	result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
   16861 				      dns_rdatatype_soa, &soa, &b);
   16862 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16863 	dns_rdatalist_init(&temprdatalist);
   16864 	temprdatalist.rdclass = rdata.rdclass;
   16865 	temprdatalist.type = rdata.type;
   16866 	temprdatalist.ttl = rdataset->ttl;
   16867 	ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
   16868 
   16869 	dns_rdataset_init(&temprdataset);
   16870 	result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
   16871 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16872 
   16873 	name = dns_fixedname_initname(&fixed);
   16874 	result = dns_db_nodefullname(db, node, name);
   16875 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16876 	dns_rdataset_getownercase(rdataset, name);
   16877 	dns_rdataset_setownercase(&temprdataset, name);
   16878 	return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 0,
   16879 				   NULL));
   16880 }
   16881 
   16882 /*
   16883  * This function should populate an nsec3paramlist_t with the
   16884  * nsecparam_t data from a zone.
   16885  */
   16886 static isc_result_t
   16887 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
   16888 	isc_result_t result;
   16889 	dns_dbnode_t *node = NULL;
   16890 	dns_rdataset_t rdataset, prdataset;
   16891 	dns_dbversion_t *version = NULL;
   16892 	nsec3param_t *nsec3param = NULL;
   16893 	nsec3param_t *nsec3p = NULL;
   16894 	nsec3param_t *next;
   16895 	dns_db_t *db = NULL;
   16896 	unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   16897 
   16898 	REQUIRE(DNS_ZONE_VALID(zone));
   16899 	REQUIRE(nsec3list != NULL);
   16900 	REQUIRE(ISC_LIST_EMPTY(*nsec3list));
   16901 
   16902 	dns_rdataset_init(&rdataset);
   16903 	dns_rdataset_init(&prdataset);
   16904 
   16905 	dns_db_attach(zone->db, &db);
   16906 	CHECK(dns_db_getoriginnode(db, &node));
   16907 
   16908 	dns_db_currentversion(db, &version);
   16909 	result = dns_db_findrdataset(db, node, version,
   16910 				     dns_rdatatype_nsec3param,
   16911 				     dns_rdatatype_none, 0, &rdataset, NULL);
   16912 
   16913 	if (result != ISC_R_SUCCESS) {
   16914 		goto getprivate;
   16915 	}
   16916 
   16917 	/*
   16918 	 * Walk nsec3param rdataset making a list of parameters (note that
   16919 	 * multiple simultaneous nsec3 chains are annoyingly legal -- this
   16920 	 * is why we use an nsec3list, even though we will usually only
   16921 	 * have one).
   16922 	 */
   16923 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   16924 	     result = dns_rdataset_next(&rdataset))
   16925 	{
   16926 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16927 		dns_rdata_t private = DNS_RDATA_INIT;
   16928 
   16929 		dns_rdataset_current(&rdataset, &rdata);
   16930 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16931 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16932 			      "looping through nsec3param data");
   16933 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   16934 		ISC_LINK_INIT(nsec3param, link);
   16935 
   16936 		/*
   16937 		 * now transfer the data from the rdata to
   16938 		 * the nsec3param
   16939 		 */
   16940 		dns_nsec3param_toprivate(&rdata, &private, zone->privatetype,
   16941 					 nsec3param->data,
   16942 					 sizeof(nsec3param->data));
   16943 		nsec3param->length = private.length;
   16944 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   16945 	}
   16946 
   16947 getprivate:
   16948 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   16949 				     dns_rdatatype_none, 0, &prdataset, NULL);
   16950 	if (result != ISC_R_SUCCESS) {
   16951 		goto done;
   16952 	}
   16953 
   16954 	/*
   16955 	 * walk private type records, converting them to nsec3 parameters
   16956 	 * using dns_nsec3param_fromprivate(), do the right thing based on
   16957 	 * CREATE and REMOVE flags
   16958 	 */
   16959 	for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS;
   16960 	     result = dns_rdataset_next(&prdataset))
   16961 	{
   16962 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16963 		dns_rdata_t private = DNS_RDATA_INIT;
   16964 
   16965 		dns_rdataset_current(&prdataset, &private);
   16966 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16967 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16968 			      "looping through nsec3param private data");
   16969 
   16970 		/*
   16971 		 * Do we have a valid private record?
   16972 		 */
   16973 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   16974 						sizeof(buf)))
   16975 		{
   16976 			continue;
   16977 		}
   16978 
   16979 		/*
   16980 		 * Remove any NSEC3PARAM records scheduled to be removed.
   16981 		 */
   16982 		if (NSEC3REMOVE(rdata.data[1])) {
   16983 			/*
   16984 			 * Zero out the flags.
   16985 			 */
   16986 			rdata.data[1] = 0;
   16987 
   16988 			for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL;
   16989 			     nsec3p = next)
   16990 			{
   16991 				next = ISC_LIST_NEXT(nsec3p, link);
   16992 
   16993 				if (nsec3p->length == rdata.length + 1 &&
   16994 				    memcmp(rdata.data, nsec3p->data + 1,
   16995 					   nsec3p->length - 1) == 0)
   16996 				{
   16997 					ISC_LIST_UNLINK(*nsec3list, nsec3p,
   16998 							link);
   16999 					isc_mem_put(zone->mctx, nsec3p,
   17000 						    sizeof(nsec3param_t));
   17001 				}
   17002 			}
   17003 			continue;
   17004 		}
   17005 
   17006 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   17007 		ISC_LINK_INIT(nsec3param, link);
   17008 
   17009 		/*
   17010 		 * Copy the remaining private records so the nsec/nsec3
   17011 		 * chain gets created.
   17012 		 */
   17013 		INSIST(private.length <= sizeof(nsec3param->data));
   17014 		memmove(nsec3param->data, private.data, private.length);
   17015 		nsec3param->length = private.length;
   17016 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   17017 	}
   17018 
   17019 done:
   17020 	if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) {
   17021 		result = ISC_R_SUCCESS;
   17022 	}
   17023 
   17024 failure:
   17025 	if (node != NULL) {
   17026 		dns_db_detachnode(db, &node);
   17027 	}
   17028 	if (version != NULL) {
   17029 		dns_db_closeversion(db, &version, false);
   17030 	}
   17031 	if (db != NULL) {
   17032 		dns_db_detach(&db);
   17033 	}
   17034 	if (dns_rdataset_isassociated(&rdataset)) {
   17035 		dns_rdataset_disassociate(&rdataset);
   17036 	}
   17037 	if (dns_rdataset_isassociated(&prdataset)) {
   17038 		dns_rdataset_disassociate(&prdataset);
   17039 	}
   17040 	return (result);
   17041 }
   17042 
   17043 /*
   17044  * Populate new zone db with private type records found by save_nsec3param().
   17045  */
   17046 static isc_result_t
   17047 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   17048 		   nsec3paramlist_t *nsec3list) {
   17049 	isc_result_t result = ISC_R_SUCCESS;
   17050 	dns_diff_t diff;
   17051 	dns_rdata_t rdata;
   17052 	nsec3param_t *nsec3p = NULL;
   17053 	nsec3param_t *next;
   17054 
   17055 	REQUIRE(DNS_ZONE_VALID(zone));
   17056 	REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
   17057 
   17058 	dns_diff_init(zone->mctx, &diff);
   17059 
   17060 	/*
   17061 	 * Loop through the list of private-type records, set the INITIAL
   17062 	 * and CREATE flags, and the add the record to the apex of the tree
   17063 	 * in db.
   17064 	 */
   17065 	for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next)
   17066 	{
   17067 		next = ISC_LIST_NEXT(nsec3p, link);
   17068 		dns_rdata_init(&rdata);
   17069 		nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
   17070 		rdata.length = nsec3p->length;
   17071 		rdata.data = nsec3p->data;
   17072 		rdata.type = zone->privatetype;
   17073 		rdata.rdclass = zone->rdclass;
   17074 		result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
   17075 				       &zone->origin, 0, &rdata);
   17076 		if (result != ISC_R_SUCCESS) {
   17077 			break;
   17078 		}
   17079 	}
   17080 
   17081 	dns_diff_clear(&diff);
   17082 	return (result);
   17083 }
   17084 
   17085 static isc_result_t
   17086 copy_non_dnssec_records(dns_db_t *db, dns_db_t *version, dns_db_t *rawdb,
   17087 			dns_dbiterator_t *dbiterator, unsigned int *oldserial) {
   17088 	dns_dbnode_t *rawnode = NULL, *node = NULL;
   17089 	dns_fixedname_t fixed;
   17090 	dns_name_t *name = dns_fixedname_initname(&fixed);
   17091 	dns_rdataset_t rdataset;
   17092 	dns_rdatasetiter_t *rdsit = NULL;
   17093 	isc_result_t result;
   17094 
   17095 	result = dns_dbiterator_current(dbiterator, &rawnode, name);
   17096 	if (result != ISC_R_SUCCESS) {
   17097 		return (ISC_R_SUCCESS);
   17098 	}
   17099 
   17100 	dns_dbiterator_pause(dbiterator);
   17101 
   17102 	result = dns_db_findnode(db, name, true, &node);
   17103 	if (result != ISC_R_SUCCESS) {
   17104 		goto cleanup;
   17105 	}
   17106 
   17107 	result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, 0, &rdsit);
   17108 	if (result != ISC_R_SUCCESS) {
   17109 		goto cleanup;
   17110 	}
   17111 
   17112 	dns_rdataset_init(&rdataset);
   17113 
   17114 	for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS;
   17115 	     result = dns_rdatasetiter_next(rdsit))
   17116 	{
   17117 		dns_rdatasetiter_current(rdsit, &rdataset);
   17118 		if (rdataset.type == dns_rdatatype_nsec ||
   17119 		    rdataset.type == dns_rdatatype_rrsig ||
   17120 		    rdataset.type == dns_rdatatype_nsec3 ||
   17121 		    rdataset.type == dns_rdatatype_dnskey ||
   17122 		    rdataset.type == dns_rdatatype_nsec3param)
   17123 		{
   17124 			dns_rdataset_disassociate(&rdataset);
   17125 			continue;
   17126 		}
   17127 		if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) {
   17128 			result = checkandaddsoa(db, node, version, &rdataset,
   17129 						*oldserial);
   17130 		} else {
   17131 			result = dns_db_addrdataset(db, node, version, 0,
   17132 						    &rdataset, 0, NULL);
   17133 		}
   17134 		dns_rdataset_disassociate(&rdataset);
   17135 		if (result != ISC_R_SUCCESS) {
   17136 			goto cleanup;
   17137 		}
   17138 	}
   17139 	if (result == ISC_R_NOMORE) {
   17140 		result = ISC_R_SUCCESS;
   17141 	}
   17142 
   17143 cleanup:
   17144 	if (rdsit != NULL) {
   17145 		dns_rdatasetiter_destroy(&rdsit);
   17146 	}
   17147 	if (rawnode) {
   17148 		dns_db_detachnode(rawdb, &rawnode);
   17149 	}
   17150 	if (node) {
   17151 		dns_db_detachnode(db, &node);
   17152 	}
   17153 	return (result);
   17154 }
   17155 
   17156 static void
   17157 receive_secure_db(isc_task_t *task, isc_event_t *event) {
   17158 	isc_result_t result;
   17159 	dns_zone_t *zone;
   17160 	dns_db_t *rawdb, *db = NULL;
   17161 	dns_dbiterator_t *dbiterator = NULL;
   17162 	dns_dbversion_t *version = NULL;
   17163 	isc_time_t loadtime;
   17164 	unsigned int oldserial = 0, *oldserialp = NULL;
   17165 	nsec3paramlist_t nsec3list;
   17166 	isc_event_t *setnsec3param_event;
   17167 	dns_zone_t *dummy;
   17168 
   17169 	UNUSED(task);
   17170 
   17171 	ISC_LIST_INIT(nsec3list);
   17172 
   17173 	zone = event->ev_arg;
   17174 	rawdb = ((struct secure_event *)event)->db;
   17175 	isc_event_free(&event);
   17176 
   17177 	LOCK_ZONE(zone);
   17178 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
   17179 		result = ISC_R_SHUTTINGDOWN;
   17180 		goto failure;
   17181 	}
   17182 
   17183 	TIME_NOW(&loadtime);
   17184 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17185 	if (zone->db != NULL) {
   17186 		result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
   17187 		if (result == ISC_R_SUCCESS) {
   17188 			oldserialp = &oldserial;
   17189 		}
   17190 
   17191 		/*
   17192 		 * assemble nsec3parameters from the old zone, and set a flag
   17193 		 * if any are found
   17194 		 */
   17195 		result = save_nsec3param(zone, &nsec3list);
   17196 		if (result != ISC_R_SUCCESS) {
   17197 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17198 			goto failure;
   17199 		}
   17200 	}
   17201 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17202 
   17203 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   17204 			       dns_dbtype_zone, zone->rdclass,
   17205 			       zone->db_argc - 1, zone->db_argv + 1, &db);
   17206 	if (result != ISC_R_SUCCESS) {
   17207 		goto failure;
   17208 	}
   17209 
   17210 	result = dns_db_setgluecachestats(db, zone->gluecachestats);
   17211 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
   17212 		goto failure;
   17213 	}
   17214 
   17215 	result = dns_db_newversion(db, &version);
   17216 	if (result != ISC_R_SUCCESS) {
   17217 		goto failure;
   17218 	}
   17219 
   17220 	result = dns_db_createiterator(rawdb, 0, &dbiterator);
   17221 	if (result != ISC_R_SUCCESS) {
   17222 		goto failure;
   17223 	}
   17224 
   17225 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   17226 	     result = dns_dbiterator_next(dbiterator))
   17227 	{
   17228 		result = copy_non_dnssec_records(db, version, rawdb, dbiterator,
   17229 						 oldserialp);
   17230 		if (result != ISC_R_SUCCESS) {
   17231 			goto failure;
   17232 		}
   17233 	}
   17234 	dns_dbiterator_destroy(&dbiterator);
   17235 	if (result != ISC_R_NOMORE) {
   17236 		goto failure;
   17237 	}
   17238 
   17239 	/*
   17240 	 * Call restore_nsec3param() to create private-type records from
   17241 	 * the old nsec3 parameters and insert them into db
   17242 	 */
   17243 	if (!ISC_LIST_EMPTY(nsec3list)) {
   17244 		result = restore_nsec3param(zone, db, version, &nsec3list);
   17245 		if (result != ISC_R_SUCCESS) {
   17246 			goto failure;
   17247 		}
   17248 	}
   17249 
   17250 	dns_db_closeversion(db, &version, true);
   17251 
   17252 	/*
   17253 	 * Lock hierarchy: zmgr, zone, raw.
   17254 	 */
   17255 	INSIST(zone != zone->raw);
   17256 	LOCK_ZONE(zone->raw);
   17257 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   17258 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   17259 	zone_needdump(zone, 0); /* XXXMPA */
   17260 	UNLOCK_ZONE(zone->raw);
   17261 
   17262 	/*
   17263 	 * Process any queued NSEC3PARAM change requests.
   17264 	 */
   17265 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   17266 		setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   17267 		ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
   17268 				ev_link);
   17269 		dummy = NULL;
   17270 		zone_iattach(zone, &dummy);
   17271 		isc_task_send(zone->task, &setnsec3param_event);
   17272 	}
   17273 
   17274 failure:
   17275 	UNLOCK_ZONE(zone);
   17276 	if (dbiterator != NULL) {
   17277 		dns_dbiterator_destroy(&dbiterator);
   17278 	}
   17279 	if (result != ISC_R_SUCCESS) {
   17280 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
   17281 			     isc_result_totext(result));
   17282 	}
   17283 
   17284 	while (!ISC_LIST_EMPTY(nsec3list)) {
   17285 		nsec3param_t *nsec3p;
   17286 		nsec3p = ISC_LIST_HEAD(nsec3list);
   17287 		ISC_LIST_UNLINK(nsec3list, nsec3p, link);
   17288 		isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
   17289 	}
   17290 	if (db != NULL) {
   17291 		if (version != NULL) {
   17292 			dns_db_closeversion(db, &version, false);
   17293 		}
   17294 		dns_db_detach(&db);
   17295 	}
   17296 	dns_db_detach(&rawdb);
   17297 	dns_zone_idetach(&zone);
   17298 
   17299 	INSIST(version == NULL);
   17300 }
   17301 
   17302 static isc_result_t
   17303 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
   17304 	isc_event_t *e;
   17305 	dns_db_t *dummy = NULL;
   17306 	dns_zone_t *secure = NULL;
   17307 
   17308 	e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECUREDB,
   17309 			       receive_secure_db, zone->secure,
   17310 			       sizeof(struct secure_event));
   17311 	dns_db_attach(db, &dummy);
   17312 	((struct secure_event *)e)->db = dummy;
   17313 	INSIST(LOCKED_ZONE(zone->secure));
   17314 	zone_iattach(zone->secure, &secure);
   17315 	isc_task_send(zone->secure->task, &e);
   17316 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   17317 	return (ISC_R_SUCCESS);
   17318 }
   17319 
   17320 isc_result_t
   17321 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   17322 	isc_result_t result;
   17323 	dns_zone_t *secure = NULL;
   17324 
   17325 	REQUIRE(DNS_ZONE_VALID(zone));
   17326 again:
   17327 	LOCK_ZONE(zone);
   17328 	if (inline_raw(zone)) {
   17329 		secure = zone->secure;
   17330 		INSIST(secure != zone);
   17331 		TRYLOCK_ZONE(result, secure);
   17332 		if (result != ISC_R_SUCCESS) {
   17333 			UNLOCK_ZONE(zone);
   17334 			secure = NULL;
   17335 			isc_thread_yield();
   17336 			goto again;
   17337 		}
   17338 	}
   17339 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   17340 	result = zone_replacedb(zone, db, dump);
   17341 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   17342 	if (secure != NULL) {
   17343 		UNLOCK_ZONE(secure);
   17344 	}
   17345 	UNLOCK_ZONE(zone);
   17346 	return (result);
   17347 }
   17348 
   17349 static isc_result_t
   17350 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   17351 	dns_dbversion_t *ver;
   17352 	isc_result_t result;
   17353 	unsigned int soacount = 0;
   17354 	unsigned int nscount = 0;
   17355 
   17356 	/*
   17357 	 * 'zone' and 'zone->db' locked by caller.
   17358 	 */
   17359 	REQUIRE(DNS_ZONE_VALID(zone));
   17360 	REQUIRE(LOCKED_ZONE(zone));
   17361 	if (inline_raw(zone)) {
   17362 		REQUIRE(LOCKED_ZONE(zone->secure));
   17363 	}
   17364 
   17365 	result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL,
   17366 				  NULL, NULL, NULL, NULL, NULL);
   17367 	if (result == ISC_R_SUCCESS) {
   17368 		if (soacount != 1) {
   17369 			dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records",
   17370 				     soacount);
   17371 			result = DNS_R_BADZONE;
   17372 		}
   17373 		if (nscount == 0 && zone->type != dns_zone_key) {
   17374 			dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
   17375 			result = DNS_R_BADZONE;
   17376 		}
   17377 		if (result != ISC_R_SUCCESS) {
   17378 			return (result);
   17379 		}
   17380 	} else {
   17381 		dns_zone_log(zone, ISC_LOG_ERROR,
   17382 			     "retrieving SOA and NS records failed: %s",
   17383 			     isc_result_totext(result));
   17384 		return (result);
   17385 	}
   17386 
   17387 	result = check_nsec3param(zone, db);
   17388 	if (result != ISC_R_SUCCESS) {
   17389 		return (result);
   17390 	}
   17391 
   17392 	ver = NULL;
   17393 	dns_db_currentversion(db, &ver);
   17394 
   17395 	/*
   17396 	 * The initial version of a secondary zone is always dumped;
   17397 	 * subsequent versions may be journaled instead if this
   17398 	 * is enabled in the configuration.
   17399 	 */
   17400 	if (zone->db != NULL && zone->journal != NULL &&
   17401 	    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   17402 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
   17403 	{
   17404 		uint32_t serial, oldserial;
   17405 
   17406 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
   17407 
   17408 		result = dns_db_getsoaserial(db, ver, &serial);
   17409 		if (result != ISC_R_SUCCESS) {
   17410 			dns_zone_log(zone, ISC_LOG_ERROR,
   17411 				     "ixfr-from-differences: unable to get "
   17412 				     "new serial");
   17413 			goto fail;
   17414 		}
   17415 
   17416 		/*
   17417 		 * This is checked in zone_postload() for primary zones.
   17418 		 */
   17419 		result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
   17420 					  &oldserial, NULL, NULL, NULL, NULL,
   17421 					  NULL);
   17422 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   17423 		RUNTIME_CHECK(soacount > 0U);
   17424 		if ((zone->type == dns_zone_secondary ||
   17425 		     (zone->type == dns_zone_redirect &&
   17426 		      zone->primaries != NULL)) &&
   17427 		    !isc_serial_gt(serial, oldserial))
   17428 		{
   17429 			uint32_t serialmin, serialmax;
   17430 			serialmin = (oldserial + 1) & 0xffffffffU;
   17431 			serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
   17432 			dns_zone_log(zone, ISC_LOG_ERROR,
   17433 				     "ixfr-from-differences: failed: "
   17434 				     "new serial (%u) out of range [%u - %u]",
   17435 				     serial, serialmin, serialmax);
   17436 			result = ISC_R_RANGE;
   17437 			goto fail;
   17438 		}
   17439 
   17440 		result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
   17441 				     zone->journal);
   17442 		if (result != ISC_R_SUCCESS) {
   17443 			char strbuf[ISC_STRERRORSIZE];
   17444 			strerror_r(errno, strbuf, sizeof(strbuf));
   17445 			dns_zone_log(zone, ISC_LOG_ERROR,
   17446 				     "ixfr-from-differences: failed: "
   17447 				     "%s",
   17448 				     strbuf);
   17449 			goto fallback;
   17450 		}
   17451 		if (dump) {
   17452 			zone_needdump(zone, DNS_DUMP_DELAY);
   17453 		} else {
   17454 			zone_journal_compact(zone, zone->db, serial);
   17455 		}
   17456 		if (zone->type == dns_zone_primary && inline_raw(zone)) {
   17457 			zone_send_secureserial(zone, serial);
   17458 		}
   17459 	} else {
   17460 	fallback:
   17461 		if (dump && zone->masterfile != NULL) {
   17462 			/*
   17463 			 * If DNS_ZONEFLG_FORCEXFER was set we don't want
   17464 			 * to keep the old masterfile.
   17465 			 */
   17466 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
   17467 			    remove(zone->masterfile) < 0 && errno != ENOENT)
   17468 			{
   17469 				char strbuf[ISC_STRERRORSIZE];
   17470 				strerror_r(errno, strbuf, sizeof(strbuf));
   17471 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17472 					      DNS_LOGMODULE_ZONE,
   17473 					      ISC_LOG_WARNING,
   17474 					      "unable to remove masterfile "
   17475 					      "'%s': '%s'",
   17476 					      zone->masterfile, strbuf);
   17477 			}
   17478 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) {
   17479 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
   17480 			} else {
   17481 				zone_needdump(zone, 0);
   17482 			}
   17483 		}
   17484 		if (dump && zone->journal != NULL) {
   17485 			/*
   17486 			 * The in-memory database just changed, and
   17487 			 * because 'dump' is set, it didn't change by
   17488 			 * being loaded from disk.  Also, we have not
   17489 			 * journaled diffs for this change.
   17490 			 * Therefore, the on-disk journal is missing
   17491 			 * the deltas for this change.	Since it can
   17492 			 * no longer be used to bring the zone
   17493 			 * up-to-date, it is useless and should be
   17494 			 * removed.
   17495 			 */
   17496 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17497 				      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   17498 				      "removing journal file");
   17499 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   17500 				char strbuf[ISC_STRERRORSIZE];
   17501 				strerror_r(errno, strbuf, sizeof(strbuf));
   17502 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17503 					      DNS_LOGMODULE_ZONE,
   17504 					      ISC_LOG_WARNING,
   17505 					      "unable to remove journal "
   17506 					      "'%s': '%s'",
   17507 					      zone->journal, strbuf);
   17508 			}
   17509 		}
   17510 
   17511 		if (inline_raw(zone)) {
   17512 			zone_send_securedb(zone, db);
   17513 		}
   17514 	}
   17515 
   17516 	dns_db_closeversion(db, &ver, false);
   17517 
   17518 	dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
   17519 
   17520 	if (zone->db != NULL) {
   17521 		zone_detachdb(zone);
   17522 	}
   17523 	zone_attachdb(zone, db);
   17524 	dns_db_settask(zone->db, zone->task);
   17525 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   17526 	return (ISC_R_SUCCESS);
   17527 
   17528 fail:
   17529 	dns_db_closeversion(db, &ver, false);
   17530 	return (result);
   17531 }
   17532 
   17533 /* The caller must hold the dblock as a writer. */
   17534 static void
   17535 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
   17536 	REQUIRE(zone->db == NULL && db != NULL);
   17537 
   17538 	dns_db_attach(db, &zone->db);
   17539 }
   17540 
   17541 /* The caller must hold the dblock as a writer. */
   17542 static void
   17543 zone_detachdb(dns_zone_t *zone) {
   17544 	REQUIRE(zone->db != NULL);
   17545 
   17546 	dns_zone_rpz_disable_db(zone, zone->db);
   17547 	dns_zone_catz_disable_db(zone, zone->db);
   17548 	dns_db_detach(&zone->db);
   17549 }
   17550 
   17551 static void
   17552 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
   17553 	isc_time_t now;
   17554 	bool again = false;
   17555 	unsigned int soacount;
   17556 	unsigned int nscount;
   17557 	uint32_t serial, refresh, retry, expire, minimum, soattl;
   17558 	isc_result_t xfrresult = result;
   17559 	bool free_needed;
   17560 	dns_zone_t *secure = NULL;
   17561 
   17562 	REQUIRE(DNS_ZONE_VALID(zone));
   17563 
   17564 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17565 		      "zone transfer finished: %s", isc_result_totext(result));
   17566 
   17567 	/*
   17568 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   17569 	 * could result in a deadlock due to a LOR so we will spin if we
   17570 	 * can't obtain both locks.
   17571 	 */
   17572 again:
   17573 	LOCK_ZONE(zone);
   17574 	if (inline_raw(zone)) {
   17575 		secure = zone->secure;
   17576 		INSIST(secure != zone);
   17577 		TRYLOCK_ZONE(result, secure);
   17578 		if (result != ISC_R_SUCCESS) {
   17579 			UNLOCK_ZONE(zone);
   17580 			secure = NULL;
   17581 			isc_thread_yield();
   17582 			goto again;
   17583 		}
   17584 	}
   17585 
   17586 	INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH));
   17587 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   17588 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   17589 
   17590 	TIME_NOW(&now);
   17591 	switch (xfrresult) {
   17592 	case ISC_R_SUCCESS:
   17593 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   17594 		FALLTHROUGH;
   17595 	case DNS_R_UPTODATE:
   17596 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   17597 		/*
   17598 		 * Has the zone expired underneath us?
   17599 		 */
   17600 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17601 		if (zone->db == NULL) {
   17602 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17603 			goto same_primary;
   17604 		}
   17605 
   17606 		/*
   17607 		 * Update the zone structure's data from the actual
   17608 		 * SOA received.
   17609 		 */
   17610 		nscount = 0;
   17611 		soacount = 0;
   17612 		INSIST(zone->db != NULL);
   17613 		result = zone_get_from_db(zone, zone->db, &nscount, &soacount,
   17614 					  &soattl, &serial, &refresh, &retry,
   17615 					  &expire, &minimum, NULL);
   17616 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17617 		if (result == ISC_R_SUCCESS) {
   17618 			if (soacount != 1) {
   17619 				dns_zone_log(zone, ISC_LOG_ERROR,
   17620 					     "transferred zone "
   17621 					     "has %d SOA records",
   17622 					     soacount);
   17623 				if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   17624 				{
   17625 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   17626 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   17627 				}
   17628 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17629 				zone_unload(zone);
   17630 				goto next_primary;
   17631 			}
   17632 			if (nscount == 0) {
   17633 				dns_zone_log(zone, ISC_LOG_ERROR,
   17634 					     "transferred zone "
   17635 					     "has no NS records");
   17636 				if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   17637 				{
   17638 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   17639 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   17640 				}
   17641 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17642 				zone_unload(zone);
   17643 				goto next_primary;
   17644 			}
   17645 			zone->refresh = RANGE(refresh, zone->minrefresh,
   17646 					      zone->maxrefresh);
   17647 			zone->retry = RANGE(retry, zone->minretry,
   17648 					    zone->maxretry);
   17649 			zone->expire = RANGE(expire,
   17650 					     zone->refresh + zone->retry,
   17651 					     DNS_MAX_EXPIRE);
   17652 			zone->soattl = soattl;
   17653 			zone->minimum = minimum;
   17654 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17655 		}
   17656 
   17657 		/*
   17658 		 * Set our next update/expire times.
   17659 		 */
   17660 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   17661 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   17662 			zone->refreshtime = now;
   17663 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17664 					  &zone->expiretime);
   17665 		} else {
   17666 			DNS_ZONE_JITTER_ADD(&now, zone->refresh,
   17667 					    &zone->refreshtime);
   17668 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17669 					  &zone->expiretime);
   17670 		}
   17671 
   17672 		/*
   17673 		 * Set loadtime.
   17674 		 */
   17675 		zone->loadtime = now;
   17676 
   17677 		if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
   17678 			char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
   17679 			if (zone->tsigkey != NULL) {
   17680 				char namebuf[DNS_NAME_FORMATSIZE];
   17681 				dns_name_format(&zone->tsigkey->name, namebuf,
   17682 						sizeof(namebuf));
   17683 				snprintf(buf, sizeof(buf), ": TSIG '%s'",
   17684 					 namebuf);
   17685 			} else {
   17686 				buf[0] = '\0';
   17687 			}
   17688 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17689 				      ISC_LOG_INFO, "transferred serial %u%s",
   17690 				      serial, buf);
   17691 			if (inline_raw(zone)) {
   17692 				zone_send_secureserial(zone, serial);
   17693 			}
   17694 		}
   17695 
   17696 		/*
   17697 		 * This is not necessary if we just performed a AXFR
   17698 		 * however it is necessary for an IXFR / UPTODATE and
   17699 		 * won't hurt with an AXFR.
   17700 		 */
   17701 		if (zone->masterfile != NULL || zone->journal != NULL) {
   17702 			unsigned int delay = DNS_DUMP_DELAY;
   17703 
   17704 			result = ISC_R_FAILURE;
   17705 			if (zone->journal != NULL) {
   17706 				result = isc_file_settime(zone->journal, &now);
   17707 			}
   17708 			if (result != ISC_R_SUCCESS && zone->masterfile != NULL)
   17709 			{
   17710 				result = isc_file_settime(zone->masterfile,
   17711 							  &now);
   17712 			}
   17713 
   17714 			if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
   17715 			    result == ISC_R_FILENOTFOUND)
   17716 			{
   17717 				delay = 0;
   17718 			}
   17719 
   17720 			if ((result == ISC_R_SUCCESS ||
   17721 			     result == ISC_R_FILENOTFOUND) &&
   17722 			    zone->masterfile != NULL)
   17723 			{
   17724 				zone_needdump(zone, delay);
   17725 			} else if (result != ISC_R_SUCCESS) {
   17726 				dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17727 					      ISC_LOG_ERROR,
   17728 					      "transfer: could not set file "
   17729 					      "modification time of '%s': %s",
   17730 					      zone->masterfile,
   17731 					      isc_result_totext(result));
   17732 			}
   17733 		}
   17734 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
   17735 		inc_stats(zone, dns_zonestatscounter_xfrsuccess);
   17736 		break;
   17737 
   17738 	case DNS_R_BADIXFR:
   17739 		/* Force retry with AXFR. */
   17740 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR);
   17741 		goto same_primary;
   17742 
   17743 	case DNS_R_TOOMANYRECORDS:
   17744 	case DNS_R_VERIFYFAILURE:
   17745 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   17746 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17747 		break;
   17748 
   17749 	default:
   17750 	next_primary:
   17751 		/*
   17752 		 * Skip to next failed / untried primary.
   17753 		 */
   17754 		do {
   17755 			zone->curprimary++;
   17756 		} while (zone->curprimary < zone->primariescnt &&
   17757 			 zone->primariesok[zone->curprimary]);
   17758 	same_primary:
   17759 		if (zone->curprimary >= zone->primariescnt) {
   17760 			zone->curprimary = 0;
   17761 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   17762 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   17763 			{
   17764 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17765 				DNS_ZONE_SETFLAG(zone,
   17766 						 DNS_ZONEFLG_USEALTXFRSRC);
   17767 				while (zone->curprimary < zone->primariescnt &&
   17768 				       zone->primariesok[zone->curprimary])
   17769 				{
   17770 					zone->curprimary++;
   17771 				}
   17772 				again = true;
   17773 			} else {
   17774 				DNS_ZONE_CLRFLAG(zone,
   17775 						 DNS_ZONEFLG_USEALTXFRSRC);
   17776 			}
   17777 		} else {
   17778 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17779 			again = true;
   17780 		}
   17781 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17782 		break;
   17783 	}
   17784 	zone_settimer(zone, &now);
   17785 
   17786 	/*
   17787 	 * If creating the transfer object failed, zone->xfr is NULL.
   17788 	 * Otherwise, we are called as the done callback of a zone
   17789 	 * transfer object that just entered its shutting-down
   17790 	 * state.  Since we are no longer responsible for shutting
   17791 	 * it down, we can detach our reference.
   17792 	 */
   17793 	if (zone->xfr != NULL) {
   17794 		dns_xfrin_detach(&zone->xfr);
   17795 	}
   17796 
   17797 	if (zone->tsigkey != NULL) {
   17798 		dns_tsigkey_detach(&zone->tsigkey);
   17799 	}
   17800 
   17801 	if (zone->transport != NULL) {
   17802 		dns_transport_detach(&zone->transport);
   17803 	}
   17804 
   17805 	/*
   17806 	 * Handle any deferred journal compaction.
   17807 	 */
   17808 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
   17809 		dns_db_t *db = NULL;
   17810 		if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) {
   17811 			zone_journal_compact(zone, db, zone->compact_serial);
   17812 			dns_db_detach(&db);
   17813 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   17814 		}
   17815 	}
   17816 
   17817 	if (secure != NULL) {
   17818 		UNLOCK_ZONE(secure);
   17819 	}
   17820 	/*
   17821 	 * This transfer finishing freed up a transfer quota slot.
   17822 	 * Let any other zones waiting for quota have it.
   17823 	 */
   17824 	if (zone->zmgr != NULL &&
   17825 	    zone->statelist == &zone->zmgr->xfrin_in_progress)
   17826 	{
   17827 		UNLOCK_ZONE(zone);
   17828 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17829 		ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
   17830 		zone->statelist = NULL;
   17831 		zmgr_resume_xfrs(zone->zmgr, false);
   17832 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17833 		LOCK_ZONE(zone);
   17834 	}
   17835 
   17836 	/*
   17837 	 * Retry with a different server if necessary.
   17838 	 */
   17839 	if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   17840 		queue_soa_query(zone);
   17841 	}
   17842 
   17843 	isc_refcount_decrement(&zone->irefs);
   17844 	free_needed = exit_check(zone);
   17845 	UNLOCK_ZONE(zone);
   17846 	if (free_needed) {
   17847 		zone_free(zone);
   17848 	}
   17849 }
   17850 
   17851 static void
   17852 zone_loaddone(void *arg, isc_result_t result) {
   17853 	static char me[] = "zone_loaddone";
   17854 	dns_load_t *load = arg;
   17855 	dns_zone_t *zone;
   17856 	isc_result_t tresult;
   17857 	dns_zone_t *secure = NULL;
   17858 
   17859 	REQUIRE(DNS_LOAD_VALID(load));
   17860 	zone = load->zone;
   17861 
   17862 	ENTER;
   17863 
   17864 	/*
   17865 	 * If zone loading failed, remove the update db callbacks prior
   17866 	 * to calling the list of callbacks in the zone load structure.
   17867 	 */
   17868 	if (result != ISC_R_SUCCESS) {
   17869 		dns_zone_rpz_disable_db(zone, load->db);
   17870 		dns_zone_catz_disable_db(zone, load->db);
   17871 	}
   17872 
   17873 	tresult = dns_db_endload(load->db, &load->callbacks);
   17874 	if (tresult != ISC_R_SUCCESS &&
   17875 	    (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
   17876 	{
   17877 		result = tresult;
   17878 	}
   17879 
   17880 	/*
   17881 	 * Lock hierarchy: zmgr, zone, raw.
   17882 	 */
   17883 again:
   17884 	LOCK_ZONE(zone);
   17885 	INSIST(zone != zone->raw);
   17886 	if (inline_secure(zone)) {
   17887 		LOCK_ZONE(zone->raw);
   17888 	} else if (inline_raw(zone)) {
   17889 		secure = zone->secure;
   17890 		TRYLOCK_ZONE(tresult, secure);
   17891 		if (tresult != ISC_R_SUCCESS) {
   17892 			UNLOCK_ZONE(zone);
   17893 			secure = NULL;
   17894 			isc_thread_yield();
   17895 			goto again;
   17896 		}
   17897 	}
   17898 	(void)zone_postload(zone, load->db, load->loadtime, result);
   17899 	zonemgr_putio(&zone->readio);
   17900 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
   17901 	zone_idetach(&load->callbacks.zone);
   17902 	/*
   17903 	 * Leave the zone frozen if the reload fails.
   17904 	 */
   17905 	if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
   17906 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
   17907 	{
   17908 		zone->update_disabled = false;
   17909 	}
   17910 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
   17911 	if (inline_secure(zone)) {
   17912 		UNLOCK_ZONE(zone->raw);
   17913 	} else if (secure != NULL) {
   17914 		UNLOCK_ZONE(secure);
   17915 	}
   17916 	UNLOCK_ZONE(zone);
   17917 
   17918 	load->magic = 0;
   17919 	dns_db_detach(&load->db);
   17920 	if (load->zone->lctx != NULL) {
   17921 		dns_loadctx_detach(&load->zone->lctx);
   17922 	}
   17923 	dns_zone_idetach(&load->zone);
   17924 	isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
   17925 }
   17926 
   17927 void
   17928 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
   17929 	REQUIRE(DNS_ZONE_VALID(zone));
   17930 	REQUIRE(table != NULL);
   17931 	REQUIRE(*table == NULL);
   17932 
   17933 	LOCK_ZONE(zone);
   17934 	if (zone->ssutable != NULL) {
   17935 		dns_ssutable_attach(zone->ssutable, table);
   17936 	}
   17937 	UNLOCK_ZONE(zone);
   17938 }
   17939 
   17940 void
   17941 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
   17942 	REQUIRE(DNS_ZONE_VALID(zone));
   17943 
   17944 	LOCK_ZONE(zone);
   17945 	if (zone->ssutable != NULL) {
   17946 		dns_ssutable_detach(&zone->ssutable);
   17947 	}
   17948 	if (table != NULL) {
   17949 		dns_ssutable_attach(table, &zone->ssutable);
   17950 	}
   17951 	UNLOCK_ZONE(zone);
   17952 }
   17953 
   17954 void
   17955 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17956 	REQUIRE(DNS_ZONE_VALID(zone));
   17957 
   17958 	zone->sigvalidityinterval = interval;
   17959 }
   17960 
   17961 uint32_t
   17962 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
   17963 	REQUIRE(DNS_ZONE_VALID(zone));
   17964 
   17965 	return (zone->sigvalidityinterval);
   17966 }
   17967 
   17968 void
   17969 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17970 	REQUIRE(DNS_ZONE_VALID(zone));
   17971 
   17972 	zone->keyvalidityinterval = interval;
   17973 }
   17974 
   17975 uint32_t
   17976 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
   17977 	REQUIRE(DNS_ZONE_VALID(zone));
   17978 
   17979 	return (zone->keyvalidityinterval);
   17980 }
   17981 
   17982 void
   17983 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
   17984 	isc_time_t now;
   17985 
   17986 	REQUIRE(DNS_ZONE_VALID(zone));
   17987 
   17988 	LOCK_ZONE(zone);
   17989 	zone->sigresigninginterval = interval;
   17990 	set_resigntime(zone);
   17991 	if (zone->task != NULL) {
   17992 		TIME_NOW(&now);
   17993 		zone_settimer(zone, &now);
   17994 	}
   17995 	UNLOCK_ZONE(zone);
   17996 }
   17997 
   17998 uint32_t
   17999 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
   18000 	REQUIRE(DNS_ZONE_VALID(zone));
   18001 
   18002 	return (zone->sigresigninginterval);
   18003 }
   18004 
   18005 static void
   18006 queue_xfrin(dns_zone_t *zone) {
   18007 	const char me[] = "queue_xfrin";
   18008 	isc_result_t result;
   18009 	dns_zonemgr_t *zmgr = zone->zmgr;
   18010 
   18011 	ENTER;
   18012 
   18013 	INSIST(zone->statelist == NULL);
   18014 
   18015 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18016 	ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
   18017 	isc_refcount_increment0(&zone->irefs);
   18018 	zone->statelist = &zmgr->waiting_for_xfrin;
   18019 	result = zmgr_start_xfrin_ifquota(zmgr, zone);
   18020 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18021 
   18022 	if (result == ISC_R_QUOTA) {
   18023 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   18024 			      "zone transfer deferred due to quota");
   18025 	} else if (result != ISC_R_SUCCESS) {
   18026 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   18027 			      "starting zone transfer: %s",
   18028 			      isc_result_totext(result));
   18029 	}
   18030 }
   18031 
   18032 /*
   18033  * This event callback is called when a zone has received
   18034  * any necessary zone transfer quota.  This is the time
   18035  * to go ahead and start the transfer.
   18036  */
   18037 static void
   18038 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
   18039 	isc_result_t result = ISC_R_SUCCESS;
   18040 	dns_peer_t *peer = NULL;
   18041 	char primary[ISC_SOCKADDR_FORMATSIZE];
   18042 	char source[ISC_SOCKADDR_FORMATSIZE];
   18043 	dns_rdatatype_t xfrtype;
   18044 	dns_zone_t *zone = event->ev_arg;
   18045 	isc_netaddr_t primaryip;
   18046 	isc_sockaddr_t sourceaddr;
   18047 	isc_sockaddr_t primaryaddr;
   18048 	isc_time_t now;
   18049 	const char *soa_before = "";
   18050 	bool loaded;
   18051 	isc_tlsctx_cache_t *zmgr_tlsctx_cache = NULL;
   18052 
   18053 	UNUSED(task);
   18054 
   18055 	INSIST(task == zone->task);
   18056 
   18057 	isc_event_free(&event);
   18058 
   18059 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   18060 		zone_xfrdone(zone, ISC_R_CANCELED);
   18061 		return;
   18062 	}
   18063 
   18064 	TIME_NOW(&now);
   18065 
   18066 	isc_sockaddr_format(&zone->primaryaddr, primary, sizeof(primary));
   18067 	if (dns_zonemgr_unreachable(zone->zmgr, &zone->primaryaddr,
   18068 				    &zone->sourceaddr, &now))
   18069 	{
   18070 		isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   18071 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   18072 			      "got_transfer_quota: skipping zone transfer as "
   18073 			      "primary %s (source %s) is unreachable (cached)",
   18074 			      primary, source);
   18075 		zone_xfrdone(zone, ISC_R_CANCELED);
   18076 		return;
   18077 	}
   18078 
   18079 	isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr);
   18080 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer);
   18081 
   18082 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   18083 		soa_before = "SOA before ";
   18084 	}
   18085 	/*
   18086 	 * Decide whether we should request IXFR or AXFR.
   18087 	 */
   18088 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   18089 	loaded = (zone->db != NULL);
   18090 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   18091 
   18092 	if (!loaded) {
   18093 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   18094 			      "no database exists yet, requesting AXFR of "
   18095 			      "initial version from %s",
   18096 			      primary);
   18097 		xfrtype = dns_rdatatype_axfr;
   18098 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
   18099 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   18100 			      "forced reload, requesting AXFR of "
   18101 			      "initial version from %s",
   18102 			      primary);
   18103 		xfrtype = dns_rdatatype_axfr;
   18104 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) {
   18105 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   18106 			      "retrying with AXFR from %s due to "
   18107 			      "previous IXFR failure",
   18108 			      primary);
   18109 		xfrtype = dns_rdatatype_axfr;
   18110 		LOCK_ZONE(zone);
   18111 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR);
   18112 		UNLOCK_ZONE(zone);
   18113 	} else {
   18114 		bool use_ixfr = true;
   18115 		if (peer != NULL) {
   18116 			result = dns_peer_getrequestixfr(peer, &use_ixfr);
   18117 		}
   18118 		if (peer == NULL || result != ISC_R_SUCCESS) {
   18119 			use_ixfr = zone->requestixfr;
   18120 		}
   18121 		if (!use_ixfr) {
   18122 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   18123 				      ISC_LOG_DEBUG(1),
   18124 				      "IXFR disabled, "
   18125 				      "requesting %sAXFR from %s",
   18126 				      soa_before, primary);
   18127 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   18128 				xfrtype = dns_rdatatype_soa;
   18129 			} else {
   18130 				xfrtype = dns_rdatatype_axfr;
   18131 			}
   18132 		} else {
   18133 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   18134 				      ISC_LOG_DEBUG(1),
   18135 				      "requesting IXFR from %s", primary);
   18136 			xfrtype = dns_rdatatype_ixfr;
   18137 		}
   18138 	}
   18139 
   18140 	/*
   18141 	 * Determine if we should attempt to sign the request with TSIG.
   18142 	 */
   18143 	result = ISC_R_NOTFOUND;
   18144 
   18145 	/*
   18146 	 * First, look for a tsig key in the primaries statement, then
   18147 	 * try for a server key.
   18148 	 */
   18149 	if ((zone->primarykeynames != NULL) &&
   18150 	    (zone->primarykeynames[zone->curprimary] != NULL))
   18151 	{
   18152 		dns_view_t *view = dns_zone_getview(zone);
   18153 		dns_name_t *keyname = zone->primarykeynames[zone->curprimary];
   18154 		result = dns_view_gettsig(view, keyname, &zone->tsigkey);
   18155 	}
   18156 	if (result != ISC_R_SUCCESS) {
   18157 		INSIST(zone->tsigkey == NULL);
   18158 		result = dns_view_getpeertsig(zone->view, &primaryip,
   18159 					      &zone->tsigkey);
   18160 	}
   18161 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   18162 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   18163 			      "could not get TSIG key for zone transfer: %s",
   18164 			      isc_result_totext(result));
   18165 	}
   18166 
   18167 	/*
   18168 	 * Get the TLS transport for the primary, if configured.
   18169 	 */
   18170 	if ((zone->primarytlsnames != NULL) &&
   18171 	    (zone->primarytlsnames[zone->curprimary] != NULL))
   18172 	{
   18173 		dns_view_t *view = dns_zone_getview(zone);
   18174 		dns_name_t *tlsname = zone->primarytlsnames[zone->curprimary];
   18175 		result = dns_view_gettransport(view, DNS_TRANSPORT_TLS, tlsname,
   18176 					       &zone->transport);
   18177 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   18178 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   18179 				      ISC_LOG_ERROR,
   18180 				      "could not get TLS configuration for "
   18181 				      "zone transfer: %s",
   18182 				      isc_result_totext(result));
   18183 		}
   18184 	}
   18185 
   18186 	LOCK_ZONE(zone);
   18187 	primaryaddr = zone->primaryaddr;
   18188 	sourceaddr = zone->sourceaddr;
   18189 	UNLOCK_ZONE(zone);
   18190 	INSIST(isc_sockaddr_pf(&primaryaddr) == isc_sockaddr_pf(&sourceaddr));
   18191 
   18192 	if (zone->xfr != NULL) {
   18193 		dns_xfrin_detach(&zone->xfr);
   18194 	}
   18195 
   18196 	zmgr_tlsctx_attach(zone->zmgr, &zmgr_tlsctx_cache);
   18197 
   18198 	result = dns_xfrin_create(zone, xfrtype, &primaryaddr, &sourceaddr,
   18199 				  zone->tsigkey, zone->transport,
   18200 				  zmgr_tlsctx_cache, zone->mctx,
   18201 				  zone->zmgr->netmgr, zone_xfrdone, &zone->xfr);
   18202 
   18203 	isc_tlsctx_cache_detach(&zmgr_tlsctx_cache);
   18204 
   18205 	/*
   18206 	 * Any failure in this function is handled like a failed
   18207 	 * zone transfer.  This ensures that we get removed from
   18208 	 * zmgr->xfrin_in_progress.
   18209 	 */
   18210 	if (result != ISC_R_SUCCESS) {
   18211 		zone_xfrdone(zone, result);
   18212 		return;
   18213 	}
   18214 
   18215 	LOCK_ZONE(zone);
   18216 	if (xfrtype == dns_rdatatype_axfr) {
   18217 		if (isc_sockaddr_pf(&primaryaddr) == PF_INET) {
   18218 			inc_stats(zone, dns_zonestatscounter_axfrreqv4);
   18219 		} else {
   18220 			inc_stats(zone, dns_zonestatscounter_axfrreqv6);
   18221 		}
   18222 	} else if (xfrtype == dns_rdatatype_ixfr) {
   18223 		if (isc_sockaddr_pf(&primaryaddr) == PF_INET) {
   18224 			inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
   18225 		} else {
   18226 			inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
   18227 		}
   18228 	}
   18229 	UNLOCK_ZONE(zone);
   18230 }
   18231 
   18232 /*
   18233  * Update forwarding support.
   18234  */
   18235 
   18236 static void
   18237 forward_destroy(dns_forward_t *forward) {
   18238 	forward->magic = 0;
   18239 	if (forward->request != NULL) {
   18240 		dns_request_destroy(&forward->request);
   18241 	}
   18242 	if (forward->msgbuf != NULL) {
   18243 		isc_buffer_free(&forward->msgbuf);
   18244 	}
   18245 	if (forward->zone != NULL) {
   18246 		LOCK(&forward->zone->lock);
   18247 		if (ISC_LINK_LINKED(forward, link)) {
   18248 			ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
   18249 		}
   18250 		UNLOCK(&forward->zone->lock);
   18251 		dns_zone_idetach(&forward->zone);
   18252 	}
   18253 	isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
   18254 }
   18255 
   18256 static isc_result_t
   18257 sendtoprimary(dns_forward_t *forward) {
   18258 	isc_result_t result;
   18259 	isc_sockaddr_t src;
   18260 
   18261 	LOCK_ZONE(forward->zone);
   18262 
   18263 	if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
   18264 		UNLOCK_ZONE(forward->zone);
   18265 		return (ISC_R_CANCELED);
   18266 	}
   18267 
   18268 	if (forward->which >= forward->zone->primariescnt) {
   18269 		UNLOCK_ZONE(forward->zone);
   18270 		return (ISC_R_NOMORE);
   18271 	}
   18272 
   18273 	forward->addr = forward->zone->primaries[forward->which];
   18274 	/*
   18275 	 * Always use TCP regardless of whether the original update
   18276 	 * used TCP.
   18277 	 * XXX The timeout may but a bit small if we are far down a
   18278 	 * transfer graph and have to try several primaries.
   18279 	 */
   18280 	switch (isc_sockaddr_pf(&forward->addr)) {
   18281 	case PF_INET:
   18282 		src = forward->zone->xfrsource4;
   18283 		break;
   18284 	case PF_INET6:
   18285 		src = forward->zone->xfrsource6;
   18286 		break;
   18287 	default:
   18288 		result = ISC_R_NOTIMPLEMENTED;
   18289 		goto unlock;
   18290 	}
   18291 	result = dns_request_createraw(forward->zone->view->requestmgr,
   18292 				       forward->msgbuf, &src, &forward->addr,
   18293 				       forward->options, 15 /* XXX */, 0, 0,
   18294 				       forward->zone->task, forward_callback,
   18295 				       forward, &forward->request);
   18296 	if (result == ISC_R_SUCCESS) {
   18297 		if (!ISC_LINK_LINKED(forward, link)) {
   18298 			ISC_LIST_APPEND(forward->zone->forwards, forward, link);
   18299 		}
   18300 	}
   18301 
   18302 unlock:
   18303 	UNLOCK_ZONE(forward->zone);
   18304 	return (result);
   18305 }
   18306 
   18307 static void
   18308 forward_callback(isc_task_t *task, isc_event_t *event) {
   18309 	const char me[] = "forward_callback";
   18310 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   18311 	dns_message_t *msg = NULL;
   18312 	char primary[ISC_SOCKADDR_FORMATSIZE];
   18313 	isc_result_t result;
   18314 	dns_forward_t *forward;
   18315 	dns_zone_t *zone;
   18316 
   18317 	UNUSED(task);
   18318 
   18319 	forward = revent->ev_arg;
   18320 	INSIST(DNS_FORWARD_VALID(forward));
   18321 	zone = forward->zone;
   18322 	INSIST(DNS_ZONE_VALID(zone));
   18323 
   18324 	ENTER;
   18325 
   18326 	isc_sockaddr_format(&forward->addr, primary, sizeof(primary));
   18327 
   18328 	if (revent->result != ISC_R_SUCCESS) {
   18329 		dns_zone_log(zone, ISC_LOG_INFO,
   18330 			     "could not forward dynamic update to %s: %s",
   18331 			     primary, isc_result_totext(revent->result));
   18332 		goto next_primary;
   18333 	}
   18334 
   18335 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   18336 
   18337 	result = dns_request_getresponse(revent->request, msg,
   18338 					 DNS_MESSAGEPARSE_PRESERVEORDER |
   18339 						 DNS_MESSAGEPARSE_CLONEBUFFER);
   18340 	if (result != ISC_R_SUCCESS) {
   18341 		goto next_primary;
   18342 	}
   18343 
   18344 	/*
   18345 	 * Unexpected opcode.
   18346 	 */
   18347 	if (msg->opcode != dns_opcode_update) {
   18348 		char opcode[128];
   18349 		isc_buffer_t rb;
   18350 
   18351 		isc_buffer_init(&rb, opcode, sizeof(opcode));
   18352 		(void)dns_opcode_totext(msg->opcode, &rb);
   18353 
   18354 		dns_zone_log(zone, ISC_LOG_INFO,
   18355 			     "forwarding dynamic update: "
   18356 			     "unexpected opcode (%.*s) from %s",
   18357 			     (int)rb.used, opcode, primary);
   18358 		goto next_primary;
   18359 	}
   18360 
   18361 	switch (msg->rcode) {
   18362 	/*
   18363 	 * Pass these rcodes back to client.
   18364 	 */
   18365 	case dns_rcode_noerror:
   18366 	case dns_rcode_yxdomain:
   18367 	case dns_rcode_yxrrset:
   18368 	case dns_rcode_nxrrset:
   18369 	case dns_rcode_refused:
   18370 	case dns_rcode_nxdomain: {
   18371 		char rcode[128];
   18372 		isc_buffer_t rb;
   18373 
   18374 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   18375 		(void)dns_rcode_totext(msg->rcode, &rb);
   18376 		dns_zone_log(zone, ISC_LOG_INFO,
   18377 			     "forwarded dynamic update: "
   18378 			     "primary %s returned: %.*s",
   18379 			     primary, (int)rb.used, rcode);
   18380 		break;
   18381 	}
   18382 
   18383 	/* These should not occur if the primaries/zone are valid. */
   18384 	case dns_rcode_notzone:
   18385 	case dns_rcode_notauth: {
   18386 		char rcode[128];
   18387 		isc_buffer_t rb;
   18388 
   18389 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   18390 		(void)dns_rcode_totext(msg->rcode, &rb);
   18391 		dns_zone_log(zone, ISC_LOG_WARNING,
   18392 			     "forwarding dynamic update: "
   18393 			     "unexpected response: primary %s returned: %.*s",
   18394 			     primary, (int)rb.used, rcode);
   18395 		goto next_primary;
   18396 	}
   18397 
   18398 	/* Try another server for these rcodes. */
   18399 	case dns_rcode_formerr:
   18400 	case dns_rcode_servfail:
   18401 	case dns_rcode_notimp:
   18402 	case dns_rcode_badvers:
   18403 	default:
   18404 		goto next_primary;
   18405 	}
   18406 
   18407 	/* call callback */
   18408 	(forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
   18409 	msg = NULL;
   18410 	dns_request_destroy(&forward->request);
   18411 	forward_destroy(forward);
   18412 	isc_event_free(&event);
   18413 	return;
   18414 
   18415 next_primary:
   18416 	if (msg != NULL) {
   18417 		dns_message_detach(&msg);
   18418 	}
   18419 	isc_event_free(&event);
   18420 	forward->which++;
   18421 	dns_request_destroy(&forward->request);
   18422 	result = sendtoprimary(forward);
   18423 	if (result != ISC_R_SUCCESS) {
   18424 		/* call callback */
   18425 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   18426 			     "exhausted dynamic update forwarder list");
   18427 		(forward->callback)(forward->callback_arg, result, NULL);
   18428 		forward_destroy(forward);
   18429 	}
   18430 }
   18431 
   18432 isc_result_t
   18433 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
   18434 		       dns_updatecallback_t callback, void *callback_arg) {
   18435 	dns_forward_t *forward;
   18436 	isc_result_t result;
   18437 	isc_region_t *mr;
   18438 
   18439 	REQUIRE(DNS_ZONE_VALID(zone));
   18440 	REQUIRE(msg != NULL);
   18441 	REQUIRE(callback != NULL);
   18442 
   18443 	forward = isc_mem_get(zone->mctx, sizeof(*forward));
   18444 
   18445 	forward->request = NULL;
   18446 	forward->zone = NULL;
   18447 	forward->msgbuf = NULL;
   18448 	forward->which = 0;
   18449 	forward->mctx = 0;
   18450 	forward->callback = callback;
   18451 	forward->callback_arg = callback_arg;
   18452 	ISC_LINK_INIT(forward, link);
   18453 	forward->magic = FORWARD_MAGIC;
   18454 	forward->options = DNS_REQUESTOPT_TCP;
   18455 	/*
   18456 	 * If we have a SIG(0) signed message we need to preserve the
   18457 	 * query id as that is included in the SIG(0) computation.
   18458 	 */
   18459 	if (msg->sig0 != NULL) {
   18460 		forward->options |= DNS_REQUESTOPT_FIXEDID;
   18461 	}
   18462 
   18463 	mr = dns_message_getrawmessage(msg);
   18464 	if (mr == NULL) {
   18465 		result = ISC_R_UNEXPECTEDEND;
   18466 		goto cleanup;
   18467 	}
   18468 
   18469 	isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
   18470 	result = isc_buffer_copyregion(forward->msgbuf, mr);
   18471 	if (result != ISC_R_SUCCESS) {
   18472 		goto cleanup;
   18473 	}
   18474 
   18475 	isc_mem_attach(zone->mctx, &forward->mctx);
   18476 	dns_zone_iattach(zone, &forward->zone);
   18477 	result = sendtoprimary(forward);
   18478 
   18479 cleanup:
   18480 	if (result != ISC_R_SUCCESS) {
   18481 		forward_destroy(forward);
   18482 	}
   18483 	return (result);
   18484 }
   18485 
   18486 isc_result_t
   18487 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
   18488 	REQUIRE(DNS_ZONE_VALID(zone));
   18489 	REQUIRE(next != NULL && *next == NULL);
   18490 
   18491 	*next = ISC_LIST_NEXT(zone, link);
   18492 	if (*next == NULL) {
   18493 		return (ISC_R_NOMORE);
   18494 	} else {
   18495 		return (ISC_R_SUCCESS);
   18496 	}
   18497 }
   18498 
   18499 isc_result_t
   18500 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
   18501 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18502 	REQUIRE(first != NULL && *first == NULL);
   18503 
   18504 	*first = ISC_LIST_HEAD(zmgr->zones);
   18505 	if (*first == NULL) {
   18506 		return (ISC_R_NOMORE);
   18507 	} else {
   18508 		return (ISC_R_SUCCESS);
   18509 	}
   18510 }
   18511 
   18512 /***
   18513  ***	Zone manager.
   18514  ***/
   18515 
   18516 #define KEYMGMT_OVERCOMMIT 3
   18517 #define KEYMGMT_BITS_MIN   2U
   18518 #define KEYMGMT_BITS_MAX   32U
   18519 
   18520 /*
   18521  * WMM: Static hash functions copied from lib/dns/rbtdb.c. Should be moved to
   18522  * lib/isc/hash.c when we refactor the hash table code.
   18523  */
   18524 #define GOLDEN_RATIO_32 0x61C88647
   18525 #define HASHSIZE(bits)	(UINT64_C(1) << (bits))
   18526 
   18527 static uint32_t
   18528 hash_index(uint32_t val, uint32_t bits) {
   18529 	return (val * GOLDEN_RATIO_32 >> (32 - bits));
   18530 }
   18531 
   18532 static uint32_t
   18533 hash_bits_grow(uint32_t bits, uint32_t count) {
   18534 	uint32_t newbits = bits;
   18535 	while (count >= HASHSIZE(newbits) && newbits < KEYMGMT_BITS_MAX) {
   18536 		newbits++;
   18537 	}
   18538 	return (newbits);
   18539 }
   18540 
   18541 static uint32_t
   18542 hash_bits_shrink(uint32_t bits, uint32_t count) {
   18543 	uint32_t newbits = bits;
   18544 	while (count <= HASHSIZE(newbits) && newbits > KEYMGMT_BITS_MIN) {
   18545 		newbits--;
   18546 	}
   18547 	return (newbits);
   18548 }
   18549 
   18550 static void
   18551 zonemgr_keymgmt_init(dns_zonemgr_t *zmgr) {
   18552 	dns_keymgmt_t *mgmt = isc_mem_get(zmgr->mctx, sizeof(*mgmt));
   18553 	uint32_t size;
   18554 
   18555 	*mgmt = (dns_keymgmt_t){
   18556 		.bits = KEYMGMT_BITS_MIN,
   18557 	};
   18558 	isc_mem_attach(zmgr->mctx, &mgmt->mctx);
   18559 	isc_rwlock_init(&mgmt->lock, 0, 0);
   18560 
   18561 	size = HASHSIZE(mgmt->bits);
   18562 	mgmt->table = isc_mem_get(mgmt->mctx, sizeof(*mgmt->table) * size);
   18563 	memset(mgmt->table, 0, size * sizeof(mgmt->table[0]));
   18564 
   18565 	atomic_init(&mgmt->count, 0);
   18566 	mgmt->magic = KEYMGMT_MAGIC;
   18567 
   18568 	zmgr->keymgmt = mgmt;
   18569 }
   18570 
   18571 static void
   18572 zonemgr_keymgmt_destroy(dns_zonemgr_t *zmgr) {
   18573 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18574 	uint32_t size;
   18575 
   18576 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18577 
   18578 	size = HASHSIZE(mgmt->bits);
   18579 
   18580 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18581 	INSIST(mgmt->count == 0);
   18582 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18583 
   18584 	mgmt->magic = 0;
   18585 	isc_rwlock_destroy(&mgmt->lock);
   18586 	isc_mem_put(mgmt->mctx, mgmt->table, size * sizeof(mgmt->table[0]));
   18587 	isc_mem_putanddetach(&mgmt->mctx, mgmt, sizeof(dns_keymgmt_t));
   18588 }
   18589 
   18590 static void
   18591 zonemgr_keymgmt_resize(dns_zonemgr_t *zmgr) {
   18592 	dns_keyfileio_t **newtable;
   18593 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18594 	uint32_t bits, newbits, count, size, newsize;
   18595 	bool grow;
   18596 
   18597 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18598 
   18599 	RWLOCK(&mgmt->lock, isc_rwlocktype_read);
   18600 	count = atomic_load_relaxed(&mgmt->count);
   18601 	bits = mgmt->bits;
   18602 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_read);
   18603 
   18604 	size = HASHSIZE(bits);
   18605 	INSIST(size > 0);
   18606 
   18607 	if (count >= (size * KEYMGMT_OVERCOMMIT)) {
   18608 		grow = true;
   18609 	} else if (count < (size / 2)) {
   18610 		grow = false;
   18611 	} else {
   18612 		/* No need to resize. */
   18613 		return;
   18614 	}
   18615 
   18616 	if (grow) {
   18617 		newbits = hash_bits_grow(bits, count);
   18618 	} else {
   18619 		newbits = hash_bits_shrink(bits, count);
   18620 	}
   18621 
   18622 	if (newbits == bits) {
   18623 		/*
   18624 		 * Bit values may stay the same if maximum or minimum is
   18625 		 * reached.
   18626 		 */
   18627 		return;
   18628 	}
   18629 
   18630 	newsize = HASHSIZE(newbits);
   18631 	INSIST(newsize > 0);
   18632 
   18633 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18634 
   18635 	newtable = isc_mem_get(mgmt->mctx, sizeof(dns_keyfileio_t *) * newsize);
   18636 	memset(newtable, 0, sizeof(dns_keyfileio_t *) * newsize);
   18637 
   18638 	for (unsigned int i = 0; i < size; i++) {
   18639 		dns_keyfileio_t *kfio, *next;
   18640 		for (kfio = mgmt->table[i]; kfio != NULL; kfio = next) {
   18641 			uint32_t hash = hash_index(kfio->hashval, newbits);
   18642 			next = kfio->next;
   18643 			kfio->next = newtable[hash];
   18644 			newtable[hash] = kfio;
   18645 		}
   18646 		mgmt->table[i] = NULL;
   18647 	}
   18648 
   18649 	isc_mem_put(mgmt->mctx, mgmt->table, sizeof(*mgmt->table) * size);
   18650 	mgmt->bits = newbits;
   18651 	mgmt->table = newtable;
   18652 
   18653 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18654 }
   18655 
   18656 static void
   18657 zonemgr_keymgmt_add(dns_zonemgr_t *zmgr, dns_zone_t *zone,
   18658 		    dns_keyfileio_t **added) {
   18659 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18660 	uint32_t hashval, hash;
   18661 	dns_keyfileio_t *kfio, *next;
   18662 
   18663 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18664 	REQUIRE(added != NULL && *added == NULL);
   18665 
   18666 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18667 
   18668 	hashval = dns_name_hash(&zone->origin, false);
   18669 	hash = hash_index(hashval, mgmt->bits);
   18670 
   18671 	for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) {
   18672 		next = kfio->next;
   18673 		if (dns_name_equal(kfio->name, &zone->origin)) {
   18674 			/* Already in table, increment the counter. */
   18675 			isc_refcount_increment(&kfio->references);
   18676 			break;
   18677 		}
   18678 	}
   18679 
   18680 	if (kfio == NULL) {
   18681 		/* No entry found, add it. */
   18682 		kfio = isc_mem_get(mgmt->mctx, sizeof(*kfio));
   18683 		*kfio = (dns_keyfileio_t){
   18684 			.hashval = hashval,
   18685 			.next = mgmt->table[hash],
   18686 			.magic = KEYFILEIO_MAGIC,
   18687 		};
   18688 
   18689 		isc_refcount_init(&kfio->references, 1);
   18690 
   18691 		kfio->name = dns_fixedname_initname(&kfio->fname);
   18692 		dns_name_copy(&zone->origin, kfio->name);
   18693 
   18694 		isc_mutex_init(&kfio->lock);
   18695 
   18696 		mgmt->table[hash] = kfio;
   18697 
   18698 		atomic_fetch_add_relaxed(&mgmt->count, 1);
   18699 	}
   18700 
   18701 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18702 
   18703 	*added = kfio;
   18704 
   18705 	/*
   18706 	 * Call resize, that function will also check if resize is necessary.
   18707 	 */
   18708 	zonemgr_keymgmt_resize(zmgr);
   18709 }
   18710 
   18711 static void
   18712 zonemgr_keymgmt_delete(dns_zonemgr_t *zmgr, dns_zone_t *zone,
   18713 		       dns_keyfileio_t **deleted) {
   18714 	dns_keymgmt_t *mgmt = zmgr->keymgmt;
   18715 	uint32_t hashval, hash;
   18716 	dns_keyfileio_t *kfio, *prev, *next;
   18717 
   18718 	REQUIRE(DNS_KEYMGMT_VALID(mgmt));
   18719 	REQUIRE(deleted != NULL && DNS_KEYFILEIO_VALID(*deleted));
   18720 
   18721 	RWLOCK(&mgmt->lock, isc_rwlocktype_write);
   18722 
   18723 	hashval = dns_name_hash(&zone->origin, false);
   18724 	hash = hash_index(hashval, mgmt->bits);
   18725 
   18726 	prev = NULL;
   18727 	for (kfio = mgmt->table[hash]; kfio != NULL; kfio = next) {
   18728 		next = kfio->next;
   18729 		if (dns_name_equal(kfio->name, &zone->origin)) {
   18730 			INSIST(kfio == *deleted);
   18731 			*deleted = NULL;
   18732 
   18733 			if (isc_refcount_decrement(&kfio->references) == 1) {
   18734 				if (prev == NULL) {
   18735 					mgmt->table[hash] = kfio->next;
   18736 				} else {
   18737 					prev->next = kfio->next;
   18738 				}
   18739 
   18740 				isc_refcount_destroy(&kfio->references);
   18741 				isc_mutex_destroy(&kfio->lock);
   18742 				isc_mem_put(mgmt->mctx, kfio, sizeof(*kfio));
   18743 
   18744 				atomic_fetch_sub_relaxed(&mgmt->count, 1);
   18745 			}
   18746 			break;
   18747 		}
   18748 
   18749 		prev = kfio;
   18750 	}
   18751 
   18752 	RWUNLOCK(&mgmt->lock, isc_rwlocktype_write);
   18753 
   18754 	/*
   18755 	 * Call resize, that function will also check if resize is necessary.
   18756 	 */
   18757 	zonemgr_keymgmt_resize(zmgr);
   18758 }
   18759 
   18760 isc_result_t
   18761 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
   18762 		   isc_timermgr_t *timermgr, isc_nm_t *netmgr,
   18763 		   dns_zonemgr_t **zmgrp) {
   18764 	dns_zonemgr_t *zmgr;
   18765 	isc_result_t result;
   18766 
   18767 	zmgr = isc_mem_get(mctx, sizeof(*zmgr));
   18768 	zmgr->mctx = NULL;
   18769 	isc_refcount_init(&zmgr->refs, 1);
   18770 	isc_mem_attach(mctx, &zmgr->mctx);
   18771 	zmgr->taskmgr = taskmgr;
   18772 	zmgr->timermgr = timermgr;
   18773 	zmgr->netmgr = netmgr;
   18774 	zmgr->zonetasks = NULL;
   18775 	zmgr->loadtasks = NULL;
   18776 	zmgr->mctxpool = NULL;
   18777 	zmgr->task = NULL;
   18778 	zmgr->checkdsrl = NULL;
   18779 	zmgr->notifyrl = NULL;
   18780 	zmgr->refreshrl = NULL;
   18781 	zmgr->startupnotifyrl = NULL;
   18782 	zmgr->startuprefreshrl = NULL;
   18783 	ISC_LIST_INIT(zmgr->zones);
   18784 	ISC_LIST_INIT(zmgr->waiting_for_xfrin);
   18785 	ISC_LIST_INIT(zmgr->xfrin_in_progress);
   18786 	memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
   18787 	for (size_t i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18788 		atomic_init(&zmgr->unreachable[i].expire, 0);
   18789 	}
   18790 	isc_rwlock_init(&zmgr->rwlock, 0, 0);
   18791 
   18792 	zmgr->transfersin = 10;
   18793 	zmgr->transfersperns = 2;
   18794 
   18795 	/* Unreachable lock. */
   18796 	isc_rwlock_init(&zmgr->urlock, 0, 0);
   18797 
   18798 	/* Create a single task for queueing of SOA queries. */
   18799 	result = isc_task_create(taskmgr, 1, &zmgr->task);
   18800 	if (result != ISC_R_SUCCESS) {
   18801 		goto free_urlock;
   18802 	}
   18803 
   18804 	isc_task_setname(zmgr->task, "zmgr", zmgr);
   18805 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18806 					&zmgr->checkdsrl);
   18807 	if (result != ISC_R_SUCCESS) {
   18808 		goto free_task;
   18809 	}
   18810 
   18811 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18812 					&zmgr->notifyrl);
   18813 	if (result != ISC_R_SUCCESS) {
   18814 		goto free_checkdsrl;
   18815 	}
   18816 
   18817 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18818 					&zmgr->refreshrl);
   18819 	if (result != ISC_R_SUCCESS) {
   18820 		goto free_notifyrl;
   18821 	}
   18822 
   18823 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18824 					&zmgr->startupnotifyrl);
   18825 	if (result != ISC_R_SUCCESS) {
   18826 		goto free_refreshrl;
   18827 	}
   18828 
   18829 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18830 					&zmgr->startuprefreshrl);
   18831 	if (result != ISC_R_SUCCESS) {
   18832 		goto free_startupnotifyrl;
   18833 	}
   18834 
   18835 	/* Key file I/O locks. */
   18836 	zonemgr_keymgmt_init(zmgr);
   18837 
   18838 	/* Default to 20 refresh queries / notifies / checkds per second. */
   18839 	setrl(zmgr->checkdsrl, &zmgr->checkdsrate, 20);
   18840 	setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
   18841 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
   18842 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
   18843 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
   18844 	isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true);
   18845 	isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true);
   18846 
   18847 	zmgr->iolimit = 1;
   18848 	zmgr->ioactive = 0;
   18849 	ISC_LIST_INIT(zmgr->high);
   18850 	ISC_LIST_INIT(zmgr->low);
   18851 
   18852 	isc_mutex_init(&zmgr->iolock);
   18853 
   18854 	zmgr->tlsctx_cache = NULL;
   18855 	isc_rwlock_init(&zmgr->tlsctx_cache_rwlock, 0, 0);
   18856 
   18857 	zmgr->magic = ZONEMGR_MAGIC;
   18858 
   18859 	*zmgrp = zmgr;
   18860 	return (ISC_R_SUCCESS);
   18861 
   18862 #if 0
   18863  free_iolock:
   18864 	isc_mutex_destroy(&zmgr->iolock);
   18865 #endif /* if 0 */
   18866 free_startupnotifyrl:
   18867 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   18868 free_refreshrl:
   18869 	isc_ratelimiter_detach(&zmgr->refreshrl);
   18870 free_notifyrl:
   18871 	isc_ratelimiter_detach(&zmgr->notifyrl);
   18872 free_checkdsrl:
   18873 	isc_ratelimiter_detach(&zmgr->checkdsrl);
   18874 free_task:
   18875 	isc_task_detach(&zmgr->task);
   18876 free_urlock:
   18877 	isc_rwlock_destroy(&zmgr->urlock);
   18878 	isc_rwlock_destroy(&zmgr->rwlock);
   18879 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   18880 	isc_mem_detach(&mctx);
   18881 	return (result);
   18882 }
   18883 
   18884 isc_result_t
   18885 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
   18886 	isc_result_t result;
   18887 	isc_mem_t *mctx = NULL;
   18888 	dns_zone_t *zone = NULL;
   18889 	void *item;
   18890 
   18891 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18892 	REQUIRE(zonep != NULL && *zonep == NULL);
   18893 
   18894 	if (zmgr->mctxpool == NULL) {
   18895 		return (ISC_R_FAILURE);
   18896 	}
   18897 
   18898 	item = isc_pool_get(zmgr->mctxpool);
   18899 	if (item == NULL) {
   18900 		return (ISC_R_FAILURE);
   18901 	}
   18902 
   18903 	isc_mem_attach((isc_mem_t *)item, &mctx);
   18904 	result = dns_zone_create(&zone, mctx);
   18905 	isc_mem_detach(&mctx);
   18906 
   18907 	if (result == ISC_R_SUCCESS) {
   18908 		*zonep = zone;
   18909 	}
   18910 
   18911 	return (result);
   18912 }
   18913 
   18914 isc_result_t
   18915 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18916 	isc_result_t result;
   18917 
   18918 	REQUIRE(DNS_ZONE_VALID(zone));
   18919 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18920 
   18921 	if (zmgr->zonetasks == NULL) {
   18922 		return (ISC_R_FAILURE);
   18923 	}
   18924 
   18925 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18926 	LOCK_ZONE(zone);
   18927 	REQUIRE(zone->task == NULL);
   18928 	REQUIRE(zone->timer == NULL);
   18929 	REQUIRE(zone->zmgr == NULL);
   18930 
   18931 	isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
   18932 	isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
   18933 
   18934 	/*
   18935 	 * Set the task name.  The tag will arbitrarily point to one
   18936 	 * of the zones sharing the task (in practice, the one
   18937 	 * to be managed last).
   18938 	 */
   18939 	isc_task_setname(zone->task, "zone", zone);
   18940 	isc_task_setname(zone->loadtask, "loadzone", zone);
   18941 
   18942 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   18943 				  NULL, zone->task, zone_timer, zone,
   18944 				  &zone->timer);
   18945 
   18946 	if (result != ISC_R_SUCCESS) {
   18947 		goto cleanup_tasks;
   18948 	}
   18949 
   18950 	/*
   18951 	 * The timer "holds" a iref.
   18952 	 */
   18953 	isc_refcount_increment0(&zone->irefs);
   18954 
   18955 	zonemgr_keymgmt_add(zmgr, zone, &zone->kfio);
   18956 	INSIST(zone->kfio != NULL);
   18957 
   18958 	ISC_LIST_APPEND(zmgr->zones, zone, link);
   18959 	zone->zmgr = zmgr;
   18960 	isc_refcount_increment(&zmgr->refs);
   18961 
   18962 	goto unlock;
   18963 
   18964 cleanup_tasks:
   18965 	isc_task_detach(&zone->loadtask);
   18966 	isc_task_detach(&zone->task);
   18967 
   18968 unlock:
   18969 	UNLOCK_ZONE(zone);
   18970 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18971 	return (result);
   18972 }
   18973 
   18974 void
   18975 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18976 	REQUIRE(DNS_ZONE_VALID(zone));
   18977 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18978 	REQUIRE(zone->zmgr == zmgr);
   18979 
   18980 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18981 	LOCK_ZONE(zone);
   18982 
   18983 	ISC_LIST_UNLINK(zmgr->zones, zone, link);
   18984 
   18985 	if (zone->kfio != NULL) {
   18986 		zonemgr_keymgmt_delete(zmgr, zone, &zone->kfio);
   18987 		ENSURE(zone->kfio == NULL);
   18988 	}
   18989 
   18990 	/* Detach below, outside of the write lock. */
   18991 	zone->zmgr = NULL;
   18992 
   18993 	UNLOCK_ZONE(zone);
   18994 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18995 
   18996 	dns_zonemgr_detach(&zmgr);
   18997 }
   18998 
   18999 void
   19000 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
   19001 	REQUIRE(DNS_ZONEMGR_VALID(source));
   19002 	REQUIRE(target != NULL && *target == NULL);
   19003 
   19004 	isc_refcount_increment(&source->refs);
   19005 
   19006 	*target = source;
   19007 }
   19008 
   19009 void
   19010 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
   19011 	dns_zonemgr_t *zmgr;
   19012 
   19013 	REQUIRE(zmgrp != NULL);
   19014 	zmgr = *zmgrp;
   19015 	*zmgrp = NULL;
   19016 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19017 
   19018 	if (isc_refcount_decrement(&zmgr->refs) == 1) {
   19019 		zonemgr_free(zmgr);
   19020 	}
   19021 }
   19022 
   19023 isc_result_t
   19024 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
   19025 	dns_zone_t *p;
   19026 
   19027 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19028 
   19029 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19030 	for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL;
   19031 	     p = ISC_LIST_NEXT(p, link))
   19032 	{
   19033 		dns_zone_maintenance(p);
   19034 	}
   19035 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19036 
   19037 	/*
   19038 	 * Recent configuration changes may have increased the
   19039 	 * amount of available transfers quota.  Make sure any
   19040 	 * transfers currently blocked on quota get started if
   19041 	 * possible.
   19042 	 */
   19043 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   19044 	zmgr_resume_xfrs(zmgr, true);
   19045 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   19046 	return (ISC_R_SUCCESS);
   19047 }
   19048 
   19049 void
   19050 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
   19051 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19052 
   19053 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   19054 	zmgr_resume_xfrs(zmgr, true);
   19055 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   19056 }
   19057 
   19058 void
   19059 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
   19060 	dns_zone_t *zone;
   19061 
   19062 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19063 
   19064 	isc_ratelimiter_shutdown(zmgr->checkdsrl);
   19065 	isc_ratelimiter_shutdown(zmgr->notifyrl);
   19066 	isc_ratelimiter_shutdown(zmgr->refreshrl);
   19067 	isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
   19068 	isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
   19069 
   19070 	if (zmgr->task != NULL) {
   19071 		isc_task_destroy(&zmgr->task);
   19072 	}
   19073 	if (zmgr->zonetasks != NULL) {
   19074 		isc_taskpool_destroy(&zmgr->zonetasks);
   19075 	}
   19076 	if (zmgr->loadtasks != NULL) {
   19077 		isc_taskpool_destroy(&zmgr->loadtasks);
   19078 	}
   19079 	if (zmgr->mctxpool != NULL) {
   19080 		isc_pool_destroy(&zmgr->mctxpool);
   19081 	}
   19082 
   19083 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19084 	for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19085 	     zone = ISC_LIST_NEXT(zone, link))
   19086 	{
   19087 		LOCK_ZONE(zone);
   19088 		forward_cancel(zone);
   19089 		UNLOCK_ZONE(zone);
   19090 	}
   19091 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19092 }
   19093 
   19094 static isc_result_t
   19095 mctxinit(void **target, void *arg) {
   19096 	isc_mem_t *mctx = NULL;
   19097 
   19098 	UNUSED(arg);
   19099 
   19100 	REQUIRE(target != NULL && *target == NULL);
   19101 
   19102 	isc_mem_create(&mctx);
   19103 	isc_mem_setname(mctx, "zonemgr-pool");
   19104 
   19105 	*target = mctx;
   19106 	return (ISC_R_SUCCESS);
   19107 }
   19108 
   19109 static void
   19110 mctxfree(void **target) {
   19111 	isc_mem_t *mctx = *(isc_mem_t **)target;
   19112 	isc_mem_detach(&mctx);
   19113 	*target = NULL;
   19114 }
   19115 
   19116 #define ZONES_PER_TASK 100
   19117 #define ZONES_PER_MCTX 1000
   19118 
   19119 isc_result_t
   19120 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
   19121 	isc_result_t result;
   19122 	int ntasks = num_zones / ZONES_PER_TASK;
   19123 	int nmctx = num_zones / ZONES_PER_MCTX;
   19124 	isc_taskpool_t *pool = NULL;
   19125 	isc_pool_t *mctxpool = NULL;
   19126 
   19127 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19128 
   19129 	/*
   19130 	 * For anything fewer than 1000 zones we use 10 tasks in
   19131 	 * the task pools.  More than that, and we'll scale at one
   19132 	 * task per 100 zones.  Similarly, for anything smaller than
   19133 	 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
   19134 	 */
   19135 	if (ntasks < 10) {
   19136 		ntasks = 10;
   19137 	}
   19138 	if (nmctx < 2) {
   19139 		nmctx = 2;
   19140 	}
   19141 
   19142 	/* Create or resize the zone task pools. */
   19143 	if (zmgr->zonetasks == NULL) {
   19144 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   19145 					     2, false, &pool);
   19146 	} else {
   19147 		result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, false,
   19148 					     &pool);
   19149 	}
   19150 
   19151 	if (result == ISC_R_SUCCESS) {
   19152 		zmgr->zonetasks = pool;
   19153 	}
   19154 
   19155 	/*
   19156 	 * We always set all tasks in the zone-load task pool to
   19157 	 * privileged.  This prevents other tasks in the system from
   19158 	 * running while the server task manager is in privileged
   19159 	 * mode.
   19160 	 */
   19161 	pool = NULL;
   19162 	if (zmgr->loadtasks == NULL) {
   19163 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   19164 					     UINT_MAX, true, &pool);
   19165 	} else {
   19166 		result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, true,
   19167 					     &pool);
   19168 	}
   19169 
   19170 	if (result == ISC_R_SUCCESS) {
   19171 		zmgr->loadtasks = pool;
   19172 	}
   19173 
   19174 	/* Create or resize the zone memory context pool. */
   19175 	if (zmgr->mctxpool == NULL) {
   19176 		result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit,
   19177 					 NULL, &mctxpool);
   19178 	} else {
   19179 		result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
   19180 	}
   19181 
   19182 	if (result == ISC_R_SUCCESS) {
   19183 		zmgr->mctxpool = mctxpool;
   19184 	}
   19185 
   19186 	return (result);
   19187 }
   19188 
   19189 static void
   19190 zonemgr_free(dns_zonemgr_t *zmgr) {
   19191 	isc_mem_t *mctx;
   19192 
   19193 	INSIST(ISC_LIST_EMPTY(zmgr->zones));
   19194 
   19195 	zmgr->magic = 0;
   19196 
   19197 	isc_refcount_destroy(&zmgr->refs);
   19198 	isc_mutex_destroy(&zmgr->iolock);
   19199 	isc_ratelimiter_detach(&zmgr->checkdsrl);
   19200 	isc_ratelimiter_detach(&zmgr->notifyrl);
   19201 	isc_ratelimiter_detach(&zmgr->refreshrl);
   19202 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   19203 	isc_ratelimiter_detach(&zmgr->startuprefreshrl);
   19204 
   19205 	isc_rwlock_destroy(&zmgr->urlock);
   19206 	isc_rwlock_destroy(&zmgr->rwlock);
   19207 	isc_rwlock_destroy(&zmgr->tlsctx_cache_rwlock);
   19208 
   19209 	zonemgr_keymgmt_destroy(zmgr);
   19210 
   19211 	mctx = zmgr->mctx;
   19212 	if (zmgr->tlsctx_cache != NULL) {
   19213 		isc_tlsctx_cache_detach(&zmgr->tlsctx_cache);
   19214 	}
   19215 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   19216 	isc_mem_detach(&mctx);
   19217 }
   19218 
   19219 void
   19220 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
   19221 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19222 
   19223 	zmgr->transfersin = value;
   19224 }
   19225 
   19226 uint32_t
   19227 dns_zonemgr_gettransfersin(dns_zonemgr_t *zmgr) {
   19228 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19229 
   19230 	return (zmgr->transfersin);
   19231 }
   19232 
   19233 void
   19234 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
   19235 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19236 
   19237 	zmgr->transfersperns = value;
   19238 }
   19239 
   19240 uint32_t
   19241 dns_zonemgr_gettransfersperns(dns_zonemgr_t *zmgr) {
   19242 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19243 
   19244 	return (zmgr->transfersperns);
   19245 }
   19246 
   19247 isc_taskmgr_t *
   19248 dns_zonemgr_gettaskmgr(dns_zonemgr_t *zmgr) {
   19249 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19250 
   19251 	return (zmgr->taskmgr);
   19252 }
   19253 
   19254 isc_timermgr_t *
   19255 dns_zonemgr_gettimermgr(dns_zonemgr_t *zmgr) {
   19256 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19257 
   19258 	return (zmgr->timermgr);
   19259 }
   19260 
   19261 /*
   19262  * Try to start a new incoming zone transfer to fill a quota
   19263  * slot that was just vacated.
   19264  *
   19265  * Requires:
   19266  *	The zone manager is locked by the caller.
   19267  */
   19268 static void
   19269 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) {
   19270 	dns_zone_t *zone;
   19271 	dns_zone_t *next;
   19272 
   19273 	for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL;
   19274 	     zone = next)
   19275 	{
   19276 		isc_result_t result;
   19277 		next = ISC_LIST_NEXT(zone, statelink);
   19278 		result = zmgr_start_xfrin_ifquota(zmgr, zone);
   19279 		if (result == ISC_R_SUCCESS) {
   19280 			if (multi) {
   19281 				continue;
   19282 			}
   19283 			/*
   19284 			 * We successfully filled the slot.  We're done.
   19285 			 */
   19286 			break;
   19287 		} else if (result == ISC_R_QUOTA) {
   19288 			/*
   19289 			 * Not enough quota.  This is probably the per-server
   19290 			 * quota, because we usually get called when a unit of
   19291 			 * global quota has just been freed.  Try the next
   19292 			 * zone, it may succeed if it uses another primary.
   19293 			 */
   19294 			continue;
   19295 		} else {
   19296 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   19297 				      ISC_LOG_DEBUG(1),
   19298 				      "starting zone transfer: %s",
   19299 				      isc_result_totext(result));
   19300 			break;
   19301 		}
   19302 	}
   19303 }
   19304 
   19305 /*
   19306  * Try to start an incoming zone transfer for 'zone', quota permitting.
   19307  *
   19308  * Requires:
   19309  *	The zone manager is locked by the caller.
   19310  *
   19311  * Returns:
   19312  *	ISC_R_SUCCESS	There was enough quota and we attempted to
   19313  *			start a transfer.  zone_xfrdone() has been or will
   19314  *			be called.
   19315  *	ISC_R_QUOTA	Not enough quota.
   19316  *	Others		Failure.
   19317  */
   19318 static isc_result_t
   19319 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   19320 	dns_peer_t *peer = NULL;
   19321 	isc_netaddr_t primaryip;
   19322 	uint32_t nxfrsin, nxfrsperns;
   19323 	dns_zone_t *x;
   19324 	uint32_t maxtransfersin, maxtransfersperns;
   19325 	isc_event_t *e;
   19326 
   19327 	/*
   19328 	 * If we are exiting just pretend we got quota so the zone will
   19329 	 * be cleaned up in the zone's task context.
   19330 	 */
   19331 	LOCK_ZONE(zone);
   19332 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   19333 		UNLOCK_ZONE(zone);
   19334 		goto gotquota;
   19335 	}
   19336 
   19337 	/*
   19338 	 * Find any configured information about the server we'd
   19339 	 * like to transfer this zone from.
   19340 	 */
   19341 	isc_netaddr_fromsockaddr(&primaryip, &zone->primaryaddr);
   19342 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &primaryip, &peer);
   19343 	UNLOCK_ZONE(zone);
   19344 
   19345 	/*
   19346 	 * Determine the total maximum number of simultaneous
   19347 	 * transfers allowed, and the maximum for this specific
   19348 	 * primary.
   19349 	 */
   19350 	maxtransfersin = zmgr->transfersin;
   19351 	maxtransfersperns = zmgr->transfersperns;
   19352 	if (peer != NULL) {
   19353 		(void)dns_peer_gettransfers(peer, &maxtransfersperns);
   19354 	}
   19355 
   19356 	/*
   19357 	 * Count the total number of transfers that are in progress,
   19358 	 * and the number of transfers in progress from this primary.
   19359 	 * We linearly scan a list of all transfers; if this turns
   19360 	 * out to be too slow, we could hash on the primary address.
   19361 	 */
   19362 	nxfrsin = nxfrsperns = 0;
   19363 	for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL;
   19364 	     x = ISC_LIST_NEXT(x, statelink))
   19365 	{
   19366 		isc_netaddr_t xip;
   19367 
   19368 		LOCK_ZONE(x);
   19369 		isc_netaddr_fromsockaddr(&xip, &x->primaryaddr);
   19370 		UNLOCK_ZONE(x);
   19371 
   19372 		nxfrsin++;
   19373 		if (isc_netaddr_equal(&xip, &primaryip)) {
   19374 			nxfrsperns++;
   19375 		}
   19376 	}
   19377 
   19378 	/* Enforce quota. */
   19379 	if (nxfrsin >= maxtransfersin) {
   19380 		return (ISC_R_QUOTA);
   19381 	}
   19382 
   19383 	if (nxfrsperns >= maxtransfersperns) {
   19384 		return (ISC_R_QUOTA);
   19385 	}
   19386 
   19387 gotquota:
   19388 	/*
   19389 	 * We have sufficient quota.  Move the zone to the "xfrin_in_progress"
   19390 	 * list and send it an event to let it start the actual transfer in the
   19391 	 * context of its own task.
   19392 	 */
   19393 	e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
   19394 			       got_transfer_quota, zone, sizeof(isc_event_t));
   19395 
   19396 	LOCK_ZONE(zone);
   19397 	INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
   19398 	ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
   19399 	ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
   19400 	zone->statelist = &zmgr->xfrin_in_progress;
   19401 	isc_task_send(zone->task, &e);
   19402 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   19403 		      "Transfer started.");
   19404 	UNLOCK_ZONE(zone);
   19405 
   19406 	return (ISC_R_SUCCESS);
   19407 }
   19408 
   19409 void
   19410 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) {
   19411 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19412 	REQUIRE(iolimit > 0);
   19413 
   19414 	zmgr->iolimit = iolimit;
   19415 }
   19416 
   19417 uint32_t
   19418 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
   19419 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19420 
   19421 	return (zmgr->iolimit);
   19422 }
   19423 
   19424 /*
   19425  * Get permission to request a file handle from the OS.
   19426  * An event will be sent to action when one is available.
   19427  * There are two queues available (high and low), the high
   19428  * queue will be serviced before the low one.
   19429  *
   19430  * zonemgr_putio() must be called after the event is delivered to
   19431  * 'action'.
   19432  */
   19433 
   19434 static isc_result_t
   19435 zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task,
   19436 	      isc_taskaction_t action, void *arg, dns_io_t **iop) {
   19437 	dns_io_t *io;
   19438 	bool queue;
   19439 
   19440 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19441 	REQUIRE(iop != NULL && *iop == NULL);
   19442 
   19443 	io = isc_mem_get(zmgr->mctx, sizeof(*io));
   19444 
   19445 	io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
   19446 				       action, arg, sizeof(*io->event));
   19447 
   19448 	io->zmgr = zmgr;
   19449 	io->high = high;
   19450 	io->task = NULL;
   19451 	isc_task_attach(task, &io->task);
   19452 	ISC_LINK_INIT(io, link);
   19453 	io->magic = IO_MAGIC;
   19454 
   19455 	LOCK(&zmgr->iolock);
   19456 	zmgr->ioactive++;
   19457 	queue = (zmgr->ioactive > zmgr->iolimit);
   19458 	if (queue) {
   19459 		if (io->high) {
   19460 			ISC_LIST_APPEND(zmgr->high, io, link);
   19461 		} else {
   19462 			ISC_LIST_APPEND(zmgr->low, io, link);
   19463 		}
   19464 	}
   19465 	UNLOCK(&zmgr->iolock);
   19466 	*iop = io;
   19467 
   19468 	if (!queue) {
   19469 		isc_task_send(io->task, &io->event);
   19470 	}
   19471 	return (ISC_R_SUCCESS);
   19472 }
   19473 
   19474 static void
   19475 zonemgr_putio(dns_io_t **iop) {
   19476 	dns_io_t *io;
   19477 	dns_io_t *next;
   19478 	dns_zonemgr_t *zmgr;
   19479 
   19480 	REQUIRE(iop != NULL);
   19481 	io = *iop;
   19482 	*iop = NULL;
   19483 	REQUIRE(DNS_IO_VALID(io));
   19484 
   19485 	INSIST(!ISC_LINK_LINKED(io, link));
   19486 	INSIST(io->event == NULL);
   19487 
   19488 	zmgr = io->zmgr;
   19489 	isc_task_detach(&io->task);
   19490 	io->magic = 0;
   19491 	isc_mem_put(zmgr->mctx, io, sizeof(*io));
   19492 
   19493 	LOCK(&zmgr->iolock);
   19494 	INSIST(zmgr->ioactive > 0);
   19495 	zmgr->ioactive--;
   19496 	next = HEAD(zmgr->high);
   19497 	if (next == NULL) {
   19498 		next = HEAD(zmgr->low);
   19499 	}
   19500 	if (next != NULL) {
   19501 		if (next->high) {
   19502 			ISC_LIST_UNLINK(zmgr->high, next, link);
   19503 		} else {
   19504 			ISC_LIST_UNLINK(zmgr->low, next, link);
   19505 		}
   19506 		INSIST(next->event != NULL);
   19507 	}
   19508 	UNLOCK(&zmgr->iolock);
   19509 	if (next != NULL) {
   19510 		isc_task_send(next->task, &next->event);
   19511 	}
   19512 }
   19513 
   19514 static void
   19515 zonemgr_cancelio(dns_io_t *io) {
   19516 	bool send_event = false;
   19517 
   19518 	REQUIRE(DNS_IO_VALID(io));
   19519 
   19520 	/*
   19521 	 * If we are queued to be run then dequeue.
   19522 	 */
   19523 	LOCK(&io->zmgr->iolock);
   19524 	if (ISC_LINK_LINKED(io, link)) {
   19525 		if (io->high) {
   19526 			ISC_LIST_UNLINK(io->zmgr->high, io, link);
   19527 		} else {
   19528 			ISC_LIST_UNLINK(io->zmgr->low, io, link);
   19529 		}
   19530 
   19531 		send_event = true;
   19532 		INSIST(io->event != NULL);
   19533 	}
   19534 	UNLOCK(&io->zmgr->iolock);
   19535 	if (send_event) {
   19536 		io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
   19537 		isc_task_send(io->task, &io->event);
   19538 	}
   19539 }
   19540 
   19541 static void
   19542 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
   19543 	char *buf;
   19544 	int buflen;
   19545 	isc_result_t result;
   19546 
   19547 	buflen = strlen(path) + strlen(templat) + 2;
   19548 
   19549 	buf = isc_mem_get(zone->mctx, buflen);
   19550 
   19551 	result = isc_file_template(path, templat, buf, buflen);
   19552 	if (result != ISC_R_SUCCESS) {
   19553 		goto cleanup;
   19554 	}
   19555 
   19556 	result = isc_file_renameunique(path, buf);
   19557 	if (result != ISC_R_SUCCESS) {
   19558 		goto cleanup;
   19559 	}
   19560 
   19561 	dns_zone_log(zone, ISC_LOG_WARNING,
   19562 		     "unable to load from '%s'; "
   19563 		     "renaming file to '%s' for failure analysis and "
   19564 		     "retransferring.",
   19565 		     path, buf);
   19566 
   19567 cleanup:
   19568 	isc_mem_put(zone->mctx, buf, buflen);
   19569 }
   19570 
   19571 static void
   19572 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
   19573 	isc_interval_t interval;
   19574 	uint32_t s, ns;
   19575 	uint32_t pertic;
   19576 	isc_result_t result;
   19577 
   19578 	if (value == 0) {
   19579 		value = 1;
   19580 	}
   19581 
   19582 	if (value == 1) {
   19583 		s = 1;
   19584 		ns = 0;
   19585 		pertic = 1;
   19586 	} else if (value <= 10) {
   19587 		s = 0;
   19588 		ns = 1000000000 / value;
   19589 		pertic = 1;
   19590 	} else {
   19591 		s = 0;
   19592 		ns = (1000000000 / value) * 10;
   19593 		pertic = 10;
   19594 	}
   19595 
   19596 	isc_interval_set(&interval, s, ns);
   19597 
   19598 	result = isc_ratelimiter_setinterval(rl, &interval);
   19599 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19600 	isc_ratelimiter_setpertic(rl, pertic);
   19601 
   19602 	*rate = value;
   19603 }
   19604 
   19605 void
   19606 dns_zonemgr_setcheckdsrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19607 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19608 
   19609 	setrl(zmgr->checkdsrl, &zmgr->checkdsrate, value);
   19610 }
   19611 
   19612 void
   19613 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19614 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19615 
   19616 	setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
   19617 }
   19618 
   19619 void
   19620 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19621 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19622 
   19623 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
   19624 }
   19625 
   19626 void
   19627 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
   19628 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19629 
   19630 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
   19631 	/* XXXMPA separate out once we have the code to support this. */
   19632 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
   19633 }
   19634 
   19635 unsigned int
   19636 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
   19637 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19638 
   19639 	return (zmgr->notifyrate);
   19640 }
   19641 
   19642 unsigned int
   19643 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
   19644 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19645 
   19646 	return (zmgr->startupnotifyrate);
   19647 }
   19648 
   19649 unsigned int
   19650 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
   19651 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19652 
   19653 	return (zmgr->serialqueryrate);
   19654 }
   19655 
   19656 bool
   19657 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   19658 			isc_sockaddr_t *local, isc_time_t *now) {
   19659 	unsigned int i;
   19660 	uint32_t seconds = isc_time_seconds(now);
   19661 	uint32_t count = 0;
   19662 
   19663 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19664 
   19665 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19666 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   19667 		if (atomic_load(&zmgr->unreachable[i].expire) >= seconds &&
   19668 		    isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   19669 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   19670 		{
   19671 			atomic_store_relaxed(&zmgr->unreachable[i].last,
   19672 					     seconds);
   19673 			count = zmgr->unreachable[i].count;
   19674 			break;
   19675 		}
   19676 	}
   19677 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19678 	return (i < UNREACH_CACHE_SIZE && count > 1U);
   19679 }
   19680 
   19681 void
   19682 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   19683 			   isc_sockaddr_t *local) {
   19684 	unsigned int i;
   19685 	char primary[ISC_SOCKADDR_FORMATSIZE];
   19686 	char source[ISC_SOCKADDR_FORMATSIZE];
   19687 
   19688 	isc_sockaddr_format(remote, primary, sizeof(primary));
   19689 	isc_sockaddr_format(local, source, sizeof(source));
   19690 
   19691 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19692 
   19693 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19694 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   19695 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   19696 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   19697 		{
   19698 			atomic_store_relaxed(&zmgr->unreachable[i].expire, 0);
   19699 			break;
   19700 		}
   19701 	}
   19702 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   19703 }
   19704 
   19705 void
   19706 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   19707 			   isc_sockaddr_t *local, isc_time_t *now) {
   19708 	uint32_t seconds = isc_time_seconds(now);
   19709 	uint32_t expire = 0, last = seconds;
   19710 	unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0;
   19711 	bool update_entry = true;
   19712 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19713 
   19714 	RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
   19715 	for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) {
   19716 		/* Existing entry? */
   19717 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   19718 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   19719 		{
   19720 			update_entry = false;
   19721 			slot = i;
   19722 			expire = atomic_load_relaxed(
   19723 				&zmgr->unreachable[i].expire);
   19724 			break;
   19725 		}
   19726 		/* Pick first empty slot? */
   19727 		if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds)
   19728 		{
   19729 			slot = i;
   19730 			break;
   19731 		}
   19732 		/* The worst case, least recently used slot? */
   19733 		if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) {
   19734 			last = atomic_load_relaxed(&zmgr->unreachable[i].last);
   19735 			oldest = i;
   19736 		}
   19737 	}
   19738 
   19739 	/* We haven't found any existing or free slots, use the oldest */
   19740 	if (slot == UNREACH_CACHE_SIZE) {
   19741 		slot = oldest;
   19742 	}
   19743 
   19744 	if (expire < seconds) {
   19745 		/* Expired or new entry, reset count to 1 */
   19746 		zmgr->unreachable[slot].count = 1;
   19747 	} else {
   19748 		zmgr->unreachable[slot].count++;
   19749 	}
   19750 	atomic_store_relaxed(&zmgr->unreachable[slot].expire,
   19751 			     seconds + UNREACH_HOLD_TIME);
   19752 	atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds);
   19753 	if (update_entry) {
   19754 		zmgr->unreachable[slot].remote = *remote;
   19755 		zmgr->unreachable[slot].local = *local;
   19756 	}
   19757 
   19758 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
   19759 }
   19760 
   19761 void
   19762 dns_zone_forcereload(dns_zone_t *zone) {
   19763 	REQUIRE(DNS_ZONE_VALID(zone));
   19764 
   19765 	if (zone->type == dns_zone_primary ||
   19766 	    (zone->type == dns_zone_redirect && zone->primaries == NULL))
   19767 	{
   19768 		return;
   19769 	}
   19770 
   19771 	LOCK_ZONE(zone);
   19772 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   19773 	UNLOCK_ZONE(zone);
   19774 	dns_zone_refresh(zone);
   19775 }
   19776 
   19777 bool
   19778 dns_zone_isforced(dns_zone_t *zone) {
   19779 	REQUIRE(DNS_ZONE_VALID(zone));
   19780 
   19781 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
   19782 }
   19783 
   19784 isc_result_t
   19785 dns_zone_setstatistics(dns_zone_t *zone, bool on) {
   19786 	/*
   19787 	 * This function is obsoleted.
   19788 	 */
   19789 	UNUSED(zone);
   19790 	UNUSED(on);
   19791 	return (ISC_R_NOTIMPLEMENTED);
   19792 }
   19793 
   19794 uint64_t *
   19795 dns_zone_getstatscounters(dns_zone_t *zone) {
   19796 	/*
   19797 	 * This function is obsoleted.
   19798 	 */
   19799 	UNUSED(zone);
   19800 	return (NULL);
   19801 }
   19802 
   19803 void
   19804 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
   19805 	REQUIRE(DNS_ZONE_VALID(zone));
   19806 	REQUIRE(zone->stats == NULL);
   19807 
   19808 	LOCK_ZONE(zone);
   19809 	zone->stats = NULL;
   19810 	isc_stats_attach(stats, &zone->stats);
   19811 	UNLOCK_ZONE(zone);
   19812 }
   19813 
   19814 void
   19815 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
   19816 	REQUIRE(DNS_ZONE_VALID(zone));
   19817 
   19818 	LOCK_ZONE(zone);
   19819 	if (zone->requeststats_on && stats == NULL) {
   19820 		zone->requeststats_on = false;
   19821 	} else if (!zone->requeststats_on && stats != NULL) {
   19822 		if (zone->requeststats == NULL) {
   19823 			isc_stats_attach(stats, &zone->requeststats);
   19824 		}
   19825 		zone->requeststats_on = true;
   19826 	}
   19827 	UNLOCK_ZONE(zone);
   19828 }
   19829 
   19830 void
   19831 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
   19832 	REQUIRE(DNS_ZONE_VALID(zone));
   19833 
   19834 	LOCK_ZONE(zone);
   19835 	if (zone->requeststats_on && stats != NULL) {
   19836 		if (zone->rcvquerystats == NULL) {
   19837 			dns_stats_attach(stats, &zone->rcvquerystats);
   19838 			zone->requeststats_on = true;
   19839 		}
   19840 	}
   19841 	UNLOCK_ZONE(zone);
   19842 }
   19843 
   19844 void
   19845 dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
   19846 	REQUIRE(DNS_ZONE_VALID(zone));
   19847 
   19848 	LOCK_ZONE(zone);
   19849 	if (stats != NULL && zone->dnssecsignstats == NULL) {
   19850 		dns_stats_attach(stats, &zone->dnssecsignstats);
   19851 	}
   19852 	UNLOCK_ZONE(zone);
   19853 }
   19854 
   19855 dns_stats_t *
   19856 dns_zone_getdnssecsignstats(dns_zone_t *zone) {
   19857 	REQUIRE(DNS_ZONE_VALID(zone));
   19858 
   19859 	return (zone->dnssecsignstats);
   19860 }
   19861 
   19862 isc_stats_t *
   19863 dns_zone_getrequeststats(dns_zone_t *zone) {
   19864 	/*
   19865 	 * We don't lock zone for efficiency reason.  This is not catastrophic
   19866 	 * because requeststats must always be valid when requeststats_on is
   19867 	 * true.
   19868 	 * Some counters may be incremented while requeststats_on is becoming
   19869 	 * false, or some cannot be incremented just after the statistics are
   19870 	 * installed, but it shouldn't matter much in practice.
   19871 	 */
   19872 	if (zone->requeststats_on) {
   19873 		return (zone->requeststats);
   19874 	} else {
   19875 		return (NULL);
   19876 	}
   19877 }
   19878 
   19879 /*
   19880  * Return the received query stats bucket
   19881  * see note from dns_zone_getrequeststats()
   19882  */
   19883 dns_stats_t *
   19884 dns_zone_getrcvquerystats(dns_zone_t *zone) {
   19885 	if (zone->requeststats_on) {
   19886 		return (zone->rcvquerystats);
   19887 	} else {
   19888 		return (NULL);
   19889 	}
   19890 }
   19891 
   19892 void
   19893 dns_zone_dialup(dns_zone_t *zone) {
   19894 	REQUIRE(DNS_ZONE_VALID(zone));
   19895 
   19896 	zone_debuglog(zone, "dns_zone_dialup", 3, "notify = %d, refresh = %d",
   19897 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
   19898 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
   19899 
   19900 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   19901 		dns_zone_notify(zone);
   19902 	}
   19903 	if (zone->type != dns_zone_primary && zone->primaries != NULL &&
   19904 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
   19905 	{
   19906 		dns_zone_refresh(zone);
   19907 	}
   19908 }
   19909 
   19910 void
   19911 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
   19912 	REQUIRE(DNS_ZONE_VALID(zone));
   19913 
   19914 	LOCK_ZONE(zone);
   19915 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
   19916 				       DNS_ZONEFLG_DIALREFRESH |
   19917 				       DNS_ZONEFLG_NOREFRESH);
   19918 	switch (dialup) {
   19919 	case dns_dialuptype_no:
   19920 		break;
   19921 	case dns_dialuptype_yes:
   19922 		DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
   19923 					DNS_ZONEFLG_DIALREFRESH |
   19924 					DNS_ZONEFLG_NOREFRESH));
   19925 		break;
   19926 	case dns_dialuptype_notify:
   19927 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19928 		break;
   19929 	case dns_dialuptype_notifypassive:
   19930 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19931 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19932 		break;
   19933 	case dns_dialuptype_refresh:
   19934 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
   19935 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19936 		break;
   19937 	case dns_dialuptype_passive:
   19938 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19939 		break;
   19940 	default:
   19941 		UNREACHABLE();
   19942 	}
   19943 	UNLOCK_ZONE(zone);
   19944 }
   19945 
   19946 isc_result_t
   19947 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
   19948 	isc_result_t result = ISC_R_SUCCESS;
   19949 
   19950 	REQUIRE(DNS_ZONE_VALID(zone));
   19951 
   19952 	LOCK_ZONE(zone);
   19953 	result = dns_zone_setstring(zone, &zone->keydirectory, directory);
   19954 	UNLOCK_ZONE(zone);
   19955 
   19956 	return (result);
   19957 }
   19958 
   19959 const char *
   19960 dns_zone_getkeydirectory(dns_zone_t *zone) {
   19961 	REQUIRE(DNS_ZONE_VALID(zone));
   19962 
   19963 	return (zone->keydirectory);
   19964 }
   19965 
   19966 unsigned int
   19967 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
   19968 	dns_zone_t *zone;
   19969 	unsigned int count = 0;
   19970 
   19971 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19972 
   19973 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19974 	switch (state) {
   19975 	case DNS_ZONESTATE_XFERRUNNING:
   19976 		for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
   19977 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19978 		{
   19979 			count++;
   19980 		}
   19981 		break;
   19982 	case DNS_ZONESTATE_XFERDEFERRED:
   19983 		for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
   19984 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19985 		{
   19986 			count++;
   19987 		}
   19988 		break;
   19989 	case DNS_ZONESTATE_SOAQUERY:
   19990 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19991 		     zone = ISC_LIST_NEXT(zone, link))
   19992 		{
   19993 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   19994 				count++;
   19995 			}
   19996 		}
   19997 		break;
   19998 	case DNS_ZONESTATE_ANY:
   19999 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   20000 		     zone = ISC_LIST_NEXT(zone, link))
   20001 		{
   20002 			dns_view_t *view = zone->view;
   20003 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   20004 				continue;
   20005 			}
   20006 			count++;
   20007 		}
   20008 		break;
   20009 	case DNS_ZONESTATE_AUTOMATIC:
   20010 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   20011 		     zone = ISC_LIST_NEXT(zone, link))
   20012 		{
   20013 			dns_view_t *view = zone->view;
   20014 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   20015 				continue;
   20016 			}
   20017 			if (zone->automatic) {
   20018 				count++;
   20019 			}
   20020 		}
   20021 		break;
   20022 	default:
   20023 		UNREACHABLE();
   20024 	}
   20025 
   20026 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   20027 
   20028 	return (count);
   20029 }
   20030 
   20031 void
   20032 dns_zone_lock_keyfiles(dns_zone_t *zone) {
   20033 	REQUIRE(DNS_ZONE_VALID(zone));
   20034 
   20035 	if (zone->kasp == NULL) {
   20036 		/* No need to lock, nothing is writing key files. */
   20037 		return;
   20038 	}
   20039 
   20040 	REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio));
   20041 	isc_mutex_lock(&zone->kfio->lock);
   20042 }
   20043 
   20044 void
   20045 dns_zone_unlock_keyfiles(dns_zone_t *zone) {
   20046 	REQUIRE(DNS_ZONE_VALID(zone));
   20047 
   20048 	if (zone->kasp == NULL) {
   20049 		/* No need to lock, nothing is writing key files. */
   20050 		return;
   20051 	}
   20052 
   20053 	REQUIRE(DNS_KEYFILEIO_VALID(zone->kfio));
   20054 	isc_mutex_unlock(&zone->kfio->lock);
   20055 }
   20056 
   20057 isc_result_t
   20058 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
   20059 		    dns_rdata_t *rdata) {
   20060 	bool ok = true;
   20061 	bool fail = false;
   20062 	char namebuf[DNS_NAME_FORMATSIZE];
   20063 	char namebuf2[DNS_NAME_FORMATSIZE];
   20064 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   20065 	int level = ISC_LOG_WARNING;
   20066 	dns_name_t bad;
   20067 
   20068 	REQUIRE(DNS_ZONE_VALID(zone));
   20069 
   20070 	if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
   20071 	    rdata->type != dns_rdatatype_nsec3)
   20072 	{
   20073 		return (ISC_R_SUCCESS);
   20074 	}
   20075 
   20076 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
   20077 	    rdata->type == dns_rdatatype_nsec3)
   20078 	{
   20079 		level = ISC_LOG_ERROR;
   20080 		fail = true;
   20081 	}
   20082 
   20083 	ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true);
   20084 	if (!ok) {
   20085 		dns_name_format(name, namebuf, sizeof(namebuf));
   20086 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   20087 		dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
   20088 			     isc_result_totext(DNS_R_BADOWNERNAME));
   20089 		if (fail) {
   20090 			return (DNS_R_BADOWNERNAME);
   20091 		}
   20092 	}
   20093 
   20094 	dns_name_init(&bad, NULL);
   20095 	ok = dns_rdata_checknames(rdata, name, &bad);
   20096 	if (!ok) {
   20097 		dns_name_format(name, namebuf, sizeof(namebuf));
   20098 		dns_name_format(&bad, namebuf2, sizeof(namebuf2));
   20099 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   20100 		dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
   20101 			     namebuf2, isc_result_totext(DNS_R_BADNAME));
   20102 		if (fail) {
   20103 			return (DNS_R_BADNAME);
   20104 		}
   20105 	}
   20106 
   20107 	return (ISC_R_SUCCESS);
   20108 }
   20109 
   20110 void
   20111 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
   20112 	REQUIRE(DNS_ZONE_VALID(zone));
   20113 	zone->checkmx = checkmx;
   20114 }
   20115 
   20116 void
   20117 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
   20118 	REQUIRE(DNS_ZONE_VALID(zone));
   20119 	zone->checksrv = checksrv;
   20120 }
   20121 
   20122 void
   20123 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
   20124 	REQUIRE(DNS_ZONE_VALID(zone));
   20125 	zone->checkns = checkns;
   20126 }
   20127 
   20128 void
   20129 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
   20130 	REQUIRE(DNS_ZONE_VALID(zone));
   20131 
   20132 	LOCK_ZONE(zone);
   20133 	zone->isself = isself;
   20134 	zone->isselfarg = arg;
   20135 	UNLOCK_ZONE(zone);
   20136 }
   20137 
   20138 void
   20139 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
   20140 	REQUIRE(DNS_ZONE_VALID(zone));
   20141 
   20142 	LOCK_ZONE(zone);
   20143 	zone->notifydelay = delay;
   20144 	UNLOCK_ZONE(zone);
   20145 }
   20146 
   20147 uint32_t
   20148 dns_zone_getnotifydelay(dns_zone_t *zone) {
   20149 	REQUIRE(DNS_ZONE_VALID(zone));
   20150 
   20151 	return (zone->notifydelay);
   20152 }
   20153 
   20154 isc_result_t
   20155 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   20156 		     bool deleteit) {
   20157 	isc_result_t result;
   20158 	REQUIRE(DNS_ZONE_VALID(zone));
   20159 
   20160 	dnssec_log(zone, ISC_LOG_NOTICE,
   20161 		   "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm,
   20162 		   keyid);
   20163 	LOCK_ZONE(zone);
   20164 	result = zone_signwithkey(zone, algorithm, keyid, deleteit);
   20165 	UNLOCK_ZONE(zone);
   20166 
   20167 	return (result);
   20168 }
   20169 
   20170 /*
   20171  * Called when a dynamic update for an NSEC3PARAM record is received.
   20172  *
   20173  * If set, transform the NSEC3 salt into human-readable form so that it can be
   20174  * logged.  Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it.
   20175  */
   20176 isc_result_t
   20177 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   20178 	isc_result_t result;
   20179 	char salt[255 * 2 + 1];
   20180 
   20181 	REQUIRE(DNS_ZONE_VALID(zone));
   20182 
   20183 	result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
   20184 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20185 	dnssec_log(zone, ISC_LOG_NOTICE,
   20186 		   "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
   20187 		   nsec3param->hash, nsec3param->iterations, salt);
   20188 	LOCK_ZONE(zone);
   20189 	result = zone_addnsec3chain(zone, nsec3param);
   20190 	UNLOCK_ZONE(zone);
   20191 
   20192 	return (result);
   20193 }
   20194 
   20195 void
   20196 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
   20197 	REQUIRE(DNS_ZONE_VALID(zone));
   20198 
   20199 	if (nodes == 0) {
   20200 		nodes = 1;
   20201 	}
   20202 	zone->nodes = nodes;
   20203 }
   20204 
   20205 void
   20206 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
   20207 	REQUIRE(DNS_ZONE_VALID(zone));
   20208 
   20209 	/*
   20210 	 * We treat signatures as a signed value so explicitly
   20211 	 * limit its range here.
   20212 	 */
   20213 	if (signatures > INT32_MAX) {
   20214 		signatures = INT32_MAX;
   20215 	} else if (signatures == 0) {
   20216 		signatures = 1;
   20217 	}
   20218 	zone->signatures = signatures;
   20219 }
   20220 
   20221 uint32_t
   20222 dns_zone_getsignatures(dns_zone_t *zone) {
   20223 	REQUIRE(DNS_ZONE_VALID(zone));
   20224 	return (zone->signatures);
   20225 }
   20226 
   20227 void
   20228 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
   20229 	REQUIRE(DNS_ZONE_VALID(zone));
   20230 	zone->privatetype = type;
   20231 }
   20232 
   20233 dns_rdatatype_t
   20234 dns_zone_getprivatetype(dns_zone_t *zone) {
   20235 	REQUIRE(DNS_ZONE_VALID(zone));
   20236 	return (zone->privatetype);
   20237 }
   20238 
   20239 static isc_result_t
   20240 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   20241 		 bool deleteit) {
   20242 	dns_signing_t *signing;
   20243 	dns_signing_t *current;
   20244 	isc_result_t result = ISC_R_SUCCESS;
   20245 	isc_time_t now;
   20246 	dns_db_t *db = NULL;
   20247 
   20248 	signing = isc_mem_get(zone->mctx, sizeof *signing);
   20249 
   20250 	signing->magic = 0;
   20251 	signing->db = NULL;
   20252 	signing->dbiterator = NULL;
   20253 	signing->algorithm = algorithm;
   20254 	signing->keyid = keyid;
   20255 	signing->deleteit = deleteit;
   20256 	signing->done = false;
   20257 
   20258 	TIME_NOW(&now);
   20259 
   20260 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   20261 	if (zone->db != NULL) {
   20262 		dns_db_attach(zone->db, &db);
   20263 	}
   20264 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   20265 
   20266 	if (db == NULL) {
   20267 		result = ISC_R_NOTFOUND;
   20268 		goto cleanup;
   20269 	}
   20270 
   20271 	dns_db_attach(db, &signing->db);
   20272 
   20273 	for (current = ISC_LIST_HEAD(zone->signing); current != NULL;
   20274 	     current = ISC_LIST_NEXT(current, link))
   20275 	{
   20276 		if (current->db == signing->db &&
   20277 		    current->algorithm == signing->algorithm &&
   20278 		    current->keyid == signing->keyid)
   20279 		{
   20280 			if (current->deleteit != signing->deleteit) {
   20281 				current->done = true;
   20282 			} else {
   20283 				goto cleanup;
   20284 			}
   20285 		}
   20286 	}
   20287 
   20288 	result = dns_db_createiterator(signing->db, 0, &signing->dbiterator);
   20289 
   20290 	if (result == ISC_R_SUCCESS) {
   20291 		result = dns_dbiterator_first(signing->dbiterator);
   20292 	}
   20293 	if (result == ISC_R_SUCCESS) {
   20294 		dns_dbiterator_pause(signing->dbiterator);
   20295 		ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
   20296 		signing = NULL;
   20297 		if (isc_time_isepoch(&zone->signingtime)) {
   20298 			zone->signingtime = now;
   20299 			if (zone->task != NULL) {
   20300 				zone_settimer(zone, &now);
   20301 			}
   20302 		}
   20303 	}
   20304 
   20305 cleanup:
   20306 	if (signing != NULL) {
   20307 		if (signing->db != NULL) {
   20308 			dns_db_detach(&signing->db);
   20309 		}
   20310 		if (signing->dbiterator != NULL) {
   20311 			dns_dbiterator_destroy(&signing->dbiterator);
   20312 		}
   20313 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   20314 	}
   20315 	if (db != NULL) {
   20316 		dns_db_detach(&db);
   20317 	}
   20318 	return (result);
   20319 }
   20320 
   20321 /* Called once; *timep should be set to the current time. */
   20322 static isc_result_t
   20323 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
   20324 	isc_result_t result;
   20325 	isc_stdtime_t now, then = 0, event;
   20326 	int i;
   20327 
   20328 	now = *timep;
   20329 
   20330 	for (i = 0; i <= DST_MAX_TIMES; i++) {
   20331 		result = dst_key_gettime(key, i, &event);
   20332 		if (result == ISC_R_SUCCESS && event > now &&
   20333 		    (then == 0 || event < then))
   20334 		{
   20335 			then = event;
   20336 		}
   20337 	}
   20338 
   20339 	if (then != 0) {
   20340 		*timep = then;
   20341 		return (ISC_R_SUCCESS);
   20342 	}
   20343 
   20344 	return (ISC_R_NOTFOUND);
   20345 }
   20346 
   20347 static isc_result_t
   20348 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   20349 	  const dns_rdata_t *rdata, bool *flag) {
   20350 	dns_rdataset_t rdataset;
   20351 	dns_dbnode_t *node = NULL;
   20352 	isc_result_t result;
   20353 
   20354 	dns_rdataset_init(&rdataset);
   20355 	if (rdata->type == dns_rdatatype_nsec3) {
   20356 		CHECK(dns_db_findnsec3node(db, name, false, &node));
   20357 	} else {
   20358 		CHECK(dns_db_findnode(db, name, false, &node));
   20359 	}
   20360 	result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
   20361 				     (isc_stdtime_t)0, &rdataset, NULL);
   20362 	if (result == ISC_R_NOTFOUND) {
   20363 		*flag = false;
   20364 		result = ISC_R_SUCCESS;
   20365 		goto failure;
   20366 	}
   20367 
   20368 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   20369 	     result = dns_rdataset_next(&rdataset))
   20370 	{
   20371 		dns_rdata_t myrdata = DNS_RDATA_INIT;
   20372 		dns_rdataset_current(&rdataset, &myrdata);
   20373 		if (!dns_rdata_compare(&myrdata, rdata)) {
   20374 			break;
   20375 		}
   20376 	}
   20377 	dns_rdataset_disassociate(&rdataset);
   20378 	if (result == ISC_R_SUCCESS) {
   20379 		*flag = true;
   20380 	} else if (result == ISC_R_NOMORE) {
   20381 		*flag = false;
   20382 		result = ISC_R_SUCCESS;
   20383 	}
   20384 
   20385 failure:
   20386 	if (node != NULL) {
   20387 		dns_db_detachnode(db, &node);
   20388 	}
   20389 	return (result);
   20390 }
   20391 
   20392 /*
   20393  * Add records to signal the state of signing or of key removal.
   20394  */
   20395 static isc_result_t
   20396 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
   20397 		    dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) {
   20398 	dns_difftuple_t *tuple, *newtuple = NULL;
   20399 	dns_rdata_dnskey_t dnskey;
   20400 	dns_rdata_t rdata = DNS_RDATA_INIT;
   20401 	bool flag;
   20402 	isc_region_t r;
   20403 	isc_result_t result = ISC_R_SUCCESS;
   20404 	uint16_t keyid;
   20405 	unsigned char buf[5];
   20406 	dns_name_t *name = dns_db_origin(db);
   20407 
   20408 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   20409 	     tuple = ISC_LIST_NEXT(tuple, link))
   20410 	{
   20411 		if (tuple->rdata.type != dns_rdatatype_dnskey) {
   20412 			continue;
   20413 		}
   20414 
   20415 		result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
   20416 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20417 		if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK |
   20418 				     DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE)
   20419 		{
   20420 			continue;
   20421 		}
   20422 
   20423 		dns_rdata_toregion(&tuple->rdata, &r);
   20424 
   20425 		keyid = dst_region_computeid(&r);
   20426 
   20427 		buf[0] = dnskey.algorithm;
   20428 		buf[1] = (keyid & 0xff00) >> 8;
   20429 		buf[2] = (keyid & 0xff);
   20430 		buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
   20431 		buf[4] = 0;
   20432 		rdata.data = buf;
   20433 		rdata.length = sizeof(buf);
   20434 		rdata.type = privatetype;
   20435 		rdata.rdclass = tuple->rdata.rdclass;
   20436 
   20437 		if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
   20438 			CHECK(rr_exists(db, ver, name, &rdata, &flag));
   20439 			if (flag) {
   20440 				continue;
   20441 			}
   20442 
   20443 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   20444 						   name, 0, &rdata, &newtuple));
   20445 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   20446 			INSIST(newtuple == NULL);
   20447 		}
   20448 
   20449 		/*
   20450 		 * Remove any record which says this operation has already
   20451 		 * completed.
   20452 		 */
   20453 		buf[4] = 1;
   20454 		CHECK(rr_exists(db, ver, name, &rdata, &flag));
   20455 		if (flag) {
   20456 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
   20457 						   name, 0, &rdata, &newtuple));
   20458 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   20459 			INSIST(newtuple == NULL);
   20460 		}
   20461 	}
   20462 failure:
   20463 	return (result);
   20464 }
   20465 
   20466 /*
   20467  * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at
   20468  * the apex, and if not tickle them and cause to sign so that newly activated
   20469  * keys are used.
   20470  */
   20471 static isc_result_t
   20472 tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db,
   20473 		  dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff,
   20474 		  dns__zonediff_t *zonediff, dst_key_t **keys,
   20475 		  unsigned int nkeys, isc_stdtime_t inception,
   20476 		  isc_stdtime_t keyexpire, bool check_ksk,
   20477 		  bool keyset_kskonly) {
   20478 	dns_difftuple_t *tuple;
   20479 	isc_result_t result;
   20480 
   20481 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   20482 	     tuple = ISC_LIST_NEXT(tuple, link))
   20483 	{
   20484 		if (tuple->rdata.type == rrtype &&
   20485 		    dns_name_equal(&tuple->name, &zone->origin))
   20486 		{
   20487 			break;
   20488 		}
   20489 	}
   20490 
   20491 	if (tuple == NULL) {
   20492 		result = del_sigs(zone, db, ver, &zone->origin, rrtype,
   20493 				  zonediff, keys, nkeys, now, false);
   20494 		if (result != ISC_R_SUCCESS) {
   20495 			dnssec_log(zone, ISC_LOG_ERROR,
   20496 				   "sign_apex:del_sigs -> %s",
   20497 				   isc_result_totext(result));
   20498 			return (result);
   20499 		}
   20500 		result = add_sigs(db, ver, &zone->origin, zone, rrtype,
   20501 				  zonediff->diff, keys, nkeys, zone->mctx, now,
   20502 				  inception, keyexpire, check_ksk,
   20503 				  keyset_kskonly);
   20504 		if (result != ISC_R_SUCCESS) {
   20505 			dnssec_log(zone, ISC_LOG_ERROR,
   20506 				   "sign_apex:add_sigs -> %s",
   20507 				   isc_result_totext(result));
   20508 			return (result);
   20509 		}
   20510 	}
   20511 
   20512 	return (ISC_R_SUCCESS);
   20513 }
   20514 
   20515 static isc_result_t
   20516 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   20517 	  isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) {
   20518 	isc_result_t result;
   20519 	isc_stdtime_t inception, soaexpire, keyexpire;
   20520 	bool check_ksk, keyset_kskonly;
   20521 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   20522 	unsigned int nkeys = 0, i;
   20523 
   20524 	result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
   20525 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   20526 	if (result != ISC_R_SUCCESS) {
   20527 		dnssec_log(zone, ISC_LOG_ERROR,
   20528 			   "sign_apex:dns__zone_findkeys -> %s",
   20529 			   isc_result_totext(result));
   20530 		return (result);
   20531 	}
   20532 
   20533 	inception = now - 3600; /* Allow for clock skew. */
   20534 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
   20535 
   20536 	keyexpire = dns_zone_getkeyvalidityinterval(zone);
   20537 	if (keyexpire == 0) {
   20538 		keyexpire = soaexpire - 1;
   20539 	} else {
   20540 		keyexpire += now;
   20541 	}
   20542 
   20543 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   20544 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   20545 
   20546 	/*
   20547 	 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY
   20548 	 * signature and if not cause them to sign so that newly activated
   20549 	 * keys are used.
   20550 	 */
   20551 	result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now,
   20552 				   diff, zonediff, zone_keys, nkeys, inception,
   20553 				   keyexpire, check_ksk, keyset_kskonly);
   20554 	if (result != ISC_R_SUCCESS) {
   20555 		goto failure;
   20556 	}
   20557 	result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff,
   20558 				   zonediff, zone_keys, nkeys, inception,
   20559 				   keyexpire, check_ksk, keyset_kskonly);
   20560 	if (result != ISC_R_SUCCESS) {
   20561 		goto failure;
   20562 	}
   20563 	result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now,
   20564 				   diff, zonediff, zone_keys, nkeys, inception,
   20565 				   keyexpire, check_ksk, keyset_kskonly);
   20566 	if (result != ISC_R_SUCCESS) {
   20567 		goto failure;
   20568 	}
   20569 
   20570 	result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
   20571 				      inception, soaexpire, keyexpire, now,
   20572 				      check_ksk, keyset_kskonly, zonediff);
   20573 
   20574 	if (result != ISC_R_SUCCESS) {
   20575 		dnssec_log(zone, ISC_LOG_ERROR,
   20576 			   "sign_apex:dns__zone_updatesigs -> %s",
   20577 			   isc_result_totext(result));
   20578 		goto failure;
   20579 	}
   20580 
   20581 failure:
   20582 	for (i = 0; i < nkeys; i++) {
   20583 		dst_key_free(&zone_keys[i]);
   20584 	}
   20585 	return (result);
   20586 }
   20587 
   20588 static isc_result_t
   20589 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   20590 		 dns_diff_t *diff) {
   20591 	isc_result_t result;
   20592 	dns_dbnode_t *node = NULL;
   20593 	dns_rdataset_t rdataset;
   20594 
   20595 	dns_rdataset_init(&rdataset);
   20596 	CHECK(dns_db_getoriginnode(db, &node));
   20597 
   20598 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   20599 				     dns_rdatatype_none, 0, &rdataset, NULL);
   20600 	if (dns_rdataset_isassociated(&rdataset)) {
   20601 		dns_rdataset_disassociate(&rdataset);
   20602 	}
   20603 	if (result != ISC_R_NOTFOUND) {
   20604 		goto failure;
   20605 	}
   20606 
   20607 	result = dns_nsec3param_deletechains(db, ver, zone, true, diff);
   20608 
   20609 failure:
   20610 	if (node != NULL) {
   20611 		dns_db_detachnode(db, &node);
   20612 	}
   20613 	return (result);
   20614 }
   20615 
   20616 /*
   20617  * Given an RRSIG rdataset and an algorithm, determine whether there
   20618  * are any signatures using that algorithm.
   20619  */
   20620 static bool
   20621 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
   20622 	dns_rdata_t rdata = DNS_RDATA_INIT;
   20623 	dns_rdata_rrsig_t rrsig;
   20624 	isc_result_t result;
   20625 
   20626 	REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
   20627 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
   20628 		return (false);
   20629 	}
   20630 
   20631 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   20632 	     result = dns_rdataset_next(rdataset))
   20633 	{
   20634 		dns_rdataset_current(rdataset, &rdata);
   20635 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   20636 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20637 		dns_rdata_reset(&rdata);
   20638 		if (rrsig.algorithm == alg) {
   20639 			return (true);
   20640 		}
   20641 	}
   20642 
   20643 	return (false);
   20644 }
   20645 
   20646 static isc_result_t
   20647 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   20648 	   dns_diff_t *diff) {
   20649 	dns_name_t *origin;
   20650 	bool build_nsec3;
   20651 	isc_result_t result;
   20652 
   20653 	origin = dns_db_origin(db);
   20654 	CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
   20655 				 &build_nsec3));
   20656 	if (build_nsec3) {
   20657 		CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone_nsecttl(zone),
   20658 					   false, zone->privatetype, diff));
   20659 	}
   20660 	CHECK(updatesecure(db, ver, origin, zone_nsecttl(zone), true, diff));
   20661 
   20662 failure:
   20663 	return (result);
   20664 }
   20665 
   20666 static void
   20667 dnssec_report(const char *format, ...) {
   20668 	va_list args;
   20669 	va_start(args, format);
   20670 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE,
   20671 		       ISC_LOG_INFO, format, args);
   20672 	va_end(args);
   20673 }
   20674 
   20675 static void
   20676 checkds_destroy(dns_checkds_t *checkds, bool locked) {
   20677 	isc_mem_t *mctx;
   20678 
   20679 	REQUIRE(DNS_CHECKDS_VALID(checkds));
   20680 
   20681 	dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   20682 		     "checkds: destroy DS query");
   20683 
   20684 	if (checkds->zone != NULL) {
   20685 		if (!locked) {
   20686 			LOCK_ZONE(checkds->zone);
   20687 		}
   20688 		REQUIRE(LOCKED_ZONE(checkds->zone));
   20689 		if (ISC_LINK_LINKED(checkds, link)) {
   20690 			ISC_LIST_UNLINK(checkds->zone->checkds_requests,
   20691 					checkds, link);
   20692 		}
   20693 		if (!locked) {
   20694 			UNLOCK_ZONE(checkds->zone);
   20695 		}
   20696 		if (locked) {
   20697 			zone_idetach(&checkds->zone);
   20698 		} else {
   20699 			dns_zone_idetach(&checkds->zone);
   20700 		}
   20701 	}
   20702 	if (checkds->request != NULL) {
   20703 		dns_request_destroy(&checkds->request);
   20704 	}
   20705 	if (checkds->key != NULL) {
   20706 		dns_tsigkey_detach(&checkds->key);
   20707 	}
   20708 	if (checkds->transport != NULL) {
   20709 		dns_transport_detach(&checkds->transport);
   20710 	}
   20711 	mctx = checkds->mctx;
   20712 	isc_mem_put(checkds->mctx, checkds, sizeof(*checkds));
   20713 	isc_mem_detach(&mctx);
   20714 }
   20715 
   20716 static isc_result_t
   20717 make_dnskey(dst_key_t *key, unsigned char *buf, int bufsize,
   20718 	    dns_rdata_t *target) {
   20719 	isc_result_t result;
   20720 	isc_buffer_t b;
   20721 	isc_region_t r;
   20722 
   20723 	isc_buffer_init(&b, buf, bufsize);
   20724 	result = dst_key_todns(key, &b);
   20725 	if (result != ISC_R_SUCCESS) {
   20726 		return (result);
   20727 	}
   20728 
   20729 	dns_rdata_reset(target);
   20730 	isc_buffer_usedregion(&b, &r);
   20731 	dns_rdata_fromregion(target, dst_key_class(key), dns_rdatatype_dnskey,
   20732 			     &r);
   20733 	return (ISC_R_SUCCESS);
   20734 }
   20735 
   20736 static bool
   20737 do_checkds(dns_zone_t *zone, dst_key_t *key, isc_stdtime_t now,
   20738 	   bool dspublish) {
   20739 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   20740 	const char *dir = dns_zone_getkeydirectory(zone);
   20741 	isc_result_t result;
   20742 	uint32_t count = 0;
   20743 
   20744 	if (dspublish) {
   20745 		(void)dst_key_getnum(key, DST_NUM_DSPUBCOUNT, &count);
   20746 		count += 1;
   20747 		dst_key_setnum(key, DST_NUM_DSPUBCOUNT, count);
   20748 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20749 			     "checkds: %u DS published "
   20750 			     "for key %u",
   20751 			     count, dst_key_id(key));
   20752 
   20753 		if (count != zone->parentalscnt) {
   20754 			return false;
   20755 		}
   20756 	} else {
   20757 		(void)dst_key_getnum(key, DST_NUM_DSDELCOUNT, &count);
   20758 		count += 1;
   20759 		dst_key_setnum(key, DST_NUM_DSDELCOUNT, count);
   20760 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20761 			     "checkds: %u DS withdrawn "
   20762 			     "for key %u",
   20763 			     count, dst_key_id(key));
   20764 
   20765 		if (count != zone->parentalscnt) {
   20766 			return false;
   20767 		}
   20768 	}
   20769 
   20770 	dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20771 		     "checkds: checkds %s for key "
   20772 		     "%u",
   20773 		     dspublish ? "published" : "withdrawn", dst_key_id(key));
   20774 
   20775 	dns_zone_lock_keyfiles(zone);
   20776 	result = dns_keymgr_checkds_id(kasp, &zone->checkds_ok, dir, now, now,
   20777 				       dspublish, dst_key_id(key),
   20778 				       dst_key_alg(key));
   20779 	dns_zone_unlock_keyfiles(zone);
   20780 
   20781 	if (result != ISC_R_SUCCESS) {
   20782 		dns_zone_log(zone, ISC_LOG_WARNING,
   20783 			     "checkds: checkds for key %u failed: %s",
   20784 			     dst_key_id(key), isc_result_totext(result));
   20785 		return false;
   20786 	}
   20787 
   20788 	return true;
   20789 }
   20790 
   20791 static isc_result_t
   20792 validate_ds(dns_zone_t *zone, dns_message_t *message) {
   20793 	UNUSED(zone);
   20794 	UNUSED(message);
   20795 
   20796 	/* Get closest trust anchor */
   20797 
   20798 	/* Check that trust anchor is (grand)parent of zone. */
   20799 
   20800 	/* Find the DNSKEY signing the message. */
   20801 
   20802 	/* Check that DNSKEY is in chain of trust. */
   20803 
   20804 	/* Validate DS RRset. */
   20805 
   20806 	return (ISC_R_SUCCESS);
   20807 }
   20808 
   20809 static void
   20810 checkds_done(isc_task_t *task, isc_event_t *event) {
   20811 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   20812 	char rcode[128];
   20813 	dns_checkds_t *checkds;
   20814 	dns_zone_t *zone;
   20815 	dns_db_t *db = NULL;
   20816 	dns_dbversion_t *version = NULL;
   20817 	dns_dnsseckey_t *key;
   20818 	dns_dnsseckeylist_t keys;
   20819 	dns_kasp_t *kasp = NULL;
   20820 	dns_message_t *message = NULL;
   20821 	dns_rdataset_t *ds_rrset = NULL;
   20822 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   20823 	isc_buffer_t buf;
   20824 	isc_result_t result;
   20825 	isc_stdtime_t now;
   20826 	isc_time_t timenow;
   20827 	bool rekey = false;
   20828 	bool empty = false;
   20829 
   20830 	UNUSED(task);
   20831 
   20832 	checkds = event->ev_arg;
   20833 	REQUIRE(DNS_CHECKDS_VALID(checkds));
   20834 
   20835 	zone = checkds->zone;
   20836 	INSIST(task == zone->task);
   20837 
   20838 	ISC_LIST_INIT(keys);
   20839 
   20840 	kasp = zone->kasp;
   20841 	INSIST(kasp != NULL);
   20842 
   20843 	isc_buffer_init(&buf, rcode, sizeof(rcode));
   20844 	isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf));
   20845 
   20846 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "checkds: DS query to %s: done",
   20847 		     addrbuf);
   20848 
   20849 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &message);
   20850 	INSIST(message != NULL);
   20851 
   20852 	CHECK(revent->result);
   20853 	CHECK(dns_request_getresponse(revent->request, message,
   20854 				      DNS_MESSAGEPARSE_PRESERVEORDER));
   20855 	CHECK(dns_rcode_totext(message->rcode, &buf));
   20856 
   20857 	dns_zone_log(zone, ISC_LOG_DEBUG(3),
   20858 		     "checkds: DS response from %s: %.*s", addrbuf,
   20859 		     (int)buf.used, rcode);
   20860 
   20861 	/* Validate response. */
   20862 	CHECK(validate_ds(zone, message));
   20863 
   20864 	/* Check RCODE. */
   20865 	if (message->rcode != dns_rcode_noerror) {
   20866 		dns_zone_log(zone, ISC_LOG_NOTICE,
   20867 			     "checkds: bad DS response from %s: %.*s", addrbuf,
   20868 			     (int)buf.used, rcode);
   20869 		goto failure;
   20870 	}
   20871 
   20872 	/* Make sure that either AA or RA bit is set. */
   20873 	if ((message->flags & DNS_MESSAGEFLAG_AA) == 0 &&
   20874 	    (message->flags & DNS_MESSAGEFLAG_RA) == 0)
   20875 	{
   20876 		dns_zone_log(zone, ISC_LOG_NOTICE,
   20877 			     "checkds: bad DS response from %s: expected AA or "
   20878 			     "RA bit set",
   20879 			     addrbuf);
   20880 		goto failure;
   20881 	}
   20882 
   20883 	/* Lookup DS RRset. */
   20884 	result = dns_message_firstname(message, DNS_SECTION_ANSWER);
   20885 	while (result == ISC_R_SUCCESS) {
   20886 		dns_name_t *name = NULL;
   20887 		dns_rdataset_t *rdataset;
   20888 
   20889 		dns_message_currentname(message, DNS_SECTION_ANSWER, &name);
   20890 		if (dns_name_compare(&zone->origin, name) != 0) {
   20891 			goto next;
   20892 		}
   20893 
   20894 		for (rdataset = ISC_LIST_HEAD(name->list); rdataset != NULL;
   20895 		     rdataset = ISC_LIST_NEXT(rdataset, link))
   20896 		{
   20897 			if (rdataset->type != dns_rdatatype_ds) {
   20898 				goto next;
   20899 			}
   20900 
   20901 			ds_rrset = rdataset;
   20902 			break;
   20903 		}
   20904 
   20905 		if (ds_rrset != NULL) {
   20906 			break;
   20907 		}
   20908 
   20909 	next:
   20910 		result = dns_message_nextname(message, DNS_SECTION_ANSWER);
   20911 	}
   20912 
   20913 	if (ds_rrset == NULL) {
   20914 		empty = true;
   20915 		dns_zone_log(zone, ISC_LOG_NOTICE,
   20916 			     "checkds: empty DS response from %s", addrbuf);
   20917 	}
   20918 
   20919 	TIME_NOW(&timenow);
   20920 	now = isc_time_seconds(&timenow);
   20921 
   20922 	CHECK(dns_zone_getdb(zone, &db));
   20923 	dns_db_currentversion(db, &version);
   20924 
   20925 	KASP_LOCK(kasp);
   20926 	LOCK_ZONE(zone);
   20927 	for (key = ISC_LIST_HEAD(zone->checkds_ok); key != NULL;
   20928 	     key = ISC_LIST_NEXT(key, link))
   20929 	{
   20930 		bool alldone = false, found = false;
   20931 		bool checkdspub = false, checkdsdel = false, ksk = false;
   20932 		dst_key_state_t ds_state = DST_KEY_STATE_NA;
   20933 		isc_stdtime_t published = 0, withdrawn = 0;
   20934 		isc_result_t ret = ISC_R_SUCCESS;
   20935 
   20936 		/* Is this key have the KSK role? */
   20937 		(void)dst_key_role(key->key, &ksk, NULL);
   20938 		if (!ksk) {
   20939 			continue;
   20940 		}
   20941 
   20942 		/* Do we need to check the DS RRset for this key? */
   20943 		(void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state);
   20944 		(void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published);
   20945 		(void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn);
   20946 
   20947 		if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) {
   20948 			checkdspub = true;
   20949 		} else if (ds_state == DST_KEY_STATE_UNRETENTIVE &&
   20950 			   withdrawn == 0)
   20951 		{
   20952 			checkdsdel = true;
   20953 		}
   20954 		if (!checkdspub && !checkdsdel) {
   20955 			continue;
   20956 		}
   20957 
   20958 		if (empty) {
   20959 			goto dswithdrawn;
   20960 		}
   20961 
   20962 		/* Find the appropriate DS record. */
   20963 		ret = dns_rdataset_first(ds_rrset);
   20964 		while (ret == ISC_R_SUCCESS) {
   20965 			dns_rdata_ds_t ds;
   20966 			dns_rdata_t dnskey = DNS_RDATA_INIT;
   20967 			dns_rdata_t dsrdata = DNS_RDATA_INIT;
   20968 			dns_rdata_t rdata = DNS_RDATA_INIT;
   20969 			isc_result_t r;
   20970 			unsigned char dsbuf[DNS_DS_BUFFERSIZE];
   20971 			unsigned char keybuf[DST_KEY_MAXSIZE];
   20972 
   20973 			dns_rdataset_current(ds_rrset, &rdata);
   20974 			r = dns_rdata_tostruct(&rdata, &ds, NULL);
   20975 			if (r != ISC_R_SUCCESS) {
   20976 				goto nextds;
   20977 			}
   20978 			/* Check key tag and algorithm. */
   20979 			if (dst_key_id(key->key) != ds.key_tag) {
   20980 				goto nextds;
   20981 			}
   20982 			if (dst_key_alg(key->key) != ds.algorithm) {
   20983 				goto nextds;
   20984 			}
   20985 			/* Derive DS from DNSKEY, see if the rdata is equal. */
   20986 			make_dnskey(key->key, keybuf, sizeof(keybuf), &dnskey);
   20987 			r = dns_ds_buildrdata(&zone->origin, &dnskey,
   20988 					      ds.digest_type, dsbuf, &dsrdata);
   20989 			if (r != ISC_R_SUCCESS) {
   20990 				goto nextds;
   20991 			}
   20992 			if (dns_rdata_compare(&rdata, &dsrdata) == 0) {
   20993 				found = true;
   20994 				if (checkdspub) {
   20995 					/* DS Published. */
   20996 					alldone = do_checkds(zone, key->key,
   20997 							     now, true);
   20998 					if (alldone) {
   20999 						rekey = true;
   21000 					}
   21001 				}
   21002 			}
   21003 
   21004 		nextds:
   21005 			ret = dns_rdataset_next(ds_rrset);
   21006 		}
   21007 
   21008 	dswithdrawn:
   21009 		/* DS withdrawn. */
   21010 		if (checkdsdel && !found) {
   21011 			alldone = do_checkds(zone, key->key, now, false);
   21012 			if (alldone) {
   21013 				rekey = true;
   21014 			}
   21015 		}
   21016 	}
   21017 	UNLOCK_ZONE(zone);
   21018 	KASP_UNLOCK(kasp);
   21019 
   21020 	/* Rekey after checkds. */
   21021 	if (rekey) {
   21022 		dns_zone_rekey(zone, false);
   21023 	}
   21024 
   21025 failure:
   21026 	if (result != ISC_R_SUCCESS) {
   21027 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21028 			     "checkds: DS request failed: %s",
   21029 			     isc_result_totext(result));
   21030 	}
   21031 
   21032 	if (version != NULL) {
   21033 		dns_db_closeversion(db, &version, false);
   21034 	}
   21035 	if (db != NULL) {
   21036 		dns_db_detach(&db);
   21037 	}
   21038 
   21039 	while (!ISC_LIST_EMPTY(keys)) {
   21040 		key = ISC_LIST_HEAD(keys);
   21041 		ISC_LIST_UNLINK(keys, key, link);
   21042 		dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key);
   21043 	}
   21044 
   21045 	isc_event_free(&event);
   21046 	checkds_destroy(checkds, false);
   21047 	dns_message_detach(&message);
   21048 }
   21049 
   21050 static bool
   21051 checkds_isqueued(dns_zone_t *zone, isc_sockaddr_t *addr, dns_tsigkey_t *key,
   21052 		 dns_transport_t *transport) {
   21053 	dns_checkds_t *checkds;
   21054 
   21055 	for (checkds = ISC_LIST_HEAD(zone->checkds_requests); checkds != NULL;
   21056 	     checkds = ISC_LIST_NEXT(checkds, link))
   21057 	{
   21058 		if (checkds->request != NULL) {
   21059 			continue;
   21060 		}
   21061 		if (addr != NULL && isc_sockaddr_equal(addr, &checkds->dst) &&
   21062 		    checkds->key == key && checkds->transport == transport)
   21063 		{
   21064 			return (true);
   21065 		}
   21066 	}
   21067 	return (false);
   21068 }
   21069 
   21070 static isc_result_t
   21071 checkds_create(isc_mem_t *mctx, unsigned int flags, dns_checkds_t **checkdsp) {
   21072 	dns_checkds_t *checkds;
   21073 
   21074 	REQUIRE(checkdsp != NULL && *checkdsp == NULL);
   21075 
   21076 	checkds = isc_mem_get(mctx, sizeof(*checkds));
   21077 	*checkds = (dns_checkds_t){
   21078 		.flags = flags,
   21079 	};
   21080 
   21081 	isc_mem_attach(mctx, &checkds->mctx);
   21082 	isc_sockaddr_any(&checkds->dst);
   21083 	ISC_LINK_INIT(checkds, link);
   21084 	checkds->magic = CHECKDS_MAGIC;
   21085 	*checkdsp = checkds;
   21086 	return (ISC_R_SUCCESS);
   21087 }
   21088 
   21089 static isc_result_t
   21090 checkds_createmessage(dns_zone_t *zone, dns_message_t **messagep) {
   21091 	dns_message_t *message = NULL;
   21092 
   21093 	dns_name_t *tempname = NULL;
   21094 	dns_rdataset_t *temprdataset = NULL;
   21095 
   21096 	isc_result_t result;
   21097 
   21098 	REQUIRE(DNS_ZONE_VALID(zone));
   21099 	REQUIRE(messagep != NULL && *messagep == NULL);
   21100 
   21101 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   21102 
   21103 	message->opcode = dns_opcode_query;
   21104 	message->rdclass = zone->rdclass;
   21105 	message->flags |= DNS_MESSAGEFLAG_RD;
   21106 
   21107 	result = dns_message_gettempname(message, &tempname);
   21108 	if (result != ISC_R_SUCCESS) {
   21109 		goto cleanup;
   21110 	}
   21111 
   21112 	result = dns_message_gettemprdataset(message, &temprdataset);
   21113 	if (result != ISC_R_SUCCESS) {
   21114 		goto cleanup;
   21115 	}
   21116 
   21117 	/*
   21118 	 * Make question.
   21119 	 */
   21120 	dns_name_init(tempname, NULL);
   21121 	dns_name_clone(&zone->origin, tempname);
   21122 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
   21123 				  dns_rdatatype_ds);
   21124 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   21125 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
   21126 	tempname = NULL;
   21127 	temprdataset = NULL;
   21128 
   21129 	*messagep = message;
   21130 	return (ISC_R_SUCCESS);
   21131 
   21132 cleanup:
   21133 	if (tempname != NULL) {
   21134 		dns_message_puttempname(message, &tempname);
   21135 	}
   21136 	if (temprdataset != NULL) {
   21137 		dns_message_puttemprdataset(message, &temprdataset);
   21138 	}
   21139 	dns_message_detach(&message);
   21140 	return (result);
   21141 }
   21142 
   21143 static void
   21144 checkds_send_toaddr(isc_task_t *task, isc_event_t *event) {
   21145 	dns_checkds_t *checkds;
   21146 	isc_result_t result;
   21147 	dns_message_t *message = NULL;
   21148 	isc_netaddr_t dstip;
   21149 	dns_tsigkey_t *key = NULL;
   21150 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   21151 	isc_sockaddr_t src;
   21152 	unsigned int options, timeout;
   21153 	bool have_checkdssource = false;
   21154 
   21155 	checkds = event->ev_arg;
   21156 	REQUIRE(DNS_CHECKDS_VALID(checkds));
   21157 
   21158 	UNUSED(task);
   21159 
   21160 	LOCK_ZONE(checkds->zone);
   21161 
   21162 	checkds->event = NULL;
   21163 
   21164 	if (DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_LOADED) == 0) {
   21165 		result = ISC_R_CANCELED;
   21166 		goto cleanup;
   21167 	}
   21168 
   21169 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
   21170 	    DNS_ZONE_FLAG(checkds->zone, DNS_ZONEFLG_EXITING) ||
   21171 	    checkds->zone->view->requestmgr == NULL ||
   21172 	    checkds->zone->db == NULL)
   21173 	{
   21174 		result = ISC_R_CANCELED;
   21175 		goto cleanup;
   21176 	}
   21177 
   21178 	/*
   21179 	 * The raw IPv4 address should also exist.  Don't send to the
   21180 	 * mapped form.
   21181 	 */
   21182 	if (isc_sockaddr_pf(&checkds->dst) == PF_INET6 &&
   21183 	    IN6_IS_ADDR_V4MAPPED(&checkds->dst.type.sin6.sin6_addr))
   21184 	{
   21185 		isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf));
   21186 		dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21187 			     "checkds: ignoring IPv6 mapped IPV4 address: %s",
   21188 			     addrbuf);
   21189 		result = ISC_R_CANCELED;
   21190 		goto cleanup;
   21191 	}
   21192 
   21193 	result = checkds_createmessage(checkds->zone, &message);
   21194 	if (result != ISC_R_SUCCESS) {
   21195 		goto cleanup;
   21196 	}
   21197 
   21198 	isc_sockaddr_format(&checkds->dst, addrbuf, sizeof(addrbuf));
   21199 	if (checkds->key != NULL) {
   21200 		/* Transfer ownership of key */
   21201 		key = checkds->key;
   21202 		checkds->key = NULL;
   21203 	} else {
   21204 		isc_netaddr_fromsockaddr(&dstip, &checkds->dst);
   21205 		result = dns_view_getpeertsig(checkds->zone->view, &dstip,
   21206 					      &key);
   21207 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   21208 			dns_zone_log(checkds->zone, ISC_LOG_ERROR,
   21209 				     "checkds: DS query to %s not sent. "
   21210 				     "Peer TSIG key lookup failure.",
   21211 				     addrbuf);
   21212 			goto cleanup_message;
   21213 		}
   21214 	}
   21215 
   21216 	if (key != NULL) {
   21217 		char namebuf[DNS_NAME_FORMATSIZE];
   21218 
   21219 		dns_name_format(&key->name, namebuf, sizeof(namebuf));
   21220 		dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21221 			     "checkds: sending DS query to %s : TSIG (%s)",
   21222 			     addrbuf, namebuf);
   21223 	} else {
   21224 		dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21225 			     "checkds: sending DS query to %s", addrbuf);
   21226 	}
   21227 	options = 0;
   21228 	if (checkds->zone->view->peers != NULL) {
   21229 		dns_peer_t *peer = NULL;
   21230 		bool usetcp = false;
   21231 		result = dns_peerlist_peerbyaddr(checkds->zone->view->peers,
   21232 						 &dstip, &peer);
   21233 		if (result == ISC_R_SUCCESS) {
   21234 			result = dns_peer_getquerysource(peer, &src);
   21235 			if (result == ISC_R_SUCCESS) {
   21236 				have_checkdssource = true;
   21237 			}
   21238 			result = dns_peer_getforcetcp(peer, &usetcp);
   21239 			if (result == ISC_R_SUCCESS && usetcp) {
   21240 				options |= DNS_FETCHOPT_TCP;
   21241 			}
   21242 		}
   21243 	}
   21244 	switch (isc_sockaddr_pf(&checkds->dst)) {
   21245 	case PF_INET:
   21246 		if (!have_checkdssource) {
   21247 			src = checkds->zone->parentalsrc4;
   21248 		}
   21249 		break;
   21250 	case PF_INET6:
   21251 		if (!have_checkdssource) {
   21252 			src = checkds->zone->parentalsrc6;
   21253 		}
   21254 		break;
   21255 	default:
   21256 		result = ISC_R_NOTIMPLEMENTED;
   21257 		goto cleanup_key;
   21258 	}
   21259 
   21260 	dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21261 		     "checkds: create request for DS query to %s", addrbuf);
   21262 
   21263 	timeout = 5;
   21264 	options |= DNS_REQUESTOPT_TCP;
   21265 	result = dns_request_create(
   21266 		checkds->zone->view->requestmgr, message, &src, &checkds->dst,
   21267 		options, key, timeout * 3 + 1, timeout, 2, checkds->zone->task,
   21268 		checkds_done, checkds, &checkds->request);
   21269 	if (result != ISC_R_SUCCESS) {
   21270 		dns_zone_log(checkds->zone, ISC_LOG_DEBUG(3),
   21271 			     "checkds: dns_request_create() to %s failed: %s",
   21272 			     addrbuf, isc_result_totext(result));
   21273 	}
   21274 
   21275 cleanup_key:
   21276 	if (key != NULL) {
   21277 		dns_tsigkey_detach(&key);
   21278 	}
   21279 cleanup_message:
   21280 	dns_message_detach(&message);
   21281 cleanup:
   21282 	UNLOCK_ZONE(checkds->zone);
   21283 	isc_event_free(&event);
   21284 	if (result != ISC_R_SUCCESS) {
   21285 		checkds_destroy(checkds, false);
   21286 	}
   21287 }
   21288 
   21289 static isc_result_t
   21290 checkds_send_queue(dns_checkds_t *checkds) {
   21291 	isc_event_t *e;
   21292 	isc_result_t result;
   21293 
   21294 	INSIST(checkds->event == NULL);
   21295 	e = isc_event_allocate(checkds->mctx, NULL, DNS_EVENT_CHECKDSSENDTOADDR,
   21296 			       checkds_send_toaddr, checkds,
   21297 			       sizeof(isc_event_t));
   21298 	e->ev_arg = checkds;
   21299 	e->ev_sender = NULL;
   21300 	result = isc_ratelimiter_enqueue(checkds->zone->zmgr->checkdsrl,
   21301 					 checkds->zone->task, &e);
   21302 	if (result != ISC_R_SUCCESS) {
   21303 		isc_event_free(&e);
   21304 		checkds->event = NULL;
   21305 	}
   21306 	return (result);
   21307 }
   21308 
   21309 static void
   21310 checkds_send(dns_zone_t *zone) {
   21311 	dns_view_t *view = dns_zone_getview(zone);
   21312 	isc_result_t result;
   21313 	unsigned int flags = 0;
   21314 
   21315 	/*
   21316 	 * Zone lock held by caller.
   21317 	 */
   21318 	REQUIRE(LOCKED_ZONE(zone));
   21319 
   21320 	dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21321 		     "checkds: start sending DS queries to %u parentals",
   21322 		     zone->parentalscnt);
   21323 
   21324 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   21325 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21326 			     "checkds: abort, named exiting");
   21327 		return;
   21328 	}
   21329 
   21330 	for (unsigned int i = 0; i < zone->parentalscnt; i++) {
   21331 		dns_tsigkey_t *key = NULL;
   21332 		dns_transport_t *transport = NULL;
   21333 		isc_sockaddr_t dst;
   21334 		dns_checkds_t *checkds = NULL;
   21335 
   21336 		if ((zone->parentalkeynames != NULL) &&
   21337 		    (zone->parentalkeynames[i] != NULL))
   21338 		{
   21339 			dns_name_t *keyname = zone->parentalkeynames[i];
   21340 			(void)dns_view_gettsig(view, keyname, &key);
   21341 		}
   21342 
   21343 		if ((zone->parentaltlsnames != NULL) &&
   21344 		    (zone->parentaltlsnames[i] != NULL))
   21345 		{
   21346 			dns_name_t *tlsname = zone->parentaltlsnames[i];
   21347 			(void)dns_view_gettransport(view, DNS_TRANSPORT_TLS,
   21348 						    tlsname, &transport);
   21349 			dns_zone_logc(
   21350 				zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   21351 				"got TLS configuration for zone transfer");
   21352 		}
   21353 
   21354 		dst = zone->parentals[i];
   21355 
   21356 		/* TODO: glue the transport to the checkds request */
   21357 
   21358 		if (checkds_isqueued(zone, &dst, key, transport)) {
   21359 			dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21360 				     "checkds: DS query to parent "
   21361 				     "%d is queued",
   21362 				     i);
   21363 			if (key != NULL) {
   21364 				dns_tsigkey_detach(&key);
   21365 			}
   21366 			if (transport != NULL) {
   21367 				dns_transport_detach(&transport);
   21368 			}
   21369 			continue;
   21370 		}
   21371 
   21372 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21373 			     "checkds: create DS query for "
   21374 			     "parent %d",
   21375 			     i);
   21376 
   21377 		result = checkds_create(zone->mctx, flags, &checkds);
   21378 		if (result != ISC_R_SUCCESS) {
   21379 			dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21380 				     "checkds: create DS query for "
   21381 				     "parent %d failed",
   21382 				     i);
   21383 			continue;
   21384 		}
   21385 		zone_iattach(zone, &checkds->zone);
   21386 		checkds->dst = dst;
   21387 
   21388 		INSIST(checkds->key == NULL);
   21389 		if (key != NULL) {
   21390 			checkds->key = key;
   21391 			key = NULL;
   21392 		}
   21393 
   21394 		INSIST(checkds->transport == NULL);
   21395 		if (transport != NULL) {
   21396 			checkds->transport = transport;
   21397 			transport = NULL;
   21398 		}
   21399 
   21400 		ISC_LIST_APPEND(zone->checkds_requests, checkds, link);
   21401 		result = checkds_send_queue(checkds);
   21402 		if (result != ISC_R_SUCCESS) {
   21403 			dns_zone_log(zone, ISC_LOG_DEBUG(3),
   21404 				     "checkds: send DS query to "
   21405 				     "parent %d failed",
   21406 				     i);
   21407 			checkds_destroy(checkds, true);
   21408 		}
   21409 	}
   21410 }
   21411 
   21412 static void
   21413 zone_checkds(dns_zone_t *zone) {
   21414 	bool cdscheck = false;
   21415 
   21416 	for (dns_dnsseckey_t *key = ISC_LIST_HEAD(zone->checkds_ok);
   21417 	     key != NULL; key = ISC_LIST_NEXT(key, link))
   21418 	{
   21419 		dst_key_state_t ds_state = DST_KEY_STATE_NA;
   21420 		bool ksk = false;
   21421 		isc_stdtime_t published = 0, withdrawn = 0;
   21422 
   21423 		/* Is this key have the KSK role? */
   21424 		(void)dst_key_role(key->key, &ksk, NULL);
   21425 		if (!ksk) {
   21426 			continue;
   21427 		}
   21428 
   21429 		/* Do we need to check the DS RRset? */
   21430 		(void)dst_key_getstate(key->key, DST_KEY_DS, &ds_state);
   21431 		(void)dst_key_gettime(key->key, DST_TIME_DSPUBLISH, &published);
   21432 		(void)dst_key_gettime(key->key, DST_TIME_DSDELETE, &withdrawn);
   21433 
   21434 		if (ds_state == DST_KEY_STATE_RUMOURED && published == 0) {
   21435 			dst_key_setnum(key->key, DST_NUM_DSPUBCOUNT, 0);
   21436 			cdscheck = true;
   21437 		} else if (ds_state == DST_KEY_STATE_UNRETENTIVE &&
   21438 			   withdrawn == 0)
   21439 		{
   21440 			dst_key_setnum(key->key, DST_NUM_DSDELCOUNT, 0);
   21441 			cdscheck = true;
   21442 		}
   21443 	}
   21444 
   21445 	if (cdscheck) {
   21446 		/* Request the DS RRset. */
   21447 		LOCK_ZONE(zone);
   21448 		checkds_send(zone);
   21449 		UNLOCK_ZONE(zone);
   21450 	}
   21451 }
   21452 
   21453 static void
   21454 zone_rekey(dns_zone_t *zone) {
   21455 	isc_result_t result;
   21456 	dns_db_t *db = NULL;
   21457 	dns_dbnode_t *node = NULL;
   21458 	dns_dbversion_t *ver = NULL;
   21459 	dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset;
   21460 	dns_dnsseckeylist_t dnskeys, keys, rmkeys;
   21461 	dns_dnsseckey_t *key = NULL;
   21462 	dns_diff_t diff, _sig_diff;
   21463 	dns_kasp_t *kasp;
   21464 	dns__zonediff_t zonediff;
   21465 	bool commit = false, newactive = false;
   21466 	bool newalg = false;
   21467 	bool fullsign;
   21468 	dns_ttl_t ttl = 3600;
   21469 	const char *dir = NULL;
   21470 	isc_mem_t *mctx = NULL;
   21471 	isc_stdtime_t now, nexttime = 0;
   21472 	isc_time_t timenow;
   21473 	isc_interval_t ival;
   21474 	char timebuf[80];
   21475 
   21476 	REQUIRE(DNS_ZONE_VALID(zone));
   21477 
   21478 	ISC_LIST_INIT(dnskeys);
   21479 	ISC_LIST_INIT(keys);
   21480 	ISC_LIST_INIT(rmkeys);
   21481 	dns_rdataset_init(&soaset);
   21482 	dns_rdataset_init(&soasigs);
   21483 	dns_rdataset_init(&keyset);
   21484 	dns_rdataset_init(&keysigs);
   21485 	dns_rdataset_init(&cdsset);
   21486 	dns_rdataset_init(&cdnskeyset);
   21487 	dir = dns_zone_getkeydirectory(zone);
   21488 	mctx = zone->mctx;
   21489 	dns_diff_init(mctx, &diff);
   21490 	dns_diff_init(mctx, &_sig_diff);
   21491 	zonediff_init(&zonediff, &_sig_diff);
   21492 
   21493 	CHECK(dns_zone_getdb(zone, &db));
   21494 	CHECK(dns_db_newversion(db, &ver));
   21495 	CHECK(dns_db_getoriginnode(db, &node));
   21496 
   21497 	TIME_NOW(&timenow);
   21498 	now = isc_time_seconds(&timenow);
   21499 
   21500 	kasp = dns_zone_getkasp(zone);
   21501 
   21502 	dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
   21503 
   21504 	/* Get the SOA record's TTL */
   21505 	CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
   21506 				  dns_rdatatype_none, 0, &soaset, &soasigs));
   21507 	ttl = soaset.ttl;
   21508 	dns_rdataset_disassociate(&soaset);
   21509 
   21510 	/* Get the DNSKEY rdataset */
   21511 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   21512 				     dns_rdatatype_none, 0, &keyset, &keysigs);
   21513 	if (result == ISC_R_SUCCESS) {
   21514 		ttl = keyset.ttl;
   21515 
   21516 		dns_zone_lock_keyfiles(zone);
   21517 
   21518 		result = dns_dnssec_keylistfromrdataset(
   21519 			&zone->origin, dir, mctx, &keyset, &keysigs, &soasigs,
   21520 			false, false, &dnskeys);
   21521 
   21522 		dns_zone_unlock_keyfiles(zone);
   21523 
   21524 		if (result != ISC_R_SUCCESS) {
   21525 			goto failure;
   21526 		}
   21527 	} else if (result != ISC_R_NOTFOUND) {
   21528 		goto failure;
   21529 	}
   21530 
   21531 	/* Get the CDS rdataset */
   21532 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds,
   21533 				     dns_rdatatype_none, 0, &cdsset, NULL);
   21534 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) {
   21535 		dns_rdataset_disassociate(&cdsset);
   21536 	}
   21537 
   21538 	/* Get the CDNSKEY rdataset */
   21539 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey,
   21540 				     dns_rdatatype_none, 0, &cdnskeyset, NULL);
   21541 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) {
   21542 		dns_rdataset_disassociate(&cdnskeyset);
   21543 	}
   21544 
   21545 	/*
   21546 	 * True when called from "rndc sign".  Indicates the zone should be
   21547 	 * fully signed now.
   21548 	 */
   21549 	fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
   21550 
   21551 	KASP_LOCK(kasp);
   21552 
   21553 	dns_zone_lock_keyfiles(zone);
   21554 	result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
   21555 					     &keys);
   21556 	dns_zone_unlock_keyfiles(zone);
   21557 
   21558 	if (result != ISC_R_SUCCESS) {
   21559 		dnssec_log(zone, ISC_LOG_DEBUG(1),
   21560 			   "zone_rekey:dns_dnssec_findmatchingkeys failed: %s",
   21561 			   isc_result_totext(result));
   21562 	}
   21563 
   21564 	if (kasp != NULL) {
   21565 		/*
   21566 		 * Check DS at parental agents. Clear ongoing checks.
   21567 		 */
   21568 		LOCK_ZONE(zone);
   21569 		checkds_cancel(zone);
   21570 		clear_keylist(&zone->checkds_ok, zone->mctx);
   21571 		ISC_LIST_INIT(zone->checkds_ok);
   21572 		UNLOCK_ZONE(zone);
   21573 
   21574 		result = dns_zone_getdnsseckeys(zone, db, ver, now,
   21575 						&zone->checkds_ok);
   21576 
   21577 		if (result == ISC_R_SUCCESS) {
   21578 			zone_checkds(zone);
   21579 		} else {
   21580 			dnssec_log(zone,
   21581 				   (result == ISC_R_NOTFOUND) ? ISC_LOG_DEBUG(1)
   21582 							      : ISC_LOG_ERROR,
   21583 				   "zone_rekey:dns_zone_getdnsseckeys failed: "
   21584 				   "%s",
   21585 				   isc_result_totext(result));
   21586 		}
   21587 
   21588 		if (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND) {
   21589 			dns_zone_lock_keyfiles(zone);
   21590 			result = dns_keymgr_run(&zone->origin, zone->rdclass,
   21591 						dir, mctx, &keys, &dnskeys,
   21592 						kasp, now, &nexttime);
   21593 			dns_zone_unlock_keyfiles(zone);
   21594 
   21595 			if (result != ISC_R_SUCCESS) {
   21596 				dnssec_log(zone, ISC_LOG_ERROR,
   21597 					   "zone_rekey:dns_dnssec_keymgr "
   21598 					   "failed: %s",
   21599 					   isc_result_totext(result));
   21600 				KASP_UNLOCK(kasp);
   21601 				goto failure;
   21602 			}
   21603 		}
   21604 	}
   21605 
   21606 	KASP_UNLOCK(kasp);
   21607 
   21608 	if (result == ISC_R_SUCCESS) {
   21609 		bool cdsdel = false;
   21610 		bool cdnskeydel = false;
   21611 		bool sane_diff, sane_dnskey;
   21612 		isc_stdtime_t when;
   21613 
   21614 		/*
   21615 		 * Publish CDS/CDNSKEY DELETE records if the zone is
   21616 		 * transitioning from secure to insecure.
   21617 		 */
   21618 		if (kasp != NULL) {
   21619 			if (strcmp(dns_kasp_getname(kasp), "insecure") == 0) {
   21620 				cdsdel = true;
   21621 				cdnskeydel = true;
   21622 			}
   21623 		} else {
   21624 			/* Check if there is a CDS DELETE record. */
   21625 			if (dns_rdataset_isassociated(&cdsset)) {
   21626 				for (result = dns_rdataset_first(&cdsset);
   21627 				     result == ISC_R_SUCCESS;
   21628 				     result = dns_rdataset_next(&cdsset))
   21629 				{
   21630 					dns_rdata_t crdata = DNS_RDATA_INIT;
   21631 					dns_rdataset_current(&cdsset, &crdata);
   21632 					/*
   21633 					 * CDS deletion record has this form
   21634 					 * "0 0 0 00" which is 5 zero octets.
   21635 					 */
   21636 					if (crdata.length == 5U &&
   21637 					    memcmp(crdata.data,
   21638 						   (unsigned char[5]){ 0, 0, 0,
   21639 								       0, 0 },
   21640 						   5) == 0)
   21641 					{
   21642 						cdsdel = true;
   21643 						break;
   21644 					}
   21645 				}
   21646 			}
   21647 
   21648 			/* Check if there is a CDNSKEY DELETE record. */
   21649 			if (dns_rdataset_isassociated(&cdnskeyset)) {
   21650 				for (result = dns_rdataset_first(&cdnskeyset);
   21651 				     result == ISC_R_SUCCESS;
   21652 				     result = dns_rdataset_next(&cdnskeyset))
   21653 				{
   21654 					dns_rdata_t crdata = DNS_RDATA_INIT;
   21655 					dns_rdataset_current(&cdnskeyset,
   21656 							     &crdata);
   21657 					/*
   21658 					 * CDNSKEY deletion record has this form
   21659 					 * "0 3 0 AA==" which is 2 zero octets,
   21660 					 * a 3, and 2 zero octets.
   21661 					 */
   21662 					if (crdata.length == 5U &&
   21663 					    memcmp(crdata.data,
   21664 						   (unsigned char[5]){ 0, 0, 3,
   21665 								       0, 0 },
   21666 						   5) == 0)
   21667 					{
   21668 						cdnskeydel = true;
   21669 						break;
   21670 					}
   21671 				}
   21672 			}
   21673 		}
   21674 
   21675 		/*
   21676 		 * Only update DNSKEY TTL if we have a policy.
   21677 		 */
   21678 		if (kasp != NULL) {
   21679 			ttl = dns_kasp_dnskeyttl(kasp);
   21680 		}
   21681 
   21682 		result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
   21683 					       &zone->origin, ttl, &diff, mctx,
   21684 					       dnssec_report);
   21685 		/*
   21686 		 * Keys couldn't be updated for some reason;
   21687 		 * try again later.
   21688 		 */
   21689 		if (result != ISC_R_SUCCESS) {
   21690 			dnssec_log(zone, ISC_LOG_ERROR,
   21691 				   "zone_rekey:couldn't update zone keys: %s",
   21692 				   isc_result_totext(result));
   21693 			goto failure;
   21694 		}
   21695 
   21696 		/*
   21697 		 * Update CDS / CDNSKEY records.
   21698 		 */
   21699 		result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset,
   21700 					       &cdnskeyset, now, ttl, &diff,
   21701 					       mctx);
   21702 		if (result != ISC_R_SUCCESS) {
   21703 			dnssec_log(zone, ISC_LOG_ERROR,
   21704 				   "zone_rekey:couldn't update CDS/CDNSKEY: %s",
   21705 				   isc_result_totext(result));
   21706 			goto failure;
   21707 		}
   21708 
   21709 		if (cdsdel || cdnskeydel) {
   21710 			/*
   21711 			 * Only publish CDS/CDNSKEY DELETE records if there is
   21712 			 * a KSK that can be used to verify the RRset. This
   21713 			 * means there must be a key with the KSK role that is
   21714 			 * published and is used for signing.
   21715 			 */
   21716 			bool allow = false;
   21717 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21718 			     key = ISC_LIST_NEXT(key, link))
   21719 			{
   21720 				dst_key_t *dstk = key->key;
   21721 
   21722 				if (dst_key_is_published(dstk, now, &when) &&
   21723 				    dst_key_is_signing(dstk, DST_BOOL_KSK, now,
   21724 						       &when))
   21725 				{
   21726 					allow = true;
   21727 					break;
   21728 				}
   21729 			}
   21730 			if (cdsdel) {
   21731 				cdsdel = allow;
   21732 			}
   21733 			if (cdnskeydel) {
   21734 				cdnskeydel = allow;
   21735 			}
   21736 		}
   21737 		result = dns_dnssec_syncdelete(
   21738 			&cdsset, &cdnskeyset, &zone->origin, zone->rdclass, ttl,
   21739 			&diff, mctx, cdsdel, cdnskeydel);
   21740 		if (result != ISC_R_SUCCESS) {
   21741 			dnssec_log(zone, ISC_LOG_ERROR,
   21742 				   "zone_rekey:couldn't update CDS/CDNSKEY "
   21743 				   "DELETE records: %s",
   21744 				   isc_result_totext(result));
   21745 			goto failure;
   21746 		}
   21747 
   21748 		/*
   21749 		 * See if any pre-existing keys have newly become active;
   21750 		 * also, see if any new key is for a new algorithm, as in that
   21751 		 * event, we need to sign the zone fully.  (If there's a new
   21752 		 * key, but it's for an already-existing algorithm, then
   21753 		 * the zone signing can be handled incrementally.)
   21754 		 */
   21755 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21756 		     key = ISC_LIST_NEXT(key, link))
   21757 		{
   21758 			if (!key->first_sign) {
   21759 				continue;
   21760 			}
   21761 
   21762 			newactive = true;
   21763 
   21764 			if (!dns_rdataset_isassociated(&keysigs)) {
   21765 				newalg = true;
   21766 				break;
   21767 			}
   21768 
   21769 			if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
   21770 				/*
   21771 				 * This isn't a new algorithm; clear
   21772 				 * first_sign so we won't sign the
   21773 				 * whole zone with this key later.
   21774 				 */
   21775 				key->first_sign = false;
   21776 			} else {
   21777 				newalg = true;
   21778 				break;
   21779 			}
   21780 		}
   21781 
   21782 		/*
   21783 		 * A sane diff is one that is not empty, and that does not
   21784 		 * introduce a zone with NSEC only DNSKEYs along with NSEC3
   21785 		 * chains.
   21786 		 */
   21787 		sane_dnskey = dns_zone_check_dnskey_nsec3(zone, db, ver, &diff,
   21788 							  NULL, 0);
   21789 		sane_diff = !ISC_LIST_EMPTY(diff.tuples) && sane_dnskey;
   21790 		if (!sane_dnskey) {
   21791 			dnssec_log(zone, ISC_LOG_ERROR,
   21792 				   "NSEC only DNSKEYs and NSEC3 chains not "
   21793 				   "allowed");
   21794 		}
   21795 
   21796 		if (newactive || fullsign || sane_diff) {
   21797 			CHECK(dns_diff_apply(&diff, db, ver));
   21798 			CHECK(clean_nsec3param(zone, db, ver, &diff));
   21799 			CHECK(add_signing_records(db, zone->privatetype, ver,
   21800 						  &diff, (newalg || fullsign)));
   21801 			CHECK(update_soa_serial(zone, db, ver, &diff, mctx,
   21802 						zone->updatemethod));
   21803 			CHECK(add_chains(zone, db, ver, &diff));
   21804 			CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff));
   21805 			CHECK(zone_journal(zone, zonediff.diff, NULL,
   21806 					   "zone_rekey"));
   21807 			commit = true;
   21808 		}
   21809 	}
   21810 
   21811 	dns_db_closeversion(db, &ver, true);
   21812 
   21813 	LOCK_ZONE(zone);
   21814 
   21815 	if (commit) {
   21816 		dns_difftuple_t *tuple;
   21817 		dns_stats_t *dnssecsignstats =
   21818 			dns_zone_getdnssecsignstats(zone);
   21819 
   21820 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   21821 
   21822 		zone_needdump(zone, DNS_DUMP_DELAY);
   21823 
   21824 		zone_settimer(zone, &timenow);
   21825 
   21826 		/* Remove any signatures from removed keys.  */
   21827 		if (!ISC_LIST_EMPTY(rmkeys)) {
   21828 			for (key = ISC_LIST_HEAD(rmkeys); key != NULL;
   21829 			     key = ISC_LIST_NEXT(key, link))
   21830 			{
   21831 				result = zone_signwithkey(
   21832 					zone, dst_key_alg(key->key),
   21833 					dst_key_id(key->key), true);
   21834 				if (result != ISC_R_SUCCESS) {
   21835 					dnssec_log(zone, ISC_LOG_ERROR,
   21836 						   "zone_signwithkey failed: "
   21837 						   "%s",
   21838 						   isc_result_totext(result));
   21839 				}
   21840 
   21841 				/* Clear DNSSEC sign statistics. */
   21842 				if (dnssecsignstats != NULL) {
   21843 					dns_dnssecsignstats_clear(
   21844 						dnssecsignstats,
   21845 						dst_key_id(key->key),
   21846 						dst_key_alg(key->key));
   21847 					/*
   21848 					 * Also clear the dnssec-sign
   21849 					 * statistics of the revoked key id.
   21850 					 */
   21851 					dns_dnssecsignstats_clear(
   21852 						dnssecsignstats,
   21853 						dst_key_rid(key->key),
   21854 						dst_key_alg(key->key));
   21855 				}
   21856 			}
   21857 		}
   21858 
   21859 		if (fullsign) {
   21860 			/*
   21861 			 * "rndc sign" was called, so we now sign the zone
   21862 			 * with all active keys, whether they're new or not.
   21863 			 */
   21864 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21865 			     key = ISC_LIST_NEXT(key, link))
   21866 			{
   21867 				if (!key->force_sign && !key->hint_sign) {
   21868 					continue;
   21869 				}
   21870 
   21871 				result = zone_signwithkey(
   21872 					zone, dst_key_alg(key->key),
   21873 					dst_key_id(key->key), false);
   21874 				if (result != ISC_R_SUCCESS) {
   21875 					dnssec_log(zone, ISC_LOG_ERROR,
   21876 						   "zone_signwithkey failed: "
   21877 						   "%s",
   21878 						   isc_result_totext(result));
   21879 				}
   21880 			}
   21881 		} else if (newalg) {
   21882 			/*
   21883 			 * We haven't been told to sign fully, but a new
   21884 			 * algorithm was added to the DNSKEY.  We sign
   21885 			 * the full zone, but only with newly active
   21886 			 * keys.
   21887 			 */
   21888 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   21889 			     key = ISC_LIST_NEXT(key, link))
   21890 			{
   21891 				if (!key->first_sign) {
   21892 					continue;
   21893 				}
   21894 
   21895 				result = zone_signwithkey(
   21896 					zone, dst_key_alg(key->key),
   21897 					dst_key_id(key->key), false);
   21898 				if (result != ISC_R_SUCCESS) {
   21899 					dnssec_log(zone, ISC_LOG_ERROR,
   21900 						   "zone_signwithkey failed: "
   21901 						   "%s",
   21902 						   isc_result_totext(result));
   21903 				}
   21904 			}
   21905 		}
   21906 
   21907 		/*
   21908 		 * Clear fullsign flag, if it was set, so we don't do
   21909 		 * another full signing next time.
   21910 		 */
   21911 		DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN);
   21912 
   21913 		/*
   21914 		 * Cause the zone to add/delete NSEC3 chains for the
   21915 		 * deferred NSEC3PARAM changes.
   21916 		 */
   21917 		for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
   21918 		     tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link))
   21919 		{
   21920 			unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   21921 			dns_rdata_t rdata = DNS_RDATA_INIT;
   21922 			dns_rdata_nsec3param_t nsec3param;
   21923 
   21924 			if (tuple->rdata.type != zone->privatetype ||
   21925 			    tuple->op != DNS_DIFFOP_ADD)
   21926 			{
   21927 				continue;
   21928 			}
   21929 
   21930 			if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
   21931 							buf, sizeof(buf)))
   21932 			{
   21933 				continue;
   21934 			}
   21935 
   21936 			result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   21937 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   21938 			if (nsec3param.flags == 0) {
   21939 				continue;
   21940 			}
   21941 
   21942 			result = zone_addnsec3chain(zone, &nsec3param);
   21943 			if (result != ISC_R_SUCCESS) {
   21944 				dnssec_log(zone, ISC_LOG_ERROR,
   21945 					   "zone_addnsec3chain failed: %s",
   21946 					   isc_result_totext(result));
   21947 			}
   21948 		}
   21949 
   21950 		/*
   21951 		 * Activate any NSEC3 chain updates that may have
   21952 		 * been scheduled before this rekey.
   21953 		 */
   21954 		if (fullsign || newalg) {
   21955 			resume_addnsec3chain(zone);
   21956 		}
   21957 
   21958 		/*
   21959 		 * Schedule the next resigning event
   21960 		 */
   21961 		set_resigntime(zone);
   21962 	}
   21963 
   21964 	isc_time_settoepoch(&zone->refreshkeytime);
   21965 
   21966 	/*
   21967 	 * If keymgr provided a next time, use the calculated next rekey time.
   21968 	 */
   21969 	if (kasp != NULL) {
   21970 		isc_time_t timenext;
   21971 		uint32_t nexttime_seconds;
   21972 
   21973 		/*
   21974 		 * Set the key refresh timer to the next scheduled key event
   21975 		 * or to 'dnssec-loadkeys-interval' seconds in the future
   21976 		 * if no next key event is scheduled (nexttime == 0).
   21977 		 */
   21978 		if (nexttime > 0) {
   21979 			nexttime_seconds = nexttime - now;
   21980 		} else {
   21981 			nexttime_seconds = zone->refreshkeyinterval;
   21982 		}
   21983 
   21984 		DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext);
   21985 		zone->refreshkeytime = timenext;
   21986 		zone_settimer(zone, &timenow);
   21987 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   21988 
   21989 		dnssec_log(zone, ISC_LOG_DEBUG(3),
   21990 			   "next key event in %u seconds", nexttime_seconds);
   21991 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   21992 	}
   21993 	/*
   21994 	 * If we're doing key maintenance, set the key refresh timer to
   21995 	 * the next scheduled key event or to 'dnssec-loadkeys-interval'
   21996 	 * seconds in the future, whichever is sooner.
   21997 	 */
   21998 	else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   21999 	{
   22000 		isc_time_t timethen;
   22001 		isc_stdtime_t then;
   22002 
   22003 		DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
   22004 				  &timethen);
   22005 		zone->refreshkeytime = timethen;
   22006 
   22007 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   22008 		     key = ISC_LIST_NEXT(key, link))
   22009 		{
   22010 			then = now;
   22011 			result = next_keyevent(key->key, &then);
   22012 			if (result != ISC_R_SUCCESS) {
   22013 				continue;
   22014 			}
   22015 
   22016 			DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   22017 			if (isc_time_compare(&timethen, &zone->refreshkeytime) <
   22018 			    0)
   22019 			{
   22020 				zone->refreshkeytime = timethen;
   22021 			}
   22022 		}
   22023 
   22024 		zone_settimer(zone, &timenow);
   22025 
   22026 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   22027 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   22028 	}
   22029 	UNLOCK_ZONE(zone);
   22030 
   22031 	if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   22032 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   22033 		     key = ISC_LIST_NEXT(key, link))
   22034 		{
   22035 			/* This debug log is used in the kasp system test */
   22036 			char algbuf[DNS_SECALG_FORMATSIZE];
   22037 			dns_secalg_format(dst_key_alg(key->key), algbuf,
   22038 					  sizeof(algbuf));
   22039 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   22040 				   "zone_rekey done: key %d/%s",
   22041 				   dst_key_id(key->key), algbuf);
   22042 		}
   22043 	}
   22044 
   22045 	result = ISC_R_SUCCESS;
   22046 
   22047 failure:
   22048 	LOCK_ZONE(zone);
   22049 	if (result != ISC_R_SUCCESS) {
   22050 		/*
   22051 		 * Something went wrong; try again in ten minutes or
   22052 		 * after a key refresh interval, whichever is shorter.
   22053 		 */
   22054 		dnssec_log(zone, ISC_LOG_DEBUG(3),
   22055 			   "zone_rekey failure: %s (retry in %u seconds)",
   22056 			   isc_result_totext(result),
   22057 			   ISC_MIN(zone->refreshkeyinterval, 600));
   22058 		isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600),
   22059 				 0);
   22060 		isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
   22061 	}
   22062 	UNLOCK_ZONE(zone);
   22063 
   22064 	dns_diff_clear(&diff);
   22065 	dns_diff_clear(&_sig_diff);
   22066 
   22067 	clear_keylist(&dnskeys, mctx);
   22068 	clear_keylist(&keys, mctx);
   22069 	clear_keylist(&rmkeys, mctx);
   22070 
   22071 	if (ver != NULL) {
   22072 		dns_db_closeversion(db, &ver, false);
   22073 	}
   22074 	if (dns_rdataset_isassociated(&cdsset)) {
   22075 		dns_rdataset_disassociate(&cdsset);
   22076 	}
   22077 	if (dns_rdataset_isassociated(&keyset)) {
   22078 		dns_rdataset_disassociate(&keyset);
   22079 	}
   22080 	if (dns_rdataset_isassociated(&keysigs)) {
   22081 		dns_rdataset_disassociate(&keysigs);
   22082 	}
   22083 	if (dns_rdataset_isassociated(&soasigs)) {
   22084 		dns_rdataset_disassociate(&soasigs);
   22085 	}
   22086 	if (dns_rdataset_isassociated(&cdnskeyset)) {
   22087 		dns_rdataset_disassociate(&cdnskeyset);
   22088 	}
   22089 	if (node != NULL) {
   22090 		dns_db_detachnode(db, &node);
   22091 	}
   22092 	if (db != NULL) {
   22093 		dns_db_detach(&db);
   22094 	}
   22095 
   22096 	INSIST(ver == NULL);
   22097 }
   22098 
   22099 void
   22100 dns_zone_rekey(dns_zone_t *zone, bool fullsign) {
   22101 	isc_time_t now;
   22102 
   22103 	if (zone->type == dns_zone_primary && zone->task != NULL) {
   22104 		LOCK_ZONE(zone);
   22105 
   22106 		if (fullsign) {
   22107 			DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN);
   22108 		}
   22109 
   22110 		TIME_NOW(&now);
   22111 		zone->refreshkeytime = now;
   22112 		zone_settimer(zone, &now);
   22113 
   22114 		UNLOCK_ZONE(zone);
   22115 	}
   22116 }
   22117 
   22118 isc_result_t
   22119 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   22120 		 unsigned int *errors) {
   22121 	isc_result_t result;
   22122 	dns_dbnode_t *node = NULL;
   22123 
   22124 	REQUIRE(DNS_ZONE_VALID(zone));
   22125 	REQUIRE(errors != NULL);
   22126 
   22127 	result = dns_db_getoriginnode(db, &node);
   22128 	if (result != ISC_R_SUCCESS) {
   22129 		return (result);
   22130 	}
   22131 	result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false);
   22132 	dns_db_detachnode(db, &node);
   22133 	return (result);
   22134 }
   22135 
   22136 isc_result_t
   22137 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
   22138 	isc_result_t result;
   22139 	dns_dbnode_t *node = NULL;
   22140 	dns_rdataset_t dnskey, cds, cdnskey;
   22141 	unsigned char algorithms[256];
   22142 	unsigned int i;
   22143 	bool empty = false;
   22144 
   22145 	enum { notexpected = 0, expected = 1, found = 2 };
   22146 
   22147 	REQUIRE(DNS_ZONE_VALID(zone));
   22148 
   22149 	result = dns_db_getoriginnode(db, &node);
   22150 	if (result != ISC_R_SUCCESS) {
   22151 		return (result);
   22152 	}
   22153 
   22154 	dns_rdataset_init(&cds);
   22155 	dns_rdataset_init(&dnskey);
   22156 	dns_rdataset_init(&cdnskey);
   22157 
   22158 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
   22159 				     dns_rdatatype_none, 0, &cds, NULL);
   22160 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   22161 		goto failure;
   22162 	}
   22163 
   22164 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
   22165 				     dns_rdatatype_none, 0, &cdnskey, NULL);
   22166 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   22167 		goto failure;
   22168 	}
   22169 
   22170 	if (!dns_rdataset_isassociated(&cds) &&
   22171 	    !dns_rdataset_isassociated(&cdnskey))
   22172 	{
   22173 		result = ISC_R_SUCCESS;
   22174 		goto failure;
   22175 	}
   22176 
   22177 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   22178 				     dns_rdatatype_none, 0, &dnskey, NULL);
   22179 	if (result == ISC_R_NOTFOUND) {
   22180 		empty = true;
   22181 	} else if (result != ISC_R_SUCCESS) {
   22182 		goto failure;
   22183 	}
   22184 
   22185 	/*
   22186 	 * For each DNSSEC algorithm in the CDS RRset there must be
   22187 	 * a matching DNSKEY record with the exception of a CDS deletion
   22188 	 * record which must be by itself.
   22189 	 */
   22190 	if (dns_rdataset_isassociated(&cds)) {
   22191 		bool delete = false;
   22192 		memset(algorithms, notexpected, sizeof(algorithms));
   22193 		for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS;
   22194 		     result = dns_rdataset_next(&cds))
   22195 		{
   22196 			dns_rdata_t crdata = DNS_RDATA_INIT;
   22197 			dns_rdata_cds_t structcds;
   22198 
   22199 			dns_rdataset_current(&cds, &crdata);
   22200 			/*
   22201 			 * CDS deletion record has this form "0 0 0 00" which
   22202 			 * is 5 zero octets.
   22203 			 */
   22204 			if (crdata.length == 5U &&
   22205 			    memcmp(crdata.data,
   22206 				   (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0)
   22207 			{
   22208 				delete = true;
   22209 				continue;
   22210 			}
   22211 
   22212 			if (empty) {
   22213 				result = DNS_R_BADCDS;
   22214 				goto failure;
   22215 			}
   22216 
   22217 			CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
   22218 			if (algorithms[structcds.algorithm] == 0) {
   22219 				algorithms[structcds.algorithm] = expected;
   22220 			}
   22221 			for (result = dns_rdataset_first(&dnskey);
   22222 			     result == ISC_R_SUCCESS;
   22223 			     result = dns_rdataset_next(&dnskey))
   22224 			{
   22225 				dns_rdata_t rdata = DNS_RDATA_INIT;
   22226 				dns_rdata_dnskey_t structdnskey;
   22227 
   22228 				dns_rdataset_current(&dnskey, &rdata);
   22229 				CHECK(dns_rdata_tostruct(&rdata, &structdnskey,
   22230 							 NULL));
   22231 
   22232 				if (structdnskey.algorithm ==
   22233 				    structcds.algorithm)
   22234 				{
   22235 					algorithms[structcds.algorithm] = found;
   22236 				}
   22237 			}
   22238 			if (result != ISC_R_NOMORE) {
   22239 				goto failure;
   22240 			}
   22241 		}
   22242 		for (i = 0; i < sizeof(algorithms); i++) {
   22243 			if (delete) {
   22244 				if (algorithms[i] != notexpected) {
   22245 					result = DNS_R_BADCDS;
   22246 					goto failure;
   22247 				}
   22248 			} else if (algorithms[i] == expected) {
   22249 				result = DNS_R_BADCDS;
   22250 				goto failure;
   22251 			}
   22252 		}
   22253 	}
   22254 
   22255 	/*
   22256 	 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
   22257 	 * a matching DNSKEY record with the exception of a CDNSKEY deletion
   22258 	 * record which must be by itself.
   22259 	 */
   22260 	if (dns_rdataset_isassociated(&cdnskey)) {
   22261 		bool delete = false;
   22262 		memset(algorithms, notexpected, sizeof(algorithms));
   22263 		for (result = dns_rdataset_first(&cdnskey);
   22264 		     result == ISC_R_SUCCESS;
   22265 		     result = dns_rdataset_next(&cdnskey))
   22266 		{
   22267 			dns_rdata_t crdata = DNS_RDATA_INIT;
   22268 			dns_rdata_cdnskey_t structcdnskey;
   22269 
   22270 			dns_rdataset_current(&cdnskey, &crdata);
   22271 			/*
   22272 			 * CDNSKEY deletion record has this form
   22273 			 * "0 3 0 AA==" which is 2 zero octets, a 3,
   22274 			 * and 2 zero octets.
   22275 			 */
   22276 			if (crdata.length == 5U &&
   22277 			    memcmp(crdata.data,
   22278 				   (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0)
   22279 			{
   22280 				delete = true;
   22281 				continue;
   22282 			}
   22283 
   22284 			if (empty) {
   22285 				result = DNS_R_BADCDNSKEY;
   22286 				goto failure;
   22287 			}
   22288 
   22289 			CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
   22290 						 NULL));
   22291 			if (algorithms[structcdnskey.algorithm] == 0) {
   22292 				algorithms[structcdnskey.algorithm] = expected;
   22293 			}
   22294 			for (result = dns_rdataset_first(&dnskey);
   22295 			     result == ISC_R_SUCCESS;
   22296 			     result = dns_rdataset_next(&dnskey))
   22297 			{
   22298 				dns_rdata_t rdata = DNS_RDATA_INIT;
   22299 				dns_rdata_dnskey_t structdnskey;
   22300 
   22301 				dns_rdataset_current(&dnskey, &rdata);
   22302 				CHECK(dns_rdata_tostruct(&rdata, &structdnskey,
   22303 							 NULL));
   22304 
   22305 				if (structdnskey.algorithm ==
   22306 				    structcdnskey.algorithm)
   22307 				{
   22308 					algorithms[structcdnskey.algorithm] =
   22309 						found;
   22310 				}
   22311 			}
   22312 			if (result != ISC_R_NOMORE) {
   22313 				goto failure;
   22314 			}
   22315 		}
   22316 		for (i = 0; i < sizeof(algorithms); i++) {
   22317 			if (delete) {
   22318 				if (algorithms[i] != notexpected) {
   22319 					result = DNS_R_BADCDNSKEY;
   22320 					goto failure;
   22321 				}
   22322 			} else if (algorithms[i] == expected) {
   22323 				result = DNS_R_BADCDNSKEY;
   22324 				goto failure;
   22325 			}
   22326 		}
   22327 	}
   22328 	result = ISC_R_SUCCESS;
   22329 
   22330 failure:
   22331 	if (dns_rdataset_isassociated(&cds)) {
   22332 		dns_rdataset_disassociate(&cds);
   22333 	}
   22334 	if (dns_rdataset_isassociated(&dnskey)) {
   22335 		dns_rdataset_disassociate(&dnskey);
   22336 	}
   22337 	if (dns_rdataset_isassociated(&cdnskey)) {
   22338 		dns_rdataset_disassociate(&cdnskey);
   22339 	}
   22340 	dns_db_detachnode(db, &node);
   22341 	return (result);
   22342 }
   22343 
   22344 void
   22345 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
   22346 	REQUIRE(DNS_ZONE_VALID(zone));
   22347 
   22348 	LOCK_ZONE(zone);
   22349 	zone->automatic = automatic;
   22350 	UNLOCK_ZONE(zone);
   22351 }
   22352 
   22353 bool
   22354 dns_zone_getautomatic(dns_zone_t *zone) {
   22355 	REQUIRE(DNS_ZONE_VALID(zone));
   22356 	return (zone->automatic);
   22357 }
   22358 
   22359 void
   22360 dns_zone_setadded(dns_zone_t *zone, bool added) {
   22361 	REQUIRE(DNS_ZONE_VALID(zone));
   22362 
   22363 	LOCK_ZONE(zone);
   22364 	zone->added = added;
   22365 	UNLOCK_ZONE(zone);
   22366 }
   22367 
   22368 bool
   22369 dns_zone_getadded(dns_zone_t *zone) {
   22370 	REQUIRE(DNS_ZONE_VALID(zone));
   22371 	return (zone->added);
   22372 }
   22373 
   22374 isc_result_t
   22375 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) {
   22376 	isc_time_t loadtime;
   22377 	isc_result_t result;
   22378 	dns_zone_t *secure = NULL;
   22379 
   22380 	TIME_NOW(&loadtime);
   22381 
   22382 	/*
   22383 	 * Lock hierarchy: zmgr, zone, raw.
   22384 	 */
   22385 again:
   22386 	LOCK_ZONE(zone);
   22387 	INSIST(zone != zone->raw);
   22388 	if (inline_secure(zone)) {
   22389 		LOCK_ZONE(zone->raw);
   22390 	} else if (inline_raw(zone)) {
   22391 		secure = zone->secure;
   22392 		TRYLOCK_ZONE(result, secure);
   22393 		if (result != ISC_R_SUCCESS) {
   22394 			UNLOCK_ZONE(zone);
   22395 			secure = NULL;
   22396 			isc_thread_yield();
   22397 			goto again;
   22398 		}
   22399 	}
   22400 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   22401 	if (inline_secure(zone)) {
   22402 		UNLOCK_ZONE(zone->raw);
   22403 	} else if (secure != NULL) {
   22404 		UNLOCK_ZONE(secure);
   22405 	}
   22406 	UNLOCK_ZONE(zone);
   22407 	return (result);
   22408 }
   22409 
   22410 isc_result_t
   22411 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
   22412 	REQUIRE(DNS_ZONE_VALID(zone));
   22413 	if (interval == 0) {
   22414 		return (ISC_R_RANGE);
   22415 	}
   22416 	/* Maximum value: 24 hours (3600 minutes) */
   22417 	if (interval > (24 * 60)) {
   22418 		interval = (24 * 60);
   22419 	}
   22420 	/* Multiply by 60 for seconds */
   22421 	zone->refreshkeyinterval = interval * 60;
   22422 	return (ISC_R_SUCCESS);
   22423 }
   22424 
   22425 void
   22426 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
   22427 	REQUIRE(DNS_ZONE_VALID(zone));
   22428 	zone->requestixfr = flag;
   22429 }
   22430 
   22431 bool
   22432 dns_zone_getrequestixfr(dns_zone_t *zone) {
   22433 	REQUIRE(DNS_ZONE_VALID(zone));
   22434 	return (zone->requestixfr);
   22435 }
   22436 
   22437 void
   22438 dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) {
   22439 	REQUIRE(DNS_ZONE_VALID(zone));
   22440 	zone->ixfr_ratio = ratio;
   22441 }
   22442 
   22443 uint32_t
   22444 dns_zone_getixfrratio(dns_zone_t *zone) {
   22445 	REQUIRE(DNS_ZONE_VALID(zone));
   22446 	return (zone->ixfr_ratio);
   22447 }
   22448 
   22449 void
   22450 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
   22451 	REQUIRE(DNS_ZONE_VALID(zone));
   22452 	zone->requestexpire = flag;
   22453 }
   22454 
   22455 bool
   22456 dns_zone_getrequestexpire(dns_zone_t *zone) {
   22457 	REQUIRE(DNS_ZONE_VALID(zone));
   22458 	return (zone->requestexpire);
   22459 }
   22460 
   22461 void
   22462 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
   22463 	REQUIRE(DNS_ZONE_VALID(zone));
   22464 	zone->updatemethod = method;
   22465 }
   22466 
   22467 dns_updatemethod_t
   22468 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
   22469 	REQUIRE(DNS_ZONE_VALID(zone));
   22470 	return (zone->updatemethod);
   22471 }
   22472 
   22473 /*
   22474  * Lock hierarchy: zmgr, zone, raw.
   22475  */
   22476 isc_result_t
   22477 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
   22478 	isc_result_t result;
   22479 	dns_zonemgr_t *zmgr;
   22480 
   22481 	REQUIRE(DNS_ZONE_VALID(zone));
   22482 	REQUIRE(zone->zmgr != NULL);
   22483 	REQUIRE(zone->task != NULL);
   22484 	REQUIRE(zone->loadtask != NULL);
   22485 	REQUIRE(zone->raw == NULL);
   22486 
   22487 	REQUIRE(DNS_ZONE_VALID(raw));
   22488 	REQUIRE(raw->zmgr == NULL);
   22489 	REQUIRE(raw->task == NULL);
   22490 	REQUIRE(raw->loadtask == NULL);
   22491 	REQUIRE(raw->secure == NULL);
   22492 
   22493 	REQUIRE(zone != raw);
   22494 
   22495 	/*
   22496 	 * Lock hierarchy: zmgr, zone, raw.
   22497 	 */
   22498 	zmgr = zone->zmgr;
   22499 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   22500 	LOCK_ZONE(zone);
   22501 	LOCK_ZONE(raw);
   22502 
   22503 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   22504 				  NULL, zone->task, zone_timer, raw,
   22505 				  &raw->timer);
   22506 	if (result != ISC_R_SUCCESS) {
   22507 		goto unlock;
   22508 	}
   22509 
   22510 	/*
   22511 	 * The timer "holds" a iref.
   22512 	 */
   22513 	isc_refcount_increment0(&raw->irefs);
   22514 
   22515 	/* dns_zone_attach(raw, &zone->raw); */
   22516 	isc_refcount_increment(&raw->erefs);
   22517 	zone->raw = raw;
   22518 
   22519 	/* dns_zone_iattach(zone,  &raw->secure); */
   22520 	zone_iattach(zone, &raw->secure);
   22521 
   22522 	isc_task_attach(zone->task, &raw->task);
   22523 	isc_task_attach(zone->loadtask, &raw->loadtask);
   22524 
   22525 	ISC_LIST_APPEND(zmgr->zones, raw, link);
   22526 	raw->zmgr = zmgr;
   22527 	isc_refcount_increment(&zmgr->refs);
   22528 
   22529 unlock:
   22530 	UNLOCK_ZONE(raw);
   22531 	UNLOCK_ZONE(zone);
   22532 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   22533 	return (result);
   22534 }
   22535 
   22536 void
   22537 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
   22538 	REQUIRE(DNS_ZONE_VALID(zone));
   22539 	REQUIRE(raw != NULL && *raw == NULL);
   22540 
   22541 	LOCK(&zone->lock);
   22542 	INSIST(zone != zone->raw);
   22543 	if (zone->raw != NULL) {
   22544 		dns_zone_attach(zone->raw, raw);
   22545 	}
   22546 	UNLOCK(&zone->lock);
   22547 }
   22548 
   22549 struct keydone {
   22550 	isc_event_t event;
   22551 	bool all;
   22552 	unsigned char data[5];
   22553 };
   22554 
   22555 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL)
   22556 
   22557 static void
   22558 keydone(isc_task_t *task, isc_event_t *event) {
   22559 	const char *me = "keydone";
   22560 	bool commit = false;
   22561 	isc_result_t result;
   22562 	dns_rdata_t rdata = DNS_RDATA_INIT;
   22563 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   22564 	dns_zone_t *zone;
   22565 	dns_db_t *db = NULL;
   22566 	dns_dbnode_t *node = NULL;
   22567 	dns_rdataset_t rdataset;
   22568 	dns_diff_t diff;
   22569 	struct keydone *kd = (struct keydone *)event;
   22570 	dns_update_log_t log = { update_log_cb, NULL };
   22571 	bool clear_pending = false;
   22572 
   22573 	UNUSED(task);
   22574 
   22575 	zone = event->ev_arg;
   22576 	INSIST(DNS_ZONE_VALID(zone));
   22577 
   22578 	ENTER;
   22579 
   22580 	dns_rdataset_init(&rdataset);
   22581 	dns_diff_init(zone->mctx, &diff);
   22582 
   22583 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   22584 	if (zone->db != NULL) {
   22585 		dns_db_attach(zone->db, &db);
   22586 	}
   22587 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   22588 	if (db == NULL) {
   22589 		goto failure;
   22590 	}
   22591 
   22592 	dns_db_currentversion(db, &oldver);
   22593 	result = dns_db_newversion(db, &newver);
   22594 	if (result != ISC_R_SUCCESS) {
   22595 		dnssec_log(zone, ISC_LOG_ERROR,
   22596 			   "keydone:dns_db_newversion -> %s",
   22597 			   isc_result_totext(result));
   22598 		goto failure;
   22599 	}
   22600 
   22601 	result = dns_db_getoriginnode(db, &node);
   22602 	if (result != ISC_R_SUCCESS) {
   22603 		goto failure;
   22604 	}
   22605 
   22606 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   22607 				     dns_rdatatype_none, 0, &rdataset, NULL);
   22608 	if (result == ISC_R_NOTFOUND) {
   22609 		INSIST(!dns_rdataset_isassociated(&rdataset));
   22610 		goto failure;
   22611 	}
   22612 	if (result != ISC_R_SUCCESS) {
   22613 		INSIST(!dns_rdataset_isassociated(&rdataset));
   22614 		goto failure;
   22615 	}
   22616 
   22617 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   22618 	     result = dns_rdataset_next(&rdataset))
   22619 	{
   22620 		bool found = false;
   22621 
   22622 		dns_rdataset_current(&rdataset, &rdata);
   22623 
   22624 		if (kd->all) {
   22625 			if (rdata.length == 5 && rdata.data[0] != 0 &&
   22626 			    rdata.data[3] == 0 && rdata.data[4] == 1)
   22627 			{
   22628 				found = true;
   22629 			} else if (rdata.data[0] == 0 &&
   22630 				   (rdata.data[2] & PENDINGFLAGS) != 0)
   22631 			{
   22632 				found = true;
   22633 				clear_pending = true;
   22634 			}
   22635 		} else if (rdata.length == 5 &&
   22636 			   memcmp(rdata.data, kd->data, 5) == 0)
   22637 		{
   22638 			found = true;
   22639 		}
   22640 
   22641 		if (found) {
   22642 			CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
   22643 					    &zone->origin, rdataset.ttl,
   22644 					    &rdata));
   22645 		}
   22646 		dns_rdata_reset(&rdata);
   22647 	}
   22648 
   22649 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   22650 		/* Write changes to journal file. */
   22651 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   22652 					zone->updatemethod));
   22653 
   22654 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   22655 					       &diff,
   22656 					       zone->sigvalidityinterval);
   22657 		if (!clear_pending) {
   22658 			CHECK(result);
   22659 		}
   22660 
   22661 		CHECK(zone_journal(zone, &diff, NULL, "keydone"));
   22662 		commit = true;
   22663 
   22664 		LOCK_ZONE(zone);
   22665 		DNS_ZONE_SETFLAG(zone,
   22666 				 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   22667 		zone_needdump(zone, 30);
   22668 		UNLOCK_ZONE(zone);
   22669 	}
   22670 
   22671 failure:
   22672 	if (dns_rdataset_isassociated(&rdataset)) {
   22673 		dns_rdataset_disassociate(&rdataset);
   22674 	}
   22675 	if (db != NULL) {
   22676 		if (node != NULL) {
   22677 			dns_db_detachnode(db, &node);
   22678 		}
   22679 		if (oldver != NULL) {
   22680 			dns_db_closeversion(db, &oldver, false);
   22681 		}
   22682 		if (newver != NULL) {
   22683 			dns_db_closeversion(db, &newver, commit);
   22684 		}
   22685 		dns_db_detach(&db);
   22686 	}
   22687 	dns_diff_clear(&diff);
   22688 	isc_event_free(&event);
   22689 	dns_zone_idetach(&zone);
   22690 
   22691 	INSIST(oldver == NULL);
   22692 	INSIST(newver == NULL);
   22693 }
   22694 
   22695 isc_result_t
   22696 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
   22697 	isc_result_t result = ISC_R_SUCCESS;
   22698 	isc_event_t *e;
   22699 	isc_buffer_t b;
   22700 	dns_zone_t *dummy = NULL;
   22701 	struct keydone *kd;
   22702 
   22703 	REQUIRE(DNS_ZONE_VALID(zone));
   22704 
   22705 	LOCK_ZONE(zone);
   22706 
   22707 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
   22708 			       zone, sizeof(struct keydone));
   22709 
   22710 	kd = (struct keydone *)e;
   22711 	if (strcasecmp(keystr, "all") == 0) {
   22712 		kd->all = true;
   22713 	} else {
   22714 		isc_textregion_t r;
   22715 		const char *algstr;
   22716 		dns_keytag_t keyid;
   22717 		dns_secalg_t alg;
   22718 		size_t n;
   22719 
   22720 		kd->all = false;
   22721 
   22722 		n = sscanf(keystr, "%hu/", &keyid);
   22723 		if (n == 0U) {
   22724 			CHECK(ISC_R_FAILURE);
   22725 		}
   22726 
   22727 		algstr = strchr(keystr, '/');
   22728 		if (algstr != NULL) {
   22729 			algstr++;
   22730 		} else {
   22731 			CHECK(ISC_R_FAILURE);
   22732 		}
   22733 
   22734 		n = sscanf(algstr, "%hhu", &alg);
   22735 		if (n == 0U) {
   22736 			DE_CONST(algstr, r.base);
   22737 			r.length = strlen(algstr);
   22738 			CHECK(dns_secalg_fromtext(&alg, &r));
   22739 		}
   22740 
   22741 		/* construct a private-type rdata */
   22742 		isc_buffer_init(&b, kd->data, sizeof(kd->data));
   22743 		isc_buffer_putuint8(&b, alg);
   22744 		isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
   22745 		isc_buffer_putuint8(&b, (keyid & 0xff));
   22746 		isc_buffer_putuint8(&b, 0);
   22747 		isc_buffer_putuint8(&b, 1);
   22748 	}
   22749 
   22750 	zone_iattach(zone, &dummy);
   22751 	isc_task_send(zone->task, &e);
   22752 
   22753 failure:
   22754 	if (e != NULL) {
   22755 		isc_event_free(&e);
   22756 	}
   22757 	UNLOCK_ZONE(zone);
   22758 	return (result);
   22759 }
   22760 
   22761 /*
   22762  * Called from the zone task's queue after the relevant event is posted by
   22763  * dns_zone_setnsec3param().
   22764  */
   22765 static void
   22766 setnsec3param(isc_task_t *task, isc_event_t *event) {
   22767 	const char *me = "setnsec3param";
   22768 	dns_zone_t *zone = event->ev_arg;
   22769 	bool loadpending;
   22770 
   22771 	INSIST(DNS_ZONE_VALID(zone));
   22772 
   22773 	UNUSED(task);
   22774 
   22775 	ENTER;
   22776 
   22777 	LOCK_ZONE(zone);
   22778 	loadpending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
   22779 	UNLOCK_ZONE(zone);
   22780 
   22781 	/*
   22782 	 * If receive_secure_serial is still processing or we have a
   22783 	 * queued event append rss_post queue.
   22784 	 */
   22785 	if (zone->rss_newver != NULL || ISC_LIST_HEAD(zone->rss_post) != NULL) {
   22786 		/*
   22787 		 * Wait for receive_secure_serial() to finish processing.
   22788 		 */
   22789 		ISC_LIST_APPEND(zone->rss_post, event, ev_link);
   22790 	} else {
   22791 		bool rescheduled = false;
   22792 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   22793 		/*
   22794 		 * The zone is not yet fully loaded. Reschedule the event to
   22795 		 * be picked up later. This turns this function into a busy
   22796 		 * wait, but it only happens at startup.
   22797 		 */
   22798 		if (zone->db == NULL && loadpending) {
   22799 			rescheduled = true;
   22800 			isc_task_send(task, &event);
   22801 		}
   22802 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   22803 		if (rescheduled) {
   22804 			return;
   22805 		}
   22806 
   22807 		rss_post(zone, event);
   22808 	}
   22809 	dns_zone_idetach(&zone);
   22810 }
   22811 
   22812 static void
   22813 salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text,
   22814 	  unsigned int textlen) {
   22815 	isc_region_t r;
   22816 	isc_buffer_t buf;
   22817 	isc_result_t result;
   22818 
   22819 	r.base = salt;
   22820 	r.length = (unsigned int)saltlen;
   22821 
   22822 	isc_buffer_init(&buf, text, textlen);
   22823 	result = isc_hex_totext(&r, 2, "", &buf);
   22824 	if (result == ISC_R_SUCCESS) {
   22825 		text[saltlen * 2] = 0;
   22826 	} else {
   22827 		text[0] = 0;
   22828 	}
   22829 }
   22830 
   22831 /*
   22832  * Check whether NSEC3 chain addition or removal specified by the private-type
   22833  * record passed with the event was already queued (or even fully performed).
   22834  * If not, modify the relevant private-type records at the zone apex and call
   22835  * resume_addnsec3chain().
   22836  */
   22837 static void
   22838 rss_post(dns_zone_t *zone, isc_event_t *event) {
   22839 	const char *me = "rss_post";
   22840 	bool commit = false;
   22841 	isc_result_t result;
   22842 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   22843 	dns_db_t *db = NULL;
   22844 	dns_dbnode_t *node = NULL;
   22845 	dns_rdataset_t prdataset, nrdataset;
   22846 	dns_diff_t diff;
   22847 	struct np3event *npe = (struct np3event *)event;
   22848 	nsec3param_t *np;
   22849 	dns_update_log_t log = { update_log_cb, NULL };
   22850 	dns_rdata_t rdata;
   22851 	bool nseconly;
   22852 	bool exists = false;
   22853 
   22854 	ENTER;
   22855 
   22856 	np = &npe->params;
   22857 
   22858 	dns_rdataset_init(&prdataset);
   22859 	dns_rdataset_init(&nrdataset);
   22860 	dns_diff_init(zone->mctx, &diff);
   22861 
   22862 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   22863 	if (zone->db != NULL) {
   22864 		dns_db_attach(zone->db, &db);
   22865 	}
   22866 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   22867 	if (db == NULL) {
   22868 		goto failure;
   22869 	}
   22870 
   22871 	dns_db_currentversion(db, &oldver);
   22872 	result = dns_db_newversion(db, &newver);
   22873 	if (result != ISC_R_SUCCESS) {
   22874 		dnssec_log(zone, ISC_LOG_ERROR,
   22875 			   "setnsec3param:dns_db_newversion -> %s",
   22876 			   isc_result_totext(result));
   22877 		goto failure;
   22878 	}
   22879 
   22880 	CHECK(dns_db_getoriginnode(db, &node));
   22881 
   22882 	/*
   22883 	 * Do we need to look up the NSEC3 parameters?
   22884 	 */
   22885 	if (np->lookup) {
   22886 		dns_rdata_nsec3param_t param;
   22887 		dns_rdata_t nrdata = DNS_RDATA_INIT;
   22888 		dns_rdata_t prdata = DNS_RDATA_INIT;
   22889 		unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
   22890 		unsigned char saltbuf[255];
   22891 		isc_buffer_t b;
   22892 
   22893 		param.salt = NULL;
   22894 		result = dns__zone_lookup_nsec3param(zone, &np->rdata, &param,
   22895 						     saltbuf, np->resalt);
   22896 		if (result == ISC_R_SUCCESS) {
   22897 			/*
   22898 			 * Success because the NSEC3PARAM already exists, but
   22899 			 * function returns void, so goto failure to clean up.
   22900 			 */
   22901 			goto failure;
   22902 		}
   22903 		if (result != DNS_R_NSEC3RESALT && result != ISC_R_NOTFOUND) {
   22904 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   22905 				   "setnsec3param:lookup nsec3param -> %s",
   22906 				   isc_result_totext(result));
   22907 			goto failure;
   22908 		}
   22909 
   22910 		INSIST(param.salt != NULL);
   22911 
   22912 		/* Update NSEC3 parameters. */
   22913 		np->rdata.hash = param.hash;
   22914 		np->rdata.flags = param.flags;
   22915 		np->rdata.iterations = param.iterations;
   22916 		np->rdata.salt_length = param.salt_length;
   22917 		np->rdata.salt = param.salt;
   22918 
   22919 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
   22920 		CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
   22921 					   dns_rdatatype_nsec3param, &np->rdata,
   22922 					   &b));
   22923 		dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
   22924 					 np->data, sizeof(np->data));
   22925 		np->length = prdata.length;
   22926 		np->nsec = false;
   22927 	}
   22928 
   22929 	/*
   22930 	 * Does a private-type record already exist for this chain?
   22931 	 */
   22932 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   22933 				     dns_rdatatype_none, 0, &prdataset, NULL);
   22934 	if (result == ISC_R_SUCCESS) {
   22935 		for (result = dns_rdataset_first(&prdataset);
   22936 		     result == ISC_R_SUCCESS;
   22937 		     result = dns_rdataset_next(&prdataset))
   22938 		{
   22939 			dns_rdata_init(&rdata);
   22940 			dns_rdataset_current(&prdataset, &rdata);
   22941 
   22942 			if (np->length == rdata.length &&
   22943 			    memcmp(rdata.data, np->data, np->length) == 0)
   22944 			{
   22945 				exists = true;
   22946 				break;
   22947 			}
   22948 		}
   22949 	} else if (result != ISC_R_NOTFOUND) {
   22950 		INSIST(!dns_rdataset_isassociated(&prdataset));
   22951 		goto failure;
   22952 	}
   22953 
   22954 	/*
   22955 	 * Does the chain already exist?
   22956 	 */
   22957 	result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param,
   22958 				     dns_rdatatype_none, 0, &nrdataset, NULL);
   22959 	if (result == ISC_R_SUCCESS) {
   22960 		for (result = dns_rdataset_first(&nrdataset);
   22961 		     result == ISC_R_SUCCESS;
   22962 		     result = dns_rdataset_next(&nrdataset))
   22963 		{
   22964 			dns_rdata_init(&rdata);
   22965 			dns_rdataset_current(&nrdataset, &rdata);
   22966 
   22967 			if (np->length == (rdata.length + 1) &&
   22968 			    memcmp(rdata.data, np->data + 1, np->length - 1) ==
   22969 				    0)
   22970 			{
   22971 				exists = true;
   22972 				break;
   22973 			}
   22974 		}
   22975 	} else if (result != ISC_R_NOTFOUND) {
   22976 		INSIST(!dns_rdataset_isassociated(&nrdataset));
   22977 		goto failure;
   22978 	}
   22979 
   22980 	/*
   22981 	 * We need to remove any existing NSEC3 chains if the supplied NSEC3
   22982 	 * parameters are supposed to replace the current ones or if we are
   22983 	 * switching to NSEC.
   22984 	 */
   22985 	if (!exists && np->replace && (np->length != 0 || np->nsec)) {
   22986 		CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec,
   22987 						  &diff));
   22988 	}
   22989 
   22990 	if (!exists && np->length != 0) {
   22991 		/*
   22992 		 * We're creating an NSEC3 chain.  Add the private-type record
   22993 		 * passed in the event handler's argument to the zone apex.
   22994 		 *
   22995 		 * If the zone is not currently capable of supporting an NSEC3
   22996 		 * chain (due to the DNSKEY RRset at the zone apex not existing
   22997 		 * or containing at least one key using an NSEC-only
   22998 		 * algorithm), add the INITIAL flag, so these parameters can be
   22999 		 * used later when NSEC3 becomes available.
   23000 		 */
   23001 		dns_rdata_init(&rdata);
   23002 
   23003 		np->data[2] |= DNS_NSEC3FLAG_CREATE;
   23004 		result = dns_nsec_nseconly(db, newver, NULL, &nseconly);
   23005 		if (result == ISC_R_NOTFOUND || nseconly) {
   23006 			np->data[2] |= DNS_NSEC3FLAG_INITIAL;
   23007 		}
   23008 
   23009 		rdata.length = np->length;
   23010 		rdata.data = np->data;
   23011 		rdata.type = zone->privatetype;
   23012 		rdata.rdclass = zone->rdclass;
   23013 		CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
   23014 				    &zone->origin, 0, &rdata));
   23015 	}
   23016 
   23017 	/*
   23018 	 * If we changed anything in the zone, write changes to journal file
   23019 	 * and set commit to true so that resume_addnsec3chain() will be
   23020 	 * called below in order to kick off adding/removing relevant NSEC3
   23021 	 * records.
   23022 	 */
   23023 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   23024 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   23025 					zone->updatemethod));
   23026 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   23027 					       &diff,
   23028 					       zone->sigvalidityinterval);
   23029 		if (result != ISC_R_NOTFOUND) {
   23030 			CHECK(result);
   23031 		}
   23032 		CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
   23033 		commit = true;
   23034 
   23035 		LOCK_ZONE(zone);
   23036 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   23037 		zone_needdump(zone, 30);
   23038 		UNLOCK_ZONE(zone);
   23039 	}
   23040 
   23041 failure:
   23042 	if (dns_rdataset_isassociated(&prdataset)) {
   23043 		dns_rdataset_disassociate(&prdataset);
   23044 	}
   23045 	if (dns_rdataset_isassociated(&nrdataset)) {
   23046 		dns_rdataset_disassociate(&nrdataset);
   23047 	}
   23048 	if (node != NULL) {
   23049 		dns_db_detachnode(db, &node);
   23050 	}
   23051 	if (oldver != NULL) {
   23052 		dns_db_closeversion(db, &oldver, false);
   23053 	}
   23054 	if (newver != NULL) {
   23055 		dns_db_closeversion(db, &newver, commit);
   23056 	}
   23057 	if (db != NULL) {
   23058 		dns_db_detach(&db);
   23059 	}
   23060 	if (commit) {
   23061 		LOCK_ZONE(zone);
   23062 		resume_addnsec3chain(zone);
   23063 		UNLOCK_ZONE(zone);
   23064 	}
   23065 	dns_diff_clear(&diff);
   23066 	isc_event_free(&event);
   23067 
   23068 	INSIST(oldver == NULL);
   23069 	INSIST(newver == NULL);
   23070 }
   23071 
   23072 /*
   23073  * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters.
   23074  *
   23075  * If 'salt' is NULL, a match is found if the salt has the requested length,
   23076  * otherwise the NSEC3 salt must match the requested salt value too.
   23077  *
   23078  * Returns  ISC_R_SUCCESS, if a match is found, or an error if no match is
   23079  * found, or if the db lookup failed.
   23080  */
   23081 isc_result_t
   23082 dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup,
   23083 			    dns_rdata_nsec3param_t *param,
   23084 			    unsigned char saltbuf[255], bool resalt) {
   23085 	isc_result_t result = ISC_R_UNEXPECTED;
   23086 	dns_dbnode_t *node = NULL;
   23087 	dns_db_t *db = NULL;
   23088 	dns_dbversion_t *version = NULL;
   23089 	dns_rdataset_t rdataset;
   23090 	dns_rdata_nsec3param_t nsec3param;
   23091 	dns_rdata_t rdata = DNS_RDATA_INIT;
   23092 
   23093 	REQUIRE(DNS_ZONE_VALID(zone));
   23094 
   23095 	dns_rdataset_init(&rdataset);
   23096 
   23097 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   23098 	if (zone->db != NULL) {
   23099 		dns_db_attach(zone->db, &db);
   23100 	}
   23101 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   23102 	if (db == NULL) {
   23103 		result = ISC_R_FAILURE;
   23104 		goto setparam;
   23105 	}
   23106 
   23107 	result = dns_db_findnode(db, &zone->origin, false, &node);
   23108 	if (result != ISC_R_SUCCESS) {
   23109 		dns_zone_log(zone, ISC_LOG_ERROR,
   23110 			     "dns__zone_lookup_nsec3param:"
   23111 			     "dns_db_findnode -> %s",
   23112 			     isc_result_totext(result));
   23113 		result = ISC_R_FAILURE;
   23114 		goto setparam;
   23115 	}
   23116 	dns_db_currentversion(db, &version);
   23117 
   23118 	result = dns_db_findrdataset(db, node, version,
   23119 				     dns_rdatatype_nsec3param,
   23120 				     dns_rdatatype_none, 0, &rdataset, NULL);
   23121 	if (result != ISC_R_SUCCESS) {
   23122 		INSIST(!dns_rdataset_isassociated(&rdataset));
   23123 		if (result != ISC_R_NOTFOUND) {
   23124 			dns_zone_log(zone, ISC_LOG_ERROR,
   23125 				     "dns__zone_lookup_nsec3param:"
   23126 				     "dns_db_findrdataset -> %s",
   23127 				     isc_result_totext(result));
   23128 		}
   23129 		goto setparam;
   23130 	}
   23131 
   23132 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   23133 	     result = dns_rdataset_next(&rdataset))
   23134 	{
   23135 		dns_rdataset_current(&rdataset, &rdata);
   23136 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   23137 		INSIST(result == ISC_R_SUCCESS);
   23138 		dns_rdata_reset(&rdata);
   23139 
   23140 		/* Check parameters. */
   23141 		if (nsec3param.hash != lookup->hash) {
   23142 			continue;
   23143 		}
   23144 		if (nsec3param.iterations != lookup->iterations) {
   23145 			continue;
   23146 		}
   23147 		if (nsec3param.salt_length != lookup->salt_length) {
   23148 			continue;
   23149 		}
   23150 		if (lookup->salt != NULL) {
   23151 			if (memcmp(nsec3param.salt, lookup->salt,
   23152 				   lookup->salt_length) != 0)
   23153 			{
   23154 				continue;
   23155 			}
   23156 		}
   23157 		/* Found a match. */
   23158 		result = ISC_R_SUCCESS;
   23159 		param->hash = nsec3param.hash;
   23160 		param->flags = nsec3param.flags;
   23161 		param->iterations = nsec3param.iterations;
   23162 		param->salt_length = nsec3param.salt_length;
   23163 		param->salt = nsec3param.salt;
   23164 		break;
   23165 	}
   23166 
   23167 	if (result == ISC_R_NOMORE) {
   23168 		result = ISC_R_NOTFOUND;
   23169 	}
   23170 
   23171 setparam:
   23172 	if (result != ISC_R_SUCCESS) {
   23173 		/* Found no match. */
   23174 		param->hash = lookup->hash;
   23175 		param->flags = lookup->flags;
   23176 		param->iterations = lookup->iterations;
   23177 		param->salt_length = lookup->salt_length;
   23178 		param->salt = lookup->salt;
   23179 	}
   23180 
   23181 	if (result != ISC_R_NOTFOUND && result != ISC_R_SUCCESS) {
   23182 		goto failure;
   23183 	}
   23184 
   23185 	if (param->salt_length == 0) {
   23186 		DE_CONST("-", param->salt);
   23187 	} else if (resalt || param->salt == NULL) {
   23188 		unsigned char *newsalt;
   23189 		unsigned char salttext[255 * 2 + 1];
   23190 		do {
   23191 			/* Generate a new salt. */
   23192 			result = dns_nsec3_generate_salt(saltbuf,
   23193 							 param->salt_length);
   23194 			if (result != ISC_R_SUCCESS) {
   23195 				break;
   23196 			}
   23197 			newsalt = saltbuf;
   23198 			salt2text(newsalt, param->salt_length, salttext,
   23199 				  sizeof(salttext));
   23200 			dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s",
   23201 				   salttext);
   23202 			/* Check for salt conflict. */
   23203 			if (param->salt != NULL &&
   23204 			    memcmp(newsalt, param->salt, param->salt_length) ==
   23205 				    0)
   23206 			{
   23207 				result = ISC_R_SUCCESS;
   23208 			} else {
   23209 				param->salt = newsalt;
   23210 				result = DNS_R_NSEC3RESALT;
   23211 			}
   23212 		} while (result == ISC_R_SUCCESS);
   23213 
   23214 		INSIST(result != ISC_R_SUCCESS);
   23215 	}
   23216 
   23217 failure:
   23218 	if (dns_rdataset_isassociated(&rdataset)) {
   23219 		dns_rdataset_disassociate(&rdataset);
   23220 	}
   23221 	if (node != NULL) {
   23222 		dns_db_detachnode(db, &node);
   23223 	}
   23224 	if (version != NULL) {
   23225 		dns_db_closeversion(db, &version, false);
   23226 	}
   23227 	if (db != NULL) {
   23228 		dns_db_detach(&db);
   23229 	}
   23230 
   23231 	return (result);
   23232 }
   23233 
   23234 /*
   23235  * Called when an "rndc signing -nsec3param ..." command is received, or the
   23236  * 'dnssec-policy' has changed.
   23237  *
   23238  * Allocate and prepare an nsec3param_t structure which holds information about
   23239  * the NSEC3 changes requested for the zone:
   23240  *
   23241  *   - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec"
   23242  *     field of the structure to true and the "replace" field to the value
   23243  *     of the "replace" argument, leaving other fields initialized to zeros, to
   23244  *     signal that the zone should be signed using NSEC instead of NSEC3,
   23245  *
   23246  *   - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at
   23247  *     the zone apex, convert it to a private-type record and store the latter
   23248  *     in the "data" field of the nsec3param_t structure.
   23249  *
   23250  * Once the nsec3param_t structure is prepared, post an event to the zone's
   23251  * task which will cause setnsec3param() to be called with the prepared
   23252  * structure passed as an argument.
   23253  */
   23254 isc_result_t
   23255 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags,
   23256 		       uint16_t iter, uint8_t saltlen, unsigned char *salt,
   23257 		       bool replace, bool resalt) {
   23258 	isc_result_t result = ISC_R_SUCCESS;
   23259 	dns_rdata_nsec3param_t param, lookup;
   23260 	dns_rdata_t nrdata = DNS_RDATA_INIT;
   23261 	dns_rdata_t prdata = DNS_RDATA_INIT;
   23262 	unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
   23263 	unsigned char saltbuf[255];
   23264 	struct np3event *npe;
   23265 	nsec3param_t *np;
   23266 	dns_zone_t *dummy = NULL;
   23267 	isc_buffer_t b;
   23268 	isc_event_t *e = NULL;
   23269 	bool do_lookup = false;
   23270 
   23271 	REQUIRE(DNS_ZONE_VALID(zone));
   23272 
   23273 	LOCK_ZONE(zone);
   23274 
   23275 	/*
   23276 	 * First check if the requested NSEC3 parameters are already set,
   23277 	 * if so, no need to set again.
   23278 	 */
   23279 	if (hash != 0) {
   23280 		lookup.hash = hash;
   23281 		lookup.flags = flags;
   23282 		lookup.iterations = iter;
   23283 		lookup.salt_length = saltlen;
   23284 		lookup.salt = salt;
   23285 		param.salt = NULL;
   23286 		result = dns__zone_lookup_nsec3param(zone, &lookup, &param,
   23287 						     saltbuf, resalt);
   23288 		if (result == ISC_R_SUCCESS) {
   23289 			UNLOCK_ZONE(zone);
   23290 			return (ISC_R_SUCCESS);
   23291 		}
   23292 		/*
   23293 		 * Schedule lookup if lookup above failed (may happen if zone
   23294 		 * db is NULL for example).
   23295 		 */
   23296 		do_lookup = (param.salt == NULL) ? true : false;
   23297 	}
   23298 
   23299 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
   23300 			       setnsec3param, zone, sizeof(struct np3event));
   23301 
   23302 	npe = (struct np3event *)e;
   23303 	np = &npe->params;
   23304 	np->replace = replace;
   23305 	np->resalt = resalt;
   23306 	np->lookup = do_lookup;
   23307 	if (hash == 0) {
   23308 		np->length = 0;
   23309 		np->nsec = true;
   23310 		dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec");
   23311 	} else {
   23312 		param.common.rdclass = zone->rdclass;
   23313 		param.common.rdtype = dns_rdatatype_nsec3param;
   23314 		ISC_LINK_INIT(&param.common, link);
   23315 		param.mctx = NULL;
   23316 		/* nsec3 specific param set in dns__zone_lookup_nsec3param() */
   23317 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
   23318 
   23319 		if (param.salt != NULL) {
   23320 			CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
   23321 						   dns_rdatatype_nsec3param,
   23322 						   &param, &b));
   23323 			dns_nsec3param_toprivate(&nrdata, &prdata,
   23324 						 zone->privatetype, np->data,
   23325 						 sizeof(np->data));
   23326 			np->length = prdata.length;
   23327 		}
   23328 
   23329 		np->rdata = param;
   23330 		np->nsec = false;
   23331 
   23332 		if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   23333 			unsigned char salttext[255 * 2 + 1];
   23334 			if (param.salt != NULL) {
   23335 				salt2text(param.salt, param.salt_length,
   23336 					  salttext, sizeof(salttext));
   23337 			}
   23338 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   23339 				   "setnsec3param:nsec3 %u %u %u %u:%s",
   23340 				   param.hash, param.flags, param.iterations,
   23341 				   param.salt_length,
   23342 				   param.salt == NULL ? "unknown"
   23343 						      : (char *)salttext);
   23344 		}
   23345 	}
   23346 
   23347 	/*
   23348 	 * setnsec3param() will silently return early if the zone does not yet
   23349 	 * have a database.  Prevent that by queueing the event up if zone->db
   23350 	 * is NULL.  All events queued here are subsequently processed by
   23351 	 * receive_secure_db() if it ever gets called or simply freed by
   23352 	 * zone_free() otherwise.
   23353 	 */
   23354 
   23355 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   23356 	if (zone->db != NULL) {
   23357 		zone_iattach(zone, &dummy);
   23358 		isc_task_send(zone->task, &e);
   23359 	} else {
   23360 		ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link);
   23361 		e = NULL;
   23362 	}
   23363 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   23364 
   23365 	result = ISC_R_SUCCESS;
   23366 
   23367 failure:
   23368 	if (e != NULL) {
   23369 		isc_event_free(&e);
   23370 	}
   23371 	UNLOCK_ZONE(zone);
   23372 	return (result);
   23373 }
   23374 
   23375 isc_result_t
   23376 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
   23377 	REQUIRE(DNS_ZONE_VALID(zone));
   23378 	REQUIRE(loadtime != NULL);
   23379 
   23380 	LOCK_ZONE(zone);
   23381 	*loadtime = zone->loadtime;
   23382 	UNLOCK_ZONE(zone);
   23383 	return (ISC_R_SUCCESS);
   23384 }
   23385 
   23386 isc_result_t
   23387 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
   23388 	REQUIRE(DNS_ZONE_VALID(zone));
   23389 	REQUIRE(expiretime != NULL);
   23390 
   23391 	LOCK_ZONE(zone);
   23392 	*expiretime = zone->expiretime;
   23393 	UNLOCK_ZONE(zone);
   23394 	return (ISC_R_SUCCESS);
   23395 }
   23396 
   23397 isc_result_t
   23398 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
   23399 	REQUIRE(DNS_ZONE_VALID(zone));
   23400 	REQUIRE(refreshtime != NULL);
   23401 
   23402 	LOCK_ZONE(zone);
   23403 	*refreshtime = zone->refreshtime;
   23404 	UNLOCK_ZONE(zone);
   23405 	return (ISC_R_SUCCESS);
   23406 }
   23407 
   23408 isc_result_t
   23409 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
   23410 	REQUIRE(DNS_ZONE_VALID(zone));
   23411 	REQUIRE(refreshkeytime != NULL);
   23412 
   23413 	LOCK_ZONE(zone);
   23414 	*refreshkeytime = zone->refreshkeytime;
   23415 	UNLOCK_ZONE(zone);
   23416 	return (ISC_R_SUCCESS);
   23417 }
   23418 
   23419 unsigned int
   23420 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
   23421 	dns_include_t *include;
   23422 	char **array = NULL;
   23423 	unsigned int n = 0;
   23424 
   23425 	REQUIRE(DNS_ZONE_VALID(zone));
   23426 	REQUIRE(includesp != NULL && *includesp == NULL);
   23427 
   23428 	LOCK_ZONE(zone);
   23429 	if (zone->nincludes == 0) {
   23430 		goto done;
   23431 	}
   23432 
   23433 	array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
   23434 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   23435 	     include = ISC_LIST_NEXT(include, link))
   23436 	{
   23437 		INSIST(n < zone->nincludes);
   23438 		array[n++] = isc_mem_strdup(zone->mctx, include->name);
   23439 	}
   23440 	INSIST(n == zone->nincludes);
   23441 	*includesp = array;
   23442 
   23443 done:
   23444 	UNLOCK_ZONE(zone);
   23445 	return (n);
   23446 }
   23447 
   23448 void
   23449 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
   23450 	REQUIRE(DNS_ZONE_VALID(zone));
   23451 
   23452 	zone->statlevel = level;
   23453 }
   23454 
   23455 dns_zonestat_level_t
   23456 dns_zone_getstatlevel(dns_zone_t *zone) {
   23457 	REQUIRE(DNS_ZONE_VALID(zone));
   23458 
   23459 	return (zone->statlevel);
   23460 }
   23461 
   23462 static void
   23463 setserial(isc_task_t *task, isc_event_t *event) {
   23464 	uint32_t oldserial, desired;
   23465 	const char *me = "setserial";
   23466 	bool commit = false;
   23467 	isc_result_t result;
   23468 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   23469 	dns_zone_t *zone;
   23470 	dns_db_t *db = NULL;
   23471 	dns_diff_t diff;
   23472 	struct ssevent *sse = (struct ssevent *)event;
   23473 	dns_update_log_t log = { update_log_cb, NULL };
   23474 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   23475 
   23476 	UNUSED(task);
   23477 
   23478 	zone = event->ev_arg;
   23479 	INSIST(DNS_ZONE_VALID(zone));
   23480 
   23481 	ENTER;
   23482 
   23483 	if (zone->update_disabled) {
   23484 		goto disabled;
   23485 	}
   23486 
   23487 	desired = sse->serial;
   23488 
   23489 	dns_diff_init(zone->mctx, &diff);
   23490 
   23491 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   23492 	if (zone->db != NULL) {
   23493 		dns_db_attach(zone->db, &db);
   23494 	}
   23495 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   23496 	if (db == NULL) {
   23497 		goto failure;
   23498 	}
   23499 
   23500 	dns_db_currentversion(db, &oldver);
   23501 	result = dns_db_newversion(db, &newver);
   23502 	if (result != ISC_R_SUCCESS) {
   23503 		dns_zone_log(zone, ISC_LOG_ERROR,
   23504 			     "setserial:dns_db_newversion -> %s",
   23505 			     isc_result_totext(result));
   23506 		goto failure;
   23507 	}
   23508 
   23509 	CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL,
   23510 				    &oldtuple));
   23511 	CHECK(dns_difftuple_copy(oldtuple, &newtuple));
   23512 	newtuple->op = DNS_DIFFOP_ADD;
   23513 
   23514 	oldserial = dns_soa_getserial(&oldtuple->rdata);
   23515 	if (desired == 0U) {
   23516 		desired = 1;
   23517 	}
   23518 	if (!isc_serial_gt(desired, oldserial)) {
   23519 		if (desired != oldserial) {
   23520 			dns_zone_log(zone, ISC_LOG_INFO,
   23521 				     "setserial: desired serial (%u) "
   23522 				     "out of range (%u-%u)",
   23523 				     desired, oldserial + 1,
   23524 				     (oldserial + 0x7fffffff));
   23525 		}
   23526 		goto failure;
   23527 	}
   23528 
   23529 	dns_soa_setserial(desired, &newtuple->rdata);
   23530 	CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
   23531 	CHECK(do_one_tuple(&newtuple, db, newver, &diff));
   23532 	result = dns_update_signatures(&log, zone, db, oldver, newver, &diff,
   23533 				       zone->sigvalidityinterval);
   23534 	if (result != ISC_R_NOTFOUND) {
   23535 		CHECK(result);
   23536 	}
   23537 
   23538 	/* Write changes to journal file. */
   23539 	CHECK(zone_journal(zone, &diff, NULL, "setserial"));
   23540 	commit = true;
   23541 
   23542 	LOCK_ZONE(zone);
   23543 	zone_needdump(zone, 30);
   23544 	UNLOCK_ZONE(zone);
   23545 
   23546 failure:
   23547 	if (oldtuple != NULL) {
   23548 		dns_difftuple_free(&oldtuple);
   23549 	}
   23550 	if (newtuple != NULL) {
   23551 		dns_difftuple_free(&newtuple);
   23552 	}
   23553 	if (oldver != NULL) {
   23554 		dns_db_closeversion(db, &oldver, false);
   23555 	}
   23556 	if (newver != NULL) {
   23557 		dns_db_closeversion(db, &newver, commit);
   23558 	}
   23559 	if (db != NULL) {
   23560 		dns_db_detach(&db);
   23561 	}
   23562 	dns_diff_clear(&diff);
   23563 
   23564 disabled:
   23565 	isc_event_free(&event);
   23566 	dns_zone_idetach(&zone);
   23567 
   23568 	INSIST(oldver == NULL);
   23569 	INSIST(newver == NULL);
   23570 }
   23571 
   23572 isc_result_t
   23573 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
   23574 	isc_result_t result = ISC_R_SUCCESS;
   23575 	dns_zone_t *dummy = NULL;
   23576 	isc_event_t *e = NULL;
   23577 	struct ssevent *sse;
   23578 
   23579 	REQUIRE(DNS_ZONE_VALID(zone));
   23580 
   23581 	LOCK_ZONE(zone);
   23582 
   23583 	if (!inline_secure(zone)) {
   23584 		if (!dns_zone_isdynamic(zone, true)) {
   23585 			result = DNS_R_NOTDYNAMIC;
   23586 			goto failure;
   23587 		}
   23588 	}
   23589 
   23590 	if (zone->update_disabled) {
   23591 		result = DNS_R_FROZEN;
   23592 		goto failure;
   23593 	}
   23594 
   23595 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL, setserial,
   23596 			       zone, sizeof(struct ssevent));
   23597 
   23598 	sse = (struct ssevent *)e;
   23599 	sse->serial = serial;
   23600 
   23601 	zone_iattach(zone, &dummy);
   23602 	isc_task_send(zone->task, &e);
   23603 
   23604 failure:
   23605 	if (e != NULL) {
   23606 		isc_event_free(&e);
   23607 	}
   23608 	UNLOCK_ZONE(zone);
   23609 	return (result);
   23610 }
   23611 
   23612 isc_stats_t *
   23613 dns_zone_getgluecachestats(dns_zone_t *zone) {
   23614 	REQUIRE(DNS_ZONE_VALID(zone));
   23615 
   23616 	return (zone->gluecachestats);
   23617 }
   23618 
   23619 bool
   23620 dns_zone_isloaded(dns_zone_t *zone) {
   23621 	REQUIRE(DNS_ZONE_VALID(zone));
   23622 
   23623 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
   23624 }
   23625 
   23626 isc_result_t
   23627 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
   23628 	dns_dbversion_t *version = NULL;
   23629 	dns_keytable_t *secroots = NULL;
   23630 	isc_result_t result;
   23631 	dns_name_t *origin;
   23632 
   23633 	const char me[] = "dns_zone_verifydb";
   23634 
   23635 	REQUIRE(DNS_ZONE_VALID(zone));
   23636 	REQUIRE(db != NULL);
   23637 
   23638 	ENTER;
   23639 
   23640 	if (dns_zone_gettype(zone) != dns_zone_mirror) {
   23641 		return (ISC_R_SUCCESS);
   23642 	}
   23643 
   23644 	if (ver == NULL) {
   23645 		dns_db_currentversion(db, &version);
   23646 	} else {
   23647 		version = ver;
   23648 	}
   23649 
   23650 	if (zone->view != NULL) {
   23651 		result = dns_view_getsecroots(zone->view, &secroots);
   23652 		if (result != ISC_R_SUCCESS) {
   23653 			goto done;
   23654 		}
   23655 	}
   23656 
   23657 	origin = dns_db_origin(db);
   23658 	result = dns_zoneverify_dnssec(zone, db, version, origin, secroots,
   23659 				       zone->mctx, true, false, dnssec_report);
   23660 
   23661 done:
   23662 	if (secroots != NULL) {
   23663 		dns_keytable_detach(&secroots);
   23664 	}
   23665 
   23666 	if (ver == NULL) {
   23667 		dns_db_closeversion(db, &version, false);
   23668 	}
   23669 
   23670 	if (result != ISC_R_SUCCESS) {
   23671 		dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s",
   23672 			   isc_result_totext(result));
   23673 		result = DNS_R_VERIFYFAILURE;
   23674 	}
   23675 
   23676 	return (result);
   23677 }
   23678 
   23679 static dns_ttl_t
   23680 zone_nsecttl(dns_zone_t *zone) {
   23681 	REQUIRE(DNS_ZONE_VALID(zone));
   23682 
   23683 	return (ISC_MIN(zone->minimum, zone->soattl));
   23684 }
   23685 
   23686 void
   23687 dns_zonemgr_set_tlsctx_cache(dns_zonemgr_t *zmgr,
   23688 			     isc_tlsctx_cache_t *tlsctx_cache) {
   23689 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   23690 	REQUIRE(tlsctx_cache != NULL);
   23691 
   23692 	RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write);
   23693 
   23694 	if (zmgr->tlsctx_cache != NULL) {
   23695 		isc_tlsctx_cache_detach(&zmgr->tlsctx_cache);
   23696 	}
   23697 
   23698 	isc_tlsctx_cache_attach(tlsctx_cache, &zmgr->tlsctx_cache);
   23699 
   23700 	RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_write);
   23701 }
   23702 
   23703 static void
   23704 zmgr_tlsctx_attach(dns_zonemgr_t *zmgr, isc_tlsctx_cache_t **ptlsctx_cache) {
   23705 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   23706 	REQUIRE(ptlsctx_cache != NULL && *ptlsctx_cache == NULL);
   23707 
   23708 	RWLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read);
   23709 
   23710 	INSIST(zmgr->tlsctx_cache != NULL);
   23711 	isc_tlsctx_cache_attach(zmgr->tlsctx_cache, ptlsctx_cache);
   23712 
   23713 	RWUNLOCK(&zmgr->tlsctx_cache_rwlock, isc_rwlocktype_read);
   23714 }
   23715