Home | History | Annotate | Line # | Download | only in dns
zone.c revision 1.12
      1 /*	$NetBSD: zone.c,v 1.12 2021/02/19 16:42:16 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 (/*CONSTCOND*/0)
    167 #define UNLOCK_ZONE(z)               \
    168 	do {                         \
    169 		(z)->locked = false; \
    170 		UNLOCK(&(z)->lock);  \
    171 	} while (/*CONSTCOND*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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 (/*CONSTCOND*/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_DIFFONRELOAD = 0x00000800U, /*%< generate a journal diff on
    485 						 * reload */
    486 	DNS_ZONEFLG_NOMASTERS = 0x00001000U,	/*%< an attempt to refresh a
    487 						 * zone with no primaries
    488 						 * occurred */
    489 	DNS_ZONEFLG_LOADING = 0x00002000U,    /*%< load from disk in progress*/
    490 	DNS_ZONEFLG_HAVETIMERS = 0x00004000U, /*%< timer values have been set
    491 					       * from SOA (if not set, we
    492 					       * are still using
    493 					       * default timer values) */
    494 	DNS_ZONEFLG_FORCEXFER = 0x00008000U,  /*%< Force a zone xfer */
    495 	DNS_ZONEFLG_NOREFRESH = 0x00010000U,
    496 	DNS_ZONEFLG_DIALNOTIFY = 0x00020000U,
    497 	DNS_ZONEFLG_DIALREFRESH = 0x00040000U,
    498 	DNS_ZONEFLG_SHUTDOWN = 0x00080000U,
    499 	DNS_ZONEFLG_NOIXFR = 0x00100000U, /*%< IXFR failed, force AXFR */
    500 	DNS_ZONEFLG_FLUSH = 0x00200000U,
    501 	DNS_ZONEFLG_NOEDNS = 0x00400000U,
    502 	DNS_ZONEFLG_USEALTXFRSRC = 0x00800000U,
    503 	DNS_ZONEFLG_SOABEFOREAXFR = 0x01000000U,
    504 	DNS_ZONEFLG_NEEDCOMPACT = 0x02000000U,
    505 	DNS_ZONEFLG_REFRESHING = 0x04000000U, /*%< Refreshing keydata */
    506 	DNS_ZONEFLG_THAW = 0x08000000U,
    507 	DNS_ZONEFLG_LOADPENDING = 0x10000000U, /*%< Loading scheduled */
    508 	DNS_ZONEFLG_NODELAY = 0x20000000U,
    509 	DNS_ZONEFLG_SENDSECURE = 0x40000000U,
    510 	DNS_ZONEFLG_NEEDSTARTUPNOTIFY = 0x80000000U, /*%< need to send out
    511 						      * notify due to the zone
    512 						      * just being loaded for
    513 						      * the first time.  */
    514 #ifndef __NetBSD__
    515 	DNS_ZONEFLG___MAX = UINT64_MAX, /* trick to make the ENUM 64-bit wide */
    516 #endif
    517 } dns_zoneflg_t;
    518 
    519 #define DNS_ZONE_OPTION(z, o)	 ((atomic_load_relaxed(&(z)->options) & (o)) != 0)
    520 #define DNS_ZONE_SETOPTION(z, o) atomic_fetch_or(&(z)->options, (o))
    521 #define DNS_ZONE_CLROPTION(z, o) atomic_fetch_and(&(z)->options, ~(o))
    522 
    523 #define DNS_ZONEKEY_OPTION(z, o) \
    524 	((atomic_load_relaxed(&(z)->keyopts) & (o)) != 0)
    525 #define DNS_ZONEKEY_SETOPTION(z, o) atomic_fetch_or(&(z)->keyopts, (o))
    526 #define DNS_ZONEKEY_CLROPTION(z, o) atomic_fetch_and(&(z)->keyopts, ~(o))
    527 
    528 /* Flags for zone_load() */
    529 typedef enum {
    530 	DNS_ZONELOADFLAG_NOSTAT = 0x00000001U, /* Do not stat() master files */
    531 	DNS_ZONELOADFLAG_THAW = 0x00000002U,   /* Thaw the zone on successful
    532 						* load. */
    533 } dns_zoneloadflag_t;
    534 
    535 #define UNREACH_CACHE_SIZE 10U
    536 #define UNREACH_HOLD_TIME  600 /* 10 minutes */
    537 
    538 #define CHECK(op)                            \
    539 	do {                                 \
    540 		result = (op);               \
    541 		if (result != ISC_R_SUCCESS) \
    542 			goto failure;        \
    543 	} while (/*CONSTCOND*/0)
    544 
    545 struct dns_unreachable {
    546 	isc_sockaddr_t remote;
    547 	isc_sockaddr_t local;
    548 	atomic_uint_fast32_t expire;
    549 	atomic_uint_fast32_t last;
    550 	uint32_t count;
    551 };
    552 
    553 struct dns_zonemgr {
    554 	unsigned int magic;
    555 	isc_mem_t *mctx;
    556 	isc_refcount_t refs;
    557 	isc_taskmgr_t *taskmgr;
    558 	isc_timermgr_t *timermgr;
    559 	isc_socketmgr_t *socketmgr;
    560 	isc_taskpool_t *zonetasks;
    561 	isc_taskpool_t *loadtasks;
    562 	isc_task_t *task;
    563 	isc_pool_t *mctxpool;
    564 	isc_ratelimiter_t *notifyrl;
    565 	isc_ratelimiter_t *refreshrl;
    566 	isc_ratelimiter_t *startupnotifyrl;
    567 	isc_ratelimiter_t *startuprefreshrl;
    568 	isc_rwlock_t rwlock;
    569 	isc_mutex_t iolock;
    570 	isc_rwlock_t urlock;
    571 
    572 	/* Locked by rwlock. */
    573 	dns_zonelist_t zones;
    574 	dns_zonelist_t waiting_for_xfrin;
    575 	dns_zonelist_t xfrin_in_progress;
    576 
    577 	/* Configuration data. */
    578 	uint32_t transfersin;
    579 	uint32_t transfersperns;
    580 	unsigned int notifyrate;
    581 	unsigned int startupnotifyrate;
    582 	unsigned int serialqueryrate;
    583 	unsigned int startupserialqueryrate;
    584 
    585 	/* Locked by iolock */
    586 	uint32_t iolimit;
    587 	uint32_t ioactive;
    588 	dns_iolist_t high;
    589 	dns_iolist_t low;
    590 
    591 	/* Locked by urlock. */
    592 	/* LRU cache */
    593 	struct dns_unreachable unreachable[UNREACH_CACHE_SIZE];
    594 };
    595 
    596 /*%
    597  * Hold notify state.
    598  */
    599 struct dns_notify {
    600 	unsigned int magic;
    601 	unsigned int flags;
    602 	isc_mem_t *mctx;
    603 	dns_zone_t *zone;
    604 	dns_adbfind_t *find;
    605 	dns_request_t *request;
    606 	dns_name_t ns;
    607 	isc_sockaddr_t dst;
    608 	dns_tsigkey_t *key;
    609 	isc_dscp_t dscp;
    610 	ISC_LINK(dns_notify_t) link;
    611 	isc_event_t *event;
    612 };
    613 
    614 #define DNS_NOTIFY_NOSOA   0x0001U
    615 #define DNS_NOTIFY_STARTUP 0x0002U
    616 
    617 /*%
    618  *	dns_stub holds state while performing a 'stub' transfer.
    619  *	'db' is the zone's 'db' or a new one if this is the initial
    620  *	transfer.
    621  */
    622 
    623 struct dns_stub {
    624 	unsigned int magic;
    625 	isc_mem_t *mctx;
    626 	dns_zone_t *zone;
    627 	dns_db_t *db;
    628 	dns_dbversion_t *version;
    629 	atomic_uint_fast32_t pending_requests;
    630 };
    631 
    632 /*%
    633  *	Hold load state.
    634  */
    635 struct dns_load {
    636 	unsigned int magic;
    637 	isc_mem_t *mctx;
    638 	dns_zone_t *zone;
    639 	dns_db_t *db;
    640 	isc_time_t loadtime;
    641 	dns_rdatacallbacks_t callbacks;
    642 };
    643 
    644 /*%
    645  *	Hold forward state.
    646  */
    647 struct dns_forward {
    648 	unsigned int magic;
    649 	isc_mem_t *mctx;
    650 	dns_zone_t *zone;
    651 	isc_buffer_t *msgbuf;
    652 	dns_request_t *request;
    653 	uint32_t which;
    654 	isc_sockaddr_t addr;
    655 	dns_updatecallback_t callback;
    656 	void *callback_arg;
    657 	unsigned int options;
    658 	ISC_LINK(dns_forward_t) link;
    659 };
    660 
    661 /*%
    662  *	Hold IO request state.
    663  */
    664 struct dns_io {
    665 	unsigned int magic;
    666 	dns_zonemgr_t *zmgr;
    667 	bool high;
    668 	isc_task_t *task;
    669 	ISC_LINK(dns_io_t) link;
    670 	isc_event_t *event;
    671 };
    672 
    673 /*%
    674  *	Hold state for when we are signing a zone with a new
    675  *	DNSKEY as result of an update.
    676  */
    677 struct dns_signing {
    678 	unsigned int magic;
    679 	dns_db_t *db;
    680 	dns_dbiterator_t *dbiterator;
    681 	dns_secalg_t algorithm;
    682 	uint16_t keyid;
    683 	bool deleteit;
    684 	bool done;
    685 	ISC_LINK(dns_signing_t) link;
    686 };
    687 
    688 struct dns_nsec3chain {
    689 	unsigned int magic;
    690 	dns_db_t *db;
    691 	dns_dbiterator_t *dbiterator;
    692 	dns_rdata_nsec3param_t nsec3param;
    693 	unsigned char salt[255];
    694 	bool done;
    695 	bool seen_nsec;
    696 	bool delete_nsec;
    697 	bool save_delete_nsec;
    698 	ISC_LINK(dns_nsec3chain_t) link;
    699 };
    700 /*%<
    701  * 'dbiterator' contains a iterator for the database.  If we are creating
    702  * a NSEC3 chain only the non-NSEC3 nodes will be iterated.  If we are
    703  * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
    704  * iterated.
    705  *
    706  * 'nsec3param' contains the parameters of the NSEC3 chain being created
    707  * or removed.
    708  *
    709  * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
    710  *
    711  * 'seen_nsec' will be set to true if, while iterating the zone to create a
    712  * NSEC3 chain, a NSEC record is seen.
    713  *
    714  * 'delete_nsec' will be set to true if, at the completion of the creation
    715  * of a NSEC3 chain, 'seen_nsec' is true.  If 'delete_nsec' is true then we
    716  * are in the process of deleting the NSEC chain.
    717  *
    718  * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
    719  * so it can be recovered in the event of a error.
    720  */
    721 
    722 struct dns_keyfetch {
    723 	dns_fixedname_t name;
    724 	dns_rdataset_t keydataset;
    725 	dns_rdataset_t dnskeyset;
    726 	dns_rdataset_t dnskeysigset;
    727 	dns_zone_t *zone;
    728 	dns_db_t *db;
    729 	dns_fetch_t *fetch;
    730 };
    731 
    732 /*%
    733  * Hold state for an asynchronous load
    734  */
    735 struct dns_asyncload {
    736 	dns_zone_t *zone;
    737 	unsigned int flags;
    738 	dns_zt_zoneloaded_t loaded;
    739 	void *loaded_arg;
    740 };
    741 
    742 /*%
    743  * Reference to an include file encountered during loading
    744  */
    745 struct dns_include {
    746 	char *name;
    747 	isc_time_t filetime;
    748 	ISC_LINK(dns_include_t) link;
    749 };
    750 
    751 /*
    752  * These can be overridden by the -T mkeytimers option on the command
    753  * line, so that we can test with shorter periods than specified in
    754  * RFC 5011.
    755  */
    756 #define HOUR  3600
    757 #define DAY   (24 * HOUR)
    758 #define MONTH (30 * DAY)
    759 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_hour = HOUR;
    760 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_day = DAY;
    761 LIBDNS_EXTERNAL_DATA unsigned int dns_zone_mkey_month = MONTH;
    762 
    763 #define SEND_BUFFER_SIZE 2048
    764 
    765 static void
    766 zone_settimer(dns_zone_t *, isc_time_t *);
    767 static void
    768 cancel_refresh(dns_zone_t *);
    769 static void
    770 zone_debuglog(dns_zone_t *zone, const char *, int debuglevel, const char *msg,
    771 	      ...) ISC_FORMAT_PRINTF(4, 5);
    772 static void
    773 notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
    774 	ISC_FORMAT_PRINTF(3, 4);
    775 static void
    776 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...)
    777 	ISC_FORMAT_PRINTF(3, 4);
    778 static void
    779 queue_xfrin(dns_zone_t *zone);
    780 static isc_result_t
    781 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
    782 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
    783 	      dns_rdata_t *rdata);
    784 static void
    785 zone_unload(dns_zone_t *zone);
    786 static void
    787 zone_expire(dns_zone_t *zone);
    788 static void
    789 zone_iattach(dns_zone_t *source, dns_zone_t **target);
    790 static void
    791 zone_idetach(dns_zone_t **zonep);
    792 static isc_result_t
    793 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump);
    794 static inline void
    795 zone_attachdb(dns_zone_t *zone, dns_db_t *db);
    796 static inline void
    797 zone_detachdb(dns_zone_t *zone);
    798 static isc_result_t
    799 default_journal(dns_zone_t *zone);
    800 static void
    801 zone_xfrdone(dns_zone_t *zone, isc_result_t result);
    802 static isc_result_t
    803 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
    804 	      isc_result_t result);
    805 static void
    806 zone_needdump(dns_zone_t *zone, unsigned int delay);
    807 static void
    808 zone_shutdown(isc_task_t *, isc_event_t *);
    809 static void
    810 zone_loaddone(void *arg, isc_result_t result);
    811 static isc_result_t
    812 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime);
    813 static void
    814 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
    815 static void
    816 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
    817 static void
    818 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
    819 static void
    820 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
    821 static isc_result_t
    822 zone_send_secureserial(dns_zone_t *zone, uint32_t serial);
    823 static void
    824 refresh_callback(isc_task_t *, isc_event_t *);
    825 static void
    826 stub_callback(isc_task_t *, isc_event_t *);
    827 static void
    828 queue_soa_query(dns_zone_t *zone);
    829 static void
    830 soa_query(isc_task_t *, isc_event_t *);
    831 static void
    832 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub);
    833 static int
    834 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type);
    835 static void
    836 notify_cancel(dns_zone_t *zone);
    837 static void
    838 notify_find_address(dns_notify_t *notify);
    839 static void
    840 notify_send(dns_notify_t *notify);
    841 static isc_result_t
    842 notify_createmessage(dns_zone_t *zone, unsigned int flags,
    843 		     dns_message_t **messagep);
    844 static void
    845 notify_done(isc_task_t *task, isc_event_t *event);
    846 static void
    847 notify_send_toaddr(isc_task_t *task, isc_event_t *event);
    848 static isc_result_t
    849 zone_dump(dns_zone_t *, bool);
    850 static void
    851 got_transfer_quota(isc_task_t *task, isc_event_t *event);
    852 static isc_result_t
    853 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone);
    854 static void
    855 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi);
    856 static void
    857 zonemgr_free(dns_zonemgr_t *zmgr);
    858 static isc_result_t
    859 zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task,
    860 	      isc_taskaction_t action, void *arg, dns_io_t **iop);
    861 static void
    862 zonemgr_putio(dns_io_t **iop);
    863 static void
    864 zonemgr_cancelio(dns_io_t *io);
    865 static void
    866 rss_post(dns_zone_t *, isc_event_t *);
    867 
    868 static isc_result_t
    869 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
    870 		 unsigned int *soacount, uint32_t *serial, uint32_t *refresh,
    871 		 uint32_t *retry, uint32_t *expire, uint32_t *minimum,
    872 		 unsigned int *errors);
    873 
    874 static void
    875 zone_freedbargs(dns_zone_t *zone);
    876 static void
    877 forward_callback(isc_task_t *task, isc_event_t *event);
    878 static void
    879 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat);
    880 static void
    881 zone_maintenance(dns_zone_t *zone);
    882 static void
    883 zone_notify(dns_zone_t *zone, isc_time_t *now);
    884 static void
    885 dump_done(void *arg, isc_result_t result);
    886 static isc_result_t
    887 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
    888 		 bool deleteit);
    889 static isc_result_t
    890 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
    891 	    dns_name_t *name, dns_diff_t *diff);
    892 static void
    893 zone_rekey(dns_zone_t *zone);
    894 static isc_result_t
    895 zone_send_securedb(dns_zone_t *zone, dns_db_t *db);
    896 static void
    897 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value);
    898 
    899 #define ENTER zone_debuglog(zone, me, 1, "enter")
    900 
    901 static const unsigned int dbargc_default = 1;
    902 static const char *dbargv_default[] = { "rbt" };
    903 
    904 #define DNS_ZONE_JITTER_ADD(a, b, c)                                         \
    905 	do {                                                                 \
    906 		isc_interval_t _i;                                           \
    907 		uint32_t _j;                                                 \
    908 		_j = (b)-isc_random_uniform((b) / 4);                        \
    909 		isc_interval_set(&_i, _j, 0);                                \
    910 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) {          \
    911 			dns_zone_log(zone, ISC_LOG_WARNING,                  \
    912 				     "epoch approaching: upgrade required: " \
    913 				     "now + %s failed",                      \
    914 				     #b);                                    \
    915 			isc_interval_set(&_i, _j / 2, 0);                    \
    916 			(void)isc_time_add((a), &_i, (c));                   \
    917 		}                                                            \
    918 	} while (/*CONSTCOND*/0)
    919 
    920 #define DNS_ZONE_TIME_ADD(a, b, c)                                           \
    921 	do {                                                                 \
    922 		isc_interval_t _i;                                           \
    923 		isc_interval_set(&_i, (b), 0);                               \
    924 		if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) {          \
    925 			dns_zone_log(zone, ISC_LOG_WARNING,                  \
    926 				     "epoch approaching: upgrade required: " \
    927 				     "now + %s failed",                      \
    928 				     #b);                                    \
    929 			isc_interval_set(&_i, (b) / 2, 0);                   \
    930 			(void)isc_time_add((a), &_i, (c));                   \
    931 		}                                                            \
    932 	} while (/*CONSTCOND*/0)
    933 
    934 typedef struct nsec3param nsec3param_t;
    935 struct nsec3param {
    936 	unsigned char data[DNS_NSEC3PARAM_BUFFERSIZE + 1];
    937 	unsigned int length;
    938 	bool nsec;
    939 	bool replace;
    940 	ISC_LINK(nsec3param_t) link;
    941 };
    942 typedef ISC_LIST(nsec3param_t) nsec3paramlist_t;
    943 struct np3event {
    944 	isc_event_t event;
    945 	nsec3param_t params;
    946 };
    947 
    948 struct ssevent {
    949 	isc_event_t event;
    950 	uint32_t serial;
    951 };
    952 
    953 struct stub_cb_args {
    954 	dns_stub_t *stub;
    955 	dns_tsigkey_t *tsig_key;
    956 	isc_dscp_t dscp;
    957 	uint16_t udpsize;
    958 	int timeout;
    959 	bool reqnsid;
    960 };
    961 
    962 struct stub_glue_request {
    963 	dns_request_t *request;
    964 	dns_name_t name;
    965 	struct stub_cb_args *args;
    966 	bool ipv4;
    967 };
    968 
    969 /*%
    970  * Increment resolver-related statistics counters.  Zone must be locked.
    971  */
    972 static inline void
    973 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
    974 	if (zone->stats != NULL) {
    975 		isc_stats_increment(zone->stats, counter);
    976 	}
    977 }
    978 
    979 /***
    980  ***	Public functions.
    981  ***/
    982 
    983 isc_result_t
    984 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
    985 	isc_result_t result;
    986 	dns_zone_t *zone;
    987 	isc_time_t now;
    988 
    989 	REQUIRE(zonep != NULL && *zonep == NULL);
    990 	REQUIRE(mctx != NULL);
    991 
    992 	TIME_NOW(&now);
    993 	zone = isc_mem_get(mctx, sizeof(*zone));
    994 
    995 	zone->mctx = NULL;
    996 	isc_mem_attach(mctx, &zone->mctx);
    997 
    998 	isc_mutex_init(&zone->lock);
    999 
   1000 	result = ZONEDB_INITLOCK(&zone->dblock);
   1001 	if (result != ISC_R_SUCCESS) {
   1002 		goto free_mutex;
   1003 	}
   1004 
   1005 	/* XXX MPA check that all elements are initialised */
   1006 #ifdef DNS_ZONE_CHECKLOCK
   1007 	zone->locked = false;
   1008 #endif /* ifdef DNS_ZONE_CHECKLOCK */
   1009 	zone->db = NULL;
   1010 	zone->zmgr = NULL;
   1011 	ISC_LINK_INIT(zone, link);
   1012 	isc_refcount_init(&zone->erefs, 1);
   1013 	isc_refcount_init(&zone->irefs, 0);
   1014 	dns_name_init(&zone->origin, NULL);
   1015 	zone->strnamerd = NULL;
   1016 	zone->strname = NULL;
   1017 	zone->strrdclass = NULL;
   1018 	zone->strviewname = NULL;
   1019 	zone->masterfile = NULL;
   1020 	ISC_LIST_INIT(zone->includes);
   1021 	ISC_LIST_INIT(zone->newincludes);
   1022 	zone->nincludes = 0;
   1023 	zone->masterformat = dns_masterformat_none;
   1024 	zone->masterstyle = NULL;
   1025 	zone->keydirectory = NULL;
   1026 	zone->journalsize = -1;
   1027 	zone->journal = NULL;
   1028 	zone->rdclass = dns_rdataclass_none;
   1029 	zone->type = dns_zone_none;
   1030 	atomic_init(&zone->flags, 0);
   1031 	atomic_init(&zone->options, 0);
   1032 	atomic_init(&zone->keyopts, 0);
   1033 	zone->db_argc = 0;
   1034 	zone->db_argv = NULL;
   1035 	isc_time_settoepoch(&zone->expiretime);
   1036 	isc_time_settoepoch(&zone->refreshtime);
   1037 	isc_time_settoepoch(&zone->dumptime);
   1038 	isc_time_settoepoch(&zone->loadtime);
   1039 	zone->notifytime = now;
   1040 	isc_time_settoepoch(&zone->resigntime);
   1041 	isc_time_settoepoch(&zone->keywarntime);
   1042 	isc_time_settoepoch(&zone->signingtime);
   1043 	isc_time_settoepoch(&zone->nsec3chaintime);
   1044 	isc_time_settoepoch(&zone->refreshkeytime);
   1045 	zone->refreshkeyinterval = 0;
   1046 	zone->refreshkeycount = 0;
   1047 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   1048 	zone->retry = DNS_ZONE_DEFAULTRETRY;
   1049 	zone->expire = 0;
   1050 	zone->minimum = 0;
   1051 	zone->maxrefresh = DNS_ZONE_MAXREFRESH;
   1052 	zone->minrefresh = DNS_ZONE_MINREFRESH;
   1053 	zone->maxretry = DNS_ZONE_MAXRETRY;
   1054 	zone->minretry = DNS_ZONE_MINRETRY;
   1055 	zone->masters = NULL;
   1056 	zone->masterdscps = NULL;
   1057 	zone->masterkeynames = NULL;
   1058 	zone->mastersok = NULL;
   1059 	zone->masterscnt = 0;
   1060 	zone->curmaster = 0;
   1061 	zone->maxttl = 0;
   1062 	zone->notify = NULL;
   1063 	zone->notifykeynames = NULL;
   1064 	zone->notifydscp = NULL;
   1065 	zone->notifytype = dns_notifytype_yes;
   1066 	zone->notifycnt = 0;
   1067 	zone->task = NULL;
   1068 	zone->loadtask = NULL;
   1069 	zone->update_acl = NULL;
   1070 	zone->forward_acl = NULL;
   1071 	zone->notify_acl = NULL;
   1072 	zone->query_acl = NULL;
   1073 	zone->queryon_acl = NULL;
   1074 	zone->xfr_acl = NULL;
   1075 	zone->update_disabled = false;
   1076 	zone->zero_no_soa_ttl = true;
   1077 	zone->check_names = dns_severity_ignore;
   1078 	zone->request = NULL;
   1079 	zone->lctx = NULL;
   1080 	zone->readio = NULL;
   1081 	zone->dctx = NULL;
   1082 	zone->writeio = NULL;
   1083 	zone->timer = NULL;
   1084 	zone->idlein = DNS_DEFAULT_IDLEIN;
   1085 	zone->idleout = DNS_DEFAULT_IDLEOUT;
   1086 	zone->log_key_expired_timer = 0;
   1087 	ISC_LIST_INIT(zone->notifies);
   1088 	isc_sockaddr_any(&zone->notifysrc4);
   1089 	isc_sockaddr_any6(&zone->notifysrc6);
   1090 	isc_sockaddr_any(&zone->xfrsource4);
   1091 	isc_sockaddr_any6(&zone->xfrsource6);
   1092 	isc_sockaddr_any(&zone->altxfrsource4);
   1093 	isc_sockaddr_any6(&zone->altxfrsource6);
   1094 	zone->notifysrc4dscp = -1;
   1095 	zone->notifysrc6dscp = -1;
   1096 	zone->xfrsource4dscp = -1;
   1097 	zone->xfrsource6dscp = -1;
   1098 	zone->altxfrsource4dscp = -1;
   1099 	zone->altxfrsource6dscp = -1;
   1100 	zone->xfr = NULL;
   1101 	zone->tsigkey = NULL;
   1102 	zone->maxxfrin = MAX_XFER_TIME;
   1103 	zone->maxxfrout = MAX_XFER_TIME;
   1104 	zone->ssutable = NULL;
   1105 	zone->sigvalidityinterval = 30 * 24 * 3600;
   1106 	zone->keyvalidityinterval = 0;
   1107 	zone->sigresigninginterval = 7 * 24 * 3600;
   1108 	zone->kasp = NULL;
   1109 	zone->view = NULL;
   1110 	zone->prev_view = NULL;
   1111 	zone->checkmx = NULL;
   1112 	zone->checksrv = NULL;
   1113 	zone->checkns = NULL;
   1114 	ISC_LINK_INIT(zone, statelink);
   1115 	zone->statelist = NULL;
   1116 	zone->stats = NULL;
   1117 	zone->requeststats_on = false;
   1118 	zone->statlevel = dns_zonestat_none;
   1119 	zone->requeststats = NULL;
   1120 	zone->rcvquerystats = NULL;
   1121 	zone->dnssecsignstats = NULL;
   1122 	zone->notifydelay = 5;
   1123 	zone->isself = NULL;
   1124 	zone->isselfarg = NULL;
   1125 	ISC_LIST_INIT(zone->signing);
   1126 	ISC_LIST_INIT(zone->nsec3chain);
   1127 	ISC_LIST_INIT(zone->setnsec3param_queue);
   1128 	zone->signatures = 10;
   1129 	zone->nodes = 100;
   1130 	zone->privatetype = (dns_rdatatype_t)0xffffU;
   1131 	zone->added = false;
   1132 	zone->automatic = false;
   1133 	zone->rpzs = NULL;
   1134 	zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1135 
   1136 	zone->catzs = NULL;
   1137 	zone->parentcatz = NULL;
   1138 
   1139 	ISC_LIST_INIT(zone->forwards);
   1140 	zone->raw = NULL;
   1141 	zone->secure = NULL;
   1142 	zone->sourceserial = 0;
   1143 	zone->sourceserialset = false;
   1144 	zone->requestixfr = true;
   1145 	zone->ixfr_ratio = 100;
   1146 	zone->requestexpire = true;
   1147 	ISC_LIST_INIT(zone->rss_events);
   1148 	ISC_LIST_INIT(zone->rss_post);
   1149 	zone->rss_db = NULL;
   1150 	zone->rss_raw = NULL;
   1151 	zone->rss_newver = NULL;
   1152 	zone->rss_oldver = NULL;
   1153 	zone->rss_event = NULL;
   1154 	zone->rss_state = NULL;
   1155 	zone->updatemethod = dns_updatemethod_increment;
   1156 	zone->maxrecords = 0U;
   1157 
   1158 	zone->magic = ZONE_MAGIC;
   1159 
   1160 	zone->gluecachestats = NULL;
   1161 	result = isc_stats_create(mctx, &zone->gluecachestats,
   1162 				  dns_gluecachestatscounter_max);
   1163 	if (result != ISC_R_SUCCESS) {
   1164 		goto free_refs;
   1165 	}
   1166 
   1167 	/* Must be after magic is set. */
   1168 	dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
   1169 
   1170 	ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
   1171 		       DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone, NULL,
   1172 		       NULL);
   1173 	*zonep = zone;
   1174 	return (ISC_R_SUCCESS);
   1175 
   1176 free_refs:
   1177 	isc_refcount_decrement0(&zone->erefs);
   1178 	isc_refcount_destroy(&zone->erefs);
   1179 	isc_refcount_destroy(&zone->irefs);
   1180 
   1181 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1182 
   1183 free_mutex:
   1184 	isc_mutex_destroy(&zone->lock);
   1185 
   1186 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1187 	return (result);
   1188 }
   1189 
   1190 /*
   1191  * Free a zone.  Because we require that there be no more
   1192  * outstanding events or references, no locking is necessary.
   1193  */
   1194 static void
   1195 zone_free(dns_zone_t *zone) {
   1196 	dns_signing_t *signing;
   1197 	dns_nsec3chain_t *nsec3chain;
   1198 	isc_event_t *event;
   1199 	dns_include_t *include;
   1200 
   1201 	REQUIRE(DNS_ZONE_VALID(zone));
   1202 	isc_refcount_destroy(&zone->erefs);
   1203 	isc_refcount_destroy(&zone->irefs);
   1204 	REQUIRE(!LOCKED_ZONE(zone));
   1205 	REQUIRE(zone->timer == NULL);
   1206 	REQUIRE(zone->zmgr == NULL);
   1207 
   1208 	/*
   1209 	 * Managed objects.  Order is important.
   1210 	 */
   1211 	if (zone->request != NULL) {
   1212 		dns_request_destroy(&zone->request); /* XXXMPA */
   1213 	}
   1214 	INSIST(zone->readio == NULL);
   1215 	INSIST(zone->statelist == NULL);
   1216 	INSIST(zone->writeio == NULL);
   1217 
   1218 	if (zone->task != NULL) {
   1219 		isc_task_detach(&zone->task);
   1220 	}
   1221 	if (zone->loadtask != NULL) {
   1222 		isc_task_detach(&zone->loadtask);
   1223 	}
   1224 	if (zone->view != NULL) {
   1225 		dns_view_weakdetach(&zone->view);
   1226 	}
   1227 	if (zone->prev_view != NULL) {
   1228 		dns_view_weakdetach(&zone->prev_view);
   1229 	}
   1230 
   1231 	/* Unmanaged objects */
   1232 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   1233 		event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   1234 		ISC_LIST_UNLINK(zone->setnsec3param_queue, event, ev_link);
   1235 		isc_event_free(&event);
   1236 	}
   1237 	while (!ISC_LIST_EMPTY(zone->rss_post)) {
   1238 		event = ISC_LIST_HEAD(zone->rss_post);
   1239 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   1240 		isc_event_free(&event);
   1241 	}
   1242 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   1243 	     signing = ISC_LIST_HEAD(zone->signing))
   1244 	{
   1245 		ISC_LIST_UNLINK(zone->signing, signing, link);
   1246 		dns_db_detach(&signing->db);
   1247 		dns_dbiterator_destroy(&signing->dbiterator);
   1248 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   1249 	}
   1250 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   1251 	     nsec3chain = ISC_LIST_HEAD(zone->nsec3chain))
   1252 	{
   1253 		ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   1254 		dns_db_detach(&nsec3chain->db);
   1255 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   1256 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   1257 	}
   1258 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   1259 	     include = ISC_LIST_HEAD(zone->includes))
   1260 	{
   1261 		ISC_LIST_UNLINK(zone->includes, include, link);
   1262 		isc_mem_free(zone->mctx, include->name);
   1263 		isc_mem_put(zone->mctx, include, sizeof *include);
   1264 	}
   1265 	for (include = ISC_LIST_HEAD(zone->newincludes); include != NULL;
   1266 	     include = ISC_LIST_HEAD(zone->newincludes))
   1267 	{
   1268 		ISC_LIST_UNLINK(zone->newincludes, include, link);
   1269 		isc_mem_free(zone->mctx, include->name);
   1270 		isc_mem_put(zone->mctx, include, sizeof *include);
   1271 	}
   1272 	if (zone->masterfile != NULL) {
   1273 		isc_mem_free(zone->mctx, zone->masterfile);
   1274 	}
   1275 	zone->masterfile = NULL;
   1276 	if (zone->keydirectory != NULL) {
   1277 		isc_mem_free(zone->mctx, zone->keydirectory);
   1278 	}
   1279 	zone->keydirectory = NULL;
   1280 	if (zone->kasp != NULL) {
   1281 		dns_kasp_detach(&zone->kasp);
   1282 	}
   1283 	zone->journalsize = -1;
   1284 	if (zone->journal != NULL) {
   1285 		isc_mem_free(zone->mctx, zone->journal);
   1286 	}
   1287 	zone->journal = NULL;
   1288 	if (zone->stats != NULL) {
   1289 		isc_stats_detach(&zone->stats);
   1290 	}
   1291 	if (zone->requeststats != NULL) {
   1292 		isc_stats_detach(&zone->requeststats);
   1293 	}
   1294 	if (zone->rcvquerystats != NULL) {
   1295 		dns_stats_detach(&zone->rcvquerystats);
   1296 	}
   1297 	if (zone->dnssecsignstats != NULL) {
   1298 		dns_stats_detach(&zone->dnssecsignstats);
   1299 	}
   1300 	if (zone->db != NULL) {
   1301 		zone_detachdb(zone);
   1302 	}
   1303 	if (zone->rpzs != NULL) {
   1304 		REQUIRE(zone->rpz_num < zone->rpzs->p.num_zones);
   1305 		dns_rpz_detach_rpzs(&zone->rpzs);
   1306 		zone->rpz_num = DNS_RPZ_INVALID_NUM;
   1307 	}
   1308 	if (zone->catzs != NULL) {
   1309 		dns_catz_catzs_detach(&zone->catzs);
   1310 	}
   1311 	zone_freedbargs(zone);
   1312 	RUNTIME_CHECK(dns_zone_setprimarieswithkeys(zone, NULL, NULL, 0) ==
   1313 		      ISC_R_SUCCESS);
   1314 	RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0) == ISC_R_SUCCESS);
   1315 	zone->check_names = dns_severity_ignore;
   1316 	if (zone->update_acl != NULL) {
   1317 		dns_acl_detach(&zone->update_acl);
   1318 	}
   1319 	if (zone->forward_acl != NULL) {
   1320 		dns_acl_detach(&zone->forward_acl);
   1321 	}
   1322 	if (zone->notify_acl != NULL) {
   1323 		dns_acl_detach(&zone->notify_acl);
   1324 	}
   1325 	if (zone->query_acl != NULL) {
   1326 		dns_acl_detach(&zone->query_acl);
   1327 	}
   1328 	if (zone->queryon_acl != NULL) {
   1329 		dns_acl_detach(&zone->queryon_acl);
   1330 	}
   1331 	if (zone->xfr_acl != NULL) {
   1332 		dns_acl_detach(&zone->xfr_acl);
   1333 	}
   1334 	if (dns_name_dynamic(&zone->origin)) {
   1335 		dns_name_free(&zone->origin, zone->mctx);
   1336 	}
   1337 	if (zone->strnamerd != NULL) {
   1338 		isc_mem_free(zone->mctx, zone->strnamerd);
   1339 	}
   1340 	if (zone->strname != NULL) {
   1341 		isc_mem_free(zone->mctx, zone->strname);
   1342 	}
   1343 	if (zone->strrdclass != NULL) {
   1344 		isc_mem_free(zone->mctx, zone->strrdclass);
   1345 	}
   1346 	if (zone->strviewname != NULL) {
   1347 		isc_mem_free(zone->mctx, zone->strviewname);
   1348 	}
   1349 	if (zone->ssutable != NULL) {
   1350 		dns_ssutable_detach(&zone->ssutable);
   1351 	}
   1352 	if (zone->gluecachestats != NULL) {
   1353 		isc_stats_detach(&zone->gluecachestats);
   1354 	}
   1355 
   1356 	/* last stuff */
   1357 	ZONEDB_DESTROYLOCK(&zone->dblock);
   1358 	isc_mutex_destroy(&zone->lock);
   1359 	zone->magic = 0;
   1360 	isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
   1361 }
   1362 
   1363 /*
   1364  * Returns true iff this the signed side of an inline-signing zone.
   1365  * Caller should hold zone lock.
   1366  */
   1367 static inline bool
   1368 inline_secure(dns_zone_t *zone) {
   1369 	REQUIRE(DNS_ZONE_VALID(zone));
   1370 	if (zone->raw != NULL) {
   1371 		return (true);
   1372 	}
   1373 	return (false);
   1374 }
   1375 
   1376 /*
   1377  * Returns true iff this the unsigned side of an inline-signing zone
   1378  * Caller should hold zone lock.
   1379  */
   1380 static inline bool
   1381 inline_raw(dns_zone_t *zone) {
   1382 	REQUIRE(DNS_ZONE_VALID(zone));
   1383 	if (zone->secure != NULL) {
   1384 		return (true);
   1385 	}
   1386 	return (false);
   1387 }
   1388 
   1389 /*
   1390  *	Single shot.
   1391  */
   1392 void
   1393 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
   1394 	char namebuf[1024];
   1395 
   1396 	REQUIRE(DNS_ZONE_VALID(zone));
   1397 	REQUIRE(rdclass != dns_rdataclass_none);
   1398 
   1399 	/*
   1400 	 * Test and set.
   1401 	 */
   1402 	LOCK_ZONE(zone);
   1403 	INSIST(zone != zone->raw);
   1404 	REQUIRE(zone->rdclass == dns_rdataclass_none ||
   1405 		zone->rdclass == rdclass);
   1406 	zone->rdclass = rdclass;
   1407 
   1408 	if (zone->strnamerd != NULL) {
   1409 		isc_mem_free(zone->mctx, zone->strnamerd);
   1410 	}
   1411 	if (zone->strrdclass != NULL) {
   1412 		isc_mem_free(zone->mctx, zone->strrdclass);
   1413 	}
   1414 
   1415 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1416 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1417 	zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
   1418 	zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
   1419 
   1420 	if (inline_secure(zone)) {
   1421 		dns_zone_setclass(zone->raw, rdclass);
   1422 	}
   1423 	UNLOCK_ZONE(zone);
   1424 }
   1425 
   1426 dns_rdataclass_t
   1427 dns_zone_getclass(dns_zone_t *zone) {
   1428 	REQUIRE(DNS_ZONE_VALID(zone));
   1429 
   1430 	return (zone->rdclass);
   1431 }
   1432 
   1433 void
   1434 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
   1435 	REQUIRE(DNS_ZONE_VALID(zone));
   1436 
   1437 	LOCK_ZONE(zone);
   1438 	zone->notifytype = notifytype;
   1439 	UNLOCK_ZONE(zone);
   1440 }
   1441 
   1442 isc_result_t
   1443 dns_zone_getserial(dns_zone_t *zone, uint32_t *serialp) {
   1444 	isc_result_t result;
   1445 	unsigned int soacount;
   1446 
   1447 	REQUIRE(DNS_ZONE_VALID(zone));
   1448 	REQUIRE(serialp != NULL);
   1449 
   1450 	LOCK_ZONE(zone);
   1451 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   1452 	if (zone->db != NULL) {
   1453 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
   1454 					  serialp, NULL, NULL, NULL, NULL,
   1455 					  NULL);
   1456 		if (result == ISC_R_SUCCESS && soacount == 0) {
   1457 			result = ISC_R_FAILURE;
   1458 		}
   1459 	} else {
   1460 		result = DNS_R_NOTLOADED;
   1461 	}
   1462 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   1463 	UNLOCK_ZONE(zone);
   1464 
   1465 	return (result);
   1466 }
   1467 
   1468 /*
   1469  *	Single shot.
   1470  */
   1471 void
   1472 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
   1473 	char namebuf[1024];
   1474 
   1475 	REQUIRE(DNS_ZONE_VALID(zone));
   1476 	REQUIRE(type != dns_zone_none);
   1477 
   1478 	/*
   1479 	 * Test and set.
   1480 	 */
   1481 	LOCK_ZONE(zone);
   1482 	REQUIRE(zone->type == dns_zone_none || zone->type == type);
   1483 	zone->type = type;
   1484 
   1485 	if (zone->strnamerd != NULL) {
   1486 		isc_mem_free(zone->mctx, zone->strnamerd);
   1487 	}
   1488 
   1489 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1490 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1491 	UNLOCK_ZONE(zone);
   1492 }
   1493 
   1494 static void
   1495 zone_freedbargs(dns_zone_t *zone) {
   1496 	unsigned int i;
   1497 
   1498 	/* Free the old database argument list. */
   1499 	if (zone->db_argv != NULL) {
   1500 		for (i = 0; i < zone->db_argc; i++) {
   1501 			isc_mem_free(zone->mctx, zone->db_argv[i]);
   1502 		}
   1503 		isc_mem_put(zone->mctx, zone->db_argv,
   1504 			    zone->db_argc * sizeof(*zone->db_argv));
   1505 	}
   1506 	zone->db_argc = 0;
   1507 	zone->db_argv = NULL;
   1508 }
   1509 
   1510 isc_result_t
   1511 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
   1512 	size_t size = 0;
   1513 	unsigned int i;
   1514 	isc_result_t result = ISC_R_SUCCESS;
   1515 	void *mem;
   1516 	char **tmp, *tmp2, *base;
   1517 
   1518 	REQUIRE(DNS_ZONE_VALID(zone));
   1519 	REQUIRE(argv != NULL && *argv == NULL);
   1520 
   1521 	LOCK_ZONE(zone);
   1522 	size = (zone->db_argc + 1) * sizeof(char *);
   1523 	for (i = 0; i < zone->db_argc; i++) {
   1524 		size += strlen(zone->db_argv[i]) + 1;
   1525 	}
   1526 	mem = isc_mem_allocate(mctx, size);
   1527 	{
   1528 		tmp = mem;
   1529 		tmp2 = mem;
   1530 		base = mem;
   1531 		tmp2 += (zone->db_argc + 1) * sizeof(char *);
   1532 		for (i = 0; i < zone->db_argc; i++) {
   1533 			*tmp++ = tmp2;
   1534 			strlcpy(tmp2, zone->db_argv[i], size - (tmp2 - base));
   1535 			tmp2 += strlen(tmp2) + 1;
   1536 		}
   1537 		*tmp = NULL;
   1538 	}
   1539 	UNLOCK_ZONE(zone);
   1540 	*argv = mem;
   1541 	return (result);
   1542 }
   1543 
   1544 void
   1545 dns_zone_setdbtype(dns_zone_t *zone, unsigned int dbargc,
   1546 		   const char *const *dbargv) {
   1547 	char **argv = NULL;
   1548 	unsigned int i;
   1549 
   1550 	REQUIRE(DNS_ZONE_VALID(zone));
   1551 	REQUIRE(dbargc >= 1);
   1552 	REQUIRE(dbargv != NULL);
   1553 
   1554 	LOCK_ZONE(zone);
   1555 
   1556 	/* Set up a new database argument list. */
   1557 	argv = isc_mem_get(zone->mctx, dbargc * sizeof(*argv));
   1558 	for (i = 0; i < dbargc; i++) {
   1559 		argv[i] = NULL;
   1560 	}
   1561 	for (i = 0; i < dbargc; i++) {
   1562 		argv[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
   1563 	}
   1564 
   1565 	/* Free the old list. */
   1566 	zone_freedbargs(zone);
   1567 
   1568 	zone->db_argc = dbargc;
   1569 	zone->db_argv = argv;
   1570 
   1571 	UNLOCK_ZONE(zone);
   1572 }
   1573 
   1574 static void
   1575 dns_zone_setview_helper(dns_zone_t *zone, dns_view_t *view) {
   1576 	char namebuf[1024];
   1577 
   1578 	if (zone->prev_view == NULL && zone->view != NULL) {
   1579 		dns_view_weakattach(zone->view, &zone->prev_view);
   1580 	}
   1581 
   1582 	INSIST(zone != zone->raw);
   1583 	if (zone->view != NULL) {
   1584 		dns_view_weakdetach(&zone->view);
   1585 	}
   1586 	dns_view_weakattach(view, &zone->view);
   1587 
   1588 	if (zone->strviewname != NULL) {
   1589 		isc_mem_free(zone->mctx, zone->strviewname);
   1590 	}
   1591 	if (zone->strnamerd != NULL) {
   1592 		isc_mem_free(zone->mctx, zone->strnamerd);
   1593 	}
   1594 
   1595 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1596 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1597 	zone_viewname_tostr(zone, namebuf, sizeof namebuf);
   1598 	zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
   1599 
   1600 	if (inline_secure(zone)) {
   1601 		dns_zone_setview(zone->raw, view);
   1602 	}
   1603 }
   1604 
   1605 void
   1606 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
   1607 	REQUIRE(DNS_ZONE_VALID(zone));
   1608 
   1609 	LOCK_ZONE(zone);
   1610 	dns_zone_setview_helper(zone, view);
   1611 	UNLOCK_ZONE(zone);
   1612 }
   1613 
   1614 dns_view_t *
   1615 dns_zone_getview(dns_zone_t *zone) {
   1616 	REQUIRE(DNS_ZONE_VALID(zone));
   1617 
   1618 	return (zone->view);
   1619 }
   1620 
   1621 void
   1622 dns_zone_setviewcommit(dns_zone_t *zone) {
   1623 	REQUIRE(DNS_ZONE_VALID(zone));
   1624 
   1625 	LOCK_ZONE(zone);
   1626 	if (zone->prev_view != NULL) {
   1627 		dns_view_weakdetach(&zone->prev_view);
   1628 	}
   1629 	UNLOCK_ZONE(zone);
   1630 }
   1631 
   1632 void
   1633 dns_zone_setviewrevert(dns_zone_t *zone) {
   1634 	REQUIRE(DNS_ZONE_VALID(zone));
   1635 
   1636 	LOCK_ZONE(zone);
   1637 	if (zone->prev_view != NULL) {
   1638 		dns_zone_setview_helper(zone, zone->prev_view);
   1639 		dns_view_weakdetach(&zone->prev_view);
   1640 	}
   1641 	UNLOCK_ZONE(zone);
   1642 }
   1643 
   1644 isc_result_t
   1645 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
   1646 	isc_result_t result = ISC_R_SUCCESS;
   1647 	char namebuf[1024];
   1648 
   1649 	REQUIRE(DNS_ZONE_VALID(zone));
   1650 	REQUIRE(origin != NULL);
   1651 
   1652 	LOCK_ZONE(zone);
   1653 	INSIST(zone != zone->raw);
   1654 	if (dns_name_dynamic(&zone->origin)) {
   1655 		dns_name_free(&zone->origin, zone->mctx);
   1656 		dns_name_init(&zone->origin, NULL);
   1657 	}
   1658 	dns_name_dup(origin, zone->mctx, &zone->origin);
   1659 
   1660 	if (zone->strnamerd != NULL) {
   1661 		isc_mem_free(zone->mctx, zone->strnamerd);
   1662 	}
   1663 	if (zone->strname != NULL) {
   1664 		isc_mem_free(zone->mctx, zone->strname);
   1665 	}
   1666 
   1667 	zone_namerd_tostr(zone, namebuf, sizeof namebuf);
   1668 	zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
   1669 	zone_name_tostr(zone, namebuf, sizeof namebuf);
   1670 	zone->strname = isc_mem_strdup(zone->mctx, namebuf);
   1671 
   1672 	if (inline_secure(zone)) {
   1673 		result = dns_zone_setorigin(zone->raw, origin);
   1674 	}
   1675 	UNLOCK_ZONE(zone);
   1676 	return (result);
   1677 }
   1678 
   1679 static isc_result_t
   1680 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
   1681 	char *copy;
   1682 
   1683 	if (value != NULL) {
   1684 		copy = isc_mem_strdup(zone->mctx, value);
   1685 	} else {
   1686 		copy = NULL;
   1687 	}
   1688 
   1689 	if (*field != NULL) {
   1690 		isc_mem_free(zone->mctx, *field);
   1691 	}
   1692 
   1693 	*field = copy;
   1694 	return (ISC_R_SUCCESS);
   1695 }
   1696 
   1697 isc_result_t
   1698 dns_zone_setfile(dns_zone_t *zone, const char *file, dns_masterformat_t format,
   1699 		 const dns_master_style_t *style) {
   1700 	isc_result_t result = ISC_R_SUCCESS;
   1701 
   1702 	REQUIRE(DNS_ZONE_VALID(zone));
   1703 
   1704 	LOCK_ZONE(zone);
   1705 	result = dns_zone_setstring(zone, &zone->masterfile, file);
   1706 	if (result == ISC_R_SUCCESS) {
   1707 		zone->masterformat = format;
   1708 		if (format == dns_masterformat_text) {
   1709 			zone->masterstyle = style;
   1710 		}
   1711 		result = default_journal(zone);
   1712 	}
   1713 	UNLOCK_ZONE(zone);
   1714 
   1715 	return (result);
   1716 }
   1717 
   1718 const char *
   1719 dns_zone_getfile(dns_zone_t *zone) {
   1720 	REQUIRE(DNS_ZONE_VALID(zone));
   1721 
   1722 	return (zone->masterfile);
   1723 }
   1724 
   1725 dns_ttl_t
   1726 dns_zone_getmaxttl(dns_zone_t *zone) {
   1727 	REQUIRE(DNS_ZONE_VALID(zone));
   1728 
   1729 	return (zone->maxttl);
   1730 }
   1731 
   1732 void
   1733 dns_zone_setmaxttl(dns_zone_t *zone, dns_ttl_t maxttl) {
   1734 	REQUIRE(DNS_ZONE_VALID(zone));
   1735 
   1736 	LOCK_ZONE(zone);
   1737 	if (maxttl != 0) {
   1738 		DNS_ZONE_SETOPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1739 	} else {
   1740 		DNS_ZONE_CLROPTION(zone, DNS_ZONEOPT_CHECKTTL);
   1741 	}
   1742 	zone->maxttl = maxttl;
   1743 	UNLOCK_ZONE(zone);
   1744 
   1745 	return;
   1746 }
   1747 
   1748 static isc_result_t
   1749 default_journal(dns_zone_t *zone) {
   1750 	isc_result_t result;
   1751 	char *journal;
   1752 
   1753 	REQUIRE(DNS_ZONE_VALID(zone));
   1754 	REQUIRE(LOCKED_ZONE(zone));
   1755 
   1756 	if (zone->masterfile != NULL) {
   1757 		/* Calculate string length including '\0'. */
   1758 		int len = strlen(zone->masterfile) + sizeof(".jnl");
   1759 		journal = isc_mem_allocate(zone->mctx, len);
   1760 		strlcpy(journal, zone->masterfile, len);
   1761 		strlcat(journal, ".jnl", len);
   1762 	} else {
   1763 		journal = NULL;
   1764 	}
   1765 	result = dns_zone_setstring(zone, &zone->journal, journal);
   1766 	if (journal != NULL) {
   1767 		isc_mem_free(zone->mctx, journal);
   1768 	}
   1769 	return (result);
   1770 }
   1771 
   1772 isc_result_t
   1773 dns_zone_setjournal(dns_zone_t *zone, const char *myjournal) {
   1774 	isc_result_t result = ISC_R_SUCCESS;
   1775 
   1776 	REQUIRE(DNS_ZONE_VALID(zone));
   1777 
   1778 	LOCK_ZONE(zone);
   1779 	result = dns_zone_setstring(zone, &zone->journal, myjournal);
   1780 	UNLOCK_ZONE(zone);
   1781 
   1782 	return (result);
   1783 }
   1784 
   1785 char *
   1786 dns_zone_getjournal(dns_zone_t *zone) {
   1787 	REQUIRE(DNS_ZONE_VALID(zone));
   1788 
   1789 	return (zone->journal);
   1790 }
   1791 
   1792 /*
   1793  * Return true iff the zone is "dynamic", in the sense that the zone's
   1794  * master file (if any) is written by the server, rather than being
   1795  * updated manually and read by the server.
   1796  *
   1797  * This is true for slave zones, mirror zones, stub zones, key zones,
   1798  * and zones that allow dynamic updates either by having an update
   1799  * policy ("ssutable") or an "allow-update" ACL with a value other than
   1800  * exactly "{ none; }".
   1801  */
   1802 bool
   1803 dns_zone_isdynamic(dns_zone_t *zone, bool ignore_freeze) {
   1804 	REQUIRE(DNS_ZONE_VALID(zone));
   1805 
   1806 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   1807 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   1808 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   1809 	{
   1810 		return (true);
   1811 	}
   1812 
   1813 	/* Inline zones are always dynamic. */
   1814 	if (zone->type == dns_zone_master && zone->raw != NULL) {
   1815 		return (true);
   1816 	}
   1817 
   1818 	/* Kasp zones are always dynamic. */
   1819 	if (dns_zone_use_kasp(zone)) {
   1820 		return (true);
   1821 	}
   1822 
   1823 	/* If !ignore_freeze, we need check whether updates are disabled.  */
   1824 	if (zone->type == dns_zone_master &&
   1825 	    (!zone->update_disabled || ignore_freeze) &&
   1826 	    ((zone->ssutable != NULL) ||
   1827 	     (zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl))))
   1828 	{
   1829 		return (true);
   1830 	}
   1831 
   1832 	return (false);
   1833 }
   1834 
   1835 /*
   1836  * Set the response policy index and information for a zone.
   1837  */
   1838 isc_result_t
   1839 dns_zone_rpz_enable(dns_zone_t *zone, dns_rpz_zones_t *rpzs,
   1840 		    dns_rpz_num_t rpz_num) {
   1841 	/*
   1842 	 * Only RBTDB zones can be used for response policy zones,
   1843 	 * because only they have the code to create the summary data.
   1844 	 * Only zones that are loaded instead of mmap()ed create the
   1845 	 * summary data and so can be policy zones.
   1846 	 */
   1847 	if (strcmp(zone->db_argv[0], "rbt") != 0 &&
   1848 	    strcmp(zone->db_argv[0], "rbt64") != 0)
   1849 	{
   1850 		return (ISC_R_NOTIMPLEMENTED);
   1851 	}
   1852 	if (zone->masterformat == dns_masterformat_map) {
   1853 		return (ISC_R_NOTIMPLEMENTED);
   1854 	}
   1855 
   1856 	/*
   1857 	 * This must happen only once or be redundant.
   1858 	 */
   1859 	LOCK_ZONE(zone);
   1860 	if (zone->rpzs != NULL) {
   1861 		REQUIRE(zone->rpzs == rpzs && zone->rpz_num == rpz_num);
   1862 	} else {
   1863 		REQUIRE(zone->rpz_num == DNS_RPZ_INVALID_NUM);
   1864 		dns_rpz_attach_rpzs(rpzs, &zone->rpzs);
   1865 		zone->rpz_num = rpz_num;
   1866 	}
   1867 	rpzs->defined |= DNS_RPZ_ZBIT(rpz_num);
   1868 	UNLOCK_ZONE(zone);
   1869 
   1870 	return (ISC_R_SUCCESS);
   1871 }
   1872 
   1873 dns_rpz_num_t
   1874 dns_zone_get_rpz_num(dns_zone_t *zone) {
   1875 	return (zone->rpz_num);
   1876 }
   1877 
   1878 /*
   1879  * If a zone is a response policy zone, mark its new database.
   1880  */
   1881 void
   1882 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1883 	isc_result_t result;
   1884 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1885 		return;
   1886 	}
   1887 	REQUIRE(zone->rpzs != NULL);
   1888 	result = dns_db_updatenotify_register(db, dns_rpz_dbupdate_callback,
   1889 					      zone->rpzs->zones[zone->rpz_num]);
   1890 	REQUIRE(result == ISC_R_SUCCESS);
   1891 }
   1892 
   1893 static void
   1894 dns_zone_rpz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1895 	if (zone->rpz_num == DNS_RPZ_INVALID_NUM) {
   1896 		return;
   1897 	}
   1898 	REQUIRE(zone->rpzs != NULL);
   1899 	(void)dns_db_updatenotify_unregister(db, dns_rpz_dbupdate_callback,
   1900 					     zone->rpzs->zones[zone->rpz_num]);
   1901 }
   1902 
   1903 void
   1904 dns_zone_catz_enable(dns_zone_t *zone, dns_catz_zones_t *catzs) {
   1905 	REQUIRE(DNS_ZONE_VALID(zone));
   1906 	REQUIRE(catzs != NULL);
   1907 
   1908 	LOCK_ZONE(zone);
   1909 	INSIST(zone->catzs == NULL || zone->catzs == catzs);
   1910 	dns_catz_catzs_set_view(catzs, zone->view);
   1911 	if (zone->catzs == NULL) {
   1912 		dns_catz_catzs_attach(catzs, &zone->catzs);
   1913 	}
   1914 	UNLOCK_ZONE(zone);
   1915 }
   1916 
   1917 /*
   1918  * If a zone is a catalog zone, attach it to update notification in database.
   1919  */
   1920 void
   1921 dns_zone_catz_enable_db(dns_zone_t *zone, dns_db_t *db) {
   1922 	REQUIRE(DNS_ZONE_VALID(zone));
   1923 	REQUIRE(db != NULL);
   1924 
   1925 	if (zone->catzs != NULL) {
   1926 		dns_db_updatenotify_register(db, dns_catz_dbupdate_callback,
   1927 					     zone->catzs);
   1928 	}
   1929 }
   1930 
   1931 static void
   1932 dns_zone_catz_disable_db(dns_zone_t *zone, dns_db_t *db) {
   1933 	REQUIRE(DNS_ZONE_VALID(zone));
   1934 	REQUIRE(db != NULL);
   1935 
   1936 	if (zone->catzs != NULL) {
   1937 		dns_db_updatenotify_unregister(db, dns_catz_dbupdate_callback,
   1938 					       zone->catzs);
   1939 	}
   1940 }
   1941 
   1942 /*
   1943  * Set catalog zone ownership of the zone
   1944  */
   1945 void
   1946 dns_zone_set_parentcatz(dns_zone_t *zone, dns_catz_zone_t *catz) {
   1947 	REQUIRE(DNS_ZONE_VALID(zone));
   1948 	REQUIRE(catz != NULL);
   1949 	LOCK_ZONE(zone);
   1950 	INSIST(zone->parentcatz == NULL || zone->parentcatz == catz);
   1951 	zone->parentcatz = catz;
   1952 	UNLOCK_ZONE(zone);
   1953 }
   1954 
   1955 dns_catz_zone_t *
   1956 dns_zone_get_parentcatz(const dns_zone_t *zone) {
   1957 	REQUIRE(DNS_ZONE_VALID(zone));
   1958 	return (zone->parentcatz);
   1959 }
   1960 
   1961 static bool
   1962 zone_touched(dns_zone_t *zone) {
   1963 	isc_result_t result;
   1964 	isc_time_t modtime;
   1965 	dns_include_t *include;
   1966 
   1967 	REQUIRE(DNS_ZONE_VALID(zone));
   1968 
   1969 	result = isc_file_getmodtime(zone->masterfile, &modtime);
   1970 	if (result != ISC_R_SUCCESS ||
   1971 	    isc_time_compare(&modtime, &zone->loadtime) > 0) {
   1972 		return (true);
   1973 	}
   1974 
   1975 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   1976 	     include = ISC_LIST_NEXT(include, link))
   1977 	{
   1978 		result = isc_file_getmodtime(include->name, &modtime);
   1979 		if (result != ISC_R_SUCCESS ||
   1980 		    isc_time_compare(&modtime, &include->filetime) > 0)
   1981 		{
   1982 			return (true);
   1983 		}
   1984 	}
   1985 
   1986 	return (false);
   1987 }
   1988 
   1989 /*
   1990  * Note: when dealing with inline-signed zones, external callers will always
   1991  * call zone_load() for the secure zone; zone_load() calls itself recursively
   1992  * in order to load the raw zone.
   1993  */
   1994 static isc_result_t
   1995 zone_load(dns_zone_t *zone, unsigned int flags, bool locked) {
   1996 	isc_result_t result;
   1997 	isc_time_t now;
   1998 	isc_time_t loadtime;
   1999 	dns_db_t *db = NULL;
   2000 	bool rbt, hasraw, is_dynamic;
   2001 
   2002 	REQUIRE(DNS_ZONE_VALID(zone));
   2003 
   2004 	if (!locked) {
   2005 		LOCK_ZONE(zone);
   2006 	}
   2007 
   2008 	INSIST(zone != zone->raw);
   2009 	hasraw = inline_secure(zone);
   2010 	if (hasraw) {
   2011 		/*
   2012 		 * We are trying to load an inline-signed zone.  First call
   2013 		 * self recursively to try loading the raw version of the zone.
   2014 		 * Assuming the raw zone file is readable, there are two
   2015 		 * possibilities:
   2016 		 *
   2017 		 *  a) the raw zone was not yet loaded and thus it will be
   2018 		 *     loaded now, synchronously; if this succeeds, a
   2019 		 *     subsequent attempt to load the signed zone file will
   2020 		 *     take place and thus zone_postload() will be called
   2021 		 *     twice: first for the raw zone and then for the secure
   2022 		 *     zone; the latter call will take care of syncing the raw
   2023 		 *     version with the secure version,
   2024 		 *
   2025 		 *  b) the raw zone was already loaded and we are trying to
   2026 		 *     reload it, which will happen asynchronously; this means
   2027 		 *     zone_postload() will only be called for the raw zone
   2028 		 *     because "result" returned by the zone_load() call below
   2029 		 *     will not be ISC_R_SUCCESS but rather DNS_R_CONTINUE;
   2030 		 *     zone_postload() called for the raw zone will take care
   2031 		 *     of syncing the raw version with the secure version.
   2032 		 */
   2033 		result = zone_load(zone->raw, flags, false);
   2034 		if (result != ISC_R_SUCCESS) {
   2035 			if (!locked) {
   2036 				UNLOCK_ZONE(zone);
   2037 			}
   2038 			return (result);
   2039 		}
   2040 		LOCK_ZONE(zone->raw);
   2041 	}
   2042 
   2043 	TIME_NOW(&now);
   2044 
   2045 	INSIST(zone->type != dns_zone_none);
   2046 
   2047 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
   2048 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2049 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2050 		}
   2051 		result = DNS_R_CONTINUE;
   2052 		goto cleanup;
   2053 	}
   2054 
   2055 	INSIST(zone->db_argc >= 1);
   2056 
   2057 	rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
   2058 	      strcmp(zone->db_argv[0], "rbt64") == 0;
   2059 
   2060 	if (zone->db != NULL && zone->masterfile == NULL && rbt) {
   2061 		/*
   2062 		 * The zone has no master file configured.
   2063 		 */
   2064 		result = ISC_R_SUCCESS;
   2065 		goto cleanup;
   2066 	}
   2067 
   2068 	is_dynamic = dns_zone_isdynamic(zone, false);
   2069 	if (zone->db != NULL && is_dynamic) {
   2070 		/*
   2071 		 * This is a slave, stub, dynamically updated, or kasp enabled
   2072 		 * zone being reloaded.  Do nothing - the database we already
   2073 		 * have is guaranteed to be up-to-date.
   2074 		 */
   2075 		if (zone->type == dns_zone_master && !hasraw) {
   2076 			result = DNS_R_DYNAMIC;
   2077 		} else {
   2078 			result = ISC_R_SUCCESS;
   2079 		}
   2080 		goto cleanup;
   2081 	}
   2082 
   2083 	/*
   2084 	 * Store the current time before the zone is loaded, so that if the
   2085 	 * file changes between the time of the load and the time that
   2086 	 * zone->loadtime is set, then the file will still be reloaded
   2087 	 * the next time dns_zone_load is called.
   2088 	 */
   2089 	TIME_NOW(&loadtime);
   2090 
   2091 	/*
   2092 	 * Don't do the load if the file that stores the zone is older
   2093 	 * than the last time the zone was loaded.  If the zone has not
   2094 	 * been loaded yet, zone->loadtime will be the epoch.
   2095 	 */
   2096 	if (zone->masterfile != NULL) {
   2097 		isc_time_t filetime;
   2098 
   2099 		/*
   2100 		 * The file is already loaded.	If we are just doing a
   2101 		 * "rndc reconfig", we are done.
   2102 		 */
   2103 		if (!isc_time_isepoch(&zone->loadtime) &&
   2104 		    (flags & DNS_ZONELOADFLAG_NOSTAT) != 0)
   2105 		{
   2106 			result = ISC_R_SUCCESS;
   2107 			goto cleanup;
   2108 		}
   2109 
   2110 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   2111 		    !zone_touched(zone)) {
   2112 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2113 				      ISC_LOG_DEBUG(1),
   2114 				      "skipping load: master file "
   2115 				      "older than last load");
   2116 			result = DNS_R_UPTODATE;
   2117 			goto cleanup;
   2118 		}
   2119 
   2120 		/*
   2121 		 * If the file modification time is in the past
   2122 		 * set loadtime to that value.
   2123 		 */
   2124 		result = isc_file_getmodtime(zone->masterfile, &filetime);
   2125 		if (result == ISC_R_SUCCESS &&
   2126 		    isc_time_compare(&loadtime, &filetime) > 0) {
   2127 			loadtime = filetime;
   2128 		}
   2129 	}
   2130 
   2131 	/*
   2132 	 * Built in zones (with the exception of empty zones) don't need
   2133 	 * to be reloaded.
   2134 	 */
   2135 	if (zone->type == dns_zone_master &&
   2136 	    strcmp(zone->db_argv[0], "_builtin") == 0 &&
   2137 	    (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
   2138 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   2139 	{
   2140 		result = ISC_R_SUCCESS;
   2141 		goto cleanup;
   2142 	}
   2143 
   2144 	/*
   2145 	 * Zones associated with a DLZ don't need to be loaded either,
   2146 	 * but we need to associate the database with the zone object.
   2147 	 */
   2148 	if (strcmp(zone->db_argv[0], "dlz") == 0) {
   2149 		dns_dlzdb_t *dlzdb;
   2150 		dns_dlzfindzone_t findzone;
   2151 
   2152 		for (dlzdb = ISC_LIST_HEAD(zone->view->dlz_unsearched);
   2153 		     dlzdb != NULL; dlzdb = ISC_LIST_NEXT(dlzdb, link))
   2154 		{
   2155 			INSIST(DNS_DLZ_VALID(dlzdb));
   2156 			if (strcmp(zone->db_argv[1], dlzdb->dlzname) == 0) {
   2157 				break;
   2158 			}
   2159 		}
   2160 
   2161 		if (dlzdb == NULL) {
   2162 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2163 				      ISC_LOG_ERROR,
   2164 				      "DLZ %s does not exist or is set "
   2165 				      "to 'search yes;'",
   2166 				      zone->db_argv[1]);
   2167 			result = ISC_R_NOTFOUND;
   2168 			goto cleanup;
   2169 		}
   2170 
   2171 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   2172 		/* ask SDLZ driver if the zone is supported */
   2173 		findzone = dlzdb->implementation->methods->findzone;
   2174 		result = (*findzone)(dlzdb->implementation->driverarg,
   2175 				     dlzdb->dbdata, dlzdb->mctx,
   2176 				     zone->view->rdclass, &zone->origin, NULL,
   2177 				     NULL, &db);
   2178 		if (result != ISC_R_NOTFOUND) {
   2179 			if (zone->db != NULL) {
   2180 				zone_detachdb(zone);
   2181 			}
   2182 			zone_attachdb(zone, db);
   2183 			dns_db_detach(&db);
   2184 			result = ISC_R_SUCCESS;
   2185 		}
   2186 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   2187 
   2188 		if (result == ISC_R_SUCCESS) {
   2189 			if (dlzdb->configure_callback == NULL) {
   2190 				goto cleanup;
   2191 			}
   2192 
   2193 			result = (*dlzdb->configure_callback)(zone->view, dlzdb,
   2194 							      zone);
   2195 			if (result != ISC_R_SUCCESS) {
   2196 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2197 					      ISC_LOG_ERROR,
   2198 					      "DLZ configuration callback: %s",
   2199 					      isc_result_totext(result));
   2200 			}
   2201 		}
   2202 		goto cleanup;
   2203 	}
   2204 
   2205 	if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   2206 	     zone->type == dns_zone_stub ||
   2207 	     (zone->type == dns_zone_redirect && zone->masters != NULL)) &&
   2208 	    rbt)
   2209 	{
   2210 		if (zone->masterfile == NULL ||
   2211 		    !isc_file_exists(zone->masterfile)) {
   2212 			if (zone->masterfile != NULL) {
   2213 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2214 					      ISC_LOG_DEBUG(1),
   2215 					      "no master file");
   2216 			}
   2217 			zone->refreshtime = now;
   2218 			if (zone->task != NULL) {
   2219 				zone_settimer(zone, &now);
   2220 			}
   2221 			result = ISC_R_SUCCESS;
   2222 			goto cleanup;
   2223 		}
   2224 	}
   2225 
   2226 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   2227 		      "starting load");
   2228 
   2229 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   2230 			       (zone->type == dns_zone_stub) ? dns_dbtype_stub
   2231 							     : dns_dbtype_zone,
   2232 			       zone->rdclass, zone->db_argc - 1,
   2233 			       zone->db_argv + 1, &db);
   2234 
   2235 	if (result != ISC_R_SUCCESS) {
   2236 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   2237 			      "loading zone: creating database: %s",
   2238 			      isc_result_totext(result));
   2239 		goto cleanup;
   2240 	}
   2241 	dns_db_settask(db, zone->task);
   2242 
   2243 	if (zone->type == dns_zone_master || zone->type == dns_zone_slave ||
   2244 	    zone->type == dns_zone_mirror)
   2245 	{
   2246 		result = dns_db_setgluecachestats(db, zone->gluecachestats);
   2247 		if (result == ISC_R_NOTIMPLEMENTED) {
   2248 			result = ISC_R_SUCCESS;
   2249 		}
   2250 		if (result != ISC_R_SUCCESS) {
   2251 			goto cleanup;
   2252 		}
   2253 	}
   2254 
   2255 	if (!dns_db_ispersistent(db)) {
   2256 		if (zone->masterfile != NULL) {
   2257 			result = zone_startload(db, zone, loadtime);
   2258 		} else {
   2259 			result = DNS_R_NOMASTERFILE;
   2260 			if (zone->type == dns_zone_master ||
   2261 			    (zone->type == dns_zone_redirect &&
   2262 			     zone->masters == NULL))
   2263 			{
   2264 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2265 					      ISC_LOG_ERROR,
   2266 					      "loading zone: "
   2267 					      "no master file configured");
   2268 				goto cleanup;
   2269 			}
   2270 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   2271 				      ISC_LOG_INFO,
   2272 				      "loading zone: "
   2273 				      "no master file configured: continuing");
   2274 		}
   2275 	}
   2276 
   2277 	if (result == DNS_R_CONTINUE) {
   2278 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
   2279 		if ((flags & DNS_ZONELOADFLAG_THAW) != 0) {
   2280 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
   2281 		}
   2282 		goto cleanup;
   2283 	}
   2284 
   2285 	result = zone_postload(zone, db, loadtime, result);
   2286 
   2287 cleanup:
   2288 	if (hasraw) {
   2289 		UNLOCK_ZONE(zone->raw);
   2290 	}
   2291 	if (!locked) {
   2292 		UNLOCK_ZONE(zone);
   2293 	}
   2294 	if (db != NULL) {
   2295 		dns_db_detach(&db);
   2296 	}
   2297 	return (result);
   2298 }
   2299 
   2300 isc_result_t
   2301 dns_zone_load(dns_zone_t *zone, bool newonly) {
   2302 	return (zone_load(zone, newonly ? DNS_ZONELOADFLAG_NOSTAT : 0, false));
   2303 }
   2304 
   2305 static void
   2306 zone_asyncload(isc_task_t *task, isc_event_t *event) {
   2307 	dns_asyncload_t *asl = event->ev_arg;
   2308 	dns_zone_t *zone = asl->zone;
   2309 	isc_result_t result;
   2310 
   2311 	UNUSED(task);
   2312 
   2313 	REQUIRE(DNS_ZONE_VALID(zone));
   2314 
   2315 	isc_event_free(&event);
   2316 
   2317 	LOCK_ZONE(zone);
   2318 	result = zone_load(zone, asl->flags, true);
   2319 	if (result != DNS_R_CONTINUE) {
   2320 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2321 	}
   2322 	UNLOCK_ZONE(zone);
   2323 
   2324 	/* Inform the zone table we've finished loading */
   2325 	if (asl->loaded != NULL) {
   2326 		(asl->loaded)(asl->loaded_arg, zone, task);
   2327 	}
   2328 
   2329 	isc_mem_put(zone->mctx, asl, sizeof(*asl));
   2330 	dns_zone_idetach(&zone);
   2331 }
   2332 
   2333 isc_result_t
   2334 dns_zone_asyncload(dns_zone_t *zone, bool newonly, dns_zt_zoneloaded_t done,
   2335 		   void *arg) {
   2336 	isc_event_t *e;
   2337 	dns_asyncload_t *asl = NULL;
   2338 
   2339 	REQUIRE(DNS_ZONE_VALID(zone));
   2340 
   2341 	if (zone->zmgr == NULL) {
   2342 		return (ISC_R_FAILURE);
   2343 	}
   2344 
   2345 	/* If we already have a load pending, stop now */
   2346 	LOCK_ZONE(zone);
   2347 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING)) {
   2348 		UNLOCK_ZONE(zone);
   2349 		return (ISC_R_ALREADYRUNNING);
   2350 	}
   2351 
   2352 	asl = isc_mem_get(zone->mctx, sizeof(*asl));
   2353 
   2354 	asl->zone = NULL;
   2355 	asl->flags = newonly ? DNS_ZONELOADFLAG_NOSTAT : 0;
   2356 	asl->loaded = done;
   2357 	asl->loaded_arg = arg;
   2358 
   2359 	e = isc_event_allocate(zone->zmgr->mctx, zone->zmgr, DNS_EVENT_ZONELOAD,
   2360 			       zone_asyncload, asl, sizeof(isc_event_t));
   2361 
   2362 	zone_iattach(zone, &asl->zone);
   2363 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   2364 	isc_task_send(zone->loadtask, &e);
   2365 	UNLOCK_ZONE(zone);
   2366 
   2367 	return (ISC_R_SUCCESS);
   2368 }
   2369 
   2370 bool
   2371 dns__zone_loadpending(dns_zone_t *zone) {
   2372 	REQUIRE(DNS_ZONE_VALID(zone));
   2373 
   2374 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING));
   2375 }
   2376 
   2377 isc_result_t
   2378 dns_zone_loadandthaw(dns_zone_t *zone) {
   2379 	isc_result_t result;
   2380 
   2381 	if (inline_raw(zone)) {
   2382 		result = zone_load(zone->secure, DNS_ZONELOADFLAG_THAW, false);
   2383 	} else {
   2384 		result = zone_load(zone, DNS_ZONELOADFLAG_THAW, false);
   2385 	}
   2386 
   2387 	switch (result) {
   2388 	case DNS_R_CONTINUE:
   2389 		/* Deferred thaw. */
   2390 		break;
   2391 	case DNS_R_UPTODATE:
   2392 	case ISC_R_SUCCESS:
   2393 	case DNS_R_SEENINCLUDE:
   2394 		zone->update_disabled = false;
   2395 		break;
   2396 	case DNS_R_NOMASTERFILE:
   2397 		zone->update_disabled = false;
   2398 		break;
   2399 	default:
   2400 		/* Error, remain in disabled state. */
   2401 		break;
   2402 	}
   2403 	return (result);
   2404 }
   2405 
   2406 static unsigned int
   2407 get_master_options(dns_zone_t *zone) {
   2408 	unsigned int options;
   2409 
   2410 	options = DNS_MASTER_ZONE | DNS_MASTER_RESIGN;
   2411 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   2412 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   2413 	{
   2414 		options |= DNS_MASTER_SLAVE;
   2415 	}
   2416 	if (zone->type == dns_zone_key) {
   2417 		options |= DNS_MASTER_KEY;
   2418 	}
   2419 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS)) {
   2420 		options |= DNS_MASTER_CHECKNS;
   2421 	}
   2422 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS)) {
   2423 		options |= DNS_MASTER_FATALNS;
   2424 	}
   2425 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES)) {
   2426 		options |= DNS_MASTER_CHECKNAMES;
   2427 	}
   2428 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
   2429 		options |= DNS_MASTER_CHECKNAMESFAIL;
   2430 	}
   2431 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX)) {
   2432 		options |= DNS_MASTER_CHECKMX;
   2433 	}
   2434 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2435 		options |= DNS_MASTER_CHECKMXFAIL;
   2436 	}
   2437 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD)) {
   2438 		options |= DNS_MASTER_CHECKWILDCARD;
   2439 	}
   2440 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKTTL)) {
   2441 		options |= DNS_MASTER_CHECKTTL;
   2442 	}
   2443 
   2444 	return (options);
   2445 }
   2446 
   2447 static void
   2448 zone_registerinclude(const char *filename, void *arg) {
   2449 	isc_result_t result;
   2450 	dns_zone_t *zone = (dns_zone_t *)arg;
   2451 	dns_include_t *inc = NULL;
   2452 
   2453 	REQUIRE(DNS_ZONE_VALID(zone));
   2454 
   2455 	if (filename == NULL) {
   2456 		return;
   2457 	}
   2458 
   2459 	/*
   2460 	 * Suppress duplicates.
   2461 	 */
   2462 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   2463 	     inc = ISC_LIST_NEXT(inc, link))
   2464 	{
   2465 		if (strcmp(filename, inc->name) == 0) {
   2466 			return;
   2467 		}
   2468 	}
   2469 
   2470 	inc = isc_mem_get(zone->mctx, sizeof(dns_include_t));
   2471 	inc->name = isc_mem_strdup(zone->mctx, filename);
   2472 	ISC_LINK_INIT(inc, link);
   2473 
   2474 	result = isc_file_getmodtime(filename, &inc->filetime);
   2475 	if (result != ISC_R_SUCCESS) {
   2476 		isc_time_settoepoch(&inc->filetime);
   2477 	}
   2478 
   2479 	ISC_LIST_APPEND(zone->newincludes, inc, link);
   2480 }
   2481 
   2482 static void
   2483 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
   2484 	dns_load_t *load = event->ev_arg;
   2485 	isc_result_t result = ISC_R_SUCCESS;
   2486 	unsigned int options;
   2487 
   2488 	REQUIRE(DNS_LOAD_VALID(load));
   2489 
   2490 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2491 		result = ISC_R_CANCELED;
   2492 	}
   2493 	isc_event_free(&event);
   2494 	if (result == ISC_R_CANCELED) {
   2495 		goto fail;
   2496 	}
   2497 
   2498 	options = get_master_options(load->zone);
   2499 
   2500 	result = dns_master_loadfileinc(
   2501 		load->zone->masterfile, dns_db_origin(load->db),
   2502 		dns_db_origin(load->db), load->zone->rdclass, options, 0,
   2503 		&load->callbacks, task, zone_loaddone, load, &load->zone->lctx,
   2504 		zone_registerinclude, load->zone, load->zone->mctx,
   2505 		load->zone->masterformat, load->zone->maxttl);
   2506 	if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
   2507 	    result != DNS_R_SEENINCLUDE)
   2508 	{
   2509 		goto fail;
   2510 	}
   2511 	return;
   2512 
   2513 fail:
   2514 	zone_loaddone(load, result);
   2515 }
   2516 
   2517 static void
   2518 get_raw_serial(dns_zone_t *raw, dns_masterrawheader_t *rawdata) {
   2519 	isc_result_t result;
   2520 	unsigned int soacount;
   2521 
   2522 	LOCK(&raw->lock);
   2523 	if (raw->db != NULL) {
   2524 		result = zone_get_from_db(raw, raw->db, NULL, &soacount,
   2525 					  &rawdata->sourceserial, NULL, NULL,
   2526 					  NULL, NULL, NULL);
   2527 		if (result == ISC_R_SUCCESS && soacount > 0U) {
   2528 			rawdata->flags |= DNS_MASTERRAW_SOURCESERIALSET;
   2529 		}
   2530 	}
   2531 	UNLOCK(&raw->lock);
   2532 }
   2533 
   2534 static void
   2535 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
   2536 	const char me[] = "zone_gotwritehandle";
   2537 	dns_zone_t *zone = event->ev_arg;
   2538 	isc_result_t result = ISC_R_SUCCESS;
   2539 	dns_dbversion_t *version = NULL;
   2540 	dns_masterrawheader_t rawdata;
   2541 	dns_db_t *db = NULL;
   2542 
   2543 	REQUIRE(DNS_ZONE_VALID(zone));
   2544 	INSIST(task == zone->task);
   2545 	ENTER;
   2546 
   2547 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) {
   2548 		result = ISC_R_CANCELED;
   2549 	}
   2550 	isc_event_free(&event);
   2551 	if (result == ISC_R_CANCELED) {
   2552 		goto fail;
   2553 	}
   2554 
   2555 	LOCK_ZONE(zone);
   2556 	INSIST(zone != zone->raw);
   2557 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   2558 	if (zone->db != NULL) {
   2559 		dns_db_attach(zone->db, &db);
   2560 	}
   2561 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   2562 	if (db != NULL) {
   2563 		const dns_master_style_t *output_style;
   2564 		dns_db_currentversion(db, &version);
   2565 		dns_master_initrawheader(&rawdata);
   2566 		if (inline_secure(zone)) {
   2567 			get_raw_serial(zone->raw, &rawdata);
   2568 		}
   2569 		if (zone->type == dns_zone_key) {
   2570 			output_style = &dns_master_style_keyzone;
   2571 		} else if (zone->masterstyle != NULL) {
   2572 			output_style = zone->masterstyle;
   2573 		} else {
   2574 			output_style = &dns_master_style_default;
   2575 		}
   2576 		result = dns_master_dumpinc(
   2577 			zone->mctx, db, version, output_style, zone->masterfile,
   2578 			zone->task, dump_done, zone, &zone->dctx,
   2579 			zone->masterformat, &rawdata);
   2580 		dns_db_closeversion(db, &version, false);
   2581 	} else {
   2582 		result = ISC_R_CANCELED;
   2583 	}
   2584 	if (db != NULL) {
   2585 		dns_db_detach(&db);
   2586 	}
   2587 	UNLOCK_ZONE(zone);
   2588 	if (result != DNS_R_CONTINUE) {
   2589 		goto fail;
   2590 	}
   2591 	return;
   2592 
   2593 fail:
   2594 	dump_done(zone, result);
   2595 }
   2596 
   2597 /*
   2598  * Save the raw serial number for inline-signing zones.
   2599  * (XXX: Other information from the header will be used
   2600  * for other purposes in the future, but for now this is
   2601  * all we're interested in.)
   2602  */
   2603 static void
   2604 zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2605 	if ((header->flags & DNS_MASTERRAW_SOURCESERIALSET) == 0) {
   2606 		return;
   2607 	}
   2608 
   2609 	zone->sourceserial = header->sourceserial;
   2610 	zone->sourceserialset = true;
   2611 }
   2612 
   2613 void
   2614 dns_zone_setrawdata(dns_zone_t *zone, dns_masterrawheader_t *header) {
   2615 	if (zone == NULL) {
   2616 		return;
   2617 	}
   2618 
   2619 	LOCK_ZONE(zone);
   2620 	zone_setrawdata(zone, header);
   2621 	UNLOCK_ZONE(zone);
   2622 }
   2623 
   2624 static isc_result_t
   2625 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
   2626 	const char me[] = "zone_startload";
   2627 	dns_load_t *load;
   2628 	isc_result_t result;
   2629 	isc_result_t tresult;
   2630 	unsigned int options;
   2631 
   2632 	ENTER;
   2633 
   2634 	dns_zone_rpz_enable_db(zone, db);
   2635 	dns_zone_catz_enable_db(zone, db);
   2636 
   2637 	options = get_master_options(zone);
   2638 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS)) {
   2639 		options |= DNS_MASTER_MANYERRORS;
   2640 	}
   2641 
   2642 	if (zone->zmgr != NULL && zone->db != NULL && zone->loadtask != NULL) {
   2643 		load = isc_mem_get(zone->mctx, sizeof(*load));
   2644 
   2645 		load->mctx = NULL;
   2646 		load->zone = NULL;
   2647 		load->db = NULL;
   2648 		load->loadtime = loadtime;
   2649 		load->magic = LOAD_MAGIC;
   2650 
   2651 		isc_mem_attach(zone->mctx, &load->mctx);
   2652 		zone_iattach(zone, &load->zone);
   2653 		dns_db_attach(db, &load->db);
   2654 		dns_rdatacallbacks_init(&load->callbacks);
   2655 		load->callbacks.rawdata = zone_setrawdata;
   2656 		zone_iattach(zone, &load->callbacks.zone);
   2657 		result = dns_db_beginload(db, &load->callbacks);
   2658 		if (result != ISC_R_SUCCESS) {
   2659 			goto cleanup;
   2660 		}
   2661 		result = zonemgr_getio(zone->zmgr, true, zone->loadtask,
   2662 				       zone_gotreadhandle, load, &zone->readio);
   2663 		if (result != ISC_R_SUCCESS) {
   2664 			/*
   2665 			 * We can't report multiple errors so ignore
   2666 			 * the result of dns_db_endload().
   2667 			 */
   2668 			(void)dns_db_endload(load->db, &load->callbacks);
   2669 			goto cleanup;
   2670 		} else {
   2671 			result = DNS_R_CONTINUE;
   2672 		}
   2673 	} else {
   2674 		dns_rdatacallbacks_t callbacks;
   2675 
   2676 		dns_rdatacallbacks_init(&callbacks);
   2677 		callbacks.rawdata = zone_setrawdata;
   2678 		zone_iattach(zone, &callbacks.zone);
   2679 		result = dns_db_beginload(db, &callbacks);
   2680 		if (result != ISC_R_SUCCESS) {
   2681 			zone_idetach(&callbacks.zone);
   2682 			return (result);
   2683 		}
   2684 		result = dns_master_loadfile(
   2685 			zone->masterfile, &zone->origin, &zone->origin,
   2686 			zone->rdclass, options, 0, &callbacks,
   2687 			zone_registerinclude, zone, zone->mctx,
   2688 			zone->masterformat, zone->maxttl);
   2689 		tresult = dns_db_endload(db, &callbacks);
   2690 		if (result == ISC_R_SUCCESS) {
   2691 			result = tresult;
   2692 		}
   2693 		zone_idetach(&callbacks.zone);
   2694 	}
   2695 
   2696 	return (result);
   2697 
   2698 cleanup:
   2699 	load->magic = 0;
   2700 	dns_db_detach(&load->db);
   2701 	zone_idetach(&load->zone);
   2702 	zone_idetach(&load->callbacks.zone);
   2703 	isc_mem_detach(&load->mctx);
   2704 	isc_mem_put(zone->mctx, load, sizeof(*load));
   2705 	return (result);
   2706 }
   2707 
   2708 static bool
   2709 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2710 	      dns_name_t *owner) {
   2711 	isc_result_t result;
   2712 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2713 	char namebuf[DNS_NAME_FORMATSIZE];
   2714 	char altbuf[DNS_NAME_FORMATSIZE];
   2715 	dns_fixedname_t fixed;
   2716 	dns_name_t *foundname;
   2717 	int level;
   2718 
   2719 	/*
   2720 	 * "." means the services does not exist.
   2721 	 */
   2722 	if (dns_name_equal(name, dns_rootname)) {
   2723 		return (true);
   2724 	}
   2725 
   2726 	/*
   2727 	 * Outside of zone.
   2728 	 */
   2729 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2730 		if (zone->checkmx != NULL) {
   2731 			return ((zone->checkmx)(zone, name, owner));
   2732 		}
   2733 		return (true);
   2734 	}
   2735 
   2736 	if (zone->type == dns_zone_master) {
   2737 		level = ISC_LOG_ERROR;
   2738 	} else {
   2739 		level = ISC_LOG_WARNING;
   2740 	}
   2741 
   2742 	foundname = dns_fixedname_initname(&fixed);
   2743 
   2744 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2745 			     foundname, NULL, NULL);
   2746 	if (result == ISC_R_SUCCESS) {
   2747 		return (true);
   2748 	}
   2749 
   2750 	if (result == DNS_R_NXRRSET) {
   2751 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2752 				     NULL, foundname, NULL, NULL);
   2753 		if (result == ISC_R_SUCCESS) {
   2754 			return (true);
   2755 		}
   2756 	}
   2757 
   2758 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2759 	dns_name_format(name, namebuf, sizeof namebuf);
   2760 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2761 	    result == DNS_R_EMPTYNAME)
   2762 	{
   2763 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL)) {
   2764 			level = ISC_LOG_WARNING;
   2765 		}
   2766 		dns_zone_log(zone, level,
   2767 			     "%s/MX '%s' has no address records (A or AAAA)",
   2768 			     ownerbuf, namebuf);
   2769 		return ((level == ISC_LOG_WARNING) ? true : false);
   2770 	}
   2771 
   2772 	if (result == DNS_R_CNAME) {
   2773 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2774 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2775 		{
   2776 			level = ISC_LOG_WARNING;
   2777 		}
   2778 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2779 			dns_zone_log(zone, level,
   2780 				     "%s/MX '%s' is a CNAME (illegal)",
   2781 				     ownerbuf, namebuf);
   2782 		}
   2783 		return ((level == ISC_LOG_WARNING) ? true : false);
   2784 	}
   2785 
   2786 	if (result == DNS_R_DNAME) {
   2787 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
   2788 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
   2789 		{
   2790 			level = ISC_LOG_WARNING;
   2791 		}
   2792 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
   2793 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2794 			dns_zone_log(zone, level,
   2795 				     "%s/MX '%s' is below a DNAME"
   2796 				     " '%s' (illegal)",
   2797 				     ownerbuf, namebuf, altbuf);
   2798 		}
   2799 		return ((level == ISC_LOG_WARNING) ? true : false);
   2800 	}
   2801 
   2802 	if (zone->checkmx != NULL && result == DNS_R_DELEGATION) {
   2803 		return ((zone->checkmx)(zone, name, owner));
   2804 	}
   2805 
   2806 	return (true);
   2807 }
   2808 
   2809 static bool
   2810 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2811 	       dns_name_t *owner) {
   2812 	isc_result_t result;
   2813 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2814 	char namebuf[DNS_NAME_FORMATSIZE];
   2815 	char altbuf[DNS_NAME_FORMATSIZE];
   2816 	dns_fixedname_t fixed;
   2817 	dns_name_t *foundname;
   2818 	int level;
   2819 
   2820 	/*
   2821 	 * "." means the services does not exist.
   2822 	 */
   2823 	if (dns_name_equal(name, dns_rootname)) {
   2824 		return (true);
   2825 	}
   2826 
   2827 	/*
   2828 	 * Outside of zone.
   2829 	 */
   2830 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2831 		if (zone->checksrv != NULL) {
   2832 			return ((zone->checksrv)(zone, name, owner));
   2833 		}
   2834 		return (true);
   2835 	}
   2836 
   2837 	if (zone->type == dns_zone_master) {
   2838 		level = ISC_LOG_ERROR;
   2839 	} else {
   2840 		level = ISC_LOG_WARNING;
   2841 	}
   2842 
   2843 	foundname = dns_fixedname_initname(&fixed);
   2844 
   2845 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2846 			     foundname, NULL, NULL);
   2847 	if (result == ISC_R_SUCCESS) {
   2848 		return (true);
   2849 	}
   2850 
   2851 	if (result == DNS_R_NXRRSET) {
   2852 		result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa, 0, 0,
   2853 				     NULL, foundname, NULL, NULL);
   2854 		if (result == ISC_R_SUCCESS) {
   2855 			return (true);
   2856 		}
   2857 	}
   2858 
   2859 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   2860 	dns_name_format(name, namebuf, sizeof namebuf);
   2861 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   2862 	    result == DNS_R_EMPTYNAME)
   2863 	{
   2864 		dns_zone_log(zone, level,
   2865 			     "%s/SRV '%s' has no address records (A or AAAA)",
   2866 			     ownerbuf, namebuf);
   2867 		/* XXX950 make fatal for 9.5.0. */
   2868 		return (true);
   2869 	}
   2870 
   2871 	if (result == DNS_R_CNAME) {
   2872 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2873 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2874 		{
   2875 			level = ISC_LOG_WARNING;
   2876 		}
   2877 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   2878 			dns_zone_log(zone, level,
   2879 				     "%s/SRV '%s' is a CNAME (illegal)",
   2880 				     ownerbuf, namebuf);
   2881 		}
   2882 		return ((level == ISC_LOG_WARNING) ? true : false);
   2883 	}
   2884 
   2885 	if (result == DNS_R_DNAME) {
   2886 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
   2887 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
   2888 		{
   2889 			level = ISC_LOG_WARNING;
   2890 		}
   2891 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
   2892 			dns_name_format(foundname, altbuf, sizeof altbuf);
   2893 			dns_zone_log(zone, level,
   2894 				     "%s/SRV '%s' is below a "
   2895 				     "DNAME '%s' (illegal)",
   2896 				     ownerbuf, namebuf, altbuf);
   2897 		}
   2898 		return ((level == ISC_LOG_WARNING) ? true : false);
   2899 	}
   2900 
   2901 	if (zone->checksrv != NULL && result == DNS_R_DELEGATION) {
   2902 		return ((zone->checksrv)(zone, name, owner));
   2903 	}
   2904 
   2905 	return (true);
   2906 }
   2907 
   2908 static bool
   2909 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
   2910 		dns_name_t *owner) {
   2911 	bool answer = true;
   2912 	isc_result_t result, tresult;
   2913 	char ownerbuf[DNS_NAME_FORMATSIZE];
   2914 	char namebuf[DNS_NAME_FORMATSIZE];
   2915 	char altbuf[DNS_NAME_FORMATSIZE];
   2916 	dns_fixedname_t fixed;
   2917 	dns_name_t *foundname;
   2918 	dns_rdataset_t a;
   2919 	dns_rdataset_t aaaa;
   2920 	int level;
   2921 
   2922 	/*
   2923 	 * Outside of zone.
   2924 	 */
   2925 	if (!dns_name_issubdomain(name, &zone->origin)) {
   2926 		if (zone->checkns != NULL) {
   2927 			return ((zone->checkns)(zone, name, owner, NULL, NULL));
   2928 		}
   2929 		return (true);
   2930 	}
   2931 
   2932 	if (zone->type == dns_zone_master) {
   2933 		level = ISC_LOG_ERROR;
   2934 	} else {
   2935 		level = ISC_LOG_WARNING;
   2936 	}
   2937 
   2938 	foundname = dns_fixedname_initname(&fixed);
   2939 	dns_rdataset_init(&a);
   2940 	dns_rdataset_init(&aaaa);
   2941 
   2942 	/*
   2943 	 * Perform a regular lookup to catch DNAME records then look
   2944 	 * for glue.
   2945 	 */
   2946 	result = dns_db_find(db, name, NULL, dns_rdatatype_a, 0, 0, NULL,
   2947 			     foundname, &a, NULL);
   2948 	switch (result) {
   2949 	case ISC_R_SUCCESS:
   2950 	case DNS_R_DNAME:
   2951 	case DNS_R_CNAME:
   2952 		break;
   2953 	default:
   2954 		if (dns_rdataset_isassociated(&a)) {
   2955 			dns_rdataset_disassociate(&a);
   2956 		}
   2957 		result = dns_db_find(db, name, NULL, dns_rdatatype_a,
   2958 				     DNS_DBFIND_GLUEOK, 0, NULL, foundname, &a,
   2959 				     NULL);
   2960 	}
   2961 	if (result == ISC_R_SUCCESS) {
   2962 		dns_rdataset_disassociate(&a);
   2963 		return (true);
   2964 	} else if (result == DNS_R_DELEGATION) {
   2965 		dns_rdataset_disassociate(&a);
   2966 	}
   2967 
   2968 	if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
   2969 	    result == DNS_R_GLUE)
   2970 	{
   2971 		tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
   2972 				      DNS_DBFIND_GLUEOK, 0, NULL, foundname,
   2973 				      &aaaa, NULL);
   2974 		if (tresult == ISC_R_SUCCESS) {
   2975 			if (dns_rdataset_isassociated(&a)) {
   2976 				dns_rdataset_disassociate(&a);
   2977 			}
   2978 			dns_rdataset_disassociate(&aaaa);
   2979 			return (true);
   2980 		}
   2981 		if (tresult == DNS_R_DELEGATION || tresult == DNS_R_DNAME) {
   2982 			dns_rdataset_disassociate(&aaaa);
   2983 		}
   2984 		if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
   2985 			/*
   2986 			 * Check glue against child zone.
   2987 			 */
   2988 			if (zone->checkns != NULL) {
   2989 				answer = (zone->checkns)(zone, name, owner, &a,
   2990 							 &aaaa);
   2991 			}
   2992 			if (dns_rdataset_isassociated(&a)) {
   2993 				dns_rdataset_disassociate(&a);
   2994 			}
   2995 			if (dns_rdataset_isassociated(&aaaa)) {
   2996 				dns_rdataset_disassociate(&aaaa);
   2997 			}
   2998 			return (answer);
   2999 		}
   3000 	}
   3001 
   3002 	dns_name_format(owner, ownerbuf, sizeof ownerbuf);
   3003 	dns_name_format(name, namebuf, sizeof namebuf);
   3004 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   3005 	    result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION)
   3006 	{
   3007 		const char *what;
   3008 		bool required = false;
   3009 		if (dns_name_issubdomain(name, owner)) {
   3010 			what = "REQUIRED GLUE ";
   3011 			required = true;
   3012 		} else if (result == DNS_R_DELEGATION) {
   3013 			what = "SIBLING GLUE ";
   3014 		} else {
   3015 			what = "";
   3016 		}
   3017 
   3018 		if (result != DNS_R_DELEGATION || required ||
   3019 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING))
   3020 		{
   3021 			dns_zone_log(zone, level,
   3022 				     "%s/NS '%s' has no %s"
   3023 				     "address records (A or AAAA)",
   3024 				     ownerbuf, namebuf, what);
   3025 			/*
   3026 			 * Log missing address record.
   3027 			 */
   3028 			if (result == DNS_R_DELEGATION && zone->checkns != NULL)
   3029 			{
   3030 				(void)(zone->checkns)(zone, name, owner, &a,
   3031 						      &aaaa);
   3032 			}
   3033 			/* XXX950 make fatal for 9.5.0. */
   3034 			/* answer = false; */
   3035 		}
   3036 	} else if (result == DNS_R_CNAME) {
   3037 		dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
   3038 			     ownerbuf, namebuf);
   3039 		/* XXX950 make fatal for 9.5.0. */
   3040 		/* answer = false; */
   3041 	} else if (result == DNS_R_DNAME) {
   3042 		dns_name_format(foundname, altbuf, sizeof altbuf);
   3043 		dns_zone_log(zone, level,
   3044 			     "%s/NS '%s' is below a DNAME '%s' (illegal)",
   3045 			     ownerbuf, namebuf, altbuf);
   3046 		/* XXX950 make fatal for 9.5.0. */
   3047 		/* answer = false; */
   3048 	}
   3049 
   3050 	if (dns_rdataset_isassociated(&a)) {
   3051 		dns_rdataset_disassociate(&a);
   3052 	}
   3053 	if (dns_rdataset_isassociated(&aaaa)) {
   3054 		dns_rdataset_disassociate(&aaaa);
   3055 	}
   3056 	return (answer);
   3057 }
   3058 
   3059 static bool
   3060 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
   3061 		     dns_rdataset_t *rdataset) {
   3062 	dns_rdataset_t tmprdataset;
   3063 	isc_result_t result;
   3064 	bool answer = true;
   3065 	bool format = true;
   3066 	int level = ISC_LOG_WARNING;
   3067 	char ownerbuf[DNS_NAME_FORMATSIZE];
   3068 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   3069 	unsigned int count1 = 0;
   3070 
   3071 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL)) {
   3072 		level = ISC_LOG_ERROR;
   3073 	}
   3074 
   3075 	dns_rdataset_init(&tmprdataset);
   3076 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   3077 	     result = dns_rdataset_next(rdataset))
   3078 	{
   3079 		dns_rdata_t rdata1 = DNS_RDATA_INIT;
   3080 		unsigned int count2 = 0;
   3081 
   3082 		count1++;
   3083 		dns_rdataset_current(rdataset, &rdata1);
   3084 		dns_rdataset_clone(rdataset, &tmprdataset);
   3085 		for (result = dns_rdataset_first(&tmprdataset);
   3086 		     result == ISC_R_SUCCESS;
   3087 		     result = dns_rdataset_next(&tmprdataset))
   3088 		{
   3089 			dns_rdata_t rdata2 = DNS_RDATA_INIT;
   3090 			count2++;
   3091 			if (count1 >= count2) {
   3092 				continue;
   3093 			}
   3094 			dns_rdataset_current(&tmprdataset, &rdata2);
   3095 			if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
   3096 				if (format) {
   3097 					dns_name_format(owner, ownerbuf,
   3098 							sizeof ownerbuf);
   3099 					dns_rdatatype_format(rdata1.type,
   3100 							     typebuf,
   3101 							     sizeof(typebuf));
   3102 					format = false;
   3103 				}
   3104 				dns_zone_log(zone, level,
   3105 					     "%s/%s has "
   3106 					     "semantically identical records",
   3107 					     ownerbuf, typebuf);
   3108 				if (level == ISC_LOG_ERROR) {
   3109 					answer = false;
   3110 				}
   3111 				break;
   3112 			}
   3113 		}
   3114 		dns_rdataset_disassociate(&tmprdataset);
   3115 		if (!format) {
   3116 			break;
   3117 		}
   3118 	}
   3119 	return (answer);
   3120 }
   3121 
   3122 static bool
   3123 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
   3124 	dns_dbiterator_t *dbiterator = NULL;
   3125 	dns_dbnode_t *node = NULL;
   3126 	dns_fixedname_t fixed;
   3127 	dns_name_t *name;
   3128 	dns_rdataset_t rdataset;
   3129 	dns_rdatasetiter_t *rdsit = NULL;
   3130 	bool ok = true;
   3131 	isc_result_t result;
   3132 
   3133 	name = dns_fixedname_initname(&fixed);
   3134 	dns_rdataset_init(&rdataset);
   3135 
   3136 	result = dns_db_createiterator(db, 0, &dbiterator);
   3137 	if (result != ISC_R_SUCCESS) {
   3138 		return (true);
   3139 	}
   3140 
   3141 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   3142 	     result = dns_dbiterator_next(dbiterator))
   3143 	{
   3144 		result = dns_dbiterator_current(dbiterator, &node, name);
   3145 		if (result != ISC_R_SUCCESS) {
   3146 			continue;
   3147 		}
   3148 
   3149 		result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
   3150 		if (result != ISC_R_SUCCESS) {
   3151 			continue;
   3152 		}
   3153 
   3154 		for (result = dns_rdatasetiter_first(rdsit);
   3155 		     result == ISC_R_SUCCESS;
   3156 		     result = dns_rdatasetiter_next(rdsit))
   3157 		{
   3158 			dns_rdatasetiter_current(rdsit, &rdataset);
   3159 			if (!zone_rrset_check_dup(zone, name, &rdataset)) {
   3160 				ok = false;
   3161 			}
   3162 			dns_rdataset_disassociate(&rdataset);
   3163 		}
   3164 		dns_rdatasetiter_destroy(&rdsit);
   3165 		dns_db_detachnode(db, &node);
   3166 	}
   3167 
   3168 	if (node != NULL) {
   3169 		dns_db_detachnode(db, &node);
   3170 	}
   3171 	dns_dbiterator_destroy(&dbiterator);
   3172 
   3173 	return (ok);
   3174 }
   3175 
   3176 static bool
   3177 isspf(const dns_rdata_t *rdata) {
   3178 	char buf[1024];
   3179 	const unsigned char *data = rdata->data;
   3180 	unsigned int rdl = rdata->length, i = 0, tl, len;
   3181 
   3182 	while (rdl > 0U) {
   3183 		len = tl = *data;
   3184 		++data;
   3185 		--rdl;
   3186 		INSIST(tl <= rdl);
   3187 		if (len > sizeof(buf) - i - 1) {
   3188 			len = sizeof(buf) - i - 1;
   3189 		}
   3190 		memmove(buf + i, data, len);
   3191 		i += len;
   3192 		data += tl;
   3193 		rdl -= tl;
   3194 	}
   3195 
   3196 	if (i < 6U) {
   3197 		return (false);
   3198 	}
   3199 
   3200 	buf[i] = 0;
   3201 	if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' ')) {
   3202 		return (true);
   3203 	}
   3204 	return (false);
   3205 }
   3206 
   3207 static bool
   3208 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
   3209 	dns_dbiterator_t *dbiterator = NULL;
   3210 	dns_dbnode_t *node = NULL;
   3211 	dns_rdataset_t rdataset;
   3212 	dns_fixedname_t fixed;
   3213 	dns_fixedname_t fixedbottom;
   3214 	dns_rdata_mx_t mx;
   3215 	dns_rdata_ns_t ns;
   3216 	dns_rdata_in_srv_t srv;
   3217 	dns_rdata_t rdata;
   3218 	dns_name_t *name;
   3219 	dns_name_t *bottom;
   3220 	isc_result_t result;
   3221 	bool ok = true, have_spf, have_txt;
   3222 
   3223 	name = dns_fixedname_initname(&fixed);
   3224 	bottom = dns_fixedname_initname(&fixedbottom);
   3225 	dns_rdataset_init(&rdataset);
   3226 	dns_rdata_init(&rdata);
   3227 
   3228 	result = dns_db_createiterator(db, 0, &dbiterator);
   3229 	if (result != ISC_R_SUCCESS) {
   3230 		return (true);
   3231 	}
   3232 
   3233 	result = dns_dbiterator_first(dbiterator);
   3234 	while (result == ISC_R_SUCCESS) {
   3235 		result = dns_dbiterator_current(dbiterator, &node, name);
   3236 		if (result != ISC_R_SUCCESS) {
   3237 			goto cleanup;
   3238 		}
   3239 
   3240 		/*
   3241 		 * Is this name visible in the zone?
   3242 		 */
   3243 		if (!dns_name_issubdomain(name, &zone->origin) ||
   3244 		    (dns_name_countlabels(bottom) > 0 &&
   3245 		     dns_name_issubdomain(name, bottom)))
   3246 		{
   3247 			goto next;
   3248 		}
   3249 
   3250 		/*
   3251 		 * Don't check the NS records at the origin.
   3252 		 */
   3253 		if (dns_name_equal(name, &zone->origin)) {
   3254 			goto checkfordname;
   3255 		}
   3256 
   3257 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
   3258 					     0, 0, &rdataset, NULL);
   3259 		if (result != ISC_R_SUCCESS) {
   3260 			goto checkfordname;
   3261 		}
   3262 		/*
   3263 		 * Remember bottom of zone due to NS.
   3264 		 */
   3265 		dns_name_copynf(name, bottom);
   3266 
   3267 		result = dns_rdataset_first(&rdataset);
   3268 		while (result == ISC_R_SUCCESS) {
   3269 			dns_rdataset_current(&rdataset, &rdata);
   3270 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   3271 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3272 			if (!zone_check_glue(zone, db, &ns.name, name)) {
   3273 				ok = false;
   3274 			}
   3275 			dns_rdata_reset(&rdata);
   3276 			result = dns_rdataset_next(&rdataset);
   3277 		}
   3278 		dns_rdataset_disassociate(&rdataset);
   3279 		goto next;
   3280 
   3281 	checkfordname:
   3282 		result = dns_db_findrdataset(db, node, NULL,
   3283 					     dns_rdatatype_dname, 0, 0,
   3284 					     &rdataset, NULL);
   3285 		if (result == ISC_R_SUCCESS) {
   3286 			/*
   3287 			 * Remember bottom of zone due to DNAME.
   3288 			 */
   3289 			dns_name_copynf(name, bottom);
   3290 			dns_rdataset_disassociate(&rdataset);
   3291 		}
   3292 
   3293 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
   3294 					     0, 0, &rdataset, NULL);
   3295 		if (result != ISC_R_SUCCESS) {
   3296 			goto checksrv;
   3297 		}
   3298 		result = dns_rdataset_first(&rdataset);
   3299 		while (result == ISC_R_SUCCESS) {
   3300 			dns_rdataset_current(&rdataset, &rdata);
   3301 			result = dns_rdata_tostruct(&rdata, &mx, NULL);
   3302 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3303 			if (!zone_check_mx(zone, db, &mx.mx, name)) {
   3304 				ok = false;
   3305 			}
   3306 			dns_rdata_reset(&rdata);
   3307 			result = dns_rdataset_next(&rdataset);
   3308 		}
   3309 		dns_rdataset_disassociate(&rdataset);
   3310 
   3311 	checksrv:
   3312 		if (zone->rdclass != dns_rdataclass_in) {
   3313 			goto next;
   3314 		}
   3315 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
   3316 					     0, 0, &rdataset, NULL);
   3317 		if (result != ISC_R_SUCCESS) {
   3318 			goto checkspf;
   3319 		}
   3320 		result = dns_rdataset_first(&rdataset);
   3321 		while (result == ISC_R_SUCCESS) {
   3322 			dns_rdataset_current(&rdataset, &rdata);
   3323 			result = dns_rdata_tostruct(&rdata, &srv, NULL);
   3324 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3325 			if (!zone_check_srv(zone, db, &srv.target, name)) {
   3326 				ok = false;
   3327 			}
   3328 			dns_rdata_reset(&rdata);
   3329 			result = dns_rdataset_next(&rdataset);
   3330 		}
   3331 		dns_rdataset_disassociate(&rdataset);
   3332 
   3333 	checkspf:
   3334 		/*
   3335 		 * Check if there is a type SPF record without an
   3336 		 * SPF-formatted type TXT record also being present.
   3337 		 */
   3338 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF)) {
   3339 			goto next;
   3340 		}
   3341 		if (zone->rdclass != dns_rdataclass_in) {
   3342 			goto next;
   3343 		}
   3344 		have_spf = have_txt = false;
   3345 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
   3346 					     0, 0, &rdataset, NULL);
   3347 		if (result == ISC_R_SUCCESS) {
   3348 			dns_rdataset_disassociate(&rdataset);
   3349 			have_spf = true;
   3350 		}
   3351 		result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
   3352 					     0, 0, &rdataset, NULL);
   3353 		if (result != ISC_R_SUCCESS) {
   3354 			goto notxt;
   3355 		}
   3356 		result = dns_rdataset_first(&rdataset);
   3357 		while (result == ISC_R_SUCCESS) {
   3358 			dns_rdataset_current(&rdataset, &rdata);
   3359 			have_txt = isspf(&rdata);
   3360 			dns_rdata_reset(&rdata);
   3361 			if (have_txt) {
   3362 				break;
   3363 			}
   3364 			result = dns_rdataset_next(&rdataset);
   3365 		}
   3366 		dns_rdataset_disassociate(&rdataset);
   3367 
   3368 	notxt:
   3369 		if (have_spf && !have_txt) {
   3370 			char namebuf[DNS_NAME_FORMATSIZE];
   3371 
   3372 			dns_name_format(name, namebuf, sizeof(namebuf));
   3373 			dns_zone_log(zone, ISC_LOG_WARNING,
   3374 				     "'%s' found type "
   3375 				     "SPF record but no SPF TXT record found, "
   3376 				     "add matching type TXT record",
   3377 				     namebuf);
   3378 		}
   3379 
   3380 	next:
   3381 		dns_db_detachnode(db, &node);
   3382 		result = dns_dbiterator_next(dbiterator);
   3383 	}
   3384 
   3385 cleanup:
   3386 	if (node != NULL) {
   3387 		dns_db_detachnode(db, &node);
   3388 	}
   3389 	dns_dbiterator_destroy(&dbiterator);
   3390 
   3391 	return (ok);
   3392 }
   3393 
   3394 /*
   3395  * OpenSSL verification of RSA keys with exponent 3 is known to be
   3396  * broken prior OpenSSL 0.9.8c/0.9.7k.	Look for such keys and warn
   3397  * if they are in use.
   3398  */
   3399 static void
   3400 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
   3401 	dns_dbnode_t *node = NULL;
   3402 	dns_dbversion_t *version = NULL;
   3403 	dns_rdata_dnskey_t dnskey;
   3404 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3405 	dns_rdataset_t rdataset;
   3406 	isc_result_t result;
   3407 
   3408 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3409 	if (result != ISC_R_SUCCESS) {
   3410 		goto cleanup;
   3411 	}
   3412 
   3413 	dns_db_currentversion(db, &version);
   3414 	dns_rdataset_init(&rdataset);
   3415 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   3416 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3417 	if (result != ISC_R_SUCCESS) {
   3418 		goto cleanup;
   3419 	}
   3420 
   3421 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3422 	     result = dns_rdataset_next(&rdataset))
   3423 	{
   3424 		dns_rdataset_current(&rdataset, &rdata);
   3425 		result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
   3426 		INSIST(result == ISC_R_SUCCESS);
   3427 
   3428 		/* RFC 3110, section 4: Performance Considerations:
   3429 		 *
   3430 		 * A public exponent of 3 minimizes the effort needed to verify
   3431 		 * a signature.  Use of 3 as the public exponent is weak for
   3432 		 * confidentiality uses since, if the same data can be collected
   3433 		 * encrypted under three different keys with an exponent of 3
   3434 		 * then, using the Chinese Remainder Theorem [NETSEC], the
   3435 		 * original plain text can be easily recovered.  If a key is
   3436 		 * known to be used only for authentication, as is the case with
   3437 		 * DNSSEC, then an exponent of 3 is acceptable.  However other
   3438 		 * applications in the future may wish to leverage DNS
   3439 		 * distributed keys for applications that do require
   3440 		 * confidentiality.  For keys which might have such other uses,
   3441 		 * a more conservative choice would be 65537 (F4, the fourth
   3442 		 * fermat number).
   3443 		 */
   3444 		if (dnskey.datalen > 1 && dnskey.data[0] == 1 &&
   3445 		    dnskey.data[1] == 3) {
   3446 			const char *algorithm = "";
   3447 			isc_region_t r;
   3448 			bool logit = true;
   3449 
   3450 			dns_rdata_toregion(&rdata, &r);
   3451 
   3452 			switch (dnskey.algorithm) {
   3453 			case DNS_KEYALG_RSAMD5:
   3454 				algorithm = "RSAMD5";
   3455 				break;
   3456 			case DNS_KEYALG_RSASHA1:
   3457 				algorithm = "RSASHA1";
   3458 				break;
   3459 			case DNS_KEYALG_NSEC3RSASHA1:
   3460 				algorithm = "NSEC3RSASHA1";
   3461 				break;
   3462 			case DNS_KEYALG_RSASHA256:
   3463 				algorithm = "RSASHA236";
   3464 				break;
   3465 			case DNS_KEYALG_RSASHA512:
   3466 				algorithm = "RSASHA512";
   3467 				break;
   3468 			default:
   3469 				logit = false;
   3470 				break;
   3471 			}
   3472 
   3473 			if (logit) {
   3474 				dnssec_log(zone, ISC_LOG_WARNING,
   3475 					   "weak %s (%u) key found "
   3476 					   "(exponent=3, id=%u)",
   3477 					   algorithm, dnskey.algorithm,
   3478 					   dst_region_computeid(&r));
   3479 			}
   3480 		}
   3481 		dns_rdata_reset(&rdata);
   3482 	}
   3483 	dns_rdataset_disassociate(&rdataset);
   3484 
   3485 cleanup:
   3486 	if (node != NULL) {
   3487 		dns_db_detachnode(db, &node);
   3488 	}
   3489 	if (version != NULL) {
   3490 		dns_db_closeversion(db, &version, false);
   3491 	}
   3492 }
   3493 
   3494 static void
   3495 resume_signingwithkey(dns_zone_t *zone) {
   3496 	dns_dbnode_t *node = NULL;
   3497 	dns_dbversion_t *version = NULL;
   3498 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3499 	dns_rdataset_t rdataset;
   3500 	isc_result_t result;
   3501 	dns_db_t *db = NULL;
   3502 
   3503 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3504 	if (zone->db != NULL) {
   3505 		dns_db_attach(zone->db, &db);
   3506 	}
   3507 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3508 	if (db == NULL) {
   3509 		goto cleanup;
   3510 	}
   3511 
   3512 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3513 	if (result != ISC_R_SUCCESS) {
   3514 		goto cleanup;
   3515 	}
   3516 
   3517 	dns_db_currentversion(db, &version);
   3518 	dns_rdataset_init(&rdataset);
   3519 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3520 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3521 	if (result != ISC_R_SUCCESS) {
   3522 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3523 		goto cleanup;
   3524 	}
   3525 
   3526 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3527 	     result = dns_rdataset_next(&rdataset))
   3528 	{
   3529 		dns_rdataset_current(&rdataset, &rdata);
   3530 		if (rdata.length != 5 || rdata.data[0] == 0 ||
   3531 		    rdata.data[4] != 0) {
   3532 			dns_rdata_reset(&rdata);
   3533 			continue;
   3534 		}
   3535 
   3536 		result = zone_signwithkey(zone, rdata.data[0],
   3537 					  (rdata.data[1] << 8) | rdata.data[2],
   3538 					  rdata.data[3]);
   3539 		if (result != ISC_R_SUCCESS) {
   3540 			dnssec_log(zone, ISC_LOG_ERROR,
   3541 				   "zone_signwithkey failed: %s",
   3542 				   dns_result_totext(result));
   3543 		}
   3544 		dns_rdata_reset(&rdata);
   3545 	}
   3546 	dns_rdataset_disassociate(&rdataset);
   3547 
   3548 cleanup:
   3549 	if (db != NULL) {
   3550 		if (node != NULL) {
   3551 			dns_db_detachnode(db, &node);
   3552 		}
   3553 		if (version != NULL) {
   3554 			dns_db_closeversion(db, &version, false);
   3555 		}
   3556 		dns_db_detach(&db);
   3557 	}
   3558 }
   3559 
   3560 /*
   3561  * Initiate adding/removing NSEC3 records belonging to the chain defined by the
   3562  * supplied NSEC3PARAM RDATA.
   3563  *
   3564  * Zone must be locked by caller.
   3565  */
   3566 static isc_result_t
   3567 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   3568 	dns_nsec3chain_t *nsec3chain, *current;
   3569 	dns_dbversion_t *version = NULL;
   3570 	bool nseconly = false, nsec3ok = false;
   3571 	isc_result_t result;
   3572 	isc_time_t now;
   3573 	unsigned int options = 0;
   3574 	char saltbuf[255 * 2 + 1];
   3575 	char flags[sizeof("INITIAL|REMOVE|CREATE|NONSEC|OPTOUT")];
   3576 	dns_db_t *db = NULL;
   3577 
   3578 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3579 	if (zone->db != NULL) {
   3580 		dns_db_attach(zone->db, &db);
   3581 	}
   3582 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3583 
   3584 	if (db == NULL) {
   3585 		result = ISC_R_SUCCESS;
   3586 		goto cleanup;
   3587 	}
   3588 
   3589 	/*
   3590 	 * If this zone is not NSEC3-capable, attempting to remove any NSEC3
   3591 	 * chain from it is pointless as it would not be possible for the
   3592 	 * latter to exist in the first place.
   3593 	 */
   3594 	dns_db_currentversion(db, &version);
   3595 	result = dns_nsec_nseconly(db, version, &nseconly);
   3596 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3597 	dns_db_closeversion(db, &version, false);
   3598 	if (!nsec3ok && (nsec3param->flags & DNS_NSEC3FLAG_REMOVE) == 0) {
   3599 		result = ISC_R_SUCCESS;
   3600 		goto cleanup;
   3601 	}
   3602 
   3603 	/*
   3604 	 * Allocate and initialize structure preserving state of
   3605 	 * adding/removing records belonging to this NSEC3 chain between
   3606 	 * separate zone_nsec3chain() calls.
   3607 	 */
   3608 	nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
   3609 
   3610 	nsec3chain->magic = 0;
   3611 	nsec3chain->done = false;
   3612 	nsec3chain->db = NULL;
   3613 	nsec3chain->dbiterator = NULL;
   3614 	nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
   3615 	nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
   3616 	nsec3chain->nsec3param.hash = nsec3param->hash;
   3617 	nsec3chain->nsec3param.iterations = nsec3param->iterations;
   3618 	nsec3chain->nsec3param.flags = nsec3param->flags;
   3619 	nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
   3620 	memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
   3621 	nsec3chain->nsec3param.salt = nsec3chain->salt;
   3622 	nsec3chain->seen_nsec = false;
   3623 	nsec3chain->delete_nsec = false;
   3624 	nsec3chain->save_delete_nsec = false;
   3625 
   3626 	/*
   3627 	 * Log NSEC3 parameters defined by supplied NSEC3PARAM RDATA.
   3628 	 */
   3629 	if (nsec3param->flags == 0) {
   3630 		strlcpy(flags, "NONE", sizeof(flags));
   3631 	} else {
   3632 		flags[0] = '\0';
   3633 		if ((nsec3param->flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   3634 			strlcat(flags, "REMOVE", sizeof(flags));
   3635 		}
   3636 		if ((nsec3param->flags & DNS_NSEC3FLAG_INITIAL) != 0) {
   3637 			if (flags[0] == '\0') {
   3638 				strlcpy(flags, "INITIAL", sizeof(flags));
   3639 			} else {
   3640 				strlcat(flags, "|INITIAL", sizeof(flags));
   3641 			}
   3642 		}
   3643 		if ((nsec3param->flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3644 			if (flags[0] == '\0') {
   3645 				strlcpy(flags, "CREATE", sizeof(flags));
   3646 			} else {
   3647 				strlcat(flags, "|CREATE", sizeof(flags));
   3648 			}
   3649 		}
   3650 		if ((nsec3param->flags & DNS_NSEC3FLAG_NONSEC) != 0) {
   3651 			if (flags[0] == '\0') {
   3652 				strlcpy(flags, "NONSEC", sizeof(flags));
   3653 			} else {
   3654 				strlcat(flags, "|NONSEC", sizeof(flags));
   3655 			}
   3656 		}
   3657 		if ((nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) != 0) {
   3658 			if (flags[0] == '\0') {
   3659 				strlcpy(flags, "OPTOUT", sizeof(flags));
   3660 			} else {
   3661 				strlcat(flags, "|OPTOUT", sizeof(flags));
   3662 			}
   3663 		}
   3664 	}
   3665 	result = dns_nsec3param_salttotext(nsec3param, saltbuf,
   3666 					   sizeof(saltbuf));
   3667 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3668 	dnssec_log(zone, ISC_LOG_INFO, "zone_addnsec3chain(%u,%s,%u,%s)",
   3669 		   nsec3param->hash, flags, nsec3param->iterations, saltbuf);
   3670 
   3671 	/*
   3672 	 * If the NSEC3 chain defined by the supplied NSEC3PARAM RDATA is
   3673 	 * currently being processed, interrupt its processing to avoid
   3674 	 * simultaneously adding and removing records for the same NSEC3 chain.
   3675 	 */
   3676 	for (current = ISC_LIST_HEAD(zone->nsec3chain); current != NULL;
   3677 	     current = ISC_LIST_NEXT(current, link))
   3678 	{
   3679 		if ((current->db == db) &&
   3680 		    (current->nsec3param.hash == nsec3param->hash) &&
   3681 		    (current->nsec3param.iterations ==
   3682 		     nsec3param->iterations) &&
   3683 		    (current->nsec3param.salt_length ==
   3684 		     nsec3param->salt_length) &&
   3685 		    memcmp(current->nsec3param.salt, nsec3param->salt,
   3686 			   nsec3param->salt_length) == 0)
   3687 		{
   3688 			current->done = true;
   3689 		}
   3690 	}
   3691 
   3692 	/*
   3693 	 * Attach zone database to the structure initialized above and create
   3694 	 * an iterator for it with appropriate options in order to avoid
   3695 	 * creating NSEC3 records for NSEC3 records.
   3696 	 */
   3697 	dns_db_attach(db, &nsec3chain->db);
   3698 	if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0) {
   3699 		options = DNS_DB_NONSEC3;
   3700 	}
   3701 	result = dns_db_createiterator(nsec3chain->db, options,
   3702 				       &nsec3chain->dbiterator);
   3703 	if (result == ISC_R_SUCCESS) {
   3704 		result = dns_dbiterator_first(nsec3chain->dbiterator);
   3705 	}
   3706 	if (result == ISC_R_SUCCESS) {
   3707 		/*
   3708 		 * Database iterator initialization succeeded.  We are now
   3709 		 * ready to kick off adding/removing records belonging to this
   3710 		 * NSEC3 chain.  Append the structure initialized above to the
   3711 		 * "nsec3chain" list for the zone and set the appropriate zone
   3712 		 * timer so that zone_nsec3chain() is called as soon as
   3713 		 * possible.
   3714 		 */
   3715 		dns_dbiterator_pause(nsec3chain->dbiterator);
   3716 		ISC_LIST_INITANDAPPEND(zone->nsec3chain, nsec3chain, link);
   3717 		nsec3chain = NULL;
   3718 		if (isc_time_isepoch(&zone->nsec3chaintime)) {
   3719 			TIME_NOW(&now);
   3720 			zone->nsec3chaintime = now;
   3721 			if (zone->task != NULL) {
   3722 				zone_settimer(zone, &now);
   3723 			}
   3724 		}
   3725 	}
   3726 
   3727 	if (nsec3chain != NULL) {
   3728 		if (nsec3chain->db != NULL) {
   3729 			dns_db_detach(&nsec3chain->db);
   3730 		}
   3731 		if (nsec3chain->dbiterator != NULL) {
   3732 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   3733 		}
   3734 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   3735 	}
   3736 
   3737 cleanup:
   3738 	if (db != NULL) {
   3739 		dns_db_detach(&db);
   3740 	}
   3741 	return (result);
   3742 }
   3743 
   3744 /*
   3745  * Find private-type records at the zone apex which signal that an NSEC3 chain
   3746  * should be added or removed.  For each such record, extract NSEC3PARAM RDATA
   3747  * and pass it to zone_addnsec3chain().
   3748  *
   3749  * Zone must be locked by caller.
   3750  */
   3751 static void
   3752 resume_addnsec3chain(dns_zone_t *zone) {
   3753 	dns_dbnode_t *node = NULL;
   3754 	dns_dbversion_t *version = NULL;
   3755 	dns_rdataset_t rdataset;
   3756 	isc_result_t result;
   3757 	dns_rdata_nsec3param_t nsec3param;
   3758 	bool nseconly = false, nsec3ok = false;
   3759 	dns_db_t *db = NULL;
   3760 
   3761 	INSIST(LOCKED_ZONE(zone));
   3762 
   3763 	if (zone->privatetype == 0) {
   3764 		return;
   3765 	}
   3766 
   3767 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3768 	if (zone->db != NULL) {
   3769 		dns_db_attach(zone->db, &db);
   3770 	}
   3771 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3772 	if (db == NULL) {
   3773 		goto cleanup;
   3774 	}
   3775 
   3776 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3777 	if (result != ISC_R_SUCCESS) {
   3778 		goto cleanup;
   3779 	}
   3780 
   3781 	dns_db_currentversion(db, &version);
   3782 
   3783 	/*
   3784 	 * In order to create NSEC3 chains we need the DNSKEY RRset at zone
   3785 	 * apex to exist and contain no keys using NSEC-only algorithms.
   3786 	 */
   3787 	result = dns_nsec_nseconly(db, version, &nseconly);
   3788 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   3789 
   3790 	/*
   3791 	 * Get the RRset containing all private-type records at the zone apex.
   3792 	 */
   3793 	dns_rdataset_init(&rdataset);
   3794 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   3795 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3796 	if (result != ISC_R_SUCCESS) {
   3797 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3798 		goto cleanup;
   3799 	}
   3800 
   3801 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3802 	     result = dns_rdataset_next(&rdataset))
   3803 	{
   3804 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   3805 		dns_rdata_t rdata = DNS_RDATA_INIT;
   3806 		dns_rdata_t private = DNS_RDATA_INIT;
   3807 
   3808 		dns_rdataset_current(&rdataset, &private);
   3809 		/*
   3810 		 * Try extracting NSEC3PARAM RDATA from this private-type
   3811 		 * record.  Failure means this private-type record does not
   3812 		 * represent an NSEC3PARAM record, so skip it.
   3813 		 */
   3814 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   3815 						sizeof(buf))) {
   3816 			continue;
   3817 		}
   3818 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3819 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   3820 		if (((nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) ||
   3821 		    ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 && nsec3ok))
   3822 		{
   3823 			/*
   3824 			 * Pass the NSEC3PARAM RDATA contained in this
   3825 			 * private-type record to zone_addnsec3chain() so that
   3826 			 * it can kick off adding or removing NSEC3 records.
   3827 			 */
   3828 			result = zone_addnsec3chain(zone, &nsec3param);
   3829 			if (result != ISC_R_SUCCESS) {
   3830 				dnssec_log(zone, ISC_LOG_ERROR,
   3831 					   "zone_addnsec3chain failed: %s",
   3832 					   dns_result_totext(result));
   3833 			}
   3834 		}
   3835 	}
   3836 	dns_rdataset_disassociate(&rdataset);
   3837 
   3838 cleanup:
   3839 	if (db != NULL) {
   3840 		if (node != NULL) {
   3841 			dns_db_detachnode(db, &node);
   3842 		}
   3843 		if (version != NULL) {
   3844 			dns_db_closeversion(db, &version, false);
   3845 		}
   3846 		dns_db_detach(&db);
   3847 	}
   3848 }
   3849 
   3850 static void
   3851 set_resigntime(dns_zone_t *zone) {
   3852 	dns_rdataset_t rdataset;
   3853 	dns_fixedname_t fixed;
   3854 	unsigned int resign;
   3855 	isc_result_t result;
   3856 	uint32_t nanosecs;
   3857 	dns_db_t *db = NULL;
   3858 
   3859 	INSIST(LOCKED_ZONE(zone));
   3860 
   3861 	/* We only re-sign zones that can be dynamically updated */
   3862 	if (zone->update_disabled) {
   3863 		return;
   3864 	}
   3865 
   3866 	if (!inline_secure(zone) &&
   3867 	    (zone->type != dns_zone_master ||
   3868 	     (zone->ssutable == NULL &&
   3869 	      (zone->update_acl == NULL || dns_acl_isnone(zone->update_acl)))))
   3870 	{
   3871 		return;
   3872 	}
   3873 
   3874 	dns_rdataset_init(&rdataset);
   3875 	dns_fixedname_init(&fixed);
   3876 
   3877 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   3878 	if (zone->db != NULL) {
   3879 		dns_db_attach(zone->db, &db);
   3880 	}
   3881 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   3882 	if (db == NULL) {
   3883 		isc_time_settoepoch(&zone->resigntime);
   3884 		return;
   3885 	}
   3886 
   3887 	result = dns_db_getsigningtime(db, &rdataset,
   3888 				       dns_fixedname_name(&fixed));
   3889 	if (result != ISC_R_SUCCESS) {
   3890 		isc_time_settoepoch(&zone->resigntime);
   3891 		goto cleanup;
   3892 	}
   3893 
   3894 	resign = rdataset.resign - dns_zone_getsigresigninginterval(zone);
   3895 	dns_rdataset_disassociate(&rdataset);
   3896 	nanosecs = isc_random_uniform(1000000000);
   3897 	isc_time_set(&zone->resigntime, resign, nanosecs);
   3898 
   3899 cleanup:
   3900 	dns_db_detach(&db);
   3901 	return;
   3902 }
   3903 
   3904 static isc_result_t
   3905 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
   3906 	dns_dbnode_t *node = NULL;
   3907 	dns_rdataset_t rdataset;
   3908 	dns_dbversion_t *version = NULL;
   3909 	dns_rdata_nsec3param_t nsec3param;
   3910 	bool ok = false;
   3911 	isc_result_t result;
   3912 	dns_rdata_t rdata = DNS_RDATA_INIT;
   3913 	bool dynamic = (zone->type == dns_zone_master)
   3914 			       ? dns_zone_isdynamic(zone, false)
   3915 			       : false;
   3916 
   3917 	dns_rdataset_init(&rdataset);
   3918 	result = dns_db_findnode(db, &zone->origin, false, &node);
   3919 	if (result != ISC_R_SUCCESS) {
   3920 		dns_zone_log(zone, ISC_LOG_ERROR,
   3921 			     "nsec3param lookup failure: %s",
   3922 			     dns_result_totext(result));
   3923 		return (result);
   3924 	}
   3925 	dns_db_currentversion(db, &version);
   3926 
   3927 	result = dns_db_findrdataset(db, node, version,
   3928 				     dns_rdatatype_nsec3param,
   3929 				     dns_rdatatype_none, 0, &rdataset, NULL);
   3930 	if (result == ISC_R_NOTFOUND) {
   3931 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3932 		result = ISC_R_SUCCESS;
   3933 		goto cleanup;
   3934 	}
   3935 	if (result != ISC_R_SUCCESS) {
   3936 		INSIST(!dns_rdataset_isassociated(&rdataset));
   3937 		dns_zone_log(zone, ISC_LOG_ERROR,
   3938 			     "nsec3param lookup failure: %s",
   3939 			     dns_result_totext(result));
   3940 		goto cleanup;
   3941 	}
   3942 
   3943 	/*
   3944 	 * For dynamic zones we must support every algorithm so we can
   3945 	 * regenerate all the NSEC3 chains.
   3946 	 * For non-dynamic zones we only need to find a supported algorithm.
   3947 	 */
   3948 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   3949 	     result = dns_rdataset_next(&rdataset))
   3950 	{
   3951 		dns_rdataset_current(&rdataset, &rdata);
   3952 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   3953 		dns_rdata_reset(&rdata);
   3954 		INSIST(result == ISC_R_SUCCESS);
   3955 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
   3956 		    nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
   3957 		{
   3958 			dns_zone_log(zone, ISC_LOG_WARNING,
   3959 				     "nsec3 test \"unknown\" hash algorithm "
   3960 				     "found: %u",
   3961 				     nsec3param.hash);
   3962 			ok = true;
   3963 		} else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
   3964 			if (dynamic) {
   3965 				dns_zone_log(zone, ISC_LOG_ERROR,
   3966 					     "unsupported nsec3 hash algorithm"
   3967 					     " in dynamic zone: %u",
   3968 					     nsec3param.hash);
   3969 				result = DNS_R_BADZONE;
   3970 				/* Stop second error message. */
   3971 				ok = true;
   3972 				break;
   3973 			} else {
   3974 				dns_zone_log(zone, ISC_LOG_WARNING,
   3975 					     "unsupported nsec3 hash "
   3976 					     "algorithm: %u",
   3977 					     nsec3param.hash);
   3978 			}
   3979 		} else {
   3980 			ok = true;
   3981 		}
   3982 	}
   3983 	if (result == ISC_R_NOMORE) {
   3984 		result = ISC_R_SUCCESS;
   3985 	}
   3986 
   3987 	if (!ok) {
   3988 		result = DNS_R_BADZONE;
   3989 		dns_zone_log(zone, ISC_LOG_ERROR,
   3990 			     "no supported nsec3 hash algorithm");
   3991 	}
   3992 
   3993 cleanup:
   3994 	if (dns_rdataset_isassociated(&rdataset)) {
   3995 		dns_rdataset_disassociate(&rdataset);
   3996 	}
   3997 	dns_db_closeversion(db, &version, false);
   3998 	dns_db_detachnode(db, &node);
   3999 	return (result);
   4000 }
   4001 
   4002 /*
   4003  * Set the timer for refreshing the key zone to the soonest future time
   4004  * of the set (current timer, keydata->refresh, keydata->addhd,
   4005  * keydata->removehd).
   4006  */
   4007 static void
   4008 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
   4009 		    isc_stdtime_t now, bool force) {
   4010 	const char me[] = "set_refreshkeytimer";
   4011 	isc_stdtime_t then;
   4012 	isc_time_t timenow, timethen;
   4013 	char timebuf[80];
   4014 
   4015 	ENTER;
   4016 	then = key->refresh;
   4017 	if (force) {
   4018 		then = now;
   4019 	}
   4020 	if (key->addhd > now && key->addhd < then) {
   4021 		then = key->addhd;
   4022 	}
   4023 	if (key->removehd > now && key->removehd < then) {
   4024 		then = key->removehd;
   4025 	}
   4026 
   4027 	TIME_NOW(&timenow);
   4028 	if (then > now) {
   4029 		DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   4030 	} else {
   4031 		timethen = timenow;
   4032 	}
   4033 	if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
   4034 	    isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
   4035 	{
   4036 		zone->refreshkeytime = timethen;
   4037 	}
   4038 
   4039 	isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   4040 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
   4041 	zone_settimer(zone, &timenow);
   4042 }
   4043 
   4044 /*
   4045  * If keynode references a key or a DS rdataset, and if the key
   4046  * zone does not contain a KEYDATA record for the corresponding name,
   4047  * then create an empty KEYDATA and push it into the zone as a placeholder,
   4048  * then schedule a key refresh immediately. This new KEYDATA record will be
   4049  * updated during the refresh.
   4050  *
   4051  * If the key zone is changed, set '*changed' to true.
   4052  */
   4053 static isc_result_t
   4054 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4055 	       dns_diff_t *diff, dns_keynode_t *keynode, dns_name_t *keyname,
   4056 	       bool *changed) {
   4057 	const char me[] = "create_keydata";
   4058 	isc_result_t result = ISC_R_SUCCESS;
   4059 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4060 	dns_rdata_keydata_t kd;
   4061 	unsigned char rrdata[4096];
   4062 	isc_buffer_t rrdatabuf;
   4063 	isc_stdtime_t now;
   4064 
   4065 	REQUIRE(keynode != NULL);
   4066 
   4067 	ENTER;
   4068 	isc_stdtime_get(&now);
   4069 
   4070 	/*
   4071 	 * If the keynode has no trust anchor set, we shouldn't be here.
   4072 	 */
   4073 	if (!dns_keynode_dsset(keynode, NULL)) {
   4074 		return (ISC_R_FAILURE);
   4075 	}
   4076 
   4077 	memset(&kd, 0, sizeof(kd));
   4078 	kd.common.rdclass = zone->rdclass;
   4079 	kd.common.rdtype = dns_rdatatype_keydata;
   4080 	ISC_LINK_INIT(&kd.common, link);
   4081 
   4082 	isc_buffer_init(&rrdatabuf, rrdata, sizeof(rrdata));
   4083 
   4084 	CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass, dns_rdatatype_keydata,
   4085 				   &kd, &rrdatabuf));
   4086 	/* Add rdata to zone. */
   4087 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, keyname, 0, &rdata));
   4088 	*changed = true;
   4089 
   4090 	/* Refresh new keys from the zone apex as soon as possible. */
   4091 	set_refreshkeytimer(zone, &kd, now, true);
   4092 	return (ISC_R_SUCCESS);
   4093 
   4094 failure:
   4095 	return (result);
   4096 }
   4097 
   4098 /*
   4099  * Remove from the key zone all the KEYDATA records found in rdataset.
   4100  */
   4101 static isc_result_t
   4102 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4103 	       dns_name_t *name, dns_rdataset_t *rdataset) {
   4104 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4105 	isc_result_t result, uresult;
   4106 
   4107 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4108 	     result = dns_rdataset_next(rdataset))
   4109 	{
   4110 		dns_rdata_reset(&rdata);
   4111 		dns_rdataset_current(rdataset, &rdata);
   4112 		uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name, 0,
   4113 					&rdata);
   4114 		if (uresult != ISC_R_SUCCESS) {
   4115 			return (uresult);
   4116 		}
   4117 	}
   4118 	if (result == ISC_R_NOMORE) {
   4119 		result = ISC_R_SUCCESS;
   4120 	}
   4121 	return (result);
   4122 }
   4123 
   4124 /*
   4125  * Compute the DNSSEC key ID for a DNSKEY record.
   4126  */
   4127 static isc_result_t
   4128 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
   4129 	    dns_keytag_t *tag) {
   4130 	isc_result_t result;
   4131 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4132 	unsigned char data[4096];
   4133 	isc_buffer_t buffer;
   4134 	dst_key_t *dstkey = NULL;
   4135 
   4136 	isc_buffer_init(&buffer, data, sizeof(data));
   4137 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4138 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4139 
   4140 	result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
   4141 	if (result == ISC_R_SUCCESS) {
   4142 		*tag = dst_key_id(dstkey);
   4143 		dst_key_free(&dstkey);
   4144 	}
   4145 
   4146 	return (result);
   4147 }
   4148 
   4149 /*
   4150  * Add key to the security roots.
   4151  */
   4152 static void
   4153 trust_key(dns_zone_t *zone, dns_name_t *keyname, dns_rdata_dnskey_t *dnskey,
   4154 	  bool initial) {
   4155 	isc_result_t result;
   4156 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4157 	unsigned char data[4096], digest[ISC_MAX_MD_SIZE];
   4158 	isc_buffer_t buffer;
   4159 	dns_keytable_t *sr = NULL;
   4160 	dns_rdata_ds_t ds;
   4161 
   4162 	result = dns_view_getsecroots(zone->view, &sr);
   4163 	if (result != ISC_R_SUCCESS) {
   4164 		return;
   4165 	}
   4166 
   4167 	/* Build DS record for key. */
   4168 	isc_buffer_init(&buffer, data, sizeof(data));
   4169 	dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
   4170 			     dns_rdatatype_dnskey, dnskey, &buffer);
   4171 	CHECK(dns_ds_fromkeyrdata(keyname, &rdata, DNS_DSDIGEST_SHA256, digest,
   4172 				  &ds));
   4173 	CHECK(dns_keytable_add(sr, true, initial, keyname, &ds));
   4174 
   4175 	dns_keytable_detach(&sr);
   4176 
   4177 failure:
   4178 	if (sr != NULL) {
   4179 		dns_keytable_detach(&sr);
   4180 	}
   4181 	return;
   4182 }
   4183 
   4184 /*
   4185  * Add a null key to the security roots for so that all queries
   4186  * to the zone will fail.
   4187  */
   4188 static void
   4189 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
   4190 	isc_result_t result;
   4191 	dns_keytable_t *sr = NULL;
   4192 
   4193 	result = dns_view_getsecroots(zone->view, &sr);
   4194 	if (result == ISC_R_SUCCESS) {
   4195 		dns_keytable_marksecure(sr, keyname);
   4196 		dns_keytable_detach(&sr);
   4197 	}
   4198 }
   4199 
   4200 /*
   4201  * Scan a set of KEYDATA records from the key zone.  The ones that are
   4202  * valid (i.e., the add holddown timer has expired) become trusted keys.
   4203  */
   4204 static void
   4205 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
   4206 	isc_result_t result;
   4207 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4208 	dns_rdata_keydata_t keydata;
   4209 	dns_rdata_dnskey_t dnskey;
   4210 	int trusted = 0, revoked = 0, pending = 0;
   4211 	isc_stdtime_t now;
   4212 	dns_keytable_t *sr = NULL;
   4213 
   4214 	isc_stdtime_get(&now);
   4215 
   4216 	result = dns_view_getsecroots(zone->view, &sr);
   4217 	if (result == ISC_R_SUCCESS) {
   4218 		dns_keytable_delete(sr, name);
   4219 		dns_keytable_detach(&sr);
   4220 	}
   4221 
   4222 	/* Now insert all the accepted trust anchors from this keydata set. */
   4223 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   4224 	     result = dns_rdataset_next(rdataset))
   4225 	{
   4226 		dns_rdata_reset(&rdata);
   4227 		dns_rdataset_current(rdataset, &rdata);
   4228 
   4229 		/* Convert rdata to keydata. */
   4230 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   4231 		if (result == ISC_R_UNEXPECTEDEND) {
   4232 			continue;
   4233 		}
   4234 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4235 
   4236 		/* Set the key refresh timer to force a fast refresh. */
   4237 		set_refreshkeytimer(zone, &keydata, now, true);
   4238 
   4239 		/* If the removal timer is nonzero, this key was revoked. */
   4240 		if (keydata.removehd != 0) {
   4241 			revoked++;
   4242 			continue;
   4243 		}
   4244 
   4245 		/*
   4246 		 * If the add timer is still pending, this key is not
   4247 		 * trusted yet.
   4248 		 */
   4249 		if (now < keydata.addhd) {
   4250 			pending++;
   4251 			continue;
   4252 		}
   4253 
   4254 		/* Convert keydata to dnskey. */
   4255 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   4256 
   4257 		/* Add to keytables. */
   4258 		trusted++;
   4259 		trust_key(zone, name, &dnskey, (keydata.addhd == 0));
   4260 	}
   4261 
   4262 	if (trusted == 0 && pending != 0) {
   4263 		char namebuf[DNS_NAME_FORMATSIZE];
   4264 		dns_name_format(name, namebuf, sizeof namebuf);
   4265 		dnssec_log(zone, ISC_LOG_ERROR,
   4266 			   "No valid trust anchors for '%s'!", namebuf);
   4267 		dnssec_log(zone, ISC_LOG_ERROR,
   4268 			   "%d key(s) revoked, %d still pending", revoked,
   4269 			   pending);
   4270 		dnssec_log(zone, ISC_LOG_ERROR, "All queries to '%s' will fail",
   4271 			   namebuf);
   4272 		fail_secure(zone, name);
   4273 	}
   4274 }
   4275 
   4276 static isc_result_t
   4277 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
   4278 	     dns_diff_t *diff) {
   4279 	dns_diff_t temp_diff;
   4280 	isc_result_t result;
   4281 
   4282 	/*
   4283 	 * Create a singleton diff.
   4284 	 */
   4285 	dns_diff_init(diff->mctx, &temp_diff);
   4286 	ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
   4287 
   4288 	/*
   4289 	 * Apply it to the database.
   4290 	 */
   4291 	result = dns_diff_apply(&temp_diff, db, ver);
   4292 	ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
   4293 	if (result != ISC_R_SUCCESS) {
   4294 		dns_difftuple_free(tuple);
   4295 		return (result);
   4296 	}
   4297 
   4298 	/*
   4299 	 * Merge it into the current pending journal entry.
   4300 	 */
   4301 	dns_diff_appendminimal(diff, tuple);
   4302 
   4303 	/*
   4304 	 * Do not clear temp_diff.
   4305 	 */
   4306 	return (ISC_R_SUCCESS);
   4307 }
   4308 
   4309 static isc_result_t
   4310 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
   4311 	      dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
   4312 	      dns_rdata_t *rdata) {
   4313 	dns_difftuple_t *tuple = NULL;
   4314 	isc_result_t result;
   4315 	result = dns_difftuple_create(diff->mctx, op, name, ttl, rdata, &tuple);
   4316 	if (result != ISC_R_SUCCESS) {
   4317 		return (result);
   4318 	}
   4319 	return (do_one_tuple(&tuple, db, ver, diff));
   4320 }
   4321 
   4322 static isc_result_t
   4323 update_soa_serial(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   4324 		  dns_diff_t *diff, isc_mem_t *mctx,
   4325 		  dns_updatemethod_t method) {
   4326 	dns_difftuple_t *deltuple = NULL;
   4327 	dns_difftuple_t *addtuple = NULL;
   4328 	uint32_t serial;
   4329 	isc_result_t result;
   4330 	dns_updatemethod_t used = dns_updatemethod_none;
   4331 
   4332 	INSIST(method != dns_updatemethod_none);
   4333 
   4334 	CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
   4335 	CHECK(dns_difftuple_copy(deltuple, &addtuple));
   4336 	addtuple->op = DNS_DIFFOP_ADD;
   4337 
   4338 	serial = dns_soa_getserial(&addtuple->rdata);
   4339 	serial = dns_update_soaserial(serial, method, &used);
   4340 	if (method != used) {
   4341 		dns_zone_log(zone, ISC_LOG_WARNING,
   4342 			     "update_soa_serial:new serial would be lower than "
   4343 			     "old serial, using increment method instead");
   4344 	}
   4345 	dns_soa_setserial(serial, &addtuple->rdata);
   4346 	CHECK(do_one_tuple(&deltuple, db, ver, diff));
   4347 	CHECK(do_one_tuple(&addtuple, db, ver, diff));
   4348 	result = ISC_R_SUCCESS;
   4349 
   4350 failure:
   4351 	if (addtuple != NULL) {
   4352 		dns_difftuple_free(&addtuple);
   4353 	}
   4354 	if (deltuple != NULL) {
   4355 		dns_difftuple_free(&deltuple);
   4356 	}
   4357 	return (result);
   4358 }
   4359 
   4360 /*
   4361  * Write all transactions in 'diff' to the zone journal file.
   4362  */
   4363 static isc_result_t
   4364 zone_journal(dns_zone_t *zone, dns_diff_t *diff, uint32_t *sourceserial,
   4365 	     const char *caller) {
   4366 	const char me[] = "zone_journal";
   4367 	const char *journalfile;
   4368 	isc_result_t result = ISC_R_SUCCESS;
   4369 	dns_journal_t *journal = NULL;
   4370 	unsigned int mode = DNS_JOURNAL_CREATE | DNS_JOURNAL_WRITE;
   4371 
   4372 	ENTER;
   4373 	journalfile = dns_zone_getjournal(zone);
   4374 	if (journalfile != NULL) {
   4375 		result = dns_journal_open(zone->mctx, journalfile, mode,
   4376 					  &journal);
   4377 		if (result != ISC_R_SUCCESS) {
   4378 			dns_zone_log(zone, ISC_LOG_ERROR,
   4379 				     "%s:dns_journal_open -> %s", caller,
   4380 				     dns_result_totext(result));
   4381 			return (result);
   4382 		}
   4383 
   4384 		if (sourceserial != NULL) {
   4385 			dns_journal_set_sourceserial(journal, *sourceserial);
   4386 		}
   4387 
   4388 		result = dns_journal_write_transaction(journal, diff);
   4389 		if (result != ISC_R_SUCCESS) {
   4390 			dns_zone_log(zone, ISC_LOG_ERROR,
   4391 				     "%s:dns_journal_write_transaction -> %s",
   4392 				     caller, dns_result_totext(result));
   4393 		}
   4394 		dns_journal_destroy(&journal);
   4395 	}
   4396 
   4397 	return (result);
   4398 }
   4399 
   4400 /*
   4401  * Create an SOA record for a newly-created zone
   4402  */
   4403 static isc_result_t
   4404 add_soa(dns_zone_t *zone, dns_db_t *db) {
   4405 	isc_result_t result;
   4406 	dns_rdata_t rdata = DNS_RDATA_INIT;
   4407 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   4408 	dns_dbversion_t *ver = NULL;
   4409 	dns_diff_t diff;
   4410 
   4411 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
   4412 
   4413 	dns_diff_init(zone->mctx, &diff);
   4414 	result = dns_db_newversion(db, &ver);
   4415 	if (result != ISC_R_SUCCESS) {
   4416 		dns_zone_log(zone, ISC_LOG_ERROR,
   4417 			     "add_soa:dns_db_newversion -> %s",
   4418 			     dns_result_totext(result));
   4419 		goto failure;
   4420 	}
   4421 
   4422 	/* Build SOA record */
   4423 	result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
   4424 				    0, 0, 0, 0, 0, buf, &rdata);
   4425 	if (result != ISC_R_SUCCESS) {
   4426 		dns_zone_log(zone, ISC_LOG_ERROR,
   4427 			     "add_soa:dns_soa_buildrdata -> %s",
   4428 			     dns_result_totext(result));
   4429 		goto failure;
   4430 	}
   4431 
   4432 	result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD, &zone->origin, 0,
   4433 			       &rdata);
   4434 
   4435 failure:
   4436 	dns_diff_clear(&diff);
   4437 	if (ver != NULL) {
   4438 		dns_db_closeversion(db, &ver, (result == ISC_R_SUCCESS));
   4439 	}
   4440 
   4441 	INSIST(ver == NULL);
   4442 
   4443 	return (result);
   4444 }
   4445 
   4446 struct addifmissing_arg {
   4447 	dns_db_t *db;
   4448 	dns_dbversion_t *ver;
   4449 	dns_diff_t *diff;
   4450 	dns_zone_t *zone;
   4451 	bool *changed;
   4452 	isc_result_t result;
   4453 };
   4454 
   4455 static void
   4456 addifmissing(dns_keytable_t *keytable, dns_keynode_t *keynode,
   4457 	     dns_name_t *keyname, void *arg) {
   4458 	dns_db_t *db = ((struct addifmissing_arg *)arg)->db;
   4459 	dns_dbversion_t *ver = ((struct addifmissing_arg *)arg)->ver;
   4460 	dns_diff_t *diff = ((struct addifmissing_arg *)arg)->diff;
   4461 	dns_zone_t *zone = ((struct addifmissing_arg *)arg)->zone;
   4462 	bool *changed = ((struct addifmissing_arg *)arg)->changed;
   4463 	isc_result_t result;
   4464 	dns_fixedname_t fname;
   4465 
   4466 	UNUSED(keytable);
   4467 
   4468 	if (((struct addifmissing_arg *)arg)->result != ISC_R_SUCCESS) {
   4469 		return;
   4470 	}
   4471 
   4472 	if (!dns_keynode_managed(keynode)) {
   4473 		return;
   4474 	}
   4475 
   4476 	/*
   4477 	 * If the keynode has no trust anchor set, return.
   4478 	 */
   4479 	if (!dns_keynode_dsset(keynode, NULL)) {
   4480 		return;
   4481 	}
   4482 
   4483 	/*
   4484 	 * Check whether there's already a KEYDATA entry for this name;
   4485 	 * if so, we don't need to add another.
   4486 	 */
   4487 	dns_fixedname_init(&fname);
   4488 	result = dns_db_find(db, keyname, ver, dns_rdatatype_keydata,
   4489 			     DNS_DBFIND_NOWILD, 0, NULL,
   4490 			     dns_fixedname_name(&fname), NULL, NULL);
   4491 	if (result == ISC_R_SUCCESS) {
   4492 		return;
   4493 	}
   4494 
   4495 	/*
   4496 	 * Create the keydata.
   4497 	 */
   4498 	result = create_keydata(zone, db, ver, diff, keynode, keyname, changed);
   4499 	if (result != ISC_R_SUCCESS && result != ISC_R_NOMORE) {
   4500 		((struct addifmissing_arg *)arg)->result = result;
   4501 	}
   4502 }
   4503 
   4504 /*
   4505  * Synchronize the set of initializing keys found in managed-keys {}
   4506  * statements with the set of trust anchors found in the managed-keys.bind
   4507  * zone.  If a domain is no longer named in managed-keys, delete all keys
   4508  * from that domain from the key zone.	If a domain is configured as an
   4509  * initial-key in trust-anchors, but there are no references to it in the
   4510  * key zone, load the key zone with the initializing key(s) for that
   4511  * domain and schedule a key refresh. If a domain is configured as
   4512  * an initial-ds in trust-anchors, fetch the DNSKEY RRset, load the key
   4513  * zone with the matching key, and schedule a key refresh.
   4514  */
   4515 static isc_result_t
   4516 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
   4517 	isc_result_t result = ISC_R_SUCCESS;
   4518 	bool changed = false;
   4519 	bool commit = false;
   4520 	dns_keynode_t *keynode = NULL;
   4521 	dns_view_t *view = zone->view;
   4522 	dns_keytable_t *sr = NULL;
   4523 	dns_dbversion_t *ver = NULL;
   4524 	dns_diff_t diff;
   4525 	dns_rriterator_t rrit;
   4526 	struct addifmissing_arg arg;
   4527 
   4528 	dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
   4529 
   4530 	dns_diff_init(zone->mctx, &diff);
   4531 
   4532 	CHECK(dns_view_getsecroots(view, &sr));
   4533 
   4534 	result = dns_db_newversion(db, &ver);
   4535 	if (result != ISC_R_SUCCESS) {
   4536 		dnssec_log(zone, ISC_LOG_ERROR,
   4537 			   "sync_keyzone:dns_db_newversion -> %s",
   4538 			   dns_result_totext(result));
   4539 		goto failure;
   4540 	}
   4541 
   4542 	/*
   4543 	 * Walk the zone DB.  If we find any keys whose names are no longer
   4544 	 * in trust-anchors, or which have been changed from initial to static,
   4545 	 * (meaning they are permanent and not RFC5011-maintained), delete
   4546 	 * them from the zone.  Otherwise call load_secroots(), which
   4547 	 * loads keys into secroots as appropriate.
   4548 	 */
   4549 	dns_rriterator_init(&rrit, db, ver, 0);
   4550 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   4551 	     result = dns_rriterator_nextrrset(&rrit))
   4552 	{
   4553 		dns_rdataset_t *rdataset = NULL;
   4554 		dns_name_t *rrname = NULL;
   4555 		uint32_t ttl;
   4556 
   4557 		dns_rriterator_current(&rrit, &rrname, &ttl, &rdataset, NULL);
   4558 		if (!dns_rdataset_isassociated(rdataset)) {
   4559 			dns_rriterator_destroy(&rrit);
   4560 			goto failure;
   4561 		}
   4562 
   4563 		if (rdataset->type != dns_rdatatype_keydata) {
   4564 			continue;
   4565 		}
   4566 		/*
   4567 		 * Release db wrlock to prevent LOR reports against
   4568 		 * dns_keytable_forall() call below.
   4569 		 */
   4570 		dns_rriterator_pause(&rrit);
   4571 		result = dns_keytable_find(sr, rrname, &keynode);
   4572 		if (result != ISC_R_SUCCESS || !dns_keynode_managed(keynode)) {
   4573 			CHECK(delete_keydata(db, ver, &diff, rrname, rdataset));
   4574 			changed = true;
   4575 		} else {
   4576 			load_secroots(zone, rrname, rdataset);
   4577 		}
   4578 
   4579 		if (keynode != NULL) {
   4580 			dns_keytable_detachkeynode(sr, &keynode);
   4581 		}
   4582 	}
   4583 	dns_rriterator_destroy(&rrit);
   4584 
   4585 	/*
   4586 	 * Walk secroots to find any initial keys that aren't in
   4587 	 * the zone.  If we find any, add them to the zone directly.
   4588 	 * If any DS-style initial keys are found, refresh the key
   4589 	 * zone so that they'll be looked up.
   4590 	 */
   4591 	arg.db = db;
   4592 	arg.ver = ver;
   4593 	arg.result = ISC_R_SUCCESS;
   4594 	arg.diff = &diff;
   4595 	arg.zone = zone;
   4596 	arg.changed = &changed;
   4597 	dns_keytable_forall(sr, addifmissing, &arg);
   4598 	result = arg.result;
   4599 	if (changed) {
   4600 		/* Write changes to journal file. */
   4601 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   4602 					zone->updatemethod));
   4603 		CHECK(zone_journal(zone, &diff, NULL, "sync_keyzone"));
   4604 
   4605 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   4606 		zone_needdump(zone, 30);
   4607 		commit = true;
   4608 	}
   4609 
   4610 failure:
   4611 	if (result != ISC_R_SUCCESS && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4612 	{
   4613 		dnssec_log(zone, ISC_LOG_ERROR,
   4614 			   "unable to synchronize managed keys: %s",
   4615 			   dns_result_totext(result));
   4616 		isc_time_settoepoch(&zone->refreshkeytime);
   4617 	}
   4618 	if (keynode != NULL) {
   4619 		dns_keytable_detachkeynode(sr, &keynode);
   4620 	}
   4621 	if (sr != NULL) {
   4622 		dns_keytable_detach(&sr);
   4623 	}
   4624 	if (ver != NULL) {
   4625 		dns_db_closeversion(db, &ver, commit);
   4626 	}
   4627 	dns_diff_clear(&diff);
   4628 
   4629 	INSIST(ver == NULL);
   4630 
   4631 	return (result);
   4632 }
   4633 
   4634 isc_result_t
   4635 dns_zone_synckeyzone(dns_zone_t *zone) {
   4636 	isc_result_t result;
   4637 	dns_db_t *db = NULL;
   4638 
   4639 	if (zone->type != dns_zone_key) {
   4640 		return (DNS_R_BADZONE);
   4641 	}
   4642 
   4643 	CHECK(dns_zone_getdb(zone, &db));
   4644 
   4645 	LOCK_ZONE(zone);
   4646 	result = sync_keyzone(zone, db);
   4647 	UNLOCK_ZONE(zone);
   4648 
   4649 failure:
   4650 	if (db != NULL) {
   4651 		dns_db_detach(&db);
   4652 	}
   4653 	return (result);
   4654 }
   4655 
   4656 static void
   4657 maybe_send_secure(dns_zone_t *zone) {
   4658 	isc_result_t result;
   4659 
   4660 	/*
   4661 	 * We've finished loading, or else failed to load, an inline-signing
   4662 	 * 'secure' zone.  We now need information about the status of the
   4663 	 * 'raw' zone.  If we failed to load, then we need it to send a
   4664 	 * copy of its database; if we succeeded, we need it to send its
   4665 	 * serial number so that we can sync with it.  If it has not yet
   4666 	 * loaded, we set a flag so that it will send the necessary
   4667 	 * information when it has finished loading.
   4668 	 */
   4669 	if (zone->raw->db != NULL) {
   4670 		if (zone->db != NULL) {
   4671 			uint32_t serial;
   4672 			unsigned int soacount;
   4673 
   4674 			result = zone_get_from_db(zone->raw, zone->raw->db,
   4675 						  NULL, &soacount, &serial,
   4676 						  NULL, NULL, NULL, NULL, NULL);
   4677 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   4678 				zone_send_secureserial(zone->raw, serial);
   4679 			}
   4680 		} else {
   4681 			zone_send_securedb(zone->raw, zone->raw->db);
   4682 		}
   4683 	} else {
   4684 		DNS_ZONE_SETFLAG(zone->raw, DNS_ZONEFLG_SENDSECURE);
   4685 	}
   4686 }
   4687 
   4688 static bool
   4689 zone_unchanged(dns_db_t *db1, dns_db_t *db2, isc_mem_t *mctx) {
   4690 	isc_result_t result;
   4691 	bool answer = false;
   4692 	dns_diff_t diff;
   4693 
   4694 	dns_diff_init(mctx, &diff);
   4695 	result = dns_db_diffx(&diff, db1, NULL, db2, NULL, NULL);
   4696 	if (result == ISC_R_SUCCESS && ISC_LIST_EMPTY(diff.tuples)) {
   4697 		answer = true;
   4698 	}
   4699 	dns_diff_clear(&diff);
   4700 	return (answer);
   4701 }
   4702 
   4703 /*
   4704  * The zone is presumed to be locked.
   4705  * If this is a inline_raw zone the secure version is also locked.
   4706  */
   4707 static isc_result_t
   4708 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
   4709 	      isc_result_t result) {
   4710 	unsigned int soacount = 0;
   4711 	unsigned int nscount = 0;
   4712 	unsigned int errors = 0;
   4713 	uint32_t serial, oldserial, refresh, retry, expire, minimum;
   4714 	isc_time_t now;
   4715 	bool needdump = false;
   4716 	bool hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4717 	bool nomaster = false;
   4718 	bool had_db = false;
   4719 	unsigned int options;
   4720 	dns_include_t *inc;
   4721 	bool is_dynamic = false;
   4722 
   4723 	INSIST(LOCKED_ZONE(zone));
   4724 	if (inline_raw(zone)) {
   4725 		INSIST(LOCKED_ZONE(zone->secure));
   4726 	}
   4727 
   4728 	TIME_NOW(&now);
   4729 
   4730 	/*
   4731 	 * Initiate zone transfer?  We may need a error code that
   4732 	 * indicates that the "permanent" form does not exist.
   4733 	 * XXX better error feedback to log.
   4734 	 */
   4735 	if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
   4736 		if (zone->type == dns_zone_slave ||
   4737 		    zone->type == dns_zone_mirror ||
   4738 		    zone->type == dns_zone_stub ||
   4739 		    (zone->type == dns_zone_redirect && zone->masters == NULL))
   4740 		{
   4741 			if (result == ISC_R_FILENOTFOUND) {
   4742 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4743 					      ISC_LOG_DEBUG(1),
   4744 					      "no master file");
   4745 			} else if (result != DNS_R_NOMASTERFILE) {
   4746 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4747 					      ISC_LOG_ERROR,
   4748 					      "loading from master file %s "
   4749 					      "failed: %s",
   4750 					      zone->masterfile,
   4751 					      dns_result_totext(result));
   4752 			}
   4753 		} else if (zone->type == dns_zone_master &&
   4754 			   inline_secure(zone) && result == ISC_R_FILENOTFOUND)
   4755 		{
   4756 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4757 				      ISC_LOG_DEBUG(1),
   4758 				      "no master file, requesting db");
   4759 			maybe_send_secure(zone);
   4760 		} else {
   4761 			int level = ISC_LOG_ERROR;
   4762 			if (zone->type == dns_zone_key &&
   4763 			    result == ISC_R_FILENOTFOUND) {
   4764 				level = ISC_LOG_DEBUG(1);
   4765 			}
   4766 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, level,
   4767 				      "loading from master file %s failed: %s",
   4768 				      zone->masterfile,
   4769 				      dns_result_totext(result));
   4770 			nomaster = true;
   4771 		}
   4772 
   4773 		if (zone->type != dns_zone_key) {
   4774 			goto cleanup;
   4775 		}
   4776 	}
   4777 
   4778 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(2),
   4779 		      "number of nodes in database: %u", dns_db_nodecount(db));
   4780 
   4781 	if (result == DNS_R_SEENINCLUDE) {
   4782 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4783 	} else {
   4784 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
   4785 	}
   4786 
   4787 	/*
   4788 	 * If there's no master file for a key zone, then the zone is new:
   4789 	 * create an SOA record.  (We do this now, instead of later, so that
   4790 	 * if there happens to be a journal file, we can roll forward from
   4791 	 * a sane starting point.)
   4792 	 */
   4793 	if (nomaster && zone->type == dns_zone_key) {
   4794 		result = add_soa(zone, db);
   4795 		if (result != ISC_R_SUCCESS) {
   4796 			goto cleanup;
   4797 		}
   4798 	}
   4799 
   4800 	/*
   4801 	 * Apply update log, if any, on initial load.
   4802 	 */
   4803 	if (zone->journal != NULL &&
   4804 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
   4805 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   4806 	{
   4807 		if (zone->type == dns_zone_master &&
   4808 		    (inline_secure(zone) ||
   4809 		     (zone->update_acl != NULL || zone->ssutable != NULL)))
   4810 		{
   4811 			options = DNS_JOURNALOPT_RESIGN;
   4812 		} else {
   4813 			options = 0;
   4814 		}
   4815 		result = dns_journal_rollforward(zone->mctx, db, options,
   4816 						 zone->journal);
   4817 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
   4818 		    result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
   4819 		    result != ISC_R_RANGE)
   4820 		{
   4821 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4822 				      ISC_LOG_ERROR,
   4823 				      "journal rollforward failed: %s",
   4824 				      dns_result_totext(result));
   4825 			goto cleanup;
   4826 		}
   4827 		if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
   4828 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4829 				      ISC_LOG_ERROR,
   4830 				      "journal rollforward failed: "
   4831 				      "journal out of sync with zone");
   4832 			goto cleanup;
   4833 		}
   4834 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   4835 			      "journal rollforward completed "
   4836 			      "successfully: %s",
   4837 			      dns_result_totext(result));
   4838 		if (result == ISC_R_SUCCESS) {
   4839 			needdump = true;
   4840 		}
   4841 	}
   4842 
   4843 	/*
   4844 	 * Obtain ns, soa and cname counts for top of zone.
   4845 	 */
   4846 	INSIST(db != NULL);
   4847 	result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
   4848 				  &refresh, &retry, &expire, &minimum, &errors);
   4849 	if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
   4850 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_ERROR,
   4851 			      "could not find NS and/or SOA records");
   4852 	}
   4853 
   4854 	/*
   4855 	 * Check to make sure the journal is up to date, and remove the
   4856 	 * journal file if it isn't, as we wouldn't be able to apply
   4857 	 * updates otherwise.
   4858 	 */
   4859 	is_dynamic = dns_zone_isdynamic(zone, true);
   4860 	if (zone->journal != NULL && is_dynamic &&
   4861 	    !DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS))
   4862 	{
   4863 		uint32_t jserial;
   4864 		dns_journal_t *journal = NULL;
   4865 		bool empty = false;
   4866 
   4867 		result = dns_journal_open(zone->mctx, zone->journal,
   4868 					  DNS_JOURNAL_READ, &journal);
   4869 		if (result == ISC_R_SUCCESS) {
   4870 			jserial = dns_journal_last_serial(journal);
   4871 			empty = dns_journal_empty(journal);
   4872 			dns_journal_destroy(&journal);
   4873 		} else {
   4874 			jserial = serial;
   4875 			result = ISC_R_SUCCESS;
   4876 		}
   4877 
   4878 		if (jserial != serial) {
   4879 			if (!empty) {
   4880 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4881 					      ISC_LOG_INFO,
   4882 					      "journal file is out of date: "
   4883 					      "removing journal file");
   4884 			}
   4885 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   4886 				char strbuf[ISC_STRERRORSIZE];
   4887 				strerror_r(errno, strbuf, sizeof(strbuf));
   4888 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   4889 					      DNS_LOGMODULE_ZONE,
   4890 					      ISC_LOG_WARNING,
   4891 					      "unable to remove journal "
   4892 					      "'%s': '%s'",
   4893 					      zone->journal, strbuf);
   4894 			}
   4895 		}
   4896 	}
   4897 
   4898 	dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_DEBUG(1),
   4899 		      "loaded; checking validity");
   4900 
   4901 	/*
   4902 	 * Master / Slave / Mirror / Stub zones require both NS and SOA records
   4903 	 * at the top of the zone.
   4904 	 */
   4905 
   4906 	switch (zone->type) {
   4907 	case dns_zone_dlz:
   4908 	case dns_zone_master:
   4909 	case dns_zone_slave:
   4910 	case dns_zone_mirror:
   4911 	case dns_zone_stub:
   4912 	case dns_zone_redirect:
   4913 		if (soacount != 1) {
   4914 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4915 				      ISC_LOG_ERROR, "has %d SOA records",
   4916 				      soacount);
   4917 			result = DNS_R_BADZONE;
   4918 		}
   4919 		if (nscount == 0) {
   4920 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   4921 				      ISC_LOG_ERROR, "has no NS records");
   4922 			result = DNS_R_BADZONE;
   4923 		}
   4924 		if (result != ISC_R_SUCCESS) {
   4925 			goto cleanup;
   4926 		}
   4927 		if (zone->type == dns_zone_master && errors != 0) {
   4928 			result = DNS_R_BADZONE;
   4929 			goto cleanup;
   4930 		}
   4931 		if (zone->type != dns_zone_stub &&
   4932 		    zone->type != dns_zone_redirect) {
   4933 			result = check_nsec3param(zone, db);
   4934 			if (result != ISC_R_SUCCESS) {
   4935 				goto cleanup;
   4936 			}
   4937 		}
   4938 		if (zone->type == dns_zone_master &&
   4939 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
   4940 		    !integrity_checks(zone, db))
   4941 		{
   4942 			result = DNS_R_BADZONE;
   4943 			goto cleanup;
   4944 		}
   4945 		if (zone->type == dns_zone_master &&
   4946 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
   4947 		    !zone_check_dup(zone, db))
   4948 		{
   4949 			result = DNS_R_BADZONE;
   4950 			goto cleanup;
   4951 		}
   4952 
   4953 		if (zone->type == dns_zone_master) {
   4954 			result = dns_zone_cdscheck(zone, db, NULL);
   4955 			if (result != ISC_R_SUCCESS) {
   4956 				dns_zone_log(zone, ISC_LOG_ERROR,
   4957 					     "CDS/CDNSKEY consistency checks "
   4958 					     "failed");
   4959 				goto cleanup;
   4960 			}
   4961 		}
   4962 
   4963 		result = dns_zone_verifydb(zone, db, NULL);
   4964 		if (result != ISC_R_SUCCESS) {
   4965 			goto cleanup;
   4966 		}
   4967 
   4968 		if (zone->db != NULL) {
   4969 			unsigned int oldsoacount;
   4970 
   4971 			/*
   4972 			 * This is checked in zone_replacedb() for slave zones
   4973 			 * as they don't reload from disk.
   4974 			 */
   4975 			result = zone_get_from_db(zone, zone->db, NULL,
   4976 						  &oldsoacount, &oldserial,
   4977 						  NULL, NULL, NULL, NULL, NULL);
   4978 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   4979 			RUNTIME_CHECK(soacount > 0U);
   4980 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   4981 			    !isc_serial_gt(serial, oldserial))
   4982 			{
   4983 				uint32_t serialmin, serialmax;
   4984 
   4985 				INSIST(zone->type == dns_zone_master);
   4986 				INSIST(zone->raw == NULL);
   4987 
   4988 				if (serial == oldserial &&
   4989 				    zone_unchanged(zone->db, db, zone->mctx)) {
   4990 					dns_zone_logc(zone,
   4991 						      DNS_LOGCATEGORY_ZONELOAD,
   4992 						      ISC_LOG_INFO,
   4993 						      "ixfr-from-differences: "
   4994 						      "unchanged");
   4995 					goto done;
   4996 				}
   4997 
   4998 				serialmin = (oldserial + 1) & 0xffffffffU;
   4999 				serialmax = (oldserial + 0x7fffffffU) &
   5000 					    0xffffffffU;
   5001 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5002 					      ISC_LOG_ERROR,
   5003 					      "ixfr-from-differences: "
   5004 					      "new serial (%u) out of range "
   5005 					      "[%u - %u]",
   5006 					      serial, serialmin, serialmax);
   5007 				result = DNS_R_BADZONE;
   5008 				goto cleanup;
   5009 			} else if (!isc_serial_ge(serial, oldserial)) {
   5010 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5011 					      ISC_LOG_ERROR,
   5012 					      "zone serial (%u/%u) has gone "
   5013 					      "backwards",
   5014 					      serial, oldserial);
   5015 			} else if (serial == oldserial && !hasinclude &&
   5016 				   strcmp(zone->db_argv[0], "_builtin") != 0)
   5017 			{
   5018 				dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5019 					      ISC_LOG_ERROR,
   5020 					      "zone serial (%u) unchanged. "
   5021 					      "zone may fail to transfer "
   5022 					      "to slaves.",
   5023 					      serial);
   5024 			}
   5025 		}
   5026 
   5027 		if (zone->type == dns_zone_master &&
   5028 		    (zone->update_acl != NULL || zone->ssutable != NULL) &&
   5029 		    dns_zone_getsigresigninginterval(zone) < (3 * refresh) &&
   5030 		    dns_db_issecure(db))
   5031 		{
   5032 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5033 				      ISC_LOG_WARNING,
   5034 				      "sig-re-signing-interval less than "
   5035 				      "3 * refresh.");
   5036 		}
   5037 
   5038 		zone->refresh = RANGE(refresh, zone->minrefresh,
   5039 				      zone->maxrefresh);
   5040 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   5041 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   5042 				     DNS_MAX_EXPIRE);
   5043 		zone->minimum = minimum;
   5044 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   5045 
   5046 		if (zone->type == dns_zone_slave ||
   5047 		    zone->type == dns_zone_mirror ||
   5048 		    zone->type == dns_zone_stub ||
   5049 		    (zone->type == dns_zone_redirect && zone->masters != NULL))
   5050 		{
   5051 			isc_time_t t;
   5052 			uint32_t delay;
   5053 
   5054 			result = isc_file_getmodtime(zone->journal, &t);
   5055 			if (result != ISC_R_SUCCESS) {
   5056 				result = isc_file_getmodtime(zone->masterfile,
   5057 							     &t);
   5058 			}
   5059 			if (result == ISC_R_SUCCESS) {
   5060 				DNS_ZONE_TIME_ADD(&t, zone->expire,
   5061 						  &zone->expiretime);
   5062 			} else {
   5063 				DNS_ZONE_TIME_ADD(&now, zone->retry,
   5064 						  &zone->expiretime);
   5065 			}
   5066 
   5067 			delay = (zone->retry -
   5068 				 isc_random_uniform((zone->retry * 3) / 4));
   5069 			DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
   5070 			if (isc_time_compare(&zone->refreshtime,
   5071 					     &zone->expiretime) >= 0) {
   5072 				zone->refreshtime = now;
   5073 			}
   5074 		}
   5075 
   5076 		break;
   5077 
   5078 	case dns_zone_key:
   5079 		result = sync_keyzone(zone, db);
   5080 		if (result != ISC_R_SUCCESS) {
   5081 			goto cleanup;
   5082 		}
   5083 		break;
   5084 
   5085 	default:
   5086 		UNEXPECTED_ERROR(__FILE__, __LINE__, "unexpected zone type %d",
   5087 				 zone->type);
   5088 		result = ISC_R_UNEXPECTED;
   5089 		goto cleanup;
   5090 	}
   5091 
   5092 	/*
   5093 	 * Check for weak DNSKEY's.
   5094 	 */
   5095 	if (zone->type == dns_zone_master) {
   5096 		zone_check_dnskeys(zone, db);
   5097 	}
   5098 
   5099 	/*
   5100 	 * Schedule DNSSEC key refresh.
   5101 	 */
   5102 	if (zone->type == dns_zone_master &&
   5103 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   5104 	{
   5105 		zone->refreshkeytime = now;
   5106 	}
   5107 
   5108 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   5109 	if (zone->db != NULL) {
   5110 		had_db = true;
   5111 		result = zone_replacedb(zone, db, false);
   5112 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5113 		if (result != ISC_R_SUCCESS) {
   5114 			goto cleanup;
   5115 		}
   5116 	} else {
   5117 		zone_attachdb(zone, db);
   5118 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   5119 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED |
   5120 					       DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   5121 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SENDSECURE) &&
   5122 		    inline_raw(zone)) {
   5123 			if (zone->secure->db == NULL) {
   5124 				zone_send_securedb(zone, db);
   5125 			} else {
   5126 				zone_send_secureserial(zone, serial);
   5127 			}
   5128 		}
   5129 	}
   5130 
   5131 	/*
   5132 	 * Finished loading inline-signing zone; need to get status
   5133 	 * from the raw side now.
   5134 	 */
   5135 	if (zone->type == dns_zone_master && inline_secure(zone)) {
   5136 		maybe_send_secure(zone);
   5137 	}
   5138 
   5139 	result = ISC_R_SUCCESS;
   5140 
   5141 	if (needdump) {
   5142 		if (zone->type == dns_zone_key) {
   5143 			zone_needdump(zone, 30);
   5144 		} else {
   5145 			zone_needdump(zone, DNS_DUMP_DELAY);
   5146 		}
   5147 	}
   5148 
   5149 	if (zone->task != NULL) {
   5150 		if (zone->type == dns_zone_master) {
   5151 			set_resigntime(zone);
   5152 			resume_signingwithkey(zone);
   5153 			resume_addnsec3chain(zone);
   5154 		}
   5155 
   5156 		is_dynamic = dns_zone_isdynamic(zone, false);
   5157 		if (zone->type == dns_zone_master &&
   5158 		    !DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN) &&
   5159 		    is_dynamic && dns_db_issecure(db))
   5160 		{
   5161 			dns_name_t *name;
   5162 			dns_fixedname_t fixed;
   5163 			dns_rdataset_t next;
   5164 
   5165 			dns_rdataset_init(&next);
   5166 			name = dns_fixedname_initname(&fixed);
   5167 
   5168 			result = dns_db_getsigningtime(db, &next, name);
   5169 			if (result == ISC_R_SUCCESS) {
   5170 				isc_stdtime_t timenow;
   5171 				char namebuf[DNS_NAME_FORMATSIZE];
   5172 				char typebuf[DNS_RDATATYPE_FORMATSIZE];
   5173 
   5174 				isc_stdtime_get(&timenow);
   5175 				dns_name_format(name, namebuf, sizeof(namebuf));
   5176 				dns_rdatatype_format(next.covers, typebuf,
   5177 						     sizeof(typebuf));
   5178 				dnssec_log(
   5179 					zone, ISC_LOG_DEBUG(3),
   5180 					"next resign: %s/%s "
   5181 					"in %d seconds",
   5182 					namebuf, typebuf,
   5183 					next.resign - timenow -
   5184 						dns_zone_getsigresigninginterval(
   5185 							zone));
   5186 				dns_rdataset_disassociate(&next);
   5187 			} else {
   5188 				dnssec_log(zone, ISC_LOG_WARNING,
   5189 					   "signed dynamic zone has no "
   5190 					   "resign event scheduled");
   5191 			}
   5192 		}
   5193 
   5194 		zone_settimer(zone, &now);
   5195 	}
   5196 
   5197 	/*
   5198 	 * Clear old include list.
   5199 	 */
   5200 	for (inc = ISC_LIST_HEAD(zone->includes); inc != NULL;
   5201 	     inc = ISC_LIST_HEAD(zone->includes))
   5202 	{
   5203 		ISC_LIST_UNLINK(zone->includes, inc, link);
   5204 		isc_mem_free(zone->mctx, inc->name);
   5205 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5206 	}
   5207 	zone->nincludes = 0;
   5208 
   5209 	/*
   5210 	 * Transfer new include list.
   5211 	 */
   5212 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5213 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5214 	{
   5215 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5216 		ISC_LIST_APPEND(zone->includes, inc, link);
   5217 		zone->nincludes++;
   5218 	}
   5219 
   5220 	if (!dns_db_ispersistent(db)) {
   5221 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5222 			      "loaded serial %u%s", serial,
   5223 			      dns_db_issecure(db) ? " (DNSSEC signed)" : "");
   5224 	}
   5225 
   5226 	if (!had_db && zone->type == dns_zone_mirror) {
   5227 		dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD, ISC_LOG_INFO,
   5228 			      "mirror zone is now in use");
   5229 	}
   5230 
   5231 	zone->loadtime = loadtime;
   5232 	goto done;
   5233 
   5234 cleanup:
   5235 	if (zone->type == dns_zone_key && result != ISC_R_SUCCESS) {
   5236 		dnssec_log(zone, ISC_LOG_ERROR,
   5237 			   "failed to initialize managed-keys (%s): "
   5238 			   "DNSSEC validation is at risk",
   5239 			   isc_result_totext(result));
   5240 	}
   5241 
   5242 	for (inc = ISC_LIST_HEAD(zone->newincludes); inc != NULL;
   5243 	     inc = ISC_LIST_HEAD(zone->newincludes))
   5244 	{
   5245 		ISC_LIST_UNLINK(zone->newincludes, inc, link);
   5246 		isc_mem_free(zone->mctx, inc->name);
   5247 		isc_mem_put(zone->mctx, inc, sizeof(*inc));
   5248 	}
   5249 	if (zone->type == dns_zone_slave || zone->type == dns_zone_mirror ||
   5250 	    zone->type == dns_zone_stub || zone->type == dns_zone_key ||
   5251 	    (zone->type == dns_zone_redirect && zone->masters != NULL))
   5252 	{
   5253 		if (result != ISC_R_NOMEMORY) {
   5254 			if (zone->journal != NULL) {
   5255 				zone_saveunique(zone, zone->journal,
   5256 						"jn-XXXXXXXX");
   5257 			}
   5258 			if (zone->masterfile != NULL) {
   5259 				zone_saveunique(zone, zone->masterfile,
   5260 						"db-XXXXXXXX");
   5261 			}
   5262 		}
   5263 
   5264 		/* Mark the zone for immediate refresh. */
   5265 		zone->refreshtime = now;
   5266 		if (zone->task != NULL) {
   5267 			zone_settimer(zone, &now);
   5268 		}
   5269 		result = ISC_R_SUCCESS;
   5270 	} else if (zone->type == dns_zone_master ||
   5271 		   zone->type == dns_zone_redirect) {
   5272 		if (!(inline_secure(zone) && result == ISC_R_FILENOTFOUND)) {
   5273 			dns_zone_logc(zone, DNS_LOGCATEGORY_ZONELOAD,
   5274 				      ISC_LOG_ERROR,
   5275 				      "not loaded due to errors.");
   5276 		} else if (zone->type == dns_zone_master) {
   5277 			result = ISC_R_SUCCESS;
   5278 		}
   5279 	}
   5280 
   5281 done:
   5282 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADPENDING);
   5283 	/*
   5284 	 * If this is an inline-signed zone and we were called for the raw
   5285 	 * zone, we need to clear DNS_ZONEFLG_LOADPENDING for the secure zone
   5286 	 * as well, but only if this is a reload, not an initial zone load: in
   5287 	 * the former case, zone_postload() will not be run for the secure
   5288 	 * zone; in the latter case, it will be.  Check which case we are
   5289 	 * dealing with by consulting the DNS_ZONEFLG_LOADED flag for the
   5290 	 * secure zone: if it is set, this must be a reload.
   5291 	 */
   5292 	if (inline_raw(zone) && DNS_ZONE_FLAG(zone->secure, DNS_ZONEFLG_LOADED))
   5293 	{
   5294 		DNS_ZONE_CLRFLAG(zone->secure, DNS_ZONEFLG_LOADPENDING);
   5295 		/*
   5296 		 * Re-start zone maintenance if it had been stalled
   5297 		 * due to DNS_ZONEFLG_LOADPENDING being set when
   5298 		 * zone_maintenance was called.
   5299 		 */
   5300 		if (zone->secure->task != NULL) {
   5301 			zone_settimer(zone->secure, &now);
   5302 		}
   5303 	}
   5304 
   5305 	zone_debuglog(zone, "zone_postload", 99, "done");
   5306 
   5307 	return (result);
   5308 }
   5309 
   5310 static bool
   5311 exit_check(dns_zone_t *zone) {
   5312 	REQUIRE(LOCKED_ZONE(zone));
   5313 
   5314 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
   5315 	    isc_refcount_current(&zone->irefs) == 0)
   5316 	{
   5317 		/*
   5318 		 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
   5319 		 */
   5320 		INSIST(isc_refcount_current(&zone->erefs) == 0);
   5321 		return (true);
   5322 	}
   5323 	return (false);
   5324 }
   5325 
   5326 static bool
   5327 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   5328 	      dns_name_t *name, bool logit) {
   5329 	isc_result_t result;
   5330 	char namebuf[DNS_NAME_FORMATSIZE];
   5331 	char altbuf[DNS_NAME_FORMATSIZE];
   5332 	dns_fixedname_t fixed;
   5333 	dns_name_t *foundname;
   5334 	int level;
   5335 
   5336 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS)) {
   5337 		return (true);
   5338 	}
   5339 
   5340 	if (zone->type == dns_zone_master) {
   5341 		level = ISC_LOG_ERROR;
   5342 	} else {
   5343 		level = ISC_LOG_WARNING;
   5344 	}
   5345 
   5346 	foundname = dns_fixedname_initname(&fixed);
   5347 
   5348 	result = dns_db_find(db, name, version, dns_rdatatype_a, 0, 0, NULL,
   5349 			     foundname, NULL, NULL);
   5350 	if (result == ISC_R_SUCCESS) {
   5351 		return (true);
   5352 	}
   5353 
   5354 	if (result == DNS_R_NXRRSET) {
   5355 		result = dns_db_find(db, name, version, dns_rdatatype_aaaa, 0,
   5356 				     0, NULL, foundname, NULL, NULL);
   5357 		if (result == ISC_R_SUCCESS) {
   5358 			return (true);
   5359 		}
   5360 	}
   5361 
   5362 	if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
   5363 	    result == DNS_R_EMPTYNAME)
   5364 	{
   5365 		if (logit) {
   5366 			dns_name_format(name, namebuf, sizeof namebuf);
   5367 			dns_zone_log(zone, level,
   5368 				     "NS '%s' has no address "
   5369 				     "records (A or AAAA)",
   5370 				     namebuf);
   5371 		}
   5372 		return (false);
   5373 	}
   5374 
   5375 	if (result == DNS_R_CNAME) {
   5376 		if (logit) {
   5377 			dns_name_format(name, namebuf, sizeof namebuf);
   5378 			dns_zone_log(zone, level,
   5379 				     "NS '%s' is a CNAME "
   5380 				     "(illegal)",
   5381 				     namebuf);
   5382 		}
   5383 		return (false);
   5384 	}
   5385 
   5386 	if (result == DNS_R_DNAME) {
   5387 		if (logit) {
   5388 			dns_name_format(name, namebuf, sizeof namebuf);
   5389 			dns_name_format(foundname, altbuf, sizeof altbuf);
   5390 			dns_zone_log(zone, level,
   5391 				     "NS '%s' is below a DNAME "
   5392 				     "'%s' (illegal)",
   5393 				     namebuf, altbuf);
   5394 		}
   5395 		return (false);
   5396 	}
   5397 
   5398 	return (true);
   5399 }
   5400 
   5401 static isc_result_t
   5402 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   5403 		 dns_dbversion_t *version, unsigned int *nscount,
   5404 		 unsigned int *errors, bool logit) {
   5405 	isc_result_t result;
   5406 	unsigned int count = 0;
   5407 	unsigned int ecount = 0;
   5408 	dns_rdataset_t rdataset;
   5409 	dns_rdata_t rdata;
   5410 	dns_rdata_ns_t ns;
   5411 
   5412 	dns_rdataset_init(&rdataset);
   5413 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
   5414 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5415 	if (result == ISC_R_NOTFOUND) {
   5416 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5417 		goto success;
   5418 	}
   5419 	if (result != ISC_R_SUCCESS) {
   5420 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5421 		goto invalidate_rdataset;
   5422 	}
   5423 
   5424 	result = dns_rdataset_first(&rdataset);
   5425 	while (result == ISC_R_SUCCESS) {
   5426 		if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
   5427 		    (zone->type == dns_zone_master ||
   5428 		     zone->type == dns_zone_slave ||
   5429 		     zone->type == dns_zone_mirror))
   5430 		{
   5431 			dns_rdata_init(&rdata);
   5432 			dns_rdataset_current(&rdataset, &rdata);
   5433 			result = dns_rdata_tostruct(&rdata, &ns, NULL);
   5434 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5435 			if (dns_name_issubdomain(&ns.name, &zone->origin) &&
   5436 			    !zone_check_ns(zone, db, version, &ns.name, logit))
   5437 			{
   5438 				ecount++;
   5439 			}
   5440 		}
   5441 		count++;
   5442 		result = dns_rdataset_next(&rdataset);
   5443 	}
   5444 	dns_rdataset_disassociate(&rdataset);
   5445 
   5446 success:
   5447 	if (nscount != NULL) {
   5448 		*nscount = count;
   5449 	}
   5450 	if (errors != NULL) {
   5451 		*errors = ecount;
   5452 	}
   5453 
   5454 	result = ISC_R_SUCCESS;
   5455 
   5456 invalidate_rdataset:
   5457 	dns_rdataset_invalidate(&rdataset);
   5458 
   5459 	return (result);
   5460 }
   5461 
   5462 static isc_result_t
   5463 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   5464 		 unsigned int *soacount, uint32_t *serial, uint32_t *refresh,
   5465 		 uint32_t *retry, uint32_t *expire, uint32_t *minimum) {
   5466 	isc_result_t result;
   5467 	unsigned int count;
   5468 	dns_rdataset_t rdataset;
   5469 	dns_rdata_t rdata = DNS_RDATA_INIT;
   5470 	dns_rdata_soa_t soa;
   5471 
   5472 	dns_rdataset_init(&rdataset);
   5473 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
   5474 				     dns_rdatatype_none, 0, &rdataset, NULL);
   5475 	if (result == ISC_R_NOTFOUND) {
   5476 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5477 		if (soacount != NULL) {
   5478 			*soacount = 0;
   5479 		}
   5480 		if (serial != NULL) {
   5481 			*serial = 0;
   5482 		}
   5483 		if (refresh != NULL) {
   5484 			*refresh = 0;
   5485 		}
   5486 		if (retry != NULL) {
   5487 			*retry = 0;
   5488 		}
   5489 		if (expire != NULL) {
   5490 			*expire = 0;
   5491 		}
   5492 		if (minimum != NULL) {
   5493 			*minimum = 0;
   5494 		}
   5495 		result = ISC_R_SUCCESS;
   5496 		goto invalidate_rdataset;
   5497 	}
   5498 	if (result != ISC_R_SUCCESS) {
   5499 		INSIST(!dns_rdataset_isassociated(&rdataset));
   5500 		goto invalidate_rdataset;
   5501 	}
   5502 
   5503 	count = 0;
   5504 	result = dns_rdataset_first(&rdataset);
   5505 	while (result == ISC_R_SUCCESS) {
   5506 		dns_rdata_init(&rdata);
   5507 		dns_rdataset_current(&rdataset, &rdata);
   5508 		count++;
   5509 		if (count == 1) {
   5510 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   5511 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   5512 		}
   5513 
   5514 		result = dns_rdataset_next(&rdataset);
   5515 		dns_rdata_reset(&rdata);
   5516 	}
   5517 	dns_rdataset_disassociate(&rdataset);
   5518 
   5519 	if (soacount != NULL) {
   5520 		*soacount = count;
   5521 	}
   5522 
   5523 	if (count > 0) {
   5524 		if (serial != NULL) {
   5525 			*serial = soa.serial;
   5526 		}
   5527 		if (refresh != NULL) {
   5528 			*refresh = soa.refresh;
   5529 		}
   5530 		if (retry != NULL) {
   5531 			*retry = soa.retry;
   5532 		}
   5533 		if (expire != NULL) {
   5534 			*expire = soa.expire;
   5535 		}
   5536 		if (minimum != NULL) {
   5537 			*minimum = soa.minimum;
   5538 		}
   5539 	} else {
   5540 		if (soacount != NULL) {
   5541 			*soacount = 0;
   5542 		}
   5543 		if (serial != NULL) {
   5544 			*serial = 0;
   5545 		}
   5546 		if (refresh != NULL) {
   5547 			*refresh = 0;
   5548 		}
   5549 		if (retry != NULL) {
   5550 			*retry = 0;
   5551 		}
   5552 		if (expire != NULL) {
   5553 			*expire = 0;
   5554 		}
   5555 		if (minimum != NULL) {
   5556 			*minimum = 0;
   5557 		}
   5558 	}
   5559 
   5560 	result = ISC_R_SUCCESS;
   5561 
   5562 invalidate_rdataset:
   5563 	dns_rdataset_invalidate(&rdataset);
   5564 
   5565 	return (result);
   5566 }
   5567 
   5568 /*
   5569  * zone must be locked.
   5570  */
   5571 static isc_result_t
   5572 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
   5573 		 unsigned int *soacount, uint32_t *serial, uint32_t *refresh,
   5574 		 uint32_t *retry, uint32_t *expire, uint32_t *minimum,
   5575 		 unsigned int *errors) {
   5576 	isc_result_t result;
   5577 	isc_result_t answer = ISC_R_SUCCESS;
   5578 	dns_dbversion_t *version = NULL;
   5579 	dns_dbnode_t *node;
   5580 
   5581 	REQUIRE(db != NULL);
   5582 	REQUIRE(zone != NULL);
   5583 
   5584 	dns_db_currentversion(db, &version);
   5585 
   5586 	if (nscount != NULL) {
   5587 		*nscount = 0;
   5588 	}
   5589 	if (soacount != NULL) {
   5590 		*soacount = 0;
   5591 	}
   5592 	if (serial != NULL) {
   5593 		*serial = 0;
   5594 	}
   5595 	if (refresh != NULL) {
   5596 		*refresh = 0;
   5597 	}
   5598 	if (retry != NULL) {
   5599 		*retry = 0;
   5600 	}
   5601 	if (expire != NULL) {
   5602 		*expire = 0;
   5603 	}
   5604 	if (errors != NULL) {
   5605 		*errors = 0;
   5606 	}
   5607 
   5608 	node = NULL;
   5609 	result = dns_db_findnode(db, &zone->origin, false, &node);
   5610 	if (result != ISC_R_SUCCESS) {
   5611 		answer = result;
   5612 		goto closeversion;
   5613 	}
   5614 
   5615 	if (nscount != NULL || errors != NULL) {
   5616 		result = zone_count_ns_rr(zone, db, node, version, nscount,
   5617 					  errors, true);
   5618 		if (result != ISC_R_SUCCESS) {
   5619 			answer = result;
   5620 		}
   5621 	}
   5622 
   5623 	if (soacount != NULL || serial != NULL || refresh != NULL ||
   5624 	    retry != NULL || expire != NULL || minimum != NULL)
   5625 	{
   5626 		result = zone_load_soa_rr(db, node, version, soacount, serial,
   5627 					  refresh, retry, expire, minimum);
   5628 		if (result != ISC_R_SUCCESS) {
   5629 			answer = result;
   5630 		}
   5631 	}
   5632 
   5633 	dns_db_detachnode(db, &node);
   5634 closeversion:
   5635 	dns_db_closeversion(db, &version, false);
   5636 
   5637 	return (answer);
   5638 }
   5639 
   5640 void
   5641 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
   5642 	REQUIRE(DNS_ZONE_VALID(source));
   5643 	REQUIRE(target != NULL && *target == NULL);
   5644 	isc_refcount_increment(&source->erefs);
   5645 	*target = source;
   5646 }
   5647 
   5648 void
   5649 dns_zone_detach(dns_zone_t **zonep) {
   5650 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5651 	dns_zone_t *zone = *zonep;
   5652 	*zonep = NULL;
   5653 
   5654 	bool free_now = false;
   5655 	dns_zone_t *raw = NULL;
   5656 	dns_zone_t *secure = NULL;
   5657 	if (isc_refcount_decrement(&zone->erefs) == 1) {
   5658 		isc_refcount_destroy(&zone->erefs);
   5659 
   5660 		LOCK_ZONE(zone);
   5661 		INSIST(zone != zone->raw);
   5662 		/*
   5663 		 * We just detached the last external reference.
   5664 		 */
   5665 		if (zone->task != NULL) {
   5666 			/*
   5667 			 * This zone is being managed.	Post
   5668 			 * its control event and let it clean
   5669 			 * up synchronously in the context of
   5670 			 * its task.
   5671 			 */
   5672 			isc_event_t *ev = &zone->ctlevent;
   5673 			isc_task_send(zone->task, &ev);
   5674 		} else {
   5675 			/*
   5676 			 * This zone is not being managed; it has
   5677 			 * no task and can have no outstanding
   5678 			 * events.  Free it immediately.
   5679 			 */
   5680 			/*
   5681 			 * Unmanaged zones should not have non-null views;
   5682 			 * we have no way of detaching from the view here
   5683 			 * without causing deadlock because this code is called
   5684 			 * with the view already locked.
   5685 			 */
   5686 			INSIST(zone->view == NULL);
   5687 			free_now = true;
   5688 			raw = zone->raw;
   5689 			zone->raw = NULL;
   5690 			secure = zone->secure;
   5691 			zone->secure = NULL;
   5692 		}
   5693 		UNLOCK_ZONE(zone);
   5694 	}
   5695 	if (free_now) {
   5696 		if (raw != NULL) {
   5697 			dns_zone_detach(&raw);
   5698 		}
   5699 		if (secure != NULL) {
   5700 			dns_zone_idetach(&secure);
   5701 		}
   5702 		zone_free(zone);
   5703 	}
   5704 }
   5705 
   5706 void
   5707 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5708 	REQUIRE(DNS_ZONE_VALID(source));
   5709 
   5710 	LOCK_ZONE(source);
   5711 	zone_iattach(source, target);
   5712 	UNLOCK_ZONE(source);
   5713 }
   5714 
   5715 static void
   5716 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
   5717 	REQUIRE(DNS_ZONE_VALID(source));
   5718 	REQUIRE(LOCKED_ZONE(source));
   5719 	REQUIRE(target != NULL && *target == NULL);
   5720 	INSIST(isc_refcount_increment0(&source->irefs) +
   5721 		       isc_refcount_current(&source->erefs) >
   5722 	       0);
   5723 	*target = source;
   5724 }
   5725 
   5726 static void
   5727 zone_idetach(dns_zone_t **zonep) {
   5728 	dns_zone_t *zone;
   5729 
   5730 	/*
   5731 	 * 'zone' locked by caller.
   5732 	 */
   5733 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5734 	REQUIRE(LOCKED_ZONE(*zonep));
   5735 
   5736 	zone = *zonep;
   5737 	*zonep = NULL;
   5738 
   5739 	INSIST(isc_refcount_decrement(&zone->irefs) - 1 +
   5740 		       isc_refcount_current(&zone->erefs) >
   5741 	       0);
   5742 }
   5743 
   5744 void
   5745 dns_zone_idetach(dns_zone_t **zonep) {
   5746 	dns_zone_t *zone;
   5747 	bool free_needed;
   5748 
   5749 	REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
   5750 
   5751 	zone = *zonep;
   5752 	*zonep = NULL;
   5753 
   5754 	if (isc_refcount_decrement(&zone->irefs) == 1) {
   5755 		LOCK_ZONE(zone);
   5756 		free_needed = exit_check(zone);
   5757 		UNLOCK_ZONE(zone);
   5758 		if (free_needed) {
   5759 			zone_free(zone);
   5760 		}
   5761 	}
   5762 }
   5763 
   5764 isc_mem_t *
   5765 dns_zone_getmctx(dns_zone_t *zone) {
   5766 	REQUIRE(DNS_ZONE_VALID(zone));
   5767 
   5768 	return (zone->mctx);
   5769 }
   5770 
   5771 dns_zonemgr_t *
   5772 dns_zone_getmgr(dns_zone_t *zone) {
   5773 	REQUIRE(DNS_ZONE_VALID(zone));
   5774 
   5775 	return (zone->zmgr);
   5776 }
   5777 
   5778 void
   5779 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, bool value) {
   5780 	REQUIRE(DNS_ZONE_VALID(zone));
   5781 
   5782 	if (value) {
   5783 		DNS_ZONE_SETFLAG(zone, flags);
   5784 	} else {
   5785 		DNS_ZONE_CLRFLAG(zone, flags);
   5786 	}
   5787 }
   5788 
   5789 void
   5790 dns_zone_setkasp(dns_zone_t *zone, dns_kasp_t *kasp) {
   5791 	REQUIRE(DNS_ZONE_VALID(zone));
   5792 
   5793 	LOCK_ZONE(zone);
   5794 	if (zone->kasp != NULL) {
   5795 		dns_kasp_t *oldkasp = zone->kasp;
   5796 		zone->kasp = NULL;
   5797 		dns_kasp_detach(&oldkasp);
   5798 	}
   5799 	zone->kasp = kasp;
   5800 	UNLOCK_ZONE(zone);
   5801 }
   5802 
   5803 dns_kasp_t *
   5804 dns_zone_getkasp(dns_zone_t *zone) {
   5805 	REQUIRE(DNS_ZONE_VALID(zone));
   5806 
   5807 	return (zone->kasp);
   5808 }
   5809 
   5810 static bool
   5811 statefile_exist(dns_zone_t *zone) {
   5812 	isc_result_t ret;
   5813 	dns_dnsseckeylist_t keys;
   5814 	dns_dnsseckey_t *key = NULL;
   5815 	isc_stdtime_t now;
   5816 	isc_time_t timenow;
   5817 	bool found = false;
   5818 
   5819 	TIME_NOW(&timenow);
   5820 	now = isc_time_seconds(&timenow);
   5821 
   5822 	ISC_LIST_INIT(keys);
   5823 
   5824 	ret = dns_dnssec_findmatchingkeys(dns_zone_getorigin(zone),
   5825 					  dns_zone_getkeydirectory(zone), now,
   5826 					  dns_zone_getmctx(zone), &keys);
   5827 	if (ret == ISC_R_SUCCESS) {
   5828 		for (key = ISC_LIST_HEAD(keys); key != NULL;
   5829 		     key = ISC_LIST_NEXT(key, link)) {
   5830 			if (dst_key_haskasp(key->key)) {
   5831 				found = true;
   5832 				break;
   5833 			}
   5834 		}
   5835 	}
   5836 
   5837 	/* Clean up keys */
   5838 	while (!ISC_LIST_EMPTY(keys)) {
   5839 		key = ISC_LIST_HEAD(keys);
   5840 		ISC_LIST_UNLINK(keys, key, link);
   5841 		dns_dnsseckey_destroy(dns_zone_getmctx(zone), &key);
   5842 	}
   5843 
   5844 	return (found);
   5845 }
   5846 
   5847 bool
   5848 dns_zone_secure_to_insecure(dns_zone_t *zone, bool reconfig) {
   5849 	REQUIRE(DNS_ZONE_VALID(zone));
   5850 
   5851 	/*
   5852 	 * If checking during reconfig, the zone is not yet updated
   5853 	 * with the new kasp configuration, so only check the key
   5854 	 * files.
   5855 	 */
   5856 	if (reconfig) {
   5857 		return (statefile_exist(zone));
   5858 	}
   5859 
   5860 	if (zone->kasp == NULL) {
   5861 		return (false);
   5862 	}
   5863 	if (strcmp(dns_kasp_getname(zone->kasp), "none") != 0) {
   5864 		return (false);
   5865 	}
   5866 	/*
   5867 	 * "dnssec-policy none", but if there are key state files
   5868 	 * this zone used to be secure but is transitioning back to
   5869 	 * insecure.
   5870 	 */
   5871 	return (statefile_exist(zone));
   5872 }
   5873 
   5874 bool
   5875 dns_zone_use_kasp(dns_zone_t *zone) {
   5876 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   5877 
   5878 	if (kasp == NULL) {
   5879 		return (false);
   5880 	} else if (strcmp(dns_kasp_getname(kasp), "none") != 0) {
   5881 		return (true);
   5882 	}
   5883 	return dns_zone_secure_to_insecure(zone, false);
   5884 }
   5885 
   5886 void
   5887 dns_zone_setoption(dns_zone_t *zone, dns_zoneopt_t option, bool value) {
   5888 	REQUIRE(DNS_ZONE_VALID(zone));
   5889 
   5890 	if (value) {
   5891 		DNS_ZONE_SETOPTION(zone, option);
   5892 	} else {
   5893 		DNS_ZONE_CLROPTION(zone, option);
   5894 	}
   5895 }
   5896 
   5897 dns_zoneopt_t
   5898 dns_zone_getoptions(dns_zone_t *zone) {
   5899 	REQUIRE(DNS_ZONE_VALID(zone));
   5900 
   5901 	return (atomic_load_relaxed(&zone->options));
   5902 }
   5903 
   5904 void
   5905 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, bool value) {
   5906 	REQUIRE(DNS_ZONE_VALID(zone));
   5907 
   5908 	if (value) {
   5909 		DNS_ZONEKEY_SETOPTION(zone, keyopt);
   5910 	} else {
   5911 		DNS_ZONEKEY_CLROPTION(zone, keyopt);
   5912 	}
   5913 }
   5914 
   5915 unsigned int
   5916 dns_zone_getkeyopts(dns_zone_t *zone) {
   5917 	REQUIRE(DNS_ZONE_VALID(zone));
   5918 
   5919 	return (atomic_load_relaxed(&zone->keyopts));
   5920 }
   5921 
   5922 isc_result_t
   5923 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5924 	REQUIRE(DNS_ZONE_VALID(zone));
   5925 
   5926 	LOCK_ZONE(zone);
   5927 	zone->xfrsource4 = *xfrsource;
   5928 	UNLOCK_ZONE(zone);
   5929 
   5930 	return (ISC_R_SUCCESS);
   5931 }
   5932 
   5933 isc_sockaddr_t *
   5934 dns_zone_getxfrsource4(dns_zone_t *zone) {
   5935 	REQUIRE(DNS_ZONE_VALID(zone));
   5936 	return (&zone->xfrsource4);
   5937 }
   5938 
   5939 isc_result_t
   5940 dns_zone_setxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5941 	REQUIRE(DNS_ZONE_VALID(zone));
   5942 
   5943 	LOCK_ZONE(zone);
   5944 	zone->xfrsource4dscp = dscp;
   5945 	UNLOCK_ZONE(zone);
   5946 
   5947 	return (ISC_R_SUCCESS);
   5948 }
   5949 
   5950 isc_dscp_t
   5951 dns_zone_getxfrsource4dscp(dns_zone_t *zone) {
   5952 	REQUIRE(DNS_ZONE_VALID(zone));
   5953 	return (zone->xfrsource4dscp);
   5954 }
   5955 
   5956 isc_result_t
   5957 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
   5958 	REQUIRE(DNS_ZONE_VALID(zone));
   5959 
   5960 	LOCK_ZONE(zone);
   5961 	zone->xfrsource6 = *xfrsource;
   5962 	UNLOCK_ZONE(zone);
   5963 
   5964 	return (ISC_R_SUCCESS);
   5965 }
   5966 
   5967 isc_sockaddr_t *
   5968 dns_zone_getxfrsource6(dns_zone_t *zone) {
   5969 	REQUIRE(DNS_ZONE_VALID(zone));
   5970 	return (&zone->xfrsource6);
   5971 }
   5972 
   5973 isc_dscp_t
   5974 dns_zone_getxfrsource6dscp(dns_zone_t *zone) {
   5975 	REQUIRE(DNS_ZONE_VALID(zone));
   5976 	return (zone->xfrsource6dscp);
   5977 }
   5978 
   5979 isc_result_t
   5980 dns_zone_setxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   5981 	REQUIRE(DNS_ZONE_VALID(zone));
   5982 
   5983 	LOCK_ZONE(zone);
   5984 	zone->xfrsource6dscp = dscp;
   5985 	UNLOCK_ZONE(zone);
   5986 
   5987 	return (ISC_R_SUCCESS);
   5988 }
   5989 
   5990 isc_result_t
   5991 dns_zone_setaltxfrsource4(dns_zone_t *zone,
   5992 			  const isc_sockaddr_t *altxfrsource) {
   5993 	REQUIRE(DNS_ZONE_VALID(zone));
   5994 
   5995 	LOCK_ZONE(zone);
   5996 	zone->altxfrsource4 = *altxfrsource;
   5997 	UNLOCK_ZONE(zone);
   5998 
   5999 	return (ISC_R_SUCCESS);
   6000 }
   6001 
   6002 isc_sockaddr_t *
   6003 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
   6004 	REQUIRE(DNS_ZONE_VALID(zone));
   6005 	return (&zone->altxfrsource4);
   6006 }
   6007 
   6008 isc_result_t
   6009 dns_zone_setaltxfrsource4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6010 	REQUIRE(DNS_ZONE_VALID(zone));
   6011 
   6012 	LOCK_ZONE(zone);
   6013 	zone->altxfrsource4dscp = dscp;
   6014 	UNLOCK_ZONE(zone);
   6015 
   6016 	return (ISC_R_SUCCESS);
   6017 }
   6018 
   6019 isc_dscp_t
   6020 dns_zone_getaltxfrsource4dscp(dns_zone_t *zone) {
   6021 	REQUIRE(DNS_ZONE_VALID(zone));
   6022 	return (zone->altxfrsource4dscp);
   6023 }
   6024 
   6025 isc_result_t
   6026 dns_zone_setaltxfrsource6(dns_zone_t *zone,
   6027 			  const isc_sockaddr_t *altxfrsource) {
   6028 	REQUIRE(DNS_ZONE_VALID(zone));
   6029 
   6030 	LOCK_ZONE(zone);
   6031 	zone->altxfrsource6 = *altxfrsource;
   6032 	UNLOCK_ZONE(zone);
   6033 
   6034 	return (ISC_R_SUCCESS);
   6035 }
   6036 
   6037 isc_sockaddr_t *
   6038 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
   6039 	REQUIRE(DNS_ZONE_VALID(zone));
   6040 	return (&zone->altxfrsource6);
   6041 }
   6042 
   6043 isc_result_t
   6044 dns_zone_setaltxfrsource6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6045 	REQUIRE(DNS_ZONE_VALID(zone));
   6046 
   6047 	LOCK_ZONE(zone);
   6048 	zone->altxfrsource6dscp = dscp;
   6049 	UNLOCK_ZONE(zone);
   6050 
   6051 	return (ISC_R_SUCCESS);
   6052 }
   6053 
   6054 isc_dscp_t
   6055 dns_zone_getaltxfrsource6dscp(dns_zone_t *zone) {
   6056 	REQUIRE(DNS_ZONE_VALID(zone));
   6057 	return (zone->altxfrsource6dscp);
   6058 }
   6059 
   6060 isc_result_t
   6061 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6062 	REQUIRE(DNS_ZONE_VALID(zone));
   6063 
   6064 	LOCK_ZONE(zone);
   6065 	zone->notifysrc4 = *notifysrc;
   6066 	UNLOCK_ZONE(zone);
   6067 
   6068 	return (ISC_R_SUCCESS);
   6069 }
   6070 
   6071 isc_sockaddr_t *
   6072 dns_zone_getnotifysrc4(dns_zone_t *zone) {
   6073 	REQUIRE(DNS_ZONE_VALID(zone));
   6074 	return (&zone->notifysrc4);
   6075 }
   6076 
   6077 isc_result_t
   6078 dns_zone_setnotifysrc4dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6079 	REQUIRE(DNS_ZONE_VALID(zone));
   6080 
   6081 	LOCK_ZONE(zone);
   6082 	zone->notifysrc4dscp = dscp;
   6083 	UNLOCK_ZONE(zone);
   6084 
   6085 	return (ISC_R_SUCCESS);
   6086 }
   6087 
   6088 isc_dscp_t
   6089 dns_zone_getnotifysrc4dscp(dns_zone_t *zone) {
   6090 	REQUIRE(DNS_ZONE_VALID(zone));
   6091 	return (zone->notifysrc4dscp);
   6092 }
   6093 
   6094 isc_result_t
   6095 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
   6096 	REQUIRE(DNS_ZONE_VALID(zone));
   6097 
   6098 	LOCK_ZONE(zone);
   6099 	zone->notifysrc6 = *notifysrc;
   6100 	UNLOCK_ZONE(zone);
   6101 
   6102 	return (ISC_R_SUCCESS);
   6103 }
   6104 
   6105 isc_sockaddr_t *
   6106 dns_zone_getnotifysrc6(dns_zone_t *zone) {
   6107 	REQUIRE(DNS_ZONE_VALID(zone));
   6108 	return (&zone->notifysrc6);
   6109 }
   6110 
   6111 static bool
   6112 same_addrs(isc_sockaddr_t const *oldlist, isc_sockaddr_t const *newlist,
   6113 	   uint32_t count) {
   6114 	unsigned int i;
   6115 
   6116 	for (i = 0; i < count; i++) {
   6117 		if (!isc_sockaddr_equal(&oldlist[i], &newlist[i])) {
   6118 			return (false);
   6119 		}
   6120 	}
   6121 	return (true);
   6122 }
   6123 
   6124 static bool
   6125 same_keynames(dns_name_t *const *oldlist, dns_name_t *const *newlist,
   6126 	      uint32_t count) {
   6127 	unsigned int i;
   6128 
   6129 	if (oldlist == NULL && newlist == NULL) {
   6130 		return (true);
   6131 	}
   6132 	if (oldlist == NULL || newlist == NULL) {
   6133 		return (false);
   6134 	}
   6135 
   6136 	for (i = 0; i < count; i++) {
   6137 		if (oldlist[i] == NULL && newlist[i] == NULL) {
   6138 			continue;
   6139 		}
   6140 		if (oldlist[i] == NULL || newlist[i] == NULL ||
   6141 		    !dns_name_equal(oldlist[i], newlist[i]))
   6142 		{
   6143 			return (false);
   6144 		}
   6145 	}
   6146 	return (true);
   6147 }
   6148 
   6149 static void
   6150 clear_addresskeylist(isc_sockaddr_t **addrsp, isc_dscp_t **dscpsp,
   6151 		     dns_name_t ***keynamesp, unsigned int *countp,
   6152 		     isc_mem_t *mctx) {
   6153 	unsigned int count;
   6154 	isc_sockaddr_t *addrs;
   6155 	isc_dscp_t *dscps;
   6156 	dns_name_t **keynames;
   6157 
   6158 	REQUIRE(countp != NULL && addrsp != NULL && dscpsp != NULL &&
   6159 		keynamesp != NULL);
   6160 
   6161 	count = *countp;
   6162 	*countp = 0;
   6163 	addrs = *addrsp;
   6164 	*addrsp = NULL;
   6165 	dscps = *dscpsp;
   6166 	*dscpsp = NULL;
   6167 	keynames = *keynamesp;
   6168 	*keynamesp = NULL;
   6169 
   6170 	if (addrs != NULL) {
   6171 		isc_mem_put(mctx, addrs, count * sizeof(isc_sockaddr_t));
   6172 	}
   6173 
   6174 	if (dscps != NULL) {
   6175 		isc_mem_put(mctx, dscps, count * sizeof(isc_dscp_t));
   6176 	}
   6177 
   6178 	if (keynames != NULL) {
   6179 		unsigned int i;
   6180 		for (i = 0; i < count; i++) {
   6181 			if (keynames[i] != NULL) {
   6182 				dns_name_free(keynames[i], mctx);
   6183 				isc_mem_put(mctx, keynames[i],
   6184 					    sizeof(dns_name_t));
   6185 				keynames[i] = NULL;
   6186 			}
   6187 		}
   6188 		isc_mem_put(mctx, keynames, count * sizeof(dns_name_t *));
   6189 	}
   6190 }
   6191 
   6192 static isc_result_t
   6193 set_addrkeylist(unsigned int count, const isc_sockaddr_t *addrs,
   6194 		isc_sockaddr_t **newaddrsp, const isc_dscp_t *dscp,
   6195 		isc_dscp_t **newdscpp, dns_name_t **names,
   6196 		dns_name_t ***newnamesp, isc_mem_t *mctx) {
   6197 	isc_sockaddr_t *newaddrs = NULL;
   6198 	isc_dscp_t *newdscp = NULL;
   6199 	dns_name_t **newnames = NULL;
   6200 	unsigned int i;
   6201 
   6202 	REQUIRE(newaddrsp != NULL && *newaddrsp == NULL);
   6203 	REQUIRE(newdscpp != NULL && *newdscpp == NULL);
   6204 	REQUIRE(newnamesp != NULL && *newnamesp == NULL);
   6205 
   6206 	newaddrs = isc_mem_get(mctx, count * sizeof(*newaddrs));
   6207 	memmove(newaddrs, addrs, count * sizeof(*newaddrs));
   6208 
   6209 	if (dscp != NULL) {
   6210 		newdscp = isc_mem_get(mctx, count * sizeof(*newdscp));
   6211 		memmove(newdscp, dscp, count * sizeof(*newdscp));
   6212 	} else {
   6213 		newdscp = NULL;
   6214 	}
   6215 
   6216 	if (names != NULL) {
   6217 		newnames = isc_mem_get(mctx, count * sizeof(*newnames));
   6218 		for (i = 0; i < count; i++) {
   6219 			newnames[i] = NULL;
   6220 		}
   6221 		for (i = 0; i < count; i++) {
   6222 			if (names[i] != NULL) {
   6223 				newnames[i] = isc_mem_get(mctx,
   6224 							  sizeof(dns_name_t));
   6225 				dns_name_init(newnames[i], NULL);
   6226 				dns_name_dup(names[i], mctx, newnames[i]);
   6227 			}
   6228 		}
   6229 	} else {
   6230 		newnames = NULL;
   6231 	}
   6232 
   6233 	*newdscpp = newdscp;
   6234 	*newaddrsp = newaddrs;
   6235 	*newnamesp = newnames;
   6236 	return (ISC_R_SUCCESS);
   6237 }
   6238 
   6239 isc_result_t
   6240 dns_zone_setnotifysrc6dscp(dns_zone_t *zone, isc_dscp_t dscp) {
   6241 	REQUIRE(DNS_ZONE_VALID(zone));
   6242 
   6243 	LOCK_ZONE(zone);
   6244 	zone->notifysrc6dscp = dscp;
   6245 	UNLOCK_ZONE(zone);
   6246 
   6247 	return (ISC_R_SUCCESS);
   6248 }
   6249 
   6250 isc_dscp_t
   6251 dns_zone_getnotifysrc6dscp(dns_zone_t *zone) {
   6252 	REQUIRE(DNS_ZONE_VALID(zone));
   6253 	return (zone->notifysrc6dscp);
   6254 }
   6255 
   6256 isc_result_t
   6257 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6258 		       uint32_t count) {
   6259 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, NULL,
   6260 					       count));
   6261 }
   6262 
   6263 isc_result_t
   6264 dns_zone_setalsonotifywithkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6265 			       dns_name_t **keynames, uint32_t count) {
   6266 	return (dns_zone_setalsonotifydscpkeys(zone, notify, NULL, keynames,
   6267 					       count));
   6268 }
   6269 
   6270 isc_result_t
   6271 dns_zone_setalsonotifydscpkeys(dns_zone_t *zone, const isc_sockaddr_t *notify,
   6272 			       const isc_dscp_t *dscps, dns_name_t **keynames,
   6273 			       uint32_t count) {
   6274 	isc_result_t result;
   6275 	isc_sockaddr_t *newaddrs = NULL;
   6276 	isc_dscp_t *newdscps = NULL;
   6277 	dns_name_t **newnames = NULL;
   6278 
   6279 	REQUIRE(DNS_ZONE_VALID(zone));
   6280 	REQUIRE(count == 0 || notify != NULL);
   6281 	if (keynames != NULL) {
   6282 		REQUIRE(count != 0);
   6283 	}
   6284 
   6285 	LOCK_ZONE(zone);
   6286 
   6287 	if (count == zone->notifycnt &&
   6288 	    same_addrs(zone->notify, notify, count) &&
   6289 	    same_keynames(zone->notifykeynames, keynames, count))
   6290 	{
   6291 		goto unlock;
   6292 	}
   6293 
   6294 	clear_addresskeylist(&zone->notify, &zone->notifydscp,
   6295 			     &zone->notifykeynames, &zone->notifycnt,
   6296 			     zone->mctx);
   6297 
   6298 	if (count == 0) {
   6299 		goto unlock;
   6300 	}
   6301 
   6302 	/*
   6303 	 * Set up the notify and notifykey lists
   6304 	 */
   6305 	result = set_addrkeylist(count, notify, &newaddrs, dscps, &newdscps,
   6306 				 keynames, &newnames, zone->mctx);
   6307 	if (result != ISC_R_SUCCESS) {
   6308 		goto unlock;
   6309 	}
   6310 
   6311 	/*
   6312 	 * Everything is ok so attach to the zone.
   6313 	 */
   6314 	zone->notify = newaddrs;
   6315 	zone->notifydscp = newdscps;
   6316 	zone->notifykeynames = newnames;
   6317 	zone->notifycnt = count;
   6318 unlock:
   6319 	UNLOCK_ZONE(zone);
   6320 	return (ISC_R_SUCCESS);
   6321 }
   6322 
   6323 isc_result_t
   6324 dns_zone_setprimaries(dns_zone_t *zone, const isc_sockaddr_t *masters,
   6325 		      uint32_t count) {
   6326 	isc_result_t result;
   6327 
   6328 	result = dns_zone_setprimarieswithkeys(zone, masters, NULL, count);
   6329 	return (result);
   6330 }
   6331 
   6332 isc_result_t
   6333 dns_zone_setprimarieswithkeys(dns_zone_t *zone, const isc_sockaddr_t *masters,
   6334 			      dns_name_t **keynames, uint32_t count) {
   6335 	isc_result_t result = ISC_R_SUCCESS;
   6336 	isc_sockaddr_t *newaddrs = NULL;
   6337 	isc_dscp_t *newdscps = NULL;
   6338 	dns_name_t **newnames = NULL;
   6339 	bool *newok;
   6340 	unsigned int i;
   6341 
   6342 	REQUIRE(DNS_ZONE_VALID(zone));
   6343 	REQUIRE(count == 0 || masters != NULL);
   6344 	if (keynames != NULL) {
   6345 		REQUIRE(count != 0);
   6346 	}
   6347 
   6348 	LOCK_ZONE(zone);
   6349 	/*
   6350 	 * The refresh code assumes that 'primaries' wouldn't change under it.
   6351 	 * If it will change then kill off any current refresh in progress
   6352 	 * and update the primaries info.  If it won't change then we can just
   6353 	 * unlock and exit.
   6354 	 */
   6355 	if (count != zone->masterscnt ||
   6356 	    !same_addrs(zone->masters, masters, count) ||
   6357 	    !same_keynames(zone->masterkeynames, keynames, count))
   6358 	{
   6359 		if (zone->request != NULL) {
   6360 			dns_request_cancel(zone->request);
   6361 		}
   6362 	} else {
   6363 		goto unlock;
   6364 	}
   6365 
   6366 	/*
   6367 	 * This needs to happen before clear_addresskeylist() sets
   6368 	 * zone->masterscnt to 0:
   6369 	 */
   6370 	if (zone->mastersok != NULL) {
   6371 		isc_mem_put(zone->mctx, zone->mastersok,
   6372 			    zone->masterscnt * sizeof(bool));
   6373 		zone->mastersok = NULL;
   6374 	}
   6375 	clear_addresskeylist(&zone->masters, &zone->masterdscps,
   6376 			     &zone->masterkeynames, &zone->masterscnt,
   6377 			     zone->mctx);
   6378 	/*
   6379 	 * If count == 0, don't allocate any space for masters, mastersok or
   6380 	 * keynames so internally, those pointers are NULL if count == 0
   6381 	 */
   6382 	if (count == 0) {
   6383 		goto unlock;
   6384 	}
   6385 
   6386 	/*
   6387 	 * mastersok must contain count elements
   6388 	 */
   6389 	newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
   6390 	for (i = 0; i < count; i++) {
   6391 		newok[i] = false;
   6392 	}
   6393 
   6394 	/*
   6395 	 * Now set up the primaries and primary key lists
   6396 	 */
   6397 	result = set_addrkeylist(count, masters, &newaddrs, NULL, &newdscps,
   6398 				 keynames, &newnames, zone->mctx);
   6399 	INSIST(newdscps == NULL);
   6400 	if (result != ISC_R_SUCCESS) {
   6401 		isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
   6402 		goto unlock;
   6403 	}
   6404 
   6405 	/*
   6406 	 * Everything is ok so attach to the zone.
   6407 	 */
   6408 	zone->curmaster = 0;
   6409 	zone->mastersok = newok;
   6410 	zone->masters = newaddrs;
   6411 	zone->masterdscps = newdscps;
   6412 	zone->masterkeynames = newnames;
   6413 	zone->masterscnt = count;
   6414 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   6415 
   6416 unlock:
   6417 	UNLOCK_ZONE(zone);
   6418 	return (result);
   6419 }
   6420 
   6421 isc_result_t
   6422 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
   6423 	isc_result_t result = ISC_R_SUCCESS;
   6424 
   6425 	REQUIRE(DNS_ZONE_VALID(zone));
   6426 
   6427 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   6428 	if (zone->db == NULL) {
   6429 		result = DNS_R_NOTLOADED;
   6430 	} else {
   6431 		dns_db_attach(zone->db, dpb);
   6432 	}
   6433 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   6434 
   6435 	return (result);
   6436 }
   6437 
   6438 void
   6439 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
   6440 	REQUIRE(DNS_ZONE_VALID(zone));
   6441 	REQUIRE(zone->type == dns_zone_staticstub);
   6442 
   6443 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   6444 	REQUIRE(zone->db == NULL);
   6445 	dns_db_attach(db, &zone->db);
   6446 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   6447 }
   6448 
   6449 /*
   6450  * Coordinates the starting of routine jobs.
   6451  */
   6452 void
   6453 dns_zone_maintenance(dns_zone_t *zone) {
   6454 	const char me[] = "dns_zone_maintenance";
   6455 	isc_time_t now;
   6456 
   6457 	REQUIRE(DNS_ZONE_VALID(zone));
   6458 	ENTER;
   6459 
   6460 	LOCK_ZONE(zone);
   6461 	TIME_NOW(&now);
   6462 	zone_settimer(zone, &now);
   6463 	UNLOCK_ZONE(zone);
   6464 }
   6465 
   6466 static inline bool
   6467 was_dumping(dns_zone_t *zone) {
   6468 	REQUIRE(LOCKED_ZONE(zone));
   6469 
   6470 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
   6471 		return (true);
   6472 	}
   6473 
   6474 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   6475 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   6476 	isc_time_settoepoch(&zone->dumptime);
   6477 	return (false);
   6478 }
   6479 
   6480 /*%
   6481  * Find up to 'maxkeys' DNSSEC keys used for signing version 'ver' of database
   6482  * 'db' for zone 'zone' in its key directory, then load these keys into 'keys'.
   6483  * Only load the public part of a given key if it is not active at timestamp
   6484  * 'now'.  Store the number of keys found in 'nkeys'.
   6485  */
   6486 isc_result_t
   6487 dns__zone_findkeys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   6488 		   isc_stdtime_t now, isc_mem_t *mctx, unsigned int maxkeys,
   6489 		   dst_key_t **keys, unsigned int *nkeys) {
   6490 	isc_result_t result;
   6491 	dns_dbnode_t *node = NULL;
   6492 	const char *directory = dns_zone_getkeydirectory(zone);
   6493 
   6494 	CHECK(dns_db_findnode(db, dns_db_origin(db), false, &node));
   6495 	memset(keys, 0, sizeof(*keys) * maxkeys);
   6496 	result = dns_dnssec_findzonekeys(db, ver, node, dns_db_origin(db),
   6497 					 directory, now, mctx, maxkeys, keys,
   6498 					 nkeys);
   6499 	if (result == ISC_R_NOTFOUND) {
   6500 		result = ISC_R_SUCCESS;
   6501 	}
   6502 failure:
   6503 	if (node != NULL) {
   6504 		dns_db_detachnode(db, &node);
   6505 	}
   6506 	return (result);
   6507 }
   6508 
   6509 static isc_result_t
   6510 offline(dns_db_t *db, dns_dbversion_t *ver, dns__zonediff_t *zonediff,
   6511 	dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata) {
   6512 	isc_result_t result;
   6513 
   6514 	if ((rdata->flags & DNS_RDATA_OFFLINE) != 0) {
   6515 		return (ISC_R_SUCCESS);
   6516 	}
   6517 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
   6518 			       name, ttl, rdata);
   6519 	if (result != ISC_R_SUCCESS) {
   6520 		return (result);
   6521 	}
   6522 	rdata->flags |= DNS_RDATA_OFFLINE;
   6523 	result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
   6524 			       name, ttl, rdata);
   6525 	zonediff->offline = true;
   6526 	return (result);
   6527 }
   6528 
   6529 static void
   6530 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when,
   6531 		       isc_stdtime_t now) {
   6532 	unsigned int delta;
   6533 	char timebuf[80];
   6534 
   6535 	zone->key_expiry = when;
   6536 	if (when <= now) {
   6537 		dns_zone_log(zone, ISC_LOG_ERROR,
   6538 			     "DNSKEY RRSIG(s) have expired");
   6539 		isc_time_settoepoch(&zone->keywarntime);
   6540 	} else if (when < now + 7 * 24 * 3600) {
   6541 		isc_time_t t;
   6542 		isc_time_set(&t, when, 0);
   6543 		isc_time_formattimestamp(&t, timebuf, 80);
   6544 		dns_zone_log(zone, ISC_LOG_WARNING,
   6545 			     "DNSKEY RRSIG(s) will expire within 7 days: %s",
   6546 			     timebuf);
   6547 		delta = when - now;
   6548 		delta--;	    /* loop prevention */
   6549 		delta /= 24 * 3600; /* to whole days */
   6550 		delta *= 24 * 3600; /* to seconds */
   6551 		isc_time_set(&zone->keywarntime, when - delta, 0);
   6552 	} else {
   6553 		isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
   6554 		isc_time_formattimestamp(&zone->keywarntime, timebuf, 80);
   6555 		dns_zone_log(zone, ISC_LOG_NOTICE, "setting keywarntime to %s",
   6556 			     timebuf);
   6557 	}
   6558 }
   6559 
   6560 /*
   6561  * Helper function to del_sigs(). We don't want to delete RRSIGs that
   6562  * have no new key.
   6563  */
   6564 static bool
   6565 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
   6566 	  bool *warn) {
   6567 	unsigned int i = 0;
   6568 	isc_result_t ret;
   6569 	bool have_ksk = false, have_zsk = false;
   6570 	bool have_pksk = false, have_pzsk = false;
   6571 
   6572 	for (i = 0; i < nkeys; i++) {
   6573 		bool ksk, zsk;
   6574 
   6575 		if (have_pksk && have_ksk && have_pzsk && have_zsk) {
   6576 			break;
   6577 		}
   6578 
   6579 		if (rrsig_ptr->algorithm != dst_key_alg(keys[i])) {
   6580 			continue;
   6581 		}
   6582 
   6583 		ret = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   6584 		if (ret != ISC_R_SUCCESS) {
   6585 			ksk = KSK(keys[i]);
   6586 		}
   6587 		ret = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   6588 		if (ret != ISC_R_SUCCESS) {
   6589 			zsk = !KSK(keys[i]);
   6590 		}
   6591 
   6592 		if (ksk) {
   6593 			have_ksk = true;
   6594 			if (dst_key_isprivate(keys[i])) {
   6595 				have_pksk = true;
   6596 			}
   6597 		}
   6598 		if (zsk) {
   6599 			have_zsk = true;
   6600 			if (dst_key_isprivate(keys[i])) {
   6601 				have_pzsk = true;
   6602 			}
   6603 		}
   6604 	}
   6605 
   6606 	if (have_zsk && have_ksk && !have_pzsk) {
   6607 		*warn = true;
   6608 	}
   6609 
   6610 	/*
   6611 	 * It's okay to delete a signature if there is an active key
   6612 	 * with the same algorithm to replace it.
   6613 	 */
   6614 	if (have_pksk || have_pzsk) {
   6615 		return (true);
   6616 	}
   6617 
   6618 	/*
   6619 	 * Failing that, it is *not* okay to delete a signature
   6620 	 * if the associated public key is still in the DNSKEY RRset
   6621 	 */
   6622 	for (i = 0; i < nkeys; i++) {
   6623 		if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
   6624 		    (rrsig_ptr->keyid == dst_key_id(keys[i])))
   6625 		{
   6626 			return (false);
   6627 		}
   6628 	}
   6629 
   6630 	/*
   6631 	 * But if the key is gone, then go ahead.
   6632 	 */
   6633 	return (true);
   6634 }
   6635 
   6636 /*
   6637  * Delete expired RRsigs and any RRsigs we are about to re-sign.
   6638  * See also update.c:del_keysigs().
   6639  */
   6640 static isc_result_t
   6641 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   6642 	 dns_rdatatype_t type, dns__zonediff_t *zonediff, dst_key_t **keys,
   6643 	 unsigned int nkeys, isc_stdtime_t now, bool incremental) {
   6644 	isc_result_t result;
   6645 	dns_dbnode_t *node = NULL;
   6646 	dns_rdataset_t rdataset;
   6647 	unsigned int i;
   6648 	dns_rdata_rrsig_t rrsig;
   6649 	bool found;
   6650 	int64_t timewarn = 0, timemaybe = 0;
   6651 
   6652 	dns_rdataset_init(&rdataset);
   6653 
   6654 	if (type == dns_rdatatype_nsec3) {
   6655 		result = dns_db_findnsec3node(db, name, false, &node);
   6656 	} else {
   6657 		result = dns_db_findnode(db, name, false, &node);
   6658 	}
   6659 	if (result == ISC_R_NOTFOUND) {
   6660 		return (ISC_R_SUCCESS);
   6661 	}
   6662 	if (result != ISC_R_SUCCESS) {
   6663 		goto failure;
   6664 	}
   6665 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
   6666 				     (isc_stdtime_t)0, &rdataset, NULL);
   6667 	dns_db_detachnode(db, &node);
   6668 
   6669 	if (result == ISC_R_NOTFOUND) {
   6670 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6671 		return (ISC_R_SUCCESS);
   6672 	}
   6673 	if (result != ISC_R_SUCCESS) {
   6674 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6675 		goto failure;
   6676 	}
   6677 
   6678 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   6679 	     result = dns_rdataset_next(&rdataset))
   6680 	{
   6681 		dns_rdata_t rdata = DNS_RDATA_INIT;
   6682 
   6683 		dns_rdataset_current(&rdataset, &rdata);
   6684 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   6685 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   6686 
   6687 		if (type != dns_rdatatype_dnskey && type != dns_rdatatype_cds &&
   6688 		    type != dns_rdatatype_cdnskey)
   6689 		{
   6690 			bool warn = false, deleted = false;
   6691 			if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
   6692 				result = update_one_rr(db, ver, zonediff->diff,
   6693 						       DNS_DIFFOP_DELRESIGN,
   6694 						       name, rdataset.ttl,
   6695 						       &rdata);
   6696 				if (result != ISC_R_SUCCESS) {
   6697 					break;
   6698 				}
   6699 				deleted = true;
   6700 			}
   6701 			if (warn) {
   6702 				/*
   6703 				 * At this point, we've got an RRSIG,
   6704 				 * which is signed by an inactive key.
   6705 				 * An administrator needs to provide a new
   6706 				 * key/alg, but until that time, we want to
   6707 				 * keep the old RRSIG.  Marking the key as
   6708 				 * offline will prevent us spinning waiting
   6709 				 * for the private part.
   6710 				 */
   6711 				if (incremental && !deleted) {
   6712 					result = offline(db, ver, zonediff,
   6713 							 name, rdataset.ttl,
   6714 							 &rdata);
   6715 					if (result != ISC_R_SUCCESS) {
   6716 						break;
   6717 					}
   6718 				}
   6719 
   6720 				/*
   6721 				 * Log the key id and algorithm of
   6722 				 * the inactive key with no replacement
   6723 				 */
   6724 				if (zone->log_key_expired_timer <= now) {
   6725 					char origin[DNS_NAME_FORMATSIZE];
   6726 					char algbuf[DNS_NAME_FORMATSIZE];
   6727 					dns_name_format(&zone->origin, origin,
   6728 							sizeof(origin));
   6729 					dns_secalg_format(rrsig.algorithm,
   6730 							  algbuf,
   6731 							  sizeof(algbuf));
   6732 					dns_zone_log(zone, ISC_LOG_WARNING,
   6733 						     "Key %s/%s/%d "
   6734 						     "missing or inactive "
   6735 						     "and has no replacement: "
   6736 						     "retaining signatures.",
   6737 						     origin, algbuf,
   6738 						     rrsig.keyid);
   6739 					zone->log_key_expired_timer = now +
   6740 								      3600;
   6741 				}
   6742 			}
   6743 			continue;
   6744 		}
   6745 
   6746 		/*
   6747 		 * KSK RRSIGs requires special processing.
   6748 		 */
   6749 		found = false;
   6750 		for (i = 0; i < nkeys; i++) {
   6751 			if (rrsig.algorithm == dst_key_alg(keys[i]) &&
   6752 			    rrsig.keyid == dst_key_id(keys[i]))
   6753 			{
   6754 				found = true;
   6755 				/*
   6756 				 * Mark offline DNSKEY.
   6757 				 * We want the earliest offline expire time
   6758 				 * iff there is a new offline signature.
   6759 				 */
   6760 				if (!dst_key_inactive(keys[i]) &&
   6761 				    !dst_key_isprivate(keys[i])) {
   6762 					int64_t timeexpire = dns_time64_from32(
   6763 						rrsig.timeexpire);
   6764 					if (timewarn != 0 &&
   6765 					    timewarn > timeexpire) {
   6766 						timewarn = timeexpire;
   6767 					}
   6768 					if (rdata.flags & DNS_RDATA_OFFLINE) {
   6769 						if (timemaybe == 0 ||
   6770 						    timemaybe > timeexpire) {
   6771 							timemaybe = timeexpire;
   6772 						}
   6773 						break;
   6774 					}
   6775 					if (timewarn == 0) {
   6776 						timewarn = timemaybe;
   6777 					}
   6778 					if (timewarn == 0 ||
   6779 					    timewarn > timeexpire) {
   6780 						timewarn = timeexpire;
   6781 					}
   6782 					result = offline(db, ver, zonediff,
   6783 							 name, rdataset.ttl,
   6784 							 &rdata);
   6785 					break;
   6786 				}
   6787 				result = update_one_rr(db, ver, zonediff->diff,
   6788 						       DNS_DIFFOP_DELRESIGN,
   6789 						       name, rdataset.ttl,
   6790 						       &rdata);
   6791 				break;
   6792 			}
   6793 		}
   6794 
   6795 		/*
   6796 		 * If there is not a matching DNSKEY then
   6797 		 * delete the RRSIG.
   6798 		 */
   6799 		if (!found) {
   6800 			result = update_one_rr(db, ver, zonediff->diff,
   6801 					       DNS_DIFFOP_DELRESIGN, name,
   6802 					       rdataset.ttl, &rdata);
   6803 		}
   6804 		if (result != ISC_R_SUCCESS) {
   6805 			break;
   6806 		}
   6807 	}
   6808 
   6809 	dns_rdataset_disassociate(&rdataset);
   6810 	if (result == ISC_R_NOMORE) {
   6811 		result = ISC_R_SUCCESS;
   6812 	}
   6813 	if (timewarn > 0) {
   6814 		isc_stdtime_t stdwarn = (isc_stdtime_t)timewarn;
   6815 		if (timewarn == stdwarn) {
   6816 			set_key_expiry_warning(zone, (isc_stdtime_t)timewarn,
   6817 					       now);
   6818 		} else {
   6819 			dns_zone_log(zone, ISC_LOG_ERROR,
   6820 				     "key expiry warning time out of range");
   6821 		}
   6822 	}
   6823 failure:
   6824 	if (node != NULL) {
   6825 		dns_db_detachnode(db, &node);
   6826 	}
   6827 	return (result);
   6828 }
   6829 
   6830 static isc_result_t
   6831 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name, dns_zone_t *zone,
   6832 	 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
   6833 	 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
   6834 	 isc_stdtime_t expire, bool check_ksk, bool keyset_kskonly) {
   6835 	isc_result_t result;
   6836 	dns_dbnode_t *node = NULL;
   6837 	dns_stats_t *dnssecsignstats;
   6838 	dns_rdataset_t rdataset;
   6839 	dns_rdata_t sig_rdata = DNS_RDATA_INIT;
   6840 	unsigned char data[1024]; /* XXX */
   6841 	isc_buffer_t buffer;
   6842 	unsigned int i, j;
   6843 	bool use_kasp = false;
   6844 
   6845 	if (dns_zone_use_kasp(zone)) {
   6846 		check_ksk = false;
   6847 		keyset_kskonly = true;
   6848 		use_kasp = true;
   6849 	}
   6850 
   6851 	dns_rdataset_init(&rdataset);
   6852 	isc_buffer_init(&buffer, data, sizeof(data));
   6853 
   6854 	if (type == dns_rdatatype_nsec3) {
   6855 		result = dns_db_findnsec3node(db, name, false, &node);
   6856 	} else {
   6857 		result = dns_db_findnode(db, name, false, &node);
   6858 	}
   6859 	if (result == ISC_R_NOTFOUND) {
   6860 		return (ISC_R_SUCCESS);
   6861 	}
   6862 	if (result != ISC_R_SUCCESS) {
   6863 		goto failure;
   6864 	}
   6865 	result = dns_db_findrdataset(db, node, ver, type, 0, (isc_stdtime_t)0,
   6866 				     &rdataset, NULL);
   6867 	dns_db_detachnode(db, &node);
   6868 	if (result == ISC_R_NOTFOUND) {
   6869 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6870 		return (ISC_R_SUCCESS);
   6871 	}
   6872 	if (result != ISC_R_SUCCESS) {
   6873 		INSIST(!dns_rdataset_isassociated(&rdataset));
   6874 		goto failure;
   6875 	}
   6876 
   6877 	for (i = 0; i < nkeys; i++) {
   6878 		bool both = false;
   6879 
   6880 		/* Don't add signatures for offline or inactive keys */
   6881 		if (!dst_key_isprivate(keys[i])) {
   6882 			continue;
   6883 		}
   6884 		if (dst_key_inactive(keys[i])) {
   6885 			continue;
   6886 		}
   6887 
   6888 		if (check_ksk && !REVOKE(keys[i])) {
   6889 			bool have_ksk, have_nonksk;
   6890 			if (KSK(keys[i])) {
   6891 				have_ksk = true;
   6892 				have_nonksk = false;
   6893 			} else {
   6894 				have_ksk = false;
   6895 				have_nonksk = true;
   6896 			}
   6897 
   6898 			for (j = 0; j < nkeys; j++) {
   6899 				if (j == i || ALG(keys[i]) != ALG(keys[j])) {
   6900 					continue;
   6901 				}
   6902 
   6903 				/* Don't consider inactive keys, however
   6904 				 * the key may be temporary offline, so do
   6905 				 * consider keys which private key files are
   6906 				 * unavailable.
   6907 				 */
   6908 				if (dst_key_inactive(keys[j])) {
   6909 					continue;
   6910 				}
   6911 
   6912 				if (REVOKE(keys[j])) {
   6913 					continue;
   6914 				}
   6915 				if (KSK(keys[j])) {
   6916 					have_ksk = true;
   6917 				} else {
   6918 					have_nonksk = true;
   6919 				}
   6920 				both = have_ksk && have_nonksk;
   6921 				if (both) {
   6922 					break;
   6923 				}
   6924 			}
   6925 		}
   6926 		if (use_kasp) {
   6927 			/*
   6928 			 * A dnssec-policy is found. Check what RRsets this
   6929 			 * key should sign.
   6930 			 */
   6931 			isc_result_t kresult;
   6932 			isc_stdtime_t when;
   6933 			bool ksk = false;
   6934 			bool zsk = false;
   6935 
   6936 			kresult = dst_key_getbool(keys[i], DST_BOOL_KSK, &ksk);
   6937 			if (kresult != ISC_R_SUCCESS) {
   6938 				if (KSK(keys[i])) {
   6939 					ksk = true;
   6940 				}
   6941 			}
   6942 			kresult = dst_key_getbool(keys[i], DST_BOOL_ZSK, &zsk);
   6943 			if (kresult != ISC_R_SUCCESS) {
   6944 				if (!KSK(keys[i])) {
   6945 					zsk = true;
   6946 				}
   6947 			}
   6948 
   6949 			if (type == dns_rdatatype_dnskey ||
   6950 			    type == dns_rdatatype_cdnskey ||
   6951 			    type == dns_rdatatype_cds)
   6952 			{
   6953 				/*
   6954 				 * DNSKEY RRset is signed with KSK.
   6955 				 * CDS and CDNSKEY RRsets too (RFC 7344, 4.1).
   6956 				 */
   6957 				if (!ksk) {
   6958 					continue;
   6959 				}
   6960 			} else if (!zsk) {
   6961 				/*
   6962 				 * Other RRsets are signed with ZSK.
   6963 				 */
   6964 				continue;
   6965 			} else if (!dst_key_is_signing(keys[i], DST_BOOL_ZSK,
   6966 						       inception, &when)) {
   6967 				/*
   6968 				 * This key is not active for zone-signing.
   6969 				 */
   6970 				continue;
   6971 			}
   6972 
   6973 			/*
   6974 			 * If this key is revoked, it may only sign the
   6975 			 * DNSKEY RRset.
   6976 			 */
   6977 			if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   6978 				continue;
   6979 			}
   6980 		} else if (both) {
   6981 			/*
   6982 			 * CDS and CDNSKEY are signed with KSK (RFC 7344, 4.1).
   6983 			 */
   6984 			if (type == dns_rdatatype_dnskey ||
   6985 			    type == dns_rdatatype_cdnskey ||
   6986 			    type == dns_rdatatype_cds)
   6987 			{
   6988 				if (!KSK(keys[i]) && keyset_kskonly) {
   6989 					continue;
   6990 				}
   6991 			} else if (KSK(keys[i])) {
   6992 				continue;
   6993 			}
   6994 		} else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey) {
   6995 			continue;
   6996 		}
   6997 
   6998 		/* Calculate the signature, creating a RRSIG RDATA. */
   6999 		isc_buffer_clear(&buffer);
   7000 		CHECK(dns_dnssec_sign(name, &rdataset, keys[i], &inception,
   7001 				      &expire, mctx, &buffer, &sig_rdata));
   7002 
   7003 		/* Update the database and journal with the RRSIG. */
   7004 		/* XXX inefficient - will cause dataset merging */
   7005 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN, name,
   7006 				    rdataset.ttl, &sig_rdata));
   7007 		dns_rdata_reset(&sig_rdata);
   7008 		isc_buffer_init(&buffer, data, sizeof(data));
   7009 
   7010 		/* Update DNSSEC sign statistics. */
   7011 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7012 		if (dnssecsignstats != NULL) {
   7013 			/* Generated a new signature. */
   7014 			dns_dnssecsignstats_increment(dnssecsignstats,
   7015 						      ID(keys[i]),
   7016 						      (uint8_t)ALG(keys[i]),
   7017 						      dns_dnssecsignstats_sign);
   7018 			/* This is a refresh. */
   7019 			dns_dnssecsignstats_increment(
   7020 				dnssecsignstats, ID(keys[i]),
   7021 				(uint8_t)ALG(keys[i]),
   7022 				dns_dnssecsignstats_refresh);
   7023 		}
   7024 	}
   7025 
   7026 failure:
   7027 	if (dns_rdataset_isassociated(&rdataset)) {
   7028 		dns_rdataset_disassociate(&rdataset);
   7029 	}
   7030 	if (node != NULL) {
   7031 		dns_db_detachnode(db, &node);
   7032 	}
   7033 	return (result);
   7034 }
   7035 
   7036 static void
   7037 zone_resigninc(dns_zone_t *zone) {
   7038 	const char *me = "zone_resigninc";
   7039 	dns_db_t *db = NULL;
   7040 	dns_dbversion_t *version = NULL;
   7041 	dns_diff_t _sig_diff;
   7042 	dns__zonediff_t zonediff;
   7043 	dns_fixedname_t fixed;
   7044 	dns_name_t *name;
   7045 	dns_rdataset_t rdataset;
   7046 	dns_rdatatype_t covers;
   7047 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   7048 	bool check_ksk, keyset_kskonly = false;
   7049 	isc_result_t result;
   7050 	isc_stdtime_t now, inception, soaexpire, expire, fullexpire, stop;
   7051 	uint32_t sigvalidityinterval, expiryinterval;
   7052 	unsigned int i;
   7053 	unsigned int nkeys = 0;
   7054 	unsigned int resign;
   7055 
   7056 	ENTER;
   7057 
   7058 	dns_rdataset_init(&rdataset);
   7059 	dns_diff_init(zone->mctx, &_sig_diff);
   7060 	zonediff_init(&zonediff, &_sig_diff);
   7061 
   7062 	/*
   7063 	 * Zone is frozen or automatic resigning is disabled.
   7064 	 * Pause for 5 minutes.
   7065 	 */
   7066 	if (zone->update_disabled ||
   7067 	    DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_NORESIGN)) {
   7068 		result = ISC_R_FAILURE;
   7069 		goto failure;
   7070 	}
   7071 
   7072 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   7073 	dns_db_attach(zone->db, &db);
   7074 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   7075 
   7076 	result = dns_db_newversion(db, &version);
   7077 	if (result != ISC_R_SUCCESS) {
   7078 		dns_zone_log(zone, ISC_LOG_ERROR,
   7079 			     "zone_resigninc:dns_db_newversion -> %s",
   7080 			     dns_result_totext(result));
   7081 		goto failure;
   7082 	}
   7083 
   7084 	isc_stdtime_get(&now);
   7085 
   7086 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   7087 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   7088 	if (result != ISC_R_SUCCESS) {
   7089 		dns_zone_log(zone, ISC_LOG_ERROR,
   7090 			     "zone_resigninc:dns__zone_findkeys -> %s",
   7091 			     dns_result_totext(result));
   7092 		goto failure;
   7093 	}
   7094 
   7095 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   7096 	inception = now - 3600; /* Allow for clock skew. */
   7097 	soaexpire = now + sigvalidityinterval;
   7098 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   7099 	if (expiryinterval > sigvalidityinterval) {
   7100 		expiryinterval = sigvalidityinterval;
   7101 	} else {
   7102 		expiryinterval = sigvalidityinterval - expiryinterval;
   7103 	}
   7104 
   7105 	/*
   7106 	 * Spread out signatures over time if they happen to be
   7107 	 * clumped.  We don't do this for each add_sigs() call as
   7108 	 * we still want some clustering to occur.  In normal operations
   7109 	 * the records should be re-signed as they fall due and they should
   7110 	 * already be spread out.  However if the server is off for a
   7111 	 * period we need to ensure that the clusters don't become
   7112 	 * synchronised by using the full jitter range.
   7113 	 */
   7114 	if (sigvalidityinterval >= 3600U) {
   7115 		uint32_t normaljitter, fulljitter;
   7116 		if (sigvalidityinterval > 7200U) {
   7117 			normaljitter = isc_random_uniform(3600);
   7118 			fulljitter = isc_random_uniform(expiryinterval);
   7119 		} else {
   7120 			normaljitter = fulljitter = isc_random_uniform(1200);
   7121 		}
   7122 		expire = soaexpire - normaljitter - 1;
   7123 		fullexpire = soaexpire - fulljitter - 1;
   7124 	} else {
   7125 		expire = fullexpire = soaexpire - 1;
   7126 	}
   7127 	stop = now + 5;
   7128 
   7129 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   7130 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   7131 
   7132 	name = dns_fixedname_initname(&fixed);
   7133 	result = dns_db_getsigningtime(db, &rdataset, name);
   7134 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   7135 		dns_zone_log(zone, ISC_LOG_ERROR,
   7136 			     "zone_resigninc:dns_db_getsigningtime -> %s",
   7137 			     dns_result_totext(result));
   7138 	}
   7139 
   7140 	i = 0;
   7141 	while (result == ISC_R_SUCCESS) {
   7142 		resign = rdataset.resign -
   7143 			 dns_zone_getsigresigninginterval(zone);
   7144 		covers = rdataset.covers;
   7145 		dns_rdataset_disassociate(&rdataset);
   7146 
   7147 		/*
   7148 		 * Stop if we hit the SOA as that means we have walked the
   7149 		 * entire zone.  The SOA record should always be the most
   7150 		 * recent signature.
   7151 		 */
   7152 		/* XXXMPA increase number of RRsets signed pre call */
   7153 		if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
   7154 		    resign > stop) {
   7155 			break;
   7156 		}
   7157 
   7158 		result = del_sigs(zone, db, version, name, covers, &zonediff,
   7159 				  zone_keys, nkeys, now, true);
   7160 		if (result != ISC_R_SUCCESS) {
   7161 			dns_zone_log(zone, ISC_LOG_ERROR,
   7162 				     "zone_resigninc:del_sigs -> %s",
   7163 				     dns_result_totext(result));
   7164 			break;
   7165 		}
   7166 
   7167 		/*
   7168 		 * If re-signing is over 5 minutes late use 'fullexpire'
   7169 		 * to redistribute the signature over the complete
   7170 		 * re-signing window, otherwise only add a small amount
   7171 		 * of jitter.
   7172 		 */
   7173 		result = add_sigs(db, version, name, zone, covers,
   7174 				  zonediff.diff, zone_keys, nkeys, zone->mctx,
   7175 				  inception,
   7176 				  resign > (now - 300) ? expire : fullexpire,
   7177 				  check_ksk, keyset_kskonly);
   7178 		if (result != ISC_R_SUCCESS) {
   7179 			dns_zone_log(zone, ISC_LOG_ERROR,
   7180 				     "zone_resigninc:add_sigs -> %s",
   7181 				     dns_result_totext(result));
   7182 			break;
   7183 		}
   7184 		result = dns_db_getsigningtime(db, &rdataset, name);
   7185 		if (nkeys == 0 && result == ISC_R_NOTFOUND) {
   7186 			result = ISC_R_SUCCESS;
   7187 			break;
   7188 		}
   7189 		if (result != ISC_R_SUCCESS) {
   7190 			dns_zone_log(zone, ISC_LOG_ERROR,
   7191 				     "zone_resigninc:dns_db_getsigningtime -> "
   7192 				     "%s",
   7193 				     dns_result_totext(result));
   7194 		}
   7195 	}
   7196 
   7197 	if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS) {
   7198 		goto failure;
   7199 	}
   7200 
   7201 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   7202 			  &zonediff, zone_keys, nkeys, now, true);
   7203 	if (result != ISC_R_SUCCESS) {
   7204 		dns_zone_log(zone, ISC_LOG_ERROR,
   7205 			     "zone_resigninc:del_sigs -> %s",
   7206 			     dns_result_totext(result));
   7207 		goto failure;
   7208 	}
   7209 
   7210 	/*
   7211 	 * Did we change anything in the zone?
   7212 	 */
   7213 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   7214 		/*
   7215 		 * Commit the changes if any key has been marked as offline.
   7216 		 */
   7217 		if (zonediff.offline) {
   7218 			dns_db_closeversion(db, &version, true);
   7219 		}
   7220 		goto failure;
   7221 	}
   7222 
   7223 	/* Increment SOA serial if we have made changes */
   7224 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   7225 				   zone->updatemethod);
   7226 	if (result != ISC_R_SUCCESS) {
   7227 		dns_zone_log(zone, ISC_LOG_ERROR,
   7228 			     "zone_resigninc:update_soa_serial -> %s",
   7229 			     dns_result_totext(result));
   7230 		goto failure;
   7231 	}
   7232 
   7233 	/*
   7234 	 * Generate maximum life time signatures so that the above loop
   7235 	 * termination is sensible.
   7236 	 */
   7237 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   7238 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   7239 			  inception, soaexpire, check_ksk, keyset_kskonly);
   7240 	if (result != ISC_R_SUCCESS) {
   7241 		dns_zone_log(zone, ISC_LOG_ERROR,
   7242 			     "zone_resigninc:add_sigs -> %s",
   7243 			     dns_result_totext(result));
   7244 		goto failure;
   7245 	}
   7246 
   7247 	/* Write changes to journal file. */
   7248 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_resigninc"));
   7249 
   7250 	/* Everything has succeeded. Commit the changes. */
   7251 	dns_db_closeversion(db, &version, true);
   7252 
   7253 failure:
   7254 	dns_diff_clear(&_sig_diff);
   7255 	for (i = 0; i < nkeys; i++) {
   7256 		dst_key_free(&zone_keys[i]);
   7257 	}
   7258 	if (version != NULL) {
   7259 		dns_db_closeversion(db, &version, false);
   7260 		dns_db_detach(&db);
   7261 	} else if (db != NULL) {
   7262 		dns_db_detach(&db);
   7263 	}
   7264 
   7265 	LOCK_ZONE(zone);
   7266 	if (result == ISC_R_SUCCESS) {
   7267 		set_resigntime(zone);
   7268 		zone_needdump(zone, DNS_DUMP_DELAY);
   7269 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   7270 	} else {
   7271 		/*
   7272 		 * Something failed.  Retry in 5 minutes.
   7273 		 */
   7274 		isc_interval_t ival;
   7275 		isc_interval_set(&ival, 300, 0);
   7276 		isc_time_nowplusinterval(&zone->resigntime, &ival);
   7277 	}
   7278 	UNLOCK_ZONE(zone);
   7279 
   7280 	INSIST(version == NULL);
   7281 }
   7282 
   7283 static isc_result_t
   7284 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
   7285 	    dns_name_t *newname, bool bottom) {
   7286 	isc_result_t result;
   7287 	dns_dbiterator_t *dbit = NULL;
   7288 	dns_rdatasetiter_t *rdsit = NULL;
   7289 	dns_dbnode_t *node = NULL;
   7290 
   7291 	CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
   7292 	CHECK(dns_dbiterator_seek(dbit, oldname));
   7293 	do {
   7294 		result = dns_dbiterator_next(dbit);
   7295 		if (result == ISC_R_NOMORE) {
   7296 			CHECK(dns_dbiterator_first(dbit));
   7297 		}
   7298 		CHECK(dns_dbiterator_current(dbit, &node, newname));
   7299 		if (bottom && dns_name_issubdomain(newname, oldname) &&
   7300 		    !dns_name_equal(newname, oldname))
   7301 		{
   7302 			dns_db_detachnode(db, &node);
   7303 			continue;
   7304 		}
   7305 		/*
   7306 		 * Is this node empty?
   7307 		 */
   7308 		CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
   7309 		result = dns_rdatasetiter_first(rdsit);
   7310 		dns_db_detachnode(db, &node);
   7311 		dns_rdatasetiter_destroy(&rdsit);
   7312 		if (result != ISC_R_NOMORE) {
   7313 			break;
   7314 		}
   7315 	} while (1);
   7316 failure:
   7317 	if (node != NULL) {
   7318 		dns_db_detachnode(db, &node);
   7319 	}
   7320 	if (dbit != NULL) {
   7321 		dns_dbiterator_destroy(&dbit);
   7322 	}
   7323 	return (result);
   7324 }
   7325 
   7326 static bool
   7327 signed_with_good_key(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
   7328 		     dns_dbversion_t *version, dns_rdatatype_t type,
   7329 		     dst_key_t *key) {
   7330 	isc_result_t result;
   7331 	dns_rdataset_t rdataset;
   7332 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7333 	dns_rdata_rrsig_t rrsig;
   7334 	int count = 0;
   7335 	dns_kasp_t *kasp = dns_zone_getkasp(zone);
   7336 
   7337 	dns_rdataset_init(&rdataset);
   7338 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
   7339 				     type, 0, &rdataset, NULL);
   7340 	if (result != ISC_R_SUCCESS) {
   7341 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7342 		return (false);
   7343 	}
   7344 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7345 	     result = dns_rdataset_next(&rdataset))
   7346 	{
   7347 		dns_rdataset_current(&rdataset, &rdata);
   7348 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   7349 		INSIST(result == ISC_R_SUCCESS);
   7350 		if (rrsig.algorithm == dst_key_alg(key) &&
   7351 		    rrsig.keyid == dst_key_id(key)) {
   7352 			dns_rdataset_disassociate(&rdataset);
   7353 			return (true);
   7354 		}
   7355 		if (rrsig.algorithm == dst_key_alg(key)) {
   7356 			count++;
   7357 		}
   7358 		dns_rdata_reset(&rdata);
   7359 	}
   7360 
   7361 	if (dns_zone_use_kasp(zone)) {
   7362 		dns_kasp_key_t *kkey;
   7363 		int zsk_count = 0;
   7364 		bool approved;
   7365 
   7366 		LOCK(&kasp->lock);
   7367 		for (kkey = ISC_LIST_HEAD(dns_kasp_keys(kasp)); kkey != NULL;
   7368 		     kkey = ISC_LIST_NEXT(kkey, link))
   7369 		{
   7370 			if (dns_kasp_key_algorithm(kkey) != dst_key_alg(key)) {
   7371 				continue;
   7372 			}
   7373 			if (dns_kasp_key_zsk(kkey)) {
   7374 				zsk_count++;
   7375 			}
   7376 		}
   7377 		UNLOCK(&kasp->lock);
   7378 
   7379 		if (type == dns_rdatatype_dnskey ||
   7380 		    type == dns_rdatatype_cdnskey || type == dns_rdatatype_cds)
   7381 		{
   7382 			/*
   7383 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7384 			 * (RFC 7344, section 4.1 specifies that they must
   7385 			 * be signed with a key in the current DS RRset,
   7386 			 * which would only include KSK's.)
   7387 			 */
   7388 			approved = false;
   7389 		} else {
   7390 			approved = (zsk_count == count);
   7391 		}
   7392 
   7393 		dns_rdataset_disassociate(&rdataset);
   7394 		return (approved);
   7395 	}
   7396 
   7397 	dns_rdataset_disassociate(&rdataset);
   7398 	return (false);
   7399 }
   7400 
   7401 static isc_result_t
   7402 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7403 	 dns_dbnode_t *node, dns_ttl_t ttl, bool bottom, dns_diff_t *diff) {
   7404 	dns_fixedname_t fixed;
   7405 	dns_name_t *next;
   7406 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7407 	isc_result_t result;
   7408 	unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
   7409 
   7410 	next = dns_fixedname_initname(&fixed);
   7411 
   7412 	CHECK(next_active(db, version, name, next, bottom));
   7413 	CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer, &rdata));
   7414 	CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
   7415 			    &rdata));
   7416 failure:
   7417 	return (result);
   7418 }
   7419 
   7420 static isc_result_t
   7421 check_if_bottom_of_zone(dns_db_t *db, dns_dbnode_t *node,
   7422 			dns_dbversion_t *version, bool *is_bottom_of_zone) {
   7423 	isc_result_t result;
   7424 	dns_rdatasetiter_t *iterator = NULL;
   7425 	dns_rdataset_t rdataset;
   7426 	bool seen_soa = false, seen_ns = false, seen_dname = false;
   7427 
   7428 	REQUIRE(is_bottom_of_zone != NULL);
   7429 
   7430 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   7431 	if (result != ISC_R_SUCCESS) {
   7432 		if (result == ISC_R_NOTFOUND) {
   7433 			result = ISC_R_SUCCESS;
   7434 		}
   7435 		return (result);
   7436 	}
   7437 
   7438 	dns_rdataset_init(&rdataset);
   7439 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7440 	     result = dns_rdatasetiter_next(iterator))
   7441 	{
   7442 		dns_rdatasetiter_current(iterator, &rdataset);
   7443 		switch (rdataset.type) {
   7444 		case dns_rdatatype_soa:
   7445 			seen_soa = true;
   7446 			break;
   7447 		case dns_rdatatype_ns:
   7448 			seen_ns = true;
   7449 			break;
   7450 		case dns_rdatatype_dname:
   7451 			seen_dname = true;
   7452 			break;
   7453 		}
   7454 		dns_rdataset_disassociate(&rdataset);
   7455 	}
   7456 	if (result != ISC_R_NOMORE) {
   7457 		goto failure;
   7458 	}
   7459 	if ((seen_ns && !seen_soa) || seen_dname) {
   7460 		*is_bottom_of_zone = true;
   7461 	}
   7462 	result = ISC_R_SUCCESS;
   7463 
   7464 failure:
   7465 	dns_rdatasetiter_destroy(&iterator);
   7466 
   7467 	return (result);
   7468 }
   7469 
   7470 static isc_result_t
   7471 sign_a_node(dns_db_t *db, dns_zone_t *zone, dns_name_t *name,
   7472 	    dns_dbnode_t *node, dns_dbversion_t *version, bool build_nsec3,
   7473 	    bool build_nsec, dst_key_t *key, isc_stdtime_t inception,
   7474 	    isc_stdtime_t expire, unsigned int minimum, bool is_ksk,
   7475 	    bool is_zsk, bool keyset_kskonly, bool is_bottom_of_zone,
   7476 	    dns_diff_t *diff, int32_t *signatures, isc_mem_t *mctx) {
   7477 	isc_result_t result;
   7478 	dns_rdatasetiter_t *iterator = NULL;
   7479 	dns_rdataset_t rdataset;
   7480 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7481 	dns_stats_t *dnssecsignstats;
   7482 
   7483 	isc_buffer_t buffer;
   7484 	unsigned char data[1024];
   7485 	bool seen_soa, seen_ns, seen_rr, seen_nsec, seen_nsec3, seen_ds;
   7486 
   7487 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   7488 	if (result != ISC_R_SUCCESS) {
   7489 		if (result == ISC_R_NOTFOUND) {
   7490 			result = ISC_R_SUCCESS;
   7491 		}
   7492 		return (result);
   7493 	}
   7494 
   7495 	dns_rdataset_init(&rdataset);
   7496 	isc_buffer_init(&buffer, data, sizeof(data));
   7497 	seen_rr = seen_soa = seen_ns = seen_nsec = seen_nsec3 = seen_ds = false;
   7498 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   7499 	     result = dns_rdatasetiter_next(iterator))
   7500 	{
   7501 		dns_rdatasetiter_current(iterator, &rdataset);
   7502 		if (rdataset.type == dns_rdatatype_soa) {
   7503 			seen_soa = true;
   7504 		} else if (rdataset.type == dns_rdatatype_ns) {
   7505 			seen_ns = true;
   7506 		} else if (rdataset.type == dns_rdatatype_ds) {
   7507 			seen_ds = true;
   7508 		} else if (rdataset.type == dns_rdatatype_nsec) {
   7509 			seen_nsec = true;
   7510 		} else if (rdataset.type == dns_rdatatype_nsec3) {
   7511 			seen_nsec3 = true;
   7512 		}
   7513 		if (rdataset.type != dns_rdatatype_rrsig) {
   7514 			seen_rr = true;
   7515 		}
   7516 		dns_rdataset_disassociate(&rdataset);
   7517 	}
   7518 	if (result != ISC_R_NOMORE) {
   7519 		goto failure;
   7520 	}
   7521 	/*
   7522 	 * Going from insecure to NSEC3.
   7523 	 * Don't generate NSEC3 records for NSEC3 records.
   7524 	 */
   7525 	if (build_nsec3 && !seen_nsec3 && seen_rr) {
   7526 		bool unsecure = !seen_ds && seen_ns && !seen_soa;
   7527 		CHECK(dns_nsec3_addnsec3s(db, version, name, minimum, unsecure,
   7528 					  diff));
   7529 		(*signatures)--;
   7530 	}
   7531 	/*
   7532 	 * Going from insecure to NSEC.
   7533 	 * Don't generate NSEC records for NSEC3 records.
   7534 	 */
   7535 	if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
   7536 		/*
   7537 		 * Build a NSEC record except at the origin.
   7538 		 */
   7539 		if (!dns_name_equal(name, dns_db_origin(db))) {
   7540 			CHECK(add_nsec(db, version, name, node, minimum,
   7541 				       is_bottom_of_zone, diff));
   7542 			/* Count a NSEC generation as a signature generation. */
   7543 			(*signatures)--;
   7544 		}
   7545 	}
   7546 	result = dns_rdatasetiter_first(iterator);
   7547 	while (result == ISC_R_SUCCESS) {
   7548 		isc_stdtime_t when;
   7549 
   7550 		dns_rdatasetiter_current(iterator, &rdataset);
   7551 		if (rdataset.type == dns_rdatatype_soa ||
   7552 		    rdataset.type == dns_rdatatype_rrsig) {
   7553 			goto next_rdataset;
   7554 		}
   7555 		if (rdataset.type == dns_rdatatype_dnskey ||
   7556 		    rdataset.type == dns_rdatatype_cdnskey ||
   7557 		    rdataset.type == dns_rdatatype_cds)
   7558 		{
   7559 			/*
   7560 			 * CDS and CDNSKEY are signed with KSK like DNSKEY.
   7561 			 * (RFC 7344, section 4.1 specifies that they must
   7562 			 * be signed with a key in the current DS RRset,
   7563 			 * which would only include KSK's.)
   7564 			 */
   7565 			if (!is_ksk && keyset_kskonly) {
   7566 				goto next_rdataset;
   7567 			}
   7568 		} else if (!is_zsk) {
   7569 			goto next_rdataset;
   7570 		} else if (is_zsk && !dst_key_is_signing(key, DST_BOOL_ZSK,
   7571 							 inception, &when)) {
   7572 			/* Only applies to dnssec-policy. */
   7573 			if (dns_zone_use_kasp(zone)) {
   7574 				goto next_rdataset;
   7575 			}
   7576 		}
   7577 
   7578 		if (seen_ns && !seen_soa && rdataset.type != dns_rdatatype_ds &&
   7579 		    rdataset.type != dns_rdatatype_nsec)
   7580 		{
   7581 			goto next_rdataset;
   7582 		}
   7583 		if (signed_with_good_key(zone, db, node, version, rdataset.type,
   7584 					 key)) {
   7585 			goto next_rdataset;
   7586 		}
   7587 
   7588 		/* Calculate the signature, creating a RRSIG RDATA. */
   7589 		isc_buffer_clear(&buffer);
   7590 		CHECK(dns_dnssec_sign(name, &rdataset, key, &inception, &expire,
   7591 				      mctx, &buffer, &rdata));
   7592 		/* Update the database and journal with the RRSIG. */
   7593 		/* XXX inefficient - will cause dataset merging */
   7594 		CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
   7595 				    name, rdataset.ttl, &rdata));
   7596 		dns_rdata_reset(&rdata);
   7597 
   7598 		/* Update DNSSEC sign statistics. */
   7599 		dnssecsignstats = dns_zone_getdnssecsignstats(zone);
   7600 		if (dnssecsignstats != NULL) {
   7601 			/* Generated a new signature. */
   7602 			dns_dnssecsignstats_increment(dnssecsignstats, ID(key),
   7603 						      ALG(key),
   7604 						      dns_dnssecsignstats_sign);
   7605 			/* This is a refresh. */
   7606 			dns_dnssecsignstats_increment(
   7607 				dnssecsignstats, ID(key), ALG(key),
   7608 				dns_dnssecsignstats_refresh);
   7609 		}
   7610 
   7611 		(*signatures)--;
   7612 	next_rdataset:
   7613 		dns_rdataset_disassociate(&rdataset);
   7614 		result = dns_rdatasetiter_next(iterator);
   7615 	}
   7616 	if (result == ISC_R_NOMORE) {
   7617 		result = ISC_R_SUCCESS;
   7618 	}
   7619 failure:
   7620 	if (dns_rdataset_isassociated(&rdataset)) {
   7621 		dns_rdataset_disassociate(&rdataset);
   7622 	}
   7623 	if (iterator != NULL) {
   7624 		dns_rdatasetiter_destroy(&iterator);
   7625 	}
   7626 	return (result);
   7627 }
   7628 
   7629 /*
   7630  * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
   7631  */
   7632 static isc_result_t
   7633 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   7634 	     dns_ttl_t minimum, bool update_only, dns_diff_t *diff) {
   7635 	isc_result_t result;
   7636 	dns_rdataset_t rdataset;
   7637 	dns_dbnode_t *node = NULL;
   7638 
   7639 	CHECK(dns_db_getoriginnode(db, &node));
   7640 	if (update_only) {
   7641 		dns_rdataset_init(&rdataset);
   7642 		result = dns_db_findrdataset(
   7643 			db, node, version, dns_rdatatype_nsec,
   7644 			dns_rdatatype_none, 0, &rdataset, NULL);
   7645 		if (dns_rdataset_isassociated(&rdataset)) {
   7646 			dns_rdataset_disassociate(&rdataset);
   7647 		}
   7648 		if (result == ISC_R_NOTFOUND) {
   7649 			goto success;
   7650 		}
   7651 		if (result != ISC_R_SUCCESS) {
   7652 			goto failure;
   7653 		}
   7654 	}
   7655 	CHECK(delete_nsec(db, version, node, name, diff));
   7656 	CHECK(add_nsec(db, version, name, node, minimum, false, diff));
   7657 success:
   7658 	result = ISC_R_SUCCESS;
   7659 failure:
   7660 	if (node != NULL) {
   7661 		dns_db_detachnode(db, &node);
   7662 	}
   7663 	return (result);
   7664 }
   7665 
   7666 static isc_result_t
   7667 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
   7668 		  dns_dbversion_t *version, bool build_nsec3, dns_ttl_t minimum,
   7669 		  dns_diff_t *diff) {
   7670 	isc_result_t result;
   7671 	dns_dbnode_t *node = NULL;
   7672 	dns_rdataset_t rdataset;
   7673 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7674 	unsigned char data[5];
   7675 	bool seen_done = false;
   7676 	bool have_rr = false;
   7677 
   7678 	dns_rdataset_init(&rdataset);
   7679 	result = dns_db_getoriginnode(signing->db, &node);
   7680 	if (result != ISC_R_SUCCESS) {
   7681 		goto failure;
   7682 	}
   7683 
   7684 	result = dns_db_findrdataset(signing->db, node, version,
   7685 				     zone->privatetype, dns_rdatatype_none, 0,
   7686 				     &rdataset, NULL);
   7687 	if (result == ISC_R_NOTFOUND) {
   7688 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7689 		result = ISC_R_SUCCESS;
   7690 		goto failure;
   7691 	}
   7692 	if (result != ISC_R_SUCCESS) {
   7693 		INSIST(!dns_rdataset_isassociated(&rdataset));
   7694 		goto failure;
   7695 	}
   7696 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7697 	     result = dns_rdataset_next(&rdataset))
   7698 	{
   7699 		dns_rdataset_current(&rdataset, &rdata);
   7700 		/*
   7701 		 * If we don't match the algorithm or keyid skip the record.
   7702 		 */
   7703 		if (rdata.length != 5 || rdata.data[0] != signing->algorithm ||
   7704 		    rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
   7705 		    rdata.data[2] != (signing->keyid & 0xff))
   7706 		{
   7707 			have_rr = true;
   7708 			dns_rdata_reset(&rdata);
   7709 			continue;
   7710 		}
   7711 		/*
   7712 		 * We have a match.  If we were signing (!signing->deleteit)
   7713 		 * and we already have a record indicating that we have
   7714 		 * finished signing (rdata.data[4] != 0) then keep it.
   7715 		 * Otherwise it needs to be deleted as we have removed all
   7716 		 * the signatures (signing->deleteit), so any record indicating
   7717 		 * completion is now out of date, or we have finished signing
   7718 		 * with the new record so we no longer need to remember that
   7719 		 * we need to sign the zone with the matching key across a
   7720 		 * nameserver re-start.
   7721 		 */
   7722 		if (!signing->deleteit && rdata.data[4] != 0) {
   7723 			seen_done = true;
   7724 			have_rr = true;
   7725 		} else {
   7726 			CHECK(update_one_rr(signing->db, version, diff,
   7727 					    DNS_DIFFOP_DEL, &zone->origin,
   7728 					    rdataset.ttl, &rdata));
   7729 		}
   7730 		dns_rdata_reset(&rdata);
   7731 	}
   7732 	if (result == ISC_R_NOMORE) {
   7733 		result = ISC_R_SUCCESS;
   7734 	}
   7735 	if (!signing->deleteit && !seen_done) {
   7736 		/*
   7737 		 * If we were signing then we need to indicate that we have
   7738 		 * finished signing the zone with this key.  If it is already
   7739 		 * there we don't need to add it a second time.
   7740 		 */
   7741 		data[0] = signing->algorithm;
   7742 		data[1] = (signing->keyid >> 8) & 0xff;
   7743 		data[2] = signing->keyid & 0xff;
   7744 		data[3] = 0;
   7745 		data[4] = 1;
   7746 		rdata.length = sizeof(data);
   7747 		rdata.data = data;
   7748 		rdata.type = zone->privatetype;
   7749 		rdata.rdclass = dns_db_class(signing->db);
   7750 		CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
   7751 				    &zone->origin, rdataset.ttl, &rdata));
   7752 	} else if (!have_rr) {
   7753 		dns_name_t *origin = dns_db_origin(signing->db);
   7754 		/*
   7755 		 * Rebuild the NSEC/NSEC3 record for the origin as we no
   7756 		 * longer have any private records.
   7757 		 */
   7758 		if (build_nsec3) {
   7759 			CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
   7760 						  minimum, false, diff));
   7761 		}
   7762 		CHECK(updatesecure(signing->db, version, origin, minimum, true,
   7763 				   diff));
   7764 	}
   7765 
   7766 failure:
   7767 	if (dns_rdataset_isassociated(&rdataset)) {
   7768 		dns_rdataset_disassociate(&rdataset);
   7769 	}
   7770 	if (node != NULL) {
   7771 		dns_db_detachnode(signing->db, &node);
   7772 	}
   7773 	return (result);
   7774 }
   7775 
   7776 /*
   7777  * Called from zone_nsec3chain() in order to update zone records indicating
   7778  * processing status of given NSEC3 chain:
   7779  *
   7780  *   - If the supplied dns_nsec3chain_t structure has been fully processed
   7781  *     (which is indicated by "active" being set to false):
   7782  *
   7783  *       - remove all NSEC3PARAM records matching the relevant NSEC3 chain,
   7784  *
   7785  *       - remove all private-type records containing NSEC3PARAM RDATA matching
   7786  *         the relevant NSEC3 chain.
   7787  *
   7788  *   - If the supplied dns_nsec3chain_t structure has not been fully processed
   7789  *     (which is indicated by "active" being set to true), only remove the
   7790  *     NSEC3PARAM record which matches the relevant NSEC3 chain and has the
   7791  *     "flags" field set to 0.
   7792  *
   7793  *   - If given NSEC3 chain is being added, add an NSEC3PARAM record contained
   7794  *     in the relevant private-type record, but with the "flags" field set to
   7795  *     0, indicating that this NSEC3 chain is now complete for this zone.
   7796  *
   7797  * Note that this function is called at different processing stages for NSEC3
   7798  * chain additions vs. removals and needs to handle all cases properly.
   7799  */
   7800 static isc_result_t
   7801 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
   7802 		 bool active, dns_rdatatype_t privatetype, dns_diff_t *diff) {
   7803 	dns_dbnode_t *node = NULL;
   7804 	dns_name_t *name = dns_db_origin(db);
   7805 	dns_rdata_t rdata = DNS_RDATA_INIT;
   7806 	dns_rdataset_t rdataset;
   7807 	dns_rdata_nsec3param_t nsec3param;
   7808 	isc_result_t result;
   7809 	isc_buffer_t buffer;
   7810 	unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
   7811 	dns_ttl_t ttl = 0;
   7812 	bool nseconly = false, nsec3ok = false;
   7813 
   7814 	dns_rdataset_init(&rdataset);
   7815 
   7816 	result = dns_db_getoriginnode(db, &node);
   7817 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   7818 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   7819 				     0, &rdataset, NULL);
   7820 	if (result == ISC_R_NOTFOUND) {
   7821 		goto try_private;
   7822 	}
   7823 	if (result != ISC_R_SUCCESS) {
   7824 		goto failure;
   7825 	}
   7826 
   7827 	/*
   7828 	 * Preserve the existing ttl.
   7829 	 */
   7830 	ttl = rdataset.ttl;
   7831 
   7832 	/*
   7833 	 * Delete all NSEC3PARAM records which match that in nsec3chain.
   7834 	 */
   7835 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7836 	     result = dns_rdataset_next(&rdataset))
   7837 	{
   7838 		dns_rdataset_current(&rdataset, &rdata);
   7839 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   7840 
   7841 		if (nsec3param.hash != chain->nsec3param.hash ||
   7842 		    (active && nsec3param.flags != 0) ||
   7843 		    nsec3param.iterations != chain->nsec3param.iterations ||
   7844 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   7845 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   7846 			   nsec3param.salt_length))
   7847 		{
   7848 			dns_rdata_reset(&rdata);
   7849 			continue;
   7850 		}
   7851 
   7852 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7853 				    rdataset.ttl, &rdata));
   7854 		dns_rdata_reset(&rdata);
   7855 	}
   7856 	if (result != ISC_R_NOMORE) {
   7857 		goto failure;
   7858 	}
   7859 
   7860 	dns_rdataset_disassociate(&rdataset);
   7861 
   7862 try_private:
   7863 
   7864 	if (active) {
   7865 		goto add;
   7866 	}
   7867 
   7868 	result = dns_nsec_nseconly(db, ver, &nseconly);
   7869 	nsec3ok = (result == ISC_R_SUCCESS && !nseconly);
   7870 
   7871 	/*
   7872 	 * Delete all private records which match that in nsec3chain.
   7873 	 */
   7874 	result = dns_db_findrdataset(db, node, ver, privatetype, 0, 0,
   7875 				     &rdataset, NULL);
   7876 	if (result == ISC_R_NOTFOUND) {
   7877 		goto add;
   7878 	}
   7879 	if (result != ISC_R_SUCCESS) {
   7880 		goto failure;
   7881 	}
   7882 
   7883 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7884 	     result = dns_rdataset_next(&rdataset))
   7885 	{
   7886 		dns_rdata_t private = DNS_RDATA_INIT;
   7887 		unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   7888 
   7889 		dns_rdataset_current(&rdataset, &private);
   7890 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   7891 						sizeof(buf))) {
   7892 			continue;
   7893 		}
   7894 		CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
   7895 
   7896 		if ((!nsec3ok &&
   7897 		     (nsec3param.flags & DNS_NSEC3FLAG_INITIAL) != 0) ||
   7898 		    nsec3param.hash != chain->nsec3param.hash ||
   7899 		    nsec3param.iterations != chain->nsec3param.iterations ||
   7900 		    nsec3param.salt_length != chain->nsec3param.salt_length ||
   7901 		    memcmp(nsec3param.salt, chain->nsec3param.salt,
   7902 			   nsec3param.salt_length))
   7903 		{
   7904 			dns_rdata_reset(&rdata);
   7905 			continue;
   7906 		}
   7907 
   7908 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7909 				    rdataset.ttl, &private));
   7910 		dns_rdata_reset(&rdata);
   7911 	}
   7912 	if (result != ISC_R_NOMORE) {
   7913 		goto failure;
   7914 	}
   7915 
   7916 add:
   7917 	if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
   7918 		result = ISC_R_SUCCESS;
   7919 		goto failure;
   7920 	}
   7921 
   7922 	/*
   7923 	 * Add a NSEC3PARAM record which matches that in nsec3chain but
   7924 	 * with all flags bits cleared.
   7925 	 *
   7926 	 * Note: we do not clear chain->nsec3param.flags as this change
   7927 	 * may be reversed.
   7928 	 */
   7929 	isc_buffer_init(&buffer, &parambuf, sizeof(parambuf));
   7930 	CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
   7931 				   dns_rdatatype_nsec3param, &chain->nsec3param,
   7932 				   &buffer));
   7933 	rdata.data[1] = 0; /* Clear flag bits. */
   7934 	CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
   7935 
   7936 failure:
   7937 	dns_db_detachnode(db, &node);
   7938 	if (dns_rdataset_isassociated(&rdataset)) {
   7939 		dns_rdataset_disassociate(&rdataset);
   7940 	}
   7941 	return (result);
   7942 }
   7943 
   7944 static isc_result_t
   7945 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   7946 	    dns_name_t *name, dns_diff_t *diff) {
   7947 	dns_rdataset_t rdataset;
   7948 	isc_result_t result;
   7949 
   7950 	dns_rdataset_init(&rdataset);
   7951 
   7952 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   7953 				     &rdataset, NULL);
   7954 	if (result == ISC_R_NOTFOUND) {
   7955 		return (ISC_R_SUCCESS);
   7956 	}
   7957 	if (result != ISC_R_SUCCESS) {
   7958 		return (result);
   7959 	}
   7960 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7961 	     result = dns_rdataset_next(&rdataset))
   7962 	{
   7963 		dns_rdata_t rdata = DNS_RDATA_INIT;
   7964 
   7965 		dns_rdataset_current(&rdataset, &rdata);
   7966 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   7967 				    rdataset.ttl, &rdata));
   7968 	}
   7969 	if (result == ISC_R_NOMORE) {
   7970 		result = ISC_R_SUCCESS;
   7971 	}
   7972 failure:
   7973 	dns_rdataset_disassociate(&rdataset);
   7974 	return (result);
   7975 }
   7976 
   7977 static isc_result_t
   7978 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
   7979 		    dns_name_t *name, const dns_rdata_nsec3param_t *param,
   7980 		    dns_diff_t *diff) {
   7981 	dns_rdataset_t rdataset;
   7982 	dns_rdata_nsec3_t nsec3;
   7983 	isc_result_t result;
   7984 
   7985 	dns_rdataset_init(&rdataset);
   7986 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3, 0, 0,
   7987 				     &rdataset, NULL);
   7988 	if (result == ISC_R_NOTFOUND) {
   7989 		return (ISC_R_SUCCESS);
   7990 	}
   7991 	if (result != ISC_R_SUCCESS) {
   7992 		return (result);
   7993 	}
   7994 
   7995 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   7996 	     result = dns_rdataset_next(&rdataset))
   7997 	{
   7998 		dns_rdata_t rdata = DNS_RDATA_INIT;
   7999 
   8000 		dns_rdataset_current(&rdataset, &rdata);
   8001 		CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
   8002 		if (nsec3.hash != param->hash ||
   8003 		    nsec3.iterations != param->iterations ||
   8004 		    nsec3.salt_length != param->salt_length ||
   8005 		    memcmp(nsec3.salt, param->salt, nsec3.salt_length))
   8006 		{
   8007 			continue;
   8008 		}
   8009 		CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
   8010 				    rdataset.ttl, &rdata));
   8011 	}
   8012 	if (result == ISC_R_NOMORE) {
   8013 		result = ISC_R_SUCCESS;
   8014 	}
   8015 failure:
   8016 	dns_rdataset_disassociate(&rdataset);
   8017 	return (result);
   8018 }
   8019 
   8020 static isc_result_t
   8021 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
   8022 		const dns_rdata_nsec3param_t *param, bool *answer) {
   8023 	dns_dbnode_t *node = NULL;
   8024 	dns_rdata_t rdata = DNS_RDATA_INIT;
   8025 	dns_rdata_nsec3param_t myparam;
   8026 	dns_rdataset_t rdataset;
   8027 	isc_result_t result;
   8028 
   8029 	*answer = false;
   8030 
   8031 	result = dns_db_getoriginnode(db, &node);
   8032 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8033 
   8034 	dns_rdataset_init(&rdataset);
   8035 
   8036 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec, 0, 0,
   8037 				     &rdataset, NULL);
   8038 	if (result == ISC_R_SUCCESS) {
   8039 		dns_rdataset_disassociate(&rdataset);
   8040 		dns_db_detachnode(db, &node);
   8041 		return (result);
   8042 	}
   8043 	if (result != ISC_R_NOTFOUND) {
   8044 		dns_db_detachnode(db, &node);
   8045 		return (result);
   8046 	}
   8047 
   8048 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param, 0,
   8049 				     0, &rdataset, NULL);
   8050 	if (result == ISC_R_NOTFOUND) {
   8051 		*answer = true;
   8052 		dns_db_detachnode(db, &node);
   8053 		return (ISC_R_SUCCESS);
   8054 	}
   8055 	if (result != ISC_R_SUCCESS) {
   8056 		dns_db_detachnode(db, &node);
   8057 		return (result);
   8058 	}
   8059 
   8060 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   8061 	     result = dns_rdataset_next(&rdataset))
   8062 	{
   8063 		dns_rdataset_current(&rdataset, &rdata);
   8064 		CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
   8065 		dns_rdata_reset(&rdata);
   8066 		/*
   8067 		 * Ignore any NSEC3PARAM removals.
   8068 		 */
   8069 		if (NSEC3REMOVE(myparam.flags)) {
   8070 			continue;
   8071 		}
   8072 		/*
   8073 		 * Ignore the chain that we are in the process of deleting.
   8074 		 */
   8075 		if (myparam.hash == param->hash &&
   8076 		    myparam.iterations == param->iterations &&
   8077 		    myparam.salt_length == param->salt_length &&
   8078 		    !memcmp(myparam.salt, param->salt, myparam.salt_length))
   8079 		{
   8080 			continue;
   8081 		}
   8082 		/*
   8083 		 * Found an active NSEC3 chain.
   8084 		 */
   8085 		break;
   8086 	}
   8087 	if (result == ISC_R_NOMORE) {
   8088 		*answer = true;
   8089 		result = ISC_R_SUCCESS;
   8090 	}
   8091 
   8092 failure:
   8093 	if (dns_rdataset_isassociated(&rdataset)) {
   8094 		dns_rdataset_disassociate(&rdataset);
   8095 	}
   8096 	dns_db_detachnode(db, &node);
   8097 	return (result);
   8098 }
   8099 
   8100 /*%
   8101  * Given a tuple which is part of a diff, return a pointer to the next tuple in
   8102  * that diff which has the same name and type (or NULL if no such tuple is
   8103  * found).
   8104  */
   8105 static dns_difftuple_t *
   8106 find_next_matching_tuple(dns_difftuple_t *cur) {
   8107 	dns_difftuple_t *next = cur;
   8108 
   8109 	while ((next = ISC_LIST_NEXT(next, link)) != NULL) {
   8110 		if (cur->rdata.type == next->rdata.type &&
   8111 		    dns_name_equal(&cur->name, &next->name))
   8112 		{
   8113 			return (next);
   8114 		}
   8115 	}
   8116 
   8117 	return (NULL);
   8118 }
   8119 
   8120 /*%
   8121  * Remove all tuples with the same name and type as 'cur' from 'src' and append
   8122  * them to 'dst'.
   8123  */
   8124 static void
   8125 move_matching_tuples(dns_difftuple_t *cur, dns_diff_t *src, dns_diff_t *dst) {
   8126 	do {
   8127 		dns_difftuple_t *next = find_next_matching_tuple(cur);
   8128 		ISC_LIST_UNLINK(src->tuples, cur, link);
   8129 		dns_diff_appendminimal(dst, &cur);
   8130 		cur = next;
   8131 	} while (cur != NULL);
   8132 }
   8133 
   8134 /*%
   8135  * Add/remove DNSSEC signatures for the list of "raw" zone changes supplied in
   8136  * 'diff'.  Gradually remove tuples from 'diff' and append them to 'zonediff'
   8137  * along with tuples representing relevant signature changes.
   8138  */
   8139 isc_result_t
   8140 dns__zone_updatesigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
   8141 		     dst_key_t *zone_keys[], unsigned int nkeys,
   8142 		     dns_zone_t *zone, isc_stdtime_t inception,
   8143 		     isc_stdtime_t expire, isc_stdtime_t keyexpire,
   8144 		     isc_stdtime_t now, bool check_ksk, bool keyset_kskonly,
   8145 		     dns__zonediff_t *zonediff) {
   8146 	dns_difftuple_t *tuple;
   8147 	isc_result_t result;
   8148 
   8149 	while ((tuple = ISC_LIST_HEAD(diff->tuples)) != NULL) {
   8150 		isc_stdtime_t exp = expire;
   8151 
   8152 		if (keyexpire != 0 &&
   8153 		    (tuple->rdata.type == dns_rdatatype_dnskey ||
   8154 		     tuple->rdata.type == dns_rdatatype_cdnskey ||
   8155 		     tuple->rdata.type == dns_rdatatype_cds))
   8156 		{
   8157 			exp = keyexpire;
   8158 		}
   8159 
   8160 		result = del_sigs(zone, db, version, &tuple->name,
   8161 				  tuple->rdata.type, zonediff, zone_keys, nkeys,
   8162 				  now, false);
   8163 		if (result != ISC_R_SUCCESS) {
   8164 			dns_zone_log(zone, ISC_LOG_ERROR,
   8165 				     "dns__zone_updatesigs:del_sigs -> %s",
   8166 				     dns_result_totext(result));
   8167 			return (result);
   8168 		}
   8169 		result = add_sigs(db, version, &tuple->name, zone,
   8170 				  tuple->rdata.type, zonediff->diff, zone_keys,
   8171 				  nkeys, zone->mctx, inception, exp, check_ksk,
   8172 				  keyset_kskonly);
   8173 		if (result != ISC_R_SUCCESS) {
   8174 			dns_zone_log(zone, ISC_LOG_ERROR,
   8175 				     "dns__zone_updatesigs:add_sigs -> %s",
   8176 				     dns_result_totext(result));
   8177 			return (result);
   8178 		}
   8179 
   8180 		/*
   8181 		 * Signature changes for all RRs with name tuple->name and type
   8182 		 * tuple->rdata.type were appended to zonediff->diff.  Now we
   8183 		 * remove all the "raw" changes with the same name and type
   8184 		 * from diff (so that they are not processed by this loop
   8185 		 * again) and append them to zonediff so that they get applied.
   8186 		 */
   8187 		move_matching_tuples(tuple, diff, zonediff->diff);
   8188 	}
   8189 	return (ISC_R_SUCCESS);
   8190 }
   8191 
   8192 /*
   8193  * Incrementally build and sign a new NSEC3 chain using the parameters
   8194  * requested.
   8195  */
   8196 static void
   8197 zone_nsec3chain(dns_zone_t *zone) {
   8198 	const char *me = "zone_nsec3chain";
   8199 	dns_db_t *db = NULL;
   8200 	dns_dbnode_t *node = NULL;
   8201 	dns_dbversion_t *version = NULL;
   8202 	dns_diff_t _sig_diff;
   8203 	dns_diff_t nsec_diff;
   8204 	dns_diff_t nsec3_diff;
   8205 	dns_diff_t param_diff;
   8206 	dns__zonediff_t zonediff;
   8207 	dns_fixedname_t fixed;
   8208 	dns_fixedname_t nextfixed;
   8209 	dns_name_t *name, *nextname;
   8210 	dns_rdataset_t rdataset;
   8211 	dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
   8212 	dns_nsec3chainlist_t cleanup;
   8213 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   8214 	int32_t signatures;
   8215 	bool check_ksk, keyset_kskonly;
   8216 	bool delegation;
   8217 	bool first;
   8218 	isc_result_t result;
   8219 	isc_stdtime_t now, inception, soaexpire, expire;
   8220 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   8221 	unsigned int i;
   8222 	unsigned int nkeys = 0;
   8223 	uint32_t nodes;
   8224 	bool unsecure = false;
   8225 	bool seen_soa, seen_ns, seen_dname, seen_ds;
   8226 	bool seen_nsec, seen_nsec3, seen_rr;
   8227 	dns_rdatasetiter_t *iterator = NULL;
   8228 	bool buildnsecchain;
   8229 	bool updatensec = false;
   8230 	dns_rdatatype_t privatetype = zone->privatetype;
   8231 
   8232 	ENTER;
   8233 
   8234 	dns_rdataset_init(&rdataset);
   8235 	name = dns_fixedname_initname(&fixed);
   8236 	nextname = dns_fixedname_initname(&nextfixed);
   8237 	dns_diff_init(zone->mctx, &param_diff);
   8238 	dns_diff_init(zone->mctx, &nsec3_diff);
   8239 	dns_diff_init(zone->mctx, &nsec_diff);
   8240 	dns_diff_init(zone->mctx, &_sig_diff);
   8241 	zonediff_init(&zonediff, &_sig_diff);
   8242 	ISC_LIST_INIT(cleanup);
   8243 
   8244 	/*
   8245 	 * Updates are disabled.  Pause for 5 minutes.
   8246 	 */
   8247 	if (zone->update_disabled) {
   8248 		result = ISC_R_FAILURE;
   8249 		goto failure;
   8250 	}
   8251 
   8252 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8253 	/*
   8254 	 * This function is called when zone timer fires, after the latter gets
   8255 	 * set by zone_addnsec3chain().  If the action triggering the call to
   8256 	 * zone_addnsec3chain() is closely followed by a zone deletion request,
   8257 	 * it might turn out that the timer thread will not be woken up until
   8258 	 * after the zone is deleted by rmzone(), which calls dns_db_detach()
   8259 	 * for zone->db, causing the latter to become NULL.  Return immediately
   8260 	 * if that happens.
   8261 	 */
   8262 	if (zone->db != NULL) {
   8263 		dns_db_attach(zone->db, &db);
   8264 	}
   8265 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8266 	if (db == NULL) {
   8267 		return;
   8268 	}
   8269 
   8270 	result = dns_db_newversion(db, &version);
   8271 	if (result != ISC_R_SUCCESS) {
   8272 		dnssec_log(zone, ISC_LOG_ERROR,
   8273 			   "zone_nsec3chain:dns_db_newversion -> %s",
   8274 			   dns_result_totext(result));
   8275 		goto failure;
   8276 	}
   8277 
   8278 	isc_stdtime_get(&now);
   8279 
   8280 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   8281 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   8282 	if (result != ISC_R_SUCCESS) {
   8283 		dnssec_log(zone, ISC_LOG_ERROR,
   8284 			   "zone_nsec3chain:dns__zone_findkeys -> %s",
   8285 			   dns_result_totext(result));
   8286 		goto failure;
   8287 	}
   8288 
   8289 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   8290 	inception = now - 3600; /* Allow for clock skew. */
   8291 	soaexpire = now + sigvalidityinterval;
   8292 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   8293 	if (expiryinterval > sigvalidityinterval) {
   8294 		expiryinterval = sigvalidityinterval;
   8295 	} else {
   8296 		expiryinterval = sigvalidityinterval - expiryinterval;
   8297 	}
   8298 
   8299 	/*
   8300 	 * Spread out signatures over time if they happen to be
   8301 	 * clumped.  We don't do this for each add_sigs() call as
   8302 	 * we still want some clustering to occur.
   8303 	 */
   8304 	if (sigvalidityinterval >= 3600U) {
   8305 		if (sigvalidityinterval > 7200U) {
   8306 			jitter = isc_random_uniform(expiryinterval);
   8307 		} else {
   8308 			jitter = isc_random_uniform(1200);
   8309 		}
   8310 		expire = soaexpire - jitter - 1;
   8311 	} else {
   8312 		expire = soaexpire - 1;
   8313 	}
   8314 
   8315 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   8316 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   8317 
   8318 	/*
   8319 	 * We keep pulling nodes off each iterator in turn until
   8320 	 * we have no more nodes to pull off or we reach the limits
   8321 	 * for this quantum.
   8322 	 */
   8323 	nodes = zone->nodes;
   8324 	signatures = zone->signatures;
   8325 	LOCK_ZONE(zone);
   8326 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8327 	UNLOCK_ZONE(zone);
   8328 	first = true;
   8329 
   8330 	if (nsec3chain != NULL) {
   8331 		nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8332 	}
   8333 	/*
   8334 	 * Generate new NSEC3 chains first.
   8335 	 *
   8336 	 * The following while loop iterates over nodes in the zone database,
   8337 	 * updating the NSEC3 chain by calling dns_nsec3_addnsec3() for each of
   8338 	 * them.  Once all nodes are processed, the "delete_nsec" field is
   8339 	 * consulted to check whether we are supposed to remove NSEC records
   8340 	 * from the zone database; if so, the database iterator is reset to
   8341 	 * point to the first node and the loop traverses all of them again,
   8342 	 * this time removing NSEC records.  If we hit a node which is obscured
   8343 	 * by a delegation or a DNAME, nodes are skipped over until we find one
   8344 	 * that is not obscured by the same obscuring name and then normal
   8345 	 * processing is resumed.
   8346 	 *
   8347 	 * The above is repeated until all requested NSEC3 chain changes are
   8348 	 * applied or when we reach the limits for this quantum, whichever
   8349 	 * happens first.
   8350 	 *
   8351 	 * Note that the "signatures" variable is only used here to limit the
   8352 	 * amount of work performed.  Actual DNSSEC signatures are only
   8353 	 * generated by dns__zone_updatesigs() calls later in this function.
   8354 	 */
   8355 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8356 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8357 
   8358 		LOCK_ZONE(zone);
   8359 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8360 
   8361 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   8362 		if (nsec3chain->done || nsec3chain->db != zone->db) {
   8363 			ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
   8364 			ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8365 		}
   8366 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   8367 		UNLOCK_ZONE(zone);
   8368 		if (ISC_LIST_TAIL(cleanup) == nsec3chain) {
   8369 			goto next_addchain;
   8370 		}
   8371 
   8372 		/*
   8373 		 * Possible future db.
   8374 		 */
   8375 		if (nsec3chain->db != db) {
   8376 			goto next_addchain;
   8377 		}
   8378 
   8379 		if (NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8380 			goto next_addchain;
   8381 		}
   8382 
   8383 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8384 
   8385 		if (nsec3chain->delete_nsec) {
   8386 			delegation = false;
   8387 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8388 			CHECK(delete_nsec(db, version, node, name, &nsec_diff));
   8389 			goto next_addnode;
   8390 		}
   8391 		/*
   8392 		 * On the first pass we need to check if the current node
   8393 		 * has not been obscured.
   8394 		 */
   8395 		delegation = false;
   8396 		unsecure = false;
   8397 		if (first) {
   8398 			dns_fixedname_t ffound;
   8399 			dns_name_t *found;
   8400 			found = dns_fixedname_initname(&ffound);
   8401 			result = dns_db_find(
   8402 				db, name, version, dns_rdatatype_soa,
   8403 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8404 			if ((result == DNS_R_DELEGATION ||
   8405 			     result == DNS_R_DNAME) &&
   8406 			    !dns_name_equal(name, found))
   8407 			{
   8408 				/*
   8409 				 * Remember the obscuring name so that
   8410 				 * we skip all obscured names.
   8411 				 */
   8412 				dns_name_copynf(found, name);
   8413 				delegation = true;
   8414 				goto next_addnode;
   8415 			}
   8416 		}
   8417 
   8418 		/*
   8419 		 * Check to see if this is a bottom of zone node.
   8420 		 */
   8421 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8422 		if (result == ISC_R_NOTFOUND) {
   8423 			/* Empty node? */
   8424 			goto next_addnode;
   8425 		}
   8426 		if (result != ISC_R_SUCCESS) {
   8427 			goto failure;
   8428 		}
   8429 
   8430 		seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec = false;
   8431 		for (result = dns_rdatasetiter_first(iterator);
   8432 		     result == ISC_R_SUCCESS;
   8433 		     result = dns_rdatasetiter_next(iterator))
   8434 		{
   8435 			dns_rdatasetiter_current(iterator, &rdataset);
   8436 			INSIST(rdataset.type != dns_rdatatype_nsec3);
   8437 			if (rdataset.type == dns_rdatatype_soa) {
   8438 				seen_soa = true;
   8439 			} else if (rdataset.type == dns_rdatatype_ns) {
   8440 				seen_ns = true;
   8441 			} else if (rdataset.type == dns_rdatatype_dname) {
   8442 				seen_dname = true;
   8443 			} else if (rdataset.type == dns_rdatatype_ds) {
   8444 				seen_ds = true;
   8445 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8446 				seen_nsec = true;
   8447 			}
   8448 			dns_rdataset_disassociate(&rdataset);
   8449 		}
   8450 		dns_rdatasetiter_destroy(&iterator);
   8451 		/*
   8452 		 * Is there a NSEC chain than needs to be cleaned up?
   8453 		 */
   8454 		if (seen_nsec) {
   8455 			nsec3chain->seen_nsec = true;
   8456 		}
   8457 		if (seen_ns && !seen_soa && !seen_ds) {
   8458 			unsecure = true;
   8459 		}
   8460 		if ((seen_ns && !seen_soa) || seen_dname) {
   8461 			delegation = true;
   8462 		}
   8463 
   8464 		/*
   8465 		 * Process one node.
   8466 		 */
   8467 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8468 		result = dns_nsec3_addnsec3(
   8469 			db, version, name, &nsec3chain->nsec3param,
   8470 			zone->minimum, unsecure, &nsec3_diff);
   8471 		if (result != ISC_R_SUCCESS) {
   8472 			dnssec_log(zone, ISC_LOG_ERROR,
   8473 				   "zone_nsec3chain:"
   8474 				   "dns_nsec3_addnsec3 -> %s",
   8475 				   dns_result_totext(result));
   8476 			goto failure;
   8477 		}
   8478 
   8479 		/*
   8480 		 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
   8481 		 * two signatures.  Additionally there will, in general, be
   8482 		 * two signature generated below.
   8483 		 *
   8484 		 * If we are only changing the optout flag the cost is half
   8485 		 * that of the cost of generating a completely new chain.
   8486 		 */
   8487 		signatures -= 4;
   8488 
   8489 		/*
   8490 		 * Go onto next node.
   8491 		 */
   8492 	next_addnode:
   8493 		first = false;
   8494 		dns_db_detachnode(db, &node);
   8495 		do {
   8496 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8497 
   8498 			if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
   8499 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8500 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8501 						       false, privatetype,
   8502 						       &param_diff));
   8503 				LOCK_ZONE(zone);
   8504 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8505 						link);
   8506 				UNLOCK_ZONE(zone);
   8507 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8508 				goto next_addchain;
   8509 			}
   8510 			if (result == ISC_R_NOMORE) {
   8511 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8512 				if (nsec3chain->seen_nsec) {
   8513 					CHECK(fixup_nsec3param(
   8514 						db, version, nsec3chain, true,
   8515 						privatetype, &param_diff));
   8516 					nsec3chain->delete_nsec = true;
   8517 					goto same_addchain;
   8518 				}
   8519 				CHECK(fixup_nsec3param(db, version, nsec3chain,
   8520 						       false, privatetype,
   8521 						       &param_diff));
   8522 				LOCK_ZONE(zone);
   8523 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8524 						link);
   8525 				UNLOCK_ZONE(zone);
   8526 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8527 				goto next_addchain;
   8528 			} else if (result != ISC_R_SUCCESS) {
   8529 				dnssec_log(zone, ISC_LOG_ERROR,
   8530 					   "zone_nsec3chain:"
   8531 					   "dns_dbiterator_next -> %s",
   8532 					   dns_result_totext(result));
   8533 				goto failure;
   8534 			} else if (delegation) {
   8535 				dns_dbiterator_current(nsec3chain->dbiterator,
   8536 						       &node, nextname);
   8537 				dns_db_detachnode(db, &node);
   8538 				if (!dns_name_issubdomain(nextname, name)) {
   8539 					break;
   8540 				}
   8541 			} else {
   8542 				break;
   8543 			}
   8544 		} while (1);
   8545 		continue;
   8546 
   8547 	same_addchain:
   8548 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8549 		first = true;
   8550 		continue;
   8551 
   8552 	next_addchain:
   8553 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8554 		nsec3chain = nextnsec3chain;
   8555 		first = true;
   8556 		if (nsec3chain != NULL) {
   8557 			nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
   8558 		}
   8559 	}
   8560 
   8561 	if (nsec3chain != NULL) {
   8562 		goto skip_removals;
   8563 	}
   8564 
   8565 	/*
   8566 	 * Process removals.
   8567 	 *
   8568 	 * This is a counterpart of the above while loop which takes care of
   8569 	 * removing an NSEC3 chain.  It starts with determining whether the
   8570 	 * zone needs to switch from NSEC3 to NSEC; if so, it first builds an
   8571 	 * NSEC chain by iterating over all nodes in the zone database and only
   8572 	 * then goes on to remove NSEC3 records be iterating over all nodes
   8573 	 * again and calling deletematchingnsec3() for each of them; otherwise,
   8574 	 * it starts removing NSEC3 records immediately.  Rules for processing
   8575 	 * obscured nodes and interrupting work are the same as for the while
   8576 	 * loop above.
   8577 	 */
   8578 	LOCK_ZONE(zone);
   8579 	nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
   8580 	UNLOCK_ZONE(zone);
   8581 	first = true;
   8582 	buildnsecchain = false;
   8583 	while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
   8584 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8585 
   8586 		LOCK_ZONE(zone);
   8587 		nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
   8588 		UNLOCK_ZONE(zone);
   8589 
   8590 		if (nsec3chain->db != db) {
   8591 			goto next_removechain;
   8592 		}
   8593 
   8594 		if (!NSEC3REMOVE(nsec3chain->nsec3param.flags)) {
   8595 			goto next_removechain;
   8596 		}
   8597 
   8598 		/*
   8599 		 * Work out if we need to build a NSEC chain as a consequence
   8600 		 * of removing this NSEC3 chain.
   8601 		 */
   8602 		if (first && !updatensec &&
   8603 		    (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0)
   8604 		{
   8605 			result = need_nsec_chain(db, version,
   8606 						 &nsec3chain->nsec3param,
   8607 						 &buildnsecchain);
   8608 			if (result != ISC_R_SUCCESS) {
   8609 				dnssec_log(zone, ISC_LOG_ERROR,
   8610 					   "zone_nsec3chain:"
   8611 					   "need_nsec_chain -> %s",
   8612 					   dns_result_totext(result));
   8613 				goto failure;
   8614 			}
   8615 		}
   8616 
   8617 		if (first) {
   8618 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   8619 				   "zone_nsec3chain:buildnsecchain = %u\n",
   8620 				   buildnsecchain);
   8621 		}
   8622 
   8623 		dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
   8624 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8625 		delegation = false;
   8626 
   8627 		if (!buildnsecchain) {
   8628 			/*
   8629 			 * Delete the NSEC3PARAM record matching this chain.
   8630 			 */
   8631 			if (first) {
   8632 				result = fixup_nsec3param(
   8633 					db, version, nsec3chain, true,
   8634 					privatetype, &param_diff);
   8635 				if (result != ISC_R_SUCCESS) {
   8636 					dnssec_log(zone, ISC_LOG_ERROR,
   8637 						   "zone_nsec3chain:"
   8638 						   "fixup_nsec3param -> %s",
   8639 						   dns_result_totext(result));
   8640 					goto failure;
   8641 				}
   8642 			}
   8643 
   8644 			/*
   8645 			 * Delete the NSEC3 records.
   8646 			 */
   8647 			result = deletematchingnsec3(db, version, node, name,
   8648 						     &nsec3chain->nsec3param,
   8649 						     &nsec3_diff);
   8650 			if (result != ISC_R_SUCCESS) {
   8651 				dnssec_log(zone, ISC_LOG_ERROR,
   8652 					   "zone_nsec3chain:"
   8653 					   "deletematchingnsec3 -> %s",
   8654 					   dns_result_totext(result));
   8655 				goto failure;
   8656 			}
   8657 			goto next_removenode;
   8658 		}
   8659 
   8660 		if (first) {
   8661 			dns_fixedname_t ffound;
   8662 			dns_name_t *found;
   8663 			found = dns_fixedname_initname(&ffound);
   8664 			result = dns_db_find(
   8665 				db, name, version, dns_rdatatype_soa,
   8666 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   8667 			if ((result == DNS_R_DELEGATION ||
   8668 			     result == DNS_R_DNAME) &&
   8669 			    !dns_name_equal(name, found))
   8670 			{
   8671 				/*
   8672 				 * Remember the obscuring name so that
   8673 				 * we skip all obscured names.
   8674 				 */
   8675 				dns_name_copynf(found, name);
   8676 				delegation = true;
   8677 				goto next_removenode;
   8678 			}
   8679 		}
   8680 
   8681 		/*
   8682 		 * Check to see if this is a bottom of zone node.
   8683 		 */
   8684 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8685 		if (result == ISC_R_NOTFOUND) {
   8686 			/* Empty node? */
   8687 			goto next_removenode;
   8688 		}
   8689 		if (result != ISC_R_SUCCESS) {
   8690 			goto failure;
   8691 		}
   8692 
   8693 		seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
   8694 			seen_rr = false;
   8695 		for (result = dns_rdatasetiter_first(iterator);
   8696 		     result == ISC_R_SUCCESS;
   8697 		     result = dns_rdatasetiter_next(iterator))
   8698 		{
   8699 			dns_rdatasetiter_current(iterator, &rdataset);
   8700 			if (rdataset.type == dns_rdatatype_soa) {
   8701 				seen_soa = true;
   8702 			} else if (rdataset.type == dns_rdatatype_ns) {
   8703 				seen_ns = true;
   8704 			} else if (rdataset.type == dns_rdatatype_dname) {
   8705 				seen_dname = true;
   8706 			} else if (rdataset.type == dns_rdatatype_nsec) {
   8707 				seen_nsec = true;
   8708 			} else if (rdataset.type == dns_rdatatype_nsec3) {
   8709 				seen_nsec3 = true;
   8710 			} else if (rdataset.type != dns_rdatatype_rrsig) {
   8711 				seen_rr = true;
   8712 			}
   8713 			dns_rdataset_disassociate(&rdataset);
   8714 		}
   8715 		dns_rdatasetiter_destroy(&iterator);
   8716 
   8717 		if (!seen_rr || seen_nsec3 || seen_nsec) {
   8718 			goto next_removenode;
   8719 		}
   8720 		if ((seen_ns && !seen_soa) || seen_dname) {
   8721 			delegation = true;
   8722 		}
   8723 
   8724 		/*
   8725 		 * Add a NSEC record except at the origin.
   8726 		 */
   8727 		if (!dns_name_equal(name, dns_db_origin(db))) {
   8728 			dns_dbiterator_pause(nsec3chain->dbiterator);
   8729 			CHECK(add_nsec(db, version, name, node, zone->minimum,
   8730 				       delegation, &nsec_diff));
   8731 			signatures--;
   8732 		}
   8733 
   8734 	next_removenode:
   8735 		first = false;
   8736 		dns_db_detachnode(db, &node);
   8737 		do {
   8738 			result = dns_dbiterator_next(nsec3chain->dbiterator);
   8739 			if (result == ISC_R_NOMORE && buildnsecchain) {
   8740 				/*
   8741 				 * The NSEC chain should now be built.
   8742 				 * We can now remove the NSEC3 chain.
   8743 				 */
   8744 				updatensec = true;
   8745 				goto same_removechain;
   8746 			}
   8747 			if (result == ISC_R_NOMORE) {
   8748 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8749 				LOCK_ZONE(zone);
   8750 				ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
   8751 						link);
   8752 				UNLOCK_ZONE(zone);
   8753 				ISC_LIST_APPEND(cleanup, nsec3chain, link);
   8754 				result = fixup_nsec3param(
   8755 					db, version, nsec3chain, false,
   8756 					privatetype, &param_diff);
   8757 				if (result != ISC_R_SUCCESS) {
   8758 					dnssec_log(zone, ISC_LOG_ERROR,
   8759 						   "zone_nsec3chain:"
   8760 						   "fixup_nsec3param -> %s",
   8761 						   dns_result_totext(result));
   8762 					goto failure;
   8763 				}
   8764 				goto next_removechain;
   8765 			} else if (result != ISC_R_SUCCESS) {
   8766 				dnssec_log(zone, ISC_LOG_ERROR,
   8767 					   "zone_nsec3chain:"
   8768 					   "dns_dbiterator_next -> %s",
   8769 					   dns_result_totext(result));
   8770 				goto failure;
   8771 			} else if (delegation) {
   8772 				dns_dbiterator_current(nsec3chain->dbiterator,
   8773 						       &node, nextname);
   8774 				dns_db_detachnode(db, &node);
   8775 				if (!dns_name_issubdomain(nextname, name)) {
   8776 					break;
   8777 				}
   8778 			} else {
   8779 				break;
   8780 			}
   8781 		} while (1);
   8782 		continue;
   8783 
   8784 	same_removechain:
   8785 		CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
   8786 		buildnsecchain = false;
   8787 		first = true;
   8788 		continue;
   8789 
   8790 	next_removechain:
   8791 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8792 		nsec3chain = nextnsec3chain;
   8793 		first = true;
   8794 	}
   8795 
   8796 skip_removals:
   8797 	/*
   8798 	 * We may need to update the NSEC/NSEC3 records for the zone apex.
   8799 	 */
   8800 	if (!ISC_LIST_EMPTY(param_diff.tuples)) {
   8801 		bool rebuild_nsec = false, rebuild_nsec3 = false;
   8802 		result = dns_db_getoriginnode(db, &node);
   8803 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   8804 		result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   8805 		if (result != ISC_R_SUCCESS) {
   8806 			dnssec_log(zone, ISC_LOG_ERROR,
   8807 				   "zone_nsec3chain:dns_db_allrdatasets -> %s",
   8808 				   dns_result_totext(result));
   8809 			goto failure;
   8810 		}
   8811 		for (result = dns_rdatasetiter_first(iterator);
   8812 		     result == ISC_R_SUCCESS;
   8813 		     result = dns_rdatasetiter_next(iterator))
   8814 		{
   8815 			dns_rdatasetiter_current(iterator, &rdataset);
   8816 			if (rdataset.type == dns_rdatatype_nsec) {
   8817 				rebuild_nsec = true;
   8818 			} else if (rdataset.type == dns_rdatatype_nsec3param) {
   8819 				rebuild_nsec3 = true;
   8820 			}
   8821 			dns_rdataset_disassociate(&rdataset);
   8822 		}
   8823 		dns_rdatasetiter_destroy(&iterator);
   8824 		dns_db_detachnode(db, &node);
   8825 
   8826 		if (rebuild_nsec) {
   8827 			if (nsec3chain != NULL) {
   8828 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8829 			}
   8830 
   8831 			result = updatesecure(db, version, &zone->origin,
   8832 					      zone->minimum, true, &nsec_diff);
   8833 			if (result != ISC_R_SUCCESS) {
   8834 				dnssec_log(zone, ISC_LOG_ERROR,
   8835 					   "zone_nsec3chain:updatesecure -> %s",
   8836 					   dns_result_totext(result));
   8837 				goto failure;
   8838 			}
   8839 		}
   8840 
   8841 		if (rebuild_nsec3) {
   8842 			if (nsec3chain != NULL) {
   8843 				dns_dbiterator_pause(nsec3chain->dbiterator);
   8844 			}
   8845 
   8846 			result = dns_nsec3_addnsec3s(
   8847 				db, version, dns_db_origin(db), zone->minimum,
   8848 				false, &nsec3_diff);
   8849 			if (result != ISC_R_SUCCESS) {
   8850 				dnssec_log(zone, ISC_LOG_ERROR,
   8851 					   "zone_nsec3chain:"
   8852 					   "dns_nsec3_addnsec3s -> %s",
   8853 					   dns_result_totext(result));
   8854 				goto failure;
   8855 			}
   8856 		}
   8857 	}
   8858 
   8859 	/*
   8860 	 * Add / update signatures for the NSEC3 records.
   8861 	 */
   8862 	if (nsec3chain != NULL) {
   8863 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8864 	}
   8865 	result = dns__zone_updatesigs(&nsec3_diff, db, version, zone_keys,
   8866 				      nkeys, zone, inception, expire, 0, now,
   8867 				      check_ksk, keyset_kskonly, &zonediff);
   8868 	if (result != ISC_R_SUCCESS) {
   8869 		dnssec_log(zone, ISC_LOG_ERROR,
   8870 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8871 			   dns_result_totext(result));
   8872 		goto failure;
   8873 	}
   8874 
   8875 	/*
   8876 	 * We have changed the NSEC3PARAM or private RRsets
   8877 	 * above so we need to update the signatures.
   8878 	 */
   8879 	result = dns__zone_updatesigs(&param_diff, db, version, zone_keys,
   8880 				      nkeys, zone, inception, expire, 0, now,
   8881 				      check_ksk, keyset_kskonly, &zonediff);
   8882 	if (result != ISC_R_SUCCESS) {
   8883 		dnssec_log(zone, ISC_LOG_ERROR,
   8884 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8885 			   dns_result_totext(result));
   8886 		goto failure;
   8887 	}
   8888 
   8889 	if (updatensec) {
   8890 		result = updatesecure(db, version, &zone->origin, zone->minimum,
   8891 				      false, &nsec_diff);
   8892 		if (result != ISC_R_SUCCESS) {
   8893 			dnssec_log(zone, ISC_LOG_ERROR,
   8894 				   "zone_nsec3chain:updatesecure -> %s",
   8895 				   dns_result_totext(result));
   8896 			goto failure;
   8897 		}
   8898 	}
   8899 
   8900 	result = dns__zone_updatesigs(&nsec_diff, db, version, zone_keys, nkeys,
   8901 				      zone, inception, expire, 0, now,
   8902 				      check_ksk, keyset_kskonly, &zonediff);
   8903 	if (result != ISC_R_SUCCESS) {
   8904 		dnssec_log(zone, ISC_LOG_ERROR,
   8905 			   "zone_nsec3chain:dns__zone_updatesigs -> %s",
   8906 			   dns_result_totext(result));
   8907 		goto failure;
   8908 	}
   8909 
   8910 	/*
   8911 	 * If we made no effective changes to the zone then we can just
   8912 	 * cleanup otherwise we need to increment the serial.
   8913 	 */
   8914 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   8915 		/*
   8916 		 * No need to call dns_db_closeversion() here as it is
   8917 		 * called with commit = true below.
   8918 		 */
   8919 		goto done;
   8920 	}
   8921 
   8922 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   8923 			  &zonediff, zone_keys, nkeys, now, false);
   8924 	if (result != ISC_R_SUCCESS) {
   8925 		dnssec_log(zone, ISC_LOG_ERROR,
   8926 			   "zone_nsec3chain:del_sigs -> %s",
   8927 			   dns_result_totext(result));
   8928 		goto failure;
   8929 	}
   8930 
   8931 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   8932 				   zone->updatemethod);
   8933 	if (result != ISC_R_SUCCESS) {
   8934 		dnssec_log(zone, ISC_LOG_ERROR,
   8935 			   "zone_nsec3chain:update_soa_serial -> %s",
   8936 			   dns_result_totext(result));
   8937 		goto failure;
   8938 	}
   8939 
   8940 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   8941 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   8942 			  inception, soaexpire, check_ksk, keyset_kskonly);
   8943 	if (result != ISC_R_SUCCESS) {
   8944 		dnssec_log(zone, ISC_LOG_ERROR,
   8945 			   "zone_nsec3chain:add_sigs -> %s",
   8946 			   dns_result_totext(result));
   8947 		goto failure;
   8948 	}
   8949 
   8950 	/* Write changes to journal file. */
   8951 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_nsec3chain"));
   8952 
   8953 	LOCK_ZONE(zone);
   8954 	zone_needdump(zone, DNS_DUMP_DELAY);
   8955 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   8956 	UNLOCK_ZONE(zone);
   8957 
   8958 done:
   8959 	/*
   8960 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   8961 	 */
   8962 	LOCK_ZONE(zone);
   8963 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   8964 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   8965 	{
   8966 		dns_dbiterator_pause(nsec3chain->dbiterator);
   8967 	}
   8968 	UNLOCK_ZONE(zone);
   8969 
   8970 	/*
   8971 	 * Everything has succeeded. Commit the changes.
   8972 	 * Unconditionally commit as zonediff.offline not checked above.
   8973 	 */
   8974 	dns_db_closeversion(db, &version, true);
   8975 
   8976 	/*
   8977 	 * Everything succeeded so we can clean these up now.
   8978 	 */
   8979 	nsec3chain = ISC_LIST_HEAD(cleanup);
   8980 	while (nsec3chain != NULL) {
   8981 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   8982 		dns_db_detach(&nsec3chain->db);
   8983 		dns_dbiterator_destroy(&nsec3chain->dbiterator);
   8984 		isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   8985 		nsec3chain = ISC_LIST_HEAD(cleanup);
   8986 	}
   8987 
   8988 	LOCK_ZONE(zone);
   8989 	set_resigntime(zone);
   8990 	UNLOCK_ZONE(zone);
   8991 
   8992 failure:
   8993 	if (result != ISC_R_SUCCESS) {
   8994 		dnssec_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
   8995 			   dns_result_totext(result));
   8996 	}
   8997 
   8998 	/*
   8999 	 * On error roll back the current nsec3chain.
   9000 	 */
   9001 	if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
   9002 		if (nsec3chain->done) {
   9003 			dns_db_detach(&nsec3chain->db);
   9004 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9005 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9006 		} else {
   9007 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9008 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9009 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9010 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9011 		}
   9012 	}
   9013 
   9014 	/*
   9015 	 * Rollback the cleanup list.
   9016 	 */
   9017 	nsec3chain = ISC_LIST_TAIL(cleanup);
   9018 	while (nsec3chain != NULL) {
   9019 		ISC_LIST_UNLINK(cleanup, nsec3chain, link);
   9020 		if (nsec3chain->done) {
   9021 			dns_db_detach(&nsec3chain->db);
   9022 			dns_dbiterator_destroy(&nsec3chain->dbiterator);
   9023 			isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
   9024 		} else {
   9025 			LOCK_ZONE(zone);
   9026 			ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
   9027 			UNLOCK_ZONE(zone);
   9028 			result = dns_dbiterator_first(nsec3chain->dbiterator);
   9029 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9030 			dns_dbiterator_pause(nsec3chain->dbiterator);
   9031 			nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
   9032 		}
   9033 		nsec3chain = ISC_LIST_TAIL(cleanup);
   9034 	}
   9035 
   9036 	LOCK_ZONE(zone);
   9037 	for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain); nsec3chain != NULL;
   9038 	     nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
   9039 	{
   9040 		dns_dbiterator_pause(nsec3chain->dbiterator);
   9041 	}
   9042 	UNLOCK_ZONE(zone);
   9043 
   9044 	dns_diff_clear(&param_diff);
   9045 	dns_diff_clear(&nsec3_diff);
   9046 	dns_diff_clear(&nsec_diff);
   9047 	dns_diff_clear(&_sig_diff);
   9048 
   9049 	if (iterator != NULL) {
   9050 		dns_rdatasetiter_destroy(&iterator);
   9051 	}
   9052 
   9053 	for (i = 0; i < nkeys; i++) {
   9054 		dst_key_free(&zone_keys[i]);
   9055 	}
   9056 
   9057 	if (node != NULL) {
   9058 		dns_db_detachnode(db, &node);
   9059 	}
   9060 	if (version != NULL) {
   9061 		dns_db_closeversion(db, &version, false);
   9062 		dns_db_detach(&db);
   9063 	} else if (db != NULL) {
   9064 		dns_db_detach(&db);
   9065 	}
   9066 
   9067 	LOCK_ZONE(zone);
   9068 	if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
   9069 		isc_interval_t interval;
   9070 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   9071 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   9072 		} else {
   9073 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   9074 		}
   9075 		isc_time_nowplusinterval(&zone->nsec3chaintime, &interval);
   9076 	} else {
   9077 		isc_time_settoepoch(&zone->nsec3chaintime);
   9078 	}
   9079 	UNLOCK_ZONE(zone);
   9080 
   9081 	INSIST(version == NULL);
   9082 }
   9083 
   9084 /*%
   9085  * Delete all RRSIG records with the given algorithm and keyid.
   9086  * Remove the NSEC record and RRSIGs if nkeys is zero.
   9087  * If all remaining RRsets are signed with the given algorithm
   9088  * set *has_algp to true.
   9089  */
   9090 static isc_result_t
   9091 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
   9092 	dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
   9093 	uint16_t keyid, bool *has_algp, dns_diff_t *diff) {
   9094 	dns_rdata_rrsig_t rrsig;
   9095 	dns_rdataset_t rdataset;
   9096 	dns_rdatasetiter_t *iterator = NULL;
   9097 	isc_result_t result;
   9098 	bool alg_missed = false;
   9099 	bool alg_found = false;
   9100 
   9101 	char namebuf[DNS_NAME_FORMATSIZE];
   9102 	dns_name_format(name, namebuf, sizeof(namebuf));
   9103 
   9104 	result = dns_db_allrdatasets(db, node, version, 0, &iterator);
   9105 	if (result != ISC_R_SUCCESS) {
   9106 		if (result == ISC_R_NOTFOUND) {
   9107 			result = ISC_R_SUCCESS;
   9108 		}
   9109 		return (result);
   9110 	}
   9111 
   9112 	dns_rdataset_init(&rdataset);
   9113 	for (result = dns_rdatasetiter_first(iterator); result == ISC_R_SUCCESS;
   9114 	     result = dns_rdatasetiter_next(iterator))
   9115 	{
   9116 		bool has_alg = false;
   9117 		dns_rdatasetiter_current(iterator, &rdataset);
   9118 		if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
   9119 			for (result = dns_rdataset_first(&rdataset);
   9120 			     result == ISC_R_SUCCESS;
   9121 			     result = dns_rdataset_next(&rdataset))
   9122 			{
   9123 				dns_rdata_t rdata = DNS_RDATA_INIT;
   9124 				dns_rdataset_current(&rdataset, &rdata);
   9125 				CHECK(update_one_rr(db, version, diff,
   9126 						    DNS_DIFFOP_DEL, name,
   9127 						    rdataset.ttl, &rdata));
   9128 			}
   9129 			if (result != ISC_R_NOMORE) {
   9130 				goto failure;
   9131 			}
   9132 			dns_rdataset_disassociate(&rdataset);
   9133 			continue;
   9134 		}
   9135 		if (rdataset.type != dns_rdatatype_rrsig) {
   9136 			dns_rdataset_disassociate(&rdataset);
   9137 			continue;
   9138 		}
   9139 		for (result = dns_rdataset_first(&rdataset);
   9140 		     result == ISC_R_SUCCESS;
   9141 		     result = dns_rdataset_next(&rdataset))
   9142 		{
   9143 			dns_rdata_t rdata = DNS_RDATA_INIT;
   9144 			dns_rdataset_current(&rdataset, &rdata);
   9145 			CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
   9146 			if (nkeys != 0 && (rrsig.algorithm != algorithm ||
   9147 					   rrsig.keyid != keyid)) {
   9148 				if (rrsig.algorithm == algorithm) {
   9149 					has_alg = true;
   9150 				}
   9151 				continue;
   9152 			}
   9153 			CHECK(update_one_rr(db, version, diff,
   9154 					    DNS_DIFFOP_DELRESIGN, name,
   9155 					    rdataset.ttl, &rdata));
   9156 		}
   9157 		dns_rdataset_disassociate(&rdataset);
   9158 		if (result != ISC_R_NOMORE) {
   9159 			break;
   9160 		}
   9161 
   9162 		/*
   9163 		 * After deleting, if there's still a signature for
   9164 		 * 'algorithm', set alg_found; if not, set alg_missed.
   9165 		 */
   9166 		if (has_alg) {
   9167 			alg_found = true;
   9168 		} else {
   9169 			alg_missed = true;
   9170 		}
   9171 	}
   9172 	if (result == ISC_R_NOMORE) {
   9173 		result = ISC_R_SUCCESS;
   9174 	}
   9175 
   9176 	/*
   9177 	 * Set `has_algp` if the algorithm was found in every RRset:
   9178 	 * i.e., found in at least one, and not missing from any.
   9179 	 */
   9180 	*has_algp = (alg_found && !alg_missed);
   9181 failure:
   9182 	if (dns_rdataset_isassociated(&rdataset)) {
   9183 		dns_rdataset_disassociate(&rdataset);
   9184 	}
   9185 	dns_rdatasetiter_destroy(&iterator);
   9186 	return (result);
   9187 }
   9188 
   9189 /*
   9190  * Incrementally sign the zone using the keys requested.
   9191  * Builds the NSEC chain if required.
   9192  */
   9193 static void
   9194 zone_sign(dns_zone_t *zone) {
   9195 	const char *me = "zone_sign";
   9196 	dns_db_t *db = NULL;
   9197 	dns_dbnode_t *node = NULL;
   9198 	dns_dbversion_t *version = NULL;
   9199 	dns_diff_t _sig_diff;
   9200 	dns_diff_t post_diff;
   9201 	dns__zonediff_t zonediff;
   9202 	dns_fixedname_t fixed;
   9203 	dns_fixedname_t nextfixed;
   9204 	dns_kasp_t *kasp;
   9205 	dns_name_t *name, *nextname;
   9206 	dns_rdataset_t rdataset;
   9207 	dns_signing_t *signing, *nextsigning;
   9208 	dns_signinglist_t cleanup;
   9209 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   9210 	int32_t signatures;
   9211 	bool check_ksk, keyset_kskonly, is_ksk, is_zsk;
   9212 	bool with_ksk, with_zsk;
   9213 	bool commit = false;
   9214 	bool is_bottom_of_zone;
   9215 	bool build_nsec = false;
   9216 	bool build_nsec3 = false;
   9217 	bool use_kasp = false;
   9218 	bool first;
   9219 	isc_result_t result;
   9220 	isc_stdtime_t now, inception, soaexpire, expire;
   9221 	uint32_t jitter, sigvalidityinterval, expiryinterval;
   9222 	unsigned int i, j;
   9223 	unsigned int nkeys = 0;
   9224 	uint32_t nodes;
   9225 
   9226 	ENTER;
   9227 
   9228 	dns_rdataset_init(&rdataset);
   9229 	name = dns_fixedname_initname(&fixed);
   9230 	nextname = dns_fixedname_initname(&nextfixed);
   9231 	dns_diff_init(zone->mctx, &_sig_diff);
   9232 	dns_diff_init(zone->mctx, &post_diff);
   9233 	zonediff_init(&zonediff, &_sig_diff);
   9234 	ISC_LIST_INIT(cleanup);
   9235 
   9236 	/*
   9237 	 * Updates are disabled.  Pause for 1 minute.
   9238 	 */
   9239 	if (zone->update_disabled) {
   9240 		result = ISC_R_FAILURE;
   9241 		goto cleanup;
   9242 	}
   9243 
   9244 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9245 	if (zone->db != NULL) {
   9246 		dns_db_attach(zone->db, &db);
   9247 	}
   9248 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9249 	if (db == NULL) {
   9250 		result = ISC_R_FAILURE;
   9251 		goto cleanup;
   9252 	}
   9253 
   9254 	result = dns_db_newversion(db, &version);
   9255 	if (result != ISC_R_SUCCESS) {
   9256 		dnssec_log(zone, ISC_LOG_ERROR,
   9257 			   "zone_sign:dns_db_newversion -> %s",
   9258 			   dns_result_totext(result));
   9259 		goto cleanup;
   9260 	}
   9261 
   9262 	isc_stdtime_get(&now);
   9263 
   9264 	result = dns__zone_findkeys(zone, db, version, now, zone->mctx,
   9265 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   9266 	if (result != ISC_R_SUCCESS) {
   9267 		dnssec_log(zone, ISC_LOG_ERROR,
   9268 			   "zone_sign:dns__zone_findkeys -> %s",
   9269 			   dns_result_totext(result));
   9270 		goto cleanup;
   9271 	}
   9272 
   9273 	kasp = dns_zone_getkasp(zone);
   9274 	sigvalidityinterval = dns_zone_getsigvalidityinterval(zone);
   9275 	inception = now - 3600; /* Allow for clock skew. */
   9276 	soaexpire = now + sigvalidityinterval;
   9277 	expiryinterval = dns_zone_getsigresigninginterval(zone);
   9278 	if (expiryinterval > sigvalidityinterval) {
   9279 		expiryinterval = sigvalidityinterval;
   9280 	} else {
   9281 		expiryinterval = sigvalidityinterval - expiryinterval;
   9282 	}
   9283 
   9284 	/*
   9285 	 * Spread out signatures over time if they happen to be
   9286 	 * clumped.  We don't do this for each add_sigs() call as
   9287 	 * we still want some clustering to occur.
   9288 	 */
   9289 	if (sigvalidityinterval >= 3600U) {
   9290 		if (sigvalidityinterval > 7200U) {
   9291 			jitter = isc_random_uniform(expiryinterval);
   9292 		} else {
   9293 			jitter = isc_random_uniform(1200);
   9294 		}
   9295 		expire = soaexpire - jitter - 1;
   9296 	} else {
   9297 		expire = soaexpire - 1;
   9298 	}
   9299 
   9300 	/*
   9301 	 * We keep pulling nodes off each iterator in turn until
   9302 	 * we have no more nodes to pull off or we reach the limits
   9303 	 * for this quantum.
   9304 	 */
   9305 	nodes = zone->nodes;
   9306 	signatures = zone->signatures;
   9307 	signing = ISC_LIST_HEAD(zone->signing);
   9308 	first = true;
   9309 
   9310 	if (dns_zone_use_kasp(zone)) {
   9311 		check_ksk = false;
   9312 		keyset_kskonly = true;
   9313 		use_kasp = true;
   9314 	} else {
   9315 		check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   9316 		keyset_kskonly = DNS_ZONE_OPTION(zone,
   9317 						 DNS_ZONEOPT_DNSKEYKSKONLY);
   9318 	}
   9319 	dnssec_log(zone, ISC_LOG_DEBUG(3), "zone_sign:use kasp -> %s",
   9320 		   use_kasp ? "yes" : "no");
   9321 
   9322 	/* Determine which type of chain to build */
   9323 	if (use_kasp) {
   9324 		build_nsec3 = dns_kasp_nsec3(kasp);
   9325 		build_nsec = !build_nsec3;
   9326 	} else {
   9327 		CHECK(dns_private_chains(db, version, zone->privatetype,
   9328 					 &build_nsec, &build_nsec3));
   9329 		/* If neither chain is found, default to NSEC */
   9330 		if (!build_nsec && !build_nsec3) {
   9331 			build_nsec = true;
   9332 		}
   9333 	}
   9334 
   9335 	while (signing != NULL && nodes-- > 0 && signatures > 0) {
   9336 		bool has_alg = false;
   9337 
   9338 		dns_dbiterator_pause(signing->dbiterator);
   9339 		nextsigning = ISC_LIST_NEXT(signing, link);
   9340 
   9341 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   9342 		if (signing->done || signing->db != zone->db) {
   9343 			/*
   9344 			 * The zone has been reloaded.	We will have to
   9345 			 * created new signings as part of the reload
   9346 			 * process so we can destroy this one.
   9347 			 */
   9348 			ISC_LIST_UNLINK(zone->signing, signing, link);
   9349 			ISC_LIST_APPEND(cleanup, signing, link);
   9350 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9351 			goto next_signing;
   9352 		}
   9353 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   9354 
   9355 		if (signing->db != db) {
   9356 			goto next_signing;
   9357 		}
   9358 
   9359 		is_bottom_of_zone = false;
   9360 
   9361 		if (first && signing->deleteit) {
   9362 			/*
   9363 			 * Remove the key we are deleting from consideration.
   9364 			 */
   9365 			for (i = 0, j = 0; i < nkeys; i++) {
   9366 				/*
   9367 				 * Find the key we want to remove.
   9368 				 */
   9369 				if (ALG(zone_keys[i]) == signing->algorithm &&
   9370 				    dst_key_id(zone_keys[i]) == signing->keyid)
   9371 				{
   9372 					bool ksk = false;
   9373 					isc_result_t ret = dst_key_getbool(
   9374 						zone_keys[i], DST_BOOL_KSK,
   9375 						&ksk);
   9376 					if (ret != ISC_R_SUCCESS) {
   9377 						ksk = KSK(zone_keys[i]);
   9378 					}
   9379 					if (ksk) {
   9380 						dst_key_free(&zone_keys[i]);
   9381 					}
   9382 					continue;
   9383 				}
   9384 				zone_keys[j] = zone_keys[i];
   9385 				j++;
   9386 			}
   9387 			for (i = j; i < nkeys; i++) {
   9388 				zone_keys[i] = NULL;
   9389 			}
   9390 			nkeys = j;
   9391 		}
   9392 
   9393 		dns_dbiterator_current(signing->dbiterator, &node, name);
   9394 
   9395 		if (signing->deleteit) {
   9396 			dns_dbiterator_pause(signing->dbiterator);
   9397 			CHECK(del_sig(db, version, name, node, nkeys,
   9398 				      signing->algorithm, signing->keyid,
   9399 				      &has_alg, zonediff.diff));
   9400 		}
   9401 
   9402 		/*
   9403 		 * On the first pass we need to check if the current node
   9404 		 * has not been obscured.
   9405 		 */
   9406 		if (first) {
   9407 			dns_fixedname_t ffound;
   9408 			dns_name_t *found;
   9409 			found = dns_fixedname_initname(&ffound);
   9410 			result = dns_db_find(
   9411 				db, name, version, dns_rdatatype_soa,
   9412 				DNS_DBFIND_NOWILD, 0, NULL, found, NULL, NULL);
   9413 			if ((result == DNS_R_DELEGATION ||
   9414 			     result == DNS_R_DNAME) &&
   9415 			    !dns_name_equal(name, found))
   9416 			{
   9417 				/*
   9418 				 * Remember the obscuring name so that
   9419 				 * we skip all obscured names.
   9420 				 */
   9421 				dns_name_copynf(found, name);
   9422 				is_bottom_of_zone = true;
   9423 				goto next_node;
   9424 			}
   9425 		}
   9426 
   9427 		/*
   9428 		 * Process one node.
   9429 		 */
   9430 		with_ksk = false;
   9431 		with_zsk = false;
   9432 		dns_dbiterator_pause(signing->dbiterator);
   9433 
   9434 		CHECK(check_if_bottom_of_zone(db, node, version,
   9435 					      &is_bottom_of_zone));
   9436 
   9437 		for (i = 0; !has_alg && i < nkeys; i++) {
   9438 			bool both = false;
   9439 
   9440 			/*
   9441 			 * Find the keys we want to sign with.
   9442 			 */
   9443 			if (!dst_key_isprivate(zone_keys[i])) {
   9444 				continue;
   9445 			}
   9446 			if (dst_key_inactive(zone_keys[i])) {
   9447 				continue;
   9448 			}
   9449 
   9450 			/*
   9451 			 * When adding look for the specific key.
   9452 			 */
   9453 			if (!signing->deleteit &&
   9454 			    (dst_key_alg(zone_keys[i]) != signing->algorithm ||
   9455 			     dst_key_id(zone_keys[i]) != signing->keyid))
   9456 			{
   9457 				continue;
   9458 			}
   9459 
   9460 			/*
   9461 			 * When deleting make sure we are properly signed
   9462 			 * with the algorithm that was being removed.
   9463 			 */
   9464 			if (signing->deleteit &&
   9465 			    ALG(zone_keys[i]) != signing->algorithm) {
   9466 				continue;
   9467 			}
   9468 
   9469 			/*
   9470 			 * Do we do KSK processing?
   9471 			 */
   9472 			if (check_ksk && !REVOKE(zone_keys[i])) {
   9473 				bool have_ksk, have_nonksk;
   9474 				if (KSK(zone_keys[i])) {
   9475 					have_ksk = true;
   9476 					have_nonksk = false;
   9477 				} else {
   9478 					have_ksk = false;
   9479 					have_nonksk = true;
   9480 				}
   9481 				for (j = 0; j < nkeys; j++) {
   9482 					if (j == i || (ALG(zone_keys[i]) !=
   9483 						       ALG(zone_keys[j]))) {
   9484 						continue;
   9485 					}
   9486 					/* Don't consider inactive keys, however
   9487 					 * the key may be temporary offline, so
   9488 					 * do consider keys which private key
   9489 					 * files are unavailable.
   9490 					 */
   9491 					if (dst_key_inactive(zone_keys[j])) {
   9492 						continue;
   9493 					}
   9494 					if (REVOKE(zone_keys[j])) {
   9495 						continue;
   9496 					}
   9497 					if (KSK(zone_keys[j])) {
   9498 						have_ksk = true;
   9499 					} else {
   9500 						have_nonksk = true;
   9501 					}
   9502 					both = have_ksk && have_nonksk;
   9503 					if (both) {
   9504 						break;
   9505 					}
   9506 				}
   9507 			}
   9508 			if (use_kasp) {
   9509 				/*
   9510 				 * A dnssec-policy is found. Check what
   9511 				 * RRsets this key can sign.
   9512 				 */
   9513 				isc_result_t kresult;
   9514 				is_ksk = false;
   9515 				kresult = dst_key_getbool(
   9516 					zone_keys[i], DST_BOOL_KSK, &is_ksk);
   9517 				if (kresult != ISC_R_SUCCESS) {
   9518 					if (KSK(zone_keys[i])) {
   9519 						is_ksk = true;
   9520 					}
   9521 				}
   9522 
   9523 				is_zsk = false;
   9524 				kresult = dst_key_getbool(
   9525 					zone_keys[i], DST_BOOL_ZSK, &is_zsk);
   9526 				if (kresult != ISC_R_SUCCESS) {
   9527 					if (!KSK(zone_keys[i])) {
   9528 						is_zsk = true;
   9529 					}
   9530 				}
   9531 				/* Treat as if we have both KSK and ZSK. */
   9532 				both = true;
   9533 			} else if (both || REVOKE(zone_keys[i])) {
   9534 				is_ksk = KSK(zone_keys[i]);
   9535 				is_zsk = !KSK(zone_keys[i]);
   9536 			} else {
   9537 				is_ksk = false;
   9538 				is_zsk = true;
   9539 			}
   9540 
   9541 			/*
   9542 			 * If deleting signatures, we need to ensure that
   9543 			 * the RRset is still signed at least once by a
   9544 			 * KSK and a ZSK.
   9545 			 */
   9546 			if (signing->deleteit && is_zsk && with_zsk) {
   9547 				continue;
   9548 			}
   9549 
   9550 			if (signing->deleteit && is_ksk && with_ksk) {
   9551 				continue;
   9552 			}
   9553 
   9554 			CHECK(sign_a_node(
   9555 				db, zone, name, node, version, build_nsec3,
   9556 				build_nsec, zone_keys[i], inception, expire,
   9557 				zone->minimum, is_ksk, is_zsk,
   9558 				(both && keyset_kskonly), is_bottom_of_zone,
   9559 				zonediff.diff, &signatures, zone->mctx));
   9560 			/*
   9561 			 * If we are adding we are done.  Look for other keys
   9562 			 * of the same algorithm if deleting.
   9563 			 */
   9564 			if (!signing->deleteit) {
   9565 				break;
   9566 			}
   9567 			if (is_zsk) {
   9568 				with_zsk = true;
   9569 			}
   9570 			if (is_ksk) {
   9571 				with_ksk = true;
   9572 			}
   9573 		}
   9574 
   9575 		/*
   9576 		 * Go onto next node.
   9577 		 */
   9578 	next_node:
   9579 		first = false;
   9580 		dns_db_detachnode(db, &node);
   9581 		do {
   9582 			result = dns_dbiterator_next(signing->dbiterator);
   9583 			if (result == ISC_R_NOMORE) {
   9584 				ISC_LIST_UNLINK(zone->signing, signing, link);
   9585 				ISC_LIST_APPEND(cleanup, signing, link);
   9586 				dns_dbiterator_pause(signing->dbiterator);
   9587 				if (nkeys != 0 && build_nsec) {
   9588 					/*
   9589 					 * We have finished regenerating the
   9590 					 * zone with a zone signing key.
   9591 					 * The NSEC chain is now complete and
   9592 					 * there is a full set of signatures
   9593 					 * for the zone.  We can now clear the
   9594 					 * OPT bit from the NSEC record.
   9595 					 */
   9596 					result = updatesecure(
   9597 						db, version, &zone->origin,
   9598 						zone->minimum, false,
   9599 						&post_diff);
   9600 					if (result != ISC_R_SUCCESS) {
   9601 						dnssec_log(zone, ISC_LOG_ERROR,
   9602 							   "updatesecure -> %s",
   9603 							   dns_result_totext(
   9604 								   result));
   9605 						goto cleanup;
   9606 					}
   9607 				}
   9608 				result = updatesignwithkey(
   9609 					zone, signing, version, build_nsec3,
   9610 					zone->minimum, &post_diff);
   9611 				if (result != ISC_R_SUCCESS) {
   9612 					dnssec_log(zone, ISC_LOG_ERROR,
   9613 						   "updatesignwithkey -> %s",
   9614 						   dns_result_totext(result));
   9615 					goto cleanup;
   9616 				}
   9617 				build_nsec = false;
   9618 				goto next_signing;
   9619 			} else if (result != ISC_R_SUCCESS) {
   9620 				dnssec_log(zone, ISC_LOG_ERROR,
   9621 					   "zone_sign:"
   9622 					   "dns_dbiterator_next -> %s",
   9623 					   dns_result_totext(result));
   9624 				goto cleanup;
   9625 			} else if (is_bottom_of_zone) {
   9626 				dns_dbiterator_current(signing->dbiterator,
   9627 						       &node, nextname);
   9628 				dns_db_detachnode(db, &node);
   9629 				if (!dns_name_issubdomain(nextname, name)) {
   9630 					break;
   9631 				}
   9632 			} else {
   9633 				break;
   9634 			}
   9635 		} while (1);
   9636 		continue;
   9637 
   9638 	next_signing:
   9639 		dns_dbiterator_pause(signing->dbiterator);
   9640 		signing = nextsigning;
   9641 		first = true;
   9642 	}
   9643 
   9644 	if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
   9645 		result = dns__zone_updatesigs(&post_diff, db, version,
   9646 					      zone_keys, nkeys, zone, inception,
   9647 					      expire, 0, now, check_ksk,
   9648 					      keyset_kskonly, &zonediff);
   9649 		if (result != ISC_R_SUCCESS) {
   9650 			dnssec_log(zone, ISC_LOG_ERROR,
   9651 				   "zone_sign:dns__zone_updatesigs -> %s",
   9652 				   dns_result_totext(result));
   9653 			goto cleanup;
   9654 		}
   9655 	}
   9656 
   9657 	/*
   9658 	 * Have we changed anything?
   9659 	 */
   9660 	if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
   9661 		if (zonediff.offline) {
   9662 			commit = true;
   9663 		}
   9664 		result = ISC_R_SUCCESS;
   9665 		goto pauseall;
   9666 	}
   9667 
   9668 	commit = true;
   9669 
   9670 	result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
   9671 			  &zonediff, zone_keys, nkeys, now, false);
   9672 	if (result != ISC_R_SUCCESS) {
   9673 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:del_sigs -> %s",
   9674 			   dns_result_totext(result));
   9675 		goto cleanup;
   9676 	}
   9677 
   9678 	result = update_soa_serial(zone, db, version, zonediff.diff, zone->mctx,
   9679 				   zone->updatemethod);
   9680 	if (result != ISC_R_SUCCESS) {
   9681 		dnssec_log(zone, ISC_LOG_ERROR,
   9682 			   "zone_sign:update_soa_serial -> %s",
   9683 			   dns_result_totext(result));
   9684 		goto cleanup;
   9685 	}
   9686 
   9687 	/*
   9688 	 * Generate maximum life time signatures so that the above loop
   9689 	 * termination is sensible.
   9690 	 */
   9691 	result = add_sigs(db, version, &zone->origin, zone, dns_rdatatype_soa,
   9692 			  zonediff.diff, zone_keys, nkeys, zone->mctx,
   9693 			  inception, soaexpire, check_ksk, keyset_kskonly);
   9694 	if (result != ISC_R_SUCCESS) {
   9695 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign:add_sigs -> %s",
   9696 			   dns_result_totext(result));
   9697 		goto cleanup;
   9698 	}
   9699 
   9700 	/*
   9701 	 * Write changes to journal file.
   9702 	 */
   9703 	CHECK(zone_journal(zone, zonediff.diff, NULL, "zone_sign"));
   9704 
   9705 pauseall:
   9706 	/*
   9707 	 * Pause all iterators so that dns_db_closeversion() can succeed.
   9708 	 */
   9709 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   9710 	     signing = ISC_LIST_NEXT(signing, link))
   9711 	{
   9712 		dns_dbiterator_pause(signing->dbiterator);
   9713 	}
   9714 
   9715 	for (signing = ISC_LIST_HEAD(cleanup); signing != NULL;
   9716 	     signing = ISC_LIST_NEXT(signing, link))
   9717 	{
   9718 		dns_dbiterator_pause(signing->dbiterator);
   9719 	}
   9720 
   9721 	/*
   9722 	 * Everything has succeeded. Commit the changes.
   9723 	 */
   9724 	dns_db_closeversion(db, &version, commit);
   9725 
   9726 	/*
   9727 	 * Everything succeeded so we can clean these up now.
   9728 	 */
   9729 	signing = ISC_LIST_HEAD(cleanup);
   9730 	while (signing != NULL) {
   9731 		ISC_LIST_UNLINK(cleanup, signing, link);
   9732 		dns_db_detach(&signing->db);
   9733 		dns_dbiterator_destroy(&signing->dbiterator);
   9734 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   9735 		signing = ISC_LIST_HEAD(cleanup);
   9736 	}
   9737 
   9738 	LOCK_ZONE(zone);
   9739 	set_resigntime(zone);
   9740 	if (commit) {
   9741 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   9742 		zone_needdump(zone, DNS_DUMP_DELAY);
   9743 	}
   9744 	UNLOCK_ZONE(zone);
   9745 
   9746 failure:
   9747 	if (result != ISC_R_SUCCESS) {
   9748 		dnssec_log(zone, ISC_LOG_ERROR, "zone_sign: failed: %s",
   9749 			   dns_result_totext(result));
   9750 	}
   9751 
   9752 cleanup:
   9753 	/*
   9754 	 * Pause all dbiterators.
   9755 	 */
   9756 	for (signing = ISC_LIST_HEAD(zone->signing); signing != NULL;
   9757 	     signing = ISC_LIST_NEXT(signing, link))
   9758 	{
   9759 		dns_dbiterator_pause(signing->dbiterator);
   9760 	}
   9761 
   9762 	/*
   9763 	 * Rollback the cleanup list.
   9764 	 */
   9765 	signing = ISC_LIST_HEAD(cleanup);
   9766 	while (signing != NULL) {
   9767 		ISC_LIST_UNLINK(cleanup, signing, link);
   9768 		ISC_LIST_PREPEND(zone->signing, signing, link);
   9769 		dns_dbiterator_first(signing->dbiterator);
   9770 		dns_dbiterator_pause(signing->dbiterator);
   9771 		signing = ISC_LIST_HEAD(cleanup);
   9772 	}
   9773 
   9774 	dns_diff_clear(&_sig_diff);
   9775 
   9776 	for (i = 0; i < nkeys; i++) {
   9777 		dst_key_free(&zone_keys[i]);
   9778 	}
   9779 
   9780 	if (node != NULL) {
   9781 		dns_db_detachnode(db, &node);
   9782 	}
   9783 
   9784 	if (version != NULL) {
   9785 		dns_db_closeversion(db, &version, false);
   9786 		dns_db_detach(&db);
   9787 	} else if (db != NULL) {
   9788 		dns_db_detach(&db);
   9789 	}
   9790 
   9791 	LOCK_ZONE(zone);
   9792 	if (ISC_LIST_HEAD(zone->signing) != NULL) {
   9793 		isc_interval_t interval;
   9794 		if (zone->update_disabled || result != ISC_R_SUCCESS) {
   9795 			isc_interval_set(&interval, 60, 0); /* 1 minute */
   9796 		} else {
   9797 			isc_interval_set(&interval, 0, 10000000); /* 10 ms */
   9798 		}
   9799 		isc_time_nowplusinterval(&zone->signingtime, &interval);
   9800 	} else {
   9801 		isc_time_settoepoch(&zone->signingtime);
   9802 	}
   9803 	UNLOCK_ZONE(zone);
   9804 
   9805 	INSIST(version == NULL);
   9806 }
   9807 
   9808 static isc_result_t
   9809 normalize_key(dns_rdata_t *rr, dns_rdata_t *target, unsigned char *data,
   9810 	      int size) {
   9811 	dns_rdata_dnskey_t dnskey;
   9812 	dns_rdata_keydata_t keydata;
   9813 	isc_buffer_t buf;
   9814 	isc_result_t result;
   9815 
   9816 	dns_rdata_reset(target);
   9817 	isc_buffer_init(&buf, data, size);
   9818 
   9819 	switch (rr->type) {
   9820 	case dns_rdatatype_dnskey:
   9821 		result = dns_rdata_tostruct(rr, &dnskey, NULL);
   9822 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9823 		dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
   9824 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   9825 				     &dnskey, &buf);
   9826 		break;
   9827 	case dns_rdatatype_keydata:
   9828 		result = dns_rdata_tostruct(rr, &keydata, NULL);
   9829 		if (result == ISC_R_UNEXPECTEDEND) {
   9830 			return (result);
   9831 		}
   9832 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9833 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   9834 		dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
   9835 				     &dnskey, &buf);
   9836 		break;
   9837 	default:
   9838 		INSIST(0);
   9839 		ISC_UNREACHABLE();
   9840 	}
   9841 	return (ISC_R_SUCCESS);
   9842 }
   9843 
   9844 /*
   9845  * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
   9846  * a KEYDATA rdataset from the key zone.
   9847  *
   9848  * 'rr' contains either a DNSKEY record, or a KEYDATA record
   9849  *
   9850  * After normalizing keys to the same format (DNSKEY, with revoke bit
   9851  * cleared), return true if a key that matches 'rr' is found in
   9852  * 'rdset', or false if not.
   9853  */
   9854 
   9855 static bool
   9856 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
   9857 	unsigned char data1[4096], data2[4096];
   9858 	dns_rdata_t rdata, rdata1, rdata2;
   9859 	isc_result_t result;
   9860 
   9861 	dns_rdata_init(&rdata);
   9862 	dns_rdata_init(&rdata1);
   9863 	dns_rdata_init(&rdata2);
   9864 
   9865 	result = normalize_key(rr, &rdata1, data1, sizeof(data1));
   9866 	if (result != ISC_R_SUCCESS) {
   9867 		return (false);
   9868 	}
   9869 
   9870 	for (result = dns_rdataset_first(rdset); result == ISC_R_SUCCESS;
   9871 	     result = dns_rdataset_next(rdset))
   9872 	{
   9873 		dns_rdata_reset(&rdata);
   9874 		dns_rdataset_current(rdset, &rdata);
   9875 		result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
   9876 		if (result != ISC_R_SUCCESS) {
   9877 			continue;
   9878 		}
   9879 		if (dns_rdata_compare(&rdata1, &rdata2) == 0) {
   9880 			return (true);
   9881 		}
   9882 	}
   9883 
   9884 	return (false);
   9885 }
   9886 
   9887 /*
   9888  * Calculate the refresh interval for a keydata zone, per
   9889  * RFC5011: MAX(1 hr,
   9890  *		MIN(15 days,
   9891  *		    1/2 * OrigTTL,
   9892  *		    1/2 * RRSigExpirationInterval))
   9893  * or for retries: MAX(1 hr,
   9894  *		       MIN(1 day,
   9895  *			   1/10 * OrigTTL,
   9896  *			   1/10 * RRSigExpirationInterval))
   9897  */
   9898 static inline isc_stdtime_t
   9899 refresh_time(dns_keyfetch_t *kfetch, bool retry) {
   9900 	isc_result_t result;
   9901 	uint32_t t;
   9902 	dns_rdataset_t *rdset;
   9903 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   9904 	dns_rdata_sig_t sig;
   9905 	isc_stdtime_t now;
   9906 
   9907 	isc_stdtime_get(&now);
   9908 
   9909 	if (dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
   9910 		rdset = &kfetch->dnskeysigset;
   9911 	} else {
   9912 		return (now + dns_zone_mkey_hour);
   9913 	}
   9914 
   9915 	result = dns_rdataset_first(rdset);
   9916 	if (result != ISC_R_SUCCESS) {
   9917 		return (now + dns_zone_mkey_hour);
   9918 	}
   9919 
   9920 	dns_rdataset_current(rdset, &sigrr);
   9921 	result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   9922 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   9923 
   9924 	if (!retry) {
   9925 		t = sig.originalttl / 2;
   9926 
   9927 		if (isc_serial_gt(sig.timeexpire, now)) {
   9928 			uint32_t exp = (sig.timeexpire - now) / 2;
   9929 			if (t > exp) {
   9930 				t = exp;
   9931 			}
   9932 		}
   9933 
   9934 		if (t > (15 * dns_zone_mkey_day)) {
   9935 			t = (15 * dns_zone_mkey_day);
   9936 		}
   9937 
   9938 		if (t < dns_zone_mkey_hour) {
   9939 			t = dns_zone_mkey_hour;
   9940 		}
   9941 	} else {
   9942 		t = sig.originalttl / 10;
   9943 
   9944 		if (isc_serial_gt(sig.timeexpire, now)) {
   9945 			uint32_t exp = (sig.timeexpire - now) / 10;
   9946 			if (t > exp) {
   9947 				t = exp;
   9948 			}
   9949 		}
   9950 
   9951 		if (t > dns_zone_mkey_day) {
   9952 			t = dns_zone_mkey_day;
   9953 		}
   9954 
   9955 		if (t < dns_zone_mkey_hour) {
   9956 			t = dns_zone_mkey_hour;
   9957 		}
   9958 	}
   9959 
   9960 	return (now + t);
   9961 }
   9962 
   9963 /*
   9964  * This routine is called when no changes are needed in a KEYDATA
   9965  * record except to simply update the refresh timer.  Caller should
   9966  * hold zone lock.
   9967  */
   9968 static isc_result_t
   9969 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff) {
   9970 	isc_result_t result;
   9971 	isc_buffer_t keyb;
   9972 	unsigned char key_buf[4096];
   9973 	dns_rdata_t rdata = DNS_RDATA_INIT;
   9974 	dns_rdata_keydata_t keydata;
   9975 	dns_name_t *name;
   9976 	dns_zone_t *zone = kfetch->zone;
   9977 	isc_stdtime_t now;
   9978 
   9979 	name = dns_fixedname_name(&kfetch->name);
   9980 	isc_stdtime_get(&now);
   9981 
   9982 	for (result = dns_rdataset_first(&kfetch->keydataset);
   9983 	     result == ISC_R_SUCCESS;
   9984 	     result = dns_rdataset_next(&kfetch->keydataset))
   9985 	{
   9986 		dns_rdata_reset(&rdata);
   9987 		dns_rdataset_current(&kfetch->keydataset, &rdata);
   9988 
   9989 		/* Delete old version */
   9990 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL, name,
   9991 				    0, &rdata));
   9992 
   9993 		/* Update refresh timer */
   9994 		result = dns_rdata_tostruct(&rdata, &keydata, NULL);
   9995 		if (result == ISC_R_UNEXPECTEDEND) {
   9996 			continue;
   9997 		}
   9998 		if (result != ISC_R_SUCCESS) {
   9999 			goto failure;
   10000 		}
   10001 		keydata.refresh = refresh_time(kfetch, true);
   10002 		set_refreshkeytimer(zone, &keydata, now, false);
   10003 
   10004 		dns_rdata_reset(&rdata);
   10005 		isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10006 		CHECK(dns_rdata_fromstruct(&rdata, zone->rdclass,
   10007 					   dns_rdatatype_keydata, &keydata,
   10008 					   &keyb));
   10009 
   10010 		/* Insert updated version */
   10011 		CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD, name,
   10012 				    0, &rdata));
   10013 	}
   10014 	result = ISC_R_SUCCESS;
   10015 failure:
   10016 	return (result);
   10017 }
   10018 
   10019 /*
   10020  * Verify that DNSKEY set is signed by the key specified in 'keydata'.
   10021  */
   10022 static bool
   10023 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
   10024 	isc_result_t result;
   10025 	dns_name_t *keyname;
   10026 	isc_mem_t *mctx;
   10027 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10028 	dns_rdata_t rr = DNS_RDATA_INIT;
   10029 	dns_rdata_rrsig_t sig;
   10030 	dns_rdata_dnskey_t dnskey;
   10031 	dst_key_t *dstkey = NULL;
   10032 	unsigned char key_buf[4096];
   10033 	isc_buffer_t keyb;
   10034 	bool answer = false;
   10035 
   10036 	REQUIRE(kfetch != NULL && keydata != NULL);
   10037 	REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
   10038 
   10039 	keyname = dns_fixedname_name(&kfetch->name);
   10040 	mctx = kfetch->zone->view->mctx;
   10041 
   10042 	/* Generate a key from keydata */
   10043 	isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10044 	dns_keydata_todnskey(keydata, &dnskey, NULL);
   10045 	dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
   10046 			     &dnskey, &keyb);
   10047 	result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
   10048 	if (result != ISC_R_SUCCESS) {
   10049 		return (false);
   10050 	}
   10051 
   10052 	/* See if that key generated any of the signatures */
   10053 	for (result = dns_rdataset_first(&kfetch->dnskeysigset);
   10054 	     result == ISC_R_SUCCESS;
   10055 	     result = dns_rdataset_next(&kfetch->dnskeysigset))
   10056 	{
   10057 		dns_fixedname_t fixed;
   10058 		dns_fixedname_init(&fixed);
   10059 
   10060 		dns_rdata_reset(&sigrr);
   10061 		dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
   10062 		result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10063 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10064 
   10065 		if (dst_key_alg(dstkey) == sig.algorithm &&
   10066 		    dst_key_rid(dstkey) == sig.keyid) {
   10067 			result = dns_dnssec_verify(
   10068 				keyname, &kfetch->dnskeyset, dstkey, false, 0,
   10069 				mctx, &sigrr, dns_fixedname_name(&fixed));
   10070 
   10071 			dnssec_log(kfetch->zone, ISC_LOG_DEBUG(3),
   10072 				   "Confirm revoked DNSKEY is self-signed: %s",
   10073 				   dns_result_totext(result));
   10074 
   10075 			if (result == ISC_R_SUCCESS) {
   10076 				answer = true;
   10077 				break;
   10078 			}
   10079 		}
   10080 	}
   10081 
   10082 	dst_key_free(&dstkey);
   10083 	return (answer);
   10084 }
   10085 
   10086 /*
   10087  * A DNSKEY set has been fetched from the zone apex of a zone whose trust
   10088  * anchors are being managed; scan the keyset, and update the key zone and the
   10089  * local trust anchors according to RFC5011.
   10090  */
   10091 static void
   10092 keyfetch_done(isc_task_t *task, isc_event_t *event) {
   10093 	isc_result_t result, eresult;
   10094 	dns_fetchevent_t *devent;
   10095 	dns_keyfetch_t *kfetch;
   10096 	dns_zone_t *zone;
   10097 	isc_mem_t *mctx = NULL;
   10098 	dns_keytable_t *secroots = NULL;
   10099 	dns_dbversion_t *ver = NULL;
   10100 	dns_diff_t diff;
   10101 	bool alldone = false;
   10102 	bool commit = false;
   10103 	dns_name_t *keyname = NULL;
   10104 	dns_rdata_t sigrr = DNS_RDATA_INIT;
   10105 	dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
   10106 	dns_rdata_t keydatarr = DNS_RDATA_INIT;
   10107 	dns_rdata_rrsig_t sig;
   10108 	dns_rdata_dnskey_t dnskey;
   10109 	dns_rdata_keydata_t keydata;
   10110 	bool initializing;
   10111 	char namebuf[DNS_NAME_FORMATSIZE];
   10112 	unsigned char key_buf[4096];
   10113 	isc_buffer_t keyb;
   10114 	dst_key_t *dstkey = NULL;
   10115 	isc_stdtime_t now;
   10116 	int pending = 0;
   10117 	bool secure = false, initial = false;
   10118 	bool free_needed;
   10119 	dns_keynode_t *keynode = NULL;
   10120 	dns_rdataset_t *dnskeys = NULL, *dnskeysigs = NULL;
   10121 	dns_rdataset_t *keydataset = NULL, dsset;
   10122 
   10123 	UNUSED(task);
   10124 	INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
   10125 	INSIST(event->ev_arg != NULL);
   10126 
   10127 	kfetch = event->ev_arg;
   10128 	zone = kfetch->zone;
   10129 	isc_mem_attach(zone->mctx, &mctx);
   10130 	keyname = dns_fixedname_name(&kfetch->name);
   10131 	dnskeys = &kfetch->dnskeyset;
   10132 	dnskeysigs = &kfetch->dnskeysigset;
   10133 	keydataset = &kfetch->keydataset;
   10134 
   10135 	devent = (dns_fetchevent_t *)event;
   10136 	eresult = devent->result;
   10137 
   10138 	/* Free resources which are not of interest */
   10139 	if (devent->node != NULL) {
   10140 		dns_db_detachnode(devent->db, &devent->node);
   10141 	}
   10142 	if (devent->db != NULL) {
   10143 		dns_db_detach(&devent->db);
   10144 	}
   10145 	isc_event_free(&event);
   10146 	dns_resolver_destroyfetch(&kfetch->fetch);
   10147 
   10148 	LOCK_ZONE(zone);
   10149 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL) {
   10150 		goto cleanup;
   10151 	}
   10152 
   10153 	isc_stdtime_get(&now);
   10154 	dns_name_format(keyname, namebuf, sizeof(namebuf));
   10155 
   10156 	result = dns_view_getsecroots(zone->view, &secroots);
   10157 	INSIST(result == ISC_R_SUCCESS);
   10158 
   10159 	dns_diff_init(mctx, &diff);
   10160 
   10161 	CHECK(dns_db_newversion(kfetch->db, &ver));
   10162 
   10163 	zone->refreshkeycount--;
   10164 	alldone = (zone->refreshkeycount == 0);
   10165 
   10166 	if (alldone) {
   10167 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10168 	}
   10169 
   10170 	dnssec_log(zone, ISC_LOG_DEBUG(3),
   10171 		   "Returned from key fetch in keyfetch_done() for '%s': %s",
   10172 		   namebuf, dns_result_totext(eresult));
   10173 
   10174 	/* Fetch failed */
   10175 	if (eresult != ISC_R_SUCCESS || !dns_rdataset_isassociated(dnskeys)) {
   10176 		dnssec_log(zone, ISC_LOG_WARNING,
   10177 			   "Unable to fetch DNSKEY set '%s': %s", namebuf,
   10178 			   dns_result_totext(eresult));
   10179 		CHECK(minimal_update(kfetch, ver, &diff));
   10180 		goto done;
   10181 	}
   10182 
   10183 	/* No RRSIGs found */
   10184 	if (!dns_rdataset_isassociated(dnskeysigs)) {
   10185 		dnssec_log(zone, ISC_LOG_WARNING,
   10186 			   "No DNSKEY RRSIGs found for '%s': %s", namebuf,
   10187 			   dns_result_totext(eresult));
   10188 		CHECK(minimal_update(kfetch, ver, &diff));
   10189 		goto done;
   10190 	}
   10191 
   10192 	/*
   10193 	 * Clear any cached trust level, as we need to run validation
   10194 	 * over again; trusted keys might have changed.
   10195 	 */
   10196 	dnskeys->trust = dnskeysigs->trust = dns_trust_none;
   10197 
   10198 	/* Look up the trust anchor */
   10199 	result = dns_keytable_find(secroots, keyname, &keynode);
   10200 	if (result != ISC_R_SUCCESS) {
   10201 		goto anchors_done;
   10202 	}
   10203 
   10204 	/*
   10205 	 * If the keynode has a DS trust anchor, use it for verification.
   10206 	 */
   10207 	dns_rdataset_init(&dsset);
   10208 	if (dns_keynode_dsset(keynode, &dsset)) {
   10209 		for (result = dns_rdataset_first(dnskeysigs);
   10210 		     result == ISC_R_SUCCESS;
   10211 		     result = dns_rdataset_next(dnskeysigs))
   10212 		{
   10213 			isc_result_t tresult;
   10214 			dns_rdata_t keyrdata = DNS_RDATA_INIT;
   10215 
   10216 			dns_rdata_reset(&sigrr);
   10217 			dns_rdataset_current(dnskeysigs, &sigrr);
   10218 			result = dns_rdata_tostruct(&sigrr, &sig, NULL);
   10219 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10220 
   10221 			for (tresult = dns_rdataset_first(&dsset);
   10222 			     tresult == ISC_R_SUCCESS;
   10223 			     tresult = dns_rdataset_next(&dsset))
   10224 			{
   10225 				dns_rdata_t dsrdata = DNS_RDATA_INIT;
   10226 				dns_rdata_ds_t ds;
   10227 
   10228 				dns_rdata_reset(&dsrdata);
   10229 				dns_rdataset_current(&dsset, &dsrdata);
   10230 				tresult = dns_rdata_tostruct(&dsrdata, &ds,
   10231 							     NULL);
   10232 				RUNTIME_CHECK(tresult == ISC_R_SUCCESS);
   10233 
   10234 				if (ds.key_tag != sig.keyid ||
   10235 				    ds.algorithm != sig.algorithm) {
   10236 					continue;
   10237 				}
   10238 
   10239 				result = dns_dnssec_matchdskey(
   10240 					keyname, &dsrdata, dnskeys, &keyrdata);
   10241 				if (result == ISC_R_SUCCESS) {
   10242 					break;
   10243 				}
   10244 			}
   10245 
   10246 			if (tresult == ISC_R_NOMORE) {
   10247 				continue;
   10248 			}
   10249 
   10250 			result = dns_dnssec_keyfromrdata(keyname, &keyrdata,
   10251 							 mctx, &dstkey);
   10252 			if (result != ISC_R_SUCCESS) {
   10253 				continue;
   10254 			}
   10255 
   10256 			result = dns_dnssec_verify(keyname, dnskeys, dstkey,
   10257 						   false, 0, mctx, &sigrr,
   10258 						   NULL);
   10259 			dst_key_free(&dstkey);
   10260 
   10261 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   10262 				   "Verifying DNSKEY set for zone "
   10263 				   "'%s' using DS %d/%d: %s",
   10264 				   namebuf, sig.keyid, sig.algorithm,
   10265 				   dns_result_totext(result));
   10266 
   10267 			if (result == ISC_R_SUCCESS) {
   10268 				dnskeys->trust = dns_trust_secure;
   10269 				dnskeysigs->trust = dns_trust_secure;
   10270 				initial = dns_keynode_initial(keynode);
   10271 				dns_keynode_trust(keynode);
   10272 				secure = true;
   10273 				break;
   10274 			}
   10275 		}
   10276 		dns_rdataset_disassociate(&dsset);
   10277 	}
   10278 
   10279 anchors_done:
   10280 	if (keynode != NULL) {
   10281 		dns_keytable_detachkeynode(secroots, &keynode);
   10282 	}
   10283 
   10284 	/*
   10285 	 * If we were not able to verify the answer using the current
   10286 	 * trusted keys then all we can do is look at any revoked keys.
   10287 	 */
   10288 	if (!secure) {
   10289 		dnssec_log(zone, ISC_LOG_INFO,
   10290 			   "DNSKEY set for zone '%s' could not be verified "
   10291 			   "with current keys",
   10292 			   namebuf);
   10293 	}
   10294 
   10295 	/*
   10296 	 * First scan keydataset to find keys that are not in dnskeyset
   10297 	 *   - Missing keys which are not scheduled for removal,
   10298 	 *     log a warning
   10299 	 *   - Missing keys which are scheduled for removal and
   10300 	 *     the remove hold-down timer has completed should
   10301 	 *     be removed from the key zone
   10302 	 *   - Missing keys whose acceptance timers have not yet
   10303 	 *     completed, log a warning and reset the acceptance
   10304 	 *     timer to 30 days in the future
   10305 	 *   - All keys not being removed have their refresh timers
   10306 	 *     updated
   10307 	 */
   10308 	initializing = true;
   10309 	for (result = dns_rdataset_first(keydataset); result == ISC_R_SUCCESS;
   10310 	     result = dns_rdataset_next(keydataset))
   10311 	{
   10312 		dns_keytag_t keytag;
   10313 
   10314 		dns_rdata_reset(&keydatarr);
   10315 		dns_rdataset_current(keydataset, &keydatarr);
   10316 		result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10317 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10318 
   10319 		dns_keydata_todnskey(&keydata, &dnskey, NULL);
   10320 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10321 		if (result != ISC_R_SUCCESS) {
   10322 			/*
   10323 			 * Skip if we cannot compute the key tag.
   10324 			 * This may happen if the algorithm is unsupported
   10325 			 */
   10326 			dns_zone_log(zone, ISC_LOG_ERROR,
   10327 				     "Cannot compute tag for key in zone %s: "
   10328 				     "%s "
   10329 				     "(skipping)",
   10330 				     namebuf, dns_result_totext(result));
   10331 			continue;
   10332 		}
   10333 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10334 
   10335 		/*
   10336 		 * If any keydata record has a nonzero add holddown, then
   10337 		 * there was a pre-existing trust anchor for this domain;
   10338 		 * that means we are *not* initializing it and shouldn't
   10339 		 * automatically trust all the keys we find at the zone apex.
   10340 		 */
   10341 		initializing = initializing && (keydata.addhd == 0);
   10342 
   10343 		if (!matchkey(dnskeys, &keydatarr)) {
   10344 			bool deletekey = false;
   10345 
   10346 			if (!secure) {
   10347 				if (keydata.removehd != 0 &&
   10348 				    keydata.removehd <= now) {
   10349 					deletekey = true;
   10350 				}
   10351 			} else if (keydata.addhd == 0) {
   10352 				deletekey = true;
   10353 			} else if (keydata.addhd > now) {
   10354 				dnssec_log(zone, ISC_LOG_INFO,
   10355 					   "Pending key %d for zone %s "
   10356 					   "unexpectedly missing "
   10357 					   "restarting 30-day acceptance "
   10358 					   "timer",
   10359 					   keytag, namebuf);
   10360 				if (keydata.addhd < now + dns_zone_mkey_month) {
   10361 					keydata.addhd = now +
   10362 							dns_zone_mkey_month;
   10363 				}
   10364 				keydata.refresh = refresh_time(kfetch, false);
   10365 			} else if (keydata.removehd == 0) {
   10366 				dnssec_log(zone, ISC_LOG_INFO,
   10367 					   "Active key %d for zone %s "
   10368 					   "unexpectedly missing",
   10369 					   keytag, namebuf);
   10370 				keydata.refresh = now + dns_zone_mkey_hour;
   10371 			} else if (keydata.removehd <= now) {
   10372 				deletekey = true;
   10373 				dnssec_log(zone, ISC_LOG_INFO,
   10374 					   "Revoked key %d for zone %s "
   10375 					   "missing: deleting from "
   10376 					   "managed keys database",
   10377 					   keytag, namebuf);
   10378 			} else {
   10379 				keydata.refresh = refresh_time(kfetch, false);
   10380 			}
   10381 
   10382 			if (secure || deletekey) {
   10383 				/* Delete old version */
   10384 				CHECK(update_one_rr(kfetch->db, ver, &diff,
   10385 						    DNS_DIFFOP_DEL, keyname, 0,
   10386 						    &keydatarr));
   10387 			}
   10388 
   10389 			if (!secure || deletekey) {
   10390 				continue;
   10391 			}
   10392 
   10393 			dns_rdata_reset(&keydatarr);
   10394 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10395 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10396 					     dns_rdatatype_keydata, &keydata,
   10397 					     &keyb);
   10398 
   10399 			/* Insert updated version */
   10400 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10401 					    DNS_DIFFOP_ADD, keyname, 0,
   10402 					    &keydatarr));
   10403 
   10404 			set_refreshkeytimer(zone, &keydata, now, false);
   10405 		}
   10406 	}
   10407 
   10408 	/*
   10409 	 * Next scan dnskeyset:
   10410 	 *   - If new keys are found (i.e., lacking a match in keydataset)
   10411 	 *     add them to the key zone and set the acceptance timer
   10412 	 *     to 30 days in the future (or to immediately if we've
   10413 	 *     determined that we're initializing the zone for the
   10414 	 *     first time)
   10415 	 *   - Previously-known keys that have been revoked
   10416 	 *     must be scheduled for removal from the key zone (or,
   10417 	 *     if they hadn't been accepted as trust anchors yet
   10418 	 *     anyway, removed at once)
   10419 	 *   - Previously-known unrevoked keys whose acceptance timers
   10420 	 *     have completed are promoted to trust anchors
   10421 	 *   - All keys not being removed have their refresh
   10422 	 *     timers updated
   10423 	 */
   10424 	for (result = dns_rdataset_first(dnskeys); result == ISC_R_SUCCESS;
   10425 	     result = dns_rdataset_next(dnskeys))
   10426 	{
   10427 		bool revoked = false;
   10428 		bool newkey = false;
   10429 		bool updatekey = false;
   10430 		bool deletekey = false;
   10431 		bool trustkey = false;
   10432 		dns_keytag_t keytag;
   10433 
   10434 		dns_rdata_reset(&dnskeyrr);
   10435 		dns_rdataset_current(dnskeys, &dnskeyrr);
   10436 		result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10437 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10438 
   10439 		/* Skip ZSK's */
   10440 		if ((dnskey.flags & DNS_KEYFLAG_KSK) == 0) {
   10441 			continue;
   10442 		}
   10443 
   10444 		result = compute_tag(keyname, &dnskey, mctx, &keytag);
   10445 		if (result != ISC_R_SUCCESS) {
   10446 			/*
   10447 			 * Skip if we cannot compute the key tag.
   10448 			 * This may happen if the algorithm is unsupported
   10449 			 */
   10450 			dns_zone_log(zone, ISC_LOG_ERROR,
   10451 				     "Cannot compute tag for key in zone %s: "
   10452 				     "%s "
   10453 				     "(skipping)",
   10454 				     namebuf, dns_result_totext(result));
   10455 			continue;
   10456 		}
   10457 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10458 
   10459 		revoked = ((dnskey.flags & DNS_KEYFLAG_REVOKE) != 0);
   10460 
   10461 		if (matchkey(keydataset, &dnskeyrr)) {
   10462 			dns_rdata_reset(&keydatarr);
   10463 			dns_rdataset_current(keydataset, &keydatarr);
   10464 			result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
   10465 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10466 
   10467 			if (revoked && revocable(kfetch, &keydata)) {
   10468 				if (keydata.addhd > now) {
   10469 					/*
   10470 					 * Key wasn't trusted yet, and now
   10471 					 * it's been revoked?  Just remove it
   10472 					 */
   10473 					deletekey = true;
   10474 					dnssec_log(zone, ISC_LOG_INFO,
   10475 						   "Pending key %d for "
   10476 						   "zone %s is now revoked: "
   10477 						   "deleting from the "
   10478 						   "managed keys database",
   10479 						   keytag, namebuf);
   10480 				} else if (keydata.removehd == 0) {
   10481 					/*
   10482 					 * Remove key from secroots.
   10483 					 */
   10484 					dns_view_untrust(zone->view, keyname,
   10485 							 &dnskey);
   10486 
   10487 					/* If initializing, delete now */
   10488 					if (keydata.addhd == 0) {
   10489 						deletekey = true;
   10490 					} else {
   10491 						keydata.removehd =
   10492 							now +
   10493 							dns_zone_mkey_month;
   10494 						keydata.flags |=
   10495 							DNS_KEYFLAG_REVOKE;
   10496 					}
   10497 
   10498 					dnssec_log(zone, ISC_LOG_INFO,
   10499 						   "Trusted key %d for "
   10500 						   "zone %s is now revoked",
   10501 						   keytag, namebuf);
   10502 				} else if (keydata.removehd < now) {
   10503 					/* Scheduled for removal */
   10504 					deletekey = true;
   10505 
   10506 					dnssec_log(zone, ISC_LOG_INFO,
   10507 						   "Revoked key %d for "
   10508 						   "zone %s removal timer "
   10509 						   "complete: deleting from "
   10510 						   "the managed keys database",
   10511 						   keytag, namebuf);
   10512 				}
   10513 			} else if (revoked && keydata.removehd == 0) {
   10514 				dnssec_log(zone, ISC_LOG_WARNING,
   10515 					   "Active key %d for zone "
   10516 					   "%s is revoked but "
   10517 					   "did not self-sign; "
   10518 					   "ignoring",
   10519 					   keytag, namebuf);
   10520 				continue;
   10521 			} else if (secure) {
   10522 				if (keydata.removehd != 0) {
   10523 					/*
   10524 					 * Key isn't revoked--but it
   10525 					 * seems it used to be.
   10526 					 * Remove it now and add it
   10527 					 * back as if it were a fresh key,
   10528 					 * with a 30-day acceptance timer.
   10529 					 */
   10530 					deletekey = true;
   10531 					newkey = true;
   10532 					keydata.removehd = 0;
   10533 					keydata.addhd = now +
   10534 							dns_zone_mkey_month;
   10535 
   10536 					dnssec_log(zone, ISC_LOG_INFO,
   10537 						   "Revoked key %d for "
   10538 						   "zone %s has returned: "
   10539 						   "starting 30-day "
   10540 						   "acceptance timer",
   10541 						   keytag, namebuf);
   10542 				} else if (keydata.addhd > now) {
   10543 					pending++;
   10544 				} else if (keydata.addhd == 0) {
   10545 					keydata.addhd = now;
   10546 				}
   10547 
   10548 				if (keydata.addhd <= now) {
   10549 					trustkey = true;
   10550 					dnssec_log(zone, ISC_LOG_INFO,
   10551 						   "Key %d for zone %s "
   10552 						   "is now trusted (%s)",
   10553 						   keytag, namebuf,
   10554 						   initial ? "initializing key "
   10555 							     "verified"
   10556 							   : "acceptance timer "
   10557 							     "complete");
   10558 				}
   10559 			} else if (keydata.addhd > now) {
   10560 				/*
   10561 				 * Not secure, and key is pending:
   10562 				 * reset the acceptance timer
   10563 				 */
   10564 				pending++;
   10565 				keydata.addhd = now + dns_zone_mkey_month;
   10566 				dnssec_log(zone, ISC_LOG_INFO,
   10567 					   "Pending key %d "
   10568 					   "for zone %s was "
   10569 					   "not validated: restarting "
   10570 					   "30-day acceptance timer",
   10571 					   keytag, namebuf);
   10572 			}
   10573 
   10574 			if (!deletekey && !newkey) {
   10575 				updatekey = true;
   10576 			}
   10577 		} else if (secure) {
   10578 			/*
   10579 			 * Key wasn't in the key zone but it's
   10580 			 * revoked now anyway, so just skip it
   10581 			 */
   10582 			if (revoked) {
   10583 				continue;
   10584 			}
   10585 
   10586 			/* Key wasn't in the key zone: add it */
   10587 			newkey = true;
   10588 
   10589 			if (initializing) {
   10590 				dnssec_log(zone, ISC_LOG_WARNING,
   10591 					   "Initializing automatic trust "
   10592 					   "anchor management for zone '%s'; "
   10593 					   "DNSKEY ID %d is now trusted, "
   10594 					   "waiving the normal 30-day "
   10595 					   "waiting period.",
   10596 					   namebuf, keytag);
   10597 				trustkey = true;
   10598 			} else {
   10599 				dnssec_log(zone, ISC_LOG_INFO,
   10600 					   "New key %d observed "
   10601 					   "for zone '%s': "
   10602 					   "starting 30-day "
   10603 					   "acceptance timer",
   10604 					   keytag, namebuf);
   10605 			}
   10606 		} else {
   10607 			/*
   10608 			 * No previously known key, and the key is not
   10609 			 * secure, so skip it.
   10610 			 */
   10611 			continue;
   10612 		}
   10613 
   10614 		/* Delete old version */
   10615 		if (deletekey || !newkey) {
   10616 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10617 					    DNS_DIFFOP_DEL, keyname, 0,
   10618 					    &keydatarr));
   10619 		}
   10620 
   10621 		if (updatekey) {
   10622 			/* Set refresh timer */
   10623 			keydata.refresh = refresh_time(kfetch, false);
   10624 			dns_rdata_reset(&keydatarr);
   10625 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10626 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10627 					     dns_rdatatype_keydata, &keydata,
   10628 					     &keyb);
   10629 
   10630 			/* Insert updated version */
   10631 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10632 					    DNS_DIFFOP_ADD, keyname, 0,
   10633 					    &keydatarr));
   10634 		} else if (newkey) {
   10635 			/* Convert DNSKEY to KEYDATA */
   10636 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10637 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10638 			dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
   10639 					       NULL);
   10640 			keydata.addhd = initializing
   10641 						? now
   10642 						: now + dns_zone_mkey_month;
   10643 			keydata.refresh = refresh_time(kfetch, false);
   10644 			dns_rdata_reset(&keydatarr);
   10645 			isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
   10646 			dns_rdata_fromstruct(&keydatarr, zone->rdclass,
   10647 					     dns_rdatatype_keydata, &keydata,
   10648 					     &keyb);
   10649 
   10650 			/* Insert into key zone */
   10651 			CHECK(update_one_rr(kfetch->db, ver, &diff,
   10652 					    DNS_DIFFOP_ADD, keyname, 0,
   10653 					    &keydatarr));
   10654 		}
   10655 
   10656 		if (trustkey) {
   10657 			/* Trust this key. */
   10658 			result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
   10659 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10660 			trust_key(zone, keyname, &dnskey, false);
   10661 		}
   10662 
   10663 		if (secure && !deletekey) {
   10664 			INSIST(newkey || updatekey);
   10665 			set_refreshkeytimer(zone, &keydata, now, false);
   10666 		}
   10667 	}
   10668 
   10669 	/*
   10670 	 * RFC5011 says, "A trust point that has all of its trust anchors
   10671 	 * revoked is considered deleted and is treated as if the trust
   10672 	 * point was never configured."  But if someone revoked their
   10673 	 * active key before the standby was trusted, that would mean the
   10674 	 * zone would suddenly be nonsecured.  We avoid this by checking to
   10675 	 * see if there's pending keydata.  If so, we put a null key in
   10676 	 * the security roots; then all queries to the zone will fail.
   10677 	 */
   10678 	if (pending != 0) {
   10679 		fail_secure(zone, keyname);
   10680 	}
   10681 
   10682 done:
   10683 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10684 		/* Write changes to journal file. */
   10685 		CHECK(update_soa_serial(zone, kfetch->db, ver, &diff, mctx,
   10686 					zone->updatemethod));
   10687 		CHECK(zone_journal(zone, &diff, NULL, "keyfetch_done"));
   10688 		commit = true;
   10689 
   10690 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   10691 		zone_needdump(zone, 30);
   10692 	} else if (result == ISC_R_NOMORE) {
   10693 		/*
   10694 		 * If "updatekey" was true for all keys found in the DNSKEY
   10695 		 * response and the previous update of those keys happened
   10696 		 * during the same second (only possible if a key refresh was
   10697 		 * externally triggered), it may happen that all relevant
   10698 		 * update_one_rr() calls will return ISC_R_SUCCESS, but
   10699 		 * diff.tuples will remain empty.  Reset result to
   10700 		 * ISC_R_SUCCESS to prevent a bogus warning from being logged.
   10701 		 */
   10702 		result = ISC_R_SUCCESS;
   10703 	}
   10704 
   10705 failure:
   10706 	if (result != ISC_R_SUCCESS) {
   10707 		dnssec_log(zone, ISC_LOG_ERROR,
   10708 			   "error during managed-keys processing (%s): "
   10709 			   "DNSSEC validation may be at risk",
   10710 			   isc_result_totext(result));
   10711 	}
   10712 	dns_diff_clear(&diff);
   10713 	if (ver != NULL) {
   10714 		dns_db_closeversion(kfetch->db, &ver, commit);
   10715 	}
   10716 
   10717 cleanup:
   10718 	dns_db_detach(&kfetch->db);
   10719 
   10720 	isc_refcount_decrement(&zone->irefs);
   10721 
   10722 	kfetch->zone = NULL;
   10723 
   10724 	if (dns_rdataset_isassociated(keydataset)) {
   10725 		dns_rdataset_disassociate(keydataset);
   10726 	}
   10727 	if (dns_rdataset_isassociated(dnskeys)) {
   10728 		dns_rdataset_disassociate(dnskeys);
   10729 	}
   10730 	if (dns_rdataset_isassociated(dnskeysigs)) {
   10731 		dns_rdataset_disassociate(dnskeysigs);
   10732 	}
   10733 
   10734 	dns_name_free(keyname, mctx);
   10735 	isc_mem_putanddetach(&mctx, kfetch, sizeof(dns_keyfetch_t));
   10736 
   10737 	if (secroots != NULL) {
   10738 		dns_keytable_detach(&secroots);
   10739 	}
   10740 
   10741 	free_needed = exit_check(zone);
   10742 	UNLOCK_ZONE(zone);
   10743 	if (free_needed) {
   10744 		zone_free(zone);
   10745 	}
   10746 
   10747 	INSIST(ver == NULL);
   10748 }
   10749 
   10750 /*
   10751  * Refresh the data in the key zone.  Initiate a fetch to look up
   10752  * DNSKEY records at the trust anchor name.
   10753  */
   10754 static void
   10755 zone_refreshkeys(dns_zone_t *zone) {
   10756 	const char me[] = "zone_refreshkeys";
   10757 	isc_result_t result;
   10758 	dns_rriterator_t rrit;
   10759 	dns_db_t *db = NULL;
   10760 	dns_dbversion_t *ver = NULL;
   10761 	dns_diff_t diff;
   10762 	dns_rdata_t rdata = DNS_RDATA_INIT;
   10763 	dns_rdata_keydata_t kd;
   10764 	isc_stdtime_t now;
   10765 	bool commit = false;
   10766 	bool fetching = false, fetch_err = false;
   10767 	bool timerset = false;
   10768 
   10769 	ENTER;
   10770 	REQUIRE(zone->db != NULL);
   10771 
   10772 	isc_stdtime_get(&now);
   10773 
   10774 	LOCK_ZONE(zone);
   10775 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   10776 		isc_time_settoepoch(&zone->refreshkeytime);
   10777 		UNLOCK_ZONE(zone);
   10778 		return;
   10779 	}
   10780 
   10781 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   10782 	dns_db_attach(zone->db, &db);
   10783 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   10784 
   10785 	dns_diff_init(zone->mctx, &diff);
   10786 
   10787 	CHECK(dns_db_newversion(db, &ver));
   10788 
   10789 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10790 
   10791 	dns_rriterator_init(&rrit, db, ver, 0);
   10792 	for (result = dns_rriterator_first(&rrit); result == ISC_R_SUCCESS;
   10793 	     result = dns_rriterator_nextrrset(&rrit))
   10794 	{
   10795 		isc_stdtime_t timer = 0xffffffff;
   10796 		dns_name_t *name = NULL, *kname = NULL;
   10797 		dns_rdataset_t *kdset = NULL;
   10798 		dns_keyfetch_t *kfetch;
   10799 		uint32_t ttl;
   10800 
   10801 		dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
   10802 		if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
   10803 		    !dns_rdataset_isassociated(kdset))
   10804 		{
   10805 			continue;
   10806 		}
   10807 
   10808 		/*
   10809 		 * Scan the stored keys looking for ones that need
   10810 		 * removal or refreshing
   10811 		 */
   10812 		for (result = dns_rdataset_first(kdset);
   10813 		     result == ISC_R_SUCCESS; result = dns_rdataset_next(kdset))
   10814 		{
   10815 			dns_rdata_reset(&rdata);
   10816 			dns_rdataset_current(kdset, &rdata);
   10817 			result = dns_rdata_tostruct(&rdata, &kd, NULL);
   10818 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   10819 
   10820 			/* Removal timer expired? */
   10821 			if (kd.removehd != 0 && kd.removehd < now) {
   10822 				dns_rriterator_pause(&rrit);
   10823 				CHECK(update_one_rr(db, ver, &diff,
   10824 						    DNS_DIFFOP_DEL, name, ttl,
   10825 						    &rdata));
   10826 				continue;
   10827 			}
   10828 
   10829 			/* Acceptance timer expired? */
   10830 			if (kd.addhd <= now) {
   10831 				timer = kd.addhd;
   10832 			}
   10833 
   10834 			/* Or do we just need to refresh the keyset? */
   10835 			if (timer > kd.refresh) {
   10836 				timer = kd.refresh;
   10837 			}
   10838 
   10839 			dns_rriterator_pause(&rrit);
   10840 			set_refreshkeytimer(zone, &kd, now, false);
   10841 			timerset = true;
   10842 		}
   10843 
   10844 		if (timer > now) {
   10845 			continue;
   10846 		}
   10847 
   10848 		dns_rriterator_pause(&rrit);
   10849 
   10850 		kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
   10851 
   10852 		zone->refreshkeycount++;
   10853 		kfetch->zone = zone;
   10854 		isc_refcount_increment0(&zone->irefs);
   10855 		kname = dns_fixedname_initname(&kfetch->name);
   10856 		dns_name_dup(name, zone->mctx, kname);
   10857 		dns_rdataset_init(&kfetch->dnskeyset);
   10858 		dns_rdataset_init(&kfetch->dnskeysigset);
   10859 		dns_rdataset_init(&kfetch->keydataset);
   10860 		dns_rdataset_clone(kdset, &kfetch->keydataset);
   10861 		kfetch->db = NULL;
   10862 		dns_db_attach(db, &kfetch->db);
   10863 		kfetch->fetch = NULL;
   10864 
   10865 		if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   10866 			char namebuf[DNS_NAME_FORMATSIZE];
   10867 			dns_name_format(kname, namebuf, sizeof(namebuf));
   10868 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   10869 				   "Creating key fetch in "
   10870 				   "zone_refreshkeys() for '%s'",
   10871 				   namebuf);
   10872 		}
   10873 
   10874 		/*
   10875 		 * Use of DNS_FETCHOPT_NOCACHED is essential here.  If it is
   10876 		 * not set and the cache still holds a non-expired, validated
   10877 		 * version of the RRset being queried for by the time the
   10878 		 * response is received, the cached RRset will be passed to
   10879 		 * keyfetch_done() instead of the one received in the response
   10880 		 * as the latter will have a lower trust level due to not being
   10881 		 * validated until keyfetch_done() is called.
   10882 		 */
   10883 
   10884 #ifdef ENABLE_AFL
   10885 		if (!dns_fuzzing_resolver) {
   10886 #endif /* ifdef ENABLE_AFL */
   10887 			result = dns_resolver_createfetch(
   10888 				zone->view->resolver, kname,
   10889 				dns_rdatatype_dnskey, NULL, NULL, NULL, NULL, 0,
   10890 				DNS_FETCHOPT_NOVALIDATE |
   10891 					DNS_FETCHOPT_UNSHARED |
   10892 					DNS_FETCHOPT_NOCACHED,
   10893 				0, NULL, zone->task, keyfetch_done, kfetch,
   10894 				&kfetch->dnskeyset, &kfetch->dnskeysigset,
   10895 				&kfetch->fetch);
   10896 #ifdef ENABLE_AFL
   10897 		} else {
   10898 			result = ISC_R_FAILURE;
   10899 		}
   10900 #endif /* ifdef ENABLE_AFL */
   10901 		if (result == ISC_R_SUCCESS) {
   10902 			fetching = true;
   10903 		} else {
   10904 			zone->refreshkeycount--;
   10905 			isc_refcount_decrement(&zone->irefs);
   10906 			dns_db_detach(&kfetch->db);
   10907 			dns_rdataset_disassociate(&kfetch->keydataset);
   10908 			dns_name_free(kname, zone->mctx);
   10909 			isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
   10910 			dnssec_log(zone, ISC_LOG_WARNING,
   10911 				   "Failed to create fetch for DNSKEY update");
   10912 			fetch_err = true;
   10913 		}
   10914 	}
   10915 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   10916 		CHECK(update_soa_serial(zone, db, ver, &diff, zone->mctx,
   10917 					zone->updatemethod));
   10918 		CHECK(zone_journal(zone, &diff, NULL, "zone_refreshkeys"));
   10919 		commit = true;
   10920 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   10921 		zone_needdump(zone, 30);
   10922 	}
   10923 
   10924 failure:
   10925 	if (fetch_err) {
   10926 		/*
   10927 		 * Error during a key fetch; retry in an hour.
   10928 		 */
   10929 		isc_time_t timenow, timethen;
   10930 		char timebuf[80];
   10931 
   10932 		TIME_NOW(&timenow);
   10933 		DNS_ZONE_TIME_ADD(&timenow, dns_zone_mkey_hour, &timethen);
   10934 		zone->refreshkeytime = timethen;
   10935 		zone_settimer(zone, &timenow);
   10936 
   10937 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   10938 		dnssec_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
   10939 			   timebuf);
   10940 	} else if (!timerset) {
   10941 		isc_time_settoepoch(&zone->refreshkeytime);
   10942 	}
   10943 
   10944 	if (!fetching) {
   10945 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
   10946 	}
   10947 
   10948 	dns_diff_clear(&diff);
   10949 	if (ver != NULL) {
   10950 		dns_rriterator_destroy(&rrit);
   10951 		dns_db_closeversion(db, &ver, commit);
   10952 	}
   10953 	dns_db_detach(&db);
   10954 
   10955 	UNLOCK_ZONE(zone);
   10956 
   10957 	INSIST(ver == NULL);
   10958 }
   10959 
   10960 static void
   10961 zone_maintenance(dns_zone_t *zone) {
   10962 	const char me[] = "zone_maintenance";
   10963 	isc_time_t now;
   10964 	isc_result_t result;
   10965 	bool dumping, load_pending, viewok;
   10966 
   10967 	REQUIRE(DNS_ZONE_VALID(zone));
   10968 	ENTER;
   10969 
   10970 	/*
   10971 	 * Are we pending load/reload?
   10972 	 */
   10973 	LOCK_ZONE(zone);
   10974 	load_pending = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING);
   10975 	UNLOCK_ZONE(zone);
   10976 
   10977 	if (load_pending) {
   10978 		return;
   10979 	}
   10980 
   10981 	/*
   10982 	 * Configuring the view of this zone may have
   10983 	 * failed, for example because the config file
   10984 	 * had a syntax error.	In that case, the view
   10985 	 * adb or resolver will be NULL, and we had better not try
   10986 	 * to do further maintenance on it.
   10987 	 */
   10988 	LOCK_ZONE(zone);
   10989 	viewok = (zone->view != NULL && zone->view->adb != NULL);
   10990 	UNLOCK_ZONE(zone);
   10991 	if (!viewok) {
   10992 		return;
   10993 	}
   10994 
   10995 	TIME_NOW(&now);
   10996 
   10997 	/*
   10998 	 * Expire check.
   10999 	 */
   11000 	switch (zone->type) {
   11001 	case dns_zone_redirect:
   11002 		if (zone->masters == NULL) {
   11003 			break;
   11004 		}
   11005 	/* FALLTHROUGH */
   11006 	case dns_zone_slave:
   11007 	case dns_zone_mirror:
   11008 	case dns_zone_stub:
   11009 		LOCK_ZONE(zone);
   11010 		if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
   11011 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11012 		{
   11013 			zone_expire(zone);
   11014 			zone->refreshtime = now;
   11015 		}
   11016 		UNLOCK_ZONE(zone);
   11017 		break;
   11018 	default:
   11019 		break;
   11020 	}
   11021 
   11022 	/*
   11023 	 * Up to date check.
   11024 	 */
   11025 	switch (zone->type) {
   11026 	case dns_zone_redirect:
   11027 		if (zone->masters == NULL) {
   11028 			break;
   11029 		}
   11030 	/* FALLTHROUGH */
   11031 	case dns_zone_slave:
   11032 	case dns_zone_mirror:
   11033 	case dns_zone_stub:
   11034 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
   11035 		    isc_time_compare(&now, &zone->refreshtime) >= 0)
   11036 		{
   11037 			dns_zone_refresh(zone);
   11038 		}
   11039 		break;
   11040 	default:
   11041 		break;
   11042 	}
   11043 
   11044 	/*
   11045 	 * Secondaries send notifies before backing up to disk,
   11046 	 * primaries after.
   11047 	 */
   11048 	if ((zone->type == dns_zone_slave || zone->type == dns_zone_mirror) &&
   11049 	    (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11050 	     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11051 	    isc_time_compare(&now, &zone->notifytime) >= 0)
   11052 	{
   11053 		zone_notify(zone, &now);
   11054 	}
   11055 
   11056 	/*
   11057 	 * Do we need to consolidate the backing store?
   11058 	 */
   11059 	switch (zone->type) {
   11060 	case dns_zone_master:
   11061 	case dns_zone_slave:
   11062 	case dns_zone_mirror:
   11063 	case dns_zone_key:
   11064 	case dns_zone_redirect:
   11065 	case dns_zone_stub:
   11066 		LOCK_ZONE(zone);
   11067 		if (zone->masterfile != NULL &&
   11068 		    isc_time_compare(&now, &zone->dumptime) >= 0 &&
   11069 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11070 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
   11071 		{
   11072 			dumping = was_dumping(zone);
   11073 		} else {
   11074 			dumping = true;
   11075 		}
   11076 		UNLOCK_ZONE(zone);
   11077 		if (!dumping) {
   11078 			result = zone_dump(zone, true); /* task locked */
   11079 			if (result != ISC_R_SUCCESS) {
   11080 				dns_zone_log(zone, ISC_LOG_WARNING,
   11081 					     "dump failed: %s",
   11082 					     dns_result_totext(result));
   11083 			}
   11084 		}
   11085 		break;
   11086 	default:
   11087 		break;
   11088 	}
   11089 
   11090 	/*
   11091 	 * Master/redirect zones send notifies now, if needed
   11092 	 */
   11093 	switch (zone->type) {
   11094 	case dns_zone_master:
   11095 	case dns_zone_redirect:
   11096 		if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   11097 		     DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY)) &&
   11098 		    isc_time_compare(&now, &zone->notifytime) >= 0)
   11099 		{
   11100 			zone_notify(zone, &now);
   11101 		}
   11102 	default:
   11103 		break;
   11104 	}
   11105 
   11106 	/*
   11107 	 * Do we need to refresh keys?
   11108 	 */
   11109 	switch (zone->type) {
   11110 	case dns_zone_key:
   11111 		if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
   11112 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   11113 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
   11114 			{
   11115 				zone_refreshkeys(zone);
   11116 			}
   11117 		}
   11118 		break;
   11119 	case dns_zone_master:
   11120 		if (!isc_time_isepoch(&zone->refreshkeytime) &&
   11121 		    isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
   11122 		    zone->rss_event == NULL)
   11123 		{
   11124 			zone_rekey(zone);
   11125 		}
   11126 	default:
   11127 		break;
   11128 	}
   11129 
   11130 	switch (zone->type) {
   11131 	case dns_zone_master:
   11132 	case dns_zone_redirect:
   11133 	case dns_zone_slave:
   11134 		/*
   11135 		 * Do we need to sign/resign some RRsets?
   11136 		 */
   11137 		if (zone->rss_event != NULL) {
   11138 			break;
   11139 		}
   11140 		if (!isc_time_isepoch(&zone->signingtime) &&
   11141 		    isc_time_compare(&now, &zone->signingtime) >= 0)
   11142 		{
   11143 			zone_sign(zone);
   11144 		} else if (!isc_time_isepoch(&zone->resigntime) &&
   11145 			   isc_time_compare(&now, &zone->resigntime) >= 0)
   11146 		{
   11147 			zone_resigninc(zone);
   11148 		} else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
   11149 			   isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
   11150 		{
   11151 			zone_nsec3chain(zone);
   11152 		}
   11153 		/*
   11154 		 * Do we need to issue a key expiry warning?
   11155 		 */
   11156 		if (!isc_time_isepoch(&zone->keywarntime) &&
   11157 		    isc_time_compare(&now, &zone->keywarntime) >= 0)
   11158 		{
   11159 			set_key_expiry_warning(zone, zone->key_expiry,
   11160 					       isc_time_seconds(&now));
   11161 		}
   11162 		break;
   11163 
   11164 	default:
   11165 		break;
   11166 	}
   11167 	LOCK_ZONE(zone);
   11168 	zone_settimer(zone, &now);
   11169 	UNLOCK_ZONE(zone);
   11170 }
   11171 
   11172 void
   11173 dns_zone_markdirty(dns_zone_t *zone) {
   11174 	uint32_t serial;
   11175 	isc_result_t result = ISC_R_SUCCESS;
   11176 	dns_zone_t *secure = NULL;
   11177 
   11178 	/*
   11179 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   11180 	 * could result in a deadlock due to a LOR so we will spin if we
   11181 	 * can't obtain the both locks.
   11182 	 */
   11183 again:
   11184 	LOCK_ZONE(zone);
   11185 	if (zone->type == dns_zone_master) {
   11186 		if (inline_raw(zone)) {
   11187 			unsigned int soacount;
   11188 			secure = zone->secure;
   11189 			INSIST(secure != zone);
   11190 			TRYLOCK_ZONE(result, secure);
   11191 			if (result != ISC_R_SUCCESS) {
   11192 				UNLOCK_ZONE(zone);
   11193 				secure = NULL;
   11194 				isc_thread_yield();
   11195 				goto again;
   11196 			}
   11197 
   11198 			ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11199 			if (zone->db != NULL) {
   11200 				result = zone_get_from_db(
   11201 					zone, zone->db, NULL, &soacount,
   11202 					&serial, NULL, NULL, NULL, NULL, NULL);
   11203 			} else {
   11204 				result = DNS_R_NOTLOADED;
   11205 			}
   11206 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11207 			if (result == ISC_R_SUCCESS && soacount > 0U) {
   11208 				zone_send_secureserial(zone, serial);
   11209 			}
   11210 		}
   11211 
   11212 		/* XXXMPA make separate call back */
   11213 		if (result == ISC_R_SUCCESS) {
   11214 			set_resigntime(zone);
   11215 			if (zone->task != NULL) {
   11216 				isc_time_t now;
   11217 				TIME_NOW(&now);
   11218 				zone_settimer(zone, &now);
   11219 			}
   11220 		}
   11221 	}
   11222 	if (secure != NULL) {
   11223 		UNLOCK_ZONE(secure);
   11224 	}
   11225 	zone_needdump(zone, DNS_DUMP_DELAY);
   11226 	UNLOCK_ZONE(zone);
   11227 }
   11228 
   11229 void
   11230 dns_zone_expire(dns_zone_t *zone) {
   11231 	REQUIRE(DNS_ZONE_VALID(zone));
   11232 
   11233 	LOCK_ZONE(zone);
   11234 	zone_expire(zone);
   11235 	UNLOCK_ZONE(zone);
   11236 }
   11237 
   11238 static void
   11239 zone_expire(dns_zone_t *zone) {
   11240 	dns_db_t *db = NULL;
   11241 
   11242 	/*
   11243 	 * 'zone' locked by caller.
   11244 	 */
   11245 
   11246 	REQUIRE(LOCKED_ZONE(zone));
   11247 
   11248 	dns_zone_log(zone, ISC_LOG_WARNING, "expired");
   11249 
   11250 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
   11251 	zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   11252 	zone->retry = DNS_ZONE_DEFAULTRETRY;
   11253 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   11254 
   11255 	/*
   11256 	 * An RPZ zone has expired; before unloading it, we must
   11257 	 * first remove it from the RPZ summary database. The
   11258 	 * easiest way to do this is "update" it with an empty
   11259 	 * database so that the update callback synchronizes
   11260 	 * the diff automatically.
   11261 	 */
   11262 	if (zone->rpzs != NULL && zone->rpz_num != DNS_RPZ_INVALID_NUM) {
   11263 		isc_result_t result;
   11264 		dns_rpz_zone_t *rpz = zone->rpzs->zones[zone->rpz_num];
   11265 
   11266 		CHECK(dns_db_create(zone->mctx, "rbt", &zone->origin,
   11267 				    dns_dbtype_zone, zone->rdclass, 0, NULL,
   11268 				    &db));
   11269 		CHECK(dns_rpz_dbupdate_callback(db, rpz));
   11270 		dns_zone_log(zone, ISC_LOG_WARNING,
   11271 			     "response-policy zone expired; "
   11272 			     "policies unloaded");
   11273 	}
   11274 
   11275 failure:
   11276 	if (db != NULL) {
   11277 		dns_db_detach(&db);
   11278 	}
   11279 
   11280 	zone_unload(zone);
   11281 }
   11282 
   11283 void
   11284 dns_zone_refresh(dns_zone_t *zone) {
   11285 	isc_interval_t i;
   11286 	uint32_t oldflags;
   11287 	unsigned int j;
   11288 	isc_result_t result;
   11289 
   11290 	REQUIRE(DNS_ZONE_VALID(zone));
   11291 
   11292 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   11293 		return;
   11294 	}
   11295 
   11296 	/*
   11297 	 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
   11298 	 * in progress at a time.
   11299 	 */
   11300 
   11301 	LOCK_ZONE(zone);
   11302 	oldflags = atomic_load(&zone->flags);
   11303 	if (zone->masterscnt == 0) {
   11304 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
   11305 		if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0) {
   11306 			dns_zone_log(zone, ISC_LOG_ERROR,
   11307 				     "cannot refresh: no primaries");
   11308 		}
   11309 		goto unlock;
   11310 	}
   11311 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   11312 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   11313 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   11314 	if ((oldflags & (DNS_ZONEFLG_REFRESH | DNS_ZONEFLG_LOADING)) != 0) {
   11315 		goto unlock;
   11316 	}
   11317 
   11318 	/*
   11319 	 * Set the next refresh time as if refresh check has failed.
   11320 	 * Setting this to the retry time will do that.  XXXMLG
   11321 	 * If we are successful it will be reset using zone->refresh.
   11322 	 */
   11323 	isc_interval_set(&i, zone->retry - isc_random_uniform(zone->retry / 4),
   11324 			 0);
   11325 	result = isc_time_nowplusinterval(&zone->refreshtime, &i);
   11326 	if (result != ISC_R_SUCCESS) {
   11327 		dns_zone_log(zone, ISC_LOG_WARNING,
   11328 			     "isc_time_nowplusinterval() failed: %s",
   11329 			     dns_result_totext(result));
   11330 	}
   11331 
   11332 	/*
   11333 	 * When lacking user-specified timer values from the SOA,
   11334 	 * do exponential backoff of the retry time up to a
   11335 	 * maximum of six hours.
   11336 	 */
   11337 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS)) {
   11338 		zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
   11339 	}
   11340 
   11341 	zone->curmaster = 0;
   11342 	for (j = 0; j < zone->masterscnt; j++) {
   11343 		zone->mastersok[j] = false;
   11344 	}
   11345 	/* initiate soa query */
   11346 	queue_soa_query(zone);
   11347 unlock:
   11348 	UNLOCK_ZONE(zone);
   11349 }
   11350 
   11351 static void
   11352 zone_journal_compact(dns_zone_t *zone, dns_db_t *db, uint32_t serial) {
   11353 	isc_result_t result;
   11354 	int32_t journalsize;
   11355 	dns_dbversion_t *ver = NULL;
   11356 	uint64_t dbsize;
   11357 
   11358 	INSIST(LOCKED_ZONE(zone));
   11359 	if (inline_raw(zone)) {
   11360 		INSIST(LOCKED_ZONE(zone->secure));
   11361 	}
   11362 
   11363 	journalsize = zone->journalsize;
   11364 	if (journalsize == -1) {
   11365 		journalsize = DNS_JOURNAL_SIZE_MAX;
   11366 		dns_db_currentversion(db, &ver);
   11367 		result = dns_db_getsize(db, ver, NULL, &dbsize);
   11368 		dns_db_closeversion(db, &ver, false);
   11369 		if (result != ISC_R_SUCCESS) {
   11370 			dns_zone_log(zone, ISC_LOG_ERROR,
   11371 				     "zone_journal_compact: "
   11372 				     "could not get zone size: %s",
   11373 				     isc_result_totext(result));
   11374 		} else if (dbsize < DNS_JOURNAL_SIZE_MAX / 2) {
   11375 			journalsize = (int32_t)dbsize * 2;
   11376 		}
   11377 	}
   11378 	zone_debuglog(zone, "zone_journal_compact", 1, "target journal size %d",
   11379 		      journalsize);
   11380 	result = dns_journal_compact(zone->mctx, zone->journal, serial,
   11381 				     journalsize);
   11382 	switch (result) {
   11383 	case ISC_R_SUCCESS:
   11384 	case ISC_R_NOSPACE:
   11385 	case ISC_R_NOTFOUND:
   11386 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "dns_journal_compact: %s",
   11387 			     dns_result_totext(result));
   11388 		break;
   11389 	default:
   11390 		dns_zone_log(zone, ISC_LOG_ERROR,
   11391 			     "dns_journal_compact failed: %s",
   11392 			     dns_result_totext(result));
   11393 		break;
   11394 	}
   11395 }
   11396 
   11397 isc_result_t
   11398 dns_zone_flush(dns_zone_t *zone) {
   11399 	isc_result_t result = ISC_R_SUCCESS;
   11400 	bool dumping;
   11401 
   11402 	REQUIRE(DNS_ZONE_VALID(zone));
   11403 
   11404 	LOCK_ZONE(zone);
   11405 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
   11406 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11407 	    zone->masterfile != NULL) {
   11408 		result = ISC_R_ALREADYRUNNING;
   11409 		dumping = was_dumping(zone);
   11410 	} else {
   11411 		dumping = true;
   11412 	}
   11413 	UNLOCK_ZONE(zone);
   11414 	if (!dumping) {
   11415 		result = zone_dump(zone, true); /* Unknown task. */
   11416 	}
   11417 	return (result);
   11418 }
   11419 
   11420 isc_result_t
   11421 dns_zone_dump(dns_zone_t *zone) {
   11422 	isc_result_t result = ISC_R_ALREADYRUNNING;
   11423 	bool dumping;
   11424 
   11425 	REQUIRE(DNS_ZONE_VALID(zone));
   11426 
   11427 	LOCK_ZONE(zone);
   11428 	dumping = was_dumping(zone);
   11429 	UNLOCK_ZONE(zone);
   11430 	if (!dumping) {
   11431 		result = zone_dump(zone, false); /* Unknown task. */
   11432 	}
   11433 	return (result);
   11434 }
   11435 
   11436 static void
   11437 zone_needdump(dns_zone_t *zone, unsigned int delay) {
   11438 	const char me[] = "zone_needdump";
   11439 	isc_time_t dumptime;
   11440 	isc_time_t now;
   11441 
   11442 	/*
   11443 	 * 'zone' locked by caller
   11444 	 */
   11445 
   11446 	REQUIRE(DNS_ZONE_VALID(zone));
   11447 	REQUIRE(LOCKED_ZONE(zone));
   11448 	ENTER;
   11449 
   11450 	/*
   11451 	 * Do we have a place to dump to and are we loaded?
   11452 	 */
   11453 	if (zone->masterfile == NULL ||
   11454 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) {
   11455 		return;
   11456 	}
   11457 
   11458 	TIME_NOW(&now);
   11459 	/* add some noise */
   11460 	DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
   11461 
   11462 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11463 	if (isc_time_isepoch(&zone->dumptime) ||
   11464 	    isc_time_compare(&zone->dumptime, &dumptime) > 0)
   11465 	{
   11466 		zone->dumptime = dumptime;
   11467 	}
   11468 	if (zone->task != NULL) {
   11469 		zone_settimer(zone, &now);
   11470 	}
   11471 }
   11472 
   11473 static void
   11474 dump_done(void *arg, isc_result_t result) {
   11475 	const char me[] = "dump_done";
   11476 	dns_zone_t *zone = arg;
   11477 	dns_zone_t *secure = NULL;
   11478 	dns_db_t *db;
   11479 	dns_dbversion_t *version;
   11480 	bool again = false;
   11481 	bool compact = false;
   11482 	uint32_t serial;
   11483 	isc_result_t tresult;
   11484 
   11485 	REQUIRE(DNS_ZONE_VALID(zone));
   11486 
   11487 	ENTER;
   11488 
   11489 	if (result == ISC_R_SUCCESS && zone->journal != NULL) {
   11490 		/*
   11491 		 * We don't own these, zone->dctx must stay valid.
   11492 		 */
   11493 		db = dns_dumpctx_db(zone->dctx);
   11494 		version = dns_dumpctx_version(zone->dctx);
   11495 		tresult = dns_db_getsoaserial(db, version, &serial);
   11496 
   11497 		/*
   11498 		 * Handle lock order inversion.
   11499 		 */
   11500 	again:
   11501 		LOCK_ZONE(zone);
   11502 		if (inline_raw(zone)) {
   11503 			secure = zone->secure;
   11504 			INSIST(secure != zone);
   11505 			TRYLOCK_ZONE(result, secure);
   11506 			if (result != ISC_R_SUCCESS) {
   11507 				UNLOCK_ZONE(zone);
   11508 				secure = NULL;
   11509 				isc_thread_yield();
   11510 				goto again;
   11511 			}
   11512 		}
   11513 
   11514 		/*
   11515 		 * If there is a secure version of this zone
   11516 		 * use its serial if it is less than ours.
   11517 		 */
   11518 		if (tresult == ISC_R_SUCCESS && secure != NULL) {
   11519 			uint32_t sserial;
   11520 			isc_result_t mresult;
   11521 
   11522 			ZONEDB_LOCK(&secure->dblock, isc_rwlocktype_read);
   11523 			if (secure->db != NULL) {
   11524 				mresult = dns_db_getsoaserial(zone->secure->db,
   11525 							      NULL, &sserial);
   11526 				if (mresult == ISC_R_SUCCESS &&
   11527 				    isc_serial_lt(sserial, serial)) {
   11528 					serial = sserial;
   11529 				}
   11530 			}
   11531 			ZONEDB_UNLOCK(&secure->dblock, isc_rwlocktype_read);
   11532 		}
   11533 		if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
   11534 			dns_db_t *zdb = NULL;
   11535 			if (dns_zone_getdb(zone, &zdb) == ISC_R_SUCCESS) {
   11536 				zone_journal_compact(zone, zdb, serial);
   11537 				dns_db_detach(&zdb);
   11538 			}
   11539 		} else if (tresult == ISC_R_SUCCESS) {
   11540 			compact = true;
   11541 			zone->compact_serial = serial;
   11542 		}
   11543 		if (secure != NULL) {
   11544 			UNLOCK_ZONE(secure);
   11545 		}
   11546 		UNLOCK_ZONE(zone);
   11547 	}
   11548 
   11549 	LOCK_ZONE(zone);
   11550 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   11551 	if (compact) {
   11552 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   11553 	}
   11554 	if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
   11555 		/*
   11556 		 * Try again in a short while.
   11557 		 */
   11558 		zone_needdump(zone, DNS_DUMP_DELAY);
   11559 	} else if (result == ISC_R_SUCCESS &&
   11560 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   11561 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11562 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11563 	{
   11564 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11565 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   11566 		isc_time_settoepoch(&zone->dumptime);
   11567 		again = true;
   11568 	} else if (result == ISC_R_SUCCESS) {
   11569 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   11570 	}
   11571 
   11572 	if (zone->dctx != NULL) {
   11573 		dns_dumpctx_detach(&zone->dctx);
   11574 	}
   11575 	zonemgr_putio(&zone->writeio);
   11576 	UNLOCK_ZONE(zone);
   11577 	if (again) {
   11578 		(void)zone_dump(zone, false);
   11579 	}
   11580 	dns_zone_idetach(&zone);
   11581 }
   11582 
   11583 static isc_result_t
   11584 zone_dump(dns_zone_t *zone, bool compact) {
   11585 	const char me[] = "zone_dump";
   11586 	isc_result_t result;
   11587 	dns_dbversion_t *version = NULL;
   11588 	bool again;
   11589 	dns_db_t *db = NULL;
   11590 	char *masterfile = NULL;
   11591 	dns_masterformat_t masterformat = dns_masterformat_none;
   11592 
   11593 	/*
   11594 	 * 'compact' MUST only be set if we are task locked.
   11595 	 */
   11596 
   11597 	REQUIRE(DNS_ZONE_VALID(zone));
   11598 	ENTER;
   11599 
   11600 redo:
   11601 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11602 	if (zone->db != NULL) {
   11603 		dns_db_attach(zone->db, &db);
   11604 	}
   11605 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11606 	LOCK_ZONE(zone);
   11607 	if (zone->masterfile != NULL) {
   11608 		masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
   11609 		masterformat = zone->masterformat;
   11610 	}
   11611 	UNLOCK_ZONE(zone);
   11612 	if (db == NULL) {
   11613 		result = DNS_R_NOTLOADED;
   11614 		goto fail;
   11615 	}
   11616 	if (masterfile == NULL) {
   11617 		result = DNS_R_NOMASTERFILE;
   11618 		goto fail;
   11619 	}
   11620 
   11621 	if (compact && zone->type != dns_zone_stub) {
   11622 		dns_zone_t *dummy = NULL;
   11623 		LOCK_ZONE(zone);
   11624 		zone_iattach(zone, &dummy);
   11625 		result = zonemgr_getio(zone->zmgr, false, zone->task,
   11626 				       zone_gotwritehandle, zone,
   11627 				       &zone->writeio);
   11628 		if (result != ISC_R_SUCCESS) {
   11629 			zone_idetach(&dummy);
   11630 		} else {
   11631 			result = DNS_R_CONTINUE;
   11632 		}
   11633 		UNLOCK_ZONE(zone);
   11634 	} else {
   11635 		const dns_master_style_t *output_style;
   11636 
   11637 		dns_masterrawheader_t rawdata;
   11638 		dns_db_currentversion(db, &version);
   11639 		dns_master_initrawheader(&rawdata);
   11640 		if (inline_secure(zone)) {
   11641 			get_raw_serial(zone->raw, &rawdata);
   11642 		}
   11643 		if (zone->type == dns_zone_key) {
   11644 			output_style = &dns_master_style_keyzone;
   11645 		} else {
   11646 			output_style = &dns_master_style_default;
   11647 		}
   11648 		result = dns_master_dump(zone->mctx, db, version, output_style,
   11649 					 masterfile, masterformat, &rawdata);
   11650 		dns_db_closeversion(db, &version, false);
   11651 	}
   11652 fail:
   11653 	if (db != NULL) {
   11654 		dns_db_detach(&db);
   11655 	}
   11656 	if (masterfile != NULL) {
   11657 		isc_mem_free(zone->mctx, masterfile);
   11658 	}
   11659 	masterfile = NULL;
   11660 
   11661 	if (result == DNS_R_CONTINUE) {
   11662 		return (ISC_R_SUCCESS); /* XXXMPA */
   11663 	}
   11664 
   11665 	again = false;
   11666 	LOCK_ZONE(zone);
   11667 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
   11668 	if (result != ISC_R_SUCCESS) {
   11669 		/*
   11670 		 * Try again in a short while.
   11671 		 */
   11672 		zone_needdump(zone, DNS_DUMP_DELAY);
   11673 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
   11674 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   11675 		   DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   11676 	{
   11677 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11678 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
   11679 		isc_time_settoepoch(&zone->dumptime);
   11680 		again = true;
   11681 	} else {
   11682 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
   11683 	}
   11684 	UNLOCK_ZONE(zone);
   11685 	if (again) {
   11686 		goto redo;
   11687 	}
   11688 
   11689 	return (result);
   11690 }
   11691 
   11692 static isc_result_t
   11693 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
   11694 	     dns_masterformat_t format, const uint32_t rawversion) {
   11695 	isc_result_t result;
   11696 	dns_dbversion_t *version = NULL;
   11697 	dns_db_t *db = NULL;
   11698 	dns_masterrawheader_t rawdata;
   11699 
   11700 	REQUIRE(DNS_ZONE_VALID(zone));
   11701 
   11702 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   11703 	if (zone->db != NULL) {
   11704 		dns_db_attach(zone->db, &db);
   11705 	}
   11706 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   11707 	if (db == NULL) {
   11708 		return (DNS_R_NOTLOADED);
   11709 	}
   11710 
   11711 	dns_db_currentversion(db, &version);
   11712 	dns_master_initrawheader(&rawdata);
   11713 	if (rawversion == 0) {
   11714 		rawdata.flags |= DNS_MASTERRAW_COMPAT;
   11715 	} else if (inline_secure(zone)) {
   11716 		get_raw_serial(zone->raw, &rawdata);
   11717 	} else if (zone->sourceserialset) {
   11718 		rawdata.flags = DNS_MASTERRAW_SOURCESERIALSET;
   11719 		rawdata.sourceserial = zone->sourceserial;
   11720 	}
   11721 	result = dns_master_dumptostream(zone->mctx, db, version, style, format,
   11722 					 &rawdata, fd);
   11723 	dns_db_closeversion(db, &version, false);
   11724 	dns_db_detach(&db);
   11725 	return (result);
   11726 }
   11727 
   11728 isc_result_t
   11729 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
   11730 		      const dns_master_style_t *style,
   11731 		      const uint32_t rawversion) {
   11732 	return (dumptostream(zone, fd, style, format, rawversion));
   11733 }
   11734 
   11735 void
   11736 dns_zone_unload(dns_zone_t *zone) {
   11737 	REQUIRE(DNS_ZONE_VALID(zone));
   11738 
   11739 	LOCK_ZONE(zone);
   11740 	zone_unload(zone);
   11741 	UNLOCK_ZONE(zone);
   11742 }
   11743 
   11744 static void
   11745 notify_cancel(dns_zone_t *zone) {
   11746 	dns_notify_t *notify;
   11747 
   11748 	/*
   11749 	 * 'zone' locked by caller.
   11750 	 */
   11751 
   11752 	REQUIRE(LOCKED_ZONE(zone));
   11753 
   11754 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   11755 	     notify = ISC_LIST_NEXT(notify, link))
   11756 	{
   11757 		if (notify->find != NULL) {
   11758 			dns_adb_cancelfind(notify->find);
   11759 		}
   11760 		if (notify->request != NULL) {
   11761 			dns_request_cancel(notify->request);
   11762 		}
   11763 	}
   11764 }
   11765 
   11766 static void
   11767 forward_cancel(dns_zone_t *zone) {
   11768 	dns_forward_t *forward;
   11769 
   11770 	/*
   11771 	 * 'zone' locked by caller.
   11772 	 */
   11773 
   11774 	REQUIRE(LOCKED_ZONE(zone));
   11775 
   11776 	for (forward = ISC_LIST_HEAD(zone->forwards); forward != NULL;
   11777 	     forward = ISC_LIST_NEXT(forward, link))
   11778 	{
   11779 		if (forward->request != NULL) {
   11780 			dns_request_cancel(forward->request);
   11781 		}
   11782 	}
   11783 }
   11784 
   11785 static void
   11786 zone_unload(dns_zone_t *zone) {
   11787 	/*
   11788 	 * 'zone' locked by caller.
   11789 	 */
   11790 
   11791 	REQUIRE(LOCKED_ZONE(zone));
   11792 
   11793 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   11794 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   11795 	{
   11796 		if (zone->writeio != NULL) {
   11797 			zonemgr_cancelio(zone->writeio);
   11798 		}
   11799 
   11800 		if (zone->dctx != NULL) {
   11801 			dns_dumpctx_cancel(zone->dctx);
   11802 		}
   11803 	}
   11804 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   11805 	zone_detachdb(zone);
   11806 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   11807 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
   11808 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
   11809 
   11810 	if (zone->type == dns_zone_mirror) {
   11811 		dns_zone_log(zone, ISC_LOG_INFO,
   11812 			     "mirror zone is no longer in use; "
   11813 			     "reverting to normal recursion");
   11814 	}
   11815 }
   11816 
   11817 void
   11818 dns_zone_setminrefreshtime(dns_zone_t *zone, uint32_t val) {
   11819 	REQUIRE(DNS_ZONE_VALID(zone));
   11820 	REQUIRE(val > 0);
   11821 
   11822 	zone->minrefresh = val;
   11823 }
   11824 
   11825 void
   11826 dns_zone_setmaxrefreshtime(dns_zone_t *zone, uint32_t val) {
   11827 	REQUIRE(DNS_ZONE_VALID(zone));
   11828 	REQUIRE(val > 0);
   11829 
   11830 	zone->maxrefresh = val;
   11831 }
   11832 
   11833 void
   11834 dns_zone_setminretrytime(dns_zone_t *zone, uint32_t val) {
   11835 	REQUIRE(DNS_ZONE_VALID(zone));
   11836 	REQUIRE(val > 0);
   11837 
   11838 	zone->minretry = val;
   11839 }
   11840 
   11841 void
   11842 dns_zone_setmaxretrytime(dns_zone_t *zone, uint32_t val) {
   11843 	REQUIRE(DNS_ZONE_VALID(zone));
   11844 	REQUIRE(val > 0);
   11845 
   11846 	zone->maxretry = val;
   11847 }
   11848 
   11849 uint32_t
   11850 dns_zone_getmaxrecords(dns_zone_t *zone) {
   11851 	REQUIRE(DNS_ZONE_VALID(zone));
   11852 
   11853 	return (zone->maxrecords);
   11854 }
   11855 
   11856 void
   11857 dns_zone_setmaxrecords(dns_zone_t *zone, uint32_t val) {
   11858 	REQUIRE(DNS_ZONE_VALID(zone));
   11859 
   11860 	zone->maxrecords = val;
   11861 }
   11862 
   11863 static bool
   11864 notify_isqueued(dns_zone_t *zone, unsigned int flags, dns_name_t *name,
   11865 		isc_sockaddr_t *addr, dns_tsigkey_t *key) {
   11866 	dns_notify_t *notify;
   11867 	dns_zonemgr_t *zmgr;
   11868 	isc_result_t result;
   11869 
   11870 	for (notify = ISC_LIST_HEAD(zone->notifies); notify != NULL;
   11871 	     notify = ISC_LIST_NEXT(notify, link))
   11872 	{
   11873 		if (notify->request != NULL) {
   11874 			continue;
   11875 		}
   11876 		if (name != NULL && dns_name_dynamic(&notify->ns) &&
   11877 		    dns_name_equal(name, &notify->ns))
   11878 		{
   11879 			goto requeue;
   11880 		}
   11881 		if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst) &&
   11882 		    notify->key == key)
   11883 		{
   11884 			goto requeue;
   11885 		}
   11886 	}
   11887 	return (false);
   11888 
   11889 requeue:
   11890 	/*
   11891 	 * If we are enqueued on the startup ratelimiter and this is
   11892 	 * not a startup notify, re-enqueue on the normal notify
   11893 	 * ratelimiter.
   11894 	 */
   11895 	if (notify->event != NULL && (flags & DNS_NOTIFY_STARTUP) == 0 &&
   11896 	    (notify->flags & DNS_NOTIFY_STARTUP) != 0)
   11897 	{
   11898 		zmgr = notify->zone->zmgr;
   11899 		result = isc_ratelimiter_dequeue(zmgr->startupnotifyrl,
   11900 						 notify->event);
   11901 		if (result != ISC_R_SUCCESS) {
   11902 			return (true);
   11903 		}
   11904 
   11905 		notify->flags &= ~DNS_NOTIFY_STARTUP;
   11906 		result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
   11907 						 notify->zone->task,
   11908 						 &notify->event);
   11909 		if (result != ISC_R_SUCCESS) {
   11910 			isc_event_free(&notify->event);
   11911 			return (false);
   11912 		}
   11913 	}
   11914 
   11915 	return (true);
   11916 }
   11917 
   11918 static bool
   11919 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
   11920 	dns_tsigkey_t *key = NULL;
   11921 	isc_sockaddr_t src;
   11922 	isc_sockaddr_t any;
   11923 	bool isself;
   11924 	isc_netaddr_t dstaddr;
   11925 	isc_result_t result;
   11926 
   11927 	if (zone->view == NULL || zone->isself == NULL) {
   11928 		return (false);
   11929 	}
   11930 
   11931 	switch (isc_sockaddr_pf(dst)) {
   11932 	case PF_INET:
   11933 		src = zone->notifysrc4;
   11934 		isc_sockaddr_any(&any);
   11935 		break;
   11936 	case PF_INET6:
   11937 		src = zone->notifysrc6;
   11938 		isc_sockaddr_any6(&any);
   11939 		break;
   11940 	default:
   11941 		return (false);
   11942 	}
   11943 
   11944 	/*
   11945 	 * When sending from any the kernel will assign a source address
   11946 	 * that matches the destination address.
   11947 	 */
   11948 	if (isc_sockaddr_eqaddr(&any, &src)) {
   11949 		src = *dst;
   11950 	}
   11951 
   11952 	isc_netaddr_fromsockaddr(&dstaddr, dst);
   11953 	result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
   11954 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   11955 		return (false);
   11956 	}
   11957 	isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
   11958 				zone->isselfarg);
   11959 	if (key != NULL) {
   11960 		dns_tsigkey_detach(&key);
   11961 	}
   11962 	return (isself);
   11963 }
   11964 
   11965 static void
   11966 notify_destroy(dns_notify_t *notify, bool locked) {
   11967 	isc_mem_t *mctx;
   11968 
   11969 	REQUIRE(DNS_NOTIFY_VALID(notify));
   11970 
   11971 	if (notify->zone != NULL) {
   11972 		if (!locked) {
   11973 			LOCK_ZONE(notify->zone);
   11974 		}
   11975 		REQUIRE(LOCKED_ZONE(notify->zone));
   11976 		if (ISC_LINK_LINKED(notify, link)) {
   11977 			ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
   11978 		}
   11979 		if (!locked) {
   11980 			UNLOCK_ZONE(notify->zone);
   11981 		}
   11982 		if (locked) {
   11983 			zone_idetach(&notify->zone);
   11984 		} else {
   11985 			dns_zone_idetach(&notify->zone);
   11986 		}
   11987 	}
   11988 	if (notify->find != NULL) {
   11989 		dns_adb_destroyfind(&notify->find);
   11990 	}
   11991 	if (notify->request != NULL) {
   11992 		dns_request_destroy(&notify->request);
   11993 	}
   11994 	if (dns_name_dynamic(&notify->ns)) {
   11995 		dns_name_free(&notify->ns, notify->mctx);
   11996 	}
   11997 	if (notify->key != NULL) {
   11998 		dns_tsigkey_detach(&notify->key);
   11999 	}
   12000 	mctx = notify->mctx;
   12001 	isc_mem_put(notify->mctx, notify, sizeof(*notify));
   12002 	isc_mem_detach(&mctx);
   12003 }
   12004 
   12005 static isc_result_t
   12006 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
   12007 	dns_notify_t *notify;
   12008 
   12009 	REQUIRE(notifyp != NULL && *notifyp == NULL);
   12010 
   12011 	notify = isc_mem_get(mctx, sizeof(*notify));
   12012 
   12013 	notify->mctx = NULL;
   12014 	isc_mem_attach(mctx, &notify->mctx);
   12015 	notify->flags = flags;
   12016 	notify->zone = NULL;
   12017 	notify->find = NULL;
   12018 	notify->request = NULL;
   12019 	notify->key = NULL;
   12020 	notify->event = NULL;
   12021 	isc_sockaddr_any(&notify->dst);
   12022 	dns_name_init(&notify->ns, NULL);
   12023 	ISC_LINK_INIT(notify, link);
   12024 	notify->magic = NOTIFY_MAGIC;
   12025 	*notifyp = notify;
   12026 	return (ISC_R_SUCCESS);
   12027 }
   12028 
   12029 /*
   12030  * XXXAG should check for DNS_ZONEFLG_EXITING
   12031  */
   12032 static void
   12033 process_adb_event(isc_task_t *task, isc_event_t *ev) {
   12034 	dns_notify_t *notify;
   12035 	isc_eventtype_t result;
   12036 
   12037 	UNUSED(task);
   12038 
   12039 	notify = ev->ev_arg;
   12040 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12041 	INSIST(task == notify->zone->task);
   12042 	result = ev->ev_type;
   12043 	isc_event_free(&ev);
   12044 	if (result == DNS_EVENT_ADBMOREADDRESSES) {
   12045 		dns_adb_destroyfind(&notify->find);
   12046 		notify_find_address(notify);
   12047 		return;
   12048 	}
   12049 	if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
   12050 		LOCK_ZONE(notify->zone);
   12051 		notify_send(notify);
   12052 		UNLOCK_ZONE(notify->zone);
   12053 	}
   12054 	notify_destroy(notify, false);
   12055 }
   12056 
   12057 static void
   12058 notify_find_address(dns_notify_t *notify) {
   12059 	isc_result_t result;
   12060 	unsigned int options;
   12061 
   12062 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12063 	options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET | DNS_ADBFIND_INET6 |
   12064 		  DNS_ADBFIND_RETURNLAME;
   12065 
   12066 	if (notify->zone->view->adb == NULL) {
   12067 		goto destroy;
   12068 	}
   12069 
   12070 	result = dns_adb_createfind(
   12071 		notify->zone->view->adb, notify->zone->task, process_adb_event,
   12072 		notify, &notify->ns, dns_rootname, 0, options, 0, NULL,
   12073 		notify->zone->view->dstport, 0, NULL, &notify->find);
   12074 
   12075 	/* Something failed? */
   12076 	if (result != ISC_R_SUCCESS) {
   12077 		goto destroy;
   12078 	}
   12079 
   12080 	/* More addresses pending? */
   12081 	if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0) {
   12082 		return;
   12083 	}
   12084 
   12085 	/* We have as many addresses as we can get. */
   12086 	LOCK_ZONE(notify->zone);
   12087 	notify_send(notify);
   12088 	UNLOCK_ZONE(notify->zone);
   12089 
   12090 destroy:
   12091 	notify_destroy(notify, false);
   12092 }
   12093 
   12094 static isc_result_t
   12095 notify_send_queue(dns_notify_t *notify, bool startup) {
   12096 	isc_event_t *e;
   12097 	isc_result_t result;
   12098 
   12099 	INSIST(notify->event == NULL);
   12100 	e = isc_event_allocate(notify->mctx, NULL, DNS_EVENT_NOTIFYSENDTOADDR,
   12101 			       notify_send_toaddr, notify, sizeof(isc_event_t));
   12102 	if (startup) {
   12103 		notify->event = e;
   12104 	}
   12105 	e->ev_arg = notify;
   12106 	e->ev_sender = NULL;
   12107 	result = isc_ratelimiter_enqueue(
   12108 		startup ? notify->zone->zmgr->startupnotifyrl
   12109 			: notify->zone->zmgr->notifyrl,
   12110 		notify->zone->task, &e);
   12111 	if (result != ISC_R_SUCCESS) {
   12112 		isc_event_free(&e);
   12113 		notify->event = NULL;
   12114 	}
   12115 	return (result);
   12116 }
   12117 
   12118 static void
   12119 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
   12120 	dns_notify_t *notify;
   12121 	isc_result_t result;
   12122 	dns_message_t *message = NULL;
   12123 	isc_netaddr_t dstip;
   12124 	dns_tsigkey_t *key = NULL;
   12125 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   12126 	isc_sockaddr_t src;
   12127 	unsigned int options, timeout;
   12128 	bool have_notifysource = false;
   12129 	bool have_notifydscp = false;
   12130 	isc_dscp_t dscp = -1;
   12131 
   12132 	notify = event->ev_arg;
   12133 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12134 
   12135 	UNUSED(task);
   12136 
   12137 	LOCK_ZONE(notify->zone);
   12138 
   12139 	notify->event = NULL;
   12140 
   12141 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
   12142 		result = ISC_R_CANCELED;
   12143 		goto cleanup;
   12144 	}
   12145 
   12146 	if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
   12147 	    DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
   12148 	    notify->zone->view->requestmgr == NULL || notify->zone->db == NULL)
   12149 	{
   12150 		result = ISC_R_CANCELED;
   12151 		goto cleanup;
   12152 	}
   12153 
   12154 	/*
   12155 	 * The raw IPv4 address should also exist.  Don't send to the
   12156 	 * mapped form.
   12157 	 */
   12158 	if (isc_sockaddr_pf(&notify->dst) == PF_INET6 &&
   12159 	    IN6_IS_ADDR_V4MAPPED(&notify->dst.type.sin6.sin6_addr))
   12160 	{
   12161 		isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12162 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12163 			   "notify: ignoring IPv6 mapped IPV4 address: %s",
   12164 			   addrbuf);
   12165 		result = ISC_R_CANCELED;
   12166 		goto cleanup;
   12167 	}
   12168 
   12169 	result = notify_createmessage(notify->zone, notify->flags, &message);
   12170 	if (result != ISC_R_SUCCESS) {
   12171 		goto cleanup;
   12172 	}
   12173 
   12174 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   12175 	if (notify->key != NULL) {
   12176 		/* Transfer ownership of key */
   12177 		key = notify->key;
   12178 		notify->key = NULL;
   12179 	} else {
   12180 		isc_netaddr_fromsockaddr(&dstip, &notify->dst);
   12181 		result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
   12182 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   12183 			notify_log(notify->zone, ISC_LOG_ERROR,
   12184 				   "NOTIFY to %s not sent. "
   12185 				   "Peer TSIG key lookup failure.",
   12186 				   addrbuf);
   12187 			goto cleanup_message;
   12188 		}
   12189 	}
   12190 
   12191 	if (key != NULL) {
   12192 		char namebuf[DNS_NAME_FORMATSIZE];
   12193 
   12194 		dns_name_format(&key->name, namebuf, sizeof(namebuf));
   12195 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12196 			   "sending notify to %s : TSIG (%s)", addrbuf,
   12197 			   namebuf);
   12198 	} else {
   12199 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   12200 			   "sending notify to %s", addrbuf);
   12201 	}
   12202 	options = 0;
   12203 	if (notify->zone->view->peers != NULL) {
   12204 		dns_peer_t *peer = NULL;
   12205 		bool usetcp = false;
   12206 		result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
   12207 						 &dstip, &peer);
   12208 		if (result == ISC_R_SUCCESS) {
   12209 			result = dns_peer_getnotifysource(peer, &src);
   12210 			if (result == ISC_R_SUCCESS) {
   12211 				have_notifysource = true;
   12212 			}
   12213 			dns_peer_getnotifydscp(peer, &dscp);
   12214 			if (dscp != -1) {
   12215 				have_notifydscp = true;
   12216 			}
   12217 			result = dns_peer_getforcetcp(peer, &usetcp);
   12218 			if (result == ISC_R_SUCCESS && usetcp) {
   12219 				options |= DNS_FETCHOPT_TCP;
   12220 			}
   12221 		}
   12222 	}
   12223 	switch (isc_sockaddr_pf(&notify->dst)) {
   12224 	case PF_INET:
   12225 		if (!have_notifysource) {
   12226 			src = notify->zone->notifysrc4;
   12227 		}
   12228 		if (!have_notifydscp) {
   12229 			dscp = notify->zone->notifysrc4dscp;
   12230 		}
   12231 		break;
   12232 	case PF_INET6:
   12233 		if (!have_notifysource) {
   12234 			src = notify->zone->notifysrc6;
   12235 		}
   12236 		if (!have_notifydscp) {
   12237 			dscp = notify->zone->notifysrc6dscp;
   12238 		}
   12239 		break;
   12240 	default:
   12241 		result = ISC_R_NOTIMPLEMENTED;
   12242 		goto cleanup_key;
   12243 	}
   12244 	timeout = 15;
   12245 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12246 		timeout = 30;
   12247 	}
   12248 	result = dns_request_createvia(
   12249 		notify->zone->view->requestmgr, message, &src, &notify->dst,
   12250 		dscp, options, key, timeout * 3, timeout, 0, notify->zone->task,
   12251 		notify_done, notify, &notify->request);
   12252 	if (result == ISC_R_SUCCESS) {
   12253 		if (isc_sockaddr_pf(&notify->dst) == AF_INET) {
   12254 			inc_stats(notify->zone,
   12255 				  dns_zonestatscounter_notifyoutv4);
   12256 		} else {
   12257 			inc_stats(notify->zone,
   12258 				  dns_zonestatscounter_notifyoutv6);
   12259 		}
   12260 	}
   12261 
   12262 cleanup_key:
   12263 	if (key != NULL) {
   12264 		dns_tsigkey_detach(&key);
   12265 	}
   12266 cleanup_message:
   12267 	dns_message_detach(&message);
   12268 cleanup:
   12269 	UNLOCK_ZONE(notify->zone);
   12270 	isc_event_free(&event);
   12271 	if (result != ISC_R_SUCCESS) {
   12272 		notify_destroy(notify, false);
   12273 	}
   12274 }
   12275 
   12276 static void
   12277 notify_send(dns_notify_t *notify) {
   12278 	dns_adbaddrinfo_t *ai;
   12279 	isc_sockaddr_t dst;
   12280 	isc_result_t result;
   12281 	dns_notify_t *newnotify = NULL;
   12282 	unsigned int flags;
   12283 	bool startup;
   12284 
   12285 	/*
   12286 	 * Zone lock held by caller.
   12287 	 */
   12288 	REQUIRE(DNS_NOTIFY_VALID(notify));
   12289 	REQUIRE(LOCKED_ZONE(notify->zone));
   12290 
   12291 	if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING)) {
   12292 		return;
   12293 	}
   12294 
   12295 	for (ai = ISC_LIST_HEAD(notify->find->list); ai != NULL;
   12296 	     ai = ISC_LIST_NEXT(ai, publink))
   12297 	{
   12298 		dst = ai->sockaddr;
   12299 		if (notify_isqueued(notify->zone, notify->flags, NULL, &dst,
   12300 				    NULL)) {
   12301 			continue;
   12302 		}
   12303 		if (notify_isself(notify->zone, &dst)) {
   12304 			continue;
   12305 		}
   12306 		newnotify = NULL;
   12307 		flags = notify->flags & DNS_NOTIFY_NOSOA;
   12308 		result = notify_create(notify->mctx, flags, &newnotify);
   12309 		if (result != ISC_R_SUCCESS) {
   12310 			goto cleanup;
   12311 		}
   12312 		zone_iattach(notify->zone, &newnotify->zone);
   12313 		ISC_LIST_APPEND(newnotify->zone->notifies, newnotify, link);
   12314 		newnotify->dst = dst;
   12315 		startup = ((notify->flags & DNS_NOTIFY_STARTUP) != 0);
   12316 		result = notify_send_queue(newnotify, startup);
   12317 		if (result != ISC_R_SUCCESS) {
   12318 			goto cleanup;
   12319 		}
   12320 		newnotify = NULL;
   12321 	}
   12322 
   12323 cleanup:
   12324 	if (newnotify != NULL) {
   12325 		notify_destroy(newnotify, true);
   12326 	}
   12327 }
   12328 
   12329 void
   12330 dns_zone_notify(dns_zone_t *zone) {
   12331 	isc_time_t now;
   12332 
   12333 	REQUIRE(DNS_ZONE_VALID(zone));
   12334 
   12335 	LOCK_ZONE(zone);
   12336 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12337 
   12338 	TIME_NOW(&now);
   12339 	zone_settimer(zone, &now);
   12340 	UNLOCK_ZONE(zone);
   12341 }
   12342 
   12343 static void
   12344 zone_notify(dns_zone_t *zone, isc_time_t *now) {
   12345 	dns_dbnode_t *node = NULL;
   12346 	dns_db_t *zonedb = NULL;
   12347 	dns_dbversion_t *version = NULL;
   12348 	dns_name_t *origin = NULL;
   12349 	dns_name_t master;
   12350 	dns_rdata_ns_t ns;
   12351 	dns_rdata_soa_t soa;
   12352 	uint32_t serial;
   12353 	dns_rdata_t rdata = DNS_RDATA_INIT;
   12354 	dns_rdataset_t nsrdset;
   12355 	dns_rdataset_t soardset;
   12356 	isc_result_t result;
   12357 	unsigned int i;
   12358 	isc_sockaddr_t dst;
   12359 	bool isqueued;
   12360 	dns_notifytype_t notifytype;
   12361 	unsigned int flags = 0;
   12362 	bool loggednotify = false;
   12363 	bool startup;
   12364 
   12365 	REQUIRE(DNS_ZONE_VALID(zone));
   12366 
   12367 	LOCK_ZONE(zone);
   12368 	startup = !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12369 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   12370 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY);
   12371 	notifytype = zone->notifytype;
   12372 	DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
   12373 	UNLOCK_ZONE(zone);
   12374 
   12375 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   12376 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
   12377 	{
   12378 		return;
   12379 	}
   12380 
   12381 	if (notifytype == dns_notifytype_no) {
   12382 		return;
   12383 	}
   12384 
   12385 	if (notifytype == dns_notifytype_masteronly &&
   12386 	    zone->type != dns_zone_master) {
   12387 		return;
   12388 	}
   12389 
   12390 	origin = &zone->origin;
   12391 
   12392 	/*
   12393 	 * If the zone is dialup we are done as we don't want to send
   12394 	 * the current soa so as to force a refresh query.
   12395 	 */
   12396 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   12397 		flags |= DNS_NOTIFY_NOSOA;
   12398 	}
   12399 
   12400 	/*
   12401 	 * Record that this was a notify due to starting up.
   12402 	 */
   12403 	if (startup) {
   12404 		flags |= DNS_NOTIFY_STARTUP;
   12405 	}
   12406 
   12407 	/*
   12408 	 * Get SOA RRset.
   12409 	 */
   12410 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   12411 	if (zone->db != NULL) {
   12412 		dns_db_attach(zone->db, &zonedb);
   12413 	}
   12414 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   12415 	if (zonedb == NULL) {
   12416 		return;
   12417 	}
   12418 	dns_db_currentversion(zonedb, &version);
   12419 	result = dns_db_findnode(zonedb, origin, false, &node);
   12420 	if (result != ISC_R_SUCCESS) {
   12421 		goto cleanup1;
   12422 	}
   12423 
   12424 	dns_rdataset_init(&soardset);
   12425 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   12426 				     dns_rdatatype_none, 0, &soardset, NULL);
   12427 	if (result != ISC_R_SUCCESS) {
   12428 		goto cleanup2;
   12429 	}
   12430 
   12431 	/*
   12432 	 * Find serial and master server's name.
   12433 	 */
   12434 	dns_name_init(&master, NULL);
   12435 	result = dns_rdataset_first(&soardset);
   12436 	if (result != ISC_R_SUCCESS) {
   12437 		goto cleanup3;
   12438 	}
   12439 	dns_rdataset_current(&soardset, &rdata);
   12440 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   12441 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12442 	dns_rdata_reset(&rdata);
   12443 	dns_name_dup(&soa.origin, zone->mctx, &master);
   12444 	serial = soa.serial;
   12445 	dns_rdataset_disassociate(&soardset);
   12446 
   12447 	/*
   12448 	 * Enqueue notify requests for 'also-notify' servers.
   12449 	 */
   12450 	LOCK_ZONE(zone);
   12451 	for (i = 0; i < zone->notifycnt; i++) {
   12452 		dns_tsigkey_t *key = NULL;
   12453 		dns_notify_t *notify = NULL;
   12454 
   12455 		if ((zone->notifykeynames != NULL) &&
   12456 		    (zone->notifykeynames[i] != NULL)) {
   12457 			dns_view_t *view = dns_zone_getview(zone);
   12458 			dns_name_t *keyname = zone->notifykeynames[i];
   12459 			(void)dns_view_gettsig(view, keyname, &key);
   12460 		}
   12461 
   12462 		dst = zone->notify[i];
   12463 		if (notify_isqueued(zone, flags, NULL, &dst, key)) {
   12464 			if (key != NULL) {
   12465 				dns_tsigkey_detach(&key);
   12466 			}
   12467 			continue;
   12468 		}
   12469 
   12470 		result = notify_create(zone->mctx, flags, &notify);
   12471 		if (result != ISC_R_SUCCESS) {
   12472 			if (key != NULL) {
   12473 				dns_tsigkey_detach(&key);
   12474 			}
   12475 			continue;
   12476 		}
   12477 
   12478 		zone_iattach(zone, &notify->zone);
   12479 		notify->dst = dst;
   12480 
   12481 		INSIST(notify->key == NULL);
   12482 
   12483 		if (key != NULL) {
   12484 			notify->key = key;
   12485 			key = NULL;
   12486 		}
   12487 
   12488 		ISC_LIST_APPEND(zone->notifies, notify, link);
   12489 		result = notify_send_queue(notify, startup);
   12490 		if (result != ISC_R_SUCCESS) {
   12491 			notify_destroy(notify, true);
   12492 		}
   12493 		if (!loggednotify) {
   12494 			notify_log(zone, ISC_LOG_INFO,
   12495 				   "sending notifies (serial %u)", serial);
   12496 			loggednotify = true;
   12497 		}
   12498 	}
   12499 	UNLOCK_ZONE(zone);
   12500 
   12501 	if (notifytype == dns_notifytype_explicit) {
   12502 		goto cleanup3;
   12503 	}
   12504 
   12505 	/*
   12506 	 * Process NS RRset to generate notifies.
   12507 	 */
   12508 
   12509 	dns_rdataset_init(&nsrdset);
   12510 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
   12511 				     dns_rdatatype_none, 0, &nsrdset, NULL);
   12512 	if (result != ISC_R_SUCCESS) {
   12513 		goto cleanup3;
   12514 	}
   12515 
   12516 	result = dns_rdataset_first(&nsrdset);
   12517 	while (result == ISC_R_SUCCESS) {
   12518 		dns_notify_t *notify = NULL;
   12519 
   12520 		dns_rdataset_current(&nsrdset, &rdata);
   12521 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   12522 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   12523 		dns_rdata_reset(&rdata);
   12524 		/*
   12525 		 * Don't notify the master server unless explicitly
   12526 		 * configured to do so.
   12527 		 */
   12528 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
   12529 		    dns_name_compare(&master, &ns.name) == 0)
   12530 		{
   12531 			result = dns_rdataset_next(&nsrdset);
   12532 			continue;
   12533 		}
   12534 
   12535 		if (!loggednotify) {
   12536 			notify_log(zone, ISC_LOG_INFO,
   12537 				   "sending notifies (serial %u)", serial);
   12538 			loggednotify = true;
   12539 		}
   12540 
   12541 		LOCK_ZONE(zone);
   12542 		isqueued = notify_isqueued(zone, flags, &ns.name, NULL, NULL);
   12543 		UNLOCK_ZONE(zone);
   12544 		if (isqueued) {
   12545 			result = dns_rdataset_next(&nsrdset);
   12546 			continue;
   12547 		}
   12548 		result = notify_create(zone->mctx, flags, &notify);
   12549 		if (result != ISC_R_SUCCESS) {
   12550 			continue;
   12551 		}
   12552 		dns_zone_iattach(zone, &notify->zone);
   12553 		dns_name_dup(&ns.name, zone->mctx, &notify->ns);
   12554 		LOCK_ZONE(zone);
   12555 		ISC_LIST_APPEND(zone->notifies, notify, link);
   12556 		UNLOCK_ZONE(zone);
   12557 		notify_find_address(notify);
   12558 		result = dns_rdataset_next(&nsrdset);
   12559 	}
   12560 	dns_rdataset_disassociate(&nsrdset);
   12561 
   12562 cleanup3:
   12563 	if (dns_name_dynamic(&master)) {
   12564 		dns_name_free(&master, zone->mctx);
   12565 	}
   12566 cleanup2:
   12567 	dns_db_detachnode(zonedb, &node);
   12568 cleanup1:
   12569 	dns_db_closeversion(zonedb, &version, false);
   12570 	dns_db_detach(&zonedb);
   12571 }
   12572 
   12573 /***
   12574  *** Private
   12575  ***/
   12576 static inline isc_result_t
   12577 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype, dns_name_t *name,
   12578 	     dns_message_t **messagep) {
   12579 	dns_message_t *message = NULL;
   12580 	dns_name_t *qname = NULL;
   12581 	dns_rdataset_t *qrdataset = NULL;
   12582 	isc_result_t result;
   12583 
   12584 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   12585 
   12586 	message->opcode = dns_opcode_query;
   12587 	message->rdclass = zone->rdclass;
   12588 
   12589 	result = dns_message_gettempname(message, &qname);
   12590 	if (result != ISC_R_SUCCESS) {
   12591 		goto cleanup;
   12592 	}
   12593 
   12594 	result = dns_message_gettemprdataset(message, &qrdataset);
   12595 	if (result != ISC_R_SUCCESS) {
   12596 		goto cleanup;
   12597 	}
   12598 
   12599 	/*
   12600 	 * Make question.
   12601 	 */
   12602 	dns_name_init(qname, NULL);
   12603 	dns_name_clone(name, qname);
   12604 	dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
   12605 	ISC_LIST_APPEND(qname->list, qrdataset, link);
   12606 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
   12607 
   12608 	*messagep = message;
   12609 	return (ISC_R_SUCCESS);
   12610 
   12611 cleanup:
   12612 	if (qname != NULL) {
   12613 		dns_message_puttempname(message, &qname);
   12614 	}
   12615 	if (qrdataset != NULL) {
   12616 		dns_message_puttemprdataset(message, &qrdataset);
   12617 	}
   12618 	dns_message_detach(&message);
   12619 	return (result);
   12620 }
   12621 
   12622 static isc_result_t
   12623 add_opt(dns_message_t *message, uint16_t udpsize, bool reqnsid,
   12624 	bool reqexpire) {
   12625 	isc_result_t result;
   12626 	dns_rdataset_t *rdataset = NULL;
   12627 	dns_ednsopt_t ednsopts[DNS_EDNSOPTIONS];
   12628 	int count = 0;
   12629 
   12630 	/* Set EDNS options if applicable. */
   12631 	if (reqnsid) {
   12632 		INSIST(count < DNS_EDNSOPTIONS);
   12633 		ednsopts[count].code = DNS_OPT_NSID;
   12634 		ednsopts[count].length = 0;
   12635 		ednsopts[count].value = NULL;
   12636 		count++;
   12637 	}
   12638 	if (reqexpire) {
   12639 		INSIST(count < DNS_EDNSOPTIONS);
   12640 		ednsopts[count].code = DNS_OPT_EXPIRE;
   12641 		ednsopts[count].length = 0;
   12642 		ednsopts[count].value = NULL;
   12643 		count++;
   12644 	}
   12645 	result = dns_message_buildopt(message, &rdataset, 0, udpsize, 0,
   12646 				      ednsopts, count);
   12647 	if (result != ISC_R_SUCCESS) {
   12648 		return (result);
   12649 	}
   12650 
   12651 	return (dns_message_setopt(message, rdataset));
   12652 }
   12653 
   12654 /*
   12655  * Called when stub zone update is finished.
   12656  * Update zone refresh, retry, expire values accordingly with
   12657  * SOA received from master, sync database to file, restart
   12658  * zone management timer.
   12659  */
   12660 static void
   12661 stub_finish_zone_update(dns_stub_t *stub, isc_time_t now) {
   12662 	uint32_t refresh, retry, expire;
   12663 	isc_result_t result;
   12664 	isc_interval_t i;
   12665 	unsigned int soacount;
   12666 	dns_zone_t *zone = stub->zone;
   12667 
   12668 	/*
   12669 	 * Tidy up.
   12670 	 */
   12671 	dns_db_closeversion(stub->db, &stub->version, true);
   12672 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   12673 	if (zone->db == NULL) {
   12674 		zone_attachdb(zone, stub->db);
   12675 	}
   12676 	result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
   12677 				  &refresh, &retry, &expire, NULL, NULL);
   12678 	if (result == ISC_R_SUCCESS && soacount > 0U) {
   12679 		zone->refresh = RANGE(refresh, zone->minrefresh,
   12680 				      zone->maxrefresh);
   12681 		zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
   12682 		zone->expire = RANGE(expire, zone->refresh + zone->retry,
   12683 				     DNS_MAX_EXPIRE);
   12684 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   12685 	}
   12686 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   12687 	dns_db_detach(&stub->db);
   12688 
   12689 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   12690 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   12691 	DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   12692 	isc_interval_set(&i, zone->expire, 0);
   12693 	DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
   12694 
   12695 	if (zone->masterfile != NULL) {
   12696 		zone_needdump(zone, 0);
   12697 	}
   12698 
   12699 	zone_settimer(zone, &now);
   12700 }
   12701 
   12702 /*
   12703  * Process answers for A and AAAA queries when
   12704  * resolving nameserver addresses for which glue
   12705  * was missing in a previous answer for a NS query.
   12706  */
   12707 static void
   12708 stub_glue_response_cb(isc_task_t *task, isc_event_t *event) {
   12709 	const char me[] = "stub_glue_response_cb";
   12710 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   12711 	dns_stub_t *stub = NULL;
   12712 	dns_message_t *msg = NULL;
   12713 	dns_zone_t *zone = NULL;
   12714 	char master[ISC_SOCKADDR_FORMATSIZE];
   12715 	char source[ISC_SOCKADDR_FORMATSIZE];
   12716 	uint32_t addr_count, cnamecnt;
   12717 	isc_result_t result;
   12718 	isc_time_t now;
   12719 	struct stub_glue_request *request;
   12720 	struct stub_cb_args *cb_args;
   12721 	dns_rdataset_t *addr_rdataset = NULL;
   12722 	dns_dbnode_t *node = NULL;
   12723 
   12724 	UNUSED(task);
   12725 
   12726 	request = revent->ev_arg;
   12727 	cb_args = request->args;
   12728 	stub = cb_args->stub;
   12729 	INSIST(DNS_STUB_VALID(stub));
   12730 
   12731 	zone = stub->zone;
   12732 
   12733 	ENTER;
   12734 
   12735 	TIME_NOW(&now);
   12736 
   12737 	LOCK_ZONE(zone);
   12738 
   12739 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   12740 		zone_debuglog(zone, me, 1, "exiting");
   12741 		goto cleanup;
   12742 	}
   12743 
   12744 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   12745 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   12746 
   12747 	if (revent->result != ISC_R_SUCCESS) {
   12748 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
   12749 					   &zone->sourceaddr, &now);
   12750 		dns_zone_log(zone, ISC_LOG_INFO,
   12751 			     "could not refresh stub from master %s"
   12752 			     " (source %s): %s",
   12753 			     master, source, dns_result_totext(revent->result));
   12754 		goto cleanup;
   12755 	}
   12756 
   12757 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   12758 	result = dns_request_getresponse(revent->request, msg, 0);
   12759 	if (result != ISC_R_SUCCESS) {
   12760 		dns_zone_log(zone, ISC_LOG_INFO,
   12761 			     "refreshing stub: unable to parse response (%s)",
   12762 			     isc_result_totext(result));
   12763 		goto cleanup;
   12764 	}
   12765 
   12766 	/*
   12767 	 * Unexpected rcode.
   12768 	 */
   12769 	if (msg->rcode != dns_rcode_noerror) {
   12770 		char rcode[128];
   12771 		isc_buffer_t rb;
   12772 
   12773 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   12774 		(void)dns_rcode_totext(msg->rcode, &rb);
   12775 
   12776 		dns_zone_log(zone, ISC_LOG_INFO,
   12777 			     "refreshing stub: "
   12778 			     "unexpected rcode (%.*s) from %s (source %s)",
   12779 			     (int)rb.used, rcode, master, source);
   12780 		goto cleanup;
   12781 	}
   12782 
   12783 	/*
   12784 	 * We need complete messages.
   12785 	 */
   12786 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   12787 		if (dns_request_usedtcp(revent->request)) {
   12788 			dns_zone_log(zone, ISC_LOG_INFO,
   12789 				     "refreshing stub: truncated TCP "
   12790 				     "response from master %s (source %s)",
   12791 				     master, source);
   12792 		}
   12793 		goto cleanup;
   12794 	}
   12795 
   12796 	/*
   12797 	 * If non-auth log.
   12798 	 */
   12799 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   12800 		dns_zone_log(zone, ISC_LOG_INFO,
   12801 			     "refreshing stub: "
   12802 			     "non-authoritative answer from "
   12803 			     "master %s (source %s)",
   12804 			     master, source);
   12805 		goto cleanup;
   12806 	}
   12807 
   12808 	/*
   12809 	 * Sanity checks.
   12810 	 */
   12811 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   12812 	addr_count = message_count(msg, DNS_SECTION_ANSWER,
   12813 				   request->ipv4 ? dns_rdatatype_a
   12814 						 : dns_rdatatype_aaaa);
   12815 
   12816 	if (cnamecnt != 0) {
   12817 		dns_zone_log(zone, ISC_LOG_INFO,
   12818 			     "refreshing stub: unexpected CNAME response "
   12819 			     "from master %s (source %s)",
   12820 			     master, source);
   12821 		goto cleanup;
   12822 	}
   12823 
   12824 	if (addr_count == 0) {
   12825 		dns_zone_log(zone, ISC_LOG_INFO,
   12826 			     "refreshing stub: no %s records in response "
   12827 			     "from master %s (source %s)",
   12828 			     request->ipv4 ? "A" : "AAAA", master, source);
   12829 		goto cleanup;
   12830 	}
   12831 	/*
   12832 	 * Extract A or AAAA RRset from message.
   12833 	 */
   12834 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &request->name,
   12835 				      request->ipv4 ? dns_rdatatype_a
   12836 						    : dns_rdatatype_aaaa,
   12837 				      dns_rdatatype_none, NULL, &addr_rdataset);
   12838 	if (result != ISC_R_SUCCESS) {
   12839 		if (result != DNS_R_NXDOMAIN && result != DNS_R_NXRRSET) {
   12840 			char namebuf[DNS_NAME_FORMATSIZE];
   12841 			dns_name_format(&request->name, namebuf,
   12842 					sizeof(namebuf));
   12843 			dns_zone_log(
   12844 				zone, ISC_LOG_INFO,
   12845 				"refreshing stub: dns_message_findname(%s/%s) "
   12846 				"failed (%s)",
   12847 				namebuf, request->ipv4 ? "A" : "AAAA",
   12848 				isc_result_totext(result));
   12849 		}
   12850 		goto cleanup;
   12851 	}
   12852 
   12853 	result = dns_db_findnode(stub->db, &request->name, true, &node);
   12854 	if (result != ISC_R_SUCCESS) {
   12855 		dns_zone_log(zone, ISC_LOG_INFO,
   12856 			     "refreshing stub: "
   12857 			     "dns_db_findnode() failed: %s",
   12858 			     dns_result_totext(result));
   12859 		goto cleanup;
   12860 	}
   12861 
   12862 	result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   12863 				    addr_rdataset, 0, NULL);
   12864 	if (result != ISC_R_SUCCESS) {
   12865 		dns_zone_log(zone, ISC_LOG_INFO,
   12866 			     "refreshing stub: "
   12867 			     "dns_db_addrdataset() failed: %s",
   12868 			     dns_result_totext(result));
   12869 	}
   12870 	dns_db_detachnode(stub->db, &node);
   12871 
   12872 cleanup:
   12873 	if (msg != NULL) {
   12874 		dns_message_detach(&msg);
   12875 	}
   12876 	isc_event_free(&event);
   12877 	dns_name_free(&request->name, zone->mctx);
   12878 	dns_request_destroy(&request->request);
   12879 	isc_mem_put(zone->mctx, request, sizeof(*request));
   12880 
   12881 	/* If last request, release all related resources */
   12882 	if (atomic_fetch_sub_release(&stub->pending_requests, 1) == 1) {
   12883 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   12884 		stub_finish_zone_update(stub, now);
   12885 		UNLOCK_ZONE(zone);
   12886 		stub->magic = 0;
   12887 		dns_zone_idetach(&stub->zone);
   12888 		INSIST(stub->db == NULL);
   12889 		INSIST(stub->version == NULL);
   12890 		isc_mem_put(stub->mctx, stub, sizeof(*stub));
   12891 	} else {
   12892 		UNLOCK_ZONE(zone);
   12893 	}
   12894 }
   12895 
   12896 /*
   12897  * Create and send an A or AAAA query to the master
   12898  * server of the stub zone given.
   12899  */
   12900 static isc_result_t
   12901 stub_request_nameserver_address(struct stub_cb_args *args, bool ipv4,
   12902 				const dns_name_t *name) {
   12903 	dns_message_t *message = NULL;
   12904 	dns_zone_t *zone;
   12905 	isc_result_t result;
   12906 	struct stub_glue_request *request;
   12907 
   12908 	zone = args->stub->zone;
   12909 	request = isc_mem_get(zone->mctx, sizeof(*request));
   12910 	request->request = NULL;
   12911 	request->args = args;
   12912 	request->name = (dns_name_t)DNS_NAME_INITEMPTY;
   12913 	request->ipv4 = ipv4;
   12914 	dns_name_dup(name, zone->mctx, &request->name);
   12915 
   12916 	result = create_query(zone, ipv4 ? dns_rdatatype_a : dns_rdatatype_aaaa,
   12917 			      &request->name, &message);
   12918 	INSIST(result == ISC_R_SUCCESS);
   12919 
   12920 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   12921 		result = add_opt(message, args->udpsize, args->reqnsid, false);
   12922 		if (result != ISC_R_SUCCESS) {
   12923 			zone_debuglog(zone, "stub_send_query", 1,
   12924 				      "unable to add opt record: %s",
   12925 				      dns_result_totext(result));
   12926 			goto fail;
   12927 		}
   12928 	}
   12929 
   12930 	atomic_fetch_add_release(&args->stub->pending_requests, 1);
   12931 
   12932 	result = dns_request_createvia(
   12933 		zone->view->requestmgr, message, &zone->sourceaddr,
   12934 		&zone->masteraddr, args->dscp, DNS_REQUESTOPT_TCP,
   12935 		args->tsig_key, args->timeout * 3, args->timeout, 0, zone->task,
   12936 		stub_glue_response_cb, request, &request->request);
   12937 
   12938 	if (result != ISC_R_SUCCESS) {
   12939 		INSIST(atomic_fetch_sub_release(&args->stub->pending_requests,
   12940 						1) > 1);
   12941 		zone_debuglog(zone, "stub_send_query", 1,
   12942 			      "dns_request_createvia() failed: %s",
   12943 			      dns_result_totext(result));
   12944 		goto fail;
   12945 	}
   12946 
   12947 	dns_message_detach(&message);
   12948 
   12949 	return (ISC_R_SUCCESS);
   12950 
   12951 fail:
   12952 	dns_name_free(&request->name, zone->mctx);
   12953 	isc_mem_put(zone->mctx, request, sizeof(*request));
   12954 
   12955 	if (message != NULL) {
   12956 		dns_message_detach(&message);
   12957 	}
   12958 
   12959 	return (result);
   12960 }
   12961 
   12962 static inline isc_result_t
   12963 save_nsrrset(dns_message_t *message, dns_name_t *name,
   12964 	     struct stub_cb_args *cb_args, dns_db_t *db,
   12965 	     dns_dbversion_t *version) {
   12966 	dns_rdataset_t *nsrdataset = NULL;
   12967 	dns_rdataset_t *rdataset = NULL;
   12968 	dns_dbnode_t *node = NULL;
   12969 	dns_rdata_ns_t ns;
   12970 	isc_result_t result;
   12971 	dns_rdata_t rdata = DNS_RDATA_INIT;
   12972 	bool has_glue = false;
   12973 	dns_name_t *ns_name;
   12974 	/*
   12975 	 * List of NS entries in answer, keep names that will be used
   12976 	 * to resolve missing A/AAAA glue for each entry.
   12977 	 */
   12978 	dns_namelist_t ns_list;
   12979 	ISC_LIST_INIT(ns_list);
   12980 
   12981 	/*
   12982 	 * Extract NS RRset from message.
   12983 	 */
   12984 	result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
   12985 				      dns_rdatatype_ns, dns_rdatatype_none,
   12986 				      NULL, &nsrdataset);
   12987 	if (result != ISC_R_SUCCESS) {
   12988 		goto done;
   12989 	}
   12990 
   12991 	/*
   12992 	 * Add NS rdataset.
   12993 	 */
   12994 	result = dns_db_findnode(db, name, true, &node);
   12995 	if (result != ISC_R_SUCCESS) {
   12996 		goto done;
   12997 	}
   12998 	result = dns_db_addrdataset(db, node, version, 0, nsrdataset, 0, NULL);
   12999 	dns_db_detachnode(db, &node);
   13000 	if (result != ISC_R_SUCCESS) {
   13001 		goto done;
   13002 	}
   13003 	/*
   13004 	 * Add glue rdatasets.
   13005 	 */
   13006 	for (result = dns_rdataset_first(nsrdataset); result == ISC_R_SUCCESS;
   13007 	     result = dns_rdataset_next(nsrdataset))
   13008 	{
   13009 		dns_rdataset_current(nsrdataset, &rdata);
   13010 		result = dns_rdata_tostruct(&rdata, &ns, NULL);
   13011 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13012 		dns_rdata_reset(&rdata);
   13013 
   13014 		if (!dns_name_issubdomain(&ns.name, name)) {
   13015 			continue;
   13016 		}
   13017 		rdataset = NULL;
   13018 		result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
   13019 					      &ns.name, dns_rdatatype_aaaa,
   13020 					      dns_rdatatype_none, NULL,
   13021 					      &rdataset);
   13022 		if (result == ISC_R_SUCCESS) {
   13023 			has_glue = true;
   13024 			result = dns_db_findnode(db, &ns.name, true, &node);
   13025 			if (result != ISC_R_SUCCESS) {
   13026 				goto done;
   13027 			}
   13028 			result = dns_db_addrdataset(db, node, version, 0,
   13029 						    rdataset, 0, NULL);
   13030 			dns_db_detachnode(db, &node);
   13031 			if (result != ISC_R_SUCCESS) {
   13032 				goto done;
   13033 			}
   13034 		}
   13035 
   13036 		rdataset = NULL;
   13037 		result = dns_message_findname(
   13038 			message, DNS_SECTION_ADDITIONAL, &ns.name,
   13039 			dns_rdatatype_a, dns_rdatatype_none, NULL, &rdataset);
   13040 		if (result == ISC_R_SUCCESS) {
   13041 			has_glue = true;
   13042 			result = dns_db_findnode(db, &ns.name, true, &node);
   13043 			if (result != ISC_R_SUCCESS) {
   13044 				goto done;
   13045 			}
   13046 			result = dns_db_addrdataset(db, node, version, 0,
   13047 						    rdataset, 0, NULL);
   13048 			dns_db_detachnode(db, &node);
   13049 			if (result != ISC_R_SUCCESS) {
   13050 				goto done;
   13051 			}
   13052 		}
   13053 
   13054 		/*
   13055 		 * If no glue is found so far, we add the name to the list to
   13056 		 * resolve the A/AAAA glue later. If any glue is found in any
   13057 		 * iteration step, this list will be discarded and only the glue
   13058 		 * provided in this message will be used.
   13059 		 */
   13060 		if (!has_glue && dns_name_issubdomain(&ns.name, name)) {
   13061 			dns_name_t *tmp_name;
   13062 			tmp_name = isc_mem_get(cb_args->stub->mctx,
   13063 					       sizeof(*tmp_name));
   13064 			dns_name_init(tmp_name, NULL);
   13065 			dns_name_dup(&ns.name, cb_args->stub->mctx, tmp_name);
   13066 			ISC_LIST_APPEND(ns_list, tmp_name, link);
   13067 		}
   13068 	}
   13069 
   13070 	if (result != ISC_R_NOMORE) {
   13071 		goto done;
   13072 	}
   13073 
   13074 	/*
   13075 	 * If no glue records were found, we attempt to resolve A/AAAA
   13076 	 * for each NS entry found in the answer.
   13077 	 */
   13078 	if (!has_glue) {
   13079 		for (ns_name = ISC_LIST_HEAD(ns_list); ns_name != NULL;
   13080 		     ns_name = ISC_LIST_NEXT(ns_name, link))
   13081 		{
   13082 			/*
   13083 			 * Resolve NS IPv4 address/A.
   13084 			 */
   13085 			result = stub_request_nameserver_address(cb_args, true,
   13086 								 ns_name);
   13087 			if (result != ISC_R_SUCCESS) {
   13088 				goto done;
   13089 			}
   13090 			/*
   13091 			 * Resolve NS IPv6 address/AAAA.
   13092 			 */
   13093 			result = stub_request_nameserver_address(cb_args, false,
   13094 								 ns_name);
   13095 			if (result != ISC_R_SUCCESS) {
   13096 				goto done;
   13097 			}
   13098 		}
   13099 	}
   13100 
   13101 	result = ISC_R_SUCCESS;
   13102 
   13103 done:
   13104 	while ((ns_name = ISC_LIST_HEAD(ns_list)) != NULL) {
   13105 		ISC_LIST_UNLINK(ns_list, ns_name, link);
   13106 		dns_name_free(ns_name, cb_args->stub->mctx);
   13107 		isc_mem_put(cb_args->stub->mctx, ns_name, sizeof(*ns_name));
   13108 	}
   13109 	return (result);
   13110 }
   13111 
   13112 static void
   13113 stub_callback(isc_task_t *task, isc_event_t *event) {
   13114 	const char me[] = "stub_callback";
   13115 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13116 	dns_stub_t *stub = NULL;
   13117 	dns_message_t *msg = NULL;
   13118 	dns_zone_t *zone = NULL;
   13119 	char master[ISC_SOCKADDR_FORMATSIZE];
   13120 	char source[ISC_SOCKADDR_FORMATSIZE];
   13121 	uint32_t nscnt, cnamecnt;
   13122 	isc_result_t result;
   13123 	isc_time_t now;
   13124 	bool exiting = false;
   13125 	unsigned int j;
   13126 	struct stub_cb_args *cb_args;
   13127 
   13128 	cb_args = revent->ev_arg;
   13129 	stub = cb_args->stub;
   13130 	INSIST(DNS_STUB_VALID(stub));
   13131 
   13132 	UNUSED(task);
   13133 
   13134 	zone = stub->zone;
   13135 
   13136 	ENTER;
   13137 
   13138 	TIME_NOW(&now);
   13139 
   13140 	LOCK_ZONE(zone);
   13141 
   13142 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13143 		zone_debuglog(zone, me, 1, "exiting");
   13144 		exiting = true;
   13145 		goto next_master;
   13146 	}
   13147 
   13148 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   13149 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13150 
   13151 	if (revent->result != ISC_R_SUCCESS) {
   13152 		if (revent->result == ISC_R_TIMEDOUT &&
   13153 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS))
   13154 		{
   13155 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13156 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13157 				     "refreshing stub: timeout retrying "
   13158 				     " without EDNS master %s (source %s)",
   13159 				     master, source);
   13160 			goto same_master;
   13161 		}
   13162 		dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
   13163 					   &zone->sourceaddr, &now);
   13164 		dns_zone_log(zone, ISC_LOG_INFO,
   13165 			     "could not refresh stub from master %s"
   13166 			     " (source %s): %s",
   13167 			     master, source, dns_result_totext(revent->result));
   13168 		goto next_master;
   13169 	}
   13170 
   13171 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13172 
   13173 	result = dns_request_getresponse(revent->request, msg, 0);
   13174 	if (result != ISC_R_SUCCESS) {
   13175 		goto next_master;
   13176 	}
   13177 
   13178 	/*
   13179 	 * Unexpected rcode.
   13180 	 */
   13181 	if (msg->rcode != dns_rcode_noerror) {
   13182 		char rcode[128];
   13183 		isc_buffer_t rb;
   13184 
   13185 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13186 		(void)dns_rcode_totext(msg->rcode, &rb);
   13187 
   13188 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13189 		    (msg->rcode == dns_rcode_servfail ||
   13190 		     msg->rcode == dns_rcode_notimp ||
   13191 		     msg->rcode == dns_rcode_formerr))
   13192 		{
   13193 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13194 				     "refreshing stub: rcode (%.*s) retrying "
   13195 				     "without EDNS master %s (source %s)",
   13196 				     (int)rb.used, rcode, master, source);
   13197 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13198 			goto same_master;
   13199 		}
   13200 
   13201 		dns_zone_log(zone, ISC_LOG_INFO,
   13202 			     "refreshing stub: "
   13203 			     "unexpected rcode (%.*s) from %s (source %s)",
   13204 			     (int)rb.used, rcode, master, source);
   13205 		goto next_master;
   13206 	}
   13207 
   13208 	/*
   13209 	 * We need complete messages.
   13210 	 */
   13211 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13212 		if (dns_request_usedtcp(revent->request)) {
   13213 			dns_zone_log(zone, ISC_LOG_INFO,
   13214 				     "refreshing stub: truncated TCP "
   13215 				     "response from master %s (source %s)",
   13216 				     master, source);
   13217 			goto next_master;
   13218 		}
   13219 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   13220 		goto same_master;
   13221 	}
   13222 
   13223 	/*
   13224 	 * If non-auth log and next master.
   13225 	 */
   13226 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13227 		dns_zone_log(zone, ISC_LOG_INFO,
   13228 			     "refreshing stub: "
   13229 			     "non-authoritative answer from "
   13230 			     "master %s (source %s)",
   13231 			     master, source);
   13232 		goto next_master;
   13233 	}
   13234 
   13235 	/*
   13236 	 * Sanity checks.
   13237 	 */
   13238 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13239 	nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
   13240 
   13241 	if (cnamecnt != 0) {
   13242 		dns_zone_log(zone, ISC_LOG_INFO,
   13243 			     "refreshing stub: unexpected CNAME response "
   13244 			     "from master %s (source %s)",
   13245 			     master, source);
   13246 		goto next_master;
   13247 	}
   13248 
   13249 	if (nscnt == 0) {
   13250 		dns_zone_log(zone, ISC_LOG_INFO,
   13251 			     "refreshing stub: no NS records in response "
   13252 			     "from master %s (source %s)",
   13253 			     master, source);
   13254 		goto next_master;
   13255 	}
   13256 
   13257 	atomic_fetch_add(&stub->pending_requests, 1);
   13258 
   13259 	/*
   13260 	 * Save answer.
   13261 	 */
   13262 	result = save_nsrrset(msg, &zone->origin, cb_args, stub->db,
   13263 			      stub->version);
   13264 	if (result != ISC_R_SUCCESS) {
   13265 		dns_zone_log(zone, ISC_LOG_INFO,
   13266 			     "refreshing stub: unable to save NS records "
   13267 			     "from master %s (source %s)",
   13268 			     master, source);
   13269 		goto next_master;
   13270 	}
   13271 
   13272 	dns_message_detach(&msg);
   13273 	isc_event_free(&event);
   13274 	dns_request_destroy(&zone->request);
   13275 
   13276 	/*
   13277 	 * Check to see if there are no outstanding requests and
   13278 	 * finish off if that is so.
   13279 	 */
   13280 	if (atomic_fetch_sub(&stub->pending_requests, 1) == 1) {
   13281 		isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13282 		stub_finish_zone_update(stub, now);
   13283 		goto free_stub;
   13284 	}
   13285 
   13286 	UNLOCK_ZONE(zone);
   13287 	return;
   13288 
   13289 next_master:
   13290 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13291 	if (stub->version != NULL) {
   13292 		dns_db_closeversion(stub->db, &stub->version, false);
   13293 	}
   13294 	if (stub->db != NULL) {
   13295 		dns_db_detach(&stub->db);
   13296 	}
   13297 	if (msg != NULL) {
   13298 		dns_message_detach(&msg);
   13299 	}
   13300 	isc_event_free(&event);
   13301 	dns_request_destroy(&zone->request);
   13302 	/*
   13303 	 * Skip to next failed / untried master.
   13304 	 */
   13305 	do {
   13306 		zone->curmaster++;
   13307 	} while (zone->curmaster < zone->masterscnt &&
   13308 		 zone->mastersok[zone->curmaster]);
   13309 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13310 	if (exiting || zone->curmaster >= zone->masterscnt) {
   13311 		bool done = true;
   13312 		if (!exiting &&
   13313 		    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   13314 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   13315 		{
   13316 			/*
   13317 			 * Did we get a good answer from all the primaries?
   13318 			 */
   13319 			for (j = 0; j < zone->masterscnt; j++) {
   13320 				if (!zone->mastersok[j]) {
   13321 					{
   13322 						done = false;
   13323 						break;
   13324 					}
   13325 				}
   13326 			}
   13327 		} else {
   13328 			done = true;
   13329 		}
   13330 		if (!done) {
   13331 			zone->curmaster = 0;
   13332 			/*
   13333 			 * Find the next failed master.
   13334 			 */
   13335 			while (zone->curmaster < zone->masterscnt &&
   13336 			       zone->mastersok[zone->curmaster]) {
   13337 				zone->curmaster++;
   13338 			}
   13339 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13340 		} else {
   13341 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13342 
   13343 			zone_settimer(zone, &now);
   13344 			goto free_stub;
   13345 		}
   13346 	}
   13347 	queue_soa_query(zone);
   13348 	goto free_stub;
   13349 
   13350 same_master:
   13351 	isc_mem_put(zone->mctx, cb_args, sizeof(*cb_args));
   13352 	if (msg != NULL) {
   13353 		dns_message_detach(&msg);
   13354 	}
   13355 	isc_event_free(&event);
   13356 	dns_request_destroy(&zone->request);
   13357 	ns_query(zone, NULL, stub);
   13358 	UNLOCK_ZONE(zone);
   13359 	goto done;
   13360 
   13361 free_stub:
   13362 	UNLOCK_ZONE(zone);
   13363 	stub->magic = 0;
   13364 	dns_zone_idetach(&stub->zone);
   13365 	INSIST(stub->db == NULL);
   13366 	INSIST(stub->version == NULL);
   13367 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   13368 
   13369 done:
   13370 	INSIST(event == NULL);
   13371 	return;
   13372 }
   13373 
   13374 /*
   13375  * Get the EDNS EXPIRE option from the response and if it exists trim
   13376  * expire to be not more than it.
   13377  */
   13378 static void
   13379 get_edns_expire(dns_zone_t *zone, dns_message_t *message, uint32_t *expirep) {
   13380 	isc_result_t result;
   13381 	uint32_t expire;
   13382 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13383 	isc_buffer_t optbuf;
   13384 	uint16_t optcode;
   13385 	uint16_t optlen;
   13386 
   13387 	REQUIRE(expirep != NULL);
   13388 	REQUIRE(message != NULL);
   13389 
   13390 	if (message->opt == NULL) {
   13391 		return;
   13392 	}
   13393 
   13394 	result = dns_rdataset_first(message->opt);
   13395 	if (result == ISC_R_SUCCESS) {
   13396 		dns_rdataset_current(message->opt, &rdata);
   13397 		isc_buffer_init(&optbuf, rdata.data, rdata.length);
   13398 		isc_buffer_add(&optbuf, rdata.length);
   13399 		while (isc_buffer_remaininglength(&optbuf) >= 4) {
   13400 			optcode = isc_buffer_getuint16(&optbuf);
   13401 			optlen = isc_buffer_getuint16(&optbuf);
   13402 			/*
   13403 			 * A EDNS EXPIRE response has a length of 4.
   13404 			 */
   13405 			if (optcode != DNS_OPT_EXPIRE || optlen != 4) {
   13406 				isc_buffer_forward(&optbuf, optlen);
   13407 				continue;
   13408 			}
   13409 			expire = isc_buffer_getuint32(&optbuf);
   13410 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13411 				     "got EDNS EXPIRE of %u", expire);
   13412 			/*
   13413 			 * Trim *expirep?
   13414 			 */
   13415 			if (expire < *expirep) {
   13416 				*expirep = expire;
   13417 			}
   13418 			break;
   13419 		}
   13420 	}
   13421 }
   13422 
   13423 /*
   13424  * Set the file modification time zone->expire seconds before expiretime.
   13425  */
   13426 static void
   13427 setmodtime(dns_zone_t *zone, isc_time_t *expiretime) {
   13428 	isc_result_t result;
   13429 	isc_time_t when;
   13430 	isc_interval_t i;
   13431 
   13432 	isc_interval_set(&i, zone->expire, 0);
   13433 	result = isc_time_subtract(expiretime, &i, &when);
   13434 	if (result != ISC_R_SUCCESS) {
   13435 		return;
   13436 	}
   13437 
   13438 	result = ISC_R_FAILURE;
   13439 	if (zone->journal != NULL) {
   13440 		result = isc_file_settime(zone->journal, &when);
   13441 	}
   13442 	if (result == ISC_R_SUCCESS &&
   13443 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   13444 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP))
   13445 	{
   13446 		result = isc_file_settime(zone->masterfile, &when);
   13447 	} else if (result != ISC_R_SUCCESS) {
   13448 		result = isc_file_settime(zone->masterfile, &when);
   13449 	}
   13450 
   13451 	/*
   13452 	 * Someone removed the file from underneath us!
   13453 	 */
   13454 	if (result == ISC_R_FILENOTFOUND) {
   13455 		zone_needdump(zone, DNS_DUMP_DELAY);
   13456 	} else if (result != ISC_R_SUCCESS) {
   13457 		dns_zone_log(zone, ISC_LOG_ERROR,
   13458 			     "refresh: could not set "
   13459 			     "file modification time of '%s': %s",
   13460 			     zone->masterfile, dns_result_totext(result));
   13461 	}
   13462 }
   13463 
   13464 /*
   13465  * An SOA query has finished (successfully or not).
   13466  */
   13467 static void
   13468 refresh_callback(isc_task_t *task, isc_event_t *event) {
   13469 	const char me[] = "refresh_callback";
   13470 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   13471 	dns_zone_t *zone;
   13472 	dns_message_t *msg = NULL;
   13473 	uint32_t soacnt, cnamecnt, soacount, nscount;
   13474 	isc_time_t now;
   13475 	char master[ISC_SOCKADDR_FORMATSIZE];
   13476 	char source[ISC_SOCKADDR_FORMATSIZE];
   13477 	dns_rdataset_t *rdataset = NULL;
   13478 	dns_rdata_t rdata = DNS_RDATA_INIT;
   13479 	dns_rdata_soa_t soa;
   13480 	isc_result_t result;
   13481 	uint32_t serial, oldserial = 0;
   13482 	unsigned int j;
   13483 	bool do_queue_xfrin = false;
   13484 
   13485 	zone = revent->ev_arg;
   13486 	INSIST(DNS_ZONE_VALID(zone));
   13487 
   13488 	UNUSED(task);
   13489 
   13490 	ENTER;
   13491 
   13492 	TIME_NOW(&now);
   13493 
   13494 	LOCK_ZONE(zone);
   13495 
   13496 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13497 		isc_event_free(&event);
   13498 		dns_request_destroy(&zone->request);
   13499 		goto detach;
   13500 	}
   13501 
   13502 	/*
   13503 	 * if timeout log and next master;
   13504 	 */
   13505 
   13506 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   13507 	isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   13508 
   13509 	if (revent->result != ISC_R_SUCCESS) {
   13510 		if (revent->result == ISC_R_TIMEDOUT &&
   13511 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS))
   13512 		{
   13513 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13514 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13515 				     "refresh: timeout retrying without EDNS "
   13516 				     "master %s (source %s)",
   13517 				     master, source);
   13518 			goto same_master;
   13519 		}
   13520 		if (revent->result == ISC_R_TIMEDOUT &&
   13521 		    !dns_request_usedtcp(revent->request)) {
   13522 			dns_zone_log(zone, ISC_LOG_INFO,
   13523 				     "refresh: retry limit for "
   13524 				     "master %s exceeded (source %s)",
   13525 				     master, source);
   13526 			/* Try with slave with TCP. */
   13527 			if ((zone->type == dns_zone_slave ||
   13528 			     zone->type == dns_zone_mirror ||
   13529 			     zone->type == dns_zone_redirect) &&
   13530 			    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH))
   13531 			{
   13532 				if (!dns_zonemgr_unreachable(
   13533 					    zone->zmgr, &zone->masteraddr,
   13534 					    &zone->sourceaddr, &now))
   13535 				{
   13536 					DNS_ZONE_SETFLAG(
   13537 						zone,
   13538 						DNS_ZONEFLG_SOABEFOREAXFR);
   13539 					goto tcp_transfer;
   13540 				}
   13541 				dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13542 					     "refresh: skipped tcp fallback "
   13543 					     "as master %s (source %s) is "
   13544 					     "unreachable (cached)",
   13545 					     master, source);
   13546 			}
   13547 		} else {
   13548 			dns_zone_log(zone, ISC_LOG_INFO,
   13549 				     "refresh: failure trying master "
   13550 				     "%s (source %s): %s",
   13551 				     master, source,
   13552 				     dns_result_totext(revent->result));
   13553 		}
   13554 		goto next_master;
   13555 	}
   13556 
   13557 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   13558 	result = dns_request_getresponse(revent->request, msg, 0);
   13559 	if (result != ISC_R_SUCCESS) {
   13560 		dns_zone_log(zone, ISC_LOG_INFO,
   13561 			     "refresh: failure trying master "
   13562 			     "%s (source %s): %s",
   13563 			     master, source, dns_result_totext(result));
   13564 		goto next_master;
   13565 	}
   13566 
   13567 	/*
   13568 	 * Unexpected rcode.
   13569 	 */
   13570 	if (msg->rcode != dns_rcode_noerror) {
   13571 		char rcode[128];
   13572 		isc_buffer_t rb;
   13573 
   13574 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   13575 		(void)dns_rcode_totext(msg->rcode, &rb);
   13576 
   13577 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13578 		    (msg->rcode == dns_rcode_servfail ||
   13579 		     msg->rcode == dns_rcode_notimp ||
   13580 		     msg->rcode == dns_rcode_formerr))
   13581 		{
   13582 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13583 				     "refresh: rcode (%.*s) retrying without "
   13584 				     "EDNS master %s (source %s)",
   13585 				     (int)rb.used, rcode, master, source);
   13586 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13587 			goto same_master;
   13588 		}
   13589 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
   13590 		    msg->rcode == dns_rcode_badvers) {
   13591 			dns_zone_log(zone, ISC_LOG_DEBUG(1),
   13592 				     "refresh: rcode (%.*s) retrying without "
   13593 				     "EDNS EXPIRE OPTION master %s (source %s)",
   13594 				     (int)rb.used, rcode, master, source);
   13595 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13596 			goto same_master;
   13597 		}
   13598 		dns_zone_log(zone, ISC_LOG_INFO,
   13599 			     "refresh: unexpected rcode (%.*s) from "
   13600 			     "master %s (source %s)",
   13601 			     (int)rb.used, rcode, master, source);
   13602 		/*
   13603 		 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
   13604 		 */
   13605 		if (msg->rcode == dns_rcode_refused &&
   13606 		    (zone->type == dns_zone_slave ||
   13607 		     zone->type == dns_zone_mirror ||
   13608 		     zone->type == dns_zone_redirect))
   13609 		{
   13610 			goto tcp_transfer;
   13611 		}
   13612 		goto next_master;
   13613 	}
   13614 
   13615 	/*
   13616 	 * If truncated punt to zone transfer which will query again.
   13617 	 */
   13618 	if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
   13619 		if (zone->type == dns_zone_slave ||
   13620 		    zone->type == dns_zone_mirror ||
   13621 		    zone->type == dns_zone_redirect)
   13622 		{
   13623 			dns_zone_log(zone, ISC_LOG_INFO,
   13624 				     "refresh: truncated UDP answer, "
   13625 				     "initiating TCP zone xfer "
   13626 				     "for master %s (source %s)",
   13627 				     master, source);
   13628 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   13629 			goto tcp_transfer;
   13630 		} else {
   13631 			INSIST(zone->type == dns_zone_stub);
   13632 			if (dns_request_usedtcp(revent->request)) {
   13633 				dns_zone_log(zone, ISC_LOG_INFO,
   13634 					     "refresh: truncated TCP response "
   13635 					     "from master %s (source %s)",
   13636 					     master, source);
   13637 				goto next_master;
   13638 			}
   13639 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
   13640 			goto same_master;
   13641 		}
   13642 	}
   13643 
   13644 	/*
   13645 	 * if non-auth log and next master;
   13646 	 */
   13647 	if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
   13648 		dns_zone_log(zone, ISC_LOG_INFO,
   13649 			     "refresh: non-authoritative answer from "
   13650 			     "master %s (source %s)",
   13651 			     master, source);
   13652 		goto next_master;
   13653 	}
   13654 
   13655 	cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
   13656 	soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
   13657 	nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
   13658 	soacount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_soa);
   13659 
   13660 	/*
   13661 	 * There should not be a CNAME record at top of zone.
   13662 	 */
   13663 	if (cnamecnt != 0) {
   13664 		dns_zone_log(zone, ISC_LOG_INFO,
   13665 			     "refresh: CNAME at top of zone "
   13666 			     "in master %s (source %s)",
   13667 			     master, source);
   13668 		goto next_master;
   13669 	}
   13670 
   13671 	/*
   13672 	 * if referral log and next master;
   13673 	 */
   13674 	if (soacnt == 0 && soacount == 0 && nscount != 0) {
   13675 		dns_zone_log(zone, ISC_LOG_INFO,
   13676 			     "refresh: referral response "
   13677 			     "from master %s (source %s)",
   13678 			     master, source);
   13679 		goto next_master;
   13680 	}
   13681 
   13682 	/*
   13683 	 * if nodata log and next master;
   13684 	 */
   13685 	if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
   13686 		dns_zone_log(zone, ISC_LOG_INFO,
   13687 			     "refresh: NODATA response "
   13688 			     "from master %s (source %s)",
   13689 			     master, source);
   13690 		goto next_master;
   13691 	}
   13692 
   13693 	/*
   13694 	 * Only one soa at top of zone.
   13695 	 */
   13696 	if (soacnt != 1) {
   13697 		dns_zone_log(zone, ISC_LOG_INFO,
   13698 			     "refresh: answer SOA count (%d) != 1 "
   13699 			     "from master %s (source %s)",
   13700 			     soacnt, master, source);
   13701 		goto next_master;
   13702 	}
   13703 
   13704 	/*
   13705 	 * Extract serial
   13706 	 */
   13707 	rdataset = NULL;
   13708 	result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
   13709 				      dns_rdatatype_soa, dns_rdatatype_none,
   13710 				      NULL, &rdataset);
   13711 	if (result != ISC_R_SUCCESS) {
   13712 		dns_zone_log(zone, ISC_LOG_INFO,
   13713 			     "refresh: unable to get SOA record "
   13714 			     "from master %s (source %s)",
   13715 			     master, source);
   13716 		goto next_master;
   13717 	}
   13718 
   13719 	result = dns_rdataset_first(rdataset);
   13720 	if (result != ISC_R_SUCCESS) {
   13721 		dns_zone_log(zone, ISC_LOG_INFO,
   13722 			     "refresh: dns_rdataset_first() failed");
   13723 		goto next_master;
   13724 	}
   13725 
   13726 	dns_rdataset_current(rdataset, &rdata);
   13727 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   13728 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13729 
   13730 	serial = soa.serial;
   13731 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
   13732 		unsigned int dbsoacount;
   13733 		result = zone_get_from_db(zone, zone->db, NULL, &dbsoacount,
   13734 					  &oldserial, NULL, NULL, NULL, NULL,
   13735 					  NULL);
   13736 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   13737 		RUNTIME_CHECK(dbsoacount > 0U);
   13738 		zone_debuglog(zone, me, 1, "serial: new %u, old %u", serial,
   13739 			      oldserial);
   13740 	} else {
   13741 		zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
   13742 			      serial);
   13743 	}
   13744 
   13745 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
   13746 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
   13747 	    isc_serial_gt(serial, oldserial))
   13748 	{
   13749 		if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   13750 					    &zone->sourceaddr, &now))
   13751 		{
   13752 			dns_zone_log(zone, ISC_LOG_INFO,
   13753 				     "refresh: skipping %s as master %s "
   13754 				     "(source %s) is unreachable (cached)",
   13755 				     (zone->type == dns_zone_slave ||
   13756 				      zone->type == dns_zone_mirror ||
   13757 				      zone->type == dns_zone_redirect)
   13758 					     ? "zone transfer"
   13759 					     : "NS query",
   13760 				     master, source);
   13761 			goto next_master;
   13762 		}
   13763 	tcp_transfer:
   13764 		isc_event_free(&event);
   13765 		dns_request_destroy(&zone->request);
   13766 		if (zone->type == dns_zone_slave ||
   13767 		    zone->type == dns_zone_mirror ||
   13768 		    zone->type == dns_zone_redirect)
   13769 		{
   13770 			do_queue_xfrin = true;
   13771 		} else {
   13772 			INSIST(zone->type == dns_zone_stub);
   13773 			ns_query(zone, rdataset, NULL);
   13774 		}
   13775 		if (msg != NULL) {
   13776 			dns_message_detach(&msg);
   13777 		}
   13778 	} else if (isc_serial_eq(soa.serial, oldserial)) {
   13779 		isc_time_t expiretime;
   13780 		uint32_t expire;
   13781 
   13782 		/*
   13783 		 * Compute the new expire time based on this response.
   13784 		 */
   13785 		expire = zone->expire;
   13786 		get_edns_expire(zone, msg, &expire);
   13787 		DNS_ZONE_TIME_ADD(&now, expire, &expiretime);
   13788 
   13789 		/*
   13790 		 * Has the expire time improved?
   13791 		 */
   13792 		if (isc_time_compare(&expiretime, &zone->expiretime) > 0) {
   13793 			zone->expiretime = expiretime;
   13794 			if (zone->masterfile != NULL) {
   13795 				setmodtime(zone, &expiretime);
   13796 			}
   13797 		}
   13798 
   13799 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   13800 		zone->mastersok[zone->curmaster] = true;
   13801 		goto next_master;
   13802 	} else {
   13803 		if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER)) {
   13804 			dns_zone_log(zone, ISC_LOG_INFO,
   13805 				     "serial number (%u) "
   13806 				     "received from master %s < ours (%u)",
   13807 				     soa.serial, master, oldserial);
   13808 		} else {
   13809 			zone_debuglog(zone, me, 1, "ahead");
   13810 		}
   13811 		zone->mastersok[zone->curmaster] = true;
   13812 		goto next_master;
   13813 	}
   13814 	if (msg != NULL) {
   13815 		dns_message_detach(&msg);
   13816 	}
   13817 	goto detach;
   13818 
   13819 next_master:
   13820 	if (msg != NULL) {
   13821 		dns_message_detach(&msg);
   13822 	}
   13823 	isc_event_free(&event);
   13824 	dns_request_destroy(&zone->request);
   13825 	/*
   13826 	 * Skip to next failed / untried master.
   13827 	 */
   13828 	do {
   13829 		zone->curmaster++;
   13830 	} while (zone->curmaster < zone->masterscnt &&
   13831 		 zone->mastersok[zone->curmaster]);
   13832 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
   13833 	if (zone->curmaster >= zone->masterscnt) {
   13834 		bool done = true;
   13835 		if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   13836 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   13837 		{
   13838 			/*
   13839 			 * Did we get a good answer from all the primaries?
   13840 			 */
   13841 			for (j = 0; j < zone->masterscnt; j++) {
   13842 				if (!zone->mastersok[j]) {
   13843 					{
   13844 						done = false;
   13845 						break;
   13846 					}
   13847 				}
   13848 			}
   13849 		} else {
   13850 			done = true;
   13851 		}
   13852 		if (!done) {
   13853 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13854 			zone->curmaster = 0;
   13855 			/*
   13856 			 * Find the next failed master.
   13857 			 */
   13858 			while (zone->curmaster < zone->masterscnt &&
   13859 			       zone->mastersok[zone->curmaster]) {
   13860 				zone->curmaster++;
   13861 			}
   13862 			goto requeue;
   13863 		}
   13864 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   13865 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   13866 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   13867 			zone->refreshtime = now;
   13868 		}
   13869 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
   13870 		zone_settimer(zone, &now);
   13871 		goto detach;
   13872 	}
   13873 
   13874 requeue:
   13875 	queue_soa_query(zone);
   13876 	goto detach;
   13877 
   13878 same_master:
   13879 	if (msg != NULL) {
   13880 		dns_message_detach(&msg);
   13881 	}
   13882 	isc_event_free(&event);
   13883 	dns_request_destroy(&zone->request);
   13884 	queue_soa_query(zone);
   13885 
   13886 detach:
   13887 	UNLOCK_ZONE(zone);
   13888 	if (do_queue_xfrin) {
   13889 		queue_xfrin(zone);
   13890 	}
   13891 	dns_zone_idetach(&zone);
   13892 	return;
   13893 }
   13894 
   13895 static void
   13896 queue_soa_query(dns_zone_t *zone) {
   13897 	const char me[] = "queue_soa_query";
   13898 	isc_event_t *e;
   13899 	dns_zone_t *dummy = NULL;
   13900 	isc_result_t result;
   13901 
   13902 	ENTER;
   13903 	/*
   13904 	 * Locked by caller
   13905 	 */
   13906 	REQUIRE(LOCKED_ZONE(zone));
   13907 
   13908 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13909 		cancel_refresh(zone);
   13910 		return;
   13911 	}
   13912 
   13913 	e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, soa_query,
   13914 			       zone, sizeof(isc_event_t));
   13915 
   13916 	/*
   13917 	 * Attach so that we won't clean up
   13918 	 * until the event is delivered.
   13919 	 */
   13920 	zone_iattach(zone, &dummy);
   13921 
   13922 	e->ev_arg = zone;
   13923 	e->ev_sender = NULL;
   13924 	result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
   13925 	if (result != ISC_R_SUCCESS) {
   13926 		zone_idetach(&dummy);
   13927 		isc_event_free(&e);
   13928 		cancel_refresh(zone);
   13929 	}
   13930 }
   13931 
   13932 static void
   13933 soa_query(isc_task_t *task, isc_event_t *event) {
   13934 	const char me[] = "soa_query";
   13935 	isc_result_t result = ISC_R_FAILURE;
   13936 	dns_message_t *message = NULL;
   13937 	dns_zone_t *zone = event->ev_arg;
   13938 	dns_zone_t *dummy = NULL;
   13939 	isc_netaddr_t masterip;
   13940 	dns_tsigkey_t *key = NULL;
   13941 	uint32_t options;
   13942 	bool cancel = true;
   13943 	int timeout;
   13944 	bool have_xfrsource, have_xfrdscp, reqnsid, reqexpire;
   13945 	uint16_t udpsize = SEND_BUFFER_SIZE;
   13946 	isc_dscp_t dscp = -1;
   13947 
   13948 	REQUIRE(DNS_ZONE_VALID(zone));
   13949 
   13950 	UNUSED(task);
   13951 
   13952 	ENTER;
   13953 
   13954 	LOCK_ZONE(zone);
   13955 	if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
   13956 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
   13957 	    zone->view->requestmgr == NULL)
   13958 	{
   13959 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   13960 			cancel = false;
   13961 		}
   13962 		goto cleanup;
   13963 	}
   13964 
   13965 again:
   13966 	result = create_query(zone, dns_rdatatype_soa, &zone->origin, &message);
   13967 	if (result != ISC_R_SUCCESS) {
   13968 		goto cleanup;
   13969 	}
   13970 
   13971 	INSIST(zone->masterscnt > 0);
   13972 	INSIST(zone->curmaster < zone->masterscnt);
   13973 
   13974 	zone->masteraddr = zone->masters[zone->curmaster];
   13975 
   13976 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   13977 	/*
   13978 	 * First, look for a tsig key in the master statement, then
   13979 	 * try for a server key.
   13980 	 */
   13981 	if ((zone->masterkeynames != NULL) &&
   13982 	    (zone->masterkeynames[zone->curmaster] != NULL))
   13983 	{
   13984 		dns_view_t *view = dns_zone_getview(zone);
   13985 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   13986 		result = dns_view_gettsig(view, keyname, &key);
   13987 		if (result != ISC_R_SUCCESS) {
   13988 			char namebuf[DNS_NAME_FORMATSIZE];
   13989 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   13990 			dns_zone_log(zone, ISC_LOG_ERROR,
   13991 				     "unable to find key: %s", namebuf);
   13992 			goto skip_master;
   13993 		}
   13994 	}
   13995 	if (key == NULL) {
   13996 		result = dns_view_getpeertsig(zone->view, &masterip, &key);
   13997 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   13998 			char addrbuf[ISC_NETADDR_FORMATSIZE];
   13999 			isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
   14000 			dns_zone_log(zone, ISC_LOG_ERROR,
   14001 				     "unable to find TSIG key for %s", addrbuf);
   14002 			goto skip_master;
   14003 		}
   14004 	}
   14005 
   14006 	options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ? DNS_REQUESTOPT_TCP
   14007 							 : 0;
   14008 	have_xfrsource = have_xfrdscp = false;
   14009 	reqnsid = zone->view->requestnsid;
   14010 	reqexpire = zone->requestexpire;
   14011 	if (zone->view->peers != NULL) {
   14012 		dns_peer_t *peer = NULL;
   14013 		bool edns, usetcp;
   14014 		result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip,
   14015 						 &peer);
   14016 		if (result == ISC_R_SUCCESS) {
   14017 			result = dns_peer_getsupportedns(peer, &edns);
   14018 			if (result == ISC_R_SUCCESS && !edns) {
   14019 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14020 			}
   14021 			result = dns_peer_gettransfersource(peer,
   14022 							    &zone->sourceaddr);
   14023 			if (result == ISC_R_SUCCESS) {
   14024 				have_xfrsource = true;
   14025 			}
   14026 			(void)dns_peer_gettransferdscp(peer, &dscp);
   14027 			if (dscp != -1) {
   14028 				have_xfrdscp = true;
   14029 			}
   14030 			if (zone->view->resolver != NULL) {
   14031 				udpsize = dns_resolver_getudpsize(
   14032 					zone->view->resolver);
   14033 			}
   14034 			(void)dns_peer_getudpsize(peer, &udpsize);
   14035 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14036 			(void)dns_peer_getrequestexpire(peer, &reqexpire);
   14037 			result = dns_peer_getforcetcp(peer, &usetcp);
   14038 			if (result == ISC_R_SUCCESS && usetcp) {
   14039 				options |= DNS_REQUESTOPT_TCP;
   14040 			}
   14041 		}
   14042 	}
   14043 
   14044 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   14045 	case PF_INET:
   14046 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14047 			if (isc_sockaddr_equal(&zone->altxfrsource4,
   14048 					       &zone->xfrsource4)) {
   14049 				goto skip_master;
   14050 			}
   14051 			zone->sourceaddr = zone->altxfrsource4;
   14052 			if (!have_xfrdscp) {
   14053 				dscp = zone->altxfrsource4dscp;
   14054 			}
   14055 		} else if (!have_xfrsource) {
   14056 			zone->sourceaddr = zone->xfrsource4;
   14057 			if (!have_xfrdscp) {
   14058 				dscp = zone->xfrsource4dscp;
   14059 			}
   14060 		}
   14061 		break;
   14062 	case PF_INET6:
   14063 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14064 			if (isc_sockaddr_equal(&zone->altxfrsource6,
   14065 					       &zone->xfrsource6)) {
   14066 				goto skip_master;
   14067 			}
   14068 			zone->sourceaddr = zone->altxfrsource6;
   14069 			if (!have_xfrdscp) {
   14070 				dscp = zone->altxfrsource6dscp;
   14071 			}
   14072 		} else if (!have_xfrsource) {
   14073 			zone->sourceaddr = zone->xfrsource6;
   14074 			if (!have_xfrdscp) {
   14075 				dscp = zone->xfrsource6dscp;
   14076 			}
   14077 		}
   14078 		break;
   14079 	default:
   14080 		result = ISC_R_NOTIMPLEMENTED;
   14081 		goto cleanup;
   14082 	}
   14083 
   14084 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14085 		result = add_opt(message, udpsize, reqnsid, reqexpire);
   14086 		if (result != ISC_R_SUCCESS) {
   14087 			zone_debuglog(zone, me, 1,
   14088 				      "unable to add opt record: %s",
   14089 				      dns_result_totext(result));
   14090 		}
   14091 	}
   14092 
   14093 	zone_iattach(zone, &dummy);
   14094 	timeout = 15;
   14095 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14096 		timeout = 30;
   14097 	}
   14098 	result = dns_request_createvia(
   14099 		zone->view->requestmgr, message, &zone->sourceaddr,
   14100 		&zone->masteraddr, dscp, options, key, timeout * 3, timeout, 0,
   14101 		zone->task, refresh_callback, zone, &zone->request);
   14102 	if (result != ISC_R_SUCCESS) {
   14103 		zone_idetach(&dummy);
   14104 		zone_debuglog(zone, me, 1,
   14105 			      "dns_request_createvia4() failed: %s",
   14106 			      dns_result_totext(result));
   14107 		goto skip_master;
   14108 	} else {
   14109 		if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET) {
   14110 			inc_stats(zone, dns_zonestatscounter_soaoutv4);
   14111 		} else {
   14112 			inc_stats(zone, dns_zonestatscounter_soaoutv6);
   14113 		}
   14114 	}
   14115 	cancel = false;
   14116 
   14117 cleanup:
   14118 	if (key != NULL) {
   14119 		dns_tsigkey_detach(&key);
   14120 	}
   14121 	if (result != ISC_R_SUCCESS) {
   14122 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14123 	}
   14124 	if (message != NULL) {
   14125 		dns_message_detach(&message);
   14126 	}
   14127 	if (cancel) {
   14128 		cancel_refresh(zone);
   14129 	}
   14130 	isc_event_free(&event);
   14131 	UNLOCK_ZONE(zone);
   14132 	dns_zone_idetach(&zone);
   14133 	return;
   14134 
   14135 skip_master:
   14136 	if (key != NULL) {
   14137 		dns_tsigkey_detach(&key);
   14138 	}
   14139 	dns_message_detach(&message);
   14140 	/*
   14141 	 * Skip to next failed / untried master.
   14142 	 */
   14143 	do {
   14144 		zone->curmaster++;
   14145 	} while (zone->curmaster < zone->masterscnt &&
   14146 		 zone->mastersok[zone->curmaster]);
   14147 	if (zone->curmaster < zone->masterscnt) {
   14148 		goto again;
   14149 	}
   14150 	zone->curmaster = 0;
   14151 	goto cleanup;
   14152 }
   14153 
   14154 static void
   14155 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
   14156 	const char me[] = "ns_query";
   14157 	isc_result_t result;
   14158 	dns_message_t *message = NULL;
   14159 	isc_netaddr_t masterip;
   14160 	dns_tsigkey_t *key = NULL;
   14161 	dns_dbnode_t *node = NULL;
   14162 	int timeout;
   14163 	bool have_xfrsource = false, have_xfrdscp = false;
   14164 	bool reqnsid;
   14165 	uint16_t udpsize = SEND_BUFFER_SIZE;
   14166 	isc_dscp_t dscp = -1;
   14167 	struct stub_cb_args *cb_args;
   14168 
   14169 	REQUIRE(DNS_ZONE_VALID(zone));
   14170 	REQUIRE(LOCKED_ZONE(zone));
   14171 	REQUIRE((soardataset != NULL && stub == NULL) ||
   14172 		(soardataset == NULL && stub != NULL));
   14173 	REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
   14174 
   14175 	ENTER;
   14176 
   14177 	if (stub == NULL) {
   14178 		stub = isc_mem_get(zone->mctx, sizeof(*stub));
   14179 		stub->magic = STUB_MAGIC;
   14180 		stub->mctx = zone->mctx;
   14181 		stub->zone = NULL;
   14182 		stub->db = NULL;
   14183 		stub->version = NULL;
   14184 		atomic_init(&stub->pending_requests, 0);
   14185 
   14186 		/*
   14187 		 * Attach so that the zone won't disappear from under us.
   14188 		 */
   14189 		zone_iattach(zone, &stub->zone);
   14190 
   14191 		/*
   14192 		 * If a db exists we will update it, otherwise we create a
   14193 		 * new one and attach it to the zone once we have the NS
   14194 		 * RRset and glue.
   14195 		 */
   14196 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14197 		if (zone->db != NULL) {
   14198 			dns_db_attach(zone->db, &stub->db);
   14199 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14200 		} else {
   14201 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14202 
   14203 			INSIST(zone->db_argc >= 1);
   14204 			result = dns_db_create(zone->mctx, zone->db_argv[0],
   14205 					       &zone->origin, dns_dbtype_stub,
   14206 					       zone->rdclass, zone->db_argc - 1,
   14207 					       zone->db_argv + 1, &stub->db);
   14208 			if (result != ISC_R_SUCCESS) {
   14209 				dns_zone_log(zone, ISC_LOG_ERROR,
   14210 					     "refreshing stub: "
   14211 					     "could not create "
   14212 					     "database: %s",
   14213 					     dns_result_totext(result));
   14214 				goto cleanup;
   14215 			}
   14216 			dns_db_settask(stub->db, zone->task);
   14217 		}
   14218 
   14219 		result = dns_db_newversion(stub->db, &stub->version);
   14220 		if (result != ISC_R_SUCCESS) {
   14221 			dns_zone_log(zone, ISC_LOG_INFO,
   14222 				     "refreshing stub: "
   14223 				     "dns_db_newversion() failed: %s",
   14224 				     dns_result_totext(result));
   14225 			goto cleanup;
   14226 		}
   14227 
   14228 		/*
   14229 		 * Update SOA record.
   14230 		 */
   14231 		result = dns_db_findnode(stub->db, &zone->origin, true, &node);
   14232 		if (result != ISC_R_SUCCESS) {
   14233 			dns_zone_log(zone, ISC_LOG_INFO,
   14234 				     "refreshing stub: "
   14235 				     "dns_db_findnode() failed: %s",
   14236 				     dns_result_totext(result));
   14237 			goto cleanup;
   14238 		}
   14239 
   14240 		result = dns_db_addrdataset(stub->db, node, stub->version, 0,
   14241 					    soardataset, 0, NULL);
   14242 		dns_db_detachnode(stub->db, &node);
   14243 		if (result != ISC_R_SUCCESS) {
   14244 			dns_zone_log(zone, ISC_LOG_INFO,
   14245 				     "refreshing stub: "
   14246 				     "dns_db_addrdataset() failed: %s",
   14247 				     dns_result_totext(result));
   14248 			goto cleanup;
   14249 		}
   14250 	}
   14251 
   14252 	/*
   14253 	 * XXX Optimisation: Create message when zone is setup and reuse.
   14254 	 */
   14255 	result = create_query(zone, dns_rdatatype_ns, &zone->origin, &message);
   14256 	INSIST(result == ISC_R_SUCCESS);
   14257 
   14258 	INSIST(zone->masterscnt > 0);
   14259 	INSIST(zone->curmaster < zone->masterscnt);
   14260 	zone->masteraddr = zone->masters[zone->curmaster];
   14261 
   14262 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   14263 	/*
   14264 	 * First, look for a tsig key in the master statement, then
   14265 	 * try for a server key.
   14266 	 */
   14267 	if ((zone->masterkeynames != NULL) &&
   14268 	    (zone->masterkeynames[zone->curmaster] != NULL))
   14269 	{
   14270 		dns_view_t *view = dns_zone_getview(zone);
   14271 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   14272 		result = dns_view_gettsig(view, keyname, &key);
   14273 		if (result != ISC_R_SUCCESS) {
   14274 			char namebuf[DNS_NAME_FORMATSIZE];
   14275 			dns_name_format(keyname, namebuf, sizeof(namebuf));
   14276 			dns_zone_log(zone, ISC_LOG_ERROR,
   14277 				     "unable to find key: %s", namebuf);
   14278 		}
   14279 	}
   14280 	if (key == NULL) {
   14281 		(void)dns_view_getpeertsig(zone->view, &masterip, &key);
   14282 	}
   14283 
   14284 	reqnsid = zone->view->requestnsid;
   14285 	if (zone->view->peers != NULL) {
   14286 		dns_peer_t *peer = NULL;
   14287 		bool edns;
   14288 		result = dns_peerlist_peerbyaddr(zone->view->peers, &masterip,
   14289 						 &peer);
   14290 		if (result == ISC_R_SUCCESS) {
   14291 			result = dns_peer_getsupportedns(peer, &edns);
   14292 			if (result == ISC_R_SUCCESS && !edns) {
   14293 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
   14294 			}
   14295 			result = dns_peer_gettransfersource(peer,
   14296 							    &zone->sourceaddr);
   14297 			if (result == ISC_R_SUCCESS) {
   14298 				have_xfrsource = true;
   14299 			}
   14300 			result = dns_peer_gettransferdscp(peer, &dscp);
   14301 			if (result == ISC_R_SUCCESS && dscp != -1) {
   14302 				have_xfrdscp = true;
   14303 			}
   14304 			if (zone->view->resolver != NULL) {
   14305 				udpsize = dns_resolver_getudpsize(
   14306 					zone->view->resolver);
   14307 			}
   14308 			(void)dns_peer_getudpsize(peer, &udpsize);
   14309 			(void)dns_peer_getrequestnsid(peer, &reqnsid);
   14310 		}
   14311 	}
   14312 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
   14313 		result = add_opt(message, udpsize, reqnsid, false);
   14314 		if (result != ISC_R_SUCCESS) {
   14315 			zone_debuglog(zone, me, 1,
   14316 				      "unable to add opt record: %s",
   14317 				      dns_result_totext(result));
   14318 		}
   14319 	}
   14320 
   14321 	/*
   14322 	 * Always use TCP so that we shouldn't truncate in additional section.
   14323 	 */
   14324 	switch (isc_sockaddr_pf(&zone->masteraddr)) {
   14325 	case PF_INET:
   14326 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14327 			zone->sourceaddr = zone->altxfrsource4;
   14328 			if (!have_xfrdscp) {
   14329 				dscp = zone->altxfrsource4dscp;
   14330 			}
   14331 		} else if (!have_xfrsource) {
   14332 			zone->sourceaddr = zone->xfrsource4;
   14333 			if (!have_xfrdscp) {
   14334 				dscp = zone->xfrsource4dscp;
   14335 			}
   14336 		}
   14337 		break;
   14338 	case PF_INET6:
   14339 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
   14340 			zone->sourceaddr = zone->altxfrsource6;
   14341 			if (!have_xfrdscp) {
   14342 				dscp = zone->altxfrsource6dscp;
   14343 			}
   14344 		} else if (!have_xfrsource) {
   14345 			zone->sourceaddr = zone->xfrsource6;
   14346 			if (!have_xfrdscp) {
   14347 				dscp = zone->xfrsource6dscp;
   14348 			}
   14349 		}
   14350 		break;
   14351 	default:
   14352 		result = ISC_R_NOTIMPLEMENTED;
   14353 		POST(result);
   14354 		goto cleanup;
   14355 	}
   14356 	timeout = 15;
   14357 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH)) {
   14358 		timeout = 30;
   14359 	}
   14360 
   14361 	/* Save request parameters so we can reuse them later on
   14362 	   for resolving missing glue A/AAAA records. */
   14363 	cb_args = isc_mem_get(zone->mctx, sizeof(*cb_args));
   14364 	cb_args->stub = stub;
   14365 	cb_args->tsig_key = key;
   14366 	cb_args->dscp = dscp;
   14367 	cb_args->udpsize = udpsize;
   14368 	cb_args->timeout = timeout;
   14369 	cb_args->reqnsid = reqnsid;
   14370 
   14371 	result = dns_request_createvia(
   14372 		zone->view->requestmgr, message, &zone->sourceaddr,
   14373 		&zone->masteraddr, dscp, DNS_REQUESTOPT_TCP, key, timeout * 3,
   14374 		timeout, 0, zone->task, stub_callback, cb_args, &zone->request);
   14375 	if (result != ISC_R_SUCCESS) {
   14376 		zone_debuglog(zone, me, 1, "dns_request_createvia() failed: %s",
   14377 			      dns_result_totext(result));
   14378 		goto cleanup;
   14379 	}
   14380 	dns_message_detach(&message);
   14381 	goto unlock;
   14382 
   14383 cleanup:
   14384 	cancel_refresh(zone);
   14385 	stub->magic = 0;
   14386 	if (stub->version != NULL) {
   14387 		dns_db_closeversion(stub->db, &stub->version, false);
   14388 	}
   14389 	if (stub->db != NULL) {
   14390 		dns_db_detach(&stub->db);
   14391 	}
   14392 	if (stub->zone != NULL) {
   14393 		zone_idetach(&stub->zone);
   14394 	}
   14395 	isc_mem_put(stub->mctx, stub, sizeof(*stub));
   14396 	if (message != NULL) {
   14397 		dns_message_detach(&message);
   14398 	}
   14399 unlock:
   14400 	if (key != NULL) {
   14401 		dns_tsigkey_detach(&key);
   14402 	}
   14403 	return;
   14404 }
   14405 
   14406 /*
   14407  * Handle the control event.  Note that although this event causes the zone
   14408  * to shut down, it is not a shutdown event in the sense of the task library.
   14409  */
   14410 static void
   14411 zone_shutdown(isc_task_t *task, isc_event_t *event) {
   14412 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   14413 	bool free_needed, linked = false;
   14414 	dns_zone_t *raw = NULL, *secure = NULL;
   14415 
   14416 	UNUSED(task);
   14417 	REQUIRE(DNS_ZONE_VALID(zone));
   14418 	INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
   14419 	INSIST(isc_refcount_current(&zone->erefs) == 0);
   14420 
   14421 	zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
   14422 
   14423 	/*
   14424 	 * Stop things being restarted after we cancel them below.
   14425 	 */
   14426 	LOCK_ZONE(zone);
   14427 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
   14428 	UNLOCK_ZONE(zone);
   14429 
   14430 	/*
   14431 	 * If we were waiting for xfrin quota, step out of
   14432 	 * the queue.
   14433 	 * If there's no zone manager, we can't be waiting for the
   14434 	 * xfrin quota
   14435 	 */
   14436 	if (zone->zmgr != NULL) {
   14437 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   14438 		if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
   14439 			ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
   14440 					statelink);
   14441 			linked = true;
   14442 			zone->statelist = NULL;
   14443 		}
   14444 		if (zone->statelist == &zone->zmgr->xfrin_in_progress) {
   14445 			ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone,
   14446 					statelink);
   14447 			zone->statelist = NULL;
   14448 			zmgr_resume_xfrs(zone->zmgr, false);
   14449 		}
   14450 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   14451 	}
   14452 
   14453 	/*
   14454 	 * In task context, no locking required.  See zone_xfrdone().
   14455 	 */
   14456 	if (zone->xfr != NULL) {
   14457 		dns_xfrin_shutdown(zone->xfr);
   14458 	}
   14459 
   14460 	/* Safe to release the zone now */
   14461 	if (zone->zmgr != NULL) {
   14462 		dns_zonemgr_releasezone(zone->zmgr, zone);
   14463 	}
   14464 
   14465 	LOCK_ZONE(zone);
   14466 	INSIST(zone != zone->raw);
   14467 	if (linked) {
   14468 		isc_refcount_decrement(&zone->irefs);
   14469 	}
   14470 	if (zone->request != NULL) {
   14471 		dns_request_cancel(zone->request);
   14472 	}
   14473 
   14474 	if (zone->readio != NULL) {
   14475 		zonemgr_cancelio(zone->readio);
   14476 	}
   14477 
   14478 	if (zone->lctx != NULL) {
   14479 		dns_loadctx_cancel(zone->lctx);
   14480 	}
   14481 
   14482 	if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
   14483 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14484 	{
   14485 		if (zone->writeio != NULL) {
   14486 			zonemgr_cancelio(zone->writeio);
   14487 		}
   14488 
   14489 		if (zone->dctx != NULL) {
   14490 			dns_dumpctx_cancel(zone->dctx);
   14491 		}
   14492 	}
   14493 
   14494 	notify_cancel(zone);
   14495 
   14496 	forward_cancel(zone);
   14497 
   14498 	if (zone->timer != NULL) {
   14499 		isc_timer_detach(&zone->timer);
   14500 		isc_refcount_decrement(&zone->irefs);
   14501 	}
   14502 
   14503 	/*
   14504 	 * We have now canceled everything set the flag to allow exit_check()
   14505 	 * to succeed.	We must not unlock between setting this flag and
   14506 	 * calling exit_check().
   14507 	 */
   14508 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
   14509 	free_needed = exit_check(zone);
   14510 	if (inline_secure(zone)) {
   14511 		raw = zone->raw;
   14512 		zone->raw = NULL;
   14513 	}
   14514 	if (inline_raw(zone)) {
   14515 		secure = zone->secure;
   14516 		zone->secure = NULL;
   14517 	}
   14518 	UNLOCK_ZONE(zone);
   14519 	if (raw != NULL) {
   14520 		dns_zone_detach(&raw);
   14521 	}
   14522 	if (secure != NULL) {
   14523 		dns_zone_idetach(&secure);
   14524 	}
   14525 	if (free_needed) {
   14526 		zone_free(zone);
   14527 	}
   14528 }
   14529 
   14530 static void
   14531 zone_timer(isc_task_t *task, isc_event_t *event) {
   14532 	const char me[] = "zone_timer";
   14533 	dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
   14534 
   14535 	UNUSED(task);
   14536 	REQUIRE(DNS_ZONE_VALID(zone));
   14537 
   14538 	ENTER;
   14539 
   14540 	zone_maintenance(zone);
   14541 
   14542 	isc_event_free(&event);
   14543 }
   14544 
   14545 static void
   14546 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
   14547 	const char me[] = "zone_settimer";
   14548 	isc_time_t next;
   14549 	isc_result_t result;
   14550 
   14551 	REQUIRE(DNS_ZONE_VALID(zone));
   14552 	REQUIRE(LOCKED_ZONE(zone));
   14553 	ENTER;
   14554 
   14555 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   14556 		return;
   14557 	}
   14558 
   14559 	isc_time_settoepoch(&next);
   14560 
   14561 	switch (zone->type) {
   14562 	case dns_zone_redirect:
   14563 		if (zone->masters != NULL) {
   14564 			goto treat_as_slave;
   14565 		}
   14566 		/* FALLTHROUGH */
   14567 
   14568 	case dns_zone_master:
   14569 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   14570 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   14571 		{
   14572 			next = zone->notifytime;
   14573 		}
   14574 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   14575 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14576 		{
   14577 			INSIST(!isc_time_isepoch(&zone->dumptime));
   14578 			if (isc_time_isepoch(&next) ||
   14579 			    isc_time_compare(&zone->dumptime, &next) < 0) {
   14580 				next = zone->dumptime;
   14581 			}
   14582 		}
   14583 		if (zone->type == dns_zone_redirect) {
   14584 			break;
   14585 		}
   14586 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
   14587 		    !isc_time_isepoch(&zone->refreshkeytime))
   14588 		{
   14589 			if (isc_time_isepoch(&next) ||
   14590 			    isc_time_compare(&zone->refreshkeytime, &next) < 0)
   14591 			{
   14592 				next = zone->refreshkeytime;
   14593 			}
   14594 		}
   14595 		if (!isc_time_isepoch(&zone->resigntime)) {
   14596 			if (isc_time_isepoch(&next) ||
   14597 			    isc_time_compare(&zone->resigntime, &next) < 0) {
   14598 				next = zone->resigntime;
   14599 			}
   14600 		}
   14601 		if (!isc_time_isepoch(&zone->keywarntime)) {
   14602 			if (isc_time_isepoch(&next) ||
   14603 			    isc_time_compare(&zone->keywarntime, &next) < 0) {
   14604 				next = zone->keywarntime;
   14605 			}
   14606 		}
   14607 		if (!isc_time_isepoch(&zone->signingtime)) {
   14608 			if (isc_time_isepoch(&next) ||
   14609 			    isc_time_compare(&zone->signingtime, &next) < 0) {
   14610 				next = zone->signingtime;
   14611 			}
   14612 		}
   14613 		if (!isc_time_isepoch(&zone->nsec3chaintime)) {
   14614 			if (isc_time_isepoch(&next) ||
   14615 			    isc_time_compare(&zone->nsec3chaintime, &next) < 0)
   14616 			{
   14617 				next = zone->nsec3chaintime;
   14618 			}
   14619 		}
   14620 		break;
   14621 
   14622 	case dns_zone_slave:
   14623 	case dns_zone_mirror:
   14624 	treat_as_slave:
   14625 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) ||
   14626 		    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDSTARTUPNOTIFY))
   14627 		{
   14628 			next = zone->notifytime;
   14629 		}
   14630 		/* FALLTHROUGH */
   14631 
   14632 	case dns_zone_stub:
   14633 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
   14634 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
   14635 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
   14636 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING) &&
   14637 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADPENDING) &&
   14638 		    !isc_time_isepoch(&zone->refreshtime) &&
   14639 		    (isc_time_isepoch(&next) ||
   14640 		     isc_time_compare(&zone->refreshtime, &next) < 0))
   14641 		{
   14642 			next = zone->refreshtime;
   14643 		}
   14644 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   14645 		    !isc_time_isepoch(&zone->expiretime))
   14646 		{
   14647 			if (isc_time_isepoch(&next) ||
   14648 			    isc_time_compare(&zone->expiretime, &next) < 0) {
   14649 				next = zone->expiretime;
   14650 			}
   14651 		}
   14652 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   14653 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14654 		{
   14655 			INSIST(!isc_time_isepoch(&zone->dumptime));
   14656 			if (isc_time_isepoch(&next) ||
   14657 			    isc_time_compare(&zone->dumptime, &next) < 0) {
   14658 				next = zone->dumptime;
   14659 			}
   14660 		}
   14661 		break;
   14662 
   14663 	case dns_zone_key:
   14664 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
   14665 		    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING))
   14666 		{
   14667 			INSIST(!isc_time_isepoch(&zone->dumptime));
   14668 			if (isc_time_isepoch(&next) ||
   14669 			    isc_time_compare(&zone->dumptime, &next) < 0) {
   14670 				next = zone->dumptime;
   14671 			}
   14672 		}
   14673 		if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
   14674 			if (isc_time_isepoch(&next) ||
   14675 			    (!isc_time_isepoch(&zone->refreshkeytime) &&
   14676 			     isc_time_compare(&zone->refreshkeytime, &next) <
   14677 				     0))
   14678 			{
   14679 				next = zone->refreshkeytime;
   14680 			}
   14681 		}
   14682 		break;
   14683 
   14684 	default:
   14685 		break;
   14686 	}
   14687 
   14688 	if (isc_time_isepoch(&next)) {
   14689 		zone_debuglog(zone, me, 10, "settimer inactive");
   14690 		result = isc_timer_reset(zone->timer, isc_timertype_inactive,
   14691 					 NULL, NULL, true);
   14692 		if (result != ISC_R_SUCCESS) {
   14693 			dns_zone_log(zone, ISC_LOG_ERROR,
   14694 				     "could not deactivate zone timer: %s",
   14695 				     isc_result_totext(result));
   14696 		}
   14697 	} else {
   14698 		if (isc_time_compare(&next, now) <= 0) {
   14699 			next = *now;
   14700 		}
   14701 		result = isc_timer_reset(zone->timer, isc_timertype_once, &next,
   14702 					 NULL, true);
   14703 		if (result != ISC_R_SUCCESS) {
   14704 			dns_zone_log(zone, ISC_LOG_ERROR,
   14705 				     "could not reset zone timer: %s",
   14706 				     isc_result_totext(result));
   14707 		}
   14708 	}
   14709 }
   14710 
   14711 static void
   14712 cancel_refresh(dns_zone_t *zone) {
   14713 	const char me[] = "cancel_refresh";
   14714 	isc_time_t now;
   14715 
   14716 	/*
   14717 	 * 'zone' locked by caller.
   14718 	 */
   14719 
   14720 	REQUIRE(DNS_ZONE_VALID(zone));
   14721 	REQUIRE(LOCKED_ZONE(zone));
   14722 
   14723 	ENTER;
   14724 
   14725 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   14726 	TIME_NOW(&now);
   14727 	zone_settimer(zone, &now);
   14728 }
   14729 
   14730 static isc_result_t
   14731 notify_createmessage(dns_zone_t *zone, unsigned int flags,
   14732 		     dns_message_t **messagep) {
   14733 	dns_db_t *zonedb = NULL;
   14734 	dns_dbnode_t *node = NULL;
   14735 	dns_dbversion_t *version = NULL;
   14736 	dns_message_t *message = NULL;
   14737 	dns_rdataset_t rdataset;
   14738 	dns_rdata_t rdata = DNS_RDATA_INIT;
   14739 
   14740 	dns_name_t *tempname = NULL;
   14741 	dns_rdata_t *temprdata = NULL;
   14742 	dns_rdatalist_t *temprdatalist = NULL;
   14743 	dns_rdataset_t *temprdataset = NULL;
   14744 
   14745 	isc_result_t result;
   14746 	isc_region_t r;
   14747 	isc_buffer_t *b = NULL;
   14748 
   14749 	REQUIRE(DNS_ZONE_VALID(zone));
   14750 	REQUIRE(messagep != NULL && *messagep == NULL);
   14751 
   14752 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER, &message);
   14753 
   14754 	message->opcode = dns_opcode_notify;
   14755 	message->flags |= DNS_MESSAGEFLAG_AA;
   14756 	message->rdclass = zone->rdclass;
   14757 
   14758 	result = dns_message_gettempname(message, &tempname);
   14759 	if (result != ISC_R_SUCCESS) {
   14760 		goto cleanup;
   14761 	}
   14762 
   14763 	result = dns_message_gettemprdataset(message, &temprdataset);
   14764 	if (result != ISC_R_SUCCESS) {
   14765 		goto cleanup;
   14766 	}
   14767 
   14768 	/*
   14769 	 * Make question.
   14770 	 */
   14771 	dns_name_init(tempname, NULL);
   14772 	dns_name_clone(&zone->origin, tempname);
   14773 	dns_rdataset_makequestion(temprdataset, zone->rdclass,
   14774 				  dns_rdatatype_soa);
   14775 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   14776 	dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
   14777 	tempname = NULL;
   14778 	temprdataset = NULL;
   14779 
   14780 	if ((flags & DNS_NOTIFY_NOSOA) != 0) {
   14781 		goto done;
   14782 	}
   14783 
   14784 	result = dns_message_gettempname(message, &tempname);
   14785 	if (result != ISC_R_SUCCESS) {
   14786 		goto soa_cleanup;
   14787 	}
   14788 	result = dns_message_gettemprdata(message, &temprdata);
   14789 	if (result != ISC_R_SUCCESS) {
   14790 		goto soa_cleanup;
   14791 	}
   14792 	result = dns_message_gettemprdataset(message, &temprdataset);
   14793 	if (result != ISC_R_SUCCESS) {
   14794 		goto soa_cleanup;
   14795 	}
   14796 	result = dns_message_gettemprdatalist(message, &temprdatalist);
   14797 	if (result != ISC_R_SUCCESS) {
   14798 		goto soa_cleanup;
   14799 	}
   14800 
   14801 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   14802 	INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
   14803 	dns_db_attach(zone->db, &zonedb);
   14804 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   14805 
   14806 	dns_name_init(tempname, NULL);
   14807 	dns_name_clone(&zone->origin, tempname);
   14808 	dns_db_currentversion(zonedb, &version);
   14809 	result = dns_db_findnode(zonedb, tempname, false, &node);
   14810 	if (result != ISC_R_SUCCESS) {
   14811 		goto soa_cleanup;
   14812 	}
   14813 
   14814 	dns_rdataset_init(&rdataset);
   14815 	result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
   14816 				     dns_rdatatype_none, 0, &rdataset, NULL);
   14817 	if (result != ISC_R_SUCCESS) {
   14818 		goto soa_cleanup;
   14819 	}
   14820 	result = dns_rdataset_first(&rdataset);
   14821 	if (result != ISC_R_SUCCESS) {
   14822 		goto soa_cleanup;
   14823 	}
   14824 	dns_rdataset_current(&rdataset, &rdata);
   14825 	dns_rdata_toregion(&rdata, &r);
   14826 	isc_buffer_allocate(zone->mctx, &b, r.length);
   14827 	isc_buffer_putmem(b, r.base, r.length);
   14828 	isc_buffer_usedregion(b, &r);
   14829 	dns_rdata_init(temprdata);
   14830 	dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
   14831 	dns_message_takebuffer(message, &b);
   14832 	result = dns_rdataset_next(&rdataset);
   14833 	dns_rdataset_disassociate(&rdataset);
   14834 	if (result != ISC_R_NOMORE) {
   14835 		goto soa_cleanup;
   14836 	}
   14837 	temprdatalist->rdclass = rdata.rdclass;
   14838 	temprdatalist->type = rdata.type;
   14839 	temprdatalist->ttl = rdataset.ttl;
   14840 	ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
   14841 
   14842 	result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
   14843 	if (result != ISC_R_SUCCESS) {
   14844 		goto soa_cleanup;
   14845 	}
   14846 
   14847 	ISC_LIST_APPEND(tempname->list, temprdataset, link);
   14848 	dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
   14849 	temprdatalist = NULL;
   14850 	temprdataset = NULL;
   14851 	temprdata = NULL;
   14852 	tempname = NULL;
   14853 
   14854 soa_cleanup:
   14855 	if (node != NULL) {
   14856 		dns_db_detachnode(zonedb, &node);
   14857 	}
   14858 	if (version != NULL) {
   14859 		dns_db_closeversion(zonedb, &version, false);
   14860 	}
   14861 	if (zonedb != NULL) {
   14862 		dns_db_detach(&zonedb);
   14863 	}
   14864 	if (tempname != NULL) {
   14865 		dns_message_puttempname(message, &tempname);
   14866 	}
   14867 	if (temprdata != NULL) {
   14868 		dns_message_puttemprdata(message, &temprdata);
   14869 	}
   14870 	if (temprdataset != NULL) {
   14871 		dns_message_puttemprdataset(message, &temprdataset);
   14872 	}
   14873 	if (temprdatalist != NULL) {
   14874 		dns_message_puttemprdatalist(message, &temprdatalist);
   14875 	}
   14876 
   14877 done:
   14878 	*messagep = message;
   14879 	return (ISC_R_SUCCESS);
   14880 
   14881 cleanup:
   14882 	if (tempname != NULL) {
   14883 		dns_message_puttempname(message, &tempname);
   14884 	}
   14885 	if (temprdataset != NULL) {
   14886 		dns_message_puttemprdataset(message, &temprdataset);
   14887 	}
   14888 	dns_message_detach(&message);
   14889 	return (result);
   14890 }
   14891 
   14892 isc_result_t
   14893 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
   14894 		       isc_sockaddr_t *to, dns_message_t *msg) {
   14895 	unsigned int i;
   14896 	dns_rdata_soa_t soa;
   14897 	dns_rdataset_t *rdataset = NULL;
   14898 	dns_rdata_t rdata = DNS_RDATA_INIT;
   14899 	isc_result_t result;
   14900 	char fromtext[ISC_SOCKADDR_FORMATSIZE];
   14901 	int match = 0;
   14902 	isc_netaddr_t netaddr;
   14903 	uint32_t serial = 0;
   14904 	bool have_serial = false;
   14905 	dns_tsigkey_t *tsigkey;
   14906 	const dns_name_t *tsig;
   14907 
   14908 	REQUIRE(DNS_ZONE_VALID(zone));
   14909 
   14910 	/*
   14911 	 * If type != T_SOA return DNS_R_NOTIMP.  We don't yet support
   14912 	 * ROLLOVER.
   14913 	 *
   14914 	 * SOA:	RFC1996
   14915 	 * Check that 'from' is a valid notify source, (zone->masters).
   14916 	 *	Return DNS_R_REFUSED if not.
   14917 	 *
   14918 	 * If the notify message contains a serial number check it
   14919 	 * against the zones serial and return if <= current serial
   14920 	 *
   14921 	 * If a refresh check is progress, if so just record the
   14922 	 * fact we received a NOTIFY and from where and return.
   14923 	 * We will perform a new refresh check when the current one
   14924 	 * completes. Return ISC_R_SUCCESS.
   14925 	 *
   14926 	 * Otherwise initiate a refresh check using 'from' as the
   14927 	 * first address to check.  Return ISC_R_SUCCESS.
   14928 	 */
   14929 
   14930 	isc_sockaddr_format(from, fromtext, sizeof(fromtext));
   14931 
   14932 	/*
   14933 	 * Notify messages are processed by the raw zone.
   14934 	 */
   14935 	LOCK_ZONE(zone);
   14936 	INSIST(zone != zone->raw);
   14937 	if (inline_secure(zone)) {
   14938 		result = dns_zone_notifyreceive(zone->raw, from, to, msg);
   14939 		UNLOCK_ZONE(zone);
   14940 		return (result);
   14941 	}
   14942 	/*
   14943 	 *  We only handle NOTIFY (SOA) at the present.
   14944 	 */
   14945 	if (isc_sockaddr_pf(from) == PF_INET) {
   14946 		inc_stats(zone, dns_zonestatscounter_notifyinv4);
   14947 	} else {
   14948 		inc_stats(zone, dns_zonestatscounter_notifyinv6);
   14949 	}
   14950 	if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
   14951 	    dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
   14952 				 dns_rdatatype_soa, dns_rdatatype_none, NULL,
   14953 				 NULL) != ISC_R_SUCCESS)
   14954 	{
   14955 		UNLOCK_ZONE(zone);
   14956 		if (msg->counts[DNS_SECTION_QUESTION] == 0) {
   14957 			dns_zone_log(zone, ISC_LOG_NOTICE,
   14958 				     "NOTIFY with no "
   14959 				     "question section from: %s",
   14960 				     fromtext);
   14961 			return (DNS_R_FORMERR);
   14962 		}
   14963 		dns_zone_log(zone, ISC_LOG_NOTICE,
   14964 			     "NOTIFY zone does not match");
   14965 		return (DNS_R_NOTIMP);
   14966 	}
   14967 
   14968 	/*
   14969 	 * If we are a master zone just succeed.
   14970 	 */
   14971 	if (zone->type == dns_zone_master) {
   14972 		UNLOCK_ZONE(zone);
   14973 		return (ISC_R_SUCCESS);
   14974 	}
   14975 
   14976 	isc_netaddr_fromsockaddr(&netaddr, from);
   14977 	for (i = 0; i < zone->masterscnt; i++) {
   14978 		if (isc_sockaddr_eqaddr(from, &zone->masters[i])) {
   14979 			break;
   14980 		}
   14981 		if (zone->view->aclenv.match_mapped &&
   14982 		    IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
   14983 		    isc_sockaddr_pf(&zone->masters[i]) == AF_INET)
   14984 		{
   14985 			isc_netaddr_t na1, na2;
   14986 			isc_netaddr_fromv4mapped(&na1, &netaddr);
   14987 			isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
   14988 			if (isc_netaddr_equal(&na1, &na2)) {
   14989 				break;
   14990 			}
   14991 		}
   14992 	}
   14993 
   14994 	/*
   14995 	 * Accept notify requests from non masters if they are on
   14996 	 * 'zone->notify_acl'.
   14997 	 */
   14998 	tsigkey = dns_message_gettsigkey(msg);
   14999 	tsig = dns_tsigkey_identity(tsigkey);
   15000 	if (i >= zone->masterscnt && zone->notify_acl != NULL &&
   15001 	    (dns_acl_match(&netaddr, tsig, zone->notify_acl,
   15002 			   &zone->view->aclenv, &match,
   15003 			   NULL) == ISC_R_SUCCESS) &&
   15004 	    match > 0)
   15005 	{
   15006 		/* Accept notify. */
   15007 	} else if (i >= zone->masterscnt) {
   15008 		UNLOCK_ZONE(zone);
   15009 		dns_zone_log(zone, ISC_LOG_INFO,
   15010 			     "refused notify from non-master: %s", fromtext);
   15011 		inc_stats(zone, dns_zonestatscounter_notifyrej);
   15012 		return (DNS_R_REFUSED);
   15013 	}
   15014 
   15015 	/*
   15016 	 * If the zone is loaded and there are answers check the serial
   15017 	 * to see if we need to do a refresh.  Do not worry about this
   15018 	 * check if we are a dialup zone as we use the notify request
   15019 	 * to trigger a refresh check.
   15020 	 */
   15021 	if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
   15022 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
   15023 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH))
   15024 	{
   15025 		result = dns_message_findname(
   15026 			msg, DNS_SECTION_ANSWER, &zone->origin,
   15027 			dns_rdatatype_soa, dns_rdatatype_none, NULL, &rdataset);
   15028 		if (result == ISC_R_SUCCESS) {
   15029 			result = dns_rdataset_first(rdataset);
   15030 		}
   15031 		if (result == ISC_R_SUCCESS) {
   15032 			uint32_t oldserial;
   15033 			unsigned int soacount;
   15034 
   15035 			dns_rdataset_current(rdataset, &rdata);
   15036 			result = dns_rdata_tostruct(&rdata, &soa, NULL);
   15037 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15038 			serial = soa.serial;
   15039 			have_serial = true;
   15040 			/*
   15041 			 * The following should safely be performed without DB
   15042 			 * lock and succeed in this context.
   15043 			 */
   15044 			result = zone_get_from_db(zone, zone->db, NULL,
   15045 						  &soacount, &oldserial, NULL,
   15046 						  NULL, NULL, NULL, NULL);
   15047 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15048 			RUNTIME_CHECK(soacount > 0U);
   15049 			if (isc_serial_le(serial, oldserial)) {
   15050 				dns_zone_log(zone, ISC_LOG_INFO,
   15051 					     "notify from %s: "
   15052 					     "zone is up to date",
   15053 					     fromtext);
   15054 				UNLOCK_ZONE(zone);
   15055 				return (ISC_R_SUCCESS);
   15056 			}
   15057 		}
   15058 	}
   15059 
   15060 	/*
   15061 	 * If we got this far and there was a refresh in progress just
   15062 	 * let it complete.  Record where we got the notify from so we
   15063 	 * can perform a refresh check when the current one completes
   15064 	 */
   15065 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   15066 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   15067 		zone->notifyfrom = *from;
   15068 		UNLOCK_ZONE(zone);
   15069 		if (have_serial) {
   15070 			dns_zone_log(zone, ISC_LOG_INFO,
   15071 				     "notify from %s: serial %u: refresh in "
   15072 				     "progress, refresh check queued",
   15073 				     fromtext, serial);
   15074 		} else {
   15075 			dns_zone_log(zone, ISC_LOG_INFO,
   15076 				     "notify from %s: refresh in progress, "
   15077 				     "refresh check queued",
   15078 				     fromtext);
   15079 		}
   15080 		return (ISC_R_SUCCESS);
   15081 	}
   15082 	if (have_serial) {
   15083 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: serial %u",
   15084 			     fromtext, serial);
   15085 	} else {
   15086 		dns_zone_log(zone, ISC_LOG_INFO, "notify from %s: no serial",
   15087 			     fromtext);
   15088 	}
   15089 	zone->notifyfrom = *from;
   15090 	UNLOCK_ZONE(zone);
   15091 
   15092 	if (to != NULL) {
   15093 		dns_zonemgr_unreachabledel(zone->zmgr, from, to);
   15094 	}
   15095 	dns_zone_refresh(zone);
   15096 	return (ISC_R_SUCCESS);
   15097 }
   15098 
   15099 void
   15100 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
   15101 	REQUIRE(DNS_ZONE_VALID(zone));
   15102 
   15103 	LOCK_ZONE(zone);
   15104 	if (zone->notify_acl != NULL) {
   15105 		dns_acl_detach(&zone->notify_acl);
   15106 	}
   15107 	dns_acl_attach(acl, &zone->notify_acl);
   15108 	UNLOCK_ZONE(zone);
   15109 }
   15110 
   15111 void
   15112 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
   15113 	REQUIRE(DNS_ZONE_VALID(zone));
   15114 
   15115 	LOCK_ZONE(zone);
   15116 	if (zone->query_acl != NULL) {
   15117 		dns_acl_detach(&zone->query_acl);
   15118 	}
   15119 	dns_acl_attach(acl, &zone->query_acl);
   15120 	UNLOCK_ZONE(zone);
   15121 }
   15122 
   15123 void
   15124 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
   15125 	REQUIRE(DNS_ZONE_VALID(zone));
   15126 
   15127 	LOCK_ZONE(zone);
   15128 	if (zone->queryon_acl != NULL) {
   15129 		dns_acl_detach(&zone->queryon_acl);
   15130 	}
   15131 	dns_acl_attach(acl, &zone->queryon_acl);
   15132 	UNLOCK_ZONE(zone);
   15133 }
   15134 
   15135 void
   15136 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
   15137 	REQUIRE(DNS_ZONE_VALID(zone));
   15138 
   15139 	LOCK_ZONE(zone);
   15140 	if (zone->update_acl != NULL) {
   15141 		dns_acl_detach(&zone->update_acl);
   15142 	}
   15143 	dns_acl_attach(acl, &zone->update_acl);
   15144 	UNLOCK_ZONE(zone);
   15145 }
   15146 
   15147 void
   15148 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
   15149 	REQUIRE(DNS_ZONE_VALID(zone));
   15150 
   15151 	LOCK_ZONE(zone);
   15152 	if (zone->forward_acl != NULL) {
   15153 		dns_acl_detach(&zone->forward_acl);
   15154 	}
   15155 	dns_acl_attach(acl, &zone->forward_acl);
   15156 	UNLOCK_ZONE(zone);
   15157 }
   15158 
   15159 void
   15160 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
   15161 	REQUIRE(DNS_ZONE_VALID(zone));
   15162 
   15163 	LOCK_ZONE(zone);
   15164 	if (zone->xfr_acl != NULL) {
   15165 		dns_acl_detach(&zone->xfr_acl);
   15166 	}
   15167 	dns_acl_attach(acl, &zone->xfr_acl);
   15168 	UNLOCK_ZONE(zone);
   15169 }
   15170 
   15171 dns_acl_t *
   15172 dns_zone_getnotifyacl(dns_zone_t *zone) {
   15173 	REQUIRE(DNS_ZONE_VALID(zone));
   15174 
   15175 	return (zone->notify_acl);
   15176 }
   15177 
   15178 dns_acl_t *
   15179 dns_zone_getqueryacl(dns_zone_t *zone) {
   15180 	REQUIRE(DNS_ZONE_VALID(zone));
   15181 
   15182 	return (zone->query_acl);
   15183 }
   15184 
   15185 dns_acl_t *
   15186 dns_zone_getqueryonacl(dns_zone_t *zone) {
   15187 	REQUIRE(DNS_ZONE_VALID(zone));
   15188 
   15189 	return (zone->queryon_acl);
   15190 }
   15191 
   15192 dns_acl_t *
   15193 dns_zone_getupdateacl(dns_zone_t *zone) {
   15194 	REQUIRE(DNS_ZONE_VALID(zone));
   15195 
   15196 	return (zone->update_acl);
   15197 }
   15198 
   15199 dns_acl_t *
   15200 dns_zone_getforwardacl(dns_zone_t *zone) {
   15201 	REQUIRE(DNS_ZONE_VALID(zone));
   15202 
   15203 	return (zone->forward_acl);
   15204 }
   15205 
   15206 dns_acl_t *
   15207 dns_zone_getxfracl(dns_zone_t *zone) {
   15208 	REQUIRE(DNS_ZONE_VALID(zone));
   15209 
   15210 	return (zone->xfr_acl);
   15211 }
   15212 
   15213 void
   15214 dns_zone_clearupdateacl(dns_zone_t *zone) {
   15215 	REQUIRE(DNS_ZONE_VALID(zone));
   15216 
   15217 	LOCK_ZONE(zone);
   15218 	if (zone->update_acl != NULL) {
   15219 		dns_acl_detach(&zone->update_acl);
   15220 	}
   15221 	UNLOCK_ZONE(zone);
   15222 }
   15223 
   15224 void
   15225 dns_zone_clearforwardacl(dns_zone_t *zone) {
   15226 	REQUIRE(DNS_ZONE_VALID(zone));
   15227 
   15228 	LOCK_ZONE(zone);
   15229 	if (zone->forward_acl != NULL) {
   15230 		dns_acl_detach(&zone->forward_acl);
   15231 	}
   15232 	UNLOCK_ZONE(zone);
   15233 }
   15234 
   15235 void
   15236 dns_zone_clearnotifyacl(dns_zone_t *zone) {
   15237 	REQUIRE(DNS_ZONE_VALID(zone));
   15238 
   15239 	LOCK_ZONE(zone);
   15240 	if (zone->notify_acl != NULL) {
   15241 		dns_acl_detach(&zone->notify_acl);
   15242 	}
   15243 	UNLOCK_ZONE(zone);
   15244 }
   15245 
   15246 void
   15247 dns_zone_clearqueryacl(dns_zone_t *zone) {
   15248 	REQUIRE(DNS_ZONE_VALID(zone));
   15249 
   15250 	LOCK_ZONE(zone);
   15251 	if (zone->query_acl != NULL) {
   15252 		dns_acl_detach(&zone->query_acl);
   15253 	}
   15254 	UNLOCK_ZONE(zone);
   15255 }
   15256 
   15257 void
   15258 dns_zone_clearqueryonacl(dns_zone_t *zone) {
   15259 	REQUIRE(DNS_ZONE_VALID(zone));
   15260 
   15261 	LOCK_ZONE(zone);
   15262 	if (zone->queryon_acl != NULL) {
   15263 		dns_acl_detach(&zone->queryon_acl);
   15264 	}
   15265 	UNLOCK_ZONE(zone);
   15266 }
   15267 
   15268 void
   15269 dns_zone_clearxfracl(dns_zone_t *zone) {
   15270 	REQUIRE(DNS_ZONE_VALID(zone));
   15271 
   15272 	LOCK_ZONE(zone);
   15273 	if (zone->xfr_acl != NULL) {
   15274 		dns_acl_detach(&zone->xfr_acl);
   15275 	}
   15276 	UNLOCK_ZONE(zone);
   15277 }
   15278 
   15279 bool
   15280 dns_zone_getupdatedisabled(dns_zone_t *zone) {
   15281 	REQUIRE(DNS_ZONE_VALID(zone));
   15282 	return (zone->update_disabled);
   15283 }
   15284 
   15285 void
   15286 dns_zone_setupdatedisabled(dns_zone_t *zone, bool state) {
   15287 	REQUIRE(DNS_ZONE_VALID(zone));
   15288 	zone->update_disabled = state;
   15289 }
   15290 
   15291 bool
   15292 dns_zone_getzeronosoattl(dns_zone_t *zone) {
   15293 	REQUIRE(DNS_ZONE_VALID(zone));
   15294 	return (zone->zero_no_soa_ttl);
   15295 }
   15296 
   15297 void
   15298 dns_zone_setzeronosoattl(dns_zone_t *zone, bool state) {
   15299 	REQUIRE(DNS_ZONE_VALID(zone));
   15300 	zone->zero_no_soa_ttl = state;
   15301 }
   15302 
   15303 void
   15304 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
   15305 	REQUIRE(DNS_ZONE_VALID(zone));
   15306 
   15307 	zone->check_names = severity;
   15308 }
   15309 
   15310 dns_severity_t
   15311 dns_zone_getchecknames(dns_zone_t *zone) {
   15312 	REQUIRE(DNS_ZONE_VALID(zone));
   15313 
   15314 	return (zone->check_names);
   15315 }
   15316 
   15317 void
   15318 dns_zone_setjournalsize(dns_zone_t *zone, int32_t size) {
   15319 	REQUIRE(DNS_ZONE_VALID(zone));
   15320 
   15321 	zone->journalsize = size;
   15322 }
   15323 
   15324 int32_t
   15325 dns_zone_getjournalsize(dns_zone_t *zone) {
   15326 	REQUIRE(DNS_ZONE_VALID(zone));
   15327 
   15328 	return (zone->journalsize);
   15329 }
   15330 
   15331 static void
   15332 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15333 	isc_result_t result = ISC_R_FAILURE;
   15334 	isc_buffer_t buffer;
   15335 
   15336 	REQUIRE(buf != NULL);
   15337 	REQUIRE(length > 1U);
   15338 
   15339 	/*
   15340 	 * Leave space for terminating '\0'.
   15341 	 */
   15342 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15343 	if (zone->type != dns_zone_redirect && zone->type != dns_zone_key) {
   15344 		if (dns_name_dynamic(&zone->origin)) {
   15345 			result = dns_name_totext(&zone->origin, true, &buffer);
   15346 		}
   15347 		if (result != ISC_R_SUCCESS &&
   15348 		    isc_buffer_availablelength(&buffer) >=
   15349 			    (sizeof("<UNKNOWN>") - 1))
   15350 		{
   15351 			isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15352 		}
   15353 
   15354 		if (isc_buffer_availablelength(&buffer) > 0) {
   15355 			isc_buffer_putstr(&buffer, "/");
   15356 		}
   15357 		(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   15358 	}
   15359 
   15360 	if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
   15361 	    strcmp(zone->view->name, "_default") != 0 &&
   15362 	    strlen(zone->view->name) < isc_buffer_availablelength(&buffer))
   15363 	{
   15364 		isc_buffer_putstr(&buffer, "/");
   15365 		isc_buffer_putstr(&buffer, zone->view->name);
   15366 	}
   15367 	if (inline_secure(zone) && 9U < isc_buffer_availablelength(&buffer)) {
   15368 		isc_buffer_putstr(&buffer, " (signed)");
   15369 	}
   15370 	if (inline_raw(zone) && 11U < isc_buffer_availablelength(&buffer)) {
   15371 		isc_buffer_putstr(&buffer, " (unsigned)");
   15372 	}
   15373 
   15374 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15375 }
   15376 
   15377 static void
   15378 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15379 	isc_result_t result = ISC_R_FAILURE;
   15380 	isc_buffer_t buffer;
   15381 
   15382 	REQUIRE(buf != NULL);
   15383 	REQUIRE(length > 1U);
   15384 
   15385 	/*
   15386 	 * Leave space for terminating '\0'.
   15387 	 */
   15388 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15389 	if (dns_name_dynamic(&zone->origin)) {
   15390 		result = dns_name_totext(&zone->origin, true, &buffer);
   15391 	}
   15392 	if (result != ISC_R_SUCCESS &&
   15393 	    isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
   15394 	{
   15395 		isc_buffer_putstr(&buffer, "<UNKNOWN>");
   15396 	}
   15397 
   15398 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15399 }
   15400 
   15401 static void
   15402 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15403 	isc_buffer_t buffer;
   15404 
   15405 	REQUIRE(buf != NULL);
   15406 	REQUIRE(length > 1U);
   15407 
   15408 	/*
   15409 	 * Leave space for terminating '\0'.
   15410 	 */
   15411 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15412 	(void)dns_rdataclass_totext(zone->rdclass, &buffer);
   15413 
   15414 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15415 }
   15416 
   15417 static void
   15418 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
   15419 	isc_buffer_t buffer;
   15420 
   15421 	REQUIRE(buf != NULL);
   15422 	REQUIRE(length > 1U);
   15423 
   15424 	/*
   15425 	 * Leave space for terminating '\0'.
   15426 	 */
   15427 	isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
   15428 
   15429 	if (zone->view == NULL) {
   15430 		isc_buffer_putstr(&buffer, "_none");
   15431 	} else if (strlen(zone->view->name) <
   15432 		   isc_buffer_availablelength(&buffer)) {
   15433 		isc_buffer_putstr(&buffer, zone->view->name);
   15434 	} else {
   15435 		isc_buffer_putstr(&buffer, "_toolong");
   15436 	}
   15437 
   15438 	buf[isc_buffer_usedlength(&buffer)] = '\0';
   15439 }
   15440 
   15441 void
   15442 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
   15443 	REQUIRE(DNS_ZONE_VALID(zone));
   15444 	REQUIRE(buf != NULL);
   15445 
   15446 	LOCK_ZONE(zone);
   15447 	zone_namerd_tostr(zone, buf, length);
   15448 	UNLOCK_ZONE(zone);
   15449 }
   15450 
   15451 void
   15452 dns_zone_nameonly(dns_zone_t *zone, char *buf, size_t length) {
   15453 	REQUIRE(DNS_ZONE_VALID(zone));
   15454 	REQUIRE(buf != NULL);
   15455 	zone_name_tostr(zone, buf, length);
   15456 }
   15457 
   15458 void
   15459 dns_zone_logv(dns_zone_t *zone, isc_logcategory_t *category, int level,
   15460 	      const char *prefix, const char *fmt, va_list ap) {
   15461 	char message[4096];
   15462 	const char *zstr;
   15463 
   15464 	REQUIRE(DNS_ZONE_VALID(zone));
   15465 
   15466 	if (!isc_log_wouldlog(dns_lctx, level)) {
   15467 		return;
   15468 	}
   15469 
   15470 	vsnprintf(message, sizeof(message), fmt, ap);
   15471 
   15472 	switch (zone->type) {
   15473 	case dns_zone_key:
   15474 		zstr = "managed-keys-zone";
   15475 		break;
   15476 	case dns_zone_redirect:
   15477 		zstr = "redirect-zone";
   15478 		break;
   15479 	default:
   15480 		zstr = "zone ";
   15481 	}
   15482 
   15483 	isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE, level,
   15484 		      "%s%s%s%s: %s", (prefix != NULL ? prefix : ""),
   15485 		      (prefix != NULL ? ": " : ""), zstr, zone->strnamerd,
   15486 		      message);
   15487 }
   15488 
   15489 static void
   15490 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   15491 	va_list ap;
   15492 
   15493 	va_start(ap, fmt);
   15494 	dns_zone_logv(zone, DNS_LOGCATEGORY_NOTIFY, level, NULL, fmt, ap);
   15495 	va_end(ap);
   15496 }
   15497 
   15498 void
   15499 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category, int level,
   15500 	      const char *fmt, ...) {
   15501 	va_list ap;
   15502 
   15503 	va_start(ap, fmt);
   15504 	dns_zone_logv(zone, category, level, NULL, fmt, ap);
   15505 	va_end(ap);
   15506 }
   15507 
   15508 void
   15509 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   15510 	va_list ap;
   15511 
   15512 	va_start(ap, fmt);
   15513 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, NULL, fmt, ap);
   15514 	va_end(ap);
   15515 }
   15516 
   15517 static void
   15518 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel, const char *fmt,
   15519 	      ...) {
   15520 	int level = ISC_LOG_DEBUG(debuglevel);
   15521 	va_list ap;
   15522 
   15523 	va_start(ap, fmt);
   15524 	dns_zone_logv(zone, DNS_LOGCATEGORY_GENERAL, level, me, fmt, ap);
   15525 	va_end(ap);
   15526 }
   15527 
   15528 static void
   15529 dnssec_log(dns_zone_t *zone, int level, const char *fmt, ...) {
   15530 	va_list ap;
   15531 
   15532 	va_start(ap, fmt);
   15533 	dns_zone_logv(zone, DNS_LOGCATEGORY_DNSSEC, level, NULL, fmt, ap);
   15534 	va_end(ap);
   15535 }
   15536 
   15537 static int
   15538 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type) {
   15539 	isc_result_t result;
   15540 	dns_name_t *name;
   15541 	dns_rdataset_t *curr;
   15542 	int count = 0;
   15543 
   15544 	result = dns_message_firstname(msg, section);
   15545 	while (result == ISC_R_SUCCESS) {
   15546 		name = NULL;
   15547 		dns_message_currentname(msg, section, &name);
   15548 
   15549 		for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
   15550 		     curr = ISC_LIST_PREV(curr, link))
   15551 		{
   15552 			if (curr->type == type) {
   15553 				count++;
   15554 			}
   15555 		}
   15556 		result = dns_message_nextname(msg, section);
   15557 	}
   15558 
   15559 	return (count);
   15560 }
   15561 
   15562 void
   15563 dns_zone_setmaxxfrin(dns_zone_t *zone, uint32_t maxxfrin) {
   15564 	REQUIRE(DNS_ZONE_VALID(zone));
   15565 
   15566 	zone->maxxfrin = maxxfrin;
   15567 }
   15568 
   15569 uint32_t
   15570 dns_zone_getmaxxfrin(dns_zone_t *zone) {
   15571 	REQUIRE(DNS_ZONE_VALID(zone));
   15572 
   15573 	return (zone->maxxfrin);
   15574 }
   15575 
   15576 void
   15577 dns_zone_setmaxxfrout(dns_zone_t *zone, uint32_t maxxfrout) {
   15578 	REQUIRE(DNS_ZONE_VALID(zone));
   15579 	zone->maxxfrout = maxxfrout;
   15580 }
   15581 
   15582 uint32_t
   15583 dns_zone_getmaxxfrout(dns_zone_t *zone) {
   15584 	REQUIRE(DNS_ZONE_VALID(zone));
   15585 
   15586 	return (zone->maxxfrout);
   15587 }
   15588 
   15589 dns_zonetype_t
   15590 dns_zone_gettype(dns_zone_t *zone) {
   15591 	REQUIRE(DNS_ZONE_VALID(zone));
   15592 
   15593 	return (zone->type);
   15594 }
   15595 
   15596 const char *
   15597 dns_zonetype_name(dns_zonetype_t type) {
   15598 	switch (type) {
   15599 	case dns_zone_none:
   15600 		return ("none");
   15601 	case dns_zone_master:
   15602 		return ("primary");
   15603 	case dns_zone_slave:
   15604 		return ("secondary");
   15605 	case dns_zone_mirror:
   15606 		return ("mirror");
   15607 	case dns_zone_stub:
   15608 		return ("stub");
   15609 	case dns_zone_staticstub:
   15610 		return ("static-stub");
   15611 	case dns_zone_key:
   15612 		return ("key");
   15613 	case dns_zone_dlz:
   15614 		return ("dlz");
   15615 	case dns_zone_redirect:
   15616 		return ("redirect");
   15617 	default:
   15618 		return ("unknown");
   15619 	}
   15620 }
   15621 
   15622 dns_zonetype_t
   15623 dns_zone_getredirecttype(dns_zone_t *zone) {
   15624 	REQUIRE(DNS_ZONE_VALID(zone));
   15625 	REQUIRE(zone->type == dns_zone_redirect);
   15626 
   15627 	return (zone->masters == NULL ? dns_zone_master : dns_zone_slave);
   15628 }
   15629 
   15630 dns_name_t *
   15631 dns_zone_getorigin(dns_zone_t *zone) {
   15632 	REQUIRE(DNS_ZONE_VALID(zone));
   15633 
   15634 	return (&zone->origin);
   15635 }
   15636 
   15637 void
   15638 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
   15639 	REQUIRE(DNS_ZONE_VALID(zone));
   15640 
   15641 	LOCK_ZONE(zone);
   15642 	if (zone->task != NULL) {
   15643 		isc_task_detach(&zone->task);
   15644 	}
   15645 	isc_task_attach(task, &zone->task);
   15646 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   15647 	if (zone->db != NULL) {
   15648 		dns_db_settask(zone->db, zone->task);
   15649 	}
   15650 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15651 	UNLOCK_ZONE(zone);
   15652 }
   15653 
   15654 void
   15655 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
   15656 	REQUIRE(DNS_ZONE_VALID(zone));
   15657 	isc_task_attach(zone->task, target);
   15658 }
   15659 
   15660 void
   15661 dns_zone_setidlein(dns_zone_t *zone, uint32_t idlein) {
   15662 	REQUIRE(DNS_ZONE_VALID(zone));
   15663 
   15664 	if (idlein == 0) {
   15665 		idlein = DNS_DEFAULT_IDLEIN;
   15666 	}
   15667 	zone->idlein = idlein;
   15668 }
   15669 
   15670 uint32_t
   15671 dns_zone_getidlein(dns_zone_t *zone) {
   15672 	REQUIRE(DNS_ZONE_VALID(zone));
   15673 
   15674 	return (zone->idlein);
   15675 }
   15676 
   15677 void
   15678 dns_zone_setidleout(dns_zone_t *zone, uint32_t idleout) {
   15679 	REQUIRE(DNS_ZONE_VALID(zone));
   15680 
   15681 	zone->idleout = idleout;
   15682 }
   15683 
   15684 uint32_t
   15685 dns_zone_getidleout(dns_zone_t *zone) {
   15686 	REQUIRE(DNS_ZONE_VALID(zone));
   15687 
   15688 	return (zone->idleout);
   15689 }
   15690 
   15691 static void
   15692 notify_done(isc_task_t *task, isc_event_t *event) {
   15693 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   15694 	dns_notify_t *notify;
   15695 	isc_result_t result;
   15696 	dns_message_t *message = NULL;
   15697 	isc_buffer_t buf;
   15698 	char rcode[128];
   15699 	char addrbuf[ISC_SOCKADDR_FORMATSIZE];
   15700 
   15701 	UNUSED(task);
   15702 
   15703 	notify = event->ev_arg;
   15704 	REQUIRE(DNS_NOTIFY_VALID(notify));
   15705 	INSIST(task == notify->zone->task);
   15706 
   15707 	isc_buffer_init(&buf, rcode, sizeof(rcode));
   15708 	isc_sockaddr_format(&notify->dst, addrbuf, sizeof(addrbuf));
   15709 	dns_message_create(notify->zone->mctx, DNS_MESSAGE_INTENTPARSE,
   15710 			   &message);
   15711 
   15712 	result = revent->result;
   15713 	if (result == ISC_R_SUCCESS) {
   15714 		result =
   15715 			dns_request_getresponse(revent->request, message,
   15716 						DNS_MESSAGEPARSE_PRESERVEORDER);
   15717 	}
   15718 	if (result == ISC_R_SUCCESS) {
   15719 		result = dns_rcode_totext(message->rcode, &buf);
   15720 	}
   15721 	if (result == ISC_R_SUCCESS) {
   15722 		notify_log(notify->zone, ISC_LOG_DEBUG(3),
   15723 			   "notify response from %s: %.*s", addrbuf,
   15724 			   (int)buf.used, rcode);
   15725 	} else {
   15726 		notify_log(notify->zone, ISC_LOG_DEBUG(2),
   15727 			   "notify to %s failed: %s", addrbuf,
   15728 			   dns_result_totext(result));
   15729 	}
   15730 
   15731 	/*
   15732 	 * Old bind's return formerr if they see a soa record.	Retry w/o
   15733 	 * the soa if we see a formerr and had sent a SOA.
   15734 	 */
   15735 	isc_event_free(&event);
   15736 	if (message->rcode == dns_rcode_formerr &&
   15737 	    (notify->flags & DNS_NOTIFY_NOSOA) == 0)
   15738 	{
   15739 		bool startup;
   15740 
   15741 		notify->flags |= DNS_NOTIFY_NOSOA;
   15742 		dns_request_destroy(&notify->request);
   15743 		startup = (notify->flags & DNS_NOTIFY_STARTUP);
   15744 		result = notify_send_queue(notify, startup);
   15745 		if (result != ISC_R_SUCCESS) {
   15746 			notify_destroy(notify, false);
   15747 		}
   15748 	} else {
   15749 		if (result == ISC_R_TIMEDOUT) {
   15750 			notify_log(notify->zone, ISC_LOG_DEBUG(1),
   15751 				   "notify to %s: retries exceeded", addrbuf);
   15752 		}
   15753 		notify_destroy(notify, false);
   15754 	}
   15755 	dns_message_detach(&message);
   15756 }
   15757 
   15758 struct secure_event {
   15759 	isc_event_t e;
   15760 	dns_db_t *db;
   15761 	uint32_t serial;
   15762 };
   15763 
   15764 static void
   15765 update_log_cb(void *arg, dns_zone_t *zone, int level, const char *message) {
   15766 	UNUSED(arg);
   15767 	dns_zone_log(zone, level, "%s", message);
   15768 }
   15769 
   15770 static isc_result_t
   15771 sync_secure_journal(dns_zone_t *zone, dns_zone_t *raw, dns_journal_t *journal,
   15772 		    uint32_t start, uint32_t end, dns_difftuple_t **soatuplep,
   15773 		    dns_diff_t *diff) {
   15774 	isc_result_t result;
   15775 	dns_difftuple_t *tuple = NULL;
   15776 	dns_diffop_t op = DNS_DIFFOP_ADD;
   15777 	int n_soa = 0;
   15778 
   15779 	REQUIRE(soatuplep != NULL);
   15780 
   15781 	if (start == end) {
   15782 		return (DNS_R_UNCHANGED);
   15783 	}
   15784 
   15785 	CHECK(dns_journal_iter_init(journal, start, end, NULL));
   15786 	for (result = dns_journal_first_rr(journal); result == ISC_R_SUCCESS;
   15787 	     result = dns_journal_next_rr(journal))
   15788 	{
   15789 		dns_name_t *name = NULL;
   15790 		uint32_t ttl;
   15791 		dns_rdata_t *rdata = NULL;
   15792 		dns_journal_current_rr(journal, &name, &ttl, &rdata);
   15793 
   15794 		if (rdata->type == dns_rdatatype_soa) {
   15795 			n_soa++;
   15796 			if (n_soa == 2) {
   15797 				/*
   15798 				 * Save the latest raw SOA record.
   15799 				 */
   15800 				if (*soatuplep != NULL) {
   15801 					dns_difftuple_free(soatuplep);
   15802 				}
   15803 				CHECK(dns_difftuple_create(
   15804 					diff->mctx, DNS_DIFFOP_ADD, name, ttl,
   15805 					rdata, soatuplep));
   15806 			}
   15807 			if (n_soa == 3) {
   15808 				n_soa = 1;
   15809 			}
   15810 			continue;
   15811 		}
   15812 
   15813 		/* Sanity. */
   15814 		if (n_soa == 0) {
   15815 			dns_zone_log(raw, ISC_LOG_ERROR,
   15816 				     "corrupt journal file: '%s'\n",
   15817 				     raw->journal);
   15818 			return (ISC_R_FAILURE);
   15819 		}
   15820 
   15821 		if (zone->privatetype != 0 && rdata->type == zone->privatetype)
   15822 		{
   15823 			continue;
   15824 		}
   15825 
   15826 		if (rdata->type == dns_rdatatype_nsec ||
   15827 		    rdata->type == dns_rdatatype_rrsig ||
   15828 		    rdata->type == dns_rdatatype_nsec3 ||
   15829 		    rdata->type == dns_rdatatype_dnskey ||
   15830 		    rdata->type == dns_rdatatype_nsec3param)
   15831 		{
   15832 			continue;
   15833 		}
   15834 
   15835 		op = (n_soa == 1) ? DNS_DIFFOP_DEL : DNS_DIFFOP_ADD;
   15836 
   15837 		CHECK(dns_difftuple_create(diff->mctx, op, name, ttl, rdata,
   15838 					   &tuple));
   15839 		dns_diff_appendminimal(diff, &tuple);
   15840 	}
   15841 	if (result == ISC_R_NOMORE) {
   15842 		result = ISC_R_SUCCESS;
   15843 	}
   15844 
   15845 failure:
   15846 	return (result);
   15847 }
   15848 
   15849 static isc_result_t
   15850 sync_secure_db(dns_zone_t *seczone, dns_zone_t *raw, dns_db_t *secdb,
   15851 	       dns_dbversion_t *secver, dns_difftuple_t **soatuple,
   15852 	       dns_diff_t *diff) {
   15853 	isc_result_t result;
   15854 	dns_db_t *rawdb = NULL;
   15855 	dns_dbversion_t *rawver = NULL;
   15856 	dns_difftuple_t *tuple = NULL, *next;
   15857 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   15858 	dns_rdata_soa_t oldsoa, newsoa;
   15859 
   15860 	REQUIRE(DNS_ZONE_VALID(seczone));
   15861 	REQUIRE(soatuple != NULL && *soatuple == NULL);
   15862 
   15863 	if (!seczone->sourceserialset) {
   15864 		return (DNS_R_UNCHANGED);
   15865 	}
   15866 
   15867 	dns_db_attach(raw->db, &rawdb);
   15868 	dns_db_currentversion(rawdb, &rawver);
   15869 	result = dns_db_diffx(diff, rawdb, rawver, secdb, secver, NULL);
   15870 	dns_db_closeversion(rawdb, &rawver, false);
   15871 	dns_db_detach(&rawdb);
   15872 
   15873 	if (result != ISC_R_SUCCESS) {
   15874 		return (result);
   15875 	}
   15876 
   15877 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL; tuple = next) {
   15878 		next = ISC_LIST_NEXT(tuple, link);
   15879 		if (tuple->rdata.type == dns_rdatatype_nsec ||
   15880 		    tuple->rdata.type == dns_rdatatype_rrsig ||
   15881 		    tuple->rdata.type == dns_rdatatype_dnskey ||
   15882 		    tuple->rdata.type == dns_rdatatype_nsec3 ||
   15883 		    tuple->rdata.type == dns_rdatatype_nsec3param)
   15884 		{
   15885 			ISC_LIST_UNLINK(diff->tuples, tuple, link);
   15886 			dns_difftuple_free(&tuple);
   15887 			continue;
   15888 		}
   15889 		if (tuple->rdata.type == dns_rdatatype_soa) {
   15890 			if (tuple->op == DNS_DIFFOP_DEL) {
   15891 				INSIST(oldtuple == NULL);
   15892 				oldtuple = tuple;
   15893 			}
   15894 			if (tuple->op == DNS_DIFFOP_ADD) {
   15895 				INSIST(newtuple == NULL);
   15896 				newtuple = tuple;
   15897 			}
   15898 		}
   15899 	}
   15900 
   15901 	if (oldtuple != NULL && newtuple != NULL) {
   15902 		result = dns_rdata_tostruct(&oldtuple->rdata, &oldsoa, NULL);
   15903 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15904 
   15905 		result = dns_rdata_tostruct(&newtuple->rdata, &newsoa, NULL);
   15906 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   15907 
   15908 		/*
   15909 		 * If the SOA records are the same except for the serial
   15910 		 * remove them from the diff.
   15911 		 */
   15912 		if (oldsoa.refresh == newsoa.refresh &&
   15913 		    oldsoa.retry == newsoa.retry &&
   15914 		    oldsoa.minimum == newsoa.minimum &&
   15915 		    oldsoa.expire == newsoa.expire &&
   15916 		    dns_name_equal(&oldsoa.origin, &newsoa.origin) &&
   15917 		    dns_name_equal(&oldsoa.contact, &newsoa.contact))
   15918 		{
   15919 			ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   15920 			dns_difftuple_free(&oldtuple);
   15921 			ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   15922 			dns_difftuple_free(&newtuple);
   15923 		}
   15924 	}
   15925 
   15926 	if (ISC_LIST_EMPTY(diff->tuples)) {
   15927 		return (DNS_R_UNCHANGED);
   15928 	}
   15929 
   15930 	/*
   15931 	 * If there are still SOA records in the diff they can now be removed
   15932 	 * saving the new SOA record.
   15933 	 */
   15934 	if (oldtuple != NULL) {
   15935 		ISC_LIST_UNLINK(diff->tuples, oldtuple, link);
   15936 		dns_difftuple_free(&oldtuple);
   15937 	}
   15938 
   15939 	if (newtuple != NULL) {
   15940 		ISC_LIST_UNLINK(diff->tuples, newtuple, link);
   15941 		*soatuple = newtuple;
   15942 	}
   15943 
   15944 	return (ISC_R_SUCCESS);
   15945 }
   15946 
   15947 static void
   15948 receive_secure_serial(isc_task_t *task, isc_event_t *event) {
   15949 	static char me[] = "receive_secure_serial";
   15950 	isc_result_t result = ISC_R_SUCCESS;
   15951 	dns_journal_t *rjournal = NULL;
   15952 	dns_journal_t *sjournal = NULL;
   15953 	uint32_t start, end;
   15954 	dns_zone_t *zone;
   15955 	dns_difftuple_t *tuple = NULL, *soatuple = NULL;
   15956 	dns_update_log_t log = { update_log_cb, NULL };
   15957 	uint32_t newserial = 0, desired = 0;
   15958 	isc_time_t timenow;
   15959 	int level = ISC_LOG_ERROR;
   15960 
   15961 	UNUSED(task);
   15962 
   15963 	zone = event->ev_arg;
   15964 	end = ((struct secure_event *)event)->serial;
   15965 
   15966 	ENTER;
   15967 
   15968 	LOCK_ZONE(zone);
   15969 
   15970 	/*
   15971 	 * If we are already processing a receive secure serial event
   15972 	 * for the zone, just queue the new one and exit.
   15973 	 */
   15974 	if (zone->rss_event != NULL && zone->rss_event != event) {
   15975 		ISC_LIST_APPEND(zone->rss_events, event, ev_link);
   15976 		UNLOCK_ZONE(zone);
   15977 		return;
   15978 	}
   15979 
   15980 nextevent:
   15981 	if (zone->rss_event != NULL) {
   15982 		INSIST(zone->rss_event == event);
   15983 		UNLOCK_ZONE(zone);
   15984 	} else {
   15985 		zone->rss_event = event;
   15986 		dns_diff_init(zone->mctx, &zone->rss_diff);
   15987 
   15988 		/*
   15989 		 * zone->db may be NULL, if the load from disk failed.
   15990 		 */
   15991 		result = ISC_R_SUCCESS;
   15992 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   15993 		if (zone->db != NULL) {
   15994 			dns_db_attach(zone->db, &zone->rss_db);
   15995 		} else {
   15996 			result = ISC_R_FAILURE;
   15997 		}
   15998 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   15999 
   16000 		if (result == ISC_R_SUCCESS && zone->raw != NULL) {
   16001 			dns_zone_attach(zone->raw, &zone->rss_raw);
   16002 		} else {
   16003 			result = ISC_R_FAILURE;
   16004 		}
   16005 
   16006 		UNLOCK_ZONE(zone);
   16007 
   16008 		CHECK(result);
   16009 
   16010 		/*
   16011 		 * We first attempt to sync the raw zone to the secure zone
   16012 		 * by using the raw zone's journal, applying all the deltas
   16013 		 * from the latest source-serial of the secure zone up to
   16014 		 * the current serial number of the raw zone.
   16015 		 *
   16016 		 * If that fails, then we'll fall back to a direct comparison
   16017 		 * between raw and secure zones.
   16018 		 */
   16019 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16020 				       zone->rss_raw->journal,
   16021 				       DNS_JOURNAL_WRITE, &rjournal));
   16022 
   16023 		result = dns_journal_open(zone->mctx, zone->journal,
   16024 					  DNS_JOURNAL_READ, &sjournal);
   16025 		if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   16026 			goto failure;
   16027 		}
   16028 
   16029 		if (!dns_journal_get_sourceserial(rjournal, &start)) {
   16030 			start = dns_journal_first_serial(rjournal);
   16031 			dns_journal_set_sourceserial(rjournal, start);
   16032 		}
   16033 		if (sjournal != NULL) {
   16034 			uint32_t serial;
   16035 			/*
   16036 			 * We read the secure journal first, if that
   16037 			 * exists use its value provided it is greater
   16038 			 * that from the raw journal.
   16039 			 */
   16040 			if (dns_journal_get_sourceserial(sjournal, &serial)) {
   16041 				if (isc_serial_gt(serial, start)) {
   16042 					start = serial;
   16043 				}
   16044 			}
   16045 			dns_journal_destroy(&sjournal);
   16046 		}
   16047 
   16048 		dns_db_currentversion(zone->rss_db, &zone->rss_oldver);
   16049 		CHECK(dns_db_newversion(zone->rss_db, &zone->rss_newver));
   16050 
   16051 		/*
   16052 		 * Try to apply diffs from the raw zone's journal to the secure
   16053 		 * zone.  If that fails, we recover by syncing up the databases
   16054 		 * directly.
   16055 		 */
   16056 		result = sync_secure_journal(zone, zone->rss_raw, rjournal,
   16057 					     start, end, &soatuple,
   16058 					     &zone->rss_diff);
   16059 		if (result == DNS_R_UNCHANGED) {
   16060 			level = ISC_LOG_INFO;
   16061 			goto failure;
   16062 		} else if (result != ISC_R_SUCCESS) {
   16063 			CHECK(sync_secure_db(zone, zone->rss_raw, zone->rss_db,
   16064 					     zone->rss_oldver, &soatuple,
   16065 					     &zone->rss_diff));
   16066 		}
   16067 
   16068 		CHECK(dns_diff_apply(&zone->rss_diff, zone->rss_db,
   16069 				     zone->rss_newver));
   16070 
   16071 		if (soatuple != NULL) {
   16072 			uint32_t oldserial;
   16073 
   16074 			CHECK(dns_db_createsoatuple(
   16075 				zone->rss_db, zone->rss_oldver,
   16076 				zone->rss_diff.mctx, DNS_DIFFOP_DEL, &tuple));
   16077 			oldserial = dns_soa_getserial(&tuple->rdata);
   16078 			newserial = desired =
   16079 				dns_soa_getserial(&soatuple->rdata);
   16080 			if (!isc_serial_gt(newserial, oldserial)) {
   16081 				newserial = oldserial + 1;
   16082 				if (newserial == 0) {
   16083 					newserial++;
   16084 				}
   16085 				dns_soa_setserial(newserial, &soatuple->rdata);
   16086 			}
   16087 			CHECK(do_one_tuple(&tuple, zone->rss_db,
   16088 					   zone->rss_newver, &zone->rss_diff));
   16089 			CHECK(do_one_tuple(&soatuple, zone->rss_db,
   16090 					   zone->rss_newver, &zone->rss_diff));
   16091 		} else {
   16092 			CHECK(update_soa_serial(zone, zone->rss_db,
   16093 						zone->rss_newver,
   16094 						&zone->rss_diff, zone->mctx,
   16095 						zone->updatemethod));
   16096 		}
   16097 	}
   16098 	result = dns_update_signaturesinc(
   16099 		&log, zone, zone->rss_db, zone->rss_oldver, zone->rss_newver,
   16100 		&zone->rss_diff, zone->sigvalidityinterval, &zone->rss_state);
   16101 	if (result == DNS_R_CONTINUE) {
   16102 		if (rjournal != NULL) {
   16103 			dns_journal_destroy(&rjournal);
   16104 		}
   16105 		isc_task_send(task, &event);
   16106 		return;
   16107 	}
   16108 	/*
   16109 	 * If something went wrong while trying to update the secure zone and
   16110 	 * the latter was already signed before, do not apply raw zone deltas
   16111 	 * to it as that would break existing DNSSEC signatures.  However, if
   16112 	 * the secure zone was not yet signed (e.g. because no signing keys
   16113 	 * were created for it), commence applying raw zone deltas to it so
   16114 	 * that contents of the raw zone and the secure zone are kept in sync.
   16115 	 */
   16116 	if (result != ISC_R_SUCCESS && dns_db_issecure(zone->rss_db)) {
   16117 		goto failure;
   16118 	}
   16119 
   16120 	if (rjournal == NULL) {
   16121 		CHECK(dns_journal_open(zone->rss_raw->mctx,
   16122 				       zone->rss_raw->journal,
   16123 				       DNS_JOURNAL_WRITE, &rjournal));
   16124 	}
   16125 	CHECK(zone_journal(zone, &zone->rss_diff, &end,
   16126 			   "receive_secure_serial"));
   16127 
   16128 	dns_journal_set_sourceserial(rjournal, end);
   16129 	dns_journal_commit(rjournal);
   16130 
   16131 	LOCK_ZONE(zone);
   16132 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   16133 
   16134 	zone->sourceserial = end;
   16135 	zone->sourceserialset = true;
   16136 	zone_needdump(zone, DNS_DUMP_DELAY);
   16137 
   16138 	/*
   16139 	 * Set resign time to make sure it is set to the earliest
   16140 	 * signature expiration.
   16141 	 */
   16142 	set_resigntime(zone);
   16143 	TIME_NOW(&timenow);
   16144 	zone_settimer(zone, &timenow);
   16145 	UNLOCK_ZONE(zone);
   16146 
   16147 	dns_db_closeversion(zone->rss_db, &zone->rss_oldver, false);
   16148 	dns_db_closeversion(zone->rss_db, &zone->rss_newver, true);
   16149 
   16150 	if (newserial != 0) {
   16151 		dns_zone_log(zone, ISC_LOG_INFO, "serial %u (unsigned %u)",
   16152 			     newserial, desired);
   16153 	}
   16154 
   16155 failure:
   16156 	isc_event_free(&zone->rss_event);
   16157 	event = ISC_LIST_HEAD(zone->rss_events);
   16158 
   16159 	if (zone->rss_raw != NULL) {
   16160 		dns_zone_detach(&zone->rss_raw);
   16161 	}
   16162 	if (result != ISC_R_SUCCESS) {
   16163 		LOCK_ZONE(zone);
   16164 		set_resigntime(zone);
   16165 		TIME_NOW(&timenow);
   16166 		zone_settimer(zone, &timenow);
   16167 		UNLOCK_ZONE(zone);
   16168 		dns_zone_log(zone, level, "receive_secure_serial: %s",
   16169 			     dns_result_totext(result));
   16170 	}
   16171 	if (tuple != NULL) {
   16172 		dns_difftuple_free(&tuple);
   16173 	}
   16174 	if (soatuple != NULL) {
   16175 		dns_difftuple_free(&soatuple);
   16176 	}
   16177 	if (zone->rss_db != NULL) {
   16178 		if (zone->rss_oldver != NULL) {
   16179 			dns_db_closeversion(zone->rss_db, &zone->rss_oldver,
   16180 					    false);
   16181 		}
   16182 		if (zone->rss_newver != NULL) {
   16183 			dns_db_closeversion(zone->rss_db, &zone->rss_newver,
   16184 					    false);
   16185 		}
   16186 		dns_db_detach(&zone->rss_db);
   16187 	}
   16188 	INSIST(zone->rss_oldver == NULL);
   16189 	INSIST(zone->rss_newver == NULL);
   16190 	if (rjournal != NULL) {
   16191 		dns_journal_destroy(&rjournal);
   16192 	}
   16193 	dns_diff_clear(&zone->rss_diff);
   16194 
   16195 	if (event != NULL) {
   16196 		LOCK_ZONE(zone);
   16197 		isc_refcount_decrement(&zone->irefs);
   16198 		ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
   16199 		goto nextevent;
   16200 	}
   16201 
   16202 	event = ISC_LIST_HEAD(zone->rss_post);
   16203 	while (event != NULL) {
   16204 		ISC_LIST_UNLINK(zone->rss_post, event, ev_link);
   16205 		rss_post(zone, event);
   16206 		event = ISC_LIST_HEAD(zone->rss_post);
   16207 	}
   16208 
   16209 	dns_zone_idetach(&zone);
   16210 }
   16211 
   16212 static isc_result_t
   16213 zone_send_secureserial(dns_zone_t *zone, uint32_t serial) {
   16214 	isc_event_t *e;
   16215 	dns_zone_t *dummy = NULL;
   16216 
   16217 	e = isc_event_allocate(zone->secure->mctx, zone,
   16218 			       DNS_EVENT_ZONESECURESERIAL,
   16219 			       receive_secure_serial, zone->secure,
   16220 			       sizeof(struct secure_event));
   16221 	((struct secure_event *)e)->serial = serial;
   16222 	INSIST(LOCKED_ZONE(zone->secure));
   16223 	zone_iattach(zone->secure, &dummy);
   16224 	isc_task_send(zone->secure->task, &e);
   16225 
   16226 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   16227 	return (ISC_R_SUCCESS);
   16228 }
   16229 
   16230 static isc_result_t
   16231 checkandaddsoa(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
   16232 	       dns_rdataset_t *rdataset, uint32_t oldserial) {
   16233 	dns_rdata_soa_t soa;
   16234 	dns_rdata_t rdata = DNS_RDATA_INIT;
   16235 	dns_rdatalist_t temprdatalist;
   16236 	dns_rdataset_t temprdataset;
   16237 	isc_buffer_t b;
   16238 	isc_result_t result;
   16239 	unsigned char buf[DNS_SOA_BUFFERSIZE];
   16240 	dns_fixedname_t fixed;
   16241 	dns_name_t *name;
   16242 
   16243 	result = dns_rdataset_first(rdataset);
   16244 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16245 	dns_rdataset_current(rdataset, &rdata);
   16246 	result = dns_rdata_tostruct(&rdata, &soa, NULL);
   16247 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16248 
   16249 	if (isc_serial_gt(soa.serial, oldserial)) {
   16250 		return (dns_db_addrdataset(db, node, version, 0, rdataset, 0,
   16251 					   NULL));
   16252 	}
   16253 	/*
   16254 	 * Always bump the serial.
   16255 	 */
   16256 	oldserial++;
   16257 	if (oldserial == 0) {
   16258 		oldserial++;
   16259 	}
   16260 	soa.serial = oldserial;
   16261 
   16262 	/*
   16263 	 * Construct a replacement rdataset.
   16264 	 */
   16265 	dns_rdata_reset(&rdata);
   16266 	isc_buffer_init(&b, buf, sizeof(buf));
   16267 	result = dns_rdata_fromstruct(&rdata, rdataset->rdclass,
   16268 				      dns_rdatatype_soa, &soa, &b);
   16269 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16270 	dns_rdatalist_init(&temprdatalist);
   16271 	temprdatalist.rdclass = rdata.rdclass;
   16272 	temprdatalist.type = rdata.type;
   16273 	temprdatalist.ttl = rdataset->ttl;
   16274 	ISC_LIST_APPEND(temprdatalist.rdata, &rdata, link);
   16275 
   16276 	dns_rdataset_init(&temprdataset);
   16277 	result = dns_rdatalist_tordataset(&temprdatalist, &temprdataset);
   16278 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16279 
   16280 	name = dns_fixedname_initname(&fixed);
   16281 	result = dns_db_nodefullname(db, node, name);
   16282 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16283 	dns_rdataset_getownercase(rdataset, name);
   16284 	dns_rdataset_setownercase(&temprdataset, name);
   16285 	return (dns_db_addrdataset(db, node, version, 0, &temprdataset, 0,
   16286 				   NULL));
   16287 }
   16288 
   16289 /*
   16290  * This function should populate an nsec3paramlist_t with the
   16291  * nsecparam_t data from a zone.
   16292  */
   16293 static isc_result_t
   16294 save_nsec3param(dns_zone_t *zone, nsec3paramlist_t *nsec3list) {
   16295 	isc_result_t result;
   16296 	dns_dbnode_t *node = NULL;
   16297 	dns_rdataset_t rdataset, prdataset;
   16298 	dns_dbversion_t *version = NULL;
   16299 	nsec3param_t *nsec3param = NULL;
   16300 	nsec3param_t *nsec3p = NULL;
   16301 	nsec3param_t *next;
   16302 	dns_db_t *db = NULL;
   16303 	unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   16304 
   16305 	REQUIRE(DNS_ZONE_VALID(zone));
   16306 	REQUIRE(nsec3list != NULL);
   16307 	REQUIRE(ISC_LIST_EMPTY(*nsec3list));
   16308 
   16309 	dns_rdataset_init(&rdataset);
   16310 	dns_rdataset_init(&prdataset);
   16311 
   16312 	dns_db_attach(zone->db, &db);
   16313 	CHECK(dns_db_getoriginnode(db, &node));
   16314 
   16315 	dns_db_currentversion(db, &version);
   16316 	result = dns_db_findrdataset(db, node, version,
   16317 				     dns_rdatatype_nsec3param,
   16318 				     dns_rdatatype_none, 0, &rdataset, NULL);
   16319 
   16320 	if (result != ISC_R_SUCCESS) {
   16321 		goto getprivate;
   16322 	}
   16323 
   16324 	/*
   16325 	 * Walk nsec3param rdataset making a list of parameters (note that
   16326 	 * multiple simultaneous nsec3 chains are annoyingly legal -- this
   16327 	 * is why we use an nsec3list, even though we will usually only
   16328 	 * have one).
   16329 	 */
   16330 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   16331 	     result = dns_rdataset_next(&rdataset))
   16332 	{
   16333 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16334 		dns_rdata_t private = DNS_RDATA_INIT;
   16335 
   16336 		dns_rdataset_current(&rdataset, &rdata);
   16337 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16338 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16339 			      "looping through nsec3param data");
   16340 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   16341 		ISC_LINK_INIT(nsec3param, link);
   16342 
   16343 		/*
   16344 		 * now transfer the data from the rdata to
   16345 		 * the nsec3param
   16346 		 */
   16347 		dns_nsec3param_toprivate(&rdata, &private, zone->privatetype,
   16348 					 nsec3param->data,
   16349 					 sizeof(nsec3param->data));
   16350 		nsec3param->length = private.length;
   16351 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   16352 	}
   16353 
   16354 getprivate:
   16355 	result = dns_db_findrdataset(db, node, version, zone->privatetype,
   16356 				     dns_rdatatype_none, 0, &prdataset, NULL);
   16357 	if (result != ISC_R_SUCCESS) {
   16358 		goto done;
   16359 	}
   16360 
   16361 	/*
   16362 	 * walk private type records, converting them to nsec3 parameters
   16363 	 * using dns_nsec3param_fromprivate(), do the right thing based on
   16364 	 * CREATE and REMOVE flags
   16365 	 */
   16366 	for (result = dns_rdataset_first(&prdataset); result == ISC_R_SUCCESS;
   16367 	     result = dns_rdataset_next(&prdataset))
   16368 	{
   16369 		dns_rdata_t rdata = DNS_RDATA_INIT;
   16370 		dns_rdata_t private = DNS_RDATA_INIT;
   16371 
   16372 		dns_rdataset_current(&prdataset, &private);
   16373 		isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16374 			      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16375 			      "looping through nsec3param private data");
   16376 
   16377 		/*
   16378 		 * Do we have a valid private record?
   16379 		 */
   16380 		if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
   16381 						sizeof(buf))) {
   16382 			continue;
   16383 		}
   16384 
   16385 		/*
   16386 		 * Remove any NSEC3PARAM records scheduled to be removed.
   16387 		 */
   16388 		if (NSEC3REMOVE(rdata.data[1])) {
   16389 			/*
   16390 			 * Zero out the flags.
   16391 			 */
   16392 			rdata.data[1] = 0;
   16393 
   16394 			for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL;
   16395 			     nsec3p = next) {
   16396 				next = ISC_LIST_NEXT(nsec3p, link);
   16397 
   16398 				if (nsec3p->length == rdata.length + 1 &&
   16399 				    memcmp(rdata.data, nsec3p->data + 1,
   16400 					   nsec3p->length - 1) == 0)
   16401 				{
   16402 					ISC_LIST_UNLINK(*nsec3list, nsec3p,
   16403 							link);
   16404 					isc_mem_put(zone->mctx, nsec3p,
   16405 						    sizeof(nsec3param_t));
   16406 				}
   16407 			}
   16408 			continue;
   16409 		}
   16410 
   16411 		nsec3param = isc_mem_get(zone->mctx, sizeof(nsec3param_t));
   16412 		ISC_LINK_INIT(nsec3param, link);
   16413 
   16414 		/*
   16415 		 * Copy the remaining private records so the nsec/nsec3
   16416 		 * chain gets created.
   16417 		 */
   16418 		INSIST(private.length <= sizeof(nsec3param->data));
   16419 		memmove(nsec3param->data, private.data, private.length);
   16420 		nsec3param->length = private.length;
   16421 		ISC_LIST_APPEND(*nsec3list, nsec3param, link);
   16422 	}
   16423 
   16424 done:
   16425 	if (result == ISC_R_NOMORE || result == ISC_R_NOTFOUND) {
   16426 		result = ISC_R_SUCCESS;
   16427 	}
   16428 
   16429 failure:
   16430 	if (node != NULL) {
   16431 		dns_db_detachnode(db, &node);
   16432 	}
   16433 	if (version != NULL) {
   16434 		dns_db_closeversion(db, &version, false);
   16435 	}
   16436 	if (db != NULL) {
   16437 		dns_db_detach(&db);
   16438 	}
   16439 	if (dns_rdataset_isassociated(&rdataset)) {
   16440 		dns_rdataset_disassociate(&rdataset);
   16441 	}
   16442 	if (dns_rdataset_isassociated(&prdataset)) {
   16443 		dns_rdataset_disassociate(&prdataset);
   16444 	}
   16445 	return (result);
   16446 }
   16447 
   16448 /*
   16449  * Populate new zone db with private type records found by save_nsec3param().
   16450  */
   16451 static isc_result_t
   16452 restore_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   16453 		   nsec3paramlist_t *nsec3list) {
   16454 	isc_result_t result = ISC_R_SUCCESS;
   16455 	dns_diff_t diff;
   16456 	dns_rdata_t rdata;
   16457 	nsec3param_t *nsec3p = NULL;
   16458 	nsec3param_t *next;
   16459 
   16460 	REQUIRE(DNS_ZONE_VALID(zone));
   16461 	REQUIRE(!ISC_LIST_EMPTY(*nsec3list));
   16462 
   16463 	dns_diff_init(zone->mctx, &diff);
   16464 
   16465 	/*
   16466 	 * Loop through the list of private-type records, set the INITIAL
   16467 	 * and CREATE flags, and the add the record to the apex of the tree
   16468 	 * in db.
   16469 	 */
   16470 	for (nsec3p = ISC_LIST_HEAD(*nsec3list); nsec3p != NULL; nsec3p = next)
   16471 	{
   16472 		next = ISC_LIST_NEXT(nsec3p, link);
   16473 		dns_rdata_init(&rdata);
   16474 		nsec3p->data[2] = DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL;
   16475 		rdata.length = nsec3p->length;
   16476 		rdata.data = nsec3p->data;
   16477 		rdata.type = zone->privatetype;
   16478 		rdata.rdclass = zone->rdclass;
   16479 		result = update_one_rr(db, version, &diff, DNS_DIFFOP_ADD,
   16480 				       &zone->origin, 0, &rdata);
   16481 		if (result != ISC_R_SUCCESS) {
   16482 			break;
   16483 		}
   16484 	}
   16485 
   16486 	dns_diff_clear(&diff);
   16487 	return (result);
   16488 }
   16489 
   16490 static isc_result_t
   16491 copy_non_dnssec_records(dns_zone_t *zone, dns_db_t *db, dns_db_t *version,
   16492 			dns_db_t *rawdb, dns_dbiterator_t *dbiterator,
   16493 			unsigned int *oldserial) {
   16494 	dns_dbnode_t *rawnode = NULL, *node = NULL;
   16495 	dns_fixedname_t fixed;
   16496 	dns_name_t *name = dns_fixedname_initname(&fixed);
   16497 	dns_rdataset_t rdataset;
   16498 	dns_rdatasetiter_t *rdsit = NULL;
   16499 	isc_result_t result;
   16500 
   16501 	result = dns_dbiterator_current(dbiterator, &rawnode, name);
   16502 	if (result != ISC_R_SUCCESS) {
   16503 		return (ISC_R_SUCCESS);
   16504 	}
   16505 
   16506 	dns_dbiterator_pause(dbiterator);
   16507 
   16508 	result = dns_db_findnode(db, name, true, &node);
   16509 	if (result != ISC_R_SUCCESS) {
   16510 		goto cleanup;
   16511 	}
   16512 
   16513 	result = dns_db_allrdatasets(rawdb, rawnode, NULL, 0, &rdsit);
   16514 	if (result != ISC_R_SUCCESS) {
   16515 		goto cleanup;
   16516 	}
   16517 
   16518 	dns_rdataset_init(&rdataset);
   16519 
   16520 	for (result = dns_rdatasetiter_first(rdsit); result == ISC_R_SUCCESS;
   16521 	     result = dns_rdatasetiter_next(rdsit))
   16522 	{
   16523 		dns_rdatasetiter_current(rdsit, &rdataset);
   16524 		if (rdataset.type == dns_rdatatype_nsec ||
   16525 		    rdataset.type == dns_rdatatype_rrsig ||
   16526 		    rdataset.type == dns_rdatatype_nsec3 ||
   16527 		    rdataset.type == dns_rdatatype_dnskey ||
   16528 		    rdataset.type == dns_rdatatype_nsec3param)
   16529 		{
   16530 			/*
   16531 			 * Allow DNSSEC records with dnssec-policy.
   16532 			 * WMM: Perhaps add config option for it.
   16533 			 */
   16534 			if (!dns_zone_use_kasp(zone)) {
   16535 				dns_rdataset_disassociate(&rdataset);
   16536 				continue;
   16537 			}
   16538 		}
   16539 		if (rdataset.type == dns_rdatatype_soa && oldserial != NULL) {
   16540 			result = checkandaddsoa(db, node, version, &rdataset,
   16541 						*oldserial);
   16542 		} else {
   16543 			result = dns_db_addrdataset(db, node, version, 0,
   16544 						    &rdataset, 0, NULL);
   16545 		}
   16546 		dns_rdataset_disassociate(&rdataset);
   16547 		if (result != ISC_R_SUCCESS) {
   16548 			goto cleanup;
   16549 		}
   16550 	}
   16551 	if (result == ISC_R_NOMORE) {
   16552 		result = ISC_R_SUCCESS;
   16553 	}
   16554 
   16555 cleanup:
   16556 	if (rdsit != NULL) {
   16557 		dns_rdatasetiter_destroy(&rdsit);
   16558 	}
   16559 	if (rawnode) {
   16560 		dns_db_detachnode(rawdb, &rawnode);
   16561 	}
   16562 	if (node) {
   16563 		dns_db_detachnode(db, &node);
   16564 	}
   16565 	return (result);
   16566 }
   16567 
   16568 static void
   16569 receive_secure_db(isc_task_t *task, isc_event_t *event) {
   16570 	isc_result_t result;
   16571 	dns_zone_t *zone;
   16572 	dns_db_t *rawdb, *db = NULL;
   16573 	dns_dbiterator_t *dbiterator = NULL;
   16574 	dns_dbversion_t *version = NULL;
   16575 	isc_time_t loadtime;
   16576 	unsigned int oldserial = 0, *oldserialp = NULL;
   16577 	nsec3paramlist_t nsec3list;
   16578 	isc_event_t *setnsec3param_event;
   16579 	dns_zone_t *dummy;
   16580 
   16581 	UNUSED(task);
   16582 
   16583 	ISC_LIST_INIT(nsec3list);
   16584 
   16585 	zone = event->ev_arg;
   16586 	rawdb = ((struct secure_event *)event)->db;
   16587 	isc_event_free(&event);
   16588 
   16589 	LOCK_ZONE(zone);
   16590 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || !inline_secure(zone)) {
   16591 		result = ISC_R_SHUTTINGDOWN;
   16592 		goto failure;
   16593 	}
   16594 
   16595 	TIME_NOW(&loadtime);
   16596 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   16597 	if (zone->db != NULL) {
   16598 		result = dns_db_getsoaserial(zone->db, NULL, &oldserial);
   16599 		if (result == ISC_R_SUCCESS) {
   16600 			oldserialp = &oldserial;
   16601 		}
   16602 
   16603 		/*
   16604 		 * assemble nsec3parameters from the old zone, and set a flag
   16605 		 * if any are found
   16606 		 */
   16607 		result = save_nsec3param(zone, &nsec3list);
   16608 		if (result != ISC_R_SUCCESS) {
   16609 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16610 			goto failure;
   16611 		}
   16612 	}
   16613 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   16614 
   16615 	result = dns_db_create(zone->mctx, zone->db_argv[0], &zone->origin,
   16616 			       dns_dbtype_zone, zone->rdclass,
   16617 			       zone->db_argc - 1, zone->db_argv + 1, &db);
   16618 	if (result != ISC_R_SUCCESS) {
   16619 		goto failure;
   16620 	}
   16621 
   16622 	result = dns_db_setgluecachestats(db, zone->gluecachestats);
   16623 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTIMPLEMENTED) {
   16624 		goto failure;
   16625 	}
   16626 
   16627 	result = dns_db_newversion(db, &version);
   16628 	if (result != ISC_R_SUCCESS) {
   16629 		goto failure;
   16630 	}
   16631 
   16632 	result = dns_db_createiterator(rawdb, 0, &dbiterator);
   16633 	if (result != ISC_R_SUCCESS) {
   16634 		goto failure;
   16635 	}
   16636 
   16637 	for (result = dns_dbiterator_first(dbiterator); result == ISC_R_SUCCESS;
   16638 	     result = dns_dbiterator_next(dbiterator))
   16639 	{
   16640 		result = copy_non_dnssec_records(zone, db, version, rawdb,
   16641 						 dbiterator, oldserialp);
   16642 		if (result != ISC_R_SUCCESS) {
   16643 			goto failure;
   16644 		}
   16645 	}
   16646 	dns_dbiterator_destroy(&dbiterator);
   16647 	if (result != ISC_R_NOMORE) {
   16648 		goto failure;
   16649 	}
   16650 
   16651 	/*
   16652 	 * Call restore_nsec3param() to create private-type records from
   16653 	 * the old nsec3 parameters and insert them into db
   16654 	 */
   16655 	if (!ISC_LIST_EMPTY(nsec3list)) {
   16656 		result = restore_nsec3param(zone, db, version, &nsec3list);
   16657 		if (result != ISC_R_SUCCESS) {
   16658 			goto failure;
   16659 		}
   16660 	}
   16661 
   16662 	dns_db_closeversion(db, &version, true);
   16663 
   16664 	/*
   16665 	 * Lock hierarchy: zmgr, zone, raw.
   16666 	 */
   16667 	INSIST(zone != zone->raw);
   16668 	LOCK_ZONE(zone->raw);
   16669 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   16670 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   16671 	zone_needdump(zone, 0); /* XXXMPA */
   16672 	UNLOCK_ZONE(zone->raw);
   16673 
   16674 	/*
   16675 	 * Process any queued NSEC3PARAM change requests.
   16676 	 */
   16677 	while (!ISC_LIST_EMPTY(zone->setnsec3param_queue)) {
   16678 		setnsec3param_event = ISC_LIST_HEAD(zone->setnsec3param_queue);
   16679 		ISC_LIST_UNLINK(zone->setnsec3param_queue, setnsec3param_event,
   16680 				ev_link);
   16681 		dummy = NULL;
   16682 		zone_iattach(zone, &dummy);
   16683 		isc_task_send(zone->task, &setnsec3param_event);
   16684 	}
   16685 
   16686 failure:
   16687 	UNLOCK_ZONE(zone);
   16688 	if (dbiterator != NULL) {
   16689 		dns_dbiterator_destroy(&dbiterator);
   16690 	}
   16691 	if (result != ISC_R_SUCCESS) {
   16692 		dns_zone_log(zone, ISC_LOG_ERROR, "receive_secure_db: %s",
   16693 			     dns_result_totext(result));
   16694 	}
   16695 
   16696 	while (!ISC_LIST_EMPTY(nsec3list)) {
   16697 		nsec3param_t *nsec3p;
   16698 		nsec3p = ISC_LIST_HEAD(nsec3list);
   16699 		ISC_LIST_UNLINK(nsec3list, nsec3p, link);
   16700 		isc_mem_put(zone->mctx, nsec3p, sizeof(nsec3param_t));
   16701 	}
   16702 	if (db != NULL) {
   16703 		if (version != NULL) {
   16704 			dns_db_closeversion(db, &version, false);
   16705 		}
   16706 		dns_db_detach(&db);
   16707 	}
   16708 	dns_db_detach(&rawdb);
   16709 	dns_zone_idetach(&zone);
   16710 
   16711 	INSIST(version == NULL);
   16712 }
   16713 
   16714 static isc_result_t
   16715 zone_send_securedb(dns_zone_t *zone, dns_db_t *db) {
   16716 	isc_event_t *e;
   16717 	dns_db_t *dummy = NULL;
   16718 	dns_zone_t *secure = NULL;
   16719 
   16720 	e = isc_event_allocate(zone->secure->mctx, zone, DNS_EVENT_ZONESECUREDB,
   16721 			       receive_secure_db, zone->secure,
   16722 			       sizeof(struct secure_event));
   16723 	dns_db_attach(db, &dummy);
   16724 	((struct secure_event *)e)->db = dummy;
   16725 	INSIST(LOCKED_ZONE(zone->secure));
   16726 	zone_iattach(zone->secure, &secure);
   16727 	isc_task_send(zone->secure->task, &e);
   16728 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SENDSECURE);
   16729 	return (ISC_R_SUCCESS);
   16730 }
   16731 
   16732 isc_result_t
   16733 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   16734 	isc_result_t result;
   16735 	dns_zone_t *secure = NULL;
   16736 
   16737 	REQUIRE(DNS_ZONE_VALID(zone));
   16738 again:
   16739 	LOCK_ZONE(zone);
   16740 	if (inline_raw(zone)) {
   16741 		secure = zone->secure;
   16742 		INSIST(secure != zone);
   16743 		TRYLOCK_ZONE(result, secure);
   16744 		if (result != ISC_R_SUCCESS) {
   16745 			UNLOCK_ZONE(zone);
   16746 			secure = NULL;
   16747 			isc_thread_yield();
   16748 			goto again;
   16749 		}
   16750 	}
   16751 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
   16752 	result = zone_replacedb(zone, db, dump);
   16753 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
   16754 	if (secure != NULL) {
   16755 		UNLOCK_ZONE(secure);
   16756 	}
   16757 	UNLOCK_ZONE(zone);
   16758 	return (result);
   16759 }
   16760 
   16761 static isc_result_t
   16762 zone_replacedb(dns_zone_t *zone, dns_db_t *db, bool dump) {
   16763 	dns_dbversion_t *ver;
   16764 	isc_result_t result;
   16765 	unsigned int soacount = 0;
   16766 	unsigned int nscount = 0;
   16767 
   16768 	/*
   16769 	 * 'zone' and 'zone->db' locked by caller.
   16770 	 */
   16771 	REQUIRE(DNS_ZONE_VALID(zone));
   16772 	REQUIRE(LOCKED_ZONE(zone));
   16773 	if (inline_raw(zone)) {
   16774 		REQUIRE(LOCKED_ZONE(zone->secure));
   16775 	}
   16776 
   16777 	result = zone_get_from_db(zone, db, &nscount, &soacount, NULL, NULL,
   16778 				  NULL, NULL, NULL, NULL);
   16779 	if (result == ISC_R_SUCCESS) {
   16780 		if (soacount != 1) {
   16781 			dns_zone_log(zone, ISC_LOG_ERROR, "has %d SOA records",
   16782 				     soacount);
   16783 			result = DNS_R_BADZONE;
   16784 		}
   16785 		if (nscount == 0 && zone->type != dns_zone_key) {
   16786 			dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
   16787 			result = DNS_R_BADZONE;
   16788 		}
   16789 		if (result != ISC_R_SUCCESS) {
   16790 			return (result);
   16791 		}
   16792 	} else {
   16793 		dns_zone_log(zone, ISC_LOG_ERROR,
   16794 			     "retrieving SOA and NS records failed: %s",
   16795 			     dns_result_totext(result));
   16796 		return (result);
   16797 	}
   16798 
   16799 	result = check_nsec3param(zone, db);
   16800 	if (result != ISC_R_SUCCESS) {
   16801 		return (result);
   16802 	}
   16803 
   16804 	ver = NULL;
   16805 	dns_db_currentversion(db, &ver);
   16806 
   16807 	/*
   16808 	 * The initial version of a slave zone is always dumped;
   16809 	 * subsequent versions may be journaled instead if this
   16810 	 * is enabled in the configuration.
   16811 	 */
   16812 	if (zone->db != NULL && zone->journal != NULL &&
   16813 	    DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
   16814 	    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER))
   16815 	{
   16816 		uint32_t serial, oldserial;
   16817 
   16818 		dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
   16819 
   16820 		result = dns_db_getsoaserial(db, ver, &serial);
   16821 		if (result != ISC_R_SUCCESS) {
   16822 			dns_zone_log(zone, ISC_LOG_ERROR,
   16823 				     "ixfr-from-differences: unable to get "
   16824 				     "new serial");
   16825 			goto fail;
   16826 		}
   16827 
   16828 		/*
   16829 		 * This is checked in zone_postload() for master zones.
   16830 		 */
   16831 		result = zone_get_from_db(zone, zone->db, NULL, &soacount,
   16832 					  &oldserial, NULL, NULL, NULL, NULL,
   16833 					  NULL);
   16834 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   16835 		RUNTIME_CHECK(soacount > 0U);
   16836 		if ((zone->type == dns_zone_slave ||
   16837 		     (zone->type == dns_zone_redirect &&
   16838 		      zone->masters != NULL)) &&
   16839 		    !isc_serial_gt(serial, oldserial))
   16840 		{
   16841 			uint32_t serialmin, serialmax;
   16842 			serialmin = (oldserial + 1) & 0xffffffffU;
   16843 			serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
   16844 			dns_zone_log(zone, ISC_LOG_ERROR,
   16845 				     "ixfr-from-differences: failed: "
   16846 				     "new serial (%u) out of range [%u - %u]",
   16847 				     serial, serialmin, serialmax);
   16848 			result = ISC_R_RANGE;
   16849 			goto fail;
   16850 		}
   16851 
   16852 		result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
   16853 				     zone->journal);
   16854 		if (result != ISC_R_SUCCESS) {
   16855 			char strbuf[ISC_STRERRORSIZE];
   16856 			strerror_r(errno, strbuf, sizeof(strbuf));
   16857 			dns_zone_log(zone, ISC_LOG_ERROR,
   16858 				     "ixfr-from-differences: failed: "
   16859 				     "%s",
   16860 				     strbuf);
   16861 			goto fallback;
   16862 		}
   16863 		if (dump) {
   16864 			zone_needdump(zone, DNS_DUMP_DELAY);
   16865 		} else {
   16866 			zone_journal_compact(zone, zone->db, serial);
   16867 		}
   16868 		if (zone->type == dns_zone_master && inline_raw(zone)) {
   16869 			zone_send_secureserial(zone, serial);
   16870 		}
   16871 	} else {
   16872 	fallback:
   16873 		if (dump && zone->masterfile != NULL) {
   16874 			/*
   16875 			 * If DNS_ZONEFLG_FORCEXFER was set we don't want
   16876 			 * to keep the old masterfile.
   16877 			 */
   16878 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
   16879 			    remove(zone->masterfile) < 0 && errno != ENOENT)
   16880 			{
   16881 				char strbuf[ISC_STRERRORSIZE];
   16882 				strerror_r(errno, strbuf, sizeof(strbuf));
   16883 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16884 					      DNS_LOGMODULE_ZONE,
   16885 					      ISC_LOG_WARNING,
   16886 					      "unable to remove masterfile "
   16887 					      "'%s': '%s'",
   16888 					      zone->masterfile, strbuf);
   16889 			}
   16890 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0) {
   16891 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
   16892 			} else {
   16893 				zone_needdump(zone, 0);
   16894 			}
   16895 		}
   16896 		if (dump && zone->journal != NULL) {
   16897 			/*
   16898 			 * The in-memory database just changed, and
   16899 			 * because 'dump' is set, it didn't change by
   16900 			 * being loaded from disk.  Also, we have not
   16901 			 * journaled diffs for this change.
   16902 			 * Therefore, the on-disk journal is missing
   16903 			 * the deltas for this change.	Since it can
   16904 			 * no longer be used to bring the zone
   16905 			 * up-to-date, it is useless and should be
   16906 			 * removed.
   16907 			 */
   16908 			isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16909 				      DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
   16910 				      "removing journal file");
   16911 			if (remove(zone->journal) < 0 && errno != ENOENT) {
   16912 				char strbuf[ISC_STRERRORSIZE];
   16913 				strerror_r(errno, strbuf, sizeof(strbuf));
   16914 				isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
   16915 					      DNS_LOGMODULE_ZONE,
   16916 					      ISC_LOG_WARNING,
   16917 					      "unable to remove journal "
   16918 					      "'%s': '%s'",
   16919 					      zone->journal, strbuf);
   16920 			}
   16921 		}
   16922 
   16923 		if (inline_raw(zone)) {
   16924 			zone_send_securedb(zone, db);
   16925 		}
   16926 	}
   16927 
   16928 	dns_db_closeversion(db, &ver, false);
   16929 
   16930 	dns_zone_log(zone, ISC_LOG_DEBUG(3), "replacing zone database");
   16931 
   16932 	if (zone->db != NULL) {
   16933 		zone_detachdb(zone);
   16934 	}
   16935 	zone_attachdb(zone, db);
   16936 	dns_db_settask(zone->db, zone->task);
   16937 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   16938 	return (ISC_R_SUCCESS);
   16939 
   16940 fail:
   16941 	dns_db_closeversion(db, &ver, false);
   16942 	return (result);
   16943 }
   16944 
   16945 /* The caller must hold the dblock as a writer. */
   16946 static inline void
   16947 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
   16948 	REQUIRE(zone->db == NULL && db != NULL);
   16949 
   16950 	dns_db_attach(db, &zone->db);
   16951 }
   16952 
   16953 /* The caller must hold the dblock as a writer. */
   16954 static inline void
   16955 zone_detachdb(dns_zone_t *zone) {
   16956 	REQUIRE(zone->db != NULL);
   16957 
   16958 	dns_db_detach(&zone->db);
   16959 }
   16960 
   16961 static void
   16962 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
   16963 	isc_time_t now;
   16964 	bool again = false;
   16965 	unsigned int soacount;
   16966 	unsigned int nscount;
   16967 	uint32_t serial, refresh, retry, expire, minimum;
   16968 	isc_result_t xfrresult = result;
   16969 	bool free_needed;
   16970 	dns_zone_t *secure = NULL;
   16971 
   16972 	REQUIRE(DNS_ZONE_VALID(zone));
   16973 
   16974 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   16975 		      "zone transfer finished: %s", dns_result_totext(result));
   16976 
   16977 	/*
   16978 	 * Obtaining a lock on the zone->secure (see zone_send_secureserial)
   16979 	 * could result in a deadlock due to a LOR so we will spin if we
   16980 	 * can't obtain the both locks.
   16981 	 */
   16982 again:
   16983 	LOCK_ZONE(zone);
   16984 	if (inline_raw(zone)) {
   16985 		secure = zone->secure;
   16986 		INSIST(secure != zone);
   16987 		TRYLOCK_ZONE(result, secure);
   16988 		if (result != ISC_R_SUCCESS) {
   16989 			UNLOCK_ZONE(zone);
   16990 			secure = NULL;
   16991 			isc_thread_yield();
   16992 			goto again;
   16993 		}
   16994 	}
   16995 
   16996 	INSIST(DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH));
   16997 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
   16998 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
   16999 
   17000 	TIME_NOW(&now);
   17001 	switch (xfrresult) {
   17002 	case ISC_R_SUCCESS:
   17003 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   17004 	/* FALLTHROUGH */
   17005 	case DNS_R_UPTODATE:
   17006 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   17007 		/*
   17008 		 * Has the zone expired underneath us?
   17009 		 */
   17010 		ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17011 		if (zone->db == NULL) {
   17012 			ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17013 			goto same_master;
   17014 		}
   17015 
   17016 		/*
   17017 		 * Update the zone structure's data from the actual
   17018 		 * SOA received.
   17019 		 */
   17020 		nscount = 0;
   17021 		soacount = 0;
   17022 		INSIST(zone->db != NULL);
   17023 		result = zone_get_from_db(zone, zone->db, &nscount, &soacount,
   17024 					  &serial, &refresh, &retry, &expire,
   17025 					  &minimum, NULL);
   17026 		ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17027 		if (result == ISC_R_SUCCESS) {
   17028 			if (soacount != 1) {
   17029 				dns_zone_log(zone, ISC_LOG_ERROR,
   17030 					     "transferred zone "
   17031 					     "has %d SOA record%s",
   17032 					     soacount,
   17033 					     (soacount != 0) ? "s" : "");
   17034 			}
   17035 			if (nscount == 0) {
   17036 				dns_zone_log(zone, ISC_LOG_ERROR,
   17037 					     "transferred zone "
   17038 					     "has no NS records");
   17039 				if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
   17040 				{
   17041 					zone->refresh = DNS_ZONE_DEFAULTREFRESH;
   17042 					zone->retry = DNS_ZONE_DEFAULTRETRY;
   17043 				}
   17044 				DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17045 				zone_unload(zone);
   17046 				goto next_master;
   17047 			}
   17048 			zone->refresh = RANGE(refresh, zone->minrefresh,
   17049 					      zone->maxrefresh);
   17050 			zone->retry = RANGE(retry, zone->minretry,
   17051 					    zone->maxretry);
   17052 			zone->expire = RANGE(expire,
   17053 					     zone->refresh + zone->retry,
   17054 					     DNS_MAX_EXPIRE);
   17055 			zone->minimum = minimum;
   17056 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
   17057 		}
   17058 
   17059 		/*
   17060 		 * Set our next update/expire times.
   17061 		 */
   17062 		if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
   17063 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
   17064 			zone->refreshtime = now;
   17065 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17066 					  &zone->expiretime);
   17067 		} else {
   17068 			DNS_ZONE_JITTER_ADD(&now, zone->refresh,
   17069 					    &zone->refreshtime);
   17070 			DNS_ZONE_TIME_ADD(&now, zone->expire,
   17071 					  &zone->expiretime);
   17072 		}
   17073 		if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
   17074 			char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
   17075 			if (zone->tsigkey != NULL) {
   17076 				char namebuf[DNS_NAME_FORMATSIZE];
   17077 				dns_name_format(&zone->tsigkey->name, namebuf,
   17078 						sizeof(namebuf));
   17079 				snprintf(buf, sizeof(buf), ": TSIG '%s'",
   17080 					 namebuf);
   17081 			} else {
   17082 				buf[0] = '\0';
   17083 			}
   17084 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17085 				      ISC_LOG_INFO, "transferred serial %u%s",
   17086 				      serial, buf);
   17087 			if (inline_raw(zone)) {
   17088 				zone_send_secureserial(zone, serial);
   17089 			}
   17090 		}
   17091 
   17092 		/*
   17093 		 * This is not necessary if we just performed a AXFR
   17094 		 * however it is necessary for an IXFR / UPTODATE and
   17095 		 * won't hurt with an AXFR.
   17096 		 */
   17097 		if (zone->masterfile != NULL || zone->journal != NULL) {
   17098 			unsigned int delay = DNS_DUMP_DELAY;
   17099 
   17100 			result = ISC_R_FAILURE;
   17101 			if (zone->journal != NULL) {
   17102 				result = isc_file_settime(zone->journal, &now);
   17103 			}
   17104 			if (result != ISC_R_SUCCESS && zone->masterfile != NULL)
   17105 			{
   17106 				result = isc_file_settime(zone->masterfile,
   17107 							  &now);
   17108 			}
   17109 
   17110 			if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
   17111 			    result == ISC_R_FILENOTFOUND)
   17112 			{
   17113 				delay = 0;
   17114 			}
   17115 
   17116 			if ((result == ISC_R_SUCCESS ||
   17117 			     result == ISC_R_FILENOTFOUND) &&
   17118 			    zone->masterfile != NULL)
   17119 			{
   17120 				zone_needdump(zone, delay);
   17121 			} else if (result != ISC_R_SUCCESS) {
   17122 				dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17123 					      ISC_LOG_ERROR,
   17124 					      "transfer: could not set file "
   17125 					      "modification time of '%s': %s",
   17126 					      zone->masterfile,
   17127 					      dns_result_totext(result));
   17128 			}
   17129 		}
   17130 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
   17131 		inc_stats(zone, dns_zonestatscounter_xfrsuccess);
   17132 		break;
   17133 
   17134 	case DNS_R_BADIXFR:
   17135 		/* Force retry with AXFR. */
   17136 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOIXFR);
   17137 		goto same_master;
   17138 
   17139 	case DNS_R_TOOMANYRECORDS:
   17140 	case DNS_R_VERIFYFAILURE:
   17141 		DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
   17142 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17143 		break;
   17144 
   17145 	default:
   17146 	next_master:
   17147 		/*
   17148 		 * Skip to next failed / untried master.
   17149 		 */
   17150 		do {
   17151 			zone->curmaster++;
   17152 		} while (zone->curmaster < zone->masterscnt &&
   17153 			 zone->mastersok[zone->curmaster]);
   17154 		/* FALLTHROUGH */
   17155 	same_master:
   17156 		if (zone->curmaster >= zone->masterscnt) {
   17157 			zone->curmaster = 0;
   17158 			if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
   17159 			    !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
   17160 			{
   17161 				DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17162 				DNS_ZONE_SETFLAG(zone,
   17163 						 DNS_ZONEFLG_USEALTXFRSRC);
   17164 				while (zone->curmaster < zone->masterscnt &&
   17165 				       zone->mastersok[zone->curmaster]) {
   17166 					zone->curmaster++;
   17167 				}
   17168 				again = true;
   17169 			} else {
   17170 				DNS_ZONE_CLRFLAG(zone,
   17171 						 DNS_ZONEFLG_USEALTXFRSRC);
   17172 			}
   17173 		} else {
   17174 			DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
   17175 			again = true;
   17176 		}
   17177 		inc_stats(zone, dns_zonestatscounter_xfrfail);
   17178 		break;
   17179 	}
   17180 	zone_settimer(zone, &now);
   17181 
   17182 	/*
   17183 	 * If creating the transfer object failed, zone->xfr is NULL.
   17184 	 * Otherwise, we are called as the done callback of a zone
   17185 	 * transfer object that just entered its shutting-down
   17186 	 * state.  Since we are no longer responsible for shutting
   17187 	 * it down, we can detach our reference.
   17188 	 */
   17189 	if (zone->xfr != NULL) {
   17190 		dns_xfrin_detach(&zone->xfr);
   17191 	}
   17192 
   17193 	if (zone->tsigkey != NULL) {
   17194 		dns_tsigkey_detach(&zone->tsigkey);
   17195 	}
   17196 
   17197 	/*
   17198 	 * Handle any deferred journal compaction.
   17199 	 */
   17200 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
   17201 		dns_db_t *db = NULL;
   17202 		if (dns_zone_getdb(zone, &db) == ISC_R_SUCCESS) {
   17203 			zone_journal_compact(zone, db, zone->compact_serial);
   17204 			dns_db_detach(&db);
   17205 			DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
   17206 		}
   17207 	}
   17208 
   17209 	if (secure != NULL) {
   17210 		UNLOCK_ZONE(secure);
   17211 	}
   17212 	/*
   17213 	 * This transfer finishing freed up a transfer quota slot.
   17214 	 * Let any other zones waiting for quota have it.
   17215 	 */
   17216 	if (zone->zmgr != NULL &&
   17217 	    zone->statelist == &zone->zmgr->xfrin_in_progress) {
   17218 		UNLOCK_ZONE(zone);
   17219 		RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17220 		ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
   17221 		zone->statelist = NULL;
   17222 		zmgr_resume_xfrs(zone->zmgr, false);
   17223 		RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
   17224 		LOCK_ZONE(zone);
   17225 	}
   17226 
   17227 	/*
   17228 	 * Retry with a different server if necessary.
   17229 	 */
   17230 	if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   17231 		queue_soa_query(zone);
   17232 	}
   17233 
   17234 	isc_refcount_decrement(&zone->irefs);
   17235 	free_needed = exit_check(zone);
   17236 	UNLOCK_ZONE(zone);
   17237 	if (free_needed) {
   17238 		zone_free(zone);
   17239 	}
   17240 }
   17241 
   17242 static void
   17243 zone_loaddone(void *arg, isc_result_t result) {
   17244 	static char me[] = "zone_loaddone";
   17245 	dns_load_t *load = arg;
   17246 	dns_zone_t *zone;
   17247 	isc_result_t tresult;
   17248 	dns_zone_t *secure = NULL;
   17249 
   17250 	REQUIRE(DNS_LOAD_VALID(load));
   17251 	zone = load->zone;
   17252 
   17253 	ENTER;
   17254 
   17255 	/*
   17256 	 * If zone loading failed, remove the update db callbacks prior
   17257 	 * to calling the list of callbacks in the zone load structure.
   17258 	 */
   17259 	if (result != ISC_R_SUCCESS) {
   17260 		dns_zone_rpz_disable_db(zone, load->db);
   17261 		dns_zone_catz_disable_db(zone, load->db);
   17262 	}
   17263 
   17264 	tresult = dns_db_endload(load->db, &load->callbacks);
   17265 	if (tresult != ISC_R_SUCCESS &&
   17266 	    (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
   17267 	{
   17268 		result = tresult;
   17269 	}
   17270 
   17271 	/*
   17272 	 * Lock hierarchy: zmgr, zone, raw.
   17273 	 */
   17274 again:
   17275 	LOCK_ZONE(zone);
   17276 	INSIST(zone != zone->raw);
   17277 	if (inline_secure(zone)) {
   17278 		LOCK_ZONE(zone->raw);
   17279 	} else if (inline_raw(zone)) {
   17280 		secure = zone->secure;
   17281 		TRYLOCK_ZONE(tresult, secure);
   17282 		if (tresult != ISC_R_SUCCESS) {
   17283 			UNLOCK_ZONE(zone);
   17284 			secure = NULL;
   17285 			isc_thread_yield();
   17286 			goto again;
   17287 		}
   17288 	}
   17289 	(void)zone_postload(zone, load->db, load->loadtime, result);
   17290 	zonemgr_putio(&zone->readio);
   17291 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADING);
   17292 	zone_idetach(&load->callbacks.zone);
   17293 	/*
   17294 	 * Leave the zone frozen if the reload fails.
   17295 	 */
   17296 	if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
   17297 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_THAW))
   17298 	{
   17299 		zone->update_disabled = false;
   17300 	}
   17301 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_THAW);
   17302 	if (inline_secure(zone)) {
   17303 		UNLOCK_ZONE(zone->raw);
   17304 	} else if (secure != NULL) {
   17305 		UNLOCK_ZONE(secure);
   17306 	}
   17307 	UNLOCK_ZONE(zone);
   17308 
   17309 	load->magic = 0;
   17310 	dns_db_detach(&load->db);
   17311 	if (load->zone->lctx != NULL) {
   17312 		dns_loadctx_detach(&load->zone->lctx);
   17313 	}
   17314 	dns_zone_idetach(&load->zone);
   17315 	isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
   17316 }
   17317 
   17318 void
   17319 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
   17320 	REQUIRE(DNS_ZONE_VALID(zone));
   17321 	REQUIRE(table != NULL);
   17322 	REQUIRE(*table == NULL);
   17323 
   17324 	LOCK_ZONE(zone);
   17325 	if (zone->ssutable != NULL) {
   17326 		dns_ssutable_attach(zone->ssutable, table);
   17327 	}
   17328 	UNLOCK_ZONE(zone);
   17329 }
   17330 
   17331 void
   17332 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
   17333 	REQUIRE(DNS_ZONE_VALID(zone));
   17334 
   17335 	LOCK_ZONE(zone);
   17336 	if (zone->ssutable != NULL) {
   17337 		dns_ssutable_detach(&zone->ssutable);
   17338 	}
   17339 	if (table != NULL) {
   17340 		dns_ssutable_attach(table, &zone->ssutable);
   17341 	}
   17342 	UNLOCK_ZONE(zone);
   17343 }
   17344 
   17345 void
   17346 dns_zone_setsigvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17347 	REQUIRE(DNS_ZONE_VALID(zone));
   17348 
   17349 	zone->sigvalidityinterval = interval;
   17350 }
   17351 
   17352 uint32_t
   17353 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
   17354 	REQUIRE(DNS_ZONE_VALID(zone));
   17355 
   17356 	return (zone->sigvalidityinterval);
   17357 }
   17358 
   17359 void
   17360 dns_zone_setkeyvalidityinterval(dns_zone_t *zone, uint32_t interval) {
   17361 	REQUIRE(DNS_ZONE_VALID(zone));
   17362 
   17363 	zone->keyvalidityinterval = interval;
   17364 }
   17365 
   17366 uint32_t
   17367 dns_zone_getkeyvalidityinterval(dns_zone_t *zone) {
   17368 	REQUIRE(DNS_ZONE_VALID(zone));
   17369 
   17370 	return (zone->keyvalidityinterval);
   17371 }
   17372 
   17373 void
   17374 dns_zone_setsigresigninginterval(dns_zone_t *zone, uint32_t interval) {
   17375 	isc_time_t now;
   17376 
   17377 	REQUIRE(DNS_ZONE_VALID(zone));
   17378 
   17379 	LOCK_ZONE(zone);
   17380 	zone->sigresigninginterval = interval;
   17381 	set_resigntime(zone);
   17382 	if (zone->task != NULL) {
   17383 		TIME_NOW(&now);
   17384 		zone_settimer(zone, &now);
   17385 	}
   17386 	UNLOCK_ZONE(zone);
   17387 }
   17388 
   17389 uint32_t
   17390 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
   17391 	REQUIRE(DNS_ZONE_VALID(zone));
   17392 
   17393 	return (zone->sigresigninginterval);
   17394 }
   17395 
   17396 static void
   17397 queue_xfrin(dns_zone_t *zone) {
   17398 	const char me[] = "queue_xfrin";
   17399 	isc_result_t result;
   17400 	dns_zonemgr_t *zmgr = zone->zmgr;
   17401 
   17402 	ENTER;
   17403 
   17404 	INSIST(zone->statelist == NULL);
   17405 
   17406 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   17407 	ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
   17408 	isc_refcount_increment0(&zone->irefs);
   17409 	zone->statelist = &zmgr->waiting_for_xfrin;
   17410 	result = zmgr_start_xfrin_ifquota(zmgr, zone);
   17411 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   17412 
   17413 	if (result == ISC_R_QUOTA) {
   17414 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   17415 			      "zone transfer deferred due to quota");
   17416 	} else if (result != ISC_R_SUCCESS) {
   17417 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   17418 			      "starting zone transfer: %s",
   17419 			      isc_result_totext(result));
   17420 	}
   17421 }
   17422 
   17423 /*
   17424  * This event callback is called when a zone has received
   17425  * any necessary zone transfer quota.  This is the time
   17426  * to go ahead and start the transfer.
   17427  */
   17428 static void
   17429 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
   17430 	isc_result_t result = ISC_R_SUCCESS;
   17431 	dns_peer_t *peer = NULL;
   17432 	char master[ISC_SOCKADDR_FORMATSIZE];
   17433 	char source[ISC_SOCKADDR_FORMATSIZE];
   17434 	dns_rdatatype_t xfrtype;
   17435 	dns_zone_t *zone = event->ev_arg;
   17436 	isc_netaddr_t masterip;
   17437 	isc_sockaddr_t sourceaddr;
   17438 	isc_sockaddr_t masteraddr;
   17439 	isc_time_t now;
   17440 	const char *soa_before = "";
   17441 	isc_dscp_t dscp = -1;
   17442 	bool loaded;
   17443 
   17444 	UNUSED(task);
   17445 
   17446 	INSIST(task == zone->task);
   17447 
   17448 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   17449 		result = ISC_R_CANCELED;
   17450 		goto cleanup;
   17451 	}
   17452 
   17453 	TIME_NOW(&now);
   17454 
   17455 	isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
   17456 	if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
   17457 				    &zone->sourceaddr, &now))
   17458 	{
   17459 		isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
   17460 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   17461 			      "got_transfer_quota: skipping zone transfer as "
   17462 			      "master %s (source %s) is unreachable (cached)",
   17463 			      master, source);
   17464 		result = ISC_R_CANCELED;
   17465 		goto cleanup;
   17466 	}
   17467 
   17468 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   17469 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   17470 
   17471 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   17472 		soa_before = "SOA before ";
   17473 	}
   17474 	/*
   17475 	 * Decide whether we should request IXFR or AXFR.
   17476 	 */
   17477 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   17478 	loaded = (zone->db != NULL);
   17479 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   17480 
   17481 	if (!loaded) {
   17482 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17483 			      "no database exists yet, requesting AXFR of "
   17484 			      "initial version from %s",
   17485 			      master);
   17486 		xfrtype = dns_rdatatype_axfr;
   17487 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
   17488 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17489 			      "forced reload, requesting AXFR of "
   17490 			      "initial version from %s",
   17491 			      master);
   17492 		xfrtype = dns_rdatatype_axfr;
   17493 	} else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOIXFR)) {
   17494 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_DEBUG(1),
   17495 			      "retrying with AXFR from %s due to "
   17496 			      "previous IXFR failure",
   17497 			      master);
   17498 		xfrtype = dns_rdatatype_axfr;
   17499 		LOCK_ZONE(zone);
   17500 		DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOIXFR);
   17501 		UNLOCK_ZONE(zone);
   17502 	} else {
   17503 		bool use_ixfr = true;
   17504 		if (peer != NULL) {
   17505 			result = dns_peer_getrequestixfr(peer, &use_ixfr);
   17506 		}
   17507 		if (peer == NULL || result != ISC_R_SUCCESS) {
   17508 			use_ixfr = zone->requestixfr;
   17509 		}
   17510 		if (!use_ixfr) {
   17511 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17512 				      ISC_LOG_DEBUG(1),
   17513 				      "IXFR disabled, "
   17514 				      "requesting %sAXFR from %s",
   17515 				      soa_before, master);
   17516 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR)) {
   17517 				xfrtype = dns_rdatatype_soa;
   17518 			} else {
   17519 				xfrtype = dns_rdatatype_axfr;
   17520 			}
   17521 		} else {
   17522 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   17523 				      ISC_LOG_DEBUG(1),
   17524 				      "requesting IXFR from %s", master);
   17525 			xfrtype = dns_rdatatype_ixfr;
   17526 		}
   17527 	}
   17528 
   17529 	/*
   17530 	 * Determine if we should attempt to sign the request with TSIG.
   17531 	 */
   17532 	result = ISC_R_NOTFOUND;
   17533 
   17534 	/*
   17535 	 * First, look for a tsig key in the master statement, then
   17536 	 * try for a server key.
   17537 	 */
   17538 	if ((zone->masterkeynames != NULL) &&
   17539 	    (zone->masterkeynames[zone->curmaster] != NULL))
   17540 	{
   17541 		dns_view_t *view = dns_zone_getview(zone);
   17542 		dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
   17543 		result = dns_view_gettsig(view, keyname, &zone->tsigkey);
   17544 	}
   17545 	if (zone->tsigkey == NULL) {
   17546 		result = dns_view_getpeertsig(zone->view, &masterip,
   17547 					      &zone->tsigkey);
   17548 	}
   17549 
   17550 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   17551 		dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
   17552 			      "could not get TSIG key for zone transfer: %s",
   17553 			      isc_result_totext(result));
   17554 	}
   17555 
   17556 	if (zone->masterdscps != NULL) {
   17557 		dscp = zone->masterdscps[zone->curmaster];
   17558 	}
   17559 
   17560 	LOCK_ZONE(zone);
   17561 	masteraddr = zone->masteraddr;
   17562 	sourceaddr = zone->sourceaddr;
   17563 	switch (isc_sockaddr_pf(&masteraddr)) {
   17564 	case PF_INET:
   17565 		if (dscp == -1) {
   17566 			dscp = zone->xfrsource4dscp;
   17567 		}
   17568 		break;
   17569 	case PF_INET6:
   17570 		if (dscp == -1) {
   17571 			dscp = zone->xfrsource6dscp;
   17572 		}
   17573 		break;
   17574 	default:
   17575 		INSIST(0);
   17576 		ISC_UNREACHABLE();
   17577 	}
   17578 	UNLOCK_ZONE(zone);
   17579 	INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
   17580 	result = dns_xfrin_create(zone, xfrtype, &masteraddr, &sourceaddr, dscp,
   17581 				  zone->tsigkey, zone->mctx,
   17582 				  zone->zmgr->timermgr, zone->zmgr->socketmgr,
   17583 				  zone->task, zone_xfrdone, &zone->xfr);
   17584 	if (result == ISC_R_SUCCESS) {
   17585 		LOCK_ZONE(zone);
   17586 		if (xfrtype == dns_rdatatype_axfr) {
   17587 			if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
   17588 				inc_stats(zone, dns_zonestatscounter_axfrreqv4);
   17589 			} else {
   17590 				inc_stats(zone, dns_zonestatscounter_axfrreqv6);
   17591 			}
   17592 		} else if (xfrtype == dns_rdatatype_ixfr) {
   17593 			if (isc_sockaddr_pf(&masteraddr) == PF_INET) {
   17594 				inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
   17595 			} else {
   17596 				inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
   17597 			}
   17598 		}
   17599 		UNLOCK_ZONE(zone);
   17600 	}
   17601 cleanup:
   17602 	/*
   17603 	 * Any failure in this function is handled like a failed
   17604 	 * zone transfer.  This ensures that we get removed from
   17605 	 * zmgr->xfrin_in_progress.
   17606 	 */
   17607 	if (result != ISC_R_SUCCESS) {
   17608 		zone_xfrdone(zone, result);
   17609 	}
   17610 
   17611 	isc_event_free(&event);
   17612 }
   17613 
   17614 /*
   17615  * Update forwarding support.
   17616  */
   17617 
   17618 static void
   17619 forward_destroy(dns_forward_t *forward) {
   17620 	forward->magic = 0;
   17621 	if (forward->request != NULL) {
   17622 		dns_request_destroy(&forward->request);
   17623 	}
   17624 	if (forward->msgbuf != NULL) {
   17625 		isc_buffer_free(&forward->msgbuf);
   17626 	}
   17627 	if (forward->zone != NULL) {
   17628 		LOCK(&forward->zone->lock);
   17629 		if (ISC_LINK_LINKED(forward, link)) {
   17630 			ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
   17631 		}
   17632 		UNLOCK(&forward->zone->lock);
   17633 		dns_zone_idetach(&forward->zone);
   17634 	}
   17635 	isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
   17636 }
   17637 
   17638 static isc_result_t
   17639 sendtomaster(dns_forward_t *forward) {
   17640 	isc_result_t result;
   17641 	isc_sockaddr_t src;
   17642 	isc_dscp_t dscp = -1;
   17643 
   17644 	LOCK_ZONE(forward->zone);
   17645 
   17646 	if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
   17647 		UNLOCK_ZONE(forward->zone);
   17648 		return (ISC_R_CANCELED);
   17649 	}
   17650 
   17651 	if (forward->which >= forward->zone->masterscnt) {
   17652 		UNLOCK_ZONE(forward->zone);
   17653 		return (ISC_R_NOMORE);
   17654 	}
   17655 
   17656 	forward->addr = forward->zone->masters[forward->which];
   17657 	/*
   17658 	 * Always use TCP regardless of whether the original update
   17659 	 * used TCP.
   17660 	 * XXX The timeout may but a bit small if we are far down a
   17661 	 * transfer graph and the master has to try several masters.
   17662 	 */
   17663 	switch (isc_sockaddr_pf(&forward->addr)) {
   17664 	case PF_INET:
   17665 		src = forward->zone->xfrsource4;
   17666 		dscp = forward->zone->xfrsource4dscp;
   17667 		break;
   17668 	case PF_INET6:
   17669 		src = forward->zone->xfrsource6;
   17670 		dscp = forward->zone->xfrsource6dscp;
   17671 		break;
   17672 	default:
   17673 		result = ISC_R_NOTIMPLEMENTED;
   17674 		goto unlock;
   17675 	}
   17676 	result = dns_request_createraw(forward->zone->view->requestmgr,
   17677 				       forward->msgbuf, &src, &forward->addr,
   17678 				       dscp, forward->options, 15 /* XXX */, 0,
   17679 				       0, forward->zone->task, forward_callback,
   17680 				       forward, &forward->request);
   17681 	if (result == ISC_R_SUCCESS) {
   17682 		if (!ISC_LINK_LINKED(forward, link)) {
   17683 			ISC_LIST_APPEND(forward->zone->forwards, forward, link);
   17684 		}
   17685 	}
   17686 
   17687 unlock:
   17688 	UNLOCK_ZONE(forward->zone);
   17689 	return (result);
   17690 }
   17691 
   17692 static void
   17693 forward_callback(isc_task_t *task, isc_event_t *event) {
   17694 	const char me[] = "forward_callback";
   17695 	dns_requestevent_t *revent = (dns_requestevent_t *)event;
   17696 	dns_message_t *msg = NULL;
   17697 	char master[ISC_SOCKADDR_FORMATSIZE];
   17698 	isc_result_t result;
   17699 	dns_forward_t *forward;
   17700 	dns_zone_t *zone;
   17701 
   17702 	UNUSED(task);
   17703 
   17704 	forward = revent->ev_arg;
   17705 	INSIST(DNS_FORWARD_VALID(forward));
   17706 	zone = forward->zone;
   17707 	INSIST(DNS_ZONE_VALID(zone));
   17708 
   17709 	ENTER;
   17710 
   17711 	isc_sockaddr_format(&forward->addr, master, sizeof(master));
   17712 
   17713 	if (revent->result != ISC_R_SUCCESS) {
   17714 		dns_zone_log(zone, ISC_LOG_INFO,
   17715 			     "could not forward dynamic update to %s: %s",
   17716 			     master, dns_result_totext(revent->result));
   17717 		goto next_master;
   17718 	}
   17719 
   17720 	dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
   17721 
   17722 	result = dns_request_getresponse(revent->request, msg,
   17723 					 DNS_MESSAGEPARSE_PRESERVEORDER |
   17724 						 DNS_MESSAGEPARSE_CLONEBUFFER);
   17725 	if (result != ISC_R_SUCCESS) {
   17726 		goto next_master;
   17727 	}
   17728 
   17729 	switch (msg->rcode) {
   17730 	/*
   17731 	 * Pass these rcodes back to client.
   17732 	 */
   17733 	case dns_rcode_noerror:
   17734 	case dns_rcode_yxdomain:
   17735 	case dns_rcode_yxrrset:
   17736 	case dns_rcode_nxrrset:
   17737 	case dns_rcode_refused:
   17738 	case dns_rcode_nxdomain: {
   17739 		char rcode[128];
   17740 		isc_buffer_t rb;
   17741 
   17742 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   17743 		(void)dns_rcode_totext(msg->rcode, &rb);
   17744 		dns_zone_log(zone, ISC_LOG_INFO,
   17745 			     "forwarded dynamic update: "
   17746 			     "master %s returned: %.*s",
   17747 			     master, (int)rb.used, rcode);
   17748 		break;
   17749 	}
   17750 
   17751 	/* These should not occur if the primaries/zone are valid. */
   17752 	case dns_rcode_notzone:
   17753 	case dns_rcode_notauth: {
   17754 		char rcode[128];
   17755 		isc_buffer_t rb;
   17756 
   17757 		isc_buffer_init(&rb, rcode, sizeof(rcode));
   17758 		(void)dns_rcode_totext(msg->rcode, &rb);
   17759 		dns_zone_log(zone, ISC_LOG_WARNING,
   17760 			     "forwarding dynamic update: "
   17761 			     "unexpected response: master %s returned: %.*s",
   17762 			     master, (int)rb.used, rcode);
   17763 		goto next_master;
   17764 	}
   17765 
   17766 	/* Try another server for these rcodes. */
   17767 	case dns_rcode_formerr:
   17768 	case dns_rcode_servfail:
   17769 	case dns_rcode_notimp:
   17770 	case dns_rcode_badvers:
   17771 	default:
   17772 		goto next_master;
   17773 	}
   17774 
   17775 	/* call callback */
   17776 	(forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
   17777 	msg = NULL;
   17778 	dns_request_destroy(&forward->request);
   17779 	forward_destroy(forward);
   17780 	isc_event_free(&event);
   17781 	return;
   17782 
   17783 next_master:
   17784 	if (msg != NULL) {
   17785 		dns_message_detach(&msg);
   17786 	}
   17787 	isc_event_free(&event);
   17788 	forward->which++;
   17789 	dns_request_destroy(&forward->request);
   17790 	result = sendtomaster(forward);
   17791 	if (result != ISC_R_SUCCESS) {
   17792 		/* call callback */
   17793 		dns_zone_log(zone, ISC_LOG_DEBUG(3),
   17794 			     "exhausted dynamic update forwarder list");
   17795 		(forward->callback)(forward->callback_arg, result, NULL);
   17796 		forward_destroy(forward);
   17797 	}
   17798 }
   17799 
   17800 isc_result_t
   17801 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
   17802 		       dns_updatecallback_t callback, void *callback_arg) {
   17803 	dns_forward_t *forward;
   17804 	isc_result_t result;
   17805 	isc_region_t *mr;
   17806 
   17807 	REQUIRE(DNS_ZONE_VALID(zone));
   17808 	REQUIRE(msg != NULL);
   17809 	REQUIRE(callback != NULL);
   17810 
   17811 	forward = isc_mem_get(zone->mctx, sizeof(*forward));
   17812 
   17813 	forward->request = NULL;
   17814 	forward->zone = NULL;
   17815 	forward->msgbuf = NULL;
   17816 	forward->which = 0;
   17817 	forward->mctx = 0;
   17818 	forward->callback = callback;
   17819 	forward->callback_arg = callback_arg;
   17820 	ISC_LINK_INIT(forward, link);
   17821 	forward->magic = FORWARD_MAGIC;
   17822 	forward->options = DNS_REQUESTOPT_TCP;
   17823 	/*
   17824 	 * If we have a SIG(0) signed message we need to preserve the
   17825 	 * query id as that is included in the SIG(0) computation.
   17826 	 */
   17827 	if (msg->sig0 != NULL) {
   17828 		forward->options |= DNS_REQUESTOPT_FIXEDID;
   17829 	}
   17830 
   17831 	mr = dns_message_getrawmessage(msg);
   17832 	if (mr == NULL) {
   17833 		result = ISC_R_UNEXPECTEDEND;
   17834 		goto cleanup;
   17835 	}
   17836 
   17837 	isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
   17838 	result = isc_buffer_copyregion(forward->msgbuf, mr);
   17839 	if (result != ISC_R_SUCCESS) {
   17840 		goto cleanup;
   17841 	}
   17842 
   17843 	isc_mem_attach(zone->mctx, &forward->mctx);
   17844 	dns_zone_iattach(zone, &forward->zone);
   17845 	result = sendtomaster(forward);
   17846 
   17847 cleanup:
   17848 	if (result != ISC_R_SUCCESS) {
   17849 		forward_destroy(forward);
   17850 	}
   17851 	return (result);
   17852 }
   17853 
   17854 isc_result_t
   17855 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
   17856 	REQUIRE(DNS_ZONE_VALID(zone));
   17857 	REQUIRE(next != NULL && *next == NULL);
   17858 
   17859 	*next = ISC_LIST_NEXT(zone, link);
   17860 	if (*next == NULL) {
   17861 		return (ISC_R_NOMORE);
   17862 	} else {
   17863 		return (ISC_R_SUCCESS);
   17864 	}
   17865 }
   17866 
   17867 isc_result_t
   17868 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
   17869 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   17870 	REQUIRE(first != NULL && *first == NULL);
   17871 
   17872 	*first = ISC_LIST_HEAD(zmgr->zones);
   17873 	if (*first == NULL) {
   17874 		return (ISC_R_NOMORE);
   17875 	} else {
   17876 		return (ISC_R_SUCCESS);
   17877 	}
   17878 }
   17879 
   17880 /***
   17881  ***	Zone manager.
   17882  ***/
   17883 
   17884 isc_result_t
   17885 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
   17886 		   isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
   17887 		   dns_zonemgr_t **zmgrp) {
   17888 	dns_zonemgr_t *zmgr;
   17889 	isc_result_t result;
   17890 
   17891 	zmgr = isc_mem_get(mctx, sizeof(*zmgr));
   17892 	zmgr->mctx = NULL;
   17893 	isc_refcount_init(&zmgr->refs, 1);
   17894 	isc_mem_attach(mctx, &zmgr->mctx);
   17895 	zmgr->taskmgr = taskmgr;
   17896 	zmgr->timermgr = timermgr;
   17897 	zmgr->socketmgr = socketmgr;
   17898 	zmgr->zonetasks = NULL;
   17899 	zmgr->loadtasks = NULL;
   17900 	zmgr->mctxpool = NULL;
   17901 	zmgr->task = NULL;
   17902 	zmgr->notifyrl = NULL;
   17903 	zmgr->refreshrl = NULL;
   17904 	zmgr->startupnotifyrl = NULL;
   17905 	zmgr->startuprefreshrl = NULL;
   17906 	ISC_LIST_INIT(zmgr->zones);
   17907 	ISC_LIST_INIT(zmgr->waiting_for_xfrin);
   17908 	ISC_LIST_INIT(zmgr->xfrin_in_progress);
   17909 	memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
   17910 	result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
   17911 	if (result != ISC_R_SUCCESS) {
   17912 		goto free_mem;
   17913 	}
   17914 
   17915 	zmgr->transfersin = 10;
   17916 	zmgr->transfersperns = 2;
   17917 
   17918 	/* Unreachable lock. */
   17919 	result = isc_rwlock_init(&zmgr->urlock, 0, 0);
   17920 	if (result != ISC_R_SUCCESS) {
   17921 		goto free_rwlock;
   17922 	}
   17923 
   17924 	/* Create a single task for queueing of SOA queries. */
   17925 	result = isc_task_create(taskmgr, 1, &zmgr->task);
   17926 	if (result != ISC_R_SUCCESS) {
   17927 		goto free_urlock;
   17928 	}
   17929 
   17930 	isc_task_setname(zmgr->task, "zmgr", zmgr);
   17931 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   17932 					&zmgr->notifyrl);
   17933 	if (result != ISC_R_SUCCESS) {
   17934 		goto free_task;
   17935 	}
   17936 
   17937 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   17938 					&zmgr->refreshrl);
   17939 	if (result != ISC_R_SUCCESS) {
   17940 		goto free_notifyrl;
   17941 	}
   17942 
   17943 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   17944 					&zmgr->startupnotifyrl);
   17945 	if (result != ISC_R_SUCCESS) {
   17946 		goto free_refreshrl;
   17947 	}
   17948 
   17949 	result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
   17950 					&zmgr->startuprefreshrl);
   17951 	if (result != ISC_R_SUCCESS) {
   17952 		goto free_startupnotifyrl;
   17953 	}
   17954 
   17955 	/* default to 20 refresh queries / notifies per second. */
   17956 	setrl(zmgr->notifyrl, &zmgr->notifyrate, 20);
   17957 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, 20);
   17958 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, 20);
   17959 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, 20);
   17960 	isc_ratelimiter_setpushpop(zmgr->startupnotifyrl, true);
   17961 	isc_ratelimiter_setpushpop(zmgr->startuprefreshrl, true);
   17962 
   17963 	zmgr->iolimit = 1;
   17964 	zmgr->ioactive = 0;
   17965 	ISC_LIST_INIT(zmgr->high);
   17966 	ISC_LIST_INIT(zmgr->low);
   17967 
   17968 	isc_mutex_init(&zmgr->iolock);
   17969 
   17970 	zmgr->magic = ZONEMGR_MAGIC;
   17971 
   17972 	*zmgrp = zmgr;
   17973 	return (ISC_R_SUCCESS);
   17974 
   17975 #if 0
   17976  free_iolock:
   17977 	isc_mutex_destroy(&zmgr->iolock);
   17978 #endif /* if 0 */
   17979 free_startupnotifyrl:
   17980 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   17981 free_refreshrl:
   17982 	isc_ratelimiter_detach(&zmgr->refreshrl);
   17983 free_notifyrl:
   17984 	isc_ratelimiter_detach(&zmgr->notifyrl);
   17985 free_task:
   17986 	isc_task_detach(&zmgr->task);
   17987 free_urlock:
   17988 	isc_rwlock_destroy(&zmgr->urlock);
   17989 free_rwlock:
   17990 	isc_rwlock_destroy(&zmgr->rwlock);
   17991 free_mem:
   17992 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   17993 	isc_mem_detach(&mctx);
   17994 	return (result);
   17995 }
   17996 
   17997 isc_result_t
   17998 dns_zonemgr_createzone(dns_zonemgr_t *zmgr, dns_zone_t **zonep) {
   17999 	isc_result_t result;
   18000 	isc_mem_t *mctx = NULL;
   18001 	dns_zone_t *zone = NULL;
   18002 	void *item;
   18003 
   18004 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18005 	REQUIRE(zonep != NULL && *zonep == NULL);
   18006 
   18007 	if (zmgr->mctxpool == NULL) {
   18008 		return (ISC_R_FAILURE);
   18009 	}
   18010 
   18011 	item = isc_pool_get(zmgr->mctxpool);
   18012 	if (item == NULL) {
   18013 		return (ISC_R_FAILURE);
   18014 	}
   18015 
   18016 	isc_mem_attach((isc_mem_t *)item, &mctx);
   18017 	result = dns_zone_create(&zone, mctx);
   18018 	isc_mem_detach(&mctx);
   18019 
   18020 	if (result == ISC_R_SUCCESS) {
   18021 		*zonep = zone;
   18022 	}
   18023 
   18024 	return (result);
   18025 }
   18026 
   18027 isc_result_t
   18028 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18029 	isc_result_t result;
   18030 
   18031 	REQUIRE(DNS_ZONE_VALID(zone));
   18032 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18033 
   18034 	if (zmgr->zonetasks == NULL) {
   18035 		return (ISC_R_FAILURE);
   18036 	}
   18037 
   18038 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18039 	LOCK_ZONE(zone);
   18040 	REQUIRE(zone->task == NULL);
   18041 	REQUIRE(zone->timer == NULL);
   18042 	REQUIRE(zone->zmgr == NULL);
   18043 
   18044 	isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
   18045 	isc_taskpool_gettask(zmgr->loadtasks, &zone->loadtask);
   18046 
   18047 	/*
   18048 	 * Set the task name.  The tag will arbitrarily point to one
   18049 	 * of the zones sharing the task (in practice, the one
   18050 	 * to be managed last).
   18051 	 */
   18052 	isc_task_setname(zone->task, "zone", zone);
   18053 	isc_task_setname(zone->loadtask, "loadzone", zone);
   18054 
   18055 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   18056 				  NULL, zone->task, zone_timer, zone,
   18057 				  &zone->timer);
   18058 
   18059 	if (result != ISC_R_SUCCESS) {
   18060 		goto cleanup_tasks;
   18061 	}
   18062 
   18063 	/*
   18064 	 * The timer "holds" a iref.
   18065 	 */
   18066 	isc_refcount_increment0(&zone->irefs);
   18067 
   18068 	ISC_LIST_APPEND(zmgr->zones, zone, link);
   18069 	zone->zmgr = zmgr;
   18070 	isc_refcount_increment(&zmgr->refs);
   18071 
   18072 	goto unlock;
   18073 
   18074 cleanup_tasks:
   18075 	isc_task_detach(&zone->loadtask);
   18076 	isc_task_detach(&zone->task);
   18077 
   18078 unlock:
   18079 	UNLOCK_ZONE(zone);
   18080 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18081 	return (result);
   18082 }
   18083 
   18084 void
   18085 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18086 	bool free_now = false;
   18087 
   18088 	REQUIRE(DNS_ZONE_VALID(zone));
   18089 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18090 	REQUIRE(zone->zmgr == zmgr);
   18091 
   18092 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18093 	LOCK_ZONE(zone);
   18094 
   18095 	ISC_LIST_UNLINK(zmgr->zones, zone, link);
   18096 	zone->zmgr = NULL;
   18097 
   18098 	if (isc_refcount_decrement(&zmgr->refs) == 1) {
   18099 		free_now = true;
   18100 	}
   18101 
   18102 	UNLOCK_ZONE(zone);
   18103 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18104 
   18105 	if (free_now) {
   18106 		zonemgr_free(zmgr);
   18107 	}
   18108 	ENSURE(zone->zmgr == NULL);
   18109 }
   18110 
   18111 void
   18112 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
   18113 	REQUIRE(DNS_ZONEMGR_VALID(source));
   18114 	REQUIRE(target != NULL && *target == NULL);
   18115 
   18116 	isc_refcount_increment(&source->refs);
   18117 
   18118 	*target = source;
   18119 }
   18120 
   18121 void
   18122 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
   18123 	dns_zonemgr_t *zmgr;
   18124 
   18125 	REQUIRE(zmgrp != NULL);
   18126 	zmgr = *zmgrp;
   18127 	*zmgrp = NULL;
   18128 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18129 
   18130 	if (isc_refcount_decrement(&zmgr->refs) == 1) {
   18131 		zonemgr_free(zmgr);
   18132 	}
   18133 }
   18134 
   18135 isc_result_t
   18136 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
   18137 	dns_zone_t *p;
   18138 
   18139 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18140 
   18141 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18142 	for (p = ISC_LIST_HEAD(zmgr->zones); p != NULL;
   18143 	     p = ISC_LIST_NEXT(p, link)) {
   18144 		dns_zone_maintenance(p);
   18145 	}
   18146 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18147 
   18148 	/*
   18149 	 * Recent configuration changes may have increased the
   18150 	 * amount of available transfers quota.  Make sure any
   18151 	 * transfers currently blocked on quota get started if
   18152 	 * possible.
   18153 	 */
   18154 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18155 	zmgr_resume_xfrs(zmgr, true);
   18156 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18157 	return (ISC_R_SUCCESS);
   18158 }
   18159 
   18160 void
   18161 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
   18162 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18163 
   18164 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18165 	zmgr_resume_xfrs(zmgr, true);
   18166 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   18167 }
   18168 
   18169 void
   18170 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
   18171 	dns_zone_t *zone;
   18172 
   18173 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18174 
   18175 	isc_ratelimiter_shutdown(zmgr->notifyrl);
   18176 	isc_ratelimiter_shutdown(zmgr->refreshrl);
   18177 	isc_ratelimiter_shutdown(zmgr->startupnotifyrl);
   18178 	isc_ratelimiter_shutdown(zmgr->startuprefreshrl);
   18179 
   18180 	if (zmgr->task != NULL) {
   18181 		isc_task_destroy(&zmgr->task);
   18182 	}
   18183 	if (zmgr->zonetasks != NULL) {
   18184 		isc_taskpool_destroy(&zmgr->zonetasks);
   18185 	}
   18186 	if (zmgr->loadtasks != NULL) {
   18187 		isc_taskpool_destroy(&zmgr->loadtasks);
   18188 	}
   18189 	if (zmgr->mctxpool != NULL) {
   18190 		isc_pool_destroy(&zmgr->mctxpool);
   18191 	}
   18192 
   18193 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18194 	for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   18195 	     zone = ISC_LIST_NEXT(zone, link))
   18196 	{
   18197 		LOCK_ZONE(zone);
   18198 		forward_cancel(zone);
   18199 		UNLOCK_ZONE(zone);
   18200 	}
   18201 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   18202 }
   18203 
   18204 static isc_result_t
   18205 mctxinit(void **target, void *arg) {
   18206 	isc_mem_t *mctx = NULL;
   18207 
   18208 	UNUSED(arg);
   18209 
   18210 	REQUIRE(target != NULL && *target == NULL);
   18211 
   18212 	isc_mem_create(&mctx);
   18213 	isc_mem_setname(mctx, "zonemgr-pool", NULL);
   18214 
   18215 	*target = mctx;
   18216 	return (ISC_R_SUCCESS);
   18217 }
   18218 
   18219 static void
   18220 mctxfree(void **target) {
   18221 	isc_mem_t *mctx = *(isc_mem_t **)target;
   18222 	isc_mem_detach(&mctx);
   18223 	*target = NULL;
   18224 }
   18225 
   18226 #define ZONES_PER_TASK 100
   18227 #define ZONES_PER_MCTX 1000
   18228 
   18229 isc_result_t
   18230 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
   18231 	isc_result_t result;
   18232 	int ntasks = num_zones / ZONES_PER_TASK;
   18233 	int nmctx = num_zones / ZONES_PER_MCTX;
   18234 	isc_taskpool_t *pool = NULL;
   18235 	isc_pool_t *mctxpool = NULL;
   18236 
   18237 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18238 
   18239 	/*
   18240 	 * For anything fewer than 1000 zones we use 10 tasks in
   18241 	 * the task pools.  More than that, and we'll scale at one
   18242 	 * task per 100 zones.  Similarly, for anything smaller than
   18243 	 * 2000 zones we use 2 memory contexts, then scale at 1:1000.
   18244 	 */
   18245 	if (ntasks < 10) {
   18246 		ntasks = 10;
   18247 	}
   18248 	if (nmctx < 2) {
   18249 		nmctx = 2;
   18250 	}
   18251 
   18252 	/* Create or resize the zone task pools. */
   18253 	if (zmgr->zonetasks == NULL) {
   18254 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   18255 					     2, &pool);
   18256 	} else {
   18257 		result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
   18258 	}
   18259 
   18260 	if (result == ISC_R_SUCCESS) {
   18261 		zmgr->zonetasks = pool;
   18262 	}
   18263 
   18264 	pool = NULL;
   18265 	if (zmgr->loadtasks == NULL) {
   18266 		result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx, ntasks,
   18267 					     2, &pool);
   18268 	} else {
   18269 		result = isc_taskpool_expand(&zmgr->loadtasks, ntasks, &pool);
   18270 	}
   18271 
   18272 	if (result == ISC_R_SUCCESS) {
   18273 		zmgr->loadtasks = pool;
   18274 	}
   18275 
   18276 	/*
   18277 	 * We always set all tasks in the zone-load task pool to
   18278 	 * privileged.  This prevents other tasks in the system from
   18279 	 * running while the server task manager is in privileged
   18280 	 * mode.
   18281 	 *
   18282 	 * NOTE: If we start using task privileges for any other
   18283 	 * part of the system than zone tasks, then this will need to be
   18284 	 * revisted.  In that case we'd want to turn on privileges for
   18285 	 * zone tasks only when we were loading, and turn them off the
   18286 	 * rest of the time.  For now, however, it's okay to just
   18287 	 * set it and forget it.
   18288 	 */
   18289 	isc_taskpool_setprivilege(zmgr->loadtasks, true);
   18290 
   18291 	/* Create or resize the zone memory context pool. */
   18292 	if (zmgr->mctxpool == NULL) {
   18293 		result = isc_pool_create(zmgr->mctx, nmctx, mctxfree, mctxinit,
   18294 					 NULL, &mctxpool);
   18295 	} else {
   18296 		result = isc_pool_expand(&zmgr->mctxpool, nmctx, &mctxpool);
   18297 	}
   18298 
   18299 	if (result == ISC_R_SUCCESS) {
   18300 		zmgr->mctxpool = mctxpool;
   18301 	}
   18302 
   18303 	return (result);
   18304 }
   18305 
   18306 static void
   18307 zonemgr_free(dns_zonemgr_t *zmgr) {
   18308 	isc_mem_t *mctx;
   18309 
   18310 	INSIST(ISC_LIST_EMPTY(zmgr->zones));
   18311 
   18312 	zmgr->magic = 0;
   18313 
   18314 	isc_refcount_destroy(&zmgr->refs);
   18315 	isc_mutex_destroy(&zmgr->iolock);
   18316 	isc_ratelimiter_detach(&zmgr->notifyrl);
   18317 	isc_ratelimiter_detach(&zmgr->refreshrl);
   18318 	isc_ratelimiter_detach(&zmgr->startupnotifyrl);
   18319 	isc_ratelimiter_detach(&zmgr->startuprefreshrl);
   18320 
   18321 	isc_rwlock_destroy(&zmgr->urlock);
   18322 	isc_rwlock_destroy(&zmgr->rwlock);
   18323 	mctx = zmgr->mctx;
   18324 	isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
   18325 	isc_mem_detach(&mctx);
   18326 }
   18327 
   18328 void
   18329 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, uint32_t value) {
   18330 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18331 
   18332 	zmgr->transfersin = value;
   18333 }
   18334 
   18335 uint32_t
   18336 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
   18337 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18338 
   18339 	return (zmgr->transfersin);
   18340 }
   18341 
   18342 void
   18343 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, uint32_t value) {
   18344 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18345 
   18346 	zmgr->transfersperns = value;
   18347 }
   18348 
   18349 uint32_t
   18350 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
   18351 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18352 
   18353 	return (zmgr->transfersperns);
   18354 }
   18355 
   18356 /*
   18357  * Try to start a new incoming zone transfer to fill a quota
   18358  * slot that was just vacated.
   18359  *
   18360  * Requires:
   18361  *	The zone manager is locked by the caller.
   18362  */
   18363 static void
   18364 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, bool multi) {
   18365 	dns_zone_t *zone;
   18366 	dns_zone_t *next;
   18367 
   18368 	for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin); zone != NULL;
   18369 	     zone = next) {
   18370 		isc_result_t result;
   18371 		next = ISC_LIST_NEXT(zone, statelink);
   18372 		result = zmgr_start_xfrin_ifquota(zmgr, zone);
   18373 		if (result == ISC_R_SUCCESS) {
   18374 			if (multi) {
   18375 				continue;
   18376 			}
   18377 			/*
   18378 			 * We successfully filled the slot.  We're done.
   18379 			 */
   18380 			break;
   18381 		} else if (result == ISC_R_QUOTA) {
   18382 			/*
   18383 			 * Not enough quota.  This is probably the per-server
   18384 			 * quota, because we usually get called when a unit of
   18385 			 * global quota has just been freed.  Try the next
   18386 			 * zone, it may succeed if it uses another master.
   18387 			 */
   18388 			continue;
   18389 		} else {
   18390 			dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN,
   18391 				      ISC_LOG_DEBUG(1),
   18392 				      "starting zone transfer: %s",
   18393 				      isc_result_totext(result));
   18394 			break;
   18395 		}
   18396 	}
   18397 }
   18398 
   18399 /*
   18400  * Try to start an incoming zone transfer for 'zone', quota permitting.
   18401  *
   18402  * Requires:
   18403  *	The zone manager is locked by the caller.
   18404  *
   18405  * Returns:
   18406  *	ISC_R_SUCCESS	There was enough quota and we attempted to
   18407  *			start a transfer.  zone_xfrdone() has been or will
   18408  *			be called.
   18409  *	ISC_R_QUOTA	Not enough quota.
   18410  *	Others		Failure.
   18411  */
   18412 static isc_result_t
   18413 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
   18414 	dns_peer_t *peer = NULL;
   18415 	isc_netaddr_t masterip;
   18416 	uint32_t nxfrsin, nxfrsperns;
   18417 	dns_zone_t *x;
   18418 	uint32_t maxtransfersin, maxtransfersperns;
   18419 	isc_event_t *e;
   18420 
   18421 	/*
   18422 	 * If we are exiting just pretend we got quota so the zone will
   18423 	 * be cleaned up in the zone's task context.
   18424 	 */
   18425 	LOCK_ZONE(zone);
   18426 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
   18427 		UNLOCK_ZONE(zone);
   18428 		goto gotquota;
   18429 	}
   18430 
   18431 	/*
   18432 	 * Find any configured information about the server we'd
   18433 	 * like to transfer this zone from.
   18434 	 */
   18435 	isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
   18436 	(void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
   18437 	UNLOCK_ZONE(zone);
   18438 
   18439 	/*
   18440 	 * Determine the total maximum number of simultaneous
   18441 	 * transfers allowed, and the maximum for this specific
   18442 	 * master.
   18443 	 */
   18444 	maxtransfersin = zmgr->transfersin;
   18445 	maxtransfersperns = zmgr->transfersperns;
   18446 	if (peer != NULL) {
   18447 		(void)dns_peer_gettransfers(peer, &maxtransfersperns);
   18448 	}
   18449 
   18450 	/*
   18451 	 * Count the total number of transfers that are in progress,
   18452 	 * and the number of transfers in progress from this master.
   18453 	 * We linearly scan a list of all transfers; if this turns
   18454 	 * out to be too slow, we could hash on the master address.
   18455 	 */
   18456 	nxfrsin = nxfrsperns = 0;
   18457 	for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress); x != NULL;
   18458 	     x = ISC_LIST_NEXT(x, statelink))
   18459 	{
   18460 		isc_netaddr_t xip;
   18461 
   18462 		LOCK_ZONE(x);
   18463 		isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
   18464 		UNLOCK_ZONE(x);
   18465 
   18466 		nxfrsin++;
   18467 		if (isc_netaddr_equal(&xip, &masterip)) {
   18468 			nxfrsperns++;
   18469 		}
   18470 	}
   18471 
   18472 	/* Enforce quota. */
   18473 	if (nxfrsin >= maxtransfersin) {
   18474 		return (ISC_R_QUOTA);
   18475 	}
   18476 
   18477 	if (nxfrsperns >= maxtransfersperns) {
   18478 		return (ISC_R_QUOTA);
   18479 	}
   18480 
   18481 gotquota:
   18482 	/*
   18483 	 * We have sufficient quota.  Move the zone to the "xfrin_in_progress"
   18484 	 * list and send it an event to let it start the actual transfer in the
   18485 	 * context of its own task.
   18486 	 */
   18487 	e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
   18488 			       got_transfer_quota, zone, sizeof(isc_event_t));
   18489 
   18490 	LOCK_ZONE(zone);
   18491 	INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
   18492 	ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
   18493 	ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
   18494 	zone->statelist = &zmgr->xfrin_in_progress;
   18495 	isc_task_send(zone->task, &e);
   18496 	dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
   18497 		      "Transfer started.");
   18498 	UNLOCK_ZONE(zone);
   18499 
   18500 	return (ISC_R_SUCCESS);
   18501 }
   18502 
   18503 void
   18504 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, uint32_t iolimit) {
   18505 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18506 	REQUIRE(iolimit > 0);
   18507 
   18508 	zmgr->iolimit = iolimit;
   18509 }
   18510 
   18511 uint32_t
   18512 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
   18513 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18514 
   18515 	return (zmgr->iolimit);
   18516 }
   18517 
   18518 /*
   18519  * Get permission to request a file handle from the OS.
   18520  * An event will be sent to action when one is available.
   18521  * There are two queues available (high and low), the high
   18522  * queue will be serviced before the low one.
   18523  *
   18524  * zonemgr_putio() must be called after the event is delivered to
   18525  * 'action'.
   18526  */
   18527 
   18528 static isc_result_t
   18529 zonemgr_getio(dns_zonemgr_t *zmgr, bool high, isc_task_t *task,
   18530 	      isc_taskaction_t action, void *arg, dns_io_t **iop) {
   18531 	dns_io_t *io;
   18532 	bool queue;
   18533 
   18534 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18535 	REQUIRE(iop != NULL && *iop == NULL);
   18536 
   18537 	io = isc_mem_get(zmgr->mctx, sizeof(*io));
   18538 
   18539 	io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
   18540 				       action, arg, sizeof(*io->event));
   18541 
   18542 	io->zmgr = zmgr;
   18543 	io->high = high;
   18544 	io->task = NULL;
   18545 	isc_task_attach(task, &io->task);
   18546 	ISC_LINK_INIT(io, link);
   18547 	io->magic = IO_MAGIC;
   18548 
   18549 	LOCK(&zmgr->iolock);
   18550 	zmgr->ioactive++;
   18551 	queue = (zmgr->ioactive > zmgr->iolimit);
   18552 	if (queue) {
   18553 		if (io->high) {
   18554 			ISC_LIST_APPEND(zmgr->high, io, link);
   18555 		} else {
   18556 			ISC_LIST_APPEND(zmgr->low, io, link);
   18557 		}
   18558 	}
   18559 	UNLOCK(&zmgr->iolock);
   18560 	*iop = io;
   18561 
   18562 	if (!queue) {
   18563 		isc_task_send(io->task, &io->event);
   18564 	}
   18565 	return (ISC_R_SUCCESS);
   18566 }
   18567 
   18568 static void
   18569 zonemgr_putio(dns_io_t **iop) {
   18570 	dns_io_t *io;
   18571 	dns_io_t *next;
   18572 	dns_zonemgr_t *zmgr;
   18573 
   18574 	REQUIRE(iop != NULL);
   18575 	io = *iop;
   18576 	*iop = NULL;
   18577 	REQUIRE(DNS_IO_VALID(io));
   18578 
   18579 	INSIST(!ISC_LINK_LINKED(io, link));
   18580 	INSIST(io->event == NULL);
   18581 
   18582 	zmgr = io->zmgr;
   18583 	isc_task_detach(&io->task);
   18584 	io->magic = 0;
   18585 	isc_mem_put(zmgr->mctx, io, sizeof(*io));
   18586 
   18587 	LOCK(&zmgr->iolock);
   18588 	INSIST(zmgr->ioactive > 0);
   18589 	zmgr->ioactive--;
   18590 	next = HEAD(zmgr->high);
   18591 	if (next == NULL) {
   18592 		next = HEAD(zmgr->low);
   18593 	}
   18594 	if (next != NULL) {
   18595 		if (next->high) {
   18596 			ISC_LIST_UNLINK(zmgr->high, next, link);
   18597 		} else {
   18598 			ISC_LIST_UNLINK(zmgr->low, next, link);
   18599 		}
   18600 		INSIST(next->event != NULL);
   18601 	}
   18602 	UNLOCK(&zmgr->iolock);
   18603 	if (next != NULL) {
   18604 		isc_task_send(next->task, &next->event);
   18605 	}
   18606 }
   18607 
   18608 static void
   18609 zonemgr_cancelio(dns_io_t *io) {
   18610 	bool send_event = false;
   18611 
   18612 	REQUIRE(DNS_IO_VALID(io));
   18613 
   18614 	/*
   18615 	 * If we are queued to be run then dequeue.
   18616 	 */
   18617 	LOCK(&io->zmgr->iolock);
   18618 	if (ISC_LINK_LINKED(io, link)) {
   18619 		if (io->high) {
   18620 			ISC_LIST_UNLINK(io->zmgr->high, io, link);
   18621 		} else {
   18622 			ISC_LIST_UNLINK(io->zmgr->low, io, link);
   18623 		}
   18624 
   18625 		send_event = true;
   18626 		INSIST(io->event != NULL);
   18627 	}
   18628 	UNLOCK(&io->zmgr->iolock);
   18629 	if (send_event) {
   18630 		io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
   18631 		isc_task_send(io->task, &io->event);
   18632 	}
   18633 }
   18634 
   18635 static void
   18636 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
   18637 	char *buf;
   18638 	int buflen;
   18639 	isc_result_t result;
   18640 
   18641 	buflen = strlen(path) + strlen(templat) + 2;
   18642 
   18643 	buf = isc_mem_get(zone->mctx, buflen);
   18644 
   18645 	result = isc_file_template(path, templat, buf, buflen);
   18646 	if (result != ISC_R_SUCCESS) {
   18647 		goto cleanup;
   18648 	}
   18649 
   18650 	result = isc_file_renameunique(path, buf);
   18651 	if (result != ISC_R_SUCCESS) {
   18652 		goto cleanup;
   18653 	}
   18654 
   18655 	dns_zone_log(zone, ISC_LOG_WARNING,
   18656 		     "unable to load from '%s'; "
   18657 		     "renaming file to '%s' for failure analysis and "
   18658 		     "retransferring.",
   18659 		     path, buf);
   18660 
   18661 cleanup:
   18662 	isc_mem_put(zone->mctx, buf, buflen);
   18663 }
   18664 
   18665 static void
   18666 setrl(isc_ratelimiter_t *rl, unsigned int *rate, unsigned int value) {
   18667 	isc_interval_t interval;
   18668 	uint32_t s, ns;
   18669 	uint32_t pertic;
   18670 	isc_result_t result;
   18671 
   18672 	if (value == 0) {
   18673 		value = 1;
   18674 	}
   18675 
   18676 	if (value == 1) {
   18677 		s = 1;
   18678 		ns = 0;
   18679 		pertic = 1;
   18680 	} else if (value <= 10) {
   18681 		s = 0;
   18682 		ns = 1000000000 / value;
   18683 		pertic = 1;
   18684 	} else {
   18685 		s = 0;
   18686 		ns = (1000000000 / value) * 10;
   18687 		pertic = 10;
   18688 	}
   18689 
   18690 	isc_interval_set(&interval, s, ns);
   18691 
   18692 	result = isc_ratelimiter_setinterval(rl, &interval);
   18693 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   18694 	isc_ratelimiter_setpertic(rl, pertic);
   18695 
   18696 	*rate = value;
   18697 }
   18698 
   18699 void
   18700 dns_zonemgr_setnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   18701 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18702 
   18703 	setrl(zmgr->notifyrl, &zmgr->notifyrate, value);
   18704 }
   18705 
   18706 void
   18707 dns_zonemgr_setstartupnotifyrate(dns_zonemgr_t *zmgr, unsigned int value) {
   18708 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18709 
   18710 	setrl(zmgr->startupnotifyrl, &zmgr->startupnotifyrate, value);
   18711 }
   18712 
   18713 void
   18714 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
   18715 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18716 
   18717 	setrl(zmgr->refreshrl, &zmgr->serialqueryrate, value);
   18718 	/* XXXMPA separate out once we have the code to support this. */
   18719 	setrl(zmgr->startuprefreshrl, &zmgr->startupserialqueryrate, value);
   18720 }
   18721 
   18722 unsigned int
   18723 dns_zonemgr_getnotifyrate(dns_zonemgr_t *zmgr) {
   18724 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18725 
   18726 	return (zmgr->notifyrate);
   18727 }
   18728 
   18729 unsigned int
   18730 dns_zonemgr_getstartupnotifyrate(dns_zonemgr_t *zmgr) {
   18731 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18732 
   18733 	return (zmgr->startupnotifyrate);
   18734 }
   18735 
   18736 unsigned int
   18737 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
   18738 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18739 
   18740 	return (zmgr->serialqueryrate);
   18741 }
   18742 
   18743 bool
   18744 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   18745 			isc_sockaddr_t *local, isc_time_t *now) {
   18746 	unsigned int i;
   18747 	uint32_t seconds = isc_time_seconds(now);
   18748 	uint32_t count = 0;
   18749 
   18750 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18751 
   18752 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18753 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18754 		if (atomic_load(&zmgr->unreachable[i].expire) >= seconds &&
   18755 		    isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   18756 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   18757 		{
   18758 			atomic_store_relaxed(&zmgr->unreachable[i].last,
   18759 					     seconds);
   18760 			count = zmgr->unreachable[i].count;
   18761 			break;
   18762 		}
   18763 	}
   18764 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18765 	return (i < UNREACH_CACHE_SIZE && count > 1U);
   18766 }
   18767 
   18768 void
   18769 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   18770 			   isc_sockaddr_t *local) {
   18771 	unsigned int i;
   18772 	char master[ISC_SOCKADDR_FORMATSIZE];
   18773 	char source[ISC_SOCKADDR_FORMATSIZE];
   18774 
   18775 	isc_sockaddr_format(remote, master, sizeof(master));
   18776 	isc_sockaddr_format(local, source, sizeof(source));
   18777 
   18778 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18779 
   18780 	RWLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18781 	for (i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18782 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   18783 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   18784 		{
   18785 			atomic_store_relaxed(&zmgr->unreachable[i].expire, 0);
   18786 			break;
   18787 		}
   18788 	}
   18789 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_read);
   18790 }
   18791 
   18792 void
   18793 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
   18794 			   isc_sockaddr_t *local, isc_time_t *now) {
   18795 	uint32_t seconds = isc_time_seconds(now);
   18796 	uint32_t expire = 0, last = seconds;
   18797 	unsigned int slot = UNREACH_CACHE_SIZE, oldest = 0;
   18798 	bool update_entry = true;
   18799 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   18800 
   18801 	RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
   18802 	for (unsigned int i = 0; i < UNREACH_CACHE_SIZE; i++) {
   18803 		/* Existing entry? */
   18804 		if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
   18805 		    isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
   18806 		{
   18807 			update_entry = false;
   18808 			slot = i;
   18809 			expire = atomic_load_relaxed(
   18810 				&zmgr->unreachable[i].expire);
   18811 			break;
   18812 		}
   18813 		/* Pick first empty slot? */
   18814 		if (atomic_load_relaxed(&zmgr->unreachable[i].expire) < seconds)
   18815 		{
   18816 			slot = i;
   18817 			break;
   18818 		}
   18819 		/* The worst case, least recently used slot? */
   18820 		if (atomic_load_relaxed(&zmgr->unreachable[i].last) < last) {
   18821 			last = atomic_load_relaxed(&zmgr->unreachable[i].last);
   18822 			oldest = i;
   18823 		}
   18824 	}
   18825 
   18826 	/* We haven't found any existing or free slots, use the oldest */
   18827 	if (slot == UNREACH_CACHE_SIZE) {
   18828 		slot = oldest;
   18829 	}
   18830 
   18831 	if (expire < seconds) {
   18832 		/* Expired or new entry, reset count to 1 */
   18833 		zmgr->unreachable[slot].count = 1;
   18834 	} else {
   18835 		zmgr->unreachable[slot].count++;
   18836 	}
   18837 	atomic_store_relaxed(&zmgr->unreachable[slot].expire,
   18838 			     seconds + UNREACH_HOLD_TIME);
   18839 	atomic_store_relaxed(&zmgr->unreachable[slot].last, seconds);
   18840 	if (update_entry) {
   18841 		zmgr->unreachable[slot].remote = *remote;
   18842 		zmgr->unreachable[slot].local = *local;
   18843 	}
   18844 
   18845 	RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
   18846 }
   18847 
   18848 void
   18849 dns_zone_forcereload(dns_zone_t *zone) {
   18850 	REQUIRE(DNS_ZONE_VALID(zone));
   18851 
   18852 	if (zone->type == dns_zone_master ||
   18853 	    (zone->type == dns_zone_redirect && zone->masters == NULL))
   18854 	{
   18855 		return;
   18856 	}
   18857 
   18858 	LOCK_ZONE(zone);
   18859 	DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
   18860 	UNLOCK_ZONE(zone);
   18861 	dns_zone_refresh(zone);
   18862 }
   18863 
   18864 bool
   18865 dns_zone_isforced(dns_zone_t *zone) {
   18866 	REQUIRE(DNS_ZONE_VALID(zone));
   18867 
   18868 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
   18869 }
   18870 
   18871 isc_result_t
   18872 dns_zone_setstatistics(dns_zone_t *zone, bool on) {
   18873 	/*
   18874 	 * This function is obsoleted.
   18875 	 */
   18876 	UNUSED(zone);
   18877 	UNUSED(on);
   18878 	return (ISC_R_NOTIMPLEMENTED);
   18879 }
   18880 
   18881 uint64_t *
   18882 dns_zone_getstatscounters(dns_zone_t *zone) {
   18883 	/*
   18884 	 * This function is obsoleted.
   18885 	 */
   18886 	UNUSED(zone);
   18887 	return (NULL);
   18888 }
   18889 
   18890 void
   18891 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
   18892 	REQUIRE(DNS_ZONE_VALID(zone));
   18893 	REQUIRE(zone->stats == NULL);
   18894 
   18895 	LOCK_ZONE(zone);
   18896 	zone->stats = NULL;
   18897 	isc_stats_attach(stats, &zone->stats);
   18898 	UNLOCK_ZONE(zone);
   18899 }
   18900 
   18901 void
   18902 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
   18903 	REQUIRE(DNS_ZONE_VALID(zone));
   18904 
   18905 	LOCK_ZONE(zone);
   18906 	if (zone->requeststats_on && stats == NULL) {
   18907 		zone->requeststats_on = false;
   18908 	} else if (!zone->requeststats_on && stats != NULL) {
   18909 		if (zone->requeststats == NULL) {
   18910 			isc_stats_attach(stats, &zone->requeststats);
   18911 			zone->requeststats_on = true;
   18912 		}
   18913 	}
   18914 	UNLOCK_ZONE(zone);
   18915 }
   18916 
   18917 void
   18918 dns_zone_setrcvquerystats(dns_zone_t *zone, dns_stats_t *stats) {
   18919 	REQUIRE(DNS_ZONE_VALID(zone));
   18920 
   18921 	LOCK_ZONE(zone);
   18922 	if (zone->requeststats_on && stats != NULL) {
   18923 		if (zone->rcvquerystats == NULL) {
   18924 			dns_stats_attach(stats, &zone->rcvquerystats);
   18925 			zone->requeststats_on = true;
   18926 		}
   18927 	}
   18928 	UNLOCK_ZONE(zone);
   18929 }
   18930 
   18931 void
   18932 dns_zone_setdnssecsignstats(dns_zone_t *zone, dns_stats_t *stats) {
   18933 	REQUIRE(DNS_ZONE_VALID(zone));
   18934 
   18935 	LOCK_ZONE(zone);
   18936 	if (stats != NULL && zone->dnssecsignstats == NULL) {
   18937 		dns_stats_attach(stats, &zone->dnssecsignstats);
   18938 	}
   18939 	UNLOCK_ZONE(zone);
   18940 }
   18941 
   18942 dns_stats_t *
   18943 dns_zone_getdnssecsignstats(dns_zone_t *zone) {
   18944 	REQUIRE(DNS_ZONE_VALID(zone));
   18945 
   18946 	return (zone->dnssecsignstats);
   18947 }
   18948 
   18949 isc_stats_t *
   18950 dns_zone_getrequeststats(dns_zone_t *zone) {
   18951 	/*
   18952 	 * We don't lock zone for efficiency reason.  This is not catastrophic
   18953 	 * because requeststats must always be valid when requeststats_on is
   18954 	 * true.
   18955 	 * Some counters may be incremented while requeststats_on is becoming
   18956 	 * false, or some cannot be incremented just after the statistics are
   18957 	 * installed, but it shouldn't matter much in practice.
   18958 	 */
   18959 	if (zone->requeststats_on) {
   18960 		return (zone->requeststats);
   18961 	} else {
   18962 		return (NULL);
   18963 	}
   18964 }
   18965 
   18966 /*
   18967  * Return the received query stats bucket
   18968  * see note from dns_zone_getrequeststats()
   18969  */
   18970 dns_stats_t *
   18971 dns_zone_getrcvquerystats(dns_zone_t *zone) {
   18972 	if (zone->requeststats_on) {
   18973 		return (zone->rcvquerystats);
   18974 	} else {
   18975 		return (NULL);
   18976 	}
   18977 }
   18978 
   18979 void
   18980 dns_zone_dialup(dns_zone_t *zone) {
   18981 	REQUIRE(DNS_ZONE_VALID(zone));
   18982 
   18983 	zone_debuglog(zone, "dns_zone_dialup", 3, "notify = %d, refresh = %d",
   18984 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
   18985 		      DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
   18986 
   18987 	if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY)) {
   18988 		dns_zone_notify(zone);
   18989 	}
   18990 	if (zone->type != dns_zone_master && zone->masters != NULL &&
   18991 	    DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
   18992 	{
   18993 		dns_zone_refresh(zone);
   18994 	}
   18995 }
   18996 
   18997 void
   18998 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
   18999 	REQUIRE(DNS_ZONE_VALID(zone));
   19000 
   19001 	LOCK_ZONE(zone);
   19002 	DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
   19003 				       DNS_ZONEFLG_DIALREFRESH |
   19004 				       DNS_ZONEFLG_NOREFRESH);
   19005 	switch (dialup) {
   19006 	case dns_dialuptype_no:
   19007 		break;
   19008 	case dns_dialuptype_yes:
   19009 		DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
   19010 					DNS_ZONEFLG_DIALREFRESH |
   19011 					DNS_ZONEFLG_NOREFRESH));
   19012 		break;
   19013 	case dns_dialuptype_notify:
   19014 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19015 		break;
   19016 	case dns_dialuptype_notifypassive:
   19017 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
   19018 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19019 		break;
   19020 	case dns_dialuptype_refresh:
   19021 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
   19022 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19023 		break;
   19024 	case dns_dialuptype_passive:
   19025 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
   19026 		break;
   19027 	default:
   19028 		INSIST(0);
   19029 		ISC_UNREACHABLE();
   19030 	}
   19031 	UNLOCK_ZONE(zone);
   19032 }
   19033 
   19034 isc_result_t
   19035 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
   19036 	isc_result_t result = ISC_R_SUCCESS;
   19037 
   19038 	REQUIRE(DNS_ZONE_VALID(zone));
   19039 
   19040 	LOCK_ZONE(zone);
   19041 	result = dns_zone_setstring(zone, &zone->keydirectory, directory);
   19042 	UNLOCK_ZONE(zone);
   19043 
   19044 	return (result);
   19045 }
   19046 
   19047 const char *
   19048 dns_zone_getkeydirectory(dns_zone_t *zone) {
   19049 	REQUIRE(DNS_ZONE_VALID(zone));
   19050 
   19051 	return (zone->keydirectory);
   19052 }
   19053 
   19054 unsigned int
   19055 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
   19056 	dns_zone_t *zone;
   19057 	unsigned int count = 0;
   19058 
   19059 	REQUIRE(DNS_ZONEMGR_VALID(zmgr));
   19060 
   19061 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19062 	switch (state) {
   19063 	case DNS_ZONESTATE_XFERRUNNING:
   19064 		for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
   19065 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19066 		{
   19067 			count++;
   19068 		}
   19069 		break;
   19070 	case DNS_ZONESTATE_XFERDEFERRED:
   19071 		for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
   19072 		     zone != NULL; zone = ISC_LIST_NEXT(zone, statelink))
   19073 		{
   19074 			count++;
   19075 		}
   19076 		break;
   19077 	case DNS_ZONESTATE_SOAQUERY:
   19078 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19079 		     zone = ISC_LIST_NEXT(zone, link))
   19080 		{
   19081 			if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
   19082 				count++;
   19083 			}
   19084 		}
   19085 		break;
   19086 	case DNS_ZONESTATE_ANY:
   19087 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19088 		     zone = ISC_LIST_NEXT(zone, link))
   19089 		{
   19090 			dns_view_t *view = zone->view;
   19091 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   19092 				continue;
   19093 			}
   19094 			count++;
   19095 		}
   19096 		break;
   19097 	case DNS_ZONESTATE_AUTOMATIC:
   19098 		for (zone = ISC_LIST_HEAD(zmgr->zones); zone != NULL;
   19099 		     zone = ISC_LIST_NEXT(zone, link))
   19100 		{
   19101 			dns_view_t *view = zone->view;
   19102 			if (view != NULL && strcmp(view->name, "_bind") == 0) {
   19103 				continue;
   19104 			}
   19105 			if (zone->automatic) {
   19106 				count++;
   19107 			}
   19108 		}
   19109 		break;
   19110 	default:
   19111 		INSIST(0);
   19112 		ISC_UNREACHABLE();
   19113 	}
   19114 
   19115 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
   19116 
   19117 	return (count);
   19118 }
   19119 
   19120 isc_result_t
   19121 dns_zone_checknames(dns_zone_t *zone, const dns_name_t *name,
   19122 		    dns_rdata_t *rdata) {
   19123 	bool ok = true;
   19124 	bool fail = false;
   19125 	char namebuf[DNS_NAME_FORMATSIZE];
   19126 	char namebuf2[DNS_NAME_FORMATSIZE];
   19127 	char typebuf[DNS_RDATATYPE_FORMATSIZE];
   19128 	int level = ISC_LOG_WARNING;
   19129 	dns_name_t bad;
   19130 
   19131 	REQUIRE(DNS_ZONE_VALID(zone));
   19132 
   19133 	if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES) &&
   19134 	    rdata->type != dns_rdatatype_nsec3)
   19135 	{
   19136 		return (ISC_R_SUCCESS);
   19137 	}
   19138 
   19139 	if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL) ||
   19140 	    rdata->type == dns_rdatatype_nsec3)
   19141 	{
   19142 		level = ISC_LOG_ERROR;
   19143 		fail = true;
   19144 	}
   19145 
   19146 	ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, true);
   19147 	if (!ok) {
   19148 		dns_name_format(name, namebuf, sizeof(namebuf));
   19149 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   19150 		dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
   19151 			     dns_result_totext(DNS_R_BADOWNERNAME));
   19152 		if (fail) {
   19153 			return (DNS_R_BADOWNERNAME);
   19154 		}
   19155 	}
   19156 
   19157 	dns_name_init(&bad, NULL);
   19158 	ok = dns_rdata_checknames(rdata, name, &bad);
   19159 	if (!ok) {
   19160 		dns_name_format(name, namebuf, sizeof(namebuf));
   19161 		dns_name_format(&bad, namebuf2, sizeof(namebuf2));
   19162 		dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
   19163 		dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
   19164 			     namebuf2, dns_result_totext(DNS_R_BADNAME));
   19165 		if (fail) {
   19166 			return (DNS_R_BADNAME);
   19167 		}
   19168 	}
   19169 
   19170 	return (ISC_R_SUCCESS);
   19171 }
   19172 
   19173 void
   19174 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
   19175 	REQUIRE(DNS_ZONE_VALID(zone));
   19176 	zone->checkmx = checkmx;
   19177 }
   19178 
   19179 void
   19180 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
   19181 	REQUIRE(DNS_ZONE_VALID(zone));
   19182 	zone->checksrv = checksrv;
   19183 }
   19184 
   19185 void
   19186 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
   19187 	REQUIRE(DNS_ZONE_VALID(zone));
   19188 	zone->checkns = checkns;
   19189 }
   19190 
   19191 void
   19192 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
   19193 	REQUIRE(DNS_ZONE_VALID(zone));
   19194 
   19195 	LOCK_ZONE(zone);
   19196 	zone->isself = isself;
   19197 	zone->isselfarg = arg;
   19198 	UNLOCK_ZONE(zone);
   19199 }
   19200 
   19201 void
   19202 dns_zone_setnotifydelay(dns_zone_t *zone, uint32_t delay) {
   19203 	REQUIRE(DNS_ZONE_VALID(zone));
   19204 
   19205 	LOCK_ZONE(zone);
   19206 	zone->notifydelay = delay;
   19207 	UNLOCK_ZONE(zone);
   19208 }
   19209 
   19210 uint32_t
   19211 dns_zone_getnotifydelay(dns_zone_t *zone) {
   19212 	REQUIRE(DNS_ZONE_VALID(zone));
   19213 
   19214 	return (zone->notifydelay);
   19215 }
   19216 
   19217 isc_result_t
   19218 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   19219 		     bool deleteit) {
   19220 	isc_result_t result;
   19221 	REQUIRE(DNS_ZONE_VALID(zone));
   19222 
   19223 	dnssec_log(zone, ISC_LOG_NOTICE,
   19224 		   "dns_zone_signwithkey(algorithm=%u, keyid=%u)", algorithm,
   19225 		   keyid);
   19226 	LOCK_ZONE(zone);
   19227 	result = zone_signwithkey(zone, algorithm, keyid, deleteit);
   19228 	UNLOCK_ZONE(zone);
   19229 
   19230 	return (result);
   19231 }
   19232 
   19233 /*
   19234  * Called when a dynamic update for an NSEC3PARAM record is received.
   19235  *
   19236  * If set, transform the NSEC3 salt into human-readable form so that it can be
   19237  * logged.  Then call zone_addnsec3chain(), passing NSEC3PARAM RDATA to it.
   19238  */
   19239 isc_result_t
   19240 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
   19241 	isc_result_t result;
   19242 	char salt[255 * 2 + 1];
   19243 
   19244 	REQUIRE(DNS_ZONE_VALID(zone));
   19245 
   19246 	result = dns_nsec3param_salttotext(nsec3param, salt, sizeof(salt));
   19247 	RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19248 	dnssec_log(zone, ISC_LOG_NOTICE,
   19249 		   "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
   19250 		   nsec3param->hash, nsec3param->iterations, salt);
   19251 	LOCK_ZONE(zone);
   19252 	result = zone_addnsec3chain(zone, nsec3param);
   19253 	UNLOCK_ZONE(zone);
   19254 
   19255 	return (result);
   19256 }
   19257 
   19258 void
   19259 dns_zone_setnodes(dns_zone_t *zone, uint32_t nodes) {
   19260 	REQUIRE(DNS_ZONE_VALID(zone));
   19261 
   19262 	if (nodes == 0) {
   19263 		nodes = 1;
   19264 	}
   19265 	zone->nodes = nodes;
   19266 }
   19267 
   19268 void
   19269 dns_zone_setsignatures(dns_zone_t *zone, uint32_t signatures) {
   19270 	REQUIRE(DNS_ZONE_VALID(zone));
   19271 
   19272 	/*
   19273 	 * We treat signatures as a signed value so explicitly
   19274 	 * limit its range here.
   19275 	 */
   19276 	if (signatures > INT32_MAX) {
   19277 		signatures = INT32_MAX;
   19278 	} else if (signatures == 0) {
   19279 		signatures = 1;
   19280 	}
   19281 	zone->signatures = signatures;
   19282 }
   19283 
   19284 uint32_t
   19285 dns_zone_getsignatures(dns_zone_t *zone) {
   19286 	REQUIRE(DNS_ZONE_VALID(zone));
   19287 	return (zone->signatures);
   19288 }
   19289 
   19290 void
   19291 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
   19292 	REQUIRE(DNS_ZONE_VALID(zone));
   19293 	zone->privatetype = type;
   19294 }
   19295 
   19296 dns_rdatatype_t
   19297 dns_zone_getprivatetype(dns_zone_t *zone) {
   19298 	REQUIRE(DNS_ZONE_VALID(zone));
   19299 	return (zone->privatetype);
   19300 }
   19301 
   19302 static isc_result_t
   19303 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, uint16_t keyid,
   19304 		 bool deleteit) {
   19305 	dns_signing_t *signing;
   19306 	dns_signing_t *current;
   19307 	isc_result_t result = ISC_R_SUCCESS;
   19308 	isc_time_t now;
   19309 	dns_db_t *db = NULL;
   19310 
   19311 	signing = isc_mem_get(zone->mctx, sizeof *signing);
   19312 
   19313 	signing->magic = 0;
   19314 	signing->db = NULL;
   19315 	signing->dbiterator = NULL;
   19316 	signing->algorithm = algorithm;
   19317 	signing->keyid = keyid;
   19318 	signing->deleteit = deleteit;
   19319 	signing->done = false;
   19320 
   19321 	TIME_NOW(&now);
   19322 
   19323 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   19324 	if (zone->db != NULL) {
   19325 		dns_db_attach(zone->db, &db);
   19326 	}
   19327 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   19328 
   19329 	if (db == NULL) {
   19330 		result = ISC_R_NOTFOUND;
   19331 		goto cleanup;
   19332 	}
   19333 
   19334 	dns_db_attach(db, &signing->db);
   19335 
   19336 	for (current = ISC_LIST_HEAD(zone->signing); current != NULL;
   19337 	     current = ISC_LIST_NEXT(current, link))
   19338 	{
   19339 		if (current->db == signing->db &&
   19340 		    current->algorithm == signing->algorithm &&
   19341 		    current->keyid == signing->keyid)
   19342 		{
   19343 			if (current->deleteit != signing->deleteit) {
   19344 				current->done = true;
   19345 			} else {
   19346 				goto cleanup;
   19347 			}
   19348 		}
   19349 	}
   19350 
   19351 	result = dns_db_createiterator(signing->db, 0, &signing->dbiterator);
   19352 
   19353 	if (result == ISC_R_SUCCESS) {
   19354 		result = dns_dbiterator_first(signing->dbiterator);
   19355 	}
   19356 	if (result == ISC_R_SUCCESS) {
   19357 		dns_dbiterator_pause(signing->dbiterator);
   19358 		ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
   19359 		signing = NULL;
   19360 		if (isc_time_isepoch(&zone->signingtime)) {
   19361 			zone->signingtime = now;
   19362 			if (zone->task != NULL) {
   19363 				zone_settimer(zone, &now);
   19364 			}
   19365 		}
   19366 	}
   19367 
   19368 cleanup:
   19369 	if (signing != NULL) {
   19370 		if (signing->db != NULL) {
   19371 			dns_db_detach(&signing->db);
   19372 		}
   19373 		if (signing->dbiterator != NULL) {
   19374 			dns_dbiterator_destroy(&signing->dbiterator);
   19375 		}
   19376 		isc_mem_put(zone->mctx, signing, sizeof *signing);
   19377 	}
   19378 	if (db != NULL) {
   19379 		dns_db_detach(&db);
   19380 	}
   19381 	return (result);
   19382 }
   19383 
   19384 static void
   19385 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
   19386 	dns_dnsseckey_t *key;
   19387 	while (!ISC_LIST_EMPTY(*list)) {
   19388 		key = ISC_LIST_HEAD(*list);
   19389 		ISC_LIST_UNLINK(*list, key, link);
   19390 		dns_dnsseckey_destroy(mctx, &key);
   19391 	}
   19392 }
   19393 
   19394 /* Called once; *timep should be set to the current time. */
   19395 static isc_result_t
   19396 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
   19397 	isc_result_t result;
   19398 	isc_stdtime_t now, then = 0, event;
   19399 	int i;
   19400 
   19401 	now = *timep;
   19402 
   19403 	for (i = 0; i <= DST_MAX_TIMES; i++) {
   19404 		result = dst_key_gettime(key, i, &event);
   19405 		if (result == ISC_R_SUCCESS && event > now &&
   19406 		    (then == 0 || event < then)) {
   19407 			then = event;
   19408 		}
   19409 	}
   19410 
   19411 	if (then != 0) {
   19412 		*timep = then;
   19413 		return (ISC_R_SUCCESS);
   19414 	}
   19415 
   19416 	return (ISC_R_NOTFOUND);
   19417 }
   19418 
   19419 static isc_result_t
   19420 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
   19421 	  const dns_rdata_t *rdata, bool *flag) {
   19422 	dns_rdataset_t rdataset;
   19423 	dns_dbnode_t *node = NULL;
   19424 	isc_result_t result;
   19425 
   19426 	dns_rdataset_init(&rdataset);
   19427 	if (rdata->type == dns_rdatatype_nsec3) {
   19428 		CHECK(dns_db_findnsec3node(db, name, false, &node));
   19429 	} else {
   19430 		CHECK(dns_db_findnode(db, name, false, &node));
   19431 	}
   19432 	result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
   19433 				     (isc_stdtime_t)0, &rdataset, NULL);
   19434 	if (result == ISC_R_NOTFOUND) {
   19435 		*flag = false;
   19436 		result = ISC_R_SUCCESS;
   19437 		goto failure;
   19438 	}
   19439 
   19440 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   19441 	     result = dns_rdataset_next(&rdataset))
   19442 	{
   19443 		dns_rdata_t myrdata = DNS_RDATA_INIT;
   19444 		dns_rdataset_current(&rdataset, &myrdata);
   19445 		if (!dns_rdata_compare(&myrdata, rdata)) {
   19446 			break;
   19447 		}
   19448 	}
   19449 	dns_rdataset_disassociate(&rdataset);
   19450 	if (result == ISC_R_SUCCESS) {
   19451 		*flag = true;
   19452 	} else if (result == ISC_R_NOMORE) {
   19453 		*flag = false;
   19454 		result = ISC_R_SUCCESS;
   19455 	}
   19456 
   19457 failure:
   19458 	if (node != NULL) {
   19459 		dns_db_detachnode(db, &node);
   19460 	}
   19461 	return (result);
   19462 }
   19463 
   19464 /*
   19465  * Add records to signal the state of signing or of key removal.
   19466  */
   19467 static isc_result_t
   19468 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
   19469 		    dns_dbversion_t *ver, dns_diff_t *diff, bool sign_all) {
   19470 	dns_difftuple_t *tuple, *newtuple = NULL;
   19471 	dns_rdata_dnskey_t dnskey;
   19472 	dns_rdata_t rdata = DNS_RDATA_INIT;
   19473 	bool flag;
   19474 	isc_region_t r;
   19475 	isc_result_t result = ISC_R_SUCCESS;
   19476 	uint16_t keyid;
   19477 	unsigned char buf[5];
   19478 	dns_name_t *name = dns_db_origin(db);
   19479 
   19480 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   19481 	     tuple = ISC_LIST_NEXT(tuple, link))
   19482 	{
   19483 		if (tuple->rdata.type != dns_rdatatype_dnskey) {
   19484 			continue;
   19485 		}
   19486 
   19487 		result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
   19488 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19489 		if ((dnskey.flags & (DNS_KEYFLAG_OWNERMASK |
   19490 				     DNS_KEYTYPE_NOAUTH)) != DNS_KEYOWNER_ZONE)
   19491 		{
   19492 			continue;
   19493 		}
   19494 
   19495 		dns_rdata_toregion(&tuple->rdata, &r);
   19496 
   19497 		keyid = dst_region_computeid(&r);
   19498 
   19499 		buf[0] = dnskey.algorithm;
   19500 		buf[1] = (keyid & 0xff00) >> 8;
   19501 		buf[2] = (keyid & 0xff);
   19502 		buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
   19503 		buf[4] = 0;
   19504 		rdata.data = buf;
   19505 		rdata.length = sizeof(buf);
   19506 		rdata.type = privatetype;
   19507 		rdata.rdclass = tuple->rdata.rdclass;
   19508 
   19509 		if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
   19510 			CHECK(rr_exists(db, ver, name, &rdata, &flag));
   19511 			if (flag) {
   19512 				continue;
   19513 			}
   19514 
   19515 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
   19516 						   name, 0, &rdata, &newtuple));
   19517 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   19518 			INSIST(newtuple == NULL);
   19519 		}
   19520 
   19521 		/*
   19522 		 * Remove any record which says this operation has already
   19523 		 * completed.
   19524 		 */
   19525 		buf[4] = 1;
   19526 		CHECK(rr_exists(db, ver, name, &rdata, &flag));
   19527 		if (flag) {
   19528 			CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
   19529 						   name, 0, &rdata, &newtuple));
   19530 			CHECK(do_one_tuple(&newtuple, db, ver, diff));
   19531 			INSIST(newtuple == NULL);
   19532 		}
   19533 	}
   19534 failure:
   19535 	return (result);
   19536 }
   19537 
   19538 /*
   19539  * See if dns__zone_updatesigs() will update signature for RRset 'rrtype' at
   19540  * the apex, and if not tickle them and cause to sign so that newly activated
   19541  * keys are used.
   19542  */
   19543 static isc_result_t
   19544 tickle_apex_rrset(dns_rdatatype_t rrtype, dns_zone_t *zone, dns_db_t *db,
   19545 		  dns_dbversion_t *ver, isc_stdtime_t now, dns_diff_t *diff,
   19546 		  dns__zonediff_t *zonediff, dst_key_t **keys,
   19547 		  unsigned int nkeys, isc_stdtime_t inception,
   19548 		  isc_stdtime_t keyexpire, bool check_ksk,
   19549 		  bool keyset_kskonly) {
   19550 	dns_difftuple_t *tuple;
   19551 	isc_result_t result;
   19552 
   19553 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   19554 	     tuple = ISC_LIST_NEXT(tuple, link))
   19555 	{
   19556 		if (tuple->rdata.type == rrtype &&
   19557 		    dns_name_equal(&tuple->name, &zone->origin)) {
   19558 			break;
   19559 		}
   19560 	}
   19561 
   19562 	if (tuple == NULL) {
   19563 		result = del_sigs(zone, db, ver, &zone->origin, rrtype,
   19564 				  zonediff, keys, nkeys, now, false);
   19565 		if (result != ISC_R_SUCCESS) {
   19566 			dnssec_log(zone, ISC_LOG_ERROR,
   19567 				   "sign_apex:del_sigs -> %s",
   19568 				   dns_result_totext(result));
   19569 			return (result);
   19570 		}
   19571 		result = add_sigs(db, ver, &zone->origin, zone, rrtype,
   19572 				  zonediff->diff, keys, nkeys, zone->mctx,
   19573 				  inception, keyexpire, check_ksk,
   19574 				  keyset_kskonly);
   19575 		if (result != ISC_R_SUCCESS) {
   19576 			dnssec_log(zone, ISC_LOG_ERROR,
   19577 				   "sign_apex:add_sigs -> %s",
   19578 				   dns_result_totext(result));
   19579 			return (result);
   19580 		}
   19581 	}
   19582 
   19583 	return (ISC_R_SUCCESS);
   19584 }
   19585 
   19586 static isc_result_t
   19587 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19588 	  isc_stdtime_t now, dns_diff_t *diff, dns__zonediff_t *zonediff) {
   19589 	isc_result_t result;
   19590 	isc_stdtime_t inception, soaexpire, keyexpire;
   19591 	bool check_ksk, keyset_kskonly;
   19592 	dst_key_t *zone_keys[DNS_MAXZONEKEYS];
   19593 	unsigned int nkeys = 0, i;
   19594 
   19595 	result = dns__zone_findkeys(zone, db, ver, now, zone->mctx,
   19596 				    DNS_MAXZONEKEYS, zone_keys, &nkeys);
   19597 	if (result != ISC_R_SUCCESS) {
   19598 		dnssec_log(zone, ISC_LOG_ERROR,
   19599 			   "sign_apex:dns__zone_findkeys -> %s",
   19600 			   dns_result_totext(result));
   19601 		return (result);
   19602 	}
   19603 
   19604 	inception = now - 3600; /* Allow for clock skew. */
   19605 	soaexpire = now + dns_zone_getsigvalidityinterval(zone);
   19606 
   19607 	keyexpire = dns_zone_getkeyvalidityinterval(zone);
   19608 	if (keyexpire == 0) {
   19609 		keyexpire = soaexpire - 1;
   19610 	} else {
   19611 		keyexpire += now;
   19612 	}
   19613 
   19614 	check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
   19615 	keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
   19616 
   19617 	/*
   19618 	 * See if dns__zone_updatesigs() will update DNSKEY/CDS/CDNSKEY
   19619 	 * signature and if not cause them to sign so that newly activated
   19620 	 * keys are used.
   19621 	 */
   19622 	result = tickle_apex_rrset(dns_rdatatype_dnskey, zone, db, ver, now,
   19623 				   diff, zonediff, zone_keys, nkeys, inception,
   19624 				   keyexpire, check_ksk, keyset_kskonly);
   19625 	if (result != ISC_R_SUCCESS) {
   19626 		goto failure;
   19627 	}
   19628 	result = tickle_apex_rrset(dns_rdatatype_cds, zone, db, ver, now, diff,
   19629 				   zonediff, zone_keys, nkeys, inception,
   19630 				   keyexpire, check_ksk, keyset_kskonly);
   19631 	if (result != ISC_R_SUCCESS) {
   19632 		goto failure;
   19633 	}
   19634 	result = tickle_apex_rrset(dns_rdatatype_cdnskey, zone, db, ver, now,
   19635 				   diff, zonediff, zone_keys, nkeys, inception,
   19636 				   keyexpire, check_ksk, keyset_kskonly);
   19637 	if (result != ISC_R_SUCCESS) {
   19638 		goto failure;
   19639 	}
   19640 
   19641 	result = dns__zone_updatesigs(diff, db, ver, zone_keys, nkeys, zone,
   19642 				      inception, soaexpire, keyexpire, now,
   19643 				      check_ksk, keyset_kskonly, zonediff);
   19644 
   19645 	if (result != ISC_R_SUCCESS) {
   19646 		dnssec_log(zone, ISC_LOG_ERROR,
   19647 			   "sign_apex:dns__zone_updatesigs -> %s",
   19648 			   dns_result_totext(result));
   19649 		goto failure;
   19650 	}
   19651 
   19652 failure:
   19653 	for (i = 0; i < nkeys; i++) {
   19654 		dst_key_free(&zone_keys[i]);
   19655 	}
   19656 	return (result);
   19657 }
   19658 
   19659 /*
   19660  * Prevent the zone entering a inconsistent state where
   19661  * NSEC only DNSKEYs are present with NSEC3 chains.
   19662  * See update.c:check_dnssec()
   19663  */
   19664 static bool
   19665 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19666 	    dns_diff_t *diff) {
   19667 	isc_result_t result;
   19668 	dns_difftuple_t *tuple;
   19669 	bool nseconly = false, nsec3 = false;
   19670 	dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
   19671 
   19672 	/* Scan the tuples for an NSEC-only DNSKEY */
   19673 	for (tuple = ISC_LIST_HEAD(diff->tuples); tuple != NULL;
   19674 	     tuple = ISC_LIST_NEXT(tuple, link))
   19675 	{
   19676 		uint8_t alg;
   19677 		if (tuple->rdata.type != dns_rdatatype_dnskey ||
   19678 		    tuple->op != DNS_DIFFOP_ADD) {
   19679 			continue;
   19680 		}
   19681 
   19682 		alg = tuple->rdata.data[3];
   19683 		if (alg == DST_ALG_RSASHA1) {
   19684 			nseconly = true;
   19685 			break;
   19686 		}
   19687 	}
   19688 
   19689 	/* Check existing DB for NSEC-only DNSKEY */
   19690 	if (!nseconly) {
   19691 		result = dns_nsec_nseconly(db, ver, &nseconly);
   19692 		if (result == ISC_R_NOTFOUND) {
   19693 			result = ISC_R_SUCCESS;
   19694 		}
   19695 		CHECK(result);
   19696 	}
   19697 
   19698 	/* Check existing DB for NSEC3 */
   19699 	if (!nsec3) {
   19700 		CHECK(dns_nsec3_activex(db, ver, false, privatetype, &nsec3));
   19701 	}
   19702 
   19703 	/* Refuse to allow NSEC3 with NSEC-only keys */
   19704 	if (nseconly && nsec3) {
   19705 		dnssec_log(zone, ISC_LOG_ERROR,
   19706 			   "NSEC only DNSKEYs and NSEC3 chains not allowed");
   19707 		goto failure;
   19708 	}
   19709 
   19710 	return (true);
   19711 
   19712 failure:
   19713 	return (false);
   19714 }
   19715 
   19716 static isc_result_t
   19717 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19718 		 dns_diff_t *diff) {
   19719 	isc_result_t result;
   19720 	dns_dbnode_t *node = NULL;
   19721 	dns_rdataset_t rdataset;
   19722 
   19723 	dns_rdataset_init(&rdataset);
   19724 	CHECK(dns_db_getoriginnode(db, &node));
   19725 
   19726 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   19727 				     dns_rdatatype_none, 0, &rdataset, NULL);
   19728 	if (dns_rdataset_isassociated(&rdataset)) {
   19729 		dns_rdataset_disassociate(&rdataset);
   19730 	}
   19731 	if (result != ISC_R_NOTFOUND) {
   19732 		goto failure;
   19733 	}
   19734 
   19735 	result = dns_nsec3param_deletechains(db, ver, zone, true, diff);
   19736 
   19737 failure:
   19738 	if (node != NULL) {
   19739 		dns_db_detachnode(db, &node);
   19740 	}
   19741 	return (result);
   19742 }
   19743 
   19744 /*
   19745  * Given an RRSIG rdataset and an algorithm, determine whether there
   19746  * are any signatures using that algorithm.
   19747  */
   19748 static bool
   19749 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
   19750 	dns_rdata_t rdata = DNS_RDATA_INIT;
   19751 	dns_rdata_rrsig_t rrsig;
   19752 	isc_result_t result;
   19753 
   19754 	REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
   19755 	if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
   19756 		return (false);
   19757 	}
   19758 
   19759 	for (result = dns_rdataset_first(rdataset); result == ISC_R_SUCCESS;
   19760 	     result = dns_rdataset_next(rdataset))
   19761 	{
   19762 		dns_rdataset_current(rdataset, &rdata);
   19763 		result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
   19764 		RUNTIME_CHECK(result == ISC_R_SUCCESS);
   19765 		dns_rdata_reset(&rdata);
   19766 		if (rrsig.algorithm == alg) {
   19767 			return (true);
   19768 		}
   19769 	}
   19770 
   19771 	return (false);
   19772 }
   19773 
   19774 static isc_result_t
   19775 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
   19776 	   dns_diff_t *diff) {
   19777 	dns_name_t *origin;
   19778 	bool build_nsec3;
   19779 	isc_result_t result;
   19780 
   19781 	origin = dns_db_origin(db);
   19782 	CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
   19783 				 &build_nsec3));
   19784 	if (build_nsec3) {
   19785 		CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
   19786 					   false, zone->privatetype, diff));
   19787 	}
   19788 	CHECK(updatesecure(db, ver, origin, zone->minimum, true, diff));
   19789 
   19790 failure:
   19791 	return (result);
   19792 }
   19793 
   19794 static void
   19795 dnssec_report(const char *format, ...) {
   19796 	va_list args;
   19797 	va_start(args, format);
   19798 	isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_DNSSEC, DNS_LOGMODULE_ZONE,
   19799 		       ISC_LOG_INFO, format, args);
   19800 	va_end(args);
   19801 }
   19802 
   19803 static void
   19804 zone_rekey(dns_zone_t *zone) {
   19805 	isc_result_t result;
   19806 	dns_db_t *db = NULL;
   19807 	dns_dbnode_t *node = NULL;
   19808 	dns_dbversion_t *ver = NULL;
   19809 	dns_rdataset_t cdsset, soaset, soasigs, keyset, keysigs, cdnskeyset;
   19810 	dns_dnsseckeylist_t dnskeys, keys, rmkeys;
   19811 	dns_dnsseckey_t *key = NULL;
   19812 	dns_diff_t diff, _sig_diff;
   19813 	dns_kasp_t *kasp;
   19814 	dns__zonediff_t zonediff;
   19815 	bool commit = false, newactive = false;
   19816 	bool newalg = false;
   19817 	bool fullsign, use_kasp;
   19818 	dns_ttl_t ttl = 3600;
   19819 	const char *dir = NULL;
   19820 	isc_mem_t *mctx = NULL;
   19821 	isc_stdtime_t now, nexttime = 0;
   19822 	isc_time_t timenow;
   19823 	isc_interval_t ival;
   19824 	char timebuf[80];
   19825 
   19826 	REQUIRE(DNS_ZONE_VALID(zone));
   19827 
   19828 	ISC_LIST_INIT(dnskeys);
   19829 	ISC_LIST_INIT(keys);
   19830 	ISC_LIST_INIT(rmkeys);
   19831 	dns_rdataset_init(&soaset);
   19832 	dns_rdataset_init(&soasigs);
   19833 	dns_rdataset_init(&keyset);
   19834 	dns_rdataset_init(&keysigs);
   19835 	dns_rdataset_init(&cdsset);
   19836 	dns_rdataset_init(&cdnskeyset);
   19837 	dir = dns_zone_getkeydirectory(zone);
   19838 	mctx = zone->mctx;
   19839 	dns_diff_init(mctx, &diff);
   19840 	dns_diff_init(mctx, &_sig_diff);
   19841 	zonediff_init(&zonediff, &_sig_diff);
   19842 
   19843 	CHECK(dns_zone_getdb(zone, &db));
   19844 	CHECK(dns_db_newversion(db, &ver));
   19845 	CHECK(dns_db_getoriginnode(db, &node));
   19846 
   19847 	TIME_NOW(&timenow);
   19848 	now = isc_time_seconds(&timenow);
   19849 
   19850 	dnssec_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
   19851 
   19852 	/* Get the SOA record's TTL */
   19853 	CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
   19854 				  dns_rdatatype_none, 0, &soaset, &soasigs));
   19855 	ttl = soaset.ttl;
   19856 	dns_rdataset_disassociate(&soaset);
   19857 
   19858 	/* Get the DNSKEY rdataset */
   19859 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
   19860 				     dns_rdatatype_none, 0, &keyset, &keysigs);
   19861 	if (result == ISC_R_SUCCESS) {
   19862 		ttl = keyset.ttl;
   19863 		CHECK(dns_dnssec_keylistfromrdataset(
   19864 			&zone->origin, dir, mctx, &keyset, &keysigs, &soasigs,
   19865 			false, false, &dnskeys));
   19866 	} else if (result != ISC_R_NOTFOUND) {
   19867 		goto failure;
   19868 	}
   19869 
   19870 	/* Get the CDS rdataset */
   19871 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cds,
   19872 				     dns_rdatatype_none, 0, &cdsset, NULL);
   19873 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdsset)) {
   19874 		dns_rdataset_disassociate(&cdsset);
   19875 	}
   19876 
   19877 	/* Get the CDNSKEY rdataset */
   19878 	result = dns_db_findrdataset(db, node, ver, dns_rdatatype_cdnskey,
   19879 				     dns_rdatatype_none, 0, &cdnskeyset, NULL);
   19880 	if (result != ISC_R_SUCCESS && dns_rdataset_isassociated(&cdnskeyset)) {
   19881 		dns_rdataset_disassociate(&cdnskeyset);
   19882 	}
   19883 
   19884 	/*
   19885 	 * True when called from "rndc sign".  Indicates the zone should be
   19886 	 * fully signed now.
   19887 	 */
   19888 	fullsign = DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN);
   19889 
   19890 	kasp = dns_zone_getkasp(zone);
   19891 	use_kasp = dns_zone_use_kasp(zone);
   19892 	if (kasp != NULL) {
   19893 		LOCK(&kasp->lock);
   19894 	}
   19895 
   19896 	result = dns_dnssec_findmatchingkeys(&zone->origin, dir, now, mctx,
   19897 					     &keys);
   19898 	if (result != ISC_R_SUCCESS) {
   19899 		dnssec_log(zone, ISC_LOG_DEBUG(1),
   19900 			   "zone_rekey:dns_dnssec_findmatchingkeys failed: %s",
   19901 			   isc_result_totext(result));
   19902 	}
   19903 
   19904 	if (use_kasp && (result == ISC_R_SUCCESS || result == ISC_R_NOTFOUND)) {
   19905 		result = dns_keymgr_run(&zone->origin, zone->rdclass, dir, mctx,
   19906 					&keys, kasp, now, &nexttime);
   19907 		if (result != ISC_R_SUCCESS) {
   19908 			dnssec_log(zone, ISC_LOG_ERROR,
   19909 				   "zone_rekey:dns_dnssec_keymgr failed: %s",
   19910 				   isc_result_totext(result));
   19911 			goto failure;
   19912 		}
   19913 	}
   19914 
   19915 	if (kasp != NULL) {
   19916 		UNLOCK(&kasp->lock);
   19917 	}
   19918 
   19919 	if (result == ISC_R_SUCCESS) {
   19920 		bool insecure = dns_zone_secure_to_insecure(zone, false);
   19921 
   19922 		/*
   19923 		 * Only update DNSKEY TTL if we have a policy.
   19924 		 */
   19925 		if (kasp != NULL && strcmp(dns_kasp_getname(kasp), "none") != 0)
   19926 		{
   19927 			ttl = dns_kasp_dnskeyttl(kasp);
   19928 		}
   19929 
   19930 		result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
   19931 					       &zone->origin, ttl, &diff, mctx,
   19932 					       dnssec_report);
   19933 		/*
   19934 		 * Keys couldn't be updated for some reason;
   19935 		 * try again later.
   19936 		 */
   19937 		if (result != ISC_R_SUCCESS) {
   19938 			dnssec_log(zone, ISC_LOG_ERROR,
   19939 				   "zone_rekey:couldn't update zone keys: %s",
   19940 				   isc_result_totext(result));
   19941 			goto failure;
   19942 		}
   19943 
   19944 		/*
   19945 		 * Update CDS / CDNSKEY records.
   19946 		 */
   19947 		result = dns_dnssec_syncupdate(&dnskeys, &rmkeys, &cdsset,
   19948 					       &cdnskeyset, now, ttl, &diff,
   19949 					       mctx);
   19950 		if (result != ISC_R_SUCCESS) {
   19951 			dnssec_log(zone, ISC_LOG_ERROR,
   19952 				   "zone_rekey:couldn't update CDS/CDNSKEY: %s",
   19953 				   isc_result_totext(result));
   19954 			goto failure;
   19955 		}
   19956 
   19957 		result = dns_dnssec_syncdelete(&cdsset, &cdnskeyset,
   19958 					       &zone->origin, zone->rdclass,
   19959 					       ttl, &diff, mctx, insecure);
   19960 		if (result != ISC_R_SUCCESS) {
   19961 			dnssec_log(zone, ISC_LOG_ERROR,
   19962 				   "zone_rekey:couldn't update CDS/CDNSKEY "
   19963 				   "DELETE records: %s",
   19964 				   isc_result_totext(result));
   19965 			goto failure;
   19966 		}
   19967 
   19968 		/*
   19969 		 * See if any pre-existing keys have newly become active;
   19970 		 * also, see if any new key is for a new algorithm, as in that
   19971 		 * event, we need to sign the zone fully.  (If there's a new
   19972 		 * key, but it's for an already-existing algorithm, then
   19973 		 * the zone signing can be handled incrementally.)
   19974 		 */
   19975 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   19976 		     key = ISC_LIST_NEXT(key, link)) {
   19977 			if (!key->first_sign) {
   19978 				continue;
   19979 			}
   19980 
   19981 			newactive = true;
   19982 
   19983 			if (!dns_rdataset_isassociated(&keysigs)) {
   19984 				newalg = true;
   19985 				break;
   19986 			}
   19987 
   19988 			if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
   19989 				/*
   19990 				 * This isn't a new algorithm; clear
   19991 				 * first_sign so we won't sign the
   19992 				 * whole zone with this key later.
   19993 				 */
   19994 				key->first_sign = false;
   19995 			} else {
   19996 				newalg = true;
   19997 				break;
   19998 			}
   19999 		}
   20000 
   20001 		if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
   20002 		    dnskey_sane(zone, db, ver, &diff))
   20003 		{
   20004 			CHECK(dns_diff_apply(&diff, db, ver));
   20005 			CHECK(clean_nsec3param(zone, db, ver, &diff));
   20006 			CHECK(add_signing_records(db, zone->privatetype, ver,
   20007 						  &diff, (newalg || fullsign)));
   20008 			CHECK(update_soa_serial(zone, db, ver, &diff, mctx,
   20009 						zone->updatemethod));
   20010 			CHECK(add_chains(zone, db, ver, &diff));
   20011 			CHECK(sign_apex(zone, db, ver, now, &diff, &zonediff));
   20012 			CHECK(zone_journal(zone, zonediff.diff, NULL,
   20013 					   "zone_rekey"));
   20014 			commit = true;
   20015 		}
   20016 	}
   20017 
   20018 	dns_db_closeversion(db, &ver, true);
   20019 
   20020 	LOCK_ZONE(zone);
   20021 
   20022 	if (commit) {
   20023 		dns_difftuple_t *tuple;
   20024 
   20025 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
   20026 
   20027 		zone_needdump(zone, DNS_DUMP_DELAY);
   20028 
   20029 		zone_settimer(zone, &timenow);
   20030 
   20031 		/* Remove any signatures from removed keys.  */
   20032 		if (!ISC_LIST_EMPTY(rmkeys)) {
   20033 			for (key = ISC_LIST_HEAD(rmkeys); key != NULL;
   20034 			     key = ISC_LIST_NEXT(key, link)) {
   20035 				result = zone_signwithkey(
   20036 					zone, dst_key_alg(key->key),
   20037 					dst_key_id(key->key), true);
   20038 				if (result != ISC_R_SUCCESS) {
   20039 					dnssec_log(zone, ISC_LOG_ERROR,
   20040 						   "zone_signwithkey failed: "
   20041 						   "%s",
   20042 						   dns_result_totext(result));
   20043 				}
   20044 			}
   20045 		}
   20046 
   20047 		if (fullsign) {
   20048 			/*
   20049 			 * "rndc sign" was called, so we now sign the zone
   20050 			 * with all active keys, whether they're new or not.
   20051 			 */
   20052 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20053 			     key = ISC_LIST_NEXT(key, link)) {
   20054 				if (!key->force_sign && !key->hint_sign) {
   20055 					continue;
   20056 				}
   20057 
   20058 				result = zone_signwithkey(
   20059 					zone, dst_key_alg(key->key),
   20060 					dst_key_id(key->key), false);
   20061 				if (result != ISC_R_SUCCESS) {
   20062 					dnssec_log(zone, ISC_LOG_ERROR,
   20063 						   "zone_signwithkey failed: "
   20064 						   "%s",
   20065 						   dns_result_totext(result));
   20066 				}
   20067 			}
   20068 		} else if (newalg) {
   20069 			/*
   20070 			 * We haven't been told to sign fully, but a new
   20071 			 * algorithm was added to the DNSKEY.  We sign
   20072 			 * the full zone, but only with newly active
   20073 			 * keys.
   20074 			 */
   20075 			for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20076 			     key = ISC_LIST_NEXT(key, link)) {
   20077 				if (!key->first_sign) {
   20078 					continue;
   20079 				}
   20080 
   20081 				result = zone_signwithkey(
   20082 					zone, dst_key_alg(key->key),
   20083 					dst_key_id(key->key), false);
   20084 				if (result != ISC_R_SUCCESS) {
   20085 					dnssec_log(zone, ISC_LOG_ERROR,
   20086 						   "zone_signwithkey failed: "
   20087 						   "%s",
   20088 						   dns_result_totext(result));
   20089 				}
   20090 			}
   20091 		}
   20092 
   20093 		/*
   20094 		 * Clear fullsign flag, if it was set, so we don't do
   20095 		 * another full signing next time.
   20096 		 */
   20097 		DNS_ZONEKEY_CLROPTION(zone, DNS_ZONEKEY_FULLSIGN);
   20098 
   20099 		/*
   20100 		 * Cause the zone to add/delete NSEC3 chains for the
   20101 		 * deferred NSEC3PARAM changes.
   20102 		 */
   20103 		for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
   20104 		     tuple != NULL; tuple = ISC_LIST_NEXT(tuple, link))
   20105 		{
   20106 			unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
   20107 			dns_rdata_t rdata = DNS_RDATA_INIT;
   20108 			dns_rdata_nsec3param_t nsec3param;
   20109 
   20110 			if (tuple->rdata.type != zone->privatetype ||
   20111 			    tuple->op != DNS_DIFFOP_ADD) {
   20112 				continue;
   20113 			}
   20114 
   20115 			if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
   20116 							buf, sizeof(buf))) {
   20117 				continue;
   20118 			}
   20119 
   20120 			result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   20121 			RUNTIME_CHECK(result == ISC_R_SUCCESS);
   20122 			if (nsec3param.flags == 0) {
   20123 				continue;
   20124 			}
   20125 
   20126 			result = zone_addnsec3chain(zone, &nsec3param);
   20127 			if (result != ISC_R_SUCCESS) {
   20128 				dnssec_log(zone, ISC_LOG_ERROR,
   20129 					   "zone_addnsec3chain failed: %s",
   20130 					   dns_result_totext(result));
   20131 			}
   20132 		}
   20133 
   20134 		/*
   20135 		 * Activate any NSEC3 chain updates that may have
   20136 		 * been scheduled before this rekey.
   20137 		 */
   20138 		if (fullsign || newalg) {
   20139 			resume_addnsec3chain(zone);
   20140 		}
   20141 
   20142 		/*
   20143 		 * Schedule the next resigning event
   20144 		 */
   20145 		set_resigntime(zone);
   20146 	}
   20147 
   20148 	isc_time_settoepoch(&zone->refreshkeytime);
   20149 
   20150 	/*
   20151 	 * If keymgr provided a next time, use the calculated next rekey time.
   20152 	 */
   20153 	if (use_kasp) {
   20154 		isc_time_t timenext;
   20155 		uint32_t nexttime_seconds;
   20156 
   20157 		/*
   20158 		 * Set the key refresh timer to the next scheduled key event
   20159 		 * or to 'dnssec-loadkeys-interval' seconds in the future
   20160 		 * if no next key event is scheduled (nexttime == 0).
   20161 		 */
   20162 		if (nexttime > 0) {
   20163 			nexttime_seconds = nexttime - now;
   20164 		} else {
   20165 			nexttime_seconds = zone->refreshkeyinterval;
   20166 		}
   20167 
   20168 		DNS_ZONE_TIME_ADD(&timenow, nexttime_seconds, &timenext);
   20169 		zone->refreshkeytime = timenext;
   20170 		zone_settimer(zone, &timenow);
   20171 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   20172 
   20173 		dnssec_log(zone, ISC_LOG_DEBUG(3),
   20174 			   "next key event in %u seconds", nexttime_seconds);
   20175 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   20176 	}
   20177 	/*
   20178 	 * If we're doing key maintenance, set the key refresh timer to
   20179 	 * the next scheduled key event or to 'dnssec-loadkeys-interval'
   20180 	 * seconds in the future, whichever is sooner.
   20181 	 */
   20182 	else if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
   20183 	{
   20184 		isc_time_t timethen;
   20185 		isc_stdtime_t then;
   20186 
   20187 		DNS_ZONE_TIME_ADD(&timenow, zone->refreshkeyinterval,
   20188 				  &timethen);
   20189 		zone->refreshkeytime = timethen;
   20190 
   20191 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20192 		     key = ISC_LIST_NEXT(key, link)) {
   20193 			then = now;
   20194 			result = next_keyevent(key->key, &then);
   20195 			if (result != ISC_R_SUCCESS) {
   20196 				continue;
   20197 			}
   20198 
   20199 			DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
   20200 			if (isc_time_compare(&timethen, &zone->refreshkeytime) <
   20201 			    0) {
   20202 				zone->refreshkeytime = timethen;
   20203 			}
   20204 		}
   20205 
   20206 		zone_settimer(zone, &timenow);
   20207 
   20208 		isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
   20209 		dnssec_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
   20210 	}
   20211 	UNLOCK_ZONE(zone);
   20212 
   20213 	if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   20214 		for (key = ISC_LIST_HEAD(dnskeys); key != NULL;
   20215 		     key = ISC_LIST_NEXT(key, link)) {
   20216 			/* This debug log is used in the kasp system test */
   20217 			char algbuf[DNS_SECALG_FORMATSIZE];
   20218 			dns_secalg_format(dst_key_alg(key->key), algbuf,
   20219 					  sizeof(algbuf));
   20220 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   20221 				   "zone_rekey done: key %d/%s",
   20222 				   dst_key_id(key->key), algbuf);
   20223 		}
   20224 	}
   20225 
   20226 	result = ISC_R_SUCCESS;
   20227 
   20228 failure:
   20229 	LOCK_ZONE(zone);
   20230 	if (result != ISC_R_SUCCESS) {
   20231 		/*
   20232 		 * Something went wrong; try again in ten minutes or
   20233 		 * after a key refresh interval, whichever is shorter.
   20234 		 */
   20235 		isc_interval_set(&ival, ISC_MIN(zone->refreshkeyinterval, 600),
   20236 				 0);
   20237 		isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
   20238 	}
   20239 	UNLOCK_ZONE(zone);
   20240 
   20241 	dns_diff_clear(&diff);
   20242 	dns_diff_clear(&_sig_diff);
   20243 
   20244 	clear_keylist(&dnskeys, mctx);
   20245 	clear_keylist(&keys, mctx);
   20246 	clear_keylist(&rmkeys, mctx);
   20247 
   20248 	if (ver != NULL) {
   20249 		dns_db_closeversion(db, &ver, false);
   20250 	}
   20251 	if (dns_rdataset_isassociated(&cdsset)) {
   20252 		dns_rdataset_disassociate(&cdsset);
   20253 	}
   20254 	if (dns_rdataset_isassociated(&keyset)) {
   20255 		dns_rdataset_disassociate(&keyset);
   20256 	}
   20257 	if (dns_rdataset_isassociated(&keysigs)) {
   20258 		dns_rdataset_disassociate(&keysigs);
   20259 	}
   20260 	if (dns_rdataset_isassociated(&soasigs)) {
   20261 		dns_rdataset_disassociate(&soasigs);
   20262 	}
   20263 	if (dns_rdataset_isassociated(&cdnskeyset)) {
   20264 		dns_rdataset_disassociate(&cdnskeyset);
   20265 	}
   20266 	if (node != NULL) {
   20267 		dns_db_detachnode(db, &node);
   20268 	}
   20269 	if (db != NULL) {
   20270 		dns_db_detach(&db);
   20271 	}
   20272 
   20273 	INSIST(ver == NULL);
   20274 }
   20275 
   20276 void
   20277 dns_zone_rekey(dns_zone_t *zone, bool fullsign) {
   20278 	isc_time_t now;
   20279 
   20280 	if (zone->type == dns_zone_master && zone->task != NULL) {
   20281 		LOCK_ZONE(zone);
   20282 
   20283 		if (fullsign) {
   20284 			DNS_ZONEKEY_SETOPTION(zone, DNS_ZONEKEY_FULLSIGN);
   20285 		}
   20286 
   20287 		TIME_NOW(&now);
   20288 		zone->refreshkeytime = now;
   20289 		zone_settimer(zone, &now);
   20290 
   20291 		UNLOCK_ZONE(zone);
   20292 	}
   20293 }
   20294 
   20295 isc_result_t
   20296 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
   20297 		 unsigned int *errors) {
   20298 	isc_result_t result;
   20299 	dns_dbnode_t *node = NULL;
   20300 
   20301 	REQUIRE(DNS_ZONE_VALID(zone));
   20302 	REQUIRE(errors != NULL);
   20303 
   20304 	result = dns_db_getoriginnode(db, &node);
   20305 	if (result != ISC_R_SUCCESS) {
   20306 		return (result);
   20307 	}
   20308 	result = zone_count_ns_rr(zone, db, node, version, NULL, errors, false);
   20309 	dns_db_detachnode(db, &node);
   20310 	return (result);
   20311 }
   20312 
   20313 isc_result_t
   20314 dns_zone_cdscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version) {
   20315 	isc_result_t result;
   20316 	dns_dbnode_t *node = NULL;
   20317 	dns_rdataset_t dnskey, cds, cdnskey;
   20318 	unsigned char buffer[DNS_DS_BUFFERSIZE];
   20319 	unsigned char algorithms[256];
   20320 	unsigned int i;
   20321 
   20322 	enum { notexpected = 0, expected = 1, found = 2 };
   20323 
   20324 	REQUIRE(DNS_ZONE_VALID(zone));
   20325 
   20326 	result = dns_db_getoriginnode(db, &node);
   20327 	if (result != ISC_R_SUCCESS) {
   20328 		return (result);
   20329 	}
   20330 
   20331 	dns_rdataset_init(&cds);
   20332 	dns_rdataset_init(&dnskey);
   20333 	dns_rdataset_init(&cdnskey);
   20334 
   20335 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cds,
   20336 				     dns_rdatatype_none, 0, &cds, NULL);
   20337 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   20338 		goto failure;
   20339 	}
   20340 
   20341 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_cdnskey,
   20342 				     dns_rdatatype_none, 0, &cdnskey, NULL);
   20343 	if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
   20344 		goto failure;
   20345 	}
   20346 
   20347 	if (!dns_rdataset_isassociated(&cds) &&
   20348 	    !dns_rdataset_isassociated(&cdnskey)) {
   20349 		result = ISC_R_SUCCESS;
   20350 		goto failure;
   20351 	}
   20352 
   20353 	result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
   20354 				     dns_rdatatype_none, 0, &dnskey, NULL);
   20355 	if (result == ISC_R_NOTFOUND) {
   20356 		if (dns_rdataset_isassociated(&cds)) {
   20357 			result = DNS_R_BADCDS;
   20358 		} else {
   20359 			result = DNS_R_BADCDNSKEY;
   20360 		}
   20361 		goto failure;
   20362 	}
   20363 	if (result != ISC_R_SUCCESS) {
   20364 		goto failure;
   20365 	}
   20366 
   20367 	/*
   20368 	 * For each DNSSEC algorithm in the CDS RRset there must be
   20369 	 * a matching DNSKEY record with the exception of a CDS deletion
   20370 	 * record which must be by itself.
   20371 	 */
   20372 	if (dns_rdataset_isassociated(&cds)) {
   20373 		bool delete = false;
   20374 		memset(algorithms, notexpected, sizeof(algorithms));
   20375 		for (result = dns_rdataset_first(&cds); result == ISC_R_SUCCESS;
   20376 		     result = dns_rdataset_next(&cds))
   20377 		{
   20378 			dns_rdata_t crdata = DNS_RDATA_INIT;
   20379 			dns_rdata_cds_t structcds;
   20380 
   20381 			dns_rdataset_current(&cds, &crdata);
   20382 			/*
   20383 			 * CDS deletion record has this form "0 0 0 00" which
   20384 			 * is 5 zero octets.
   20385 			 */
   20386 			if (crdata.length == 5U &&
   20387 			    memcmp(crdata.data,
   20388 				   (unsigned char[5]){ 0, 0, 0, 0, 0 }, 5) == 0)
   20389 			{
   20390 				delete = true;
   20391 				continue;
   20392 			}
   20393 			CHECK(dns_rdata_tostruct(&crdata, &structcds, NULL));
   20394 			if (algorithms[structcds.algorithm] == 0) {
   20395 				algorithms[structcds.algorithm] = expected;
   20396 			}
   20397 			for (result = dns_rdataset_first(&dnskey);
   20398 			     result == ISC_R_SUCCESS;
   20399 			     result = dns_rdataset_next(&dnskey))
   20400 			{
   20401 				dns_rdata_t rdata = DNS_RDATA_INIT;
   20402 				dns_rdata_t dsrdata = DNS_RDATA_INIT;
   20403 
   20404 				dns_rdataset_current(&dnskey, &rdata);
   20405 				CHECK(dns_ds_buildrdata(&zone->origin, &rdata,
   20406 							structcds.digest_type,
   20407 							buffer, &dsrdata));
   20408 				if (crdata.length == dsrdata.length &&
   20409 				    memcmp(crdata.data, dsrdata.data,
   20410 					   dsrdata.length) == 0)
   20411 				{
   20412 					algorithms[structcds.algorithm] = found;
   20413 				}
   20414 			}
   20415 			if (result != ISC_R_NOMORE) {
   20416 				goto failure;
   20417 			}
   20418 		}
   20419 		for (i = 0; i < sizeof(algorithms); i++) {
   20420 			if (delete) {
   20421 				if (algorithms[i] != notexpected) {
   20422 					result = DNS_R_BADCDS;
   20423 					goto failure;
   20424 				}
   20425 			} else if (algorithms[i] == expected) {
   20426 				result = DNS_R_BADCDS;
   20427 				goto failure;
   20428 			}
   20429 		}
   20430 	}
   20431 
   20432 	/*
   20433 	 * For each DNSSEC algorithm in the CDNSKEY RRset there must be
   20434 	 * a matching DNSKEY record with the exception of a CDNSKEY deletion
   20435 	 * record which must be by itself.
   20436 	 */
   20437 	if (dns_rdataset_isassociated(&cdnskey)) {
   20438 		bool delete = false;
   20439 		memset(algorithms, notexpected, sizeof(algorithms));
   20440 		for (result = dns_rdataset_first(&cdnskey);
   20441 		     result == ISC_R_SUCCESS;
   20442 		     result = dns_rdataset_next(&cdnskey))
   20443 		{
   20444 			dns_rdata_t crdata = DNS_RDATA_INIT;
   20445 			dns_rdata_cdnskey_t structcdnskey;
   20446 
   20447 			dns_rdataset_current(&cdnskey, &crdata);
   20448 			/*
   20449 			 * CDNSKEY deletion record has this form
   20450 			 * "0 3 0 AA==" which is 2 zero octets, a 3,
   20451 			 * and 2 zero octets.
   20452 			 */
   20453 			if (crdata.length == 5U &&
   20454 			    memcmp(crdata.data,
   20455 				   (unsigned char[5]){ 0, 0, 3, 0, 0 }, 5) == 0)
   20456 			{
   20457 				delete = true;
   20458 				continue;
   20459 			}
   20460 			CHECK(dns_rdata_tostruct(&crdata, &structcdnskey,
   20461 						 NULL));
   20462 			if (algorithms[structcdnskey.algorithm] == 0) {
   20463 				algorithms[structcdnskey.algorithm] = expected;
   20464 			}
   20465 			for (result = dns_rdataset_first(&dnskey);
   20466 			     result == ISC_R_SUCCESS;
   20467 			     result = dns_rdataset_next(&dnskey))
   20468 			{
   20469 				dns_rdata_t rdata = DNS_RDATA_INIT;
   20470 
   20471 				dns_rdataset_current(&dnskey, &rdata);
   20472 				if (crdata.length == rdata.length &&
   20473 				    memcmp(crdata.data, rdata.data,
   20474 					   rdata.length) == 0)
   20475 				{
   20476 					algorithms[structcdnskey.algorithm] =
   20477 						found;
   20478 				}
   20479 			}
   20480 			if (result != ISC_R_NOMORE) {
   20481 				goto failure;
   20482 			}
   20483 		}
   20484 		for (i = 0; i < sizeof(algorithms); i++) {
   20485 			if (delete) {
   20486 				if (algorithms[i] != notexpected) {
   20487 					result = DNS_R_BADCDNSKEY;
   20488 					goto failure;
   20489 				}
   20490 			} else if (algorithms[i] == expected) {
   20491 				result = DNS_R_BADCDNSKEY;
   20492 				goto failure;
   20493 			}
   20494 		}
   20495 	}
   20496 	result = ISC_R_SUCCESS;
   20497 
   20498 failure:
   20499 	if (dns_rdataset_isassociated(&cds)) {
   20500 		dns_rdataset_disassociate(&cds);
   20501 	}
   20502 	if (dns_rdataset_isassociated(&dnskey)) {
   20503 		dns_rdataset_disassociate(&dnskey);
   20504 	}
   20505 	if (dns_rdataset_isassociated(&cdnskey)) {
   20506 		dns_rdataset_disassociate(&cdnskey);
   20507 	}
   20508 	dns_db_detachnode(db, &node);
   20509 	return (result);
   20510 }
   20511 
   20512 void
   20513 dns_zone_setautomatic(dns_zone_t *zone, bool automatic) {
   20514 	REQUIRE(DNS_ZONE_VALID(zone));
   20515 
   20516 	LOCK_ZONE(zone);
   20517 	zone->automatic = automatic;
   20518 	UNLOCK_ZONE(zone);
   20519 }
   20520 
   20521 bool
   20522 dns_zone_getautomatic(dns_zone_t *zone) {
   20523 	REQUIRE(DNS_ZONE_VALID(zone));
   20524 	return (zone->automatic);
   20525 }
   20526 
   20527 void
   20528 dns_zone_setadded(dns_zone_t *zone, bool added) {
   20529 	REQUIRE(DNS_ZONE_VALID(zone));
   20530 
   20531 	LOCK_ZONE(zone);
   20532 	zone->added = added;
   20533 	UNLOCK_ZONE(zone);
   20534 }
   20535 
   20536 bool
   20537 dns_zone_getadded(dns_zone_t *zone) {
   20538 	REQUIRE(DNS_ZONE_VALID(zone));
   20539 	return (zone->added);
   20540 }
   20541 
   20542 isc_result_t
   20543 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db) {
   20544 	isc_time_t loadtime;
   20545 	isc_result_t result;
   20546 	dns_zone_t *secure = NULL;
   20547 
   20548 	TIME_NOW(&loadtime);
   20549 
   20550 	/*
   20551 	 * Lock hierarchy: zmgr, zone, raw.
   20552 	 */
   20553 again:
   20554 	LOCK_ZONE(zone);
   20555 	INSIST(zone != zone->raw);
   20556 	if (inline_secure(zone)) {
   20557 		LOCK_ZONE(zone->raw);
   20558 	} else if (inline_raw(zone)) {
   20559 		secure = zone->secure;
   20560 		TRYLOCK_ZONE(result, secure);
   20561 		if (result != ISC_R_SUCCESS) {
   20562 			UNLOCK_ZONE(zone);
   20563 			secure = NULL;
   20564 			isc_thread_yield();
   20565 			goto again;
   20566 		}
   20567 	}
   20568 	result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);
   20569 	if (inline_secure(zone)) {
   20570 		UNLOCK_ZONE(zone->raw);
   20571 	} else if (secure != NULL) {
   20572 		UNLOCK_ZONE(secure);
   20573 	}
   20574 	UNLOCK_ZONE(zone);
   20575 	return (result);
   20576 }
   20577 
   20578 isc_result_t
   20579 dns_zone_setrefreshkeyinterval(dns_zone_t *zone, uint32_t interval) {
   20580 	REQUIRE(DNS_ZONE_VALID(zone));
   20581 	if (interval == 0) {
   20582 		return (ISC_R_RANGE);
   20583 	}
   20584 	/* Maximum value: 24 hours (3600 minutes) */
   20585 	if (interval > (24 * 60)) {
   20586 		interval = (24 * 60);
   20587 	}
   20588 	/* Multiply by 60 for seconds */
   20589 	zone->refreshkeyinterval = interval * 60;
   20590 	return (ISC_R_SUCCESS);
   20591 }
   20592 
   20593 void
   20594 dns_zone_setrequestixfr(dns_zone_t *zone, bool flag) {
   20595 	REQUIRE(DNS_ZONE_VALID(zone));
   20596 	zone->requestixfr = flag;
   20597 }
   20598 
   20599 bool
   20600 dns_zone_getrequestixfr(dns_zone_t *zone) {
   20601 	REQUIRE(DNS_ZONE_VALID(zone));
   20602 	return (zone->requestixfr);
   20603 }
   20604 
   20605 void
   20606 dns_zone_setixfrratio(dns_zone_t *zone, uint32_t ratio) {
   20607 	REQUIRE(DNS_ZONE_VALID(zone));
   20608 	zone->ixfr_ratio = ratio;
   20609 }
   20610 
   20611 uint32_t
   20612 dns_zone_getixfrratio(dns_zone_t *zone) {
   20613 	REQUIRE(DNS_ZONE_VALID(zone));
   20614 	return (zone->ixfr_ratio);
   20615 }
   20616 
   20617 void
   20618 dns_zone_setrequestexpire(dns_zone_t *zone, bool flag) {
   20619 	REQUIRE(DNS_ZONE_VALID(zone));
   20620 	zone->requestexpire = flag;
   20621 }
   20622 
   20623 bool
   20624 dns_zone_getrequestexpire(dns_zone_t *zone) {
   20625 	REQUIRE(DNS_ZONE_VALID(zone));
   20626 	return (zone->requestexpire);
   20627 }
   20628 
   20629 void
   20630 dns_zone_setserialupdatemethod(dns_zone_t *zone, dns_updatemethod_t method) {
   20631 	REQUIRE(DNS_ZONE_VALID(zone));
   20632 	zone->updatemethod = method;
   20633 }
   20634 
   20635 dns_updatemethod_t
   20636 dns_zone_getserialupdatemethod(dns_zone_t *zone) {
   20637 	REQUIRE(DNS_ZONE_VALID(zone));
   20638 	return (zone->updatemethod);
   20639 }
   20640 
   20641 /*
   20642  * Lock hierarchy: zmgr, zone, raw.
   20643  */
   20644 isc_result_t
   20645 dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
   20646 	isc_result_t result;
   20647 	dns_zonemgr_t *zmgr;
   20648 
   20649 	REQUIRE(DNS_ZONE_VALID(zone));
   20650 	REQUIRE(zone->zmgr != NULL);
   20651 	REQUIRE(zone->task != NULL);
   20652 	REQUIRE(zone->loadtask != NULL);
   20653 	REQUIRE(zone->raw == NULL);
   20654 
   20655 	REQUIRE(DNS_ZONE_VALID(raw));
   20656 	REQUIRE(raw->zmgr == NULL);
   20657 	REQUIRE(raw->task == NULL);
   20658 	REQUIRE(raw->loadtask == NULL);
   20659 	REQUIRE(raw->secure == NULL);
   20660 
   20661 	REQUIRE(zone != raw);
   20662 
   20663 	/*
   20664 	 * Lock hierarchy: zmgr, zone, raw.
   20665 	 */
   20666 	zmgr = zone->zmgr;
   20667 	RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   20668 	LOCK_ZONE(zone);
   20669 	LOCK_ZONE(raw);
   20670 
   20671 	result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive, NULL,
   20672 				  NULL, zone->task, zone_timer, raw,
   20673 				  &raw->timer);
   20674 	if (result != ISC_R_SUCCESS) {
   20675 		goto unlock;
   20676 	}
   20677 
   20678 	/*
   20679 	 * The timer "holds" a iref.
   20680 	 */
   20681 	isc_refcount_increment0(&raw->irefs);
   20682 
   20683 	/* dns_zone_attach(raw, &zone->raw); */
   20684 	isc_refcount_increment(&raw->erefs);
   20685 	zone->raw = raw;
   20686 
   20687 	/* dns_zone_iattach(zone,  &raw->secure); */
   20688 	zone_iattach(zone, &raw->secure);
   20689 
   20690 	isc_task_attach(zone->task, &raw->task);
   20691 	isc_task_attach(zone->loadtask, &raw->loadtask);
   20692 
   20693 	ISC_LIST_APPEND(zmgr->zones, raw, link);
   20694 	raw->zmgr = zmgr;
   20695 	isc_refcount_increment(&zmgr->refs);
   20696 
   20697 unlock:
   20698 	UNLOCK_ZONE(raw);
   20699 	UNLOCK_ZONE(zone);
   20700 	RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
   20701 	return (result);
   20702 }
   20703 
   20704 void
   20705 dns_zone_getraw(dns_zone_t *zone, dns_zone_t **raw) {
   20706 	REQUIRE(DNS_ZONE_VALID(zone));
   20707 	REQUIRE(raw != NULL && *raw == NULL);
   20708 
   20709 	LOCK(&zone->lock);
   20710 	INSIST(zone != zone->raw);
   20711 	if (zone->raw != NULL) {
   20712 		dns_zone_attach(zone->raw, raw);
   20713 	}
   20714 	UNLOCK(&zone->lock);
   20715 }
   20716 
   20717 struct keydone {
   20718 	isc_event_t event;
   20719 	bool all;
   20720 	unsigned char data[5];
   20721 };
   20722 
   20723 #define PENDINGFLAGS (DNS_NSEC3FLAG_CREATE | DNS_NSEC3FLAG_INITIAL)
   20724 
   20725 static void
   20726 keydone(isc_task_t *task, isc_event_t *event) {
   20727 	const char *me = "keydone";
   20728 	bool commit = false;
   20729 	isc_result_t result;
   20730 	dns_rdata_t rdata = DNS_RDATA_INIT;
   20731 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   20732 	dns_zone_t *zone;
   20733 	dns_db_t *db = NULL;
   20734 	dns_dbnode_t *node = NULL;
   20735 	dns_rdataset_t rdataset;
   20736 	dns_diff_t diff;
   20737 	struct keydone *kd = (struct keydone *)event;
   20738 	dns_update_log_t log = { update_log_cb, NULL };
   20739 	bool clear_pending = false;
   20740 
   20741 	UNUSED(task);
   20742 
   20743 	zone = event->ev_arg;
   20744 	INSIST(DNS_ZONE_VALID(zone));
   20745 
   20746 	ENTER;
   20747 
   20748 	dns_rdataset_init(&rdataset);
   20749 	dns_diff_init(zone->mctx, &diff);
   20750 
   20751 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   20752 	if (zone->db != NULL) {
   20753 		dns_db_attach(zone->db, &db);
   20754 	}
   20755 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   20756 	if (db == NULL) {
   20757 		goto failure;
   20758 	}
   20759 
   20760 	dns_db_currentversion(db, &oldver);
   20761 	result = dns_db_newversion(db, &newver);
   20762 	if (result != ISC_R_SUCCESS) {
   20763 		dnssec_log(zone, ISC_LOG_ERROR,
   20764 			   "keydone:dns_db_newversion -> %s",
   20765 			   dns_result_totext(result));
   20766 		goto failure;
   20767 	}
   20768 
   20769 	result = dns_db_getoriginnode(db, &node);
   20770 	if (result != ISC_R_SUCCESS) {
   20771 		goto failure;
   20772 	}
   20773 
   20774 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   20775 				     dns_rdatatype_none, 0, &rdataset, NULL);
   20776 	if (result == ISC_R_NOTFOUND) {
   20777 		INSIST(!dns_rdataset_isassociated(&rdataset));
   20778 		goto failure;
   20779 	}
   20780 	if (result != ISC_R_SUCCESS) {
   20781 		INSIST(!dns_rdataset_isassociated(&rdataset));
   20782 		goto failure;
   20783 	}
   20784 
   20785 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   20786 	     result = dns_rdataset_next(&rdataset))
   20787 	{
   20788 		bool found = false;
   20789 
   20790 		dns_rdataset_current(&rdataset, &rdata);
   20791 
   20792 		if (kd->all) {
   20793 			if (rdata.length == 5 && rdata.data[0] != 0 &&
   20794 			    rdata.data[3] == 0 && rdata.data[4] == 1)
   20795 			{
   20796 				found = true;
   20797 			} else if (rdata.data[0] == 0 &&
   20798 				   (rdata.data[2] & PENDINGFLAGS) != 0) {
   20799 				found = true;
   20800 				clear_pending = true;
   20801 			}
   20802 		} else if (rdata.length == 5 &&
   20803 			   memcmp(rdata.data, kd->data, 5) == 0) {
   20804 			found = true;
   20805 		}
   20806 
   20807 		if (found) {
   20808 			CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_DEL,
   20809 					    &zone->origin, rdataset.ttl,
   20810 					    &rdata));
   20811 		}
   20812 		dns_rdata_reset(&rdata);
   20813 	}
   20814 
   20815 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   20816 		/* Write changes to journal file. */
   20817 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   20818 					zone->updatemethod));
   20819 
   20820 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   20821 					       &diff,
   20822 					       zone->sigvalidityinterval);
   20823 		if (!clear_pending) {
   20824 			CHECK(result);
   20825 		}
   20826 
   20827 		CHECK(zone_journal(zone, &diff, NULL, "keydone"));
   20828 		commit = true;
   20829 
   20830 		LOCK_ZONE(zone);
   20831 		DNS_ZONE_SETFLAG(zone,
   20832 				 DNS_ZONEFLG_LOADED | DNS_ZONEFLG_NEEDNOTIFY);
   20833 		zone_needdump(zone, 30);
   20834 		UNLOCK_ZONE(zone);
   20835 	}
   20836 
   20837 failure:
   20838 	if (dns_rdataset_isassociated(&rdataset)) {
   20839 		dns_rdataset_disassociate(&rdataset);
   20840 	}
   20841 	if (db != NULL) {
   20842 		if (node != NULL) {
   20843 			dns_db_detachnode(db, &node);
   20844 		}
   20845 		if (oldver != NULL) {
   20846 			dns_db_closeversion(db, &oldver, false);
   20847 		}
   20848 		if (newver != NULL) {
   20849 			dns_db_closeversion(db, &newver, commit);
   20850 		}
   20851 		dns_db_detach(&db);
   20852 	}
   20853 	dns_diff_clear(&diff);
   20854 	isc_event_free(&event);
   20855 	dns_zone_idetach(&zone);
   20856 
   20857 	INSIST(oldver == NULL);
   20858 	INSIST(newver == NULL);
   20859 }
   20860 
   20861 isc_result_t
   20862 dns_zone_keydone(dns_zone_t *zone, const char *keystr) {
   20863 	isc_result_t result = ISC_R_SUCCESS;
   20864 	isc_event_t *e;
   20865 	isc_buffer_t b;
   20866 	dns_zone_t *dummy = NULL;
   20867 	struct keydone *kd;
   20868 
   20869 	REQUIRE(DNS_ZONE_VALID(zone));
   20870 
   20871 	LOCK_ZONE(zone);
   20872 
   20873 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_KEYDONE, keydone,
   20874 			       zone, sizeof(struct keydone));
   20875 
   20876 	kd = (struct keydone *)e;
   20877 	if (strcasecmp(keystr, "all") == 0) {
   20878 		kd->all = true;
   20879 	} else {
   20880 		isc_textregion_t r;
   20881 		const char *algstr;
   20882 		dns_keytag_t keyid;
   20883 		dns_secalg_t alg;
   20884 		size_t n;
   20885 
   20886 		kd->all = false;
   20887 
   20888 		n = sscanf(keystr, "%hu/", &keyid);
   20889 		if (n == 0U) {
   20890 			CHECK(ISC_R_FAILURE);
   20891 		}
   20892 
   20893 		algstr = strchr(keystr, '/');
   20894 		if (algstr != NULL) {
   20895 			algstr++;
   20896 		} else {
   20897 			CHECK(ISC_R_FAILURE);
   20898 		}
   20899 
   20900 		n = sscanf(algstr, "%hhu", &alg);
   20901 		if (n == 0U) {
   20902 			DE_CONST(algstr, r.base);
   20903 			r.length = strlen(algstr);
   20904 			CHECK(dns_secalg_fromtext(&alg, &r));
   20905 		}
   20906 
   20907 		/* construct a private-type rdata */
   20908 		isc_buffer_init(&b, kd->data, sizeof(kd->data));
   20909 		isc_buffer_putuint8(&b, alg);
   20910 		isc_buffer_putuint8(&b, (keyid & 0xff00) >> 8);
   20911 		isc_buffer_putuint8(&b, (keyid & 0xff));
   20912 		isc_buffer_putuint8(&b, 0);
   20913 		isc_buffer_putuint8(&b, 1);
   20914 	}
   20915 
   20916 	zone_iattach(zone, &dummy);
   20917 	isc_task_send(zone->task, &e);
   20918 
   20919 failure:
   20920 	if (e != NULL) {
   20921 		isc_event_free(&e);
   20922 	}
   20923 	UNLOCK_ZONE(zone);
   20924 	return (result);
   20925 }
   20926 
   20927 /*
   20928  * Called from the zone task's queue after the relevant event is posted by
   20929  * dns_zone_setnsec3param().
   20930  */
   20931 static void
   20932 setnsec3param(isc_task_t *task, isc_event_t *event) {
   20933 	const char *me = "setnsec3param";
   20934 	dns_zone_t *zone = event->ev_arg;
   20935 
   20936 	INSIST(DNS_ZONE_VALID(zone));
   20937 
   20938 	UNUSED(task);
   20939 
   20940 	ENTER;
   20941 
   20942 	/*
   20943 	 * If receive_secure_serial is still processing or we have a
   20944 	 * queued event append rss_post queue.
   20945 	 */
   20946 	if (zone->rss_newver != NULL || ISC_LIST_HEAD(zone->rss_post) != NULL) {
   20947 		/*
   20948 		 * Wait for receive_secure_serial() to finish processing.
   20949 		 */
   20950 		ISC_LIST_APPEND(zone->rss_post, event, ev_link);
   20951 	} else {
   20952 		rss_post(zone, event);
   20953 	}
   20954 	dns_zone_idetach(&zone);
   20955 }
   20956 
   20957 /*
   20958  * Check whether NSEC3 chain addition or removal specified by the private-type
   20959  * record passed with the event was already queued (or even fully performed).
   20960  * If not, modify the relevant private-type records at the zone apex and call
   20961  * resume_addnsec3chain().
   20962  */
   20963 static void
   20964 rss_post(dns_zone_t *zone, isc_event_t *event) {
   20965 	const char *me = "rss_post";
   20966 	bool commit = false;
   20967 	isc_result_t result;
   20968 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   20969 	dns_db_t *db = NULL;
   20970 	dns_dbnode_t *node = NULL;
   20971 	dns_rdataset_t prdataset, nrdataset;
   20972 	dns_diff_t diff;
   20973 	struct np3event *npe = (struct np3event *)event;
   20974 	nsec3param_t *np;
   20975 	dns_update_log_t log = { update_log_cb, NULL };
   20976 	dns_rdata_t rdata;
   20977 	bool nseconly;
   20978 	bool exists = false;
   20979 
   20980 	ENTER;
   20981 
   20982 	np = &npe->params;
   20983 
   20984 	dns_rdataset_init(&prdataset);
   20985 	dns_rdataset_init(&nrdataset);
   20986 	dns_diff_init(zone->mctx, &diff);
   20987 
   20988 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   20989 	if (zone->db != NULL) {
   20990 		dns_db_attach(zone->db, &db);
   20991 	}
   20992 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   20993 	if (db == NULL) {
   20994 		goto failure;
   20995 	}
   20996 
   20997 	dns_db_currentversion(db, &oldver);
   20998 	result = dns_db_newversion(db, &newver);
   20999 	if (result != ISC_R_SUCCESS) {
   21000 		dnssec_log(zone, ISC_LOG_ERROR,
   21001 			   "setnsec3param:dns_db_newversion -> %s",
   21002 			   dns_result_totext(result));
   21003 		goto failure;
   21004 	}
   21005 
   21006 	CHECK(dns_db_getoriginnode(db, &node));
   21007 
   21008 	/*
   21009 	 * Does a private-type record already exist for this chain?
   21010 	 */
   21011 	result = dns_db_findrdataset(db, node, newver, zone->privatetype,
   21012 				     dns_rdatatype_none, 0, &prdataset, NULL);
   21013 	if (result == ISC_R_SUCCESS) {
   21014 		for (result = dns_rdataset_first(&prdataset);
   21015 		     result == ISC_R_SUCCESS;
   21016 		     result = dns_rdataset_next(&prdataset))
   21017 		{
   21018 			dns_rdata_init(&rdata);
   21019 			dns_rdataset_current(&prdataset, &rdata);
   21020 
   21021 			if (np->length == rdata.length &&
   21022 			    memcmp(rdata.data, np->data, np->length) == 0) {
   21023 				exists = true;
   21024 				break;
   21025 			}
   21026 		}
   21027 	} else if (result != ISC_R_NOTFOUND) {
   21028 		INSIST(!dns_rdataset_isassociated(&prdataset));
   21029 		goto failure;
   21030 	}
   21031 
   21032 	/*
   21033 	 * Does the chain already exist?
   21034 	 */
   21035 	result = dns_db_findrdataset(db, node, newver, dns_rdatatype_nsec3param,
   21036 				     dns_rdatatype_none, 0, &nrdataset, NULL);
   21037 	if (result == ISC_R_SUCCESS) {
   21038 		for (result = dns_rdataset_first(&nrdataset);
   21039 		     result == ISC_R_SUCCESS;
   21040 		     result = dns_rdataset_next(&nrdataset))
   21041 		{
   21042 			dns_rdata_init(&rdata);
   21043 			dns_rdataset_current(&nrdataset, &rdata);
   21044 
   21045 			if (np->length == (rdata.length + 1) &&
   21046 			    memcmp(rdata.data, np->data + 1, np->length - 1) ==
   21047 				    0)
   21048 			{
   21049 				exists = true;
   21050 				break;
   21051 			}
   21052 		}
   21053 	} else if (result != ISC_R_NOTFOUND) {
   21054 		INSIST(!dns_rdataset_isassociated(&nrdataset));
   21055 		goto failure;
   21056 	}
   21057 
   21058 	/*
   21059 	 * We need to remove any existing NSEC3 chains if the supplied NSEC3
   21060 	 * parameters are supposed to replace the current ones or if we are
   21061 	 * switching to NSEC.
   21062 	 */
   21063 	if (!exists && np->replace && (np->length != 0 || np->nsec)) {
   21064 		CHECK(dns_nsec3param_deletechains(db, newver, zone, !np->nsec,
   21065 						  &diff));
   21066 	}
   21067 
   21068 	if (!exists && np->length != 0) {
   21069 		/*
   21070 		 * We're creating an NSEC3 chain.  Add the private-type record
   21071 		 * passed in the event handler's argument to the zone apex.
   21072 		 *
   21073 		 * If the zone is not currently capable of supporting an NSEC3
   21074 		 * chain (due to the DNSKEY RRset at the zone apex not existing
   21075 		 * or containing at least one key using an NSEC-only
   21076 		 * algorithm), add the INITIAL flag, so these parameters can be
   21077 		 * used later when NSEC3 becomes available.
   21078 		 */
   21079 		dns_rdata_init(&rdata);
   21080 
   21081 		np->data[2] |= DNS_NSEC3FLAG_CREATE;
   21082 		result = dns_nsec_nseconly(db, newver, &nseconly);
   21083 		if (result == ISC_R_NOTFOUND || nseconly) {
   21084 			np->data[2] |= DNS_NSEC3FLAG_INITIAL;
   21085 		}
   21086 
   21087 		rdata.length = np->length;
   21088 		rdata.data = np->data;
   21089 		rdata.type = zone->privatetype;
   21090 		rdata.rdclass = zone->rdclass;
   21091 		CHECK(update_one_rr(db, newver, &diff, DNS_DIFFOP_ADD,
   21092 				    &zone->origin, 0, &rdata));
   21093 	}
   21094 
   21095 	/*
   21096 	 * If we changed anything in the zone, write changes to journal file
   21097 	 * and set commit to true so that resume_addnsec3chain() will be
   21098 	 * called below in order to kick off adding/removing relevant NSEC3
   21099 	 * records.
   21100 	 */
   21101 	if (!ISC_LIST_EMPTY(diff.tuples)) {
   21102 		CHECK(update_soa_serial(zone, db, newver, &diff, zone->mctx,
   21103 					zone->updatemethod));
   21104 		result = dns_update_signatures(&log, zone, db, oldver, newver,
   21105 					       &diff,
   21106 					       zone->sigvalidityinterval);
   21107 		if (result != ISC_R_NOTFOUND) {
   21108 			CHECK(result);
   21109 		}
   21110 		CHECK(zone_journal(zone, &diff, NULL, "setnsec3param"));
   21111 		commit = true;
   21112 
   21113 		LOCK_ZONE(zone);
   21114 		DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
   21115 		zone_needdump(zone, 30);
   21116 		UNLOCK_ZONE(zone);
   21117 	}
   21118 
   21119 failure:
   21120 	if (dns_rdataset_isassociated(&prdataset)) {
   21121 		dns_rdataset_disassociate(&prdataset);
   21122 	}
   21123 	if (dns_rdataset_isassociated(&nrdataset)) {
   21124 		dns_rdataset_disassociate(&nrdataset);
   21125 	}
   21126 	if (node != NULL) {
   21127 		dns_db_detachnode(db, &node);
   21128 	}
   21129 	if (oldver != NULL) {
   21130 		dns_db_closeversion(db, &oldver, false);
   21131 	}
   21132 	if (newver != NULL) {
   21133 		dns_db_closeversion(db, &newver, commit);
   21134 	}
   21135 	if (db != NULL) {
   21136 		dns_db_detach(&db);
   21137 	}
   21138 	if (commit) {
   21139 		LOCK_ZONE(zone);
   21140 		resume_addnsec3chain(zone);
   21141 		UNLOCK_ZONE(zone);
   21142 	}
   21143 	dns_diff_clear(&diff);
   21144 	isc_event_free(&event);
   21145 
   21146 	INSIST(oldver == NULL);
   21147 	INSIST(newver == NULL);
   21148 }
   21149 
   21150 static void
   21151 salt2text(unsigned char *salt, uint8_t saltlen, unsigned char *text,
   21152 	  unsigned int textlen) {
   21153 	isc_region_t r;
   21154 	isc_buffer_t buf;
   21155 	isc_result_t result;
   21156 
   21157 	r.base = salt;
   21158 	r.length = (unsigned int)saltlen;
   21159 
   21160 	isc_buffer_init(&buf, text, textlen);
   21161 	result = isc_hex_totext(&r, 2, "", &buf);
   21162 	if (result == ISC_R_SUCCESS) {
   21163 		text[saltlen * 2] = 0;
   21164 	} else {
   21165 		text[0] = 0;
   21166 	}
   21167 }
   21168 
   21169 /*
   21170  * Check if zone has NSEC3PARAM (and thus a chain) with the right parameters.
   21171  *
   21172  * If 'salt' is NULL, a match is found if the salt has the requested length,
   21173  * otherwise the NSEC3 salt must match the requested salt value too.
   21174  *
   21175  * Returns  ISC_R_SUCCESS, if a match is found, or an error if no match is
   21176  * found, or if the db lookup failed.
   21177  */
   21178 isc_result_t
   21179 dns__zone_lookup_nsec3param(dns_zone_t *zone, dns_rdata_nsec3param_t *lookup,
   21180 			    dns_rdata_nsec3param_t *param,
   21181 			    unsigned char saltbuf[255], bool resalt) {
   21182 	isc_result_t result = ISC_R_UNEXPECTED;
   21183 	dns_dbnode_t *node = NULL;
   21184 	dns_db_t *db = NULL;
   21185 	dns_dbversion_t *version = NULL;
   21186 	dns_rdataset_t rdataset;
   21187 	dns_rdata_nsec3param_t nsec3param;
   21188 	dns_rdata_t rdata = DNS_RDATA_INIT;
   21189 
   21190 	REQUIRE(DNS_ZONE_VALID(zone));
   21191 
   21192 	dns_rdataset_init(&rdataset);
   21193 
   21194 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   21195 	if (zone->db != NULL) {
   21196 		dns_db_attach(zone->db, &db);
   21197 	}
   21198 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   21199 	if (db == NULL) {
   21200 		goto setparam;
   21201 	}
   21202 
   21203 	result = dns_db_findnode(db, &zone->origin, false, &node);
   21204 	if (result != ISC_R_SUCCESS) {
   21205 		dns_zone_log(zone, ISC_LOG_ERROR,
   21206 			     "nsec3param lookup failure: %s",
   21207 			     dns_result_totext(result));
   21208 		goto setparam;
   21209 	}
   21210 	dns_db_currentversion(db, &version);
   21211 
   21212 	result = dns_db_findrdataset(db, node, version,
   21213 				     dns_rdatatype_nsec3param,
   21214 				     dns_rdatatype_none, 0, &rdataset, NULL);
   21215 	if (result != ISC_R_SUCCESS) {
   21216 		INSIST(!dns_rdataset_isassociated(&rdataset));
   21217 		if (result != ISC_R_NOTFOUND) {
   21218 			dns_zone_log(zone, ISC_LOG_ERROR,
   21219 				     "nsec3param lookup failure: %s",
   21220 				     dns_result_totext(result));
   21221 		}
   21222 		goto setparam;
   21223 	}
   21224 
   21225 	for (result = dns_rdataset_first(&rdataset); result == ISC_R_SUCCESS;
   21226 	     result = dns_rdataset_next(&rdataset))
   21227 	{
   21228 		dns_rdataset_current(&rdataset, &rdata);
   21229 		result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
   21230 		INSIST(result == ISC_R_SUCCESS);
   21231 		dns_rdata_reset(&rdata);
   21232 
   21233 		/* Check parameters. */
   21234 		if (nsec3param.hash != lookup->hash) {
   21235 			continue;
   21236 		}
   21237 		if (nsec3param.iterations != lookup->iterations) {
   21238 			continue;
   21239 		}
   21240 		if (nsec3param.salt_length != lookup->salt_length) {
   21241 			continue;
   21242 		}
   21243 		if (lookup->salt != NULL) {
   21244 			if (memcmp(nsec3param.salt, lookup->salt,
   21245 				   lookup->salt_length) != 0) {
   21246 				continue;
   21247 			}
   21248 		}
   21249 		/* Found a match. */
   21250 		result = ISC_R_SUCCESS;
   21251 		param->hash = nsec3param.hash;
   21252 		param->flags = nsec3param.flags;
   21253 		param->iterations = nsec3param.iterations;
   21254 		param->salt_length = nsec3param.salt_length;
   21255 		param->salt = nsec3param.salt;
   21256 		break;
   21257 	}
   21258 
   21259 setparam:
   21260 	if (result != ISC_R_SUCCESS) {
   21261 		/* Found no match. */
   21262 		result = ISC_R_NOTFOUND;
   21263 		param->hash = lookup->hash;
   21264 		param->flags = lookup->flags;
   21265 		param->iterations = lookup->iterations;
   21266 		param->salt_length = lookup->salt_length;
   21267 		param->salt = lookup->salt;
   21268 	}
   21269 
   21270 	if (param->salt_length == 0) {
   21271 		DE_CONST("-", param->salt);
   21272 	} else if (resalt || param->salt == NULL) {
   21273 		unsigned char *newsalt;
   21274 		unsigned char salttext[255 * 2 + 1];
   21275 		do {
   21276 			/* Generate a new salt. */
   21277 			result = dns_nsec3_generate_salt(saltbuf,
   21278 							 param->salt_length);
   21279 			if (result != ISC_R_SUCCESS) {
   21280 				break;
   21281 			}
   21282 			newsalt = saltbuf;
   21283 			salt2text(newsalt, param->salt_length, salttext,
   21284 				  sizeof(salttext));
   21285 			dnssec_log(zone, ISC_LOG_INFO, "generated salt: %s",
   21286 				   salttext);
   21287 			/* Check for salt conflict. */
   21288 			if (param->salt != NULL &&
   21289 			    memcmp(newsalt, param->salt, param->salt_length) ==
   21290 				    0)
   21291 			{
   21292 				result = ISC_R_SUCCESS;
   21293 			} else {
   21294 				param->salt = newsalt;
   21295 				result = DNS_R_NSEC3RESALT;
   21296 			}
   21297 		} while (result == ISC_R_SUCCESS);
   21298 
   21299 		INSIST(result != ISC_R_SUCCESS);
   21300 	}
   21301 
   21302 	if (dns_rdataset_isassociated(&rdataset)) {
   21303 		dns_rdataset_disassociate(&rdataset);
   21304 	}
   21305 	if (node != NULL) {
   21306 		dns_db_detachnode(db, &node);
   21307 	}
   21308 	if (version != NULL) {
   21309 		dns_db_closeversion(db, &version, false);
   21310 	}
   21311 	if (db != NULL) {
   21312 		dns_db_detach(&db);
   21313 	}
   21314 
   21315 	return (result);
   21316 }
   21317 
   21318 /*
   21319  * Called when an "rndc signing -nsec3param ..." command is received, or the
   21320  * 'dnssec-policy' has changed.
   21321  *
   21322  * Allocate and prepare an nsec3param_t structure which holds information about
   21323  * the NSEC3 changes requested for the zone:
   21324  *
   21325  *   - if NSEC3 is to be disabled ("-nsec3param none"), only set the "nsec"
   21326  *     field of the structure to true and the "replace" field to the value
   21327  *     of the "replace" argument, leaving other fields initialized to zeros, to
   21328  *     signal that the zone should be signed using NSEC instead of NSEC3,
   21329  *
   21330  *   - otherwise, prepare NSEC3PARAM RDATA that will eventually be inserted at
   21331  *     the zone apex, convert it to a private-type record and store the latter
   21332  *     in the "data" field of the nsec3param_t structure.
   21333  *
   21334  * Once the nsec3param_t structure is prepared, post an event to the zone's
   21335  * task which will cause setnsec3param() to be called with the prepared
   21336  * structure passed as an argument.
   21337  */
   21338 isc_result_t
   21339 dns_zone_setnsec3param(dns_zone_t *zone, uint8_t hash, uint8_t flags,
   21340 		       uint16_t iter, uint8_t saltlen, unsigned char *salt,
   21341 		       bool replace, bool resalt) {
   21342 	isc_result_t result = ISC_R_SUCCESS;
   21343 	dns_rdata_nsec3param_t param, lookup;
   21344 	dns_rdata_t nrdata = DNS_RDATA_INIT;
   21345 	dns_rdata_t prdata = DNS_RDATA_INIT;
   21346 	unsigned char nbuf[DNS_NSEC3PARAM_BUFFERSIZE];
   21347 	unsigned char saltbuf[255];
   21348 	struct np3event *npe;
   21349 	nsec3param_t *np;
   21350 	dns_zone_t *dummy = NULL;
   21351 	isc_buffer_t b;
   21352 	isc_event_t *e = NULL;
   21353 
   21354 	REQUIRE(DNS_ZONE_VALID(zone));
   21355 
   21356 	LOCK_ZONE(zone);
   21357 
   21358 	/*
   21359 	 * First check if the requested NSEC3 parameters are already set,
   21360 	 * if so, no need to set again.
   21361 	 */
   21362 	if (hash != 0) {
   21363 		lookup.hash = hash;
   21364 		lookup.flags = flags;
   21365 		lookup.iterations = iter;
   21366 		lookup.salt_length = saltlen;
   21367 		lookup.salt = salt;
   21368 		param.salt = NULL;
   21369 		result = dns__zone_lookup_nsec3param(zone, &lookup, &param,
   21370 						     saltbuf, resalt);
   21371 		if (result == ISC_R_SUCCESS) {
   21372 			UNLOCK_ZONE(zone);
   21373 			return (ISC_R_SUCCESS);
   21374 		}
   21375 		INSIST(param.salt != NULL);
   21376 	}
   21377 
   21378 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETNSEC3PARAM,
   21379 			       setnsec3param, zone, sizeof(struct np3event));
   21380 
   21381 	npe = (struct np3event *)e;
   21382 	np = &npe->params;
   21383 
   21384 	np->replace = replace;
   21385 	if (hash == 0) {
   21386 		np->length = 0;
   21387 		np->nsec = true;
   21388 		dnssec_log(zone, ISC_LOG_DEBUG(3), "setnsec3param:nsec");
   21389 	} else {
   21390 		param.common.rdclass = zone->rdclass;
   21391 		param.common.rdtype = dns_rdatatype_nsec3param;
   21392 		ISC_LINK_INIT(&param.common, link);
   21393 		param.mctx = NULL;
   21394 		/* nsec3 specific param set in dns__zone_lookup_nsec3param() */
   21395 		isc_buffer_init(&b, nbuf, sizeof(nbuf));
   21396 		CHECK(dns_rdata_fromstruct(&nrdata, zone->rdclass,
   21397 					   dns_rdatatype_nsec3param, &param,
   21398 					   &b));
   21399 		dns_nsec3param_toprivate(&nrdata, &prdata, zone->privatetype,
   21400 					 np->data, sizeof(np->data));
   21401 		np->length = prdata.length;
   21402 		np->nsec = false;
   21403 
   21404 		if (isc_log_wouldlog(dns_lctx, ISC_LOG_DEBUG(3))) {
   21405 			unsigned char salttext[255 * 2 + 1];
   21406 			salt2text(param.salt, param.salt_length, salttext,
   21407 				  sizeof(salttext));
   21408 			dnssec_log(zone, ISC_LOG_DEBUG(3),
   21409 				   "setnsec3param:nsec3 %u %u %u %s",
   21410 				   param.hash, param.flags, param.iterations,
   21411 				   salttext);
   21412 		}
   21413 	}
   21414 
   21415 	/*
   21416 	 * setnsec3param() will silently return early if the zone does not yet
   21417 	 * have a database.  Prevent that by queueing the event up if zone->db
   21418 	 * is NULL.  All events queued here are subsequently processed by
   21419 	 * receive_secure_db() if it ever gets called or simply freed by
   21420 	 * zone_free() otherwise.
   21421 	 */
   21422 
   21423 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   21424 	if (zone->db != NULL) {
   21425 		zone_iattach(zone, &dummy);
   21426 		isc_task_send(zone->task, &e);
   21427 	} else {
   21428 		ISC_LIST_APPEND(zone->setnsec3param_queue, e, ev_link);
   21429 		e = NULL;
   21430 	}
   21431 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   21432 
   21433 	result = ISC_R_SUCCESS;
   21434 
   21435 failure:
   21436 	if (e != NULL) {
   21437 		isc_event_free(&e);
   21438 	}
   21439 	UNLOCK_ZONE(zone);
   21440 	return (result);
   21441 }
   21442 
   21443 isc_result_t
   21444 dns_zone_getloadtime(dns_zone_t *zone, isc_time_t *loadtime) {
   21445 	REQUIRE(DNS_ZONE_VALID(zone));
   21446 	REQUIRE(loadtime != NULL);
   21447 
   21448 	LOCK_ZONE(zone);
   21449 	*loadtime = zone->loadtime;
   21450 	UNLOCK_ZONE(zone);
   21451 	return (ISC_R_SUCCESS);
   21452 }
   21453 
   21454 isc_result_t
   21455 dns_zone_getexpiretime(dns_zone_t *zone, isc_time_t *expiretime) {
   21456 	REQUIRE(DNS_ZONE_VALID(zone));
   21457 	REQUIRE(expiretime != NULL);
   21458 
   21459 	LOCK_ZONE(zone);
   21460 	*expiretime = zone->expiretime;
   21461 	UNLOCK_ZONE(zone);
   21462 	return (ISC_R_SUCCESS);
   21463 }
   21464 
   21465 isc_result_t
   21466 dns_zone_getrefreshtime(dns_zone_t *zone, isc_time_t *refreshtime) {
   21467 	REQUIRE(DNS_ZONE_VALID(zone));
   21468 	REQUIRE(refreshtime != NULL);
   21469 
   21470 	LOCK_ZONE(zone);
   21471 	*refreshtime = zone->refreshtime;
   21472 	UNLOCK_ZONE(zone);
   21473 	return (ISC_R_SUCCESS);
   21474 }
   21475 
   21476 isc_result_t
   21477 dns_zone_getrefreshkeytime(dns_zone_t *zone, isc_time_t *refreshkeytime) {
   21478 	REQUIRE(DNS_ZONE_VALID(zone));
   21479 	REQUIRE(refreshkeytime != NULL);
   21480 
   21481 	LOCK_ZONE(zone);
   21482 	*refreshkeytime = zone->refreshkeytime;
   21483 	UNLOCK_ZONE(zone);
   21484 	return (ISC_R_SUCCESS);
   21485 }
   21486 
   21487 unsigned int
   21488 dns_zone_getincludes(dns_zone_t *zone, char ***includesp) {
   21489 	dns_include_t *include;
   21490 	char **array = NULL;
   21491 	unsigned int n = 0;
   21492 
   21493 	REQUIRE(DNS_ZONE_VALID(zone));
   21494 	REQUIRE(includesp != NULL && *includesp == NULL);
   21495 
   21496 	LOCK_ZONE(zone);
   21497 	if (zone->nincludes == 0) {
   21498 		goto done;
   21499 	}
   21500 
   21501 	array = isc_mem_allocate(zone->mctx, sizeof(char *) * zone->nincludes);
   21502 	for (include = ISC_LIST_HEAD(zone->includes); include != NULL;
   21503 	     include = ISC_LIST_NEXT(include, link))
   21504 	{
   21505 		INSIST(n < zone->nincludes);
   21506 		array[n++] = isc_mem_strdup(zone->mctx, include->name);
   21507 	}
   21508 	INSIST(n == zone->nincludes);
   21509 	*includesp = array;
   21510 
   21511 done:
   21512 	UNLOCK_ZONE(zone);
   21513 	return (n);
   21514 }
   21515 
   21516 void
   21517 dns_zone_setstatlevel(dns_zone_t *zone, dns_zonestat_level_t level) {
   21518 	REQUIRE(DNS_ZONE_VALID(zone));
   21519 
   21520 	zone->statlevel = level;
   21521 }
   21522 
   21523 dns_zonestat_level_t
   21524 dns_zone_getstatlevel(dns_zone_t *zone) {
   21525 	REQUIRE(DNS_ZONE_VALID(zone));
   21526 
   21527 	return (zone->statlevel);
   21528 }
   21529 
   21530 static void
   21531 setserial(isc_task_t *task, isc_event_t *event) {
   21532 	uint32_t oldserial, desired;
   21533 	const char *me = "setserial";
   21534 	bool commit = false;
   21535 	isc_result_t result;
   21536 	dns_dbversion_t *oldver = NULL, *newver = NULL;
   21537 	dns_zone_t *zone;
   21538 	dns_db_t *db = NULL;
   21539 	dns_diff_t diff;
   21540 	struct ssevent *sse = (struct ssevent *)event;
   21541 	dns_update_log_t log = { update_log_cb, NULL };
   21542 	dns_difftuple_t *oldtuple = NULL, *newtuple = NULL;
   21543 
   21544 	UNUSED(task);
   21545 
   21546 	zone = event->ev_arg;
   21547 	INSIST(DNS_ZONE_VALID(zone));
   21548 
   21549 	ENTER;
   21550 
   21551 	if (zone->update_disabled) {
   21552 		goto failure;
   21553 	}
   21554 
   21555 	desired = sse->serial;
   21556 
   21557 	dns_diff_init(zone->mctx, &diff);
   21558 
   21559 	ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
   21560 	if (zone->db != NULL) {
   21561 		dns_db_attach(zone->db, &db);
   21562 	}
   21563 	ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
   21564 	if (db == NULL) {
   21565 		goto failure;
   21566 	}
   21567 
   21568 	dns_db_currentversion(db, &oldver);
   21569 	result = dns_db_newversion(db, &newver);
   21570 	if (result != ISC_R_SUCCESS) {
   21571 		dns_zone_log(zone, ISC_LOG_ERROR,
   21572 			     "setserial:dns_db_newversion -> %s",
   21573 			     dns_result_totext(result));
   21574 		goto failure;
   21575 	}
   21576 
   21577 	CHECK(dns_db_createsoatuple(db, oldver, diff.mctx, DNS_DIFFOP_DEL,
   21578 				    &oldtuple));
   21579 	CHECK(dns_difftuple_copy(oldtuple, &newtuple));
   21580 	newtuple->op = DNS_DIFFOP_ADD;
   21581 
   21582 	oldserial = dns_soa_getserial(&oldtuple->rdata);
   21583 	if (desired == 0U) {
   21584 		desired = 1;
   21585 	}
   21586 	if (!isc_serial_gt(desired, oldserial)) {
   21587 		if (desired != oldserial) {
   21588 			dns_zone_log(zone, ISC_LOG_INFO,
   21589 				     "setserial: desired serial (%u) "
   21590 				     "out of range (%u-%u)",
   21591 				     desired, oldserial + 1,
   21592 				     (oldserial + 0x7fffffff));
   21593 		}
   21594 		goto failure;
   21595 	}
   21596 
   21597 	dns_soa_setserial(desired, &newtuple->rdata);
   21598 	CHECK(do_one_tuple(&oldtuple, db, newver, &diff));
   21599 	CHECK(do_one_tuple(&newtuple, db, newver, &diff));
   21600 	result = dns_update_signatures(&log, zone, db, oldver, newver, &diff,
   21601 				       zone->sigvalidityinterval);
   21602 	if (result != ISC_R_NOTFOUND) {
   21603 		CHECK(result);
   21604 	}
   21605 
   21606 	/* Write changes to journal file. */
   21607 	CHECK(zone_journal(zone, &diff, NULL, "setserial"));
   21608 	commit = true;
   21609 
   21610 	LOCK_ZONE(zone);
   21611 	zone_needdump(zone, 30);
   21612 	UNLOCK_ZONE(zone);
   21613 
   21614 failure:
   21615 	if (oldtuple != NULL) {
   21616 		dns_difftuple_free(&oldtuple);
   21617 	}
   21618 	if (newtuple != NULL) {
   21619 		dns_difftuple_free(&newtuple);
   21620 	}
   21621 	if (oldver != NULL) {
   21622 		dns_db_closeversion(db, &oldver, false);
   21623 	}
   21624 	if (newver != NULL) {
   21625 		dns_db_closeversion(db, &newver, commit);
   21626 	}
   21627 	if (db != NULL) {
   21628 		dns_db_detach(&db);
   21629 	}
   21630 	dns_diff_clear(&diff);
   21631 	isc_event_free(&event);
   21632 	dns_zone_idetach(&zone);
   21633 
   21634 	INSIST(oldver == NULL);
   21635 	INSIST(newver == NULL);
   21636 }
   21637 
   21638 isc_result_t
   21639 dns_zone_setserial(dns_zone_t *zone, uint32_t serial) {
   21640 	isc_result_t result = ISC_R_SUCCESS;
   21641 	dns_zone_t *dummy = NULL;
   21642 	isc_event_t *e = NULL;
   21643 	struct ssevent *sse;
   21644 
   21645 	REQUIRE(DNS_ZONE_VALID(zone));
   21646 
   21647 	LOCK_ZONE(zone);
   21648 
   21649 	if (!inline_secure(zone)) {
   21650 		if (!dns_zone_isdynamic(zone, true)) {
   21651 			result = DNS_R_NOTDYNAMIC;
   21652 			goto failure;
   21653 		}
   21654 	}
   21655 
   21656 	if (zone->update_disabled) {
   21657 		result = DNS_R_FROZEN;
   21658 		goto failure;
   21659 	}
   21660 
   21661 	e = isc_event_allocate(zone->mctx, zone, DNS_EVENT_SETSERIAL, setserial,
   21662 			       zone, sizeof(struct ssevent));
   21663 
   21664 	sse = (struct ssevent *)e;
   21665 	sse->serial = serial;
   21666 
   21667 	zone_iattach(zone, &dummy);
   21668 	isc_task_send(zone->task, &e);
   21669 
   21670 failure:
   21671 	if (e != NULL) {
   21672 		isc_event_free(&e);
   21673 	}
   21674 	UNLOCK_ZONE(zone);
   21675 	return (result);
   21676 }
   21677 
   21678 isc_stats_t *
   21679 dns_zone_getgluecachestats(dns_zone_t *zone) {
   21680 	REQUIRE(DNS_ZONE_VALID(zone));
   21681 
   21682 	return (zone->gluecachestats);
   21683 }
   21684 
   21685 bool
   21686 dns_zone_isloaded(dns_zone_t *zone) {
   21687 	REQUIRE(DNS_ZONE_VALID(zone));
   21688 
   21689 	return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED));
   21690 }
   21691 
   21692 isc_result_t
   21693 dns_zone_verifydb(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver) {
   21694 	dns_dbversion_t *version = NULL;
   21695 	dns_keytable_t *secroots = NULL;
   21696 	isc_result_t result;
   21697 	dns_name_t *origin;
   21698 
   21699 	const char me[] = "dns_zone_verifydb";
   21700 
   21701 	REQUIRE(DNS_ZONE_VALID(zone));
   21702 	REQUIRE(db != NULL);
   21703 
   21704 	ENTER;
   21705 
   21706 	if (dns_zone_gettype(zone) != dns_zone_mirror) {
   21707 		return (ISC_R_SUCCESS);
   21708 	}
   21709 
   21710 	if (ver == NULL) {
   21711 		dns_db_currentversion(db, &version);
   21712 	} else {
   21713 		version = ver;
   21714 	}
   21715 
   21716 	if (zone->view != NULL) {
   21717 		result = dns_view_getsecroots(zone->view, &secroots);
   21718 		if (result != ISC_R_SUCCESS) {
   21719 			goto done;
   21720 		}
   21721 	}
   21722 
   21723 	origin = dns_db_origin(db);
   21724 	result = dns_zoneverify_dnssec(zone, db, version, origin, secroots,
   21725 				       zone->mctx, true, false, dnssec_report);
   21726 
   21727 done:
   21728 	if (secroots != NULL) {
   21729 		dns_keytable_detach(&secroots);
   21730 	}
   21731 
   21732 	if (ver == NULL) {
   21733 		dns_db_closeversion(db, &version, false);
   21734 	}
   21735 
   21736 	if (result != ISC_R_SUCCESS) {
   21737 		dnssec_log(zone, ISC_LOG_ERROR, "zone verification failed: %s",
   21738 			   isc_result_totext(result));
   21739 		result = DNS_R_VERIFYFAILURE;
   21740 	}
   21741 
   21742 	return (result);
   21743 }
   21744