Home | History | Annotate | Line # | Download | only in dns
zone.c revision 1.14
      1 /*	$NetBSD: zone.c,v 1.14 2021/04/29 17:26:11 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      5  *
      6  * This Source Code Form is subject to the terms of the Mozilla Public
      7  * License, v. 2.0. If a copy of the MPL was not distributed with this
      8  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
      9  *
     10  * See the COPYRIGHT file distributed with this work for additional
     11  * information regarding copyright ownership.
     12  */
     13 
     14 /*! \file */
     15 
     16 #include <errno.h>
     17 #include <inttypes.h>
     18 #include <stdbool.h>
     19 
     20 #include <isc/atomic.h>
     21 #include <isc/file.h>
     22 #include <isc/hex.h>
     23 #include <isc/md.h>
     24 #include <isc/mutex.h>
     25 #include <isc/pool.h>
     26 #include <isc/print.h>
     27 #include <isc/random.h>
     28 #include <isc/ratelimiter.h>
     29 #include <isc/refcount.h>
     30 #include <isc/rwlock.h>
     31 #include <isc/serial.h>
     32 #include <isc/stats.h>
     33 #include <isc/stdtime.h>
     34 #include <isc/strerr.h>
     35 #include <isc/string.h>
     36 #include <isc/taskpool.h>
     37 #include <isc/thread.h>
     38 #include <isc/timer.h>
     39 #include <isc/util.h>
     40 
     41 #include <dns/acl.h>
     42 #include <dns/adb.h>
     43 #include <dns/callbacks.h>
     44 #include <dns/catz.h>
     45 #include <dns/db.h>
     46 #include <dns/dbiterator.h>
     47 #include <dns/dlz.h>
     48 #include <dns/dnssec.h>
     49 #include <dns/events.h>
     50 #include <dns/journal.h>
     51 #include <dns/kasp.h>
     52 #include <dns/keydata.h>
     53 #include <dns/keymgr.h>
     54 #include <dns/keytable.h>
     55 #include <dns/keyvalues.h>
     56 #include <dns/log.h>
     57 #include <dns/master.h>
     58 #include <dns/masterdump.h>
     59 #include <dns/message.h>
     60 #include <dns/name.h>
     61 #include <dns/nsec.h>
     62 #include <dns/nsec3.h>
     63 #include <dns/peer.h>
     64 #include <dns/private.h>
     65 #include <dns/rcode.h>
     66 #include <dns/rdata.h>
     67 #include <dns/rdataclass.h>
     68 #include <dns/rdatalist.h>
     69 #include <dns/rdataset.h>
     70 #include <dns/rdatasetiter.h>
     71 #include <dns/rdatastruct.h>
     72 #include <dns/rdatatype.h>
     73 #include <dns/request.h>
     74 #include <dns/resolver.h>
     75 #include <dns/result.h>
     76 #include <dns/rriterator.h>
     77 #include <dns/soa.h>
     78 #include <dns/ssu.h>
     79 #include <dns/stats.h>
     80 #include <dns/time.h>
     81 #include <dns/tsig.h>
     82 #include <dns/update.h>
     83 #include <dns/xfrin.h>
     84 #include <dns/zone.h>
     85 #include <dns/zoneverify.h>
     86 #include <dns/zt.h>
     87 
     88 #include <dst/dst.h>
     89 
     90 #include "zone_p.h"
     91 
     92 #define ZONE_MAGIC	     ISC_MAGIC('Z', 'O', 'N', 'E')
     93 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
     94 
     95 #define NOTIFY_MAGIC		 ISC_MAGIC('N', 't', 'f', 'y')
     96 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
     97 
     98 #define STUB_MAGIC	     ISC_MAGIC('S', 't', 'u', 'b')
     99 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
    100 
    101 #define ZONEMGR_MAGIC		ISC_MAGIC('Z', 'm', 'g', 'r')
    102 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
    103 
    104 #define LOAD_MAGIC	     ISC_MAGIC('L', 'o', 'a', 'd')
    105 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
    106 
    107 #define FORWARD_MAGIC		ISC_MAGIC('F', 'o', 'r', 'w')
    108 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
    109 
    110 #define IO_MAGIC	   ISC_MAGIC('Z', 'm', 'I', 'O')
    111 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
    112 
    113 /*%
    114  * Ensure 'a' is at least 'min' but not more than 'max'.
    115  */
    116 #define RANGE(a, min, max) (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
    117 
    118 #define NSEC3REMOVE(x) (((x)&DNS_NSEC3FLAG_REMOVE) != 0)
    119 
    120 /*%
    121  * Key flags
    122  */
    123 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
    124 #define KSK(x)	  ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
    125 #define ID(x)	  dst_key_id(x)
    126 #define ALG(x)	  dst_key_alg(x)
    127 
    128 /*
    129  * Default values.
    130  */
    131 #define DNS_DEFAULT_IDLEIN  3600       /*%< 1 hour */
    132 #define DNS_DEFAULT_IDLEOUT 3600       /*%< 1 hour */
    133 #define MAX_XFER_TIME	    (2 * 3600) /*%< Documented default is 2 hours */
    134 #define RESIGN_DELAY	    3600       /*%< 1 hour */
    135 
    136 #ifndef DNS_MAX_EXPIRE
    137 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
    138 #endif				/* ifndef DNS_MAX_EXPIRE */
    139 
    140 #ifndef DNS_DUMP_DELAY
    141 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
    142 #endif			   /* ifndef DNS_DUMP_DELAY */
    143 
    144 typedef struct dns_notify dns_notify_t;
    145 typedef struct dns_stub dns_stub_t;
    146 typedef struct dns_load dns_load_t;
    147 typedef struct dns_forward dns_forward_t;
    148 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
    149 typedef struct dns_io dns_io_t;
    150 typedef ISC_LIST(dns_io_t) dns_iolist_t;
    151 typedef struct dns_signing dns_signing_t;
    152 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
    153 typedef struct dns_nsec3chain dns_nsec3chain_t;
    154 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
    155 typedef struct dns_keyfetch dns_keyfetch_t;
    156 typedef struct dns_asyncload dns_asyncload_t;
    157 typedef struct dns_include dns_include_t;
    158 
    159 #define DNS_ZONE_CHECKLOCK
    160 #ifdef DNS_ZONE_CHECKLOCK
    161 #define LOCK_ZONE(z)                  \
    162 	do {                          \
    163 		LOCK(&(z)->lock);     \
    164 		INSIST(!(z)->locked); \
    165 		(z)->locked = true;   \
    166 	} while (0)
    167 #define UNLOCK_ZONE(z)               \
    168 	do {                         \
    169 		(z)->locked = false; \
    170 		UNLOCK(&(z)->lock);  \
    171 	} while (0)
    172 #define LOCKED_ZONE(z) ((z)->locked)
    173 #define TRYLOCK_ZONE(result, z)                         \
    174 	do {                                            \
    175 		result = isc_mutex_trylock(&(z)->lock); \
    176 		if (result == ISC_R_SUCCESS) {          \
    177 			INSIST(!(z)->locked);           \
    178 			(z)->locked = true;             \
    179 		}                                       \
    180 	} while (0)
    181 #else /* ifdef DNS_ZONE_CHECKLOCK */
    182 #define LOCK_ZONE(z)   LOCK(&(z)->lock)
    183 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
    184 #define LOCKED_ZONE(z) true
    185 #define TRYLOCK_ZONE(result, z)                         \
    186 	do {                                            \
    187 		result = isc_mutex_trylock(&(z)->lock); \
    188 	} while (0)
    189 #endif /* ifdef DNS_ZONE_CHECKLOCK */
    190 
    191 #define ZONEDB_INITLOCK(l)    isc_rwlock_init((l), 0, 0)
    192 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
    193 #define ZONEDB_LOCK(l, t)     RWLOCK((l), (t))
    194 #define ZONEDB_UNLOCK(l, t)   RWUNLOCK((l), (t))
    195 
    196 #ifdef ENABLE_AFL
    197 extern bool dns_fuzzing_resolver;
    198 #endif /* ifdef ENABLE_AFL */
    199 
    200 struct dns_zone {
    201 	/* Unlocked */
    202 	unsigned int magic;
    203 	isc_mutex_t lock;
    204 #ifdef DNS_ZONE_CHECKLOCK
    205 	bool locked;
    206 #endif /* ifdef DNS_ZONE_CHECKLOCK */
    207 	isc_mem_t *mctx;
    208 	isc_refcount_t erefs;
    209 
    210 	isc_rwlock_t dblock;
    211 	dns_db_t *db; /* Locked by dblock */
    212 
    213 	/* Locked */
    214 	dns_zonemgr_t *zmgr;
    215 	ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
    216 	isc_timer_t *timer;
    217 	isc_refcount_t irefs;
    218 	dns_name_t origin;
    219 	char *masterfile;
    220 	ISC_LIST(dns_include_t) includes;    /* Include files */
    221 	ISC_LIST(dns_include_t) newincludes; /* Loading */
    222 	unsigned int nincludes;
    223 	dns_masterformat_t masterformat;
    224 	const dns_master_style_t *masterstyle;
    225 	char *journal;
    226 	int32_t journalsize;
    227 	dns_rdataclass_t rdclass;
    228 	dns_zonetype_t type;
    229 #ifdef __NetBSD__
    230 	atomic_uint_fast32_t flags;
    231 	atomic_uint_fast32_t options;
    232 #else
    233 	atomic_uint_fast64_t flags;
    234 	atomic_uint_fast64_t options;
    235 #endif
    236 	unsigned int db_argc;
    237 	char **db_argv;
    238 	isc_time_t expiretime;
    239 	isc_time_t refreshtime;
    240 	isc_time_t dumptime;
    241 	isc_time_t loadtime;
    242 	isc_time_t notifytime;
    243 	isc_time_t resigntime;
    244 	isc_time_t keywarntime;
    245 	isc_time_t signingtime;
    246 	isc_time_t nsec3chaintime;
    247 	isc_time_t refreshkeytime;
    248 	uint32_t refreshkeyinterval;
    249 	uint32_t refreshkeycount;
    250 	uint32_t refresh;
    251 	uint32_t retry;
    252 	uint32_t expire;
    253 	uint32_t minimum;
    254 	isc_stdtime_t key_expiry;
    255 	isc_stdtime_t log_key_expired_timer;
    256 	char *keydirectory;
    257 
    258 	uint32_t maxrefresh;
    259 	uint32_t minrefresh;
    260 	uint32_t maxretry;
    261 	uint32_t minretry;
    262 
    263 	uint32_t maxrecords;
    264 
    265 	isc_sockaddr_t *masters;
    266 	isc_dscp_t *masterdscps;
    267 	dns_name_t **masterkeynames;
    268 	bool *mastersok;
    269 	unsigned int masterscnt;
    270 	unsigned int curmaster;
    271 	isc_sockaddr_t masteraddr;
    272 	dns_notifytype_t notifytype;
    273 	isc_sockaddr_t *notify;
    274 	dns_name_t **notifykeynames;
    275 	isc_dscp_t *notifydscp;
    276 	unsigned int notifycnt;
    277 	isc_sockaddr_t notifyfrom;
    278 	isc_task_t *task;
    279 	isc_task_t *loadtask;
    280 	isc_sockaddr_t notifysrc4;
    281 	isc_sockaddr_t notifysrc6;
    282 	isc_sockaddr_t xfrsource4;
    283 	isc_sockaddr_t xfrsource6;
    284 	isc_sockaddr_t altxfrsource4;
    285 	isc_sockaddr_t altxfrsource6;
    286 	isc_sockaddr_t sourceaddr;
    287 	isc_dscp_t notifysrc4dscp;
    288 	isc_dscp_t notifysrc6dscp;
    289 	isc_dscp_t xfrsource4dscp;
    290 	isc_dscp_t xfrsource6dscp;
    291 	isc_dscp_t altxfrsource4dscp;
    292 	isc_dscp_t altxfrsource6dscp;
    293 	dns_xfrin_ctx_t *xfr;	/* task locked */
    294 	dns_tsigkey_t *tsigkey; /* key used for xfr */
    295 	/* Access Control Lists */
    296 	dns_acl_t *update_acl;
    297 	dns_acl_t *forward_acl;
    298 	dns_acl_t *notify_acl;
    299 	dns_acl_t *query_acl;
    300 	dns_acl_t *queryon_acl;
    301 	dns_acl_t *xfr_acl;
    302 	bool update_disabled;
    303 	bool zero_no_soa_ttl;
    304 	dns_severity_t check_names;
    305 	ISC_LIST(dns_notify_t) notifies;
    306 	dns_request_t *request;
    307 	dns_loadctx_t *lctx;
    308 	dns_io_t *readio;
    309 	dns_dumpctx_t *dctx;
    310 	dns_io_t *writeio;
    311 	uint32_t maxxfrin;
    312 	uint32_t maxxfrout;
    313 	uint32_t idlein;
    314 	uint32_t idleout;
    315 	isc_event_t ctlevent;
    316 	dns_ssutable_t *ssutable;
    317 	uint32_t sigvalidityinterval;
    318 	uint32_t keyvalidityinterval;
    319 	uint32_t sigresigninginterval;
    320 	dns_view_t *view;
    321 	dns_view_t *prev_view;
    322 	dns_kasp_t *kasp;
    323 	dns_checkmxfunc_t checkmx;
    324 	dns_checksrvfunc_t checksrv;
    325 	dns_checknsfunc_t checkns;
    326 	/*%
    327 	 * Zones in certain states such as "waiting for zone transfer"
    328 	 * or "zone transfer in progress" are kept on per-state linked lists
    329 	 * in the zone manager using the 'statelink' field.  The 'statelist'
    330 	 * field points at the list the zone is currently on.  It the zone
    331 	 * is not on any such list, statelist is NULL.
    332 	 */
    333 	ISC_LINK(dns_zone_t) statelink;
    334 	dns_zonelist_t *statelist;
    335 	/*%
    336 	 * Statistics counters about zone management.
    337 	 */
    338 	isc_stats_t *stats;
    339 	/*%
    340 	 * Optional per-zone statistics counters.  Counted outside of this
    341 	 * module.
    342 	 */
    343 	dns_zonestat_level_t statlevel;
    344 	bool requeststats_on;
    345 	isc_stats_t *requeststats;
    346 	dns_stats_t *rcvquerystats;
    347 	dns_stats_t *dnssecsignstats;
    348 	uint32_t notifydelay;
    349 	dns_isselffunc_t isself;
    350 	void *isselfarg;
    351 
    352 	char *strnamerd;
    353 	char *strname;
    354 	char *strrdclass;
    355 	char *strviewname;
    356 
    357 	/*%
    358 	 * Serial number for deferred journal compaction.
    359 	 */
    360 	uint32_t compact_serial;
    361 	/*%
    362 	 * Keys that are signing the zone for the first time.
    363 	 */
    364 	dns_signinglist_t signing;
    365 	dns_nsec3chainlist_t nsec3chain;
    366 	/*%
    367 	 * List of outstanding NSEC3PARAM change requests.
    368 	 */
    369 	isc_eventlist_t setnsec3param_queue;
    370 	/*%
    371 	 * Signing / re-signing quantum stopping parameters.
    372 	 */
    373 	uint32_t signatures;
    374 	uint32_t nodes;
    375 	dns_rdatatype_t privatetype;
    376 
    377 	/*%
    378 	 * Autosigning/key-maintenance options
    379 	 */
    380 #ifdef __NetBSD__
    381 	atomic_uint_fast32_t keyopts;
    382 #else
    383 	atomic_uint_fast64_t keyopts;
    384 #endif
    385 
    386 	/*%
    387 	 * True if added by "rndc addzone"
    388 	 */
    389 	bool added;
    390 
    391 	/*%
    392 	 * True if added by automatically by named.
    393 	 */
    394 	bool automatic;
    395 
    396 	/*%
    397 	 * response policy data to be relayed to the database
    398 	 */
    399 	dns_rpz_zones_t *rpzs;
    400 	dns_rpz_num_t rpz_num;
    401 
    402 	/*%
    403 	 * catalog zone data
    404 	 */
    405 	dns_catz_zones_t *catzs;
    406 
    407 	/*%
    408 	 * parent catalog zone
    409 	 */
    410 	dns_catz_zone_t *parentcatz;
    411 
    412 	/*%
    413 	 * Serial number update method.
    414 	 */
    415 	dns_updatemethod_t updatemethod;
    416 
    417 	/*%
    418 	 * whether ixfr is requested
    419 	 */
    420 	bool requestixfr;
    421 	uint32_t ixfr_ratio;
    422 
    423 	/*%
    424 	 * whether EDNS EXPIRE is requested
    425 	 */
    426 	bool requestexpire;
    427 
    428 	/*%
    429 	 * Outstanding forwarded UPDATE requests.
    430 	 */
    431 	dns_forwardlist_t forwards;
    432 
    433 	dns_zone_t *raw;
    434 	dns_zone_t *secure;
    435 
    436 	bool sourceserialset;
    437 	uint32_t sourceserial;
    438 
    439 	/*%
    440 	 * maximum zone ttl
    441 	 */
    442 	dns_ttl_t maxttl;
    443 
    444 	/*
    445 	 * Inline zone signing state.
    446 	 */
    447 	dns_diff_t rss_diff;
    448 	isc_eventlist_t rss_events;
    449 	isc_eventlist_t rss_post;
    450 	dns_dbversion_t *rss_newver;
    451 	dns_dbversion_t *rss_oldver;
    452 	dns_db_t *rss_db;
    453 	dns_zone_t *rss_raw;
    454 	isc_event_t *rss_event;
    455 	dns_update_state_t *rss_state;
    456 
    457 	isc_stats_t *gluecachestats;
    458 };
    459 
    460 #define zonediff_init(z, d)                \
    461 	do {                               \
    462 		dns__zonediff_t *_z = (z); \
    463 		(_z)->diff = (d);          \
    464 		(_z)->offline = false;     \
    465 	} while (0)
    466 
    467 #define DNS_ZONE_FLAG(z, f)    ((atomic_load_relaxed(&(z)->flags) & (f)) != 0)
    468 #define DNS_ZONE_SETFLAG(z, f) atomic_fetch_or(&(z)->flags, (f))
    469 #define DNS_ZONE_CLRFLAG(z, f) atomic_fetch_and(&(z)->flags, ~(f))
    470 typedef enum {
    471 	DNS_ZONEFLG_REFRESH = 0x00000001U,     /*%< refresh check in progress */
    472 	DNS_ZONEFLG_NEEDDUMP = 0x00000002U,    /*%< zone need consolidation */
    473 	DNS_ZONEFLG_USEVC = 0x00000004U,       /*%< use tcp for refresh query */
    474 	DNS_ZONEFLG_DUMPING = 0x00000008U,     /*%< a dump is in progress */
    475 	DNS_ZONEFLG_HASINCLUDE = 0x00000010U,  /*%< $INCLUDE in zone file */
    476 	DNS_ZONEFLG_LOADED = 0x00000020U,      /*%< database has loaded */
    477 	DNS_ZONEFLG_EXITING = 0x00000040U,     /*%< zone is being destroyed */
    478 	DNS_ZONEFLG_EXPIRED = 0x00000080U,     /*%< zone has expired */
    479 	DNS_ZONEFLG_NEEDREFRESH = 0x00000100U, /*%< refresh check needed */
    480 	DNS_ZONEFLG_UPTODATE = 0x00000200U,    /*%< zone contents are
    481 						* up-to-date */
    482 	DNS_ZONEFLG_NEEDNOTIFY = 0x00000400U,  /*%< need to send out notify
    483 						* messages */
    484 	DNS_ZONEFLG_FIXJOURNAL = 0x00000800U,  /*%< journal file had
    485 						* recoverable error,
    486 						* needs rewriting */
    487 	DNS_ZONEFLG_NOMASTERS = 0x00001000U,   /*%< an attempt to refresh a
    488 						* zone with no primaries
    489 						* occurred */
    490 	DNS_ZONEFLG_LOADING = 0x00002000U,     /*%< load from disk in progress*/
    491 	DNS_ZONEFLG_HAVETIMERS = 0x00004000U,  /*%< timer values have been set
    492 						* from SOA (if not set, we
    493 						* are still using
    494 						* default timer values) */
    495 	DNS_ZONEFLG_FORCEXFER = 0x00008000U,   /*%< Force a zone xfer */
    496 	DNS_ZONEFLG_NOREFRESH = 0x00010000U,
    497 	DNS_ZONEFLG_DIALNOTIFY = 0x00020000U,
    498 	DNS_ZONEFLG_DIALREFRESH = 0x00040000U,
    499 	DNS_ZONEFLG_SHUTDOWN = 0x00080000U,
    500 	DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */
    501 	DNS_ZONEFLG_FLUSH = 0x00200000U,
    502 	DNS_ZONEFLG_NOEDNS = 0x00400000U,
    503 	DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U,
    504 	DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U,
    505 	DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U,
    506 	DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */
    507 	DNS_ZONEFLG_THAW = 0x08000000U,
    508 	DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */
    509 	DNS_ZONEFLG_NODELAY = 0x20000000U,
    510 	DNS_ZONEFLG_SENDSECURE = 0x40000000U,
    511 	DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out
    512 						      * notify due to the zone
    513 						      * just being loaded for
    514 						      * the first time. */
    515 #ifndef __NetBSD__
    516 	/*
    517 	 * DO NOT add any new zone flags here until all platforms
    518 	 * support 64-bit enum values. Currently they fail on
    519 	 * Windows.
    520 	 */
    521 	DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */
    522 #endif
    523 } dns_zoneflg_t;
    524 
    525 #define DNS_ZONE_OPTION(z, o)	 ((atomic_load_relaxed(&(z)->options) & (o)) != 0)
    526 #define DNS_ZONE_SETOPTION(z, o) atomic_fetch_or(&(z)->options, (o))
    527 #define DNS_ZONE_CLROPTION(z, o) atomic_fetch_and(&(z)->options, ~(o))
    528 
    529 #define DNS_ZONEKEY_OPTION(z, o) \
    530 	((atomic_load_relaxed(&(z)->keyopts) & (o)) != 0)
    531 #define DNS_ZONEKEY_SETOPTION(z, o) atomic_fetch_or(&(z)->keyopts, (o))
    532 #define DNS_ZONEKEY_CLROPTION(z, o) atomic_fetch_and(&(z)->keyopts, ~(o))
    533 
    534 /* Flags for zone_load() */
    535 typedef enum {
    536 	DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */
    537 	DNS_ZONELOADFLAG_THAW = 0x00000002U,   /* Thaw the zone on successful
    538 						* load. */
    539 } dns_zoneloadflag_t;
    540 
    541 #define UNREACH_CACHE_SIZE 10U
    542 #define UNREACH_HOLD_TIME  600 /* 10 minutes */
    543 
    544 #define CHECK(op)                            \
    545 	do {                                 \
    546 		result = (op);               \
    547 		if (result != ISC_R_SUCCESS) \
    548 			goto failure;        \
    549 	} while (0)
    550 
    551 struct dns_unreachable {
    552 	isc_sockaddr_t remote;
    553 	isc_sockaddr_t local;
    554 	atomic_uint_fast32_t expire;
    555 	atomic_uint_fast32_t last;
    556 	uint32_t count;
    557 };
    558 
    559 struct dns_zonemgr {
    560 	unsigned int magic;
    561 	isc_mem_t *mctx;
    562 	isc_refcount_t refs;
    563 	isc_taskmgr_t *taskmgr;
    564 	isc_timermgr_t *timermgr;
    565 	isc_socketmgr_t *socketmgr;
    566 	isc_taskpool_t *zonetasks;
    567 	isc_taskpool_t *loadtasks;
    568 	isc_task_t *task;
    569 	isc_pool_t *mctxpool;
    570 	isc_ratelimiter_t *notifyrl;
    571 	isc_ratelimiter_t *refreshrl;
    572 	isc_ratelimiter_t *startupnotifyrl;
    573 	isc_ratelimiter_t *startuprefreshrl;
    574 	isc_rwlock_t rwlock;
    575 	isc_mutex_t iolock;
    576 	isc_rwlock_t urlock;
    577 
    578 	/* Locked by rwlock. */
    579 	dns_zonelist_t zones;
    580 	dns_zonelist_t waiting_for_xfrin;
    581 	dns_zonelist_t xfrin_in_progress;
    582 
    583 	/* Configuration data. */
    584 	uint32_t transfersin;
    585 	uint32_t transfersperns;
    586 	unsigned int notifyrate;
    587 	unsigned int startupnotifyrate;
    588 	unsigned int serialqueryrate;
    589 	unsigned int startupserialqueryrate;
    590 
    591 	/* Locked by iolock */
    592 	uint32_t iolimit;
    593 	uint32_t ioactive;
    594 	dns_iolist_t high;
    595 	dns_iolist_t low;
    596 
    597 	/* Locked by urlock. */
    598 	/* LRU cache */
    599 	struct dns_unreachable unreachable[UNREACH_CACHE_SIZE];
    600 };
    601 
    602 /*%
    603  * Hold notify state.
    604  */
    605 struct dns_notify {
    606 	unsigned int magic;
    607 	unsigned int flags;
    608 	isc_mem_t *mctx;
    609 	dns_zone_t *zone;
    610 	dns_adbfind_t *find;
    611 	dns_request_t *request;
    612 	dns_name_t ns;
    613 	isc_sockaddr_t dst;
    614 	dns_tsigkey_t *key;
    615 	isc_dscp_t dscp;
    616 	ISC_LINK(dns_notify_t) link;
    617 	isc_event_t *event;
    618 };
    619 
    620 #define DNS_NOTIFY_NOSOA   0x0001U
    621 #define DNS_NOTIFY_STARTUP 0x0002U
    622 
    623 /*%
    624  *	dns_stub holds state while performing a 'stub' transfer.
    625  *	'db' is the zone's 'db' or a new one if this is the initial
    626  *	transfer.
    627  */
    628 
    629 struct dns_stub {
    630 	unsigned int magic;
    631 	isc_mem_t *mctx;
    632 	dns_zone_t *zone;
    633 	dns_db_t *db;
    634 	dns_dbversion_t *version;
    635 	atomic_uint_fast32_t pending_requests;
    636 };
    637 
    638 /*%
    639  *	Hold load state.
    640  */
    641 struct dns_load {
    642 	unsigned int magic;
    643 	isc_mem_t *mctx;
    644 	dns_zone_t *zone;
    645 	dns_db_t *db;
    646 	isc_time_t loadtime;
    647 	dns_rdatacallbacks_t callbacks;
    648 };
    649 
    650 /*%
    651  *	Hold forward state.
    652  */
    653 struct dns_forward {
    654 	unsigned int magic;
    655 	isc_mem_t *mctx;
    656 	dns_zone_t *zone;
    657 	isc_buffer_t *msgbuf;
    658 	dns_request_t *request;
    659 	uint32_t which;
    660 	isc_sockaddr_t addr;
    661 	dns_updatecallback_t callback;
    662 	void *callback_arg;
    663 	unsigned int options;
    664 	ISC_LINK(dns_forward_t) link;
    665 };
    666 
    667 /*%
    668  *	Hold IO request state.
    669  */
    670 struct dns_io {
    671 	unsigned int magic;
    672 	dns_zonemgr_t *zmgr;
    673 	bool high;
    674 	isc_task_t *task;
    675 	ISC_LINK(dns_io_t) link;
    676 	isc_event_t *event;
    677 };
    678 
    679 /*%
    680  *	Hold state for when we are signing a zone with a new
    681  *	DNSKEY as result of an update.
    682  */
    683 struct dns_signing {
    684 	unsigned int magic;
    685 	dns_db_t *db;
    686 	dns_dbiterator_t *dbiterator;
    687 	dns_secalg_t algorithm;
    688 	uint16_t keyid;
    689 	bool deleteit;
    690 	bool done;
    691 	ISC_LINK(dns_signing_t) link;
    692 };
    693 
    694 struct dns_nsec3chain {
    695 	unsigned int magic;
    696 	dns_db_t *db;
    697 	dns_dbiterator_t *dbiterator;
    698 	dns_rdata_nsec3param_t nsec3param;
    699 	unsigned char salt[255];
    700 	bool done;
    701 	bool seen_nsec;
    702 	bool delete_nsec;
    703 	bool save_delete_nsec;
    704 	ISC_LINK(dns_nsec3chain_t) link;
    705 };
    706 /*%<
    707  * 'dbiterator' contains a iterator for the database.  If we are creating
    708  * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
    709  * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
    710  * iterated.
    711  *
    712  * 'nsec3param' contains the parameters of the NSEC3 chain being created
    713  * or removed.
    714  *
    715  * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
    716  *
    717  * 'seen_nsec' will be set to true if, while iterating the zone to create a
    718  * NSEC3 chain, a NSEC record is seen.
    719  *
    720  * 'delete_nsec' will be set to true if, at the completion of the creation
    721  * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
    722  * are in the process of deleting the NSEC chain.
    723  *
    724  * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
    725  * so it can be recovered in the event of a error.
    726  */
    727 
    728 struct dns_keyfetch {
    729 	dns_fixedname_t name;
    730 	dns_rdataset_t keydataset;
    731 	dns_rdataset_t dnskeyset;
    732 	dns_rdataset_t dnskeysigset;
    733 	dns_zone_t *zone;
    734 	dns_db_t *db;
    735 	dns_fetch_t *fetch;
    736 };
    737 
    738 /*%
    739  * Hold state for an asynchronous load
    740  */
    741 struct dns_asyncload {
    742 	dns_zone_t *zone;
    743 	unsigned int flags;
    744 	dns_zt_zoneloaded_t loaded;
    745 	void *loaded_arg;
    746 };
    747 
    748 /*%
    749  * Reference to an include file encountered during loading
    750  */
    751 struct dns_include {
    752 	char *name;
    753 	isc_time_t filetime;
    754 	ISC_LINK(dns_include_t) link;
    755 };
    756 
    757 /*
    758  * These can be overridden by the -T mkeytimers option on the command
    759  * line, so that we can test with shorter periods than specified in
    760  * RFC 5011.
    761  */
    762 #define HOUR  3600
    763 #define DAY   (24 * HOUR)
    764 #define MONTH (30 * DAY)
    765 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR;
    766 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY;
    767 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH;
    768 
    769 #define SEND_BUFFER_SIZE 2048
    770 
    771 static void
    772 zone_settimer(dns_zone_t *, isc_time_t *);
    773 static void
    774 cancel_refresh(dns_zone_t *);
    775 static void
    776 zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg,
    777 	      ...) ISC_FORMAT_PRINTF(4, 5);
    778 static void
    779 notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
    780 	ISC_FORMAT_PRINTF(3, 4);
    781 static void
    782 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...)
    783 	ISC_FORMAT_PRINTF(3, 4);
    784 static void
    785 queue_xfrin(dns_zone_t *zone);
    786 static isc_result_t
    787 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
    788 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
    789 	      dns_rdata_t *rdata);
    790 static void
    791 zone_unload(dns_zone_t *zone);
    792 static void
    793 zone_expire(dns_zone_t *zone);
    794 static void
    795 zone_iattach(dns_zone_t *source, dns_zone_t **target);
    796 static void
    797 zone_idetach(dns_zone_t **zonep);
    798 static isc_result_t
    799 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump);
    800 static inline void
    801 zone_attachdb(dns_zone_t *zone, dns_db_t *db);
    802 static inline void
    803 zone_detachdb(dns_zone_t *zone);
    804 static isc_result_t
    805 default_journal(dns_zone_t *zone);
    806 static void
    807 zone_xfrdone(dns_zone_t *zone, isc_result_t result);
    808 static isc_result_t
    809 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
    810 	      isc_result_t result);
    811 static void
    812 zone_needdump(dns_zone_t *zone, unsigned int delay);
    813 static void
    814 zone_shutdown(isc_task_t *, isc_event_t *);
    815 static void
    816 zone_loaddone(void *arg, isc_result_t result);
    817 static isc_result_t
    818 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime);
    819 static void
    820 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
    821 static void
    822 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
    823 static void
    824 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
    825 static void
    826 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
    827 static isc_result_t
    828 zone_send_secureserial(dns_zone_t *zone, uint32_t serial);
    829 static void
    830 refresh_callback(isc_task_t *, isc_event_t *);
    831 static void
    832 stub_callback(isc_task_t *, isc_event_t *);
    833 static void
    834 queue_soa_query(dns_zone_t *zone);
    835 static void
    836 soa_query(isc_task_t *, isc_event_t *);
    837 static void
    838 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub);
    839 static int
    840 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type);
    841 static void
    842 notify_cancel(dns_zone_t *zone);
    843 static void
    844 notify_find_address(dns_notify_t *notify);
    845 static void
    846 notify_send(dns_notify_t *notify);
    847 static isc_result_t
    848 notify_createmessage(dns_zone_t *zone, unsigned int flags,
    849 		     dns_message_t **messagep);
    850 static void
    851 notify_done(isc_task_t *task, isc_event_t *event);
    852 static void
    853 notify_send_toaddr(isc_task_t *task, isc_event_t *event);
    854 static isc_result_t
    855 zone_dump(dns_zone_t *, bool);
    856 static void
    857 got_transfer_quota(isc_task_t *task, isc_event_t *event);
    858 static isc_result_t
    859 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone);
    860 static void
    861 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi);
    862 static void
    863 zonemgr_free(dns_zonemgr_t *zmgr);
    864 static isc_result_t
    865 zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task,
    866 	      isc_taskaction_t action, void *arg, dns_io_t **iop);
    867 static void
    868 zonemgr_putio(dns_io_t **iop);
    869 static void
    870 zonemgr_cancelio(dns_io_t *io);
    871 static void
    872 rss_post(dns_zone_t *, isc_event_t *);
    873 
    874 static isc_result_t
    875 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
    876 		 unsigned int *soacount, uint32_t *serial, uint32_t *refresh,
    877 		 uint32_t *retry, uint32_t *expire, uint32_t *minimum,
    878 		 unsigned int *errors);
    879 
    880 static void
    881 zone_freedbargs(dns_zone_t *zone);
    882 static void
    883 forward_callback(isc_task_t *task, isc_event_t *event);
    884 static void
    885 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat);
    886 static void
    887 zone_maintenance(dns_zone_t *zone);
    888 static void
    889 zone_notify(dns_zone_t *zone, isc_time_t *now);
    890 static void
    891 dump_done(void *arg, isc_result_t result);
    892 static isc_result_t
    893 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
    894 		 bool deleteit);
    895 static isc_result_t
    896 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
    897 	    dns_name_t *name, dns_diff_t *diff);
    898 static void
    899 zone_rekey(dns_zone_t *zone);
    900 static isc_result_t
    901 zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
    902 static void
    903 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value);
    904 static void
    905 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial);
    906 static isc_result_t
    907 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump,
    908 			 bool *fixjournal);
    909 
    910 #define ENTER zone_debuglog(zone, me, 1, "enter")
    911 
    912 static const unsigned int dbargc_default = 1;
    913 static const char *dbargv_default[] = { "rbt" };
    914 
    915 #define DNS_ZONE_JITTER_ADD(a, b, c)                                         \
    916 	do {                                                                 \
    917 		isc_interval_t _i;                                           \
    918 		uint32_t _j;                                                 \
    919 		_j = (b)-isc_random_uniform((b) / 4);                        \
    920 		isc_interval_set(&_i, _j, 0);                                \
    921 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) {          \
    922 			dns_zone_log(zone, ISC_LOG_WARNING,                  \
    923 				     "epoch approaching: upgrade required: " \
    924 				     "now + %s failed",                      \
    925 				     #b);                                    \
    926 			isc_interval_set(&_i, _j / 2, 0);                    \
    927 			(void)isc_time_add((a), &_i, (c));                   \
    928 		}                                                            \
    929 	} while (0)
    930 
    931 #define DNS_ZONE_TIME_ADD(a, b, c)                                           \
    932 	do {                                                                 \
    933 		isc_interval_t _i;                                           \
    934 		isc_interval_set(&_i, (b), 0);                               \
    935 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) {          \
    936 			dns_zone_log(zone, ISC_LOG_WARNING,                  \
    937 				     "epoch approaching: upgrade required: " \
    938 				     "now + %s failed",                      \
    939 				     #b);                                    \
    940 			isc_interval_set(&_i, (b) / 2, 0);                   \
    941 			(void)isc_time_add((a), &_i, (c));                   \
    942 		}                                                            \
    943 	} while (0)
    944 
    945 typedef struct nsec3param nsec3param_t;
    946 struct nsec3param {
    947 	unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
    948 	unsigned int length;
    949 	bool nsec;
    950 	bool replace;
    951 	ISC_LINK(nsec3param_t) link;
    952 };
    953 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
    954 struct np3event {
    955 	isc_event_t event;
    956 	nsec3param_t params;
    957 };
    958 
    959 struct ssevent {
    960 	isc_event_t event;
    961 	uint32_t serial;
    962 };
    963 
    964 struct stub_cb_args {
    965 	dns_stub_t *stub;
    966 	dns_tsigkey_t *tsig_key;
    967 	isc_dscp_t dscp;
    968 	uint16_t udpsize;
    969 	int timeout;
    970 	bool reqnsid;
    971 };
    972 
    973 struct stub_glue_request {
    974 	dns_request_t *request;
    975 	dns_name_t name;
    976 	struct stub_cb_args *args;
    977 	bool ipv4;
    978 };
    979 
    980 /*%
    981  * Increment resolver-related statistics counters.  Zone must be locked.
    982  */
    983 static inline void
    984 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
    985 	if (zone->stats != NULL) {
    986 		isc_stats_increment(zone->stats, counter);
    987 	}
    988 }
    989 
    990 /***
    991  ***	Public functions.
    992  ***/
    993 
    994 isc_result_t
    995 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
    996 	isc_result_t result;
    997 	dns_zone_t *zone;
    998 	isc_time_t now;
    999 
   1000 	REQUIRE(zonep != NULL && *zonep == NULL);
   1001 	REQUIRE(mctx != NULL);
   1002 
   1003 	TIME_NOW(&now);
   1004 	zone = isc_mem_get(mctx, sizeof(*zone));
   1005 
   1006 	zone->mctx = NULL;
   1007 	isc_mem_attach(mctx, &zone->mctx);
   1008 	isc_mutex_init(&zone->lock);
   1009 	ZONEDB_INITLOCK(&zone->dblock);
   1010 	/* XXX MPA check that all elements are initialised */
   1011 #ifdef DNS_ZONE_CHECKLOCK
   1012 	zone->locked = false;
   1013 #endif /* ifdef DNS_ZONE_CHECKLOCK */
   1014 	zone->db = NULL;
   1015 	zone->zmgr = NULL;
   1016 	ISC_LINK_INIT(zone, link);
   1017 	isc_refcount_init(&zone->erefs, 1);
   1018 	isc_refcount_init(&zone->irefs, 0);
   1019 	dns_name_init(&zone->origin, NULL);
   1020 	zone->strnamerd = NULL;
   1021 	zone->strname = NULL;
   1022 	zone->strrdclass = NULL;
   1023 	zone->strviewname = NULL;
   1024 	zone->masterfile = NULL;
   1025 	ISC_LIST_INIT(zone->includes);
   1026 	ISC_LIST_INIT(zone->newincludes);
   1027 	zone->nincludes = 0;
   1028 	zone->masterformat = dns_masterformat_none;
   1029 	zone->masterstyle = NULL;
   1030 	zone->keydirectory = NULL;
   1031 	zone->journalsize = -1;
   1032 	zone->journal = NULL;
   1033 	zone->rdclass = dns_rdataclass_none;
   1034 	zone->type = dns_zone_none;
   1035 	atomic_init(&zone->flags, 0);
   1036 	atomic_init(&zone->options, 0);
   1037 	atomic_init(&zone->keyopts, 0);
   1038 	zone->db_argc = 0;
   1039 	zone->db_argv = NULL;
   1040 	isc_time_settoepoch(&zone->expiretime);
   1041 	isc_time_settoepoch(&zone->refreshtime);
   1042 	isc_time_settoepoch(&zone->dumptime);
   1043 	isc_time_settoepoch(&zone->loadtime);
   1044 	zone->notifytime = now;
   1045 	isc_time_settoepoch(&zone->resigntime);
   1046 	isc_time_settoepoch(&zone->keywarntime);
   1047 	isc_time_settoepoch(&zone->signingtime);
   1048 	isc_time_settoepoch(&zone->nsec3chaintime);
   1049 	isc_time_settoepoch(&zone->refreshkeytime);
   1050 	zone->refreshkeyinterval = 0;
   1051 	zone->refreshkeycount = 0;
   1052 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   1053 	zone->retry = DNS_ZONE_DEFAULTRETRY;
   1054 	zone->expire = 0;
   1055 	zone->minimum = 0;
   1056 	zone->maxrefresh = DNS_ZONE_MAXREFRESH;
   1057 	zone->minrefresh = DNS_ZONE_MINREFRESH;
   1058 	zone->maxretry = DNS_ZONE_MAXRETRY;
   1059 	zone->minretry = DNS_ZONE_MINRETRY;
   1060 	zone->masters = NULL;
   1061 	zone->masterdscps = NULL;
   1062 	zone->masterkeynames = NULL;
   1063 	zone->mastersok = NULL;
   1064 	zone->masterscnt = 0;
   1065 	zone->curmaster = 0;
   1066 	zone->maxttl = 0;
   1067 	zone->notify = NULL;
   1068 	zone->notifykeynames = NULL;
   1069 	zone->notifydscp = NULL;
   1070 	zone->notifytype = dns_notifytype_yes;
   1071 	zone->notifycnt = 0;
   1072 	zone->task = NULL;
   1073 	zone->loadtask = NULL;
   1074 	zone->update_acl = NULL;
   1075 	zone->forward_acl = NULL;
   1076 	zone->notify_acl = NULL;
   1077 	zone->query_acl = NULL;
   1078 	zone->queryon_acl = NULL;
   1079 	zone->xfr_acl = NULL;
   1080 	zone->update_disabled = false;
   1081 	zone->zero_no_soa_ttl = true;
   1082 	zone->check_names = dns_severity_ignore;
   1083 	zone->request = NULL;
   1084 	zone->lctx = NULL;
   1085 	zone->readio = NULL;
   1086 	zone->dctx = NULL;
   1087 	zone->writeio = NULL;
   1088 	zone->timer = NULL;
   1089 	zone->idlein = DNS_DEFAULT_IDLEIN;
   1090 	zone->idleout = DNS_DEFAULT_IDLEOUT;
   1091 	zone->log_key_expired_timer = 0;
   1092 	ISC_LIST_INIT(zone->notifies);
   1093 	isc_sockaddr_any(&zone->notifysrc4);
   1094 	isc_sockaddr_any6(&zone->notifysrc6);
   1095 	isc_sockaddr_any(&zone->xfrsource4);
   1096 	isc_sockaddr_any6(&zone->xfrsource6);
   1097 	isc_sockaddr_any(&zone->altxfrsource4);
   1098 	isc_sockaddr_any6(&zone->altxfrsource6);
   1099 	zone->notifysrc4dscp = -1;
   1100 	zone->notifysrc6dscp = -1;
   1101 	zone->xfrsource4dscp = -1;
   1102 	zone->xfrsource6dscp = -1;
   1103 	zone->altxfrsource4dscp = -1;
   1104 	zone->altxfrsource6dscp = -1;
   1105 	zone->xfr = NULL;
   1106 	zone->tsigkey = NULL;
   1107 	zone->maxxfrin = MAX_XFER_TIME;
   1108 	zone->maxxfrout = MAX_XFER_TIME;
   1109 	zone->ssutable = NULL;
   1110 	zone->sigvalidityinterval = 30 * 24 * 3600;
   1111 	zone->keyvalidityinterval = 0;
   1112 	zone->sigresigninginterval = 7 * 24 * 3600;
   1113 	zone->kasp = NULL;
   1114 	zone->view = NULL;
   1115 	zone->prev_view = NULL;
   1116 	zone->checkmx = NULL;
   1117 	zone->checksrv = NULL;
   1118 	zone->checkns = NULL;
   1119 	ISC_LINK_INIT(zone, statelink);
   1120 	zone->statelist = NULL;
   1121 	zone->stats = NULL;
   1122 	zone->requeststats_on = false;
   1123 	zone->statlevel = dns_zonestat_none;
   1124 	zone->requeststats = NULL;
   1125 	zone->rcvquerystats = NULL;
   1126 	zone->dnssecsignstats = NULL;
   1127 	zone->notifydelay = 5;
   1128 	zone->isself = NULL;
   1129 	zone->isselfarg = NULL;
   1130 	ISC_LIST_INIT(zone->signing);
   1131 	ISC_LIST_INIT(zone->nsec3chain);
   1132 	ISC_LIST_INIT(zone->setnsec3param_queue);
   1133 	zone->signatures = 10;
   1134 	zone->nodes = 100;
   1135 	zone->privatetype = (dns_rdatatype_t)0xffffU;
   1136 	zone->added = false;
   1137 	zone->automatic = false;
   1138 	zone->rpzs = NULL;
   1139 	zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1140 
   1141 	zone->catzs = NULL;
   1142 	zone->parentcatz = NULL;
   1143 
   1144 	ISC_LIST_INIT(zone->forwards);
   1145 	zone->raw = NULL;
   1146 	zone->secure = NULL;
   1147 	zone->sourceserial = 0;
   1148 	zone->sourceserialset = false;
   1149 	zone->requestixfr = true;
   1150 	zone->ixfr_ratio = 100;
   1151 	zone->requestexpire = true;
   1152 	ISC_LIST_INIT(zone->rss_events);
   1153 	ISC_LIST_INIT(zone->rss_post);
   1154 	zone->rss_db = NULL;
   1155 	zone->rss_raw = NULL;
   1156 	zone->rss_newver = NULL;
   1157 	zone->rss_oldver = NULL;
   1158 	zone->rss_event = NULL;
   1159 	zone->rss_state = NULL;
   1160 	zone->updatemethod = dns_updatemethod_increment;
   1161 	zone->maxrecords = 0U;
   1162 
   1163 	zone->magic = ZONE_MAGIC;
   1164 
   1165 	zone->gluecachestats = NULL;
   1166 	result = isc_stats_create(mctx, &zone->gluecachestats,
   1167 				  dns_gluecachestatscounter_max);
   1168 	if (result != ISC_R_SUCCESS) {
   1169 		goto free_refs;
   1170 	}
   1171 
   1172 	/* Must be after magic is set. */
   1173 	dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
   1174 
   1175 	ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
   1176 		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL,
   1177 		       NULL);
   1178 	*zonep = zone;
   1179 	return (ISC_R_SUCCESS);
   1180 
   1181 free_refs:
   1182 	isc_refcount_decrement0(&zone->erefs);
   1183 	isc_refcount_destroy(&zone->erefs);
   1184 	isc_refcount_destroy(&zone->irefs);
   1185 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1186 	isc_mutex_destroy(&zone->lock);
   1187 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1188 	return (result);
   1189 }
   1190 
   1191 /*
   1192  * Free a zone.  Because we require that there be no more
   1193  * outstanding events or references, no locking is necessary.
   1194  */
   1195 static void
   1196 zone_free(dns_zone_t *zone) {
   1197 	dns_signing_t *signing;
   1198 	dns_nsec3chain_t *nsec3chain;
   1199 	isc_event_t *event;
   1200 	dns_include_t *include;
   1201 
   1202 	REQUIRE(DNS_ZONE_VALID(zone));
   1203 	isc_refcount_destroy(&zone->erefs);
   1204 	isc_refcount_destroy(&zone->irefs);
   1205 	REQUIRE(!LOCKED_ZONE(zone));
   1206 	REQUIRE(zone->timer == NULL);
   1207 	REQUIRE(zone->zmgr == NULL);
   1208 
   1209 	/*
   1210 	 * Managed objects.  Order is important.
   1211 	 */
   1212 	if (zone->request != NULL) {
   1213 		dns_request_destroy(&zone->request); /* XXXMPA */
   1214 	}
   1215 	INSIST(zone->readio == NULL);
   1216 	INSIST(zone->statelist == NULL);
   1217 	INSIST(zone->writeio == NULL);
   1218 
   1219 	if (zone->task != NULL) {
   1220 		isc_task_detach(&zone->task);
   1221 	}
   1222 	if (zone->loadtask != NULL) {
   1223 		isc_task_detach(&zone->loadtask);
   1224 	}
   1225 	if (zone->view != NULL) {
   1226 		dns_view_weakdetach(&zone->view);
   1227 	}
   1228 	if (zone->prev_view != NULL) {
   1229 		dns_view_weakdetach(&zone->prev_view);
   1230 	}
   1231 
   1232 	/* Unmanaged objects */
   1233 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   1234 		event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   1235 		ISC_LIST_UNLINK(zone->setnsec3param_queue, event, ev_link);
   1236 		isc_event_free(&event);
   1237 	}
   1238 	while (!ISC_LIST_EMPTY(zone->rss_post)) {
   1239 		event = ISC_LIST_HEAD(zone->rss_post);
   1240 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   1241 		isc_event_free(&event);
   1242 	}
   1243 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   1244 	     signing = ISC_LIST_HEAD(zone->signing))
   1245 	{
   1246 		ISC_LIST_UNLINK(zone->signing, signing, link);
   1247 		dns_db_detach(&signing->db);
   1248 		dns_dbiterator_destroy(&signing->dbiterator);
   1249 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   1250 	}
   1251 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   1252 	     nsec3chain = ISC_LIST_HEAD(zone->nsec3chain))
   1253 	{
   1254 		ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   1255 		dns_db_detach(&nsec3chain->db);
   1256 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   1257 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   1258 	}
   1259 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   1260 	     include = ISC_LIST_HEAD(zone->includes))
   1261 	{
   1262 		ISC_LIST_UNLINK(zone->includes, include, link);
   1263 		isc_mem_free(zone->mctx, include->name);
   1264 		isc_mem_put(zone->mctx, include, sizeof *include);
   1265 	}
   1266 	for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL;
   1267 	     include = ISC_LIST_HEAD(zone->newincludes))
   1268 	{
   1269 		ISC_LIST_UNLINK(zone->newincludes, include, link);
   1270 		isc_mem_free(zone->mctx, include->name);
   1271 		isc_mem_put(zone->mctx, include, sizeof *include);
   1272 	}
   1273 	if (zone->masterfile != NULL) {
   1274 		isc_mem_free(zone->mctx, zone->masterfile);
   1275 	}
   1276 	zone->masterfile = NULL;
   1277 	if (zone->keydirectory != NULL) {
   1278 		isc_mem_free(zone->mctx, zone->keydirectory);
   1279 	}
   1280 	zone->keydirectory = NULL;
   1281 	if (zone->kasp != NULL) {
   1282 		dns_kasp_detach(&zone->kasp);
   1283 	}
   1284 	zone->journalsize = -1;
   1285 	if (zone->journal != NULL) {
   1286 		isc_mem_free(zone->mctx, zone->journal);
   1287 	}
   1288 	zone->journal = NULL;
   1289 	if (zone->stats != NULL) {
   1290 		isc_stats_detach(&zone->stats);
   1291 	}
   1292 	if (zone->requeststats != NULL) {
   1293 		isc_stats_detach(&zone->requeststats);
   1294 	}
   1295 	if (zone->rcvquerystats != NULL) {
   1296 		dns_stats_detach(&zone->rcvquerystats);
   1297 	}
   1298 	if (zone->dnssecsignstats != NULL) {
   1299 		dns_stats_detach(&zone->dnssecsignstats);
   1300 	}
   1301 	if (zone->db != NULL) {
   1302 		zone_detachdb(zone);
   1303 	}
   1304 	if (zone->rpzs != NULL) {
   1305 		REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
   1306 		dns_rpz_detach_rpzs(&zone->rpzs);
   1307 		zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1308 	}
   1309 	if (zone->catzs != NULL) {
   1310 		dns_catz_catzs_detach(&zone->catzs);
   1311 	}
   1312 	zone_freedbargs(zone);
   1313 	RUNTIME_CHECK(dns_zone_setprimarieswithkeys(zone, NULL, NULL, 0) ==
   1314 		      ISC_R_SUCCESS);
   1315 	RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
   1316 	zone->check_names = dns_severity_ignore;
   1317 	if (zone->update_acl != NULL) {
   1318 		dns_acl_detach(&zone->update_acl);
   1319 	}
   1320 	if (zone->forward_acl != NULL) {
   1321 		dns_acl_detach(&zone->forward_acl);
   1322 	}
   1323 	if (zone->notify_acl != NULL) {
   1324 		dns_acl_detach(&zone->notify_acl);
   1325 	}
   1326 	if (zone->query_acl != NULL) {
   1327 		dns_acl_detach(&zone->query_acl);
   1328 	}
   1329 	if (zone->queryon_acl != NULL) {
   1330 		dns_acl_detach(&zone->queryon_acl);
   1331 	}
   1332 	if (zone->xfr_acl != NULL) {
   1333 		dns_acl_detach(&zone->xfr_acl);
   1334 	}
   1335 	if (dns_name_dynamic(&zone->origin)) {
   1336 		dns_name_free(&zone->origin, zone->mctx);
   1337 	}
   1338 	if (zone->strnamerd != NULL) {
   1339 		isc_mem_free(zone->mctx, zone->strnamerd);
   1340 	}
   1341 	if (zone->strname != NULL) {
   1342 		isc_mem_free(zone->mctx, zone->strname);
   1343 	}
   1344 	if (zone->strrdclass != NULL) {
   1345 		isc_mem_free(zone->mctx, zone->strrdclass);
   1346 	}
   1347 	if (zone->strviewname != NULL) {
   1348 		isc_mem_free(zone->mctx, zone->strviewname);
   1349 	}
   1350 	if (zone->ssutable != NULL) {
   1351 		dns_ssutable_detach(&zone->ssutable);
   1352 	}
   1353 	if (zone->gluecachestats != NULL) {
   1354 		isc_stats_detach(&zone->gluecachestats);
   1355 	}
   1356 
   1357 	/* last stuff */
   1358 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1359 	isc_mutex_destroy(&zone->lock);
   1360 	zone->magic = 0;
   1361 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1362 }
   1363 
   1364 /*
   1365  * Returns true iff this the signed side of an inline-signing zone.
   1366  * Caller should hold zone lock.
   1367  */
   1368 static inline bool
   1369 inline_secure(dns_zone_t *zone) {
   1370 	REQUIRE(DNS_ZONE_VALID(zone));
   1371 	if (zone->raw != NULL) {
   1372 		return (true);
   1373 	}
   1374 	return (false);
   1375 }
   1376 
   1377 /*
   1378  * Returns true iff this the unsigned side of an inline-signing zone
   1379  * Caller should hold zone lock.
   1380  */
   1381 static inline bool
   1382 inline_raw(dns_zone_t *zone) {
   1383 	REQUIRE(DNS_ZONE_VALID(zone));
   1384 	if (zone->secure != NULL) {
   1385 		return (true);
   1386 	}
   1387 	return (false);
   1388 }
   1389 
   1390 /*
   1391  *	Single shot.
   1392  */
   1393 void
   1394 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
   1395 	char namebuf[1024];
   1396 
   1397 	REQUIRE(DNS_ZONE_VALID(zone));
   1398 	REQUIRE(rdclass != dns_rdataclass_none);
   1399 
   1400 	/*
   1401 	 * Test and set.
   1402 	 */
   1403 	LOCK_ZONE(zone);
   1404 	INSIST(zone != zone->raw);
   1405 	REQUIRE(zone->rdclass == dns_rdataclass_none ||
   1406 		zone->rdclass == rdclass);
   1407 	zone->rdclass = rdclass;
   1408 
   1409 	if (zone->strnamerd != NULL) {
   1410 		isc_mem_free(zone->mctx, zone->strnamerd);
   1411 	}
   1412 	if (zone->strrdclass != NULL) {
   1413 		isc_mem_free(zone->mctx, zone->strrdclass);
   1414 	}
   1415 
   1416 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1417 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1418 	zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
   1419 	zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
   1420 
   1421 	if (inline_secure(zone)) {
   1422 		dns_zone_setclass(zone->raw, rdclass);
   1423 	}
   1424 	UNLOCK_ZONE(zone);
   1425 }
   1426 
   1427 dns_rdataclass_t
   1428 dns_zone_getclass(dns_zone_t *zone) {
   1429 	REQUIRE(DNS_ZONE_VALID(zone));
   1430 
   1431 	return (zone->rdclass);
   1432 }
   1433 
   1434 void
   1435 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
   1436 	REQUIRE(DNS_ZONE_VALID(zone));
   1437 
   1438 	LOCK_ZONE(zone);
   1439 	zone->notifytype = notifytype;
   1440 	UNLOCK_ZONE(zone);
   1441 }
   1442 
   1443 isc_result_t
   1444 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
   1445 	isc_result_t result;
   1446 	unsigned int soacount;
   1447 
   1448 	REQUIRE(DNS_ZONE_VALID(zone));
   1449 	REQUIRE(serialp != NULL);
   1450 
   1451 	LOCK_ZONE(zone);
   1452 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   1453 	if (zone->db != NULL) {
   1454 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
   1455 					  serialp, NULL, NULL, NULL, NULL,
   1456 					  NULL);
   1457 		if (result == ISC_R_SUCCESS && soacount == 0) {
   1458 			result = ISC_R_FAILURE;
   1459 		}
   1460 	} else {
   1461 		result = DNS_R_NOTLOADED;
   1462 	}
   1463 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   1464 	UNLOCK_ZONE(zone);
   1465 
   1466 	return (result);
   1467 }
   1468 
   1469 /*
   1470  *	Single shot.
   1471  */
   1472 void
   1473 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
   1474 	char namebuf[1024];
   1475 
   1476 	REQUIRE(DNS_ZONE_VALID(zone));
   1477 	REQUIRE(type != dns_zone_none);
   1478 
   1479 	/*
   1480 	 * Test and set.
   1481 	 */
   1482 	LOCK_ZONE(zone);
   1483 	REQUIRE(zone->type == dns_zone_none || zone->type == type);
   1484 	zone->type = type;
   1485 
   1486 	if (zone->strnamerd != NULL) {
   1487 		isc_mem_free(zone->mctx, zone->strnamerd);
   1488 	}
   1489 
   1490 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1491 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1492 	UNLOCK_ZONE(zone);
   1493 }
   1494 
   1495 static void
   1496 zone_freedbargs(dns_zone_t *zone) {
   1497 	unsigned int i;
   1498 
   1499 	/* Free the old database argument list. */
   1500 	if (zone->db_argv != NULL) {
   1501 		for (i = 0; i < zone->db_argc; i++) {
   1502 			isc_mem_free(zone->mctx, zone->db_argv[i]);
   1503 		}
   1504 		isc_mem_put(zone->mctx, zone->db_argv,
   1505 			    zone->db_argc * sizeof(*zone->db_argv));
   1506 	}
   1507 	zone->db_argc = 0;
   1508 	zone->db_argv = NULL;
   1509 }
   1510 
   1511 isc_result_t
   1512 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
   1513 	size_t size = 0;
   1514 	unsigned int i;
   1515 	isc_result_t result = ISC_R_SUCCESS;
   1516 	void *mem;
   1517 	char **tmp, *tmp2, *base;
   1518 
   1519 	REQUIRE(DNS_ZONE_VALID(zone));
   1520 	REQUIRE(argv != NULL && *argv == NULL);
   1521 
   1522 	LOCK_ZONE(zone);
   1523 	size = (zone->db_argc + 1) * sizeof(char *);
   1524 	for (i = 0; i < zone->db_argc; i++) {
   1525 		size += strlen(zone->db_argv[i]) + 1;
   1526 	}
   1527 	mem = isc_mem_allocate(mctx, size);
   1528 	{
   1529 		tmp = mem;
   1530 		tmp2 = mem;
   1531 		base = mem;
   1532 		tmp2 += (zone->db_argc + 1) * sizeof(char *);
   1533 		for (i = 0; i < zone->db_argc; i++) {
   1534 			*tmp++ = tmp2;
   1535 			strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
   1536 			tmp2 += strlen(tmp2) + 1;
   1537 		}
   1538 		*tmp = NULL;
   1539 	}
   1540 	UNLOCK_ZONE(zone);
   1541 	*argv = mem;
   1542 	return (result);
   1543 }
   1544 
   1545 void
   1546 dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc,
   1547 		   const char *const *dbargv) {
   1548 	char **argv = NULL;
   1549 	unsigned int i;
   1550 
   1551 	REQUIRE(DNS_ZONE_VALID(zone));
   1552 	REQUIRE(dbargc >= 1);
   1553 	REQUIRE(dbargv != NULL);
   1554 
   1555 	LOCK_ZONE(zone);
   1556 
   1557 	/* Set up a new database argument list. */
   1558 	argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv));
   1559 	for (i = 0; i < dbargc; i++) {
   1560 		argv[i] = NULL;
   1561 	}
   1562 	for (i = 0; i < dbargc; i++) {
   1563 		argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
   1564 	}
   1565 
   1566 	/* Free the old list. */
   1567 	zone_freedbargs(zone);
   1568 
   1569 	zone->db_argc = dbargc;
   1570 	zone->db_argv = argv;
   1571 
   1572 	UNLOCK_ZONE(zone);
   1573 }
   1574 
   1575 static void
   1576 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
   1577 	char namebuf[1024];
   1578 
   1579 	if (zone->prev_view == NULL && zone->view != NULL) {
   1580 		dns_view_weakattach(zone->view, &zone->prev_view);
   1581 	}
   1582 
   1583 	INSIST(zone != zone->raw);
   1584 	if (zone->view != NULL) {
   1585 		dns_view_weakdetach(&zone->view);
   1586 	}
   1587 	dns_view_weakattach(view, &zone->view);
   1588 
   1589 	if (zone->strviewname != NULL) {
   1590 		isc_mem_free(zone->mctx, zone->strviewname);
   1591 	}
   1592 	if (zone->strnamerd != NULL) {
   1593 		isc_mem_free(zone->mctx, zone->strnamerd);
   1594 	}
   1595 
   1596 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1597 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1598 	zone_viewname_tostr(zone, namebuf, sizeof namebuf);
   1599 	zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
   1600 
   1601 	if (inline_secure(zone)) {
   1602 		dns_zone_setview(zone->raw, view);
   1603 	}
   1604 }
   1605 
   1606 void
   1607 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
   1608 	REQUIRE(DNS_ZONE_VALID(zone));
   1609 
   1610 	LOCK_ZONE(zone);
   1611 	dns_zone_setview_helper(zone, view);
   1612 	UNLOCK_ZONE(zone);
   1613 }
   1614 
   1615 dns_view_t *
   1616 dns_zone_getview(dns_zone_t *zone) {
   1617 	REQUIRE(DNS_ZONE_VALID(zone));
   1618 
   1619 	return (zone->view);
   1620 }
   1621 
   1622 void
   1623 dns_zone_setviewcommit(dns_zone_t *zone) {
   1624 	REQUIRE(DNS_ZONE_VALID(zone));
   1625 
   1626 	LOCK_ZONE(zone);
   1627 	if (zone->prev_view != NULL) {
   1628 		dns_view_weakdetach(&zone->prev_view);
   1629 	}
   1630 	if (inline_secure(zone)) {
   1631 		dns_zone_setviewcommit(zone->raw);
   1632 	}
   1633 	UNLOCK_ZONE(zone);
   1634 }
   1635 
   1636 void
   1637 dns_zone_setviewrevert(dns_zone_t *zone) {
   1638 	REQUIRE(DNS_ZONE_VALID(zone));
   1639 
   1640 	LOCK_ZONE(zone);
   1641 	if (zone->prev_view != NULL) {
   1642 		dns_zone_setview_helper(zone, zone->prev_view);
   1643 		dns_view_weakdetach(&zone->prev_view);
   1644 	}
   1645 	if (inline_secure(zone)) {
   1646 		dns_zone_setviewrevert(zone->raw);
   1647 	}
   1648 	UNLOCK_ZONE(zone);
   1649 }
   1650 
   1651 isc_result_t
   1652 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
   1653 	isc_result_t result = ISC_R_SUCCESS;
   1654 	char namebuf[1024];
   1655 
   1656 	REQUIRE(DNS_ZONE_VALID(zone));
   1657 	REQUIRE(origin != NULL);
   1658 
   1659 	LOCK_ZONE(zone);
   1660 	INSIST(zone != zone->raw);
   1661 	if (dns_name_dynamic(&zone->origin)) {
   1662 		dns_name_free(&zone->origin, zone->mctx);
   1663 		dns_name_init(&zone->origin, NULL);
   1664 	}
   1665 	dns_name_dup(origin, zone->mctx, &zone->origin);
   1666 
   1667 	if (zone->strnamerd != NULL) {
   1668 		isc_mem_free(zone->mctx, zone->strnamerd);
   1669 	}
   1670 	if (zone->strname != NULL) {
   1671 		isc_mem_free(zone->mctx, zone->strname);
   1672 	}
   1673 
   1674 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1675 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1676 	zone_name_tostr(zone, namebuf, sizeof namebuf);
   1677 	zone->strname = isc_mem_strdup(zone->mctx, namebuf);
   1678 
   1679 	if (inline_secure(zone)) {
   1680 		result = dns_zone_setorigin(zone->raw, origin);
   1681 	}
   1682 	UNLOCK_ZONE(zone);
   1683 	return (result);
   1684 }
   1685 
   1686 static isc_result_t
   1687 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
   1688 	char *copy;
   1689 
   1690 	if (value != NULL) {
   1691 		copy = isc_mem_strdup(zone->mctx, value);
   1692 	} else {
   1693 		copy = NULL;
   1694 	}
   1695 
   1696 	if (*field != NULL) {
   1697 		isc_mem_free(zone->mctx, *field);
   1698 	}
   1699 
   1700 	*field = copy;
   1701 	return (ISC_R_SUCCESS);
   1702 }
   1703 
   1704 isc_result_t
   1705 dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format,
   1706 		 const dns_master_style_t *style) {
   1707 	isc_result_t result = ISC_R_SUCCESS;
   1708 
   1709 	REQUIRE(DNS_ZONE_VALID(zone));
   1710 
   1711 	LOCK_ZONE(zone);
   1712 	result = dns_zone_setstring(zone, &zone->masterfile, file);
   1713 	if (result == ISC_R_SUCCESS) {
   1714 		zone->masterformat = format;
   1715 		if (format == dns_masterformat_text) {
   1716 			zone->masterstyle = style;
   1717 		}
   1718 		result = default_journal(zone);
   1719 	}
   1720 	UNLOCK_ZONE(zone);
   1721 
   1722 	return (result);
   1723 }
   1724 
   1725 const char *
   1726 dns_zone_getfile(dns_zone_t *zone) {
   1727 	REQUIRE(DNS_ZONE_VALID(zone));
   1728 
   1729 	return (zone->masterfile);
   1730 }
   1731 
   1732 dns_ttl_t
   1733 dns_zone_getmaxttl(dns_zone_t *zone) {
   1734 	REQUIRE(DNS_ZONE_VALID(zone));
   1735 
   1736 	return (zone->maxttl);
   1737 }
   1738 
   1739 void
   1740 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
   1741 	REQUIRE(DNS_ZONE_VALID(zone));
   1742 
   1743 	LOCK_ZONE(zone);
   1744 	if (maxttl != 0) {
   1745 		DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1746 	} else {
   1747 		DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1748 	}
   1749 	zone->maxttl = maxttl;
   1750 	UNLOCK_ZONE(zone);
   1751 
   1752 	return;
   1753 }
   1754 
   1755 static isc_result_t
   1756 default_journal(dns_zone_t *zone) {
   1757 	isc_result_t result;
   1758 	char *journal;
   1759 
   1760 	REQUIRE(DNS_ZONE_VALID(zone));
   1761 	REQUIRE(LOCKED_ZONE(zone));
   1762 
   1763 	if (zone->masterfile != NULL) {
   1764 		/* Calculate string length including '\0'. */
   1765 		int len = strlen(zone->masterfile) + sizeof(".jnl");
   1766 		journal = isc_mem_allocate(zone->mctx, len);
   1767 		strlcpy(journal, zone->masterfile, len);
   1768 		strlcat(journal, ".jnl", len);
   1769 	} else {
   1770 		journal = NULL;
   1771 	}
   1772 	result = dns_zone_setstring(zone, &zone->journal, journal);
   1773 	if (journal != NULL) {
   1774 		isc_mem_free(zone->mctx, journal);
   1775 	}
   1776 	return (result);
   1777 }
   1778 
   1779 isc_result_t
   1780 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
   1781 	isc_result_t result = ISC_R_SUCCESS;
   1782 
   1783 	REQUIRE(DNS_ZONE_VALID(zone));
   1784 
   1785 	LOCK_ZONE(zone);
   1786 	result = dns_zone_setstring(zone, &zone->journal, myjournal);
   1787 	UNLOCK_ZONE(zone);
   1788 
   1789 	return (result);
   1790 }
   1791 
   1792 char *
   1793 dns_zone_getjournal(dns_zone_t *zone) {
   1794 	REQUIRE(DNS_ZONE_VALID(zone));
   1795 
   1796 	return (zone->journal);
   1797 }
   1798 
   1799 /*
   1800  * Return true iff the zone is "dynamic", in the sense that the zone's
   1801  * master file (if any) is written by the server, rather than being
   1802  * updated manually and read by the server.
   1803  *
   1804  * This is true for slave zones, mirror zones, stub zones, key zones,
   1805  * and zones that allow dynamic updates either by having an update
   1806  * policy ("ssutable") or an "allow-update" ACL with a value other than
   1807  * exactly "{ none; }".
   1808  */
   1809 bool
   1810 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
   1811 	REQUIRE(DNS_ZONE_VALID(zone));
   1812 
   1813 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   1814 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   1815 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   1816 	{
   1817 		return (true);
   1818 	}
   1819 
   1820 	/* Inline zones are always dynamic. */
   1821 	if (zone->type == dns_zone_master && zone->raw != NULL) {
   1822 		return (true);
   1823 	}
   1824 
   1825 	/* If !ignore_freeze, we need check whether updates are disabled.  */
   1826 	if (zone->type == dns_zone_master &&
   1827 	    (!zone->update_disabled || ignore_freeze) &&
   1828 	    ((zone->ssutable != NULL) ||
   1829 	     (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
   1830 	{
   1831 		return (true);
   1832 	}
   1833 
   1834 	return (false);
   1835 }
   1836 
   1837 /*
   1838  * Set the response policy index and information for a zone.
   1839  */
   1840 isc_result_t
   1841 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
   1842 		    dns_rpz_num_t rpz_num) {
   1843 	/*
   1844 	 * Only RBTDB zones can be used for response policy zones,
   1845 	 * because only they have the code to create the summary data.
   1846 	 * Only zones that are loaded instead of mmap()ed create the
   1847 	 * summary data and so can be policy zones.
   1848 	 */
   1849 	if (strcmp(zone->db_argv[0], "rbt") != 0 &&
   1850 	    strcmp(zone->db_argv[0], "rbt64") != 0)
   1851 	{
   1852 		return (ISC_R_NOTIMPLEMENTED);
   1853 	}
   1854 	if (zone->masterformat == dns_masterformat_map) {
   1855 		return (ISC_R_NOTIMPLEMENTED);
   1856 	}
   1857 
   1858 	/*
   1859 	 * This must happen only once or be redundant.
   1860 	 */
   1861 	LOCK_ZONE(zone);
   1862 	if (zone->rpzs != NULL) {
   1863 		REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
   1864 	} else {
   1865 		REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
   1866 		dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
   1867 		zone->rpz_num = rpz_num;
   1868 	}
   1869 	rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
   1870 	UNLOCK_ZONE(zone);
   1871 
   1872 	return (ISC_R_SUCCESS);
   1873 }
   1874 
   1875 dns_rpz_num_t
   1876 dns_zone_get_rpz_num(dns_zone_t *zone) {
   1877 	return (zone->rpz_num);
   1878 }
   1879 
   1880 /*
   1881  * If a zone is a response policy zone, mark its new database.
   1882  */
   1883 void
   1884 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1885 	isc_result_t result;
   1886 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1887 		return;
   1888 	}
   1889 	REQUIRE(zone->rpzs != NULL);
   1890 	result = dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback,
   1891 					      zone->rpzs->zones[zone->rpz_num]);
   1892 	REQUIRE(result == ISC_R_SUCCESS);
   1893 }
   1894 
   1895 static void
   1896 dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1897 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1898 		return;
   1899 	}
   1900 	REQUIRE(zone->rpzs != NULL);
   1901 	(void)dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback,
   1902 					     zone->rpzs->zones[zone->rpz_num]);
   1903 }
   1904 
   1905 void
   1906 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
   1907 	REQUIRE(DNS_ZONE_VALID(zone));
   1908 	REQUIRE(catzs != NULL);
   1909 
   1910 	LOCK_ZONE(zone);
   1911 	INSIST(zone->catzs == NULL || zone->catzs == catzs);
   1912 	dns_catz_catzs_set_view(catzs, zone->view);
   1913 	if (zone->catzs == NULL) {
   1914 		dns_catz_catzs_attach(catzs, &zone->catzs);
   1915 	}
   1916 	UNLOCK_ZONE(zone);
   1917 }
   1918 
   1919 /*
   1920  * If a zone is a catalog zone, attach it to update notification in database.
   1921  */
   1922 void
   1923 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1924 	REQUIRE(DNS_ZONE_VALID(zone));
   1925 	REQUIRE(db != NULL);
   1926 
   1927 	if (zone->catzs != NULL) {
   1928 		dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
   1929 					     zone->catzs);
   1930 	}
   1931 }
   1932 
   1933 static void
   1934 dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1935 	REQUIRE(DNS_ZONE_VALID(zone));
   1936 	REQUIRE(db != NULL);
   1937 
   1938 	if (zone->catzs != NULL) {
   1939 		dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback,
   1940 					       zone->catzs);
   1941 	}
   1942 }
   1943 
   1944 /*
   1945  * Set catalog zone ownership of the zone
   1946  */
   1947 void
   1948 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) {
   1949 	REQUIRE(DNS_ZONE_VALID(zone));
   1950 	REQUIRE(catz != NULL);
   1951 	LOCK_ZONE(zone);
   1952 	INSIST(zone->parentcatz == NULL || zone->parentcatz == catz);
   1953 	zone->parentcatz = catz;
   1954 	UNLOCK_ZONE(zone);
   1955 }
   1956 
   1957 dns_catz_zone_t *
   1958 dns_zone_get_parentcatz(const dns_zone_t *zone) {
   1959 	REQUIRE(DNS_ZONE_VALID(zone));
   1960 	return (zone->parentcatz);
   1961 }
   1962 
   1963 static bool
   1964 zone_touched(dns_zone_t *zone) {
   1965 	isc_result_t result;
   1966 	isc_time_t modtime;
   1967 	dns_include_t *include;
   1968 
   1969 	REQUIRE(DNS_ZONE_VALID(zone));
   1970 
   1971 	result = isc_file_getmodtime(zone->masterfile, &modtime);
   1972 	if (result != ISC_R_SUCCESS ||
   1973 	    isc_time_compare(&modtime, &zone->loadtime) > 0) {
   1974 		return (true);
   1975 	}
   1976 
   1977 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   1978 	     include = ISC_LIST_NEXT(include, link))
   1979 	{
   1980 		result = isc_file_getmodtime(include->name, &modtime);
   1981 		if (result != ISC_R_SUCCESS ||
   1982 		    isc_time_compare(&modtime, &include->filetime) > 0)
   1983 		{
   1984 			return (true);
   1985 		}
   1986 	}
   1987 
   1988 	return (false);
   1989 }
   1990 
   1991 /*
   1992  * Note: when dealing with inline-signed zones, external callers will always
   1993  * call zone_load() for the secure zone; zone_load() calls itself recursively
   1994  * in order to load the raw zone.
   1995  */
   1996 static isc_result_t
   1997 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
   1998 	isc_result_t result;
   1999 	isc_time_t now;
   2000 	isc_time_t loadtime;
   2001 	dns_db_t *db = NULL;
   2002 	bool rbt, hasraw, is_dynamic;
   2003 
   2004 	REQUIRE(DNS_ZONE_VALID(zone));
   2005 
   2006 	if (!locked) {
   2007 		LOCK_ZONE(zone);
   2008 	}
   2009 
   2010 	INSIST(zone != zone->raw);
   2011 	hasraw = inline_secure(zone);
   2012 	if (hasraw) {
   2013 		/*
   2014 		 * We are trying to load an inline-signed zone.  First call
   2015 		 * self recursively to try loading the raw version of the zone.
   2016 		 * Assuming the raw zone file is readable, there are two
   2017 		 * possibilities:
   2018 		 *
   2019 		 *  a) the raw zone was not yet loaded and thus it will be
   2020 		 *     loaded now, synchronously; if this succeeds, a
   2021 		 *     subsequent attempt to load the signed zone file will
   2022 		 *     take place and thus zone_postload() will be called
   2023 		 *     twice: first for the raw zone and then for the secure
   2024 		 *     zone; the latter call will take care of syncing the raw
   2025 		 *     version with the secure version,
   2026 		 *
   2027 		 *  b) the raw zone was already loaded and we are trying to
   2028 		 *     reload it, which will happen asynchronously; this means
   2029 		 *     zone_postload() will only be called for the raw zone
   2030 		 *     because "result" returned by the zone_load() call below
   2031 		 *     will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE;
   2032 		 *     zone_postload() called for the raw zone will take care
   2033 		 *     of syncing the raw version with the secure version.
   2034 		 */
   2035 		result = zone_load(zone->raw, flags, false);
   2036 		if (result != ISC_R_SUCCESS) {
   2037 			if (!locked) {
   2038 				UNLOCK_ZONE(zone);
   2039 			}
   2040 			return (result);
   2041 		}
   2042 		LOCK_ZONE(zone->raw);
   2043 	}
   2044 
   2045 	TIME_NOW(&now);
   2046 
   2047 	INSIST(zone->type != dns_zone_none);
   2048 
   2049 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
   2050 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2051 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2052 		}
   2053 		result = DNS_R_CONTINUE;
   2054 		goto cleanup;
   2055 	}
   2056 
   2057 	INSIST(zone->db_argc >= 1);
   2058 
   2059 	rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
   2060 	      strcmp(zone->db_argv[0], "rbt64") == 0;
   2061 
   2062 	if (zone->db != NULL && zone->masterfile == NULL && rbt) {
   2063 		/*
   2064 		 * The zone has no master file configured.
   2065 		 */
   2066 		result = ISC_R_SUCCESS;
   2067 		goto cleanup;
   2068 	}
   2069 
   2070 	is_dynamic = dns_zone_isdynamic(zone, false);
   2071 	if (zone->db != NULL && is_dynamic) {
   2072 		/*
   2073 		 * This is a slave, stub, or dynamically updated zone being
   2074 		 * reloaded.  Do nothing - the database we already
   2075 		 * have is guaranteed to be up-to-date.
   2076 		 */
   2077 		if (zone->type == dns_zone_master && !hasraw) {
   2078 			result = DNS_R_DYNAMIC;
   2079 		} else {
   2080 			result = ISC_R_SUCCESS;
   2081 		}
   2082 		goto cleanup;
   2083 	}
   2084 
   2085 	/*
   2086 	 * Store the current time before the zone is loaded, so that if the
   2087 	 * file changes between the time of the load and the time that
   2088 	 * zone->loadtime is set, then the file will still be reloaded
   2089 	 * the next time dns_zone_load is called.
   2090 	 */
   2091 	TIME_NOW(&loadtime);
   2092 
   2093 	/*
   2094 	 * Don't do the load if the file that stores the zone is older
   2095 	 * than the last time the zone was loaded.  If the zone has not
   2096 	 * been loaded yet, zone->loadtime will be the epoch.
   2097 	 */
   2098 	if (zone->masterfile != NULL) {
   2099 		isc_time_t filetime;
   2100 
   2101 		/*
   2102 		 * The file is already loaded.	If we are just doing a
   2103 		 * "rndc reconfig", we are done.
   2104 		 */
   2105 		if (!isc_time_isepoch(&zone->loadtime) &&
   2106 		    (flags & DNS_ZONELOADFLAG_NOSTAT) != 0)
   2107 		{
   2108 			result = ISC_R_SUCCESS;
   2109 			goto cleanup;
   2110 		}
   2111 
   2112 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   2113 		    !zone_touched(zone)) {
   2114 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2115 				      ISC_LOG_DEBUG(1),
   2116 				      "skipping load: master file "
   2117 				      "older than last load");
   2118 			result = DNS_R_UPTODATE;
   2119 			goto cleanup;
   2120 		}
   2121 
   2122 		/*
   2123 		 * If the file modification time is in the past
   2124 		 * set loadtime to that value.
   2125 		 */
   2126 		result = isc_file_getmodtime(zone->masterfile, &filetime);
   2127 		if (result == ISC_R_SUCCESS &&
   2128 		    isc_time_compare(&loadtime, &filetime) > 0) {
   2129 			loadtime = filetime;
   2130 		}
   2131 	}
   2132 
   2133 	/*
   2134 	 * Built in zones (with the exception of empty zones) don't need
   2135 	 * to be reloaded.
   2136 	 */
   2137 	if (zone->type == dns_zone_master &&
   2138 	    strcmp(zone->db_argv[0], "_builtin") == 0 &&
   2139 	    (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
   2140 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   2141 	{
   2142 		result = ISC_R_SUCCESS;
   2143 		goto cleanup;
   2144 	}
   2145 
   2146 	/*
   2147 	 * Zones associated with a DLZ don't need to be loaded either,
   2148 	 * but we need to associate the database with the zone object.
   2149 	 */
   2150 	if (strcmp(zone->db_argv[0], "dlz") == 0) {
   2151 		dns_dlzdb_t *dlzdb;
   2152 		dns_dlzfindzone_t findzone;
   2153 
   2154 		for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
   2155 		     dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link))
   2156 		{
   2157 			INSIST(DNS_DLZ_VALID(dlzdb));
   2158 			if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) {
   2159 				break;
   2160 			}
   2161 		}
   2162 
   2163 		if (dlzdb == NULL) {
   2164 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2165 				      ISC_LOG_ERROR,
   2166 				      "DLZ %s does not exist or is set "
   2167 				      "to 'search yes;'",
   2168 				      zone->db_argv[1]);
   2169 			result = ISC_R_NOTFOUND;
   2170 			goto cleanup;
   2171 		}
   2172 
   2173 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   2174 		/* ask SDLZ driver if the zone is supported */
   2175 		findzone = dlzdb->implementation->methods->findzone;
   2176 		result = (*findzone)(dlzdb->implementation->driverarg,
   2177 				     dlzdb->dbdata, dlzdb->mctx,
   2178 				     zone->view->rdclass, &zone->origin, NULL,
   2179 				     NULL, &db);
   2180 		if (result != ISC_R_NOTFOUND) {
   2181 			if (zone->db != NULL) {
   2182 				zone_detachdb(zone);
   2183 			}
   2184 			zone_attachdb(zone, db);
   2185 			dns_db_detach(&db);
   2186 			result = ISC_R_SUCCESS;
   2187 		}
   2188 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   2189 
   2190 		if (result == ISC_R_SUCCESS) {
   2191 			if (dlzdb->configure_callback == NULL) {
   2192 				goto cleanup;
   2193 			}
   2194 
   2195 			result = (*dlzdb->configure_callback)(zone->view, dlzdb,
   2196 							      zone);
   2197 			if (result != ISC_R_SUCCESS) {
   2198 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2199 					      ISC_LOG_ERROR,
   2200 					      "DLZ configuration callback: %s",
   2201 					      isc_result_totext(result));
   2202 			}
   2203 		}
   2204 		goto cleanup;
   2205 	}
   2206 
   2207 	if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   2208 	     zone->type == dns_zone_stub ||
   2209 	     (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
   2210 	    rbt)
   2211 	{
   2212 		if (zone->masterfile == NULL ||
   2213 		    !isc_file_exists(zone->masterfile)) {
   2214 			if (zone->masterfile != NULL) {
   2215 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2216 					      ISC_LOG_DEBUG(1),
   2217 					      "no master file");
   2218 			}
   2219 			zone->refreshtime = now;
   2220 			if (zone->task != NULL) {
   2221 				zone_settimer(zone, &now);
   2222 			}
   2223 			result = ISC_R_SUCCESS;
   2224 			goto cleanup;
   2225 		}
   2226 	}
   2227 
   2228 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   2229 		      "starting load");
   2230 
   2231 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   2232 			       (zone->type == dns_zone_stub) ? dns_dbtype_stub
   2233 							     : dns_dbtype_zone,
   2234 			       zone->rdclass, zone->db_argc - 1,
   2235 			       zone->db_argv + 1, &db);
   2236 
   2237 	if (result != ISC_R_SUCCESS) {
   2238 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   2239 			      "loading zone: creating database: %s",
   2240 			      isc_result_totext(result));
   2241 		goto cleanup;
   2242 	}
   2243 	dns_db_settask(db, zone->task);
   2244 
   2245 	if (zone->type == dns_zone_master || zone->type == dns_zone_slave ||
   2246 	    zone->type == dns_zone_mirror)
   2247 	{
   2248 		result = dns_db_setgluecachestats(db, zone->gluecachestats);
   2249 		if (result == ISC_R_NOTIMPLEMENTED) {
   2250 			result = ISC_R_SUCCESS;
   2251 		}
   2252 		if (result != ISC_R_SUCCESS) {
   2253 			goto cleanup;
   2254 		}
   2255 	}
   2256 
   2257 	if (!dns_db_ispersistent(db)) {
   2258 		if (zone->masterfile != NULL) {
   2259 			result = zone_startload(db, zone, loadtime);
   2260 		} else {
   2261 			result = DNS_R_NOMASTERFILE;
   2262 			if (zone->type == dns_zone_master ||
   2263 			    (zone->type == dns_zone_redirect &&
   2264 			     zone->masters == NULL))
   2265 			{
   2266 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2267 					      ISC_LOG_ERROR,
   2268 					      "loading zone: "
   2269 					      "no master file configured");
   2270 				goto cleanup;
   2271 			}
   2272 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2273 				      ISC_LOG_INFO,
   2274 				      "loading zone: "
   2275 				      "no master file configured: continuing");
   2276 		}
   2277 	}
   2278 
   2279 	if (result == DNS_R_CONTINUE) {
   2280 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
   2281 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2282 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2283 		}
   2284 		goto cleanup;
   2285 	}
   2286 
   2287 	result = zone_postload(zone, db, loadtime, result);
   2288 
   2289 cleanup:
   2290 	if (hasraw) {
   2291 		UNLOCK_ZONE(zone->raw);
   2292 	}
   2293 	if (!locked) {
   2294 		UNLOCK_ZONE(zone);
   2295 	}
   2296 	if (db != NULL) {
   2297 		dns_db_detach(&db);
   2298 	}
   2299 	return (result);
   2300 }
   2301 
   2302 isc_result_t
   2303 dns_zone_load(dns_zone_t *zone, bool newonly) {
   2304 	return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
   2305 }
   2306 
   2307 static void
   2308 zone_asyncload(isc_task_t *task, isc_event_t *event) {
   2309 	dns_asyncload_t *asl = event->ev_arg;
   2310 	dns_zone_t *zone = asl->zone;
   2311 	isc_result_t result;
   2312 
   2313 	UNUSED(task);
   2314 
   2315 	REQUIRE(DNS_ZONE_VALID(zone));
   2316 
   2317 	isc_event_free(&event);
   2318 
   2319 	LOCK_ZONE(zone);
   2320 	result = zone_load(zone, asl->flags, true);
   2321 	if (result != DNS_R_CONTINUE) {
   2322 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2323 	}
   2324 	UNLOCK_ZONE(zone);
   2325 
   2326 	/* Inform the zone table we've finished loading */
   2327 	if (asl->loaded != NULL) {
   2328 		(asl->loaded)(asl->loaded_arg, zone, task);
   2329 	}
   2330 
   2331 	isc_mem_put(zone->mctx, asl, sizeof(*asl));
   2332 	dns_zone_idetach(&zone);
   2333 }
   2334 
   2335 isc_result_t
   2336 dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_zoneloaded_t done,
   2337 		   void *arg) {
   2338 	isc_event_t *e;
   2339 	dns_asyncload_t *asl = NULL;
   2340 
   2341 	REQUIRE(DNS_ZONE_VALID(zone));
   2342 
   2343 	if (zone->zmgr == NULL) {
   2344 		return (ISC_R_FAILURE);
   2345 	}
   2346 
   2347 	/* If we already have a load pending, stop now */
   2348 	LOCK_ZONE(zone);
   2349 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) {
   2350 		UNLOCK_ZONE(zone);
   2351 		return (ISC_R_ALREADYRUNNING);
   2352 	}
   2353 
   2354 	asl = isc_mem_get(zone->mctx, sizeof(*asl));
   2355 
   2356 	asl->zone = NULL;
   2357 	asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
   2358 	asl->loaded = done;
   2359 	asl->loaded_arg = arg;
   2360 
   2361 	e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, DNS_EVENT_ZONELOAD,
   2362 			       zone_asyncload, asl, sizeof(isc_event_t));
   2363 
   2364 	zone_iattach(zone, &asl->zone);
   2365 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2366 	isc_task_send(zone->loadtask, &e);
   2367 	UNLOCK_ZONE(zone);
   2368 
   2369 	return (ISC_R_SUCCESS);
   2370 }
   2371 
   2372 bool
   2373 dns__zone_loadpending(dns_zone_t *zone) {
   2374 	REQUIRE(DNS_ZONE_VALID(zone));
   2375 
   2376 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
   2377 }
   2378 
   2379 isc_result_t
   2380 dns_zone_loadandthaw(dns_zone_t *zone) {
   2381 	isc_result_t result;
   2382 
   2383 	if (inline_raw(zone)) {
   2384 		result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false);
   2385 	} else {
   2386 		/*
   2387 		 * When thawing a zone, we don't know what changes
   2388 		 * have been made. If we do DNSSEC maintenance on this
   2389 		 * zone, schedule a full sign for this zone.
   2390 		 */
   2391 		if (zone->type == dns_zone_master &&
   2392 		    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   2393 		{
   2394 			DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN);
   2395 		}
   2396 		result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false);
   2397 	}
   2398 
   2399 	switch (result) {
   2400 	case DNS_R_CONTINUE:
   2401 		/* Deferred thaw. */
   2402 		break;
   2403 	case DNS_R_UPTODATE:
   2404 	case ISC_R_SUCCESS:
   2405 	case DNS_R_SEENINCLUDE:
   2406 		zone->update_disabled = false;
   2407 		break;
   2408 	case DNS_R_NOMASTERFILE:
   2409 		zone->update_disabled = false;
   2410 		break;
   2411 	default:
   2412 		/* Error, remain in disabled state. */
   2413 		break;
   2414 	}
   2415 	return (result);
   2416 }
   2417 
   2418 static unsigned int
   2419 get_master_options(dns_zone_t *zone) {
   2420 	unsigned int options;
   2421 
   2422 	options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
   2423 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   2424 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   2425 	{
   2426 		options |= DNS_MASTER_SLAVE;
   2427 	}
   2428 	if (zone->type == dns_zone_key) {
   2429 		options |= DNS_MASTER_KEY;
   2430 	}
   2431 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
   2432 		options |= DNS_MASTER_CHECKNS;
   2433 	}
   2434 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
   2435 		options |= DNS_MASTER_FATALNS;
   2436 	}
   2437 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
   2438 		options |= DNS_MASTER_CHECKNAMES;
   2439 	}
   2440 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
   2441 		options |= DNS_MASTER_CHECKNAMESFAIL;
   2442 	}
   2443 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
   2444 		options |= DNS_MASTER_CHECKMX;
   2445 	}
   2446 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2447 		options |= DNS_MASTER_CHECKMXFAIL;
   2448 	}
   2449 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
   2450 		options |= DNS_MASTER_CHECKWILDCARD;
   2451 	}
   2452 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
   2453 		options |= DNS_MASTER_CHECKTTL;
   2454 	}
   2455 
   2456 	return (options);
   2457 }
   2458 
   2459 static void
   2460 zone_registerinclude(const char *filename, void *arg) {
   2461 	isc_result_t result;
   2462 	dns_zone_t *zone = (dns_zone_t *)arg;
   2463 	dns_include_t *inc = NULL;
   2464 
   2465 	REQUIRE(DNS_ZONE_VALID(zone));
   2466 
   2467 	if (filename == NULL) {
   2468 		return;
   2469 	}
   2470 
   2471 	/*
   2472 	 * Suppress duplicates.
   2473 	 */
   2474 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   2475 	     inc = ISC_LIST_NEXT(inc, link))
   2476 	{
   2477 		if (strcmp(filename, inc->name) == 0) {
   2478 			return;
   2479 		}
   2480 	}
   2481 
   2482 	inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
   2483 	inc->name = isc_mem_strdup(zone->mctx, filename);
   2484 	ISC_LINK_INIT(inc, link);
   2485 
   2486 	result = isc_file_getmodtime(filename, &inc->filetime);
   2487 	if (result != ISC_R_SUCCESS) {
   2488 		isc_time_settoepoch(&inc->filetime);
   2489 	}
   2490 
   2491 	ISC_LIST_APPEND(zone->newincludes, inc, link);
   2492 }
   2493 
   2494 static void
   2495 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
   2496 	dns_load_t *load = event->ev_arg;
   2497 	isc_result_t result = ISC_R_SUCCESS;
   2498 	unsigned int options;
   2499 
   2500 	REQUIRE(DNS_LOAD_VALID(load));
   2501 
   2502 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2503 		result = ISC_R_CANCELED;
   2504 	}
   2505 	isc_event_free(&event);
   2506 	if (result == ISC_R_CANCELED) {
   2507 		goto fail;
   2508 	}
   2509 
   2510 	options = get_master_options(load->zone);
   2511 
   2512 	result = dns_master_loadfileinc(
   2513 		load->zone->masterfile, dns_db_origin(load->db),
   2514 		dns_db_origin(load->db), load->zone->rdclass, options, 0,
   2515 		&load->callbacks, task, zone_loaddone, load, &load->zone->lctx,
   2516 		zone_registerinclude, load->zone, load->zone->mctx,
   2517 		load->zone->masterformat, load->zone->maxttl);
   2518 	if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
   2519 	    result != DNS_R_SEENINCLUDE)
   2520 	{
   2521 		goto fail;
   2522 	}
   2523 	return;
   2524 
   2525 fail:
   2526 	zone_loaddone(load, result);
   2527 }
   2528 
   2529 static void
   2530 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
   2531 	isc_result_t result;
   2532 	unsigned int soacount;
   2533 
   2534 	LOCK(&raw->lock);
   2535 	if (raw->db != NULL) {
   2536 		result = zone_get_from_db(raw, raw->db, NULL, &soacount,
   2537 					  &rawdata->sourceserial, NULL, NULL,
   2538 					  NULL, NULL, NULL);
   2539 		if (result == ISC_R_SUCCESS && soacount > 0U) {
   2540 			rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
   2541 		}
   2542 	}
   2543 	UNLOCK(&raw->lock);
   2544 }
   2545 
   2546 static void
   2547 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
   2548 	const char me[] = "zone_gotwritehandle";
   2549 	dns_zone_t *zone = event->ev_arg;
   2550 	isc_result_t result = ISC_R_SUCCESS;
   2551 	dns_dbversion_t *version = NULL;
   2552 	dns_masterrawheader_t rawdata;
   2553 	dns_db_t *db = NULL;
   2554 
   2555 	REQUIRE(DNS_ZONE_VALID(zone));
   2556 	INSIST(task == zone->task);
   2557 	ENTER;
   2558 
   2559 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2560 		result = ISC_R_CANCELED;
   2561 	}
   2562 	isc_event_free(&event);
   2563 	if (result == ISC_R_CANCELED) {
   2564 		goto fail;
   2565 	}
   2566 
   2567 	LOCK_ZONE(zone);
   2568 	INSIST(zone != zone->raw);
   2569 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   2570 	if (zone->db != NULL) {
   2571 		dns_db_attach(zone->db, &db);
   2572 	}
   2573 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   2574 	if (db != NULL) {
   2575 		const dns_master_style_t *output_style;
   2576 		dns_db_currentversion(db, &version);
   2577 		dns_master_initrawheader(&rawdata);
   2578 		if (inline_secure(zone)) {
   2579 			get_raw_serial(zone->raw, &rawdata);
   2580 		}
   2581 		if (zone->type == dns_zone_key) {
   2582 			output_style = &dns_master_style_keyzone;
   2583 		} else if (zone->masterstyle != NULL) {
   2584 			output_style = zone->masterstyle;
   2585 		} else {
   2586 			output_style = &dns_master_style_default;
   2587 		}
   2588 		result = dns_master_dumpinc(
   2589 			zone->mctx, db, version, output_style, zone->masterfile,
   2590 			zone->task, dump_done, zone, &zone->dctx,
   2591 			zone->masterformat, &rawdata);
   2592 		dns_db_closeversion(db, &version, false);
   2593 	} else {
   2594 		result = ISC_R_CANCELED;
   2595 	}
   2596 	if (db != NULL) {
   2597 		dns_db_detach(&db);
   2598 	}
   2599 	UNLOCK_ZONE(zone);
   2600 	if (result != DNS_R_CONTINUE) {
   2601 		goto fail;
   2602 	}
   2603 	return;
   2604 
   2605 fail:
   2606 	dump_done(zone, result);
   2607 }
   2608 
   2609 /*
   2610  * Save the raw serial number for inline-signing zones.
   2611  * (XXX: Other information from the header will be used
   2612  * for other purposes in the future, but for now this is
   2613  * all we're interested in.)
   2614  */
   2615 static void
   2616 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2617 	if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) {
   2618 		return;
   2619 	}
   2620 
   2621 	zone->sourceserial = header->sourceserial;
   2622 	zone->sourceserialset = true;
   2623 }
   2624 
   2625 void
   2626 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2627 	if (zone == NULL) {
   2628 		return;
   2629 	}
   2630 
   2631 	LOCK_ZONE(zone);
   2632 	zone_setrawdata(zone, header);
   2633 	UNLOCK_ZONE(zone);
   2634 }
   2635 
   2636 static isc_result_t
   2637 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
   2638 	const char me[] = "zone_startload";
   2639 	dns_load_t *load;
   2640 	isc_result_t result;
   2641 	isc_result_t tresult;
   2642 	unsigned int options;
   2643 
   2644 	ENTER;
   2645 
   2646 	dns_zone_rpz_enable_db(zone, db);
   2647 	dns_zone_catz_enable_db(zone, db);
   2648 
   2649 	options = get_master_options(zone);
   2650 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) {
   2651 		options |= DNS_MASTER_MANYERRORS;
   2652 	}
   2653 
   2654 	if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
   2655 		load = isc_mem_get(zone->mctx, sizeof(*load));
   2656 
   2657 		load->mctx = NULL;
   2658 		load->zone = NULL;
   2659 		load->db = NULL;
   2660 		load->loadtime = loadtime;
   2661 		load->magic = LOAD_MAGIC;
   2662 
   2663 		isc_mem_attach(zone->mctx, &load->mctx);
   2664 		zone_iattach(zone, &load->zone);
   2665 		dns_db_attach(db, &load->db);
   2666 		dns_rdatacallbacks_init(&load->callbacks);
   2667 		load->callbacks.rawdata = zone_setrawdata;
   2668 		zone_iattach(zone, &load->callbacks.zone);
   2669 		result = dns_db_beginload(db, &load->callbacks);
   2670 		if (result != ISC_R_SUCCESS) {
   2671 			goto cleanup;
   2672 		}
   2673 		result = zonemgr_getio(zone->zmgr, true, zone->loadtask,
   2674 				       zone_gotreadhandle, load, &zone->readio);
   2675 		if (result != ISC_R_SUCCESS) {
   2676 			/*
   2677 			 * We can't report multiple errors so ignore
   2678 			 * the result of dns_db_endload().
   2679 			 */
   2680 			(void)dns_db_endload(load->db, &load->callbacks);
   2681 			goto cleanup;
   2682 		} else {
   2683 			result = DNS_R_CONTINUE;
   2684 		}
   2685 	} else {
   2686 		dns_rdatacallbacks_t callbacks;
   2687 
   2688 		dns_rdatacallbacks_init(&callbacks);
   2689 		callbacks.rawdata = zone_setrawdata;
   2690 		zone_iattach(zone, &callbacks.zone);
   2691 		result = dns_db_beginload(db, &callbacks);
   2692 		if (result != ISC_R_SUCCESS) {
   2693 			zone_idetach(&callbacks.zone);
   2694 			return (result);
   2695 		}
   2696 		result = dns_master_loadfile(
   2697 			zone->masterfile, &zone->origin, &zone->origin,
   2698 			zone->rdclass, options, 0, &callbacks,
   2699 			zone_registerinclude, zone, zone->mctx,
   2700 			zone->masterformat, zone->maxttl);
   2701 		tresult = dns_db_endload(db, &callbacks);
   2702 		if (result == ISC_R_SUCCESS) {
   2703 			result = tresult;
   2704 		}
   2705 		zone_idetach(&callbacks.zone);
   2706 	}
   2707 
   2708 	return (result);
   2709 
   2710 cleanup:
   2711 	load->magic = 0;
   2712 	dns_db_detach(&load->db);
   2713 	zone_idetach(&load->zone);
   2714 	zone_idetach(&load->callbacks.zone);
   2715 	isc_mem_detach(&load->mctx);
   2716 	isc_mem_put(zone->mctx, load, sizeof(*load));
   2717 	return (result);
   2718 }
   2719 
   2720 static bool
   2721 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2722 	      dns_name_t *owner) {
   2723 	isc_result_t result;
   2724 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2725 	char namebuf[DNS_NAME_FORMATSIZE];
   2726 	char altbuf[DNS_NAME_FORMATSIZE];
   2727 	dns_fixedname_t fixed;
   2728 	dns_name_t *foundname;
   2729 	int level;
   2730 
   2731 	/*
   2732 	 * "." means the services does not exist.
   2733 	 */
   2734 	if (dns_name_equal(name, dns_rootname)) {
   2735 		return (true);
   2736 	}
   2737 
   2738 	/*
   2739 	 * Outside of zone.
   2740 	 */
   2741 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2742 		if (zone->checkmx != NULL) {
   2743 			return ((zone->checkmx)(zone, name, owner));
   2744 		}
   2745 		return (true);
   2746 	}
   2747 
   2748 	if (zone->type == dns_zone_master) {
   2749 		level = ISC_LOG_ERROR;
   2750 	} else {
   2751 		level = ISC_LOG_WARNING;
   2752 	}
   2753 
   2754 	foundname = dns_fixedname_initname(&fixed);
   2755 
   2756 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2757 			     foundname, NULL, NULL);
   2758 	if (result == ISC_R_SUCCESS) {
   2759 		return (true);
   2760 	}
   2761 
   2762 	if (result == DNS_R_NXRRSET) {
   2763 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2764 				     NULL, foundname, NULL, NULL);
   2765 		if (result == ISC_R_SUCCESS) {
   2766 			return (true);
   2767 		}
   2768 	}
   2769 
   2770 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2771 	dns_name_format(name, namebuf, sizeof namebuf);
   2772 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2773 	    result == DNS_R_EMPTYNAME)
   2774 	{
   2775 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2776 			level = ISC_LOG_WARNING;
   2777 		}
   2778 		dns_zone_log(zone, level,
   2779 			     "%s/MX '%s' has no address records (A or AAAA)",
   2780 			     ownerbuf, namebuf);
   2781 		return ((level == ISC_LOG_WARNING) ? true : false);
   2782 	}
   2783 
   2784 	if (result == DNS_R_CNAME) {
   2785 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2786 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2787 		{
   2788 			level = ISC_LOG_WARNING;
   2789 		}
   2790 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2791 			dns_zone_log(zone, level,
   2792 				     "%s/MX '%s' is a CNAME (illegal)",
   2793 				     ownerbuf, namebuf);
   2794 		}
   2795 		return ((level == ISC_LOG_WARNING) ? true : false);
   2796 	}
   2797 
   2798 	if (result == DNS_R_DNAME) {
   2799 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2800 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2801 		{
   2802 			level = ISC_LOG_WARNING;
   2803 		}
   2804 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2805 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2806 			dns_zone_log(zone, level,
   2807 				     "%s/MX '%s' is below a DNAME"
   2808 				     " '%s' (illegal)",
   2809 				     ownerbuf, namebuf, altbuf);
   2810 		}
   2811 		return ((level == ISC_LOG_WARNING) ? true : false);
   2812 	}
   2813 
   2814 	if (zone->checkmx != NULL && result == DNS_R_DELEGATION) {
   2815 		return ((zone->checkmx)(zone, name, owner));
   2816 	}
   2817 
   2818 	return (true);
   2819 }
   2820 
   2821 static bool
   2822 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2823 	       dns_name_t *owner) {
   2824 	isc_result_t result;
   2825 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2826 	char namebuf[DNS_NAME_FORMATSIZE];
   2827 	char altbuf[DNS_NAME_FORMATSIZE];
   2828 	dns_fixedname_t fixed;
   2829 	dns_name_t *foundname;
   2830 	int level;
   2831 
   2832 	/*
   2833 	 * "." means the services does not exist.
   2834 	 */
   2835 	if (dns_name_equal(name, dns_rootname)) {
   2836 		return (true);
   2837 	}
   2838 
   2839 	/*
   2840 	 * Outside of zone.
   2841 	 */
   2842 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2843 		if (zone->checksrv != NULL) {
   2844 			return ((zone->checksrv)(zone, name, owner));
   2845 		}
   2846 		return (true);
   2847 	}
   2848 
   2849 	if (zone->type == dns_zone_master) {
   2850 		level = ISC_LOG_ERROR;
   2851 	} else {
   2852 		level = ISC_LOG_WARNING;
   2853 	}
   2854 
   2855 	foundname = dns_fixedname_initname(&fixed);
   2856 
   2857 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2858 			     foundname, NULL, NULL);
   2859 	if (result == ISC_R_SUCCESS) {
   2860 		return (true);
   2861 	}
   2862 
   2863 	if (result == DNS_R_NXRRSET) {
   2864 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2865 				     NULL, foundname, NULL, NULL);
   2866 		if (result == ISC_R_SUCCESS) {
   2867 			return (true);
   2868 		}
   2869 	}
   2870 
   2871 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2872 	dns_name_format(name, namebuf, sizeof namebuf);
   2873 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2874 	    result == DNS_R_EMPTYNAME)
   2875 	{
   2876 		dns_zone_log(zone, level,
   2877 			     "%s/SRV '%s' has no address records (A or AAAA)",
   2878 			     ownerbuf, namebuf);
   2879 		/* XXX950 make fatal for 9.5.0. */
   2880 		return (true);
   2881 	}
   2882 
   2883 	if (result == DNS_R_CNAME) {
   2884 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2885 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2886 		{
   2887 			level = ISC_LOG_WARNING;
   2888 		}
   2889 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   2890 			dns_zone_log(zone, level,
   2891 				     "%s/SRV '%s' is a CNAME (illegal)",
   2892 				     ownerbuf, namebuf);
   2893 		}
   2894 		return ((level == ISC_LOG_WARNING) ? true : false);
   2895 	}
   2896 
   2897 	if (result == DNS_R_DNAME) {
   2898 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2899 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2900 		{
   2901 			level = ISC_LOG_WARNING;
   2902 		}
   2903 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   2904 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2905 			dns_zone_log(zone, level,
   2906 				     "%s/SRV '%s' is below a "
   2907 				     "DNAME '%s' (illegal)",
   2908 				     ownerbuf, namebuf, altbuf);
   2909 		}
   2910 		return ((level == ISC_LOG_WARNING) ? true : false);
   2911 	}
   2912 
   2913 	if (zone->checksrv != NULL && result == DNS_R_DELEGATION) {
   2914 		return ((zone->checksrv)(zone, name, owner));
   2915 	}
   2916 
   2917 	return (true);
   2918 }
   2919 
   2920 static bool
   2921 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2922 		dns_name_t *owner) {
   2923 	bool answer = true;
   2924 	isc_result_t result, tresult;
   2925 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2926 	char namebuf[DNS_NAME_FORMATSIZE];
   2927 	char altbuf[DNS_NAME_FORMATSIZE];
   2928 	dns_fixedname_t fixed;
   2929 	dns_name_t *foundname;
   2930 	dns_rdataset_t a;
   2931 	dns_rdataset_t aaaa;
   2932 	int level;
   2933 
   2934 	/*
   2935 	 * Outside of zone.
   2936 	 */
   2937 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2938 		if (zone->checkns != NULL) {
   2939 			return ((zone->checkns)(zone, name, owner, NULL, NULL));
   2940 		}
   2941 		return (true);
   2942 	}
   2943 
   2944 	if (zone->type == dns_zone_master) {
   2945 		level = ISC_LOG_ERROR;
   2946 	} else {
   2947 		level = ISC_LOG_WARNING;
   2948 	}
   2949 
   2950 	foundname = dns_fixedname_initname(&fixed);
   2951 	dns_rdataset_init(&a);
   2952 	dns_rdataset_init(&aaaa);
   2953 
   2954 	/*
   2955 	 * Perform a regular lookup to catch DNAME records then look
   2956 	 * for glue.
   2957 	 */
   2958 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2959 			     foundname, &a, NULL);
   2960 	switch (result) {
   2961 	case ISC_R_SUCCESS:
   2962 	case DNS_R_DNAME:
   2963 	case DNS_R_CNAME:
   2964 		break;
   2965 	default:
   2966 		if (dns_rdataset_isassociated(&a)) {
   2967 			dns_rdataset_disassociate(&a);
   2968 		}
   2969 		result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   2970 				     DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a,
   2971 				     NULL);
   2972 	}
   2973 	if (result == ISC_R_SUCCESS) {
   2974 		dns_rdataset_disassociate(&a);
   2975 		return (true);
   2976 	} else if (result == DNS_R_DELEGATION) {
   2977 		dns_rdataset_disassociate(&a);
   2978 	}
   2979 
   2980 	if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
   2981 	    result == DNS_R_GLUE)
   2982 	{
   2983 		tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
   2984 				      DNS_DBFIND_GLUEOK, 0, NULL, foundname,
   2985 				      &aaaa, NULL);
   2986 		if (tresult == ISC_R_SUCCESS) {
   2987 			if (dns_rdataset_isassociated(&a)) {
   2988 				dns_rdataset_disassociate(&a);
   2989 			}
   2990 			dns_rdataset_disassociate(&aaaa);
   2991 			return (true);
   2992 		}
   2993 		if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) {
   2994 			dns_rdataset_disassociate(&aaaa);
   2995 		}
   2996 		if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
   2997 			/*
   2998 			 * Check glue against child zone.
   2999 			 */
   3000 			if (zone->checkns != NULL) {
   3001 				answer = (zone->checkns)(zone, name, owner, &a,
   3002 							 &aaaa);
   3003 			}
   3004 			if (dns_rdataset_isassociated(&a)) {
   3005 				dns_rdataset_disassociate(&a);
   3006 			}
   3007 			if (dns_rdataset_isassociated(&aaaa)) {
   3008 				dns_rdataset_disassociate(&aaaa);
   3009 			}
   3010 			return (answer);
   3011 		}
   3012 	}
   3013 
   3014 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   3015 	dns_name_format(name, namebuf, sizeof namebuf);
   3016 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   3017 	    result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION)
   3018 	{
   3019 		const char *what;
   3020 		bool required = false;
   3021 		if (dns_name_issubdomain(name, owner)) {
   3022 			what = "REQUIRED GLUE ";
   3023 			required = true;
   3024 		} else if (result == DNS_R_DELEGATION) {
   3025 			what = "SIBLING GLUE ";
   3026 		} else {
   3027 			what = "";
   3028 		}
   3029 
   3030 		if (result != DNS_R_DELEGATION || required ||
   3031 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING))
   3032 		{
   3033 			dns_zone_log(zone, level,
   3034 				     "%s/NS '%s' has no %s"
   3035 				     "address records (A or AAAA)",
   3036 				     ownerbuf, namebuf, what);
   3037 			/*
   3038 			 * Log missing address record.
   3039 			 */
   3040 			if (result == DNS_R_DELEGATION && zone->checkns != NULL)
   3041 			{
   3042 				(void)(zone->checkns)(zone, name, owner, &a,
   3043 						      &aaaa);
   3044 			}
   3045 			/* XXX950 make fatal for 9.5.0. */
   3046 			/* answer = false; */
   3047 		}
   3048 	} else if (result == DNS_R_CNAME) {
   3049 		dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
   3050 			     ownerbuf, namebuf);
   3051 		/* XXX950 make fatal for 9.5.0. */
   3052 		/* answer = false; */
   3053 	} else if (result == DNS_R_DNAME) {
   3054 		dns_name_format(foundname, altbuf, sizeof altbuf);
   3055 		dns_zone_log(zone, level,
   3056 			     "%s/NS '%s' is below a DNAME '%s' (illegal)",
   3057 			     ownerbuf, namebuf, altbuf);
   3058 		/* XXX950 make fatal for 9.5.0. */
   3059 		/* answer = false; */
   3060 	}
   3061 
   3062 	if (dns_rdataset_isassociated(&a)) {
   3063 		dns_rdataset_disassociate(&a);
   3064 	}
   3065 	if (dns_rdataset_isassociated(&aaaa)) {
   3066 		dns_rdataset_disassociate(&aaaa);
   3067 	}
   3068 	return (answer);
   3069 }
   3070 
   3071 static bool
   3072 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
   3073 		     dns_rdataset_t *rdataset) {
   3074 	dns_rdataset_t tmprdataset;
   3075 	isc_result_t result;
   3076 	bool answer = true;
   3077 	bool format = true;
   3078 	int level = ISC_LOG_WARNING;
   3079 	char ownerbuf[DNS_NAME_FORMATSIZE];
   3080 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   3081 	unsigned int count1 = 0;
   3082 
   3083 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) {
   3084 		level = ISC_LOG_ERROR;
   3085 	}
   3086 
   3087 	dns_rdataset_init(&tmprdataset);
   3088 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   3089 	     result = dns_rdataset_next(rdataset))
   3090 	{
   3091 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   3092 		unsigned int count2 = 0;
   3093 
   3094 		count1++;
   3095 		dns_rdataset_current(rdataset, &rdata1);
   3096 		dns_rdataset_clone(rdataset, &tmprdataset);
   3097 		for (result = dns_rdataset_first(&tmprdataset);
   3098 		     result == ISC_R_SUCCESS;
   3099 		     result = dns_rdataset_next(&tmprdataset))
   3100 		{
   3101 			dns_rdata_t rdata2 = DNS_RDATA_INIT;
   3102 			count2++;
   3103 			if (count1 >= count2) {
   3104 				continue;
   3105 			}
   3106 			dns_rdataset_current(&tmprdataset, &rdata2);
   3107 			if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
   3108 				if (format) {
   3109 					dns_name_format(owner, ownerbuf,
   3110 							sizeof ownerbuf);
   3111 					dns_rdatatype_format(rdata1.type,
   3112 							     typebuf,
   3113 							     sizeof(typebuf));
   3114 					format = false;
   3115 				}
   3116 				dns_zone_log(zone, level,
   3117 					     "%s/%s has "
   3118 					     "semantically identical records",
   3119 					     ownerbuf, typebuf);
   3120 				if (level == ISC_LOG_ERROR) {
   3121 					answer = false;
   3122 				}
   3123 				break;
   3124 			}
   3125 		}
   3126 		dns_rdataset_disassociate(&tmprdataset);
   3127 		if (!format) {
   3128 			break;
   3129 		}
   3130 	}
   3131 	return (answer);
   3132 }
   3133 
   3134 static bool
   3135 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
   3136 	dns_dbiterator_t *dbiterator = NULL;
   3137 	dns_dbnode_t *node = NULL;
   3138 	dns_fixedname_t fixed;
   3139 	dns_name_t *name;
   3140 	dns_rdataset_t rdataset;
   3141 	dns_rdatasetiter_t *rdsit = NULL;
   3142 	bool ok = true;
   3143 	isc_result_t result;
   3144 
   3145 	name = dns_fixedname_initname(&fixed);
   3146 	dns_rdataset_init(&rdataset);
   3147 
   3148 	result = dns_db_createiterator(db, 0, &dbiterator);
   3149 	if (result != ISC_R_SUCCESS) {
   3150 		return (true);
   3151 	}
   3152 
   3153 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   3154 	     result = dns_dbiterator_next(dbiterator))
   3155 	{
   3156 		result = dns_dbiterator_current(dbiterator, &node, name);
   3157 		if (result != ISC_R_SUCCESS) {
   3158 			continue;
   3159 		}
   3160 
   3161 		result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
   3162 		if (result != ISC_R_SUCCESS) {
   3163 			continue;
   3164 		}
   3165 
   3166 		for (result = dns_rdatasetiter_first(rdsit);
   3167 		     result == ISC_R_SUCCESS;
   3168 		     result = dns_rdatasetiter_next(rdsit))
   3169 		{
   3170 			dns_rdatasetiter_current(rdsit, &rdataset);
   3171 			if (!zone_rrset_check_dup(zone, name, &rdataset)) {
   3172 				ok = false;
   3173 			}
   3174 			dns_rdataset_disassociate(&rdataset);
   3175 		}
   3176 		dns_rdatasetiter_destroy(&rdsit);
   3177 		dns_db_detachnode(db, &node);
   3178 	}
   3179 
   3180 	if (node != NULL) {
   3181 		dns_db_detachnode(db, &node);
   3182 	}
   3183 	dns_dbiterator_destroy(&dbiterator);
   3184 
   3185 	return (ok);
   3186 }
   3187 
   3188 static bool
   3189 isspf(const dns_rdata_t *rdata) {
   3190 	char buf[1024];
   3191 	const unsigned char *data = rdata->data;
   3192 	unsigned int rdl = rdata->length, i = 0, tl, len;
   3193 
   3194 	while (rdl > 0U) {
   3195 		len = tl = *data;
   3196 		++data;
   3197 		--rdl;
   3198 		INSIST(tl <= rdl);
   3199 		if (len > sizeof(buf) - i - 1) {
   3200 			len = sizeof(buf) - i - 1;
   3201 		}
   3202 		memmove(buf + i, data, len);
   3203 		i += len;
   3204 		data += tl;
   3205 		rdl -= tl;
   3206 	}
   3207 
   3208 	if (i < 6U) {
   3209 		return (false);
   3210 	}
   3211 
   3212 	buf[i] = 0;
   3213 	if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) {
   3214 		return (true);
   3215 	}
   3216 	return (false);
   3217 }
   3218 
   3219 static bool
   3220 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
   3221 	dns_dbiterator_t *dbiterator = NULL;
   3222 	dns_dbnode_t *node = NULL;
   3223 	dns_rdataset_t rdataset;
   3224 	dns_fixedname_t fixed;
   3225 	dns_fixedname_t fixedbottom;
   3226 	dns_rdata_mx_t mx;
   3227 	dns_rdata_ns_t ns;
   3228 	dns_rdata_in_srv_t srv;
   3229 	dns_rdata_t rdata;
   3230 	dns_name_t *name;
   3231 	dns_name_t *bottom;
   3232 	isc_result_t result;
   3233 	bool ok = true, have_spf, have_txt;
   3234 
   3235 	name = dns_fixedname_initname(&fixed);
   3236 	bottom = dns_fixedname_initname(&fixedbottom);
   3237 	dns_rdataset_init(&rdataset);
   3238 	dns_rdata_init(&rdata);
   3239 
   3240 	result = dns_db_createiterator(db, 0, &dbiterator);
   3241 	if (result != ISC_R_SUCCESS) {
   3242 		return (true);
   3243 	}
   3244 
   3245 	result = dns_dbiterator_first(dbiterator);
   3246 	while (result == ISC_R_SUCCESS) {
   3247 		result = dns_dbiterator_current(dbiterator, &node, name);
   3248 		if (result != ISC_R_SUCCESS) {
   3249 			goto cleanup;
   3250 		}
   3251 
   3252 		/*
   3253 		 * Is this name visible in the zone?
   3254 		 */
   3255 		if (!dns_name_issubdomain(name, &zone->origin) ||
   3256 		    (dns_name_countlabels(bottom) > 0 &&
   3257 		     dns_name_issubdomain(name, bottom)))
   3258 		{
   3259 			goto next;
   3260 		}
   3261 
   3262 		/*
   3263 		 * Don't check the NS records at the origin.
   3264 		 */
   3265 		if (dns_name_equal(name, &zone->origin)) {
   3266 			goto checkfordname;
   3267 		}
   3268 
   3269 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
   3270 					     0, 0, &rdataset, NULL);
   3271 		if (result != ISC_R_SUCCESS) {
   3272 			goto checkfordname;
   3273 		}
   3274 		/*
   3275 		 * Remember bottom of zone due to NS.
   3276 		 */
   3277 		dns_name_copynf(name, bottom);
   3278 
   3279 		result = dns_rdataset_first(&rdataset);
   3280 		while (result == ISC_R_SUCCESS) {
   3281 			dns_rdataset_current(&rdataset, &rdata);
   3282 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   3283 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3284 			if (!zone_check_glue(zone, db, &ns.name, name)) {
   3285 				ok = false;
   3286 			}
   3287 			dns_rdata_reset(&rdata);
   3288 			result = dns_rdataset_next(&rdataset);
   3289 		}
   3290 		dns_rdataset_disassociate(&rdataset);
   3291 		goto next;
   3292 
   3293 	checkfordname:
   3294 		result = dns_db_findrdataset(db, node, NULL,
   3295 					     dns_rdatatype_dname, 0, 0,
   3296 					     &rdataset, NULL);
   3297 		if (result == ISC_R_SUCCESS) {
   3298 			/*
   3299 			 * Remember bottom of zone due to DNAME.
   3300 			 */
   3301 			dns_name_copynf(name, bottom);
   3302 			dns_rdataset_disassociate(&rdataset);
   3303 		}
   3304 
   3305 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
   3306 					     0, 0, &rdataset, NULL);
   3307 		if (result != ISC_R_SUCCESS) {
   3308 			goto checksrv;
   3309 		}
   3310 		result = dns_rdataset_first(&rdataset);
   3311 		while (result == ISC_R_SUCCESS) {
   3312 			dns_rdataset_current(&rdataset, &rdata);
   3313 			result = dns_rdata_tostruct(&rdata, &mx, NULL);
   3314 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3315 			if (!zone_check_mx(zone, db, &mx.mx, name)) {
   3316 				ok = false;
   3317 			}
   3318 			dns_rdata_reset(&rdata);
   3319 			result = dns_rdataset_next(&rdataset);
   3320 		}
   3321 		dns_rdataset_disassociate(&rdataset);
   3322 
   3323 	checksrv:
   3324 		if (zone->rdclass != dns_rdataclass_in) {
   3325 			goto next;
   3326 		}
   3327 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
   3328 					     0, 0, &rdataset, NULL);
   3329 		if (result != ISC_R_SUCCESS) {
   3330 			goto checkspf;
   3331 		}
   3332 		result = dns_rdataset_first(&rdataset);
   3333 		while (result == ISC_R_SUCCESS) {
   3334 			dns_rdataset_current(&rdataset, &rdata);
   3335 			result = dns_rdata_tostruct(&rdata, &srv, NULL);
   3336 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3337 			if (!zone_check_srv(zone, db, &srv.target, name)) {
   3338 				ok = false;
   3339 			}
   3340 			dns_rdata_reset(&rdata);
   3341 			result = dns_rdataset_next(&rdataset);
   3342 		}
   3343 		dns_rdataset_disassociate(&rdataset);
   3344 
   3345 	checkspf:
   3346 		/*
   3347 		 * Check if there is a type SPF record without an
   3348 		 * SPF-formatted type TXT record also being present.
   3349 		 */
   3350 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) {
   3351 			goto next;
   3352 		}
   3353 		if (zone->rdclass != dns_rdataclass_in) {
   3354 			goto next;
   3355 		}
   3356 		have_spf = have_txt = false;
   3357 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
   3358 					     0, 0, &rdataset, NULL);
   3359 		if (result == ISC_R_SUCCESS) {
   3360 			dns_rdataset_disassociate(&rdataset);
   3361 			have_spf = true;
   3362 		}
   3363 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
   3364 					     0, 0, &rdataset, NULL);
   3365 		if (result != ISC_R_SUCCESS) {
   3366 			goto notxt;
   3367 		}
   3368 		result = dns_rdataset_first(&rdataset);
   3369 		while (result == ISC_R_SUCCESS) {
   3370 			dns_rdataset_current(&rdataset, &rdata);
   3371 			have_txt = isspf(&rdata);
   3372 			dns_rdata_reset(&rdata);
   3373 			if (have_txt) {
   3374 				break;
   3375 			}
   3376 			result = dns_rdataset_next(&rdataset);
   3377 		}
   3378 		dns_rdataset_disassociate(&rdataset);
   3379 
   3380 	notxt:
   3381 		if (have_spf && !have_txt) {
   3382 			char namebuf[DNS_NAME_FORMATSIZE];
   3383 
   3384 			dns_name_format(name, namebuf, sizeof(namebuf));
   3385 			dns_zone_log(zone, ISC_LOG_WARNING,
   3386 				     "'%s' found type "
   3387 				     "SPF record but no SPF TXT record found, "
   3388 				     "add matching type TXT record",
   3389 				     namebuf);
   3390 		}
   3391 
   3392 	next:
   3393 		dns_db_detachnode(db, &node);
   3394 		result = dns_dbiterator_next(dbiterator);
   3395 	}
   3396 
   3397 cleanup:
   3398 	if (node != NULL) {
   3399 		dns_db_detachnode(db, &node);
   3400 	}
   3401 	dns_dbiterator_destroy(&dbiterator);
   3402 
   3403 	return (ok);
   3404 }
   3405 
   3406 /*
   3407  * OpenSSL verification of RSA keys with exponent 3 is known to be
   3408  * broken prior OpenSSL 0.9.8c/0.9.7k.	Look for such keys and warn
   3409  * if they are in use.
   3410  */
   3411 static void
   3412 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
   3413 	dns_dbnode_t *node = NULL;
   3414 	dns_dbversion_t *version = NULL;
   3415 	dns_rdata_dnskey_t dnskey;
   3416 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3417 	dns_rdataset_t rdataset;
   3418 	isc_result_t result;
   3419 
   3420 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3421 	if (result != ISC_R_SUCCESS) {
   3422 		goto cleanup;
   3423 	}
   3424 
   3425 	dns_db_currentversion(db, &version);
   3426 	dns_rdataset_init(&rdataset);
   3427 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   3428 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3429 	if (result != ISC_R_SUCCESS) {
   3430 		goto cleanup;
   3431 	}
   3432 
   3433 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3434 	     result = dns_rdataset_next(&rdataset))
   3435 	{
   3436 		dns_rdataset_current(&rdataset, &rdata);
   3437 		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
   3438 		INSIST(result == ISC_R_SUCCESS);
   3439 
   3440 		/* RFC 3110, section 4: Performance Considerations:
   3441 		 *
   3442 		 * A public exponent of 3 minimizes the effort needed to verify
   3443 		 * a signature.  Use of 3 as the public exponent is weak for
   3444 		 * confidentiality uses since, if the same data can be collected
   3445 		 * encrypted under three different keys with an exponent of 3
   3446 		 * then, using the Chinese Remainder Theorem [NETSEC], the
   3447 		 * original plain text can be easily recovered.  If a key is
   3448 		 * known to be used only for authentication, as is the case with
   3449 		 * DNSSEC, then an exponent of 3 is acceptable.  However other
   3450 		 * applications in the future may wish to leverage DNS
   3451 		 * distributed keys for applications that do require
   3452 		 * confidentiality.  For keys which might have such other uses,
   3453 		 * a more conservative choice would be 65537 (F4, the fourth
   3454 		 * fermat number).
   3455 		 */
   3456 		if (dnskey.datalen > 1 && dnskey.data[0] == 1 &&
   3457 		    dnskey.data[1] == 3) {
   3458 			const char *algorithm = "";
   3459 			isc_region_t r;
   3460 			bool logit = true;
   3461 
   3462 			dns_rdata_toregion(&rdata, &r);
   3463 
   3464 			switch (dnskey.algorithm) {
   3465 			case DNS_KEYALG_RSAMD5:
   3466 				algorithm = "RSAMD5";
   3467 				break;
   3468 			case DNS_KEYALG_RSASHA1:
   3469 				algorithm = "RSASHA1";
   3470 				break;
   3471 			case DNS_KEYALG_NSEC3RSASHA1:
   3472 				algorithm = "NSEC3RSASHA1";
   3473 				break;
   3474 			case DNS_KEYALG_RSASHA256:
   3475 				algorithm = "RSASHA236";
   3476 				break;
   3477 			case DNS_KEYALG_RSASHA512:
   3478 				algorithm = "RSASHA512";
   3479 				break;
   3480 			default:
   3481 				logit = false;
   3482 				break;
   3483 			}
   3484 
   3485 			if (logit) {
   3486 				dnssec_log(zone, ISC_LOG_WARNING,
   3487 					   "weak %s (%u) key found "
   3488 					   "(exponent=3, id=%u)",
   3489 					   algorithm, dnskey.algorithm,
   3490 					   dst_region_computeid(&r));
   3491 			}
   3492 		}
   3493 		dns_rdata_reset(&rdata);
   3494 	}
   3495 	dns_rdataset_disassociate(&rdataset);
   3496 
   3497 cleanup:
   3498 	if (node != NULL) {
   3499 		dns_db_detachnode(db, &node);
   3500 	}
   3501 	if (version != NULL) {
   3502 		dns_db_closeversion(db, &version, false);
   3503 	}
   3504 }
   3505 
   3506 static void
   3507 resume_signingwithkey(dns_zone_t *zone) {
   3508 	dns_dbnode_t *node = NULL;
   3509 	dns_dbversion_t *version = NULL;
   3510 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3511 	dns_rdataset_t rdataset;
   3512 	isc_result_t result;
   3513 	dns_db_t *db = NULL;
   3514 
   3515 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3516 	if (zone->db != NULL) {
   3517 		dns_db_attach(zone->db, &db);
   3518 	}
   3519 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3520 	if (db == NULL) {
   3521 		goto cleanup;
   3522 	}
   3523 
   3524 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3525 	if (result != ISC_R_SUCCESS) {
   3526 		goto cleanup;
   3527 	}
   3528 
   3529 	dns_db_currentversion(db, &version);
   3530 	dns_rdataset_init(&rdataset);
   3531 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3532 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3533 	if (result != ISC_R_SUCCESS) {
   3534 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3535 		goto cleanup;
   3536 	}
   3537 
   3538 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3539 	     result = dns_rdataset_next(&rdataset))
   3540 	{
   3541 		dns_rdataset_current(&rdataset, &rdata);
   3542 		if (rdata.length != 5 || rdata.data[0] == 0 ||
   3543 		    rdata.data[4] != 0) {
   3544 			dns_rdata_reset(&rdata);
   3545 			continue;
   3546 		}
   3547 
   3548 		result = zone_signwithkey(zone, rdata.data[0],
   3549 					  (rdata.data[1] << 8) | rdata.data[2],
   3550 					  rdata.data[3]);
   3551 		if (result != ISC_R_SUCCESS) {
   3552 			dnssec_log(zone, ISC_LOG_ERROR,
   3553 				   "zone_signwithkey failed: %s",
   3554 				   dns_result_totext(result));
   3555 		}
   3556 		dns_rdata_reset(&rdata);
   3557 	}
   3558 	dns_rdataset_disassociate(&rdataset);
   3559 
   3560 cleanup:
   3561 	if (db != NULL) {
   3562 		if (node != NULL) {
   3563 			dns_db_detachnode(db, &node);
   3564 		}
   3565 		if (version != NULL) {
   3566 			dns_db_closeversion(db, &version, false);
   3567 		}
   3568 		dns_db_detach(&db);
   3569 	}
   3570 }
   3571 
   3572 /*
   3573  * Initiate adding/removing NSEC3 records belonging to the chain defined by the
   3574  * supplied NSEC3PARAM RDATA.
   3575  *
   3576  * Zone must be locked by caller.
   3577  */
   3578 static isc_result_t
   3579 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   3580 	dns_nsec3chain_t *nsec3chain, *current;
   3581 	dns_dbversion_t *version = NULL;
   3582 	bool nseconly = false, nsec3ok = false;
   3583 	isc_result_t result;
   3584 	isc_time_t now;
   3585 	unsigned int options = 0;
   3586 	char saltbuf[255 * 2 + 1];
   3587 	char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
   3588 	dns_db_t *db = NULL;
   3589 
   3590 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3591 	if (zone->db != NULL) {
   3592 		dns_db_attach(zone->db, &db);
   3593 	}
   3594 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3595 
   3596 	if (db == NULL) {
   3597 		result = ISC_R_SUCCESS;
   3598 		goto cleanup;
   3599 	}
   3600 
   3601 	/*
   3602 	 * If this zone is not NSEC3-capable, attempting to remove any NSEC3
   3603 	 * chain from it is pointless as it would not be possible for the
   3604 	 * latter to exist in the first place.
   3605 	 */
   3606 	dns_db_currentversion(db, &version);
   3607 	result = dns_nsec_nseconly(db, version, &nseconly);
   3608 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3609 	dns_db_closeversion(db, &version, false);
   3610 	if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
   3611 		result = ISC_R_SUCCESS;
   3612 		goto cleanup;
   3613 	}
   3614 
   3615 	/*
   3616 	 * Allocate and initialize structure preserving state of
   3617 	 * adding/removing records belonging to this NSEC3 chain between
   3618 	 * separate zone_nsec3chain() calls.
   3619 	 */
   3620 	nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
   3621 
   3622 	nsec3chain->magic = 0;
   3623 	nsec3chain->done = false;
   3624 	nsec3chain->db = NULL;
   3625 	nsec3chain->dbiterator = NULL;
   3626 	nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
   3627 	nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
   3628 	nsec3chain->nsec3param.hash = nsec3param->hash;
   3629 	nsec3chain->nsec3param.iterations = nsec3param->iterations;
   3630 	nsec3chain->nsec3param.flags = nsec3param->flags;
   3631 	nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
   3632 	memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
   3633 	nsec3chain->nsec3param.salt = nsec3chain->salt;
   3634 	nsec3chain->seen_nsec = false;
   3635 	nsec3chain->delete_nsec = false;
   3636 	nsec3chain->save_delete_nsec = false;
   3637 
   3638 	/*
   3639 	 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA.
   3640 	 */
   3641 	if (nsec3param->flags == 0) {
   3642 		strlcpy(flags, "NONE", sizeof(flags));
   3643 	} else {
   3644 		flags[0] = '\0';
   3645 		if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   3646 			strlcat(flags, "REMOVE", sizeof(flags));
   3647 		}
   3648 		if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) {
   3649 			if (flags[0] == '\0') {
   3650 				strlcpy(flags, "INITIAL", sizeof(flags));
   3651 			} else {
   3652 				strlcat(flags, "|INITIAL", sizeof(flags));
   3653 			}
   3654 		}
   3655 		if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3656 			if (flags[0] == '\0') {
   3657 				strlcpy(flags, "CREATE", sizeof(flags));
   3658 			} else {
   3659 				strlcat(flags, "|CREATE", sizeof(flags));
   3660 			}
   3661 		}
   3662 		if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) {
   3663 			if (flags[0] == '\0') {
   3664 				strlcpy(flags, "NONSEC", sizeof(flags));
   3665 			} else {
   3666 				strlcat(flags, "|NONSEC", sizeof(flags));
   3667 			}
   3668 		}
   3669 		if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) {
   3670 			if (flags[0] == '\0') {
   3671 				strlcpy(flags, "OPTOUT", sizeof(flags));
   3672 			} else {
   3673 				strlcat(flags, "|OPTOUT", sizeof(flags));
   3674 			}
   3675 		}
   3676 	}
   3677 	result = dns_nsec3param_salttotext(nsec3param, saltbuf,
   3678 					   sizeof(saltbuf));
   3679 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3680 	dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)",
   3681 		   nsec3param->hash, flags, nsec3param->iterations, saltbuf);
   3682 
   3683 	/*
   3684 	 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is
   3685 	 * currently being processed, interrupt its processing to avoid
   3686 	 * simultaneously adding and removing records for the same NSEC3 chain.
   3687 	 */
   3688 	for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL;
   3689 	     current = ISC_LIST_NEXT(current, link))
   3690 	{
   3691 		if ((current->db == db) &&
   3692 		    (current->nsec3param.hash == nsec3param->hash) &&
   3693 		    (current->nsec3param.iterations ==
   3694 		     nsec3param->iterations) &&
   3695 		    (current->nsec3param.salt_length ==
   3696 		     nsec3param->salt_length) &&
   3697 		    memcmp(current->nsec3param.salt, nsec3param->salt,
   3698 			   nsec3param->salt_length) == 0)
   3699 		{
   3700 			current->done = true;
   3701 		}
   3702 	}
   3703 
   3704 	/*
   3705 	 * Attach zone database to the structure initialized above and create
   3706 	 * an iterator for it with appropriate options in order to avoid
   3707 	 * creating NSEC3 records for NSEC3 records.
   3708 	 */
   3709 	dns_db_attach(db, &nsec3chain->db);
   3710 	if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3711 		options = DNS_DB_NONSEC3;
   3712 	}
   3713 	result = dns_db_createiterator(nsec3chain->db, options,
   3714 				       &nsec3chain->dbiterator);
   3715 	if (result == ISC_R_SUCCESS) {
   3716 		result = dns_dbiterator_first(nsec3chain->dbiterator);
   3717 	}
   3718 	if (result == ISC_R_SUCCESS) {
   3719 		/*
   3720 		 * Database iterator initialization succeeded.  We are now
   3721 		 * ready to kick off adding/removing records belonging to this
   3722 		 * NSEC3 chain.  Append the structure initialized above to the
   3723 		 * "nsec3chain" list for the zone and set the appropriate zone
   3724 		 * timer so that zone_nsec3chain() is called as soon as
   3725 		 * possible.
   3726 		 */
   3727 		dns_dbiterator_pause(nsec3chain->dbiterator);
   3728 		ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link);
   3729 		nsec3chain = NULL;
   3730 		if (isc_time_isepoch(&zone->nsec3chaintime)) {
   3731 			TIME_NOW(&now);
   3732 			zone->nsec3chaintime = now;
   3733 			if (zone->task != NULL) {
   3734 				zone_settimer(zone, &now);
   3735 			}
   3736 		}
   3737 	}
   3738 
   3739 	if (nsec3chain != NULL) {
   3740 		if (nsec3chain->db != NULL) {
   3741 			dns_db_detach(&nsec3chain->db);
   3742 		}
   3743 		if (nsec3chain->dbiterator != NULL) {
   3744 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   3745 		}
   3746 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   3747 	}
   3748 
   3749 cleanup:
   3750 	if (db != NULL) {
   3751 		dns_db_detach(&db);
   3752 	}
   3753 	return (result);
   3754 }
   3755 
   3756 /*
   3757  * Find private-type records at the zone apex which signal that an NSEC3 chain
   3758  * should be added or removed.  For each such record, extract NSEC3PARAM RDATA
   3759  * and pass it to zone_addnsec3chain().
   3760  *
   3761  * Zone must be locked by caller.
   3762  */
   3763 static void
   3764 resume_addnsec3chain(dns_zone_t *zone) {
   3765 	dns_dbnode_t *node = NULL;
   3766 	dns_dbversion_t *version = NULL;
   3767 	dns_rdataset_t rdataset;
   3768 	isc_result_t result;
   3769 	dns_rdata_nsec3param_t nsec3param;
   3770 	bool nseconly = false, nsec3ok = false;
   3771 	dns_db_t *db = NULL;
   3772 
   3773 	INSIST(LOCKED_ZONE(zone));
   3774 
   3775 	if (zone->privatetype == 0) {
   3776 		return;
   3777 	}
   3778 
   3779 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3780 	if (zone->db != NULL) {
   3781 		dns_db_attach(zone->db, &db);
   3782 	}
   3783 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3784 	if (db == NULL) {
   3785 		goto cleanup;
   3786 	}
   3787 
   3788 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3789 	if (result != ISC_R_SUCCESS) {
   3790 		goto cleanup;
   3791 	}
   3792 
   3793 	dns_db_currentversion(db, &version);
   3794 
   3795 	/*
   3796 	 * In order to create NSEC3 chains we need the DNSKEY RRset at zone
   3797 	 * apex to exist and contain no keys using NSEC-only algorithms.
   3798 	 */
   3799 	result = dns_nsec_nseconly(db, version, &nseconly);
   3800 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3801 
   3802 	/*
   3803 	 * Get the RRset containing all private-type records at the zone apex.
   3804 	 */
   3805 	dns_rdataset_init(&rdataset);
   3806 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3807 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3808 	if (result != ISC_R_SUCCESS) {
   3809 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3810 		goto cleanup;
   3811 	}
   3812 
   3813 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3814 	     result = dns_rdataset_next(&rdataset))
   3815 	{
   3816 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   3817 		dns_rdata_t rdata = DNS_RDATA_INIT;
   3818 		dns_rdata_t private = DNS_RDATA_INIT;
   3819 
   3820 		dns_rdataset_current(&rdataset, &private);
   3821 		/*
   3822 		 * Try extracting NSEC3PARAM RDATA from this private-type
   3823 		 * record.  Failure means this private-type record does not
   3824 		 * represent an NSEC3PARAM record, so skip it.
   3825 		 */
   3826 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   3827 						sizeof(buf))) {
   3828 			continue;
   3829 		}
   3830 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3831 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3832 		if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
   3833 		    ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
   3834 		{
   3835 			/*
   3836 			 * Pass the NSEC3PARAM RDATA contained in this
   3837 			 * private-type record to zone_addnsec3chain() so that
   3838 			 * it can kick off adding or removing NSEC3 records.
   3839 			 */
   3840 			result = zone_addnsec3chain(zone, &nsec3param);
   3841 			if (result != ISC_R_SUCCESS) {
   3842 				dnssec_log(zone, ISC_LOG_ERROR,
   3843 					   "zone_addnsec3chain failed: %s",
   3844 					   dns_result_totext(result));
   3845 			}
   3846 		}
   3847 	}
   3848 	dns_rdataset_disassociate(&rdataset);
   3849 
   3850 cleanup:
   3851 	if (db != NULL) {
   3852 		if (node != NULL) {
   3853 			dns_db_detachnode(db, &node);
   3854 		}
   3855 		if (version != NULL) {
   3856 			dns_db_closeversion(db, &version, false);
   3857 		}
   3858 		dns_db_detach(&db);
   3859 	}
   3860 }
   3861 
   3862 static void
   3863 set_resigntime(dns_zone_t *zone) {
   3864 	dns_rdataset_t rdataset;
   3865 	dns_fixedname_t fixed;
   3866 	unsigned int resign;
   3867 	isc_result_t result;
   3868 	uint32_t nanosecs;
   3869 	dns_db_t *db = NULL;
   3870 
   3871 	INSIST(LOCKED_ZONE(zone));
   3872 
   3873 	/* We only re-sign zones that can be dynamically updated */
   3874 	if (zone->update_disabled) {
   3875 		return;
   3876 	}
   3877 
   3878 	if (!inline_secure(zone) &&
   3879 	    (zone->type != dns_zone_master ||
   3880 	     (zone->ssutable == NULL &&
   3881 	      (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
   3882 	{
   3883 		return;
   3884 	}
   3885 
   3886 	dns_rdataset_init(&rdataset);
   3887 	dns_fixedname_init(&fixed);
   3888 
   3889 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3890 	if (zone->db != NULL) {
   3891 		dns_db_attach(zone->db, &db);
   3892 	}
   3893 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3894 	if (db == NULL) {
   3895 		isc_time_settoepoch(&zone->resigntime);
   3896 		return;
   3897 	}
   3898 
   3899 	result = dns_db_getsigningtime(db, &rdataset,
   3900 				       dns_fixedname_name(&fixed));
   3901 	if (result != ISC_R_SUCCESS) {
   3902 		isc_time_settoepoch(&zone->resigntime);
   3903 		goto cleanup;
   3904 	}
   3905 
   3906 	resign = rdataset.resign - dns_zone_getsigresigninginterval(zone);
   3907 	dns_rdataset_disassociate(&rdataset);
   3908 	nanosecs = isc_random_uniform(1000000000);
   3909 	isc_time_set(&zone->resigntime, resign, nanosecs);
   3910 
   3911 cleanup:
   3912 	dns_db_detach(&db);
   3913 	return;
   3914 }
   3915 
   3916 static isc_result_t
   3917 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
   3918 	dns_dbnode_t *node = NULL;
   3919 	dns_rdataset_t rdataset;
   3920 	dns_dbversion_t *version = NULL;
   3921 	dns_rdata_nsec3param_t nsec3param;
   3922 	bool ok = false;
   3923 	isc_result_t result;
   3924 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3925 	bool dynamic = (zone->type == dns_zone_master)
   3926 			       ? dns_zone_isdynamic(zone, false)
   3927 			       : false;
   3928 
   3929 	dns_rdataset_init(&rdataset);
   3930 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3931 	if (result != ISC_R_SUCCESS) {
   3932 		dns_zone_log(zone, ISC_LOG_ERROR,
   3933 			     "nsec3param lookup failure: %s",
   3934 			     dns_result_totext(result));
   3935 		return (result);
   3936 	}
   3937 	dns_db_currentversion(db, &version);
   3938 
   3939 	result = dns_db_findrdataset(db, node, version,
   3940 				     dns_rdatatype_nsec3param,
   3941 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3942 	if (result == ISC_R_NOTFOUND) {
   3943 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3944 		result = ISC_R_SUCCESS;
   3945 		goto cleanup;
   3946 	}
   3947 	if (result != ISC_R_SUCCESS) {
   3948 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3949 		dns_zone_log(zone, ISC_LOG_ERROR,
   3950 			     "nsec3param lookup failure: %s",
   3951 			     dns_result_totext(result));
   3952 		goto cleanup;
   3953 	}
   3954 
   3955 	/*
   3956 	 * For dynamic zones we must support every algorithm so we can
   3957 	 * regenerate all the NSEC3 chains.
   3958 	 * For non-dynamic zones we only need to find a supported algorithm.
   3959 	 */
   3960 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3961 	     result = dns_rdataset_next(&rdataset))
   3962 	{
   3963 		dns_rdataset_current(&rdataset, &rdata);
   3964 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3965 		dns_rdata_reset(&rdata);
   3966 		INSIST(result == ISC_R_SUCCESS);
   3967 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
   3968 		    nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
   3969 		{
   3970 			dns_zone_log(zone, ISC_LOG_WARNING,
   3971 				     "nsec3 test \"unknown\" hash algorithm "
   3972 				     "found: %u",
   3973 				     nsec3param.hash);
   3974 			ok = true;
   3975 		} else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
   3976 			if (dynamic) {
   3977 				dns_zone_log(zone, ISC_LOG_ERROR,
   3978 					     "unsupported nsec3 hash algorithm"
   3979 					     " in dynamic zone: %u",
   3980 					     nsec3param.hash);
   3981 				result = DNS_R_BADZONE;
   3982 				/* Stop second error message. */
   3983 				ok = true;
   3984 				break;
   3985 			} else {
   3986 				dns_zone_log(zone, ISC_LOG_WARNING,
   3987 					     "unsupported nsec3 hash "
   3988 					     "algorithm: %u",
   3989 					     nsec3param.hash);
   3990 			}
   3991 		} else {
   3992 			ok = true;
   3993 		}
   3994 	}
   3995 	if (result == ISC_R_NOMORE) {
   3996 		result = ISC_R_SUCCESS;
   3997 	}
   3998 
   3999 	if (!ok) {
   4000 		result = DNS_R_BADZONE;
   4001 		dns_zone_log(zone, ISC_LOG_ERROR,
   4002 			     "no supported nsec3 hash algorithm");
   4003 	}
   4004 
   4005 cleanup:
   4006 	if (dns_rdataset_isassociated(&rdataset)) {
   4007 		dns_rdataset_disassociate(&rdataset);
   4008 	}
   4009 	dns_db_closeversion(db, &version, false);
   4010 	dns_db_detachnode(db, &node);
   4011 	return (result);
   4012 }
   4013 
   4014 /*
   4015  * Set the timer for refreshing the key zone to the soonest future time
   4016  * of the set (current timer, keydata->refresh, keydata->addhd,
   4017  * keydata->removehd).
   4018  */
   4019 static void
   4020 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
   4021 		    isc_stdtime_t now, bool force) {
   4022 	const char me[] = "set_refreshkeytimer";
   4023 	isc_stdtime_t then;
   4024 	isc_time_t timenow, timethen;
   4025 	char timebuf[80];
   4026 
   4027 	ENTER;
   4028 	then = key->refresh;
   4029 	if (force) {
   4030 		then = now;
   4031 	}
   4032 	if (key->addhd > now && key->addhd < then) {
   4033 		then = key->addhd;
   4034 	}
   4035 	if (key->removehd > now && key->removehd < then) {
   4036 		then = key->removehd;
   4037 	}
   4038 
   4039 	TIME_NOW(&timenow);
   4040 	if (then > now) {
   4041 		DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   4042 	} else {
   4043 		timethen = timenow;
   4044 	}
   4045 	if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
   4046 	    isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
   4047 	{
   4048 		zone->refreshkeytime = timethen;
   4049 	}
   4050 
   4051 	isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   4052 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
   4053 	zone_settimer(zone, &timenow);
   4054 }
   4055 
   4056 /*
   4057  * If keynode references a key or a DS rdataset, and if the key
   4058  * zone does not contain a KEYDATA record for the corresponding name,
   4059  * then create an empty KEYDATA and push it into the zone as a placeholder,
   4060  * then schedule a key refresh immediately. This new KEYDATA record will be
   4061  * updated during the refresh.
   4062  *
   4063  * If the key zone is changed, set '*changed' to true.
   4064  */
   4065 static isc_result_t
   4066 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4067 	       dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname,
   4068 	       bool *changed) {
   4069 	const char me[] = "create_keydata";
   4070 	isc_result_t result = ISC_R_SUCCESS;
   4071 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4072 	dns_rdata_keydata_t kd;
   4073 	unsigned char rrdata[4096];
   4074 	isc_buffer_t rrdatabuf;
   4075 	isc_stdtime_t now;
   4076 
   4077 	REQUIRE(keynode != NULL);
   4078 
   4079 	ENTER;
   4080 	isc_stdtime_get(&now);
   4081 
   4082 	/*
   4083 	 * If the keynode has no trust anchor set, we shouldn't be here.
   4084 	 */
   4085 	if (!dns_keynode_dsset(keynode, NULL)) {
   4086 		return (ISC_R_FAILURE);
   4087 	}
   4088 
   4089 	memset(&kd, 0, sizeof(kd));
   4090 	kd.common.rdclass = zone->rdclass;
   4091 	kd.common.rdtype = dns_rdatatype_keydata;
   4092 	ISC_LINK_INIT(&kd.common, link);
   4093 
   4094 	isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
   4095 
   4096 	CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata,
   4097 				   &kd, &rrdatabuf));
   4098 	/* Add rdata to zone. */
   4099 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata));
   4100 	*changed = true;
   4101 
   4102 	/* Refresh new keys from the zone apex as soon as possible. */
   4103 	set_refreshkeytimer(zone, &kd, now, true);
   4104 	return (ISC_R_SUCCESS);
   4105 
   4106 failure:
   4107 	return (result);
   4108 }
   4109 
   4110 /*
   4111  * Remove from the key zone all the KEYDATA records found in rdataset.
   4112  */
   4113 static isc_result_t
   4114 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4115 	       dns_name_t *name, dns_rdataset_t *rdataset) {
   4116 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4117 	isc_result_t result, uresult;
   4118 
   4119 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4120 	     result = dns_rdataset_next(rdataset))
   4121 	{
   4122 		dns_rdata_reset(&rdata);
   4123 		dns_rdataset_current(rdataset, &rdata);
   4124 		uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0,
   4125 					&rdata);
   4126 		if (uresult != ISC_R_SUCCESS) {
   4127 			return (uresult);
   4128 		}
   4129 	}
   4130 	if (result == ISC_R_NOMORE) {
   4131 		result = ISC_R_SUCCESS;
   4132 	}
   4133 	return (result);
   4134 }
   4135 
   4136 /*
   4137  * Compute the DNSSEC key ID for a DNSKEY record.
   4138  */
   4139 static isc_result_t
   4140 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
   4141 	    dns_keytag_t *tag) {
   4142 	isc_result_t result;
   4143 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4144 	unsigned char data[4096];
   4145 	isc_buffer_t buffer;
   4146 	dst_key_t *dstkey = NULL;
   4147 
   4148 	isc_buffer_init(&buffer, data, sizeof(data));
   4149 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4150 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4151 
   4152 	result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
   4153 	if (result == ISC_R_SUCCESS) {
   4154 		*tag = dst_key_id(dstkey);
   4155 		dst_key_free(&dstkey);
   4156 	}
   4157 
   4158 	return (result);
   4159 }
   4160 
   4161 /*
   4162  * Add key to the security roots.
   4163  */
   4164 static void
   4165 trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey,
   4166 	  bool initial) {
   4167 	isc_result_t result;
   4168 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4169 	unsigned char data[4096], digest[ISC_MAX_MD_SIZE];
   4170 	isc_buffer_t buffer;
   4171 	dns_keytable_t *sr = NULL;
   4172 	dns_rdata_ds_t ds;
   4173 
   4174 	result = dns_view_getsecroots(zone->view, &sr);
   4175 	if (result != ISC_R_SUCCESS) {
   4176 		return;
   4177 	}
   4178 
   4179 	/* Build DS record for key. */
   4180 	isc_buffer_init(&buffer, data, sizeof(data));
   4181 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4182 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4183 	CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest,
   4184 				  &ds));
   4185 	CHECK(dns_keytable_add(sr, true, initial, keyname, &ds));
   4186 
   4187 	dns_keytable_detach(&sr);
   4188 
   4189 failure:
   4190 	if (sr != NULL) {
   4191 		dns_keytable_detach(&sr);
   4192 	}
   4193 	return;
   4194 }
   4195 
   4196 /*
   4197  * Add a null key to the security roots for so that all queries
   4198  * to the zone will fail.
   4199  */
   4200 static void
   4201 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
   4202 	isc_result_t result;
   4203 	dns_keytable_t *sr = NULL;
   4204 
   4205 	result = dns_view_getsecroots(zone->view, &sr);
   4206 	if (result == ISC_R_SUCCESS) {
   4207 		dns_keytable_marksecure(sr, keyname);
   4208 		dns_keytable_detach(&sr);
   4209 	}
   4210 }
   4211 
   4212 /*
   4213  * Scan a set of KEYDATA records from the key zone.  The ones that are
   4214  * valid (i.e., the add holddown timer has expired) become trusted keys.
   4215  */
   4216 static void
   4217 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
   4218 	isc_result_t result;
   4219 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4220 	dns_rdata_keydata_t keydata;
   4221 	dns_rdata_dnskey_t dnskey;
   4222 	int trusted = 0, revoked = 0, pending = 0;
   4223 	isc_stdtime_t now;
   4224 	dns_keytable_t *sr = NULL;
   4225 
   4226 	isc_stdtime_get(&now);
   4227 
   4228 	result = dns_view_getsecroots(zone->view, &sr);
   4229 	if (result == ISC_R_SUCCESS) {
   4230 		dns_keytable_delete(sr, name);
   4231 		dns_keytable_detach(&sr);
   4232 	}
   4233 
   4234 	/* Now insert all the accepted trust anchors from this keydata set. */
   4235 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4236 	     result = dns_rdataset_next(rdataset))
   4237 	{
   4238 		dns_rdata_reset(&rdata);
   4239 		dns_rdataset_current(rdataset, &rdata);
   4240 
   4241 		/* Convert rdata to keydata. */
   4242 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   4243 		if (result == ISC_R_UNEXPECTEDEND) {
   4244 			continue;
   4245 		}
   4246 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4247 
   4248 		/* Set the key refresh timer to force a fast refresh. */
   4249 		set_refreshkeytimer(zone, &keydata, now, true);
   4250 
   4251 		/* If the removal timer is nonzero, this key was revoked. */
   4252 		if (keydata.removehd != 0) {
   4253 			revoked++;
   4254 			continue;
   4255 		}
   4256 
   4257 		/*
   4258 		 * If the add timer is still pending, this key is not
   4259 		 * trusted yet.
   4260 		 */
   4261 		if (now < keydata.addhd) {
   4262 			pending++;
   4263 			continue;
   4264 		}
   4265 
   4266 		/* Convert keydata to dnskey. */
   4267 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   4268 
   4269 		/* Add to keytables. */
   4270 		trusted++;
   4271 		trust_key(zone, name, &dnskey, (keydata.addhd == 0));
   4272 	}
   4273 
   4274 	if (trusted == 0 && pending != 0) {
   4275 		char namebuf[DNS_NAME_FORMATSIZE];
   4276 		dns_name_format(name, namebuf, sizeof namebuf);
   4277 		dnssec_log(zone, ISC_LOG_ERROR,
   4278 			   "No valid trust anchors for '%s'!", namebuf);
   4279 		dnssec_log(zone, ISC_LOG_ERROR,
   4280 			   "%d key(s) revoked, %d still pending", revoked,
   4281 			   pending);
   4282 		dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail",
   4283 			   namebuf);
   4284 		fail_secure(zone, name);
   4285 	}
   4286 }
   4287 
   4288 static isc_result_t
   4289 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
   4290 	     dns_diff_t *diff) {
   4291 	dns_diff_t temp_diff;
   4292 	isc_result_t result;
   4293 
   4294 	/*
   4295 	 * Create a singleton diff.
   4296 	 */
   4297 	dns_diff_init(diff->mctx, &temp_diff);
   4298 	ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
   4299 
   4300 	/*
   4301 	 * Apply it to the database.
   4302 	 */
   4303 	result = dns_diff_apply(&temp_diff, db, ver);
   4304 	ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
   4305 	if (result != ISC_R_SUCCESS) {
   4306 		dns_difftuple_free(tuple);
   4307 		return (result);
   4308 	}
   4309 
   4310 	/*
   4311 	 * Merge it into the current pending journal entry.
   4312 	 */
   4313 	dns_diff_appendminimal(diff, tuple);
   4314 
   4315 	/*
   4316 	 * Do not clear temp_diff.
   4317 	 */
   4318 	return (ISC_R_SUCCESS);
   4319 }
   4320 
   4321 static isc_result_t
   4322 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4323 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
   4324 	      dns_rdata_t *rdata) {
   4325 	dns_difftuple_t *tuple = NULL;
   4326 	isc_result_t result;
   4327 	result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple);
   4328 	if (result != ISC_R_SUCCESS) {
   4329 		return (result);
   4330 	}
   4331 	return (do_one_tuple(&tuple, db, ver, diff));
   4332 }
   4333 
   4334 static isc_result_t
   4335 update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4336 		  dns_diff_t *diff, isc_mem_t *mctx,
   4337 		  dns_updatemethod_t method) {
   4338 	dns_difftuple_t *deltuple = NULL;
   4339 	dns_difftuple_t *addtuple = NULL;
   4340 	uint32_t serial;
   4341 	isc_result_t result;
   4342 	dns_updatemethod_t used = dns_updatemethod_none;
   4343 
   4344 	INSIST(method != dns_updatemethod_none);
   4345 
   4346 	CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
   4347 	CHECK(dns_difftuple_copy(deltuple, &addtuple));
   4348 	addtuple->op = DNS_DIFFOP_ADD;
   4349 
   4350 	serial = dns_soa_getserial(&addtuple->rdata);
   4351 	serial = dns_update_soaserial(serial, method, &used);
   4352 	if (method != used) {
   4353 		dns_zone_log(zone, ISC_LOG_WARNING,
   4354 			     "update_soa_serial:new serial would be lower than "
   4355 			     "old serial, using increment method instead");
   4356 	}
   4357 	dns_soa_setserial(serial, &addtuple->rdata);
   4358 	CHECK(do_one_tuple(&deltuple, db, ver, diff));
   4359 	CHECK(do_one_tuple(&addtuple, db, ver, diff));
   4360 	result = ISC_R_SUCCESS;
   4361 
   4362 failure:
   4363 	if (addtuple != NULL) {
   4364 		dns_difftuple_free(&addtuple);
   4365 	}
   4366 	if (deltuple != NULL) {
   4367 		dns_difftuple_free(&deltuple);
   4368 	}
   4369 	return (result);
   4370 }
   4371 
   4372 /*
   4373  * Write all transactions in 'diff' to the zone journal file.
   4374  */
   4375 static isc_result_t
   4376 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial,
   4377 	     const char *caller) {
   4378 	const char me[] = "zone_journal";
   4379 	const char *journalfile;
   4380 	isc_result_t result = ISC_R_SUCCESS;
   4381 	dns_journal_t *journal = NULL;
   4382 	unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE;
   4383 
   4384 	ENTER;
   4385 	journalfile = dns_zone_getjournal(zone);
   4386 	if (journalfile != NULL) {
   4387 		result = dns_journal_open(zone->mctx, journalfile, mode,
   4388 					  &journal);
   4389 		if (result != ISC_R_SUCCESS) {
   4390 			dns_zone_log(zone, ISC_LOG_ERROR,
   4391 				     "%s:dns_journal_open -> %s", caller,
   4392 				     dns_result_totext(result));
   4393 			return (result);
   4394 		}
   4395 
   4396 		if (sourceserial != NULL) {
   4397 			dns_journal_set_sourceserial(journal, *sourceserial);
   4398 		}
   4399 
   4400 		result = dns_journal_write_transaction(journal, diff);
   4401 		if (result != ISC_R_SUCCESS) {
   4402 			dns_zone_log(zone, ISC_LOG_ERROR,
   4403 				     "%s:dns_journal_write_transaction -> %s",
   4404 				     caller, dns_result_totext(result));
   4405 		}
   4406 		dns_journal_destroy(&journal);
   4407 	}
   4408 
   4409 	return (result);
   4410 }
   4411 
   4412 /*
   4413  * Create an SOA record for a newly-created zone
   4414  */
   4415 static isc_result_t
   4416 add_soa(dns_zone_t *zone, dns_db_t *db) {
   4417 	isc_result_t result;
   4418 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4419 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   4420 	dns_dbversion_t *ver = NULL;
   4421 	dns_diff_t diff;
   4422 
   4423 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
   4424 
   4425 	dns_diff_init(zone->mctx, &diff);
   4426 	result = dns_db_newversion(db, &ver);
   4427 	if (result != ISC_R_SUCCESS) {
   4428 		dns_zone_log(zone, ISC_LOG_ERROR,
   4429 			     "add_soa:dns_db_newversion -> %s",
   4430 			     dns_result_totext(result));
   4431 		goto failure;
   4432 	}
   4433 
   4434 	/* Build SOA record */
   4435 	result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
   4436 				    0, 0, 0, 0, 0, buf, &rdata);
   4437 	if (result != ISC_R_SUCCESS) {
   4438 		dns_zone_log(zone, ISC_LOG_ERROR,
   4439 			     "add_soa:dns_soa_buildrdata -> %s",
   4440 			     dns_result_totext(result));
   4441 		goto failure;
   4442 	}
   4443 
   4444 	result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0,
   4445 			       &rdata);
   4446 
   4447 failure:
   4448 	dns_diff_clear(&diff);
   4449 	if (ver != NULL) {
   4450 		dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS));
   4451 	}
   4452 
   4453 	INSIST(ver == NULL);
   4454 
   4455 	return (result);
   4456 }
   4457 
   4458 struct addifmissing_arg {
   4459 	dns_db_t *db;
   4460 	dns_dbversion_t *ver;
   4461 	dns_diff_t *diff;
   4462 	dns_zone_t *zone;
   4463 	bool *changed;
   4464 	isc_result_t result;
   4465 };
   4466 
   4467 static void
   4468 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode,
   4469 	     dns_name_t *keyname, void *arg) {
   4470 	dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
   4471 	dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
   4472 	dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
   4473 	dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
   4474 	bool *changed = ((struct addifmissing_arg *)arg)->changed;
   4475 	isc_result_t result;
   4476 	dns_fixedname_t fname;
   4477 
   4478 	UNUSED(keytable);
   4479 
   4480 	if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) {
   4481 		return;
   4482 	}
   4483 
   4484 	if (!dns_keynode_managed(keynode)) {
   4485 		return;
   4486 	}
   4487 
   4488 	/*
   4489 	 * If the keynode has no trust anchor set, return.
   4490 	 */
   4491 	if (!dns_keynode_dsset(keynode, NULL)) {
   4492 		return;
   4493 	}
   4494 
   4495 	/*
   4496 	 * Check whether there's already a KEYDATA entry for this name;
   4497 	 * if so, we don't need to add another.
   4498 	 */
   4499 	dns_fixedname_init(&fname);
   4500 	result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata,
   4501 			     DNS_DBFIND_NOWILD, 0, NULL,
   4502 			     dns_fixedname_name(&fname), NULL, NULL);
   4503 	if (result == ISC_R_SUCCESS) {
   4504 		return;
   4505 	}
   4506 
   4507 	/*
   4508 	 * Create the keydata.
   4509 	 */
   4510 	result = create_keydata(zone, db, ver, diff, keynode, keyname, changed);
   4511 	if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
   4512 		((struct addifmissing_arg *)arg)->result = result;
   4513 	}
   4514 }
   4515 
   4516 /*
   4517  * Synchronize the set of initializing keys found in managed-keys {}
   4518  * statements with the set of trust anchors found in the managed-keys.bind
   4519  * zone.  If a domain is no longer named in managed-keys, delete all keys
   4520  * from that domain from the key zone.	If a domain is configured as an
   4521  * initial-key in trust-anchors, but there are no references to it in the
   4522  * key zone, load the key zone with the initializing key(s) for that
   4523  * domain and schedule a key refresh. If a domain is configured as
   4524  * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key
   4525  * zone with the matching key, and schedule a key refresh.
   4526  */
   4527 static isc_result_t
   4528 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
   4529 	isc_result_t result = ISC_R_SUCCESS;
   4530 	bool changed = false;
   4531 	bool commit = false;
   4532 	dns_keynode_t *keynode = NULL;
   4533 	dns_view_t *view = zone->view;
   4534 	dns_keytable_t *sr = NULL;
   4535 	dns_dbversion_t *ver = NULL;
   4536 	dns_diff_t diff;
   4537 	dns_rriterator_t rrit;
   4538 	struct addifmissing_arg arg;
   4539 
   4540 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
   4541 
   4542 	dns_diff_init(zone->mctx, &diff);
   4543 
   4544 	CHECK(dns_view_getsecroots(view, &sr));
   4545 
   4546 	result = dns_db_newversion(db, &ver);
   4547 	if (result != ISC_R_SUCCESS) {
   4548 		dnssec_log(zone, ISC_LOG_ERROR,
   4549 			   "sync_keyzone:dns_db_newversion -> %s",
   4550 			   dns_result_totext(result));
   4551 		goto failure;
   4552 	}
   4553 
   4554 	/*
   4555 	 * Walk the zone DB.  If we find any keys whose names are no longer
   4556 	 * in trust-anchors, or which have been changed from initial to static,
   4557 	 * (meaning they are permanent and not RFC5011-maintained), delete
   4558 	 * them from the zone.  Otherwise call load_secroots(), which
   4559 	 * loads keys into secroots as appropriate.
   4560 	 */
   4561 	dns_rriterator_init(&rrit, db, ver, 0);
   4562 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   4563 	     result = dns_rriterator_nextrrset(&rrit))
   4564 	{
   4565 		dns_rdataset_t *rdataset = NULL;
   4566 		dns_name_t *rrname = NULL;
   4567 		uint32_t ttl;
   4568 
   4569 		dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL);
   4570 		if (!dns_rdataset_isassociated(rdataset)) {
   4571 			dns_rriterator_destroy(&rrit);
   4572 			goto failure;
   4573 		}
   4574 
   4575 		if (rdataset->type != dns_rdatatype_keydata) {
   4576 			continue;
   4577 		}
   4578 		/*
   4579 		 * Release db wrlock to prevent LOR reports against
   4580 		 * dns_keytable_forall() call below.
   4581 		 */
   4582 		dns_rriterator_pause(&rrit);
   4583 		result = dns_keytable_find(sr, rrname, &keynode);
   4584 		if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) {
   4585 			CHECK(delete_keydata(db, ver, &diff, rrname, rdataset));
   4586 			changed = true;
   4587 		} else {
   4588 			load_secroots(zone, rrname, rdataset);
   4589 		}
   4590 
   4591 		if (keynode != NULL) {
   4592 			dns_keytable_detachkeynode(sr, &keynode);
   4593 		}
   4594 	}
   4595 	dns_rriterator_destroy(&rrit);
   4596 
   4597 	/*
   4598 	 * Walk secroots to find any initial keys that aren't in
   4599 	 * the zone.  If we find any, add them to the zone directly.
   4600 	 * If any DS-style initial keys are found, refresh the key
   4601 	 * zone so that they'll be looked up.
   4602 	 */
   4603 	arg.db = db;
   4604 	arg.ver = ver;
   4605 	arg.result = ISC_R_SUCCESS;
   4606 	arg.diff = &diff;
   4607 	arg.zone = zone;
   4608 	arg.changed = &changed;
   4609 	dns_keytable_forall(sr, addifmissing, &arg);
   4610 	result = arg.result;
   4611 	if (changed) {
   4612 		/* Write changes to journal file. */
   4613 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   4614 					zone->updatemethod));
   4615 		CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
   4616 
   4617 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   4618 		zone_needdump(zone, 30);
   4619 		commit = true;
   4620 	}
   4621 
   4622 failure:
   4623 	if (result != ISC_R_SUCCESS && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4624 	{
   4625 		dnssec_log(zone, ISC_LOG_ERROR,
   4626 			   "unable to synchronize managed keys: %s",
   4627 			   dns_result_totext(result));
   4628 		isc_time_settoepoch(&zone->refreshkeytime);
   4629 	}
   4630 	if (keynode != NULL) {
   4631 		dns_keytable_detachkeynode(sr, &keynode);
   4632 	}
   4633 	if (sr != NULL) {
   4634 		dns_keytable_detach(&sr);
   4635 	}
   4636 	if (ver != NULL) {
   4637 		dns_db_closeversion(db, &ver, commit);
   4638 	}
   4639 	dns_diff_clear(&diff);
   4640 
   4641 	INSIST(ver == NULL);
   4642 
   4643 	return (result);
   4644 }
   4645 
   4646 isc_result_t
   4647 dns_zone_synckeyzone(dns_zone_t *zone) {
   4648 	isc_result_t result;
   4649 	dns_db_t *db = NULL;
   4650 
   4651 	if (zone->type != dns_zone_key) {
   4652 		return (DNS_R_BADZONE);
   4653 	}
   4654 
   4655 	CHECK(dns_zone_getdb(zone, &db));
   4656 
   4657 	LOCK_ZONE(zone);
   4658 	result = sync_keyzone(zone, db);
   4659 	UNLOCK_ZONE(zone);
   4660 
   4661 failure:
   4662 	if (db != NULL) {
   4663 		dns_db_detach(&db);
   4664 	}
   4665 	return (result);
   4666 }
   4667 
   4668 static void
   4669 maybe_send_secure(dns_zone_t *zone) {
   4670 	isc_result_t result;
   4671 
   4672 	/*
   4673 	 * We've finished loading, or else failed to load, an inline-signing
   4674 	 * 'secure' zone.  We now need information about the status of the
   4675 	 * 'raw' zone.  If we failed to load, then we need it to send a
   4676 	 * copy of its database; if we succeeded, we need it to send its
   4677 	 * serial number so that we can sync with it.  If it has not yet
   4678 	 * loaded, we set a flag so that it will send the necessary
   4679 	 * information when it has finished loading.
   4680 	 */
   4681 	if (zone->raw->db != NULL) {
   4682 		if (zone->db != NULL) {
   4683 			uint32_t serial;
   4684 			unsigned int soacount;
   4685 
   4686 			result = zone_get_from_db(zone->raw, zone->raw->db,
   4687 						  NULL, &soacount, &serial,
   4688 						  NULL, NULL, NULL, NULL, NULL);
   4689 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   4690 				zone_send_secureserial(zone->raw, serial);
   4691 			}
   4692 		} else {
   4693 			zone_send_securedb(zone->raw, zone->raw->db);
   4694 		}
   4695 	} else {
   4696 		DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
   4697 	}
   4698 }
   4699 
   4700 static bool
   4701 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
   4702 	isc_result_t result;
   4703 	bool answer = false;
   4704 	dns_diff_t diff;
   4705 
   4706 	dns_diff_init(mctx, &diff);
   4707 	result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
   4708 	if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) {
   4709 		answer = true;
   4710 	}
   4711 	dns_diff_clear(&diff);
   4712 	return (answer);
   4713 }
   4714 
   4715 /*
   4716  * The zone is presumed to be locked.
   4717  * If this is a inline_raw zone the secure version is also locked.
   4718  */
   4719 static isc_result_t
   4720 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
   4721 	      isc_result_t result) {
   4722 	unsigned int soacount = 0;
   4723 	unsigned int nscount = 0;
   4724 	unsigned int errors = 0;
   4725 	uint32_t serial, oldserial, refresh, retry, expire, minimum;
   4726 	isc_time_t now;
   4727 	bool needdump = false;
   4728 	bool fixjournal = false;
   4729 	bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4730 	bool nomaster = false;
   4731 	bool had_db = false;
   4732 	dns_include_t *inc;
   4733 	bool is_dynamic = false;
   4734 
   4735 	INSIST(LOCKED_ZONE(zone));
   4736 	if (inline_raw(zone)) {
   4737 		INSIST(LOCKED_ZONE(zone->secure));
   4738 	}
   4739 
   4740 	TIME_NOW(&now);
   4741 
   4742 	/*
   4743 	 * Initiate zone transfer?  We may need a error code that
   4744 	 * indicates that the "permanent" form does not exist.
   4745 	 * XXX better error feedback to log.
   4746 	 */
   4747 	if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
   4748 		if (zone->type == dns_zone_slave ||
   4749 		    zone->type == dns_zone_mirror ||
   4750 		    zone->type == dns_zone_stub ||
   4751 		    (zone->type == dns_zone_redirect && zone->masters == NULL))
   4752 		{
   4753 			if (result == ISC_R_FILENOTFOUND) {
   4754 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4755 					      ISC_LOG_DEBUG(1),
   4756 					      "no master file");
   4757 			} else if (result != DNS_R_NOMASTERFILE) {
   4758 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4759 					      ISC_LOG_ERROR,
   4760 					      "loading from master file %s "
   4761 					      "failed: %s",
   4762 					      zone->masterfile,
   4763 					      dns_result_totext(result));
   4764 			}
   4765 		} else if (zone->type == dns_zone_master &&
   4766 			   inline_secure(zone) && result == ISC_R_FILENOTFOUND)
   4767 		{
   4768 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4769 				      ISC_LOG_DEBUG(1),
   4770 				      "no master file, requesting db");
   4771 			maybe_send_secure(zone);
   4772 		} else {
   4773 			int level = ISC_LOG_ERROR;
   4774 			if (zone->type == dns_zone_key &&
   4775 			    result == ISC_R_FILENOTFOUND) {
   4776 				level = ISC_LOG_DEBUG(1);
   4777 			}
   4778 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level,
   4779 				      "loading from master file %s failed: %s",
   4780 				      zone->masterfile,
   4781 				      dns_result_totext(result));
   4782 			nomaster = true;
   4783 		}
   4784 
   4785 		if (zone->type != dns_zone_key) {
   4786 			goto cleanup;
   4787 		}
   4788 	}
   4789 
   4790 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
   4791 		      "number of nodes in database: %u", dns_db_nodecount(db));
   4792 
   4793 	if (result == DNS_R_SEENINCLUDE) {
   4794 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4795 	} else {
   4796 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4797 	}
   4798 
   4799 	/*
   4800 	 * If there's no master file for a key zone, then the zone is new:
   4801 	 * create an SOA record.  (We do this now, instead of later, so that
   4802 	 * if there happens to be a journal file, we can roll forward from
   4803 	 * a sane starting point.)
   4804 	 */
   4805 	if (nomaster && zone->type == dns_zone_key) {
   4806 		result = add_soa(zone, db);
   4807 		if (result != ISC_R_SUCCESS) {
   4808 			goto cleanup;
   4809 		}
   4810 	}
   4811 
   4812 	/*
   4813 	 * Apply update log, if any, on initial load.
   4814 	 */
   4815 	if (zone->journal != NULL &&
   4816 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
   4817 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4818 	{
   4819 		result = zone_journal_rollforward(zone, db, &needdump,
   4820 						  &fixjournal);
   4821 		if (result != ISC_R_SUCCESS) {
   4822 			goto cleanup;
   4823 		}
   4824 	}
   4825 
   4826 	/*
   4827 	 * Obtain ns, soa and cname counts for top of zone.
   4828 	 */
   4829 	INSIST(db != NULL);
   4830 	result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
   4831 				  &refresh, &retry, &expire, &minimum, &errors);
   4832 	if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
   4833 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   4834 			      "could not find NS and/or SOA records");
   4835 	}
   4836 
   4837 	/*
   4838 	 * Process any queued NSEC3PARAM change requests. Only for dynamic
   4839 	 * zones, an inline-signing zone will perform this action when
   4840 	 * receiving the secure db (receive_secure_db).
   4841 	 */
   4842 	is_dynamic = dns_zone_isdynamic(zone, true);
   4843 	if (is_dynamic) {
   4844 		isc_event_t *setnsec3param_event;
   4845 		dns_zone_t *dummy;
   4846 
   4847 		while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   4848 			setnsec3param_event =
   4849 				ISC_LIST_HEAD(zone->setnsec3param_queue);
   4850 			ISC_LIST_UNLINK(zone->setnsec3param_queue,
   4851 					setnsec3param_event, ev_link);
   4852 			dummy = NULL;
   4853 			zone_iattach(zone, &dummy);
   4854 			isc_task_send(zone->task, &setnsec3param_event);
   4855 		}
   4856 	}
   4857 
   4858 	/*
   4859 	 * Check to make sure the journal is up to date, and remove the
   4860 	 * journal file if it isn't, as we wouldn't be able to apply
   4861 	 * updates otherwise.
   4862 	 */
   4863 	if (zone->journal != NULL && is_dynamic &&
   4864 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
   4865 	{
   4866 		uint32_t jserial;
   4867 		dns_journal_t *journal = NULL;
   4868 		bool empty = false;
   4869 
   4870 		result = dns_journal_open(zone->mctx, zone->journal,
   4871 					  DNS_JOURNAL_READ, &journal);
   4872 		if (result == ISC_R_SUCCESS) {
   4873 			jserial = dns_journal_last_serial(journal);
   4874 			empty = dns_journal_empty(journal);
   4875 			dns_journal_destroy(&journal);
   4876 		} else {
   4877 			jserial = serial;
   4878 			result = ISC_R_SUCCESS;
   4879 		}
   4880 
   4881 		if (jserial != serial) {
   4882 			if (!empty) {
   4883 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4884 					      ISC_LOG_INFO,
   4885 					      "journal file is out of date: "
   4886 					      "removing journal file");
   4887 			}
   4888 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   4889 				char strbuf[ISC_STRERRORSIZE];
   4890 				strerror_r(errno, strbuf, sizeof(strbuf));
   4891 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   4892 					      DNS_LOGMODULE_ZONE,
   4893 					      ISC_LOG_WARNING,
   4894 					      "unable to remove journal "
   4895 					      "'%s': '%s'",
   4896 					      zone->journal, strbuf);
   4897 			}
   4898 		}
   4899 	}
   4900 
   4901 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   4902 		      "loaded; checking validity");
   4903 
   4904 	/*
   4905 	 * Master / Slave / Mirror / Stub zones require both NS and SOA records
   4906 	 * at the top of the zone.
   4907 	 */
   4908 
   4909 	switch (zone->type) {
   4910 	case dns_zone_dlz:
   4911 	case dns_zone_master:
   4912 	case dns_zone_slave:
   4913 	case dns_zone_mirror:
   4914 	case dns_zone_stub:
   4915 	case dns_zone_redirect:
   4916 		if (soacount != 1) {
   4917 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4918 				      ISC_LOG_ERROR, "has %d SOA records",
   4919 				      soacount);
   4920 			result = DNS_R_BADZONE;
   4921 		}
   4922 		if (nscount == 0) {
   4923 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4924 				      ISC_LOG_ERROR, "has no NS records");
   4925 			result = DNS_R_BADZONE;
   4926 		}
   4927 		if (result != ISC_R_SUCCESS) {
   4928 			goto cleanup;
   4929 		}
   4930 		if (zone->type == dns_zone_master && errors != 0) {
   4931 			result = DNS_R_BADZONE;
   4932 			goto cleanup;
   4933 		}
   4934 		if (zone->type != dns_zone_stub &&
   4935 		    zone->type != dns_zone_redirect) {
   4936 			result = check_nsec3param(zone, db);
   4937 			if (result != ISC_R_SUCCESS) {
   4938 				goto cleanup;
   4939 			}
   4940 		}
   4941 		if (zone->type == dns_zone_master &&
   4942 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
   4943 		    !integrity_checks(zone, db))
   4944 		{
   4945 			result = DNS_R_BADZONE;
   4946 			goto cleanup;
   4947 		}
   4948 		if (zone->type == dns_zone_master &&
   4949 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
   4950 		    !zone_check_dup(zone, db))
   4951 		{
   4952 			result = DNS_R_BADZONE;
   4953 			goto cleanup;
   4954 		}
   4955 
   4956 		if (zone->type == dns_zone_master) {
   4957 			result = dns_zone_cdscheck(zone, db, NULL);
   4958 			if (result != ISC_R_SUCCESS) {
   4959 				dns_zone_log(zone, ISC_LOG_ERROR,
   4960 					     "CDS/CDNSKEY consistency checks "
   4961 					     "failed");
   4962 				goto cleanup;
   4963 			}
   4964 		}
   4965 
   4966 		result = dns_zone_verifydb(zone, db, NULL);
   4967 		if (result != ISC_R_SUCCESS) {
   4968 			goto cleanup;
   4969 		}
   4970 
   4971 		if (zone->db != NULL) {
   4972 			unsigned int oldsoacount;
   4973 
   4974 			/*
   4975 			 * This is checked in zone_replacedb() for slave zones
   4976 			 * as they don't reload from disk.
   4977 			 */
   4978 			result = zone_get_from_db(zone, zone->db, NULL,
   4979 						  &oldsoacount, &oldserial,
   4980 						  NULL, NULL, NULL, NULL, NULL);
   4981 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4982 			RUNTIME_CHECK(soacount > 0U);
   4983 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   4984 			    !isc_serial_gt(serial, oldserial))
   4985 			{
   4986 				uint32_t serialmin, serialmax;
   4987 
   4988 				INSIST(zone->type == dns_zone_master);
   4989 				INSIST(zone->raw == NULL);
   4990 
   4991 				if (serial == oldserial &&
   4992 				    zone_unchanged(zone->db, db, zone->mctx)) {
   4993 					dns_zone_logc(zone,
   4994 						      DNS_LOGCATEGORY_ZONELOAD,
   4995 						      ISC_LOG_INFO,
   4996 						      "ixfr-from-differences: "
   4997 						      "unchanged");
   4998 					goto done;
   4999 				}
   5000 
   5001 				serialmin = (oldserial + 1) & 0xffffffffU;
   5002 				serialmax = (oldserial + 0x7fffffffU) &
   5003 					    0xffffffffU;
   5004 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5005 					      ISC_LOG_ERROR,
   5006 					      "ixfr-from-differences: "
   5007 					      "new serial (%u) out of range "
   5008 					      "[%u - %u]",
   5009 					      serial, serialmin, serialmax);
   5010 				result = DNS_R_BADZONE;
   5011 				goto cleanup;
   5012 			} else if (!isc_serial_ge(serial, oldserial)) {
   5013 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5014 					      ISC_LOG_ERROR,
   5015 					      "zone serial (%u/%u) has gone "
   5016 					      "backwards",
   5017 					      serial, oldserial);
   5018 			} else if (serial == oldserial && !hasinclude &&
   5019 				   strcmp(zone->db_argv[0], "_builtin") != 0)
   5020 			{
   5021 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5022 					      ISC_LOG_ERROR,
   5023 					      "zone serial (%u) unchanged. "
   5024 					      "zone may fail to transfer "
   5025 					      "to slaves.",
   5026 					      serial);
   5027 			}
   5028 		}
   5029 
   5030 		if (zone->type == dns_zone_master &&
   5031 		    (zone->update_acl != NULL || zone->ssutable != NULL) &&
   5032 		    dns_zone_getsigresigninginterval(zone) < (3 * refresh) &&
   5033 		    dns_db_issecure(db))
   5034 		{
   5035 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5036 				      ISC_LOG_WARNING,
   5037 				      "sig-re-signing-interval less than "
   5038 				      "3 * refresh.");
   5039 		}
   5040 
   5041 		zone->refresh = RANGE(refresh, zone->minrefresh,
   5042 				      zone->maxrefresh);
   5043 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   5044 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   5045 				     DNS_MAX_EXPIRE);
   5046 		zone->minimum = minimum;
   5047 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   5048 
   5049 		if (zone->type == dns_zone_slave ||
   5050 		    zone->type == dns_zone_mirror ||
   5051 		    zone->type == dns_zone_stub ||
   5052 		    (zone->type == dns_zone_redirect && zone->masters != NULL))
   5053 		{
   5054 			isc_time_t t;
   5055 			uint32_t delay;
   5056 
   5057 			result = isc_file_getmodtime(zone->journal, &t);
   5058 			if (result != ISC_R_SUCCESS) {
   5059 				result = isc_file_getmodtime(zone->masterfile,
   5060 							     &t);
   5061 			}
   5062 			if (result == ISC_R_SUCCESS) {
   5063 				DNS_ZONE_TIME_ADD(&t, zone->expire,
   5064 						  &zone->expiretime);
   5065 			} else {
   5066 				DNS_ZONE_TIME_ADD(&now, zone->retry,
   5067 						  &zone->expiretime);
   5068 			}
   5069 
   5070 			delay = (zone->retry -
   5071 				 isc_random_uniform((zone->retry * 3) / 4));
   5072 			DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
   5073 			if (isc_time_compare(&zone->refreshtime,
   5074 					     &zone->expiretime) >= 0) {
   5075 				zone->refreshtime = now;
   5076 			}
   5077 		}
   5078 
   5079 		break;
   5080 
   5081 	case dns_zone_key:
   5082 		result = sync_keyzone(zone, db);
   5083 		if (result != ISC_R_SUCCESS) {
   5084 			goto cleanup;
   5085 		}
   5086 		break;
   5087 
   5088 	default:
   5089 		UNEXPECTED_ERROR(__FILE__, __LINE__, "unexpected zone type %d",
   5090 				 zone->type);
   5091 		result = ISC_R_UNEXPECTED;
   5092 		goto cleanup;
   5093 	}
   5094 
   5095 	/*
   5096 	 * Check for weak DNSKEY's.
   5097 	 */
   5098 	if (zone->type == dns_zone_master) {
   5099 		zone_check_dnskeys(zone, db);
   5100 	}
   5101 
   5102 	/*
   5103 	 * Schedule DNSSEC key refresh.
   5104 	 */
   5105 	if (zone->type == dns_zone_master &&
   5106 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   5107 	{
   5108 		zone->refreshkeytime = now;
   5109 	}
   5110 
   5111 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   5112 	if (zone->db != NULL) {
   5113 		had_db = true;
   5114 		result = zone_replacedb(zone, db, false);
   5115 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5116 		if (result != ISC_R_SUCCESS) {
   5117 			goto cleanup;
   5118 		}
   5119 	} else {
   5120 		zone_attachdb(zone, db);
   5121 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5122 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED |
   5123 					       DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   5124 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
   5125 		    inline_raw(zone)) {
   5126 			if (zone->secure->db == NULL) {
   5127 				zone_send_securedb(zone, db);
   5128 			} else {
   5129 				zone_send_secureserial(zone, serial);
   5130 			}
   5131 		}
   5132 	}
   5133 
   5134 	/*
   5135 	 * Finished loading inline-signing zone; need to get status
   5136 	 * from the raw side now.
   5137 	 */
   5138 	if (zone->type == dns_zone_master && inline_secure(zone)) {
   5139 		maybe_send_secure(zone);
   5140 	}
   5141 
   5142 	result = ISC_R_SUCCESS;
   5143 
   5144 	if (fixjournal) {
   5145 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FIXJOURNAL);
   5146 		zone_journal_compact(zone, zone->db, 0);
   5147 	}
   5148 	if (needdump) {
   5149 		if (zone->type == dns_zone_key) {
   5150 			zone_needdump(zone, 30);
   5151 		} else {
   5152 			zone_needdump(zone, DNS_DUMP_DELAY);
   5153 		}
   5154 	}
   5155 
   5156 	if (zone->task != NULL) {
   5157 		if (zone->type == dns_zone_master) {
   5158 			set_resigntime(zone);
   5159 			resume_signingwithkey(zone);
   5160 			resume_addnsec3chain(zone);
   5161 		}
   5162 
   5163 		is_dynamic = dns_zone_isdynamic(zone, false);
   5164 		if (zone->type == dns_zone_master &&
   5165 		    !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
   5166 		    is_dynamic && dns_db_issecure(db))
   5167 		{
   5168 			dns_name_t *name;
   5169 			dns_fixedname_t fixed;
   5170 			dns_rdataset_t next;
   5171 
   5172 			dns_rdataset_init(&next);
   5173 			name = dns_fixedname_initname(&fixed);
   5174 
   5175 			result = dns_db_getsigningtime(db, &next, name);
   5176 			if (result == ISC_R_SUCCESS) {
   5177 				isc_stdtime_t timenow;
   5178 				char namebuf[DNS_NAME_FORMATSIZE];
   5179 				char typebuf[DNS_RDATATYPE_FORMATSIZE];
   5180 
   5181 				isc_stdtime_get(&timenow);
   5182 				dns_name_format(name, namebuf, sizeof(namebuf));
   5183 				dns_rdatatype_format(next.covers, typebuf,
   5184 						     sizeof(typebuf));
   5185 				dnssec_log(
   5186 					zone, ISC_LOG_DEBUG(3),
   5187 					"next resign: %s/%s "
   5188 					"in %d seconds",
   5189 					namebuf, typebuf,
   5190 					next.resign - timenow -
   5191 						dns_zone_getsigresigninginterval(
   5192 							zone));
   5193 				dns_rdataset_disassociate(&next);
   5194 			} else {
   5195 				dnssec_log(zone, ISC_LOG_WARNING,
   5196 					   "signed dynamic zone has no "
   5197 					   "resign event scheduled");
   5198 			}
   5199 		}
   5200 
   5201 		zone_settimer(zone, &now);
   5202 	}
   5203 
   5204 	/*
   5205 	 * Clear old include list.
   5206 	 */
   5207 	for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL;
   5208 	     inc = ISC_LIST_HEAD(zone->includes))
   5209 	{
   5210 		ISC_LIST_UNLINK(zone->includes, inc, link);
   5211 		isc_mem_free(zone->mctx, inc->name);
   5212 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5213 	}
   5214 	zone->nincludes = 0;
   5215 
   5216 	/*
   5217 	 * Transfer new include list.
   5218 	 */
   5219 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5220 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5221 	{
   5222 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5223 		ISC_LIST_APPEND(zone->includes, inc, link);
   5224 		zone->nincludes++;
   5225 	}
   5226 
   5227 	if (!dns_db_ispersistent(db)) {
   5228 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5229 			      "loaded serial %u%s", serial,
   5230 			      dns_db_issecure(db) ? " (DNSSEC signed)" : "");
   5231 	}
   5232 
   5233 	if (!had_db && zone->type == dns_zone_mirror) {
   5234 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5235 			      "mirror zone is now in use");
   5236 	}
   5237 
   5238 	zone->loadtime = loadtime;
   5239 	goto done;
   5240 
   5241 cleanup:
   5242 	if (zone->type == dns_zone_key && result != ISC_R_SUCCESS) {
   5243 		dnssec_log(zone, ISC_LOG_ERROR,
   5244 			   "failed to initialize managed-keys (%s): "
   5245 			   "DNSSEC validation is at risk",
   5246 			   isc_result_totext(result));
   5247 	}
   5248 
   5249 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5250 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5251 	{
   5252 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5253 		isc_mem_free(zone->mctx, inc->name);
   5254 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5255 	}
   5256 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   5257 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   5258 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   5259 	{
   5260 		if (result != ISC_R_NOMEMORY) {
   5261 			if (zone->journal != NULL) {
   5262 				zone_saveunique(zone, zone->journal,
   5263 						"jn-XXXXXXXX");
   5264 			}
   5265 			if (zone->masterfile != NULL) {
   5266 				zone_saveunique(zone, zone->masterfile,
   5267 						"db-XXXXXXXX");
   5268 			}
   5269 		}
   5270 
   5271 		/* Mark the zone for immediate refresh. */
   5272 		zone->refreshtime = now;
   5273 		if (zone->task != NULL) {
   5274 			zone_settimer(zone, &now);
   5275 		}
   5276 		result = ISC_R_SUCCESS;
   5277 	} else if (zone->type == dns_zone_master ||
   5278 		   zone->type == dns_zone_redirect) {
   5279 		if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
   5280 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5281 				      ISC_LOG_ERROR,
   5282 				      "not loaded due to errors.");
   5283 		} else if (zone->type == dns_zone_master) {
   5284 			result = ISC_R_SUCCESS;
   5285 		}
   5286 	}
   5287 
   5288 done:
   5289 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   5290 	/*
   5291 	 * If this is an inline-signed zone and we were called for the raw
   5292 	 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone
   5293 	 * as well, but only if this is a reload, not an initial zone load: in
   5294 	 * the former case, zone_postload() will not be run for the secure
   5295 	 * zone; in the latter case, it will be.  Check which case we are
   5296 	 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the
   5297 	 * secure zone: if it is set, this must be a reload.
   5298 	 */
   5299 	if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
   5300 	{
   5301 		DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
   5302 		/*
   5303 		 * Re-start zone maintenance if it had been stalled
   5304 		 * due to DNS_ZONEFLG_LOADPENDING being set when
   5305 		 * zone_maintenance was called.
   5306 		 */
   5307 		if (zone->secure->task != NULL) {
   5308 			zone_settimer(zone->secure, &now);
   5309 		}
   5310 	}
   5311 
   5312 	zone_debuglog(zone, "zone_postload", 99, "done");
   5313 
   5314 	return (result);
   5315 }
   5316 
   5317 static bool
   5318 exit_check(dns_zone_t *zone) {
   5319 	REQUIRE(LOCKED_ZONE(zone));
   5320 
   5321 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
   5322 	    isc_refcount_current(&zone->irefs) == 0)
   5323 	{
   5324 		/*
   5325 		 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
   5326 		 */
   5327 		INSIST(isc_refcount_current(&zone->erefs) == 0);
   5328 		return (true);
   5329 	}
   5330 	return (false);
   5331 }
   5332 
   5333 static bool
   5334 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   5335 	      dns_name_t *name, bool logit) {
   5336 	isc_result_t result;
   5337 	char namebuf[DNS_NAME_FORMATSIZE];
   5338 	char altbuf[DNS_NAME_FORMATSIZE];
   5339 	dns_fixedname_t fixed;
   5340 	dns_name_t *foundname;
   5341 	int level;
   5342 
   5343 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) {
   5344 		return (true);
   5345 	}
   5346 
   5347 	if (zone->type == dns_zone_master) {
   5348 		level = ISC_LOG_ERROR;
   5349 	} else {
   5350 		level = ISC_LOG_WARNING;
   5351 	}
   5352 
   5353 	foundname = dns_fixedname_initname(&fixed);
   5354 
   5355 	result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL,
   5356 			     foundname, NULL, NULL);
   5357 	if (result == ISC_R_SUCCESS) {
   5358 		return (true);
   5359 	}
   5360 
   5361 	if (result == DNS_R_NXRRSET) {
   5362 		result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0,
   5363 				     0, NULL, foundname, NULL, NULL);
   5364 		if (result == ISC_R_SUCCESS) {
   5365 			return (true);
   5366 		}
   5367 	}
   5368 
   5369 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   5370 	    result == DNS_R_EMPTYNAME)
   5371 	{
   5372 		if (logit) {
   5373 			dns_name_format(name, namebuf, sizeof namebuf);
   5374 			dns_zone_log(zone, level,
   5375 				     "NS '%s' has no address "
   5376 				     "records (A or AAAA)",
   5377 				     namebuf);
   5378 		}
   5379 		return (false);
   5380 	}
   5381 
   5382 	if (result == DNS_R_CNAME) {
   5383 		if (logit) {
   5384 			dns_name_format(name, namebuf, sizeof namebuf);
   5385 			dns_zone_log(zone, level,
   5386 				     "NS '%s' is a CNAME "
   5387 				     "(illegal)",
   5388 				     namebuf);
   5389 		}
   5390 		return (false);
   5391 	}
   5392 
   5393 	if (result == DNS_R_DNAME) {
   5394 		if (logit) {
   5395 			dns_name_format(name, namebuf, sizeof namebuf);
   5396 			dns_name_format(foundname, altbuf, sizeof altbuf);
   5397 			dns_zone_log(zone, level,
   5398 				     "NS '%s' is below a DNAME "
   5399 				     "'%s' (illegal)",
   5400 				     namebuf, altbuf);
   5401 		}
   5402 		return (false);
   5403 	}
   5404 
   5405 	return (true);
   5406 }
   5407 
   5408 static isc_result_t
   5409 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   5410 		 dns_dbversion_t *version, unsigned int *nscount,
   5411 		 unsigned int *errors, bool logit) {
   5412 	isc_result_t result;
   5413 	unsigned int count = 0;
   5414 	unsigned int ecount = 0;
   5415 	dns_rdataset_t rdataset;
   5416 	dns_rdata_t rdata;
   5417 	dns_rdata_ns_t ns;
   5418 
   5419 	dns_rdataset_init(&rdataset);
   5420 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
   5421 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5422 	if (result == ISC_R_NOTFOUND) {
   5423 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5424 		goto success;
   5425 	}
   5426 	if (result != ISC_R_SUCCESS) {
   5427 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5428 		goto invalidate_rdataset;
   5429 	}
   5430 
   5431 	result = dns_rdataset_first(&rdataset);
   5432 	while (result == ISC_R_SUCCESS) {
   5433 		if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
   5434 		    (zone->type == dns_zone_master ||
   5435 		     zone->type == dns_zone_slave ||
   5436 		     zone->type == dns_zone_mirror))
   5437 		{
   5438 			dns_rdata_init(&rdata);
   5439 			dns_rdataset_current(&rdataset, &rdata);
   5440 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   5441 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5442 			if (dns_name_issubdomain(&ns.name, &zone->origin) &&
   5443 			    !zone_check_ns(zone, db, version, &ns.name, logit))
   5444 			{
   5445 				ecount++;
   5446 			}
   5447 		}
   5448 		count++;
   5449 		result = dns_rdataset_next(&rdataset);
   5450 	}
   5451 	dns_rdataset_disassociate(&rdataset);
   5452 
   5453 success:
   5454 	if (nscount != NULL) {
   5455 		*nscount = count;
   5456 	}
   5457 	if (errors != NULL) {
   5458 		*errors = ecount;
   5459 	}
   5460 
   5461 	result = ISC_R_SUCCESS;
   5462 
   5463 invalidate_rdataset:
   5464 	dns_rdataset_invalidate(&rdataset);
   5465 
   5466 	return (result);
   5467 }
   5468 
   5469 static isc_result_t
   5470 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   5471 		 unsigned int *soacount, uint32_t *serial, uint32_t *refresh,
   5472 		 uint32_t *retry, uint32_t *expire, uint32_t *minimum) {
   5473 	isc_result_t result;
   5474 	unsigned int count;
   5475 	dns_rdataset_t rdataset;
   5476 	dns_rdata_t rdata = DNS_RDATA_INIT;
   5477 	dns_rdata_soa_t soa;
   5478 
   5479 	dns_rdataset_init(&rdataset);
   5480 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
   5481 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5482 	if (result == ISC_R_NOTFOUND) {
   5483 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5484 		if (soacount != NULL) {
   5485 			*soacount = 0;
   5486 		}
   5487 		if (serial != NULL) {
   5488 			*serial = 0;
   5489 		}
   5490 		if (refresh != NULL) {
   5491 			*refresh = 0;
   5492 		}
   5493 		if (retry != NULL) {
   5494 			*retry = 0;
   5495 		}
   5496 		if (expire != NULL) {
   5497 			*expire = 0;
   5498 		}
   5499 		if (minimum != NULL) {
   5500 			*minimum = 0;
   5501 		}
   5502 		result = ISC_R_SUCCESS;
   5503 		goto invalidate_rdataset;
   5504 	}
   5505 	if (result != ISC_R_SUCCESS) {
   5506 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5507 		goto invalidate_rdataset;
   5508 	}
   5509 
   5510 	count = 0;
   5511 	result = dns_rdataset_first(&rdataset);
   5512 	while (result == ISC_R_SUCCESS) {
   5513 		dns_rdata_init(&rdata);
   5514 		dns_rdataset_current(&rdataset, &rdata);
   5515 		count++;
   5516 		if (count == 1) {
   5517 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   5518 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5519 		}
   5520 
   5521 		result = dns_rdataset_next(&rdataset);
   5522 		dns_rdata_reset(&rdata);
   5523 	}
   5524 	dns_rdataset_disassociate(&rdataset);
   5525 
   5526 	if (soacount != NULL) {
   5527 		*soacount = count;
   5528 	}
   5529 
   5530 	if (count > 0) {
   5531 		if (serial != NULL) {
   5532 			*serial = soa.serial;
   5533 		}
   5534 		if (refresh != NULL) {
   5535 			*refresh = soa.refresh;
   5536 		}
   5537 		if (retry != NULL) {
   5538 			*retry = soa.retry;
   5539 		}
   5540 		if (expire != NULL) {
   5541 			*expire = soa.expire;
   5542 		}
   5543 		if (minimum != NULL) {
   5544 			*minimum = soa.minimum;
   5545 		}
   5546 	} else {
   5547 		if (soacount != NULL) {
   5548 			*soacount = 0;
   5549 		}
   5550 		if (serial != NULL) {
   5551 			*serial = 0;
   5552 		}
   5553 		if (refresh != NULL) {
   5554 			*refresh = 0;
   5555 		}
   5556 		if (retry != NULL) {
   5557 			*retry = 0;
   5558 		}
   5559 		if (expire != NULL) {
   5560 			*expire = 0;
   5561 		}
   5562 		if (minimum != NULL) {
   5563 			*minimum = 0;
   5564 		}
   5565 	}
   5566 
   5567 	result = ISC_R_SUCCESS;
   5568 
   5569 invalidate_rdataset:
   5570 	dns_rdataset_invalidate(&rdataset);
   5571 
   5572 	return (result);
   5573 }
   5574 
   5575 /*
   5576  * zone must be locked.
   5577  */
   5578 static isc_result_t
   5579 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
   5580 		 unsigned int *soacount, uint32_t *serial, uint32_t *refresh,
   5581 		 uint32_t *retry, uint32_t *expire, uint32_t *minimum,
   5582 		 unsigned int *errors) {
   5583 	isc_result_t result;
   5584 	isc_result_t answer = ISC_R_SUCCESS;
   5585 	dns_dbversion_t *version = NULL;
   5586 	dns_dbnode_t *node;
   5587 
   5588 	REQUIRE(db != NULL);
   5589 	REQUIRE(zone != NULL);
   5590 
   5591 	dns_db_currentversion(db, &version);
   5592 
   5593 	if (nscount != NULL) {
   5594 		*nscount = 0;
   5595 	}
   5596 	if (soacount != NULL) {
   5597 		*soacount = 0;
   5598 	}
   5599 	if (serial != NULL) {
   5600 		*serial = 0;
   5601 	}
   5602 	if (refresh != NULL) {
   5603 		*refresh = 0;
   5604 	}
   5605 	if (retry != NULL) {
   5606 		*retry = 0;
   5607 	}
   5608 	if (expire != NULL) {
   5609 		*expire = 0;
   5610 	}
   5611 	if (errors != NULL) {
   5612 		*errors = 0;
   5613 	}
   5614 
   5615 	node = NULL;
   5616 	result = dns_db_findnode(db, &zone->origin, false, &node);
   5617 	if (result != ISC_R_SUCCESS) {
   5618 		answer = result;
   5619 		goto closeversion;
   5620 	}
   5621 
   5622 	if (nscount != NULL || errors != NULL) {
   5623 		result = zone_count_ns_rr(zone, db, node, version, nscount,
   5624 					  errors, true);
   5625 		if (result != ISC_R_SUCCESS) {
   5626 			answer = result;
   5627 		}
   5628 	}
   5629 
   5630 	if (soacount != NULL || serial != NULL || refresh != NULL ||
   5631 	    retry != NULL || expire != NULL || minimum != NULL)
   5632 	{
   5633 		result = zone_load_soa_rr(db, node, version, soacount, serial,
   5634 					  refresh, retry, expire, minimum);
   5635 		if (result != ISC_R_SUCCESS) {
   5636 			answer = result;
   5637 		}
   5638 	}
   5639 
   5640 	dns_db_detachnode(db, &node);
   5641 closeversion:
   5642 	dns_db_closeversion(db, &version, false);
   5643 
   5644 	return (answer);
   5645 }
   5646 
   5647 void
   5648 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
   5649 	REQUIRE(DNS_ZONE_VALID(source));
   5650 	REQUIRE(target != NULL && *target == NULL);
   5651 	isc_refcount_increment(&source->erefs);
   5652 	*target = source;
   5653 }
   5654 
   5655 void
   5656 dns_zone_detach(dns_zone_t **zonep) {
   5657 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5658 	dns_zone_t *zone = *zonep;
   5659 	*zonep = NULL;
   5660 
   5661 	bool free_now = false;
   5662 	dns_zone_t *raw = NULL;
   5663 	dns_zone_t *secure = NULL;
   5664 	if (isc_refcount_decrement(&zone->erefs) == 1) {
   5665 		isc_refcount_destroy(&zone->erefs);
   5666 
   5667 		LOCK_ZONE(zone);
   5668 		INSIST(zone != zone->raw);
   5669 		/*
   5670 		 * We just detached the last external reference.
   5671 		 */
   5672 		if (zone->task != NULL) {
   5673 			/*
   5674 			 * This zone is being managed.	Post
   5675 			 * its control event and let it clean
   5676 			 * up synchronously in the context of
   5677 			 * its task.
   5678 			 */
   5679 			isc_event_t *ev = &zone->ctlevent;
   5680 			isc_task_send(zone->task, &ev);
   5681 		} else {
   5682 			/*
   5683 			 * This zone is not being managed; it has
   5684 			 * no task and can have no outstanding
   5685 			 * events.  Free it immediately.
   5686 			 */
   5687 			/*
   5688 			 * Unmanaged zones should not have non-null views;
   5689 			 * we have no way of detaching from the view here
   5690 			 * without causing deadlock because this code is called
   5691 			 * with the view already locked.
   5692 			 */
   5693 			INSIST(zone->view == NULL);
   5694 			free_now = true;
   5695 			raw = zone->raw;
   5696 			zone->raw = NULL;
   5697 			secure = zone->secure;
   5698 			zone->secure = NULL;
   5699 		}
   5700 		UNLOCK_ZONE(zone);
   5701 	}
   5702 	if (free_now) {
   5703 		if (raw != NULL) {
   5704 			dns_zone_detach(&raw);
   5705 		}
   5706 		if (secure != NULL) {
   5707 			dns_zone_idetach(&secure);
   5708 		}
   5709 		zone_free(zone);
   5710 	}
   5711 }
   5712 
   5713 void
   5714 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5715 	REQUIRE(DNS_ZONE_VALID(source));
   5716 
   5717 	LOCK_ZONE(source);
   5718 	zone_iattach(source, target);
   5719 	UNLOCK_ZONE(source);
   5720 }
   5721 
   5722 static void
   5723 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5724 	REQUIRE(DNS_ZONE_VALID(source));
   5725 	REQUIRE(LOCKED_ZONE(source));
   5726 	REQUIRE(target != NULL && *target == NULL);
   5727 	INSIST(isc_refcount_increment0(&source->irefs) +
   5728 		       isc_refcount_current(&source->erefs) >
   5729 	       0);
   5730 	*target = source;
   5731 }
   5732 
   5733 static void
   5734 zone_idetach(dns_zone_t **zonep) {
   5735 	dns_zone_t *zone;
   5736 
   5737 	/*
   5738 	 * 'zone' locked by caller.
   5739 	 */
   5740 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5741 	REQUIRE(LOCKED_ZONE(*zonep));
   5742 
   5743 	zone = *zonep;
   5744 	*zonep = NULL;
   5745 
   5746 	INSIST(isc_refcount_decrement(&zone->irefs) - 1 +
   5747 		       isc_refcount_current(&zone->erefs) >
   5748 	       0);
   5749 }
   5750 
   5751 void
   5752 dns_zone_idetach(dns_zone_t **zonep) {
   5753 	dns_zone_t *zone;
   5754 	bool free_needed;
   5755 
   5756 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5757 
   5758 	zone = *zonep;
   5759 	*zonep = NULL;
   5760 
   5761 	if (isc_refcount_decrement(&zone->irefs) == 1) {
   5762 		LOCK_ZONE(zone);
   5763 		free_needed = exit_check(zone);
   5764 		UNLOCK_ZONE(zone);
   5765 		if (free_needed) {
   5766 			zone_free(zone);
   5767 		}
   5768 	}
   5769 }
   5770 
   5771 isc_mem_t *
   5772 dns_zone_getmctx(dns_zone_t *zone) {
   5773 	REQUIRE(DNS_ZONE_VALID(zone));
   5774 
   5775 	return (zone->mctx);
   5776 }
   5777 
   5778 dns_zonemgr_t *
   5779 dns_zone_getmgr(dns_zone_t *zone) {
   5780 	REQUIRE(DNS_ZONE_VALID(zone));
   5781 
   5782 	return (zone->zmgr);
   5783 }
   5784 
   5785 void
   5786 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, bool value) {
   5787 	REQUIRE(DNS_ZONE_VALID(zone));
   5788 
   5789 	if (value) {
   5790 		DNS_ZONE_SETFLAG(zone, flags);
   5791 	} else {
   5792 		DNS_ZONE_CLRFLAG(zone, flags);
   5793 	}
   5794 }
   5795 
   5796 void
   5797 dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) {
   5798 	REQUIRE(DNS_ZONE_VALID(zone));
   5799 
   5800 	LOCK_ZONE(zone);
   5801 	if (zone->kasp != NULL) {
   5802 		dns_kasp_t *oldkasp = zone->kasp;
   5803 		zone->kasp = NULL;
   5804 		dns_kasp_detach(&oldkasp);
   5805 	}
   5806 	zone->kasp = kasp;
   5807 	UNLOCK_ZONE(zone);
   5808 }
   5809 
   5810 dns_kasp_t *
   5811 dns_zone_getkasp(dns_zone_t *zone) {
   5812 	REQUIRE(DNS_ZONE_VALID(zone));
   5813 
   5814 	return (zone->kasp);
   5815 }
   5816 
   5817 static bool
   5818 statefile_exist(dns_zone_t *zone) {
   5819 	isc_result_t ret;
   5820 	dns_dnsseckeylist_t keys;
   5821 	dns_dnsseckey_t *key = NULL;
   5822 	isc_stdtime_t now;
   5823 	isc_time_t timenow;
   5824 	bool found = false;
   5825 
   5826 	TIME_NOW(&timenow);
   5827 	now = isc_time_seconds(&timenow);
   5828 
   5829 	ISC_LIST_INIT(keys);
   5830 
   5831 	ret = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone),
   5832 					  dns_zone_getkeydirectory(zone), now,
   5833 					  dns_zone_getmctx(zone), &keys);
   5834 	if (ret == ISC_R_SUCCESS) {
   5835 		for (key = ISC_LIST_HEAD(keys); key != NULL;
   5836 		     key = ISC_LIST_NEXT(key, link)) {
   5837 			if (dst_key_haskasp(key->key)) {
   5838 				found = true;
   5839 				break;
   5840 			}
   5841 		}
   5842 	}
   5843 
   5844 	/* Clean up keys */
   5845 	while (!ISC_LIST_EMPTY(keys)) {
   5846 		key = ISC_LIST_HEAD(keys);
   5847 		ISC_LIST_UNLINK(keys, key, link);
   5848 		dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key);
   5849 	}
   5850 
   5851 	return (found);
   5852 }
   5853 
   5854 bool
   5855 dns_zone_secure_to_insecure(dns_zone_t *zone, bool reconfig) {
   5856 	REQUIRE(DNS_ZONE_VALID(zone));
   5857 
   5858 	/*
   5859 	 * If checking during reconfig, the zone is not yet updated
   5860 	 * with the new kasp configuration, so only check the key
   5861 	 * files.
   5862 	 */
   5863 	if (reconfig) {
   5864 		return (statefile_exist(zone));
   5865 	}
   5866 
   5867 	if (zone->kasp == NULL) {
   5868 		return (false);
   5869 	}
   5870 	if (strcmp(dns_kasp_getname(zone->kasp), "none") != 0) {
   5871 		return (false);
   5872 	}
   5873 	/*
   5874 	 * "dnssec-policy none", but if there are key state files
   5875 	 * this zone used to be secure but is transitioning back to
   5876 	 * insecure.
   5877 	 */
   5878 	return (statefile_exist(zone));
   5879 }
   5880 
   5881 bool
   5882 dns_zone_use_kasp(dns_zone_t *zone) {
   5883 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   5884 
   5885 	if (kasp == NULL) {
   5886 		return (false);
   5887 	} else if (strcmp(dns_kasp_getname(kasp), "none") != 0) {
   5888 		return (true);
   5889 	}
   5890 	return dns_zone_secure_to_insecure(zone, false);
   5891 }
   5892 
   5893 void
   5894 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) {
   5895 	REQUIRE(DNS_ZONE_VALID(zone));
   5896 
   5897 	if (value) {
   5898 		DNS_ZONE_SETOPTION(zone, option);
   5899 	} else {
   5900 		DNS_ZONE_CLROPTION(zone, option);
   5901 	}
   5902 }
   5903 
   5904 dns_zoneopt_t
   5905 dns_zone_getoptions(dns_zone_t *zone) {
   5906 	REQUIRE(DNS_ZONE_VALID(zone));
   5907 
   5908 	return (atomic_load_relaxed(&zone->options));
   5909 }
   5910 
   5911 void
   5912 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) {
   5913 	REQUIRE(DNS_ZONE_VALID(zone));
   5914 
   5915 	if (value) {
   5916 		DNS_ZONEKEY_SETOPTION(zone, keyopt);
   5917 	} else {
   5918 		DNS_ZONEKEY_CLROPTION(zone, keyopt);
   5919 	}
   5920 }
   5921 
   5922 unsigned int
   5923 dns_zone_getkeyopts(dns_zone_t *zone) {
   5924 	REQUIRE(DNS_ZONE_VALID(zone));
   5925 
   5926 	return (atomic_load_relaxed(&zone->keyopts));
   5927 }
   5928 
   5929 isc_result_t
   5930 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5931 	REQUIRE(DNS_ZONE_VALID(zone));
   5932 
   5933 	LOCK_ZONE(zone);
   5934 	zone->xfrsource4 = *xfrsource;
   5935 	UNLOCK_ZONE(zone);
   5936 
   5937 	return (ISC_R_SUCCESS);
   5938 }
   5939 
   5940 isc_sockaddr_t *
   5941 dns_zone_getxfrsource4(dns_zone_t *zone) {
   5942 	REQUIRE(DNS_ZONE_VALID(zone));
   5943 	return (&zone->xfrsource4);
   5944 }
   5945 
   5946 isc_result_t
   5947 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5948 	REQUIRE(DNS_ZONE_VALID(zone));
   5949 
   5950 	LOCK_ZONE(zone);
   5951 	zone->xfrsource4dscp = dscp;
   5952 	UNLOCK_ZONE(zone);
   5953 
   5954 	return (ISC_R_SUCCESS);
   5955 }
   5956 
   5957 isc_dscp_t
   5958 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
   5959 	REQUIRE(DNS_ZONE_VALID(zone));
   5960 	return (zone->xfrsource4dscp);
   5961 }
   5962 
   5963 isc_result_t
   5964 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5965 	REQUIRE(DNS_ZONE_VALID(zone));
   5966 
   5967 	LOCK_ZONE(zone);
   5968 	zone->xfrsource6 = *xfrsource;
   5969 	UNLOCK_ZONE(zone);
   5970 
   5971 	return (ISC_R_SUCCESS);
   5972 }
   5973 
   5974 isc_sockaddr_t *
   5975 dns_zone_getxfrsource6(dns_zone_t *zone) {
   5976 	REQUIRE(DNS_ZONE_VALID(zone));
   5977 	return (&zone->xfrsource6);
   5978 }
   5979 
   5980 isc_dscp_t
   5981 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
   5982 	REQUIRE(DNS_ZONE_VALID(zone));
   5983 	return (zone->xfrsource6dscp);
   5984 }
   5985 
   5986 isc_result_t
   5987 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5988 	REQUIRE(DNS_ZONE_VALID(zone));
   5989 
   5990 	LOCK_ZONE(zone);
   5991 	zone->xfrsource6dscp = dscp;
   5992 	UNLOCK_ZONE(zone);
   5993 
   5994 	return (ISC_R_SUCCESS);
   5995 }
   5996 
   5997 isc_result_t
   5998 dns_zone_setaltxfrsource4(dns_zone_t *zone,
   5999 			  const isc_sockaddr_t *altxfrsource) {
   6000 	REQUIRE(DNS_ZONE_VALID(zone));
   6001 
   6002 	LOCK_ZONE(zone);
   6003 	zone->altxfrsource4 = *altxfrsource;
   6004 	UNLOCK_ZONE(zone);
   6005 
   6006 	return (ISC_R_SUCCESS);
   6007 }
   6008 
   6009 isc_sockaddr_t *
   6010 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
   6011 	REQUIRE(DNS_ZONE_VALID(zone));
   6012 	return (&zone->altxfrsource4);
   6013 }
   6014 
   6015 isc_result_t
   6016 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6017 	REQUIRE(DNS_ZONE_VALID(zone));
   6018 
   6019 	LOCK_ZONE(zone);
   6020 	zone->altxfrsource4dscp = dscp;
   6021 	UNLOCK_ZONE(zone);
   6022 
   6023 	return (ISC_R_SUCCESS);
   6024 }
   6025 
   6026 isc_dscp_t
   6027 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
   6028 	REQUIRE(DNS_ZONE_VALID(zone));
   6029 	return (zone->altxfrsource4dscp);
   6030 }
   6031 
   6032 isc_result_t
   6033 dns_zone_setaltxfrsource6(dns_zone_t *zone,
   6034 			  const isc_sockaddr_t *altxfrsource) {
   6035 	REQUIRE(DNS_ZONE_VALID(zone));
   6036 
   6037 	LOCK_ZONE(zone);
   6038 	zone->altxfrsource6 = *altxfrsource;
   6039 	UNLOCK_ZONE(zone);
   6040 
   6041 	return (ISC_R_SUCCESS);
   6042 }
   6043 
   6044 isc_sockaddr_t *
   6045 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
   6046 	REQUIRE(DNS_ZONE_VALID(zone));
   6047 	return (&zone->altxfrsource6);
   6048 }
   6049 
   6050 isc_result_t
   6051 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6052 	REQUIRE(DNS_ZONE_VALID(zone));
   6053 
   6054 	LOCK_ZONE(zone);
   6055 	zone->altxfrsource6dscp = dscp;
   6056 	UNLOCK_ZONE(zone);
   6057 
   6058 	return (ISC_R_SUCCESS);
   6059 }
   6060 
   6061 isc_dscp_t
   6062 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
   6063 	REQUIRE(DNS_ZONE_VALID(zone));
   6064 	return (zone->altxfrsource6dscp);
   6065 }
   6066 
   6067 isc_result_t
   6068 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6069 	REQUIRE(DNS_ZONE_VALID(zone));
   6070 
   6071 	LOCK_ZONE(zone);
   6072 	zone->notifysrc4 = *notifysrc;
   6073 	UNLOCK_ZONE(zone);
   6074 
   6075 	return (ISC_R_SUCCESS);
   6076 }
   6077 
   6078 isc_sockaddr_t *
   6079 dns_zone_getnotifysrc4(dns_zone_t *zone) {
   6080 	REQUIRE(DNS_ZONE_VALID(zone));
   6081 	return (&zone->notifysrc4);
   6082 }
   6083 
   6084 isc_result_t
   6085 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6086 	REQUIRE(DNS_ZONE_VALID(zone));
   6087 
   6088 	LOCK_ZONE(zone);
   6089 	zone->notifysrc4dscp = dscp;
   6090 	UNLOCK_ZONE(zone);
   6091 
   6092 	return (ISC_R_SUCCESS);
   6093 }
   6094 
   6095 isc_dscp_t
   6096 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
   6097 	REQUIRE(DNS_ZONE_VALID(zone));
   6098 	return (zone->notifysrc4dscp);
   6099 }
   6100 
   6101 isc_result_t
   6102 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6103 	REQUIRE(DNS_ZONE_VALID(zone));
   6104 
   6105 	LOCK_ZONE(zone);
   6106 	zone->notifysrc6 = *notifysrc;
   6107 	UNLOCK_ZONE(zone);
   6108 
   6109 	return (ISC_R_SUCCESS);
   6110 }
   6111 
   6112 isc_sockaddr_t *
   6113 dns_zone_getnotifysrc6(dns_zone_t *zone) {
   6114 	REQUIRE(DNS_ZONE_VALID(zone));
   6115 	return (&zone->notifysrc6);
   6116 }
   6117 
   6118 static bool
   6119 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
   6120 	   uint32_t count) {
   6121 	unsigned int i;
   6122 
   6123 	for (i = 0; i < count; i++) {
   6124 		if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) {
   6125 			return (false);
   6126 		}
   6127 	}
   6128 	return (true);
   6129 }
   6130 
   6131 static bool
   6132 same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist,
   6133 	      uint32_t count) {
   6134 	unsigned int i;
   6135 
   6136 	if (oldlist == NULL && newlist == NULL) {
   6137 		return (true);
   6138 	}
   6139 	if (oldlist == NULL || newlist == NULL) {
   6140 		return (false);
   6141 	}
   6142 
   6143 	for (i = 0; i < count; i++) {
   6144 		if (oldlist[i] == NULL && newlist[i] == NULL) {
   6145 			continue;
   6146 		}
   6147 		if (oldlist[i] == NULL || newlist[i] == NULL ||
   6148 		    !dns_name_equal(oldlist[i], newlist[i]))
   6149 		{
   6150 			return (false);
   6151 		}
   6152 	}
   6153 	return (true);
   6154 }
   6155 
   6156 static void
   6157 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
   6158 		     dns_name_t ***keynamesp, unsigned int *countp,
   6159 		     isc_mem_t *mctx) {
   6160 	unsigned int count;
   6161 	isc_sockaddr_t *addrs;
   6162 	isc_dscp_t *dscps;
   6163 	dns_name_t **keynames;
   6164 
   6165 	REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
   6166 		keynamesp != NULL);
   6167 
   6168 	count = *countp;
   6169 	*countp = 0;
   6170 	addrs = *addrsp;
   6171 	*addrsp = NULL;
   6172 	dscps = *dscpsp;
   6173 	*dscpsp = NULL;
   6174 	keynames = *keynamesp;
   6175 	*keynamesp = NULL;
   6176 
   6177 	if (addrs != NULL) {
   6178 		isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
   6179 	}
   6180 
   6181 	if (dscps != NULL) {
   6182 		isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
   6183 	}
   6184 
   6185 	if (keynames != NULL) {
   6186 		unsigned int i;
   6187 		for (i = 0; i < count; i++) {
   6188 			if (keynames[i] != NULL) {
   6189 				dns_name_free(keynames[i], mctx);
   6190 				isc_mem_put(mctx, keynames[i],
   6191 					    sizeof(dns_name_t));
   6192 				keynames[i] = NULL;
   6193 			}
   6194 		}
   6195 		isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
   6196 	}
   6197 }
   6198 
   6199 static isc_result_t
   6200 set_addrkeylist(unsigned int count, const isc_sockaddr_t *addrs,
   6201 		isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp,
   6202 		isc_dscp_t **newdscpp, dns_name_t **names,
   6203 		dns_name_t ***newnamesp, isc_mem_t *mctx) {
   6204 	isc_sockaddr_t *newaddrs = NULL;
   6205 	isc_dscp_t *newdscp = NULL;
   6206 	dns_name_t **newnames = NULL;
   6207 	unsigned int i;
   6208 
   6209 	REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
   6210 	REQUIRE(newdscpp != NULL && *newdscpp == NULL);
   6211 	REQUIRE(newnamesp != NULL && *newnamesp == NULL);
   6212 
   6213 	newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
   6214 	memmove(newaddrs, addrs, count * sizeof(*newaddrs));
   6215 
   6216 	if (dscp != NULL) {
   6217 		newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
   6218 		memmove(newdscp, dscp, count * sizeof(*newdscp));
   6219 	} else {
   6220 		newdscp = NULL;
   6221 	}
   6222 
   6223 	if (names != NULL) {
   6224 		newnames = isc_mem_get(mctx, count * sizeof(*newnames));
   6225 		for (i = 0; i < count; i++) {
   6226 			newnames[i] = NULL;
   6227 		}
   6228 		for (i = 0; i < count; i++) {
   6229 			if (names[i] != NULL) {
   6230 				newnames[i] = isc_mem_get(mctx,
   6231 							  sizeof(dns_name_t));
   6232 				dns_name_init(newnames[i], NULL);
   6233 				dns_name_dup(names[i], mctx, newnames[i]);
   6234 			}
   6235 		}
   6236 	} else {
   6237 		newnames = NULL;
   6238 	}
   6239 
   6240 	*newdscpp = newdscp;
   6241 	*newaddrsp = newaddrs;
   6242 	*newnamesp = newnames;
   6243 	return (ISC_R_SUCCESS);
   6244 }
   6245 
   6246 isc_result_t
   6247 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6248 	REQUIRE(DNS_ZONE_VALID(zone));
   6249 
   6250 	LOCK_ZONE(zone);
   6251 	zone->notifysrc6dscp = dscp;
   6252 	UNLOCK_ZONE(zone);
   6253 
   6254 	return (ISC_R_SUCCESS);
   6255 }
   6256 
   6257 isc_dscp_t
   6258 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
   6259 	REQUIRE(DNS_ZONE_VALID(zone));
   6260 	return (zone->notifysrc6dscp);
   6261 }
   6262 
   6263 isc_result_t
   6264 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6265 		       uint32_t count) {
   6266 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
   6267 					       count));
   6268 }
   6269 
   6270 isc_result_t
   6271 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6272 			       dns_name_t **keynames, uint32_t count) {
   6273 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
   6274 					       count));
   6275 }
   6276 
   6277 isc_result_t
   6278 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6279 			       const isc_dscp_t *dscps, dns_name_t **keynames,
   6280 			       uint32_t count) {
   6281 	isc_result_t result;
   6282 	isc_sockaddr_t *newaddrs = NULL;
   6283 	isc_dscp_t *newdscps = NULL;
   6284 	dns_name_t **newnames = NULL;
   6285 
   6286 	REQUIRE(DNS_ZONE_VALID(zone));
   6287 	REQUIRE(count == 0 || notify != NULL);
   6288 	if (keynames != NULL) {
   6289 		REQUIRE(count != 0);
   6290 	}
   6291 
   6292 	LOCK_ZONE(zone);
   6293 
   6294 	if (count == zone->notifycnt &&
   6295 	    same_addrs(zone->notify, notify, count) &&
   6296 	    same_keynames(zone->notifykeynames, keynames, count))
   6297 	{
   6298 		goto unlock;
   6299 	}
   6300 
   6301 	clear_addresskeylist(&zone->notify, &zone->notifydscp,
   6302 			     &zone->notifykeynames, &zone->notifycnt,
   6303 			     zone->mctx);
   6304 
   6305 	if (count == 0) {
   6306 		goto unlock;
   6307 	}
   6308 
   6309 	/*
   6310 	 * Set up the notify and notifykey lists
   6311 	 */
   6312 	result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
   6313 				 keynames, &newnames, zone->mctx);
   6314 	if (result != ISC_R_SUCCESS) {
   6315 		goto unlock;
   6316 	}
   6317 
   6318 	/*
   6319 	 * Everything is ok so attach to the zone.
   6320 	 */
   6321 	zone->notify = newaddrs;
   6322 	zone->notifydscp = newdscps;
   6323 	zone->notifykeynames = newnames;
   6324 	zone->notifycnt = count;
   6325 unlock:
   6326 	UNLOCK_ZONE(zone);
   6327 	return (ISC_R_SUCCESS);
   6328 }
   6329 
   6330 isc_result_t
   6331 dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *masters,
   6332 		      uint32_t count) {
   6333 	isc_result_t result;
   6334 
   6335 	result = dns_zone_setprimarieswithkeys(zone, masters, NULL, count);
   6336 	return (result);
   6337 }
   6338 
   6339 isc_result_t
   6340 dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
   6341 			      dns_name_t **keynames, uint32_t count) {
   6342 	isc_result_t result = ISC_R_SUCCESS;
   6343 	isc_sockaddr_t *newaddrs = NULL;
   6344 	isc_dscp_t *newdscps = NULL;
   6345 	dns_name_t **newnames = NULL;
   6346 	bool *newok;
   6347 	unsigned int i;
   6348 
   6349 	REQUIRE(DNS_ZONE_VALID(zone));
   6350 	REQUIRE(count == 0 || masters != NULL);
   6351 	if (keynames != NULL) {
   6352 		REQUIRE(count != 0);
   6353 	}
   6354 
   6355 	LOCK_ZONE(zone);
   6356 	/*
   6357 	 * The refresh code assumes that 'primaries' wouldn't change under it.
   6358 	 * If it will change then kill off any current refresh in progress
   6359 	 * and update the primaries info.  If it won't change then we can just
   6360 	 * unlock and exit.
   6361 	 */
   6362 	if (count != zone->masterscnt ||
   6363 	    !same_addrs(zone->masters, masters, count) ||
   6364 	    !same_keynames(zone->masterkeynames, keynames, count))
   6365 	{
   6366 		if (zone->request != NULL) {
   6367 			dns_request_cancel(zone->request);
   6368 		}
   6369 	} else {
   6370 		goto unlock;
   6371 	}
   6372 
   6373 	/*
   6374 	 * This needs to happen before clear_addresskeylist() sets
   6375 	 * zone->masterscnt to 0:
   6376 	 */
   6377 	if (zone->mastersok != NULL) {
   6378 		isc_mem_put(zone->mctx, zone->mastersok,
   6379 			    zone->masterscnt * sizeof(bool));
   6380 		zone->mastersok = NULL;
   6381 	}
   6382 	clear_addresskeylist(&zone->masters, &zone->masterdscps,
   6383 			     &zone->masterkeynames, &zone->masterscnt,
   6384 			     zone->mctx);
   6385 	/*
   6386 	 * If count == 0, don't allocate any space for masters, mastersok or
   6387 	 * keynames so internally, those pointers are NULL if count == 0
   6388 	 */
   6389 	if (count == 0) {
   6390 		goto unlock;
   6391 	}
   6392 
   6393 	/*
   6394 	 * mastersok must contain count elements
   6395 	 */
   6396 	newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
   6397 	for (i = 0; i < count; i++) {
   6398 		newok[i] = false;
   6399 	}
   6400 
   6401 	/*
   6402 	 * Now set up the primaries and primary key lists
   6403 	 */
   6404 	result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
   6405 				 keynames, &newnames, zone->mctx);
   6406 	INSIST(newdscps == NULL);
   6407 	if (result != ISC_R_SUCCESS) {
   6408 		isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
   6409 		goto unlock;
   6410 	}
   6411 
   6412 	/*
   6413 	 * Everything is ok so attach to the zone.
   6414 	 */
   6415 	zone->curmaster = 0;
   6416 	zone->mastersok = newok;
   6417 	zone->masters = newaddrs;
   6418 	zone->masterdscps = newdscps;
   6419 	zone->masterkeynames = newnames;
   6420 	zone->masterscnt = count;
   6421 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   6422 
   6423 unlock:
   6424 	UNLOCK_ZONE(zone);
   6425 	return (result);
   6426 }
   6427 
   6428 isc_result_t
   6429 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
   6430 	isc_result_t result = ISC_R_SUCCESS;
   6431 
   6432 	REQUIRE(DNS_ZONE_VALID(zone));
   6433 
   6434 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   6435 	if (zone->db == NULL) {
   6436 		result = DNS_R_NOTLOADED;
   6437 	} else {
   6438 		dns_db_attach(zone->db, dpb);
   6439 	}
   6440 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   6441 
   6442 	return (result);
   6443 }
   6444 
   6445 void
   6446 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
   6447 	REQUIRE(DNS_ZONE_VALID(zone));
   6448 	REQUIRE(zone->type == dns_zone_staticstub);
   6449 
   6450 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   6451 	REQUIRE(zone->db == NULL);
   6452 	dns_db_attach(db, &zone->db);
   6453 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   6454 }
   6455 
   6456 /*
   6457  * Coordinates the starting of routine jobs.
   6458  */
   6459 void
   6460 dns_zone_maintenance(dns_zone_t *zone) {
   6461 	const char me[] = "dns_zone_maintenance";
   6462 	isc_time_t now;
   6463 
   6464 	REQUIRE(DNS_ZONE_VALID(zone));
   6465 	ENTER;
   6466 
   6467 	LOCK_ZONE(zone);
   6468 	TIME_NOW(&now);
   6469 	zone_settimer(zone, &now);
   6470 	UNLOCK_ZONE(zone);
   6471 }
   6472 
   6473 static inline bool
   6474 was_dumping(dns_zone_t *zone) {
   6475 	REQUIRE(LOCKED_ZONE(zone));
   6476 
   6477 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   6478 		return (true);
   6479 	}
   6480 
   6481 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   6482 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   6483 	isc_time_settoepoch(&zone->dumptime);
   6484 	return (false);
   6485 }
   6486 
   6487 /*%
   6488  * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database
   6489  * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'.
   6490  * Only load the public part of a given key if it is not active at timestamp
   6491  * 'now'.  Store the number of keys found in 'nkeys'.
   6492  */
   6493 isc_result_t
   6494 dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   6495 		   isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys,
   6496 		   dst_key_t **keys, unsigned int *nkeys) {
   6497 	isc_result_t result;
   6498 	dns_dbnode_t *node = NULL;
   6499 	const char *directory = dns_zone_getkeydirectory(zone);
   6500 
   6501 	CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
   6502 	memset(keys, 0, sizeof(*keys) * maxkeys);
   6503 	result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
   6504 					 directory, now, mctx, maxkeys, keys,
   6505 					 nkeys);
   6506 	if (result == ISC_R_NOTFOUND) {
   6507 		result = ISC_R_SUCCESS;
   6508 	}
   6509 failure:
   6510 	if (node != NULL) {
   6511 		dns_db_detachnode(db, &node);
   6512 	}
   6513 	return (result);
   6514 }
   6515 
   6516 static isc_result_t
   6517 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff,
   6518 	dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) {
   6519 	isc_result_t result;
   6520 
   6521 	if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) {
   6522 		return (ISC_R_SUCCESS);
   6523 	}
   6524 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
   6525 			       name, ttl, rdata);
   6526 	if (result != ISC_R_SUCCESS) {
   6527 		return (result);
   6528 	}
   6529 	rdata->flags |= DNS_RDATA_OFFLINE;
   6530 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
   6531 			       name, ttl, rdata);
   6532 	zonediff->offline = true;
   6533 	return (result);
   6534 }
   6535 
   6536 static void
   6537 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when,
   6538 		       isc_stdtime_t now) {
   6539 	unsigned int delta;
   6540 	char timebuf[80];
   6541 
   6542 	zone->key_expiry = when;
   6543 	if (when <= now) {
   6544 		dns_zone_log(zone, ISC_LOG_ERROR,
   6545 			     "DNSKEY RRSIG(s) have expired");
   6546 		isc_time_settoepoch(&zone->keywarntime);
   6547 	} else if (when < now + 7 * 24 * 3600) {
   6548 		isc_time_t t;
   6549 		isc_time_set(&t, when, 0);
   6550 		isc_time_formattimestamp(&t, timebuf, 80);
   6551 		dns_zone_log(zone, ISC_LOG_WARNING,
   6552 			     "DNSKEY RRSIG(s) will expire within 7 days: %s",
   6553 			     timebuf);
   6554 		delta = when - now;
   6555 		delta--;	    /* loop prevention */
   6556 		delta /= 24 * 3600; /* to whole days */
   6557 		delta *= 24 * 3600; /* to seconds */
   6558 		isc_time_set(&zone->keywarntime, when - delta, 0);
   6559 	} else {
   6560 		isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
   6561 		isc_time_formattimestamp(&zone->keywarntime, timebuf, 80);
   6562 		dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s",
   6563 			     timebuf);
   6564 	}
   6565 }
   6566 
   6567 /*
   6568  * Helper function to del_sigs(). We don't want to delete RRSIGs that
   6569  * have no new key.
   6570  */
   6571 static bool
   6572 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
   6573 	  bool *warn) {
   6574 	unsigned int i = 0;
   6575 	isc_result_t ret;
   6576 	bool have_ksk = false, have_zsk = false;
   6577 	bool have_pksk = false, have_pzsk = false;
   6578 
   6579 	for (i = 0; i < nkeys; i++) {
   6580 		bool ksk, zsk;
   6581 
   6582 		if (have_pksk && have_ksk && have_pzsk && have_zsk) {
   6583 			break;
   6584 		}
   6585 
   6586 		if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) {
   6587 			continue;
   6588 		}
   6589 
   6590 		ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   6591 		if (ret != ISC_R_SUCCESS) {
   6592 			ksk = KSK(keys[i]);
   6593 		}
   6594 		ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   6595 		if (ret != ISC_R_SUCCESS) {
   6596 			zsk = !KSK(keys[i]);
   6597 		}
   6598 
   6599 		if (ksk) {
   6600 			have_ksk = true;
   6601 			if (dst_key_isprivate(keys[i])) {
   6602 				have_pksk = true;
   6603 			}
   6604 		}
   6605 		if (zsk) {
   6606 			have_zsk = true;
   6607 			if (dst_key_isprivate(keys[i])) {
   6608 				have_pzsk = true;
   6609 			}
   6610 		}
   6611 	}
   6612 
   6613 	if (have_zsk && have_ksk && !have_pzsk) {
   6614 		*warn = true;
   6615 	}
   6616 
   6617 	/*
   6618 	 * It's okay to delete a signature if there is an active key
   6619 	 * with the same algorithm to replace it.
   6620 	 */
   6621 	if (have_pksk || have_pzsk) {
   6622 		return (true);
   6623 	}
   6624 
   6625 	/*
   6626 	 * Failing that, it is *not* okay to delete a signature
   6627 	 * if the associated public key is still in the DNSKEY RRset
   6628 	 */
   6629 	for (i = 0; i < nkeys; i++) {
   6630 		if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
   6631 		    (rrsig_ptr->keyid == dst_key_id(keys[i])))
   6632 		{
   6633 			return (false);
   6634 		}
   6635 	}
   6636 
   6637 	/*
   6638 	 * But if the key is gone, then go ahead.
   6639 	 */
   6640 	return (true);
   6641 }
   6642 
   6643 /*
   6644  * Delete expired RRsigs and any RRsigs we are about to re-sign.
   6645  * See also update.c:del_keysigs().
   6646  */
   6647 static isc_result_t
   6648 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   6649 	 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys,
   6650 	 unsigned int nkeys, isc_stdtime_t now, bool incremental) {
   6651 	isc_result_t result;
   6652 	dns_dbnode_t *node = NULL;
   6653 	dns_rdataset_t rdataset;
   6654 	unsigned int i;
   6655 	dns_rdata_rrsig_t rrsig;
   6656 	bool found;
   6657 	int64_t timewarn = 0, timemaybe = 0;
   6658 
   6659 	dns_rdataset_init(&rdataset);
   6660 
   6661 	if (type == dns_rdatatype_nsec3) {
   6662 		result = dns_db_findnsec3node(db, name, false, &node);
   6663 	} else {
   6664 		result = dns_db_findnode(db, name, false, &node);
   6665 	}
   6666 	if (result == ISC_R_NOTFOUND) {
   6667 		return (ISC_R_SUCCESS);
   6668 	}
   6669 	if (result != ISC_R_SUCCESS) {
   6670 		goto failure;
   6671 	}
   6672 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
   6673 				     (isc_stdtime_t)0, &rdataset, NULL);
   6674 	dns_db_detachnode(db, &node);
   6675 
   6676 	if (result == ISC_R_NOTFOUND) {
   6677 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6678 		return (ISC_R_SUCCESS);
   6679 	}
   6680 	if (result != ISC_R_SUCCESS) {
   6681 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6682 		goto failure;
   6683 	}
   6684 
   6685 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   6686 	     result = dns_rdataset_next(&rdataset))
   6687 	{
   6688 		dns_rdata_t rdata = DNS_RDATA_INIT;
   6689 
   6690 		dns_rdataset_current(&rdataset, &rdata);
   6691 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   6692 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6693 
   6694 		if (type != dns_rdatatype_dnskey && type != dns_rdatatype_cds &&
   6695 		    type != dns_rdatatype_cdnskey)
   6696 		{
   6697 			bool warn = false, deleted = false;
   6698 			if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
   6699 				result = update_one_rr(db, ver, zonediff->diff,
   6700 						       DNS_DIFFOP_DELRESIGN,
   6701 						       name, rdataset.ttl,
   6702 						       &rdata);
   6703 				if (result != ISC_R_SUCCESS) {
   6704 					break;
   6705 				}
   6706 				deleted = true;
   6707 			}
   6708 			if (warn) {
   6709 				/*
   6710 				 * At this point, we've got an RRSIG,
   6711 				 * which is signed by an inactive key.
   6712 				 * An administrator needs to provide a new
   6713 				 * key/alg, but until that time, we want to
   6714 				 * keep the old RRSIG.  Marking the key as
   6715 				 * offline will prevent us spinning waiting
   6716 				 * for the private part.
   6717 				 */
   6718 				if (incremental && !deleted) {
   6719 					result = offline(db, ver, zonediff,
   6720 							 name, rdataset.ttl,
   6721 							 &rdata);
   6722 					if (result != ISC_R_SUCCESS) {
   6723 						break;
   6724 					}
   6725 				}
   6726 
   6727 				/*
   6728 				 * Log the key id and algorithm of
   6729 				 * the inactive key with no replacement
   6730 				 */
   6731 				if (zone->log_key_expired_timer <= now) {
   6732 					char origin[DNS_NAME_FORMATSIZE];
   6733 					char algbuf[DNS_NAME_FORMATSIZE];
   6734 					dns_name_format(&zone->origin, origin,
   6735 							sizeof(origin));
   6736 					dns_secalg_format(rrsig.algorithm,
   6737 							  algbuf,
   6738 							  sizeof(algbuf));
   6739 					dns_zone_log(zone, ISC_LOG_WARNING,
   6740 						     "Key %s/%s/%d "
   6741 						     "missing or inactive "
   6742 						     "and has no replacement: "
   6743 						     "retaining signatures.",
   6744 						     origin, algbuf,
   6745 						     rrsig.keyid);
   6746 					zone->log_key_expired_timer = now +
   6747 								      3600;
   6748 				}
   6749 			}
   6750 			continue;
   6751 		}
   6752 
   6753 		/*
   6754 		 * KSK RRSIGs requires special processing.
   6755 		 */
   6756 		found = false;
   6757 		for (i = 0; i < nkeys; i++) {
   6758 			if (rrsig.algorithm == dst_key_alg(keys[i]) &&
   6759 			    rrsig.keyid == dst_key_id(keys[i]))
   6760 			{
   6761 				found = true;
   6762 				/*
   6763 				 * Mark offline DNSKEY.
   6764 				 * We want the earliest offline expire time
   6765 				 * iff there is a new offline signature.
   6766 				 */
   6767 				if (!dst_key_inactive(keys[i]) &&
   6768 				    !dst_key_isprivate(keys[i])) {
   6769 					int64_t timeexpire = dns_time64_from32(
   6770 						rrsig.timeexpire);
   6771 					if (timewarn != 0 &&
   6772 					    timewarn > timeexpire) {
   6773 						timewarn = timeexpire;
   6774 					}
   6775 					if (rdata.flags & DNS_RDATA_OFFLINE) {
   6776 						if (timemaybe == 0 ||
   6777 						    timemaybe > timeexpire) {
   6778 							timemaybe = timeexpire;
   6779 						}
   6780 						break;
   6781 					}
   6782 					if (timewarn == 0) {
   6783 						timewarn = timemaybe;
   6784 					}
   6785 					if (timewarn == 0 ||
   6786 					    timewarn > timeexpire) {
   6787 						timewarn = timeexpire;
   6788 					}
   6789 					result = offline(db, ver, zonediff,
   6790 							 name, rdataset.ttl,
   6791 							 &rdata);
   6792 					break;
   6793 				}
   6794 				result = update_one_rr(db, ver, zonediff->diff,
   6795 						       DNS_DIFFOP_DELRESIGN,
   6796 						       name, rdataset.ttl,
   6797 						       &rdata);
   6798 				break;
   6799 			}
   6800 		}
   6801 
   6802 		/*
   6803 		 * If there is not a matching DNSKEY then
   6804 		 * delete the RRSIG.
   6805 		 */
   6806 		if (!found) {
   6807 			result = update_one_rr(db, ver, zonediff->diff,
   6808 					       DNS_DIFFOP_DELRESIGN, name,
   6809 					       rdataset.ttl, &rdata);
   6810 		}
   6811 		if (result != ISC_R_SUCCESS) {
   6812 			break;
   6813 		}
   6814 	}
   6815 
   6816 	dns_rdataset_disassociate(&rdataset);
   6817 	if (result == ISC_R_NOMORE) {
   6818 		result = ISC_R_SUCCESS;
   6819 	}
   6820 	if (timewarn > 0) {
   6821 		isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
   6822 		if (timewarn == stdwarn) {
   6823 			set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
   6824 					       now);
   6825 		} else {
   6826 			dns_zone_log(zone, ISC_LOG_ERROR,
   6827 				     "key expiry warning time out of range");
   6828 		}
   6829 	}
   6830 failure:
   6831 	if (node != NULL) {
   6832 		dns_db_detachnode(db, &node);
   6833 	}
   6834 	return (result);
   6835 }
   6836 
   6837 static isc_result_t
   6838 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone,
   6839 	 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
   6840 	 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
   6841 	 isc_stdtime_t expire, bool check_ksk, bool keyset_kskonly) {
   6842 	isc_result_t result;
   6843 	dns_dbnode_t *node = NULL;
   6844 	dns_stats_t *dnssecsignstats;
   6845 	dns_rdataset_t rdataset;
   6846 	dns_rdata_t sig_rdata = DNS_RDATA_INIT;
   6847 	unsigned char data[1024]; /* XXX */
   6848 	isc_buffer_t buffer;
   6849 	unsigned int i, j;
   6850 	bool use_kasp = false;
   6851 
   6852 	if (dns_zone_use_kasp(zone)) {
   6853 		check_ksk = false;
   6854 		keyset_kskonly = true;
   6855 		use_kasp = true;
   6856 	}
   6857 
   6858 	dns_rdataset_init(&rdataset);
   6859 	isc_buffer_init(&buffer, data, sizeof(data));
   6860 
   6861 	if (type == dns_rdatatype_nsec3) {
   6862 		result = dns_db_findnsec3node(db, name, false, &node);
   6863 	} else {
   6864 		result = dns_db_findnode(db, name, false, &node);
   6865 	}
   6866 	if (result == ISC_R_NOTFOUND) {
   6867 		return (ISC_R_SUCCESS);
   6868 	}
   6869 	if (result != ISC_R_SUCCESS) {
   6870 		goto failure;
   6871 	}
   6872 	result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0,
   6873 				     &rdataset, NULL);
   6874 	dns_db_detachnode(db, &node);
   6875 	if (result == ISC_R_NOTFOUND) {
   6876 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6877 		return (ISC_R_SUCCESS);
   6878 	}
   6879 	if (result != ISC_R_SUCCESS) {
   6880 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6881 		goto failure;
   6882 	}
   6883 
   6884 	for (i = 0; i < nkeys; i++) {
   6885 		bool both = false;
   6886 
   6887 		/* Don't add signatures for offline or inactive keys */
   6888 		if (!dst_key_isprivate(keys[i])) {
   6889 			continue;
   6890 		}
   6891 		if (dst_key_inactive(keys[i])) {
   6892 			continue;
   6893 		}
   6894 
   6895 		if (check_ksk && !REVOKE(keys[i])) {
   6896 			bool have_ksk, have_nonksk;
   6897 			if (KSK(keys[i])) {
   6898 				have_ksk = true;
   6899 				have_nonksk = false;
   6900 			} else {
   6901 				have_ksk = false;
   6902 				have_nonksk = true;
   6903 			}
   6904 
   6905 			for (j = 0; j < nkeys; j++) {
   6906 				if (j == i || ALG(keys[i]) != ALG(keys[j])) {
   6907 					continue;
   6908 				}
   6909 
   6910 				/* Don't consider inactive keys, however
   6911 				 * the key may be temporary offline, so do
   6912 				 * consider keys which private key files are
   6913 				 * unavailable.
   6914 				 */
   6915 				if (dst_key_inactive(keys[j])) {
   6916 					continue;
   6917 				}
   6918 
   6919 				if (REVOKE(keys[j])) {
   6920 					continue;
   6921 				}
   6922 				if (KSK(keys[j])) {
   6923 					have_ksk = true;
   6924 				} else {
   6925 					have_nonksk = true;
   6926 				}
   6927 				both = have_ksk && have_nonksk;
   6928 				if (both) {
   6929 					break;
   6930 				}
   6931 			}
   6932 		}
   6933 		if (use_kasp) {
   6934 			/*
   6935 			 * A dnssec-policy is found. Check what RRsets this
   6936 			 * key should sign.
   6937 			 */
   6938 			isc_result_t kresult;
   6939 			isc_stdtime_t when;
   6940 			bool ksk = false;
   6941 			bool zsk = false;
   6942 
   6943 			kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   6944 			if (kresult != ISC_R_SUCCESS) {
   6945 				if (KSK(keys[i])) {
   6946 					ksk = true;
   6947 				}
   6948 			}
   6949 			kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   6950 			if (kresult != ISC_R_SUCCESS) {
   6951 				if (!KSK(keys[i])) {
   6952 					zsk = true;
   6953 				}
   6954 			}
   6955 
   6956 			if (type == dns_rdatatype_dnskey ||
   6957 			    type == dns_rdatatype_cdnskey ||
   6958 			    type == dns_rdatatype_cds)
   6959 			{
   6960 				/*
   6961 				 * DNSKEY RRset is signed with KSK.
   6962 				 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1).
   6963 				 */
   6964 				if (!ksk) {
   6965 					continue;
   6966 				}
   6967 			} else if (!zsk) {
   6968 				/*
   6969 				 * Other RRsets are signed with ZSK.
   6970 				 */
   6971 				continue;
   6972 			} else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK,
   6973 						       inception, &when)) {
   6974 				/*
   6975 				 * This key is not active for zone-signing.
   6976 				 */
   6977 				continue;
   6978 			}
   6979 
   6980 			/*
   6981 			 * If this key is revoked, it may only sign the
   6982 			 * DNSKEY RRset.
   6983 			 */
   6984 			if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   6985 				continue;
   6986 			}
   6987 		} else if (both) {
   6988 			/*
   6989 			 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
   6990 			 */
   6991 			if (type == dns_rdatatype_dnskey ||
   6992 			    type == dns_rdatatype_cdnskey ||
   6993 			    type == dns_rdatatype_cds)
   6994 			{
   6995 				if (!KSK(keys[i]) && keyset_kskonly) {
   6996 					continue;
   6997 				}
   6998 			} else if (KSK(keys[i])) {
   6999 				continue;
   7000 			}
   7001 		} else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   7002 			continue;
   7003 		}
   7004 
   7005 		/* Calculate the signature, creating a RRSIG RDATA. */
   7006 		isc_buffer_clear(&buffer);
   7007 		CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception,
   7008 				      &expire, mctx, &buffer, &sig_rdata));
   7009 
   7010 		/* Update the database and journal with the RRSIG. */
   7011 		/* XXX inefficient - will cause dataset merging */
   7012 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name,
   7013 				    rdataset.ttl, &sig_rdata));
   7014 		dns_rdata_reset(&sig_rdata);
   7015 		isc_buffer_init(&buffer, data, sizeof(data));
   7016 
   7017 		/* Update DNSSEC sign statistics. */
   7018 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7019 		if (dnssecsignstats != NULL) {
   7020 			/* Generated a new signature. */
   7021 			dns_dnssecsignstats_increment(dnssecsignstats,
   7022 						      ID(keys[i]),
   7023 						      (uint8_t)ALG(keys[i]),
   7024 						      dns_dnssecsignstats_sign);
   7025 			/* This is a refresh. */
   7026 			dns_dnssecsignstats_increment(
   7027 				dnssecsignstats, ID(keys[i]),
   7028 				(uint8_t)ALG(keys[i]),
   7029 				dns_dnssecsignstats_refresh);
   7030 		}
   7031 	}
   7032 
   7033 failure:
   7034 	if (dns_rdataset_isassociated(&rdataset)) {
   7035 		dns_rdataset_disassociate(&rdataset);
   7036 	}
   7037 	if (node != NULL) {
   7038 		dns_db_detachnode(db, &node);
   7039 	}
   7040 	return (result);
   7041 }
   7042 
   7043 static void
   7044 zone_resigninc(dns_zone_t *zone) {
   7045 	const char *me = "zone_resigninc";
   7046 	dns_db_t *db = NULL;
   7047 	dns_dbversion_t *version = NULL;
   7048 	dns_diff_t _sig_diff;
   7049 	dns__zonediff_t zonediff;
   7050 	dns_fixedname_t fixed;
   7051 	dns_name_t *name;
   7052 	dns_rdataset_t rdataset;
   7053 	dns_rdatatype_t covers;
   7054 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   7055 	bool check_ksk, keyset_kskonly = false;
   7056 	isc_result_t result;
   7057 	isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop;
   7058 	uint32_t sigvalidityinterval, expiryinterval;
   7059 	unsigned int i;
   7060 	unsigned int nkeys = 0;
   7061 	unsigned int resign;
   7062 
   7063 	ENTER;
   7064 
   7065 	dns_rdataset_init(&rdataset);
   7066 	dns_diff_init(zone->mctx, &_sig_diff);
   7067 	zonediff_init(&zonediff, &_sig_diff);
   7068 
   7069 	/*
   7070 	 * Zone is frozen or automatic resigning is disabled.
   7071 	 * Pause for 5 minutes.
   7072 	 */
   7073 	if (zone->update_disabled ||
   7074 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) {
   7075 		result = ISC_R_FAILURE;
   7076 		goto failure;
   7077 	}
   7078 
   7079 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   7080 	dns_db_attach(zone->db, &db);
   7081 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   7082 
   7083 	result = dns_db_newversion(db, &version);
   7084 	if (result != ISC_R_SUCCESS) {
   7085 		dns_zone_log(zone, ISC_LOG_ERROR,
   7086 			     "zone_resigninc:dns_db_newversion -> %s",
   7087 			     dns_result_totext(result));
   7088 		goto failure;
   7089 	}
   7090 
   7091 	isc_stdtime_get(&now);
   7092 
   7093 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   7094 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   7095 	if (result != ISC_R_SUCCESS) {
   7096 		dns_zone_log(zone, ISC_LOG_ERROR,
   7097 			     "zone_resigninc:dns__zone_findkeys -> %s",
   7098 			     dns_result_totext(result));
   7099 		goto failure;
   7100 	}
   7101 
   7102 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   7103 	inception = now - 3600; /* Allow for clock skew. */
   7104 	soaexpire = now + sigvalidityinterval;
   7105 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   7106 	if (expiryinterval > sigvalidityinterval) {
   7107 		expiryinterval = sigvalidityinterval;
   7108 	} else {
   7109 		expiryinterval = sigvalidityinterval - expiryinterval;
   7110 	}
   7111 
   7112 	/*
   7113 	 * Spread out signatures over time if they happen to be
   7114 	 * clumped.  We don't do this for each add_sigs() call as
   7115 	 * we still want some clustering to occur.  In normal operations
   7116 	 * the records should be re-signed as they fall due and they should
   7117 	 * already be spread out.  However if the server is off for a
   7118 	 * period we need to ensure that the clusters don't become
   7119 	 * synchronised by using the full jitter range.
   7120 	 */
   7121 	if (sigvalidityinterval >= 3600U) {
   7122 		uint32_t normaljitter, fulljitter;
   7123 		if (sigvalidityinterval > 7200U) {
   7124 			normaljitter = isc_random_uniform(3600);
   7125 			fulljitter = isc_random_uniform(expiryinterval);
   7126 		} else {
   7127 			normaljitter = fulljitter = isc_random_uniform(1200);
   7128 		}
   7129 		expire = soaexpire - normaljitter - 1;
   7130 		fullexpire = soaexpire - fulljitter - 1;
   7131 	} else {
   7132 		expire = fullexpire = soaexpire - 1;
   7133 	}
   7134 	stop = now + 5;
   7135 
   7136 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   7137 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   7138 
   7139 	name = dns_fixedname_initname(&fixed);
   7140 	result = dns_db_getsigningtime(db, &rdataset, name);
   7141 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   7142 		dns_zone_log(zone, ISC_LOG_ERROR,
   7143 			     "zone_resigninc:dns_db_getsigningtime -> %s",
   7144 			     dns_result_totext(result));
   7145 	}
   7146 
   7147 	i = 0;
   7148 	while (result == ISC_R_SUCCESS) {
   7149 		resign = rdataset.resign -
   7150 			 dns_zone_getsigresigninginterval(zone);
   7151 		covers = rdataset.covers;
   7152 		dns_rdataset_disassociate(&rdataset);
   7153 
   7154 		/*
   7155 		 * Stop if we hit the SOA as that means we have walked the
   7156 		 * entire zone.  The SOA record should always be the most
   7157 		 * recent signature.
   7158 		 */
   7159 		/* XXXMPA increase number of RRsets signed pre call */
   7160 		if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
   7161 		    resign > stop) {
   7162 			break;
   7163 		}
   7164 
   7165 		result = del_sigs(zone, db, version, name, covers, &zonediff,
   7166 				  zone_keys, nkeys, now, true);
   7167 		if (result != ISC_R_SUCCESS) {
   7168 			dns_zone_log(zone, ISC_LOG_ERROR,
   7169 				     "zone_resigninc:del_sigs -> %s",
   7170 				     dns_result_totext(result));
   7171 			break;
   7172 		}
   7173 
   7174 		/*
   7175 		 * If re-signing is over 5 minutes late use 'fullexpire'
   7176 		 * to redistribute the signature over the complete
   7177 		 * re-signing window, otherwise only add a small amount
   7178 		 * of jitter.
   7179 		 */
   7180 		result = add_sigs(db, version, name, zone, covers,
   7181 				  zonediff.diff, zone_keys, nkeys, zone->mctx,
   7182 				  inception,
   7183 				  resign > (now - 300) ? expire : fullexpire,
   7184 				  check_ksk, keyset_kskonly);
   7185 		if (result != ISC_R_SUCCESS) {
   7186 			dns_zone_log(zone, ISC_LOG_ERROR,
   7187 				     "zone_resigninc:add_sigs -> %s",
   7188 				     dns_result_totext(result));
   7189 			break;
   7190 		}
   7191 		result = dns_db_getsigningtime(db, &rdataset, name);
   7192 		if (nkeys == 0 && result == ISC_R_NOTFOUND) {
   7193 			result = ISC_R_SUCCESS;
   7194 			break;
   7195 		}
   7196 		if (result != ISC_R_SUCCESS) {
   7197 			dns_zone_log(zone, ISC_LOG_ERROR,
   7198 				     "zone_resigninc:dns_db_getsigningtime -> "
   7199 				     "%s",
   7200 				     dns_result_totext(result));
   7201 		}
   7202 	}
   7203 
   7204 	if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) {
   7205 		goto failure;
   7206 	}
   7207 
   7208 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   7209 			  &zonediff, zone_keys, nkeys, now, true);
   7210 	if (result != ISC_R_SUCCESS) {
   7211 		dns_zone_log(zone, ISC_LOG_ERROR,
   7212 			     "zone_resigninc:del_sigs -> %s",
   7213 			     dns_result_totext(result));
   7214 		goto failure;
   7215 	}
   7216 
   7217 	/*
   7218 	 * Did we change anything in the zone?
   7219 	 */
   7220 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   7221 		/*
   7222 		 * Commit the changes if any key has been marked as offline.
   7223 		 */
   7224 		if (zonediff.offline) {
   7225 			dns_db_closeversion(db, &version, true);
   7226 		}
   7227 		goto failure;
   7228 	}
   7229 
   7230 	/* Increment SOA serial if we have made changes */
   7231 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   7232 				   zone->updatemethod);
   7233 	if (result != ISC_R_SUCCESS) {
   7234 		dns_zone_log(zone, ISC_LOG_ERROR,
   7235 			     "zone_resigninc:update_soa_serial -> %s",
   7236 			     dns_result_totext(result));
   7237 		goto failure;
   7238 	}
   7239 
   7240 	/*
   7241 	 * Generate maximum life time signatures so that the above loop
   7242 	 * termination is sensible.
   7243 	 */
   7244 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   7245 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   7246 			  inception, soaexpire, check_ksk, keyset_kskonly);
   7247 	if (result != ISC_R_SUCCESS) {
   7248 		dns_zone_log(zone, ISC_LOG_ERROR,
   7249 			     "zone_resigninc:add_sigs -> %s",
   7250 			     dns_result_totext(result));
   7251 		goto failure;
   7252 	}
   7253 
   7254 	/* Write changes to journal file. */
   7255 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
   7256 
   7257 	/* Everything has succeeded. Commit the changes. */
   7258 	dns_db_closeversion(db, &version, true);
   7259 
   7260 failure:
   7261 	dns_diff_clear(&_sig_diff);
   7262 	for (i = 0; i < nkeys; i++) {
   7263 		dst_key_free(&zone_keys[i]);
   7264 	}
   7265 	if (version != NULL) {
   7266 		dns_db_closeversion(db, &version, false);
   7267 		dns_db_detach(&db);
   7268 	} else if (db != NULL) {
   7269 		dns_db_detach(&db);
   7270 	}
   7271 
   7272 	LOCK_ZONE(zone);
   7273 	if (result == ISC_R_SUCCESS) {
   7274 		set_resigntime(zone);
   7275 		zone_needdump(zone, DNS_DUMP_DELAY);
   7276 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   7277 	} else {
   7278 		/*
   7279 		 * Something failed.  Retry in 5 minutes.
   7280 		 */
   7281 		isc_interval_t ival;
   7282 		isc_interval_set(&ival, 300, 0);
   7283 		isc_time_nowplusinterval(&zone->resigntime, &ival);
   7284 	}
   7285 	UNLOCK_ZONE(zone);
   7286 
   7287 	INSIST(version == NULL);
   7288 }
   7289 
   7290 static isc_result_t
   7291 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
   7292 	    dns_name_t *newname, bool bottom) {
   7293 	isc_result_t result;
   7294 	dns_dbiterator_t *dbit = NULL;
   7295 	dns_rdatasetiter_t *rdsit = NULL;
   7296 	dns_dbnode_t *node = NULL;
   7297 
   7298 	CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
   7299 	CHECK(dns_dbiterator_seek(dbit, oldname));
   7300 	do {
   7301 		result = dns_dbiterator_next(dbit);
   7302 		if (result == ISC_R_NOMORE) {
   7303 			CHECK(dns_dbiterator_first(dbit));
   7304 		}
   7305 		CHECK(dns_dbiterator_current(dbit, &node, newname));
   7306 		if (bottom && dns_name_issubdomain(newname, oldname) &&
   7307 		    !dns_name_equal(newname, oldname))
   7308 		{
   7309 			dns_db_detachnode(db, &node);
   7310 			continue;
   7311 		}
   7312 		/*
   7313 		 * Is this node empty?
   7314 		 */
   7315 		CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
   7316 		result = dns_rdatasetiter_first(rdsit);
   7317 		dns_db_detachnode(db, &node);
   7318 		dns_rdatasetiter_destroy(&rdsit);
   7319 		if (result != ISC_R_NOMORE) {
   7320 			break;
   7321 		}
   7322 	} while (1);
   7323 failure:
   7324 	if (node != NULL) {
   7325 		dns_db_detachnode(db, &node);
   7326 	}
   7327 	if (dbit != NULL) {
   7328 		dns_dbiterator_destroy(&dbit);
   7329 	}
   7330 	return (result);
   7331 }
   7332 
   7333 static bool
   7334 signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   7335 		     dns_dbversion_t *version, dns_rdatatype_t type,
   7336 		     dst_key_t *key) {
   7337 	isc_result_t result;
   7338 	dns_rdataset_t rdataset;
   7339 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7340 	dns_rdata_rrsig_t rrsig;
   7341 	int count = 0;
   7342 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   7343 
   7344 	dns_rdataset_init(&rdataset);
   7345 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
   7346 				     type, 0, &rdataset, NULL);
   7347 	if (result != ISC_R_SUCCESS) {
   7348 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7349 		return (false);
   7350 	}
   7351 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7352 	     result = dns_rdataset_next(&rdataset))
   7353 	{
   7354 		dns_rdataset_current(&rdataset, &rdata);
   7355 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   7356 		INSIST(result == ISC_R_SUCCESS);
   7357 		if (rrsig.algorithm == dst_key_alg(key) &&
   7358 		    rrsig.keyid == dst_key_id(key)) {
   7359 			dns_rdataset_disassociate(&rdataset);
   7360 			return (true);
   7361 		}
   7362 		if (rrsig.algorithm == dst_key_alg(key)) {
   7363 			count++;
   7364 		}
   7365 		dns_rdata_reset(&rdata);
   7366 	}
   7367 
   7368 	if (dns_zone_use_kasp(zone)) {
   7369 		dns_kasp_key_t *kkey;
   7370 		int zsk_count = 0;
   7371 		bool approved;
   7372 
   7373 		LOCK(&kasp->lock);
   7374 		for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
   7375 		     kkey = ISC_LIST_NEXT(kkey, link))
   7376 		{
   7377 			if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) {
   7378 				continue;
   7379 			}
   7380 			if (dns_kasp_key_zsk(kkey)) {
   7381 				zsk_count++;
   7382 			}
   7383 		}
   7384 		UNLOCK(&kasp->lock);
   7385 
   7386 		if (type == dns_rdatatype_dnskey ||
   7387 		    type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds)
   7388 		{
   7389 			/*
   7390 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7391 			 * (RFC 7344, section 4.1 specifies that they must
   7392 			 * be signed with a key in the current DS RRset,
   7393 			 * which would only include KSK's.)
   7394 			 */
   7395 			approved = false;
   7396 		} else {
   7397 			approved = (zsk_count == count);
   7398 		}
   7399 
   7400 		dns_rdataset_disassociate(&rdataset);
   7401 		return (approved);
   7402 	}
   7403 
   7404 	dns_rdataset_disassociate(&rdataset);
   7405 	return (false);
   7406 }
   7407 
   7408 static isc_result_t
   7409 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7410 	 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) {
   7411 	dns_fixedname_t fixed;
   7412 	dns_name_t *next;
   7413 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7414 	isc_result_t result;
   7415 	unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
   7416 
   7417 	next = dns_fixedname_initname(&fixed);
   7418 
   7419 	CHECK(next_active(db, version, name, next, bottom));
   7420 	CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata));
   7421 	CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
   7422 			    &rdata));
   7423 failure:
   7424 	return (result);
   7425 }
   7426 
   7427 static isc_result_t
   7428 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node,
   7429 			dns_dbversion_t *version, bool *is_bottom_of_zone) {
   7430 	isc_result_t result;
   7431 	dns_rdatasetiter_t *iterator = NULL;
   7432 	dns_rdataset_t rdataset;
   7433 	bool seen_soa = false, seen_ns = false, seen_dname = false;
   7434 
   7435 	REQUIRE(is_bottom_of_zone != NULL);
   7436 
   7437 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   7438 	if (result != ISC_R_SUCCESS) {
   7439 		if (result == ISC_R_NOTFOUND) {
   7440 			result = ISC_R_SUCCESS;
   7441 		}
   7442 		return (result);
   7443 	}
   7444 
   7445 	dns_rdataset_init(&rdataset);
   7446 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7447 	     result = dns_rdatasetiter_next(iterator))
   7448 	{
   7449 		dns_rdatasetiter_current(iterator, &rdataset);
   7450 		switch (rdataset.type) {
   7451 		case dns_rdatatype_soa:
   7452 			seen_soa = true;
   7453 			break;
   7454 		case dns_rdatatype_ns:
   7455 			seen_ns = true;
   7456 			break;
   7457 		case dns_rdatatype_dname:
   7458 			seen_dname = true;
   7459 			break;
   7460 		}
   7461 		dns_rdataset_disassociate(&rdataset);
   7462 	}
   7463 	if (result != ISC_R_NOMORE) {
   7464 		goto failure;
   7465 	}
   7466 	if ((seen_ns && !seen_soa) || seen_dname) {
   7467 		*is_bottom_of_zone = true;
   7468 	}
   7469 	result = ISC_R_SUCCESS;
   7470 
   7471 failure:
   7472 	dns_rdatasetiter_destroy(&iterator);
   7473 
   7474 	return (result);
   7475 }
   7476 
   7477 static isc_result_t
   7478 sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
   7479 	    dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3,
   7480 	    bool build_nsec, dst_key_t *key, isc_stdtime_t inception,
   7481 	    isc_stdtime_t expire, unsigned int minimum, bool is_ksk,
   7482 	    bool is_zsk, bool keyset_kskonly, bool is_bottom_of_zone,
   7483 	    dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx) {
   7484 	isc_result_t result;
   7485 	dns_rdatasetiter_t *iterator = NULL;
   7486 	dns_rdataset_t rdataset;
   7487 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7488 	dns_stats_t *dnssecsignstats;
   7489 
   7490 	isc_buffer_t buffer;
   7491 	unsigned char data[1024];
   7492 	bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds;
   7493 
   7494 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   7495 	if (result != ISC_R_SUCCESS) {
   7496 		if (result == ISC_R_NOTFOUND) {
   7497 			result = ISC_R_SUCCESS;
   7498 		}
   7499 		return (result);
   7500 	}
   7501 
   7502 	dns_rdataset_init(&rdataset);
   7503 	isc_buffer_init(&buffer, data, sizeof(data));
   7504 	seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false;
   7505 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7506 	     result = dns_rdatasetiter_next(iterator))
   7507 	{
   7508 		dns_rdatasetiter_current(iterator, &rdataset);
   7509 		if (rdataset.type == dns_rdatatype_soa) {
   7510 			seen_soa = true;
   7511 		} else if (rdataset.type == dns_rdatatype_ns) {
   7512 			seen_ns = true;
   7513 		} else if (rdataset.type == dns_rdatatype_ds) {
   7514 			seen_ds = true;
   7515 		} else if (rdataset.type == dns_rdatatype_nsec) {
   7516 			seen_nsec = true;
   7517 		} else if (rdataset.type == dns_rdatatype_nsec3) {
   7518 			seen_nsec3 = true;
   7519 		}
   7520 		if (rdataset.type != dns_rdatatype_rrsig) {
   7521 			seen_rr = true;
   7522 		}
   7523 		dns_rdataset_disassociate(&rdataset);
   7524 	}
   7525 	if (result != ISC_R_NOMORE) {
   7526 		goto failure;
   7527 	}
   7528 	/*
   7529 	 * Going from insecure to NSEC3.
   7530 	 * Don't generate NSEC3 records for NSEC3 records.
   7531 	 */
   7532 	if (build_nsec3 && !seen_nsec3 && seen_rr) {
   7533 		bool unsecure = !seen_ds && seen_ns && !seen_soa;
   7534 		CHECK(dns_nsec3_addnsec3s(db, version, name, minimum, unsecure,
   7535 					  diff));
   7536 		(*signatures)--;
   7537 	}
   7538 	/*
   7539 	 * Going from insecure to NSEC.
   7540 	 * Don't generate NSEC records for NSEC3 records.
   7541 	 */
   7542 	if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
   7543 		/*
   7544 		 * Build a NSEC record except at the origin.
   7545 		 */
   7546 		if (!dns_name_equal(name, dns_db_origin(db))) {
   7547 			CHECK(add_nsec(db, version, name, node, minimum,
   7548 				       is_bottom_of_zone, diff));
   7549 			/* Count a NSEC generation as a signature generation. */
   7550 			(*signatures)--;
   7551 		}
   7552 	}
   7553 	result = dns_rdatasetiter_first(iterator);
   7554 	while (result == ISC_R_SUCCESS) {
   7555 		isc_stdtime_t when;
   7556 
   7557 		dns_rdatasetiter_current(iterator, &rdataset);
   7558 		if (rdataset.type == dns_rdatatype_soa ||
   7559 		    rdataset.type == dns_rdatatype_rrsig) {
   7560 			goto next_rdataset;
   7561 		}
   7562 		if (rdataset.type == dns_rdatatype_dnskey ||
   7563 		    rdataset.type == dns_rdatatype_cdnskey ||
   7564 		    rdataset.type == dns_rdatatype_cds)
   7565 		{
   7566 			/*
   7567 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7568 			 * (RFC 7344, section 4.1 specifies that they must
   7569 			 * be signed with a key in the current DS RRset,
   7570 			 * which would only include KSK's.)
   7571 			 */
   7572 			if (!is_ksk && keyset_kskonly) {
   7573 				goto next_rdataset;
   7574 			}
   7575 		} else if (!is_zsk) {
   7576 			goto next_rdataset;
   7577 		} else if (is_zsk && !dst_key_is_signing(key, DST_BOOL_ZSK,
   7578 							 inception, &when)) {
   7579 			/* Only applies to dnssec-policy. */
   7580 			if (dns_zone_use_kasp(zone)) {
   7581 				goto next_rdataset;
   7582 			}
   7583 		}
   7584 
   7585 		if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds &&
   7586 		    rdataset.type != dns_rdatatype_nsec)
   7587 		{
   7588 			goto next_rdataset;
   7589 		}
   7590 		if (signed_with_good_key(zone, db, node, version, rdataset.type,
   7591 					 key)) {
   7592 			goto next_rdataset;
   7593 		}
   7594 
   7595 		/* Calculate the signature, creating a RRSIG RDATA. */
   7596 		isc_buffer_clear(&buffer);
   7597 		CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, &expire,
   7598 				      mctx, &buffer, &rdata));
   7599 		/* Update the database and journal with the RRSIG. */
   7600 		/* XXX inefficient - will cause dataset merging */
   7601 		CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
   7602 				    name, rdataset.ttl, &rdata));
   7603 		dns_rdata_reset(&rdata);
   7604 
   7605 		/* Update DNSSEC sign statistics. */
   7606 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7607 		if (dnssecsignstats != NULL) {
   7608 			/* Generated a new signature. */
   7609 			dns_dnssecsignstats_increment(dnssecsignstats, ID(key),
   7610 						      ALG(key),
   7611 						      dns_dnssecsignstats_sign);
   7612 			/* This is a refresh. */
   7613 			dns_dnssecsignstats_increment(
   7614 				dnssecsignstats, ID(key), ALG(key),
   7615 				dns_dnssecsignstats_refresh);
   7616 		}
   7617 
   7618 		(*signatures)--;
   7619 	next_rdataset:
   7620 		dns_rdataset_disassociate(&rdataset);
   7621 		result = dns_rdatasetiter_next(iterator);
   7622 	}
   7623 	if (result == ISC_R_NOMORE) {
   7624 		result = ISC_R_SUCCESS;
   7625 	}
   7626 failure:
   7627 	if (dns_rdataset_isassociated(&rdataset)) {
   7628 		dns_rdataset_disassociate(&rdataset);
   7629 	}
   7630 	if (iterator != NULL) {
   7631 		dns_rdatasetiter_destroy(&iterator);
   7632 	}
   7633 	return (result);
   7634 }
   7635 
   7636 /*
   7637  * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
   7638  */
   7639 static isc_result_t
   7640 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7641 	     dns_ttl_t minimum, bool update_only, dns_diff_t *diff) {
   7642 	isc_result_t result;
   7643 	dns_rdataset_t rdataset;
   7644 	dns_dbnode_t *node = NULL;
   7645 
   7646 	CHECK(dns_db_getoriginnode(db, &node));
   7647 	if (update_only) {
   7648 		dns_rdataset_init(&rdataset);
   7649 		result = dns_db_findrdataset(
   7650 			db, node, version, dns_rdatatype_nsec,
   7651 			dns_rdatatype_none, 0, &rdataset, NULL);
   7652 		if (dns_rdataset_isassociated(&rdataset)) {
   7653 			dns_rdataset_disassociate(&rdataset);
   7654 		}
   7655 		if (result == ISC_R_NOTFOUND) {
   7656 			goto success;
   7657 		}
   7658 		if (result != ISC_R_SUCCESS) {
   7659 			goto failure;
   7660 		}
   7661 	}
   7662 	CHECK(delete_nsec(db, version, node, name, diff));
   7663 	CHECK(add_nsec(db, version, name, node, minimum, false, diff));
   7664 success:
   7665 	result = ISC_R_SUCCESS;
   7666 failure:
   7667 	if (node != NULL) {
   7668 		dns_db_detachnode(db, &node);
   7669 	}
   7670 	return (result);
   7671 }
   7672 
   7673 static isc_result_t
   7674 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
   7675 		  dns_dbversion_t *version, bool build_nsec3, dns_ttl_t minimum,
   7676 		  dns_diff_t *diff) {
   7677 	isc_result_t result;
   7678 	dns_dbnode_t *node = NULL;
   7679 	dns_rdataset_t rdataset;
   7680 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7681 	unsigned char data[5];
   7682 	bool seen_done = false;
   7683 	bool have_rr = false;
   7684 
   7685 	dns_rdataset_init(&rdataset);
   7686 	result = dns_db_getoriginnode(signing->db, &node);
   7687 	if (result != ISC_R_SUCCESS) {
   7688 		goto failure;
   7689 	}
   7690 
   7691 	result = dns_db_findrdataset(signing->db, node, version,
   7692 				     zone->privatetype, dns_rdatatype_none, 0,
   7693 				     &rdataset, NULL);
   7694 	if (result == ISC_R_NOTFOUND) {
   7695 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7696 		result = ISC_R_SUCCESS;
   7697 		goto failure;
   7698 	}
   7699 	if (result != ISC_R_SUCCESS) {
   7700 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7701 		goto failure;
   7702 	}
   7703 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7704 	     result = dns_rdataset_next(&rdataset))
   7705 	{
   7706 		dns_rdataset_current(&rdataset, &rdata);
   7707 		/*
   7708 		 * If we don't match the algorithm or keyid skip the record.
   7709 		 */
   7710 		if (rdata.length != 5 || rdata.data[0] != signing->algorithm ||
   7711 		    rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
   7712 		    rdata.data[2] != (signing->keyid & 0xff))
   7713 		{
   7714 			have_rr = true;
   7715 			dns_rdata_reset(&rdata);
   7716 			continue;
   7717 		}
   7718 		/*
   7719 		 * We have a match.  If we were signing (!signing->deleteit)
   7720 		 * and we already have a record indicating that we have
   7721 		 * finished signing (rdata.data[4] != 0) then keep it.
   7722 		 * Otherwise it needs to be deleted as we have removed all
   7723 		 * the signatures (signing->deleteit), so any record indicating
   7724 		 * completion is now out of date, or we have finished signing
   7725 		 * with the new record so we no longer need to remember that
   7726 		 * we need to sign the zone with the matching key across a
   7727 		 * nameserver re-start.
   7728 		 */
   7729 		if (!signing->deleteit && rdata.data[4] != 0) {
   7730 			seen_done = true;
   7731 			have_rr = true;
   7732 		} else {
   7733 			CHECK(update_one_rr(signing->db, version, diff,
   7734 					    DNS_DIFFOP_DEL, &zone->origin,
   7735 					    rdataset.ttl, &rdata));
   7736 		}
   7737 		dns_rdata_reset(&rdata);
   7738 	}
   7739 	if (result == ISC_R_NOMORE) {
   7740 		result = ISC_R_SUCCESS;
   7741 	}
   7742 	if (!signing->deleteit && !seen_done) {
   7743 		/*
   7744 		 * If we were signing then we need to indicate that we have
   7745 		 * finished signing the zone with this key.  If it is already
   7746 		 * there we don't need to add it a second time.
   7747 		 */
   7748 		data[0] = signing->algorithm;
   7749 		data[1] = (signing->keyid >> 8) & 0xff;
   7750 		data[2] = signing->keyid & 0xff;
   7751 		data[3] = 0;
   7752 		data[4] = 1;
   7753 		rdata.length = sizeof(data);
   7754 		rdata.data = data;
   7755 		rdata.type = zone->privatetype;
   7756 		rdata.rdclass = dns_db_class(signing->db);
   7757 		CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
   7758 				    &zone->origin, rdataset.ttl, &rdata));
   7759 	} else if (!have_rr) {
   7760 		dns_name_t *origin = dns_db_origin(signing->db);
   7761 		/*
   7762 		 * Rebuild the NSEC/NSEC3 record for the origin as we no
   7763 		 * longer have any private records.
   7764 		 */
   7765 		if (build_nsec3) {
   7766 			CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
   7767 						  minimum, false, diff));
   7768 		}
   7769 		CHECK(updatesecure(signing->db, version, origin, minimum, true,
   7770 				   diff));
   7771 	}
   7772 
   7773 failure:
   7774 	if (dns_rdataset_isassociated(&rdataset)) {
   7775 		dns_rdataset_disassociate(&rdataset);
   7776 	}
   7777 	if (node != NULL) {
   7778 		dns_db_detachnode(signing->db, &node);
   7779 	}
   7780 	return (result);
   7781 }
   7782 
   7783 /*
   7784  * Called from zone_nsec3chain() in order to update zone records indicating
   7785  * processing status of given NSEC3 chain:
   7786  *
   7787  *   - If the supplied dns_nsec3chain_t structure has been fully processed
   7788  *     (which is indicated by "active" being set to false):
   7789  *
   7790  *       - remove all NSEC3PARAM records matching the relevant NSEC3 chain,
   7791  *
   7792  *       - remove all private-type records containing NSEC3PARAM RDATA matching
   7793  *         the relevant NSEC3 chain.
   7794  *
   7795  *   - If the supplied dns_nsec3chain_t structure has not been fully processed
   7796  *     (which is indicated by "active" being set to true), only remove the
   7797  *     NSEC3PARAM record which matches the relevant NSEC3 chain and has the
   7798  *     "flags" field set to 0.
   7799  *
   7800  *   - If given NSEC3 chain is being added, add an NSEC3PARAM record contained
   7801  *     in the relevant private-type record, but with the "flags" field set to
   7802  *     0, indicating that this NSEC3 chain is now complete for this zone.
   7803  *
   7804  * Note that this function is called at different processing stages for NSEC3
   7805  * chain additions vs. removals and needs to handle all cases properly.
   7806  */
   7807 static isc_result_t
   7808 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
   7809 		 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) {
   7810 	dns_dbnode_t *node = NULL;
   7811 	dns_name_t *name = dns_db_origin(db);
   7812 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7813 	dns_rdataset_t rdataset;
   7814 	dns_rdata_nsec3param_t nsec3param;
   7815 	isc_result_t result;
   7816 	isc_buffer_t buffer;
   7817 	unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
   7818 	dns_ttl_t ttl = 0;
   7819 	bool nseconly = false, nsec3ok = false;
   7820 
   7821 	dns_rdataset_init(&rdataset);
   7822 
   7823 	result = dns_db_getoriginnode(db, &node);
   7824 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   7825 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   7826 				     0, &rdataset, NULL);
   7827 	if (result == ISC_R_NOTFOUND) {
   7828 		goto try_private;
   7829 	}
   7830 	if (result != ISC_R_SUCCESS) {
   7831 		goto failure;
   7832 	}
   7833 
   7834 	/*
   7835 	 * Preserve the existing ttl.
   7836 	 */
   7837 	ttl = rdataset.ttl;
   7838 
   7839 	/*
   7840 	 * Delete all NSEC3PARAM records which match that in nsec3chain.
   7841 	 */
   7842 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7843 	     result = dns_rdataset_next(&rdataset))
   7844 	{
   7845 		dns_rdataset_current(&rdataset, &rdata);
   7846 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   7847 
   7848 		if (nsec3param.hash != chain->nsec3param.hash ||
   7849 		    (active && nsec3param.flags != 0) ||
   7850 		    nsec3param.iterations != chain->nsec3param.iterations ||
   7851 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   7852 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   7853 			   nsec3param.salt_length))
   7854 		{
   7855 			dns_rdata_reset(&rdata);
   7856 			continue;
   7857 		}
   7858 
   7859 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7860 				    rdataset.ttl, &rdata));
   7861 		dns_rdata_reset(&rdata);
   7862 	}
   7863 	if (result != ISC_R_NOMORE) {
   7864 		goto failure;
   7865 	}
   7866 
   7867 	dns_rdataset_disassociate(&rdataset);
   7868 
   7869 try_private:
   7870 
   7871 	if (active) {
   7872 		goto add;
   7873 	}
   7874 
   7875 	result = dns_nsec_nseconly(db, ver, &nseconly);
   7876 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   7877 
   7878 	/*
   7879 	 * Delete all private records which match that in nsec3chain.
   7880 	 */
   7881 	result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0,
   7882 				     &rdataset, NULL);
   7883 	if (result == ISC_R_NOTFOUND) {
   7884 		goto add;
   7885 	}
   7886 	if (result != ISC_R_SUCCESS) {
   7887 		goto failure;
   7888 	}
   7889 
   7890 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7891 	     result = dns_rdataset_next(&rdataset))
   7892 	{
   7893 		dns_rdata_t private = DNS_RDATA_INIT;
   7894 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   7895 
   7896 		dns_rdataset_current(&rdataset, &private);
   7897 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   7898 						sizeof(buf))) {
   7899 			continue;
   7900 		}
   7901 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   7902 
   7903 		if ((!nsec3ok &&
   7904 		     (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
   7905 		    nsec3param.hash != chain->nsec3param.hash ||
   7906 		    nsec3param.iterations != chain->nsec3param.iterations ||
   7907 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   7908 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   7909 			   nsec3param.salt_length))
   7910 		{
   7911 			dns_rdata_reset(&rdata);
   7912 			continue;
   7913 		}
   7914 
   7915 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7916 				    rdataset.ttl, &private));
   7917 		dns_rdata_reset(&rdata);
   7918 	}
   7919 	if (result != ISC_R_NOMORE) {
   7920 		goto failure;
   7921 	}
   7922 
   7923 add:
   7924 	if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   7925 		result = ISC_R_SUCCESS;
   7926 		goto failure;
   7927 	}
   7928 
   7929 	/*
   7930 	 * Add a NSEC3PARAM record which matches that in nsec3chain but
   7931 	 * with all flags bits cleared.
   7932 	 *
   7933 	 * Note: we do not clear chain->nsec3param.flags as this change
   7934 	 * may be reversed.
   7935 	 */
   7936 	isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
   7937 	CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
   7938 				   dns_rdatatype_nsec3param, &chain->nsec3param,
   7939 				   &buffer));
   7940 	rdata.data[1] = 0; /* Clear flag bits. */
   7941 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
   7942 
   7943 failure:
   7944 	dns_db_detachnode(db, &node);
   7945 	if (dns_rdataset_isassociated(&rdataset)) {
   7946 		dns_rdataset_disassociate(&rdataset);
   7947 	}
   7948 	return (result);
   7949 }
   7950 
   7951 static isc_result_t
   7952 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   7953 	    dns_name_t *name, dns_diff_t *diff) {
   7954 	dns_rdataset_t rdataset;
   7955 	isc_result_t result;
   7956 
   7957 	dns_rdataset_init(&rdataset);
   7958 
   7959 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   7960 				     &rdataset, NULL);
   7961 	if (result == ISC_R_NOTFOUND) {
   7962 		return (ISC_R_SUCCESS);
   7963 	}
   7964 	if (result != ISC_R_SUCCESS) {
   7965 		return (result);
   7966 	}
   7967 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7968 	     result = dns_rdataset_next(&rdataset))
   7969 	{
   7970 		dns_rdata_t rdata = DNS_RDATA_INIT;
   7971 
   7972 		dns_rdataset_current(&rdataset, &rdata);
   7973 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7974 				    rdataset.ttl, &rdata));
   7975 	}
   7976 	if (result == ISC_R_NOMORE) {
   7977 		result = ISC_R_SUCCESS;
   7978 	}
   7979 failure:
   7980 	dns_rdataset_disassociate(&rdataset);
   7981 	return (result);
   7982 }
   7983 
   7984 static isc_result_t
   7985 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   7986 		    dns_name_t *name, const dns_rdata_nsec3param_t *param,
   7987 		    dns_diff_t *diff) {
   7988 	dns_rdataset_t rdataset;
   7989 	dns_rdata_nsec3_t nsec3;
   7990 	isc_result_t result;
   7991 
   7992 	dns_rdataset_init(&rdataset);
   7993 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0,
   7994 				     &rdataset, NULL);
   7995 	if (result == ISC_R_NOTFOUND) {
   7996 		return (ISC_R_SUCCESS);
   7997 	}
   7998 	if (result != ISC_R_SUCCESS) {
   7999 		return (result);
   8000 	}
   8001 
   8002 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8003 	     result = dns_rdataset_next(&rdataset))
   8004 	{
   8005 		dns_rdata_t rdata = DNS_RDATA_INIT;
   8006 
   8007 		dns_rdataset_current(&rdataset, &rdata);
   8008 		CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
   8009 		if (nsec3.hash != param->hash ||
   8010 		    nsec3.iterations != param->iterations ||
   8011 		    nsec3.salt_length != param->salt_length ||
   8012 		    memcmp(nsec3.salt, param->salt, nsec3.salt_length))
   8013 		{
   8014 			continue;
   8015 		}
   8016 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8017 				    rdataset.ttl, &rdata));
   8018 	}
   8019 	if (result == ISC_R_NOMORE) {
   8020 		result = ISC_R_SUCCESS;
   8021 	}
   8022 failure:
   8023 	dns_rdataset_disassociate(&rdataset);
   8024 	return (result);
   8025 }
   8026 
   8027 static isc_result_t
   8028 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
   8029 		const dns_rdata_nsec3param_t *param, bool *answer) {
   8030 	dns_dbnode_t *node = NULL;
   8031 	dns_rdata_t rdata = DNS_RDATA_INIT;
   8032 	dns_rdata_nsec3param_t myparam;
   8033 	dns_rdataset_t rdataset;
   8034 	isc_result_t result;
   8035 
   8036 	*answer = false;
   8037 
   8038 	result = dns_db_getoriginnode(db, &node);
   8039 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8040 
   8041 	dns_rdataset_init(&rdataset);
   8042 
   8043 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   8044 				     &rdataset, NULL);
   8045 	if (result == ISC_R_SUCCESS) {
   8046 		dns_rdataset_disassociate(&rdataset);
   8047 		dns_db_detachnode(db, &node);
   8048 		return (result);
   8049 	}
   8050 	if (result != ISC_R_NOTFOUND) {
   8051 		dns_db_detachnode(db, &node);
   8052 		return (result);
   8053 	}
   8054 
   8055 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   8056 				     0, &rdataset, NULL);
   8057 	if (result == ISC_R_NOTFOUND) {
   8058 		*answer = true;
   8059 		dns_db_detachnode(db, &node);
   8060 		return (ISC_R_SUCCESS);
   8061 	}
   8062 	if (result != ISC_R_SUCCESS) {
   8063 		dns_db_detachnode(db, &node);
   8064 		return (result);
   8065 	}
   8066 
   8067 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8068 	     result = dns_rdataset_next(&rdataset))
   8069 	{
   8070 		dns_rdataset_current(&rdataset, &rdata);
   8071 		CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
   8072 		dns_rdata_reset(&rdata);
   8073 		/*
   8074 		 * Ignore any NSEC3PARAM removals.
   8075 		 */
   8076 		if (NSEC3REMOVE(myparam.flags)) {
   8077 			continue;
   8078 		}
   8079 		/*
   8080 		 * Ignore the chain that we are in the process of deleting.
   8081 		 */
   8082 		if (myparam.hash == param->hash &&
   8083 		    myparam.iterations == param->iterations &&
   8084 		    myparam.salt_length == param->salt_length &&
   8085 		    !memcmp(myparam.salt, param->salt, myparam.salt_length))
   8086 		{
   8087 			continue;
   8088 		}
   8089 		/*
   8090 		 * Found an active NSEC3 chain.
   8091 		 */
   8092 		break;
   8093 	}
   8094 	if (result == ISC_R_NOMORE) {
   8095 		*answer = true;
   8096 		result = ISC_R_SUCCESS;
   8097 	}
   8098 
   8099 failure:
   8100 	if (dns_rdataset_isassociated(&rdataset)) {
   8101 		dns_rdataset_disassociate(&rdataset);
   8102 	}
   8103 	dns_db_detachnode(db, &node);
   8104 	return (result);
   8105 }
   8106 
   8107 /*%
   8108  * Given a tuple which is part of a diff, return a pointer to the next tuple in
   8109  * that diff which has the same name and type (or NULL if no such tuple is
   8110  * found).
   8111  */
   8112 static dns_difftuple_t *
   8113 find_next_matching_tuple(dns_difftuple_t *cur) {
   8114 	dns_difftuple_t *next = cur;
   8115 
   8116 	while ((next = ISC_LIST_NEXT(next, link)) != NULL) {
   8117 		if (cur->rdata.type == next->rdata.type &&
   8118 		    dns_name_equal(&cur->name, &next->name))
   8119 		{
   8120 			return (next);
   8121 		}
   8122 	}
   8123 
   8124 	return (NULL);
   8125 }
   8126 
   8127 /*%
   8128  * Remove all tuples with the same name and type as 'cur' from 'src' and append
   8129  * them to 'dst'.
   8130  */
   8131 static void
   8132 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) {
   8133 	do {
   8134 		dns_difftuple_t *next = find_next_matching_tuple(cur);
   8135 		ISC_LIST_UNLINK(src->tuples, cur, link);
   8136 		dns_diff_appendminimal(dst, &cur);
   8137 		cur = next;
   8138 	} while (cur != NULL);
   8139 }
   8140 
   8141 /*%
   8142  * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in
   8143  * 'diff'.  Gradually remove tuples from 'diff' and append them to 'zonediff'
   8144  * along with tuples representing relevant signature changes.
   8145  */
   8146 isc_result_t
   8147 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
   8148 		     dst_key_t *zone_keys[], unsigned int nkeys,
   8149 		     dns_zone_t *zone, isc_stdtime_t inception,
   8150 		     isc_stdtime_t expire, isc_stdtime_t keyexpire,
   8151 		     isc_stdtime_t now, bool check_ksk, bool keyset_kskonly,
   8152 		     dns__zonediff_t *zonediff) {
   8153 	dns_difftuple_t *tuple;
   8154 	isc_result_t result;
   8155 
   8156 	while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) {
   8157 		isc_stdtime_t exp = expire;
   8158 
   8159 		if (keyexpire != 0 &&
   8160 		    (tuple->rdata.type == dns_rdatatype_dnskey ||
   8161 		     tuple->rdata.type == dns_rdatatype_cdnskey ||
   8162 		     tuple->rdata.type == dns_rdatatype_cds))
   8163 		{
   8164 			exp = keyexpire;
   8165 		}
   8166 
   8167 		result = del_sigs(zone, db, version, &tuple->name,
   8168 				  tuple->rdata.type, zonediff, zone_keys, nkeys,
   8169 				  now, false);
   8170 		if (result != ISC_R_SUCCESS) {
   8171 			dns_zone_log(zone, ISC_LOG_ERROR,
   8172 				     "dns__zone_updatesigs:del_sigs -> %s",
   8173 				     dns_result_totext(result));
   8174 			return (result);
   8175 		}
   8176 		result = add_sigs(db, version, &tuple->name, zone,
   8177 				  tuple->rdata.type, zonediff->diff, zone_keys,
   8178 				  nkeys, zone->mctx, inception, exp, check_ksk,
   8179 				  keyset_kskonly);
   8180 		if (result != ISC_R_SUCCESS) {
   8181 			dns_zone_log(zone, ISC_LOG_ERROR,
   8182 				     "dns__zone_updatesigs:add_sigs -> %s",
   8183 				     dns_result_totext(result));
   8184 			return (result);
   8185 		}
   8186 
   8187 		/*
   8188 		 * Signature changes for all RRs with name tuple->name and type
   8189 		 * tuple->rdata.type were appended to zonediff->diff.  Now we
   8190 		 * remove all the "raw" changes with the same name and type
   8191 		 * from diff (so that they are not processed by this loop
   8192 		 * again) and append them to zonediff so that they get applied.
   8193 		 */
   8194 		move_matching_tuples(tuple, diff, zonediff->diff);
   8195 	}
   8196 	return (ISC_R_SUCCESS);
   8197 }
   8198 
   8199 /*
   8200  * Incrementally build and sign a new NSEC3 chain using the parameters
   8201  * requested.
   8202  */
   8203 static void
   8204 zone_nsec3chain(dns_zone_t *zone) {
   8205 	const char *me = "zone_nsec3chain";
   8206 	dns_db_t *db = NULL;
   8207 	dns_dbnode_t *node = NULL;
   8208 	dns_dbversion_t *version = NULL;
   8209 	dns_diff_t _sig_diff;
   8210 	dns_diff_t nsec_diff;
   8211 	dns_diff_t nsec3_diff;
   8212 	dns_diff_t param_diff;
   8213 	dns__zonediff_t zonediff;
   8214 	dns_fixedname_t fixed;
   8215 	dns_fixedname_t nextfixed;
   8216 	dns_name_t *name, *nextname;
   8217 	dns_rdataset_t rdataset;
   8218 	dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
   8219 	dns_nsec3chainlist_t cleanup;
   8220 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   8221 	int32_t signatures;
   8222 	bool check_ksk, keyset_kskonly;
   8223 	bool delegation;
   8224 	bool first;
   8225 	isc_result_t result;
   8226 	isc_stdtime_t now, inception, soaexpire, expire;
   8227 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   8228 	unsigned int i;
   8229 	unsigned int nkeys = 0;
   8230 	uint32_t nodes;
   8231 	bool unsecure = false;
   8232 	bool seen_soa, seen_ns, seen_dname, seen_ds;
   8233 	bool seen_nsec, seen_nsec3, seen_rr;
   8234 	dns_rdatasetiter_t *iterator = NULL;
   8235 	bool buildnsecchain;
   8236 	bool updatensec = false;
   8237 	dns_rdatatype_t privatetype = zone->privatetype;
   8238 
   8239 	ENTER;
   8240 
   8241 	dns_rdataset_init(&rdataset);
   8242 	name = dns_fixedname_initname(&fixed);
   8243 	nextname = dns_fixedname_initname(&nextfixed);
   8244 	dns_diff_init(zone->mctx, &param_diff);
   8245 	dns_diff_init(zone->mctx, &nsec3_diff);
   8246 	dns_diff_init(zone->mctx, &nsec_diff);
   8247 	dns_diff_init(zone->mctx, &_sig_diff);
   8248 	zonediff_init(&zonediff, &_sig_diff);
   8249 	ISC_LIST_INIT(cleanup);
   8250 
   8251 	/*
   8252 	 * Updates are disabled.  Pause for 5 minutes.
   8253 	 */
   8254 	if (zone->update_disabled) {
   8255 		result = ISC_R_FAILURE;
   8256 		goto failure;
   8257 	}
   8258 
   8259 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8260 	/*
   8261 	 * This function is called when zone timer fires, after the latter gets
   8262 	 * set by zone_addnsec3chain().  If the action triggering the call to
   8263 	 * zone_addnsec3chain() is closely followed by a zone deletion request,
   8264 	 * it might turn out that the timer thread will not be woken up until
   8265 	 * after the zone is deleted by rmzone(), which calls dns_db_detach()
   8266 	 * for zone->db, causing the latter to become NULL.  Return immediately
   8267 	 * if that happens.
   8268 	 */
   8269 	if (zone->db != NULL) {
   8270 		dns_db_attach(zone->db, &db);
   8271 	}
   8272 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8273 	if (db == NULL) {
   8274 		return;
   8275 	}
   8276 
   8277 	result = dns_db_newversion(db, &version);
   8278 	if (result != ISC_R_SUCCESS) {
   8279 		dnssec_log(zone, ISC_LOG_ERROR,
   8280 			   "zone_nsec3chain:dns_db_newversion -> %s",
   8281 			   dns_result_totext(result));
   8282 		goto failure;
   8283 	}
   8284 
   8285 	isc_stdtime_get(&now);
   8286 
   8287 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   8288 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   8289 	if (result != ISC_R_SUCCESS) {
   8290 		dnssec_log(zone, ISC_LOG_ERROR,
   8291 			   "zone_nsec3chain:dns__zone_findkeys -> %s",
   8292 			   dns_result_totext(result));
   8293 		goto failure;
   8294 	}
   8295 
   8296 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   8297 	inception = now - 3600; /* Allow for clock skew. */
   8298 	soaexpire = now + sigvalidityinterval;
   8299 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   8300 	if (expiryinterval > sigvalidityinterval) {
   8301 		expiryinterval = sigvalidityinterval;
   8302 	} else {
   8303 		expiryinterval = sigvalidityinterval - expiryinterval;
   8304 	}
   8305 
   8306 	/*
   8307 	 * Spread out signatures over time if they happen to be
   8308 	 * clumped.  We don't do this for each add_sigs() call as
   8309 	 * we still want some clustering to occur.
   8310 	 */
   8311 	if (sigvalidityinterval >= 3600U) {
   8312 		if (sigvalidityinterval > 7200U) {
   8313 			jitter = isc_random_uniform(expiryinterval);
   8314 		} else {
   8315 			jitter = isc_random_uniform(1200);
   8316 		}
   8317 		expire = soaexpire - jitter - 1;
   8318 	} else {
   8319 		expire = soaexpire - 1;
   8320 	}
   8321 
   8322 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   8323 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   8324 
   8325 	/*
   8326 	 * We keep pulling nodes off each iterator in turn until
   8327 	 * we have no more nodes to pull off or we reach the limits
   8328 	 * for this quantum.
   8329 	 */
   8330 	nodes = zone->nodes;
   8331 	signatures = zone->signatures;
   8332 	LOCK_ZONE(zone);
   8333 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8334 	UNLOCK_ZONE(zone);
   8335 	first = true;
   8336 
   8337 	if (nsec3chain != NULL) {
   8338 		nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8339 	}
   8340 	/*
   8341 	 * Generate new NSEC3 chains first.
   8342 	 *
   8343 	 * The following while loop iterates over nodes in the zone database,
   8344 	 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of
   8345 	 * them.  Once all nodes are processed, the "delete_nsec" field is
   8346 	 * consulted to check whether we are supposed to remove NSEC records
   8347 	 * from the zone database; if so, the database iterator is reset to
   8348 	 * point to the first node and the loop traverses all of them again,
   8349 	 * this time removing NSEC records.  If we hit a node which is obscured
   8350 	 * by a delegation or a DNAME, nodes are skipped over until we find one
   8351 	 * that is not obscured by the same obscuring name and then normal
   8352 	 * processing is resumed.
   8353 	 *
   8354 	 * The above is repeated until all requested NSEC3 chain changes are
   8355 	 * applied or when we reach the limits for this quantum, whichever
   8356 	 * happens first.
   8357 	 *
   8358 	 * Note that the "signatures" variable is only used here to limit the
   8359 	 * amount of work performed.  Actual DNSSEC signatures are only
   8360 	 * generated by dns__zone_updatesigs() calls later in this function.
   8361 	 */
   8362 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8363 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8364 
   8365 		LOCK_ZONE(zone);
   8366 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8367 
   8368 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8369 		if (nsec3chain->done || nsec3chain->db != zone->db) {
   8370 			ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   8371 			ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8372 		}
   8373 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8374 		UNLOCK_ZONE(zone);
   8375 		if (ISC_LIST_TAIL(cleanup) == nsec3chain) {
   8376 			goto next_addchain;
   8377 		}
   8378 
   8379 		/*
   8380 		 * Possible future db.
   8381 		 */
   8382 		if (nsec3chain->db != db) {
   8383 			goto next_addchain;
   8384 		}
   8385 
   8386 		if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8387 			goto next_addchain;
   8388 		}
   8389 
   8390 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8391 
   8392 		if (nsec3chain->delete_nsec) {
   8393 			delegation = false;
   8394 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8395 			CHECK(delete_nsec(db, version, node, name, &nsec_diff));
   8396 			goto next_addnode;
   8397 		}
   8398 		/*
   8399 		 * On the first pass we need to check if the current node
   8400 		 * has not been obscured.
   8401 		 */
   8402 		delegation = false;
   8403 		unsecure = false;
   8404 		if (first) {
   8405 			dns_fixedname_t ffound;
   8406 			dns_name_t *found;
   8407 			found = dns_fixedname_initname(&ffound);
   8408 			result = dns_db_find(
   8409 				db, name, version, dns_rdatatype_soa,
   8410 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8411 			if ((result == DNS_R_DELEGATION ||
   8412 			     result == DNS_R_DNAME) &&
   8413 			    !dns_name_equal(name, found))
   8414 			{
   8415 				/*
   8416 				 * Remember the obscuring name so that
   8417 				 * we skip all obscured names.
   8418 				 */
   8419 				dns_name_copynf(found, name);
   8420 				delegation = true;
   8421 				goto next_addnode;
   8422 			}
   8423 		}
   8424 
   8425 		/*
   8426 		 * Check to see if this is a bottom of zone node.
   8427 		 */
   8428 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8429 		if (result == ISC_R_NOTFOUND) {
   8430 			/* Empty node? */
   8431 			goto next_addnode;
   8432 		}
   8433 		if (result != ISC_R_SUCCESS) {
   8434 			goto failure;
   8435 		}
   8436 
   8437 		seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false;
   8438 		for (result = dns_rdatasetiter_first(iterator);
   8439 		     result == ISC_R_SUCCESS;
   8440 		     result = dns_rdatasetiter_next(iterator))
   8441 		{
   8442 			dns_rdatasetiter_current(iterator, &rdataset);
   8443 			INSIST(rdataset.type != dns_rdatatype_nsec3);
   8444 			if (rdataset.type == dns_rdatatype_soa) {
   8445 				seen_soa = true;
   8446 			} else if (rdataset.type == dns_rdatatype_ns) {
   8447 				seen_ns = true;
   8448 			} else if (rdataset.type == dns_rdatatype_dname) {
   8449 				seen_dname = true;
   8450 			} else if (rdataset.type == dns_rdatatype_ds) {
   8451 				seen_ds = true;
   8452 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8453 				seen_nsec = true;
   8454 			}
   8455 			dns_rdataset_disassociate(&rdataset);
   8456 		}
   8457 		dns_rdatasetiter_destroy(&iterator);
   8458 		/*
   8459 		 * Is there a NSEC chain than needs to be cleaned up?
   8460 		 */
   8461 		if (seen_nsec) {
   8462 			nsec3chain->seen_nsec = true;
   8463 		}
   8464 		if (seen_ns && !seen_soa && !seen_ds) {
   8465 			unsecure = true;
   8466 		}
   8467 		if ((seen_ns && !seen_soa) || seen_dname) {
   8468 			delegation = true;
   8469 		}
   8470 
   8471 		/*
   8472 		 * Process one node.
   8473 		 */
   8474 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8475 		result = dns_nsec3_addnsec3(
   8476 			db, version, name, &nsec3chain->nsec3param,
   8477 			zone->minimum, unsecure, &nsec3_diff);
   8478 		if (result != ISC_R_SUCCESS) {
   8479 			dnssec_log(zone, ISC_LOG_ERROR,
   8480 				   "zone_nsec3chain:"
   8481 				   "dns_nsec3_addnsec3 -> %s",
   8482 				   dns_result_totext(result));
   8483 			goto failure;
   8484 		}
   8485 
   8486 		/*
   8487 		 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
   8488 		 * two signatures.  Additionally there will, in general, be
   8489 		 * two signature generated below.
   8490 		 *
   8491 		 * If we are only changing the optout flag the cost is half
   8492 		 * that of the cost of generating a completely new chain.
   8493 		 */
   8494 		signatures -= 4;
   8495 
   8496 		/*
   8497 		 * Go onto next node.
   8498 		 */
   8499 	next_addnode:
   8500 		first = false;
   8501 		dns_db_detachnode(db, &node);
   8502 		do {
   8503 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8504 
   8505 			if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
   8506 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8507 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8508 						       false, privatetype,
   8509 						       &param_diff));
   8510 				LOCK_ZONE(zone);
   8511 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8512 						link);
   8513 				UNLOCK_ZONE(zone);
   8514 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8515 				goto next_addchain;
   8516 			}
   8517 			if (result == ISC_R_NOMORE) {
   8518 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8519 				if (nsec3chain->seen_nsec) {
   8520 					CHECK(fixup_nsec3param(
   8521 						db, version, nsec3chain, true,
   8522 						privatetype, &param_diff));
   8523 					nsec3chain->delete_nsec = true;
   8524 					goto same_addchain;
   8525 				}
   8526 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8527 						       false, privatetype,
   8528 						       &param_diff));
   8529 				LOCK_ZONE(zone);
   8530 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8531 						link);
   8532 				UNLOCK_ZONE(zone);
   8533 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8534 				goto next_addchain;
   8535 			} else if (result != ISC_R_SUCCESS) {
   8536 				dnssec_log(zone, ISC_LOG_ERROR,
   8537 					   "zone_nsec3chain:"
   8538 					   "dns_dbiterator_next -> %s",
   8539 					   dns_result_totext(result));
   8540 				goto failure;
   8541 			} else if (delegation) {
   8542 				dns_dbiterator_current(nsec3chain->dbiterator,
   8543 						       &node, nextname);
   8544 				dns_db_detachnode(db, &node);
   8545 				if (!dns_name_issubdomain(nextname, name)) {
   8546 					break;
   8547 				}
   8548 			} else {
   8549 				break;
   8550 			}
   8551 		} while (1);
   8552 		continue;
   8553 
   8554 	same_addchain:
   8555 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8556 		first = true;
   8557 		continue;
   8558 
   8559 	next_addchain:
   8560 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8561 		nsec3chain = nextnsec3chain;
   8562 		first = true;
   8563 		if (nsec3chain != NULL) {
   8564 			nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8565 		}
   8566 	}
   8567 
   8568 	if (nsec3chain != NULL) {
   8569 		goto skip_removals;
   8570 	}
   8571 
   8572 	/*
   8573 	 * Process removals.
   8574 	 *
   8575 	 * This is a counterpart of the above while loop which takes care of
   8576 	 * removing an NSEC3 chain.  It starts with determining whether the
   8577 	 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an
   8578 	 * NSEC chain by iterating over all nodes in the zone database and only
   8579 	 * then goes on to remove NSEC3 records be iterating over all nodes
   8580 	 * again and calling deletematchingnsec3() for each of them; otherwise,
   8581 	 * it starts removing NSEC3 records immediately.  Rules for processing
   8582 	 * obscured nodes and interrupting work are the same as for the while
   8583 	 * loop above.
   8584 	 */
   8585 	LOCK_ZONE(zone);
   8586 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8587 	UNLOCK_ZONE(zone);
   8588 	first = true;
   8589 	buildnsecchain = false;
   8590 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8591 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8592 
   8593 		LOCK_ZONE(zone);
   8594 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8595 		UNLOCK_ZONE(zone);
   8596 
   8597 		if (nsec3chain->db != db) {
   8598 			goto next_removechain;
   8599 		}
   8600 
   8601 		if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8602 			goto next_removechain;
   8603 		}
   8604 
   8605 		/*
   8606 		 * Work out if we need to build a NSEC chain as a consequence
   8607 		 * of removing this NSEC3 chain.
   8608 		 */
   8609 		if (first && !updatensec &&
   8610 		    (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
   8611 		{
   8612 			result = need_nsec_chain(db, version,
   8613 						 &nsec3chain->nsec3param,
   8614 						 &buildnsecchain);
   8615 			if (result != ISC_R_SUCCESS) {
   8616 				dnssec_log(zone, ISC_LOG_ERROR,
   8617 					   "zone_nsec3chain:"
   8618 					   "need_nsec_chain -> %s",
   8619 					   dns_result_totext(result));
   8620 				goto failure;
   8621 			}
   8622 		}
   8623 
   8624 		if (first) {
   8625 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   8626 				   "zone_nsec3chain:buildnsecchain = %u\n",
   8627 				   buildnsecchain);
   8628 		}
   8629 
   8630 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8631 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8632 		delegation = false;
   8633 
   8634 		if (!buildnsecchain) {
   8635 			/*
   8636 			 * Delete the NSEC3PARAM record matching this chain.
   8637 			 */
   8638 			if (first) {
   8639 				result = fixup_nsec3param(
   8640 					db, version, nsec3chain, true,
   8641 					privatetype, &param_diff);
   8642 				if (result != ISC_R_SUCCESS) {
   8643 					dnssec_log(zone, ISC_LOG_ERROR,
   8644 						   "zone_nsec3chain:"
   8645 						   "fixup_nsec3param -> %s",
   8646 						   dns_result_totext(result));
   8647 					goto failure;
   8648 				}
   8649 			}
   8650 
   8651 			/*
   8652 			 * Delete the NSEC3 records.
   8653 			 */
   8654 			result = deletematchingnsec3(db, version, node, name,
   8655 						     &nsec3chain->nsec3param,
   8656 						     &nsec3_diff);
   8657 			if (result != ISC_R_SUCCESS) {
   8658 				dnssec_log(zone, ISC_LOG_ERROR,
   8659 					   "zone_nsec3chain:"
   8660 					   "deletematchingnsec3 -> %s",
   8661 					   dns_result_totext(result));
   8662 				goto failure;
   8663 			}
   8664 			goto next_removenode;
   8665 		}
   8666 
   8667 		if (first) {
   8668 			dns_fixedname_t ffound;
   8669 			dns_name_t *found;
   8670 			found = dns_fixedname_initname(&ffound);
   8671 			result = dns_db_find(
   8672 				db, name, version, dns_rdatatype_soa,
   8673 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8674 			if ((result == DNS_R_DELEGATION ||
   8675 			     result == DNS_R_DNAME) &&
   8676 			    !dns_name_equal(name, found))
   8677 			{
   8678 				/*
   8679 				 * Remember the obscuring name so that
   8680 				 * we skip all obscured names.
   8681 				 */
   8682 				dns_name_copynf(found, name);
   8683 				delegation = true;
   8684 				goto next_removenode;
   8685 			}
   8686 		}
   8687 
   8688 		/*
   8689 		 * Check to see if this is a bottom of zone node.
   8690 		 */
   8691 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8692 		if (result == ISC_R_NOTFOUND) {
   8693 			/* Empty node? */
   8694 			goto next_removenode;
   8695 		}
   8696 		if (result != ISC_R_SUCCESS) {
   8697 			goto failure;
   8698 		}
   8699 
   8700 		seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
   8701 			seen_rr = false;
   8702 		for (result = dns_rdatasetiter_first(iterator);
   8703 		     result == ISC_R_SUCCESS;
   8704 		     result = dns_rdatasetiter_next(iterator))
   8705 		{
   8706 			dns_rdatasetiter_current(iterator, &rdataset);
   8707 			if (rdataset.type == dns_rdatatype_soa) {
   8708 				seen_soa = true;
   8709 			} else if (rdataset.type == dns_rdatatype_ns) {
   8710 				seen_ns = true;
   8711 			} else if (rdataset.type == dns_rdatatype_dname) {
   8712 				seen_dname = true;
   8713 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8714 				seen_nsec = true;
   8715 			} else if (rdataset.type == dns_rdatatype_nsec3) {
   8716 				seen_nsec3 = true;
   8717 			} else if (rdataset.type != dns_rdatatype_rrsig) {
   8718 				seen_rr = true;
   8719 			}
   8720 			dns_rdataset_disassociate(&rdataset);
   8721 		}
   8722 		dns_rdatasetiter_destroy(&iterator);
   8723 
   8724 		if (!seen_rr || seen_nsec3 || seen_nsec) {
   8725 			goto next_removenode;
   8726 		}
   8727 		if ((seen_ns && !seen_soa) || seen_dname) {
   8728 			delegation = true;
   8729 		}
   8730 
   8731 		/*
   8732 		 * Add a NSEC record except at the origin.
   8733 		 */
   8734 		if (!dns_name_equal(name, dns_db_origin(db))) {
   8735 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8736 			CHECK(add_nsec(db, version, name, node, zone->minimum,
   8737 				       delegation, &nsec_diff));
   8738 			signatures--;
   8739 		}
   8740 
   8741 	next_removenode:
   8742 		first = false;
   8743 		dns_db_detachnode(db, &node);
   8744 		do {
   8745 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8746 			if (result == ISC_R_NOMORE && buildnsecchain) {
   8747 				/*
   8748 				 * The NSEC chain should now be built.
   8749 				 * We can now remove the NSEC3 chain.
   8750 				 */
   8751 				updatensec = true;
   8752 				goto same_removechain;
   8753 			}
   8754 			if (result == ISC_R_NOMORE) {
   8755 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8756 				LOCK_ZONE(zone);
   8757 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8758 						link);
   8759 				UNLOCK_ZONE(zone);
   8760 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8761 				result = fixup_nsec3param(
   8762 					db, version, nsec3chain, false,
   8763 					privatetype, &param_diff);
   8764 				if (result != ISC_R_SUCCESS) {
   8765 					dnssec_log(zone, ISC_LOG_ERROR,
   8766 						   "zone_nsec3chain:"
   8767 						   "fixup_nsec3param -> %s",
   8768 						   dns_result_totext(result));
   8769 					goto failure;
   8770 				}
   8771 				goto next_removechain;
   8772 			} else if (result != ISC_R_SUCCESS) {
   8773 				dnssec_log(zone, ISC_LOG_ERROR,
   8774 					   "zone_nsec3chain:"
   8775 					   "dns_dbiterator_next -> %s",
   8776 					   dns_result_totext(result));
   8777 				goto failure;
   8778 			} else if (delegation) {
   8779 				dns_dbiterator_current(nsec3chain->dbiterator,
   8780 						       &node, nextname);
   8781 				dns_db_detachnode(db, &node);
   8782 				if (!dns_name_issubdomain(nextname, name)) {
   8783 					break;
   8784 				}
   8785 			} else {
   8786 				break;
   8787 			}
   8788 		} while (1);
   8789 		continue;
   8790 
   8791 	same_removechain:
   8792 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8793 		buildnsecchain = false;
   8794 		first = true;
   8795 		continue;
   8796 
   8797 	next_removechain:
   8798 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8799 		nsec3chain = nextnsec3chain;
   8800 		first = true;
   8801 	}
   8802 
   8803 skip_removals:
   8804 	/*
   8805 	 * We may need to update the NSEC/NSEC3 records for the zone apex.
   8806 	 */
   8807 	if (!ISC_LIST_EMPTY(param_diff.tuples)) {
   8808 		bool rebuild_nsec = false, rebuild_nsec3 = false;
   8809 		result = dns_db_getoriginnode(db, &node);
   8810 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8811 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8812 		if (result != ISC_R_SUCCESS) {
   8813 			dnssec_log(zone, ISC_LOG_ERROR,
   8814 				   "zone_nsec3chain:dns_db_allrdatasets -> %s",
   8815 				   dns_result_totext(result));
   8816 			goto failure;
   8817 		}
   8818 		for (result = dns_rdatasetiter_first(iterator);
   8819 		     result == ISC_R_SUCCESS;
   8820 		     result = dns_rdatasetiter_next(iterator))
   8821 		{
   8822 			dns_rdatasetiter_current(iterator, &rdataset);
   8823 			if (rdataset.type == dns_rdatatype_nsec) {
   8824 				rebuild_nsec = true;
   8825 			} else if (rdataset.type == dns_rdatatype_nsec3param) {
   8826 				rebuild_nsec3 = true;
   8827 			}
   8828 			dns_rdataset_disassociate(&rdataset);
   8829 		}
   8830 		dns_rdatasetiter_destroy(&iterator);
   8831 		dns_db_detachnode(db, &node);
   8832 
   8833 		if (rebuild_nsec) {
   8834 			if (nsec3chain != NULL) {
   8835 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8836 			}
   8837 
   8838 			result = updatesecure(db, version, &zone->origin,
   8839 					      zone->minimum, true, &nsec_diff);
   8840 			if (result != ISC_R_SUCCESS) {
   8841 				dnssec_log(zone, ISC_LOG_ERROR,
   8842 					   "zone_nsec3chain:updatesecure -> %s",
   8843 					   dns_result_totext(result));
   8844 				goto failure;
   8845 			}
   8846 		}
   8847 
   8848 		if (rebuild_nsec3) {
   8849 			if (nsec3chain != NULL) {
   8850 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8851 			}
   8852 
   8853 			result = dns_nsec3_addnsec3s(
   8854 				db, version, dns_db_origin(db), zone->minimum,
   8855 				false, &nsec3_diff);
   8856 			if (result != ISC_R_SUCCESS) {
   8857 				dnssec_log(zone, ISC_LOG_ERROR,
   8858 					   "zone_nsec3chain:"
   8859 					   "dns_nsec3_addnsec3s -> %s",
   8860 					   dns_result_totext(result));
   8861 				goto failure;
   8862 			}
   8863 		}
   8864 	}
   8865 
   8866 	/*
   8867 	 * Add / update signatures for the NSEC3 records.
   8868 	 */
   8869 	if (nsec3chain != NULL) {
   8870 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8871 	}
   8872 	result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys,
   8873 				      nkeys, zone, inception, expire, 0, now,
   8874 				      check_ksk, keyset_kskonly, &zonediff);
   8875 	if (result != ISC_R_SUCCESS) {
   8876 		dnssec_log(zone, ISC_LOG_ERROR,
   8877 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8878 			   dns_result_totext(result));
   8879 		goto failure;
   8880 	}
   8881 
   8882 	/*
   8883 	 * We have changed the NSEC3PARAM or private RRsets
   8884 	 * above so we need to update the signatures.
   8885 	 */
   8886 	result = dns__zone_updatesigs(&param_diff, db, version, zone_keys,
   8887 				      nkeys, zone, inception, expire, 0, now,
   8888 				      check_ksk, keyset_kskonly, &zonediff);
   8889 	if (result != ISC_R_SUCCESS) {
   8890 		dnssec_log(zone, ISC_LOG_ERROR,
   8891 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8892 			   dns_result_totext(result));
   8893 		goto failure;
   8894 	}
   8895 
   8896 	if (updatensec) {
   8897 		result = updatesecure(db, version, &zone->origin, zone->minimum,
   8898 				      false, &nsec_diff);
   8899 		if (result != ISC_R_SUCCESS) {
   8900 			dnssec_log(zone, ISC_LOG_ERROR,
   8901 				   "zone_nsec3chain:updatesecure -> %s",
   8902 				   dns_result_totext(result));
   8903 			goto failure;
   8904 		}
   8905 	}
   8906 
   8907 	result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys,
   8908 				      zone, inception, expire, 0, now,
   8909 				      check_ksk, keyset_kskonly, &zonediff);
   8910 	if (result != ISC_R_SUCCESS) {
   8911 		dnssec_log(zone, ISC_LOG_ERROR,
   8912 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8913 			   dns_result_totext(result));
   8914 		goto failure;
   8915 	}
   8916 
   8917 	/*
   8918 	 * If we made no effective changes to the zone then we can just
   8919 	 * cleanup otherwise we need to increment the serial.
   8920 	 */
   8921 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   8922 		/*
   8923 		 * No need to call dns_db_closeversion() here as it is
   8924 		 * called with commit = true below.
   8925 		 */
   8926 		goto done;
   8927 	}
   8928 
   8929 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   8930 			  &zonediff, zone_keys, nkeys, now, false);
   8931 	if (result != ISC_R_SUCCESS) {
   8932 		dnssec_log(zone, ISC_LOG_ERROR,
   8933 			   "zone_nsec3chain:del_sigs -> %s",
   8934 			   dns_result_totext(result));
   8935 		goto failure;
   8936 	}
   8937 
   8938 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   8939 				   zone->updatemethod);
   8940 	if (result != ISC_R_SUCCESS) {
   8941 		dnssec_log(zone, ISC_LOG_ERROR,
   8942 			   "zone_nsec3chain:update_soa_serial -> %s",
   8943 			   dns_result_totext(result));
   8944 		goto failure;
   8945 	}
   8946 
   8947 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   8948 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   8949 			  inception, soaexpire, check_ksk, keyset_kskonly);
   8950 	if (result != ISC_R_SUCCESS) {
   8951 		dnssec_log(zone, ISC_LOG_ERROR,
   8952 			   "zone_nsec3chain:add_sigs -> %s",
   8953 			   dns_result_totext(result));
   8954 		goto failure;
   8955 	}
   8956 
   8957 	/* Write changes to journal file. */
   8958 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
   8959 
   8960 	LOCK_ZONE(zone);
   8961 	zone_needdump(zone, DNS_DUMP_DELAY);
   8962 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   8963 	UNLOCK_ZONE(zone);
   8964 
   8965 done:
   8966 	/*
   8967 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   8968 	 */
   8969 	LOCK_ZONE(zone);
   8970 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   8971 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   8972 	{
   8973 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8974 	}
   8975 	UNLOCK_ZONE(zone);
   8976 
   8977 	/*
   8978 	 * Everything has succeeded. Commit the changes.
   8979 	 * Unconditionally commit as zonediff.offline not checked above.
   8980 	 */
   8981 	dns_db_closeversion(db, &version, true);
   8982 
   8983 	/*
   8984 	 * Everything succeeded so we can clean these up now.
   8985 	 */
   8986 	nsec3chain = ISC_LIST_HEAD(cleanup);
   8987 	while (nsec3chain != NULL) {
   8988 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   8989 		dns_db_detach(&nsec3chain->db);
   8990 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   8991 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   8992 		nsec3chain = ISC_LIST_HEAD(cleanup);
   8993 	}
   8994 
   8995 	LOCK_ZONE(zone);
   8996 	set_resigntime(zone);
   8997 	UNLOCK_ZONE(zone);
   8998 
   8999 failure:
   9000 	if (result != ISC_R_SUCCESS) {
   9001 		dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
   9002 			   dns_result_totext(result));
   9003 	}
   9004 
   9005 	/*
   9006 	 * On error roll back the current nsec3chain.
   9007 	 */
   9008 	if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
   9009 		if (nsec3chain->done) {
   9010 			dns_db_detach(&nsec3chain->db);
   9011 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9012 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9013 		} else {
   9014 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9015 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9016 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9017 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9018 		}
   9019 	}
   9020 
   9021 	/*
   9022 	 * Rollback the cleanup list.
   9023 	 */
   9024 	nsec3chain = ISC_LIST_TAIL(cleanup);
   9025 	while (nsec3chain != NULL) {
   9026 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   9027 		if (nsec3chain->done) {
   9028 			dns_db_detach(&nsec3chain->db);
   9029 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9030 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9031 		} else {
   9032 			LOCK_ZONE(zone);
   9033 			ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
   9034 			UNLOCK_ZONE(zone);
   9035 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9036 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9037 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9038 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9039 		}
   9040 		nsec3chain = ISC_LIST_TAIL(cleanup);
   9041 	}
   9042 
   9043 	LOCK_ZONE(zone);
   9044 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   9045 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   9046 	{
   9047 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9048 	}
   9049 	UNLOCK_ZONE(zone);
   9050 
   9051 	dns_diff_clear(&param_diff);
   9052 	dns_diff_clear(&nsec3_diff);
   9053 	dns_diff_clear(&nsec_diff);
   9054 	dns_diff_clear(&_sig_diff);
   9055 
   9056 	if (iterator != NULL) {
   9057 		dns_rdatasetiter_destroy(&iterator);
   9058 	}
   9059 
   9060 	for (i = 0; i < nkeys; i++) {
   9061 		dst_key_free(&zone_keys[i]);
   9062 	}
   9063 
   9064 	if (node != NULL) {
   9065 		dns_db_detachnode(db, &node);
   9066 	}
   9067 	if (version != NULL) {
   9068 		dns_db_closeversion(db, &version, false);
   9069 		dns_db_detach(&db);
   9070 	} else if (db != NULL) {
   9071 		dns_db_detach(&db);
   9072 	}
   9073 
   9074 	LOCK_ZONE(zone);
   9075 	if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
   9076 		isc_interval_t interval;
   9077 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   9078 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   9079 		} else {
   9080 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   9081 		}
   9082 		isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
   9083 	} else {
   9084 		isc_time_settoepoch(&zone->nsec3chaintime);
   9085 	}
   9086 	UNLOCK_ZONE(zone);
   9087 
   9088 	INSIST(version == NULL);
   9089 }
   9090 
   9091 /*%
   9092  * Delete all RRSIG records with the given algorithm and keyid.
   9093  * Remove the NSEC record and RRSIGs if nkeys is zero.
   9094  * If all remaining RRsets are signed with the given algorithm
   9095  * set *has_algp to true.
   9096  */
   9097 static isc_result_t
   9098 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   9099 	dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
   9100 	uint16_t keyid, bool *has_algp, dns_diff_t *diff) {
   9101 	dns_rdata_rrsig_t rrsig;
   9102 	dns_rdataset_t rdataset;
   9103 	dns_rdatasetiter_t *iterator = NULL;
   9104 	isc_result_t result;
   9105 	bool alg_missed = false;
   9106 	bool alg_found = false;
   9107 
   9108 	char namebuf[DNS_NAME_FORMATSIZE];
   9109 	dns_name_format(name, namebuf, sizeof(namebuf));
   9110 
   9111 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   9112 	if (result != ISC_R_SUCCESS) {
   9113 		if (result == ISC_R_NOTFOUND) {
   9114 			result = ISC_R_SUCCESS;
   9115 		}
   9116 		return (result);
   9117 	}
   9118 
   9119 	dns_rdataset_init(&rdataset);
   9120 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   9121 	     result = dns_rdatasetiter_next(iterator))
   9122 	{
   9123 		bool has_alg = false;
   9124 		dns_rdatasetiter_current(iterator, &rdataset);
   9125 		if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
   9126 			for (result = dns_rdataset_first(&rdataset);
   9127 			     result == ISC_R_SUCCESS;
   9128 			     result = dns_rdataset_next(&rdataset))
   9129 			{
   9130 				dns_rdata_t rdata = DNS_RDATA_INIT;
   9131 				dns_rdataset_current(&rdataset, &rdata);
   9132 				CHECK(update_one_rr(db, version, diff,
   9133 						    DNS_DIFFOP_DEL, name,
   9134 						    rdataset.ttl, &rdata));
   9135 			}
   9136 			if (result != ISC_R_NOMORE) {
   9137 				goto failure;
   9138 			}
   9139 			dns_rdataset_disassociate(&rdataset);
   9140 			continue;
   9141 		}
   9142 		if (rdataset.type != dns_rdatatype_rrsig) {
   9143 			dns_rdataset_disassociate(&rdataset);
   9144 			continue;
   9145 		}
   9146 		for (result = dns_rdataset_first(&rdataset);
   9147 		     result == ISC_R_SUCCESS;
   9148 		     result = dns_rdataset_next(&rdataset))
   9149 		{
   9150 			dns_rdata_t rdata = DNS_RDATA_INIT;
   9151 			dns_rdataset_current(&rdataset, &rdata);
   9152 			CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
   9153 			if (nkeys != 0 && (rrsig.algorithm != algorithm ||
   9154 					   rrsig.keyid != keyid)) {
   9155 				if (rrsig.algorithm == algorithm) {
   9156 					has_alg = true;
   9157 				}
   9158 				continue;
   9159 			}
   9160 			CHECK(update_one_rr(db, version, diff,
   9161 					    DNS_DIFFOP_DELRESIGN, name,
   9162 					    rdataset.ttl, &rdata));
   9163 		}
   9164 		dns_rdataset_disassociate(&rdataset);
   9165 		if (result != ISC_R_NOMORE) {
   9166 			break;
   9167 		}
   9168 
   9169 		/*
   9170 		 * After deleting, if there's still a signature for
   9171 		 * 'algorithm', set alg_found; if not, set alg_missed.
   9172 		 */
   9173 		if (has_alg) {
   9174 			alg_found = true;
   9175 		} else {
   9176 			alg_missed = true;
   9177 		}
   9178 	}
   9179 	if (result == ISC_R_NOMORE) {
   9180 		result = ISC_R_SUCCESS;
   9181 	}
   9182 
   9183 	/*
   9184 	 * Set `has_algp` if the algorithm was found in every RRset:
   9185 	 * i.e., found in at least one, and not missing from any.
   9186 	 */
   9187 	*has_algp = (alg_found && !alg_missed);
   9188 failure:
   9189 	if (dns_rdataset_isassociated(&rdataset)) {
   9190 		dns_rdataset_disassociate(&rdataset);
   9191 	}
   9192 	dns_rdatasetiter_destroy(&iterator);
   9193 	return (result);
   9194 }
   9195 
   9196 /*
   9197  * Incrementally sign the zone using the keys requested.
   9198  * Builds the NSEC chain if required.
   9199  */
   9200 static void
   9201 zone_sign(dns_zone_t *zone) {
   9202 	const char *me = "zone_sign";
   9203 	dns_db_t *db = NULL;
   9204 	dns_dbnode_t *node = NULL;
   9205 	dns_dbversion_t *version = NULL;
   9206 	dns_diff_t _sig_diff;
   9207 	dns_diff_t post_diff;
   9208 	dns__zonediff_t zonediff;
   9209 	dns_fixedname_t fixed;
   9210 	dns_fixedname_t nextfixed;
   9211 	dns_kasp_t *kasp;
   9212 	dns_name_t *name, *nextname;
   9213 	dns_rdataset_t rdataset;
   9214 	dns_signing_t *signing, *nextsigning;
   9215 	dns_signinglist_t cleanup;
   9216 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   9217 	int32_t signatures;
   9218 	bool check_ksk, keyset_kskonly, is_ksk, is_zsk;
   9219 	bool with_ksk, with_zsk;
   9220 	bool commit = false;
   9221 	bool is_bottom_of_zone;
   9222 	bool build_nsec = false;
   9223 	bool build_nsec3 = false;
   9224 	bool use_kasp = false;
   9225 	bool first;
   9226 	isc_result_t result;
   9227 	isc_stdtime_t now, inception, soaexpire, expire;
   9228 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   9229 	unsigned int i, j;
   9230 	unsigned int nkeys = 0;
   9231 	uint32_t nodes;
   9232 
   9233 	ENTER;
   9234 
   9235 	dns_rdataset_init(&rdataset);
   9236 	name = dns_fixedname_initname(&fixed);
   9237 	nextname = dns_fixedname_initname(&nextfixed);
   9238 	dns_diff_init(zone->mctx, &_sig_diff);
   9239 	dns_diff_init(zone->mctx, &post_diff);
   9240 	zonediff_init(&zonediff, &_sig_diff);
   9241 	ISC_LIST_INIT(cleanup);
   9242 
   9243 	/*
   9244 	 * Updates are disabled.  Pause for 1 minute.
   9245 	 */
   9246 	if (zone->update_disabled) {
   9247 		result = ISC_R_FAILURE;
   9248 		goto cleanup;
   9249 	}
   9250 
   9251 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9252 	if (zone->db != NULL) {
   9253 		dns_db_attach(zone->db, &db);
   9254 	}
   9255 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9256 	if (db == NULL) {
   9257 		result = ISC_R_FAILURE;
   9258 		goto cleanup;
   9259 	}
   9260 
   9261 	result = dns_db_newversion(db, &version);
   9262 	if (result != ISC_R_SUCCESS) {
   9263 		dnssec_log(zone, ISC_LOG_ERROR,
   9264 			   "zone_sign:dns_db_newversion -> %s",
   9265 			   dns_result_totext(result));
   9266 		goto cleanup;
   9267 	}
   9268 
   9269 	isc_stdtime_get(&now);
   9270 
   9271 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   9272 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   9273 	if (result != ISC_R_SUCCESS) {
   9274 		dnssec_log(zone, ISC_LOG_ERROR,
   9275 			   "zone_sign:dns__zone_findkeys -> %s",
   9276 			   dns_result_totext(result));
   9277 		goto cleanup;
   9278 	}
   9279 
   9280 	kasp = dns_zone_getkasp(zone);
   9281 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   9282 	inception = now - 3600; /* Allow for clock skew. */
   9283 	soaexpire = now + sigvalidityinterval;
   9284 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   9285 	if (expiryinterval > sigvalidityinterval) {
   9286 		expiryinterval = sigvalidityinterval;
   9287 	} else {
   9288 		expiryinterval = sigvalidityinterval - expiryinterval;
   9289 	}
   9290 
   9291 	/*
   9292 	 * Spread out signatures over time if they happen to be
   9293 	 * clumped.  We don't do this for each add_sigs() call as
   9294 	 * we still want some clustering to occur.
   9295 	 */
   9296 	if (sigvalidityinterval >= 3600U) {
   9297 		if (sigvalidityinterval > 7200U) {
   9298 			jitter = isc_random_uniform(expiryinterval);
   9299 		} else {
   9300 			jitter = isc_random_uniform(1200);
   9301 		}
   9302 		expire = soaexpire - jitter - 1;
   9303 	} else {
   9304 		expire = soaexpire - 1;
   9305 	}
   9306 
   9307 	/*
   9308 	 * We keep pulling nodes off each iterator in turn until
   9309 	 * we have no more nodes to pull off or we reach the limits
   9310 	 * for this quantum.
   9311 	 */
   9312 	nodes = zone->nodes;
   9313 	signatures = zone->signatures;
   9314 	signing = ISC_LIST_HEAD(zone->signing);
   9315 	first = true;
   9316 
   9317 	if (dns_zone_use_kasp(zone)) {
   9318 		check_ksk = false;
   9319 		keyset_kskonly = true;
   9320 		use_kasp = true;
   9321 	} else {
   9322 		check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   9323 		keyset_kskonly = DNS_ZONE_OPTION(zone,
   9324 						 DNS_ZONEOPT_DNSKEYKSKONLY);
   9325 	}
   9326 	dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s",
   9327 		   use_kasp ? "yes" : "no");
   9328 
   9329 	/* Determine which type of chain to build */
   9330 	if (use_kasp) {
   9331 		build_nsec3 = dns_kasp_nsec3(kasp);
   9332 		build_nsec = !build_nsec3;
   9333 	} else {
   9334 		CHECK(dns_private_chains(db, version, zone->privatetype,
   9335 					 &build_nsec, &build_nsec3));
   9336 		/* If neither chain is found, default to NSEC */
   9337 		if (!build_nsec && !build_nsec3) {
   9338 			build_nsec = true;
   9339 		}
   9340 	}
   9341 
   9342 	while (signing != NULL && nodes-- > 0 && signatures > 0) {
   9343 		bool has_alg = false;
   9344 
   9345 		dns_dbiterator_pause(signing->dbiterator);
   9346 		nextsigning = ISC_LIST_NEXT(signing, link);
   9347 
   9348 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9349 		if (signing->done || signing->db != zone->db) {
   9350 			/*
   9351 			 * The zone has been reloaded.	We will have to
   9352 			 * created new signings as part of the reload
   9353 			 * process so we can destroy this one.
   9354 			 */
   9355 			ISC_LIST_UNLINK(zone->signing, signing, link);
   9356 			ISC_LIST_APPEND(cleanup, signing, link);
   9357 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9358 			goto next_signing;
   9359 		}
   9360 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9361 
   9362 		if (signing->db != db) {
   9363 			goto next_signing;
   9364 		}
   9365 
   9366 		is_bottom_of_zone = false;
   9367 
   9368 		if (first && signing->deleteit) {
   9369 			/*
   9370 			 * Remove the key we are deleting from consideration.
   9371 			 */
   9372 			for (i = 0, j = 0; i < nkeys; i++) {
   9373 				/*
   9374 				 * Find the key we want to remove.
   9375 				 */
   9376 				if (ALG(zone_keys[i]) == signing->algorithm &&
   9377 				    dst_key_id(zone_keys[i]) == signing->keyid)
   9378 				{
   9379 					bool ksk = false;
   9380 					isc_result_t ret = dst_key_getbool(
   9381 						zone_keys[i], DST_BOOL_KSK,
   9382 						&ksk);
   9383 					if (ret != ISC_R_SUCCESS) {
   9384 						ksk = KSK(zone_keys[i]);
   9385 					}
   9386 					if (ksk) {
   9387 						dst_key_free(&zone_keys[i]);
   9388 					}
   9389 					continue;
   9390 				}
   9391 				zone_keys[j] = zone_keys[i];
   9392 				j++;
   9393 			}
   9394 			for (i = j; i < nkeys; i++) {
   9395 				zone_keys[i] = NULL;
   9396 			}
   9397 			nkeys = j;
   9398 		}
   9399 
   9400 		dns_dbiterator_current(signing->dbiterator, &node, name);
   9401 
   9402 		if (signing->deleteit) {
   9403 			dns_dbiterator_pause(signing->dbiterator);
   9404 			CHECK(del_sig(db, version, name, node, nkeys,
   9405 				      signing->algorithm, signing->keyid,
   9406 				      &has_alg, zonediff.diff));
   9407 		}
   9408 
   9409 		/*
   9410 		 * On the first pass we need to check if the current node
   9411 		 * has not been obscured.
   9412 		 */
   9413 		if (first) {
   9414 			dns_fixedname_t ffound;
   9415 			dns_name_t *found;
   9416 			found = dns_fixedname_initname(&ffound);
   9417 			result = dns_db_find(
   9418 				db, name, version, dns_rdatatype_soa,
   9419 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   9420 			if ((result == DNS_R_DELEGATION ||
   9421 			     result == DNS_R_DNAME) &&
   9422 			    !dns_name_equal(name, found))
   9423 			{
   9424 				/*
   9425 				 * Remember the obscuring name so that
   9426 				 * we skip all obscured names.
   9427 				 */
   9428 				dns_name_copynf(found, name);
   9429 				is_bottom_of_zone = true;
   9430 				goto next_node;
   9431 			}
   9432 		}
   9433 
   9434 		/*
   9435 		 * Process one node.
   9436 		 */
   9437 		with_ksk = false;
   9438 		with_zsk = false;
   9439 		dns_dbiterator_pause(signing->dbiterator);
   9440 
   9441 		CHECK(check_if_bottom_of_zone(db, node, version,
   9442 					      &is_bottom_of_zone));
   9443 
   9444 		for (i = 0; !has_alg && i < nkeys; i++) {
   9445 			bool both = false;
   9446 
   9447 			/*
   9448 			 * Find the keys we want to sign with.
   9449 			 */
   9450 			if (!dst_key_isprivate(zone_keys[i])) {
   9451 				continue;
   9452 			}
   9453 			if (dst_key_inactive(zone_keys[i])) {
   9454 				continue;
   9455 			}
   9456 
   9457 			/*
   9458 			 * When adding look for the specific key.
   9459 			 */
   9460 			if (!signing->deleteit &&
   9461 			    (dst_key_alg(zone_keys[i]) != signing->algorithm ||
   9462 			     dst_key_id(zone_keys[i]) != signing->keyid))
   9463 			{
   9464 				continue;
   9465 			}
   9466 
   9467 			/*
   9468 			 * When deleting make sure we are properly signed
   9469 			 * with the algorithm that was being removed.
   9470 			 */
   9471 			if (signing->deleteit &&
   9472 			    ALG(zone_keys[i]) != signing->algorithm) {
   9473 				continue;
   9474 			}
   9475 
   9476 			/*
   9477 			 * Do we do KSK processing?
   9478 			 */
   9479 			if (check_ksk && !REVOKE(zone_keys[i])) {
   9480 				bool have_ksk, have_nonksk;
   9481 				if (KSK(zone_keys[i])) {
   9482 					have_ksk = true;
   9483 					have_nonksk = false;
   9484 				} else {
   9485 					have_ksk = false;
   9486 					have_nonksk = true;
   9487 				}
   9488 				for (j = 0; j < nkeys; j++) {
   9489 					if (j == i || (ALG(zone_keys[i]) !=
   9490 						       ALG(zone_keys[j]))) {
   9491 						continue;
   9492 					}
   9493 					/* Don't consider inactive keys, however
   9494 					 * the key may be temporary offline, so
   9495 					 * do consider keys which private key
   9496 					 * files are unavailable.
   9497 					 */
   9498 					if (dst_key_inactive(zone_keys[j])) {
   9499 						continue;
   9500 					}
   9501 					if (REVOKE(zone_keys[j])) {
   9502 						continue;
   9503 					}
   9504 					if (KSK(zone_keys[j])) {
   9505 						have_ksk = true;
   9506 					} else {
   9507 						have_nonksk = true;
   9508 					}
   9509 					both = have_ksk && have_nonksk;
   9510 					if (both) {
   9511 						break;
   9512 					}
   9513 				}
   9514 			}
   9515 			if (use_kasp) {
   9516 				/*
   9517 				 * A dnssec-policy is found. Check what
   9518 				 * RRsets this key can sign.
   9519 				 */
   9520 				isc_result_t kresult;
   9521 				is_ksk = false;
   9522 				kresult = dst_key_getbool(
   9523 					zone_keys[i], DST_BOOL_KSK, &is_ksk);
   9524 				if (kresult != ISC_R_SUCCESS) {
   9525 					if (KSK(zone_keys[i])) {
   9526 						is_ksk = true;
   9527 					}
   9528 				}
   9529 
   9530 				is_zsk = false;
   9531 				kresult = dst_key_getbool(
   9532 					zone_keys[i], DST_BOOL_ZSK, &is_zsk);
   9533 				if (kresult != ISC_R_SUCCESS) {
   9534 					if (!KSK(zone_keys[i])) {
   9535 						is_zsk = true;
   9536 					}
   9537 				}
   9538 				/* Treat as if we have both KSK and ZSK. */
   9539 				both = true;
   9540 			} else if (both || REVOKE(zone_keys[i])) {
   9541 				is_ksk = KSK(zone_keys[i]);
   9542 				is_zsk = !KSK(zone_keys[i]);
   9543 			} else {
   9544 				is_ksk = false;
   9545 				is_zsk = true;
   9546 			}
   9547 
   9548 			/*
   9549 			 * If deleting signatures, we need to ensure that
   9550 			 * the RRset is still signed at least once by a
   9551 			 * KSK and a ZSK.
   9552 			 */
   9553 			if (signing->deleteit && is_zsk && with_zsk) {
   9554 				continue;
   9555 			}
   9556 
   9557 			if (signing->deleteit && is_ksk && with_ksk) {
   9558 				continue;
   9559 			}
   9560 
   9561 			CHECK(sign_a_node(
   9562 				db, zone, name, node, version, build_nsec3,
   9563 				build_nsec, zone_keys[i], inception, expire,
   9564 				zone->minimum, is_ksk, is_zsk,
   9565 				(both && keyset_kskonly), is_bottom_of_zone,
   9566 				zonediff.diff, &signatures, zone->mctx));
   9567 			/*
   9568 			 * If we are adding we are done.  Look for other keys
   9569 			 * of the same algorithm if deleting.
   9570 			 */
   9571 			if (!signing->deleteit) {
   9572 				break;
   9573 			}
   9574 			if (is_zsk) {
   9575 				with_zsk = true;
   9576 			}
   9577 			if (is_ksk) {
   9578 				with_ksk = true;
   9579 			}
   9580 		}
   9581 
   9582 		/*
   9583 		 * Go onto next node.
   9584 		 */
   9585 	next_node:
   9586 		first = false;
   9587 		dns_db_detachnode(db, &node);
   9588 		do {
   9589 			result = dns_dbiterator_next(signing->dbiterator);
   9590 			if (result == ISC_R_NOMORE) {
   9591 				ISC_LIST_UNLINK(zone->signing, signing, link);
   9592 				ISC_LIST_APPEND(cleanup, signing, link);
   9593 				dns_dbiterator_pause(signing->dbiterator);
   9594 				if (nkeys != 0 && build_nsec) {
   9595 					/*
   9596 					 * We have finished regenerating the
   9597 					 * zone with a zone signing key.
   9598 					 * The NSEC chain is now complete and
   9599 					 * there is a full set of signatures
   9600 					 * for the zone.  We can now clear the
   9601 					 * OPT bit from the NSEC record.
   9602 					 */
   9603 					result = updatesecure(
   9604 						db, version, &zone->origin,
   9605 						zone->minimum, false,
   9606 						&post_diff);
   9607 					if (result != ISC_R_SUCCESS) {
   9608 						dnssec_log(zone, ISC_LOG_ERROR,
   9609 							   "updatesecure -> %s",
   9610 							   dns_result_totext(
   9611 								   result));
   9612 						goto cleanup;
   9613 					}
   9614 				}
   9615 				result = updatesignwithkey(
   9616 					zone, signing, version, build_nsec3,
   9617 					zone->minimum, &post_diff);
   9618 				if (result != ISC_R_SUCCESS) {
   9619 					dnssec_log(zone, ISC_LOG_ERROR,
   9620 						   "updatesignwithkey -> %s",
   9621 						   dns_result_totext(result));
   9622 					goto cleanup;
   9623 				}
   9624 				build_nsec = false;
   9625 				goto next_signing;
   9626 			} else if (result != ISC_R_SUCCESS) {
   9627 				dnssec_log(zone, ISC_LOG_ERROR,
   9628 					   "zone_sign:"
   9629 					   "dns_dbiterator_next -> %s",
   9630 					   dns_result_totext(result));
   9631 				goto cleanup;
   9632 			} else if (is_bottom_of_zone) {
   9633 				dns_dbiterator_current(signing->dbiterator,
   9634 						       &node, nextname);
   9635 				dns_db_detachnode(db, &node);
   9636 				if (!dns_name_issubdomain(nextname, name)) {
   9637 					break;
   9638 				}
   9639 			} else {
   9640 				break;
   9641 			}
   9642 		} while (1);
   9643 		continue;
   9644 
   9645 	next_signing:
   9646 		dns_dbiterator_pause(signing->dbiterator);
   9647 		signing = nextsigning;
   9648 		first = true;
   9649 	}
   9650 
   9651 	if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
   9652 		result = dns__zone_updatesigs(&post_diff, db, version,
   9653 					      zone_keys, nkeys, zone, inception,
   9654 					      expire, 0, now, check_ksk,
   9655 					      keyset_kskonly, &zonediff);
   9656 		if (result != ISC_R_SUCCESS) {
   9657 			dnssec_log(zone, ISC_LOG_ERROR,
   9658 				   "zone_sign:dns__zone_updatesigs -> %s",
   9659 				   dns_result_totext(result));
   9660 			goto cleanup;
   9661 		}
   9662 	}
   9663 
   9664 	/*
   9665 	 * Have we changed anything?
   9666 	 */
   9667 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   9668 		if (zonediff.offline) {
   9669 			commit = true;
   9670 		}
   9671 		result = ISC_R_SUCCESS;
   9672 		goto pauseall;
   9673 	}
   9674 
   9675 	commit = true;
   9676 
   9677 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   9678 			  &zonediff, zone_keys, nkeys, now, false);
   9679 	if (result != ISC_R_SUCCESS) {
   9680 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s",
   9681 			   dns_result_totext(result));
   9682 		goto cleanup;
   9683 	}
   9684 
   9685 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   9686 				   zone->updatemethod);
   9687 	if (result != ISC_R_SUCCESS) {
   9688 		dnssec_log(zone, ISC_LOG_ERROR,
   9689 			   "zone_sign:update_soa_serial -> %s",
   9690 			   dns_result_totext(result));
   9691 		goto cleanup;
   9692 	}
   9693 
   9694 	/*
   9695 	 * Generate maximum life time signatures so that the above loop
   9696 	 * termination is sensible.
   9697 	 */
   9698 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   9699 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   9700 			  inception, soaexpire, check_ksk, keyset_kskonly);
   9701 	if (result != ISC_R_SUCCESS) {
   9702 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s",
   9703 			   dns_result_totext(result));
   9704 		goto cleanup;
   9705 	}
   9706 
   9707 	/*
   9708 	 * Write changes to journal file.
   9709 	 */
   9710 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
   9711 
   9712 pauseall:
   9713 	/*
   9714 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   9715 	 */
   9716 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   9717 	     signing = ISC_LIST_NEXT(signing, link))
   9718 	{
   9719 		dns_dbiterator_pause(signing->dbiterator);
   9720 	}
   9721 
   9722 	for (signing = ISC_LIST_HEAD(cleanup); signing != NULL;
   9723 	     signing = ISC_LIST_NEXT(signing, link))
   9724 	{
   9725 		dns_dbiterator_pause(signing->dbiterator);
   9726 	}
   9727 
   9728 	/*
   9729 	 * Everything has succeeded. Commit the changes.
   9730 	 */
   9731 	dns_db_closeversion(db, &version, commit);
   9732 
   9733 	/*
   9734 	 * Everything succeeded so we can clean these up now.
   9735 	 */
   9736 	signing = ISC_LIST_HEAD(cleanup);
   9737 	while (signing != NULL) {
   9738 		ISC_LIST_UNLINK(cleanup, signing, link);
   9739 		dns_db_detach(&signing->db);
   9740 		dns_dbiterator_destroy(&signing->dbiterator);
   9741 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   9742 		signing = ISC_LIST_HEAD(cleanup);
   9743 	}
   9744 
   9745 	LOCK_ZONE(zone);
   9746 	set_resigntime(zone);
   9747 	if (commit) {
   9748 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   9749 		zone_needdump(zone, DNS_DUMP_DELAY);
   9750 	}
   9751 	UNLOCK_ZONE(zone);
   9752 
   9753 failure:
   9754 	if (result != ISC_R_SUCCESS) {
   9755 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s",
   9756 			   dns_result_totext(result));
   9757 	}
   9758 
   9759 cleanup:
   9760 	/*
   9761 	 * Pause all dbiterators.
   9762 	 */
   9763 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   9764 	     signing = ISC_LIST_NEXT(signing, link))
   9765 	{
   9766 		dns_dbiterator_pause(signing->dbiterator);
   9767 	}
   9768 
   9769 	/*
   9770 	 * Rollback the cleanup list.
   9771 	 */
   9772 	signing = ISC_LIST_HEAD(cleanup);
   9773 	while (signing != NULL) {
   9774 		ISC_LIST_UNLINK(cleanup, signing, link);
   9775 		ISC_LIST_PREPEND(zone->signing, signing, link);
   9776 		dns_dbiterator_first(signing->dbiterator);
   9777 		dns_dbiterator_pause(signing->dbiterator);
   9778 		signing = ISC_LIST_HEAD(cleanup);
   9779 	}
   9780 
   9781 	dns_diff_clear(&_sig_diff);
   9782 
   9783 	for (i = 0; i < nkeys; i++) {
   9784 		dst_key_free(&zone_keys[i]);
   9785 	}
   9786 
   9787 	if (node != NULL) {
   9788 		dns_db_detachnode(db, &node);
   9789 	}
   9790 
   9791 	if (version != NULL) {
   9792 		dns_db_closeversion(db, &version, false);
   9793 		dns_db_detach(&db);
   9794 	} else if (db != NULL) {
   9795 		dns_db_detach(&db);
   9796 	}
   9797 
   9798 	LOCK_ZONE(zone);
   9799 	if (ISC_LIST_HEAD(zone->signing) != NULL) {
   9800 		isc_interval_t interval;
   9801 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   9802 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   9803 		} else {
   9804 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   9805 		}
   9806 		isc_time_nowplusinterval(&zone->signingtime, &interval);
   9807 	} else {
   9808 		isc_time_settoepoch(&zone->signingtime);
   9809 	}
   9810 	UNLOCK_ZONE(zone);
   9811 
   9812 	INSIST(version == NULL);
   9813 }
   9814 
   9815 static isc_result_t
   9816 normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data,
   9817 	      int size) {
   9818 	dns_rdata_dnskey_t dnskey;
   9819 	dns_rdata_keydata_t keydata;
   9820 	isc_buffer_t buf;
   9821 	isc_result_t result;
   9822 
   9823 	dns_rdata_reset(target);
   9824 	isc_buffer_init(&buf, data, size);
   9825 
   9826 	switch (rr->type) {
   9827 	case dns_rdatatype_dnskey:
   9828 		result = dns_rdata_tostruct(rr, &dnskey, NULL);
   9829 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9830 		dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
   9831 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   9832 				     &dnskey, &buf);
   9833 		break;
   9834 	case dns_rdatatype_keydata:
   9835 		result = dns_rdata_tostruct(rr, &keydata, NULL);
   9836 		if (result == ISC_R_UNEXPECTEDEND) {
   9837 			return (result);
   9838 		}
   9839 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9840 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   9841 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   9842 				     &dnskey, &buf);
   9843 		break;
   9844 	default:
   9845 		INSIST(0);
   9846 		ISC_UNREACHABLE();
   9847 	}
   9848 	return (ISC_R_SUCCESS);
   9849 }
   9850 
   9851 /*
   9852  * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
   9853  * a KEYDATA rdataset from the key zone.
   9854  *
   9855  * 'rr' contains either a DNSKEY record, or a KEYDATA record
   9856  *
   9857  * After normalizing keys to the same format (DNSKEY, with revoke bit
   9858  * cleared), return true if a key that matches 'rr' is found in
   9859  * 'rdset', or false if not.
   9860  */
   9861 
   9862 static bool
   9863 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
   9864 	unsigned char data1[4096], data2[4096];
   9865 	dns_rdata_t rdata, rdata1, rdata2;
   9866 	isc_result_t result;
   9867 
   9868 	dns_rdata_init(&rdata);
   9869 	dns_rdata_init(&rdata1);
   9870 	dns_rdata_init(&rdata2);
   9871 
   9872 	result = normalize_key(rr, &rdata1, data1, sizeof(data1));
   9873 	if (result != ISC_R_SUCCESS) {
   9874 		return (false);
   9875 	}
   9876 
   9877 	for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS;
   9878 	     result = dns_rdataset_next(rdset))
   9879 	{
   9880 		dns_rdata_reset(&rdata);
   9881 		dns_rdataset_current(rdset, &rdata);
   9882 		result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
   9883 		if (result != ISC_R_SUCCESS) {
   9884 			continue;
   9885 		}
   9886 		if (dns_rdata_compare(&rdata1, &rdata2) == 0) {
   9887 			return (true);
   9888 		}
   9889 	}
   9890 
   9891 	return (false);
   9892 }
   9893 
   9894 /*
   9895  * Calculate the refresh interval for a keydata zone, per
   9896  * RFC5011: MAX(1 hr,
   9897  *		MIN(15 days,
   9898  *		    1/2 * OrigTTL,
   9899  *		    1/2 * RRSigExpirationInterval))
   9900  * or for retries: MAX(1 hr,
   9901  *		       MIN(1 day,
   9902  *			   1/10 * OrigTTL,
   9903  *			   1/10 * RRSigExpirationInterval))
   9904  */
   9905 static inline isc_stdtime_t
   9906 refresh_time(dns_keyfetch_t *kfetch, bool retry) {
   9907 	isc_result_t result;
   9908 	uint32_t t;
   9909 	dns_rdataset_t *rdset;
   9910 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   9911 	dns_rdata_sig_t sig;
   9912 	isc_stdtime_t now;
   9913 
   9914 	isc_stdtime_get(&now);
   9915 
   9916 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
   9917 		rdset = &kfetch->dnskeysigset;
   9918 	} else {
   9919 		return (now + dns_zone_mkey_hour);
   9920 	}
   9921 
   9922 	result = dns_rdataset_first(rdset);
   9923 	if (result != ISC_R_SUCCESS) {
   9924 		return (now + dns_zone_mkey_hour);
   9925 	}
   9926 
   9927 	dns_rdataset_current(rdset, &sigrr);
   9928 	result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   9929 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9930 
   9931 	if (!retry) {
   9932 		t = sig.originalttl / 2;
   9933 
   9934 		if (isc_serial_gt(sig.timeexpire, now)) {
   9935 			uint32_t exp = (sig.timeexpire - now) / 2;
   9936 			if (t > exp) {
   9937 				t = exp;
   9938 			}
   9939 		}
   9940 
   9941 		if (t > (15 * dns_zone_mkey_day)) {
   9942 			t = (15 * dns_zone_mkey_day);
   9943 		}
   9944 
   9945 		if (t < dns_zone_mkey_hour) {
   9946 			t = dns_zone_mkey_hour;
   9947 		}
   9948 	} else {
   9949 		t = sig.originalttl / 10;
   9950 
   9951 		if (isc_serial_gt(sig.timeexpire, now)) {
   9952 			uint32_t exp = (sig.timeexpire - now) / 10;
   9953 			if (t > exp) {
   9954 				t = exp;
   9955 			}
   9956 		}
   9957 
   9958 		if (t > dns_zone_mkey_day) {
   9959 			t = dns_zone_mkey_day;
   9960 		}
   9961 
   9962 		if (t < dns_zone_mkey_hour) {
   9963 			t = dns_zone_mkey_hour;
   9964 		}
   9965 	}
   9966 
   9967 	return (now + t);
   9968 }
   9969 
   9970 /*
   9971  * This routine is called when no changes are needed in a KEYDATA
   9972  * record except to simply update the refresh timer.  Caller should
   9973  * hold zone lock.
   9974  */
   9975 static isc_result_t
   9976 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) {
   9977 	isc_result_t result;
   9978 	isc_buffer_t keyb;
   9979 	unsigned char key_buf[4096];
   9980 	dns_rdata_t rdata = DNS_RDATA_INIT;
   9981 	dns_rdata_keydata_t keydata;
   9982 	dns_name_t *name;
   9983 	dns_zone_t *zone = kfetch->zone;
   9984 	isc_stdtime_t now;
   9985 
   9986 	name = dns_fixedname_name(&kfetch->name);
   9987 	isc_stdtime_get(&now);
   9988 
   9989 	for (result = dns_rdataset_first(&kfetch->keydataset);
   9990 	     result == ISC_R_SUCCESS;
   9991 	     result = dns_rdataset_next(&kfetch->keydataset))
   9992 	{
   9993 		dns_rdata_reset(&rdata);
   9994 		dns_rdataset_current(&kfetch->keydataset, &rdata);
   9995 
   9996 		/* Delete old version */
   9997 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name,
   9998 				    0, &rdata));
   9999 
   10000 		/* Update refresh timer */
   10001 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   10002 		if (result == ISC_R_UNEXPECTEDEND) {
   10003 			continue;
   10004 		}
   10005 		if (result != ISC_R_SUCCESS) {
   10006 			goto failure;
   10007 		}
   10008 		keydata.refresh = refresh_time(kfetch, true);
   10009 		set_refreshkeytimer(zone, &keydata, now, false);
   10010 
   10011 		dns_rdata_reset(&rdata);
   10012 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10013 		CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass,
   10014 					   dns_rdatatype_keydata, &keydata,
   10015 					   &keyb));
   10016 
   10017 		/* Insert updated version */
   10018 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name,
   10019 				    0, &rdata));
   10020 	}
   10021 	result = ISC_R_SUCCESS;
   10022 failure:
   10023 	return (result);
   10024 }
   10025 
   10026 /*
   10027  * Verify that DNSKEY set is signed by the key specified in 'keydata'.
   10028  */
   10029 static bool
   10030 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
   10031 	isc_result_t result;
   10032 	dns_name_t *keyname;
   10033 	isc_mem_t *mctx;
   10034 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10035 	dns_rdata_t rr = DNS_RDATA_INIT;
   10036 	dns_rdata_rrsig_t sig;
   10037 	dns_rdata_dnskey_t dnskey;
   10038 	dst_key_t *dstkey = NULL;
   10039 	unsigned char key_buf[4096];
   10040 	isc_buffer_t keyb;
   10041 	bool answer = false;
   10042 
   10043 	REQUIRE(kfetch != NULL && keydata != NULL);
   10044 	REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
   10045 
   10046 	keyname = dns_fixedname_name(&kfetch->name);
   10047 	mctx = kfetch->zone->view->mctx;
   10048 
   10049 	/* Generate a key from keydata */
   10050 	isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10051 	dns_keydata_todnskey(keydata, &dnskey, NULL);
   10052 	dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
   10053 			     &dnskey, &keyb);
   10054 	result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
   10055 	if (result != ISC_R_SUCCESS) {
   10056 		return (false);
   10057 	}
   10058 
   10059 	/* See if that key generated any of the signatures */
   10060 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
   10061 	     result == ISC_R_SUCCESS;
   10062 	     result = dns_rdataset_next(&kfetch->dnskeysigset))
   10063 	{
   10064 		dns_fixedname_t fixed;
   10065 		dns_fixedname_init(&fixed);
   10066 
   10067 		dns_rdata_reset(&sigrr);
   10068 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
   10069 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10070 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10071 
   10072 		if (dst_key_alg(dstkey) == sig.algorithm &&
   10073 		    dst_key_rid(dstkey) == sig.keyid) {
   10074 			result = dns_dnssec_verify(
   10075 				keyname, &kfetch->dnskeyset, dstkey, false, 0,
   10076 				mctx, &sigrr, dns_fixedname_name(&fixed));
   10077 
   10078 			dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3),
   10079 				   "Confirm revoked DNSKEY is self-signed: %s",
   10080 				   dns_result_totext(result));
   10081 
   10082 			if (result == ISC_R_SUCCESS) {
   10083 				answer = true;
   10084 				break;
   10085 			}
   10086 		}
   10087 	}
   10088 
   10089 	dst_key_free(&dstkey);
   10090 	return (answer);
   10091 }
   10092 
   10093 /*
   10094  * A DNSKEY set has been fetched from the zone apex of a zone whose trust
   10095  * anchors are being managed; scan the keyset, and update the key zone and the
   10096  * local trust anchors according to RFC5011.
   10097  */
   10098 static void
   10099 keyfetch_done(isc_task_t *task, isc_event_t *event) {
   10100 	isc_result_t result, eresult;
   10101 	dns_fetchevent_t *devent;
   10102 	dns_keyfetch_t *kfetch;
   10103 	dns_zone_t *zone;
   10104 	isc_mem_t *mctx = NULL;
   10105 	dns_keytable_t *secroots = NULL;
   10106 	dns_dbversion_t *ver = NULL;
   10107 	dns_diff_t diff;
   10108 	bool alldone = false;
   10109 	bool commit = false;
   10110 	dns_name_t *keyname = NULL;
   10111 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10112 	dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
   10113 	dns_rdata_t keydatarr = DNS_RDATA_INIT;
   10114 	dns_rdata_rrsig_t sig;
   10115 	dns_rdata_dnskey_t dnskey;
   10116 	dns_rdata_keydata_t keydata;
   10117 	bool initializing;
   10118 	char namebuf[DNS_NAME_FORMATSIZE];
   10119 	unsigned char key_buf[4096];
   10120 	isc_buffer_t keyb;
   10121 	dst_key_t *dstkey = NULL;
   10122 	isc_stdtime_t now;
   10123 	int pending = 0;
   10124 	bool secure = false, initial = false;
   10125 	bool free_needed;
   10126 	dns_keynode_t *keynode = NULL;
   10127 	dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL;
   10128 	dns_rdataset_t *keydataset = NULL, dsset;
   10129 
   10130 	UNUSED(task);
   10131 	INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
   10132 	INSIST(event->ev_arg != NULL);
   10133 
   10134 	kfetch = event->ev_arg;
   10135 	zone = kfetch->zone;
   10136 	isc_mem_attach(zone->mctx, &mctx);
   10137 	keyname = dns_fixedname_name(&kfetch->name);
   10138 	dnskeys = &kfetch->dnskeyset;
   10139 	dnskeysigs = &kfetch->dnskeysigset;
   10140 	keydataset = &kfetch->keydataset;
   10141 
   10142 	devent = (dns_fetchevent_t *)event;
   10143 	eresult = devent->result;
   10144 
   10145 	/* Free resources which are not of interest */
   10146 	if (devent->node != NULL) {
   10147 		dns_db_detachnode(devent->db, &devent->node);
   10148 	}
   10149 	if (devent->db != NULL) {
   10150 		dns_db_detach(&devent->db);
   10151 	}
   10152 	isc_event_free(&event);
   10153 	dns_resolver_destroyfetch(&kfetch->fetch);
   10154 
   10155 	LOCK_ZONE(zone);
   10156 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) {
   10157 		goto cleanup;
   10158 	}
   10159 
   10160 	isc_stdtime_get(&now);
   10161 	dns_name_format(keyname, namebuf, sizeof(namebuf));
   10162 
   10163 	result = dns_view_getsecroots(zone->view, &secroots);
   10164 	INSIST(result == ISC_R_SUCCESS);
   10165 
   10166 	dns_diff_init(mctx, &diff);
   10167 
   10168 	CHECK(dns_db_newversion(kfetch->db, &ver));
   10169 
   10170 	zone->refreshkeycount--;
   10171 	alldone = (zone->refreshkeycount == 0);
   10172 
   10173 	if (alldone) {
   10174 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10175 	}
   10176 
   10177 	dnssec_log(zone, ISC_LOG_DEBUG(3),
   10178 		   "Returned from key fetch in keyfetch_done() for '%s': %s",
   10179 		   namebuf, dns_result_totext(eresult));
   10180 
   10181 	/* Fetch failed */
   10182 	if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) {
   10183 		dnssec_log(zone, ISC_LOG_WARNING,
   10184 			   "Unable to fetch DNSKEY set '%s': %s", namebuf,
   10185 			   dns_result_totext(eresult));
   10186 		CHECK(minimal_update(kfetch, ver, &diff));
   10187 		goto done;
   10188 	}
   10189 
   10190 	/* No RRSIGs found */
   10191 	if (!dns_rdataset_isassociated(dnskeysigs)) {
   10192 		dnssec_log(zone, ISC_LOG_WARNING,
   10193 			   "No DNSKEY RRSIGs found for '%s': %s", namebuf,
   10194 			   dns_result_totext(eresult));
   10195 		CHECK(minimal_update(kfetch, ver, &diff));
   10196 		goto done;
   10197 	}
   10198 
   10199 	/*
   10200 	 * Clear any cached trust level, as we need to run validation
   10201 	 * over again; trusted keys might have changed.
   10202 	 */
   10203 	dnskeys->trust = dnskeysigs->trust = dns_trust_none;
   10204 
   10205 	/* Look up the trust anchor */
   10206 	result = dns_keytable_find(secroots, keyname, &keynode);
   10207 	if (result != ISC_R_SUCCESS) {
   10208 		goto anchors_done;
   10209 	}
   10210 
   10211 	/*
   10212 	 * If the keynode has a DS trust anchor, use it for verification.
   10213 	 */
   10214 	dns_rdataset_init(&dsset);
   10215 	if (dns_keynode_dsset(keynode, &dsset)) {
   10216 		for (result = dns_rdataset_first(dnskeysigs);
   10217 		     result == ISC_R_SUCCESS;
   10218 		     result = dns_rdataset_next(dnskeysigs))
   10219 		{
   10220 			isc_result_t tresult;
   10221 			dns_rdata_t keyrdata = DNS_RDATA_INIT;
   10222 
   10223 			dns_rdata_reset(&sigrr);
   10224 			dns_rdataset_current(dnskeysigs, &sigrr);
   10225 			result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10226 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10227 
   10228 			for (tresult = dns_rdataset_first(&dsset);
   10229 			     tresult == ISC_R_SUCCESS;
   10230 			     tresult = dns_rdataset_next(&dsset))
   10231 			{
   10232 				dns_rdata_t dsrdata = DNS_RDATA_INIT;
   10233 				dns_rdata_ds_t ds;
   10234 
   10235 				dns_rdata_reset(&dsrdata);
   10236 				dns_rdataset_current(&dsset, &dsrdata);
   10237 				tresult = dns_rdata_tostruct(&dsrdata, &ds,
   10238 							     NULL);
   10239 				RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
   10240 
   10241 				if (ds.key_tag != sig.keyid ||
   10242 				    ds.algorithm != sig.algorithm) {
   10243 					continue;
   10244 				}
   10245 
   10246 				result = dns_dnssec_matchdskey(
   10247 					keyname, &dsrdata, dnskeys, &keyrdata);
   10248 				if (result == ISC_R_SUCCESS) {
   10249 					break;
   10250 				}
   10251 			}
   10252 
   10253 			if (tresult == ISC_R_NOMORE) {
   10254 				continue;
   10255 			}
   10256 
   10257 			result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
   10258 							 mctx, &dstkey);
   10259 			if (result != ISC_R_SUCCESS) {
   10260 				continue;
   10261 			}
   10262 
   10263 			result = dns_dnssec_verify(keyname, dnskeys, dstkey,
   10264 						   false, 0, mctx, &sigrr,
   10265 						   NULL);
   10266 			dst_key_free(&dstkey);
   10267 
   10268 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   10269 				   "Verifying DNSKEY set for zone "
   10270 				   "'%s' using DS %d/%d: %s",
   10271 				   namebuf, sig.keyid, sig.algorithm,
   10272 				   dns_result_totext(result));
   10273 
   10274 			if (result == ISC_R_SUCCESS) {
   10275 				dnskeys->trust = dns_trust_secure;
   10276 				dnskeysigs->trust = dns_trust_secure;
   10277 				initial = dns_keynode_initial(keynode);
   10278 				dns_keynode_trust(keynode);
   10279 				secure = true;
   10280 				break;
   10281 			}
   10282 		}
   10283 		dns_rdataset_disassociate(&dsset);
   10284 	}
   10285 
   10286 anchors_done:
   10287 	if (keynode != NULL) {
   10288 		dns_keytable_detachkeynode(secroots, &keynode);
   10289 	}
   10290 
   10291 	/*
   10292 	 * If we were not able to verify the answer using the current
   10293 	 * trusted keys then all we can do is look at any revoked keys.
   10294 	 */
   10295 	if (!secure) {
   10296 		dnssec_log(zone, ISC_LOG_INFO,
   10297 			   "DNSKEY set for zone '%s' could not be verified "
   10298 			   "with current keys",
   10299 			   namebuf);
   10300 	}
   10301 
   10302 	/*
   10303 	 * First scan keydataset to find keys that are not in dnskeyset
   10304 	 *   - Missing keys which are not scheduled for removal,
   10305 	 *     log a warning
   10306 	 *   - Missing keys which are scheduled for removal and
   10307 	 *     the remove hold-down timer has completed should
   10308 	 *     be removed from the key zone
   10309 	 *   - Missing keys whose acceptance timers have not yet
   10310 	 *     completed, log a warning and reset the acceptance
   10311 	 *     timer to 30 days in the future
   10312 	 *   - All keys not being removed have their refresh timers
   10313 	 *     updated
   10314 	 */
   10315 	initializing = true;
   10316 	for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS;
   10317 	     result = dns_rdataset_next(keydataset))
   10318 	{
   10319 		dns_keytag_t keytag;
   10320 
   10321 		dns_rdata_reset(&keydatarr);
   10322 		dns_rdataset_current(keydataset, &keydatarr);
   10323 		result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10324 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10325 
   10326 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   10327 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10328 		if (result != ISC_R_SUCCESS) {
   10329 			/*
   10330 			 * Skip if we cannot compute the key tag.
   10331 			 * This may happen if the algorithm is unsupported
   10332 			 */
   10333 			dns_zone_log(zone, ISC_LOG_ERROR,
   10334 				     "Cannot compute tag for key in zone %s: "
   10335 				     "%s "
   10336 				     "(skipping)",
   10337 				     namebuf, dns_result_totext(result));
   10338 			continue;
   10339 		}
   10340 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10341 
   10342 		/*
   10343 		 * If any keydata record has a nonzero add holddown, then
   10344 		 * there was a pre-existing trust anchor for this domain;
   10345 		 * that means we are *not* initializing it and shouldn't
   10346 		 * automatically trust all the keys we find at the zone apex.
   10347 		 */
   10348 		initializing = initializing && (keydata.addhd == 0);
   10349 
   10350 		if (!matchkey(dnskeys, &keydatarr)) {
   10351 			bool deletekey = false;
   10352 
   10353 			if (!secure) {
   10354 				if (keydata.removehd != 0 &&
   10355 				    keydata.removehd <= now) {
   10356 					deletekey = true;
   10357 				}
   10358 			} else if (keydata.addhd == 0) {
   10359 				deletekey = true;
   10360 			} else if (keydata.addhd > now) {
   10361 				dnssec_log(zone, ISC_LOG_INFO,
   10362 					   "Pending key %d for zone %s "
   10363 					   "unexpectedly missing "
   10364 					   "restarting 30-day acceptance "
   10365 					   "timer",
   10366 					   keytag, namebuf);
   10367 				if (keydata.addhd < now + dns_zone_mkey_month) {
   10368 					keydata.addhd = now +
   10369 							dns_zone_mkey_month;
   10370 				}
   10371 				keydata.refresh = refresh_time(kfetch, false);
   10372 			} else if (keydata.removehd == 0) {
   10373 				dnssec_log(zone, ISC_LOG_INFO,
   10374 					   "Active key %d for zone %s "
   10375 					   "unexpectedly missing",
   10376 					   keytag, namebuf);
   10377 				keydata.refresh = now + dns_zone_mkey_hour;
   10378 			} else if (keydata.removehd <= now) {
   10379 				deletekey = true;
   10380 				dnssec_log(zone, ISC_LOG_INFO,
   10381 					   "Revoked key %d for zone %s "
   10382 					   "missing: deleting from "
   10383 					   "managed keys database",
   10384 					   keytag, namebuf);
   10385 			} else {
   10386 				keydata.refresh = refresh_time(kfetch, false);
   10387 			}
   10388 
   10389 			if (secure || deletekey) {
   10390 				/* Delete old version */
   10391 				CHECK(update_one_rr(kfetch->db, ver, &diff,
   10392 						    DNS_DIFFOP_DEL, keyname, 0,
   10393 						    &keydatarr));
   10394 			}
   10395 
   10396 			if (!secure || deletekey) {
   10397 				continue;
   10398 			}
   10399 
   10400 			dns_rdata_reset(&keydatarr);
   10401 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10402 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10403 					     dns_rdatatype_keydata, &keydata,
   10404 					     &keyb);
   10405 
   10406 			/* Insert updated version */
   10407 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10408 					    DNS_DIFFOP_ADD, keyname, 0,
   10409 					    &keydatarr));
   10410 
   10411 			set_refreshkeytimer(zone, &keydata, now, false);
   10412 		}
   10413 	}
   10414 
   10415 	/*
   10416 	 * Next scan dnskeyset:
   10417 	 *   - If new keys are found (i.e., lacking a match in keydataset)
   10418 	 *     add them to the key zone and set the acceptance timer
   10419 	 *     to 30 days in the future (or to immediately if we've
   10420 	 *     determined that we're initializing the zone for the
   10421 	 *     first time)
   10422 	 *   - Previously-known keys that have been revoked
   10423 	 *     must be scheduled for removal from the key zone (or,
   10424 	 *     if they hadn't been accepted as trust anchors yet
   10425 	 *     anyway, removed at once)
   10426 	 *   - Previously-known unrevoked keys whose acceptance timers
   10427 	 *     have completed are promoted to trust anchors
   10428 	 *   - All keys not being removed have their refresh
   10429 	 *     timers updated
   10430 	 */
   10431 	for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS;
   10432 	     result = dns_rdataset_next(dnskeys))
   10433 	{
   10434 		bool revoked = false;
   10435 		bool newkey = false;
   10436 		bool updatekey = false;
   10437 		bool deletekey = false;
   10438 		bool trustkey = false;
   10439 		dns_keytag_t keytag;
   10440 
   10441 		dns_rdata_reset(&dnskeyrr);
   10442 		dns_rdataset_current(dnskeys, &dnskeyrr);
   10443 		result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10444 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10445 
   10446 		/* Skip ZSK's */
   10447 		if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
   10448 			continue;
   10449 		}
   10450 
   10451 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10452 		if (result != ISC_R_SUCCESS) {
   10453 			/*
   10454 			 * Skip if we cannot compute the key tag.
   10455 			 * This may happen if the algorithm is unsupported
   10456 			 */
   10457 			dns_zone_log(zone, ISC_LOG_ERROR,
   10458 				     "Cannot compute tag for key in zone %s: "
   10459 				     "%s "
   10460 				     "(skipping)",
   10461 				     namebuf, dns_result_totext(result));
   10462 			continue;
   10463 		}
   10464 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10465 
   10466 		revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
   10467 
   10468 		if (matchkey(keydataset, &dnskeyrr)) {
   10469 			dns_rdata_reset(&keydatarr);
   10470 			dns_rdataset_current(keydataset, &keydatarr);
   10471 			result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10472 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10473 
   10474 			if (revoked && revocable(kfetch, &keydata)) {
   10475 				if (keydata.addhd > now) {
   10476 					/*
   10477 					 * Key wasn't trusted yet, and now
   10478 					 * it's been revoked?  Just remove it
   10479 					 */
   10480 					deletekey = true;
   10481 					dnssec_log(zone, ISC_LOG_INFO,
   10482 						   "Pending key %d for "
   10483 						   "zone %s is now revoked: "
   10484 						   "deleting from the "
   10485 						   "managed keys database",
   10486 						   keytag, namebuf);
   10487 				} else if (keydata.removehd == 0) {
   10488 					/*
   10489 					 * Remove key from secroots.
   10490 					 */
   10491 					dns_view_untrust(zone->view, keyname,
   10492 							 &dnskey);
   10493 
   10494 					/* If initializing, delete now */
   10495 					if (keydata.addhd == 0) {
   10496 						deletekey = true;
   10497 					} else {
   10498 						keydata.removehd =
   10499 							now +
   10500 							dns_zone_mkey_month;
   10501 						keydata.flags |=
   10502 							DNS_KEYFLAG_REVOKE;
   10503 					}
   10504 
   10505 					dnssec_log(zone, ISC_LOG_INFO,
   10506 						   "Trusted key %d for "
   10507 						   "zone %s is now revoked",
   10508 						   keytag, namebuf);
   10509 				} else if (keydata.removehd < now) {
   10510 					/* Scheduled for removal */
   10511 					deletekey = true;
   10512 
   10513 					dnssec_log(zone, ISC_LOG_INFO,
   10514 						   "Revoked key %d for "
   10515 						   "zone %s removal timer "
   10516 						   "complete: deleting from "
   10517 						   "the managed keys database",
   10518 						   keytag, namebuf);
   10519 				}
   10520 			} else if (revoked && keydata.removehd == 0) {
   10521 				dnssec_log(zone, ISC_LOG_WARNING,
   10522 					   "Active key %d for zone "
   10523 					   "%s is revoked but "
   10524 					   "did not self-sign; "
   10525 					   "ignoring",
   10526 					   keytag, namebuf);
   10527 				continue;
   10528 			} else if (secure) {
   10529 				if (keydata.removehd != 0) {
   10530 					/*
   10531 					 * Key isn't revoked--but it
   10532 					 * seems it used to be.
   10533 					 * Remove it now and add it
   10534 					 * back as if it were a fresh key,
   10535 					 * with a 30-day acceptance timer.
   10536 					 */
   10537 					deletekey = true;
   10538 					newkey = true;
   10539 					keydata.removehd = 0;
   10540 					keydata.addhd = now +
   10541 							dns_zone_mkey_month;
   10542 
   10543 					dnssec_log(zone, ISC_LOG_INFO,
   10544 						   "Revoked key %d for "
   10545 						   "zone %s has returned: "
   10546 						   "starting 30-day "
   10547 						   "acceptance timer",
   10548 						   keytag, namebuf);
   10549 				} else if (keydata.addhd > now) {
   10550 					pending++;
   10551 				} else if (keydata.addhd == 0) {
   10552 					keydata.addhd = now;
   10553 				}
   10554 
   10555 				if (keydata.addhd <= now) {
   10556 					trustkey = true;
   10557 					dnssec_log(zone, ISC_LOG_INFO,
   10558 						   "Key %d for zone %s "
   10559 						   "is now trusted (%s)",
   10560 						   keytag, namebuf,
   10561 						   initial ? "initializing key "
   10562 							     "verified"
   10563 							   : "acceptance timer "
   10564 							     "complete");
   10565 				}
   10566 			} else if (keydata.addhd > now) {
   10567 				/*
   10568 				 * Not secure, and key is pending:
   10569 				 * reset the acceptance timer
   10570 				 */
   10571 				pending++;
   10572 				keydata.addhd = now + dns_zone_mkey_month;
   10573 				dnssec_log(zone, ISC_LOG_INFO,
   10574 					   "Pending key %d "
   10575 					   "for zone %s was "
   10576 					   "not validated: restarting "
   10577 					   "30-day acceptance timer",
   10578 					   keytag, namebuf);
   10579 			}
   10580 
   10581 			if (!deletekey && !newkey) {
   10582 				updatekey = true;
   10583 			}
   10584 		} else if (secure) {
   10585 			/*
   10586 			 * Key wasn't in the key zone but it's
   10587 			 * revoked now anyway, so just skip it
   10588 			 */
   10589 			if (revoked) {
   10590 				continue;
   10591 			}
   10592 
   10593 			/* Key wasn't in the key zone: add it */
   10594 			newkey = true;
   10595 
   10596 			if (initializing) {
   10597 				dnssec_log(zone, ISC_LOG_WARNING,
   10598 					   "Initializing automatic trust "
   10599 					   "anchor management for zone '%s'; "
   10600 					   "DNSKEY ID %d is now trusted, "
   10601 					   "waiving the normal 30-day "
   10602 					   "waiting period.",
   10603 					   namebuf, keytag);
   10604 				trustkey = true;
   10605 			} else {
   10606 				dnssec_log(zone, ISC_LOG_INFO,
   10607 					   "New key %d observed "
   10608 					   "for zone '%s': "
   10609 					   "starting 30-day "
   10610 					   "acceptance timer",
   10611 					   keytag, namebuf);
   10612 			}
   10613 		} else {
   10614 			/*
   10615 			 * No previously known key, and the key is not
   10616 			 * secure, so skip it.
   10617 			 */
   10618 			continue;
   10619 		}
   10620 
   10621 		/* Delete old version */
   10622 		if (deletekey || !newkey) {
   10623 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10624 					    DNS_DIFFOP_DEL, keyname, 0,
   10625 					    &keydatarr));
   10626 		}
   10627 
   10628 		if (updatekey) {
   10629 			/* Set refresh timer */
   10630 			keydata.refresh = refresh_time(kfetch, false);
   10631 			dns_rdata_reset(&keydatarr);
   10632 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10633 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10634 					     dns_rdatatype_keydata, &keydata,
   10635 					     &keyb);
   10636 
   10637 			/* Insert updated version */
   10638 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10639 					    DNS_DIFFOP_ADD, keyname, 0,
   10640 					    &keydatarr));
   10641 		} else if (newkey) {
   10642 			/* Convert DNSKEY to KEYDATA */
   10643 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10644 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10645 			dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
   10646 					       NULL);
   10647 			keydata.addhd = initializing
   10648 						? now
   10649 						: now + dns_zone_mkey_month;
   10650 			keydata.refresh = refresh_time(kfetch, false);
   10651 			dns_rdata_reset(&keydatarr);
   10652 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10653 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10654 					     dns_rdatatype_keydata, &keydata,
   10655 					     &keyb);
   10656 
   10657 			/* Insert into key zone */
   10658 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10659 					    DNS_DIFFOP_ADD, keyname, 0,
   10660 					    &keydatarr));
   10661 		}
   10662 
   10663 		if (trustkey) {
   10664 			/* Trust this key. */
   10665 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10666 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10667 			trust_key(zone, keyname, &dnskey, false);
   10668 		}
   10669 
   10670 		if (secure && !deletekey) {
   10671 			INSIST(newkey || updatekey);
   10672 			set_refreshkeytimer(zone, &keydata, now, false);
   10673 		}
   10674 	}
   10675 
   10676 	/*
   10677 	 * RFC5011 says, "A trust point that has all of its trust anchors
   10678 	 * revoked is considered deleted and is treated as if the trust
   10679 	 * point was never configured."  But if someone revoked their
   10680 	 * active key before the standby was trusted, that would mean the
   10681 	 * zone would suddenly be nonsecured.  We avoid this by checking to
   10682 	 * see if there's pending keydata.  If so, we put a null key in
   10683 	 * the security roots; then all queries to the zone will fail.
   10684 	 */
   10685 	if (pending != 0) {
   10686 		fail_secure(zone, keyname);
   10687 	}
   10688 
   10689 done:
   10690 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10691 		/* Write changes to journal file. */
   10692 		CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx,
   10693 					zone->updatemethod));
   10694 		CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
   10695 		commit = true;
   10696 
   10697 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   10698 		zone_needdump(zone, 30);
   10699 	} else if (result == ISC_R_NOMORE) {
   10700 		/*
   10701 		 * If "updatekey" was true for all keys found in the DNSKEY
   10702 		 * response and the previous update of those keys happened
   10703 		 * during the same second (only possible if a key refresh was
   10704 		 * externally triggered), it may happen that all relevant
   10705 		 * update_one_rr() calls will return ISC_R_SUCCESS, but
   10706 		 * diff.tuples will remain empty.  Reset result to
   10707 		 * ISC_R_SUCCESS to prevent a bogus warning from being logged.
   10708 		 */
   10709 		result = ISC_R_SUCCESS;
   10710 	}
   10711 
   10712 failure:
   10713 	if (result != ISC_R_SUCCESS) {
   10714 		dnssec_log(zone, ISC_LOG_ERROR,
   10715 			   "error during managed-keys processing (%s): "
   10716 			   "DNSSEC validation may be at risk",
   10717 			   isc_result_totext(result));
   10718 	}
   10719 	dns_diff_clear(&diff);
   10720 	if (ver != NULL) {
   10721 		dns_db_closeversion(kfetch->db, &ver, commit);
   10722 	}
   10723 
   10724 cleanup:
   10725 	dns_db_detach(&kfetch->db);
   10726 
   10727 	isc_refcount_decrement(&zone->irefs);
   10728 
   10729 	kfetch->zone = NULL;
   10730 
   10731 	if (dns_rdataset_isassociated(keydataset)) {
   10732 		dns_rdataset_disassociate(keydataset);
   10733 	}
   10734 	if (dns_rdataset_isassociated(dnskeys)) {
   10735 		dns_rdataset_disassociate(dnskeys);
   10736 	}
   10737 	if (dns_rdataset_isassociated(dnskeysigs)) {
   10738 		dns_rdataset_disassociate(dnskeysigs);
   10739 	}
   10740 
   10741 	dns_name_free(keyname, mctx);
   10742 	isc_mem_putanddetach(&mctx, kfetch, sizeof(dns_keyfetch_t));
   10743 
   10744 	if (secroots != NULL) {
   10745 		dns_keytable_detach(&secroots);
   10746 	}
   10747 
   10748 	free_needed = exit_check(zone);
   10749 	UNLOCK_ZONE(zone);
   10750 	if (free_needed) {
   10751 		zone_free(zone);
   10752 	}
   10753 
   10754 	INSIST(ver == NULL);
   10755 }
   10756 
   10757 /*
   10758  * Refresh the data in the key zone.  Initiate a fetch to look up
   10759  * DNSKEY records at the trust anchor name.
   10760  */
   10761 static void
   10762 zone_refreshkeys(dns_zone_t *zone) {
   10763 	const char me[] = "zone_refreshkeys";
   10764 	isc_result_t result;
   10765 	dns_rriterator_t rrit;
   10766 	dns_db_t *db = NULL;
   10767 	dns_dbversion_t *ver = NULL;
   10768 	dns_diff_t diff;
   10769 	dns_rdata_t rdata = DNS_RDATA_INIT;
   10770 	dns_rdata_keydata_t kd;
   10771 	isc_stdtime_t now;
   10772 	bool commit = false;
   10773 	bool fetching = false, fetch_err = false;
   10774 	bool timerset = false;
   10775 
   10776 	ENTER;
   10777 	REQUIRE(zone->db != NULL);
   10778 
   10779 	isc_stdtime_get(&now);
   10780 
   10781 	LOCK_ZONE(zone);
   10782 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   10783 		isc_time_settoepoch(&zone->refreshkeytime);
   10784 		UNLOCK_ZONE(zone);
   10785 		return;
   10786 	}
   10787 
   10788 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   10789 	dns_db_attach(zone->db, &db);
   10790 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   10791 
   10792 	dns_diff_init(zone->mctx, &diff);
   10793 
   10794 	CHECK(dns_db_newversion(db, &ver));
   10795 
   10796 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10797 
   10798 	dns_rriterator_init(&rrit, db, ver, 0);
   10799 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   10800 	     result = dns_rriterator_nextrrset(&rrit))
   10801 	{
   10802 		isc_stdtime_t timer = 0xffffffff;
   10803 		dns_name_t *name = NULL, *kname = NULL;
   10804 		dns_rdataset_t *kdset = NULL;
   10805 		dns_keyfetch_t *kfetch;
   10806 		uint32_t ttl;
   10807 
   10808 		dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
   10809 		if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
   10810 		    !dns_rdataset_isassociated(kdset))
   10811 		{
   10812 			continue;
   10813 		}
   10814 
   10815 		/*
   10816 		 * Scan the stored keys looking for ones that need
   10817 		 * removal or refreshing
   10818 		 */
   10819 		for (result = dns_rdataset_first(kdset);
   10820 		     result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset))
   10821 		{
   10822 			dns_rdata_reset(&rdata);
   10823 			dns_rdataset_current(kdset, &rdata);
   10824 			result = dns_rdata_tostruct(&rdata, &kd, NULL);
   10825 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10826 
   10827 			/* Removal timer expired? */
   10828 			if (kd.removehd != 0 && kd.removehd < now) {
   10829 				dns_rriterator_pause(&rrit);
   10830 				CHECK(update_one_rr(db, ver, &diff,
   10831 						    DNS_DIFFOP_DEL, name, ttl,
   10832 						    &rdata));
   10833 				continue;
   10834 			}
   10835 
   10836 			/* Acceptance timer expired? */
   10837 			if (kd.addhd <= now) {
   10838 				timer = kd.addhd;
   10839 			}
   10840 
   10841 			/* Or do we just need to refresh the keyset? */
   10842 			if (timer > kd.refresh) {
   10843 				timer = kd.refresh;
   10844 			}
   10845 
   10846 			dns_rriterator_pause(&rrit);
   10847 			set_refreshkeytimer(zone, &kd, now, false);
   10848 			timerset = true;
   10849 		}
   10850 
   10851 		if (timer > now) {
   10852 			continue;
   10853 		}
   10854 
   10855 		dns_rriterator_pause(&rrit);
   10856 
   10857 		kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
   10858 
   10859 		zone->refreshkeycount++;
   10860 		kfetch->zone = zone;
   10861 		isc_refcount_increment0(&zone->irefs);
   10862 		kname = dns_fixedname_initname(&kfetch->name);
   10863 		dns_name_dup(name, zone->mctx, kname);
   10864 		dns_rdataset_init(&kfetch->dnskeyset);
   10865 		dns_rdataset_init(&kfetch->dnskeysigset);
   10866 		dns_rdataset_init(&kfetch->keydataset);
   10867 		dns_rdataset_clone(kdset, &kfetch->keydataset);
   10868 		kfetch->db = NULL;
   10869 		dns_db_attach(db, &kfetch->db);
   10870 		kfetch->fetch = NULL;
   10871 
   10872 		if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   10873 			char namebuf[DNS_NAME_FORMATSIZE];
   10874 			dns_name_format(kname, namebuf, sizeof(namebuf));
   10875 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   10876 				   "Creating key fetch in "
   10877 				   "zone_refreshkeys() for '%s'",
   10878 				   namebuf);
   10879 		}
   10880 
   10881 		/*
   10882 		 * Use of DNS_FETCHOPT_NOCACHED is essential here.  If it is
   10883 		 * not set and the cache still holds a non-expired, validated
   10884 		 * version of the RRset being queried for by the time the
   10885 		 * response is received, the cached RRset will be passed to
   10886 		 * keyfetch_done() instead of the one received in the response
   10887 		 * as the latter will have a lower trust level due to not being
   10888 		 * validated until keyfetch_done() is called.
   10889 		 */
   10890 
   10891 #ifdef ENABLE_AFL
   10892 		if (!dns_fuzzing_resolver) {
   10893 #endif /* ifdef ENABLE_AFL */
   10894 			result = dns_resolver_createfetch(
   10895 				zone->view->resolver, kname,
   10896 				dns_rdatatype_dnskey, NULL, NULL, NULL, NULL, 0,
   10897 				DNS_FETCHOPT_NOVALIDATE |
   10898 					DNS_FETCHOPT_UNSHARED |
   10899 					DNS_FETCHOPT_NOCACHED,
   10900 				0, NULL, zone->task, keyfetch_done, kfetch,
   10901 				&kfetch->dnskeyset, &kfetch->dnskeysigset,
   10902 				&kfetch->fetch);
   10903 #ifdef ENABLE_AFL
   10904 		} else {
   10905 			result = ISC_R_FAILURE;
   10906 		}
   10907 #endif /* ifdef ENABLE_AFL */
   10908 		if (result == ISC_R_SUCCESS) {
   10909 			fetching = true;
   10910 		} else {
   10911 			zone->refreshkeycount--;
   10912 			isc_refcount_decrement(&zone->irefs);
   10913 			dns_db_detach(&kfetch->db);
   10914 			dns_rdataset_disassociate(&kfetch->keydataset);
   10915 			dns_name_free(kname, zone->mctx);
   10916 			isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
   10917 			dnssec_log(zone, ISC_LOG_WARNING,
   10918 				   "Failed to create fetch for DNSKEY update");
   10919 			fetch_err = true;
   10920 		}
   10921 	}
   10922 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10923 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   10924 					zone->updatemethod));
   10925 		CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
   10926 		commit = true;
   10927 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   10928 		zone_needdump(zone, 30);
   10929 	}
   10930 
   10931 failure:
   10932 	if (fetch_err) {
   10933 		/*
   10934 		 * Error during a key fetch; retry in an hour.
   10935 		 */
   10936 		isc_time_t timenow, timethen;
   10937 		char timebuf[80];
   10938 
   10939 		TIME_NOW(&timenow);
   10940 		DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
   10941 		zone->refreshkeytime = timethen;
   10942 		zone_settimer(zone, &timenow);
   10943 
   10944 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   10945 		dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
   10946 			   timebuf);
   10947 	} else if (!timerset) {
   10948 		isc_time_settoepoch(&zone->refreshkeytime);
   10949 	}
   10950 
   10951 	if (!fetching) {
   10952 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10953 	}
   10954 
   10955 	dns_diff_clear(&diff);
   10956 	if (ver != NULL) {
   10957 		dns_rriterator_destroy(&rrit);
   10958 		dns_db_closeversion(db, &ver, commit);
   10959 	}
   10960 	dns_db_detach(&db);
   10961 
   10962 	UNLOCK_ZONE(zone);
   10963 
   10964 	INSIST(ver == NULL);
   10965 }
   10966 
   10967 static void
   10968 zone_maintenance(dns_zone_t *zone) {
   10969 	const char me[] = "zone_maintenance";
   10970 	isc_time_t now;
   10971 	isc_result_t result;
   10972 	bool dumping, load_pending, viewok;
   10973 	bool need_notify;
   10974 
   10975 	REQUIRE(DNS_ZONE_VALID(zone));
   10976 	ENTER;
   10977 
   10978 	/*
   10979 	 * Are we pending load/reload?
   10980 	 */
   10981 	LOCK_ZONE(zone);
   10982 	load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
   10983 	UNLOCK_ZONE(zone);
   10984 
   10985 	if (load_pending) {
   10986 		return;
   10987 	}
   10988 
   10989 	/*
   10990 	 * Configuring the view of this zone may have
   10991 	 * failed, for example because the config file
   10992 	 * had a syntax error.	In that case, the view
   10993 	 * adb or resolver will be NULL, and we had better not try
   10994 	 * to do further maintenance on it.
   10995 	 */
   10996 	LOCK_ZONE(zone);
   10997 	viewok = (zone->view != NULL && zone->view->adb != NULL);
   10998 	UNLOCK_ZONE(zone);
   10999 	if (!viewok) {
   11000 		return;
   11001 	}
   11002 
   11003 	TIME_NOW(&now);
   11004 
   11005 	/*
   11006 	 * Expire check.
   11007 	 */
   11008 	switch (zone->type) {
   11009 	case dns_zone_redirect:
   11010 		if (zone->masters == NULL) {
   11011 			break;
   11012 		}
   11013 	/* FALLTHROUGH */
   11014 	case dns_zone_slave:
   11015 	case dns_zone_mirror:
   11016 	case dns_zone_stub:
   11017 		LOCK_ZONE(zone);
   11018 		if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
   11019 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11020 		{
   11021 			zone_expire(zone);
   11022 			zone->refreshtime = now;
   11023 		}
   11024 		UNLOCK_ZONE(zone);
   11025 		break;
   11026 	default:
   11027 		break;
   11028 	}
   11029 
   11030 	/*
   11031 	 * Up to date check.
   11032 	 */
   11033 	switch (zone->type) {
   11034 	case dns_zone_redirect:
   11035 		if (zone->masters == NULL) {
   11036 			break;
   11037 		}
   11038 	/* FALLTHROUGH */
   11039 	case dns_zone_slave:
   11040 	case dns_zone_mirror:
   11041 	case dns_zone_stub:
   11042 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
   11043 		    isc_time_compare(&now, &zone->refreshtime) >= 0)
   11044 		{
   11045 			dns_zone_refresh(zone);
   11046 		}
   11047 		break;
   11048 	default:
   11049 		break;
   11050 	}
   11051 
   11052 	/*
   11053 	 * Secondaries send notifies before backing up to disk,
   11054 	 * primaries after.
   11055 	 */
   11056 	LOCK_ZONE(zone);
   11057 	need_notify = (zone->type == dns_zone_slave ||
   11058 		       zone->type == dns_zone_mirror) &&
   11059 		      (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11060 		       DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11061 		      (isc_time_compare(&now, &zone->notifytime) >= 0);
   11062 	UNLOCK_ZONE(zone);
   11063 
   11064 	if (need_notify) {
   11065 		zone_notify(zone, &now);
   11066 	}
   11067 
   11068 	/*
   11069 	 * Do we need to consolidate the backing store?
   11070 	 */
   11071 	switch (zone->type) {
   11072 	case dns_zone_master:
   11073 	case dns_zone_slave:
   11074 	case dns_zone_mirror:
   11075 	case dns_zone_key:
   11076 	case dns_zone_redirect:
   11077 	case dns_zone_stub:
   11078 		LOCK_ZONE(zone);
   11079 		if (zone->masterfile != NULL &&
   11080 		    isc_time_compare(&now, &zone->dumptime) >= 0 &&
   11081 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11082 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
   11083 		{
   11084 			dumping = was_dumping(zone);
   11085 		} else {
   11086 			dumping = true;
   11087 		}
   11088 		UNLOCK_ZONE(zone);
   11089 		if (!dumping) {
   11090 			result = zone_dump(zone, true); /* task locked */
   11091 			if (result != ISC_R_SUCCESS) {
   11092 				dns_zone_log(zone, ISC_LOG_WARNING,
   11093 					     "dump failed: %s",
   11094 					     dns_result_totext(result));
   11095 			}
   11096 		}
   11097 		break;
   11098 	default:
   11099 		break;
   11100 	}
   11101 
   11102 	/*
   11103 	 * Master/redirect zones send notifies now, if needed
   11104 	 */
   11105 	switch (zone->type) {
   11106 	case dns_zone_master:
   11107 	case dns_zone_redirect:
   11108 		if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11109 		     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11110 		    isc_time_compare(&now, &zone->notifytime) >= 0)
   11111 		{
   11112 			zone_notify(zone, &now);
   11113 		}
   11114 	default:
   11115 		break;
   11116 	}
   11117 
   11118 	/*
   11119 	 * Do we need to refresh keys?
   11120 	 */
   11121 	switch (zone->type) {
   11122 	case dns_zone_key:
   11123 		if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
   11124 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11125 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
   11126 			{
   11127 				zone_refreshkeys(zone);
   11128 			}
   11129 		}
   11130 		break;
   11131 	case dns_zone_master:
   11132 		if (!isc_time_isepoch(&zone->refreshkeytime) &&
   11133 		    isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
   11134 		    zone->rss_event == NULL)
   11135 		{
   11136 			zone_rekey(zone);
   11137 		}
   11138 	default:
   11139 		break;
   11140 	}
   11141 
   11142 	switch (zone->type) {
   11143 	case dns_zone_master:
   11144 	case dns_zone_redirect:
   11145 	case dns_zone_slave:
   11146 		/*
   11147 		 * Do we need to sign/resign some RRsets?
   11148 		 */
   11149 		if (zone->rss_event != NULL) {
   11150 			break;
   11151 		}
   11152 		if (!isc_time_isepoch(&zone->signingtime) &&
   11153 		    isc_time_compare(&now, &zone->signingtime) >= 0)
   11154 		{
   11155 			zone_sign(zone);
   11156 		} else if (!isc_time_isepoch(&zone->resigntime) &&
   11157 			   isc_time_compare(&now, &zone->resigntime) >= 0)
   11158 		{
   11159 			zone_resigninc(zone);
   11160 		} else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
   11161 			   isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
   11162 		{
   11163 			zone_nsec3chain(zone);
   11164 		}
   11165 		/*
   11166 		 * Do we need to issue a key expiry warning?
   11167 		 */
   11168 		if (!isc_time_isepoch(&zone->keywarntime) &&
   11169 		    isc_time_compare(&now, &zone->keywarntime) >= 0)
   11170 		{
   11171 			set_key_expiry_warning(zone, zone->key_expiry,
   11172 					       isc_time_seconds(&now));
   11173 		}
   11174 		break;
   11175 
   11176 	default:
   11177 		break;
   11178 	}
   11179 	LOCK_ZONE(zone);
   11180 	zone_settimer(zone, &now);
   11181 	UNLOCK_ZONE(zone);
   11182 }
   11183 
   11184 void
   11185 dns_zone_markdirty(dns_zone_t *zone) {
   11186 	uint32_t serial;
   11187 	isc_result_t result = ISC_R_SUCCESS;
   11188 	dns_zone_t *secure = NULL;
   11189 
   11190 	/*
   11191 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   11192 	 * could result in a deadlock due to a LOR so we will spin if we
   11193 	 * can't obtain the both locks.
   11194 	 */
   11195 again:
   11196 	LOCK_ZONE(zone);
   11197 	if (zone->type == dns_zone_master) {
   11198 		if (inline_raw(zone)) {
   11199 			unsigned int soacount;
   11200 			secure = zone->secure;
   11201 			INSIST(secure != zone);
   11202 			TRYLOCK_ZONE(result, secure);
   11203 			if (result != ISC_R_SUCCESS) {
   11204 				UNLOCK_ZONE(zone);
   11205 				secure = NULL;
   11206 				isc_thread_yield();
   11207 				goto again;
   11208 			}
   11209 
   11210 			ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11211 			if (zone->db != NULL) {
   11212 				result = zone_get_from_db(
   11213 					zone, zone->db, NULL, &soacount,
   11214 					&serial, NULL, NULL, NULL, NULL, NULL);
   11215 			} else {
   11216 				result = DNS_R_NOTLOADED;
   11217 			}
   11218 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11219 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   11220 				zone_send_secureserial(zone, serial);
   11221 			}
   11222 		}
   11223 
   11224 		/* XXXMPA make separate call back */
   11225 		if (result == ISC_R_SUCCESS) {
   11226 			set_resigntime(zone);
   11227 			if (zone->task != NULL) {
   11228 				isc_time_t now;
   11229 				TIME_NOW(&now);
   11230 				zone_settimer(zone, &now);
   11231 			}
   11232 		}
   11233 	}
   11234 	if (secure != NULL) {
   11235 		UNLOCK_ZONE(secure);
   11236 	}
   11237 	zone_needdump(zone, DNS_DUMP_DELAY);
   11238 	UNLOCK_ZONE(zone);
   11239 }
   11240 
   11241 void
   11242 dns_zone_expire(dns_zone_t *zone) {
   11243 	REQUIRE(DNS_ZONE_VALID(zone));
   11244 
   11245 	LOCK_ZONE(zone);
   11246 	zone_expire(zone);
   11247 	UNLOCK_ZONE(zone);
   11248 }
   11249 
   11250 static void
   11251 zone_expire(dns_zone_t *zone) {
   11252 	dns_db_t *db = NULL;
   11253 
   11254 	/*
   11255 	 * 'zone' locked by caller.
   11256 	 */
   11257 
   11258 	REQUIRE(LOCKED_ZONE(zone));
   11259 
   11260 	dns_zone_log(zone, ISC_LOG_WARNING, "expired");
   11261 
   11262 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
   11263 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   11264 	zone->retry = DNS_ZONE_DEFAULTRETRY;
   11265 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   11266 
   11267 	/*
   11268 	 * An RPZ zone has expired; before unloading it, we must
   11269 	 * first remove it from the RPZ summary database. The
   11270 	 * easiest way to do this is "update" it with an empty
   11271 	 * database so that the update callback synchronizes
   11272 	 * the diff automatically.
   11273 	 */
   11274 	if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) {
   11275 		isc_result_t result;
   11276 		dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num];
   11277 
   11278 		CHECK(dns_db_create(zone->mctx, "rbt", &zone->origin,
   11279 				    dns_dbtype_zone, zone->rdclass, 0, NULL,
   11280 				    &db));
   11281 		CHECK(dns_rpz_dbupdate_callback(db, rpz));
   11282 		dns_zone_log(zone, ISC_LOG_WARNING,
   11283 			     "response-policy zone expired; "
   11284 			     "policies unloaded");
   11285 	}
   11286 
   11287 failure:
   11288 	if (db != NULL) {
   11289 		dns_db_detach(&db);
   11290 	}
   11291 
   11292 	zone_unload(zone);
   11293 }
   11294 
   11295 void
   11296 dns_zone_refresh(dns_zone_t *zone) {
   11297 	isc_interval_t i;
   11298 	uint32_t oldflags;
   11299 	unsigned int j;
   11300 	isc_result_t result;
   11301 
   11302 	REQUIRE(DNS_ZONE_VALID(zone));
   11303 
   11304 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11305 		return;
   11306 	}
   11307 
   11308 	/*
   11309 	 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
   11310 	 * in progress at a time.
   11311 	 */
   11312 
   11313 	LOCK_ZONE(zone);
   11314 	oldflags = atomic_load(&zone->flags);
   11315 	if (zone->masterscnt == 0) {
   11316 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   11317 		if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) {
   11318 			dns_zone_log(zone, ISC_LOG_ERROR,
   11319 				     "cannot refresh: no primaries");
   11320 		}
   11321 		goto unlock;
   11322 	}
   11323 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   11324 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   11325 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   11326 	if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) {
   11327 		goto unlock;
   11328 	}
   11329 
   11330 	/*
   11331 	 * Set the next refresh time as if refresh check has failed.
   11332 	 * Setting this to the retry time will do that.  XXXMLG
   11333 	 * If we are successful it will be reset using zone->refresh.
   11334 	 */
   11335 	isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4),
   11336 			 0);
   11337 	result = isc_time_nowplusinterval(&zone->refreshtime, &i);
   11338 	if (result != ISC_R_SUCCESS) {
   11339 		dns_zone_log(zone, ISC_LOG_WARNING,
   11340 			     "isc_time_nowplusinterval() failed: %s",
   11341 			     dns_result_totext(result));
   11342 	}
   11343 
   11344 	/*
   11345 	 * When lacking user-specified timer values from the SOA,
   11346 	 * do exponential backoff of the retry time up to a
   11347 	 * maximum of six hours.
   11348 	 */
   11349 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) {
   11350 		zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
   11351 	}
   11352 
   11353 	zone->curmaster = 0;
   11354 	for (j = 0; j < zone->masterscnt; j++) {
   11355 		zone->mastersok[j] = false;
   11356 	}
   11357 	/* initiate soa query */
   11358 	queue_soa_query(zone);
   11359 unlock:
   11360 	UNLOCK_ZONE(zone);
   11361 }
   11362 
   11363 static isc_result_t
   11364 zone_journal_rollforward(dns_zone_t *zone, dns_db_t *db, bool *needdump,
   11365 			 bool *fixjournal) {
   11366 	dns_journal_t *journal = NULL;
   11367 	unsigned int options;
   11368 	isc_result_t result;
   11369 
   11370 	if (zone->type == dns_zone_master &&
   11371 	    (inline_secure(zone) ||
   11372 	     (zone->update_acl != NULL || zone->ssutable != NULL)))
   11373 	{
   11374 		options = DNS_JOURNALOPT_RESIGN;
   11375 	} else {
   11376 		options = 0;
   11377 	}
   11378 
   11379 	result = dns_journal_open(zone->mctx, zone->journal, DNS_JOURNAL_READ,
   11380 				  &journal);
   11381 	if (result == ISC_R_NOTFOUND) {
   11382 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(3),
   11383 			      "no journal file, but that's OK ");
   11384 		return (ISC_R_SUCCESS);
   11385 	} else if (result != ISC_R_SUCCESS) {
   11386 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11387 			      "journal open failed: %s",
   11388 			      dns_result_totext(result));
   11389 		return (result);
   11390 	}
   11391 
   11392 	if (dns_journal_empty(journal)) {
   11393 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   11394 			      "journal empty");
   11395 		dns_journal_destroy(&journal);
   11396 		return (ISC_R_SUCCESS);
   11397 	}
   11398 
   11399 	result = dns_journal_rollforward(journal, db, options);
   11400 	switch (result) {
   11401 	case ISC_R_SUCCESS:
   11402 		*needdump = true;
   11403 		/* FALLTHROUGH */
   11404 	case DNS_R_UPTODATE:
   11405 		if (dns_journal_recovered(journal)) {
   11406 			*fixjournal = true;
   11407 			dns_zone_logc(
   11408 				zone, DNS_LOGCATEGORY_ZONELOAD,
   11409 				ISC_LOG_DEBUG(1),
   11410 				"journal rollforward completed successfully "
   11411 				"using old journal format: %s",
   11412 				dns_result_totext(result));
   11413 		} else {
   11414 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   11415 				      ISC_LOG_DEBUG(1),
   11416 				      "journal rollforward completed "
   11417 				      "successfully: %s",
   11418 				      dns_result_totext(result));
   11419 		}
   11420 
   11421 		dns_journal_destroy(&journal);
   11422 		return (ISC_R_SUCCESS);
   11423 	case ISC_R_NOTFOUND:
   11424 	case ISC_R_RANGE:
   11425 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11426 			      "journal rollforward failed: journal out of sync "
   11427 			      "with zone");
   11428 		dns_journal_destroy(&journal);
   11429 		return (result);
   11430 	default:
   11431 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   11432 			      "journal rollforward failed: %s",
   11433 			      dns_result_totext(result));
   11434 		dns_journal_destroy(&journal);
   11435 		return (result);
   11436 	}
   11437 }
   11438 
   11439 static void
   11440 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) {
   11441 	isc_result_t result;
   11442 	int32_t journalsize;
   11443 	dns_dbversion_t *ver = NULL;
   11444 	uint64_t dbsize;
   11445 	uint32_t options = 0;
   11446 
   11447 	INSIST(LOCKED_ZONE(zone));
   11448 	if (inline_raw(zone)) {
   11449 		INSIST(LOCKED_ZONE(zone->secure));
   11450 	}
   11451 
   11452 	journalsize = zone->journalsize;
   11453 	if (journalsize == -1) {
   11454 		journalsize = DNS_JOURNAL_SIZE_MAX;
   11455 		dns_db_currentversion(db, &ver);
   11456 		result = dns_db_getsize(db, ver, NULL, &dbsize);
   11457 		dns_db_closeversion(db, &ver, false);
   11458 		if (result != ISC_R_SUCCESS) {
   11459 			dns_zone_log(zone, ISC_LOG_ERROR,
   11460 				     "zone_journal_compact: "
   11461 				     "could not get zone size: %s",
   11462 				     isc_result_totext(result));
   11463 		} else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) {
   11464 			journalsize = (int32_t)dbsize * 2;
   11465 		}
   11466 	}
   11467 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FIXJOURNAL)) {
   11468 		options |= DNS_JOURNAL_COMPACTALL;
   11469 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FIXJOURNAL);
   11470 		zone_debuglog(zone, "zone_journal_compact", 1,
   11471 			      "repair full journal");
   11472 	} else {
   11473 		zone_debuglog(zone, "zone_journal_compact", 1,
   11474 			      "target journal size %d", journalsize);
   11475 	}
   11476 	result = dns_journal_compact(zone->mctx, zone->journal, serial, options,
   11477 				     journalsize);
   11478 	switch (result) {
   11479 	case ISC_R_SUCCESS:
   11480 	case ISC_R_NOSPACE:
   11481 	case ISC_R_NOTFOUND:
   11482 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s",
   11483 			     dns_result_totext(result));
   11484 		break;
   11485 	default:
   11486 		dns_zone_log(zone, ISC_LOG_ERROR,
   11487 			     "dns_journal_compact failed: %s",
   11488 			     dns_result_totext(result));
   11489 		break;
   11490 	}
   11491 }
   11492 
   11493 isc_result_t
   11494 dns_zone_flush(dns_zone_t *zone) {
   11495 	isc_result_t result = ISC_R_SUCCESS;
   11496 	bool dumping;
   11497 
   11498 	REQUIRE(DNS_ZONE_VALID(zone));
   11499 
   11500 	LOCK_ZONE(zone);
   11501 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
   11502 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11503 	    zone->masterfile != NULL) {
   11504 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   11505 		result = ISC_R_ALREADYRUNNING;
   11506 		dumping = was_dumping(zone);
   11507 	} else {
   11508 		dumping = true;
   11509 	}
   11510 	UNLOCK_ZONE(zone);
   11511 	if (!dumping) {
   11512 		result = zone_dump(zone, true); /* Unknown task. */
   11513 	}
   11514 	return (result);
   11515 }
   11516 
   11517 isc_result_t
   11518 dns_zone_dump(dns_zone_t *zone) {
   11519 	isc_result_t result = ISC_R_ALREADYRUNNING;
   11520 	bool dumping;
   11521 
   11522 	REQUIRE(DNS_ZONE_VALID(zone));
   11523 
   11524 	LOCK_ZONE(zone);
   11525 	dumping = was_dumping(zone);
   11526 	UNLOCK_ZONE(zone);
   11527 	if (!dumping) {
   11528 		result = zone_dump(zone, false); /* Unknown task. */
   11529 	}
   11530 	return (result);
   11531 }
   11532 
   11533 static void
   11534 zone_needdump(dns_zone_t *zone, unsigned int delay) {
   11535 	const char me[] = "zone_needdump";
   11536 	isc_time_t dumptime;
   11537 	isc_time_t now;
   11538 
   11539 	/*
   11540 	 * 'zone' locked by caller
   11541 	 */
   11542 
   11543 	REQUIRE(DNS_ZONE_VALID(zone));
   11544 	REQUIRE(LOCKED_ZONE(zone));
   11545 	ENTER;
   11546 
   11547 	/*
   11548 	 * Do we have a place to dump to and are we loaded?
   11549 	 */
   11550 	if (zone->masterfile == NULL ||
   11551 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) {
   11552 		return;
   11553 	}
   11554 
   11555 	TIME_NOW(&now);
   11556 	/* add some noise */
   11557 	DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
   11558 
   11559 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11560 	if (isc_time_isepoch(&zone->dumptime) ||
   11561 	    isc_time_compare(&zone->dumptime, &dumptime) > 0)
   11562 	{
   11563 		zone->dumptime = dumptime;
   11564 	}
   11565 	if (zone->task != NULL) {
   11566 		zone_settimer(zone, &now);
   11567 	}
   11568 }
   11569 
   11570 static void
   11571 dump_done(void *arg, isc_result_t result) {
   11572 	const char me[] = "dump_done";
   11573 	dns_zone_t *zone = arg;
   11574 	dns_zone_t *secure = NULL;
   11575 	dns_db_t *db;
   11576 	dns_dbversion_t *version;
   11577 	bool again = false;
   11578 	bool compact = false;
   11579 	uint32_t serial;
   11580 	isc_result_t tresult;
   11581 
   11582 	REQUIRE(DNS_ZONE_VALID(zone));
   11583 
   11584 	ENTER;
   11585 
   11586 	if (result == ISC_R_SUCCESS && zone->journal != NULL) {
   11587 		/*
   11588 		 * We don't own these, zone->dctx must stay valid.
   11589 		 */
   11590 		db = dns_dumpctx_db(zone->dctx);
   11591 		version = dns_dumpctx_version(zone->dctx);
   11592 		tresult = dns_db_getsoaserial(db, version, &serial);
   11593 
   11594 		/*
   11595 		 * Handle lock order inversion.
   11596 		 */
   11597 	again:
   11598 		LOCK_ZONE(zone);
   11599 		if (inline_raw(zone)) {
   11600 			secure = zone->secure;
   11601 			INSIST(secure != zone);
   11602 			TRYLOCK_ZONE(result, secure);
   11603 			if (result != ISC_R_SUCCESS) {
   11604 				UNLOCK_ZONE(zone);
   11605 				secure = NULL;
   11606 				isc_thread_yield();
   11607 				goto again;
   11608 			}
   11609 		}
   11610 
   11611 		/*
   11612 		 * If there is a secure version of this zone
   11613 		 * use its serial if it is less than ours.
   11614 		 */
   11615 		if (tresult == ISC_R_SUCCESS && secure != NULL) {
   11616 			uint32_t sserial;
   11617 			isc_result_t mresult;
   11618 
   11619 			ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
   11620 			if (secure->db != NULL) {
   11621 				mresult = dns_db_getsoaserial(zone->secure->db,
   11622 							      NULL, &sserial);
   11623 				if (mresult == ISC_R_SUCCESS &&
   11624 				    isc_serial_lt(sserial, serial)) {
   11625 					serial = sserial;
   11626 				}
   11627 			}
   11628 			ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
   11629 		}
   11630 		if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
   11631 			dns_db_t *zdb = NULL;
   11632 			if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) {
   11633 				zone_journal_compact(zone, zdb, serial);
   11634 				dns_db_detach(&zdb);
   11635 			}
   11636 		} else if (tresult == ISC_R_SUCCESS) {
   11637 			compact = true;
   11638 			zone->compact_serial = serial;
   11639 		}
   11640 		if (secure != NULL) {
   11641 			UNLOCK_ZONE(secure);
   11642 		}
   11643 		UNLOCK_ZONE(zone);
   11644 	}
   11645 
   11646 	LOCK_ZONE(zone);
   11647 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   11648 	if (compact) {
   11649 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   11650 	}
   11651 	if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
   11652 		/*
   11653 		 * Try again in a short while.
   11654 		 */
   11655 		zone_needdump(zone, DNS_DUMP_DELAY);
   11656 	} else if (result == ISC_R_SUCCESS &&
   11657 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   11658 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11659 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11660 	{
   11661 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11662 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   11663 		isc_time_settoepoch(&zone->dumptime);
   11664 		again = true;
   11665 	} else if (result == ISC_R_SUCCESS) {
   11666 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   11667 	}
   11668 
   11669 	if (zone->dctx != NULL) {
   11670 		dns_dumpctx_detach(&zone->dctx);
   11671 	}
   11672 	zonemgr_putio(&zone->writeio);
   11673 	UNLOCK_ZONE(zone);
   11674 	if (again) {
   11675 		(void)zone_dump(zone, false);
   11676 	}
   11677 	dns_zone_idetach(&zone);
   11678 }
   11679 
   11680 static isc_result_t
   11681 zone_dump(dns_zone_t *zone, bool compact) {
   11682 	const char me[] = "zone_dump";
   11683 	isc_result_t result;
   11684 	dns_dbversion_t *version = NULL;
   11685 	bool again;
   11686 	dns_db_t *db = NULL;
   11687 	char *masterfile = NULL;
   11688 	dns_masterformat_t masterformat = dns_masterformat_none;
   11689 
   11690 	/*
   11691 	 * 'compact' MUST only be set if we are task locked.
   11692 	 */
   11693 
   11694 	REQUIRE(DNS_ZONE_VALID(zone));
   11695 	ENTER;
   11696 
   11697 redo:
   11698 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11699 	if (zone->db != NULL) {
   11700 		dns_db_attach(zone->db, &db);
   11701 	}
   11702 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11703 	LOCK_ZONE(zone);
   11704 	if (zone->masterfile != NULL) {
   11705 		masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
   11706 		masterformat = zone->masterformat;
   11707 	}
   11708 	UNLOCK_ZONE(zone);
   11709 	if (db == NULL) {
   11710 		result = DNS_R_NOTLOADED;
   11711 		goto fail;
   11712 	}
   11713 	if (masterfile == NULL) {
   11714 		result = DNS_R_NOMASTERFILE;
   11715 		goto fail;
   11716 	}
   11717 
   11718 	if (compact && zone->type != dns_zone_stub) {
   11719 		dns_zone_t *dummy = NULL;
   11720 		LOCK_ZONE(zone);
   11721 		zone_iattach(zone, &dummy);
   11722 		result = zonemgr_getio(zone->zmgr, false, zone->task,
   11723 				       zone_gotwritehandle, zone,
   11724 				       &zone->writeio);
   11725 		if (result != ISC_R_SUCCESS) {
   11726 			zone_idetach(&dummy);
   11727 		} else {
   11728 			result = DNS_R_CONTINUE;
   11729 		}
   11730 		UNLOCK_ZONE(zone);
   11731 	} else {
   11732 		const dns_master_style_t *output_style;
   11733 
   11734 		dns_masterrawheader_t rawdata;
   11735 		dns_db_currentversion(db, &version);
   11736 		dns_master_initrawheader(&rawdata);
   11737 		if (inline_secure(zone)) {
   11738 			get_raw_serial(zone->raw, &rawdata);
   11739 		}
   11740 		if (zone->type == dns_zone_key) {
   11741 			output_style = &dns_master_style_keyzone;
   11742 		} else {
   11743 			output_style = &dns_master_style_default;
   11744 		}
   11745 		result = dns_master_dump(zone->mctx, db, version, output_style,
   11746 					 masterfile, masterformat, &rawdata);
   11747 		dns_db_closeversion(db, &version, false);
   11748 	}
   11749 fail:
   11750 	if (db != NULL) {
   11751 		dns_db_detach(&db);
   11752 	}
   11753 	if (masterfile != NULL) {
   11754 		isc_mem_free(zone->mctx, masterfile);
   11755 	}
   11756 	masterfile = NULL;
   11757 
   11758 	if (result == DNS_R_CONTINUE) {
   11759 		return (ISC_R_SUCCESS); /* XXXMPA */
   11760 	}
   11761 
   11762 	again = false;
   11763 	LOCK_ZONE(zone);
   11764 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   11765 	if (result != ISC_R_SUCCESS) {
   11766 		/*
   11767 		 * Try again in a short while.
   11768 		 */
   11769 		zone_needdump(zone, DNS_DUMP_DELAY);
   11770 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   11771 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11772 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11773 	{
   11774 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11775 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   11776 		isc_time_settoepoch(&zone->dumptime);
   11777 		again = true;
   11778 	} else {
   11779 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   11780 	}
   11781 	UNLOCK_ZONE(zone);
   11782 	if (again) {
   11783 		goto redo;
   11784 	}
   11785 
   11786 	return (result);
   11787 }
   11788 
   11789 static isc_result_t
   11790 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
   11791 	     dns_masterformat_t format, const uint32_t rawversion) {
   11792 	isc_result_t result;
   11793 	dns_dbversion_t *version = NULL;
   11794 	dns_db_t *db = NULL;
   11795 	dns_masterrawheader_t rawdata;
   11796 
   11797 	REQUIRE(DNS_ZONE_VALID(zone));
   11798 
   11799 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11800 	if (zone->db != NULL) {
   11801 		dns_db_attach(zone->db, &db);
   11802 	}
   11803 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11804 	if (db == NULL) {
   11805 		return (DNS_R_NOTLOADED);
   11806 	}
   11807 
   11808 	dns_db_currentversion(db, &version);
   11809 	dns_master_initrawheader(&rawdata);
   11810 	if (rawversion == 0) {
   11811 		rawdata.flags |= DNS_MASTERRAW_COMPAT;
   11812 	} else if (inline_secure(zone)) {
   11813 		get_raw_serial(zone->raw, &rawdata);
   11814 	} else if (zone->sourceserialset) {
   11815 		rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
   11816 		rawdata.sourceserial = zone->sourceserial;
   11817 	}
   11818 	result = dns_master_dumptostream(zone->mctx, db, version, style, format,
   11819 					 &rawdata, fd);
   11820 	dns_db_closeversion(db, &version, false);
   11821 	dns_db_detach(&db);
   11822 	return (result);
   11823 }
   11824 
   11825 isc_result_t
   11826 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
   11827 		      const dns_master_style_t *style,
   11828 		      const uint32_t rawversion) {
   11829 	return (dumptostream(zone, fd, style, format, rawversion));
   11830 }
   11831 
   11832 void
   11833 dns_zone_unload(dns_zone_t *zone) {
   11834 	REQUIRE(DNS_ZONE_VALID(zone));
   11835 
   11836 	LOCK_ZONE(zone);
   11837 	zone_unload(zone);
   11838 	UNLOCK_ZONE(zone);
   11839 }
   11840 
   11841 static void
   11842 notify_cancel(dns_zone_t *zone) {
   11843 	dns_notify_t *notify;
   11844 
   11845 	/*
   11846 	 * 'zone' locked by caller.
   11847 	 */
   11848 
   11849 	REQUIRE(LOCKED_ZONE(zone));
   11850 
   11851 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   11852 	     notify = ISC_LIST_NEXT(notify, link))
   11853 	{
   11854 		if (notify->find != NULL) {
   11855 			dns_adb_cancelfind(notify->find);
   11856 		}
   11857 		if (notify->request != NULL) {
   11858 			dns_request_cancel(notify->request);
   11859 		}
   11860 	}
   11861 }
   11862 
   11863 static void
   11864 forward_cancel(dns_zone_t *zone) {
   11865 	dns_forward_t *forward;
   11866 
   11867 	/*
   11868 	 * 'zone' locked by caller.
   11869 	 */
   11870 
   11871 	REQUIRE(LOCKED_ZONE(zone));
   11872 
   11873 	for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL;
   11874 	     forward = ISC_LIST_NEXT(forward, link))
   11875 	{
   11876 		if (forward->request != NULL) {
   11877 			dns_request_cancel(forward->request);
   11878 		}
   11879 	}
   11880 }
   11881 
   11882 static void
   11883 zone_unload(dns_zone_t *zone) {
   11884 	/*
   11885 	 * 'zone' locked by caller.
   11886 	 */
   11887 
   11888 	REQUIRE(LOCKED_ZONE(zone));
   11889 
   11890 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   11891 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   11892 	{
   11893 		if (zone->writeio != NULL) {
   11894 			zonemgr_cancelio(zone->writeio);
   11895 		}
   11896 
   11897 		if (zone->dctx != NULL) {
   11898 			dns_dumpctx_cancel(zone->dctx);
   11899 		}
   11900 	}
   11901 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   11902 	zone_detachdb(zone);
   11903 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   11904 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
   11905 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11906 
   11907 	if (zone->type == dns_zone_mirror) {
   11908 		dns_zone_log(zone, ISC_LOG_INFO,
   11909 			     "mirror zone is no longer in use; "
   11910 			     "reverting to normal recursion");
   11911 	}
   11912 }
   11913 
   11914 void
   11915 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
   11916 	REQUIRE(DNS_ZONE_VALID(zone));
   11917 	REQUIRE(val > 0);
   11918 
   11919 	zone->minrefresh = val;
   11920 }
   11921 
   11922 void
   11923 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
   11924 	REQUIRE(DNS_ZONE_VALID(zone));
   11925 	REQUIRE(val > 0);
   11926 
   11927 	zone->maxrefresh = val;
   11928 }
   11929 
   11930 void
   11931 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
   11932 	REQUIRE(DNS_ZONE_VALID(zone));
   11933 	REQUIRE(val > 0);
   11934 
   11935 	zone->minretry = val;
   11936 }
   11937 
   11938 void
   11939 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
   11940 	REQUIRE(DNS_ZONE_VALID(zone));
   11941 	REQUIRE(val > 0);
   11942 
   11943 	zone->maxretry = val;
   11944 }
   11945 
   11946 uint32_t
   11947 dns_zone_getmaxrecords(dns_zone_t *zone) {
   11948 	REQUIRE(DNS_ZONE_VALID(zone));
   11949 
   11950 	return (zone->maxrecords);
   11951 }
   11952 
   11953 void
   11954 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
   11955 	REQUIRE(DNS_ZONE_VALID(zone));
   11956 
   11957 	zone->maxrecords = val;
   11958 }
   11959 
   11960 static bool
   11961 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
   11962 		isc_sockaddr_t *addr, dns_tsigkey_t *key) {
   11963 	dns_notify_t *notify;
   11964 	dns_zonemgr_t *zmgr;
   11965 	isc_result_t result;
   11966 
   11967 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   11968 	     notify = ISC_LIST_NEXT(notify, link))
   11969 	{
   11970 		if (notify->request != NULL) {
   11971 			continue;
   11972 		}
   11973 		if (name != NULL && dns_name_dynamic(&notify->ns) &&
   11974 		    dns_name_equal(name, &notify->ns))
   11975 		{
   11976 			goto requeue;
   11977 		}
   11978 		if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
   11979 		    notify->key == key)
   11980 		{
   11981 			goto requeue;
   11982 		}
   11983 	}
   11984 	return (false);
   11985 
   11986 requeue:
   11987 	/*
   11988 	 * If we are enqueued on the startup ratelimiter and this is
   11989 	 * not a startup notify, re-enqueue on the normal notify
   11990 	 * ratelimiter.
   11991 	 */
   11992 	if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
   11993 	    (notify->flags & DNS_NOTIFY_STARTUP) != 0)
   11994 	{
   11995 		zmgr = notify->zone->zmgr;
   11996 		result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
   11997 						 notify->event);
   11998 		if (result != ISC_R_SUCCESS) {
   11999 			return (true);
   12000 		}
   12001 
   12002 		notify->flags &= ~DNS_NOTIFY_STARTUP;
   12003 		result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
   12004 						 notify->zone->task,
   12005 						 &notify->event);
   12006 		if (result != ISC_R_SUCCESS) {
   12007 			isc_event_free(&notify->event);
   12008 			return (false);
   12009 		}
   12010 	}
   12011 
   12012 	return (true);
   12013 }
   12014 
   12015 static bool
   12016 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
   12017 	dns_tsigkey_t *key = NULL;
   12018 	isc_sockaddr_t src;
   12019 	isc_sockaddr_t any;
   12020 	bool isself;
   12021 	isc_netaddr_t dstaddr;
   12022 	isc_result_t result;
   12023 
   12024 	if (zone->view == NULL || zone->isself == NULL) {
   12025 		return (false);
   12026 	}
   12027 
   12028 	switch (isc_sockaddr_pf(dst)) {
   12029 	case PF_INET:
   12030 		src = zone->notifysrc4;
   12031 		isc_sockaddr_any(&any);
   12032 		break;
   12033 	case PF_INET6:
   12034 		src = zone->notifysrc6;
   12035 		isc_sockaddr_any6(&any);
   12036 		break;
   12037 	default:
   12038 		return (false);
   12039 	}
   12040 
   12041 	/*
   12042 	 * When sending from any the kernel will assign a source address
   12043 	 * that matches the destination address.
   12044 	 */
   12045 	if (isc_sockaddr_eqaddr(&any, &src)) {
   12046 		src = *dst;
   12047 	}
   12048 
   12049 	isc_netaddr_fromsockaddr(&dstaddr, dst);
   12050 	result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
   12051 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12052 		return (false);
   12053 	}
   12054 	isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
   12055 				zone->isselfarg);
   12056 	if (key != NULL) {
   12057 		dns_tsigkey_detach(&key);
   12058 	}
   12059 	return (isself);
   12060 }
   12061 
   12062 static void
   12063 notify_destroy(dns_notify_t *notify, bool locked) {
   12064 	isc_mem_t *mctx;
   12065 
   12066 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12067 
   12068 	if (notify->zone != NULL) {
   12069 		if (!locked) {
   12070 			LOCK_ZONE(notify->zone);
   12071 		}
   12072 		REQUIRE(LOCKED_ZONE(notify->zone));
   12073 		if (ISC_LINK_LINKED(notify, link)) {
   12074 			ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
   12075 		}
   12076 		if (!locked) {
   12077 			UNLOCK_ZONE(notify->zone);
   12078 		}
   12079 		if (locked) {
   12080 			zone_idetach(&notify->zone);
   12081 		} else {
   12082 			dns_zone_idetach(&notify->zone);
   12083 		}
   12084 	}
   12085 	if (notify->find != NULL) {
   12086 		dns_adb_destroyfind(&notify->find);
   12087 	}
   12088 	if (notify->request != NULL) {
   12089 		dns_request_destroy(&notify->request);
   12090 	}
   12091 	if (dns_name_dynamic(&notify->ns)) {
   12092 		dns_name_free(&notify->ns, notify->mctx);
   12093 	}
   12094 	if (notify->key != NULL) {
   12095 		dns_tsigkey_detach(&notify->key);
   12096 	}
   12097 	mctx = notify->mctx;
   12098 	isc_mem_put(notify->mctx, notify, sizeof(*notify));
   12099 	isc_mem_detach(&mctx);
   12100 }
   12101 
   12102 static isc_result_t
   12103 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
   12104 	dns_notify_t *notify;
   12105 
   12106 	REQUIRE(notifyp != NULL && *notifyp == NULL);
   12107 
   12108 	notify = isc_mem_get(mctx, sizeof(*notify));
   12109 
   12110 	notify->mctx = NULL;
   12111 	isc_mem_attach(mctx, &notify->mctx);
   12112 	notify->flags = flags;
   12113 	notify->zone = NULL;
   12114 	notify->find = NULL;
   12115 	notify->request = NULL;
   12116 	notify->key = NULL;
   12117 	notify->event = NULL;
   12118 	isc_sockaddr_any(&notify->dst);
   12119 	dns_name_init(&notify->ns, NULL);
   12120 	ISC_LINK_INIT(notify, link);
   12121 	notify->magic = NOTIFY_MAGIC;
   12122 	*notifyp = notify;
   12123 	return (ISC_R_SUCCESS);
   12124 }
   12125 
   12126 /*
   12127  * XXXAG should check for DNS_ZONEFLG_EXITING
   12128  */
   12129 static void
   12130 process_adb_event(isc_task_t *task, isc_event_t *ev) {
   12131 	dns_notify_t *notify;
   12132 	isc_eventtype_t result;
   12133 
   12134 	UNUSED(task);
   12135 
   12136 	notify = ev->ev_arg;
   12137 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12138 	INSIST(task == notify->zone->task);
   12139 	result = ev->ev_type;
   12140 	isc_event_free(&ev);
   12141 	if (result == DNS_EVENT_ADBMOREADDRESSES) {
   12142 		dns_adb_destroyfind(&notify->find);
   12143 		notify_find_address(notify);
   12144 		return;
   12145 	}
   12146 	if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
   12147 		LOCK_ZONE(notify->zone);
   12148 		notify_send(notify);
   12149 		UNLOCK_ZONE(notify->zone);
   12150 	}
   12151 	notify_destroy(notify, false);
   12152 }
   12153 
   12154 static void
   12155 notify_find_address(dns_notify_t *notify) {
   12156 	isc_result_t result;
   12157 	unsigned int options;
   12158 
   12159 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12160 	options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 |
   12161 		  DNS_ADBFIND_RETURNLAME;
   12162 
   12163 	if (notify->zone->view->adb == NULL) {
   12164 		goto destroy;
   12165 	}
   12166 
   12167 	result = dns_adb_createfind(
   12168 		notify->zone->view->adb, notify->zone->task, process_adb_event,
   12169 		notify, &notify->ns, dns_rootname, 0, options, 0, NULL,
   12170 		notify->zone->view->dstport, 0, NULL, &notify->find);
   12171 
   12172 	/* Something failed? */
   12173 	if (result != ISC_R_SUCCESS) {
   12174 		goto destroy;
   12175 	}
   12176 
   12177 	/* More addresses pending? */
   12178 	if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) {
   12179 		return;
   12180 	}
   12181 
   12182 	/* We have as many addresses as we can get. */
   12183 	LOCK_ZONE(notify->zone);
   12184 	notify_send(notify);
   12185 	UNLOCK_ZONE(notify->zone);
   12186 
   12187 destroy:
   12188 	notify_destroy(notify, false);
   12189 }
   12190 
   12191 static isc_result_t
   12192 notify_send_queue(dns_notify_t *notify, bool startup) {
   12193 	isc_event_t *e;
   12194 	isc_result_t result;
   12195 
   12196 	INSIST(notify->event == NULL);
   12197 	e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
   12198 			       notify_send_toaddr, notify, sizeof(isc_event_t));
   12199 	if (startup) {
   12200 		notify->event = e;
   12201 	}
   12202 	e->ev_arg = notify;
   12203 	e->ev_sender = NULL;
   12204 	result = isc_ratelimiter_enqueue(
   12205 		startup ? notify->zone->zmgr->startupnotifyrl
   12206 			: notify->zone->zmgr->notifyrl,
   12207 		notify->zone->task, &e);
   12208 	if (result != ISC_R_SUCCESS) {
   12209 		isc_event_free(&e);
   12210 		notify->event = NULL;
   12211 	}
   12212 	return (result);
   12213 }
   12214 
   12215 static void
   12216 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
   12217 	dns_notify_t *notify;
   12218 	isc_result_t result;
   12219 	dns_message_t *message = NULL;
   12220 	isc_netaddr_t dstip;
   12221 	dns_tsigkey_t *key = NULL;
   12222 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   12223 	isc_sockaddr_t src;
   12224 	unsigned int options, timeout;
   12225 	bool have_notifysource = false;
   12226 	bool have_notifydscp = false;
   12227 	isc_dscp_t dscp = -1;
   12228 
   12229 	notify = event->ev_arg;
   12230 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12231 
   12232 	UNUSED(task);
   12233 
   12234 	LOCK_ZONE(notify->zone);
   12235 
   12236 	notify->event = NULL;
   12237 
   12238 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
   12239 		result = ISC_R_CANCELED;
   12240 		goto cleanup;
   12241 	}
   12242 
   12243 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
   12244 	    DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
   12245 	    notify->zone->view->requestmgr == NULL || notify->zone->db == NULL)
   12246 	{
   12247 		result = ISC_R_CANCELED;
   12248 		goto cleanup;
   12249 	}
   12250 
   12251 	/*
   12252 	 * The raw IPv4 address should also exist.  Don't send to the
   12253 	 * mapped form.
   12254 	 */
   12255 	if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
   12256 	    IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr))
   12257 	{
   12258 		isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12259 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12260 			   "notify: ignoring IPv6 mapped IPV4 address: %s",
   12261 			   addrbuf);
   12262 		result = ISC_R_CANCELED;
   12263 		goto cleanup;
   12264 	}
   12265 
   12266 	result = notify_createmessage(notify->zone, notify->flags, &message);
   12267 	if (result != ISC_R_SUCCESS) {
   12268 		goto cleanup;
   12269 	}
   12270 
   12271 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12272 	if (notify->key != NULL) {
   12273 		/* Transfer ownership of key */
   12274 		key = notify->key;
   12275 		notify->key = NULL;
   12276 	} else {
   12277 		isc_netaddr_fromsockaddr(&dstip, &notify->dst);
   12278 		result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
   12279 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12280 			notify_log(notify->zone, ISC_LOG_ERROR,
   12281 				   "NOTIFY to %s not sent. "
   12282 				   "Peer TSIG key lookup failure.",
   12283 				   addrbuf);
   12284 			goto cleanup_message;
   12285 		}
   12286 	}
   12287 
   12288 	if (key != NULL) {
   12289 		char namebuf[DNS_NAME_FORMATSIZE];
   12290 
   12291 		dns_name_format(&key->name, namebuf, sizeof(namebuf));
   12292 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12293 			   "sending notify to %s : TSIG (%s)", addrbuf,
   12294 			   namebuf);
   12295 	} else {
   12296 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12297 			   "sending notify to %s", addrbuf);
   12298 	}
   12299 	options = 0;
   12300 	if (notify->zone->view->peers != NULL) {
   12301 		dns_peer_t *peer = NULL;
   12302 		bool usetcp = false;
   12303 		result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
   12304 						 &dstip, &peer);
   12305 		if (result == ISC_R_SUCCESS) {
   12306 			result = dns_peer_getnotifysource(peer, &src);
   12307 			if (result == ISC_R_SUCCESS) {
   12308 				have_notifysource = true;
   12309 			}
   12310 			dns_peer_getnotifydscp(peer, &dscp);
   12311 			if (dscp != -1) {
   12312 				have_notifydscp = true;
   12313 			}
   12314 			result = dns_peer_getforcetcp(peer, &usetcp);
   12315 			if (result == ISC_R_SUCCESS && usetcp) {
   12316 				options |= DNS_FETCHOPT_TCP;
   12317 			}
   12318 		}
   12319 	}
   12320 	switch (isc_sockaddr_pf(&notify->dst)) {
   12321 	case PF_INET:
   12322 		if (!have_notifysource) {
   12323 			src = notify->zone->notifysrc4;
   12324 		}
   12325 		if (!have_notifydscp) {
   12326 			dscp = notify->zone->notifysrc4dscp;
   12327 		}
   12328 		break;
   12329 	case PF_INET6:
   12330 		if (!have_notifysource) {
   12331 			src = notify->zone->notifysrc6;
   12332 		}
   12333 		if (!have_notifydscp) {
   12334 			dscp = notify->zone->notifysrc6dscp;
   12335 		}
   12336 		break;
   12337 	default:
   12338 		result = ISC_R_NOTIMPLEMENTED;
   12339 		goto cleanup_key;
   12340 	}
   12341 	timeout = 15;
   12342 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12343 		timeout = 30;
   12344 	}
   12345 	result = dns_request_createvia(
   12346 		notify->zone->view->requestmgr, message, &src, &notify->dst,
   12347 		dscp, options, key, timeout * 3, timeout, 0, notify->zone->task,
   12348 		notify_done, notify, &notify->request);
   12349 	if (result == ISC_R_SUCCESS) {
   12350 		if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
   12351 			inc_stats(notify->zone,
   12352 				  dns_zonestatscounter_notifyoutv4);
   12353 		} else {
   12354 			inc_stats(notify->zone,
   12355 				  dns_zonestatscounter_notifyoutv6);
   12356 		}
   12357 	}
   12358 
   12359 cleanup_key:
   12360 	if (key != NULL) {
   12361 		dns_tsigkey_detach(&key);
   12362 	}
   12363 cleanup_message:
   12364 	dns_message_detach(&message);
   12365 cleanup:
   12366 	UNLOCK_ZONE(notify->zone);
   12367 	isc_event_free(&event);
   12368 	if (result != ISC_R_SUCCESS) {
   12369 		notify_destroy(notify, false);
   12370 	}
   12371 }
   12372 
   12373 static void
   12374 notify_send(dns_notify_t *notify) {
   12375 	dns_adbaddrinfo_t *ai;
   12376 	isc_sockaddr_t dst;
   12377 	isc_result_t result;
   12378 	dns_notify_t *newnotify = NULL;
   12379 	unsigned int flags;
   12380 	bool startup;
   12381 
   12382 	/*
   12383 	 * Zone lock held by caller.
   12384 	 */
   12385 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12386 	REQUIRE(LOCKED_ZONE(notify->zone));
   12387 
   12388 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) {
   12389 		return;
   12390 	}
   12391 
   12392 	for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL;
   12393 	     ai = ISC_LIST_NEXT(ai, publink))
   12394 	{
   12395 		dst = ai->sockaddr;
   12396 		if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
   12397 				    NULL)) {
   12398 			continue;
   12399 		}
   12400 		if (notify_isself(notify->zone, &dst)) {
   12401 			continue;
   12402 		}
   12403 		newnotify = NULL;
   12404 		flags = notify->flags & DNS_NOTIFY_NOSOA;
   12405 		result = notify_create(notify->mctx, flags, &newnotify);
   12406 		if (result != ISC_R_SUCCESS) {
   12407 			goto cleanup;
   12408 		}
   12409 		zone_iattach(notify->zone, &newnotify->zone);
   12410 		ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link);
   12411 		newnotify->dst = dst;
   12412 		startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0);
   12413 		result = notify_send_queue(newnotify, startup);
   12414 		if (result != ISC_R_SUCCESS) {
   12415 			goto cleanup;
   12416 		}
   12417 		newnotify = NULL;
   12418 	}
   12419 
   12420 cleanup:
   12421 	if (newnotify != NULL) {
   12422 		notify_destroy(newnotify, true);
   12423 	}
   12424 }
   12425 
   12426 void
   12427 dns_zone_notify(dns_zone_t *zone) {
   12428 	isc_time_t now;
   12429 
   12430 	REQUIRE(DNS_ZONE_VALID(zone));
   12431 
   12432 	LOCK_ZONE(zone);
   12433 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12434 
   12435 	TIME_NOW(&now);
   12436 	zone_settimer(zone, &now);
   12437 	UNLOCK_ZONE(zone);
   12438 }
   12439 
   12440 static void
   12441 zone_notify(dns_zone_t *zone, isc_time_t *now) {
   12442 	dns_dbnode_t *node = NULL;
   12443 	dns_db_t *zonedb = NULL;
   12444 	dns_dbversion_t *version = NULL;
   12445 	dns_name_t *origin = NULL;
   12446 	dns_name_t master;
   12447 	dns_rdata_ns_t ns;
   12448 	dns_rdata_soa_t soa;
   12449 	uint32_t serial;
   12450 	dns_rdata_t rdata = DNS_RDATA_INIT;
   12451 	dns_rdataset_t nsrdset;
   12452 	dns_rdataset_t soardset;
   12453 	isc_result_t result;
   12454 	unsigned int i;
   12455 	isc_sockaddr_t dst;
   12456 	bool isqueued;
   12457 	dns_notifytype_t notifytype;
   12458 	unsigned int flags = 0;
   12459 	bool loggednotify = false;
   12460 	bool startup;
   12461 
   12462 	REQUIRE(DNS_ZONE_VALID(zone));
   12463 
   12464 	LOCK_ZONE(zone);
   12465 	startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12466 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12467 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   12468 	notifytype = zone->notifytype;
   12469 	DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
   12470 	UNLOCK_ZONE(zone);
   12471 
   12472 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   12473 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12474 	{
   12475 		return;
   12476 	}
   12477 
   12478 	if (notifytype == dns_notifytype_no) {
   12479 		return;
   12480 	}
   12481 
   12482 	if (notifytype == dns_notifytype_masteronly &&
   12483 	    zone->type != dns_zone_master) {
   12484 		return;
   12485 	}
   12486 
   12487 	origin = &zone->origin;
   12488 
   12489 	/*
   12490 	 * If the zone is dialup we are done as we don't want to send
   12491 	 * the current soa so as to force a refresh query.
   12492 	 */
   12493 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12494 		flags |= DNS_NOTIFY_NOSOA;
   12495 	}
   12496 
   12497 	/*
   12498 	 * Record that this was a notify due to starting up.
   12499 	 */
   12500 	if (startup) {
   12501 		flags |= DNS_NOTIFY_STARTUP;
   12502 	}
   12503 
   12504 	/*
   12505 	 * Get SOA RRset.
   12506 	 */
   12507 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12508 	if (zone->db != NULL) {
   12509 		dns_db_attach(zone->db, &zonedb);
   12510 	}
   12511 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12512 	if (zonedb == NULL) {
   12513 		return;
   12514 	}
   12515 	dns_db_currentversion(zonedb, &version);
   12516 	result = dns_db_findnode(zonedb, origin, false, &node);
   12517 	if (result != ISC_R_SUCCESS) {
   12518 		goto cleanup1;
   12519 	}
   12520 
   12521 	dns_rdataset_init(&soardset);
   12522 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   12523 				     dns_rdatatype_none, 0, &soardset, NULL);
   12524 	if (result != ISC_R_SUCCESS) {
   12525 		goto cleanup2;
   12526 	}
   12527 
   12528 	/*
   12529 	 * Find serial and master server's name.
   12530 	 */
   12531 	dns_name_init(&master, NULL);
   12532 	result = dns_rdataset_first(&soardset);
   12533 	if (result != ISC_R_SUCCESS) {
   12534 		goto cleanup3;
   12535 	}
   12536 	dns_rdataset_current(&soardset, &rdata);
   12537 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   12538 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12539 	dns_rdata_reset(&rdata);
   12540 	dns_name_dup(&soa.origin, zone->mctx, &master);
   12541 	serial = soa.serial;
   12542 	dns_rdataset_disassociate(&soardset);
   12543 
   12544 	/*
   12545 	 * Enqueue notify requests for 'also-notify' servers.
   12546 	 */
   12547 	LOCK_ZONE(zone);
   12548 	for (i = 0; i < zone->notifycnt; i++) {
   12549 		dns_tsigkey_t *key = NULL;
   12550 		dns_notify_t *notify = NULL;
   12551 
   12552 		if ((zone->notifykeynames != NULL) &&
   12553 		    (zone->notifykeynames[i] != NULL)) {
   12554 			dns_view_t *view = dns_zone_getview(zone);
   12555 			dns_name_t *keyname = zone->notifykeynames[i];
   12556 			(void)dns_view_gettsig(view, keyname, &key);
   12557 		}
   12558 
   12559 		dst = zone->notify[i];
   12560 		if (notify_isqueued(zone, flags, NULL, &dst, key)) {
   12561 			if (key != NULL) {
   12562 				dns_tsigkey_detach(&key);
   12563 			}
   12564 			continue;
   12565 		}
   12566 
   12567 		result = notify_create(zone->mctx, flags, &notify);
   12568 		if (result != ISC_R_SUCCESS) {
   12569 			if (key != NULL) {
   12570 				dns_tsigkey_detach(&key);
   12571 			}
   12572 			continue;
   12573 		}
   12574 
   12575 		zone_iattach(zone, &notify->zone);
   12576 		notify->dst = dst;
   12577 
   12578 		INSIST(notify->key == NULL);
   12579 
   12580 		if (key != NULL) {
   12581 			notify->key = key;
   12582 			key = NULL;
   12583 		}
   12584 
   12585 		ISC_LIST_APPEND(zone->notifies, notify, link);
   12586 		result = notify_send_queue(notify, startup);
   12587 		if (result != ISC_R_SUCCESS) {
   12588 			notify_destroy(notify, true);
   12589 		}
   12590 		if (!loggednotify) {
   12591 			notify_log(zone, ISC_LOG_INFO,
   12592 				   "sending notifies (serial %u)", serial);
   12593 			loggednotify = true;
   12594 		}
   12595 	}
   12596 	UNLOCK_ZONE(zone);
   12597 
   12598 	if (notifytype == dns_notifytype_explicit) {
   12599 		goto cleanup3;
   12600 	}
   12601 
   12602 	/*
   12603 	 * Process NS RRset to generate notifies.
   12604 	 */
   12605 
   12606 	dns_rdataset_init(&nsrdset);
   12607 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
   12608 				     dns_rdatatype_none, 0, &nsrdset, NULL);
   12609 	if (result != ISC_R_SUCCESS) {
   12610 		goto cleanup3;
   12611 	}
   12612 
   12613 	result = dns_rdataset_first(&nsrdset);
   12614 	while (result == ISC_R_SUCCESS) {
   12615 		dns_notify_t *notify = NULL;
   12616 
   12617 		dns_rdataset_current(&nsrdset, &rdata);
   12618 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   12619 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12620 		dns_rdata_reset(&rdata);
   12621 		/*
   12622 		 * Don't notify the master server unless explicitly
   12623 		 * configured to do so.
   12624 		 */
   12625 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
   12626 		    dns_name_compare(&master, &ns.name) == 0)
   12627 		{
   12628 			result = dns_rdataset_next(&nsrdset);
   12629 			continue;
   12630 		}
   12631 
   12632 		if (!loggednotify) {
   12633 			notify_log(zone, ISC_LOG_INFO,
   12634 				   "sending notifies (serial %u)", serial);
   12635 			loggednotify = true;
   12636 		}
   12637 
   12638 		LOCK_ZONE(zone);
   12639 		isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
   12640 		UNLOCK_ZONE(zone);
   12641 		if (isqueued) {
   12642 			result = dns_rdataset_next(&nsrdset);
   12643 			continue;
   12644 		}
   12645 		result = notify_create(zone->mctx, flags, &notify);
   12646 		if (result != ISC_R_SUCCESS) {
   12647 			continue;
   12648 		}
   12649 		dns_zone_iattach(zone, &notify->zone);
   12650 		dns_name_dup(&ns.name, zone->mctx, &notify->ns);
   12651 		LOCK_ZONE(zone);
   12652 		ISC_LIST_APPEND(zone->notifies, notify, link);
   12653 		UNLOCK_ZONE(zone);
   12654 		notify_find_address(notify);
   12655 		result = dns_rdataset_next(&nsrdset);
   12656 	}
   12657 	dns_rdataset_disassociate(&nsrdset);
   12658 
   12659 cleanup3:
   12660 	if (dns_name_dynamic(&master)) {
   12661 		dns_name_free(&master, zone->mctx);
   12662 	}
   12663 cleanup2:
   12664 	dns_db_detachnode(zonedb, &node);
   12665 cleanup1:
   12666 	dns_db_closeversion(zonedb, &version, false);
   12667 	dns_db_detach(&zonedb);
   12668 }
   12669 
   12670 /***
   12671  *** Private
   12672  ***/
   12673 static inline isc_result_t
   12674 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name,
   12675 	     dns_message_t **messagep) {
   12676 	dns_message_t *message = NULL;
   12677 	dns_name_t *qname = NULL;
   12678 	dns_rdataset_t *qrdataset = NULL;
   12679 	isc_result_t result;
   12680 
   12681 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   12682 
   12683 	message->opcode = dns_opcode_query;
   12684 	message->rdclass = zone->rdclass;
   12685 
   12686 	result = dns_message_gettempname(message, &qname);
   12687 	if (result != ISC_R_SUCCESS) {
   12688 		goto cleanup;
   12689 	}
   12690 
   12691 	result = dns_message_gettemprdataset(message, &qrdataset);
   12692 	if (result != ISC_R_SUCCESS) {
   12693 		goto cleanup;
   12694 	}
   12695 
   12696 	/*
   12697 	 * Make question.
   12698 	 */
   12699 	dns_name_init(qname, NULL);
   12700 	dns_name_clone(name, qname);
   12701 	dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
   12702 	ISC_LIST_APPEND(qname->list, qrdataset, link);
   12703 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
   12704 
   12705 	*messagep = message;
   12706 	return (ISC_R_SUCCESS);
   12707 
   12708 cleanup:
   12709 	if (qname != NULL) {
   12710 		dns_message_puttempname(message, &qname);
   12711 	}
   12712 	if (qrdataset != NULL) {
   12713 		dns_message_puttemprdataset(message, &qrdataset);
   12714 	}
   12715 	dns_message_detach(&message);
   12716 	return (result);
   12717 }
   12718 
   12719 static isc_result_t
   12720 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
   12721 	bool reqexpire) {
   12722 	isc_result_t result;
   12723 	dns_rdataset_t *rdataset = NULL;
   12724 	dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
   12725 	int count = 0;
   12726 
   12727 	/* Set EDNS options if applicable. */
   12728 	if (reqnsid) {
   12729 		INSIST(count < DNS_EDNSOPTIONS);
   12730 		ednsopts[count].code = DNS_OPT_NSID;
   12731 		ednsopts[count].length = 0;
   12732 		ednsopts[count].value = NULL;
   12733 		count++;
   12734 	}
   12735 	if (reqexpire) {
   12736 		INSIST(count < DNS_EDNSOPTIONS);
   12737 		ednsopts[count].code = DNS_OPT_EXPIRE;
   12738 		ednsopts[count].length = 0;
   12739 		ednsopts[count].value = NULL;
   12740 		count++;
   12741 	}
   12742 	result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
   12743 				      ednsopts, count);
   12744 	if (result != ISC_R_SUCCESS) {
   12745 		return (result);
   12746 	}
   12747 
   12748 	return (dns_message_setopt(message, rdataset));
   12749 }
   12750 
   12751 /*
   12752  * Called when stub zone update is finished.
   12753  * Update zone refresh, retry, expire values accordingly with
   12754  * SOA received from master, sync database to file, restart
   12755  * zone management timer.
   12756  */
   12757 static void
   12758 stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) {
   12759 	uint32_t refresh, retry, expire;
   12760 	isc_result_t result;
   12761 	isc_interval_t i;
   12762 	unsigned int soacount;
   12763 	dns_zone_t *zone = stub->zone;
   12764 
   12765 	/*
   12766 	 * Tidy up.
   12767 	 */
   12768 	dns_db_closeversion(stub->db, &stub->version, true);
   12769 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   12770 	if (zone->db == NULL) {
   12771 		zone_attachdb(zone, stub->db);
   12772 	}
   12773 	result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
   12774 				  &refresh, &retry, &expire, NULL, NULL);
   12775 	if (result == ISC_R_SUCCESS && soacount > 0U) {
   12776 		zone->refresh = RANGE(refresh, zone->minrefresh,
   12777 				      zone->maxrefresh);
   12778 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   12779 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   12780 				     DNS_MAX_EXPIRE);
   12781 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   12782 	}
   12783 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   12784 	dns_db_detach(&stub->db);
   12785 
   12786 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   12787 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   12788 	DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   12789 	isc_interval_set(&i, zone->expire, 0);
   12790 	DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
   12791 
   12792 	if (zone->masterfile != NULL) {
   12793 		zone_needdump(zone, 0);
   12794 	}
   12795 
   12796 	zone_settimer(zone, &now);
   12797 }
   12798 
   12799 /*
   12800  * Process answers for A and AAAA queries when
   12801  * resolving nameserver addresses for which glue
   12802  * was missing in a previous answer for a NS query.
   12803  */
   12804 static void
   12805 stub_glue_response_cb(isc_task_t *task, isc_event_t *event) {
   12806 	const char me[] = "stub_glue_response_cb";
   12807 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   12808 	dns_stub_t *stub = NULL;
   12809 	dns_message_t *msg = NULL;
   12810 	dns_zone_t *zone = NULL;
   12811 	char master[ISC_SOCKADDR_FORMATSIZE];
   12812 	char source[ISC_SOCKADDR_FORMATSIZE];
   12813 	uint32_t addr_count, cnamecnt;
   12814 	isc_result_t result;
   12815 	isc_time_t now;
   12816 	struct stub_glue_request *request;
   12817 	struct stub_cb_args *cb_args;
   12818 	dns_rdataset_t *addr_rdataset = NULL;
   12819 	dns_dbnode_t *node = NULL;
   12820 
   12821 	UNUSED(task);
   12822 
   12823 	request = revent->ev_arg;
   12824 	cb_args = request->args;
   12825 	stub = cb_args->stub;
   12826 	INSIST(DNS_STUB_VALID(stub));
   12827 
   12828 	zone = stub->zone;
   12829 
   12830 	ENTER;
   12831 
   12832 	TIME_NOW(&now);
   12833 
   12834 	LOCK_ZONE(zone);
   12835 
   12836 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   12837 		zone_debuglog(zone, me, 1, "exiting");
   12838 		goto cleanup;
   12839 	}
   12840 
   12841 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   12842 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   12843 
   12844 	if (revent->result != ISC_R_SUCCESS) {
   12845 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
   12846 					   &zone->sourceaddr, &now);
   12847 		dns_zone_log(zone, ISC_LOG_INFO,
   12848 			     "could not refresh stub from master %s"
   12849 			     " (source %s): %s",
   12850 			     master, source, dns_result_totext(revent->result));
   12851 		goto cleanup;
   12852 	}
   12853 
   12854 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   12855 	result = dns_request_getresponse(revent->request, msg, 0);
   12856 	if (result != ISC_R_SUCCESS) {
   12857 		dns_zone_log(zone, ISC_LOG_INFO,
   12858 			     "refreshing stub: unable to parse response (%s)",
   12859 			     isc_result_totext(result));
   12860 		goto cleanup;
   12861 	}
   12862 
   12863 	/*
   12864 	 * Unexpected rcode.
   12865 	 */
   12866 	if (msg->rcode != dns_rcode_noerror) {
   12867 		char rcode[128];
   12868 		isc_buffer_t rb;
   12869 
   12870 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   12871 		(void)dns_rcode_totext(msg->rcode, &rb);
   12872 
   12873 		dns_zone_log(zone, ISC_LOG_INFO,
   12874 			     "refreshing stub: "
   12875 			     "unexpected rcode (%.*s) from %s (source %s)",
   12876 			     (int)rb.used, rcode, master, source);
   12877 		goto cleanup;
   12878 	}
   12879 
   12880 	/*
   12881 	 * We need complete messages.
   12882 	 */
   12883 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   12884 		if (dns_request_usedtcp(revent->request)) {
   12885 			dns_zone_log(zone, ISC_LOG_INFO,
   12886 				     "refreshing stub: truncated TCP "
   12887 				     "response from master %s (source %s)",
   12888 				     master, source);
   12889 		}
   12890 		goto cleanup;
   12891 	}
   12892 
   12893 	/*
   12894 	 * If non-auth log.
   12895 	 */
   12896 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   12897 		dns_zone_log(zone, ISC_LOG_INFO,
   12898 			     "refreshing stub: "
   12899 			     "non-authoritative answer from "
   12900 			     "master %s (source %s)",
   12901 			     master, source);
   12902 		goto cleanup;
   12903 	}
   12904 
   12905 	/*
   12906 	 * Sanity checks.
   12907 	 */
   12908 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   12909 	addr_count = message_count(msg, DNS_SECTION_ANSWER,
   12910 				   request->ipv4 ? dns_rdatatype_a
   12911 						 : dns_rdatatype_aaaa);
   12912 
   12913 	if (cnamecnt != 0) {
   12914 		dns_zone_log(zone, ISC_LOG_INFO,
   12915 			     "refreshing stub: unexpected CNAME response "
   12916 			     "from master %s (source %s)",
   12917 			     master, source);
   12918 		goto cleanup;
   12919 	}
   12920 
   12921 	if (addr_count == 0) {
   12922 		dns_zone_log(zone, ISC_LOG_INFO,
   12923 			     "refreshing stub: no %s records in response "
   12924 			     "from master %s (source %s)",
   12925 			     request->ipv4 ? "A" : "AAAA", master, source);
   12926 		goto cleanup;
   12927 	}
   12928 	/*
   12929 	 * Extract A or AAAA RRset from message.
   12930 	 */
   12931 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &request->name,
   12932 				      request->ipv4 ? dns_rdatatype_a
   12933 						    : dns_rdatatype_aaaa,
   12934 				      dns_rdatatype_none, NULL, &addr_rdataset);
   12935 	if (result != ISC_R_SUCCESS) {
   12936 		if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) {
   12937 			char namebuf[DNS_NAME_FORMATSIZE];
   12938 			dns_name_format(&request->name, namebuf,
   12939 					sizeof(namebuf));
   12940 			dns_zone_log(
   12941 				zone, ISC_LOG_INFO,
   12942 				"refreshing stub: dns_message_findname(%s/%s) "
   12943 				"failed (%s)",
   12944 				namebuf, request->ipv4 ? "A" : "AAAA",
   12945 				isc_result_totext(result));
   12946 		}
   12947 		goto cleanup;
   12948 	}
   12949 
   12950 	result = dns_db_findnode(stub->db, &request->name, true, &node);
   12951 	if (result != ISC_R_SUCCESS) {
   12952 		dns_zone_log(zone, ISC_LOG_INFO,
   12953 			     "refreshing stub: "
   12954 			     "dns_db_findnode() failed: %s",
   12955 			     dns_result_totext(result));
   12956 		goto cleanup;
   12957 	}
   12958 
   12959 	result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   12960 				    addr_rdataset, 0, NULL);
   12961 	if (result != ISC_R_SUCCESS) {
   12962 		dns_zone_log(zone, ISC_LOG_INFO,
   12963 			     "refreshing stub: "
   12964 			     "dns_db_addrdataset() failed: %s",
   12965 			     dns_result_totext(result));
   12966 	}
   12967 	dns_db_detachnode(stub->db, &node);
   12968 
   12969 cleanup:
   12970 	if (msg != NULL) {
   12971 		dns_message_detach(&msg);
   12972 	}
   12973 	isc_event_free(&event);
   12974 	dns_name_free(&request->name, zone->mctx);
   12975 	dns_request_destroy(&request->request);
   12976 	isc_mem_put(zone->mctx, request, sizeof(*request));
   12977 
   12978 	/* If last request, release all related resources */
   12979 	if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) {
   12980 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   12981 		stub_finish_zone_update(stub, now);
   12982 		UNLOCK_ZONE(zone);
   12983 		stub->magic = 0;
   12984 		dns_zone_idetach(&stub->zone);
   12985 		INSIST(stub->db == NULL);
   12986 		INSIST(stub->version == NULL);
   12987 		isc_mem_put(stub->mctx, stub, sizeof(*stub));
   12988 	} else {
   12989 		UNLOCK_ZONE(zone);
   12990 	}
   12991 }
   12992 
   12993 /*
   12994  * Create and send an A or AAAA query to the master
   12995  * server of the stub zone given.
   12996  */
   12997 static isc_result_t
   12998 stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4,
   12999 				const dns_name_t *name) {
   13000 	dns_message_t *message = NULL;
   13001 	dns_zone_t *zone;
   13002 	isc_result_t result;
   13003 	struct stub_glue_request *request;
   13004 
   13005 	zone = args->stub->zone;
   13006 	request = isc_mem_get(zone->mctx, sizeof(*request));
   13007 	request->request = NULL;
   13008 	request->args = args;
   13009 	request->name = (dns_name_t)DNS_NAME_INITEMPTY;
   13010 	request->ipv4 = ipv4;
   13011 	dns_name_dup(name, zone->mctx, &request->name);
   13012 
   13013 	result = create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa,
   13014 			      &request->name, &message);
   13015 	INSIST(result == ISC_R_SUCCESS);
   13016 
   13017 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   13018 		result = add_opt(message, args->udpsize, args->reqnsid, false);
   13019 		if (result != ISC_R_SUCCESS) {
   13020 			zone_debuglog(zone, "stub_send_query", 1,
   13021 				      "unable to add opt record: %s",
   13022 				      dns_result_totext(result));
   13023 			goto fail;
   13024 		}
   13025 	}
   13026 
   13027 	atomic_fetch_add_release(&args->stub->pending_requests, 1);
   13028 
   13029 	result = dns_request_createvia(
   13030 		zone->view->requestmgr, message, &zone->sourceaddr,
   13031 		&zone->masteraddr, args->dscp, DNS_REQUESTOPT_TCP,
   13032 		args->tsig_key, args->timeout * 3, args->timeout, 0, zone->task,
   13033 		stub_glue_response_cb, request, &request->request);
   13034 
   13035 	if (result != ISC_R_SUCCESS) {
   13036 		INSIST(atomic_fetch_sub_release(&args->stub->pending_requests,
   13037 						1) > 1);
   13038 		zone_debuglog(zone, "stub_send_query", 1,
   13039 			      "dns_request_createvia() failed: %s",
   13040 			      dns_result_totext(result));
   13041 		goto fail;
   13042 	}
   13043 
   13044 	dns_message_detach(&message);
   13045 
   13046 	return (ISC_R_SUCCESS);
   13047 
   13048 fail:
   13049 	dns_name_free(&request->name, zone->mctx);
   13050 	isc_mem_put(zone->mctx, request, sizeof(*request));
   13051 
   13052 	if (message != NULL) {
   13053 		dns_message_detach(&message);
   13054 	}
   13055 
   13056 	return (result);
   13057 }
   13058 
   13059 static inline isc_result_t
   13060 save_nsrrset(dns_message_t *message, dns_name_t *name,
   13061 	     struct stub_cb_args *cb_args, dns_db_t *db,
   13062 	     dns_dbversion_t *version) {
   13063 	dns_rdataset_t *nsrdataset = NULL;
   13064 	dns_rdataset_t *rdataset = NULL;
   13065 	dns_dbnode_t *node = NULL;
   13066 	dns_rdata_ns_t ns;
   13067 	isc_result_t result;
   13068 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13069 	bool has_glue = false;
   13070 	dns_name_t *ns_name;
   13071 	/*
   13072 	 * List of NS entries in answer, keep names that will be used
   13073 	 * to resolve missing A/AAAA glue for each entry.
   13074 	 */
   13075 	dns_namelist_t ns_list;
   13076 	ISC_LIST_INIT(ns_list);
   13077 
   13078 	/*
   13079 	 * Extract NS RRset from message.
   13080 	 */
   13081 	result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
   13082 				      dns_rdatatype_ns, dns_rdatatype_none,
   13083 				      NULL, &nsrdataset);
   13084 	if (result != ISC_R_SUCCESS) {
   13085 		goto done;
   13086 	}
   13087 
   13088 	/*
   13089 	 * Add NS rdataset.
   13090 	 */
   13091 	result = dns_db_findnode(db, name, true, &node);
   13092 	if (result != ISC_R_SUCCESS) {
   13093 		goto done;
   13094 	}
   13095 	result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL);
   13096 	dns_db_detachnode(db, &node);
   13097 	if (result != ISC_R_SUCCESS) {
   13098 		goto done;
   13099 	}
   13100 	/*
   13101 	 * Add glue rdatasets.
   13102 	 */
   13103 	for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS;
   13104 	     result = dns_rdataset_next(nsrdataset))
   13105 	{
   13106 		dns_rdataset_current(nsrdataset, &rdata);
   13107 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   13108 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13109 		dns_rdata_reset(&rdata);
   13110 
   13111 		if (!dns_name_issubdomain(&ns.name, name)) {
   13112 			continue;
   13113 		}
   13114 		rdataset = NULL;
   13115 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
   13116 					      &ns.name, dns_rdatatype_aaaa,
   13117 					      dns_rdatatype_none, NULL,
   13118 					      &rdataset);
   13119 		if (result == ISC_R_SUCCESS) {
   13120 			has_glue = true;
   13121 			result = dns_db_findnode(db, &ns.name, true, &node);
   13122 			if (result != ISC_R_SUCCESS) {
   13123 				goto done;
   13124 			}
   13125 			result = dns_db_addrdataset(db, node, version, 0,
   13126 						    rdataset, 0, NULL);
   13127 			dns_db_detachnode(db, &node);
   13128 			if (result != ISC_R_SUCCESS) {
   13129 				goto done;
   13130 			}
   13131 		}
   13132 
   13133 		rdataset = NULL;
   13134 		result = dns_message_findname(
   13135 			message, DNS_SECTION_ADDITIONAL, &ns.name,
   13136 			dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset);
   13137 		if (result == ISC_R_SUCCESS) {
   13138 			has_glue = true;
   13139 			result = dns_db_findnode(db, &ns.name, true, &node);
   13140 			if (result != ISC_R_SUCCESS) {
   13141 				goto done;
   13142 			}
   13143 			result = dns_db_addrdataset(db, node, version, 0,
   13144 						    rdataset, 0, NULL);
   13145 			dns_db_detachnode(db, &node);
   13146 			if (result != ISC_R_SUCCESS) {
   13147 				goto done;
   13148 			}
   13149 		}
   13150 
   13151 		/*
   13152 		 * If no glue is found so far, we add the name to the list to
   13153 		 * resolve the A/AAAA glue later. If any glue is found in any
   13154 		 * iteration step, this list will be discarded and only the glue
   13155 		 * provided in this message will be used.
   13156 		 */
   13157 		if (!has_glue && dns_name_issubdomain(&ns.name, name)) {
   13158 			dns_name_t *tmp_name;
   13159 			tmp_name = isc_mem_get(cb_args->stub->mctx,
   13160 					       sizeof(*tmp_name));
   13161 			dns_name_init(tmp_name, NULL);
   13162 			dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name);
   13163 			ISC_LIST_APPEND(ns_list, tmp_name, link);
   13164 		}
   13165 	}
   13166 
   13167 	if (result != ISC_R_NOMORE) {
   13168 		goto done;
   13169 	}
   13170 
   13171 	/*
   13172 	 * If no glue records were found, we attempt to resolve A/AAAA
   13173 	 * for each NS entry found in the answer.
   13174 	 */
   13175 	if (!has_glue) {
   13176 		for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL;
   13177 		     ns_name = ISC_LIST_NEXT(ns_name, link))
   13178 		{
   13179 			/*
   13180 			 * Resolve NS IPv4 address/A.
   13181 			 */
   13182 			result = stub_request_nameserver_address(cb_args, true,
   13183 								 ns_name);
   13184 			if (result != ISC_R_SUCCESS) {
   13185 				goto done;
   13186 			}
   13187 			/*
   13188 			 * Resolve NS IPv6 address/AAAA.
   13189 			 */
   13190 			result = stub_request_nameserver_address(cb_args, false,
   13191 								 ns_name);
   13192 			if (result != ISC_R_SUCCESS) {
   13193 				goto done;
   13194 			}
   13195 		}
   13196 	}
   13197 
   13198 	result = ISC_R_SUCCESS;
   13199 
   13200 done:
   13201 	while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) {
   13202 		ISC_LIST_UNLINK(ns_list, ns_name, link);
   13203 		dns_name_free(ns_name, cb_args->stub->mctx);
   13204 		isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name));
   13205 	}
   13206 	return (result);
   13207 }
   13208 
   13209 static void
   13210 stub_callback(isc_task_t *task, isc_event_t *event) {
   13211 	const char me[] = "stub_callback";
   13212 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13213 	dns_stub_t *stub = NULL;
   13214 	dns_message_t *msg = NULL;
   13215 	dns_zone_t *zone = NULL;
   13216 	char master[ISC_SOCKADDR_FORMATSIZE];
   13217 	char source[ISC_SOCKADDR_FORMATSIZE];
   13218 	uint32_t nscnt, cnamecnt;
   13219 	isc_result_t result;
   13220 	isc_time_t now;
   13221 	bool exiting = false;
   13222 	unsigned int j;
   13223 	struct stub_cb_args *cb_args;
   13224 
   13225 	cb_args = revent->ev_arg;
   13226 	stub = cb_args->stub;
   13227 	INSIST(DNS_STUB_VALID(stub));
   13228 
   13229 	UNUSED(task);
   13230 
   13231 	zone = stub->zone;
   13232 
   13233 	ENTER;
   13234 
   13235 	TIME_NOW(&now);
   13236 
   13237 	LOCK_ZONE(zone);
   13238 
   13239 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13240 		zone_debuglog(zone, me, 1, "exiting");
   13241 		exiting = true;
   13242 		goto next_master;
   13243 	}
   13244 
   13245 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   13246 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13247 
   13248 	if (revent->result != ISC_R_SUCCESS) {
   13249 		if (revent->result == ISC_R_TIMEDOUT &&
   13250 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS))
   13251 		{
   13252 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13253 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13254 				     "refreshing stub: timeout retrying "
   13255 				     " without EDNS master %s (source %s)",
   13256 				     master, source);
   13257 			goto same_master;
   13258 		}
   13259 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
   13260 					   &zone->sourceaddr, &now);
   13261 		dns_zone_log(zone, ISC_LOG_INFO,
   13262 			     "could not refresh stub from master %s"
   13263 			     " (source %s): %s",
   13264 			     master, source, dns_result_totext(revent->result));
   13265 		goto next_master;
   13266 	}
   13267 
   13268 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13269 
   13270 	result = dns_request_getresponse(revent->request, msg, 0);
   13271 	if (result != ISC_R_SUCCESS) {
   13272 		goto next_master;
   13273 	}
   13274 
   13275 	/*
   13276 	 * Unexpected rcode.
   13277 	 */
   13278 	if (msg->rcode != dns_rcode_noerror) {
   13279 		char rcode[128];
   13280 		isc_buffer_t rb;
   13281 
   13282 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13283 		(void)dns_rcode_totext(msg->rcode, &rb);
   13284 
   13285 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13286 		    (msg->rcode == dns_rcode_servfail ||
   13287 		     msg->rcode == dns_rcode_notimp ||
   13288 		     msg->rcode == dns_rcode_formerr))
   13289 		{
   13290 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13291 				     "refreshing stub: rcode (%.*s) retrying "
   13292 				     "without EDNS master %s (source %s)",
   13293 				     (int)rb.used, rcode, master, source);
   13294 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13295 			goto same_master;
   13296 		}
   13297 
   13298 		dns_zone_log(zone, ISC_LOG_INFO,
   13299 			     "refreshing stub: "
   13300 			     "unexpected rcode (%.*s) from %s (source %s)",
   13301 			     (int)rb.used, rcode, master, source);
   13302 		goto next_master;
   13303 	}
   13304 
   13305 	/*
   13306 	 * We need complete messages.
   13307 	 */
   13308 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13309 		if (dns_request_usedtcp(revent->request)) {
   13310 			dns_zone_log(zone, ISC_LOG_INFO,
   13311 				     "refreshing stub: truncated TCP "
   13312 				     "response from master %s (source %s)",
   13313 				     master, source);
   13314 			goto next_master;
   13315 		}
   13316 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   13317 		goto same_master;
   13318 	}
   13319 
   13320 	/*
   13321 	 * If non-auth log and next master.
   13322 	 */
   13323 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13324 		dns_zone_log(zone, ISC_LOG_INFO,
   13325 			     "refreshing stub: "
   13326 			     "non-authoritative answer from "
   13327 			     "master %s (source %s)",
   13328 			     master, source);
   13329 		goto next_master;
   13330 	}
   13331 
   13332 	/*
   13333 	 * Sanity checks.
   13334 	 */
   13335 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13336 	nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
   13337 
   13338 	if (cnamecnt != 0) {
   13339 		dns_zone_log(zone, ISC_LOG_INFO,
   13340 			     "refreshing stub: unexpected CNAME response "
   13341 			     "from master %s (source %s)",
   13342 			     master, source);
   13343 		goto next_master;
   13344 	}
   13345 
   13346 	if (nscnt == 0) {
   13347 		dns_zone_log(zone, ISC_LOG_INFO,
   13348 			     "refreshing stub: no NS records in response "
   13349 			     "from master %s (source %s)",
   13350 			     master, source);
   13351 		goto next_master;
   13352 	}
   13353 
   13354 	atomic_fetch_add(&stub->pending_requests, 1);
   13355 
   13356 	/*
   13357 	 * Save answer.
   13358 	 */
   13359 	result = save_nsrrset(msg, &zone->origin, cb_args, stub->db,
   13360 			      stub->version);
   13361 	if (result != ISC_R_SUCCESS) {
   13362 		dns_zone_log(zone, ISC_LOG_INFO,
   13363 			     "refreshing stub: unable to save NS records "
   13364 			     "from master %s (source %s)",
   13365 			     master, source);
   13366 		goto next_master;
   13367 	}
   13368 
   13369 	dns_message_detach(&msg);
   13370 	isc_event_free(&event);
   13371 	dns_request_destroy(&zone->request);
   13372 
   13373 	/*
   13374 	 * Check to see if there are no outstanding requests and
   13375 	 * finish off if that is so.
   13376 	 */
   13377 	if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) {
   13378 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13379 		stub_finish_zone_update(stub, now);
   13380 		goto free_stub;
   13381 	}
   13382 
   13383 	UNLOCK_ZONE(zone);
   13384 	return;
   13385 
   13386 next_master:
   13387 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13388 	if (stub->version != NULL) {
   13389 		dns_db_closeversion(stub->db, &stub->version, false);
   13390 	}
   13391 	if (stub->db != NULL) {
   13392 		dns_db_detach(&stub->db);
   13393 	}
   13394 	if (msg != NULL) {
   13395 		dns_message_detach(&msg);
   13396 	}
   13397 	isc_event_free(&event);
   13398 	dns_request_destroy(&zone->request);
   13399 	/*
   13400 	 * Skip to next failed / untried master.
   13401 	 */
   13402 	do {
   13403 		zone->curmaster++;
   13404 	} while (zone->curmaster < zone->masterscnt &&
   13405 		 zone->mastersok[zone->curmaster]);
   13406 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13407 	if (exiting || zone->curmaster >= zone->masterscnt) {
   13408 		bool done = true;
   13409 		if (!exiting &&
   13410 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   13411 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   13412 		{
   13413 			/*
   13414 			 * Did we get a good answer from all the primaries?
   13415 			 */
   13416 			for (j = 0; j < zone->masterscnt; j++) {
   13417 				if (!zone->mastersok[j]) {
   13418 					{
   13419 						done = false;
   13420 						break;
   13421 					}
   13422 				}
   13423 			}
   13424 		} else {
   13425 			done = true;
   13426 		}
   13427 		if (!done) {
   13428 			zone->curmaster = 0;
   13429 			/*
   13430 			 * Find the next failed master.
   13431 			 */
   13432 			while (zone->curmaster < zone->masterscnt &&
   13433 			       zone->mastersok[zone->curmaster]) {
   13434 				zone->curmaster++;
   13435 			}
   13436 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13437 		} else {
   13438 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13439 
   13440 			zone_settimer(zone, &now);
   13441 			goto free_stub;
   13442 		}
   13443 	}
   13444 	queue_soa_query(zone);
   13445 	goto free_stub;
   13446 
   13447 same_master:
   13448 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13449 	if (msg != NULL) {
   13450 		dns_message_detach(&msg);
   13451 	}
   13452 	isc_event_free(&event);
   13453 	dns_request_destroy(&zone->request);
   13454 	ns_query(zone, NULL, stub);
   13455 	UNLOCK_ZONE(zone);
   13456 	goto done;
   13457 
   13458 free_stub:
   13459 	UNLOCK_ZONE(zone);
   13460 	stub->magic = 0;
   13461 	dns_zone_idetach(&stub->zone);
   13462 	INSIST(stub->db == NULL);
   13463 	INSIST(stub->version == NULL);
   13464 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   13465 
   13466 done:
   13467 	INSIST(event == NULL);
   13468 	return;
   13469 }
   13470 
   13471 /*
   13472  * Get the EDNS EXPIRE option from the response and if it exists trim
   13473  * expire to be not more than it.
   13474  */
   13475 static void
   13476 get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) {
   13477 	isc_result_t result;
   13478 	uint32_t expire;
   13479 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13480 	isc_buffer_t optbuf;
   13481 	uint16_t optcode;
   13482 	uint16_t optlen;
   13483 
   13484 	REQUIRE(expirep != NULL);
   13485 	REQUIRE(message != NULL);
   13486 
   13487 	if (message->opt == NULL) {
   13488 		return;
   13489 	}
   13490 
   13491 	result = dns_rdataset_first(message->opt);
   13492 	if (result == ISC_R_SUCCESS) {
   13493 		dns_rdataset_current(message->opt, &rdata);
   13494 		isc_buffer_init(&optbuf, rdata.data, rdata.length);
   13495 		isc_buffer_add(&optbuf, rdata.length);
   13496 		while (isc_buffer_remaininglength(&optbuf) >= 4) {
   13497 			optcode = isc_buffer_getuint16(&optbuf);
   13498 			optlen = isc_buffer_getuint16(&optbuf);
   13499 			/*
   13500 			 * A EDNS EXPIRE response has a length of 4.
   13501 			 */
   13502 			if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
   13503 				isc_buffer_forward(&optbuf, optlen);
   13504 				continue;
   13505 			}
   13506 			expire = isc_buffer_getuint32(&optbuf);
   13507 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13508 				     "got EDNS EXPIRE of %u", expire);
   13509 			/*
   13510 			 * Trim *expirep?
   13511 			 */
   13512 			if (expire < *expirep) {
   13513 				*expirep = expire;
   13514 			}
   13515 			break;
   13516 		}
   13517 	}
   13518 }
   13519 
   13520 /*
   13521  * Set the file modification time zone->expire seconds before expiretime.
   13522  */
   13523 static void
   13524 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
   13525 	isc_result_t result;
   13526 	isc_time_t when;
   13527 	isc_interval_t i;
   13528 
   13529 	isc_interval_set(&i, zone->expire, 0);
   13530 	result = isc_time_subtract(expiretime, &i, &when);
   13531 	if (result != ISC_R_SUCCESS) {
   13532 		return;
   13533 	}
   13534 
   13535 	result = ISC_R_FAILURE;
   13536 	if (zone->journal != NULL) {
   13537 		result = isc_file_settime(zone->journal, &when);
   13538 	}
   13539 	if (result == ISC_R_SUCCESS &&
   13540 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   13541 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
   13542 	{
   13543 		result = isc_file_settime(zone->masterfile, &when);
   13544 	} else if (result != ISC_R_SUCCESS) {
   13545 		result = isc_file_settime(zone->masterfile, &when);
   13546 	}
   13547 
   13548 	/*
   13549 	 * Someone removed the file from underneath us!
   13550 	 */
   13551 	if (result == ISC_R_FILENOTFOUND) {
   13552 		zone_needdump(zone, DNS_DUMP_DELAY);
   13553 	} else if (result != ISC_R_SUCCESS) {
   13554 		dns_zone_log(zone, ISC_LOG_ERROR,
   13555 			     "refresh: could not set "
   13556 			     "file modification time of '%s': %s",
   13557 			     zone->masterfile, dns_result_totext(result));
   13558 	}
   13559 }
   13560 
   13561 /*
   13562  * An SOA query has finished (successfully or not).
   13563  */
   13564 static void
   13565 refresh_callback(isc_task_t *task, isc_event_t *event) {
   13566 	const char me[] = "refresh_callback";
   13567 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13568 	dns_zone_t *zone;
   13569 	dns_message_t *msg = NULL;
   13570 	uint32_t soacnt, cnamecnt, soacount, nscount;
   13571 	isc_time_t now;
   13572 	char master[ISC_SOCKADDR_FORMATSIZE];
   13573 	char source[ISC_SOCKADDR_FORMATSIZE];
   13574 	dns_rdataset_t *rdataset = NULL;
   13575 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13576 	dns_rdata_soa_t soa;
   13577 	isc_result_t result;
   13578 	uint32_t serial, oldserial = 0;
   13579 	unsigned int j;
   13580 	bool do_queue_xfrin = false;
   13581 
   13582 	zone = revent->ev_arg;
   13583 	INSIST(DNS_ZONE_VALID(zone));
   13584 
   13585 	UNUSED(task);
   13586 
   13587 	ENTER;
   13588 
   13589 	TIME_NOW(&now);
   13590 
   13591 	LOCK_ZONE(zone);
   13592 
   13593 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13594 		isc_event_free(&event);
   13595 		dns_request_destroy(&zone->request);
   13596 		goto detach;
   13597 	}
   13598 
   13599 	/*
   13600 	 * if timeout log and next master;
   13601 	 */
   13602 
   13603 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   13604 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13605 
   13606 	if (revent->result != ISC_R_SUCCESS) {
   13607 		if (revent->result == ISC_R_TIMEDOUT &&
   13608 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS))
   13609 		{
   13610 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13611 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13612 				     "refresh: timeout retrying without EDNS "
   13613 				     "master %s (source %s)",
   13614 				     master, source);
   13615 			goto same_master;
   13616 		}
   13617 		if (revent->result == ISC_R_TIMEDOUT &&
   13618 		    !dns_request_usedtcp(revent->request)) {
   13619 			dns_zone_log(zone, ISC_LOG_INFO,
   13620 				     "refresh: retry limit for "
   13621 				     "master %s exceeded (source %s)",
   13622 				     master, source);
   13623 			/* Try with slave with TCP. */
   13624 			if ((zone->type == dns_zone_slave ||
   13625 			     zone->type == dns_zone_mirror ||
   13626 			     zone->type == dns_zone_redirect) &&
   13627 			    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
   13628 			{
   13629 				if (!dns_zonemgr_unreachable(
   13630 					    zone->zmgr, &zone->masteraddr,
   13631 					    &zone->sourceaddr, &now))
   13632 				{
   13633 					DNS_ZONE_SETFLAG(
   13634 						zone,
   13635 						DNS_ZONEFLG_SOABEFOREAXFR);
   13636 					goto tcp_transfer;
   13637 				}
   13638 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13639 					     "refresh: skipped tcp fallback "
   13640 					     "as master %s (source %s) is "
   13641 					     "unreachable (cached)",
   13642 					     master, source);
   13643 			}
   13644 		} else {
   13645 			dns_zone_log(zone, ISC_LOG_INFO,
   13646 				     "refresh: failure trying master "
   13647 				     "%s (source %s): %s",
   13648 				     master, source,
   13649 				     dns_result_totext(revent->result));
   13650 		}
   13651 		goto next_master;
   13652 	}
   13653 
   13654 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13655 	result = dns_request_getresponse(revent->request, msg, 0);
   13656 	if (result != ISC_R_SUCCESS) {
   13657 		dns_zone_log(zone, ISC_LOG_INFO,
   13658 			     "refresh: failure trying master "
   13659 			     "%s (source %s): %s",
   13660 			     master, source, dns_result_totext(result));
   13661 		goto next_master;
   13662 	}
   13663 
   13664 	/*
   13665 	 * Unexpected rcode.
   13666 	 */
   13667 	if (msg->rcode != dns_rcode_noerror) {
   13668 		char rcode[128];
   13669 		isc_buffer_t rb;
   13670 
   13671 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13672 		(void)dns_rcode_totext(msg->rcode, &rb);
   13673 
   13674 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13675 		    (msg->rcode == dns_rcode_servfail ||
   13676 		     msg->rcode == dns_rcode_notimp ||
   13677 		     msg->rcode == dns_rcode_formerr))
   13678 		{
   13679 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13680 				     "refresh: rcode (%.*s) retrying without "
   13681 				     "EDNS master %s (source %s)",
   13682 				     (int)rb.used, rcode, master, source);
   13683 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13684 			goto same_master;
   13685 		}
   13686 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13687 		    msg->rcode == dns_rcode_badvers) {
   13688 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13689 				     "refresh: rcode (%.*s) retrying without "
   13690 				     "EDNS EXPIRE OPTION master %s (source %s)",
   13691 				     (int)rb.used, rcode, master, source);
   13692 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13693 			goto same_master;
   13694 		}
   13695 		dns_zone_log(zone, ISC_LOG_INFO,
   13696 			     "refresh: unexpected rcode (%.*s) from "
   13697 			     "master %s (source %s)",
   13698 			     (int)rb.used, rcode, master, source);
   13699 		/*
   13700 		 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
   13701 		 */
   13702 		if (msg->rcode == dns_rcode_refused &&
   13703 		    (zone->type == dns_zone_slave ||
   13704 		     zone->type == dns_zone_mirror ||
   13705 		     zone->type == dns_zone_redirect))
   13706 		{
   13707 			goto tcp_transfer;
   13708 		}
   13709 		goto next_master;
   13710 	}
   13711 
   13712 	/*
   13713 	 * If truncated punt to zone transfer which will query again.
   13714 	 */
   13715 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13716 		if (zone->type == dns_zone_slave ||
   13717 		    zone->type == dns_zone_mirror ||
   13718 		    zone->type == dns_zone_redirect)
   13719 		{
   13720 			dns_zone_log(zone, ISC_LOG_INFO,
   13721 				     "refresh: truncated UDP answer, "
   13722 				     "initiating TCP zone xfer "
   13723 				     "for master %s (source %s)",
   13724 				     master, source);
   13725 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   13726 			goto tcp_transfer;
   13727 		} else {
   13728 			INSIST(zone->type == dns_zone_stub);
   13729 			if (dns_request_usedtcp(revent->request)) {
   13730 				dns_zone_log(zone, ISC_LOG_INFO,
   13731 					     "refresh: truncated TCP response "
   13732 					     "from master %s (source %s)",
   13733 					     master, source);
   13734 				goto next_master;
   13735 			}
   13736 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   13737 			goto same_master;
   13738 		}
   13739 	}
   13740 
   13741 	/*
   13742 	 * if non-auth log and next master;
   13743 	 */
   13744 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13745 		dns_zone_log(zone, ISC_LOG_INFO,
   13746 			     "refresh: non-authoritative answer from "
   13747 			     "master %s (source %s)",
   13748 			     master, source);
   13749 		goto next_master;
   13750 	}
   13751 
   13752 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13753 	soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
   13754 	nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
   13755 	soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa);
   13756 
   13757 	/*
   13758 	 * There should not be a CNAME record at top of zone.
   13759 	 */
   13760 	if (cnamecnt != 0) {
   13761 		dns_zone_log(zone, ISC_LOG_INFO,
   13762 			     "refresh: CNAME at top of zone "
   13763 			     "in master %s (source %s)",
   13764 			     master, source);
   13765 		goto next_master;
   13766 	}
   13767 
   13768 	/*
   13769 	 * if referral log and next master;
   13770 	 */
   13771 	if (soacnt == 0 && soacount == 0 && nscount != 0) {
   13772 		dns_zone_log(zone, ISC_LOG_INFO,
   13773 			     "refresh: referral response "
   13774 			     "from master %s (source %s)",
   13775 			     master, source);
   13776 		goto next_master;
   13777 	}
   13778 
   13779 	/*
   13780 	 * if nodata log and next master;
   13781 	 */
   13782 	if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
   13783 		dns_zone_log(zone, ISC_LOG_INFO,
   13784 			     "refresh: NODATA response "
   13785 			     "from master %s (source %s)",
   13786 			     master, source);
   13787 		goto next_master;
   13788 	}
   13789 
   13790 	/*
   13791 	 * Only one soa at top of zone.
   13792 	 */
   13793 	if (soacnt != 1) {
   13794 		dns_zone_log(zone, ISC_LOG_INFO,
   13795 			     "refresh: answer SOA count (%d) != 1 "
   13796 			     "from master %s (source %s)",
   13797 			     soacnt, master, source);
   13798 		goto next_master;
   13799 	}
   13800 
   13801 	/*
   13802 	 * Extract serial
   13803 	 */
   13804 	rdataset = NULL;
   13805 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
   13806 				      dns_rdatatype_soa, dns_rdatatype_none,
   13807 				      NULL, &rdataset);
   13808 	if (result != ISC_R_SUCCESS) {
   13809 		dns_zone_log(zone, ISC_LOG_INFO,
   13810 			     "refresh: unable to get SOA record "
   13811 			     "from master %s (source %s)",
   13812 			     master, source);
   13813 		goto next_master;
   13814 	}
   13815 
   13816 	result = dns_rdataset_first(rdataset);
   13817 	if (result != ISC_R_SUCCESS) {
   13818 		dns_zone_log(zone, ISC_LOG_INFO,
   13819 			     "refresh: dns_rdataset_first() failed");
   13820 		goto next_master;
   13821 	}
   13822 
   13823 	dns_rdataset_current(rdataset, &rdata);
   13824 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   13825 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13826 
   13827 	serial = soa.serial;
   13828 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   13829 		unsigned int dbsoacount;
   13830 		result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
   13831 					  &oldserial, NULL, NULL, NULL, NULL,
   13832 					  NULL);
   13833 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13834 		RUNTIME_CHECK(dbsoacount > 0U);
   13835 		zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial,
   13836 			      oldserial);
   13837 	} else {
   13838 		zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
   13839 			      serial);
   13840 	}
   13841 
   13842 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
   13843 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
   13844 	    isc_serial_gt(serial, oldserial))
   13845 	{
   13846 		if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   13847 					    &zone->sourceaddr, &now))
   13848 		{
   13849 			dns_zone_log(zone, ISC_LOG_INFO,
   13850 				     "refresh: skipping %s as master %s "
   13851 				     "(source %s) is unreachable (cached)",
   13852 				     (zone->type == dns_zone_slave ||
   13853 				      zone->type == dns_zone_mirror ||
   13854 				      zone->type == dns_zone_redirect)
   13855 					     ? "zone transfer"
   13856 					     : "NS query",
   13857 				     master, source);
   13858 			goto next_master;
   13859 		}
   13860 	tcp_transfer:
   13861 		isc_event_free(&event);
   13862 		dns_request_destroy(&zone->request);
   13863 		if (zone->type == dns_zone_slave ||
   13864 		    zone->type == dns_zone_mirror ||
   13865 		    zone->type == dns_zone_redirect)
   13866 		{
   13867 			do_queue_xfrin = true;
   13868 		} else {
   13869 			INSIST(zone->type == dns_zone_stub);
   13870 			ns_query(zone, rdataset, NULL);
   13871 		}
   13872 		if (msg != NULL) {
   13873 			dns_message_detach(&msg);
   13874 		}
   13875 	} else if (isc_serial_eq(soa.serial, oldserial)) {
   13876 		isc_time_t expiretime;
   13877 		uint32_t expire;
   13878 
   13879 		/*
   13880 		 * Compute the new expire time based on this response.
   13881 		 */
   13882 		expire = zone->expire;
   13883 		get_edns_expire(zone, msg, &expire);
   13884 		DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
   13885 
   13886 		/*
   13887 		 * Has the expire time improved?
   13888 		 */
   13889 		if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
   13890 			zone->expiretime = expiretime;
   13891 			if (zone->masterfile != NULL) {
   13892 				setmodtime(zone, &expiretime);
   13893 			}
   13894 		}
   13895 
   13896 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   13897 		zone->mastersok[zone->curmaster] = true;
   13898 		goto next_master;
   13899 	} else {
   13900 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) {
   13901 			dns_zone_log(zone, ISC_LOG_INFO,
   13902 				     "serial number (%u) "
   13903 				     "received from master %s < ours (%u)",
   13904 				     soa.serial, master, oldserial);
   13905 		} else {
   13906 			zone_debuglog(zone, me, 1, "ahead");
   13907 		}
   13908 		zone->mastersok[zone->curmaster] = true;
   13909 		goto next_master;
   13910 	}
   13911 	if (msg != NULL) {
   13912 		dns_message_detach(&msg);
   13913 	}
   13914 	goto detach;
   13915 
   13916 next_master:
   13917 	if (msg != NULL) {
   13918 		dns_message_detach(&msg);
   13919 	}
   13920 	isc_event_free(&event);
   13921 	dns_request_destroy(&zone->request);
   13922 	/*
   13923 	 * Skip to next failed / untried master.
   13924 	 */
   13925 	do {
   13926 		zone->curmaster++;
   13927 	} while (zone->curmaster < zone->masterscnt &&
   13928 		 zone->mastersok[zone->curmaster]);
   13929 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13930 	if (zone->curmaster >= zone->masterscnt) {
   13931 		bool done = true;
   13932 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   13933 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   13934 		{
   13935 			/*
   13936 			 * Did we get a good answer from all the primaries?
   13937 			 */
   13938 			for (j = 0; j < zone->masterscnt; j++) {
   13939 				if (!zone->mastersok[j]) {
   13940 					{
   13941 						done = false;
   13942 						break;
   13943 					}
   13944 				}
   13945 			}
   13946 		} else {
   13947 			done = true;
   13948 		}
   13949 		if (!done) {
   13950 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13951 			zone->curmaster = 0;
   13952 			/*
   13953 			 * Find the next failed master.
   13954 			 */
   13955 			while (zone->curmaster < zone->masterscnt &&
   13956 			       zone->mastersok[zone->curmaster]) {
   13957 				zone->curmaster++;
   13958 			}
   13959 			goto requeue;
   13960 		}
   13961 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13962 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   13963 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   13964 			zone->refreshtime = now;
   13965 		}
   13966 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13967 		zone_settimer(zone, &now);
   13968 		goto detach;
   13969 	}
   13970 
   13971 requeue:
   13972 	queue_soa_query(zone);
   13973 	goto detach;
   13974 
   13975 same_master:
   13976 	if (msg != NULL) {
   13977 		dns_message_detach(&msg);
   13978 	}
   13979 	isc_event_free(&event);
   13980 	dns_request_destroy(&zone->request);
   13981 	queue_soa_query(zone);
   13982 
   13983 detach:
   13984 	UNLOCK_ZONE(zone);
   13985 	if (do_queue_xfrin) {
   13986 		queue_xfrin(zone);
   13987 	}
   13988 	dns_zone_idetach(&zone);
   13989 	return;
   13990 }
   13991 
   13992 static void
   13993 queue_soa_query(dns_zone_t *zone) {
   13994 	const char me[] = "queue_soa_query";
   13995 	isc_event_t *e;
   13996 	dns_zone_t *dummy = NULL;
   13997 	isc_result_t result;
   13998 
   13999 	ENTER;
   14000 	/*
   14001 	 * Locked by caller
   14002 	 */
   14003 	REQUIRE(LOCKED_ZONE(zone));
   14004 
   14005 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14006 		cancel_refresh(zone);
   14007 		return;
   14008 	}
   14009 
   14010 	e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, soa_query,
   14011 			       zone, sizeof(isc_event_t));
   14012 
   14013 	/*
   14014 	 * Attach so that we won't clean up
   14015 	 * until the event is delivered.
   14016 	 */
   14017 	zone_iattach(zone, &dummy);
   14018 
   14019 	e->ev_arg = zone;
   14020 	e->ev_sender = NULL;
   14021 	result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
   14022 	if (result != ISC_R_SUCCESS) {
   14023 		zone_idetach(&dummy);
   14024 		isc_event_free(&e);
   14025 		cancel_refresh(zone);
   14026 	}
   14027 }
   14028 
   14029 static void
   14030 soa_query(isc_task_t *task, isc_event_t *event) {
   14031 	const char me[] = "soa_query";
   14032 	isc_result_t result = ISC_R_FAILURE;
   14033 	dns_message_t *message = NULL;
   14034 	dns_zone_t *zone = event->ev_arg;
   14035 	dns_zone_t *dummy = NULL;
   14036 	isc_netaddr_t masterip;
   14037 	dns_tsigkey_t *key = NULL;
   14038 	uint32_t options;
   14039 	bool cancel = true;
   14040 	int timeout;
   14041 	bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
   14042 	uint16_t udpsize = SEND_BUFFER_SIZE;
   14043 	isc_dscp_t dscp = -1;
   14044 
   14045 	REQUIRE(DNS_ZONE_VALID(zone));
   14046 
   14047 	UNUSED(task);
   14048 
   14049 	ENTER;
   14050 
   14051 	LOCK_ZONE(zone);
   14052 	if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
   14053 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   14054 	    zone->view->requestmgr == NULL)
   14055 	{
   14056 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14057 			cancel = false;
   14058 		}
   14059 		goto cleanup;
   14060 	}
   14061 
   14062 again:
   14063 	result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
   14064 	if (result != ISC_R_SUCCESS) {
   14065 		goto cleanup;
   14066 	}
   14067 
   14068 	INSIST(zone->masterscnt > 0);
   14069 	INSIST(zone->curmaster < zone->masterscnt);
   14070 
   14071 	zone->masteraddr = zone->masters[zone->curmaster];
   14072 
   14073 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   14074 	/*
   14075 	 * First, look for a tsig key in the master statement, then
   14076 	 * try for a server key.
   14077 	 */
   14078 	if ((zone->masterkeynames != NULL) &&
   14079 	    (zone->masterkeynames[zone->curmaster] != NULL))
   14080 	{
   14081 		dns_view_t *view = dns_zone_getview(zone);
   14082 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   14083 		result = dns_view_gettsig(view, keyname, &key);
   14084 		if (result != ISC_R_SUCCESS) {
   14085 			char namebuf[DNS_NAME_FORMATSIZE];
   14086 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   14087 			dns_zone_log(zone, ISC_LOG_ERROR,
   14088 				     "unable to find key: %s", namebuf);
   14089 			goto skip_master;
   14090 		}
   14091 	}
   14092 	if (key == NULL) {
   14093 		result = dns_view_getpeertsig(zone->view, &masterip, &key);
   14094 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   14095 			char addrbuf[ISC_NETADDR_FORMATSIZE];
   14096 			isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
   14097 			dns_zone_log(zone, ISC_LOG_ERROR,
   14098 				     "unable to find TSIG key for %s", addrbuf);
   14099 			goto skip_master;
   14100 		}
   14101 	}
   14102 
   14103 	options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP
   14104 							 : 0;
   14105 	have_xfrsource = have_xfrdscp = false;
   14106 	reqnsid = zone->view->requestnsid;
   14107 	reqexpire = zone->requestexpire;
   14108 	if (zone->view->peers != NULL) {
   14109 		dns_peer_t *peer = NULL;
   14110 		bool edns, usetcp;
   14111 		result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip,
   14112 						 &peer);
   14113 		if (result == ISC_R_SUCCESS) {
   14114 			result = dns_peer_getsupportedns(peer, &edns);
   14115 			if (result == ISC_R_SUCCESS && !edns) {
   14116 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14117 			}
   14118 			result = dns_peer_gettransfersource(peer,
   14119 							    &zone->sourceaddr);
   14120 			if (result == ISC_R_SUCCESS) {
   14121 				have_xfrsource = true;
   14122 			}
   14123 			(void)dns_peer_gettransferdscp(peer, &dscp);
   14124 			if (dscp != -1) {
   14125 				have_xfrdscp = true;
   14126 			}
   14127 			if (zone->view->resolver != NULL) {
   14128 				udpsize = dns_resolver_getudpsize(
   14129 					zone->view->resolver);
   14130 			}
   14131 			(void)dns_peer_getudpsize(peer, &udpsize);
   14132 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14133 			(void)dns_peer_getrequestexpire(peer, &reqexpire);
   14134 			result = dns_peer_getforcetcp(peer, &usetcp);
   14135 			if (result == ISC_R_SUCCESS && usetcp) {
   14136 				options |= DNS_REQUESTOPT_TCP;
   14137 			}
   14138 		}
   14139 	}
   14140 
   14141 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   14142 	case PF_INET:
   14143 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14144 			if (isc_sockaddr_equal(&zone->altxfrsource4,
   14145 					       &zone->xfrsource4)) {
   14146 				goto skip_master;
   14147 			}
   14148 			zone->sourceaddr = zone->altxfrsource4;
   14149 			if (!have_xfrdscp) {
   14150 				dscp = zone->altxfrsource4dscp;
   14151 			}
   14152 		} else if (!have_xfrsource) {
   14153 			zone->sourceaddr = zone->xfrsource4;
   14154 			if (!have_xfrdscp) {
   14155 				dscp = zone->xfrsource4dscp;
   14156 			}
   14157 		}
   14158 		break;
   14159 	case PF_INET6:
   14160 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14161 			if (isc_sockaddr_equal(&zone->altxfrsource6,
   14162 					       &zone->xfrsource6)) {
   14163 				goto skip_master;
   14164 			}
   14165 			zone->sourceaddr = zone->altxfrsource6;
   14166 			if (!have_xfrdscp) {
   14167 				dscp = zone->altxfrsource6dscp;
   14168 			}
   14169 		} else if (!have_xfrsource) {
   14170 			zone->sourceaddr = zone->xfrsource6;
   14171 			if (!have_xfrdscp) {
   14172 				dscp = zone->xfrsource6dscp;
   14173 			}
   14174 		}
   14175 		break;
   14176 	default:
   14177 		result = ISC_R_NOTIMPLEMENTED;
   14178 		goto cleanup;
   14179 	}
   14180 
   14181 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14182 		result = add_opt(message, udpsize, reqnsid, reqexpire);
   14183 		if (result != ISC_R_SUCCESS) {
   14184 			zone_debuglog(zone, me, 1,
   14185 				      "unable to add opt record: %s",
   14186 				      dns_result_totext(result));
   14187 		}
   14188 	}
   14189 
   14190 	zone_iattach(zone, &dummy);
   14191 	timeout = 15;
   14192 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14193 		timeout = 30;
   14194 	}
   14195 	result = dns_request_createvia(
   14196 		zone->view->requestmgr, message, &zone->sourceaddr,
   14197 		&zone->masteraddr, dscp, options, key, timeout * 3, timeout, 0,
   14198 		zone->task, refresh_callback, zone, &zone->request);
   14199 	if (result != ISC_R_SUCCESS) {
   14200 		zone_idetach(&dummy);
   14201 		zone_debuglog(zone, me, 1,
   14202 			      "dns_request_createvia4() failed: %s",
   14203 			      dns_result_totext(result));
   14204 		goto skip_master;
   14205 	} else {
   14206 		if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) {
   14207 			inc_stats(zone, dns_zonestatscounter_soaoutv4);
   14208 		} else {
   14209 			inc_stats(zone, dns_zonestatscounter_soaoutv6);
   14210 		}
   14211 	}
   14212 	cancel = false;
   14213 
   14214 cleanup:
   14215 	if (key != NULL) {
   14216 		dns_tsigkey_detach(&key);
   14217 	}
   14218 	if (result != ISC_R_SUCCESS) {
   14219 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14220 	}
   14221 	if (message != NULL) {
   14222 		dns_message_detach(&message);
   14223 	}
   14224 	if (cancel) {
   14225 		cancel_refresh(zone);
   14226 	}
   14227 	isc_event_free(&event);
   14228 	UNLOCK_ZONE(zone);
   14229 	dns_zone_idetach(&zone);
   14230 	return;
   14231 
   14232 skip_master:
   14233 	if (key != NULL) {
   14234 		dns_tsigkey_detach(&key);
   14235 	}
   14236 	dns_message_detach(&message);
   14237 	/*
   14238 	 * Skip to next failed / untried master.
   14239 	 */
   14240 	do {
   14241 		zone->curmaster++;
   14242 	} while (zone->curmaster < zone->masterscnt &&
   14243 		 zone->mastersok[zone->curmaster]);
   14244 	if (zone->curmaster < zone->masterscnt) {
   14245 		goto again;
   14246 	}
   14247 	zone->curmaster = 0;
   14248 	goto cleanup;
   14249 }
   14250 
   14251 static void
   14252 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
   14253 	const char me[] = "ns_query";
   14254 	isc_result_t result;
   14255 	dns_message_t *message = NULL;
   14256 	isc_netaddr_t masterip;
   14257 	dns_tsigkey_t *key = NULL;
   14258 	dns_dbnode_t *node = NULL;
   14259 	int timeout;
   14260 	bool have_xfrsource = false, have_xfrdscp = false;
   14261 	bool reqnsid;
   14262 	uint16_t udpsize = SEND_BUFFER_SIZE;
   14263 	isc_dscp_t dscp = -1;
   14264 	struct stub_cb_args *cb_args;
   14265 
   14266 	REQUIRE(DNS_ZONE_VALID(zone));
   14267 	REQUIRE(LOCKED_ZONE(zone));
   14268 	REQUIRE((soardataset != NULL && stub == NULL) ||
   14269 		(soardataset == NULL && stub != NULL));
   14270 	REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
   14271 
   14272 	ENTER;
   14273 
   14274 	if (stub == NULL) {
   14275 		stub = isc_mem_get(zone->mctx, sizeof(*stub));
   14276 		stub->magic = STUB_MAGIC;
   14277 		stub->mctx = zone->mctx;
   14278 		stub->zone = NULL;
   14279 		stub->db = NULL;
   14280 		stub->version = NULL;
   14281 		atomic_init(&stub->pending_requests, 0);
   14282 
   14283 		/*
   14284 		 * Attach so that the zone won't disappear from under us.
   14285 		 */
   14286 		zone_iattach(zone, &stub->zone);
   14287 
   14288 		/*
   14289 		 * If a db exists we will update it, otherwise we create a
   14290 		 * new one and attach it to the zone once we have the NS
   14291 		 * RRset and glue.
   14292 		 */
   14293 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14294 		if (zone->db != NULL) {
   14295 			dns_db_attach(zone->db, &stub->db);
   14296 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14297 		} else {
   14298 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14299 
   14300 			INSIST(zone->db_argc >= 1);
   14301 			result = dns_db_create(zone->mctx, zone->db_argv[0],
   14302 					       &zone->origin, dns_dbtype_stub,
   14303 					       zone->rdclass, zone->db_argc - 1,
   14304 					       zone->db_argv + 1, &stub->db);
   14305 			if (result != ISC_R_SUCCESS) {
   14306 				dns_zone_log(zone, ISC_LOG_ERROR,
   14307 					     "refreshing stub: "
   14308 					     "could not create "
   14309 					     "database: %s",
   14310 					     dns_result_totext(result));
   14311 				goto cleanup;
   14312 			}
   14313 			dns_db_settask(stub->db, zone->task);
   14314 		}
   14315 
   14316 		result = dns_db_newversion(stub->db, &stub->version);
   14317 		if (result != ISC_R_SUCCESS) {
   14318 			dns_zone_log(zone, ISC_LOG_INFO,
   14319 				     "refreshing stub: "
   14320 				     "dns_db_newversion() failed: %s",
   14321 				     dns_result_totext(result));
   14322 			goto cleanup;
   14323 		}
   14324 
   14325 		/*
   14326 		 * Update SOA record.
   14327 		 */
   14328 		result = dns_db_findnode(stub->db, &zone->origin, true, &node);
   14329 		if (result != ISC_R_SUCCESS) {
   14330 			dns_zone_log(zone, ISC_LOG_INFO,
   14331 				     "refreshing stub: "
   14332 				     "dns_db_findnode() failed: %s",
   14333 				     dns_result_totext(result));
   14334 			goto cleanup;
   14335 		}
   14336 
   14337 		result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   14338 					    soardataset, 0, NULL);
   14339 		dns_db_detachnode(stub->db, &node);
   14340 		if (result != ISC_R_SUCCESS) {
   14341 			dns_zone_log(zone, ISC_LOG_INFO,
   14342 				     "refreshing stub: "
   14343 				     "dns_db_addrdataset() failed: %s",
   14344 				     dns_result_totext(result));
   14345 			goto cleanup;
   14346 		}
   14347 	}
   14348 
   14349 	/*
   14350 	 * XXX Optimisation: Create message when zone is setup and reuse.
   14351 	 */
   14352 	result = create_query(zone, dns_rdatatype_ns, &zone->origin, &message);
   14353 	INSIST(result == ISC_R_SUCCESS);
   14354 
   14355 	INSIST(zone->masterscnt > 0);
   14356 	INSIST(zone->curmaster < zone->masterscnt);
   14357 	zone->masteraddr = zone->masters[zone->curmaster];
   14358 
   14359 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   14360 	/*
   14361 	 * First, look for a tsig key in the master statement, then
   14362 	 * try for a server key.
   14363 	 */
   14364 	if ((zone->masterkeynames != NULL) &&
   14365 	    (zone->masterkeynames[zone->curmaster] != NULL))
   14366 	{
   14367 		dns_view_t *view = dns_zone_getview(zone);
   14368 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   14369 		result = dns_view_gettsig(view, keyname, &key);
   14370 		if (result != ISC_R_SUCCESS) {
   14371 			char namebuf[DNS_NAME_FORMATSIZE];
   14372 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   14373 			dns_zone_log(zone, ISC_LOG_ERROR,
   14374 				     "unable to find key: %s", namebuf);
   14375 		}
   14376 	}
   14377 	if (key == NULL) {
   14378 		(void)dns_view_getpeertsig(zone->view, &masterip, &key);
   14379 	}
   14380 
   14381 	reqnsid = zone->view->requestnsid;
   14382 	if (zone->view->peers != NULL) {
   14383 		dns_peer_t *peer = NULL;
   14384 		bool edns;
   14385 		result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip,
   14386 						 &peer);
   14387 		if (result == ISC_R_SUCCESS) {
   14388 			result = dns_peer_getsupportedns(peer, &edns);
   14389 			if (result == ISC_R_SUCCESS && !edns) {
   14390 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14391 			}
   14392 			result = dns_peer_gettransfersource(peer,
   14393 							    &zone->sourceaddr);
   14394 			if (result == ISC_R_SUCCESS) {
   14395 				have_xfrsource = true;
   14396 			}
   14397 			result = dns_peer_gettransferdscp(peer, &dscp);
   14398 			if (result == ISC_R_SUCCESS && dscp != -1) {
   14399 				have_xfrdscp = true;
   14400 			}
   14401 			if (zone->view->resolver != NULL) {
   14402 				udpsize = dns_resolver_getudpsize(
   14403 					zone->view->resolver);
   14404 			}
   14405 			(void)dns_peer_getudpsize(peer, &udpsize);
   14406 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14407 		}
   14408 	}
   14409 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14410 		result = add_opt(message, udpsize, reqnsid, false);
   14411 		if (result != ISC_R_SUCCESS) {
   14412 			zone_debuglog(zone, me, 1,
   14413 				      "unable to add opt record: %s",
   14414 				      dns_result_totext(result));
   14415 		}
   14416 	}
   14417 
   14418 	/*
   14419 	 * Always use TCP so that we shouldn't truncate in additional section.
   14420 	 */
   14421 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   14422 	case PF_INET:
   14423 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14424 			zone->sourceaddr = zone->altxfrsource4;
   14425 			if (!have_xfrdscp) {
   14426 				dscp = zone->altxfrsource4dscp;
   14427 			}
   14428 		} else if (!have_xfrsource) {
   14429 			zone->sourceaddr = zone->xfrsource4;
   14430 			if (!have_xfrdscp) {
   14431 				dscp = zone->xfrsource4dscp;
   14432 			}
   14433 		}
   14434 		break;
   14435 	case PF_INET6:
   14436 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14437 			zone->sourceaddr = zone->altxfrsource6;
   14438 			if (!have_xfrdscp) {
   14439 				dscp = zone->altxfrsource6dscp;
   14440 			}
   14441 		} else if (!have_xfrsource) {
   14442 			zone->sourceaddr = zone->xfrsource6;
   14443 			if (!have_xfrdscp) {
   14444 				dscp = zone->xfrsource6dscp;
   14445 			}
   14446 		}
   14447 		break;
   14448 	default:
   14449 		result = ISC_R_NOTIMPLEMENTED;
   14450 		POST(result);
   14451 		goto cleanup;
   14452 	}
   14453 	timeout = 15;
   14454 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14455 		timeout = 30;
   14456 	}
   14457 
   14458 	/* Save request parameters so we can reuse them later on
   14459 	   for resolving missing glue A/AAAA records. */
   14460 	cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args));
   14461 	cb_args->stub = stub;
   14462 	cb_args->tsig_key = key;
   14463 	cb_args->dscp = dscp;
   14464 	cb_args->udpsize = udpsize;
   14465 	cb_args->timeout = timeout;
   14466 	cb_args->reqnsid = reqnsid;
   14467 
   14468 	result = dns_request_createvia(
   14469 		zone->view->requestmgr, message, &zone->sourceaddr,
   14470 		&zone->masteraddr, dscp, DNS_REQUESTOPT_TCP, key, timeout * 3,
   14471 		timeout, 0, zone->task, stub_callback, cb_args, &zone->request);
   14472 	if (result != ISC_R_SUCCESS) {
   14473 		zone_debuglog(zone, me, 1, "dns_request_createvia() failed: %s",
   14474 			      dns_result_totext(result));
   14475 		goto cleanup;
   14476 	}
   14477 	dns_message_detach(&message);
   14478 	goto unlock;
   14479 
   14480 cleanup:
   14481 	cancel_refresh(zone);
   14482 	stub->magic = 0;
   14483 	if (stub->version != NULL) {
   14484 		dns_db_closeversion(stub->db, &stub->version, false);
   14485 	}
   14486 	if (stub->db != NULL) {
   14487 		dns_db_detach(&stub->db);
   14488 	}
   14489 	if (stub->zone != NULL) {
   14490 		zone_idetach(&stub->zone);
   14491 	}
   14492 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   14493 	if (message != NULL) {
   14494 		dns_message_detach(&message);
   14495 	}
   14496 unlock:
   14497 	if (key != NULL) {
   14498 		dns_tsigkey_detach(&key);
   14499 	}
   14500 	return;
   14501 }
   14502 
   14503 /*
   14504  * Handle the control event.  Note that although this event causes the zone
   14505  * to shut down, it is not a shutdown event in the sense of the task library.
   14506  */
   14507 static void
   14508 zone_shutdown(isc_task_t *task, isc_event_t *event) {
   14509 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   14510 	bool free_needed, linked = false;
   14511 	dns_zone_t *raw = NULL, *secure = NULL;
   14512 
   14513 	UNUSED(task);
   14514 	REQUIRE(DNS_ZONE_VALID(zone));
   14515 	INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
   14516 	INSIST(isc_refcount_current(&zone->erefs) == 0);
   14517 
   14518 	zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
   14519 
   14520 	/*
   14521 	 * Stop things being restarted after we cancel them below.
   14522 	 */
   14523 	LOCK_ZONE(zone);
   14524 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
   14525 	UNLOCK_ZONE(zone);
   14526 
   14527 	/*
   14528 	 * If we were waiting for xfrin quota, step out of
   14529 	 * the queue.
   14530 	 * If there's no zone manager, we can't be waiting for the
   14531 	 * xfrin quota
   14532 	 */
   14533 	if (zone->zmgr != NULL) {
   14534 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   14535 		if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
   14536 			ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
   14537 					statelink);
   14538 			linked = true;
   14539 			zone->statelist = NULL;
   14540 		}
   14541 		if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
   14542 			ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
   14543 					statelink);
   14544 			zone->statelist = NULL;
   14545 			zmgr_resume_xfrs(zone->zmgr, false);
   14546 		}
   14547 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   14548 	}
   14549 
   14550 	/*
   14551 	 * In task context, no locking required.  See zone_xfrdone().
   14552 	 */
   14553 	if (zone->xfr != NULL) {
   14554 		dns_xfrin_shutdown(zone->xfr);
   14555 	}
   14556 
   14557 	/* Safe to release the zone now */
   14558 	if (zone->zmgr != NULL) {
   14559 		dns_zonemgr_releasezone(zone->zmgr, zone);
   14560 	}
   14561 
   14562 	LOCK_ZONE(zone);
   14563 	INSIST(zone != zone->raw);
   14564 	if (linked) {
   14565 		isc_refcount_decrement(&zone->irefs);
   14566 	}
   14567 	if (zone->request != NULL) {
   14568 		dns_request_cancel(zone->request);
   14569 	}
   14570 
   14571 	if (zone->readio != NULL) {
   14572 		zonemgr_cancelio(zone->readio);
   14573 	}
   14574 
   14575 	if (zone->lctx != NULL) {
   14576 		dns_loadctx_cancel(zone->lctx);
   14577 	}
   14578 
   14579 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   14580 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14581 	{
   14582 		if (zone->writeio != NULL) {
   14583 			zonemgr_cancelio(zone->writeio);
   14584 		}
   14585 
   14586 		if (zone->dctx != NULL) {
   14587 			dns_dumpctx_cancel(zone->dctx);
   14588 		}
   14589 	}
   14590 
   14591 	notify_cancel(zone);
   14592 
   14593 	forward_cancel(zone);
   14594 
   14595 	if (zone->timer != NULL) {
   14596 		isc_timer_detach(&zone->timer);
   14597 		isc_refcount_decrement(&zone->irefs);
   14598 	}
   14599 
   14600 	/*
   14601 	 * We have now canceled everything set the flag to allow exit_check()
   14602 	 * to succeed.	We must not unlock between setting this flag and
   14603 	 * calling exit_check().
   14604 	 */
   14605 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
   14606 	free_needed = exit_check(zone);
   14607 	if (inline_secure(zone)) {
   14608 		raw = zone->raw;
   14609 		zone->raw = NULL;
   14610 	}
   14611 	if (inline_raw(zone)) {
   14612 		secure = zone->secure;
   14613 		zone->secure = NULL;
   14614 	}
   14615 	UNLOCK_ZONE(zone);
   14616 	if (raw != NULL) {
   14617 		dns_zone_detach(&raw);
   14618 	}
   14619 	if (secure != NULL) {
   14620 		dns_zone_idetach(&secure);
   14621 	}
   14622 	if (free_needed) {
   14623 		zone_free(zone);
   14624 	}
   14625 }
   14626 
   14627 static void
   14628 zone_timer(isc_task_t *task, isc_event_t *event) {
   14629 	const char me[] = "zone_timer";
   14630 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   14631 
   14632 	UNUSED(task);
   14633 	REQUIRE(DNS_ZONE_VALID(zone));
   14634 
   14635 	ENTER;
   14636 
   14637 	zone_maintenance(zone);
   14638 
   14639 	isc_event_free(&event);
   14640 }
   14641 
   14642 static void
   14643 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
   14644 	const char me[] = "zone_settimer";
   14645 	isc_time_t next;
   14646 	isc_result_t result;
   14647 
   14648 	REQUIRE(DNS_ZONE_VALID(zone));
   14649 	REQUIRE(LOCKED_ZONE(zone));
   14650 	ENTER;
   14651 
   14652 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14653 		return;
   14654 	}
   14655 
   14656 	isc_time_settoepoch(&next);
   14657 
   14658 	switch (zone->type) {
   14659 	case dns_zone_redirect:
   14660 		if (zone->masters != NULL) {
   14661 			goto treat_as_slave;
   14662 		}
   14663 		/* FALLTHROUGH */
   14664 
   14665 	case dns_zone_master:
   14666 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   14667 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   14668 		{
   14669 			next = zone->notifytime;
   14670 		}
   14671 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   14672 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14673 		{
   14674 			INSIST(!isc_time_isepoch(&zone->dumptime));
   14675 			if (isc_time_isepoch(&next) ||
   14676 			    isc_time_compare(&zone->dumptime, &next) < 0) {
   14677 				next = zone->dumptime;
   14678 			}
   14679 		}
   14680 		if (zone->type == dns_zone_redirect) {
   14681 			break;
   14682 		}
   14683 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
   14684 		    !isc_time_isepoch(&zone->refreshkeytime))
   14685 		{
   14686 			if (isc_time_isepoch(&next) ||
   14687 			    isc_time_compare(&zone->refreshkeytime, &next) < 0)
   14688 			{
   14689 				next = zone->refreshkeytime;
   14690 			}
   14691 		}
   14692 		if (!isc_time_isepoch(&zone->resigntime)) {
   14693 			if (isc_time_isepoch(&next) ||
   14694 			    isc_time_compare(&zone->resigntime, &next) < 0) {
   14695 				next = zone->resigntime;
   14696 			}
   14697 		}
   14698 		if (!isc_time_isepoch(&zone->keywarntime)) {
   14699 			if (isc_time_isepoch(&next) ||
   14700 			    isc_time_compare(&zone->keywarntime, &next) < 0) {
   14701 				next = zone->keywarntime;
   14702 			}
   14703 		}
   14704 		if (!isc_time_isepoch(&zone->signingtime)) {
   14705 			if (isc_time_isepoch(&next) ||
   14706 			    isc_time_compare(&zone->signingtime, &next) < 0) {
   14707 				next = zone->signingtime;
   14708 			}
   14709 		}
   14710 		if (!isc_time_isepoch(&zone->nsec3chaintime)) {
   14711 			if (isc_time_isepoch(&next) ||
   14712 			    isc_time_compare(&zone->nsec3chaintime, &next) < 0)
   14713 			{
   14714 				next = zone->nsec3chaintime;
   14715 			}
   14716 		}
   14717 		break;
   14718 
   14719 	case dns_zone_slave:
   14720 	case dns_zone_mirror:
   14721 	treat_as_slave:
   14722 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   14723 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   14724 		{
   14725 			next = zone->notifytime;
   14726 		}
   14727 		/* FALLTHROUGH */
   14728 
   14729 	case dns_zone_stub:
   14730 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
   14731 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
   14732 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
   14733 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
   14734 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
   14735 		    !isc_time_isepoch(&zone->refreshtime) &&
   14736 		    (isc_time_isepoch(&next) ||
   14737 		     isc_time_compare(&zone->refreshtime, &next) < 0))
   14738 		{
   14739 			next = zone->refreshtime;
   14740 		}
   14741 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   14742 		    !isc_time_isepoch(&zone->expiretime))
   14743 		{
   14744 			if (isc_time_isepoch(&next) ||
   14745 			    isc_time_compare(&zone->expiretime, &next) < 0) {
   14746 				next = zone->expiretime;
   14747 			}
   14748 		}
   14749 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   14750 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14751 		{
   14752 			INSIST(!isc_time_isepoch(&zone->dumptime));
   14753 			if (isc_time_isepoch(&next) ||
   14754 			    isc_time_compare(&zone->dumptime, &next) < 0) {
   14755 				next = zone->dumptime;
   14756 			}
   14757 		}
   14758 		break;
   14759 
   14760 	case dns_zone_key:
   14761 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   14762 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14763 		{
   14764 			INSIST(!isc_time_isepoch(&zone->dumptime));
   14765 			if (isc_time_isepoch(&next) ||
   14766 			    isc_time_compare(&zone->dumptime, &next) < 0) {
   14767 				next = zone->dumptime;
   14768 			}
   14769 		}
   14770 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
   14771 			if (isc_time_isepoch(&next) ||
   14772 			    (!isc_time_isepoch(&zone->refreshkeytime) &&
   14773 			     isc_time_compare(&zone->refreshkeytime, &next) <
   14774 				     0))
   14775 			{
   14776 				next = zone->refreshkeytime;
   14777 			}
   14778 		}
   14779 		break;
   14780 
   14781 	default:
   14782 		break;
   14783 	}
   14784 
   14785 	if (isc_time_isepoch(&next)) {
   14786 		zone_debuglog(zone, me, 10, "settimer inactive");
   14787 		result = isc_timer_reset(zone->timer, isc_timertype_inactive,
   14788 					 NULL, NULL, true);
   14789 		if (result != ISC_R_SUCCESS) {
   14790 			dns_zone_log(zone, ISC_LOG_ERROR,
   14791 				     "could not deactivate zone timer: %s",
   14792 				     isc_result_totext(result));
   14793 		}
   14794 	} else {
   14795 		if (isc_time_compare(&next, now) <= 0) {
   14796 			next = *now;
   14797 		}
   14798 		result = isc_timer_reset(zone->timer, isc_timertype_once, &next,
   14799 					 NULL, true);
   14800 		if (result != ISC_R_SUCCESS) {
   14801 			dns_zone_log(zone, ISC_LOG_ERROR,
   14802 				     "could not reset zone timer: %s",
   14803 				     isc_result_totext(result));
   14804 		}
   14805 	}
   14806 }
   14807 
   14808 static void
   14809 cancel_refresh(dns_zone_t *zone) {
   14810 	const char me[] = "cancel_refresh";
   14811 	isc_time_t now;
   14812 
   14813 	/*
   14814 	 * 'zone' locked by caller.
   14815 	 */
   14816 
   14817 	REQUIRE(DNS_ZONE_VALID(zone));
   14818 	REQUIRE(LOCKED_ZONE(zone));
   14819 
   14820 	ENTER;
   14821 
   14822 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14823 	TIME_NOW(&now);
   14824 	zone_settimer(zone, &now);
   14825 }
   14826 
   14827 static isc_result_t
   14828 notify_createmessage(dns_zone_t *zone, unsigned int flags,
   14829 		     dns_message_t **messagep) {
   14830 	dns_db_t *zonedb = NULL;
   14831 	dns_dbnode_t *node = NULL;
   14832 	dns_dbversion_t *version = NULL;
   14833 	dns_message_t *message = NULL;
   14834 	dns_rdataset_t rdataset;
   14835 	dns_rdata_t rdata = DNS_RDATA_INIT;
   14836 
   14837 	dns_name_t *tempname = NULL;
   14838 	dns_rdata_t *temprdata = NULL;
   14839 	dns_rdatalist_t *temprdatalist = NULL;
   14840 	dns_rdataset_t *temprdataset = NULL;
   14841 
   14842 	isc_result_t result;
   14843 	isc_region_t r;
   14844 	isc_buffer_t *b = NULL;
   14845 
   14846 	REQUIRE(DNS_ZONE_VALID(zone));
   14847 	REQUIRE(messagep != NULL && *messagep == NULL);
   14848 
   14849 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   14850 
   14851 	message->opcode = dns_opcode_notify;
   14852 	message->flags |= DNS_MESSAGEFLAG_AA;
   14853 	message->rdclass = zone->rdclass;
   14854 
   14855 	result = dns_message_gettempname(message, &tempname);
   14856 	if (result != ISC_R_SUCCESS) {
   14857 		goto cleanup;
   14858 	}
   14859 
   14860 	result = dns_message_gettemprdataset(message, &temprdataset);
   14861 	if (result != ISC_R_SUCCESS) {
   14862 		goto cleanup;
   14863 	}
   14864 
   14865 	/*
   14866 	 * Make question.
   14867 	 */
   14868 	dns_name_init(tempname, NULL);
   14869 	dns_name_clone(&zone->origin, tempname);
   14870 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
   14871 				  dns_rdatatype_soa);
   14872 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   14873 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
   14874 	tempname = NULL;
   14875 	temprdataset = NULL;
   14876 
   14877 	if ((flags & DNS_NOTIFY_NOSOA) != 0) {
   14878 		goto done;
   14879 	}
   14880 
   14881 	result = dns_message_gettempname(message, &tempname);
   14882 	if (result != ISC_R_SUCCESS) {
   14883 		goto soa_cleanup;
   14884 	}
   14885 	result = dns_message_gettemprdata(message, &temprdata);
   14886 	if (result != ISC_R_SUCCESS) {
   14887 		goto soa_cleanup;
   14888 	}
   14889 	result = dns_message_gettemprdataset(message, &temprdataset);
   14890 	if (result != ISC_R_SUCCESS) {
   14891 		goto soa_cleanup;
   14892 	}
   14893 	result = dns_message_gettemprdatalist(message, &temprdatalist);
   14894 	if (result != ISC_R_SUCCESS) {
   14895 		goto soa_cleanup;
   14896 	}
   14897 
   14898 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14899 	INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
   14900 	dns_db_attach(zone->db, &zonedb);
   14901 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14902 
   14903 	dns_name_init(tempname, NULL);
   14904 	dns_name_clone(&zone->origin, tempname);
   14905 	dns_db_currentversion(zonedb, &version);
   14906 	result = dns_db_findnode(zonedb, tempname, false, &node);
   14907 	if (result != ISC_R_SUCCESS) {
   14908 		goto soa_cleanup;
   14909 	}
   14910 
   14911 	dns_rdataset_init(&rdataset);
   14912 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   14913 				     dns_rdatatype_none, 0, &rdataset, NULL);
   14914 	if (result != ISC_R_SUCCESS) {
   14915 		goto soa_cleanup;
   14916 	}
   14917 	result = dns_rdataset_first(&rdataset);
   14918 	if (result != ISC_R_SUCCESS) {
   14919 		goto soa_cleanup;
   14920 	}
   14921 	dns_rdataset_current(&rdataset, &rdata);
   14922 	dns_rdata_toregion(&rdata, &r);
   14923 	isc_buffer_allocate(zone->mctx, &b, r.length);
   14924 	isc_buffer_putmem(b, r.base, r.length);
   14925 	isc_buffer_usedregion(b, &r);
   14926 	dns_rdata_init(temprdata);
   14927 	dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
   14928 	dns_message_takebuffer(message, &b);
   14929 	result = dns_rdataset_next(&rdataset);
   14930 	dns_rdataset_disassociate(&rdataset);
   14931 	if (result != ISC_R_NOMORE) {
   14932 		goto soa_cleanup;
   14933 	}
   14934 	temprdatalist->rdclass = rdata.rdclass;
   14935 	temprdatalist->type = rdata.type;
   14936 	temprdatalist->ttl = rdataset.ttl;
   14937 	ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
   14938 
   14939 	result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
   14940 	if (result != ISC_R_SUCCESS) {
   14941 		goto soa_cleanup;
   14942 	}
   14943 
   14944 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   14945 	dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
   14946 	temprdatalist = NULL;
   14947 	temprdataset = NULL;
   14948 	temprdata = NULL;
   14949 	tempname = NULL;
   14950 
   14951 soa_cleanup:
   14952 	if (node != NULL) {
   14953 		dns_db_detachnode(zonedb, &node);
   14954 	}
   14955 	if (version != NULL) {
   14956 		dns_db_closeversion(zonedb, &version, false);
   14957 	}
   14958 	if (zonedb != NULL) {
   14959 		dns_db_detach(&zonedb);
   14960 	}
   14961 	if (tempname != NULL) {
   14962 		dns_message_puttempname(message, &tempname);
   14963 	}
   14964 	if (temprdata != NULL) {
   14965 		dns_message_puttemprdata(message, &temprdata);
   14966 	}
   14967 	if (temprdataset != NULL) {
   14968 		dns_message_puttemprdataset(message, &temprdataset);
   14969 	}
   14970 	if (temprdatalist != NULL) {
   14971 		dns_message_puttemprdatalist(message, &temprdatalist);
   14972 	}
   14973 
   14974 done:
   14975 	*messagep = message;
   14976 	return (ISC_R_SUCCESS);
   14977 
   14978 cleanup:
   14979 	if (tempname != NULL) {
   14980 		dns_message_puttempname(message, &tempname);
   14981 	}
   14982 	if (temprdataset != NULL) {
   14983 		dns_message_puttemprdataset(message, &temprdataset);
   14984 	}
   14985 	dns_message_detach(&message);
   14986 	return (result);
   14987 }
   14988 
   14989 isc_result_t
   14990 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
   14991 		       isc_sockaddr_t *to, dns_message_t *msg) {
   14992 	unsigned int i;
   14993 	dns_rdata_soa_t soa;
   14994 	dns_rdataset_t *rdataset = NULL;
   14995 	dns_rdata_t rdata = DNS_RDATA_INIT;
   14996 	isc_result_t result;
   14997 	char fromtext[ISC_SOCKADDR_FORMATSIZE];
   14998 	int match = 0;
   14999 	isc_netaddr_t netaddr;
   15000 	uint32_t serial = 0;
   15001 	bool have_serial = false;
   15002 	dns_tsigkey_t *tsigkey;
   15003 	const dns_name_t *tsig;
   15004 
   15005 	REQUIRE(DNS_ZONE_VALID(zone));
   15006 
   15007 	/*
   15008 	 * If type != T_SOA return DNS_R_NOTIMP.  We don't yet support
   15009 	 * ROLLOVER.
   15010 	 *
   15011 	 * SOA:	RFC1996
   15012 	 * Check that 'from' is a valid notify source, (zone->masters).
   15013 	 *	Return DNS_R_REFUSED if not.
   15014 	 *
   15015 	 * If the notify message contains a serial number check it
   15016 	 * against the zones serial and return if <= current serial
   15017 	 *
   15018 	 * If a refresh check is progress, if so just record the
   15019 	 * fact we received a NOTIFY and from where and return.
   15020 	 * We will perform a new refresh check when the current one
   15021 	 * completes. Return ISC_R_SUCCESS.
   15022 	 *
   15023 	 * Otherwise initiate a refresh check using 'from' as the
   15024 	 * first address to check.  Return ISC_R_SUCCESS.
   15025 	 */
   15026 
   15027 	isc_sockaddr_format(from, fromtext, sizeof(fromtext));
   15028 
   15029 	/*
   15030 	 * Notify messages are processed by the raw zone.
   15031 	 */
   15032 	LOCK_ZONE(zone);
   15033 	INSIST(zone != zone->raw);
   15034 	if (inline_secure(zone)) {
   15035 		result = dns_zone_notifyreceive(zone->raw, from, to, msg);
   15036 		UNLOCK_ZONE(zone);
   15037 		return (result);
   15038 	}
   15039 	/*
   15040 	 *  We only handle NOTIFY (SOA) at the present.
   15041 	 */
   15042 	if (isc_sockaddr_pf(from) == PF_INET) {
   15043 		inc_stats(zone, dns_zonestatscounter_notifyinv4);
   15044 	} else {
   15045 		inc_stats(zone, dns_zonestatscounter_notifyinv6);
   15046 	}
   15047 	if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
   15048 	    dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
   15049 				 dns_rdatatype_soa, dns_rdatatype_none, NULL,
   15050 				 NULL) != ISC_R_SUCCESS)
   15051 	{
   15052 		UNLOCK_ZONE(zone);
   15053 		if (msg->counts[DNS_SECTION_QUESTION] == 0) {
   15054 			dns_zone_log(zone, ISC_LOG_NOTICE,
   15055 				     "NOTIFY with no "
   15056 				     "question section from: %s",
   15057 				     fromtext);
   15058 			return (DNS_R_FORMERR);
   15059 		}
   15060 		dns_zone_log(zone, ISC_LOG_NOTICE,
   15061 			     "NOTIFY zone does not match");
   15062 		return (DNS_R_NOTIMP);
   15063 	}
   15064 
   15065 	/*
   15066 	 * If we are a master zone just succeed.
   15067 	 */
   15068 	if (zone->type == dns_zone_master) {
   15069 		UNLOCK_ZONE(zone);
   15070 		return (ISC_R_SUCCESS);
   15071 	}
   15072 
   15073 	isc_netaddr_fromsockaddr(&netaddr, from);
   15074 	for (i = 0; i < zone->masterscnt; i++) {
   15075 		if (isc_sockaddr_eqaddr(from, &zone->masters[i])) {
   15076 			break;
   15077 		}
   15078 		if (zone->view->aclenv.match_mapped &&
   15079 		    IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
   15080 		    isc_sockaddr_pf(&zone->masters[i]) == AF_INET)
   15081 		{
   15082 			isc_netaddr_t na1, na2;
   15083 			isc_netaddr_fromv4mapped(&na1, &netaddr);
   15084 			isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
   15085 			if (isc_netaddr_equal(&na1, &na2)) {
   15086 				break;
   15087 			}
   15088 		}
   15089 	}
   15090 
   15091 	/*
   15092 	 * Accept notify requests from non masters if they are on
   15093 	 * 'zone->notify_acl'.
   15094 	 */
   15095 	tsigkey = dns_message_gettsigkey(msg);
   15096 	tsig = dns_tsigkey_identity(tsigkey);
   15097 	if (i >= zone->masterscnt && zone->notify_acl != NULL &&
   15098 	    (dns_acl_match(&netaddr, tsig, zone->notify_acl,
   15099 			   &zone->view->aclenv, &match,
   15100 			   NULL) == ISC_R_SUCCESS) &&
   15101 	    match > 0)
   15102 	{
   15103 		/* Accept notify. */
   15104 	} else if (i >= zone->masterscnt) {
   15105 		UNLOCK_ZONE(zone);
   15106 		dns_zone_log(zone, ISC_LOG_INFO,
   15107 			     "refused notify from non-master: %s", fromtext);
   15108 		inc_stats(zone, dns_zonestatscounter_notifyrej);
   15109 		return (DNS_R_REFUSED);
   15110 	}
   15111 
   15112 	/*
   15113 	 * If the zone is loaded and there are answers check the serial
   15114 	 * to see if we need to do a refresh.  Do not worry about this
   15115 	 * check if we are a dialup zone as we use the notify request
   15116 	 * to trigger a refresh check.
   15117 	 */
   15118 	if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
   15119 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   15120 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH))
   15121 	{
   15122 		result = dns_message_findname(
   15123 			msg, DNS_SECTION_ANSWER, &zone->origin,
   15124 			dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset);
   15125 		if (result == ISC_R_SUCCESS) {
   15126 			result = dns_rdataset_first(rdataset);
   15127 		}
   15128 		if (result == ISC_R_SUCCESS) {
   15129 			uint32_t oldserial;
   15130 			unsigned int soacount;
   15131 
   15132 			dns_rdataset_current(rdataset, &rdata);
   15133 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   15134 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15135 			serial = soa.serial;
   15136 			have_serial = true;
   15137 			/*
   15138 			 * The following should safely be performed without DB
   15139 			 * lock and succeed in this context.
   15140 			 */
   15141 			result = zone_get_from_db(zone, zone->db, NULL,
   15142 						  &soacount, &oldserial, NULL,
   15143 						  NULL, NULL, NULL, NULL);
   15144 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15145 			RUNTIME_CHECK(soacount > 0U);
   15146 			if (isc_serial_le(serial, oldserial)) {
   15147 				dns_zone_log(zone, ISC_LOG_INFO,
   15148 					     "notify from %s: "
   15149 					     "zone is up to date",
   15150 					     fromtext);
   15151 				UNLOCK_ZONE(zone);
   15152 				return (ISC_R_SUCCESS);
   15153 			}
   15154 		}
   15155 	}
   15156 
   15157 	/*
   15158 	 * If we got this far and there was a refresh in progress just
   15159 	 * let it complete.  Record where we got the notify from so we
   15160 	 * can perform a refresh check when the current one completes
   15161 	 */
   15162 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   15163 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   15164 		zone->notifyfrom = *from;
   15165 		UNLOCK_ZONE(zone);
   15166 		if (have_serial) {
   15167 			dns_zone_log(zone, ISC_LOG_INFO,
   15168 				     "notify from %s: serial %u: refresh in "
   15169 				     "progress, refresh check queued",
   15170 				     fromtext, serial);
   15171 		} else {
   15172 			dns_zone_log(zone, ISC_LOG_INFO,
   15173 				     "notify from %s: refresh in progress, "
   15174 				     "refresh check queued",
   15175 				     fromtext);
   15176 		}
   15177 		return (ISC_R_SUCCESS);
   15178 	}
   15179 	if (have_serial) {
   15180 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
   15181 			     fromtext, serial);
   15182 	} else {
   15183 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
   15184 			     fromtext);
   15185 	}
   15186 	zone->notifyfrom = *from;
   15187 	UNLOCK_ZONE(zone);
   15188 
   15189 	if (to != NULL) {
   15190 		dns_zonemgr_unreachabledel(zone->zmgr, from, to);
   15191 	}
   15192 	dns_zone_refresh(zone);
   15193 	return (ISC_R_SUCCESS);
   15194 }
   15195 
   15196 void
   15197 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
   15198 	REQUIRE(DNS_ZONE_VALID(zone));
   15199 
   15200 	LOCK_ZONE(zone);
   15201 	if (zone->notify_acl != NULL) {
   15202 		dns_acl_detach(&zone->notify_acl);
   15203 	}
   15204 	dns_acl_attach(acl, &zone->notify_acl);
   15205 	UNLOCK_ZONE(zone);
   15206 }
   15207 
   15208 void
   15209 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
   15210 	REQUIRE(DNS_ZONE_VALID(zone));
   15211 
   15212 	LOCK_ZONE(zone);
   15213 	if (zone->query_acl != NULL) {
   15214 		dns_acl_detach(&zone->query_acl);
   15215 	}
   15216 	dns_acl_attach(acl, &zone->query_acl);
   15217 	UNLOCK_ZONE(zone);
   15218 }
   15219 
   15220 void
   15221 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
   15222 	REQUIRE(DNS_ZONE_VALID(zone));
   15223 
   15224 	LOCK_ZONE(zone);
   15225 	if (zone->queryon_acl != NULL) {
   15226 		dns_acl_detach(&zone->queryon_acl);
   15227 	}
   15228 	dns_acl_attach(acl, &zone->queryon_acl);
   15229 	UNLOCK_ZONE(zone);
   15230 }
   15231 
   15232 void
   15233 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
   15234 	REQUIRE(DNS_ZONE_VALID(zone));
   15235 
   15236 	LOCK_ZONE(zone);
   15237 	if (zone->update_acl != NULL) {
   15238 		dns_acl_detach(&zone->update_acl);
   15239 	}
   15240 	dns_acl_attach(acl, &zone->update_acl);
   15241 	UNLOCK_ZONE(zone);
   15242 }
   15243 
   15244 void
   15245 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
   15246 	REQUIRE(DNS_ZONE_VALID(zone));
   15247 
   15248 	LOCK_ZONE(zone);
   15249 	if (zone->forward_acl != NULL) {
   15250 		dns_acl_detach(&zone->forward_acl);
   15251 	}
   15252 	dns_acl_attach(acl, &zone->forward_acl);
   15253 	UNLOCK_ZONE(zone);
   15254 }
   15255 
   15256 void
   15257 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
   15258 	REQUIRE(DNS_ZONE_VALID(zone));
   15259 
   15260 	LOCK_ZONE(zone);
   15261 	if (zone->xfr_acl != NULL) {
   15262 		dns_acl_detach(&zone->xfr_acl);
   15263 	}
   15264 	dns_acl_attach(acl, &zone->xfr_acl);
   15265 	UNLOCK_ZONE(zone);
   15266 }
   15267 
   15268 dns_acl_t *
   15269 dns_zone_getnotifyacl(dns_zone_t *zone) {
   15270 	REQUIRE(DNS_ZONE_VALID(zone));
   15271 
   15272 	return (zone->notify_acl);
   15273 }
   15274 
   15275 dns_acl_t *
   15276 dns_zone_getqueryacl(dns_zone_t *zone) {
   15277 	REQUIRE(DNS_ZONE_VALID(zone));
   15278 
   15279 	return (zone->query_acl);
   15280 }
   15281 
   15282 dns_acl_t *
   15283 dns_zone_getqueryonacl(dns_zone_t *zone) {
   15284 	REQUIRE(DNS_ZONE_VALID(zone));
   15285 
   15286 	return (zone->queryon_acl);
   15287 }
   15288 
   15289 dns_acl_t *
   15290 dns_zone_getupdateacl(dns_zone_t *zone) {
   15291 	REQUIRE(DNS_ZONE_VALID(zone));
   15292 
   15293 	return (zone->update_acl);
   15294 }
   15295 
   15296 dns_acl_t *
   15297 dns_zone_getforwardacl(dns_zone_t *zone) {
   15298 	REQUIRE(DNS_ZONE_VALID(zone));
   15299 
   15300 	return (zone->forward_acl);
   15301 }
   15302 
   15303 dns_acl_t *
   15304 dns_zone_getxfracl(dns_zone_t *zone) {
   15305 	REQUIRE(DNS_ZONE_VALID(zone));
   15306 
   15307 	return (zone->xfr_acl);
   15308 }
   15309 
   15310 void
   15311 dns_zone_clearupdateacl(dns_zone_t *zone) {
   15312 	REQUIRE(DNS_ZONE_VALID(zone));
   15313 
   15314 	LOCK_ZONE(zone);
   15315 	if (zone->update_acl != NULL) {
   15316 		dns_acl_detach(&zone->update_acl);
   15317 	}
   15318 	UNLOCK_ZONE(zone);
   15319 }
   15320 
   15321 void
   15322 dns_zone_clearforwardacl(dns_zone_t *zone) {
   15323 	REQUIRE(DNS_ZONE_VALID(zone));
   15324 
   15325 	LOCK_ZONE(zone);
   15326 	if (zone->forward_acl != NULL) {
   15327 		dns_acl_detach(&zone->forward_acl);
   15328 	}
   15329 	UNLOCK_ZONE(zone);
   15330 }
   15331 
   15332 void
   15333 dns_zone_clearnotifyacl(dns_zone_t *zone) {
   15334 	REQUIRE(DNS_ZONE_VALID(zone));
   15335 
   15336 	LOCK_ZONE(zone);
   15337 	if (zone->notify_acl != NULL) {
   15338 		dns_acl_detach(&zone->notify_acl);
   15339 	}
   15340 	UNLOCK_ZONE(zone);
   15341 }
   15342 
   15343 void
   15344 dns_zone_clearqueryacl(dns_zone_t *zone) {
   15345 	REQUIRE(DNS_ZONE_VALID(zone));
   15346 
   15347 	LOCK_ZONE(zone);
   15348 	if (zone->query_acl != NULL) {
   15349 		dns_acl_detach(&zone->query_acl);
   15350 	}
   15351 	UNLOCK_ZONE(zone);
   15352 }
   15353 
   15354 void
   15355 dns_zone_clearqueryonacl(dns_zone_t *zone) {
   15356 	REQUIRE(DNS_ZONE_VALID(zone));
   15357 
   15358 	LOCK_ZONE(zone);
   15359 	if (zone->queryon_acl != NULL) {
   15360 		dns_acl_detach(&zone->queryon_acl);
   15361 	}
   15362 	UNLOCK_ZONE(zone);
   15363 }
   15364 
   15365 void
   15366 dns_zone_clearxfracl(dns_zone_t *zone) {
   15367 	REQUIRE(DNS_ZONE_VALID(zone));
   15368 
   15369 	LOCK_ZONE(zone);
   15370 	if (zone->xfr_acl != NULL) {
   15371 		dns_acl_detach(&zone->xfr_acl);
   15372 	}
   15373 	UNLOCK_ZONE(zone);
   15374 }
   15375 
   15376 bool
   15377 dns_zone_getupdatedisabled(dns_zone_t *zone) {
   15378 	REQUIRE(DNS_ZONE_VALID(zone));
   15379 	return (zone->update_disabled);
   15380 }
   15381 
   15382 void
   15383 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
   15384 	REQUIRE(DNS_ZONE_VALID(zone));
   15385 	zone->update_disabled = state;
   15386 }
   15387 
   15388 bool
   15389 dns_zone_getzeronosoattl(dns_zone_t *zone) {
   15390 	REQUIRE(DNS_ZONE_VALID(zone));
   15391 	return (zone->zero_no_soa_ttl);
   15392 }
   15393 
   15394 void
   15395 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
   15396 	REQUIRE(DNS_ZONE_VALID(zone));
   15397 	zone->zero_no_soa_ttl = state;
   15398 }
   15399 
   15400 void
   15401 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
   15402 	REQUIRE(DNS_ZONE_VALID(zone));
   15403 
   15404 	zone->check_names = severity;
   15405 }
   15406 
   15407 dns_severity_t
   15408 dns_zone_getchecknames(dns_zone_t *zone) {
   15409 	REQUIRE(DNS_ZONE_VALID(zone));
   15410 
   15411 	return (zone->check_names);
   15412 }
   15413 
   15414 void
   15415 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
   15416 	REQUIRE(DNS_ZONE_VALID(zone));
   15417 
   15418 	zone->journalsize = size;
   15419 }
   15420 
   15421 int32_t
   15422 dns_zone_getjournalsize(dns_zone_t *zone) {
   15423 	REQUIRE(DNS_ZONE_VALID(zone));
   15424 
   15425 	return (zone->journalsize);
   15426 }
   15427 
   15428 static void
   15429 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15430 	isc_result_t result = ISC_R_FAILURE;
   15431 	isc_buffer_t buffer;
   15432 
   15433 	REQUIRE(buf != NULL);
   15434 	REQUIRE(length > 1U);
   15435 
   15436 	/*
   15437 	 * Leave space for terminating '\0'.
   15438 	 */
   15439 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15440 	if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
   15441 		if (dns_name_dynamic(&zone->origin)) {
   15442 			result = dns_name_totext(&zone->origin, true, &buffer);
   15443 		}
   15444 		if (result != ISC_R_SUCCESS &&
   15445 		    isc_buffer_availablelength(&buffer) >=
   15446 			    (sizeof("<UNKNOWN>") - 1))
   15447 		{
   15448 			isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15449 		}
   15450 
   15451 		if (isc_buffer_availablelength(&buffer) > 0) {
   15452 			isc_buffer_putstr(&buffer, "/");
   15453 		}
   15454 		(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   15455 	}
   15456 
   15457 	if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
   15458 	    strcmp(zone->view->name, "_default") != 0 &&
   15459 	    strlen(zone->view->name) < isc_buffer_availablelength(&buffer))
   15460 	{
   15461 		isc_buffer_putstr(&buffer, "/");
   15462 		isc_buffer_putstr(&buffer, zone->view->name);
   15463 	}
   15464 	if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) {
   15465 		isc_buffer_putstr(&buffer, " (signed)");
   15466 	}
   15467 	if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) {
   15468 		isc_buffer_putstr(&buffer, " (unsigned)");
   15469 	}
   15470 
   15471 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15472 }
   15473 
   15474 static void
   15475 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15476 	isc_result_t result = ISC_R_FAILURE;
   15477 	isc_buffer_t buffer;
   15478 
   15479 	REQUIRE(buf != NULL);
   15480 	REQUIRE(length > 1U);
   15481 
   15482 	/*
   15483 	 * Leave space for terminating '\0'.
   15484 	 */
   15485 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15486 	if (dns_name_dynamic(&zone->origin)) {
   15487 		result = dns_name_totext(&zone->origin, true, &buffer);
   15488 	}
   15489 	if (result != ISC_R_SUCCESS &&
   15490 	    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
   15491 	{
   15492 		isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15493 	}
   15494 
   15495 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15496 }
   15497 
   15498 static void
   15499 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15500 	isc_buffer_t buffer;
   15501 
   15502 	REQUIRE(buf != NULL);
   15503 	REQUIRE(length > 1U);
   15504 
   15505 	/*
   15506 	 * Leave space for terminating '\0'.
   15507 	 */
   15508 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15509 	(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   15510 
   15511 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15512 }
   15513 
   15514 static void
   15515 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15516 	isc_buffer_t buffer;
   15517 
   15518 	REQUIRE(buf != NULL);
   15519 	REQUIRE(length > 1U);
   15520 
   15521 	/*
   15522 	 * Leave space for terminating '\0'.
   15523 	 */
   15524 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15525 
   15526 	if (zone->view == NULL) {
   15527 		isc_buffer_putstr(&buffer, "_none");
   15528 	} else if (strlen(zone->view->name) <
   15529 		   isc_buffer_availablelength(&buffer)) {
   15530 		isc_buffer_putstr(&buffer, zone->view->name);
   15531 	} else {
   15532 		isc_buffer_putstr(&buffer, "_toolong");
   15533 	}
   15534 
   15535 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15536 }
   15537 
   15538 void
   15539 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
   15540 	REQUIRE(DNS_ZONE_VALID(zone));
   15541 	REQUIRE(buf != NULL);
   15542 
   15543 	LOCK_ZONE(zone);
   15544 	zone_namerd_tostr(zone, buf, length);
   15545 	UNLOCK_ZONE(zone);
   15546 }
   15547 
   15548 void
   15549 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
   15550 	REQUIRE(DNS_ZONE_VALID(zone));
   15551 	REQUIRE(buf != NULL);
   15552 	zone_name_tostr(zone, buf, length);
   15553 }
   15554 
   15555 void
   15556 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level,
   15557 	      const char *prefix, const char *fmt, va_list ap) {
   15558 	char message[4096];
   15559 	const char *zstr;
   15560 
   15561 	REQUIRE(DNS_ZONE_VALID(zone));
   15562 
   15563 	if (!isc_log_wouldlog(dns_lctx, level)) {
   15564 		return;
   15565 	}
   15566 
   15567 	vsnprintf(message, sizeof(message), fmt, ap);
   15568 
   15569 	switch (zone->type) {
   15570 	case dns_zone_key:
   15571 		zstr = "managed-keys-zone";
   15572 		break;
   15573 	case dns_zone_redirect:
   15574 		zstr = "redirect-zone";
   15575 		break;
   15576 	default:
   15577 		zstr = "zone ";
   15578 	}
   15579 
   15580 	isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level,
   15581 		      "%s%s%s%s: %s", (prefix != NULL ? prefix : ""),
   15582 		      (prefix != NULL ? ": " : ""), zstr, zone->strnamerd,
   15583 		      message);
   15584 }
   15585 
   15586 static void
   15587 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   15588 	va_list ap;
   15589 
   15590 	va_start(ap, fmt);
   15591 	dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap);
   15592 	va_end(ap);
   15593 }
   15594 
   15595 void
   15596 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level,
   15597 	      const char *fmt, ...) {
   15598 	va_list ap;
   15599 
   15600 	va_start(ap, fmt);
   15601 	dns_zone_logv(zone, category, level, NULL, fmt, ap);
   15602 	va_end(ap);
   15603 }
   15604 
   15605 void
   15606 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   15607 	va_list ap;
   15608 
   15609 	va_start(ap, fmt);
   15610 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap);
   15611 	va_end(ap);
   15612 }
   15613 
   15614 static void
   15615 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt,
   15616 	      ...) {
   15617 	int level = ISC_LOG_DEBUG(debuglevel);
   15618 	va_list ap;
   15619 
   15620 	va_start(ap, fmt);
   15621 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap);
   15622 	va_end(ap);
   15623 }
   15624 
   15625 static void
   15626 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   15627 	va_list ap;
   15628 
   15629 	va_start(ap, fmt);
   15630 	dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap);
   15631 	va_end(ap);
   15632 }
   15633 
   15634 static int
   15635 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) {
   15636 	isc_result_t result;
   15637 	dns_name_t *name;
   15638 	dns_rdataset_t *curr;
   15639 	int count = 0;
   15640 
   15641 	result = dns_message_firstname(msg, section);
   15642 	while (result == ISC_R_SUCCESS) {
   15643 		name = NULL;
   15644 		dns_message_currentname(msg, section, &name);
   15645 
   15646 		for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
   15647 		     curr = ISC_LIST_PREV(curr, link))
   15648 		{
   15649 			if (curr->type == type) {
   15650 				count++;
   15651 			}
   15652 		}
   15653 		result = dns_message_nextname(msg, section);
   15654 	}
   15655 
   15656 	return (count);
   15657 }
   15658 
   15659 void
   15660 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
   15661 	REQUIRE(DNS_ZONE_VALID(zone));
   15662 
   15663 	zone->maxxfrin = maxxfrin;
   15664 }
   15665 
   15666 uint32_t
   15667 dns_zone_getmaxxfrin(dns_zone_t *zone) {
   15668 	REQUIRE(DNS_ZONE_VALID(zone));
   15669 
   15670 	return (zone->maxxfrin);
   15671 }
   15672 
   15673 void
   15674 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
   15675 	REQUIRE(DNS_ZONE_VALID(zone));
   15676 	zone->maxxfrout = maxxfrout;
   15677 }
   15678 
   15679 uint32_t
   15680 dns_zone_getmaxxfrout(dns_zone_t *zone) {
   15681 	REQUIRE(DNS_ZONE_VALID(zone));
   15682 
   15683 	return (zone->maxxfrout);
   15684 }
   15685 
   15686 dns_zonetype_t
   15687 dns_zone_gettype(dns_zone_t *zone) {
   15688 	REQUIRE(DNS_ZONE_VALID(zone));
   15689 
   15690 	return (zone->type);
   15691 }
   15692 
   15693 const char *
   15694 dns_zonetype_name(dns_zonetype_t type) {
   15695 	switch (type) {
   15696 	case dns_zone_none:
   15697 		return ("none");
   15698 	case dns_zone_master:
   15699 		return ("primary");
   15700 	case dns_zone_slave:
   15701 		return ("secondary");
   15702 	case dns_zone_mirror:
   15703 		return ("mirror");
   15704 	case dns_zone_stub:
   15705 		return ("stub");
   15706 	case dns_zone_staticstub:
   15707 		return ("static-stub");
   15708 	case dns_zone_key:
   15709 		return ("key");
   15710 	case dns_zone_dlz:
   15711 		return ("dlz");
   15712 	case dns_zone_redirect:
   15713 		return ("redirect");
   15714 	default:
   15715 		return ("unknown");
   15716 	}
   15717 }
   15718 
   15719 dns_zonetype_t
   15720 dns_zone_getredirecttype(dns_zone_t *zone) {
   15721 	REQUIRE(DNS_ZONE_VALID(zone));
   15722 	REQUIRE(zone->type == dns_zone_redirect);
   15723 
   15724 	return (zone->masters == NULL ? dns_zone_master : dns_zone_slave);
   15725 }
   15726 
   15727 dns_name_t *
   15728 dns_zone_getorigin(dns_zone_t *zone) {
   15729 	REQUIRE(DNS_ZONE_VALID(zone));
   15730 
   15731 	return (&zone->origin);
   15732 }
   15733 
   15734 void
   15735 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
   15736 	REQUIRE(DNS_ZONE_VALID(zone));
   15737 
   15738 	LOCK_ZONE(zone);
   15739 	if (zone->task != NULL) {
   15740 		isc_task_detach(&zone->task);
   15741 	}
   15742 	isc_task_attach(task, &zone->task);
   15743 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   15744 	if (zone->db != NULL) {
   15745 		dns_db_settask(zone->db, zone->task);
   15746 	}
   15747 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15748 	UNLOCK_ZONE(zone);
   15749 }
   15750 
   15751 void
   15752 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
   15753 	REQUIRE(DNS_ZONE_VALID(zone));
   15754 	isc_task_attach(zone->task, target);
   15755 }
   15756 
   15757 void
   15758 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
   15759 	REQUIRE(DNS_ZONE_VALID(zone));
   15760 
   15761 	if (idlein == 0) {
   15762 		idlein = DNS_DEFAULT_IDLEIN;
   15763 	}
   15764 	zone->idlein = idlein;
   15765 }
   15766 
   15767 uint32_t
   15768 dns_zone_getidlein(dns_zone_t *zone) {
   15769 	REQUIRE(DNS_ZONE_VALID(zone));
   15770 
   15771 	return (zone->idlein);
   15772 }
   15773 
   15774 void
   15775 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
   15776 	REQUIRE(DNS_ZONE_VALID(zone));
   15777 
   15778 	zone->idleout = idleout;
   15779 }
   15780 
   15781 uint32_t
   15782 dns_zone_getidleout(dns_zone_t *zone) {
   15783 	REQUIRE(DNS_ZONE_VALID(zone));
   15784 
   15785 	return (zone->idleout);
   15786 }
   15787 
   15788 static void
   15789 notify_done(isc_task_t *task, isc_event_t *event) {
   15790 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   15791 	dns_notify_t *notify;
   15792 	isc_result_t result;
   15793 	dns_message_t *message = NULL;
   15794 	isc_buffer_t buf;
   15795 	char rcode[128];
   15796 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   15797 
   15798 	UNUSED(task);
   15799 
   15800 	notify = event->ev_arg;
   15801 	REQUIRE(DNS_NOTIFY_VALID(notify));
   15802 	INSIST(task == notify->zone->task);
   15803 
   15804 	isc_buffer_init(&buf, rcode, sizeof(rcode));
   15805 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   15806 	dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE,
   15807 			   &message);
   15808 
   15809 	result = revent->result;
   15810 	if (result == ISC_R_SUCCESS) {
   15811 		result =
   15812 			dns_request_getresponse(revent->request, message,
   15813 						DNS_MESSAGEPARSE_PRESERVEORDER);
   15814 	}
   15815 	if (result == ISC_R_SUCCESS) {
   15816 		result = dns_rcode_totext(message->rcode, &buf);
   15817 	}
   15818 	if (result == ISC_R_SUCCESS) {
   15819 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   15820 			   "notify response from %s: %.*s", addrbuf,
   15821 			   (int)buf.used, rcode);
   15822 	} else {
   15823 		notify_log(notify->zone, ISC_LOG_DEBUG(2),
   15824 			   "notify to %s failed: %s", addrbuf,
   15825 			   dns_result_totext(result));
   15826 	}
   15827 
   15828 	/*
   15829 	 * Old bind's return formerr if they see a soa record.	Retry w/o
   15830 	 * the soa if we see a formerr and had sent a SOA.
   15831 	 */
   15832 	isc_event_free(&event);
   15833 	if (message->rcode == dns_rcode_formerr &&
   15834 	    (notify->flags & DNS_NOTIFY_NOSOA) == 0)
   15835 	{
   15836 		bool startup;
   15837 
   15838 		notify->flags |= DNS_NOTIFY_NOSOA;
   15839 		dns_request_destroy(&notify->request);
   15840 		startup = (notify->flags & DNS_NOTIFY_STARTUP);
   15841 		result = notify_send_queue(notify, startup);
   15842 		if (result != ISC_R_SUCCESS) {
   15843 			notify_destroy(notify, false);
   15844 		}
   15845 	} else {
   15846 		if (result == ISC_R_TIMEDOUT) {
   15847 			notify_log(notify->zone, ISC_LOG_DEBUG(1),
   15848 				   "notify to %s: retries exceeded", addrbuf);
   15849 		}
   15850 		notify_destroy(notify, false);
   15851 	}
   15852 	dns_message_detach(&message);
   15853 }
   15854 
   15855 struct secure_event {
   15856 	isc_event_t e;
   15857 	dns_db_t *db;
   15858 	uint32_t serial;
   15859 };
   15860 
   15861 static void
   15862 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
   15863 	UNUSED(arg);
   15864 	dns_zone_log(zone, level, "%s", message);
   15865 }
   15866 
   15867 static isc_result_t
   15868 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
   15869 		    uint32_t start, uint32_t end, dns_difftuple_t **soatuplep,
   15870 		    dns_diff_t *diff) {
   15871 	isc_result_t result;
   15872 	dns_difftuple_t *tuple = NULL;
   15873 	dns_diffop_t op = DNS_DIFFOP_ADD;
   15874 	int n_soa = 0;
   15875 
   15876 	REQUIRE(soatuplep != NULL);
   15877 
   15878 	if (start == end) {
   15879 		return (DNS_R_UNCHANGED);
   15880 	}
   15881 
   15882 	CHECK(dns_journal_iter_init(journal, start, end, NULL));
   15883 	for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS;
   15884 	     result = dns_journal_next_rr(journal))
   15885 	{
   15886 		dns_name_t *name = NULL;
   15887 		uint32_t ttl;
   15888 		dns_rdata_t *rdata = NULL;
   15889 		dns_journal_current_rr(journal, &name, &ttl, &rdata);
   15890 
   15891 		if (rdata->type == dns_rdatatype_soa) {
   15892 			n_soa++;
   15893 			if (n_soa == 2) {
   15894 				/*
   15895 				 * Save the latest raw SOA record.
   15896 				 */
   15897 				if (*soatuplep != NULL) {
   15898 					dns_difftuple_free(soatuplep);
   15899 				}
   15900 				CHECK(dns_difftuple_create(
   15901 					diff->mctx, DNS_DIFFOP_ADD, name, ttl,
   15902 					rdata, soatuplep));
   15903 			}
   15904 			if (n_soa == 3) {
   15905 				n_soa = 1;
   15906 			}
   15907 			continue;
   15908 		}
   15909 
   15910 		/* Sanity. */
   15911 		if (n_soa == 0) {
   15912 			dns_zone_log(raw, ISC_LOG_ERROR,
   15913 				     "corrupt journal file: '%s'\n",
   15914 				     raw->journal);
   15915 			return (ISC_R_FAILURE);
   15916 		}
   15917 
   15918 		if (zone->privatetype != 0 && rdata->type == zone->privatetype)
   15919 		{
   15920 			continue;
   15921 		}
   15922 
   15923 		if (rdata->type == dns_rdatatype_nsec ||
   15924 		    rdata->type == dns_rdatatype_rrsig ||
   15925 		    rdata->type == dns_rdatatype_nsec3 ||
   15926 		    rdata->type == dns_rdatatype_dnskey ||
   15927 		    rdata->type == dns_rdatatype_nsec3param)
   15928 		{
   15929 			continue;
   15930 		}
   15931 
   15932 		op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
   15933 
   15934 		CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
   15935 					   &tuple));
   15936 		dns_diff_appendminimal(diff, &tuple);
   15937 	}
   15938 	if (result == ISC_R_NOMORE) {
   15939 		result = ISC_R_SUCCESS;
   15940 	}
   15941 
   15942 failure:
   15943 	return (result);
   15944 }
   15945 
   15946 static isc_result_t
   15947 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
   15948 	       dns_dbversion_t *secver, dns_difftuple_t **soatuple,
   15949 	       dns_diff_t *diff) {
   15950 	isc_result_t result;
   15951 	dns_db_t *rawdb = NULL;
   15952 	dns_dbversion_t *rawver = NULL;
   15953 	dns_difftuple_t *tuple = NULL, *next;
   15954 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   15955 	dns_rdata_soa_t oldsoa, newsoa;
   15956 
   15957 	REQUIRE(DNS_ZONE_VALID(seczone));
   15958 	REQUIRE(soatuple != NULL && *soatuple == NULL);
   15959 
   15960 	if (!seczone->sourceserialset) {
   15961 		return (DNS_R_UNCHANGED);
   15962 	}
   15963 
   15964 	dns_db_attach(raw->db, &rawdb);
   15965 	dns_db_currentversion(rawdb, &rawver);
   15966 	result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
   15967 	dns_db_closeversion(rawdb, &rawver, false);
   15968 	dns_db_detach(&rawdb);
   15969 
   15970 	if (result != ISC_R_SUCCESS) {
   15971 		return (result);
   15972 	}
   15973 
   15974 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) {
   15975 		next = ISC_LIST_NEXT(tuple, link);
   15976 		if (tuple->rdata.type == dns_rdatatype_nsec ||
   15977 		    tuple->rdata.type == dns_rdatatype_rrsig ||
   15978 		    tuple->rdata.type == dns_rdatatype_dnskey ||
   15979 		    tuple->rdata.type == dns_rdatatype_nsec3 ||
   15980 		    tuple->rdata.type == dns_rdatatype_nsec3param)
   15981 		{
   15982 			ISC_LIST_UNLINK(diff->tuples, tuple, link);
   15983 			dns_difftuple_free(&tuple);
   15984 			continue;
   15985 		}
   15986 		if (tuple->rdata.type == dns_rdatatype_soa) {
   15987 			if (tuple->op == DNS_DIFFOP_DEL) {
   15988 				INSIST(oldtuple == NULL);
   15989 				oldtuple = tuple;
   15990 			}
   15991 			if (tuple->op == DNS_DIFFOP_ADD) {
   15992 				INSIST(newtuple == NULL);
   15993 				newtuple = tuple;
   15994 			}
   15995 		}
   15996 	}
   15997 
   15998 	if (oldtuple != NULL && newtuple != NULL) {
   15999 		result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
   16000 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16001 
   16002 		result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
   16003 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16004 
   16005 		/*
   16006 		 * If the SOA records are the same except for the serial
   16007 		 * remove them from the diff.
   16008 		 */
   16009 		if (oldsoa.refresh == newsoa.refresh &&
   16010 		    oldsoa.retry == newsoa.retry &&
   16011 		    oldsoa.minimum == newsoa.minimum &&
   16012 		    oldsoa.expire == newsoa.expire &&
   16013 		    dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
   16014 		    dns_name_equal(&oldsoa.contact, &newsoa.contact))
   16015 		{
   16016 			ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   16017 			dns_difftuple_free(&oldtuple);
   16018 			ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   16019 			dns_difftuple_free(&newtuple);
   16020 		}
   16021 	}
   16022 
   16023 	if (ISC_LIST_EMPTY(diff->tuples)) {
   16024 		return (DNS_R_UNCHANGED);
   16025 	}
   16026 
   16027 	/*
   16028 	 * If there are still SOA records in the diff they can now be removed
   16029 	 * saving the new SOA record.
   16030 	 */
   16031 	if (oldtuple != NULL) {
   16032 		ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   16033 		dns_difftuple_free(&oldtuple);
   16034 	}
   16035 
   16036 	if (newtuple != NULL) {
   16037 		ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   16038 		*soatuple = newtuple;
   16039 	}
   16040 
   16041 	return (ISC_R_SUCCESS);
   16042 }
   16043 
   16044 static void
   16045 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
   16046 	static char me[] = "receive_secure_serial";
   16047 	isc_result_t result = ISC_R_SUCCESS;
   16048 	dns_journal_t *rjournal = NULL;
   16049 	dns_journal_t *sjournal = NULL;
   16050 	uint32_t start, end;
   16051 	dns_zone_t *zone;
   16052 	dns_difftuple_t *tuple = NULL, *soatuple = NULL;
   16053 	dns_update_log_t log = { update_log_cb, NULL };
   16054 	uint32_t newserial = 0, desired = 0;
   16055 	isc_time_t timenow;
   16056 	int level = ISC_LOG_ERROR;
   16057 
   16058 	UNUSED(task);
   16059 
   16060 	zone = event->ev_arg;
   16061 	end = ((struct secure_event *)event)->serial;
   16062 
   16063 	ENTER;
   16064 
   16065 	LOCK_ZONE(zone);
   16066 
   16067 	/*
   16068 	 * If we are already processing a receive secure serial event
   16069 	 * for the zone, just queue the new one and exit.
   16070 	 */
   16071 	if (zone->rss_event != NULL && zone->rss_event != event) {
   16072 		ISC_LIST_APPEND(zone->rss_events, event, ev_link);
   16073 		UNLOCK_ZONE(zone);
   16074 		return;
   16075 	}
   16076 
   16077 nextevent:
   16078 	if (zone->rss_event != NULL) {
   16079 		INSIST(zone->rss_event == event);
   16080 		UNLOCK_ZONE(zone);
   16081 	} else {
   16082 		zone->rss_event = event;
   16083 		dns_diff_init(zone->mctx, &zone->rss_diff);
   16084 
   16085 		/*
   16086 		 * zone->db may be NULL, if the load from disk failed.
   16087 		 */
   16088 		result = ISC_R_SUCCESS;
   16089 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16090 		if (zone->db != NULL) {
   16091 			dns_db_attach(zone->db, &zone->rss_db);
   16092 		} else {
   16093 			result = ISC_R_FAILURE;
   16094 		}
   16095 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16096 
   16097 		if (result == ISC_R_SUCCESS && zone->raw != NULL) {
   16098 			dns_zone_attach(zone->raw, &zone->rss_raw);
   16099 		} else {
   16100 			result = ISC_R_FAILURE;
   16101 		}
   16102 
   16103 		UNLOCK_ZONE(zone);
   16104 
   16105 		CHECK(result);
   16106 
   16107 		/*
   16108 		 * We first attempt to sync the raw zone to the secure zone
   16109 		 * by using the raw zone's journal, applying all the deltas
   16110 		 * from the latest source-serial of the secure zone up to
   16111 		 * the current serial number of the raw zone.
   16112 		 *
   16113 		 * If that fails, then we'll fall back to a direct comparison
   16114 		 * between raw and secure zones.
   16115 		 */
   16116 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16117 				       zone->rss_raw->journal,
   16118 				       DNS_JOURNAL_WRITE, &rjournal));
   16119 
   16120 		result = dns_journal_open(zone->mctx, zone->journal,
   16121 					  DNS_JOURNAL_READ, &sjournal);
   16122 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   16123 			goto failure;
   16124 		}
   16125 
   16126 		if (!dns_journal_get_sourceserial(rjournal, &start)) {
   16127 			start = dns_journal_first_serial(rjournal);
   16128 			dns_journal_set_sourceserial(rjournal, start);
   16129 		}
   16130 		if (sjournal != NULL) {
   16131 			uint32_t serial;
   16132 			/*
   16133 			 * We read the secure journal first, if that
   16134 			 * exists use its value provided it is greater
   16135 			 * that from the raw journal.
   16136 			 */
   16137 			if (dns_journal_get_sourceserial(sjournal, &serial)) {
   16138 				if (isc_serial_gt(serial, start)) {
   16139 					start = serial;
   16140 				}
   16141 			}
   16142 			dns_journal_destroy(&sjournal);
   16143 		}
   16144 
   16145 		dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
   16146 		CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
   16147 
   16148 		/*
   16149 		 * Try to apply diffs from the raw zone's journal to the secure
   16150 		 * zone.  If that fails, we recover by syncing up the databases
   16151 		 * directly.
   16152 		 */
   16153 		result = sync_secure_journal(zone, zone->rss_raw, rjournal,
   16154 					     start, end, &soatuple,
   16155 					     &zone->rss_diff);
   16156 		if (result == DNS_R_UNCHANGED) {
   16157 			level = ISC_LOG_INFO;
   16158 			goto failure;
   16159 		} else if (result != ISC_R_SUCCESS) {
   16160 			CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
   16161 					     zone->rss_oldver, &soatuple,
   16162 					     &zone->rss_diff));
   16163 		}
   16164 
   16165 		CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
   16166 				     zone->rss_newver));
   16167 
   16168 		if (soatuple != NULL) {
   16169 			uint32_t oldserial;
   16170 
   16171 			CHECK(dns_db_createsoatuple(
   16172 				zone->rss_db, zone->rss_oldver,
   16173 				zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple));
   16174 			oldserial = dns_soa_getserial(&tuple->rdata);
   16175 			newserial = desired =
   16176 				dns_soa_getserial(&soatuple->rdata);
   16177 			if (!isc_serial_gt(newserial, oldserial)) {
   16178 				newserial = oldserial + 1;
   16179 				if (newserial == 0) {
   16180 					newserial++;
   16181 				}
   16182 				dns_soa_setserial(newserial, &soatuple->rdata);
   16183 			}
   16184 			CHECK(do_one_tuple(&tuple, zone->rss_db,
   16185 					   zone->rss_newver, &zone->rss_diff));
   16186 			CHECK(do_one_tuple(&soatuple, zone->rss_db,
   16187 					   zone->rss_newver, &zone->rss_diff));
   16188 		} else {
   16189 			CHECK(update_soa_serial(zone, zone->rss_db,
   16190 						zone->rss_newver,
   16191 						&zone->rss_diff, zone->mctx,
   16192 						zone->updatemethod));
   16193 		}
   16194 	}
   16195 	result = dns_update_signaturesinc(
   16196 		&log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver,
   16197 		&zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state);
   16198 	if (result == DNS_R_CONTINUE) {
   16199 		if (rjournal != NULL) {
   16200 			dns_journal_destroy(&rjournal);
   16201 		}
   16202 		isc_task_send(task, &event);
   16203 		return;
   16204 	}
   16205 	/*
   16206 	 * If something went wrong while trying to update the secure zone and
   16207 	 * the latter was already signed before, do not apply raw zone deltas
   16208 	 * to it as that would break existing DNSSEC signatures.  However, if
   16209 	 * the secure zone was not yet signed (e.g. because no signing keys
   16210 	 * were created for it), commence applying raw zone deltas to it so
   16211 	 * that contents of the raw zone and the secure zone are kept in sync.
   16212 	 */
   16213 	if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
   16214 		goto failure;
   16215 	}
   16216 
   16217 	if (rjournal == NULL) {
   16218 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16219 				       zone->rss_raw->journal,
   16220 				       DNS_JOURNAL_WRITE, &rjournal));
   16221 	}
   16222 	CHECK(zone_journal(zone, &zone->rss_diff, &end,
   16223 			   "receive_secure_serial"));
   16224 
   16225 	dns_journal_set_sourceserial(rjournal, end);
   16226 	dns_journal_commit(rjournal);
   16227 
   16228 	LOCK_ZONE(zone);
   16229 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   16230 
   16231 	zone->sourceserial = end;
   16232 	zone->sourceserialset = true;
   16233 	zone_needdump(zone, DNS_DUMP_DELAY);
   16234 
   16235 	/*
   16236 	 * Set resign time to make sure it is set to the earliest
   16237 	 * signature expiration.
   16238 	 */
   16239 	set_resigntime(zone);
   16240 	TIME_NOW(&timenow);
   16241 	zone_settimer(zone, &timenow);
   16242 	UNLOCK_ZONE(zone);
   16243 
   16244 	dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false);
   16245 	dns_db_closeversion(zone->rss_db, &zone->rss_newver, true);
   16246 
   16247 	if (newserial != 0) {
   16248 		dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
   16249 			     newserial, desired);
   16250 	}
   16251 
   16252 failure:
   16253 	isc_event_free(&zone->rss_event);
   16254 	event = ISC_LIST_HEAD(zone->rss_events);
   16255 
   16256 	if (zone->rss_raw != NULL) {
   16257 		dns_zone_detach(&zone->rss_raw);
   16258 	}
   16259 	if (result != ISC_R_SUCCESS) {
   16260 		LOCK_ZONE(zone);
   16261 		set_resigntime(zone);
   16262 		TIME_NOW(&timenow);
   16263 		zone_settimer(zone, &timenow);
   16264 		UNLOCK_ZONE(zone);
   16265 		dns_zone_log(zone, level, "receive_secure_serial: %s",
   16266 			     dns_result_totext(result));
   16267 	}
   16268 	if (tuple != NULL) {
   16269 		dns_difftuple_free(&tuple);
   16270 	}
   16271 	if (soatuple != NULL) {
   16272 		dns_difftuple_free(&soatuple);
   16273 	}
   16274 	if (zone->rss_db != NULL) {
   16275 		if (zone->rss_oldver != NULL) {
   16276 			dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
   16277 					    false);
   16278 		}
   16279 		if (zone->rss_newver != NULL) {
   16280 			dns_db_closeversion(zone->rss_db, &zone->rss_newver,
   16281 					    false);
   16282 		}
   16283 		dns_db_detach(&zone->rss_db);
   16284 	}
   16285 	INSIST(zone->rss_oldver == NULL);
   16286 	INSIST(zone->rss_newver == NULL);
   16287 	if (rjournal != NULL) {
   16288 		dns_journal_destroy(&rjournal);
   16289 	}
   16290 	dns_diff_clear(&zone->rss_diff);
   16291 
   16292 	if (event != NULL) {
   16293 		LOCK_ZONE(zone);
   16294 		isc_refcount_decrement(&zone->irefs);
   16295 		ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
   16296 		goto nextevent;
   16297 	}
   16298 
   16299 	event = ISC_LIST_HEAD(zone->rss_post);
   16300 	while (event != NULL) {
   16301 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   16302 		rss_post(zone, event);
   16303 		event = ISC_LIST_HEAD(zone->rss_post);
   16304 	}
   16305 
   16306 	dns_zone_idetach(&zone);
   16307 }
   16308 
   16309 static isc_result_t
   16310 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) {
   16311 	isc_event_t *e;
   16312 	dns_zone_t *dummy = NULL;
   16313 
   16314 	e = isc_event_allocate(zone->secure->mctx, zone,
   16315 			       DNS_EVENT_ZONESECURESERIAL,
   16316 			       receive_secure_serial, zone->secure,
   16317 			       sizeof(struct secure_event));
   16318 	((struct secure_event *)e)->serial = serial;
   16319 	INSIST(LOCKED_ZONE(zone->secure));
   16320 	zone_iattach(zone->secure, &dummy);
   16321 	isc_task_send(zone->secure->task, &e);
   16322 
   16323 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   16324 	return (ISC_R_SUCCESS);
   16325 }
   16326 
   16327 static isc_result_t
   16328 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   16329 	       dns_rdataset_t *rdataset, uint32_t oldserial) {
   16330 	dns_rdata_soa_t soa;
   16331 	dns_rdata_t rdata = DNS_RDATA_INIT;
   16332 	dns_rdatalist_t temprdatalist;
   16333 	dns_rdataset_t temprdataset;
   16334 	isc_buffer_t b;
   16335 	isc_result_t result;
   16336 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   16337 	dns_fixedname_t fixed;
   16338 	dns_name_t *name;
   16339 
   16340 	result = dns_rdataset_first(rdataset);
   16341 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16342 	dns_rdataset_current(rdataset, &rdata);
   16343 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   16344 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16345 
   16346 	if (isc_serial_gt(soa.serial, oldserial)) {
   16347 		return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
   16348 					   NULL));
   16349 	}
   16350 	/*
   16351 	 * Always bump the serial.
   16352 	 */
   16353 	oldserial++;
   16354 	if (oldserial == 0) {
   16355 		oldserial++;
   16356 	}
   16357 	soa.serial = oldserial;
   16358 
   16359 	/*
   16360 	 * Construct a replacement rdataset.
   16361 	 */
   16362 	dns_rdata_reset(&rdata);
   16363 	isc_buffer_init(&b, buf, sizeof(buf));
   16364 	result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
   16365 				      dns_rdatatype_soa, &soa, &b);
   16366 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16367 	dns_rdatalist_init(&temprdatalist);
   16368 	temprdatalist.rdclass = rdata.rdclass;
   16369 	temprdatalist.type = rdata.type;
   16370 	temprdatalist.ttl = rdataset->ttl;
   16371 	ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
   16372 
   16373 	dns_rdataset_init(&temprdataset);
   16374 	result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
   16375 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16376 
   16377 	name = dns_fixedname_initname(&fixed);
   16378 	result = dns_db_nodefullname(db, node, name);
   16379 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16380 	dns_rdataset_getownercase(rdataset, name);
   16381 	dns_rdataset_setownercase(&temprdataset, name);
   16382 	return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 0,
   16383 				   NULL));
   16384 }
   16385 
   16386 /*
   16387  * This function should populate an nsec3paramlist_t with the
   16388  * nsecparam_t data from a zone.
   16389  */
   16390 static isc_result_t
   16391 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
   16392 	isc_result_t result;
   16393 	dns_dbnode_t *node = NULL;
   16394 	dns_rdataset_t rdataset, prdataset;
   16395 	dns_dbversion_t *version = NULL;
   16396 	nsec3param_t *nsec3param = NULL;
   16397 	nsec3param_t *nsec3p = NULL;
   16398 	nsec3param_t *next;
   16399 	dns_db_t *db = NULL;
   16400 	unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   16401 
   16402 	REQUIRE(DNS_ZONE_VALID(zone));
   16403 	REQUIRE(nsec3list != NULL);
   16404 	REQUIRE(ISC_LIST_EMPTY(*nsec3list));
   16405 
   16406 	dns_rdataset_init(&rdataset);
   16407 	dns_rdataset_init(&prdataset);
   16408 
   16409 	dns_db_attach(zone->db, &db);
   16410 	CHECK(dns_db_getoriginnode(db, &node));
   16411 
   16412 	dns_db_currentversion(db, &version);
   16413 	result = dns_db_findrdataset(db, node, version,
   16414 				     dns_rdatatype_nsec3param,
   16415 				     dns_rdatatype_none, 0, &rdataset, NULL);
   16416 
   16417 	if (result != ISC_R_SUCCESS) {
   16418 		goto getprivate;
   16419 	}
   16420 
   16421 	/*
   16422 	 * Walk nsec3param rdataset making a list of parameters (note that
   16423 	 * multiple simultaneous nsec3 chains are annoyingly legal -- this
   16424 	 * is why we use an nsec3list, even though we will usually only
   16425 	 * have one).
   16426 	 */
   16427 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   16428 	     result = dns_rdataset_next(&rdataset))
   16429 	{
   16430 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16431 		dns_rdata_t private = DNS_RDATA_INIT;
   16432 
   16433 		dns_rdataset_current(&rdataset, &rdata);
   16434 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16435 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16436 			      "looping through nsec3param data");
   16437 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   16438 		ISC_LINK_INIT(nsec3param, link);
   16439 
   16440 		/*
   16441 		 * now transfer the data from the rdata to
   16442 		 * the nsec3param
   16443 		 */
   16444 		dns_nsec3param_toprivate(&rdata, &private, zone->privatetype,
   16445 					 nsec3param->data,
   16446 					 sizeof(nsec3param->data));
   16447 		nsec3param->length = private.length;
   16448 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   16449 	}
   16450 
   16451 getprivate:
   16452 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   16453 				     dns_rdatatype_none, 0, &prdataset, NULL);
   16454 	if (result != ISC_R_SUCCESS) {
   16455 		goto done;
   16456 	}
   16457 
   16458 	/*
   16459 	 * walk private type records, converting them to nsec3 parameters
   16460 	 * using dns_nsec3param_fromprivate(), do the right thing based on
   16461 	 * CREATE and REMOVE flags
   16462 	 */
   16463 	for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS;
   16464 	     result = dns_rdataset_next(&prdataset))
   16465 	{
   16466 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16467 		dns_rdata_t private = DNS_RDATA_INIT;
   16468 
   16469 		dns_rdataset_current(&prdataset, &private);
   16470 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16471 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16472 			      "looping through nsec3param private data");
   16473 
   16474 		/*
   16475 		 * Do we have a valid private record?
   16476 		 */
   16477 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   16478 						sizeof(buf))) {
   16479 			continue;
   16480 		}
   16481 
   16482 		/*
   16483 		 * Remove any NSEC3PARAM records scheduled to be removed.
   16484 		 */
   16485 		if (NSEC3REMOVE(rdata.data[1])) {
   16486 			/*
   16487 			 * Zero out the flags.
   16488 			 */
   16489 			rdata.data[1] = 0;
   16490 
   16491 			for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL;
   16492 			     nsec3p = next) {
   16493 				next = ISC_LIST_NEXT(nsec3p, link);
   16494 
   16495 				if (nsec3p->length == rdata.length + 1 &&
   16496 				    memcmp(rdata.data, nsec3p->data + 1,
   16497 					   nsec3p->length - 1) == 0)
   16498 				{
   16499 					ISC_LIST_UNLINK(*nsec3list, nsec3p,
   16500 							link);
   16501 					isc_mem_put(zone->mctx, nsec3p,
   16502 						    sizeof(nsec3param_t));
   16503 				}
   16504 			}
   16505 			continue;
   16506 		}
   16507 
   16508 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   16509 		ISC_LINK_INIT(nsec3param, link);
   16510 
   16511 		/*
   16512 		 * Copy the remaining private records so the nsec/nsec3
   16513 		 * chain gets created.
   16514 		 */
   16515 		INSIST(private.length <= sizeof(nsec3param->data));
   16516 		memmove(nsec3param->data, private.data, private.length);
   16517 		nsec3param->length = private.length;
   16518 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   16519 	}
   16520 
   16521 done:
   16522 	if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) {
   16523 		result = ISC_R_SUCCESS;
   16524 	}
   16525 
   16526 failure:
   16527 	if (node != NULL) {
   16528 		dns_db_detachnode(db, &node);
   16529 	}
   16530 	if (version != NULL) {
   16531 		dns_db_closeversion(db, &version, false);
   16532 	}
   16533 	if (db != NULL) {
   16534 		dns_db_detach(&db);
   16535 	}
   16536 	if (dns_rdataset_isassociated(&rdataset)) {
   16537 		dns_rdataset_disassociate(&rdataset);
   16538 	}
   16539 	if (dns_rdataset_isassociated(&prdataset)) {
   16540 		dns_rdataset_disassociate(&prdataset);
   16541 	}
   16542 	return (result);
   16543 }
   16544 
   16545 /*
   16546  * Populate new zone db with private type records found by save_nsec3param().
   16547  */
   16548 static isc_result_t
   16549 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   16550 		   nsec3paramlist_t *nsec3list) {
   16551 	isc_result_t result = ISC_R_SUCCESS;
   16552 	dns_diff_t diff;
   16553 	dns_rdata_t rdata;
   16554 	nsec3param_t *nsec3p = NULL;
   16555 	nsec3param_t *next;
   16556 
   16557 	REQUIRE(DNS_ZONE_VALID(zone));
   16558 	REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
   16559 
   16560 	dns_diff_init(zone->mctx, &diff);
   16561 
   16562 	/*
   16563 	 * Loop through the list of private-type records, set the INITIAL
   16564 	 * and CREATE flags, and the add the record to the apex of the tree
   16565 	 * in db.
   16566 	 */
   16567 	for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next)
   16568 	{
   16569 		next = ISC_LIST_NEXT(nsec3p, link);
   16570 		dns_rdata_init(&rdata);
   16571 		nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
   16572 		rdata.length = nsec3p->length;
   16573 		rdata.data = nsec3p->data;
   16574 		rdata.type = zone->privatetype;
   16575 		rdata.rdclass = zone->rdclass;
   16576 		result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
   16577 				       &zone->origin, 0, &rdata);
   16578 		if (result != ISC_R_SUCCESS) {
   16579 			break;
   16580 		}
   16581 	}
   16582 
   16583 	dns_diff_clear(&diff);
   16584 	return (result);
   16585 }
   16586 
   16587 static isc_result_t
   16588 copy_non_dnssec_records(dns_zone_t *zone, dns_db_t *db, dns_db_t *version,
   16589 			dns_db_t *rawdb, dns_dbiterator_t *dbiterator,
   16590 			unsigned int *oldserial) {
   16591 	dns_dbnode_t *rawnode = NULL, *node = NULL;
   16592 	dns_fixedname_t fixed;
   16593 	dns_name_t *name = dns_fixedname_initname(&fixed);
   16594 	dns_rdataset_t rdataset;
   16595 	dns_rdatasetiter_t *rdsit = NULL;
   16596 	isc_result_t result;
   16597 
   16598 	result = dns_dbiterator_current(dbiterator, &rawnode, name);
   16599 	if (result != ISC_R_SUCCESS) {
   16600 		return (ISC_R_SUCCESS);
   16601 	}
   16602 
   16603 	dns_dbiterator_pause(dbiterator);
   16604 
   16605 	result = dns_db_findnode(db, name, true, &node);
   16606 	if (result != ISC_R_SUCCESS) {
   16607 		goto cleanup;
   16608 	}
   16609 
   16610 	result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
   16611 	if (result != ISC_R_SUCCESS) {
   16612 		goto cleanup;
   16613 	}
   16614 
   16615 	dns_rdataset_init(&rdataset);
   16616 
   16617 	for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS;
   16618 	     result = dns_rdatasetiter_next(rdsit))
   16619 	{
   16620 		dns_rdatasetiter_current(rdsit, &rdataset);
   16621 		if (rdataset.type == dns_rdatatype_nsec ||
   16622 		    rdataset.type == dns_rdatatype_rrsig ||
   16623 		    rdataset.type == dns_rdatatype_nsec3 ||
   16624 		    rdataset.type == dns_rdatatype_dnskey ||
   16625 		    rdataset.type == dns_rdatatype_nsec3param)
   16626 		{
   16627 			/*
   16628 			 * Allow DNSSEC records with dnssec-policy.
   16629 			 * WMM: Perhaps add config option for it.
   16630 			 */
   16631 			if (!dns_zone_use_kasp(zone)) {
   16632 				dns_rdataset_disassociate(&rdataset);
   16633 				continue;
   16634 			}
   16635 		}
   16636 		if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) {
   16637 			result = checkandaddsoa(db, node, version, &rdataset,
   16638 						*oldserial);
   16639 		} else {
   16640 			result = dns_db_addrdataset(db, node, version, 0,
   16641 						    &rdataset, 0, NULL);
   16642 		}
   16643 		dns_rdataset_disassociate(&rdataset);
   16644 		if (result != ISC_R_SUCCESS) {
   16645 			goto cleanup;
   16646 		}
   16647 	}
   16648 	if (result == ISC_R_NOMORE) {
   16649 		result = ISC_R_SUCCESS;
   16650 	}
   16651 
   16652 cleanup:
   16653 	if (rdsit != NULL) {
   16654 		dns_rdatasetiter_destroy(&rdsit);
   16655 	}
   16656 	if (rawnode) {
   16657 		dns_db_detachnode(rawdb, &rawnode);
   16658 	}
   16659 	if (node) {
   16660 		dns_db_detachnode(db, &node);
   16661 	}
   16662 	return (result);
   16663 }
   16664 
   16665 static void
   16666 receive_secure_db(isc_task_t *task, isc_event_t *event) {
   16667 	isc_result_t result;
   16668 	dns_zone_t *zone;
   16669 	dns_db_t *rawdb, *db = NULL;
   16670 	dns_dbiterator_t *dbiterator = NULL;
   16671 	dns_dbversion_t *version = NULL;
   16672 	isc_time_t loadtime;
   16673 	unsigned int oldserial = 0, *oldserialp = NULL;
   16674 	nsec3paramlist_t nsec3list;
   16675 	isc_event_t *setnsec3param_event;
   16676 	dns_zone_t *dummy;
   16677 
   16678 	UNUSED(task);
   16679 
   16680 	ISC_LIST_INIT(nsec3list);
   16681 
   16682 	zone = event->ev_arg;
   16683 	rawdb = ((struct secure_event *)event)->db;
   16684 	isc_event_free(&event);
   16685 
   16686 	LOCK_ZONE(zone);
   16687 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
   16688 		result = ISC_R_SHUTTINGDOWN;
   16689 		goto failure;
   16690 	}
   16691 
   16692 	TIME_NOW(&loadtime);
   16693 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16694 	if (zone->db != NULL) {
   16695 		result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
   16696 		if (result == ISC_R_SUCCESS) {
   16697 			oldserialp = &oldserial;
   16698 		}
   16699 
   16700 		/*
   16701 		 * assemble nsec3parameters from the old zone, and set a flag
   16702 		 * if any are found
   16703 		 */
   16704 		result = save_nsec3param(zone, &nsec3list);
   16705 		if (result != ISC_R_SUCCESS) {
   16706 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16707 			goto failure;
   16708 		}
   16709 	}
   16710 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16711 
   16712 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   16713 			       dns_dbtype_zone, zone->rdclass,
   16714 			       zone->db_argc - 1, zone->db_argv + 1, &db);
   16715 	if (result != ISC_R_SUCCESS) {
   16716 		goto failure;
   16717 	}
   16718 
   16719 	result = dns_db_setgluecachestats(db, zone->gluecachestats);
   16720 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
   16721 		goto failure;
   16722 	}
   16723 
   16724 	result = dns_db_newversion(db, &version);
   16725 	if (result != ISC_R_SUCCESS) {
   16726 		goto failure;
   16727 	}
   16728 
   16729 	result = dns_db_createiterator(rawdb, 0, &dbiterator);
   16730 	if (result != ISC_R_SUCCESS) {
   16731 		goto failure;
   16732 	}
   16733 
   16734 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   16735 	     result = dns_dbiterator_next(dbiterator))
   16736 	{
   16737 		result = copy_non_dnssec_records(zone, db, version, rawdb,
   16738 						 dbiterator, oldserialp);
   16739 		if (result != ISC_R_SUCCESS) {
   16740 			goto failure;
   16741 		}
   16742 	}
   16743 	dns_dbiterator_destroy(&dbiterator);
   16744 	if (result != ISC_R_NOMORE) {
   16745 		goto failure;
   16746 	}
   16747 
   16748 	/*
   16749 	 * Call restore_nsec3param() to create private-type records from
   16750 	 * the old nsec3 parameters and insert them into db
   16751 	 */
   16752 	if (!ISC_LIST_EMPTY(nsec3list)) {
   16753 		result = restore_nsec3param(zone, db, version, &nsec3list);
   16754 		if (result != ISC_R_SUCCESS) {
   16755 			goto failure;
   16756 		}
   16757 	}
   16758 
   16759 	dns_db_closeversion(db, &version, true);
   16760 
   16761 	/*
   16762 	 * Lock hierarchy: zmgr, zone, raw.
   16763 	 */
   16764 	INSIST(zone != zone->raw);
   16765 	LOCK_ZONE(zone->raw);
   16766 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   16767 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   16768 	zone_needdump(zone, 0); /* XXXMPA */
   16769 	UNLOCK_ZONE(zone->raw);
   16770 
   16771 	/*
   16772 	 * Process any queued NSEC3PARAM change requests.
   16773 	 */
   16774 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   16775 		setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   16776 		ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
   16777 				ev_link);
   16778 		dummy = NULL;
   16779 		zone_iattach(zone, &dummy);
   16780 		isc_task_send(zone->task, &setnsec3param_event);
   16781 	}
   16782 
   16783 failure:
   16784 	UNLOCK_ZONE(zone);
   16785 	if (dbiterator != NULL) {
   16786 		dns_dbiterator_destroy(&dbiterator);
   16787 	}
   16788 	if (result != ISC_R_SUCCESS) {
   16789 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
   16790 			     dns_result_totext(result));
   16791 	}
   16792 
   16793 	while (!ISC_LIST_EMPTY(nsec3list)) {
   16794 		nsec3param_t *nsec3p;
   16795 		nsec3p = ISC_LIST_HEAD(nsec3list);
   16796 		ISC_LIST_UNLINK(nsec3list, nsec3p, link);
   16797 		isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
   16798 	}
   16799 	if (db != NULL) {
   16800 		if (version != NULL) {
   16801 			dns_db_closeversion(db, &version, false);
   16802 		}
   16803 		dns_db_detach(&db);
   16804 	}
   16805 	dns_db_detach(&rawdb);
   16806 	dns_zone_idetach(&zone);
   16807 
   16808 	INSIST(version == NULL);
   16809 }
   16810 
   16811 static isc_result_t
   16812 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
   16813 	isc_event_t *e;
   16814 	dns_db_t *dummy = NULL;
   16815 	dns_zone_t *secure = NULL;
   16816 
   16817 	e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECUREDB,
   16818 			       receive_secure_db, zone->secure,
   16819 			       sizeof(struct secure_event));
   16820 	dns_db_attach(db, &dummy);
   16821 	((struct secure_event *)e)->db = dummy;
   16822 	INSIST(LOCKED_ZONE(zone->secure));
   16823 	zone_iattach(zone->secure, &secure);
   16824 	isc_task_send(zone->secure->task, &e);
   16825 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   16826 	return (ISC_R_SUCCESS);
   16827 }
   16828 
   16829 isc_result_t
   16830 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   16831 	isc_result_t result;
   16832 	dns_zone_t *secure = NULL;
   16833 
   16834 	REQUIRE(DNS_ZONE_VALID(zone));
   16835 again:
   16836 	LOCK_ZONE(zone);
   16837 	if (inline_raw(zone)) {
   16838 		secure = zone->secure;
   16839 		INSIST(secure != zone);
   16840 		TRYLOCK_ZONE(result, secure);
   16841 		if (result != ISC_R_SUCCESS) {
   16842 			UNLOCK_ZONE(zone);
   16843 			secure = NULL;
   16844 			isc_thread_yield();
   16845 			goto again;
   16846 		}
   16847 	}
   16848 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   16849 	result = zone_replacedb(zone, db, dump);
   16850 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   16851 	if (secure != NULL) {
   16852 		UNLOCK_ZONE(secure);
   16853 	}
   16854 	UNLOCK_ZONE(zone);
   16855 	return (result);
   16856 }
   16857 
   16858 static isc_result_t
   16859 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   16860 	dns_dbversion_t *ver;
   16861 	isc_result_t result;
   16862 	unsigned int soacount = 0;
   16863 	unsigned int nscount = 0;
   16864 
   16865 	/*
   16866 	 * 'zone' and 'zone->db' locked by caller.
   16867 	 */
   16868 	REQUIRE(DNS_ZONE_VALID(zone));
   16869 	REQUIRE(LOCKED_ZONE(zone));
   16870 	if (inline_raw(zone)) {
   16871 		REQUIRE(LOCKED_ZONE(zone->secure));
   16872 	}
   16873 
   16874 	result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL,
   16875 				  NULL, NULL, NULL, NULL);
   16876 	if (result == ISC_R_SUCCESS) {
   16877 		if (soacount != 1) {
   16878 			dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records",
   16879 				     soacount);
   16880 			result = DNS_R_BADZONE;
   16881 		}
   16882 		if (nscount == 0 && zone->type != dns_zone_key) {
   16883 			dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
   16884 			result = DNS_R_BADZONE;
   16885 		}
   16886 		if (result != ISC_R_SUCCESS) {
   16887 			return (result);
   16888 		}
   16889 	} else {
   16890 		dns_zone_log(zone, ISC_LOG_ERROR,
   16891 			     "retrieving SOA and NS records failed: %s",
   16892 			     dns_result_totext(result));
   16893 		return (result);
   16894 	}
   16895 
   16896 	result = check_nsec3param(zone, db);
   16897 	if (result != ISC_R_SUCCESS) {
   16898 		return (result);
   16899 	}
   16900 
   16901 	ver = NULL;
   16902 	dns_db_currentversion(db, &ver);
   16903 
   16904 	/*
   16905 	 * The initial version of a slave zone is always dumped;
   16906 	 * subsequent versions may be journaled instead if this
   16907 	 * is enabled in the configuration.
   16908 	 */
   16909 	if (zone->db != NULL && zone->journal != NULL &&
   16910 	    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   16911 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
   16912 	{
   16913 		uint32_t serial, oldserial;
   16914 
   16915 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
   16916 
   16917 		result = dns_db_getsoaserial(db, ver, &serial);
   16918 		if (result != ISC_R_SUCCESS) {
   16919 			dns_zone_log(zone, ISC_LOG_ERROR,
   16920 				     "ixfr-from-differences: unable to get "
   16921 				     "new serial");
   16922 			goto fail;
   16923 		}
   16924 
   16925 		/*
   16926 		 * This is checked in zone_postload() for master zones.
   16927 		 */
   16928 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
   16929 					  &oldserial, NULL, NULL, NULL, NULL,
   16930 					  NULL);
   16931 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16932 		RUNTIME_CHECK(soacount > 0U);
   16933 		if ((zone->type == dns_zone_slave ||
   16934 		     (zone->type == dns_zone_redirect &&
   16935 		      zone->masters != NULL)) &&
   16936 		    !isc_serial_gt(serial, oldserial))
   16937 		{
   16938 			uint32_t serialmin, serialmax;
   16939 			serialmin = (oldserial + 1) & 0xffffffffU;
   16940 			serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
   16941 			dns_zone_log(zone, ISC_LOG_ERROR,
   16942 				     "ixfr-from-differences: failed: "
   16943 				     "new serial (%u) out of range [%u - %u]",
   16944 				     serial, serialmin, serialmax);
   16945 			result = ISC_R_RANGE;
   16946 			goto fail;
   16947 		}
   16948 
   16949 		result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
   16950 				     zone->journal);
   16951 		if (result != ISC_R_SUCCESS) {
   16952 			char strbuf[ISC_STRERRORSIZE];
   16953 			strerror_r(errno, strbuf, sizeof(strbuf));
   16954 			dns_zone_log(zone, ISC_LOG_ERROR,
   16955 				     "ixfr-from-differences: failed: "
   16956 				     "%s",
   16957 				     strbuf);
   16958 			goto fallback;
   16959 		}
   16960 		if (dump) {
   16961 			zone_needdump(zone, DNS_DUMP_DELAY);
   16962 		} else {
   16963 			zone_journal_compact(zone, zone->db, serial);
   16964 		}
   16965 		if (zone->type == dns_zone_master && inline_raw(zone)) {
   16966 			zone_send_secureserial(zone, serial);
   16967 		}
   16968 	} else {
   16969 	fallback:
   16970 		if (dump && zone->masterfile != NULL) {
   16971 			/*
   16972 			 * If DNS_ZONEFLG_FORCEXFER was set we don't want
   16973 			 * to keep the old masterfile.
   16974 			 */
   16975 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
   16976 			    remove(zone->masterfile) < 0 && errno != ENOENT)
   16977 			{
   16978 				char strbuf[ISC_STRERRORSIZE];
   16979 				strerror_r(errno, strbuf, sizeof(strbuf));
   16980 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16981 					      DNS_LOGMODULE_ZONE,
   16982 					      ISC_LOG_WARNING,
   16983 					      "unable to remove masterfile "
   16984 					      "'%s': '%s'",
   16985 					      zone->masterfile, strbuf);
   16986 			}
   16987 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) {
   16988 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
   16989 			} else {
   16990 				zone_needdump(zone, 0);
   16991 			}
   16992 		}
   16993 		if (dump && zone->journal != NULL) {
   16994 			/*
   16995 			 * The in-memory database just changed, and
   16996 			 * because 'dump' is set, it didn't change by
   16997 			 * being loaded from disk.  Also, we have not
   16998 			 * journaled diffs for this change.
   16999 			 * Therefore, the on-disk journal is missing
   17000 			 * the deltas for this change.	Since it can
   17001 			 * no longer be used to bring the zone
   17002 			 * up-to-date, it is useless and should be
   17003 			 * removed.
   17004 			 */
   17005 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17006 				      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   17007 				      "removing journal file");
   17008 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   17009 				char strbuf[ISC_STRERRORSIZE];
   17010 				strerror_r(errno, strbuf, sizeof(strbuf));
   17011 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   17012 					      DNS_LOGMODULE_ZONE,
   17013 					      ISC_LOG_WARNING,
   17014 					      "unable to remove journal "
   17015 					      "'%s': '%s'",
   17016 					      zone->journal, strbuf);
   17017 			}
   17018 		}
   17019 
   17020 		if (inline_raw(zone)) {
   17021 			zone_send_securedb(zone, db);
   17022 		}
   17023 	}
   17024 
   17025 	dns_db_closeversion(db, &ver, false);
   17026 
   17027 	dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
   17028 
   17029 	if (zone->db != NULL) {
   17030 		zone_detachdb(zone);
   17031 	}
   17032 	zone_attachdb(zone, db);
   17033 	dns_db_settask(zone->db, zone->task);
   17034 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   17035 	return (ISC_R_SUCCESS);
   17036 
   17037 fail:
   17038 	dns_db_closeversion(db, &ver, false);
   17039 	return (result);
   17040 }
   17041 
   17042 /* The caller must hold the dblock as a writer. */
   17043 static inline void
   17044 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
   17045 	REQUIRE(zone->db == NULL && db != NULL);
   17046 
   17047 	dns_db_attach(db, &zone->db);
   17048 }
   17049 
   17050 /* The caller must hold the dblock as a writer. */
   17051 static inline void
   17052 zone_detachdb(dns_zone_t *zone) {
   17053 	REQUIRE(zone->db != NULL);
   17054 
   17055 	dns_db_detach(&zone->db);
   17056 }
   17057 
   17058 static void
   17059 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
   17060 	isc_time_t now;
   17061 	bool again = false;
   17062 	unsigned int soacount;
   17063 	unsigned int nscount;
   17064 	uint32_t serial, refresh, retry, expire, minimum;
   17065 	isc_result_t xfrresult = result;
   17066 	bool free_needed;
   17067 	dns_zone_t *secure = NULL;
   17068 
   17069 	REQUIRE(DNS_ZONE_VALID(zone));
   17070 
   17071 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17072 		      "zone transfer finished: %s", dns_result_totext(result));
   17073 
   17074 	/*
   17075 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   17076 	 * could result in a deadlock due to a LOR so we will spin if we
   17077 	 * can't obtain the both locks.
   17078 	 */
   17079 again:
   17080 	LOCK_ZONE(zone);
   17081 	if (inline_raw(zone)) {
   17082 		secure = zone->secure;
   17083 		INSIST(secure != zone);
   17084 		TRYLOCK_ZONE(result, secure);
   17085 		if (result != ISC_R_SUCCESS) {
   17086 			UNLOCK_ZONE(zone);
   17087 			secure = NULL;
   17088 			isc_thread_yield();
   17089 			goto again;
   17090 		}
   17091 	}
   17092 
   17093 	INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH));
   17094 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   17095 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   17096 
   17097 	TIME_NOW(&now);
   17098 	switch (xfrresult) {
   17099 	case ISC_R_SUCCESS:
   17100 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   17101 	/* FALLTHROUGH */
   17102 	case DNS_R_UPTODATE:
   17103 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   17104 		/*
   17105 		 * Has the zone expired underneath us?
   17106 		 */
   17107 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17108 		if (zone->db == NULL) {
   17109 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17110 			goto same_master;
   17111 		}
   17112 
   17113 		/*
   17114 		 * Update the zone structure's data from the actual
   17115 		 * SOA received.
   17116 		 */
   17117 		nscount = 0;
   17118 		soacount = 0;
   17119 		INSIST(zone->db != NULL);
   17120 		result = zone_get_from_db(zone, zone->db, &nscount, &soacount,
   17121 					  &serial, &refresh, &retry, &expire,
   17122 					  &minimum, NULL);
   17123 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17124 		if (result == ISC_R_SUCCESS) {
   17125 			if (soacount != 1) {
   17126 				dns_zone_log(zone, ISC_LOG_ERROR,
   17127 					     "transferred zone "
   17128 					     "has %d SOA records",
   17129 					     soacount);
   17130 				if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   17131 				{
   17132 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   17133 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   17134 				}
   17135 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17136 				zone_unload(zone);
   17137 				goto next_master;
   17138 			}
   17139 			if (nscount == 0) {
   17140 				dns_zone_log(zone, ISC_LOG_ERROR,
   17141 					     "transferred zone "
   17142 					     "has no NS records");
   17143 				if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   17144 				{
   17145 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   17146 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   17147 				}
   17148 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17149 				zone_unload(zone);
   17150 				goto next_master;
   17151 			}
   17152 			zone->refresh = RANGE(refresh, zone->minrefresh,
   17153 					      zone->maxrefresh);
   17154 			zone->retry = RANGE(retry, zone->minretry,
   17155 					    zone->maxretry);
   17156 			zone->expire = RANGE(expire,
   17157 					     zone->refresh + zone->retry,
   17158 					     DNS_MAX_EXPIRE);
   17159 			zone->minimum = minimum;
   17160 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17161 		}
   17162 
   17163 		/*
   17164 		 * Set our next update/expire times.
   17165 		 */
   17166 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   17167 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   17168 			zone->refreshtime = now;
   17169 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17170 					  &zone->expiretime);
   17171 		} else {
   17172 			DNS_ZONE_JITTER_ADD(&now, zone->refresh,
   17173 					    &zone->refreshtime);
   17174 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17175 					  &zone->expiretime);
   17176 		}
   17177 		if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
   17178 			char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
   17179 			if (zone->tsigkey != NULL) {
   17180 				char namebuf[DNS_NAME_FORMATSIZE];
   17181 				dns_name_format(&zone->tsigkey->name, namebuf,
   17182 						sizeof(namebuf));
   17183 				snprintf(buf, sizeof(buf), ": TSIG '%s'",
   17184 					 namebuf);
   17185 			} else {
   17186 				buf[0] = '\0';
   17187 			}
   17188 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17189 				      ISC_LOG_INFO, "transferred serial %u%s",
   17190 				      serial, buf);
   17191 			if (inline_raw(zone)) {
   17192 				zone_send_secureserial(zone, serial);
   17193 			}
   17194 		}
   17195 
   17196 		/*
   17197 		 * This is not necessary if we just performed a AXFR
   17198 		 * however it is necessary for an IXFR / UPTODATE and
   17199 		 * won't hurt with an AXFR.
   17200 		 */
   17201 		if (zone->masterfile != NULL || zone->journal != NULL) {
   17202 			unsigned int delay = DNS_DUMP_DELAY;
   17203 
   17204 			result = ISC_R_FAILURE;
   17205 			if (zone->journal != NULL) {
   17206 				result = isc_file_settime(zone->journal, &now);
   17207 			}
   17208 			if (result != ISC_R_SUCCESS && zone->masterfile != NULL)
   17209 			{
   17210 				result = isc_file_settime(zone->masterfile,
   17211 							  &now);
   17212 			}
   17213 
   17214 			if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
   17215 			    result == ISC_R_FILENOTFOUND)
   17216 			{
   17217 				delay = 0;
   17218 			}
   17219 
   17220 			if ((result == ISC_R_SUCCESS ||
   17221 			     result == ISC_R_FILENOTFOUND) &&
   17222 			    zone->masterfile != NULL)
   17223 			{
   17224 				zone_needdump(zone, delay);
   17225 			} else if (result != ISC_R_SUCCESS) {
   17226 				dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17227 					      ISC_LOG_ERROR,
   17228 					      "transfer: could not set file "
   17229 					      "modification time of '%s': %s",
   17230 					      zone->masterfile,
   17231 					      dns_result_totext(result));
   17232 			}
   17233 		}
   17234 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
   17235 		inc_stats(zone, dns_zonestatscounter_xfrsuccess);
   17236 		break;
   17237 
   17238 	case DNS_R_BADIXFR:
   17239 		/* Force retry with AXFR. */
   17240 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR);
   17241 		goto same_master;
   17242 
   17243 	case DNS_R_TOOMANYRECORDS:
   17244 	case DNS_R_VERIFYFAILURE:
   17245 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   17246 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17247 		break;
   17248 
   17249 	default:
   17250 	next_master:
   17251 		/*
   17252 		 * Skip to next failed / untried master.
   17253 		 */
   17254 		do {
   17255 			zone->curmaster++;
   17256 		} while (zone->curmaster < zone->masterscnt &&
   17257 			 zone->mastersok[zone->curmaster]);
   17258 		/* FALLTHROUGH */
   17259 	same_master:
   17260 		if (zone->curmaster >= zone->masterscnt) {
   17261 			zone->curmaster = 0;
   17262 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   17263 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   17264 			{
   17265 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17266 				DNS_ZONE_SETFLAG(zone,
   17267 						 DNS_ZONEFLG_USEALTXFRSRC);
   17268 				while (zone->curmaster < zone->masterscnt &&
   17269 				       zone->mastersok[zone->curmaster]) {
   17270 					zone->curmaster++;
   17271 				}
   17272 				again = true;
   17273 			} else {
   17274 				DNS_ZONE_CLRFLAG(zone,
   17275 						 DNS_ZONEFLG_USEALTXFRSRC);
   17276 			}
   17277 		} else {
   17278 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17279 			again = true;
   17280 		}
   17281 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17282 		break;
   17283 	}
   17284 	zone_settimer(zone, &now);
   17285 
   17286 	/*
   17287 	 * If creating the transfer object failed, zone->xfr is NULL.
   17288 	 * Otherwise, we are called as the done callback of a zone
   17289 	 * transfer object that just entered its shutting-down
   17290 	 * state.  Since we are no longer responsible for shutting
   17291 	 * it down, we can detach our reference.
   17292 	 */
   17293 	if (zone->xfr != NULL) {
   17294 		dns_xfrin_detach(&zone->xfr);
   17295 	}
   17296 
   17297 	if (zone->tsigkey != NULL) {
   17298 		dns_tsigkey_detach(&zone->tsigkey);
   17299 	}
   17300 
   17301 	/*
   17302 	 * Handle any deferred journal compaction.
   17303 	 */
   17304 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
   17305 		dns_db_t *db = NULL;
   17306 		if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) {
   17307 			zone_journal_compact(zone, db, zone->compact_serial);
   17308 			dns_db_detach(&db);
   17309 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   17310 		}
   17311 	}
   17312 
   17313 	if (secure != NULL) {
   17314 		UNLOCK_ZONE(secure);
   17315 	}
   17316 	/*
   17317 	 * This transfer finishing freed up a transfer quota slot.
   17318 	 * Let any other zones waiting for quota have it.
   17319 	 */
   17320 	if (zone->zmgr != NULL &&
   17321 	    zone->statelist == &zone->zmgr->xfrin_in_progress) {
   17322 		UNLOCK_ZONE(zone);
   17323 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17324 		ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
   17325 		zone->statelist = NULL;
   17326 		zmgr_resume_xfrs(zone->zmgr, false);
   17327 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17328 		LOCK_ZONE(zone);
   17329 	}
   17330 
   17331 	/*
   17332 	 * Retry with a different server if necessary.
   17333 	 */
   17334 	if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   17335 		queue_soa_query(zone);
   17336 	}
   17337 
   17338 	isc_refcount_decrement(&zone->irefs);
   17339 	free_needed = exit_check(zone);
   17340 	UNLOCK_ZONE(zone);
   17341 	if (free_needed) {
   17342 		zone_free(zone);
   17343 	}
   17344 }
   17345 
   17346 static void
   17347 zone_loaddone(void *arg, isc_result_t result) {
   17348 	static char me[] = "zone_loaddone";
   17349 	dns_load_t *load = arg;
   17350 	dns_zone_t *zone;
   17351 	isc_result_t tresult;
   17352 	dns_zone_t *secure = NULL;
   17353 
   17354 	REQUIRE(DNS_LOAD_VALID(load));
   17355 	zone = load->zone;
   17356 
   17357 	ENTER;
   17358 
   17359 	/*
   17360 	 * If zone loading failed, remove the update db callbacks prior
   17361 	 * to calling the list of callbacks in the zone load structure.
   17362 	 */
   17363 	if (result != ISC_R_SUCCESS) {
   17364 		dns_zone_rpz_disable_db(zone, load->db);
   17365 		dns_zone_catz_disable_db(zone, load->db);
   17366 	}
   17367 
   17368 	tresult = dns_db_endload(load->db, &load->callbacks);
   17369 	if (tresult != ISC_R_SUCCESS &&
   17370 	    (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
   17371 	{
   17372 		result = tresult;
   17373 	}
   17374 
   17375 	/*
   17376 	 * Lock hierarchy: zmgr, zone, raw.
   17377 	 */
   17378 again:
   17379 	LOCK_ZONE(zone);
   17380 	INSIST(zone != zone->raw);
   17381 	if (inline_secure(zone)) {
   17382 		LOCK_ZONE(zone->raw);
   17383 	} else if (inline_raw(zone)) {
   17384 		secure = zone->secure;
   17385 		TRYLOCK_ZONE(tresult, secure);
   17386 		if (tresult != ISC_R_SUCCESS) {
   17387 			UNLOCK_ZONE(zone);
   17388 			secure = NULL;
   17389 			isc_thread_yield();
   17390 			goto again;
   17391 		}
   17392 	}
   17393 	(void)zone_postload(zone, load->db, load->loadtime, result);
   17394 	zonemgr_putio(&zone->readio);
   17395 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
   17396 	zone_idetach(&load->callbacks.zone);
   17397 	/*
   17398 	 * Leave the zone frozen if the reload fails.
   17399 	 */
   17400 	if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
   17401 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
   17402 	{
   17403 		zone->update_disabled = false;
   17404 	}
   17405 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
   17406 	if (inline_secure(zone)) {
   17407 		UNLOCK_ZONE(zone->raw);
   17408 	} else if (secure != NULL) {
   17409 		UNLOCK_ZONE(secure);
   17410 	}
   17411 	UNLOCK_ZONE(zone);
   17412 
   17413 	load->magic = 0;
   17414 	dns_db_detach(&load->db);
   17415 	if (load->zone->lctx != NULL) {
   17416 		dns_loadctx_detach(&load->zone->lctx);
   17417 	}
   17418 	dns_zone_idetach(&load->zone);
   17419 	isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
   17420 }
   17421 
   17422 void
   17423 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
   17424 	REQUIRE(DNS_ZONE_VALID(zone));
   17425 	REQUIRE(table != NULL);
   17426 	REQUIRE(*table == NULL);
   17427 
   17428 	LOCK_ZONE(zone);
   17429 	if (zone->ssutable != NULL) {
   17430 		dns_ssutable_attach(zone->ssutable, table);
   17431 	}
   17432 	UNLOCK_ZONE(zone);
   17433 }
   17434 
   17435 void
   17436 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
   17437 	REQUIRE(DNS_ZONE_VALID(zone));
   17438 
   17439 	LOCK_ZONE(zone);
   17440 	if (zone->ssutable != NULL) {
   17441 		dns_ssutable_detach(&zone->ssutable);
   17442 	}
   17443 	if (table != NULL) {
   17444 		dns_ssutable_attach(table, &zone->ssutable);
   17445 	}
   17446 	UNLOCK_ZONE(zone);
   17447 }
   17448 
   17449 void
   17450 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17451 	REQUIRE(DNS_ZONE_VALID(zone));
   17452 
   17453 	zone->sigvalidityinterval = interval;
   17454 }
   17455 
   17456 uint32_t
   17457 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
   17458 	REQUIRE(DNS_ZONE_VALID(zone));
   17459 
   17460 	return (zone->sigvalidityinterval);
   17461 }
   17462 
   17463 void
   17464 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17465 	REQUIRE(DNS_ZONE_VALID(zone));
   17466 
   17467 	zone->keyvalidityinterval = interval;
   17468 }
   17469 
   17470 uint32_t
   17471 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
   17472 	REQUIRE(DNS_ZONE_VALID(zone));
   17473 
   17474 	return (zone->keyvalidityinterval);
   17475 }
   17476 
   17477 void
   17478 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
   17479 	isc_time_t now;
   17480 
   17481 	REQUIRE(DNS_ZONE_VALID(zone));
   17482 
   17483 	LOCK_ZONE(zone);
   17484 	zone->sigresigninginterval = interval;
   17485 	set_resigntime(zone);
   17486 	if (zone->task != NULL) {
   17487 		TIME_NOW(&now);
   17488 		zone_settimer(zone, &now);
   17489 	}
   17490 	UNLOCK_ZONE(zone);
   17491 }
   17492 
   17493 uint32_t
   17494 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
   17495 	REQUIRE(DNS_ZONE_VALID(zone));
   17496 
   17497 	return (zone->sigresigninginterval);
   17498 }
   17499 
   17500 static void
   17501 queue_xfrin(dns_zone_t *zone) {
   17502 	const char me[] = "queue_xfrin";
   17503 	isc_result_t result;
   17504 	dns_zonemgr_t *zmgr = zone->zmgr;
   17505 
   17506 	ENTER;
   17507 
   17508 	INSIST(zone->statelist == NULL);
   17509 
   17510 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   17511 	ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
   17512 	isc_refcount_increment0(&zone->irefs);
   17513 	zone->statelist = &zmgr->waiting_for_xfrin;
   17514 	result = zmgr_start_xfrin_ifquota(zmgr, zone);
   17515 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   17516 
   17517 	if (result == ISC_R_QUOTA) {
   17518 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   17519 			      "zone transfer deferred due to quota");
   17520 	} else if (result != ISC_R_SUCCESS) {
   17521 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   17522 			      "starting zone transfer: %s",
   17523 			      isc_result_totext(result));
   17524 	}
   17525 }
   17526 
   17527 /*
   17528  * This event callback is called when a zone has received
   17529  * any necessary zone transfer quota.  This is the time
   17530  * to go ahead and start the transfer.
   17531  */
   17532 static void
   17533 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
   17534 	isc_result_t result = ISC_R_SUCCESS;
   17535 	dns_peer_t *peer = NULL;
   17536 	char master[ISC_SOCKADDR_FORMATSIZE];
   17537 	char source[ISC_SOCKADDR_FORMATSIZE];
   17538 	dns_rdatatype_t xfrtype;
   17539 	dns_zone_t *zone = event->ev_arg;
   17540 	isc_netaddr_t masterip;
   17541 	isc_sockaddr_t sourceaddr;
   17542 	isc_sockaddr_t masteraddr;
   17543 	isc_time_t now;
   17544 	const char *soa_before = "";
   17545 	isc_dscp_t dscp = -1;
   17546 	bool loaded;
   17547 
   17548 	UNUSED(task);
   17549 
   17550 	INSIST(task == zone->task);
   17551 
   17552 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   17553 		result = ISC_R_CANCELED;
   17554 		goto cleanup;
   17555 	}
   17556 
   17557 	TIME_NOW(&now);
   17558 
   17559 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   17560 	if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   17561 				    &zone->sourceaddr, &now))
   17562 	{
   17563 		isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   17564 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   17565 			      "got_transfer_quota: skipping zone transfer as "
   17566 			      "master %s (source %s) is unreachable (cached)",
   17567 			      master, source);
   17568 		result = ISC_R_CANCELED;
   17569 		goto cleanup;
   17570 	}
   17571 
   17572 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   17573 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   17574 
   17575 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   17576 		soa_before = "SOA before ";
   17577 	}
   17578 	/*
   17579 	 * Decide whether we should request IXFR or AXFR.
   17580 	 */
   17581 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17582 	loaded = (zone->db != NULL);
   17583 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17584 
   17585 	if (!loaded) {
   17586 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17587 			      "no database exists yet, requesting AXFR of "
   17588 			      "initial version from %s",
   17589 			      master);
   17590 		xfrtype = dns_rdatatype_axfr;
   17591 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
   17592 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17593 			      "forced reload, requesting AXFR of "
   17594 			      "initial version from %s",
   17595 			      master);
   17596 		xfrtype = dns_rdatatype_axfr;
   17597 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) {
   17598 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17599 			      "retrying with AXFR from %s due to "
   17600 			      "previous IXFR failure",
   17601 			      master);
   17602 		xfrtype = dns_rdatatype_axfr;
   17603 		LOCK_ZONE(zone);
   17604 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR);
   17605 		UNLOCK_ZONE(zone);
   17606 	} else {
   17607 		bool use_ixfr = true;
   17608 		if (peer != NULL) {
   17609 			result = dns_peer_getrequestixfr(peer, &use_ixfr);
   17610 		}
   17611 		if (peer == NULL || result != ISC_R_SUCCESS) {
   17612 			use_ixfr = zone->requestixfr;
   17613 		}
   17614 		if (!use_ixfr) {
   17615 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17616 				      ISC_LOG_DEBUG(1),
   17617 				      "IXFR disabled, "
   17618 				      "requesting %sAXFR from %s",
   17619 				      soa_before, master);
   17620 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   17621 				xfrtype = dns_rdatatype_soa;
   17622 			} else {
   17623 				xfrtype = dns_rdatatype_axfr;
   17624 			}
   17625 		} else {
   17626 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17627 				      ISC_LOG_DEBUG(1),
   17628 				      "requesting IXFR from %s", master);
   17629 			xfrtype = dns_rdatatype_ixfr;
   17630 		}
   17631 	}
   17632 
   17633 	/*
   17634 	 * Determine if we should attempt to sign the request with TSIG.
   17635 	 */
   17636 	result = ISC_R_NOTFOUND;
   17637 
   17638 	/*
   17639 	 * First, look for a tsig key in the master statement, then
   17640 	 * try for a server key.
   17641 	 */
   17642 	if ((zone->masterkeynames != NULL) &&
   17643 	    (zone->masterkeynames[zone->curmaster] != NULL))
   17644 	{
   17645 		dns_view_t *view = dns_zone_getview(zone);
   17646 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   17647 		result = dns_view_gettsig(view, keyname, &zone->tsigkey);
   17648 	}
   17649 	if (zone->tsigkey == NULL) {
   17650 		result = dns_view_getpeertsig(zone->view, &masterip,
   17651 					      &zone->tsigkey);
   17652 	}
   17653 
   17654 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   17655 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   17656 			      "could not get TSIG key for zone transfer: %s",
   17657 			      isc_result_totext(result));
   17658 	}
   17659 
   17660 	if (zone->masterdscps != NULL) {
   17661 		dscp = zone->masterdscps[zone->curmaster];
   17662 	}
   17663 
   17664 	LOCK_ZONE(zone);
   17665 	masteraddr = zone->masteraddr;
   17666 	sourceaddr = zone->sourceaddr;
   17667 	switch (isc_sockaddr_pf(&masteraddr)) {
   17668 	case PF_INET:
   17669 		if (dscp == -1) {
   17670 			dscp = zone->xfrsource4dscp;
   17671 		}
   17672 		break;
   17673 	case PF_INET6:
   17674 		if (dscp == -1) {
   17675 			dscp = zone->xfrsource6dscp;
   17676 		}
   17677 		break;
   17678 	default:
   17679 		INSIST(0);
   17680 		ISC_UNREACHABLE();
   17681 	}
   17682 	UNLOCK_ZONE(zone);
   17683 	INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
   17684 	result = dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr, dscp,
   17685 				  zone->tsigkey, zone->mctx,
   17686 				  zone->zmgr->timermgr, zone->zmgr->socketmgr,
   17687 				  zone->task, zone_xfrdone, &zone->xfr);
   17688 	if (result == ISC_R_SUCCESS) {
   17689 		LOCK_ZONE(zone);
   17690 		if (xfrtype == dns_rdatatype_axfr) {
   17691 			if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
   17692 				inc_stats(zone, dns_zonestatscounter_axfrreqv4);
   17693 			} else {
   17694 				inc_stats(zone, dns_zonestatscounter_axfrreqv6);
   17695 			}
   17696 		} else if (xfrtype == dns_rdatatype_ixfr) {
   17697 			if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
   17698 				inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
   17699 			} else {
   17700 				inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
   17701 			}
   17702 		}
   17703 		UNLOCK_ZONE(zone);
   17704 	}
   17705 cleanup:
   17706 	/*
   17707 	 * Any failure in this function is handled like a failed
   17708 	 * zone transfer.  This ensures that we get removed from
   17709 	 * zmgr->xfrin_in_progress.
   17710 	 */
   17711 	if (result != ISC_R_SUCCESS) {
   17712 		zone_xfrdone(zone, result);
   17713 	}
   17714 
   17715 	isc_event_free(&event);
   17716 }
   17717 
   17718 /*
   17719  * Update forwarding support.
   17720  */
   17721 
   17722 static void
   17723 forward_destroy(dns_forward_t *forward) {
   17724 	forward->magic = 0;
   17725 	if (forward->request != NULL) {
   17726 		dns_request_destroy(&forward->request);
   17727 	}
   17728 	if (forward->msgbuf != NULL) {
   17729 		isc_buffer_free(&forward->msgbuf);
   17730 	}
   17731 	if (forward->zone != NULL) {
   17732 		LOCK(&forward->zone->lock);
   17733 		if (ISC_LINK_LINKED(forward, link)) {
   17734 			ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
   17735 		}
   17736 		UNLOCK(&forward->zone->lock);
   17737 		dns_zone_idetach(&forward->zone);
   17738 	}
   17739 	isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
   17740 }
   17741 
   17742 static isc_result_t
   17743 sendtomaster(dns_forward_t *forward) {
   17744 	isc_result_t result;
   17745 	isc_sockaddr_t src;
   17746 	isc_dscp_t dscp = -1;
   17747 
   17748 	LOCK_ZONE(forward->zone);
   17749 
   17750 	if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
   17751 		UNLOCK_ZONE(forward->zone);
   17752 		return (ISC_R_CANCELED);
   17753 	}
   17754 
   17755 	if (forward->which >= forward->zone->masterscnt) {
   17756 		UNLOCK_ZONE(forward->zone);
   17757 		return (ISC_R_NOMORE);
   17758 	}
   17759 
   17760 	forward->addr = forward->zone->masters[forward->which];
   17761 	/*
   17762 	 * Always use TCP regardless of whether the original update
   17763 	 * used TCP.
   17764 	 * XXX The timeout may but a bit small if we are far down a
   17765 	 * transfer graph and the master has to try several masters.
   17766 	 */
   17767 	switch (isc_sockaddr_pf(&forward->addr)) {
   17768 	case PF_INET:
   17769 		src = forward->zone->xfrsource4;
   17770 		dscp = forward->zone->xfrsource4dscp;
   17771 		break;
   17772 	case PF_INET6:
   17773 		src = forward->zone->xfrsource6;
   17774 		dscp = forward->zone->xfrsource6dscp;
   17775 		break;
   17776 	default:
   17777 		result = ISC_R_NOTIMPLEMENTED;
   17778 		goto unlock;
   17779 	}
   17780 	result = dns_request_createraw(forward->zone->view->requestmgr,
   17781 				       forward->msgbuf, &src, &forward->addr,
   17782 				       dscp, forward->options, 15 /* XXX */, 0,
   17783 				       0, forward->zone->task, forward_callback,
   17784 				       forward, &forward->request);
   17785 	if (result == ISC_R_SUCCESS) {
   17786 		if (!ISC_LINK_LINKED(forward, link)) {
   17787 			ISC_LIST_APPEND(forward->zone->forwards, forward, link);
   17788 		}
   17789 	}
   17790 
   17791 unlock:
   17792 	UNLOCK_ZONE(forward->zone);
   17793 	return (result);
   17794 }
   17795 
   17796 static void
   17797 forward_callback(isc_task_t *task, isc_event_t *event) {
   17798 	const char me[] = "forward_callback";
   17799 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   17800 	dns_message_t *msg = NULL;
   17801 	char master[ISC_SOCKADDR_FORMATSIZE];
   17802 	isc_result_t result;
   17803 	dns_forward_t *forward;
   17804 	dns_zone_t *zone;
   17805 
   17806 	UNUSED(task);
   17807 
   17808 	forward = revent->ev_arg;
   17809 	INSIST(DNS_FORWARD_VALID(forward));
   17810 	zone = forward->zone;
   17811 	INSIST(DNS_ZONE_VALID(zone));
   17812 
   17813 	ENTER;
   17814 
   17815 	isc_sockaddr_format(&forward->addr, master, sizeof(master));
   17816 
   17817 	if (revent->result != ISC_R_SUCCESS) {
   17818 		dns_zone_log(zone, ISC_LOG_INFO,
   17819 			     "could not forward dynamic update to %s: %s",
   17820 			     master, dns_result_totext(revent->result));
   17821 		goto next_master;
   17822 	}
   17823 
   17824 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   17825 
   17826 	result = dns_request_getresponse(revent->request, msg,
   17827 					 DNS_MESSAGEPARSE_PRESERVEORDER |
   17828 						 DNS_MESSAGEPARSE_CLONEBUFFER);
   17829 	if (result != ISC_R_SUCCESS) {
   17830 		goto next_master;
   17831 	}
   17832 
   17833 	switch (msg->rcode) {
   17834 	/*
   17835 	 * Pass these rcodes back to client.
   17836 	 */
   17837 	case dns_rcode_noerror:
   17838 	case dns_rcode_yxdomain:
   17839 	case dns_rcode_yxrrset:
   17840 	case dns_rcode_nxrrset:
   17841 	case dns_rcode_refused:
   17842 	case dns_rcode_nxdomain: {
   17843 		char rcode[128];
   17844 		isc_buffer_t rb;
   17845 
   17846 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   17847 		(void)dns_rcode_totext(msg->rcode, &rb);
   17848 		dns_zone_log(zone, ISC_LOG_INFO,
   17849 			     "forwarded dynamic update: "
   17850 			     "master %s returned: %.*s",
   17851 			     master, (int)rb.used, rcode);
   17852 		break;
   17853 	}
   17854 
   17855 	/* These should not occur if the primaries/zone are valid. */
   17856 	case dns_rcode_notzone:
   17857 	case dns_rcode_notauth: {
   17858 		char rcode[128];
   17859 		isc_buffer_t rb;
   17860 
   17861 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   17862 		(void)dns_rcode_totext(msg->rcode, &rb);
   17863 		dns_zone_log(zone, ISC_LOG_WARNING,
   17864 			     "forwarding dynamic update: "
   17865 			     "unexpected response: master %s returned: %.*s",
   17866 			     master, (int)rb.used, rcode);
   17867 		goto next_master;
   17868 	}
   17869 
   17870 	/* Try another server for these rcodes. */
   17871 	case dns_rcode_formerr:
   17872 	case dns_rcode_servfail:
   17873 	case dns_rcode_notimp:
   17874 	case dns_rcode_badvers:
   17875 	default:
   17876 		goto next_master;
   17877 	}
   17878 
   17879 	/* call callback */
   17880 	(forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
   17881 	msg = NULL;
   17882 	dns_request_destroy(&forward->request);
   17883 	forward_destroy(forward);
   17884 	isc_event_free(&event);
   17885 	return;
   17886 
   17887 next_master:
   17888 	if (msg != NULL) {
   17889 		dns_message_detach(&msg);
   17890 	}
   17891 	isc_event_free(&event);
   17892 	forward->which++;
   17893 	dns_request_destroy(&forward->request);
   17894 	result = sendtomaster(forward);
   17895 	if (result != ISC_R_SUCCESS) {
   17896 		/* call callback */
   17897 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   17898 			     "exhausted dynamic update forwarder list");
   17899 		(forward->callback)(forward->callback_arg, result, NULL);
   17900 		forward_destroy(forward);
   17901 	}
   17902 }
   17903 
   17904 isc_result_t
   17905 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
   17906 		       dns_updatecallback_t callback, void *callback_arg) {
   17907 	dns_forward_t *forward;
   17908 	isc_result_t result;
   17909 	isc_region_t *mr;
   17910 
   17911 	REQUIRE(DNS_ZONE_VALID(zone));
   17912 	REQUIRE(msg != NULL);
   17913 	REQUIRE(callback != NULL);
   17914 
   17915 	forward = isc_mem_get(zone->mctx, sizeof(*forward));
   17916 
   17917 	forward->request = NULL;
   17918 	forward->zone = NULL;
   17919 	forward->msgbuf = NULL;
   17920 	forward->which = 0;
   17921 	forward->mctx = 0;
   17922 	forward->callback = callback;
   17923 	forward->callback_arg = callback_arg;
   17924 	ISC_LINK_INIT(forward, link);
   17925 	forward->magic = FORWARD_MAGIC;
   17926 	forward->options = DNS_REQUESTOPT_TCP;
   17927 	/*
   17928 	 * If we have a SIG(0) signed message we need to preserve the
   17929 	 * query id as that is included in the SIG(0) computation.
   17930 	 */
   17931 	if (msg->sig0 != NULL) {
   17932 		forward->options |= DNS_REQUESTOPT_FIXEDID;
   17933 	}
   17934 
   17935 	mr = dns_message_getrawmessage(msg);
   17936 	if (mr == NULL) {
   17937 		result = ISC_R_UNEXPECTEDEND;
   17938 		goto cleanup;
   17939 	}
   17940 
   17941 	isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
   17942 	result = isc_buffer_copyregion(forward->msgbuf, mr);
   17943 	if (result != ISC_R_SUCCESS) {
   17944 		goto cleanup;
   17945 	}
   17946 
   17947 	isc_mem_attach(zone->mctx, &forward->mctx);
   17948 	dns_zone_iattach(zone, &forward->zone);
   17949 	result = sendtomaster(forward);
   17950 
   17951 cleanup:
   17952 	if (result != ISC_R_SUCCESS) {
   17953 		forward_destroy(forward);
   17954 	}
   17955 	return (result);
   17956 }
   17957 
   17958 isc_result_t
   17959 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
   17960 	REQUIRE(DNS_ZONE_VALID(zone));
   17961 	REQUIRE(next != NULL && *next == NULL);
   17962 
   17963 	*next = ISC_LIST_NEXT(zone, link);
   17964 	if (*next == NULL) {
   17965 		return (ISC_R_NOMORE);
   17966 	} else {
   17967 		return (ISC_R_SUCCESS);
   17968 	}
   17969 }
   17970 
   17971 isc_result_t
   17972 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
   17973 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17974 	REQUIRE(first != NULL && *first == NULL);
   17975 
   17976 	*first = ISC_LIST_HEAD(zmgr->zones);
   17977 	if (*first == NULL) {
   17978 		return (ISC_R_NOMORE);
   17979 	} else {
   17980 		return (ISC_R_SUCCESS);
   17981 	}
   17982 }
   17983 
   17984 /***
   17985  ***	Zone manager.
   17986  ***/
   17987 
   17988 isc_result_t
   17989 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
   17990 		   isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
   17991 		   dns_zonemgr_t **zmgrp) {
   17992 	dns_zonemgr_t *zmgr;
   17993 	isc_result_t result;
   17994 
   17995 	zmgr = isc_mem_get(mctx, sizeof(*zmgr));
   17996 	zmgr->mctx = NULL;
   17997 	isc_refcount_init(&zmgr->refs, 1);
   17998 	isc_mem_attach(mctx, &zmgr->mctx);
   17999 	zmgr->taskmgr = taskmgr;
   18000 	zmgr->timermgr = timermgr;
   18001 	zmgr->socketmgr = socketmgr;
   18002 	zmgr->zonetasks = NULL;
   18003 	zmgr->loadtasks = NULL;
   18004 	zmgr->mctxpool = NULL;
   18005 	zmgr->task = NULL;
   18006 	zmgr->notifyrl = NULL;
   18007 	zmgr->refreshrl = NULL;
   18008 	zmgr->startupnotifyrl = NULL;
   18009 	zmgr->startuprefreshrl = NULL;
   18010 	ISC_LIST_INIT(zmgr->zones);
   18011 	ISC_LIST_INIT(zmgr->waiting_for_xfrin);
   18012 	ISC_LIST_INIT(zmgr->xfrin_in_progress);
   18013 	memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
   18014 	isc_rwlock_init(&zmgr->rwlock, 0, 0);
   18015 
   18016 	zmgr->transfersin = 10;
   18017 	zmgr->transfersperns = 2;
   18018 
   18019 	/* Unreachable lock. */
   18020 	isc_rwlock_init(&zmgr->urlock, 0, 0);
   18021 
   18022 	/* Create a single task for queueing of SOA queries. */
   18023 	result = isc_task_create(taskmgr, 1, &zmgr->task);
   18024 	if (result != ISC_R_SUCCESS) {
   18025 		goto free_urlock;
   18026 	}
   18027 
   18028 	isc_task_setname(zmgr->task, "zmgr", zmgr);
   18029 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18030 					&zmgr->notifyrl);
   18031 	if (result != ISC_R_SUCCESS) {
   18032 		goto free_task;
   18033 	}
   18034 
   18035 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18036 					&zmgr->refreshrl);
   18037 	if (result != ISC_R_SUCCESS) {
   18038 		goto free_notifyrl;
   18039 	}
   18040 
   18041 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18042 					&zmgr->startupnotifyrl);
   18043 	if (result != ISC_R_SUCCESS) {
   18044 		goto free_refreshrl;
   18045 	}
   18046 
   18047 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   18048 					&zmgr->startuprefreshrl);
   18049 	if (result != ISC_R_SUCCESS) {
   18050 		goto free_startupnotifyrl;
   18051 	}
   18052 
   18053 	/* default to 20 refresh queries / notifies per second. */
   18054 	setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
   18055 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
   18056 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
   18057 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
   18058 	isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true);
   18059 	isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true);
   18060 
   18061 	zmgr->iolimit = 1;
   18062 	zmgr->ioactive = 0;
   18063 	ISC_LIST_INIT(zmgr->high);
   18064 	ISC_LIST_INIT(zmgr->low);
   18065 
   18066 	isc_mutex_init(&zmgr->iolock);
   18067 
   18068 	zmgr->magic = ZONEMGR_MAGIC;
   18069 
   18070 	*zmgrp = zmgr;
   18071 	return (ISC_R_SUCCESS);
   18072 
   18073 #if 0
   18074  free_iolock:
   18075 	isc_mutex_destroy(&zmgr->iolock);
   18076 #endif /* if 0 */
   18077 free_startupnotifyrl:
   18078 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   18079 free_refreshrl:
   18080 	isc_ratelimiter_detach(&zmgr->refreshrl);
   18081 free_notifyrl:
   18082 	isc_ratelimiter_detach(&zmgr->notifyrl);
   18083 free_task:
   18084 	isc_task_detach(&zmgr->task);
   18085 free_urlock:
   18086 	isc_rwlock_destroy(&zmgr->urlock);
   18087 	isc_rwlock_destroy(&zmgr->rwlock);
   18088 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   18089 	isc_mem_detach(&mctx);
   18090 	return (result);
   18091 }
   18092 
   18093 isc_result_t
   18094 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
   18095 	isc_result_t result;
   18096 	isc_mem_t *mctx = NULL;
   18097 	dns_zone_t *zone = NULL;
   18098 	void *item;
   18099 
   18100 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18101 	REQUIRE(zonep != NULL && *zonep == NULL);
   18102 
   18103 	if (zmgr->mctxpool == NULL) {
   18104 		return (ISC_R_FAILURE);
   18105 	}
   18106 
   18107 	item = isc_pool_get(zmgr->mctxpool);
   18108 	if (item == NULL) {
   18109 		return (ISC_R_FAILURE);
   18110 	}
   18111 
   18112 	isc_mem_attach((isc_mem_t *)item, &mctx);
   18113 	result = dns_zone_create(&zone, mctx);
   18114 	isc_mem_detach(&mctx);
   18115 
   18116 	if (result == ISC_R_SUCCESS) {
   18117 		*zonep = zone;
   18118 	}
   18119 
   18120 	return (result);
   18121 }
   18122 
   18123 isc_result_t
   18124 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18125 	isc_result_t result;
   18126 
   18127 	REQUIRE(DNS_ZONE_VALID(zone));
   18128 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18129 
   18130 	if (zmgr->zonetasks == NULL) {
   18131 		return (ISC_R_FAILURE);
   18132 	}
   18133 
   18134 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18135 	LOCK_ZONE(zone);
   18136 	REQUIRE(zone->task == NULL);
   18137 	REQUIRE(zone->timer == NULL);
   18138 	REQUIRE(zone->zmgr == NULL);
   18139 
   18140 	isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
   18141 	isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
   18142 
   18143 	/*
   18144 	 * Set the task name.  The tag will arbitrarily point to one
   18145 	 * of the zones sharing the task (in practice, the one
   18146 	 * to be managed last).
   18147 	 */
   18148 	isc_task_setname(zone->task, "zone", zone);
   18149 	isc_task_setname(zone->loadtask, "loadzone", zone);
   18150 
   18151 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   18152 				  NULL, zone->task, zone_timer, zone,
   18153 				  &zone->timer);
   18154 
   18155 	if (result != ISC_R_SUCCESS) {
   18156 		goto cleanup_tasks;
   18157 	}
   18158 
   18159 	/*
   18160 	 * The timer "holds" a iref.
   18161 	 */
   18162 	isc_refcount_increment0(&zone->irefs);
   18163 
   18164 	ISC_LIST_APPEND(zmgr->zones, zone, link);
   18165 	zone->zmgr = zmgr;
   18166 	isc_refcount_increment(&zmgr->refs);
   18167 
   18168 	goto unlock;
   18169 
   18170 cleanup_tasks:
   18171 	isc_task_detach(&zone->loadtask);
   18172 	isc_task_detach(&zone->task);
   18173 
   18174 unlock:
   18175 	UNLOCK_ZONE(zone);
   18176 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18177 	return (result);
   18178 }
   18179 
   18180 void
   18181 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18182 	bool free_now = false;
   18183 
   18184 	REQUIRE(DNS_ZONE_VALID(zone));
   18185 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18186 	REQUIRE(zone->zmgr == zmgr);
   18187 
   18188 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18189 	LOCK_ZONE(zone);
   18190 
   18191 	ISC_LIST_UNLINK(zmgr->zones, zone, link);
   18192 	zone->zmgr = NULL;
   18193 
   18194 	if (isc_refcount_decrement(&zmgr->refs) == 1) {
   18195 		free_now = true;
   18196 	}
   18197 
   18198 	UNLOCK_ZONE(zone);
   18199 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18200 
   18201 	if (free_now) {
   18202 		zonemgr_free(zmgr);
   18203 	}
   18204 	ENSURE(zone->zmgr == NULL);
   18205 }
   18206 
   18207 void
   18208 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
   18209 	REQUIRE(DNS_ZONEMGR_VALID(source));
   18210 	REQUIRE(target != NULL && *target == NULL);
   18211 
   18212 	isc_refcount_increment(&source->refs);
   18213 
   18214 	*target = source;
   18215 }
   18216 
   18217 void
   18218 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
   18219 	dns_zonemgr_t *zmgr;
   18220 
   18221 	REQUIRE(zmgrp != NULL);
   18222 	zmgr = *zmgrp;
   18223 	*zmgrp = NULL;
   18224 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18225 
   18226 	if (isc_refcount_decrement(&zmgr->refs) == 1) {
   18227 		zonemgr_free(zmgr);
   18228 	}
   18229 }
   18230 
   18231 isc_result_t
   18232 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
   18233 	dns_zone_t *p;
   18234 
   18235 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18236 
   18237 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18238 	for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL;
   18239 	     p = ISC_LIST_NEXT(p, link)) {
   18240 		dns_zone_maintenance(p);
   18241 	}
   18242 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18243 
   18244 	/*
   18245 	 * Recent configuration changes may have increased the
   18246 	 * amount of available transfers quota.  Make sure any
   18247 	 * transfers currently blocked on quota get started if
   18248 	 * possible.
   18249 	 */
   18250 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18251 	zmgr_resume_xfrs(zmgr, true);
   18252 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18253 	return (ISC_R_SUCCESS);
   18254 }
   18255 
   18256 void
   18257 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
   18258 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18259 
   18260 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18261 	zmgr_resume_xfrs(zmgr, true);
   18262 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18263 }
   18264 
   18265 void
   18266 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
   18267 	dns_zone_t *zone;
   18268 
   18269 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18270 
   18271 	isc_ratelimiter_shutdown(zmgr->notifyrl);
   18272 	isc_ratelimiter_shutdown(zmgr->refreshrl);
   18273 	isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
   18274 	isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
   18275 
   18276 	if (zmgr->task != NULL) {
   18277 		isc_task_destroy(&zmgr->task);
   18278 	}
   18279 	if (zmgr->zonetasks != NULL) {
   18280 		isc_taskpool_destroy(&zmgr->zonetasks);
   18281 	}
   18282 	if (zmgr->loadtasks != NULL) {
   18283 		isc_taskpool_destroy(&zmgr->loadtasks);
   18284 	}
   18285 	if (zmgr->mctxpool != NULL) {
   18286 		isc_pool_destroy(&zmgr->mctxpool);
   18287 	}
   18288 
   18289 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18290 	for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   18291 	     zone = ISC_LIST_NEXT(zone, link))
   18292 	{
   18293 		LOCK_ZONE(zone);
   18294 		forward_cancel(zone);
   18295 		UNLOCK_ZONE(zone);
   18296 	}
   18297 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18298 }
   18299 
   18300 static isc_result_t
   18301 mctxinit(void **target, void *arg) {
   18302 	isc_mem_t *mctx = NULL;
   18303 
   18304 	UNUSED(arg);
   18305 
   18306 	REQUIRE(target != NULL && *target == NULL);
   18307 
   18308 	isc_mem_create(&mctx);
   18309 	isc_mem_setname(mctx, "zonemgr-pool", NULL);
   18310 
   18311 	*target = mctx;
   18312 	return (ISC_R_SUCCESS);
   18313 }
   18314 
   18315 static void
   18316 mctxfree(void **target) {
   18317 	isc_mem_t *mctx = *(isc_mem_t **)target;
   18318 	isc_mem_detach(&mctx);
   18319 	*target = NULL;
   18320 }
   18321 
   18322 #define ZONES_PER_TASK 100
   18323 #define ZONES_PER_MCTX 1000
   18324 
   18325 isc_result_t
   18326 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
   18327 	isc_result_t result;
   18328 	int ntasks = num_zones / ZONES_PER_TASK;
   18329 	int nmctx = num_zones / ZONES_PER_MCTX;
   18330 	isc_taskpool_t *pool = NULL;
   18331 	isc_pool_t *mctxpool = NULL;
   18332 
   18333 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18334 
   18335 	/*
   18336 	 * For anything fewer than 1000 zones we use 10 tasks in
   18337 	 * the task pools.  More than that, and we'll scale at one
   18338 	 * task per 100 zones.  Similarly, for anything smaller than
   18339 	 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
   18340 	 */
   18341 	if (ntasks < 10) {
   18342 		ntasks = 10;
   18343 	}
   18344 	if (nmctx < 2) {
   18345 		nmctx = 2;
   18346 	}
   18347 
   18348 	/* Create or resize the zone task pools. */
   18349 	if (zmgr->zonetasks == NULL) {
   18350 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   18351 					     2, &pool);
   18352 	} else {
   18353 		result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
   18354 	}
   18355 
   18356 	if (result == ISC_R_SUCCESS) {
   18357 		zmgr->zonetasks = pool;
   18358 	}
   18359 
   18360 	pool = NULL;
   18361 	if (zmgr->loadtasks == NULL) {
   18362 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   18363 					     2, &pool);
   18364 	} else {
   18365 		result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
   18366 	}
   18367 
   18368 	if (result == ISC_R_SUCCESS) {
   18369 		zmgr->loadtasks = pool;
   18370 	}
   18371 
   18372 	/*
   18373 	 * We always set all tasks in the zone-load task pool to
   18374 	 * privileged.  This prevents other tasks in the system from
   18375 	 * running while the server task manager is in privileged
   18376 	 * mode.
   18377 	 *
   18378 	 * NOTE: If we start using task privileges for any other
   18379 	 * part of the system than zone tasks, then this will need to be
   18380 	 * revisted.  In that case we'd want to turn on privileges for
   18381 	 * zone tasks only when we were loading, and turn them off the
   18382 	 * rest of the time.  For now, however, it's okay to just
   18383 	 * set it and forget it.
   18384 	 */
   18385 	isc_taskpool_setprivilege(zmgr->loadtasks, true);
   18386 
   18387 	/* Create or resize the zone memory context pool. */
   18388 	if (zmgr->mctxpool == NULL) {
   18389 		result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit,
   18390 					 NULL, &mctxpool);
   18391 	} else {
   18392 		result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
   18393 	}
   18394 
   18395 	if (result == ISC_R_SUCCESS) {
   18396 		zmgr->mctxpool = mctxpool;
   18397 	}
   18398 
   18399 	return (result);
   18400 }
   18401 
   18402 static void
   18403 zonemgr_free(dns_zonemgr_t *zmgr) {
   18404 	isc_mem_t *mctx;
   18405 
   18406 	INSIST(ISC_LIST_EMPTY(zmgr->zones));
   18407 
   18408 	zmgr->magic = 0;
   18409 
   18410 	isc_refcount_destroy(&zmgr->refs);
   18411 	isc_mutex_destroy(&zmgr->iolock);
   18412 	isc_ratelimiter_detach(&zmgr->notifyrl);
   18413 	isc_ratelimiter_detach(&zmgr->refreshrl);
   18414 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   18415 	isc_ratelimiter_detach(&zmgr->startuprefreshrl);
   18416 
   18417 	isc_rwlock_destroy(&zmgr->urlock);
   18418 	isc_rwlock_destroy(&zmgr->rwlock);
   18419 	mctx = zmgr->mctx;
   18420 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   18421 	isc_mem_detach(&mctx);
   18422 }
   18423 
   18424 void
   18425 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
   18426 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18427 
   18428 	zmgr->transfersin = value;
   18429 }
   18430 
   18431 uint32_t
   18432 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
   18433 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18434 
   18435 	return (zmgr->transfersin);
   18436 }
   18437 
   18438 void
   18439 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
   18440 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18441 
   18442 	zmgr->transfersperns = value;
   18443 }
   18444 
   18445 uint32_t
   18446 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
   18447 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18448 
   18449 	return (zmgr->transfersperns);
   18450 }
   18451 
   18452 /*
   18453  * Try to start a new incoming zone transfer to fill a quota
   18454  * slot that was just vacated.
   18455  *
   18456  * Requires:
   18457  *	The zone manager is locked by the caller.
   18458  */
   18459 static void
   18460 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) {
   18461 	dns_zone_t *zone;
   18462 	dns_zone_t *next;
   18463 
   18464 	for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL;
   18465 	     zone = next) {
   18466 		isc_result_t result;
   18467 		next = ISC_LIST_NEXT(zone, statelink);
   18468 		result = zmgr_start_xfrin_ifquota(zmgr, zone);
   18469 		if (result == ISC_R_SUCCESS) {
   18470 			if (multi) {
   18471 				continue;
   18472 			}
   18473 			/*
   18474 			 * We successfully filled the slot.  We're done.
   18475 			 */
   18476 			break;
   18477 		} else if (result == ISC_R_QUOTA) {
   18478 			/*
   18479 			 * Not enough quota.  This is probably the per-server
   18480 			 * quota, because we usually get called when a unit of
   18481 			 * global quota has just been freed.  Try the next
   18482 			 * zone, it may succeed if it uses another master.
   18483 			 */
   18484 			continue;
   18485 		} else {
   18486 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   18487 				      ISC_LOG_DEBUG(1),
   18488 				      "starting zone transfer: %s",
   18489 				      isc_result_totext(result));
   18490 			break;
   18491 		}
   18492 	}
   18493 }
   18494 
   18495 /*
   18496  * Try to start an incoming zone transfer for 'zone', quota permitting.
   18497  *
   18498  * Requires:
   18499  *	The zone manager is locked by the caller.
   18500  *
   18501  * Returns:
   18502  *	ISC_R_SUCCESS	There was enough quota and we attempted to
   18503  *			start a transfer.  zone_xfrdone() has been or will
   18504  *			be called.
   18505  *	ISC_R_QUOTA	Not enough quota.
   18506  *	Others		Failure.
   18507  */
   18508 static isc_result_t
   18509 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18510 	dns_peer_t *peer = NULL;
   18511 	isc_netaddr_t masterip;
   18512 	uint32_t nxfrsin, nxfrsperns;
   18513 	dns_zone_t *x;
   18514 	uint32_t maxtransfersin, maxtransfersperns;
   18515 	isc_event_t *e;
   18516 
   18517 	/*
   18518 	 * If we are exiting just pretend we got quota so the zone will
   18519 	 * be cleaned up in the zone's task context.
   18520 	 */
   18521 	LOCK_ZONE(zone);
   18522 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   18523 		UNLOCK_ZONE(zone);
   18524 		goto gotquota;
   18525 	}
   18526 
   18527 	/*
   18528 	 * Find any configured information about the server we'd
   18529 	 * like to transfer this zone from.
   18530 	 */
   18531 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   18532 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   18533 	UNLOCK_ZONE(zone);
   18534 
   18535 	/*
   18536 	 * Determine the total maximum number of simultaneous
   18537 	 * transfers allowed, and the maximum for this specific
   18538 	 * master.
   18539 	 */
   18540 	maxtransfersin = zmgr->transfersin;
   18541 	maxtransfersperns = zmgr->transfersperns;
   18542 	if (peer != NULL) {
   18543 		(void)dns_peer_gettransfers(peer, &maxtransfersperns);
   18544 	}
   18545 
   18546 	/*
   18547 	 * Count the total number of transfers that are in progress,
   18548 	 * and the number of transfers in progress from this master.
   18549 	 * We linearly scan a list of all transfers; if this turns
   18550 	 * out to be too slow, we could hash on the master address.
   18551 	 */
   18552 	nxfrsin = nxfrsperns = 0;
   18553 	for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL;
   18554 	     x = ISC_LIST_NEXT(x, statelink))
   18555 	{
   18556 		isc_netaddr_t xip;
   18557 
   18558 		LOCK_ZONE(x);
   18559 		isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
   18560 		UNLOCK_ZONE(x);
   18561 
   18562 		nxfrsin++;
   18563 		if (isc_netaddr_equal(&xip, &masterip)) {
   18564 			nxfrsperns++;
   18565 		}
   18566 	}
   18567 
   18568 	/* Enforce quota. */
   18569 	if (nxfrsin >= maxtransfersin) {
   18570 		return (ISC_R_QUOTA);
   18571 	}
   18572 
   18573 	if (nxfrsperns >= maxtransfersperns) {
   18574 		return (ISC_R_QUOTA);
   18575 	}
   18576 
   18577 gotquota:
   18578 	/*
   18579 	 * We have sufficient quota.  Move the zone to the "xfrin_in_progress"
   18580 	 * list and send it an event to let it start the actual transfer in the
   18581 	 * context of its own task.
   18582 	 */
   18583 	e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
   18584 			       got_transfer_quota, zone, sizeof(isc_event_t));
   18585 
   18586 	LOCK_ZONE(zone);
   18587 	INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
   18588 	ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
   18589 	ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
   18590 	zone->statelist = &zmgr->xfrin_in_progress;
   18591 	isc_task_send(zone->task, &e);
   18592 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   18593 		      "Transfer started.");
   18594 	UNLOCK_ZONE(zone);
   18595 
   18596 	return (ISC_R_SUCCESS);
   18597 }
   18598 
   18599 void
   18600 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) {
   18601 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18602 	REQUIRE(iolimit > 0);
   18603 
   18604 	zmgr->iolimit = iolimit;
   18605 }
   18606 
   18607 uint32_t
   18608 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
   18609 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18610 
   18611 	return (zmgr->iolimit);
   18612 }
   18613 
   18614 /*
   18615  * Get permission to request a file handle from the OS.
   18616  * An event will be sent to action when one is available.
   18617  * There are two queues available (high and low), the high
   18618  * queue will be serviced before the low one.
   18619  *
   18620  * zonemgr_putio() must be called after the event is delivered to
   18621  * 'action'.
   18622  */
   18623 
   18624 static isc_result_t
   18625 zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task,
   18626 	      isc_taskaction_t action, void *arg, dns_io_t **iop) {
   18627 	dns_io_t *io;
   18628 	bool queue;
   18629 
   18630 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18631 	REQUIRE(iop != NULL && *iop == NULL);
   18632 
   18633 	io = isc_mem_get(zmgr->mctx, sizeof(*io));
   18634 
   18635 	io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
   18636 				       action, arg, sizeof(*io->event));
   18637 
   18638 	io->zmgr = zmgr;
   18639 	io->high = high;
   18640 	io->task = NULL;
   18641 	isc_task_attach(task, &io->task);
   18642 	ISC_LINK_INIT(io, link);
   18643 	io->magic = IO_MAGIC;
   18644 
   18645 	LOCK(&zmgr->iolock);
   18646 	zmgr->ioactive++;
   18647 	queue = (zmgr->ioactive > zmgr->iolimit);
   18648 	if (queue) {
   18649 		if (io->high) {
   18650 			ISC_LIST_APPEND(zmgr->high, io, link);
   18651 		} else {
   18652 			ISC_LIST_APPEND(zmgr->low, io, link);
   18653 		}
   18654 	}
   18655 	UNLOCK(&zmgr->iolock);
   18656 	*iop = io;
   18657 
   18658 	if (!queue) {
   18659 		isc_task_send(io->task, &io->event);
   18660 	}
   18661 	return (ISC_R_SUCCESS);
   18662 }
   18663 
   18664 static void
   18665 zonemgr_putio(dns_io_t **iop) {
   18666 	dns_io_t *io;
   18667 	dns_io_t *next;
   18668 	dns_zonemgr_t *zmgr;
   18669 
   18670 	REQUIRE(iop != NULL);
   18671 	io = *iop;
   18672 	*iop = NULL;
   18673 	REQUIRE(DNS_IO_VALID(io));
   18674 
   18675 	INSIST(!ISC_LINK_LINKED(io, link));
   18676 	INSIST(io->event == NULL);
   18677 
   18678 	zmgr = io->zmgr;
   18679 	isc_task_detach(&io->task);
   18680 	io->magic = 0;
   18681 	isc_mem_put(zmgr->mctx, io, sizeof(*io));
   18682 
   18683 	LOCK(&zmgr->iolock);
   18684 	INSIST(zmgr->ioactive > 0);
   18685 	zmgr->ioactive--;
   18686 	next = HEAD(zmgr->high);
   18687 	if (next == NULL) {
   18688 		next = HEAD(zmgr->low);
   18689 	}
   18690 	if (next != NULL) {
   18691 		if (next->high) {
   18692 			ISC_LIST_UNLINK(zmgr->high, next, link);
   18693 		} else {
   18694 			ISC_LIST_UNLINK(zmgr->low, next, link);
   18695 		}
   18696 		INSIST(next->event != NULL);
   18697 	}
   18698 	UNLOCK(&zmgr->iolock);
   18699 	if (next != NULL) {
   18700 		isc_task_send(next->task, &next->event);
   18701 	}
   18702 }
   18703 
   18704 static void
   18705 zonemgr_cancelio(dns_io_t *io) {
   18706 	bool send_event = false;
   18707 
   18708 	REQUIRE(DNS_IO_VALID(io));
   18709 
   18710 	/*
   18711 	 * If we are queued to be run then dequeue.
   18712 	 */
   18713 	LOCK(&io->zmgr->iolock);
   18714 	if (ISC_LINK_LINKED(io, link)) {
   18715 		if (io->high) {
   18716 			ISC_LIST_UNLINK(io->zmgr->high, io, link);
   18717 		} else {
   18718 			ISC_LIST_UNLINK(io->zmgr->low, io, link);
   18719 		}
   18720 
   18721 		send_event = true;
   18722 		INSIST(io->event != NULL);
   18723 	}
   18724 	UNLOCK(&io->zmgr->iolock);
   18725 	if (send_event) {
   18726 		io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
   18727 		isc_task_send(io->task, &io->event);
   18728 	}
   18729 }
   18730 
   18731 static void
   18732 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
   18733 	char *buf;
   18734 	int buflen;
   18735 	isc_result_t result;
   18736 
   18737 	buflen = strlen(path) + strlen(templat) + 2;
   18738 
   18739 	buf = isc_mem_get(zone->mctx, buflen);
   18740 
   18741 	result = isc_file_template(path, templat, buf, buflen);
   18742 	if (result != ISC_R_SUCCESS) {
   18743 		goto cleanup;
   18744 	}
   18745 
   18746 	result = isc_file_renameunique(path, buf);
   18747 	if (result != ISC_R_SUCCESS) {
   18748 		goto cleanup;
   18749 	}
   18750 
   18751 	dns_zone_log(zone, ISC_LOG_WARNING,
   18752 		     "unable to load from '%s'; "
   18753 		     "renaming file to '%s' for failure analysis and "
   18754 		     "retransferring.",
   18755 		     path, buf);
   18756 
   18757 cleanup:
   18758 	isc_mem_put(zone->mctx, buf, buflen);
   18759 }
   18760 
   18761 static void
   18762 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
   18763 	isc_interval_t interval;
   18764 	uint32_t s, ns;
   18765 	uint32_t pertic;
   18766 	isc_result_t result;
   18767 
   18768 	if (value == 0) {
   18769 		value = 1;
   18770 	}
   18771 
   18772 	if (value == 1) {
   18773 		s = 1;
   18774 		ns = 0;
   18775 		pertic = 1;
   18776 	} else if (value <= 10) {
   18777 		s = 0;
   18778 		ns = 1000000000 / value;
   18779 		pertic = 1;
   18780 	} else {
   18781 		s = 0;
   18782 		ns = (1000000000 / value) * 10;
   18783 		pertic = 10;
   18784 	}
   18785 
   18786 	isc_interval_set(&interval, s, ns);
   18787 
   18788 	result = isc_ratelimiter_setinterval(rl, &interval);
   18789 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   18790 	isc_ratelimiter_setpertic(rl, pertic);
   18791 
   18792 	*rate = value;
   18793 }
   18794 
   18795 void
   18796 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   18797 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18798 
   18799 	setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
   18800 }
   18801 
   18802 void
   18803 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   18804 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18805 
   18806 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
   18807 }
   18808 
   18809 void
   18810 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
   18811 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18812 
   18813 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
   18814 	/* XXXMPA separate out once we have the code to support this. */
   18815 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
   18816 }
   18817 
   18818 unsigned int
   18819 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
   18820 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18821 
   18822 	return (zmgr->notifyrate);
   18823 }
   18824 
   18825 unsigned int
   18826 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
   18827 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18828 
   18829 	return (zmgr->startupnotifyrate);
   18830 }
   18831 
   18832 unsigned int
   18833 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
   18834 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18835 
   18836 	return (zmgr->serialqueryrate);
   18837 }
   18838 
   18839 bool
   18840 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   18841 			isc_sockaddr_t *local, isc_time_t *now) {
   18842 	unsigned int i;
   18843 	uint32_t seconds = isc_time_seconds(now);
   18844 	uint32_t count = 0;
   18845 
   18846 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18847 
   18848 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18849 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18850 		if (atomic_load(&zmgr->unreachable[i].expire) >= seconds &&
   18851 		    isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   18852 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   18853 		{
   18854 			atomic_store_relaxed(&zmgr->unreachable[i].last,
   18855 					     seconds);
   18856 			count = zmgr->unreachable[i].count;
   18857 			break;
   18858 		}
   18859 	}
   18860 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18861 	return (i < UNREACH_CACHE_SIZE && count > 1U);
   18862 }
   18863 
   18864 void
   18865 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   18866 			   isc_sockaddr_t *local) {
   18867 	unsigned int i;
   18868 	char master[ISC_SOCKADDR_FORMATSIZE];
   18869 	char source[ISC_SOCKADDR_FORMATSIZE];
   18870 
   18871 	isc_sockaddr_format(remote, master, sizeof(master));
   18872 	isc_sockaddr_format(local, source, sizeof(source));
   18873 
   18874 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18875 
   18876 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18877 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18878 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   18879 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   18880 		{
   18881 			atomic_store_relaxed(&zmgr->unreachable[i].expire, 0);
   18882 			break;
   18883 		}
   18884 	}
   18885 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18886 }
   18887 
   18888 void
   18889 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   18890 			   isc_sockaddr_t *local, isc_time_t *now) {
   18891 	uint32_t seconds = isc_time_seconds(now);
   18892 	uint32_t expire = 0, last = seconds;
   18893 	unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0;
   18894 	bool update_entry = true;
   18895 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18896 
   18897 	RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
   18898 	for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18899 		/* Existing entry? */
   18900 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   18901 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   18902 		{
   18903 			update_entry = false;
   18904 			slot = i;
   18905 			expire = atomic_load_relaxed(
   18906 				&zmgr->unreachable[i].expire);
   18907 			break;
   18908 		}
   18909 		/* Pick first empty slot? */
   18910 		if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds)
   18911 		{
   18912 			slot = i;
   18913 			break;
   18914 		}
   18915 		/* The worst case, least recently used slot? */
   18916 		if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) {
   18917 			last = atomic_load_relaxed(&zmgr->unreachable[i].last);
   18918 			oldest = i;
   18919 		}
   18920 	}
   18921 
   18922 	/* We haven't found any existing or free slots, use the oldest */
   18923 	if (slot == UNREACH_CACHE_SIZE) {
   18924 		slot = oldest;
   18925 	}
   18926 
   18927 	if (expire < seconds) {
   18928 		/* Expired or new entry, reset count to 1 */
   18929 		zmgr->unreachable[slot].count = 1;
   18930 	} else {
   18931 		zmgr->unreachable[slot].count++;
   18932 	}
   18933 	atomic_store_relaxed(&zmgr->unreachable[slot].expire,
   18934 			     seconds + UNREACH_HOLD_TIME);
   18935 	atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds);
   18936 	if (update_entry) {
   18937 		zmgr->unreachable[slot].remote = *remote;
   18938 		zmgr->unreachable[slot].local = *local;
   18939 	}
   18940 
   18941 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
   18942 }
   18943 
   18944 void
   18945 dns_zone_forcereload(dns_zone_t *zone) {
   18946 	REQUIRE(DNS_ZONE_VALID(zone));
   18947 
   18948 	if (zone->type == dns_zone_master ||
   18949 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   18950 	{
   18951 		return;
   18952 	}
   18953 
   18954 	LOCK_ZONE(zone);
   18955 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   18956 	UNLOCK_ZONE(zone);
   18957 	dns_zone_refresh(zone);
   18958 }
   18959 
   18960 bool
   18961 dns_zone_isforced(dns_zone_t *zone) {
   18962 	REQUIRE(DNS_ZONE_VALID(zone));
   18963 
   18964 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
   18965 }
   18966 
   18967 isc_result_t
   18968 dns_zone_setstatistics(dns_zone_t *zone, bool on) {
   18969 	/*
   18970 	 * This function is obsoleted.
   18971 	 */
   18972 	UNUSED(zone);
   18973 	UNUSED(on);
   18974 	return (ISC_R_NOTIMPLEMENTED);
   18975 }
   18976 
   18977 uint64_t *
   18978 dns_zone_getstatscounters(dns_zone_t *zone) {
   18979 	/*
   18980 	 * This function is obsoleted.
   18981 	 */
   18982 	UNUSED(zone);
   18983 	return (NULL);
   18984 }
   18985 
   18986 void
   18987 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
   18988 	REQUIRE(DNS_ZONE_VALID(zone));
   18989 	REQUIRE(zone->stats == NULL);
   18990 
   18991 	LOCK_ZONE(zone);
   18992 	zone->stats = NULL;
   18993 	isc_stats_attach(stats, &zone->stats);
   18994 	UNLOCK_ZONE(zone);
   18995 }
   18996 
   18997 void
   18998 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
   18999 	REQUIRE(DNS_ZONE_VALID(zone));
   19000 
   19001 	LOCK_ZONE(zone);
   19002 	if (zone->requeststats_on && stats == NULL) {
   19003 		zone->requeststats_on = false;
   19004 	} else if (!zone->requeststats_on && stats != NULL) {
   19005 		if (zone->requeststats == NULL) {
   19006 			isc_stats_attach(stats, &zone->requeststats);
   19007 			zone->requeststats_on = true;
   19008 		}
   19009 	}
   19010 	UNLOCK_ZONE(zone);
   19011 }
   19012 
   19013 void
   19014 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
   19015 	REQUIRE(DNS_ZONE_VALID(zone));
   19016 
   19017 	LOCK_ZONE(zone);
   19018 	if (zone->requeststats_on && stats != NULL) {
   19019 		if (zone->rcvquerystats == NULL) {
   19020 			dns_stats_attach(stats, &zone->rcvquerystats);
   19021 			zone->requeststats_on = true;
   19022 		}
   19023 	}
   19024 	UNLOCK_ZONE(zone);
   19025 }
   19026 
   19027 void
   19028 dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
   19029 	REQUIRE(DNS_ZONE_VALID(zone));
   19030 
   19031 	LOCK_ZONE(zone);
   19032 	if (stats != NULL && zone->dnssecsignstats == NULL) {
   19033 		dns_stats_attach(stats, &zone->dnssecsignstats);
   19034 	}
   19035 	UNLOCK_ZONE(zone);
   19036 }
   19037 
   19038 dns_stats_t *
   19039 dns_zone_getdnssecsignstats(dns_zone_t *zone) {
   19040 	REQUIRE(DNS_ZONE_VALID(zone));
   19041 
   19042 	return (zone->dnssecsignstats);
   19043 }
   19044 
   19045 isc_stats_t *
   19046 dns_zone_getrequeststats(dns_zone_t *zone) {
   19047 	/*
   19048 	 * We don't lock zone for efficiency reason.  This is not catastrophic
   19049 	 * because requeststats must always be valid when requeststats_on is
   19050 	 * true.
   19051 	 * Some counters may be incremented while requeststats_on is becoming
   19052 	 * false, or some cannot be incremented just after the statistics are
   19053 	 * installed, but it shouldn't matter much in practice.
   19054 	 */
   19055 	if (zone->requeststats_on) {
   19056 		return (zone->requeststats);
   19057 	} else {
   19058 		return (NULL);
   19059 	}
   19060 }
   19061 
   19062 /*
   19063  * Return the received query stats bucket
   19064  * see note from dns_zone_getrequeststats()
   19065  */
   19066 dns_stats_t *
   19067 dns_zone_getrcvquerystats(dns_zone_t *zone) {
   19068 	if (zone->requeststats_on) {
   19069 		return (zone->rcvquerystats);
   19070 	} else {
   19071 		return (NULL);
   19072 	}
   19073 }
   19074 
   19075 void
   19076 dns_zone_dialup(dns_zone_t *zone) {
   19077 	REQUIRE(DNS_ZONE_VALID(zone));
   19078 
   19079 	zone_debuglog(zone, "dns_zone_dialup", 3, "notify = %d, refresh = %d",
   19080 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
   19081 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
   19082 
   19083 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   19084 		dns_zone_notify(zone);
   19085 	}
   19086 	if (zone->type != dns_zone_master && zone->masters != NULL &&
   19087 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
   19088 	{
   19089 		dns_zone_refresh(zone);
   19090 	}
   19091 }
   19092 
   19093 void
   19094 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
   19095 	REQUIRE(DNS_ZONE_VALID(zone));
   19096 
   19097 	LOCK_ZONE(zone);
   19098 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
   19099 				       DNS_ZONEFLG_DIALREFRESH |
   19100 				       DNS_ZONEFLG_NOREFRESH);
   19101 	switch (dialup) {
   19102 	case dns_dialuptype_no:
   19103 		break;
   19104 	case dns_dialuptype_yes:
   19105 		DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
   19106 					DNS_ZONEFLG_DIALREFRESH |
   19107 					DNS_ZONEFLG_NOREFRESH));
   19108 		break;
   19109 	case dns_dialuptype_notify:
   19110 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19111 		break;
   19112 	case dns_dialuptype_notifypassive:
   19113 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19114 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19115 		break;
   19116 	case dns_dialuptype_refresh:
   19117 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
   19118 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19119 		break;
   19120 	case dns_dialuptype_passive:
   19121 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19122 		break;
   19123 	default:
   19124 		INSIST(0);
   19125 		ISC_UNREACHABLE();
   19126 	}
   19127 	UNLOCK_ZONE(zone);
   19128 }
   19129 
   19130 isc_result_t
   19131 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
   19132 	isc_result_t result = ISC_R_SUCCESS;
   19133 
   19134 	REQUIRE(DNS_ZONE_VALID(zone));
   19135 
   19136 	LOCK_ZONE(zone);
   19137 	result = dns_zone_setstring(zone, &zone->keydirectory, directory);
   19138 	UNLOCK_ZONE(zone);
   19139 
   19140 	return (result);
   19141 }
   19142 
   19143 const char *
   19144 dns_zone_getkeydirectory(dns_zone_t *zone) {
   19145 	REQUIRE(DNS_ZONE_VALID(zone));
   19146 
   19147 	return (zone->keydirectory);
   19148 }
   19149 
   19150 unsigned int
   19151 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
   19152 	dns_zone_t *zone;
   19153 	unsigned int count = 0;
   19154 
   19155 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19156 
   19157 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19158 	switch (state) {
   19159 	case DNS_ZONESTATE_XFERRUNNING:
   19160 		for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
   19161 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19162 		{
   19163 			count++;
   19164 		}
   19165 		break;
   19166 	case DNS_ZONESTATE_XFERDEFERRED:
   19167 		for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
   19168 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19169 		{
   19170 			count++;
   19171 		}
   19172 		break;
   19173 	case DNS_ZONESTATE_SOAQUERY:
   19174 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19175 		     zone = ISC_LIST_NEXT(zone, link))
   19176 		{
   19177 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   19178 				count++;
   19179 			}
   19180 		}
   19181 		break;
   19182 	case DNS_ZONESTATE_ANY:
   19183 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19184 		     zone = ISC_LIST_NEXT(zone, link))
   19185 		{
   19186 			dns_view_t *view = zone->view;
   19187 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   19188 				continue;
   19189 			}
   19190 			count++;
   19191 		}
   19192 		break;
   19193 	case DNS_ZONESTATE_AUTOMATIC:
   19194 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19195 		     zone = ISC_LIST_NEXT(zone, link))
   19196 		{
   19197 			dns_view_t *view = zone->view;
   19198 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   19199 				continue;
   19200 			}
   19201 			if (zone->automatic) {
   19202 				count++;
   19203 			}
   19204 		}
   19205 		break;
   19206 	default:
   19207 		INSIST(0);
   19208 		ISC_UNREACHABLE();
   19209 	}
   19210 
   19211 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19212 
   19213 	return (count);
   19214 }
   19215 
   19216 isc_result_t
   19217 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
   19218 		    dns_rdata_t *rdata) {
   19219 	bool ok = true;
   19220 	bool fail = false;
   19221 	char namebuf[DNS_NAME_FORMATSIZE];
   19222 	char namebuf2[DNS_NAME_FORMATSIZE];
   19223 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   19224 	int level = ISC_LOG_WARNING;
   19225 	dns_name_t bad;
   19226 
   19227 	REQUIRE(DNS_ZONE_VALID(zone));
   19228 
   19229 	if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
   19230 	    rdata->type != dns_rdatatype_nsec3)
   19231 	{
   19232 		return (ISC_R_SUCCESS);
   19233 	}
   19234 
   19235 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
   19236 	    rdata->type == dns_rdatatype_nsec3)
   19237 	{
   19238 		level = ISC_LOG_ERROR;
   19239 		fail = true;
   19240 	}
   19241 
   19242 	ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true);
   19243 	if (!ok) {
   19244 		dns_name_format(name, namebuf, sizeof(namebuf));
   19245 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   19246 		dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
   19247 			     dns_result_totext(DNS_R_BADOWNERNAME));
   19248 		if (fail) {
   19249 			return (DNS_R_BADOWNERNAME);
   19250 		}
   19251 	}
   19252 
   19253 	dns_name_init(&bad, NULL);
   19254 	ok = dns_rdata_checknames(rdata, name, &bad);
   19255 	if (!ok) {
   19256 		dns_name_format(name, namebuf, sizeof(namebuf));
   19257 		dns_name_format(&bad, namebuf2, sizeof(namebuf2));
   19258 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   19259 		dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
   19260 			     namebuf2, dns_result_totext(DNS_R_BADNAME));
   19261 		if (fail) {
   19262 			return (DNS_R_BADNAME);
   19263 		}
   19264 	}
   19265 
   19266 	return (ISC_R_SUCCESS);
   19267 }
   19268 
   19269 void
   19270 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
   19271 	REQUIRE(DNS_ZONE_VALID(zone));
   19272 	zone->checkmx = checkmx;
   19273 }
   19274 
   19275 void
   19276 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
   19277 	REQUIRE(DNS_ZONE_VALID(zone));
   19278 	zone->checksrv = checksrv;
   19279 }
   19280 
   19281 void
   19282 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
   19283 	REQUIRE(DNS_ZONE_VALID(zone));
   19284 	zone->checkns = checkns;
   19285 }
   19286 
   19287 void
   19288 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
   19289 	REQUIRE(DNS_ZONE_VALID(zone));
   19290 
   19291 	LOCK_ZONE(zone);
   19292 	zone->isself = isself;
   19293 	zone->isselfarg = arg;
   19294 	UNLOCK_ZONE(zone);
   19295 }
   19296 
   19297 void
   19298 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
   19299 	REQUIRE(DNS_ZONE_VALID(zone));
   19300 
   19301 	LOCK_ZONE(zone);
   19302 	zone->notifydelay = delay;
   19303 	UNLOCK_ZONE(zone);
   19304 }
   19305 
   19306 uint32_t
   19307 dns_zone_getnotifydelay(dns_zone_t *zone) {
   19308 	REQUIRE(DNS_ZONE_VALID(zone));
   19309 
   19310 	return (zone->notifydelay);
   19311 }
   19312 
   19313 isc_result_t
   19314 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   19315 		     bool deleteit) {
   19316 	isc_result_t result;
   19317 	REQUIRE(DNS_ZONE_VALID(zone));
   19318 
   19319 	dnssec_log(zone, ISC_LOG_NOTICE,
   19320 		   "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm,
   19321 		   keyid);
   19322 	LOCK_ZONE(zone);
   19323 	result = zone_signwithkey(zone, algorithm, keyid, deleteit);
   19324 	UNLOCK_ZONE(zone);
   19325 
   19326 	return (result);
   19327 }
   19328 
   19329 /*
   19330  * Called when a dynamic update for an NSEC3PARAM record is received.
   19331  *
   19332  * If set, transform the NSEC3 salt into human-readable form so that it can be
   19333  * logged.  Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it.
   19334  */
   19335 isc_result_t
   19336 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   19337 	isc_result_t result;
   19338 	char salt[255 * 2 + 1];
   19339 
   19340 	REQUIRE(DNS_ZONE_VALID(zone));
   19341 
   19342 	result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
   19343 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19344 	dnssec_log(zone, ISC_LOG_NOTICE,
   19345 		   "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
   19346 		   nsec3param->hash, nsec3param->iterations, salt);
   19347 	LOCK_ZONE(zone);
   19348 	result = zone_addnsec3chain(zone, nsec3param);
   19349 	UNLOCK_ZONE(zone);
   19350 
   19351 	return (result);
   19352 }
   19353 
   19354 void
   19355 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
   19356 	REQUIRE(DNS_ZONE_VALID(zone));
   19357 
   19358 	if (nodes == 0) {
   19359 		nodes = 1;
   19360 	}
   19361 	zone->nodes = nodes;
   19362 }
   19363 
   19364 void
   19365 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
   19366 	REQUIRE(DNS_ZONE_VALID(zone));
   19367 
   19368 	/*
   19369 	 * We treat signatures as a signed value so explicitly
   19370 	 * limit its range here.
   19371 	 */
   19372 	if (signatures > INT32_MAX) {
   19373 		signatures = INT32_MAX;
   19374 	} else if (signatures == 0) {
   19375 		signatures = 1;
   19376 	}
   19377 	zone->signatures = signatures;
   19378 }
   19379 
   19380 uint32_t
   19381 dns_zone_getsignatures(dns_zone_t *zone) {
   19382 	REQUIRE(DNS_ZONE_VALID(zone));
   19383 	return (zone->signatures);
   19384 }
   19385 
   19386 void
   19387 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
   19388 	REQUIRE(DNS_ZONE_VALID(zone));
   19389 	zone->privatetype = type;
   19390 }
   19391 
   19392 dns_rdatatype_t
   19393 dns_zone_getprivatetype(dns_zone_t *zone) {
   19394 	REQUIRE(DNS_ZONE_VALID(zone));
   19395 	return (zone->privatetype);
   19396 }
   19397 
   19398 static isc_result_t
   19399 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   19400 		 bool deleteit) {
   19401 	dns_signing_t *signing;
   19402 	dns_signing_t *current;
   19403 	isc_result_t result = ISC_R_SUCCESS;
   19404 	isc_time_t now;
   19405 	dns_db_t *db = NULL;
   19406 
   19407 	signing = isc_mem_get(zone->mctx, sizeof *signing);
   19408 
   19409 	signing->magic = 0;
   19410 	signing->db = NULL;
   19411 	signing->dbiterator = NULL;
   19412 	signing->algorithm = algorithm;
   19413 	signing->keyid = keyid;
   19414 	signing->deleteit = deleteit;
   19415 	signing->done = false;
   19416 
   19417 	TIME_NOW(&now);
   19418 
   19419 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   19420 	if (zone->db != NULL) {
   19421 		dns_db_attach(zone->db, &db);
   19422 	}
   19423 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   19424 
   19425 	if (db == NULL) {
   19426 		result = ISC_R_NOTFOUND;
   19427 		goto cleanup;
   19428 	}
   19429 
   19430 	dns_db_attach(db, &signing->db);
   19431 
   19432 	for (current = ISC_LIST_HEAD(zone->signing); current != NULL;
   19433 	     current = ISC_LIST_NEXT(current, link))
   19434 	{
   19435 		if (current->db == signing->db &&
   19436 		    current->algorithm == signing->algorithm &&
   19437 		    current->keyid == signing->keyid)
   19438 		{
   19439 			if (current->deleteit != signing->deleteit) {
   19440 				current->done = true;
   19441 			} else {
   19442 				goto cleanup;
   19443 			}
   19444 		}
   19445 	}
   19446 
   19447 	result = dns_db_createiterator(signing->db, 0, &signing->dbiterator);
   19448 
   19449 	if (result == ISC_R_SUCCESS) {
   19450 		result = dns_dbiterator_first(signing->dbiterator);
   19451 	}
   19452 	if (result == ISC_R_SUCCESS) {
   19453 		dns_dbiterator_pause(signing->dbiterator);
   19454 		ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
   19455 		signing = NULL;
   19456 		if (isc_time_isepoch(&zone->signingtime)) {
   19457 			zone->signingtime = now;
   19458 			if (zone->task != NULL) {
   19459 				zone_settimer(zone, &now);
   19460 			}
   19461 		}
   19462 	}
   19463 
   19464 cleanup:
   19465 	if (signing != NULL) {
   19466 		if (signing->db != NULL) {
   19467 			dns_db_detach(&signing->db);
   19468 		}
   19469 		if (signing->dbiterator != NULL) {
   19470 			dns_dbiterator_destroy(&signing->dbiterator);
   19471 		}
   19472 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   19473 	}
   19474 	if (db != NULL) {
   19475 		dns_db_detach(&db);
   19476 	}
   19477 	return (result);
   19478 }
   19479 
   19480 static void
   19481 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
   19482 	dns_dnsseckey_t *key;
   19483 	while (!ISC_LIST_EMPTY(*list)) {
   19484 		key = ISC_LIST_HEAD(*list);
   19485 		ISC_LIST_UNLINK(*list, key, link);
   19486 		dns_dnsseckey_destroy(mctx, &key);
   19487 	}
   19488 }
   19489 
   19490 /* Called once; *timep should be set to the current time. */
   19491 static isc_result_t
   19492 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
   19493 	isc_result_t result;
   19494 	isc_stdtime_t now, then = 0, event;
   19495 	int i;
   19496 
   19497 	now = *timep;
   19498 
   19499 	for (i = 0; i <= DST_MAX_TIMES; i++) {
   19500 		result = dst_key_gettime(key, i, &event);
   19501 		if (result == ISC_R_SUCCESS && event > now &&
   19502 		    (then == 0 || event < then)) {
   19503 			then = event;
   19504 		}
   19505 	}
   19506 
   19507 	if (then != 0) {
   19508 		*timep = then;
   19509 		return (ISC_R_SUCCESS);
   19510 	}
   19511 
   19512 	return (ISC_R_NOTFOUND);
   19513 }
   19514 
   19515 static isc_result_t
   19516 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   19517 	  const dns_rdata_t *rdata, bool *flag) {
   19518 	dns_rdataset_t rdataset;
   19519 	dns_dbnode_t *node = NULL;
   19520 	isc_result_t result;
   19521 
   19522 	dns_rdataset_init(&rdataset);
   19523 	if (rdata->type == dns_rdatatype_nsec3) {
   19524 		CHECK(dns_db_findnsec3node(db, name, false, &node));
   19525 	} else {
   19526 		CHECK(dns_db_findnode(db, name, false, &node));
   19527 	}
   19528 	result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
   19529 				     (isc_stdtime_t)0, &rdataset, NULL);
   19530 	if (result == ISC_R_NOTFOUND) {
   19531 		*flag = false;
   19532 		result = ISC_R_SUCCESS;
   19533 		goto failure;
   19534 	}
   19535 
   19536 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   19537 	     result = dns_rdataset_next(&rdataset))
   19538 	{
   19539 		dns_rdata_t myrdata = DNS_RDATA_INIT;
   19540 		dns_rdataset_current(&rdataset, &myrdata);
   19541 		if (!dns_rdata_compare(&myrdata, rdata)) {
   19542 			break;
   19543 		}
   19544 	}
   19545 	dns_rdataset_disassociate(&rdataset);
   19546 	if (result == ISC_R_SUCCESS) {
   19547 		*flag = true;
   19548 	} else if (result == ISC_R_NOMORE) {
   19549 		*flag = false;
   19550 		result = ISC_R_SUCCESS;
   19551 	}
   19552 
   19553 failure:
   19554 	if (node != NULL) {
   19555 		dns_db_detachnode(db, &node);
   19556 	}
   19557 	return (result);
   19558 }
   19559 
   19560 /*
   19561  * Add records to signal the state of signing or of key removal.
   19562  */
   19563 static isc_result_t
   19564 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
   19565 		    dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) {
   19566 	dns_difftuple_t *tuple, *newtuple = NULL;
   19567 	dns_rdata_dnskey_t dnskey;
   19568 	dns_rdata_t rdata = DNS_RDATA_INIT;
   19569 	bool flag;
   19570 	isc_region_t r;
   19571 	isc_result_t result = ISC_R_SUCCESS;
   19572 	uint16_t keyid;
   19573 	unsigned char buf[5];
   19574 	dns_name_t *name = dns_db_origin(db);
   19575 
   19576 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   19577 	     tuple = ISC_LIST_NEXT(tuple, link))
   19578 	{
   19579 		if (tuple->rdata.type != dns_rdatatype_dnskey) {
   19580 			continue;
   19581 		}
   19582 
   19583 		result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
   19584 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19585 		if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK |
   19586 				     DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE)
   19587 		{
   19588 			continue;
   19589 		}
   19590 
   19591 		dns_rdata_toregion(&tuple->rdata, &r);
   19592 
   19593 		keyid = dst_region_computeid(&r);
   19594 
   19595 		buf[0] = dnskey.algorithm;
   19596 		buf[1] = (keyid & 0xff00) >> 8;
   19597 		buf[2] = (keyid & 0xff);
   19598 		buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
   19599 		buf[4] = 0;
   19600 		rdata.data = buf;
   19601 		rdata.length = sizeof(buf);
   19602 		rdata.type = privatetype;
   19603 		rdata.rdclass = tuple->rdata.rdclass;
   19604 
   19605 		if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
   19606 			CHECK(rr_exists(db, ver, name, &rdata, &flag));
   19607 			if (flag) {
   19608 				continue;
   19609 			}
   19610 
   19611 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   19612 						   name, 0, &rdata, &newtuple));
   19613 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   19614 			INSIST(newtuple == NULL);
   19615 		}
   19616 
   19617 		/*
   19618 		 * Remove any record which says this operation has already
   19619 		 * completed.
   19620 		 */
   19621 		buf[4] = 1;
   19622 		CHECK(rr_exists(db, ver, name, &rdata, &flag));
   19623 		if (flag) {
   19624 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
   19625 						   name, 0, &rdata, &newtuple));
   19626 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   19627 			INSIST(newtuple == NULL);
   19628 		}
   19629 	}
   19630 failure:
   19631 	return (result);
   19632 }
   19633 
   19634 /*
   19635  * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at
   19636  * the apex, and if not tickle them and cause to sign so that newly activated
   19637  * keys are used.
   19638  */
   19639 static isc_result_t
   19640 tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db,
   19641 		  dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff,
   19642 		  dns__zonediff_t *zonediff, dst_key_t **keys,
   19643 		  unsigned int nkeys, isc_stdtime_t inception,
   19644 		  isc_stdtime_t keyexpire, bool check_ksk,
   19645 		  bool keyset_kskonly) {
   19646 	dns_difftuple_t *tuple;
   19647 	isc_result_t result;
   19648 
   19649 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   19650 	     tuple = ISC_LIST_NEXT(tuple, link))
   19651 	{
   19652 		if (tuple->rdata.type == rrtype &&
   19653 		    dns_name_equal(&tuple->name, &zone->origin)) {
   19654 			break;
   19655 		}
   19656 	}
   19657 
   19658 	if (tuple == NULL) {
   19659 		result = del_sigs(zone, db, ver, &zone->origin, rrtype,
   19660 				  zonediff, keys, nkeys, now, false);
   19661 		if (result != ISC_R_SUCCESS) {
   19662 			dnssec_log(zone, ISC_LOG_ERROR,
   19663 				   "sign_apex:del_sigs -> %s",
   19664 				   dns_result_totext(result));
   19665 			return (result);
   19666 		}
   19667 		result = add_sigs(db, ver, &zone->origin, zone, rrtype,
   19668 				  zonediff->diff, keys, nkeys, zone->mctx,
   19669 				  inception, keyexpire, check_ksk,
   19670 				  keyset_kskonly);
   19671 		if (result != ISC_R_SUCCESS) {
   19672 			dnssec_log(zone, ISC_LOG_ERROR,
   19673 				   "sign_apex:add_sigs -> %s",
   19674 				   dns_result_totext(result));
   19675 			return (result);
   19676 		}
   19677 	}
   19678 
   19679 	return (ISC_R_SUCCESS);
   19680 }
   19681 
   19682 static isc_result_t
   19683 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19684 	  isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) {
   19685 	isc_result_t result;
   19686 	isc_stdtime_t inception, soaexpire, keyexpire;
   19687 	bool check_ksk, keyset_kskonly;
   19688 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   19689 	unsigned int nkeys = 0, i;
   19690 
   19691 	result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
   19692 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   19693 	if (result != ISC_R_SUCCESS) {
   19694 		dnssec_log(zone, ISC_LOG_ERROR,
   19695 			   "sign_apex:dns__zone_findkeys -> %s",
   19696 			   dns_result_totext(result));
   19697 		return (result);
   19698 	}
   19699 
   19700 	inception = now - 3600; /* Allow for clock skew. */
   19701 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
   19702 
   19703 	keyexpire = dns_zone_getkeyvalidityinterval(zone);
   19704 	if (keyexpire == 0) {
   19705 		keyexpire = soaexpire - 1;
   19706 	} else {
   19707 		keyexpire += now;
   19708 	}
   19709 
   19710 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   19711 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   19712 
   19713 	/*
   19714 	 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY
   19715 	 * signature and if not cause them to sign so that newly activated
   19716 	 * keys are used.
   19717 	 */
   19718 	result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now,
   19719 				   diff, zonediff, zone_keys, nkeys, inception,
   19720 				   keyexpire, check_ksk, keyset_kskonly);
   19721 	if (result != ISC_R_SUCCESS) {
   19722 		goto failure;
   19723 	}
   19724 	result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff,
   19725 				   zonediff, zone_keys, nkeys, inception,
   19726 				   keyexpire, check_ksk, keyset_kskonly);
   19727 	if (result != ISC_R_SUCCESS) {
   19728 		goto failure;
   19729 	}
   19730 	result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now,
   19731 				   diff, zonediff, zone_keys, nkeys, inception,
   19732 				   keyexpire, check_ksk, keyset_kskonly);
   19733 	if (result != ISC_R_SUCCESS) {
   19734 		goto failure;
   19735 	}
   19736 
   19737 	result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
   19738 				      inception, soaexpire, keyexpire, now,
   19739 				      check_ksk, keyset_kskonly, zonediff);
   19740 
   19741 	if (result != ISC_R_SUCCESS) {
   19742 		dnssec_log(zone, ISC_LOG_ERROR,
   19743 			   "sign_apex:dns__zone_updatesigs -> %s",
   19744 			   dns_result_totext(result));
   19745 		goto failure;
   19746 	}
   19747 
   19748 failure:
   19749 	for (i = 0; i < nkeys; i++) {
   19750 		dst_key_free(&zone_keys[i]);
   19751 	}
   19752 	return (result);
   19753 }
   19754 
   19755 /*
   19756  * Prevent the zone entering a inconsistent state where
   19757  * NSEC only DNSKEYs are present with NSEC3 chains.
   19758  * See update.c:check_dnssec()
   19759  */
   19760 static bool
   19761 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19762 	    dns_diff_t *diff) {
   19763 	isc_result_t result;
   19764 	dns_difftuple_t *tuple;
   19765 	bool nseconly = false, nsec3 = false;
   19766 	dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
   19767 
   19768 	/* Scan the tuples for an NSEC-only DNSKEY */
   19769 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   19770 	     tuple = ISC_LIST_NEXT(tuple, link))
   19771 	{
   19772 		uint8_t alg;
   19773 		if (tuple->rdata.type != dns_rdatatype_dnskey ||
   19774 		    tuple->op != DNS_DIFFOP_ADD) {
   19775 			continue;
   19776 		}
   19777 
   19778 		alg = tuple->rdata.data[3];
   19779 		if (alg == DST_ALG_RSASHA1) {
   19780 			nseconly = true;
   19781 			break;
   19782 		}
   19783 	}
   19784 
   19785 	/* Check existing DB for NSEC-only DNSKEY */
   19786 	if (!nseconly) {
   19787 		result = dns_nsec_nseconly(db, ver, &nseconly);
   19788 		if (result == ISC_R_NOTFOUND) {
   19789 			result = ISC_R_SUCCESS;
   19790 		}
   19791 		CHECK(result);
   19792 	}
   19793 
   19794 	/* Check existing DB for NSEC3 */
   19795 	if (!nsec3) {
   19796 		CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3));
   19797 	}
   19798 
   19799 	/* Refuse to allow NSEC3 with NSEC-only keys */
   19800 	if (nseconly && nsec3) {
   19801 		dnssec_log(zone, ISC_LOG_ERROR,
   19802 			   "NSEC only DNSKEYs and NSEC3 chains not allowed");
   19803 		goto failure;
   19804 	}
   19805 
   19806 	return (true);
   19807 
   19808 failure:
   19809 	return (false);
   19810 }
   19811 
   19812 static isc_result_t
   19813 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19814 		 dns_diff_t *diff) {
   19815 	isc_result_t result;
   19816 	dns_dbnode_t *node = NULL;
   19817 	dns_rdataset_t rdataset;
   19818 
   19819 	dns_rdataset_init(&rdataset);
   19820 	CHECK(dns_db_getoriginnode(db, &node));
   19821 
   19822 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   19823 				     dns_rdatatype_none, 0, &rdataset, NULL);
   19824 	if (dns_rdataset_isassociated(&rdataset)) {
   19825 		dns_rdataset_disassociate(&rdataset);
   19826 	}
   19827 	if (result != ISC_R_NOTFOUND) {
   19828 		goto failure;
   19829 	}
   19830 
   19831 	result = dns_nsec3param_deletechains(db, ver, zone, true, diff);
   19832 
   19833 failure:
   19834 	if (node != NULL) {
   19835 		dns_db_detachnode(db, &node);
   19836 	}
   19837 	return (result);
   19838 }
   19839 
   19840 /*
   19841  * Given an RRSIG rdataset and an algorithm, determine whether there
   19842  * are any signatures using that algorithm.
   19843  */
   19844 static bool
   19845 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
   19846 	dns_rdata_t rdata = DNS_RDATA_INIT;
   19847 	dns_rdata_rrsig_t rrsig;
   19848 	isc_result_t result;
   19849 
   19850 	REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
   19851 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
   19852 		return (false);
   19853 	}
   19854 
   19855 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   19856 	     result = dns_rdataset_next(rdataset))
   19857 	{
   19858 		dns_rdataset_current(rdataset, &rdata);
   19859 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   19860 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19861 		dns_rdata_reset(&rdata);
   19862 		if (rrsig.algorithm == alg) {
   19863 			return (true);
   19864 		}
   19865 	}
   19866 
   19867 	return (false);
   19868 }
   19869 
   19870 static isc_result_t
   19871 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19872 	   dns_diff_t *diff) {
   19873 	dns_name_t *origin;
   19874 	bool build_nsec3;
   19875 	isc_result_t result;
   19876 
   19877 	origin = dns_db_origin(db);
   19878 	CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
   19879 				 &build_nsec3));
   19880 	if (build_nsec3) {
   19881 		CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
   19882 					   false, zone->privatetype, diff));
   19883 	}
   19884 	CHECK(updatesecure(db, ver, origin, zone->minimum, true, diff));
   19885 
   19886 failure:
   19887 	return (result);
   19888 }
   19889 
   19890 static void
   19891 dnssec_report(const char *format, ...) {
   19892 	va_list args;
   19893 	va_start(args, format);
   19894 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE,
   19895 		       ISC_LOG_INFO, format, args);
   19896 	va_end(args);
   19897 }
   19898 
   19899 static void
   19900 zone_rekey(dns_zone_t *zone) {
   19901 	isc_result_t result;
   19902 	dns_db_t *db = NULL;
   19903 	dns_dbnode_t *node = NULL;
   19904 	dns_dbversion_t *ver = NULL;
   19905 	dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset;
   19906 	dns_dnsseckeylist_t dnskeys, keys, rmkeys;
   19907 	dns_dnsseckey_t *key = NULL;
   19908 	dns_diff_t diff, _sig_diff;
   19909 	dns_kasp_t *kasp;
   19910 	dns__zonediff_t zonediff;
   19911 	bool commit = false, newactive = false;
   19912 	bool newalg = false;
   19913 	bool fullsign, use_kasp;
   19914 	dns_ttl_t ttl = 3600;
   19915 	const char *dir = NULL;
   19916 	isc_mem_t *mctx = NULL;
   19917 	isc_stdtime_t now, nexttime = 0;
   19918 	isc_time_t timenow;
   19919 	isc_interval_t ival;
   19920 	char timebuf[80];
   19921 
   19922 	REQUIRE(DNS_ZONE_VALID(zone));
   19923 
   19924 	ISC_LIST_INIT(dnskeys);
   19925 	ISC_LIST_INIT(keys);
   19926 	ISC_LIST_INIT(rmkeys);
   19927 	dns_rdataset_init(&soaset);
   19928 	dns_rdataset_init(&soasigs);
   19929 	dns_rdataset_init(&keyset);
   19930 	dns_rdataset_init(&keysigs);
   19931 	dns_rdataset_init(&cdsset);
   19932 	dns_rdataset_init(&cdnskeyset);
   19933 	dir = dns_zone_getkeydirectory(zone);
   19934 	mctx = zone->mctx;
   19935 	dns_diff_init(mctx, &diff);
   19936 	dns_diff_init(mctx, &_sig_diff);
   19937 	zonediff_init(&zonediff, &_sig_diff);
   19938 
   19939 	CHECK(dns_zone_getdb(zone, &db));
   19940 	CHECK(dns_db_newversion(db, &ver));
   19941 	CHECK(dns_db_getoriginnode(db, &node));
   19942 
   19943 	TIME_NOW(&timenow);
   19944 	now = isc_time_seconds(&timenow);
   19945 
   19946 	dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
   19947 
   19948 	/* Get the SOA record's TTL */
   19949 	CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
   19950 				  dns_rdatatype_none, 0, &soaset, &soasigs));
   19951 	ttl = soaset.ttl;
   19952 	dns_rdataset_disassociate(&soaset);
   19953 
   19954 	/* Get the DNSKEY rdataset */
   19955 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   19956 				     dns_rdatatype_none, 0, &keyset, &keysigs);
   19957 	if (result == ISC_R_SUCCESS) {
   19958 		ttl = keyset.ttl;
   19959 		CHECK(dns_dnssec_keylistfromrdataset(
   19960 			&zone->origin, dir, mctx, &keyset, &keysigs, &soasigs,
   19961 			false, false, &dnskeys));
   19962 	} else if (result != ISC_R_NOTFOUND) {
   19963 		goto failure;
   19964 	}
   19965 
   19966 	/* Get the CDS rdataset */
   19967 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds,
   19968 				     dns_rdatatype_none, 0, &cdsset, NULL);
   19969 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) {
   19970 		dns_rdataset_disassociate(&cdsset);
   19971 	}
   19972 
   19973 	/* Get the CDNSKEY rdataset */
   19974 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey,
   19975 				     dns_rdatatype_none, 0, &cdnskeyset, NULL);
   19976 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) {
   19977 		dns_rdataset_disassociate(&cdnskeyset);
   19978 	}
   19979 
   19980 	/*
   19981 	 * True when called from "rndc sign".  Indicates the zone should be
   19982 	 * fully signed now.
   19983 	 */
   19984 	fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
   19985 
   19986 	kasp = dns_zone_getkasp(zone);
   19987 	use_kasp = dns_zone_use_kasp(zone);
   19988 	if (kasp != NULL) {
   19989 		LOCK(&kasp->lock);
   19990 	}
   19991 
   19992 	result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
   19993 					     &keys);
   19994 	if (result != ISC_R_SUCCESS) {
   19995 		dnssec_log(zone, ISC_LOG_DEBUG(1),
   19996 			   "zone_rekey:dns_dnssec_findmatchingkeys failed: %s",
   19997 			   isc_result_totext(result));
   19998 	}
   19999 
   20000 	if (use_kasp && (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND)) {
   20001 		result = dns_keymgr_run(&zone->origin, zone->rdclass, dir, mctx,
   20002 					&keys, kasp, now, &nexttime);
   20003 		if (result != ISC_R_SUCCESS) {
   20004 			dnssec_log(zone, ISC_LOG_ERROR,
   20005 				   "zone_rekey:dns_dnssec_keymgr failed: %s",
   20006 				   isc_result_totext(result));
   20007 			goto failure;
   20008 		}
   20009 	}
   20010 
   20011 	if (kasp != NULL) {
   20012 		UNLOCK(&kasp->lock);
   20013 	}
   20014 
   20015 	if (result == ISC_R_SUCCESS) {
   20016 		/*
   20017 		 * Publish CDS/CDNSKEY DELETE records if the zone is
   20018 		 * transitioning from secure to insecure.
   20019 		 */
   20020 		bool cds_delete = dns_zone_secure_to_insecure(zone, false);
   20021 		isc_stdtime_t when;
   20022 
   20023 		/*
   20024 		 * Only update DNSKEY TTL if we have a policy.
   20025 		 */
   20026 		if (kasp != NULL && strcmp(dns_kasp_getname(kasp), "none") != 0)
   20027 		{
   20028 			ttl = dns_kasp_dnskeyttl(kasp);
   20029 		}
   20030 
   20031 		result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
   20032 					       &zone->origin, ttl, &diff, mctx,
   20033 					       dnssec_report);
   20034 		/*
   20035 		 * Keys couldn't be updated for some reason;
   20036 		 * try again later.
   20037 		 */
   20038 		if (result != ISC_R_SUCCESS) {
   20039 			dnssec_log(zone, ISC_LOG_ERROR,
   20040 				   "zone_rekey:couldn't update zone keys: %s",
   20041 				   isc_result_totext(result));
   20042 			goto failure;
   20043 		}
   20044 
   20045 		/*
   20046 		 * Update CDS / CDNSKEY records.
   20047 		 */
   20048 		result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset,
   20049 					       &cdnskeyset, now, ttl, &diff,
   20050 					       mctx);
   20051 		if (result != ISC_R_SUCCESS) {
   20052 			dnssec_log(zone, ISC_LOG_ERROR,
   20053 				   "zone_rekey:couldn't update CDS/CDNSKEY: %s",
   20054 				   isc_result_totext(result));
   20055 			goto failure;
   20056 		}
   20057 
   20058 		if (cds_delete) {
   20059 			/*
   20060 			 * Only publish CDS/CDNSKEY DELETE records if there is
   20061 			 * a KSK that can be used to verify the RRset. This
   20062 			 * means there must be a key with the KSK role that is
   20063 			 * published and is used for signing.
   20064 			 */
   20065 			cds_delete = false;
   20066 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20067 			     key = ISC_LIST_NEXT(key, link)) {
   20068 				dst_key_t *dstk = key->key;
   20069 				bool ksk = false;
   20070 				(void)dst_key_getbool(dstk, DST_BOOL_KSK, &ksk);
   20071 				if (!ksk) {
   20072 					continue;
   20073 				}
   20074 
   20075 				if (dst_key_haskasp(dstk) &&
   20076 				    dst_key_is_published(dstk, now, &when) &&
   20077 				    dst_key_is_signing(dstk, DST_BOOL_KSK, now,
   20078 						       &when))
   20079 				{
   20080 					cds_delete = true;
   20081 					break;
   20082 				}
   20083 			}
   20084 		}
   20085 		result = dns_dnssec_syncdelete(&cdsset, &cdnskeyset,
   20086 					       &zone->origin, zone->rdclass,
   20087 					       ttl, &diff, mctx, cds_delete);
   20088 		if (result != ISC_R_SUCCESS) {
   20089 			dnssec_log(zone, ISC_LOG_ERROR,
   20090 				   "zone_rekey:couldn't update CDS/CDNSKEY "
   20091 				   "DELETE records: %s",
   20092 				   isc_result_totext(result));
   20093 			goto failure;
   20094 		}
   20095 
   20096 		/*
   20097 		 * See if any pre-existing keys have newly become active;
   20098 		 * also, see if any new key is for a new algorithm, as in that
   20099 		 * event, we need to sign the zone fully.  (If there's a new
   20100 		 * key, but it's for an already-existing algorithm, then
   20101 		 * the zone signing can be handled incrementally.)
   20102 		 */
   20103 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20104 		     key = ISC_LIST_NEXT(key, link)) {
   20105 			if (!key->first_sign) {
   20106 				continue;
   20107 			}
   20108 
   20109 			newactive = true;
   20110 
   20111 			if (!dns_rdataset_isassociated(&keysigs)) {
   20112 				newalg = true;
   20113 				break;
   20114 			}
   20115 
   20116 			if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
   20117 				/*
   20118 				 * This isn't a new algorithm; clear
   20119 				 * first_sign so we won't sign the
   20120 				 * whole zone with this key later.
   20121 				 */
   20122 				key->first_sign = false;
   20123 			} else {
   20124 				newalg = true;
   20125 				break;
   20126 			}
   20127 		}
   20128 
   20129 		if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
   20130 		    dnskey_sane(zone, db, ver, &diff))
   20131 		{
   20132 			CHECK(dns_diff_apply(&diff, db, ver));
   20133 			CHECK(clean_nsec3param(zone, db, ver, &diff));
   20134 			CHECK(add_signing_records(db, zone->privatetype, ver,
   20135 						  &diff, (newalg || fullsign)));
   20136 			CHECK(update_soa_serial(zone, db, ver, &diff, mctx,
   20137 						zone->updatemethod));
   20138 			CHECK(add_chains(zone, db, ver, &diff));
   20139 			CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff));
   20140 			CHECK(zone_journal(zone, zonediff.diff, NULL,
   20141 					   "zone_rekey"));
   20142 			commit = true;
   20143 		}
   20144 	}
   20145 
   20146 	dns_db_closeversion(db, &ver, true);
   20147 
   20148 	LOCK_ZONE(zone);
   20149 
   20150 	if (commit) {
   20151 		dns_difftuple_t *tuple;
   20152 
   20153 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   20154 
   20155 		zone_needdump(zone, DNS_DUMP_DELAY);
   20156 
   20157 		zone_settimer(zone, &timenow);
   20158 
   20159 		/* Remove any signatures from removed keys.  */
   20160 		if (!ISC_LIST_EMPTY(rmkeys)) {
   20161 			for (key = ISC_LIST_HEAD(rmkeys); key != NULL;
   20162 			     key = ISC_LIST_NEXT(key, link)) {
   20163 				result = zone_signwithkey(
   20164 					zone, dst_key_alg(key->key),
   20165 					dst_key_id(key->key), true);
   20166 				if (result != ISC_R_SUCCESS) {
   20167 					dnssec_log(zone, ISC_LOG_ERROR,
   20168 						   "zone_signwithkey failed: "
   20169 						   "%s",
   20170 						   dns_result_totext(result));
   20171 				}
   20172 			}
   20173 		}
   20174 
   20175 		if (fullsign) {
   20176 			/*
   20177 			 * "rndc sign" was called, so we now sign the zone
   20178 			 * with all active keys, whether they're new or not.
   20179 			 */
   20180 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20181 			     key = ISC_LIST_NEXT(key, link)) {
   20182 				if (!key->force_sign && !key->hint_sign) {
   20183 					continue;
   20184 				}
   20185 
   20186 				result = zone_signwithkey(
   20187 					zone, dst_key_alg(key->key),
   20188 					dst_key_id(key->key), false);
   20189 				if (result != ISC_R_SUCCESS) {
   20190 					dnssec_log(zone, ISC_LOG_ERROR,
   20191 						   "zone_signwithkey failed: "
   20192 						   "%s",
   20193 						   dns_result_totext(result));
   20194 				}
   20195 			}
   20196 		} else if (newalg) {
   20197 			/*
   20198 			 * We haven't been told to sign fully, but a new
   20199 			 * algorithm was added to the DNSKEY.  We sign
   20200 			 * the full zone, but only with newly active
   20201 			 * keys.
   20202 			 */
   20203 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20204 			     key = ISC_LIST_NEXT(key, link)) {
   20205 				if (!key->first_sign) {
   20206 					continue;
   20207 				}
   20208 
   20209 				result = zone_signwithkey(
   20210 					zone, dst_key_alg(key->key),
   20211 					dst_key_id(key->key), false);
   20212 				if (result != ISC_R_SUCCESS) {
   20213 					dnssec_log(zone, ISC_LOG_ERROR,
   20214 						   "zone_signwithkey failed: "
   20215 						   "%s",
   20216 						   dns_result_totext(result));
   20217 				}
   20218 			}
   20219 		}
   20220 
   20221 		/*
   20222 		 * Clear fullsign flag, if it was set, so we don't do
   20223 		 * another full signing next time.
   20224 		 */
   20225 		DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN);
   20226 
   20227 		/*
   20228 		 * Cause the zone to add/delete NSEC3 chains for the
   20229 		 * deferred NSEC3PARAM changes.
   20230 		 */
   20231 		for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
   20232 		     tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link))
   20233 		{
   20234 			unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   20235 			dns_rdata_t rdata = DNS_RDATA_INIT;
   20236 			dns_rdata_nsec3param_t nsec3param;
   20237 
   20238 			if (tuple->rdata.type != zone->privatetype ||
   20239 			    tuple->op != DNS_DIFFOP_ADD) {
   20240 				continue;
   20241 			}
   20242 
   20243 			if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
   20244 							buf, sizeof(buf))) {
   20245 				continue;
   20246 			}
   20247 
   20248 			result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   20249 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20250 			if (nsec3param.flags == 0) {
   20251 				continue;
   20252 			}
   20253 
   20254 			result = zone_addnsec3chain(zone, &nsec3param);
   20255 			if (result != ISC_R_SUCCESS) {
   20256 				dnssec_log(zone, ISC_LOG_ERROR,
   20257 					   "zone_addnsec3chain failed: %s",
   20258 					   dns_result_totext(result));
   20259 			}
   20260 		}
   20261 
   20262 		/*
   20263 		 * Activate any NSEC3 chain updates that may have
   20264 		 * been scheduled before this rekey.
   20265 		 */
   20266 		if (fullsign || newalg) {
   20267 			resume_addnsec3chain(zone);
   20268 		}
   20269 
   20270 		/*
   20271 		 * Schedule the next resigning event
   20272 		 */
   20273 		set_resigntime(zone);
   20274 	}
   20275 
   20276 	isc_time_settoepoch(&zone->refreshkeytime);
   20277 
   20278 	/*
   20279 	 * If keymgr provided a next time, use the calculated next rekey time.
   20280 	 */
   20281 	if (use_kasp) {
   20282 		isc_time_t timenext;
   20283 		uint32_t nexttime_seconds;
   20284 
   20285 		/*
   20286 		 * Set the key refresh timer to the next scheduled key event
   20287 		 * or to 'dnssec-loadkeys-interval' seconds in the future
   20288 		 * if no next key event is scheduled (nexttime == 0).
   20289 		 */
   20290 		if (nexttime > 0) {
   20291 			nexttime_seconds = nexttime - now;
   20292 		} else {
   20293 			nexttime_seconds = zone->refreshkeyinterval;
   20294 		}
   20295 
   20296 		DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext);
   20297 		zone->refreshkeytime = timenext;
   20298 		zone_settimer(zone, &timenow);
   20299 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   20300 
   20301 		dnssec_log(zone, ISC_LOG_DEBUG(3),
   20302 			   "next key event in %u seconds", nexttime_seconds);
   20303 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   20304 	}
   20305 	/*
   20306 	 * If we're doing key maintenance, set the key refresh timer to
   20307 	 * the next scheduled key event or to 'dnssec-loadkeys-interval'
   20308 	 * seconds in the future, whichever is sooner.
   20309 	 */
   20310 	else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   20311 	{
   20312 		isc_time_t timethen;
   20313 		isc_stdtime_t then;
   20314 
   20315 		DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
   20316 				  &timethen);
   20317 		zone->refreshkeytime = timethen;
   20318 
   20319 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20320 		     key = ISC_LIST_NEXT(key, link)) {
   20321 			then = now;
   20322 			result = next_keyevent(key->key, &then);
   20323 			if (result != ISC_R_SUCCESS) {
   20324 				continue;
   20325 			}
   20326 
   20327 			DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   20328 			if (isc_time_compare(&timethen, &zone->refreshkeytime) <
   20329 			    0) {
   20330 				zone->refreshkeytime = timethen;
   20331 			}
   20332 		}
   20333 
   20334 		zone_settimer(zone, &timenow);
   20335 
   20336 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   20337 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   20338 	}
   20339 	UNLOCK_ZONE(zone);
   20340 
   20341 	if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   20342 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20343 		     key = ISC_LIST_NEXT(key, link)) {
   20344 			/* This debug log is used in the kasp system test */
   20345 			char algbuf[DNS_SECALG_FORMATSIZE];
   20346 			dns_secalg_format(dst_key_alg(key->key), algbuf,
   20347 					  sizeof(algbuf));
   20348 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   20349 				   "zone_rekey done: key %d/%s",
   20350 				   dst_key_id(key->key), algbuf);
   20351 		}
   20352 	}
   20353 
   20354 	result = ISC_R_SUCCESS;
   20355 
   20356 failure:
   20357 	LOCK_ZONE(zone);
   20358 	if (result != ISC_R_SUCCESS) {
   20359 		/*
   20360 		 * Something went wrong; try again in ten minutes or
   20361 		 * after a key refresh interval, whichever is shorter.
   20362 		 */
   20363 		isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600),
   20364 				 0);
   20365 		isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
   20366 	}
   20367 	UNLOCK_ZONE(zone);
   20368 
   20369 	dns_diff_clear(&diff);
   20370 	dns_diff_clear(&_sig_diff);
   20371 
   20372 	clear_keylist(&dnskeys, mctx);
   20373 	clear_keylist(&keys, mctx);
   20374 	clear_keylist(&rmkeys, mctx);
   20375 
   20376 	if (ver != NULL) {
   20377 		dns_db_closeversion(db, &ver, false);
   20378 	}
   20379 	if (dns_rdataset_isassociated(&cdsset)) {
   20380 		dns_rdataset_disassociate(&cdsset);
   20381 	}
   20382 	if (dns_rdataset_isassociated(&keyset)) {
   20383 		dns_rdataset_disassociate(&keyset);
   20384 	}
   20385 	if (dns_rdataset_isassociated(&keysigs)) {
   20386 		dns_rdataset_disassociate(&keysigs);
   20387 	}
   20388 	if (dns_rdataset_isassociated(&soasigs)) {
   20389 		dns_rdataset_disassociate(&soasigs);
   20390 	}
   20391 	if (dns_rdataset_isassociated(&cdnskeyset)) {
   20392 		dns_rdataset_disassociate(&cdnskeyset);
   20393 	}
   20394 	if (node != NULL) {
   20395 		dns_db_detachnode(db, &node);
   20396 	}
   20397 	if (db != NULL) {
   20398 		dns_db_detach(&db);
   20399 	}
   20400 
   20401 	INSIST(ver == NULL);
   20402 }
   20403 
   20404 void
   20405 dns_zone_rekey(dns_zone_t *zone, bool fullsign) {
   20406 	isc_time_t now;
   20407 
   20408 	if (zone->type == dns_zone_master && zone->task != NULL) {
   20409 		LOCK_ZONE(zone);
   20410 
   20411 		if (fullsign) {
   20412 			DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN);
   20413 		}
   20414 
   20415 		TIME_NOW(&now);
   20416 		zone->refreshkeytime = now;
   20417 		zone_settimer(zone, &now);
   20418 
   20419 		UNLOCK_ZONE(zone);
   20420 	}
   20421 }
   20422 
   20423 isc_result_t
   20424 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   20425 		 unsigned int *errors) {
   20426 	isc_result_t result;
   20427 	dns_dbnode_t *node = NULL;
   20428 
   20429 	REQUIRE(DNS_ZONE_VALID(zone));
   20430 	REQUIRE(errors != NULL);
   20431 
   20432 	result = dns_db_getoriginnode(db, &node);
   20433 	if (result != ISC_R_SUCCESS) {
   20434 		return (result);
   20435 	}
   20436 	result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false);
   20437 	dns_db_detachnode(db, &node);
   20438 	return (result);
   20439 }
   20440 
   20441 isc_result_t
   20442 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
   20443 	isc_result_t result;
   20444 	dns_dbnode_t *node = NULL;
   20445 	dns_rdataset_t dnskey, cds, cdnskey;
   20446 	unsigned char buffer[DNS_DS_BUFFERSIZE];
   20447 	unsigned char algorithms[256];
   20448 	unsigned int i;
   20449 	bool empty = false;
   20450 
   20451 	enum { notexpected = 0, expected = 1, found = 2 };
   20452 
   20453 	REQUIRE(DNS_ZONE_VALID(zone));
   20454 
   20455 	result = dns_db_getoriginnode(db, &node);
   20456 	if (result != ISC_R_SUCCESS) {
   20457 		return (result);
   20458 	}
   20459 
   20460 	dns_rdataset_init(&cds);
   20461 	dns_rdataset_init(&dnskey);
   20462 	dns_rdataset_init(&cdnskey);
   20463 
   20464 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
   20465 				     dns_rdatatype_none, 0, &cds, NULL);
   20466 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   20467 		goto failure;
   20468 	}
   20469 
   20470 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
   20471 				     dns_rdatatype_none, 0, &cdnskey, NULL);
   20472 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   20473 		goto failure;
   20474 	}
   20475 
   20476 	if (!dns_rdataset_isassociated(&cds) &&
   20477 	    !dns_rdataset_isassociated(&cdnskey)) {
   20478 		result = ISC_R_SUCCESS;
   20479 		goto failure;
   20480 	}
   20481 
   20482 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   20483 				     dns_rdatatype_none, 0, &dnskey, NULL);
   20484 	if (result == ISC_R_NOTFOUND) {
   20485 		empty = true;
   20486 	} else if (result != ISC_R_SUCCESS) {
   20487 		goto failure;
   20488 	}
   20489 
   20490 	/*
   20491 	 * For each DNSSEC algorithm in the CDS RRset there must be
   20492 	 * a matching DNSKEY record with the exception of a CDS deletion
   20493 	 * record which must be by itself.
   20494 	 */
   20495 	if (dns_rdataset_isassociated(&cds)) {
   20496 		bool delete = false;
   20497 		memset(algorithms, notexpected, sizeof(algorithms));
   20498 		for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS;
   20499 		     result = dns_rdataset_next(&cds))
   20500 		{
   20501 			dns_rdata_t crdata = DNS_RDATA_INIT;
   20502 			dns_rdata_cds_t structcds;
   20503 
   20504 			dns_rdataset_current(&cds, &crdata);
   20505 			/*
   20506 			 * CDS deletion record has this form "0 0 0 00" which
   20507 			 * is 5 zero octets.
   20508 			 */
   20509 			if (crdata.length == 5U &&
   20510 			    memcmp(crdata.data,
   20511 				   (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0)
   20512 			{
   20513 				delete = true;
   20514 				continue;
   20515 			}
   20516 
   20517 			if (empty) {
   20518 				result = DNS_R_BADCDS;
   20519 				goto failure;
   20520 			}
   20521 
   20522 			CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
   20523 			if (algorithms[structcds.algorithm] == 0) {
   20524 				algorithms[structcds.algorithm] = expected;
   20525 			}
   20526 			for (result = dns_rdataset_first(&dnskey);
   20527 			     result == ISC_R_SUCCESS;
   20528 			     result = dns_rdataset_next(&dnskey))
   20529 			{
   20530 				dns_rdata_t rdata = DNS_RDATA_INIT;
   20531 				dns_rdata_t dsrdata = DNS_RDATA_INIT;
   20532 
   20533 				dns_rdataset_current(&dnskey, &rdata);
   20534 				CHECK(dns_ds_buildrdata(&zone->origin, &rdata,
   20535 							structcds.digest_type,
   20536 							buffer, &dsrdata));
   20537 				if (crdata.length == dsrdata.length &&
   20538 				    memcmp(crdata.data, dsrdata.data,
   20539 					   dsrdata.length) == 0)
   20540 				{
   20541 					algorithms[structcds.algorithm] = found;
   20542 				}
   20543 			}
   20544 			if (result != ISC_R_NOMORE) {
   20545 				goto failure;
   20546 			}
   20547 		}
   20548 		for (i = 0; i < sizeof(algorithms); i++) {
   20549 			if (delete) {
   20550 				if (algorithms[i] != notexpected) {
   20551 					result = DNS_R_BADCDS;
   20552 					goto failure;
   20553 				}
   20554 			} else if (algorithms[i] == expected) {
   20555 				result = DNS_R_BADCDS;
   20556 				goto failure;
   20557 			}
   20558 		}
   20559 	}
   20560 
   20561 	/*
   20562 	 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
   20563 	 * a matching DNSKEY record with the exception of a CDNSKEY deletion
   20564 	 * record which must be by itself.
   20565 	 */
   20566 	if (dns_rdataset_isassociated(&cdnskey)) {
   20567 		bool delete = false;
   20568 		memset(algorithms, notexpected, sizeof(algorithms));
   20569 		for (result = dns_rdataset_first(&cdnskey);
   20570 		     result == ISC_R_SUCCESS;
   20571 		     result = dns_rdataset_next(&cdnskey))
   20572 		{
   20573 			dns_rdata_t crdata = DNS_RDATA_INIT;
   20574 			dns_rdata_cdnskey_t structcdnskey;
   20575 
   20576 			dns_rdataset_current(&cdnskey, &crdata);
   20577 			/*
   20578 			 * CDNSKEY deletion record has this form
   20579 			 * "0 3 0 AA==" which is 2 zero octets, a 3,
   20580 			 * and 2 zero octets.
   20581 			 */
   20582 			if (crdata.length == 5U &&
   20583 			    memcmp(crdata.data,
   20584 				   (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0)
   20585 			{
   20586 				delete = true;
   20587 				continue;
   20588 			}
   20589 
   20590 			if (empty) {
   20591 				result = DNS_R_BADCDNSKEY;
   20592 				goto failure;
   20593 			}
   20594 
   20595 			CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
   20596 						 NULL));
   20597 			if (algorithms[structcdnskey.algorithm] == 0) {
   20598 				algorithms[structcdnskey.algorithm] = expected;
   20599 			}
   20600 			for (result = dns_rdataset_first(&dnskey);
   20601 			     result == ISC_R_SUCCESS;
   20602 			     result = dns_rdataset_next(&dnskey))
   20603 			{
   20604 				dns_rdata_t rdata = DNS_RDATA_INIT;
   20605 
   20606 				dns_rdataset_current(&dnskey, &rdata);
   20607 				if (crdata.length == rdata.length &&
   20608 				    memcmp(crdata.data, rdata.data,
   20609 					   rdata.length) == 0)
   20610 				{
   20611 					algorithms[structcdnskey.algorithm] =
   20612 						found;
   20613 				}
   20614 			}
   20615 			if (result != ISC_R_NOMORE) {
   20616 				goto failure;
   20617 			}
   20618 		}
   20619 		for (i = 0; i < sizeof(algorithms); i++) {
   20620 			if (delete) {
   20621 				if (algorithms[i] != notexpected) {
   20622 					result = DNS_R_BADCDNSKEY;
   20623 					goto failure;
   20624 				}
   20625 			} else if (algorithms[i] == expected) {
   20626 				result = DNS_R_BADCDNSKEY;
   20627 				goto failure;
   20628 			}
   20629 		}
   20630 	}
   20631 	result = ISC_R_SUCCESS;
   20632 
   20633 failure:
   20634 	if (dns_rdataset_isassociated(&cds)) {
   20635 		dns_rdataset_disassociate(&cds);
   20636 	}
   20637 	if (dns_rdataset_isassociated(&dnskey)) {
   20638 		dns_rdataset_disassociate(&dnskey);
   20639 	}
   20640 	if (dns_rdataset_isassociated(&cdnskey)) {
   20641 		dns_rdataset_disassociate(&cdnskey);
   20642 	}
   20643 	dns_db_detachnode(db, &node);
   20644 	return (result);
   20645 }
   20646 
   20647 void
   20648 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
   20649 	REQUIRE(DNS_ZONE_VALID(zone));
   20650 
   20651 	LOCK_ZONE(zone);
   20652 	zone->automatic = automatic;
   20653 	UNLOCK_ZONE(zone);
   20654 }
   20655 
   20656 bool
   20657 dns_zone_getautomatic(dns_zone_t *zone) {
   20658 	REQUIRE(DNS_ZONE_VALID(zone));
   20659 	return (zone->automatic);
   20660 }
   20661 
   20662 void
   20663 dns_zone_setadded(dns_zone_t *zone, bool added) {
   20664 	REQUIRE(DNS_ZONE_VALID(zone));
   20665 
   20666 	LOCK_ZONE(zone);
   20667 	zone->added = added;
   20668 	UNLOCK_ZONE(zone);
   20669 }
   20670 
   20671 bool
   20672 dns_zone_getadded(dns_zone_t *zone) {
   20673 	REQUIRE(DNS_ZONE_VALID(zone));
   20674 	return (zone->added);
   20675 }
   20676 
   20677 isc_result_t
   20678 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) {
   20679 	isc_time_t loadtime;
   20680 	isc_result_t result;
   20681 	dns_zone_t *secure = NULL;
   20682 
   20683 	TIME_NOW(&loadtime);
   20684 
   20685 	/*
   20686 	 * Lock hierarchy: zmgr, zone, raw.
   20687 	 */
   20688 again:
   20689 	LOCK_ZONE(zone);
   20690 	INSIST(zone != zone->raw);
   20691 	if (inline_secure(zone)) {
   20692 		LOCK_ZONE(zone->raw);
   20693 	} else if (inline_raw(zone)) {
   20694 		secure = zone->secure;
   20695 		TRYLOCK_ZONE(result, secure);
   20696 		if (result != ISC_R_SUCCESS) {
   20697 			UNLOCK_ZONE(zone);
   20698 			secure = NULL;
   20699 			isc_thread_yield();
   20700 			goto again;
   20701 		}
   20702 	}
   20703 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   20704 	if (inline_secure(zone)) {
   20705 		UNLOCK_ZONE(zone->raw);
   20706 	} else if (secure != NULL) {
   20707 		UNLOCK_ZONE(secure);
   20708 	}
   20709 	UNLOCK_ZONE(zone);
   20710 	return (result);
   20711 }
   20712 
   20713 isc_result_t
   20714 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
   20715 	REQUIRE(DNS_ZONE_VALID(zone));
   20716 	if (interval == 0) {
   20717 		return (ISC_R_RANGE);
   20718 	}
   20719 	/* Maximum value: 24 hours (3600 minutes) */
   20720 	if (interval > (24 * 60)) {
   20721 		interval = (24 * 60);
   20722 	}
   20723 	/* Multiply by 60 for seconds */
   20724 	zone->refreshkeyinterval = interval * 60;
   20725 	return (ISC_R_SUCCESS);
   20726 }
   20727 
   20728 void
   20729 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
   20730 	REQUIRE(DNS_ZONE_VALID(zone));
   20731 	zone->requestixfr = flag;
   20732 }
   20733 
   20734 bool
   20735 dns_zone_getrequestixfr(dns_zone_t *zone) {
   20736 	REQUIRE(DNS_ZONE_VALID(zone));
   20737 	return (zone->requestixfr);
   20738 }
   20739 
   20740 void
   20741 dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) {
   20742 	REQUIRE(DNS_ZONE_VALID(zone));
   20743 	zone->ixfr_ratio = ratio;
   20744 }
   20745 
   20746 uint32_t
   20747 dns_zone_getixfrratio(dns_zone_t *zone) {
   20748 	REQUIRE(DNS_ZONE_VALID(zone));
   20749 	return (zone->ixfr_ratio);
   20750 }
   20751 
   20752 void
   20753 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
   20754 	REQUIRE(DNS_ZONE_VALID(zone));
   20755 	zone->requestexpire = flag;
   20756 }
   20757 
   20758 bool
   20759 dns_zone_getrequestexpire(dns_zone_t *zone) {
   20760 	REQUIRE(DNS_ZONE_VALID(zone));
   20761 	return (zone->requestexpire);
   20762 }
   20763 
   20764 void
   20765 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
   20766 	REQUIRE(DNS_ZONE_VALID(zone));
   20767 	zone->updatemethod = method;
   20768 }
   20769 
   20770 dns_updatemethod_t
   20771 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
   20772 	REQUIRE(DNS_ZONE_VALID(zone));
   20773 	return (zone->updatemethod);
   20774 }
   20775 
   20776 /*
   20777  * Lock hierarchy: zmgr, zone, raw.
   20778  */
   20779 isc_result_t
   20780 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
   20781 	isc_result_t result;
   20782 	dns_zonemgr_t *zmgr;
   20783 
   20784 	REQUIRE(DNS_ZONE_VALID(zone));
   20785 	REQUIRE(zone->zmgr != NULL);
   20786 	REQUIRE(zone->task != NULL);
   20787 	REQUIRE(zone->loadtask != NULL);
   20788 	REQUIRE(zone->raw == NULL);
   20789 
   20790 	REQUIRE(DNS_ZONE_VALID(raw));
   20791 	REQUIRE(raw->zmgr == NULL);
   20792 	REQUIRE(raw->task == NULL);
   20793 	REQUIRE(raw->loadtask == NULL);
   20794 	REQUIRE(raw->secure == NULL);
   20795 
   20796 	REQUIRE(zone != raw);
   20797 
   20798 	/*
   20799 	 * Lock hierarchy: zmgr, zone, raw.
   20800 	 */
   20801 	zmgr = zone->zmgr;
   20802 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   20803 	LOCK_ZONE(zone);
   20804 	LOCK_ZONE(raw);
   20805 
   20806 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   20807 				  NULL, zone->task, zone_timer, raw,
   20808 				  &raw->timer);
   20809 	if (result != ISC_R_SUCCESS) {
   20810 		goto unlock;
   20811 	}
   20812 
   20813 	/*
   20814 	 * The timer "holds" a iref.
   20815 	 */
   20816 	isc_refcount_increment0(&raw->irefs);
   20817 
   20818 	/* dns_zone_attach(raw, &zone->raw); */
   20819 	isc_refcount_increment(&raw->erefs);
   20820 	zone->raw = raw;
   20821 
   20822 	/* dns_zone_iattach(zone,  &raw->secure); */
   20823 	zone_iattach(zone, &raw->secure);
   20824 
   20825 	isc_task_attach(zone->task, &raw->task);
   20826 	isc_task_attach(zone->loadtask, &raw->loadtask);
   20827 
   20828 	ISC_LIST_APPEND(zmgr->zones, raw, link);
   20829 	raw->zmgr = zmgr;
   20830 	isc_refcount_increment(&zmgr->refs);
   20831 
   20832 unlock:
   20833 	UNLOCK_ZONE(raw);
   20834 	UNLOCK_ZONE(zone);
   20835 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   20836 	return (result);
   20837 }
   20838 
   20839 void
   20840 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
   20841 	REQUIRE(DNS_ZONE_VALID(zone));
   20842 	REQUIRE(raw != NULL && *raw == NULL);
   20843 
   20844 	LOCK(&zone->lock);
   20845 	INSIST(zone != zone->raw);
   20846 	if (zone->raw != NULL) {
   20847 		dns_zone_attach(zone->raw, raw);
   20848 	}
   20849 	UNLOCK(&zone->lock);
   20850 }
   20851 
   20852 struct keydone {
   20853 	isc_event_t event;
   20854 	bool all;
   20855 	unsigned char data[5];
   20856 };
   20857 
   20858 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL)
   20859 
   20860 static void
   20861 keydone(isc_task_t *task, isc_event_t *event) {
   20862 	const char *me = "keydone";
   20863 	bool commit = false;
   20864 	isc_result_t result;
   20865 	dns_rdata_t rdata = DNS_RDATA_INIT;
   20866 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   20867 	dns_zone_t *zone;
   20868 	dns_db_t *db = NULL;
   20869 	dns_dbnode_t *node = NULL;
   20870 	dns_rdataset_t rdataset;
   20871 	dns_diff_t diff;
   20872 	struct keydone *kd = (struct keydone *)event;
   20873 	dns_update_log_t log = { update_log_cb, NULL };
   20874 	bool clear_pending = false;
   20875 
   20876 	UNUSED(task);
   20877 
   20878 	zone = event->ev_arg;
   20879 	INSIST(DNS_ZONE_VALID(zone));
   20880 
   20881 	ENTER;
   20882 
   20883 	dns_rdataset_init(&rdataset);
   20884 	dns_diff_init(zone->mctx, &diff);
   20885 
   20886 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   20887 	if (zone->db != NULL) {
   20888 		dns_db_attach(zone->db, &db);
   20889 	}
   20890 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   20891 	if (db == NULL) {
   20892 		goto failure;
   20893 	}
   20894 
   20895 	dns_db_currentversion(db, &oldver);
   20896 	result = dns_db_newversion(db, &newver);
   20897 	if (result != ISC_R_SUCCESS) {
   20898 		dnssec_log(zone, ISC_LOG_ERROR,
   20899 			   "keydone:dns_db_newversion -> %s",
   20900 			   dns_result_totext(result));
   20901 		goto failure;
   20902 	}
   20903 
   20904 	result = dns_db_getoriginnode(db, &node);
   20905 	if (result != ISC_R_SUCCESS) {
   20906 		goto failure;
   20907 	}
   20908 
   20909 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   20910 				     dns_rdatatype_none, 0, &rdataset, NULL);
   20911 	if (result == ISC_R_NOTFOUND) {
   20912 		INSIST(!dns_rdataset_isassociated(&rdataset));
   20913 		goto failure;
   20914 	}
   20915 	if (result != ISC_R_SUCCESS) {
   20916 		INSIST(!dns_rdataset_isassociated(&rdataset));
   20917 		goto failure;
   20918 	}
   20919 
   20920 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   20921 	     result = dns_rdataset_next(&rdataset))
   20922 	{
   20923 		bool found = false;
   20924 
   20925 		dns_rdataset_current(&rdataset, &rdata);
   20926 
   20927 		if (kd->all) {
   20928 			if (rdata.length == 5 && rdata.data[0] != 0 &&
   20929 			    rdata.data[3] == 0 && rdata.data[4] == 1)
   20930 			{
   20931 				found = true;
   20932 			} else if (rdata.data[0] == 0 &&
   20933 				   (rdata.data[2] & PENDINGFLAGS) != 0) {
   20934 				found = true;
   20935 				clear_pending = true;
   20936 			}
   20937 		} else if (rdata.length == 5 &&
   20938 			   memcmp(rdata.data, kd->data, 5) == 0) {
   20939 			found = true;
   20940 		}
   20941 
   20942 		if (found) {
   20943 			CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
   20944 					    &zone->origin, rdataset.ttl,
   20945 					    &rdata));
   20946 		}
   20947 		dns_rdata_reset(&rdata);
   20948 	}
   20949 
   20950 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   20951 		/* Write changes to journal file. */
   20952 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   20953 					zone->updatemethod));
   20954 
   20955 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   20956 					       &diff,
   20957 					       zone->sigvalidityinterval);
   20958 		if (!clear_pending) {
   20959 			CHECK(result);
   20960 		}
   20961 
   20962 		CHECK(zone_journal(zone, &diff, NULL, "keydone"));
   20963 		commit = true;
   20964 
   20965 		LOCK_ZONE(zone);
   20966 		DNS_ZONE_SETFLAG(zone,
   20967 				 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   20968 		zone_needdump(zone, 30);
   20969 		UNLOCK_ZONE(zone);
   20970 	}
   20971 
   20972 failure:
   20973 	if (dns_rdataset_isassociated(&rdataset)) {
   20974 		dns_rdataset_disassociate(&rdataset);
   20975 	}
   20976 	if (db != NULL) {
   20977 		if (node != NULL) {
   20978 			dns_db_detachnode(db, &node);
   20979 		}
   20980 		if (oldver != NULL) {
   20981 			dns_db_closeversion(db, &oldver, false);
   20982 		}
   20983 		if (newver != NULL) {
   20984 			dns_db_closeversion(db, &newver, commit);
   20985 		}
   20986 		dns_db_detach(&db);
   20987 	}
   20988 	dns_diff_clear(&diff);
   20989 	isc_event_free(&event);
   20990 	dns_zone_idetach(&zone);
   20991 
   20992 	INSIST(oldver == NULL);
   20993 	INSIST(newver == NULL);
   20994 }
   20995 
   20996 isc_result_t
   20997 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
   20998 	isc_result_t result = ISC_R_SUCCESS;
   20999 	isc_event_t *e;
   21000 	isc_buffer_t b;
   21001 	dns_zone_t *dummy = NULL;
   21002 	struct keydone *kd;
   21003 
   21004 	REQUIRE(DNS_ZONE_VALID(zone));
   21005 
   21006 	LOCK_ZONE(zone);
   21007 
   21008 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
   21009 			       zone, sizeof(struct keydone));
   21010 
   21011 	kd = (struct keydone *)e;
   21012 	if (strcasecmp(keystr, "all") == 0) {
   21013 		kd->all = true;
   21014 	} else {
   21015 		isc_textregion_t r;
   21016 		const char *algstr;
   21017 		dns_keytag_t keyid;
   21018 		dns_secalg_t alg;
   21019 		size_t n;
   21020 
   21021 		kd->all = false;
   21022 
   21023 		n = sscanf(keystr, "%hu/", &keyid);
   21024 		if (n == 0U) {
   21025 			CHECK(ISC_R_FAILURE);
   21026 		}
   21027 
   21028 		algstr = strchr(keystr, '/');
   21029 		if (algstr != NULL) {
   21030 			algstr++;
   21031 		} else {
   21032 			CHECK(ISC_R_FAILURE);
   21033 		}
   21034 
   21035 		n = sscanf(algstr, "%hhu", &alg);
   21036 		if (n == 0U) {
   21037 			DE_CONST(algstr, r.base);
   21038 			r.length = strlen(algstr);
   21039 			CHECK(dns_secalg_fromtext(&alg, &r));
   21040 		}
   21041 
   21042 		/* construct a private-type rdata */
   21043 		isc_buffer_init(&b, kd->data, sizeof(kd->data));
   21044 		isc_buffer_putuint8(&b, alg);
   21045 		isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
   21046 		isc_buffer_putuint8(&b, (keyid & 0xff));
   21047 		isc_buffer_putuint8(&b, 0);
   21048 		isc_buffer_putuint8(&b, 1);
   21049 	}
   21050 
   21051 	zone_iattach(zone, &dummy);
   21052 	isc_task_send(zone->task, &e);
   21053 
   21054 failure:
   21055 	if (e != NULL) {
   21056 		isc_event_free(&e);
   21057 	}
   21058 	UNLOCK_ZONE(zone);
   21059 	return (result);
   21060 }
   21061 
   21062 /*
   21063  * Called from the zone task's queue after the relevant event is posted by
   21064  * dns_zone_setnsec3param().
   21065  */
   21066 static void
   21067 setnsec3param(isc_task_t *task, isc_event_t *event) {
   21068 	const char *me = "setnsec3param";
   21069 	dns_zone_t *zone = event->ev_arg;
   21070 
   21071 	INSIST(DNS_ZONE_VALID(zone));
   21072 
   21073 	UNUSED(task);
   21074 
   21075 	ENTER;
   21076 
   21077 	/*
   21078 	 * If receive_secure_serial is still processing or we have a
   21079 	 * queued event append rss_post queue.
   21080 	 */
   21081 	if (zone->rss_newver != NULL || ISC_LIST_HEAD(zone->rss_post) != NULL) {
   21082 		/*
   21083 		 * Wait for receive_secure_serial() to finish processing.
   21084 		 */
   21085 		ISC_LIST_APPEND(zone->rss_post, event, ev_link);
   21086 	} else {
   21087 		rss_post(zone, event);
   21088 	}
   21089 	dns_zone_idetach(&zone);
   21090 }
   21091 
   21092 /*
   21093  * Check whether NSEC3 chain addition or removal specified by the private-type
   21094  * record passed with the event was already queued (or even fully performed).
   21095  * If not, modify the relevant private-type records at the zone apex and call
   21096  * resume_addnsec3chain().
   21097  */
   21098 static void
   21099 rss_post(dns_zone_t *zone, isc_event_t *event) {
   21100 	const char *me = "rss_post";
   21101 	bool commit = false;
   21102 	isc_result_t result;
   21103 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   21104 	dns_db_t *db = NULL;
   21105 	dns_dbnode_t *node = NULL;
   21106 	dns_rdataset_t prdataset, nrdataset;
   21107 	dns_diff_t diff;
   21108 	struct np3event *npe = (struct np3event *)event;
   21109 	nsec3param_t *np;
   21110 	dns_update_log_t log = { update_log_cb, NULL };
   21111 	dns_rdata_t rdata;
   21112 	bool nseconly;
   21113 	bool exists = false;
   21114 
   21115 	ENTER;
   21116 
   21117 	np = &npe->params;
   21118 
   21119 	dns_rdataset_init(&prdataset);
   21120 	dns_rdataset_init(&nrdataset);
   21121 	dns_diff_init(zone->mctx, &diff);
   21122 
   21123 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   21124 	if (zone->db != NULL) {
   21125 		dns_db_attach(zone->db, &db);
   21126 	}
   21127 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   21128 	if (db == NULL) {
   21129 		goto failure;
   21130 	}
   21131 
   21132 	dns_db_currentversion(db, &oldver);
   21133 	result = dns_db_newversion(db, &newver);
   21134 	if (result != ISC_R_SUCCESS) {
   21135 		dnssec_log(zone, ISC_LOG_ERROR,
   21136 			   "setnsec3param:dns_db_newversion -> %s",
   21137 			   dns_result_totext(result));
   21138 		goto failure;
   21139 	}
   21140 
   21141 	CHECK(dns_db_getoriginnode(db, &node));
   21142 
   21143 	/*
   21144 	 * Does a private-type record already exist for this chain?
   21145 	 */
   21146 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   21147 				     dns_rdatatype_none, 0, &prdataset, NULL);
   21148 	if (result == ISC_R_SUCCESS) {
   21149 		for (result = dns_rdataset_first(&prdataset);
   21150 		     result == ISC_R_SUCCESS;
   21151 		     result = dns_rdataset_next(&prdataset))
   21152 		{
   21153 			dns_rdata_init(&rdata);
   21154 			dns_rdataset_current(&prdataset, &rdata);
   21155 
   21156 			if (np->length == rdata.length &&
   21157 			    memcmp(rdata.data, np->data, np->length) == 0) {
   21158 				exists = true;
   21159 				break;
   21160 			}
   21161 		}
   21162 	} else if (result != ISC_R_NOTFOUND) {
   21163 		INSIST(!dns_rdataset_isassociated(&prdataset));
   21164 		goto failure;
   21165 	}
   21166 
   21167 	/*
   21168 	 * Does the chain already exist?
   21169 	 */
   21170 	result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param,
   21171 				     dns_rdatatype_none, 0, &nrdataset, NULL);
   21172 	if (result == ISC_R_SUCCESS) {
   21173 		for (result = dns_rdataset_first(&nrdataset);
   21174 		     result == ISC_R_SUCCESS;
   21175 		     result = dns_rdataset_next(&nrdataset))
   21176 		{
   21177 			dns_rdata_init(&rdata);
   21178 			dns_rdataset_current(&nrdataset, &rdata);
   21179 
   21180 			if (np->length == (rdata.length + 1) &&
   21181 			    memcmp(rdata.data, np->data + 1, np->length - 1) ==
   21182 				    0)
   21183 			{
   21184 				exists = true;
   21185 				break;
   21186 			}
   21187 		}
   21188 	} else if (result != ISC_R_NOTFOUND) {
   21189 		INSIST(!dns_rdataset_isassociated(&nrdataset));
   21190 		goto failure;
   21191 	}
   21192 
   21193 	/*
   21194 	 * We need to remove any existing NSEC3 chains if the supplied NSEC3
   21195 	 * parameters are supposed to replace the current ones or if we are
   21196 	 * switching to NSEC.
   21197 	 */
   21198 	if (!exists && np->replace && (np->length != 0 || np->nsec)) {
   21199 		CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec,
   21200 						  &diff));
   21201 	}
   21202 
   21203 	if (!exists && np->length != 0) {
   21204 		/*
   21205 		 * We're creating an NSEC3 chain.  Add the private-type record
   21206 		 * passed in the event handler's argument to the zone apex.
   21207 		 *
   21208 		 * If the zone is not currently capable of supporting an NSEC3
   21209 		 * chain (due to the DNSKEY RRset at the zone apex not existing
   21210 		 * or containing at least one key using an NSEC-only
   21211 		 * algorithm), add the INITIAL flag, so these parameters can be
   21212 		 * used later when NSEC3 becomes available.
   21213 		 */
   21214 		dns_rdata_init(&rdata);
   21215 
   21216 		np->data[2] |= DNS_NSEC3FLAG_CREATE;
   21217 		result = dns_nsec_nseconly(db, newver, &nseconly);
   21218 		if (result == ISC_R_NOTFOUND || nseconly) {
   21219 			np->data[2] |= DNS_NSEC3FLAG_INITIAL;
   21220 		}
   21221 
   21222 		rdata.length = np->length;
   21223 		rdata.data = np->data;
   21224 		rdata.type = zone->privatetype;
   21225 		rdata.rdclass = zone->rdclass;
   21226 		CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
   21227 				    &zone->origin, 0, &rdata));
   21228 	}
   21229 
   21230 	/*
   21231 	 * If we changed anything in the zone, write changes to journal file
   21232 	 * and set commit to true so that resume_addnsec3chain() will be
   21233 	 * called below in order to kick off adding/removing relevant NSEC3
   21234 	 * records.
   21235 	 */
   21236 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   21237 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   21238 					zone->updatemethod));
   21239 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   21240 					       &diff,
   21241 					       zone->sigvalidityinterval);
   21242 		if (result != ISC_R_NOTFOUND) {
   21243 			CHECK(result);
   21244 		}
   21245 		CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
   21246 		commit = true;
   21247 
   21248 		LOCK_ZONE(zone);
   21249 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   21250 		zone_needdump(zone, 30);
   21251 		UNLOCK_ZONE(zone);
   21252 	}
   21253 
   21254 failure:
   21255 	if (dns_rdataset_isassociated(&prdataset)) {
   21256 		dns_rdataset_disassociate(&prdataset);
   21257 	}
   21258 	if (dns_rdataset_isassociated(&nrdataset)) {
   21259 		dns_rdataset_disassociate(&nrdataset);
   21260 	}
   21261 	if (node != NULL) {
   21262 		dns_db_detachnode(db, &node);
   21263 	}
   21264 	if (oldver != NULL) {
   21265 		dns_db_closeversion(db, &oldver, false);
   21266 	}
   21267 	if (newver != NULL) {
   21268 		dns_db_closeversion(db, &newver, commit);
   21269 	}
   21270 	if (db != NULL) {
   21271 		dns_db_detach(&db);
   21272 	}
   21273 	if (commit) {
   21274 		LOCK_ZONE(zone);
   21275 		resume_addnsec3chain(zone);
   21276 		UNLOCK_ZONE(zone);
   21277 	}
   21278 	dns_diff_clear(&diff);
   21279 	isc_event_free(&event);
   21280 
   21281 	INSIST(oldver == NULL);
   21282 	INSIST(newver == NULL);
   21283 }
   21284 
   21285 static void
   21286 salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text,
   21287 	  unsigned int textlen) {
   21288 	isc_region_t r;
   21289 	isc_buffer_t buf;
   21290 	isc_result_t result;
   21291 
   21292 	r.base = salt;
   21293 	r.length = (unsigned int)saltlen;
   21294 
   21295 	isc_buffer_init(&buf, text, textlen);
   21296 	result = isc_hex_totext(&r, 2, "", &buf);
   21297 	if (result == ISC_R_SUCCESS) {
   21298 		text[saltlen * 2] = 0;
   21299 	} else {
   21300 		text[0] = 0;
   21301 	}
   21302 }
   21303 
   21304 /*
   21305  * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters.
   21306  *
   21307  * If 'salt' is NULL, a match is found if the salt has the requested length,
   21308  * otherwise the NSEC3 salt must match the requested salt value too.
   21309  *
   21310  * Returns  ISC_R_SUCCESS, if a match is found, or an error if no match is
   21311  * found, or if the db lookup failed.
   21312  */
   21313 isc_result_t
   21314 dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup,
   21315 			    dns_rdata_nsec3param_t *param,
   21316 			    unsigned char saltbuf[255], bool resalt) {
   21317 	isc_result_t result = ISC_R_UNEXPECTED;
   21318 	dns_dbnode_t *node = NULL;
   21319 	dns_db_t *db = NULL;
   21320 	dns_dbversion_t *version = NULL;
   21321 	dns_rdataset_t rdataset;
   21322 	dns_rdata_nsec3param_t nsec3param;
   21323 	dns_rdata_t rdata = DNS_RDATA_INIT;
   21324 
   21325 	REQUIRE(DNS_ZONE_VALID(zone));
   21326 
   21327 	dns_rdataset_init(&rdataset);
   21328 
   21329 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   21330 	if (zone->db != NULL) {
   21331 		dns_db_attach(zone->db, &db);
   21332 	}
   21333 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   21334 	if (db == NULL) {
   21335 		goto setparam;
   21336 	}
   21337 
   21338 	result = dns_db_findnode(db, &zone->origin, false, &node);
   21339 	if (result != ISC_R_SUCCESS) {
   21340 		dns_zone_log(zone, ISC_LOG_ERROR,
   21341 			     "nsec3param lookup failure: %s",
   21342 			     dns_result_totext(result));
   21343 		goto setparam;
   21344 	}
   21345 	dns_db_currentversion(db, &version);
   21346 
   21347 	result = dns_db_findrdataset(db, node, version,
   21348 				     dns_rdatatype_nsec3param,
   21349 				     dns_rdatatype_none, 0, &rdataset, NULL);
   21350 	if (result != ISC_R_SUCCESS) {
   21351 		INSIST(!dns_rdataset_isassociated(&rdataset));
   21352 		if (result != ISC_R_NOTFOUND) {
   21353 			dns_zone_log(zone, ISC_LOG_ERROR,
   21354 				     "nsec3param lookup failure: %s",
   21355 				     dns_result_totext(result));
   21356 		}
   21357 		goto setparam;
   21358 	}
   21359 
   21360 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   21361 	     result = dns_rdataset_next(&rdataset))
   21362 	{
   21363 		dns_rdataset_current(&rdataset, &rdata);
   21364 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   21365 		INSIST(result == ISC_R_SUCCESS);
   21366 		dns_rdata_reset(&rdata);
   21367 
   21368 		/* Check parameters. */
   21369 		if (nsec3param.hash != lookup->hash) {
   21370 			continue;
   21371 		}
   21372 		if (nsec3param.iterations != lookup->iterations) {
   21373 			continue;
   21374 		}
   21375 		if (nsec3param.salt_length != lookup->salt_length) {
   21376 			continue;
   21377 		}
   21378 		if (lookup->salt != NULL) {
   21379 			if (memcmp(nsec3param.salt, lookup->salt,
   21380 				   lookup->salt_length) != 0) {
   21381 				continue;
   21382 			}
   21383 		}
   21384 		/* Found a match. */
   21385 		result = ISC_R_SUCCESS;
   21386 		param->hash = nsec3param.hash;
   21387 		param->flags = nsec3param.flags;
   21388 		param->iterations = nsec3param.iterations;
   21389 		param->salt_length = nsec3param.salt_length;
   21390 		param->salt = nsec3param.salt;
   21391 		break;
   21392 	}
   21393 
   21394 setparam:
   21395 	if (result != ISC_R_SUCCESS) {
   21396 		/* Found no match. */
   21397 		result = ISC_R_NOTFOUND;
   21398 		param->hash = lookup->hash;
   21399 		param->flags = lookup->flags;
   21400 		param->iterations = lookup->iterations;
   21401 		param->salt_length = lookup->salt_length;
   21402 		param->salt = lookup->salt;
   21403 	}
   21404 
   21405 	if (param->salt_length == 0) {
   21406 		DE_CONST("-", param->salt);
   21407 	} else if (resalt || param->salt == NULL) {
   21408 		unsigned char *newsalt;
   21409 		unsigned char salttext[255 * 2 + 1];
   21410 		do {
   21411 			/* Generate a new salt. */
   21412 			result = dns_nsec3_generate_salt(saltbuf,
   21413 							 param->salt_length);
   21414 			if (result != ISC_R_SUCCESS) {
   21415 				break;
   21416 			}
   21417 			newsalt = saltbuf;
   21418 			salt2text(newsalt, param->salt_length, salttext,
   21419 				  sizeof(salttext));
   21420 			dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s",
   21421 				   salttext);
   21422 			/* Check for salt conflict. */
   21423 			if (param->salt != NULL &&
   21424 			    memcmp(newsalt, param->salt, param->salt_length) ==
   21425 				    0)
   21426 			{
   21427 				result = ISC_R_SUCCESS;
   21428 			} else {
   21429 				param->salt = newsalt;
   21430 				result = DNS_R_NSEC3RESALT;
   21431 			}
   21432 		} while (result == ISC_R_SUCCESS);
   21433 
   21434 		INSIST(result != ISC_R_SUCCESS);
   21435 	}
   21436 
   21437 	if (dns_rdataset_isassociated(&rdataset)) {
   21438 		dns_rdataset_disassociate(&rdataset);
   21439 	}
   21440 	if (node != NULL) {
   21441 		dns_db_detachnode(db, &node);
   21442 	}
   21443 	if (version != NULL) {
   21444 		dns_db_closeversion(db, &version, false);
   21445 	}
   21446 	if (db != NULL) {
   21447 		dns_db_detach(&db);
   21448 	}
   21449 
   21450 	return (result);
   21451 }
   21452 
   21453 /*
   21454  * Called when an "rndc signing -nsec3param ..." command is received, or the
   21455  * 'dnssec-policy' has changed.
   21456  *
   21457  * Allocate and prepare an nsec3param_t structure which holds information about
   21458  * the NSEC3 changes requested for the zone:
   21459  *
   21460  *   - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec"
   21461  *     field of the structure to true and the "replace" field to the value
   21462  *     of the "replace" argument, leaving other fields initialized to zeros, to
   21463  *     signal that the zone should be signed using NSEC instead of NSEC3,
   21464  *
   21465  *   - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at
   21466  *     the zone apex, convert it to a private-type record and store the latter
   21467  *     in the "data" field of the nsec3param_t structure.
   21468  *
   21469  * Once the nsec3param_t structure is prepared, post an event to the zone's
   21470  * task which will cause setnsec3param() to be called with the prepared
   21471  * structure passed as an argument.
   21472  */
   21473 isc_result_t
   21474 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags,
   21475 		       uint16_t iter, uint8_t saltlen, unsigned char *salt,
   21476 		       bool replace, bool resalt) {
   21477 	isc_result_t result = ISC_R_SUCCESS;
   21478 	dns_rdata_nsec3param_t param, lookup;
   21479 	dns_rdata_t nrdata = DNS_RDATA_INIT;
   21480 	dns_rdata_t prdata = DNS_RDATA_INIT;
   21481 	unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
   21482 	unsigned char saltbuf[255];
   21483 	struct np3event *npe;
   21484 	nsec3param_t *np;
   21485 	dns_zone_t *dummy = NULL;
   21486 	isc_buffer_t b;
   21487 	isc_event_t *e = NULL;
   21488 
   21489 	REQUIRE(DNS_ZONE_VALID(zone));
   21490 
   21491 	LOCK_ZONE(zone);
   21492 
   21493 	/*
   21494 	 * First check if the requested NSEC3 parameters are already set,
   21495 	 * if so, no need to set again.
   21496 	 */
   21497 	if (hash != 0) {
   21498 		lookup.hash = hash;
   21499 		lookup.flags = flags;
   21500 		lookup.iterations = iter;
   21501 		lookup.salt_length = saltlen;
   21502 		lookup.salt = salt;
   21503 		param.salt = NULL;
   21504 		result = dns__zone_lookup_nsec3param(zone, &lookup, &param,
   21505 						     saltbuf, resalt);
   21506 		if (result == ISC_R_SUCCESS) {
   21507 			UNLOCK_ZONE(zone);
   21508 			return (ISC_R_SUCCESS);
   21509 		}
   21510 		INSIST(param.salt != NULL);
   21511 	}
   21512 
   21513 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
   21514 			       setnsec3param, zone, sizeof(struct np3event));
   21515 
   21516 	npe = (struct np3event *)e;
   21517 	np = &npe->params;
   21518 
   21519 	np->replace = replace;
   21520 	if (hash == 0) {
   21521 		np->length = 0;
   21522 		np->nsec = true;
   21523 		dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec");
   21524 	} else {
   21525 		param.common.rdclass = zone->rdclass;
   21526 		param.common.rdtype = dns_rdatatype_nsec3param;
   21527 		ISC_LINK_INIT(&param.common, link);
   21528 		param.mctx = NULL;
   21529 		/* nsec3 specific param set in dns__zone_lookup_nsec3param() */
   21530 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
   21531 		CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
   21532 					   dns_rdatatype_nsec3param, &param,
   21533 					   &b));
   21534 		dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
   21535 					 np->data, sizeof(np->data));
   21536 		np->length = prdata.length;
   21537 		np->nsec = false;
   21538 
   21539 		if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   21540 			unsigned char salttext[255 * 2 + 1];
   21541 			salt2text(param.salt, param.salt_length, salttext,
   21542 				  sizeof(salttext));
   21543 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   21544 				   "setnsec3param:nsec3 %u %u %u %s",
   21545 				   param.hash, param.flags, param.iterations,
   21546 				   salttext);
   21547 		}
   21548 	}
   21549 
   21550 	/*
   21551 	 * setnsec3param() will silently return early if the zone does not yet
   21552 	 * have a database.  Prevent that by queueing the event up if zone->db
   21553 	 * is NULL.  All events queued here are subsequently processed by
   21554 	 * receive_secure_db() if it ever gets called or simply freed by
   21555 	 * zone_free() otherwise.
   21556 	 */
   21557 
   21558 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   21559 	if (zone->db != NULL) {
   21560 		zone_iattach(zone, &dummy);
   21561 		isc_task_send(zone->task, &e);
   21562 	} else {
   21563 		ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link);
   21564 		e = NULL;
   21565 	}
   21566 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   21567 
   21568 	result = ISC_R_SUCCESS;
   21569 
   21570 failure:
   21571 	if (e != NULL) {
   21572 		isc_event_free(&e);
   21573 	}
   21574 	UNLOCK_ZONE(zone);
   21575 	return (result);
   21576 }
   21577 
   21578 isc_result_t
   21579 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
   21580 	REQUIRE(DNS_ZONE_VALID(zone));
   21581 	REQUIRE(loadtime != NULL);
   21582 
   21583 	LOCK_ZONE(zone);
   21584 	*loadtime = zone->loadtime;
   21585 	UNLOCK_ZONE(zone);
   21586 	return (ISC_R_SUCCESS);
   21587 }
   21588 
   21589 isc_result_t
   21590 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
   21591 	REQUIRE(DNS_ZONE_VALID(zone));
   21592 	REQUIRE(expiretime != NULL);
   21593 
   21594 	LOCK_ZONE(zone);
   21595 	*expiretime = zone->expiretime;
   21596 	UNLOCK_ZONE(zone);
   21597 	return (ISC_R_SUCCESS);
   21598 }
   21599 
   21600 isc_result_t
   21601 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
   21602 	REQUIRE(DNS_ZONE_VALID(zone));
   21603 	REQUIRE(refreshtime != NULL);
   21604 
   21605 	LOCK_ZONE(zone);
   21606 	*refreshtime = zone->refreshtime;
   21607 	UNLOCK_ZONE(zone);
   21608 	return (ISC_R_SUCCESS);
   21609 }
   21610 
   21611 isc_result_t
   21612 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
   21613 	REQUIRE(DNS_ZONE_VALID(zone));
   21614 	REQUIRE(refreshkeytime != NULL);
   21615 
   21616 	LOCK_ZONE(zone);
   21617 	*refreshkeytime = zone->refreshkeytime;
   21618 	UNLOCK_ZONE(zone);
   21619 	return (ISC_R_SUCCESS);
   21620 }
   21621 
   21622 unsigned int
   21623 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
   21624 	dns_include_t *include;
   21625 	char **array = NULL;
   21626 	unsigned int n = 0;
   21627 
   21628 	REQUIRE(DNS_ZONE_VALID(zone));
   21629 	REQUIRE(includesp != NULL && *includesp == NULL);
   21630 
   21631 	LOCK_ZONE(zone);
   21632 	if (zone->nincludes == 0) {
   21633 		goto done;
   21634 	}
   21635 
   21636 	array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
   21637 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   21638 	     include = ISC_LIST_NEXT(include, link))
   21639 	{
   21640 		INSIST(n < zone->nincludes);
   21641 		array[n++] = isc_mem_strdup(zone->mctx, include->name);
   21642 	}
   21643 	INSIST(n == zone->nincludes);
   21644 	*includesp = array;
   21645 
   21646 done:
   21647 	UNLOCK_ZONE(zone);
   21648 	return (n);
   21649 }
   21650 
   21651 void
   21652 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
   21653 	REQUIRE(DNS_ZONE_VALID(zone));
   21654 
   21655 	zone->statlevel = level;
   21656 }
   21657 
   21658 dns_zonestat_level_t
   21659 dns_zone_getstatlevel(dns_zone_t *zone) {
   21660 	REQUIRE(DNS_ZONE_VALID(zone));
   21661 
   21662 	return (zone->statlevel);
   21663 }
   21664 
   21665 static void
   21666 setserial(isc_task_t *task, isc_event_t *event) {
   21667 	uint32_t oldserial, desired;
   21668 	const char *me = "setserial";
   21669 	bool commit = false;
   21670 	isc_result_t result;
   21671 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   21672 	dns_zone_t *zone;
   21673 	dns_db_t *db = NULL;
   21674 	dns_diff_t diff;
   21675 	struct ssevent *sse = (struct ssevent *)event;
   21676 	dns_update_log_t log = { update_log_cb, NULL };
   21677 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   21678 
   21679 	UNUSED(task);
   21680 
   21681 	zone = event->ev_arg;
   21682 	INSIST(DNS_ZONE_VALID(zone));
   21683 
   21684 	ENTER;
   21685 
   21686 	if (zone->update_disabled) {
   21687 		goto failure;
   21688 	}
   21689 
   21690 	desired = sse->serial;
   21691 
   21692 	dns_diff_init(zone->mctx, &diff);
   21693 
   21694 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   21695 	if (zone->db != NULL) {
   21696 		dns_db_attach(zone->db, &db);
   21697 	}
   21698 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   21699 	if (db == NULL) {
   21700 		goto failure;
   21701 	}
   21702 
   21703 	dns_db_currentversion(db, &oldver);
   21704 	result = dns_db_newversion(db, &newver);
   21705 	if (result != ISC_R_SUCCESS) {
   21706 		dns_zone_log(zone, ISC_LOG_ERROR,
   21707 			     "setserial:dns_db_newversion -> %s",
   21708 			     dns_result_totext(result));
   21709 		goto failure;
   21710 	}
   21711 
   21712 	CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL,
   21713 				    &oldtuple));
   21714 	CHECK(dns_difftuple_copy(oldtuple, &newtuple));
   21715 	newtuple->op = DNS_DIFFOP_ADD;
   21716 
   21717 	oldserial = dns_soa_getserial(&oldtuple->rdata);
   21718 	if (desired == 0U) {
   21719 		desired = 1;
   21720 	}
   21721 	if (!isc_serial_gt(desired, oldserial)) {
   21722 		if (desired != oldserial) {
   21723 			dns_zone_log(zone, ISC_LOG_INFO,
   21724 				     "setserial: desired serial (%u) "
   21725 				     "out of range (%u-%u)",
   21726 				     desired, oldserial + 1,
   21727 				     (oldserial + 0x7fffffff));
   21728 		}
   21729 		goto failure;
   21730 	}
   21731 
   21732 	dns_soa_setserial(desired, &newtuple->rdata);
   21733 	CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
   21734 	CHECK(do_one_tuple(&newtuple, db, newver, &diff));
   21735 	result = dns_update_signatures(&log, zone, db, oldver, newver, &diff,
   21736 				       zone->sigvalidityinterval);
   21737 	if (result != ISC_R_NOTFOUND) {
   21738 		CHECK(result);
   21739 	}
   21740 
   21741 	/* Write changes to journal file. */
   21742 	CHECK(zone_journal(zone, &diff, NULL, "setserial"));
   21743 	commit = true;
   21744 
   21745 	LOCK_ZONE(zone);
   21746 	zone_needdump(zone, 30);
   21747 	UNLOCK_ZONE(zone);
   21748 
   21749 failure:
   21750 	if (oldtuple != NULL) {
   21751 		dns_difftuple_free(&oldtuple);
   21752 	}
   21753 	if (newtuple != NULL) {
   21754 		dns_difftuple_free(&newtuple);
   21755 	}
   21756 	if (oldver != NULL) {
   21757 		dns_db_closeversion(db, &oldver, false);
   21758 	}
   21759 	if (newver != NULL) {
   21760 		dns_db_closeversion(db, &newver, commit);
   21761 	}
   21762 	if (db != NULL) {
   21763 		dns_db_detach(&db);
   21764 	}
   21765 	dns_diff_clear(&diff);
   21766 	isc_event_free(&event);
   21767 	dns_zone_idetach(&zone);
   21768 
   21769 	INSIST(oldver == NULL);
   21770 	INSIST(newver == NULL);
   21771 }
   21772 
   21773 isc_result_t
   21774 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
   21775 	isc_result_t result = ISC_R_SUCCESS;
   21776 	dns_zone_t *dummy = NULL;
   21777 	isc_event_t *e = NULL;
   21778 	struct ssevent *sse;
   21779 
   21780 	REQUIRE(DNS_ZONE_VALID(zone));
   21781 
   21782 	LOCK_ZONE(zone);
   21783 
   21784 	if (!inline_secure(zone)) {
   21785 		if (!dns_zone_isdynamic(zone, true)) {
   21786 			result = DNS_R_NOTDYNAMIC;
   21787 			goto failure;
   21788 		}
   21789 	}
   21790 
   21791 	if (zone->update_disabled) {
   21792 		result = DNS_R_FROZEN;
   21793 		goto failure;
   21794 	}
   21795 
   21796 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL, setserial,
   21797 			       zone, sizeof(struct ssevent));
   21798 
   21799 	sse = (struct ssevent *)e;
   21800 	sse->serial = serial;
   21801 
   21802 	zone_iattach(zone, &dummy);
   21803 	isc_task_send(zone->task, &e);
   21804 
   21805 failure:
   21806 	if (e != NULL) {
   21807 		isc_event_free(&e);
   21808 	}
   21809 	UNLOCK_ZONE(zone);
   21810 	return (result);
   21811 }
   21812 
   21813 isc_stats_t *
   21814 dns_zone_getgluecachestats(dns_zone_t *zone) {
   21815 	REQUIRE(DNS_ZONE_VALID(zone));
   21816 
   21817 	return (zone->gluecachestats);
   21818 }
   21819 
   21820 bool
   21821 dns_zone_isloaded(dns_zone_t *zone) {
   21822 	REQUIRE(DNS_ZONE_VALID(zone));
   21823 
   21824 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
   21825 }
   21826 
   21827 isc_result_t
   21828 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
   21829 	dns_dbversion_t *version = NULL;
   21830 	dns_keytable_t *secroots = NULL;
   21831 	isc_result_t result;
   21832 	dns_name_t *origin;
   21833 
   21834 	const char me[] = "dns_zone_verifydb";
   21835 
   21836 	REQUIRE(DNS_ZONE_VALID(zone));
   21837 	REQUIRE(db != NULL);
   21838 
   21839 	ENTER;
   21840 
   21841 	if (dns_zone_gettype(zone) != dns_zone_mirror) {
   21842 		return (ISC_R_SUCCESS);
   21843 	}
   21844 
   21845 	if (ver == NULL) {
   21846 		dns_db_currentversion(db, &version);
   21847 	} else {
   21848 		version = ver;
   21849 	}
   21850 
   21851 	if (zone->view != NULL) {
   21852 		result = dns_view_getsecroots(zone->view, &secroots);
   21853 		if (result != ISC_R_SUCCESS) {
   21854 			goto done;
   21855 		}
   21856 	}
   21857 
   21858 	origin = dns_db_origin(db);
   21859 	result = dns_zoneverify_dnssec(zone, db, version, origin, secroots,
   21860 				       zone->mctx, true, false, dnssec_report);
   21861 
   21862 done:
   21863 	if (secroots != NULL) {
   21864 		dns_keytable_detach(&secroots);
   21865 	}
   21866 
   21867 	if (ver == NULL) {
   21868 		dns_db_closeversion(db, &version, false);
   21869 	}
   21870 
   21871 	if (result != ISC_R_SUCCESS) {
   21872 		dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s",
   21873 			   isc_result_totext(result));
   21874 		result = DNS_R_VERIFYFAILURE;
   21875 	}
   21876 
   21877 	return (result);
   21878 }
   21879