2 * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
26 #include <isc/mutex.h>
27 #include <isc/print.h>
28 #include <isc/random.h>
29 #include <isc/ratelimiter.h>
30 #include <isc/refcount.h>
31 #include <isc/rwlock.h>
32 #include <isc/serial.h>
33 #include <isc/strerror.h>
34 #include <isc/stats.h>
35 #include <isc/stdtime.h>
36 #include <isc/string.h>
37 #include <isc/taskpool.h>
38 #include <isc/timer.h>
41 #include <dns/acache.h>
44 #include <dns/callbacks.h>
46 #include <dns/dbiterator.h>
47 #include <dns/dnssec.h>
48 #include <dns/events.h>
49 #include <dns/journal.h>
50 #include <dns/keydata.h>
51 #include <dns/keytable.h>
52 #include <dns/keyvalues.h>
54 #include <dns/master.h>
55 #include <dns/masterdump.h>
56 #include <dns/message.h>
59 #include <dns/nsec3.h>
61 #include <dns/private.h>
63 #include <dns/rcode.h>
64 #include <dns/rdataclass.h>
65 #include <dns/rdatalist.h>
66 #include <dns/rdataset.h>
67 #include <dns/rdatasetiter.h>
68 #include <dns/rdatastruct.h>
69 #include <dns/rdatatype.h>
70 #include <dns/request.h>
71 #include <dns/resolver.h>
72 #include <dns/result.h>
73 #include <dns/rriterator.h>
76 #include <dns/stats.h>
79 #include <dns/xfrin.h>
84 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
85 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
87 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
88 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
90 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
91 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
93 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
94 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
96 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
97 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
99 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
100 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
102 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
103 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
106 * Ensure 'a' is at least 'min' but not more than 'max'.
108 #define RANGE(a, min, max) \
109 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
111 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
116 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
117 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
118 #define ALG(x) dst_key_alg(x)
123 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
124 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
125 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
126 #define RESIGN_DELAY 3600 /*%< 1 hour */
128 #ifndef DNS_MAX_EXPIRE
129 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
132 #ifndef DNS_DUMP_DELAY
133 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
136 typedef struct dns_notify dns_notify_t;
137 typedef struct dns_stub dns_stub_t;
138 typedef struct dns_load dns_load_t;
139 typedef struct dns_forward dns_forward_t;
140 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
141 typedef struct dns_io dns_io_t;
142 typedef ISC_LIST(dns_io_t) dns_iolist_t;
143 typedef struct dns_signing dns_signing_t;
144 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
145 typedef struct dns_nsec3chain dns_nsec3chain_t;
146 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
147 typedef struct dns_keyfetch dns_keyfetch_t;
149 #define DNS_ZONE_CHECKLOCK
150 #ifdef DNS_ZONE_CHECKLOCK
151 #define LOCK_ZONE(z) \
152 do { LOCK(&(z)->lock); \
153 INSIST((z)->locked == ISC_FALSE); \
154 (z)->locked = ISC_TRUE; \
156 #define UNLOCK_ZONE(z) \
157 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
158 #define LOCKED_ZONE(z) ((z)->locked)
160 #define LOCK_ZONE(z) LOCK(&(z)->lock)
161 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
162 #define LOCKED_ZONE(z) ISC_TRUE
165 #ifdef ISC_RWLOCK_USEATOMIC
166 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
167 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
168 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
169 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
171 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
172 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
173 #define ZONEDB_LOCK(l, t) LOCK(l)
174 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
181 #ifdef DNS_ZONE_CHECKLOCK
182 isc_boolean_t locked;
185 isc_refcount_t erefs;
187 #ifdef ISC_RWLOCK_USEATOMIC
192 dns_db_t *db; /* Locked by dblock */
196 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
201 dns_masterformat_t masterformat;
203 isc_int32_t journalsize;
204 dns_rdataclass_t rdclass;
207 unsigned int options;
208 unsigned int db_argc;
210 isc_time_t expiretime;
211 isc_time_t refreshtime;
214 isc_time_t notifytime;
215 isc_time_t resigntime;
216 isc_time_t keywarntime;
217 isc_time_t signingtime;
218 isc_time_t nsec3chaintime;
219 isc_time_t refreshkeytime;
220 isc_uint32_t refreshkeycount;
221 isc_uint32_t refresh;
224 isc_uint32_t minimum;
225 isc_stdtime_t key_expiry;
226 isc_stdtime_t log_key_expired_timer;
229 isc_uint32_t maxrefresh;
230 isc_uint32_t minrefresh;
231 isc_uint32_t maxretry;
232 isc_uint32_t minretry;
234 isc_sockaddr_t *masters;
235 dns_name_t **masterkeynames;
236 isc_boolean_t *mastersok;
237 unsigned int masterscnt;
238 unsigned int curmaster;
239 isc_sockaddr_t masteraddr;
240 dns_notifytype_t notifytype;
241 isc_sockaddr_t *notify;
242 unsigned int notifycnt;
243 isc_sockaddr_t notifyfrom;
245 isc_sockaddr_t notifysrc4;
246 isc_sockaddr_t notifysrc6;
247 isc_sockaddr_t xfrsource4;
248 isc_sockaddr_t xfrsource6;
249 isc_sockaddr_t altxfrsource4;
250 isc_sockaddr_t altxfrsource6;
251 isc_sockaddr_t sourceaddr;
252 dns_xfrin_ctx_t *xfr; /* task locked */
253 dns_tsigkey_t *tsigkey; /* key used for xfr */
254 /* Access Control Lists */
255 dns_acl_t *update_acl;
256 dns_acl_t *forward_acl;
257 dns_acl_t *notify_acl;
258 dns_acl_t *query_acl;
259 dns_acl_t *queryon_acl;
261 isc_boolean_t update_disabled;
262 isc_boolean_t zero_no_soa_ttl;
263 dns_severity_t check_names;
264 ISC_LIST(dns_notify_t) notifies;
265 dns_request_t *request;
270 isc_uint32_t maxxfrin;
271 isc_uint32_t maxxfrout;
273 isc_uint32_t idleout;
274 isc_event_t ctlevent;
275 dns_ssutable_t *ssutable;
276 isc_uint32_t sigvalidityinterval;
277 isc_uint32_t sigresigninginterval;
279 dns_acache_t *acache;
280 dns_checkmxfunc_t checkmx;
281 dns_checksrvfunc_t checksrv;
282 dns_checknsfunc_t checkns;
284 * Zones in certain states such as "waiting for zone transfer"
285 * or "zone transfer in progress" are kept on per-state linked lists
286 * in the zone manager using the 'statelink' field. The 'statelist'
287 * field points at the list the zone is currently on. It the zone
288 * is not on any such list, statelist is NULL.
290 ISC_LINK(dns_zone_t) statelink;
291 dns_zonelist_t *statelist;
293 * Statistics counters about zone management.
297 * Optional per-zone statistics counters. Counted outside of this
300 isc_boolean_t requeststats_on;
301 isc_stats_t *requeststats;
302 isc_uint32_t notifydelay;
303 dns_isselffunc_t isself;
312 * Serial number for deferred journal compaction.
314 isc_uint32_t compact_serial;
316 * Keys that are signing the zone for the first time.
318 dns_signinglist_t signing;
319 dns_nsec3chainlist_t nsec3chain;
321 * Signing / re-signing quantum stopping parameters.
323 isc_uint32_t signatures;
325 dns_rdatatype_t privatetype;
328 * Autosigning/key-maintenance options
330 isc_uint32_t keyopts;
333 * True if added by "rndc addzone"
338 * whether a rpz radix was needed when last loaded
340 isc_boolean_t rpz_zone;
343 * Outstanding forwarded UPDATE requests.
345 dns_forwardlist_t forwards;
348 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
349 #define DNS_ZONE_SETFLAG(z,f) do { \
350 INSIST(LOCKED_ZONE(z)); \
353 #define DNS_ZONE_CLRFLAG(z,f) do { \
354 INSIST(LOCKED_ZONE(z)); \
355 (z)->flags &= ~(f); \
357 /* XXX MPA these may need to go back into zone.h */
358 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
359 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
360 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
361 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
362 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
363 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
364 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
365 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
366 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
367 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
369 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
371 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
373 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
374 * zone with no masters
376 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
377 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
378 * from SOA (if not set, we
380 * default timer values) */
381 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
382 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
383 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
384 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
385 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
386 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
387 #define DNS_ZONEFLG_FLUSH 0x00200000U
388 #define DNS_ZONEFLG_NOEDNS 0x00400000U
389 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
390 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
391 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
392 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
393 #define DNS_ZONEFLG_THAW 0x08000000U
394 /* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */
395 #define DNS_ZONEFLG_NODELAY 0x20000000U
397 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
398 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
400 /* Flags for zone_load() */
401 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
402 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
405 #define UNREACH_CHACHE_SIZE 10U
406 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
409 do { result = (op); \
410 if (result != ISC_R_SUCCESS) goto failure; \
413 struct dns_unreachable {
414 isc_sockaddr_t remote;
415 isc_sockaddr_t local;
423 int refs; /* Locked by rwlock */
424 isc_taskmgr_t * taskmgr;
425 isc_timermgr_t * timermgr;
426 isc_socketmgr_t * socketmgr;
427 isc_taskpool_t * zonetasks;
429 isc_ratelimiter_t * rl;
434 /* Locked by rwlock. */
435 dns_zonelist_t zones;
436 dns_zonelist_t waiting_for_xfrin;
437 dns_zonelist_t xfrin_in_progress;
439 /* Configuration data. */
440 isc_uint32_t transfersin;
441 isc_uint32_t transfersperns;
442 unsigned int serialqueryrate;
444 /* Locked by iolock */
445 isc_uint32_t iolimit;
446 isc_uint32_t ioactive;
450 /* Locked by urlock. */
452 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
464 dns_request_t *request;
467 ISC_LINK(dns_notify_t) link;
470 #define DNS_NOTIFY_NOSOA 0x0001U
473 * dns_stub holds state while performing a 'stub' transfer.
474 * 'db' is the zone's 'db' or a new one if this is the initial
483 dns_dbversion_t *version;
495 dns_rdatacallbacks_t callbacks;
499 * Hold forward state.
505 isc_buffer_t *msgbuf;
506 dns_request_t *request;
509 dns_updatecallback_t callback;
511 ISC_LINK(dns_forward_t) link;
515 * Hold IO request state.
522 ISC_LINK(dns_io_t) link;
527 * Hold state for when we are signing a zone with a new
528 * DNSKEY as result of an update.
533 dns_dbiterator_t *dbiterator;
534 dns_secalg_t algorithm;
536 isc_boolean_t delete;
538 ISC_LINK(dns_signing_t) link;
541 struct dns_nsec3chain {
544 dns_dbiterator_t *dbiterator;
545 dns_rdata_nsec3param_t nsec3param;
546 unsigned char salt[255];
548 isc_boolean_t seen_nsec;
549 isc_boolean_t delete_nsec;
550 isc_boolean_t save_delete_nsec;
551 ISC_LINK(dns_nsec3chain_t) link;
554 * 'dbiterator' contains a iterator for the database. If we are creating
555 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
556 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
559 * 'nsec3param' contains the parameters of the NSEC3 chain being created
562 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
564 * 'seen_nsec' will be set to true if, while iterating the zone to create a
565 * NSEC3 chain, a NSEC record is seen.
567 * 'delete_nsec' will be set to true if, at the completion of the creation
568 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
569 * are in the process of deleting the NSEC chain.
571 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
572 * so it can be recovered in the event of a error.
575 struct dns_keyfetch {
576 dns_fixedname_t name;
577 dns_rdataset_t keydataset;
578 dns_rdataset_t dnskeyset;
579 dns_rdataset_t dnskeysigset;
586 #define DAY (24*HOUR)
587 #define MONTH (30*DAY)
589 #define SEND_BUFFER_SIZE 2048
591 static void zone_settimer(dns_zone_t *, isc_time_t *);
592 static void cancel_refresh(dns_zone_t *);
593 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
594 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
595 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
596 ISC_FORMAT_PRINTF(3, 4);
597 static void queue_xfrin(dns_zone_t *zone);
598 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
599 dns_diff_t *diff, dns_diffop_t op,
600 dns_name_t *name, dns_ttl_t ttl,
602 static void zone_unload(dns_zone_t *zone);
603 static void zone_expire(dns_zone_t *zone);
604 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
605 static void zone_idetach(dns_zone_t **zonep);
606 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
608 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
609 static inline void zone_detachdb(dns_zone_t *zone);
610 static isc_result_t default_journal(dns_zone_t *zone);
611 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
612 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
613 isc_time_t loadtime, isc_result_t result);
614 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
615 static void zone_shutdown(isc_task_t *, isc_event_t *);
616 static void zone_loaddone(void *arg, isc_result_t result);
617 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
618 isc_time_t loadtime);
619 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
620 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
621 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
622 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
625 /* ondestroy example */
626 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
629 static void refresh_callback(isc_task_t *, isc_event_t *);
630 static void stub_callback(isc_task_t *, isc_event_t *);
631 static void queue_soa_query(dns_zone_t *zone);
632 static void soa_query(isc_task_t *, isc_event_t *);
633 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
635 static int message_count(dns_message_t *msg, dns_section_t section,
636 dns_rdatatype_t type);
637 static void notify_cancel(dns_zone_t *zone);
638 static void notify_find_address(dns_notify_t *notify);
639 static void notify_send(dns_notify_t *notify);
640 static isc_result_t notify_createmessage(dns_zone_t *zone,
642 dns_message_t **messagep);
643 static void notify_done(isc_task_t *task, isc_event_t *event);
644 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
645 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
646 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
647 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
649 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
650 static void zonemgr_free(dns_zonemgr_t *zmgr);
651 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
652 isc_task_t *task, isc_taskaction_t action,
653 void *arg, dns_io_t **iop);
654 static void zonemgr_putio(dns_io_t **iop);
655 static void zonemgr_cancelio(dns_io_t *io);
658 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
659 unsigned int *soacount, isc_uint32_t *serial,
660 isc_uint32_t *refresh, isc_uint32_t *retry,
661 isc_uint32_t *expire, isc_uint32_t *minimum,
662 unsigned int *errors);
664 static void zone_freedbargs(dns_zone_t *zone);
665 static void forward_callback(isc_task_t *task, isc_event_t *event);
666 static void zone_saveunique(dns_zone_t *zone, const char *path,
667 const char *templat);
668 static void zone_maintenance(dns_zone_t *zone);
669 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
670 static void dump_done(void *arg, isc_result_t result);
671 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
672 isc_uint16_t keyid, isc_boolean_t delete);
673 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
674 dns_dbnode_t *node, dns_name_t *name,
676 static void zone_rekey(dns_zone_t *zone);
677 static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
678 dst_key_t **keys, unsigned int nkeys);
680 #define ENTER zone_debuglog(zone, me, 1, "enter")
682 static const unsigned int dbargc_default = 1;
683 static const char *dbargv_default[] = { "rbt" };
685 #define DNS_ZONE_JITTER_ADD(a, b, c) \
689 _j = isc_random_jitter((b), (b)/4); \
690 isc_interval_set(&_i, _j, 0); \
691 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
692 dns_zone_log(zone, ISC_LOG_WARNING, \
693 "epoch approaching: upgrade required: " \
694 "now + %s failed", #b); \
695 isc_interval_set(&_i, _j/2, 0); \
696 (void)isc_time_add((a), &_i, (c)); \
700 #define DNS_ZONE_TIME_ADD(a, b, c) \
703 isc_interval_set(&_i, (b), 0); \
704 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
705 dns_zone_log(zone, ISC_LOG_WARNING, \
706 "epoch approaching: upgrade required: " \
707 "now + %s failed", #b); \
708 isc_interval_set(&_i, (b)/2, 0); \
709 (void)isc_time_add((a), &_i, (c)); \
714 * Increment resolver-related statistics counters. Zone must be locked.
717 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
718 if (zone->stats != NULL)
719 isc_stats_increment(zone->stats, counter);
723 *** Public functions.
727 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
732 REQUIRE(zonep != NULL && *zonep == NULL);
733 REQUIRE(mctx != NULL);
736 zone = isc_mem_get(mctx, sizeof(*zone));
738 return (ISC_R_NOMEMORY);
741 isc_mem_attach(mctx, &zone->mctx);
743 result = isc_mutex_init(&zone->lock);
744 if (result != ISC_R_SUCCESS)
747 result = ZONEDB_INITLOCK(&zone->dblock);
748 if (result != ISC_R_SUCCESS)
751 /* XXX MPA check that all elements are initialised */
752 #ifdef DNS_ZONE_CHECKLOCK
753 zone->locked = ISC_FALSE;
757 ISC_LINK_INIT(zone, link);
758 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
759 if (result != ISC_R_SUCCESS)
762 dns_name_init(&zone->origin, NULL);
763 zone->strnamerd = NULL;
764 zone->strname = NULL;
765 zone->strrdclass = NULL;
766 zone->strviewname = NULL;
767 zone->masterfile = NULL;
768 zone->masterformat = dns_masterformat_none;
769 zone->keydirectory = NULL;
770 zone->journalsize = -1;
771 zone->journal = NULL;
772 zone->rdclass = dns_rdataclass_none;
773 zone->type = dns_zone_none;
778 zone->db_argv = NULL;
779 isc_time_settoepoch(&zone->expiretime);
780 isc_time_settoepoch(&zone->refreshtime);
781 isc_time_settoepoch(&zone->dumptime);
782 isc_time_settoepoch(&zone->loadtime);
783 zone->notifytime = now;
784 isc_time_settoepoch(&zone->resigntime);
785 isc_time_settoepoch(&zone->keywarntime);
786 isc_time_settoepoch(&zone->signingtime);
787 isc_time_settoepoch(&zone->nsec3chaintime);
788 isc_time_settoepoch(&zone->refreshkeytime);
789 zone->refreshkeycount = 0;
790 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
791 zone->retry = DNS_ZONE_DEFAULTRETRY;
794 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
795 zone->minrefresh = DNS_ZONE_MINREFRESH;
796 zone->maxretry = DNS_ZONE_MAXRETRY;
797 zone->minretry = DNS_ZONE_MINRETRY;
798 zone->masters = NULL;
799 zone->masterkeynames = NULL;
800 zone->mastersok = NULL;
801 zone->masterscnt = 0;
804 zone->notifytype = dns_notifytype_yes;
807 zone->update_acl = NULL;
808 zone->forward_acl = NULL;
809 zone->notify_acl = NULL;
810 zone->query_acl = NULL;
811 zone->queryon_acl = NULL;
812 zone->xfr_acl = NULL;
813 zone->update_disabled = ISC_FALSE;
814 zone->zero_no_soa_ttl = ISC_TRUE;
815 zone->check_names = dns_severity_ignore;
816 zone->request = NULL;
820 zone->writeio = NULL;
822 zone->idlein = DNS_DEFAULT_IDLEIN;
823 zone->idleout = DNS_DEFAULT_IDLEOUT;
824 zone->log_key_expired_timer = 0;
825 ISC_LIST_INIT(zone->notifies);
826 isc_sockaddr_any(&zone->notifysrc4);
827 isc_sockaddr_any6(&zone->notifysrc6);
828 isc_sockaddr_any(&zone->xfrsource4);
829 isc_sockaddr_any6(&zone->xfrsource6);
830 isc_sockaddr_any(&zone->altxfrsource4);
831 isc_sockaddr_any6(&zone->altxfrsource6);
833 zone->tsigkey = NULL;
834 zone->maxxfrin = MAX_XFER_TIME;
835 zone->maxxfrout = MAX_XFER_TIME;
836 zone->ssutable = NULL;
837 zone->sigvalidityinterval = 30 * 24 * 3600;
838 zone->sigresigninginterval = 7 * 24 * 3600;
841 zone->checkmx = NULL;
842 zone->checksrv = NULL;
843 zone->checkns = NULL;
844 ISC_LINK_INIT(zone, statelink);
845 zone->statelist = NULL;
847 zone->requeststats_on = ISC_FALSE;
848 zone->requeststats = NULL;
849 zone->notifydelay = 5;
851 zone->isselfarg = NULL;
852 ISC_LIST_INIT(zone->signing);
853 ISC_LIST_INIT(zone->nsec3chain);
854 zone->signatures = 10;
856 zone->privatetype = (dns_rdatatype_t)0xffffU;
857 zone->added = ISC_FALSE;
858 zone->rpz_zone = ISC_FALSE;
859 ISC_LIST_INIT(zone->forwards);
861 zone->magic = ZONE_MAGIC;
863 /* Must be after magic is set. */
864 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
865 if (result != ISC_R_SUCCESS)
868 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
869 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
872 return (ISC_R_SUCCESS);
875 isc_refcount_decrement(&zone->erefs, NULL);
876 isc_refcount_destroy(&zone->erefs);
879 ZONEDB_DESTROYLOCK(&zone->dblock);
882 DESTROYLOCK(&zone->lock);
885 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
890 * Free a zone. Because we require that there be no more
891 * outstanding events or references, no locking is necessary.
894 zone_free(dns_zone_t *zone) {
895 isc_mem_t *mctx = NULL;
896 dns_signing_t *signing;
897 dns_nsec3chain_t *nsec3chain;
899 REQUIRE(DNS_ZONE_VALID(zone));
900 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
901 REQUIRE(zone->irefs == 0);
902 REQUIRE(!LOCKED_ZONE(zone));
903 REQUIRE(zone->timer == NULL);
906 * Managed objects. Order is important.
908 if (zone->request != NULL)
909 dns_request_destroy(&zone->request); /* XXXMPA */
910 INSIST(zone->readio == NULL);
911 INSIST(zone->statelist == NULL);
912 INSIST(zone->writeio == NULL);
914 if (zone->task != NULL)
915 isc_task_detach(&zone->task);
916 if (zone->zmgr != NULL)
917 dns_zonemgr_releasezone(zone->zmgr, zone);
919 /* Unmanaged objects */
920 for (signing = ISC_LIST_HEAD(zone->signing);
922 signing = ISC_LIST_HEAD(zone->signing)) {
923 ISC_LIST_UNLINK(zone->signing, signing, link);
924 dns_db_detach(&signing->db);
925 dns_dbiterator_destroy(&signing->dbiterator);
926 isc_mem_put(zone->mctx, signing, sizeof *signing);
928 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
930 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
931 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
932 dns_db_detach(&nsec3chain->db);
933 dns_dbiterator_destroy(&nsec3chain->dbiterator);
934 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
936 if (zone->masterfile != NULL)
937 isc_mem_free(zone->mctx, zone->masterfile);
938 zone->masterfile = NULL;
939 if (zone->keydirectory != NULL)
940 isc_mem_free(zone->mctx, zone->keydirectory);
941 zone->keydirectory = NULL;
942 zone->journalsize = -1;
943 if (zone->journal != NULL)
944 isc_mem_free(zone->mctx, zone->journal);
945 zone->journal = NULL;
946 if (zone->stats != NULL)
947 isc_stats_detach(&zone->stats);
948 if (zone->requeststats != NULL)
949 isc_stats_detach(&zone->requeststats);
950 if (zone->db != NULL)
952 if (zone->acache != NULL)
953 dns_acache_detach(&zone->acache);
954 zone_freedbargs(zone);
955 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
957 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
959 zone->check_names = dns_severity_ignore;
960 if (zone->update_acl != NULL)
961 dns_acl_detach(&zone->update_acl);
962 if (zone->forward_acl != NULL)
963 dns_acl_detach(&zone->forward_acl);
964 if (zone->notify_acl != NULL)
965 dns_acl_detach(&zone->notify_acl);
966 if (zone->query_acl != NULL)
967 dns_acl_detach(&zone->query_acl);
968 if (zone->queryon_acl != NULL)
969 dns_acl_detach(&zone->queryon_acl);
970 if (zone->xfr_acl != NULL)
971 dns_acl_detach(&zone->xfr_acl);
972 if (dns_name_dynamic(&zone->origin))
973 dns_name_free(&zone->origin, zone->mctx);
974 if (zone->strnamerd != NULL)
975 isc_mem_free(zone->mctx, zone->strnamerd);
976 if (zone->strname != NULL)
977 isc_mem_free(zone->mctx, zone->strname);
978 if (zone->strrdclass != NULL)
979 isc_mem_free(zone->mctx, zone->strrdclass);
980 if (zone->strviewname != NULL)
981 isc_mem_free(zone->mctx, zone->strviewname);
982 if (zone->ssutable != NULL)
983 dns_ssutable_detach(&zone->ssutable);
986 ZONEDB_DESTROYLOCK(&zone->dblock);
987 DESTROYLOCK(&zone->lock);
988 isc_refcount_destroy(&zone->erefs);
991 isc_mem_put(mctx, zone, sizeof(*zone));
992 isc_mem_detach(&mctx);
999 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1002 REQUIRE(DNS_ZONE_VALID(zone));
1003 REQUIRE(rdclass != dns_rdataclass_none);
1009 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1010 zone->rdclass == rdclass);
1011 zone->rdclass = rdclass;
1013 if (zone->strnamerd != NULL)
1014 isc_mem_free(zone->mctx, zone->strnamerd);
1015 if (zone->strrdclass != NULL)
1016 isc_mem_free(zone->mctx, zone->strrdclass);
1018 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1019 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1020 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1021 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1027 dns_zone_getclass(dns_zone_t *zone) {
1028 REQUIRE(DNS_ZONE_VALID(zone));
1030 return (zone->rdclass);
1034 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1035 REQUIRE(DNS_ZONE_VALID(zone));
1038 zone->notifytype = notifytype;
1043 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1044 isc_result_t result;
1046 REQUIRE(DNS_ZONE_VALID(zone));
1047 REQUIRE(serialp != NULL);
1050 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1051 if (zone->db != NULL) {
1052 result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
1053 NULL, NULL, NULL, NULL, NULL);
1055 result = DNS_R_NOTLOADED;
1056 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1063 dns_zone_getserial(dns_zone_t *zone) {
1064 isc_result_t result;
1065 isc_uint32_t serial;
1067 result = dns_zone_getserial2(zone, &serial);
1068 if (result != ISC_R_SUCCESS)
1069 serial = 0; /* XXX: not really correct, but no other choice */
1078 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1080 REQUIRE(DNS_ZONE_VALID(zone));
1081 REQUIRE(type != dns_zone_none);
1087 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1093 zone_freedbargs(dns_zone_t *zone) {
1096 /* Free the old database argument list. */
1097 if (zone->db_argv != NULL) {
1098 for (i = 0; i < zone->db_argc; i++)
1099 isc_mem_free(zone->mctx, zone->db_argv[i]);
1100 isc_mem_put(zone->mctx, zone->db_argv,
1101 zone->db_argc * sizeof(*zone->db_argv));
1104 zone->db_argv = NULL;
1108 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1111 isc_result_t result = ISC_R_SUCCESS;
1115 REQUIRE(DNS_ZONE_VALID(zone));
1116 REQUIRE(argv != NULL && *argv == NULL);
1119 size = (zone->db_argc + 1) * sizeof(char *);
1120 for (i = 0; i < zone->db_argc; i++)
1121 size += strlen(zone->db_argv[i]) + 1;
1122 mem = isc_mem_allocate(mctx, size);
1126 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1127 for (i = 0; i < zone->db_argc; i++) {
1129 strcpy(tmp2, zone->db_argv[i]);
1130 tmp2 += strlen(tmp2) + 1;
1134 result = ISC_R_NOMEMORY;
1141 dns_zone_setdbtype(dns_zone_t *zone,
1142 unsigned int dbargc, const char * const *dbargv) {
1143 isc_result_t result = ISC_R_SUCCESS;
1147 REQUIRE(DNS_ZONE_VALID(zone));
1148 REQUIRE(dbargc >= 1);
1149 REQUIRE(dbargv != NULL);
1153 /* Set up a new database argument list. */
1154 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1157 for (i = 0; i < dbargc; i++)
1159 for (i = 0; i < dbargc; i++) {
1160 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1165 /* Free the old list. */
1166 zone_freedbargs(zone);
1168 zone->db_argc = dbargc;
1169 zone->db_argv = new;
1170 result = ISC_R_SUCCESS;
1175 for (i = 0; i < dbargc; i++)
1177 isc_mem_free(zone->mctx, new[i]);
1178 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1180 result = ISC_R_NOMEMORY;
1188 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1190 REQUIRE(DNS_ZONE_VALID(zone));
1193 if (zone->view != NULL)
1194 dns_view_weakdetach(&zone->view);
1195 dns_view_weakattach(view, &zone->view);
1197 if (zone->strviewname != NULL)
1198 isc_mem_free(zone->mctx, zone->strviewname);
1199 if (zone->strnamerd != NULL)
1200 isc_mem_free(zone->mctx, zone->strnamerd);
1202 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1203 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1204 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1205 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1212 dns_zone_getview(dns_zone_t *zone) {
1213 REQUIRE(DNS_ZONE_VALID(zone));
1215 return (zone->view);
1220 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1221 isc_result_t result;
1224 REQUIRE(DNS_ZONE_VALID(zone));
1225 REQUIRE(origin != NULL);
1228 if (dns_name_dynamic(&zone->origin)) {
1229 dns_name_free(&zone->origin, zone->mctx);
1230 dns_name_init(&zone->origin, NULL);
1232 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1234 if (zone->strnamerd != NULL)
1235 isc_mem_free(zone->mctx, zone->strnamerd);
1236 if (zone->strname != NULL)
1237 isc_mem_free(zone->mctx, zone->strname);
1239 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1240 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1241 zone_name_tostr(zone, namebuf, sizeof namebuf);
1242 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1249 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1250 REQUIRE(DNS_ZONE_VALID(zone));
1251 REQUIRE(acache != NULL);
1254 if (zone->acache != NULL)
1255 dns_acache_detach(&zone->acache);
1256 dns_acache_attach(acache, &zone->acache);
1257 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1258 if (zone->db != NULL) {
1259 isc_result_t result;
1262 * If the zone reuses an existing DB, the DB needs to be
1263 * set in the acache explicitly. We can safely ignore the
1264 * case where the DB is already set. If other error happens,
1265 * the acache will not work effectively.
1267 result = dns_acache_setdb(acache, zone->db);
1268 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1269 UNEXPECTED_ERROR(__FILE__, __LINE__,
1270 "dns_acache_setdb() failed: %s",
1271 isc_result_totext(result));
1274 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1279 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1282 if (value != NULL) {
1283 copy = isc_mem_strdup(zone->mctx, value);
1285 return (ISC_R_NOMEMORY);
1291 isc_mem_free(zone->mctx, *field);
1294 return (ISC_R_SUCCESS);
1298 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1299 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1303 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1304 dns_masterformat_t format) {
1305 isc_result_t result = ISC_R_SUCCESS;
1307 REQUIRE(DNS_ZONE_VALID(zone));
1310 result = dns_zone_setstring(zone, &zone->masterfile, file);
1311 if (result == ISC_R_SUCCESS) {
1312 zone->masterformat = format;
1313 result = default_journal(zone);
1321 dns_zone_getfile(dns_zone_t *zone) {
1322 REQUIRE(DNS_ZONE_VALID(zone));
1324 return (zone->masterfile);
1328 default_journal(dns_zone_t *zone) {
1329 isc_result_t result;
1332 REQUIRE(DNS_ZONE_VALID(zone));
1333 REQUIRE(LOCKED_ZONE(zone));
1335 if (zone->masterfile != NULL) {
1336 /* Calculate string length including '\0'. */
1337 int len = strlen(zone->masterfile) + sizeof(".jnl");
1338 journal = isc_mem_allocate(zone->mctx, len);
1339 if (journal == NULL)
1340 return (ISC_R_NOMEMORY);
1341 strcpy(journal, zone->masterfile);
1342 strcat(journal, ".jnl");
1346 result = dns_zone_setstring(zone, &zone->journal, journal);
1347 if (journal != NULL)
1348 isc_mem_free(zone->mctx, journal);
1353 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1354 isc_result_t result = ISC_R_SUCCESS;
1356 REQUIRE(DNS_ZONE_VALID(zone));
1359 result = dns_zone_setstring(zone, &zone->journal, journal);
1366 dns_zone_getjournal(dns_zone_t *zone) {
1367 REQUIRE(DNS_ZONE_VALID(zone));
1369 return (zone->journal);
1373 * Return true iff the zone is "dynamic", in the sense that the zone's
1374 * master file (if any) is written by the server, rather than being
1375 * updated manually and read by the server.
1377 * This is true for slave zones, stub zones, key zones, and zones that
1378 * allow dynamic updates either by having an update policy ("ssutable")
1379 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1381 static isc_boolean_t
1382 zone_isdynamic(dns_zone_t *zone) {
1383 REQUIRE(DNS_ZONE_VALID(zone));
1385 return (ISC_TF(zone->type == dns_zone_slave ||
1386 zone->type == dns_zone_stub ||
1387 zone->type == dns_zone_key ||
1388 (!zone->update_disabled && zone->ssutable != NULL) ||
1389 (!zone->update_disabled && zone->update_acl != NULL &&
1390 !dns_acl_isnone(zone->update_acl))));
1395 zone_load(dns_zone_t *zone, unsigned int flags) {
1396 isc_result_t result;
1398 isc_time_t loadtime, filetime;
1399 dns_db_t *db = NULL;
1402 REQUIRE(DNS_ZONE_VALID(zone));
1407 INSIST(zone->type != dns_zone_none);
1409 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1410 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1412 result = DNS_R_CONTINUE;
1417 INSIST(zone->db_argc >= 1);
1419 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1420 strcmp(zone->db_argv[0], "rbt64") == 0;
1422 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1424 * The zone has no master file configured.
1426 result = ISC_R_SUCCESS;
1430 if (zone->db != NULL && zone_isdynamic(zone)) {
1432 * This is a slave, stub, or dynamically updated
1433 * zone being reloaded. Do nothing - the database
1434 * we already have is guaranteed to be up-to-date.
1436 if (zone->type == dns_zone_master)
1437 result = DNS_R_DYNAMIC;
1439 result = ISC_R_SUCCESS;
1444 * Store the current time before the zone is loaded, so that if the
1445 * file changes between the time of the load and the time that
1446 * zone->loadtime is set, then the file will still be reloaded
1447 * the next time dns_zone_load is called.
1449 TIME_NOW(&loadtime);
1452 * Don't do the load if the file that stores the zone is older
1453 * than the last time the zone was loaded. If the zone has not
1454 * been loaded yet, zone->loadtime will be the epoch.
1456 if (zone->masterfile != NULL) {
1458 * The file is already loaded. If we are just doing a
1459 * "rndc reconfig", we are done.
1461 if (!isc_time_isepoch(&zone->loadtime) &&
1462 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 &&
1463 zone->rpz_zone == dns_rpz_needed()) {
1464 result = ISC_R_SUCCESS;
1468 result = isc_file_getmodtime(zone->masterfile, &filetime);
1469 if (result == ISC_R_SUCCESS) {
1470 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1471 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1472 isc_time_compare(&filetime, &zone->loadtime) <= 0 &&
1473 zone->rpz_zone == dns_rpz_needed()) {
1474 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1475 "skipping load: master file "
1476 "older than last load");
1477 result = DNS_R_UPTODATE;
1480 loadtime = filetime;
1481 zone->rpz_zone = dns_rpz_needed();
1486 * Built in zones (with the exception of empty zones) don't need
1489 if (zone->type == dns_zone_master &&
1490 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1491 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1492 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1493 result = ISC_R_SUCCESS;
1497 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1499 if (zone->masterfile == NULL ||
1500 !isc_file_exists(zone->masterfile)) {
1501 if (zone->masterfile != NULL) {
1502 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1505 zone->refreshtime = now;
1506 if (zone->task != NULL)
1507 zone_settimer(zone, &now);
1508 result = ISC_R_SUCCESS;
1513 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1515 result = dns_db_create(zone->mctx, zone->db_argv[0],
1516 &zone->origin, (zone->type == dns_zone_stub) ?
1517 dns_dbtype_stub : dns_dbtype_zone,
1519 zone->db_argc - 1, zone->db_argv + 1,
1522 if (result != ISC_R_SUCCESS) {
1523 dns_zone_log(zone, ISC_LOG_ERROR,
1524 "loading zone: creating database: %s",
1525 isc_result_totext(result));
1528 dns_db_settask(db, zone->task);
1530 if (! dns_db_ispersistent(db)) {
1531 if (zone->masterfile != NULL) {
1532 result = zone_startload(db, zone, loadtime);
1534 result = DNS_R_NOMASTERFILE;
1535 if (zone->type == dns_zone_master) {
1536 dns_zone_log(zone, ISC_LOG_ERROR,
1538 "no master file configured");
1541 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1542 "no master file configured: continuing");
1546 if (result == DNS_R_CONTINUE) {
1547 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1548 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1549 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1553 result = zone_postload(zone, db, loadtime, result);
1563 dns_zone_load(dns_zone_t *zone) {
1564 return (zone_load(zone, 0));
1568 dns_zone_loadnew(dns_zone_t *zone) {
1569 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1573 dns_zone_loadandthaw(dns_zone_t *zone) {
1574 isc_result_t result;
1576 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1578 case DNS_R_CONTINUE:
1579 /* Deferred thaw. */
1582 case DNS_R_UPTODATE:
1583 case DNS_R_SEENINCLUDE:
1584 zone->update_disabled = ISC_FALSE;
1586 case DNS_R_NOMASTERFILE:
1587 zone->update_disabled = ISC_FALSE;
1590 /* Error, remain in disabled state. */
1597 get_master_options(dns_zone_t *zone) {
1598 unsigned int options;
1600 options = DNS_MASTER_ZONE;
1601 if (zone->type == dns_zone_slave)
1602 options |= DNS_MASTER_SLAVE;
1603 if (zone->type == dns_zone_key)
1604 options |= DNS_MASTER_KEY;
1605 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1606 options |= DNS_MASTER_CHECKNS;
1607 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1608 options |= DNS_MASTER_FATALNS;
1609 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1610 options |= DNS_MASTER_CHECKNAMES;
1611 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1612 options |= DNS_MASTER_CHECKNAMESFAIL;
1613 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1614 options |= DNS_MASTER_CHECKMX;
1615 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1616 options |= DNS_MASTER_CHECKMXFAIL;
1617 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1618 options |= DNS_MASTER_CHECKWILDCARD;
1619 if (zone->type == dns_zone_master &&
1620 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1621 zone->ssutable != NULL))
1622 options |= DNS_MASTER_RESIGN;
1627 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1628 dns_load_t *load = event->ev_arg;
1629 isc_result_t result = ISC_R_SUCCESS;
1630 unsigned int options;
1632 REQUIRE(DNS_LOAD_VALID(load));
1634 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1635 result = ISC_R_CANCELED;
1636 isc_event_free(&event);
1637 if (result == ISC_R_CANCELED)
1640 options = get_master_options(load->zone);
1642 result = dns_master_loadfileinc3(load->zone->masterfile,
1643 dns_db_origin(load->db),
1644 dns_db_origin(load->db),
1645 load->zone->rdclass,
1647 load->zone->sigresigninginterval,
1648 &load->callbacks, task,
1649 zone_loaddone, load,
1650 &load->zone->lctx, load->zone->mctx,
1651 load->zone->masterformat);
1652 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1653 result != DNS_R_SEENINCLUDE)
1658 zone_loaddone(load, result);
1662 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1663 const char me[] = "zone_gotwritehandle";
1664 dns_zone_t *zone = event->ev_arg;
1665 isc_result_t result = ISC_R_SUCCESS;
1666 dns_dbversion_t *version = NULL;
1668 REQUIRE(DNS_ZONE_VALID(zone));
1669 INSIST(task == zone->task);
1672 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1673 result = ISC_R_CANCELED;
1674 isc_event_free(&event);
1675 if (result == ISC_R_CANCELED)
1679 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1680 if (zone->db != NULL) {
1681 dns_db_currentversion(zone->db, &version);
1682 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1683 &dns_master_style_default,
1684 zone->masterfile, zone->task,
1685 dump_done, zone, &zone->dctx,
1686 zone->masterformat);
1687 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1689 result = ISC_R_CANCELED;
1690 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1692 if (result != DNS_R_CONTINUE)
1697 dump_done(zone, result);
1701 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1703 isc_result_t result;
1704 isc_result_t tresult;
1705 unsigned int options;
1707 options = get_master_options(zone);
1709 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1710 options |= DNS_MASTER_MANYERRORS;
1712 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1713 load = isc_mem_get(zone->mctx, sizeof(*load));
1715 return (ISC_R_NOMEMORY);
1720 load->loadtime = loadtime;
1721 load->magic = LOAD_MAGIC;
1723 isc_mem_attach(zone->mctx, &load->mctx);
1724 zone_iattach(zone, &load->zone);
1725 dns_db_attach(db, &load->db);
1726 dns_rdatacallbacks_init(&load->callbacks);
1727 result = dns_db_beginload(db, &load->callbacks.add,
1728 &load->callbacks.add_private);
1729 if (result != ISC_R_SUCCESS)
1731 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1732 zone_gotreadhandle, load,
1734 if (result != ISC_R_SUCCESS) {
1736 * We can't report multiple errors so ignore
1737 * the result of dns_db_endload().
1739 (void)dns_db_endload(load->db,
1740 &load->callbacks.add_private);
1743 result = DNS_R_CONTINUE;
1745 dns_rdatacallbacks_t callbacks;
1747 dns_rdatacallbacks_init(&callbacks);
1748 result = dns_db_beginload(db, &callbacks.add,
1749 &callbacks.add_private);
1750 if (result != ISC_R_SUCCESS)
1752 result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1753 &zone->origin, zone->rdclass,
1754 options, zone->sigresigninginterval,
1755 &callbacks, zone->mctx,
1756 zone->masterformat);
1757 tresult = dns_db_endload(db, &callbacks.add_private);
1758 if (result == ISC_R_SUCCESS)
1766 dns_db_detach(&load->db);
1767 zone_idetach(&load->zone);
1768 isc_mem_detach(&load->mctx);
1769 isc_mem_put(zone->mctx, load, sizeof(*load));
1773 static isc_boolean_t
1774 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1777 isc_result_t result;
1778 char ownerbuf[DNS_NAME_FORMATSIZE];
1779 char namebuf[DNS_NAME_FORMATSIZE];
1780 char altbuf[DNS_NAME_FORMATSIZE];
1781 dns_fixedname_t fixed;
1782 dns_name_t *foundname;
1786 * "." means the services does not exist.
1788 if (dns_name_equal(name, dns_rootname))
1794 if (!dns_name_issubdomain(name, &zone->origin)) {
1795 if (zone->checkmx != NULL)
1796 return ((zone->checkmx)(zone, name, owner));
1800 if (zone->type == dns_zone_master)
1801 level = ISC_LOG_ERROR;
1803 level = ISC_LOG_WARNING;
1805 dns_fixedname_init(&fixed);
1806 foundname = dns_fixedname_name(&fixed);
1808 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1809 0, 0, NULL, foundname, NULL, NULL);
1810 if (result == ISC_R_SUCCESS)
1813 if (result == DNS_R_NXRRSET) {
1814 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1815 0, 0, NULL, foundname, NULL, NULL);
1816 if (result == ISC_R_SUCCESS)
1820 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1821 dns_name_format(name, namebuf, sizeof namebuf);
1822 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1823 result == DNS_R_EMPTYNAME) {
1824 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1825 level = ISC_LOG_WARNING;
1826 dns_zone_log(zone, level,
1827 "%s/MX '%s' has no address records (A or AAAA)",
1829 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1832 if (result == DNS_R_CNAME) {
1833 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1834 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1835 level = ISC_LOG_WARNING;
1836 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1837 dns_zone_log(zone, level,
1838 "%s/MX '%s' is a CNAME (illegal)",
1840 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1843 if (result == DNS_R_DNAME) {
1844 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1845 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1846 level = ISC_LOG_WARNING;
1847 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1848 dns_name_format(foundname, altbuf, sizeof altbuf);
1849 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1850 " '%s' (illegal)", ownerbuf, namebuf,
1853 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1856 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1857 return ((zone->checkmx)(zone, name, owner));
1862 static isc_boolean_t
1863 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1866 isc_result_t result;
1867 char ownerbuf[DNS_NAME_FORMATSIZE];
1868 char namebuf[DNS_NAME_FORMATSIZE];
1869 char altbuf[DNS_NAME_FORMATSIZE];
1870 dns_fixedname_t fixed;
1871 dns_name_t *foundname;
1875 * "." means the services does not exist.
1877 if (dns_name_equal(name, dns_rootname))
1883 if (!dns_name_issubdomain(name, &zone->origin)) {
1884 if (zone->checksrv != NULL)
1885 return ((zone->checksrv)(zone, name, owner));
1889 if (zone->type == dns_zone_master)
1890 level = ISC_LOG_ERROR;
1892 level = ISC_LOG_WARNING;
1894 dns_fixedname_init(&fixed);
1895 foundname = dns_fixedname_name(&fixed);
1897 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1898 0, 0, NULL, foundname, NULL, NULL);
1899 if (result == ISC_R_SUCCESS)
1902 if (result == DNS_R_NXRRSET) {
1903 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1904 0, 0, NULL, foundname, NULL, NULL);
1905 if (result == ISC_R_SUCCESS)
1909 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1910 dns_name_format(name, namebuf, sizeof namebuf);
1911 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1912 result == DNS_R_EMPTYNAME) {
1913 dns_zone_log(zone, level,
1914 "%s/SRV '%s' has no address records (A or AAAA)",
1916 /* XXX950 make fatal for 9.5.0. */
1920 if (result == DNS_R_CNAME) {
1921 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1922 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1923 level = ISC_LOG_WARNING;
1924 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1925 dns_zone_log(zone, level,
1926 "%s/SRV '%s' is a CNAME (illegal)",
1928 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1931 if (result == DNS_R_DNAME) {
1932 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1933 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1934 level = ISC_LOG_WARNING;
1935 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1936 dns_name_format(foundname, altbuf, sizeof altbuf);
1937 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1938 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1941 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1944 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1945 return ((zone->checksrv)(zone, name, owner));
1950 static isc_boolean_t
1951 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1954 isc_boolean_t answer = ISC_TRUE;
1955 isc_result_t result, tresult;
1956 char ownerbuf[DNS_NAME_FORMATSIZE];
1957 char namebuf[DNS_NAME_FORMATSIZE];
1958 char altbuf[DNS_NAME_FORMATSIZE];
1959 dns_fixedname_t fixed;
1960 dns_name_t *foundname;
1962 dns_rdataset_t aaaa;
1968 if (!dns_name_issubdomain(name, &zone->origin)) {
1969 if (zone->checkns != NULL)
1970 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1974 if (zone->type == dns_zone_master)
1975 level = ISC_LOG_ERROR;
1977 level = ISC_LOG_WARNING;
1979 dns_fixedname_init(&fixed);
1980 foundname = dns_fixedname_name(&fixed);
1981 dns_rdataset_init(&a);
1982 dns_rdataset_init(&aaaa);
1984 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1985 DNS_DBFIND_GLUEOK, 0, NULL,
1986 foundname, &a, NULL);
1988 if (result == ISC_R_SUCCESS) {
1989 dns_rdataset_disassociate(&a);
1991 } else if (result == DNS_R_DELEGATION)
1992 dns_rdataset_disassociate(&a);
1994 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1995 result == DNS_R_GLUE) {
1996 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1997 DNS_DBFIND_GLUEOK, 0, NULL,
1998 foundname, &aaaa, NULL);
1999 if (tresult == ISC_R_SUCCESS) {
2000 dns_rdataset_disassociate(&aaaa);
2003 if (tresult == DNS_R_DELEGATION)
2004 dns_rdataset_disassociate(&aaaa);
2005 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2007 * Check glue against child zone.
2009 if (zone->checkns != NULL)
2010 answer = (zone->checkns)(zone, name, owner,
2012 if (dns_rdataset_isassociated(&a))
2013 dns_rdataset_disassociate(&a);
2014 if (dns_rdataset_isassociated(&aaaa))
2015 dns_rdataset_disassociate(&aaaa);
2020 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2021 dns_name_format(name, namebuf, sizeof namebuf);
2022 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2023 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2025 isc_boolean_t required = ISC_FALSE;
2026 if (dns_name_issubdomain(name, owner)) {
2027 what = "REQUIRED GLUE ";
2028 required = ISC_TRUE;
2029 } else if (result == DNS_R_DELEGATION)
2030 what = "SIBLING GLUE ";
2034 if (result != DNS_R_DELEGATION || required ||
2035 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2036 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2037 "address records (A or AAAA)",
2038 ownerbuf, namebuf, what);
2040 * Log missing address record.
2042 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2043 (void)(zone->checkns)(zone, name, owner,
2045 /* XXX950 make fatal for 9.5.0. */
2046 /* answer = ISC_FALSE; */
2048 } else if (result == DNS_R_CNAME) {
2049 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2051 /* XXX950 make fatal for 9.5.0. */
2052 /* answer = ISC_FALSE; */
2053 } else if (result == DNS_R_DNAME) {
2054 dns_name_format(foundname, altbuf, sizeof altbuf);
2055 dns_zone_log(zone, level,
2056 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2057 ownerbuf, namebuf, altbuf);
2058 /* XXX950 make fatal for 9.5.0. */
2059 /* answer = ISC_FALSE; */
2062 if (dns_rdataset_isassociated(&a))
2063 dns_rdataset_disassociate(&a);
2064 if (dns_rdataset_isassociated(&aaaa))
2065 dns_rdataset_disassociate(&aaaa);
2069 static isc_boolean_t
2070 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2071 dns_rdataset_t *rdataset)
2073 dns_rdataset_t tmprdataset;
2074 isc_result_t result;
2075 isc_boolean_t answer = ISC_TRUE;
2076 isc_boolean_t format = ISC_TRUE;
2077 int level = ISC_LOG_WARNING;
2078 char ownerbuf[DNS_NAME_FORMATSIZE];
2079 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2080 unsigned int count1 = 0;
2082 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2083 level = ISC_LOG_ERROR;
2085 dns_rdataset_init(&tmprdataset);
2086 for (result = dns_rdataset_first(rdataset);
2087 result == ISC_R_SUCCESS;
2088 result = dns_rdataset_next(rdataset)) {
2089 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2090 unsigned int count2 = 0;
2093 dns_rdataset_current(rdataset, &rdata1);
2094 dns_rdataset_clone(rdataset, &tmprdataset);
2095 for (result = dns_rdataset_first(&tmprdataset);
2096 result == ISC_R_SUCCESS;
2097 result = dns_rdataset_next(&tmprdataset)) {
2098 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2100 if (count1 >= count2)
2102 dns_rdataset_current(&tmprdataset, &rdata2);
2103 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2105 dns_name_format(owner, ownerbuf,
2107 dns_rdatatype_format(rdata1.type,
2112 dns_zone_log(zone, level, "%s/%s has "
2113 "semantically identical records",
2115 if (level == ISC_LOG_ERROR)
2120 dns_rdataset_disassociate(&tmprdataset);
2127 static isc_boolean_t
2128 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2129 dns_dbiterator_t *dbiterator = NULL;
2130 dns_dbnode_t *node = NULL;
2131 dns_fixedname_t fixed;
2133 dns_rdataset_t rdataset;
2134 dns_rdatasetiter_t *rdsit = NULL;
2135 isc_boolean_t ok = ISC_TRUE;
2136 isc_result_t result;
2138 dns_fixedname_init(&fixed);
2139 name = dns_fixedname_name(&fixed);
2140 dns_rdataset_init(&rdataset);
2142 result = dns_db_createiterator(db, 0, &dbiterator);
2143 if (result != ISC_R_SUCCESS)
2146 for (result = dns_dbiterator_first(dbiterator);
2147 result == ISC_R_SUCCESS;
2148 result = dns_dbiterator_next(dbiterator)) {
2149 result = dns_dbiterator_current(dbiterator, &node, name);
2150 if (result != ISC_R_SUCCESS)
2153 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2154 if (result != ISC_R_SUCCESS)
2157 for (result = dns_rdatasetiter_first(rdsit);
2158 result == ISC_R_SUCCESS;
2159 result = dns_rdatasetiter_next(rdsit)) {
2160 dns_rdatasetiter_current(rdsit, &rdataset);
2161 if (!zone_rrset_check_dup(zone, name, &rdataset))
2163 dns_rdataset_disassociate(&rdataset);
2165 dns_rdatasetiter_destroy(&rdsit);
2166 dns_db_detachnode(db, &node);
2170 dns_db_detachnode(db, &node);
2171 dns_dbiterator_destroy(&dbiterator);
2176 static isc_boolean_t
2177 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2178 dns_dbiterator_t *dbiterator = NULL;
2179 dns_dbnode_t *node = NULL;
2180 dns_rdataset_t rdataset;
2181 dns_fixedname_t fixed;
2182 dns_fixedname_t fixedbottom;
2185 dns_rdata_in_srv_t srv;
2189 isc_result_t result;
2190 isc_boolean_t ok = ISC_TRUE;
2192 dns_fixedname_init(&fixed);
2193 name = dns_fixedname_name(&fixed);
2194 dns_fixedname_init(&fixedbottom);
2195 bottom = dns_fixedname_name(&fixedbottom);
2196 dns_rdataset_init(&rdataset);
2197 dns_rdata_init(&rdata);
2199 result = dns_db_createiterator(db, 0, &dbiterator);
2200 if (result != ISC_R_SUCCESS)
2203 result = dns_dbiterator_first(dbiterator);
2204 while (result == ISC_R_SUCCESS) {
2205 result = dns_dbiterator_current(dbiterator, &node, name);
2206 if (result != ISC_R_SUCCESS)
2210 * Is this name visible in the zone?
2212 if (!dns_name_issubdomain(name, &zone->origin) ||
2213 (dns_name_countlabels(bottom) > 0 &&
2214 dns_name_issubdomain(name, bottom)))
2218 * Don't check the NS records at the origin.
2220 if (dns_name_equal(name, &zone->origin))
2223 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2224 0, 0, &rdataset, NULL);
2225 if (result != ISC_R_SUCCESS)
2228 * Remember bottom of zone.
2230 dns_name_copy(name, bottom, NULL);
2232 result = dns_rdataset_first(&rdataset);
2233 while (result == ISC_R_SUCCESS) {
2234 dns_rdataset_current(&rdataset, &rdata);
2235 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2236 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2237 if (!zone_check_glue(zone, db, &ns.name, name))
2239 dns_rdata_reset(&rdata);
2240 result = dns_rdataset_next(&rdataset);
2242 dns_rdataset_disassociate(&rdataset);
2246 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2247 0, 0, &rdataset, NULL);
2248 if (result != ISC_R_SUCCESS)
2250 result = dns_rdataset_first(&rdataset);
2251 while (result == ISC_R_SUCCESS) {
2252 dns_rdataset_current(&rdataset, &rdata);
2253 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2254 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2255 if (!zone_check_mx(zone, db, &mx.mx, name))
2257 dns_rdata_reset(&rdata);
2258 result = dns_rdataset_next(&rdataset);
2260 dns_rdataset_disassociate(&rdataset);
2263 if (zone->rdclass != dns_rdataclass_in)
2265 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2266 0, 0, &rdataset, NULL);
2267 if (result != ISC_R_SUCCESS)
2269 result = dns_rdataset_first(&rdataset);
2270 while (result == ISC_R_SUCCESS) {
2271 dns_rdataset_current(&rdataset, &rdata);
2272 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2273 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2274 if (!zone_check_srv(zone, db, &srv.target, name))
2276 dns_rdata_reset(&rdata);
2277 result = dns_rdataset_next(&rdataset);
2279 dns_rdataset_disassociate(&rdataset);
2282 dns_db_detachnode(db, &node);
2283 result = dns_dbiterator_next(dbiterator);
2288 dns_db_detachnode(db, &node);
2289 dns_dbiterator_destroy(&dbiterator);
2295 * OpenSSL verification of RSA keys with exponent 3 is known to be
2296 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2297 * if they are in use.
2300 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2301 dns_dbnode_t *node = NULL;
2302 dns_dbversion_t *version = NULL;
2303 dns_rdata_dnskey_t dnskey;
2304 dns_rdata_t rdata = DNS_RDATA_INIT;
2305 dns_rdataset_t rdataset;
2306 isc_result_t result;
2307 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2308 const char *algorithm;
2310 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2311 if (result != ISC_R_SUCCESS)
2314 dns_db_currentversion(db, &version);
2315 dns_rdataset_init(&rdataset);
2316 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2317 dns_rdatatype_none, 0, &rdataset, NULL);
2318 if (result != ISC_R_SUCCESS)
2321 for (result = dns_rdataset_first(&rdataset);
2322 result == ISC_R_SUCCESS;
2323 result = dns_rdataset_next(&rdataset))
2325 dns_rdataset_current(&rdataset, &rdata);
2326 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2327 INSIST(result == ISC_R_SUCCESS);
2329 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2330 dnskey.algorithm == DST_ALG_RSAMD5) &&
2331 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2332 dnskey.data[1] == 3)
2334 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2336 foundrsa = ISC_TRUE;
2337 algorithm = "RSASHA1";
2340 foundmd5 = ISC_TRUE;
2341 algorithm = "RSAMD5";
2344 dns_zone_log(zone, ISC_LOG_WARNING,
2345 "weak %s (%u) key found "
2346 "(exponent=3)", algorithm,
2348 if (foundrsa && foundmd5)
2351 dns_rdata_reset(&rdata);
2353 dns_rdataset_disassociate(&rdataset);
2357 dns_db_detachnode(db, &node);
2358 if (version != NULL)
2359 dns_db_closeversion(db, &version, ISC_FALSE);
2363 resume_signingwithkey(dns_zone_t *zone) {
2364 dns_dbnode_t *node = NULL;
2365 dns_dbversion_t *version = NULL;
2366 dns_rdata_t rdata = DNS_RDATA_INIT;
2367 dns_rdataset_t rdataset;
2368 isc_result_t result;
2370 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2371 if (result != ISC_R_SUCCESS)
2374 dns_db_currentversion(zone->db, &version);
2375 dns_rdataset_init(&rdataset);
2376 result = dns_db_findrdataset(zone->db, node, version,
2378 dns_rdatatype_none, 0,
2380 if (result != ISC_R_SUCCESS) {
2381 INSIST(!dns_rdataset_isassociated(&rdataset));
2385 for (result = dns_rdataset_first(&rdataset);
2386 result == ISC_R_SUCCESS;
2387 result = dns_rdataset_next(&rdataset))
2389 dns_rdataset_current(&rdataset, &rdata);
2390 if (rdata.length != 5 ||
2391 rdata.data[0] == 0 || rdata.data[4] != 0) {
2392 dns_rdata_reset(&rdata);
2396 result = zone_signwithkey(zone, rdata.data[0],
2397 (rdata.data[1] << 8) | rdata.data[2],
2398 ISC_TF(rdata.data[3]));
2399 if (result != ISC_R_SUCCESS) {
2400 dns_zone_log(zone, ISC_LOG_ERROR,
2401 "zone_signwithkey failed: %s",
2402 dns_result_totext(result));
2404 dns_rdata_reset(&rdata);
2406 dns_rdataset_disassociate(&rdataset);
2410 dns_db_detachnode(zone->db, &node);
2411 if (version != NULL)
2412 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2416 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2417 dns_nsec3chain_t *nsec3chain, *current;
2418 isc_result_t result;
2420 unsigned int options = 0;
2421 char saltbuf[255*2+1];
2422 char flags[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")];
2425 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2426 if (nsec3chain == NULL)
2427 return (ISC_R_NOMEMORY);
2429 nsec3chain->magic = 0;
2430 nsec3chain->done = ISC_FALSE;
2431 nsec3chain->db = NULL;
2432 nsec3chain->dbiterator = NULL;
2433 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2434 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2435 nsec3chain->nsec3param.hash = nsec3param->hash;
2436 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2437 nsec3chain->nsec3param.flags = nsec3param->flags;
2438 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2439 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2440 nsec3chain->nsec3param.salt = nsec3chain->salt;
2441 nsec3chain->seen_nsec = ISC_FALSE;
2442 nsec3chain->delete_nsec = ISC_FALSE;
2443 nsec3chain->save_delete_nsec = ISC_FALSE;
2445 if (nsec3param->flags == 0)
2446 strlcpy(flags, "NONE", sizeof(flags));
2449 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
2450 strlcat(flags, "REMOVE", sizeof(flags));
2451 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
2452 if (flags[0] == '\0')
2453 strlcpy(flags, "CREATE", sizeof(flags));
2455 strlcat(flags, "|CREATE", sizeof(flags));
2457 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
2458 if (flags[0] == '\0')
2459 strlcpy(flags, "NONSEC", sizeof(flags));
2461 strlcat(flags, "|NONSEC", sizeof(flags));
2463 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
2464 if (flags[0] == '\0')
2465 strlcpy(flags, "OPTOUT", sizeof(flags));
2467 strlcat(flags, "|OPTOUT", sizeof(flags));
2470 if (nsec3param->salt_length == 0)
2471 strlcpy(saltbuf, "-", sizeof(saltbuf));
2473 for (i = 0; i < nsec3param->salt_length; i++)
2474 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
2475 dns_zone_log(zone, ISC_LOG_INFO,
2476 "zone_addnsec3chain(%u,%s,%u,%s)",
2477 nsec3param->hash, flags, nsec3param->iterations,
2479 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2481 current = ISC_LIST_NEXT(current, link)) {
2482 if (current->db == zone->db &&
2483 current->nsec3param.hash == nsec3param->hash &&
2484 current->nsec3param.iterations == nsec3param->iterations &&
2485 current->nsec3param.salt_length == nsec3param->salt_length
2486 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2487 nsec3param->salt_length))
2488 current->done = ISC_TRUE;
2491 if (zone->db != NULL) {
2492 dns_db_attach(zone->db, &nsec3chain->db);
2493 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2494 options = DNS_DB_NONSEC3;
2495 result = dns_db_createiterator(nsec3chain->db, options,
2496 &nsec3chain->dbiterator);
2497 if (result == ISC_R_SUCCESS)
2498 dns_dbiterator_first(nsec3chain->dbiterator);
2499 if (result == ISC_R_SUCCESS) {
2500 dns_dbiterator_pause(nsec3chain->dbiterator);
2501 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2504 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2506 zone->nsec3chaintime = now;
2507 if (zone->task != NULL)
2508 zone_settimer(zone, &now);
2512 result = ISC_R_NOTFOUND;
2514 if (nsec3chain != NULL) {
2515 if (nsec3chain->db != NULL)
2516 dns_db_detach(&nsec3chain->db);
2517 if (nsec3chain->dbiterator != NULL)
2518 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2519 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2525 resume_addnsec3chain(dns_zone_t *zone) {
2526 dns_dbnode_t *node = NULL;
2527 dns_dbversion_t *version = NULL;
2528 dns_rdataset_t rdataset;
2529 isc_result_t result;
2530 dns_rdata_nsec3param_t nsec3param;
2532 if (zone->privatetype == 0)
2535 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2536 if (result != ISC_R_SUCCESS)
2539 dns_db_currentversion(zone->db, &version);
2540 dns_rdataset_init(&rdataset);
2541 result = dns_db_findrdataset(zone->db, node, version,
2542 zone->privatetype, dns_rdatatype_none,
2543 0, &rdataset, NULL);
2544 if (result != ISC_R_SUCCESS) {
2545 INSIST(!dns_rdataset_isassociated(&rdataset));
2549 for (result = dns_rdataset_first(&rdataset);
2550 result == ISC_R_SUCCESS;
2551 result = dns_rdataset_next(&rdataset))
2553 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
2554 dns_rdata_t rdata = DNS_RDATA_INIT;
2555 dns_rdata_t private = DNS_RDATA_INIT;
2557 dns_rdataset_current(&rdataset, &private);
2558 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2561 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2562 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2563 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2564 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2565 result = zone_addnsec3chain(zone, &nsec3param);
2566 if (result != ISC_R_SUCCESS) {
2567 dns_zone_log(zone, ISC_LOG_ERROR,
2568 "zone_addnsec3chain failed: %s",
2569 dns_result_totext(result));
2573 dns_rdataset_disassociate(&rdataset);
2576 dns_db_detachnode(zone->db, &node);
2577 if (version != NULL)
2578 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2582 set_resigntime(dns_zone_t *zone) {
2583 dns_rdataset_t rdataset;
2584 dns_fixedname_t fixed;
2585 unsigned int resign;
2586 isc_result_t result;
2587 isc_uint32_t nanosecs;
2589 dns_rdataset_init(&rdataset);
2590 dns_fixedname_init(&fixed);
2591 result = dns_db_getsigningtime(zone->db, &rdataset,
2592 dns_fixedname_name(&fixed));
2593 if (result != ISC_R_SUCCESS) {
2594 isc_time_settoepoch(&zone->resigntime);
2597 resign = rdataset.resign;
2598 dns_rdataset_disassociate(&rdataset);
2599 isc_random_get(&nanosecs);
2600 nanosecs %= 1000000000;
2601 isc_time_set(&zone->resigntime, resign, nanosecs);
2605 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2606 dns_dbnode_t *node = NULL;
2607 dns_rdataset_t rdataset;
2608 dns_dbversion_t *version = NULL;
2609 dns_rdata_nsec3param_t nsec3param;
2610 isc_boolean_t ok = ISC_FALSE;
2611 isc_result_t result;
2612 dns_rdata_t rdata = DNS_RDATA_INIT;
2613 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2614 zone_isdynamic(zone) : ISC_FALSE;
2616 dns_rdataset_init(&rdataset);
2617 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2618 if (result != ISC_R_SUCCESS) {
2619 dns_zone_log(zone, ISC_LOG_ERROR,
2620 "nsec3param lookup failure: %s",
2621 dns_result_totext(result));
2624 dns_db_currentversion(db, &version);
2626 result = dns_db_findrdataset(db, node, version,
2627 dns_rdatatype_nsec3param,
2628 dns_rdatatype_none, 0, &rdataset, NULL);
2629 if (result == ISC_R_NOTFOUND) {
2630 INSIST(!dns_rdataset_isassociated(&rdataset));
2631 result = ISC_R_SUCCESS;
2634 if (result != ISC_R_SUCCESS) {
2635 INSIST(!dns_rdataset_isassociated(&rdataset));
2636 dns_zone_log(zone, ISC_LOG_ERROR,
2637 "nsec3param lookup failure: %s",
2638 dns_result_totext(result));
2643 * For dynamic zones we must support every algorithm so we can
2644 * regenerate all the NSEC3 chains.
2645 * For non-dynamic zones we only need to find a supported algorithm.
2647 for (result = dns_rdataset_first(&rdataset);
2648 result == ISC_R_SUCCESS;
2649 result = dns_rdataset_next(&rdataset))
2651 dns_rdataset_current(&rdataset, &rdata);
2652 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2653 dns_rdata_reset(&rdata);
2654 INSIST(result == ISC_R_SUCCESS);
2655 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2656 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2658 dns_zone_log(zone, ISC_LOG_WARNING,
2659 "nsec3 test \"unknown\" hash algorithm found: %u",
2662 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2664 dns_zone_log(zone, ISC_LOG_ERROR,
2665 "unsupported nsec3 hash algorithm"
2666 " in dynamic zone: %u",
2668 result = DNS_R_BADZONE;
2669 /* Stop second error message. */
2673 dns_zone_log(zone, ISC_LOG_WARNING,
2674 "unsupported nsec3 hash algorithm: %u",
2679 if (result == ISC_R_NOMORE)
2680 result = ISC_R_SUCCESS;
2683 result = DNS_R_BADZONE;
2684 dns_zone_log(zone, ISC_LOG_ERROR,
2685 "no supported nsec3 hash algorithm");
2689 if (dns_rdataset_isassociated(&rdataset))
2690 dns_rdataset_disassociate(&rdataset);
2691 dns_db_closeversion(db, &version, ISC_FALSE);
2692 dns_db_detachnode(db, &node);
2697 * Set the timer for refreshing the key zone to the soonest future time
2698 * of the set (current timer, keydata->refresh, keydata->addhd,
2699 * keydata->removehd).
2702 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
2705 const char me[] = "set_refreshkeytimer";
2707 isc_time_t timenow, timethen;
2711 then = key->refresh;
2712 if (key->addhd > now && key->addhd < then)
2714 if (key->removehd > now && key->removehd < then)
2715 then = key->removehd;
2719 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
2722 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
2723 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
2724 zone->refreshkeytime = timethen;
2726 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
2727 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
2728 zone_settimer(zone, &timenow);
2732 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
2733 * If the key zone is changed, set '*changed' to ISC_TRUE.
2736 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
2737 dns_diff_t *diff, dns_keytable_t *keytable,
2738 dns_keynode_t **keynodep, isc_boolean_t *changed)
2740 const char me[] = "create_keydata";
2741 isc_result_t result = ISC_R_SUCCESS;
2742 isc_buffer_t keyb, dstb;
2743 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
2744 dns_rdata_keydata_t keydata;
2745 dns_rdata_dnskey_t dnskey;
2746 dns_rdata_t rdata = DNS_RDATA_INIT;
2747 dns_keynode_t *keynode;
2752 REQUIRE(keynodep != NULL);
2753 keynode = *keynodep;
2756 isc_stdtime_get(&now);
2758 /* Loop in case there's more than one key. */
2759 while (result == ISC_R_SUCCESS) {
2760 dns_keynode_t *nextnode = NULL;
2762 key = dns_keynode_key(keynode);
2766 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
2767 CHECK(dst_key_todns(key, &dstb));
2769 /* Convert DST key to DNSKEY. */
2770 dns_rdata_reset(&rdata);
2771 isc_buffer_usedregion(&dstb, &r);
2772 dns_rdata_fromregion(&rdata, dst_key_class(key),
2773 dns_rdatatype_dnskey, &r);
2775 /* DSTKEY to KEYDATA. */
2776 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
2777 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
2780 /* KEYDATA to rdata. */
2781 dns_rdata_reset(&rdata);
2782 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
2783 CHECK(dns_rdata_fromstruct(&rdata,
2784 zone->rdclass, dns_rdatatype_keydata,
2787 /* Add rdata to zone. */
2788 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
2789 dst_key_name(key), 0, &rdata));
2790 *changed = ISC_TRUE;
2793 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
2794 if (result != ISC_R_NOTFOUND) {
2795 dns_keytable_detachkeynode(keytable, &keynode);
2800 /* Refresh new keys from the zone apex as soon as possible. */
2802 set_refreshkeytimer(zone, &keydata, now);
2804 if (keynode != NULL)
2805 dns_keytable_detachkeynode(keytable, &keynode);
2808 return (ISC_R_SUCCESS);
2815 * Remove from the key zone all the KEYDATA records found in rdataset.
2818 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
2819 dns_name_t *name, dns_rdataset_t *rdataset)
2821 dns_rdata_t rdata = DNS_RDATA_INIT;
2822 isc_result_t result, uresult;
2824 for (result = dns_rdataset_first(rdataset);
2825 result == ISC_R_SUCCESS;
2826 result = dns_rdataset_next(rdataset)) {
2827 dns_rdata_reset(&rdata);
2828 dns_rdataset_current(rdataset, &rdata);
2829 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
2831 if (uresult != ISC_R_SUCCESS)
2834 if (result == ISC_R_NOMORE)
2835 result = ISC_R_SUCCESS;
2840 * Compute the DNSSEC key ID for a DNSKEY record.
2843 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
2846 isc_result_t result;
2847 dns_rdata_t rdata = DNS_RDATA_INIT;
2848 unsigned char data[4096];
2849 isc_buffer_t buffer;
2850 dst_key_t *dstkey = NULL;
2852 isc_buffer_init(&buffer, data, sizeof(data));
2853 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
2854 dns_rdatatype_dnskey, dnskey, &buffer);
2856 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
2857 if (result == ISC_R_SUCCESS)
2858 *tag = dst_key_id(dstkey);
2859 dst_key_free(&dstkey);
2865 * Add key to the security roots.
2868 trust_key(dns_zone_t *zone, dns_name_t *keyname,
2869 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
2870 isc_result_t result;
2871 dns_rdata_t rdata = DNS_RDATA_INIT;
2872 unsigned char data[4096];
2873 isc_buffer_t buffer;
2874 dns_keytable_t *sr = NULL;
2875 dst_key_t *dstkey = NULL;
2877 /* Convert dnskey to DST key. */
2878 isc_buffer_init(&buffer, data, sizeof(data));
2879 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
2880 dns_rdatatype_dnskey, dnskey, &buffer);
2882 result = dns_view_getsecroots(zone->view, &sr);
2883 if (result != ISC_R_SUCCESS)
2886 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
2887 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
2888 dns_keytable_detach(&sr);
2892 dst_key_free(&dstkey);
2894 dns_keytable_detach(&sr);
2899 * Add a null key to the security roots for so that all queries
2900 * to the zone will fail.
2903 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
2904 isc_result_t result;
2905 dns_keytable_t *sr = NULL;
2907 result = dns_view_getsecroots(zone->view, &sr);
2908 if (result == ISC_R_SUCCESS) {
2909 dns_keytable_marksecure(sr, keyname);
2910 dns_keytable_detach(&sr);
2915 * Scan a set of KEYDATA records from the key zone. The ones that are
2916 * valid (i.e., the add holddown timer has expired) become trusted keys.
2919 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
2920 isc_result_t result;
2921 dns_rdata_t rdata = DNS_RDATA_INIT;
2922 dns_rdata_keydata_t keydata;
2923 dns_rdata_dnskey_t dnskey;
2924 isc_mem_t *mctx = zone->mctx;
2925 int trusted = 0, revoked = 0, pending = 0;
2927 dns_keytable_t *sr = NULL;
2929 isc_stdtime_get(&now);
2931 result = dns_view_getsecroots(zone->view, &sr);
2932 if (result == ISC_R_SUCCESS) {
2933 dns_keytable_delete(sr, name);
2934 dns_keytable_detach(&sr);
2937 /* Now insert all the accepted trust anchors from this keydata set. */
2938 for (result = dns_rdataset_first(rdataset);
2939 result == ISC_R_SUCCESS;
2940 result = dns_rdataset_next(rdataset)) {
2941 dns_rdata_reset(&rdata);
2942 dns_rdataset_current(rdataset, &rdata);
2944 /* Convert rdata to keydata. */
2945 dns_rdata_tostruct(&rdata, &keydata, NULL);
2947 /* Set the key refresh timer. */
2948 set_refreshkeytimer(zone, &keydata, now);
2950 /* If the removal timer is nonzero, this key was revoked. */
2951 if (keydata.removehd != 0) {
2957 * If the add timer is still pending, this key is not
2960 if (now < keydata.addhd) {
2965 /* Convert keydata to dnskey. */
2966 dns_keydata_todnskey(&keydata, &dnskey, NULL);
2968 /* Add to keytables. */
2970 trust_key(zone, name, &dnskey, mctx);
2973 if (trusted == 0 && pending != 0) {
2974 char namebuf[DNS_NAME_FORMATSIZE];
2975 dns_name_format(name, namebuf, sizeof namebuf);
2976 dns_zone_log(zone, ISC_LOG_ERROR,
2977 "No valid trust anchors for '%s'!", namebuf);
2978 dns_zone_log(zone, ISC_LOG_ERROR,
2979 "%d key(s) revoked, %d still pending",
2981 dns_zone_log(zone, ISC_LOG_ERROR,
2982 "All queries to '%s' will fail", namebuf);
2983 fail_secure(zone, name);
2988 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
2991 dns_diff_t temp_diff;
2992 isc_result_t result;
2995 * Create a singleton diff.
2997 dns_diff_init(diff->mctx, &temp_diff);
2998 temp_diff.resign = diff->resign;
2999 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3002 * Apply it to the database.
3004 result = dns_diff_apply(&temp_diff, db, ver);
3005 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3006 if (result != ISC_R_SUCCESS) {
3007 dns_difftuple_free(tuple);
3012 * Merge it into the current pending journal entry.
3014 dns_diff_appendminimal(diff, tuple);
3017 * Do not clear temp_diff.
3019 return (ISC_R_SUCCESS);
3023 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3024 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3027 dns_difftuple_t *tuple = NULL;
3028 isc_result_t result;
3029 result = dns_difftuple_create(diff->mctx, op,
3030 name, ttl, rdata, &tuple);
3031 if (result != ISC_R_SUCCESS)
3033 return (do_one_tuple(&tuple, db, ver, diff));
3037 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3038 dns_diff_t *diff, isc_mem_t *mctx) {
3039 dns_difftuple_t *deltuple = NULL;
3040 dns_difftuple_t *addtuple = NULL;
3041 isc_uint32_t serial;
3042 isc_result_t result;
3044 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3045 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3046 addtuple->op = DNS_DIFFOP_ADD;
3048 serial = dns_soa_getserial(&addtuple->rdata);
3051 serial = (serial + 1) & 0xFFFFFFFF;
3055 dns_soa_setserial(serial, &addtuple->rdata);
3056 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3057 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3058 result = ISC_R_SUCCESS;
3061 if (addtuple != NULL)
3062 dns_difftuple_free(&addtuple);
3063 if (deltuple != NULL)
3064 dns_difftuple_free(&deltuple);
3069 * Write all transactions in 'diff' to the zone journal file.
3072 zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) {
3073 const char me[] = "zone_journal";
3074 const char *journalfile;
3075 isc_result_t result = ISC_R_SUCCESS;
3076 dns_journal_t *journal = NULL;
3079 journalfile = dns_zone_getjournal(zone);
3080 if (journalfile != NULL) {
3081 result = dns_journal_open(zone->mctx, journalfile,
3082 ISC_TRUE, &journal);
3083 if (result != ISC_R_SUCCESS) {
3084 dns_zone_log(zone, ISC_LOG_ERROR,
3085 "%s:dns_journal_open -> %s\n",
3086 caller, dns_result_totext(result));
3090 result = dns_journal_write_transaction(journal, diff);
3091 dns_journal_destroy(&journal);
3092 if (result != ISC_R_SUCCESS) {
3093 dns_zone_log(zone, ISC_LOG_ERROR,
3094 "%s:dns_journal_write_transaction -> %s\n",
3095 caller, dns_result_totext(result));
3103 * Create an SOA record for a newly-created zone
3106 add_soa(dns_zone_t *zone, dns_db_t *db) {
3107 isc_result_t result;
3108 dns_rdata_t rdata = DNS_RDATA_INIT;
3109 unsigned char buf[DNS_SOA_BUFFERSIZE];
3110 dns_dbversion_t *ver = NULL;
3113 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3115 dns_diff_init(zone->mctx, &diff);
3116 result = dns_db_newversion(db, &ver);
3117 if (result != ISC_R_SUCCESS) {
3118 dns_zone_log(zone, ISC_LOG_ERROR,
3119 "add_soa:dns_db_newversion -> %s\n",
3120 dns_result_totext(result));
3124 /* Build SOA record */
3125 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3126 0, 0, 0, 0, 0, buf, &rdata);
3127 if (result != ISC_R_SUCCESS) {
3128 dns_zone_log(zone, ISC_LOG_ERROR,
3129 "add_soa:dns_soa_buildrdata -> %s\n",
3130 dns_result_totext(result));
3134 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3135 &zone->origin, 0, &rdata);
3138 dns_diff_clear(&diff);
3140 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3146 * Synchronize the set of initializing keys found in managed-keys {}
3147 * statements with the set of trust anchors found in the managed-keys.bind
3148 * zone. If a domain is no longer named in managed-keys, delete all keys
3149 * from that domain from the key zone. If a domain is mentioned in in
3150 * managed-keys but there are no references to it in the key zone, load
3151 * the key zone with the initializing key(s) for that domain.
3154 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3155 isc_result_t result = ISC_R_SUCCESS;
3156 isc_boolean_t changed = ISC_FALSE;
3157 isc_boolean_t commit = ISC_FALSE;
3158 dns_rbtnodechain_t chain;
3160 dns_name_t foundname, *origin;
3161 dns_keynode_t *keynode = NULL;
3162 dns_view_t *view = zone->view;
3163 dns_keytable_t *sr = NULL;
3164 dns_dbversion_t *ver = NULL;
3166 dns_rriterator_t rrit;
3168 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3170 dns_name_init(&foundname, NULL);
3171 dns_fixedname_init(&fn);
3172 origin = dns_fixedname_name(&fn);
3174 dns_diff_init(zone->mctx, &diff);
3176 CHECK(dns_view_getsecroots(view, &sr));
3178 result = dns_db_newversion(db, &ver);
3179 if (result != ISC_R_SUCCESS) {
3180 dns_zone_log(zone, ISC_LOG_ERROR,
3181 "sync_keyzone:dns_db_newversion -> %s\n",
3182 dns_result_totext(result));
3187 * Walk the zone DB. If we find any keys whose names are no longer
3188 * in managed-keys (or *are* in trusted-keys, meaning they are
3189 * permanent and not RFC5011-maintained), delete them from the
3190 * zone. Otherwise call load_secroots(), which loads keys into
3191 * secroots as appropriate.
3193 dns_rriterator_init(&rrit, db, ver, 0);
3194 for (result = dns_rriterator_first(&rrit);
3195 result == ISC_R_SUCCESS;
3196 result = dns_rriterator_nextrrset(&rrit)) {
3197 dns_rdataset_t *rdataset = NULL;
3198 dns_name_t *rrname = NULL;
3201 dns_rriterator_current(&rrit, &rrname, &ttl,
3203 if (!dns_rdataset_isassociated(rdataset)) {
3204 dns_rriterator_destroy(&rrit);
3208 if (rdataset->type != dns_rdatatype_keydata)
3211 result = dns_keytable_find(sr, rrname, &keynode);
3212 if ((result != ISC_R_SUCCESS &&
3213 result != DNS_R_PARTIALMATCH) ||
3214 dns_keynode_managed(keynode) == ISC_FALSE) {
3215 CHECK(delete_keydata(db, ver, &diff,
3219 load_secroots(zone, rrname, rdataset);
3222 if (keynode != NULL)
3223 dns_keytable_detachkeynode(sr, &keynode);
3225 dns_rriterator_destroy(&rrit);
3228 * Now walk secroots to find any managed keys that aren't
3229 * in the zone. If we find any, we add them to the zone.
3231 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3232 dns_rbtnodechain_init(&chain, zone->mctx);
3233 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3234 if (result == ISC_R_NOTFOUND)
3235 result = ISC_R_NOMORE;
3236 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3237 dns_rbtnode_t *rbtnode = NULL;
3239 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3240 if (rbtnode->data == NULL)
3243 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
3244 if (dns_keynode_managed(keynode)) {
3245 dns_fixedname_t fname;
3246 dns_name_t *keyname;
3249 key = dns_keynode_key(keynode);
3250 dns_fixedname_init(&fname);
3252 if (key == NULL) /* fail_secure() was called. */
3255 keyname = dst_key_name(key);
3256 result = dns_db_find(db, keyname, ver,
3257 dns_rdatatype_keydata,
3258 DNS_DBFIND_NOWILD, 0, NULL,
3259 dns_fixedname_name(&fname),
3261 if (result != ISC_R_SUCCESS)
3262 result = create_keydata(zone, db, ver, &diff,
3263 sr, &keynode, &changed);
3264 if (result != ISC_R_SUCCESS)
3268 result = dns_rbtnodechain_next(&chain, &foundname, origin);
3269 if (keynode != NULL)
3270 dns_keytable_detachkeynode(sr, &keynode);
3272 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
3274 if (result == ISC_R_NOMORE)
3275 result = ISC_R_SUCCESS;
3278 /* Write changes to journal file. */
3279 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
3280 CHECK(zone_journal(zone, &diff, "sync_keyzone"));
3282 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
3283 zone_needdump(zone, 30);
3288 if (keynode != NULL)
3289 dns_keytable_detachkeynode(sr, &keynode);
3291 dns_keytable_detach(&sr);
3293 dns_db_closeversion(db, &ver, commit);
3294 dns_diff_clear(&diff);
3300 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
3301 isc_result_t result)
3303 unsigned int soacount = 0;
3304 unsigned int nscount = 0;
3305 unsigned int errors = 0;
3306 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
3308 isc_boolean_t needdump = ISC_FALSE;
3309 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3310 isc_boolean_t nomaster = ISC_FALSE;
3311 unsigned int options;
3316 * Initiate zone transfer? We may need a error code that
3317 * indicates that the "permanent" form does not exist.
3318 * XXX better error feedback to log.
3320 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
3321 if (zone->type == dns_zone_slave ||
3322 zone->type == dns_zone_stub) {
3323 if (result == ISC_R_FILENOTFOUND)
3324 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3326 else if (result != DNS_R_NOMASTERFILE)
3327 dns_zone_log(zone, ISC_LOG_ERROR,
3328 "loading from master file %s "
3331 dns_result_totext(result));
3333 int level = ISC_LOG_ERROR;
3334 if (zone->type == dns_zone_key &&
3335 result == ISC_R_FILENOTFOUND)
3336 level = ISC_LOG_DEBUG(1);
3337 dns_zone_log(zone, level,
3338 "loading from master file %s failed: %s",
3340 dns_result_totext(result));
3341 nomaster = ISC_TRUE;
3344 if (zone->type != dns_zone_key)
3348 dns_zone_log(zone, ISC_LOG_DEBUG(2),
3349 "number of nodes in database: %u",
3350 dns_db_nodecount(db));
3352 if (result == DNS_R_SEENINCLUDE)
3353 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3355 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3358 * If there's no master file for a key zone, then the zone is new:
3359 * create an SOA record. (We do this now, instead of later, so that
3360 * if there happens to be a journal file, we can roll forward from
3361 * a sane starting point.)
3363 if (nomaster && zone->type == dns_zone_key) {
3364 result = add_soa(zone, db);
3365 if (result != ISC_R_SUCCESS)
3370 * Apply update log, if any, on initial load.
3372 if (zone->journal != NULL &&
3373 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
3374 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3376 if (zone->type == dns_zone_master &&
3377 (zone->update_acl != NULL || zone->ssutable != NULL))
3378 options = DNS_JOURNALOPT_RESIGN;
3381 result = dns_journal_rollforward2(zone->mctx, db, options,
3382 zone->sigresigninginterval,
3384 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
3385 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
3386 result != ISC_R_RANGE) {
3387 dns_zone_log(zone, ISC_LOG_ERROR,
3388 "journal rollforward failed: %s",
3389 dns_result_totext(result));
3392 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
3393 dns_zone_log(zone, ISC_LOG_ERROR,
3394 "journal rollforward failed: "
3395 "journal out of sync with zone");
3398 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3399 "journal rollforward completed "
3401 dns_result_totext(result));
3402 if (result == ISC_R_SUCCESS)
3403 needdump = ISC_TRUE;
3406 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
3408 * Obtain ns, soa and cname counts for top of zone.
3411 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
3412 &refresh, &retry, &expire, &minimum,
3414 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
3415 dns_zone_log(zone, ISC_LOG_ERROR,
3416 "could not find NS and/or SOA records");
3420 * Master / Slave / Stub zones require both NS and SOA records at
3421 * the top of the zone.
3424 switch (zone->type) {
3426 case dns_zone_master:
3427 case dns_zone_slave:
3429 if (soacount != 1) {
3430 dns_zone_log(zone, ISC_LOG_ERROR,
3431 "has %d SOA records", soacount);
3432 result = DNS_R_BADZONE;
3435 dns_zone_log(zone, ISC_LOG_ERROR,
3436 "has no NS records");
3437 result = DNS_R_BADZONE;
3439 if (result != ISC_R_SUCCESS)
3441 if (zone->type == dns_zone_master && errors != 0) {
3442 result = DNS_R_BADZONE;
3445 if (zone->type != dns_zone_stub) {
3446 result = check_nsec3param(zone, db);
3447 if (result != ISC_R_SUCCESS)
3450 if (zone->type == dns_zone_master &&
3451 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
3452 !integrity_checks(zone, db)) {
3453 result = DNS_R_BADZONE;
3457 if (zone->type == dns_zone_master &&
3458 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
3459 !zone_check_dup(zone, db)) {
3460 result = DNS_R_BADZONE;
3464 if (zone->db != NULL) {
3466 * This is checked in zone_replacedb() for slave zones
3467 * as they don't reload from disk.
3469 result = zone_get_from_db(zone, zone->db, NULL, NULL,
3470 &oldserial, NULL, NULL, NULL,
3472 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3473 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
3474 !isc_serial_gt(serial, oldserial)) {
3475 isc_uint32_t serialmin, serialmax;
3477 INSIST(zone->type == dns_zone_master);
3479 serialmin = (oldserial + 1) & 0xffffffffU;
3480 serialmax = (oldserial + 0x7fffffffU) &
3482 dns_zone_log(zone, ISC_LOG_ERROR,
3483 "ixfr-from-differences: "
3484 "new serial (%u) out of range "
3485 "[%u - %u]", serial, serialmin,
3487 result = DNS_R_BADZONE;
3489 } else if (!isc_serial_ge(serial, oldserial))
3490 dns_zone_log(zone, ISC_LOG_ERROR,
3491 "zone serial (%u/%u) has gone "
3492 "backwards", serial, oldserial);
3493 else if (serial == oldserial && !hasinclude &&
3494 strcmp(zone->db_argv[0], "_builtin") != 0)
3495 dns_zone_log(zone, ISC_LOG_ERROR,
3496 "zone serial (%u) unchanged. "
3497 "zone may fail to transfer "
3498 "to slaves.", serial);
3501 if (zone->type == dns_zone_master &&
3502 (zone->update_acl != NULL || zone->ssutable != NULL) &&
3503 zone->sigresigninginterval < (3 * refresh) &&
3504 dns_db_issecure(db))
3506 dns_zone_log(zone, ISC_LOG_WARNING,
3507 "sig-re-signing-interval less than "
3511 zone->refresh = RANGE(refresh,
3512 zone->minrefresh, zone->maxrefresh);
3513 zone->retry = RANGE(retry,
3514 zone->minretry, zone->maxretry);
3515 zone->expire = RANGE(expire, zone->refresh + zone->retry,
3517 zone->minimum = minimum;
3518 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
3520 if (zone->type == dns_zone_slave ||
3521 zone->type == dns_zone_stub) {
3525 result = isc_file_getmodtime(zone->journal, &t);
3526 if (result != ISC_R_SUCCESS)
3527 result = isc_file_getmodtime(zone->masterfile,
3529 if (result == ISC_R_SUCCESS)
3530 DNS_ZONE_TIME_ADD(&t, zone->expire,
3533 DNS_ZONE_TIME_ADD(&now, zone->retry,
3536 delay = isc_random_jitter(zone->retry,
3537 (zone->retry * 3) / 4);
3538 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
3539 if (isc_time_compare(&zone->refreshtime,
3540 &zone->expiretime) >= 0)
3541 zone->refreshtime = now;
3546 result = sync_keyzone(zone, db);
3547 if (result != ISC_R_SUCCESS)
3552 UNEXPECTED_ERROR(__FILE__, __LINE__,
3553 "unexpected zone type %d", zone->type);
3554 result = ISC_R_UNEXPECTED;
3559 * Check for weak DNSKEY's.
3561 if (zone->type == dns_zone_master)
3562 zone_check_dnskeys(zone, db);
3565 * Schedule DNSSEC key refresh.
3567 if (zone->type == dns_zone_master &&
3568 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
3569 zone->refreshkeytime = now;
3572 /* destroy notification example. */
3574 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
3575 DNS_EVENT_DBDESTROYED,
3576 dns_zonemgr_dbdestroyed,
3578 sizeof(isc_event_t));
3579 dns_db_ondestroy(db, zone->task, &e);
3583 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
3584 if (zone->db != NULL) {
3585 result = zone_replacedb(zone, db, ISC_FALSE);
3586 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3587 if (result != ISC_R_SUCCESS)
3590 zone_attachdb(zone, db);
3591 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3592 DNS_ZONE_SETFLAG(zone,
3593 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
3596 result = ISC_R_SUCCESS;
3599 if (zone->type == dns_zone_key)
3600 zone_needdump(zone, 30);
3602 zone_needdump(zone, DNS_DUMP_DELAY);
3605 if (zone->task != NULL) {
3606 if (zone->type == dns_zone_master) {
3607 set_resigntime(zone);
3608 resume_signingwithkey(zone);
3609 resume_addnsec3chain(zone);
3612 if (zone->type == dns_zone_master &&
3613 zone_isdynamic(zone) &&
3614 dns_db_issecure(db)) {
3616 dns_fixedname_t fixed;
3617 dns_rdataset_t next;
3619 dns_rdataset_init(&next);
3620 dns_fixedname_init(&fixed);
3621 name = dns_fixedname_name(&fixed);
3623 result = dns_db_getsigningtime(db, &next, name);
3624 if (result == ISC_R_SUCCESS) {
3625 isc_stdtime_t timenow;
3626 char namebuf[DNS_NAME_FORMATSIZE];
3627 char typebuf[DNS_RDATATYPE_FORMATSIZE];
3629 isc_stdtime_get(&timenow);
3630 dns_name_format(name, namebuf, sizeof(namebuf));
3631 dns_rdatatype_format(next.covers,
3632 typebuf, sizeof(typebuf));
3633 dns_zone_log(zone, ISC_LOG_DEBUG(3),
3634 "next resign: %s/%s in %d seconds",
3636 next.resign - timenow);
3637 dns_rdataset_disassociate(&next);
3639 dns_zone_log(zone, ISC_LOG_WARNING,
3640 "signed dynamic zone has no "
3641 "resign event scheduled");
3644 zone_settimer(zone, &now);
3647 if (! dns_db_ispersistent(db))
3648 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
3649 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
3651 zone->loadtime = loadtime;
3655 if (zone->type == dns_zone_slave ||
3656 zone->type == dns_zone_stub ||
3657 zone->type == dns_zone_key) {
3658 if (zone->journal != NULL)
3659 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
3660 if (zone->masterfile != NULL)
3661 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
3663 /* Mark the zone for immediate refresh. */
3664 zone->refreshtime = now;
3665 if (zone->task != NULL)
3666 zone_settimer(zone, &now);
3667 result = ISC_R_SUCCESS;
3668 } else if (zone->type == dns_zone_master)
3669 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
3673 static isc_boolean_t
3674 exit_check(dns_zone_t *zone) {
3676 REQUIRE(LOCKED_ZONE(zone));
3678 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
3682 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
3684 INSIST(isc_refcount_current(&zone->erefs) == 0);
3690 static isc_boolean_t
3691 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
3692 dns_name_t *name, isc_boolean_t logit)
3694 isc_result_t result;
3695 char namebuf[DNS_NAME_FORMATSIZE];
3696 char altbuf[DNS_NAME_FORMATSIZE];
3697 dns_fixedname_t fixed;
3698 dns_name_t *foundname;
3701 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
3704 if (zone->type == dns_zone_master)
3705 level = ISC_LOG_ERROR;
3707 level = ISC_LOG_WARNING;
3709 dns_fixedname_init(&fixed);
3710 foundname = dns_fixedname_name(&fixed);
3712 result = dns_db_find(db, name, version, dns_rdatatype_a,
3713 0, 0, NULL, foundname, NULL, NULL);
3714 if (result == ISC_R_SUCCESS)
3717 if (result == DNS_R_NXRRSET) {
3718 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
3719 0, 0, NULL, foundname, NULL, NULL);
3720 if (result == ISC_R_SUCCESS)
3724 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
3725 result == DNS_R_EMPTYNAME) {
3727 dns_name_format(name, namebuf, sizeof namebuf);
3728 dns_zone_log(zone, level, "NS '%s' has no address "
3729 "records (A or AAAA)", namebuf);
3734 if (result == DNS_R_CNAME) {
3736 dns_name_format(name, namebuf, sizeof namebuf);
3737 dns_zone_log(zone, level, "NS '%s' is a CNAME "
3738 "(illegal)", namebuf);
3743 if (result == DNS_R_DNAME) {
3745 dns_name_format(name, namebuf, sizeof namebuf);
3746 dns_name_format(foundname, altbuf, sizeof altbuf);
3747 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
3748 "'%s' (illegal)", namebuf, altbuf);
3757 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
3758 dns_dbversion_t *version, unsigned int *nscount,
3759 unsigned int *errors, isc_boolean_t logit)
3761 isc_result_t result;
3762 unsigned int count = 0;
3763 unsigned int ecount = 0;
3764 dns_rdataset_t rdataset;
3768 dns_rdataset_init(&rdataset);
3769 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
3770 dns_rdatatype_none, 0, &rdataset, NULL);
3771 if (result == ISC_R_NOTFOUND) {
3772 INSIST(!dns_rdataset_isassociated(&rdataset));
3775 if (result != ISC_R_SUCCESS) {
3776 INSIST(!dns_rdataset_isassociated(&rdataset));
3777 goto invalidate_rdataset;
3780 result = dns_rdataset_first(&rdataset);
3781 while (result == ISC_R_SUCCESS) {
3782 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
3783 (zone->type == dns_zone_master ||
3784 zone->type == dns_zone_slave)) {
3785 dns_rdata_init(&rdata);
3786 dns_rdataset_current(&rdataset, &rdata);
3787 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3788 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3789 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
3790 !zone_check_ns(zone, db, version, &ns.name, logit))
3794 result = dns_rdataset_next(&rdataset);
3796 dns_rdataset_disassociate(&rdataset);
3799 if (nscount != NULL)
3804 result = ISC_R_SUCCESS;
3806 invalidate_rdataset:
3807 dns_rdataset_invalidate(&rdataset);
3813 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
3814 unsigned int *soacount,
3815 isc_uint32_t *serial, isc_uint32_t *refresh,
3816 isc_uint32_t *retry, isc_uint32_t *expire,
3817 isc_uint32_t *minimum)
3819 isc_result_t result;
3821 dns_rdataset_t rdataset;
3822 dns_rdata_t rdata = DNS_RDATA_INIT;
3823 dns_rdata_soa_t soa;
3825 dns_rdataset_init(&rdataset);
3826 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
3827 dns_rdatatype_none, 0, &rdataset, NULL);
3828 if (result == ISC_R_NOTFOUND) {
3829 INSIST(!dns_rdataset_isassociated(&rdataset));
3830 if (soacount != NULL)
3834 if (refresh != NULL)
3840 if (minimum != NULL)
3842 result = ISC_R_SUCCESS;
3843 goto invalidate_rdataset;
3845 if (result != ISC_R_SUCCESS) {
3846 INSIST(!dns_rdataset_isassociated(&rdataset));
3847 goto invalidate_rdataset;
3851 result = dns_rdataset_first(&rdataset);
3852 while (result == ISC_R_SUCCESS) {
3853 dns_rdata_init(&rdata);
3854 dns_rdataset_current(&rdataset, &rdata);
3857 result = dns_rdata_tostruct(&rdata, &soa, NULL);
3858 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3861 result = dns_rdataset_next(&rdataset);
3862 dns_rdata_reset(&rdata);
3864 dns_rdataset_disassociate(&rdataset);
3866 if (soacount != NULL)
3871 *serial = soa.serial;
3872 if (refresh != NULL)
3873 *refresh = soa.refresh;
3877 *expire = soa.expire;
3878 if (minimum != NULL)
3879 *minimum = soa.minimum;
3882 result = ISC_R_SUCCESS;
3884 invalidate_rdataset:
3885 dns_rdataset_invalidate(&rdataset);
3891 * zone must be locked.
3894 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
3895 unsigned int *soacount, isc_uint32_t *serial,
3896 isc_uint32_t *refresh, isc_uint32_t *retry,
3897 isc_uint32_t *expire, isc_uint32_t *minimum,
3898 unsigned int *errors)
3900 isc_result_t result;
3901 isc_result_t answer = ISC_R_SUCCESS;
3902 dns_dbversion_t *version = NULL;
3905 REQUIRE(db != NULL);
3906 REQUIRE(zone != NULL);
3908 dns_db_currentversion(db, &version);
3911 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3912 if (result != ISC_R_SUCCESS) {
3917 if (nscount != NULL || errors != NULL) {
3918 result = zone_count_ns_rr(zone, db, node, version,
3919 nscount, errors, ISC_TRUE);
3920 if (result != ISC_R_SUCCESS)
3924 if (soacount != NULL || serial != NULL || refresh != NULL
3925 || retry != NULL || expire != NULL || minimum != NULL) {
3926 result = zone_load_soa_rr(db, node, version, soacount,
3927 serial, refresh, retry, expire,
3929 if (result != ISC_R_SUCCESS)
3933 dns_db_detachnode(db, &node);
3935 dns_db_closeversion(db, &version, ISC_FALSE);
3941 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
3942 REQUIRE(DNS_ZONE_VALID(source));
3943 REQUIRE(target != NULL && *target == NULL);
3944 isc_refcount_increment(&source->erefs, NULL);
3949 dns_zone_detach(dns_zone_t **zonep) {
3952 isc_boolean_t free_now = ISC_FALSE;
3954 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3958 isc_refcount_decrement(&zone->erefs, &refs);
3963 * We just detached the last external reference.
3965 if (zone->task != NULL) {
3967 * This zone is being managed. Post
3968 * its control event and let it clean
3969 * up synchronously in the context of
3972 isc_event_t *ev = &zone->ctlevent;
3973 isc_task_send(zone->task, &ev);
3976 * This zone is not being managed; it has
3977 * no task and can have no outstanding
3978 * events. Free it immediately.
3981 * Unmanaged zones should not have non-null views;
3982 * we have no way of detaching from the view here
3983 * without causing deadlock because this code is called
3984 * with the view already locked.
3986 INSIST(zone->view == NULL);
3987 free_now = ISC_TRUE;
3997 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3998 REQUIRE(DNS_ZONE_VALID(source));
3999 REQUIRE(target != NULL && *target == NULL);
4001 zone_iattach(source, target);
4002 UNLOCK_ZONE(source);
4006 dns_zone_synckeyzone(dns_zone_t *zone) {
4007 isc_result_t result;
4008 dns_db_t *db = NULL;
4010 if (zone->type != dns_zone_key)
4011 return (DNS_R_BADZONE);
4013 CHECK(dns_zone_getdb(zone, &db));
4016 result = sync_keyzone(zone, db);
4026 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4029 * 'source' locked by caller.
4031 REQUIRE(LOCKED_ZONE(source));
4032 REQUIRE(DNS_ZONE_VALID(source));
4033 REQUIRE(target != NULL && *target == NULL);
4034 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
4036 INSIST(source->irefs != 0);
4041 zone_idetach(dns_zone_t **zonep) {
4045 * 'zone' locked by caller.
4047 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4049 REQUIRE(LOCKED_ZONE(*zonep));
4052 INSIST(zone->irefs > 0);
4054 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
4058 dns_zone_idetach(dns_zone_t **zonep) {
4060 isc_boolean_t free_needed;
4062 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4067 INSIST(zone->irefs > 0);
4069 free_needed = exit_check(zone);
4076 dns_zone_getmctx(dns_zone_t *zone) {
4077 REQUIRE(DNS_ZONE_VALID(zone));
4079 return (zone->mctx);
4083 dns_zone_getmgr(dns_zone_t *zone) {
4084 REQUIRE(DNS_ZONE_VALID(zone));
4086 return (zone->zmgr);
4090 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
4091 REQUIRE(DNS_ZONE_VALID(zone));
4095 DNS_ZONE_SETFLAG(zone, flags);
4097 DNS_ZONE_CLRFLAG(zone, flags);
4102 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
4104 REQUIRE(DNS_ZONE_VALID(zone));
4108 zone->options |= option;
4110 zone->options &= ~option;
4115 dns_zone_getoptions(dns_zone_t *zone) {
4117 REQUIRE(DNS_ZONE_VALID(zone));
4119 return (zone->options);
4123 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
4125 REQUIRE(DNS_ZONE_VALID(zone));
4129 zone->keyopts |= keyopt;
4131 zone->keyopts &= ~keyopt;
4136 dns_zone_getkeyopts(dns_zone_t *zone) {
4138 REQUIRE(DNS_ZONE_VALID(zone));
4140 return (zone->keyopts);
4144 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4145 REQUIRE(DNS_ZONE_VALID(zone));
4148 zone->xfrsource4 = *xfrsource;
4151 return (ISC_R_SUCCESS);
4155 dns_zone_getxfrsource4(dns_zone_t *zone) {
4156 REQUIRE(DNS_ZONE_VALID(zone));
4157 return (&zone->xfrsource4);
4161 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4162 REQUIRE(DNS_ZONE_VALID(zone));
4165 zone->xfrsource6 = *xfrsource;
4168 return (ISC_R_SUCCESS);
4172 dns_zone_getxfrsource6(dns_zone_t *zone) {
4173 REQUIRE(DNS_ZONE_VALID(zone));
4174 return (&zone->xfrsource6);
4178 dns_zone_setaltxfrsource4(dns_zone_t *zone,
4179 const isc_sockaddr_t *altxfrsource)
4181 REQUIRE(DNS_ZONE_VALID(zone));
4184 zone->altxfrsource4 = *altxfrsource;
4187 return (ISC_R_SUCCESS);
4191 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
4192 REQUIRE(DNS_ZONE_VALID(zone));
4193 return (&zone->altxfrsource4);
4197 dns_zone_setaltxfrsource6(dns_zone_t *zone,
4198 const isc_sockaddr_t *altxfrsource)
4200 REQUIRE(DNS_ZONE_VALID(zone));
4203 zone->altxfrsource6 = *altxfrsource;
4206 return (ISC_R_SUCCESS);
4210 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
4211 REQUIRE(DNS_ZONE_VALID(zone));
4212 return (&zone->altxfrsource6);
4216 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4217 REQUIRE(DNS_ZONE_VALID(zone));
4220 zone->notifysrc4 = *notifysrc;
4223 return (ISC_R_SUCCESS);
4227 dns_zone_getnotifysrc4(dns_zone_t *zone) {
4228 REQUIRE(DNS_ZONE_VALID(zone));
4229 return (&zone->notifysrc4);
4233 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4234 REQUIRE(DNS_ZONE_VALID(zone));
4237 zone->notifysrc6 = *notifysrc;
4240 return (ISC_R_SUCCESS);
4244 dns_zone_getnotifysrc6(dns_zone_t *zone) {
4245 REQUIRE(DNS_ZONE_VALID(zone));
4246 return (&zone->notifysrc6);
4250 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
4253 isc_sockaddr_t *new;
4255 REQUIRE(DNS_ZONE_VALID(zone));
4256 REQUIRE(count == 0 || notify != NULL);
4259 if (zone->notify != NULL) {
4260 isc_mem_put(zone->mctx, zone->notify,
4261 zone->notifycnt * sizeof(*new));
4262 zone->notify = NULL;
4263 zone->notifycnt = 0;
4266 new = isc_mem_get(zone->mctx, count * sizeof(*new));
4269 return (ISC_R_NOMEMORY);
4271 memcpy(new, notify, count * sizeof(*new));
4273 zone->notifycnt = count;
4276 return (ISC_R_SUCCESS);
4280 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
4283 isc_result_t result;
4285 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
4289 static isc_boolean_t
4290 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
4295 for (i = 0; i < count; i++)
4296 if (!isc_sockaddr_equal(&old[i], &new[i]))
4301 static isc_boolean_t
4302 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
4305 if (old == NULL && new == NULL)
4307 if (old == NULL || new == NULL)
4310 for (i = 0; i < count; i++) {
4311 if (old[i] == NULL && new[i] == NULL)
4313 if (old[i] == NULL || new[i] == NULL ||
4314 !dns_name_equal(old[i], new[i]))
4321 dns_zone_setmasterswithkeys(dns_zone_t *zone,
4322 const isc_sockaddr_t *masters,
4323 dns_name_t **keynames,
4326 isc_sockaddr_t *new;
4327 isc_result_t result = ISC_R_SUCCESS;
4328 dns_name_t **newname;
4329 isc_boolean_t *newok;
4332 REQUIRE(DNS_ZONE_VALID(zone));
4333 REQUIRE(count == 0 || masters != NULL);
4334 if (keynames != NULL) {
4335 REQUIRE(count != 0);
4340 * The refresh code assumes that 'masters' wouldn't change under it.
4341 * If it will change then kill off any current refresh in progress
4342 * and update the masters info. If it won't change then we can just
4345 if (count != zone->masterscnt ||
4346 !same_masters(zone->masters, masters, count) ||
4347 !same_keynames(zone->masterkeynames, keynames, count)) {
4348 if (zone->request != NULL)
4349 dns_request_cancel(zone->request);
4352 if (zone->masters != NULL) {
4353 isc_mem_put(zone->mctx, zone->masters,
4354 zone->masterscnt * sizeof(*new));
4355 zone->masters = NULL;
4357 if (zone->masterkeynames != NULL) {
4358 for (i = 0; i < zone->masterscnt; i++) {
4359 if (zone->masterkeynames[i] != NULL) {
4360 dns_name_free(zone->masterkeynames[i],
4362 isc_mem_put(zone->mctx,
4363 zone->masterkeynames[i],
4364 sizeof(dns_name_t));
4365 zone->masterkeynames[i] = NULL;
4368 isc_mem_put(zone->mctx, zone->masterkeynames,
4369 zone->masterscnt * sizeof(dns_name_t *));
4370 zone->masterkeynames = NULL;
4372 if (zone->mastersok != NULL) {
4373 isc_mem_put(zone->mctx, zone->mastersok,
4374 zone->masterscnt * sizeof(isc_boolean_t));
4375 zone->mastersok = NULL;
4377 zone->masterscnt = 0;
4379 * If count == 0, don't allocate any space for masters, mastersok or
4380 * keynames so internally, those pointers are NULL if count == 0
4386 * masters must contain count elements!
4388 new = isc_mem_get(zone->mctx, count * sizeof(*new));
4390 result = ISC_R_NOMEMORY;
4393 memcpy(new, masters, count * sizeof(*new));
4396 * Similarly for mastersok.
4398 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
4399 if (newok == NULL) {
4400 result = ISC_R_NOMEMORY;
4401 isc_mem_put(zone->mctx, new, count * sizeof(*new));
4404 for (i = 0; i < count; i++)
4405 newok[i] = ISC_FALSE;
4408 * if keynames is non-NULL, it must contain count elements!
4411 if (keynames != NULL) {
4412 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
4413 if (newname == NULL) {
4414 result = ISC_R_NOMEMORY;
4415 isc_mem_put(zone->mctx, new, count * sizeof(*new));
4416 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
4419 for (i = 0; i < count; i++)
4421 for (i = 0; i < count; i++) {
4422 if (keynames[i] != NULL) {
4423 newname[i] = isc_mem_get(zone->mctx,
4424 sizeof(dns_name_t));
4425 if (newname[i] == NULL)
4427 dns_name_init(newname[i], NULL);
4428 result = dns_name_dup(keynames[i], zone->mctx,
4430 if (result != ISC_R_SUCCESS) {
4432 for (i = 0; i < count; i++)
4433 if (newname[i] != NULL)
4437 isc_mem_put(zone->mctx, new,
4438 count * sizeof(*new));
4439 isc_mem_put(zone->mctx, newok,
4440 count * sizeof(*newok));
4441 isc_mem_put(zone->mctx, newname,
4442 count * sizeof(*newname));
4450 * Everything is ok so attach to the zone.
4452 zone->curmaster = 0;
4453 zone->masters = new;
4454 zone->mastersok = newok;
4455 zone->masterkeynames = newname;
4456 zone->masterscnt = count;
4457 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
4465 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
4466 isc_result_t result = ISC_R_SUCCESS;
4468 REQUIRE(DNS_ZONE_VALID(zone));
4470 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4471 if (zone->db == NULL)
4472 result = DNS_R_NOTLOADED;
4474 dns_db_attach(zone->db, dpb);
4475 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4481 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
4482 REQUIRE(DNS_ZONE_VALID(zone));
4483 REQUIRE(zone->type == dns_zone_staticstub);
4485 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4486 REQUIRE(zone->db == NULL);
4487 dns_db_attach(db, &zone->db);
4488 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4492 * Co-ordinates the starting of routine jobs.
4496 dns_zone_maintenance(dns_zone_t *zone) {
4497 const char me[] = "dns_zone_maintenance";
4500 REQUIRE(DNS_ZONE_VALID(zone));
4505 zone_settimer(zone, &now);
4509 static inline isc_boolean_t
4510 was_dumping(dns_zone_t *zone) {
4511 isc_boolean_t dumping;
4513 REQUIRE(LOCKED_ZONE(zone));
4515 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
4516 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
4518 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
4519 isc_time_settoepoch(&zone->dumptime);
4525 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
4526 isc_mem_t *mctx, unsigned int maxkeys,
4527 dst_key_t **keys, unsigned int *nkeys)
4529 isc_result_t result;
4530 dns_dbnode_t *node = NULL;
4531 const char *directory = dns_zone_getkeydirectory(zone);
4533 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
4534 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
4535 directory, mctx, maxkeys, keys,
4537 if (result == ISC_R_NOTFOUND)
4538 result = ISC_R_SUCCESS;
4541 dns_db_detachnode(db, &node);
4546 offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
4547 dns_ttl_t ttl, dns_rdata_t *rdata)
4549 isc_result_t result;
4551 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
4552 return (ISC_R_SUCCESS);
4553 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
4555 if (result != ISC_R_SUCCESS)
4557 rdata->flags |= DNS_RDATA_OFFLINE;
4558 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
4564 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
4569 zone->key_expiry = when;
4571 dns_zone_log(zone, ISC_LOG_ERROR,
4572 "DNSKEY RRSIG(s) have expired");
4573 isc_time_settoepoch(&zone->keywarntime);
4574 } else if (when < now + 7 * 24 * 3600) {
4576 isc_time_set(&t, when, 0);
4577 isc_time_formattimestamp(&t, timebuf, 80);
4578 dns_zone_log(zone, ISC_LOG_WARNING,
4579 "DNSKEY RRSIG(s) will expire within 7 days: %s",
4582 delta--; /* loop prevention */
4583 delta /= 24 * 3600; /* to whole days */
4584 delta *= 24 * 3600; /* to seconds */
4585 isc_time_set(&zone->keywarntime, when - delta, 0);
4587 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
4588 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
4589 dns_zone_log(zone, ISC_LOG_NOTICE,
4590 "setting keywarntime to %s", timebuf);
4595 * Helper function to del_sigs(). We don't want to delete RRSIGs that
4598 static isc_boolean_t
4599 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) {
4603 * It's okay to delete a signature if there is an active ZSK
4604 * with the same algorithm
4606 for (i = 0; i < nkeys; i++) {
4607 if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) &&
4608 (dst_key_isprivate(keys[i])) && !KSK(keys[i]))
4613 * Failing that, it is *not* okay to delete a signature
4614 * if the associated public key is still in the DNSKEY RRset
4616 for (i = 0; i < nkeys; i++) {
4617 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
4618 (rrsig_ptr->keyid == dst_key_id(keys[i])))
4623 * But if the key is gone, then go ahead.
4629 * Delete expired RRsigs and any RRsigs we are about to re-sign.
4630 * See also update.c:del_keysigs().
4633 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
4634 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
4635 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
4637 isc_result_t result;
4638 dns_dbnode_t *node = NULL;
4639 dns_rdataset_t rdataset;
4641 dns_rdata_rrsig_t rrsig;
4642 isc_boolean_t found, changed;
4643 isc_int64_t warn = 0, maybe = 0;
4645 dns_rdataset_init(&rdataset);
4647 if (type == dns_rdatatype_nsec3)
4648 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
4650 result = dns_db_findnode(db, name, ISC_FALSE, &node);
4651 if (result == ISC_R_NOTFOUND)
4652 return (ISC_R_SUCCESS);
4653 if (result != ISC_R_SUCCESS)
4655 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
4656 (isc_stdtime_t) 0, &rdataset, NULL);
4657 dns_db_detachnode(db, &node);
4659 if (result == ISC_R_NOTFOUND) {
4660 INSIST(!dns_rdataset_isassociated(&rdataset));
4661 return (ISC_R_SUCCESS);
4663 if (result != ISC_R_SUCCESS) {
4664 INSIST(!dns_rdataset_isassociated(&rdataset));
4668 changed = ISC_FALSE;
4669 for (result = dns_rdataset_first(&rdataset);
4670 result == ISC_R_SUCCESS;
4671 result = dns_rdataset_next(&rdataset)) {
4672 dns_rdata_t rdata = DNS_RDATA_INIT;
4674 dns_rdataset_current(&rdataset, &rdata);
4675 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4676 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4678 if (type != dns_rdatatype_dnskey) {
4679 if (delsig_ok(&rrsig, keys, nkeys)) {
4680 result = update_one_rr(db, ver, diff,
4681 DNS_DIFFOP_DELRESIGN, name,
4682 rdataset.ttl, &rdata);
4685 if (result != ISC_R_SUCCESS)
4689 * At this point, we've got an RRSIG,
4690 * which is signed by an inactive key.
4691 * An administrator needs to provide a new
4692 * key/alg, but until that time, we want to
4693 * keep the old RRSIG. Marking the key as
4694 * offline will prevent us spinning waiting
4695 * for the private part.
4698 result = offline(db, ver, diff, name,
4699 rdataset.ttl, &rdata);
4701 if (result != ISC_R_SUCCESS)
4706 * Log the key id and algorithm of
4707 * the inactive key with no replacement
4709 if (zone->log_key_expired_timer <= now) {
4710 char origin[DNS_NAME_FORMATSIZE];
4711 char algbuf[DNS_NAME_FORMATSIZE];
4712 dns_name_format(&zone->origin, origin,
4714 dns_secalg_format(rrsig.algorithm,
4717 dns_zone_log(zone, ISC_LOG_WARNING,
4719 "missing or inactive "
4720 "and has no replacement: "
4721 "retaining signatures.",
4724 zone->log_key_expired_timer = now +
4732 * RRSIG(DNSKEY) requires special processing.
4735 for (i = 0; i < nkeys; i++) {
4736 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
4737 rrsig.keyid == dst_key_id(keys[i])) {
4740 * Mark offline RRSIG(DNSKEY).
4741 * We want the earliest offline expire time
4742 * iff there is a new offline signature.
4744 if (!dst_key_isprivate(keys[i])) {
4745 isc_int64_t timeexpire =
4746 dns_time64_from32(rrsig.timeexpire);
4747 if (warn != 0 && warn > timeexpire)
4749 if (rdata.flags & DNS_RDATA_OFFLINE) {
4757 if (warn == 0 || warn > timeexpire)
4759 result = offline(db, ver, diff, name,
4760 rdataset.ttl, &rdata);
4763 result = update_one_rr(db, ver, diff,
4764 DNS_DIFFOP_DELRESIGN,
4772 * If there is not a matching DNSKEY then
4776 result = update_one_rr(db, ver, diff,
4777 DNS_DIFFOP_DELRESIGN, name,
4778 rdataset.ttl, &rdata);
4779 if (result != ISC_R_SUCCESS)
4783 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
4784 dns_db_resigned(db, &rdataset, ver);
4786 dns_rdataset_disassociate(&rdataset);
4787 if (result == ISC_R_NOMORE)
4788 result = ISC_R_SUCCESS;
4790 #if defined(STDTIME_ON_32BITS)
4791 isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
4792 if (warn == stdwarn)
4794 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
4795 #if defined(STDTIME_ON_32BITS)
4797 dns_zone_log(zone, ISC_LOG_ERROR,
4798 "key expiry warning time out of range");
4803 dns_db_detachnode(db, &node);
4808 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
4809 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
4810 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
4811 isc_stdtime_t expire, isc_boolean_t check_ksk,
4812 isc_boolean_t keyset_kskonly)
4814 isc_result_t result;
4815 dns_dbnode_t *node = NULL;
4816 dns_rdataset_t rdataset;
4817 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
4818 unsigned char data[1024]; /* XXX */
4819 isc_buffer_t buffer;
4822 dns_rdataset_init(&rdataset);
4823 isc_buffer_init(&buffer, data, sizeof(data));
4825 if (type == dns_rdatatype_nsec3)
4826 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
4828 result = dns_db_findnode(db, name, ISC_FALSE, &node);
4829 if (result == ISC_R_NOTFOUND)
4830 return (ISC_R_SUCCESS);
4831 if (result != ISC_R_SUCCESS)
4833 result = dns_db_findrdataset(db, node, ver, type, 0,
4834 (isc_stdtime_t) 0, &rdataset, NULL);
4835 dns_db_detachnode(db, &node);
4836 if (result == ISC_R_NOTFOUND) {
4837 INSIST(!dns_rdataset_isassociated(&rdataset));
4838 return (ISC_R_SUCCESS);
4840 if (result != ISC_R_SUCCESS) {
4841 INSIST(!dns_rdataset_isassociated(&rdataset));
4845 for (i = 0; i < nkeys; i++) {
4846 isc_boolean_t both = ISC_FALSE;
4848 if (!dst_key_isprivate(keys[i]))
4851 if (check_ksk && !REVOKE(keys[i])) {
4852 isc_boolean_t have_ksk, have_nonksk;
4854 have_ksk = ISC_TRUE;
4855 have_nonksk = ISC_FALSE;
4857 have_ksk = ISC_FALSE;
4858 have_nonksk = ISC_TRUE;
4860 for (j = 0; j < nkeys; j++) {
4861 if (j == i || ALG(keys[i]) != ALG(keys[j]))
4863 if (REVOKE(keys[j]))
4866 have_ksk = ISC_TRUE;
4868 have_nonksk = ISC_TRUE;
4869 both = have_ksk && have_nonksk;
4875 if (type == dns_rdatatype_dnskey) {
4876 if (!KSK(keys[i]) && keyset_kskonly)
4878 } else if (KSK(keys[i]))
4880 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
4883 /* Calculate the signature, creating a RRSIG RDATA. */
4884 isc_buffer_clear(&buffer);
4885 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
4886 &inception, &expire,
4887 mctx, &buffer, &sig_rdata));
4888 /* Update the database and journal with the RRSIG. */
4889 /* XXX inefficient - will cause dataset merging */
4890 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
4891 name, rdataset.ttl, &sig_rdata));
4892 dns_rdata_reset(&sig_rdata);
4893 isc_buffer_init(&buffer, data, sizeof(data));
4897 if (dns_rdataset_isassociated(&rdataset))
4898 dns_rdataset_disassociate(&rdataset);
4900 dns_db_detachnode(db, &node);
4905 zone_resigninc(dns_zone_t *zone) {
4906 dns_db_t *db = NULL;
4907 dns_dbversion_t *version = NULL;
4908 dns_diff_t sig_diff;
4909 dns_fixedname_t fixed;
4911 dns_rdataset_t rdataset;
4912 dns_rdatatype_t covers;
4913 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
4914 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
4915 isc_result_t result;
4916 isc_stdtime_t now, inception, soaexpire, expire, stop;
4917 isc_uint32_t jitter;
4919 unsigned int nkeys = 0;
4920 unsigned int resign;
4922 dns_rdataset_init(&rdataset);
4923 dns_fixedname_init(&fixed);
4924 dns_diff_init(zone->mctx, &sig_diff);
4925 sig_diff.resign = zone->sigresigninginterval;
4928 * Updates are disabled. Pause for 5 minutes.
4930 if (zone->update_disabled) {
4931 result = ISC_R_FAILURE;
4935 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4936 dns_db_attach(zone->db, &db);
4937 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4939 result = dns_db_newversion(db, &version);
4940 if (result != ISC_R_SUCCESS) {
4941 dns_zone_log(zone, ISC_LOG_ERROR,
4942 "zone_resigninc:dns_db_newversion -> %s\n",
4943 dns_result_totext(result));
4947 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
4949 if (result != ISC_R_SUCCESS) {
4950 dns_zone_log(zone, ISC_LOG_ERROR,
4951 "zone_resigninc:find_zone_keys -> %s\n",
4952 dns_result_totext(result));
4956 isc_stdtime_get(&now);
4957 inception = now - 3600; /* Allow for clock skew. */
4958 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
4960 * Spread out signatures over time if they happen to be
4961 * clumped. We don't do this for each add_sigs() call as
4962 * we still want some clustering to occur.
4964 isc_random_get(&jitter);
4965 expire = soaexpire - jitter % 3600;
4968 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
4969 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
4971 name = dns_fixedname_name(&fixed);
4972 result = dns_db_getsigningtime(db, &rdataset, name);
4973 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
4974 dns_zone_log(zone, ISC_LOG_ERROR,
4975 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4976 dns_result_totext(result));
4980 while (result == ISC_R_SUCCESS) {
4981 resign = rdataset.resign;
4982 covers = rdataset.covers;
4983 dns_rdataset_disassociate(&rdataset);
4986 * Stop if we hit the SOA as that means we have walked the
4987 * entire zone. The SOA record should always be the most
4990 /* XXXMPA increase number of RRsets signed pre call */
4991 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
4995 result = del_sigs(zone, db, version, name, covers, &sig_diff,
4996 zone_keys, nkeys, now, ISC_TRUE);
4997 if (result != ISC_R_SUCCESS) {
4998 dns_zone_log(zone, ISC_LOG_ERROR,
4999 "zone_resigninc:del_sigs -> %s\n",
5000 dns_result_totext(result));
5004 result = add_sigs(db, version, name, covers, &sig_diff,
5005 zone_keys, nkeys, zone->mctx, inception,
5006 expire, check_ksk, keyset_kskonly);
5007 if (result != ISC_R_SUCCESS) {
5008 dns_zone_log(zone, ISC_LOG_ERROR,
5009 "zone_resigninc:add_sigs -> %s\n",
5010 dns_result_totext(result));
5013 result = dns_db_getsigningtime(db, &rdataset,
5014 dns_fixedname_name(&fixed));
5015 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
5016 result = ISC_R_SUCCESS;
5019 if (result != ISC_R_SUCCESS)
5020 dns_zone_log(zone, ISC_LOG_ERROR,
5021 "zone_resigninc:dns_db_getsigningtime -> %s\n",
5022 dns_result_totext(result));
5025 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
5028 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5029 &sig_diff, zone_keys, nkeys, now, ISC_TRUE);
5030 if (result != ISC_R_SUCCESS) {
5031 dns_zone_log(zone, ISC_LOG_ERROR,
5032 "zone_resigninc:del_sigs -> %s\n",
5033 dns_result_totext(result));
5038 * Did we change anything in the zone?
5040 if (ISC_LIST_EMPTY(sig_diff.tuples))
5043 /* Increment SOA serial if we have made changes */
5044 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5045 if (result != ISC_R_SUCCESS) {
5046 dns_zone_log(zone, ISC_LOG_ERROR,
5047 "zone_resigninc:increment_soa_serial -> %s\n",
5048 dns_result_totext(result));
5053 * Generate maximum life time signatures so that the above loop
5054 * termination is sensible.
5056 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5057 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5058 soaexpire, check_ksk, keyset_kskonly);
5059 if (result != ISC_R_SUCCESS) {
5060 dns_zone_log(zone, ISC_LOG_ERROR,
5061 "zone_resigninc:add_sigs -> %s\n",
5062 dns_result_totext(result));
5066 /* Write changes to journal file. */
5067 CHECK(zone_journal(zone, &sig_diff, "zone_resigninc"));
5069 /* Everything has succeeded. Commit the changes. */
5070 dns_db_closeversion(db, &version, ISC_TRUE);
5073 dns_diff_clear(&sig_diff);
5074 for (i = 0; i < nkeys; i++)
5075 dst_key_free(&zone_keys[i]);
5076 if (version != NULL) {
5077 dns_db_closeversion(zone->db, &version, ISC_FALSE);
5079 } else if (db != NULL)
5081 if (result == ISC_R_SUCCESS) {
5082 set_resigntime(zone);
5084 zone_needdump(zone, DNS_DUMP_DELAY);
5085 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5089 * Something failed. Retry in 5 minutes.
5091 isc_interval_t ival;
5092 isc_interval_set(&ival, 300, 0);
5093 isc_time_nowplusinterval(&zone->resigntime, &ival);
5098 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
5099 dns_name_t *newname, isc_boolean_t bottom)
5101 isc_result_t result;
5102 dns_dbiterator_t *dbit = NULL;
5103 dns_rdatasetiter_t *rdsit = NULL;
5104 dns_dbnode_t *node = NULL;
5106 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
5107 CHECK(dns_dbiterator_seek(dbit, oldname));
5109 result = dns_dbiterator_next(dbit);
5110 if (result == ISC_R_NOMORE)
5111 CHECK(dns_dbiterator_first(dbit));
5112 CHECK(dns_dbiterator_current(dbit, &node, newname));
5113 if (bottom && dns_name_issubdomain(newname, oldname) &&
5114 !dns_name_equal(newname, oldname)) {
5115 dns_db_detachnode(db, &node);
5119 * Is this node empty?
5121 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
5122 result = dns_rdatasetiter_first(rdsit);
5123 dns_db_detachnode(db, &node);
5124 dns_rdatasetiter_destroy(&rdsit);
5125 if (result != ISC_R_NOMORE)
5130 dns_db_detachnode(db, &node);
5132 dns_dbiterator_destroy(&dbit);
5136 static isc_boolean_t
5137 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5138 dns_rdatatype_t type, dst_key_t *key)
5140 isc_result_t result;
5141 dns_rdataset_t rdataset;
5142 dns_rdata_t rdata = DNS_RDATA_INIT;
5143 dns_rdata_rrsig_t rrsig;
5145 dns_rdataset_init(&rdataset);
5146 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
5147 type, 0, &rdataset, NULL);
5148 if (result != ISC_R_SUCCESS) {
5149 INSIST(!dns_rdataset_isassociated(&rdataset));
5152 for (result = dns_rdataset_first(&rdataset);
5153 result == ISC_R_SUCCESS;
5154 result = dns_rdataset_next(&rdataset)) {
5155 dns_rdataset_current(&rdataset, &rdata);
5156 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5157 INSIST(result == ISC_R_SUCCESS);
5158 if (rrsig.algorithm == dst_key_alg(key) &&
5159 rrsig.keyid == dst_key_id(key)) {
5160 dns_rdataset_disassociate(&rdataset);
5163 dns_rdata_reset(&rdata);
5165 dns_rdataset_disassociate(&rdataset);
5170 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5171 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
5174 dns_fixedname_t fixed;
5176 dns_rdata_t rdata = DNS_RDATA_INIT;
5177 isc_result_t result;
5178 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
5180 dns_fixedname_init(&fixed);
5181 next = dns_fixedname_name(&fixed);
5183 CHECK(next_active(db, version, name, next, bottom));
5184 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
5186 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
5193 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
5194 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5195 isc_boolean_t build_nsec, dst_key_t *key,
5196 isc_stdtime_t inception, isc_stdtime_t expire,
5197 unsigned int minimum, isc_boolean_t is_ksk,
5198 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
5199 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
5201 isc_result_t result;
5202 dns_rdatasetiter_t *iterator = NULL;
5203 dns_rdataset_t rdataset;
5204 dns_rdata_t rdata = DNS_RDATA_INIT;
5205 isc_buffer_t buffer;
5206 unsigned char data[1024];
5207 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
5208 seen_nsec3, seen_ds;
5209 isc_boolean_t bottom;
5211 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5212 if (result != ISC_R_SUCCESS) {
5213 if (result == ISC_R_NOTFOUND)
5214 result = ISC_R_SUCCESS;
5218 dns_rdataset_init(&rdataset);
5219 isc_buffer_init(&buffer, data, sizeof(data));
5220 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
5221 seen_nsec3 = seen_ds = ISC_FALSE;
5222 for (result = dns_rdatasetiter_first(iterator);
5223 result == ISC_R_SUCCESS;
5224 result = dns_rdatasetiter_next(iterator)) {
5225 dns_rdatasetiter_current(iterator, &rdataset);
5226 if (rdataset.type == dns_rdatatype_soa)
5227 seen_soa = ISC_TRUE;
5228 else if (rdataset.type == dns_rdatatype_ns)
5230 else if (rdataset.type == dns_rdatatype_ds)
5232 else if (rdataset.type == dns_rdatatype_dname)
5233 seen_dname = ISC_TRUE;
5234 else if (rdataset.type == dns_rdatatype_nsec)
5235 seen_nsec = ISC_TRUE;
5236 else if (rdataset.type == dns_rdatatype_nsec3)
5237 seen_nsec3 = ISC_TRUE;
5238 if (rdataset.type != dns_rdatatype_rrsig)
5240 dns_rdataset_disassociate(&rdataset);
5242 if (result != ISC_R_NOMORE)
5244 if (seen_ns && !seen_soa)
5245 *delegation = ISC_TRUE;
5247 * Going from insecure to NSEC3.
5248 * Don't generate NSEC3 records for NSEC3 records.
5250 if (build_nsec3 && !seen_nsec3 && seen_rr) {
5251 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
5252 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
5257 * Going from insecure to NSEC.
5258 * Don't generate NSEC records for NSEC3 records.
5260 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
5261 /* Build and add NSEC. */
5262 bottom = (seen_ns && !seen_soa) || seen_dname;
5264 * Build a NSEC record except at the origin.
5266 if (!dns_name_equal(name, dns_db_origin(db))) {
5267 CHECK(add_nsec(db, version, name, node, minimum,
5269 /* Count a NSEC generation as a signature generation. */
5273 result = dns_rdatasetiter_first(iterator);
5274 while (result == ISC_R_SUCCESS) {
5275 dns_rdatasetiter_current(iterator, &rdataset);
5276 if (rdataset.type == dns_rdatatype_soa ||
5277 rdataset.type == dns_rdatatype_rrsig)
5279 if (rdataset.type == dns_rdatatype_dnskey) {
5280 if (!is_ksk && keyset_kskonly)
5285 rdataset.type != dns_rdatatype_ds &&
5286 rdataset.type != dns_rdatatype_nsec)
5288 if (signed_with_key(db, node, version, rdataset.type, key))
5290 /* Calculate the signature, creating a RRSIG RDATA. */
5291 isc_buffer_clear(&buffer);
5292 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
5293 &expire, mctx, &buffer, &rdata));
5294 /* Update the database and journal with the RRSIG. */
5295 /* XXX inefficient - will cause dataset merging */
5296 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
5297 name, rdataset.ttl, &rdata));
5298 dns_rdata_reset(&rdata);
5301 dns_rdataset_disassociate(&rdataset);
5302 result = dns_rdatasetiter_next(iterator);
5304 if (result == ISC_R_NOMORE)
5305 result = ISC_R_SUCCESS;
5307 *delegation = ISC_TRUE;
5309 if (dns_rdataset_isassociated(&rdataset))
5310 dns_rdataset_disassociate(&rdataset);
5311 if (iterator != NULL)
5312 dns_rdatasetiter_destroy(&iterator);
5317 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
5320 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5321 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
5323 isc_result_t result;
5324 dns_rdataset_t rdataset;
5325 dns_dbnode_t *node = NULL;
5327 CHECK(dns_db_getoriginnode(db, &node));
5329 dns_rdataset_init(&rdataset);
5330 result = dns_db_findrdataset(db, node, version,
5333 0, &rdataset, NULL);
5334 if (dns_rdataset_isassociated(&rdataset))
5335 dns_rdataset_disassociate(&rdataset);
5336 if (result == ISC_R_NOTFOUND)
5338 if (result != ISC_R_SUCCESS)
5341 CHECK(delete_nsec(db, version, node, name, diff));
5342 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
5344 result = ISC_R_SUCCESS;
5347 dns_db_detachnode(db, &node);
5352 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
5353 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5354 dns_ttl_t minimum, dns_diff_t *diff)
5356 isc_result_t result;
5357 dns_dbnode_t *node = NULL;
5358 dns_rdataset_t rdataset;
5359 dns_rdata_t rdata = DNS_RDATA_INIT;
5360 unsigned char data[5];
5361 isc_boolean_t seen_done = ISC_FALSE;
5362 isc_boolean_t have_rr = ISC_FALSE;
5364 dns_rdataset_init(&rdataset);
5365 result = dns_db_getoriginnode(signing->db, &node);
5366 if (result != ISC_R_SUCCESS)
5369 result = dns_db_findrdataset(signing->db, node, version,
5370 zone->privatetype, dns_rdatatype_none,
5371 0, &rdataset, NULL);
5372 if (result == ISC_R_NOTFOUND) {
5373 INSIST(!dns_rdataset_isassociated(&rdataset));
5374 result = ISC_R_SUCCESS;
5377 if (result != ISC_R_SUCCESS) {
5378 INSIST(!dns_rdataset_isassociated(&rdataset));
5381 for (result = dns_rdataset_first(&rdataset);
5382 result == ISC_R_SUCCESS;
5383 result = dns_rdataset_next(&rdataset)) {
5384 dns_rdataset_current(&rdataset, &rdata);
5386 * If we don't match the algorithm or keyid skip the record.
5388 if (rdata.length != 5 ||
5389 rdata.data[0] != signing->algorithm ||
5390 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
5391 rdata.data[2] != (signing->keyid & 0xff)) {
5393 dns_rdata_reset(&rdata);
5397 * We have a match. If we were signing (!signing->delete)
5398 * and we already have a record indicating that we have
5399 * finished signing (rdata.data[4] != 0) then keep it.
5400 * Otherwise it needs to be deleted as we have removed all
5401 * the signatures (signing->delete), so any record indicating
5402 * completion is now out of date, or we have finished signing
5403 * with the new record so we no longer need to remember that
5404 * we need to sign the zone with the matching key across a
5405 * nameserver re-start.
5407 if (!signing->delete && rdata.data[4] != 0) {
5408 seen_done = ISC_TRUE;
5411 CHECK(update_one_rr(signing->db, version, diff,
5412 DNS_DIFFOP_DEL, &zone->origin,
5413 rdataset.ttl, &rdata));
5414 dns_rdata_reset(&rdata);
5416 if (result == ISC_R_NOMORE)
5417 result = ISC_R_SUCCESS;
5418 if (!signing->delete && !seen_done) {
5420 * If we were signing then we need to indicate that we have
5421 * finished signing the zone with this key. If it is already
5422 * there we don't need to add it a second time.
5424 data[0] = signing->algorithm;
5425 data[1] = (signing->keyid >> 8) & 0xff;
5426 data[2] = signing->keyid & 0xff;
5429 rdata.length = sizeof(data);
5431 rdata.type = zone->privatetype;
5432 rdata.rdclass = dns_db_class(signing->db);
5433 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
5434 &zone->origin, rdataset.ttl, &rdata));
5435 } else if (!have_rr) {
5436 dns_name_t *origin = dns_db_origin(signing->db);
5438 * Rebuild the NSEC/NSEC3 record for the origin as we no
5439 * longer have any private records.
5442 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
5443 minimum, ISC_FALSE, diff));
5444 CHECK(updatesecure(signing->db, version, origin, minimum,
5449 if (dns_rdataset_isassociated(&rdataset))
5450 dns_rdataset_disassociate(&rdataset);
5452 dns_db_detachnode(signing->db, &node);
5457 * If 'active' is set then we are not done with the chain yet so only
5458 * delete the nsec3param record which indicates a full chain exists
5462 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
5463 isc_boolean_t active, dns_rdatatype_t privatetype,
5466 dns_dbnode_t *node = NULL;
5467 dns_name_t *name = dns_db_origin(db);
5468 dns_rdata_t rdata = DNS_RDATA_INIT;
5469 dns_rdataset_t rdataset;
5470 dns_rdata_nsec3param_t nsec3param;
5471 isc_result_t result;
5472 isc_buffer_t buffer;
5473 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
5476 dns_rdataset_init(&rdataset);
5478 result = dns_db_getoriginnode(db, &node);
5479 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5480 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
5481 0, 0, &rdataset, NULL);
5482 if (result == ISC_R_NOTFOUND)
5484 if (result != ISC_R_SUCCESS)
5488 * Preserve the existing ttl.
5493 * Delete all NSEC3PARAM records which match that in nsec3chain.
5495 for (result = dns_rdataset_first(&rdataset);
5496 result == ISC_R_SUCCESS;
5497 result = dns_rdataset_next(&rdataset)) {
5499 dns_rdataset_current(&rdataset, &rdata);
5500 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
5502 if (nsec3param.hash != chain->nsec3param.hash ||
5503 (active && nsec3param.flags != 0) ||
5504 nsec3param.iterations != chain->nsec3param.iterations ||
5505 nsec3param.salt_length != chain->nsec3param.salt_length ||
5506 memcmp(nsec3param.salt, chain->nsec3param.salt,
5507 nsec3param.salt_length)) {
5508 dns_rdata_reset(&rdata);
5512 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
5513 name, rdataset.ttl, &rdata));
5514 dns_rdata_reset(&rdata);
5516 if (result != ISC_R_NOMORE)
5519 dns_rdataset_disassociate(&rdataset);
5526 * Delete all private records which match that in nsec3chain.
5528 result = dns_db_findrdataset(db, node, ver, privatetype,
5529 0, 0, &rdataset, NULL);
5530 if (result == ISC_R_NOTFOUND)
5532 if (result != ISC_R_SUCCESS)
5535 for (result = dns_rdataset_first(&rdataset);
5536 result == ISC_R_SUCCESS;
5537 result = dns_rdataset_next(&rdataset)) {
5538 dns_rdata_t private = DNS_RDATA_INIT;
5539 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
5541 dns_rdataset_current(&rdataset, &private);
5542 if (!dns_nsec3param_fromprivate(&private, &rdata,
5545 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
5547 if (nsec3param.hash != chain->nsec3param.hash ||
5548 nsec3param.iterations != chain->nsec3param.iterations ||
5549 nsec3param.salt_length != chain->nsec3param.salt_length ||
5550 memcmp(nsec3param.salt, chain->nsec3param.salt,
5551 nsec3param.salt_length)) {
5552 dns_rdata_reset(&rdata);
5556 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
5557 name, rdataset.ttl, &private));
5558 dns_rdata_reset(&rdata);
5560 if (result != ISC_R_NOMORE)
5564 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
5565 result = ISC_R_SUCCESS;
5570 * Add a NSEC3PARAM record which matches that in nsec3chain but
5571 * with all flags bits cleared.
5573 * Note: we do not clear chain->nsec3param.flags as this change
5576 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
5577 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
5578 dns_rdatatype_nsec3param,
5579 &chain->nsec3param, &buffer));
5580 rdata.data[1] = 0; /* Clear flag bits. */
5581 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
5584 dns_db_detachnode(db, &node);
5585 if (dns_rdataset_isassociated(&rdataset))
5586 dns_rdataset_disassociate(&rdataset);
5591 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
5592 dns_name_t *name, dns_diff_t *diff)
5594 dns_rdataset_t rdataset;
5595 isc_result_t result;
5597 dns_rdataset_init(&rdataset);
5599 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
5600 0, 0, &rdataset, NULL);
5601 if (result == ISC_R_NOTFOUND)
5602 return (ISC_R_SUCCESS);
5603 if (result != ISC_R_SUCCESS)
5605 for (result = dns_rdataset_first(&rdataset);
5606 result == ISC_R_SUCCESS;
5607 result = dns_rdataset_next(&rdataset)) {
5608 dns_rdata_t rdata = DNS_RDATA_INIT;
5610 dns_rdataset_current(&rdataset, &rdata);
5611 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
5612 rdataset.ttl, &rdata));
5614 if (result == ISC_R_NOMORE)
5615 result = ISC_R_SUCCESS;
5617 dns_rdataset_disassociate(&rdataset);
5622 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
5623 dns_name_t *name, const dns_rdata_nsec3param_t *param,
5626 dns_rdataset_t rdataset;
5627 dns_rdata_nsec3_t nsec3;
5628 isc_result_t result;
5630 dns_rdataset_init(&rdataset);
5631 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
5632 0, 0, &rdataset, NULL);
5633 if (result == ISC_R_NOTFOUND)
5634 return (ISC_R_SUCCESS);
5635 if (result != ISC_R_SUCCESS)
5638 for (result = dns_rdataset_first(&rdataset);
5639 result == ISC_R_SUCCESS;
5640 result = dns_rdataset_next(&rdataset)) {
5641 dns_rdata_t rdata = DNS_RDATA_INIT;
5643 dns_rdataset_current(&rdataset, &rdata);
5644 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
5645 if (nsec3.hash != param->hash ||
5646 nsec3.iterations != param->iterations ||
5647 nsec3.salt_length != param->salt_length ||
5648 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
5650 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
5651 rdataset.ttl, &rdata));
5653 if (result == ISC_R_NOMORE)
5654 result = ISC_R_SUCCESS;
5656 dns_rdataset_disassociate(&rdataset);
5661 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
5662 const dns_rdata_nsec3param_t *param,
5663 isc_boolean_t *answer)
5665 dns_dbnode_t *node = NULL;
5666 dns_rdata_t rdata = DNS_RDATA_INIT;
5667 dns_rdata_nsec3param_t myparam;
5668 dns_rdataset_t rdataset;
5669 isc_result_t result;
5671 *answer = ISC_FALSE;
5673 result = dns_db_getoriginnode(db, &node);
5674 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5676 dns_rdataset_init(&rdataset);
5678 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
5679 0, 0, &rdataset, NULL);
5680 if (result == ISC_R_SUCCESS) {
5681 dns_rdataset_disassociate(&rdataset);
5682 dns_db_detachnode(db, &node);
5685 if (result != ISC_R_NOTFOUND) {
5686 dns_db_detachnode(db, &node);
5690 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
5691 0, 0, &rdataset, NULL);
5692 if (result == ISC_R_NOTFOUND) {
5694 dns_db_detachnode(db, &node);
5695 return (ISC_R_SUCCESS);
5697 if (result != ISC_R_SUCCESS) {
5698 dns_db_detachnode(db, &node);
5702 for (result = dns_rdataset_first(&rdataset);
5703 result == ISC_R_SUCCESS;
5704 result = dns_rdataset_next(&rdataset)) {
5705 dns_rdataset_current(&rdataset, &rdata);
5706 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
5707 dns_rdata_reset(&rdata);
5709 * Ignore any NSEC3PARAM removals.
5711 if (NSEC3REMOVE(myparam.flags))
5714 * Ignore the chain that we are in the process of deleting.
5716 if (myparam.hash == param->hash &&
5717 myparam.iterations == param->iterations &&
5718 myparam.salt_length == param->salt_length &&
5719 !memcmp(myparam.salt, param->salt, myparam.salt_length))
5722 * Found an active NSEC3 chain.
5726 if (result == ISC_R_NOMORE) {
5728 result = ISC_R_SUCCESS;
5732 if (dns_rdataset_isassociated(&rdataset))
5733 dns_rdataset_disassociate(&rdataset);
5734 dns_db_detachnode(db, &node);
5739 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
5740 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
5741 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
5742 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
5743 dns_diff_t *sig_diff)
5745 dns_difftuple_t *tuple;
5746 isc_result_t result;
5748 for (tuple = ISC_LIST_HEAD(diff->tuples);
5750 tuple = ISC_LIST_HEAD(diff->tuples)) {
5751 result = del_sigs(zone, db, version, &tuple->name,
5752 tuple->rdata.type, sig_diff,
5753 zone_keys, nkeys, now, ISC_FALSE);
5754 if (result != ISC_R_SUCCESS) {
5755 dns_zone_log(zone, ISC_LOG_ERROR,
5756 "update_sigs:del_sigs -> %s\n",
5757 dns_result_totext(result));
5760 result = add_sigs(db, version, &tuple->name,
5761 tuple->rdata.type, sig_diff,
5762 zone_keys, nkeys, zone->mctx, inception,
5763 expire, check_ksk, keyset_kskonly);
5764 if (result != ISC_R_SUCCESS) {
5765 dns_zone_log(zone, ISC_LOG_ERROR,
5766 "update_sigs:add_sigs -> %s\n",
5767 dns_result_totext(result));
5772 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5773 while (next != NULL &&
5774 (tuple->rdata.type != next->rdata.type ||
5775 !dns_name_equal(&tuple->name, &next->name)))
5776 next = ISC_LIST_NEXT(next, link);
5777 ISC_LIST_UNLINK(diff->tuples, tuple, link);
5778 dns_diff_appendminimal(sig_diff, &tuple);
5779 INSIST(tuple == NULL);
5781 } while (tuple != NULL);
5783 return (ISC_R_SUCCESS);
5787 * Incrementally build and sign a new NSEC3 chain using the parameters
5791 zone_nsec3chain(dns_zone_t *zone) {
5792 dns_db_t *db = NULL;
5793 dns_dbnode_t *node = NULL;
5794 dns_dbversion_t *version = NULL;
5795 dns_diff_t sig_diff;
5796 dns_diff_t nsec_diff;
5797 dns_diff_t nsec3_diff;
5798 dns_diff_t param_diff;
5799 dns_fixedname_t fixed;
5800 dns_fixedname_t nextfixed;
5801 dns_name_t *name, *nextname;
5802 dns_rdataset_t rdataset;
5803 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
5804 dns_nsec3chainlist_t cleanup;
5805 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
5806 isc_int32_t signatures;
5807 isc_boolean_t check_ksk, keyset_kskonly;
5808 isc_boolean_t delegation;
5809 isc_boolean_t first;
5810 isc_result_t result;
5811 isc_stdtime_t now, inception, soaexpire, expire;
5812 isc_uint32_t jitter;
5814 unsigned int nkeys = 0;
5816 isc_boolean_t unsecure = ISC_FALSE;
5817 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
5818 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
5819 dns_rdatasetiter_t *iterator = NULL;
5820 isc_boolean_t buildnsecchain;
5821 isc_boolean_t updatensec = ISC_FALSE;
5822 dns_rdatatype_t privatetype = zone->privatetype;
5824 dns_rdataset_init(&rdataset);
5825 dns_fixedname_init(&fixed);
5826 name = dns_fixedname_name(&fixed);
5827 dns_fixedname_init(&nextfixed);
5828 nextname = dns_fixedname_name(&nextfixed);
5829 dns_diff_init(zone->mctx, ¶m_diff);
5830 dns_diff_init(zone->mctx, &nsec3_diff);
5831 dns_diff_init(zone->mctx, &nsec_diff);
5832 dns_diff_init(zone->mctx, &sig_diff);
5833 sig_diff.resign = zone->sigresigninginterval;
5834 ISC_LIST_INIT(cleanup);
5837 * Updates are disabled. Pause for 5 minutes.
5839 if (zone->update_disabled) {
5840 result = ISC_R_FAILURE;
5844 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5845 dns_db_attach(zone->db, &db);
5846 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5848 result = dns_db_newversion(db, &version);
5849 if (result != ISC_R_SUCCESS) {
5850 dns_zone_log(zone, ISC_LOG_ERROR,
5851 "zone_nsec3chain:dns_db_newversion -> %s\n",
5852 dns_result_totext(result));
5856 result = find_zone_keys(zone, db, version, zone->mctx,
5857 DNS_MAXZONEKEYS, zone_keys, &nkeys);
5858 if (result != ISC_R_SUCCESS) {
5859 dns_zone_log(zone, ISC_LOG_ERROR,
5860 "zone_nsec3chain:find_zone_keys -> %s\n",
5861 dns_result_totext(result));
5865 isc_stdtime_get(&now);
5866 inception = now - 3600; /* Allow for clock skew. */
5867 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5870 * Spread out signatures over time if they happen to be
5871 * clumped. We don't do this for each add_sigs() call as
5872 * we still want some clustering to occur.
5874 isc_random_get(&jitter);
5875 expire = soaexpire - jitter % 3600;
5877 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5878 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
5881 * We keep pulling nodes off each iterator in turn until
5882 * we have no more nodes to pull off or we reach the limits
5885 nodes = zone->nodes;
5886 signatures = zone->signatures;
5888 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5892 if (nsec3chain != NULL)
5893 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
5895 * Generate new NSEC3 chains first.
5897 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
5899 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
5901 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5902 if (nsec3chain->done || nsec3chain->db != zone->db) {
5903 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
5904 ISC_LIST_APPEND(cleanup, nsec3chain, link);
5906 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5908 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
5912 * Possible future db.
5914 if (nsec3chain->db != db) {
5918 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
5921 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
5923 if (nsec3chain->delete_nsec) {
5924 delegation = ISC_FALSE;
5925 dns_dbiterator_pause(nsec3chain->dbiterator);
5926 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
5930 * On the first pass we need to check if the current node
5931 * has not been obscured.
5933 delegation = ISC_FALSE;
5934 unsecure = ISC_FALSE;
5936 dns_fixedname_t ffound;
5938 dns_fixedname_init(&ffound);
5939 found = dns_fixedname_name(&ffound);
5940 result = dns_db_find(db, name, version,
5942 DNS_DBFIND_NOWILD, 0, NULL, found,
5944 if ((result == DNS_R_DELEGATION ||
5945 result == DNS_R_DNAME) &&
5946 !dns_name_equal(name, found)) {
5948 * Remember the obscuring name so that
5949 * we skip all obscured names.
5951 dns_name_copy(found, name, NULL);
5952 delegation = ISC_TRUE;
5958 * Check to see if this is a bottom of zone node.
5960 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5961 if (result == ISC_R_NOTFOUND) /* Empty node? */
5963 if (result != ISC_R_SUCCESS)
5966 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
5968 for (result = dns_rdatasetiter_first(iterator);
5969 result == ISC_R_SUCCESS;
5970 result = dns_rdatasetiter_next(iterator)) {
5971 dns_rdatasetiter_current(iterator, &rdataset);
5972 INSIST(rdataset.type != dns_rdatatype_nsec3);
5973 if (rdataset.type == dns_rdatatype_soa)
5974 seen_soa = ISC_TRUE;
5975 else if (rdataset.type == dns_rdatatype_ns)
5977 else if (rdataset.type == dns_rdatatype_dname)
5978 seen_dname = ISC_TRUE;
5979 else if (rdataset.type == dns_rdatatype_ds)
5981 else if (rdataset.type == dns_rdatatype_nsec)
5982 seen_nsec = ISC_TRUE;
5983 dns_rdataset_disassociate(&rdataset);
5985 dns_rdatasetiter_destroy(&iterator);
5987 * Is there a NSEC chain than needs to be cleaned up?
5990 nsec3chain->seen_nsec = ISC_TRUE;
5991 if (seen_ns && !seen_soa && !seen_ds)
5992 unsecure = ISC_TRUE;
5993 if ((seen_ns && !seen_soa) || seen_dname)
5994 delegation = ISC_TRUE;
5999 dns_dbiterator_pause(nsec3chain->dbiterator);
6000 result = dns_nsec3_addnsec3(db, version, name,
6001 &nsec3chain->nsec3param,
6002 zone->minimum, unsecure,
6004 if (result != ISC_R_SUCCESS) {
6005 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6006 "dns_nsec3_addnsec3 -> %s\n",
6007 dns_result_totext(result));
6012 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
6013 * two signatures. Additionally there will, in general, be
6014 * two signature generated below.
6016 * If we are only changing the optout flag the cost is half
6017 * that of the cost of generating a completely new chain.
6022 * Go onto next node.
6026 dns_db_detachnode(db, &node);
6028 result = dns_dbiterator_next(nsec3chain->dbiterator);
6030 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
6031 CHECK(fixup_nsec3param(db, version, nsec3chain,
6032 ISC_FALSE, privatetype,
6035 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6038 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6041 if (result == ISC_R_NOMORE) {
6042 dns_dbiterator_pause(nsec3chain->dbiterator);
6043 if (nsec3chain->seen_nsec) {
6044 CHECK(fixup_nsec3param(db, version,
6049 nsec3chain->delete_nsec = ISC_TRUE;
6052 CHECK(fixup_nsec3param(db, version, nsec3chain,
6053 ISC_FALSE, privatetype,
6056 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6059 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6061 } else if (result != ISC_R_SUCCESS) {
6062 dns_zone_log(zone, ISC_LOG_ERROR,
6064 "dns_dbiterator_next -> %s\n",
6065 dns_result_totext(result));
6067 } else if (delegation) {
6068 dns_dbiterator_current(nsec3chain->dbiterator,
6070 dns_db_detachnode(db, &node);
6071 if (!dns_name_issubdomain(nextname, name))
6079 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6084 dns_dbiterator_pause(nsec3chain->dbiterator);
6085 nsec3chain = nextnsec3chain;
6087 if (nsec3chain != NULL)
6088 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6095 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6098 buildnsecchain = ISC_FALSE;
6099 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6101 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6104 if (nsec3chain->db != db)
6105 goto next_removechain;
6107 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
6108 goto next_removechain;
6111 * Work out if we need to build a NSEC chain as a consequence
6112 * of removing this NSEC3 chain.
6114 if (first && !updatensec &&
6115 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) {
6116 result = need_nsec_chain(db, version,
6117 &nsec3chain->nsec3param,
6119 if (result != ISC_R_SUCCESS) {
6120 dns_zone_log(zone, ISC_LOG_ERROR,
6122 "need_nsec_chain -> %s\n",
6123 dns_result_totext(result));
6129 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
6130 "buildnsecchain = %u\n", buildnsecchain);
6132 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6133 delegation = ISC_FALSE;
6135 if (!buildnsecchain) {
6137 * Delete the NSECPARAM record that matches this chain.
6140 result = fixup_nsec3param(db, version,
6142 ISC_TRUE, privatetype,
6144 if (result != ISC_R_SUCCESS) {
6145 dns_zone_log(zone, ISC_LOG_ERROR,
6147 "fixup_nsec3param -> %s\n",
6148 dns_result_totext(result));
6154 * Delete the NSEC3 records.
6156 result = deletematchingnsec3(db, version, node, name,
6157 &nsec3chain->nsec3param,
6159 if (result != ISC_R_SUCCESS) {
6160 dns_zone_log(zone, ISC_LOG_ERROR,
6162 "deletematchingnsec3 -> %s\n",
6163 dns_result_totext(result));
6166 goto next_removenode;
6170 dns_fixedname_t ffound;
6172 dns_fixedname_init(&ffound);
6173 found = dns_fixedname_name(&ffound);
6174 result = dns_db_find(db, name, version,
6176 DNS_DBFIND_NOWILD, 0, NULL, found,
6178 if ((result == DNS_R_DELEGATION ||
6179 result == DNS_R_DNAME) &&
6180 !dns_name_equal(name, found)) {
6182 * Remember the obscuring name so that
6183 * we skip all obscured names.
6185 dns_name_copy(found, name, NULL);
6186 delegation = ISC_TRUE;
6187 goto next_removenode;
6192 * Check to see if this is a bottom of zone node.
6194 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6195 if (result == ISC_R_NOTFOUND) /* Empty node? */
6196 goto next_removenode;
6197 if (result != ISC_R_SUCCESS)
6200 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
6201 seen_rr = ISC_FALSE;
6202 for (result = dns_rdatasetiter_first(iterator);
6203 result == ISC_R_SUCCESS;
6204 result = dns_rdatasetiter_next(iterator)) {
6205 dns_rdatasetiter_current(iterator, &rdataset);
6206 if (rdataset.type == dns_rdatatype_soa)
6207 seen_soa = ISC_TRUE;
6208 else if (rdataset.type == dns_rdatatype_ns)
6210 else if (rdataset.type == dns_rdatatype_dname)
6211 seen_dname = ISC_TRUE;
6212 else if (rdataset.type == dns_rdatatype_nsec)
6213 seen_nsec = ISC_TRUE;
6214 else if (rdataset.type == dns_rdatatype_nsec3)
6215 seen_nsec3 = ISC_TRUE;
6216 if (rdataset.type != dns_rdatatype_rrsig)
6218 dns_rdataset_disassociate(&rdataset);
6220 dns_rdatasetiter_destroy(&iterator);
6222 if (!seen_rr || seen_nsec3 || seen_nsec)
6223 goto next_removenode;
6224 if ((seen_ns && !seen_soa) || seen_dname)
6225 delegation = ISC_TRUE;
6228 * Add a NSEC record except at the origin.
6230 if (!dns_name_equal(name, dns_db_origin(db))) {
6231 dns_dbiterator_pause(nsec3chain->dbiterator);
6232 CHECK(add_nsec(db, version, name, node, zone->minimum,
6233 delegation, &nsec_diff));
6238 dns_db_detachnode(db, &node);
6240 result = dns_dbiterator_next(nsec3chain->dbiterator);
6241 if (result == ISC_R_NOMORE && buildnsecchain) {
6243 * The NSEC chain should now be built.
6244 * We can now remove the NSEC3 chain.
6246 updatensec = ISC_TRUE;
6247 goto same_removechain;
6249 if (result == ISC_R_NOMORE) {
6251 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6254 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6255 dns_dbiterator_pause(nsec3chain->dbiterator);
6256 result = fixup_nsec3param(db, version,
6257 nsec3chain, ISC_FALSE,
6260 if (result != ISC_R_SUCCESS) {
6261 dns_zone_log(zone, ISC_LOG_ERROR,
6263 "fixup_nsec3param -> %s\n",
6264 dns_result_totext(result));
6267 goto next_removechain;
6268 } else if (result != ISC_R_SUCCESS) {
6269 dns_zone_log(zone, ISC_LOG_ERROR,
6271 "dns_dbiterator_next -> %s\n",
6272 dns_result_totext(result));
6274 } else if (delegation) {
6275 dns_dbiterator_current(nsec3chain->dbiterator,
6277 dns_db_detachnode(db, &node);
6278 if (!dns_name_issubdomain(nextname, name))
6286 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6287 buildnsecchain = ISC_FALSE;
6292 dns_dbiterator_pause(nsec3chain->dbiterator);
6293 nsec3chain = nextnsec3chain;
6298 * We may need to update the NSEC/NSEC3 records for the zone apex.
6300 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
6301 isc_boolean_t rebuild_nsec = ISC_FALSE,
6302 rebuild_nsec3 = ISC_FALSE;
6303 result = dns_db_getoriginnode(db, &node);
6304 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6305 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6306 if (result != ISC_R_SUCCESS) {
6307 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6308 "dns_db_allrdatasets -> %s\n",
6309 dns_result_totext(result));
6312 for (result = dns_rdatasetiter_first(iterator);
6313 result == ISC_R_SUCCESS;
6314 result = dns_rdatasetiter_next(iterator)) {
6315 dns_rdatasetiter_current(iterator, &rdataset);
6316 if (rdataset.type == dns_rdatatype_nsec)
6317 rebuild_nsec = ISC_TRUE;
6318 if (rdataset.type == dns_rdatatype_nsec3param)
6319 rebuild_nsec3 = ISC_TRUE;
6320 dns_rdataset_disassociate(&rdataset);
6322 dns_rdatasetiter_destroy(&iterator);
6323 dns_db_detachnode(db, &node);
6326 if (nsec3chain != NULL)
6327 dns_dbiterator_pause(nsec3chain->dbiterator);
6328 result = updatesecure(db, version, &zone->origin,
6329 zone->minimum, ISC_TRUE,
6331 if (result != ISC_R_SUCCESS) {
6332 dns_zone_log(zone, ISC_LOG_ERROR,
6334 "updatesecure -> %s\n",
6335 dns_result_totext(result));
6339 if (rebuild_nsec3) {
6340 result = dns_nsec3_addnsec3s(db, version,
6342 zone->minimum, ISC_FALSE,
6344 if (result != ISC_R_SUCCESS) {
6345 dns_zone_log(zone, ISC_LOG_ERROR,
6347 "dns_nsec3_addnsec3s -> %s\n",
6348 dns_result_totext(result));
6355 * Add / update signatures for the NSEC3 records.
6357 result = update_sigs(&nsec3_diff, db, version, zone_keys,
6358 nkeys, zone, inception, expire, now,
6359 check_ksk, keyset_kskonly, &sig_diff);
6360 if (result != ISC_R_SUCCESS) {
6361 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6362 "update_sigs -> %s\n", dns_result_totext(result));
6367 * We have changed the NSEC3PARAM or private RRsets
6368 * above so we need to update the signatures.
6370 result = update_sigs(¶m_diff, db, version, zone_keys,
6371 nkeys, zone, inception, expire, now,
6372 check_ksk, keyset_kskonly, &sig_diff);
6373 if (result != ISC_R_SUCCESS) {
6374 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6375 "update_sigs -> %s\n", dns_result_totext(result));
6380 if (nsec3chain != NULL)
6381 dns_dbiterator_pause(nsec3chain->dbiterator);
6382 result = updatesecure(db, version, &zone->origin,
6383 zone->minimum, ISC_FALSE, &nsec_diff);
6384 if (result != ISC_R_SUCCESS) {
6385 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6386 "updatesecure -> %s\n",
6387 dns_result_totext(result));
6392 result = update_sigs(&nsec_diff, db, version, zone_keys,
6393 nkeys, zone, inception, expire, now,
6394 check_ksk, keyset_kskonly, &sig_diff);
6395 if (result != ISC_R_SUCCESS) {
6396 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6397 "update_sigs -> %s\n", dns_result_totext(result));
6402 * If we made no effective changes to the zone then we can just
6403 * cleanup otherwise we need to increment the serial.
6405 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
6408 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6409 &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
6410 if (result != ISC_R_SUCCESS) {
6411 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6412 "del_sigs -> %s\n", dns_result_totext(result));
6416 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
6417 if (result != ISC_R_SUCCESS) {
6418 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6419 "increment_soa_serial -> %s\n",
6420 dns_result_totext(result));
6424 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6425 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
6426 soaexpire, check_ksk, keyset_kskonly);
6427 if (result != ISC_R_SUCCESS) {
6428 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6429 "add_sigs -> %s\n", dns_result_totext(result));
6433 /* Write changes to journal file. */
6434 CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain"));
6437 zone_needdump(zone, DNS_DUMP_DELAY);
6438 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6443 * Pause all iterators so that dns_db_closeversion() can succeed.
6446 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6448 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
6449 dns_dbiterator_pause(nsec3chain->dbiterator);
6453 * Everything has succeeded. Commit the changes.
6455 dns_db_closeversion(db, &version, ISC_TRUE);
6458 * Everything succeeded so we can clean these up now.
6460 nsec3chain = ISC_LIST_HEAD(cleanup);
6461 while (nsec3chain != NULL) {
6462 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
6463 dns_db_detach(&nsec3chain->db);
6464 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6465 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6466 nsec3chain = ISC_LIST_HEAD(cleanup);
6469 set_resigntime(zone);
6472 if (result != ISC_R_SUCCESS)
6473 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s\n",
6474 dns_result_totext(result));
6476 * On error roll back the current nsec3chain.
6478 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
6479 if (nsec3chain->done) {
6480 dns_db_detach(&nsec3chain->db);
6481 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6482 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6484 result = dns_dbiterator_first(nsec3chain->dbiterator);
6485 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6486 dns_dbiterator_pause(nsec3chain->dbiterator);
6487 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
6492 * Rollback the cleanup list.
6494 nsec3chain = ISC_LIST_TAIL(cleanup);
6495 while (nsec3chain != NULL) {
6496 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
6497 if (nsec3chain->done) {
6498 dns_db_detach(&nsec3chain->db);
6499 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6500 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6503 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
6505 result = dns_dbiterator_first(nsec3chain->dbiterator);
6506 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6507 dns_dbiterator_pause(nsec3chain->dbiterator);
6508 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
6510 nsec3chain = ISC_LIST_TAIL(cleanup);
6514 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6516 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
6517 dns_dbiterator_pause(nsec3chain->dbiterator);
6520 dns_diff_clear(¶m_diff);
6521 dns_diff_clear(&nsec3_diff);
6522 dns_diff_clear(&nsec_diff);
6523 dns_diff_clear(&sig_diff);
6525 if (iterator != NULL)
6526 dns_rdatasetiter_destroy(&iterator);
6528 for (i = 0; i < nkeys; i++)
6529 dst_key_free(&zone_keys[i]);
6532 dns_db_detachnode(db, &node);
6533 if (version != NULL) {
6534 dns_db_closeversion(db, &version, ISC_FALSE);
6536 } else if (db != NULL)
6540 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
6542 if (zone->update_disabled || result != ISC_R_SUCCESS)
6543 isc_interval_set(&i, 60, 0); /* 1 minute */
6545 isc_interval_set(&i, 0, 10000000); /* 10 ms */
6546 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
6548 isc_time_settoepoch(&zone->nsec3chaintime);
6553 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6554 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
6555 isc_uint16_t keyid, dns_diff_t *diff)
6557 dns_rdata_rrsig_t rrsig;
6558 dns_rdataset_t rdataset;
6559 dns_rdatasetiter_t *iterator = NULL;
6560 isc_result_t result;
6562 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6563 if (result != ISC_R_SUCCESS) {
6564 if (result == ISC_R_NOTFOUND)
6565 result = ISC_R_SUCCESS;
6569 dns_rdataset_init(&rdataset);
6570 for (result = dns_rdatasetiter_first(iterator);
6571 result == ISC_R_SUCCESS;
6572 result = dns_rdatasetiter_next(iterator)) {
6573 dns_rdatasetiter_current(iterator, &rdataset);
6574 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
6575 for (result = dns_rdataset_first(&rdataset);
6576 result == ISC_R_SUCCESS;
6577 result = dns_rdataset_next(&rdataset)) {
6578 dns_rdata_t rdata = DNS_RDATA_INIT;
6579 dns_rdataset_current(&rdataset, &rdata);
6580 CHECK(update_one_rr(db, version, diff,
6581 DNS_DIFFOP_DEL, name,
6582 rdataset.ttl, &rdata));
6584 if (result != ISC_R_NOMORE)
6586 dns_rdataset_disassociate(&rdataset);
6589 if (rdataset.type != dns_rdatatype_rrsig) {
6590 dns_rdataset_disassociate(&rdataset);
6593 for (result = dns_rdataset_first(&rdataset);
6594 result == ISC_R_SUCCESS;
6595 result = dns_rdataset_next(&rdataset)) {
6596 dns_rdata_t rdata = DNS_RDATA_INIT;
6597 dns_rdataset_current(&rdataset, &rdata);
6598 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
6599 if (rrsig.algorithm != algorithm ||
6600 rrsig.keyid != keyid)
6602 CHECK(update_one_rr(db, version, diff,
6603 DNS_DIFFOP_DELRESIGN, name,
6604 rdataset.ttl, &rdata));
6606 dns_rdataset_disassociate(&rdataset);
6607 if (result != ISC_R_NOMORE)
6610 if (result == ISC_R_NOMORE)
6611 result = ISC_R_SUCCESS;
6613 if (dns_rdataset_isassociated(&rdataset))
6614 dns_rdataset_disassociate(&rdataset);
6615 dns_rdatasetiter_destroy(&iterator);
6620 * Incrementally sign the zone using the keys requested.
6621 * Builds the NSEC chain if required.
6624 zone_sign(dns_zone_t *zone) {
6625 dns_db_t *db = NULL;
6626 dns_dbnode_t *node = NULL;
6627 dns_dbversion_t *version = NULL;
6628 dns_diff_t sig_diff;
6629 dns_diff_t post_diff;
6630 dns_fixedname_t fixed;
6631 dns_fixedname_t nextfixed;
6632 dns_name_t *name, *nextname;
6633 dns_rdataset_t rdataset;
6634 dns_signing_t *signing, *nextsigning;
6635 dns_signinglist_t cleanup;
6636 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6637 isc_int32_t signatures;
6638 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
6639 isc_boolean_t commit = ISC_FALSE;
6640 isc_boolean_t delegation;
6641 isc_boolean_t build_nsec = ISC_FALSE;
6642 isc_boolean_t build_nsec3 = ISC_FALSE;
6643 isc_boolean_t first;
6644 isc_result_t result;
6645 isc_stdtime_t now, inception, soaexpire, expire;
6646 isc_uint32_t jitter;
6648 unsigned int nkeys = 0;
6651 dns_rdataset_init(&rdataset);
6652 dns_fixedname_init(&fixed);
6653 name = dns_fixedname_name(&fixed);
6654 dns_fixedname_init(&nextfixed);
6655 nextname = dns_fixedname_name(&nextfixed);
6656 dns_diff_init(zone->mctx, &sig_diff);
6657 sig_diff.resign = zone->sigresigninginterval;
6658 dns_diff_init(zone->mctx, &post_diff);
6659 ISC_LIST_INIT(cleanup);
6662 * Updates are disabled. Pause for 5 minutes.
6664 if (zone->update_disabled) {
6665 result = ISC_R_FAILURE;
6669 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6670 dns_db_attach(zone->db, &db);
6671 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6673 result = dns_db_newversion(db, &version);
6674 if (result != ISC_R_SUCCESS) {
6675 dns_zone_log(zone, ISC_LOG_ERROR,
6676 "zone_sign:dns_db_newversion -> %s\n",
6677 dns_result_totext(result));
6681 result = find_zone_keys(zone, db, version, zone->mctx,
6682 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6683 if (result != ISC_R_SUCCESS) {
6684 dns_zone_log(zone, ISC_LOG_ERROR,
6685 "zone_sign:find_zone_keys -> %s\n",
6686 dns_result_totext(result));
6690 isc_stdtime_get(&now);
6691 inception = now - 3600; /* Allow for clock skew. */
6692 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6695 * Spread out signatures over time if they happen to be
6696 * clumped. We don't do this for each add_sigs() call as
6697 * we still want some clustering to occur.
6699 isc_random_get(&jitter);
6700 expire = soaexpire - jitter % 3600;
6703 * We keep pulling nodes off each iterator in turn until
6704 * we have no more nodes to pull off or we reach the limits
6707 nodes = zone->nodes;
6708 signatures = zone->signatures;
6709 signing = ISC_LIST_HEAD(zone->signing);
6712 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6713 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6715 /* Determine which type of chain to build */
6716 CHECK(dns_private_chains(db, version, zone->privatetype,
6717 &build_nsec, &build_nsec3));
6719 /* If neither chain is found, default to NSEC */
6720 if (!build_nsec && !build_nsec3)
6721 build_nsec = ISC_TRUE;
6723 while (signing != NULL && nodes-- > 0 && signatures > 0) {
6724 nextsigning = ISC_LIST_NEXT(signing, link);
6726 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6727 if (signing->done || signing->db != zone->db) {
6729 * The zone has been reloaded. We will have
6730 * created new signings as part of the reload
6731 * process so we can destroy this one.
6733 ISC_LIST_UNLINK(zone->signing, signing, link);
6734 ISC_LIST_APPEND(cleanup, signing, link);
6735 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6738 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6740 if (signing->db != db)
6743 delegation = ISC_FALSE;
6745 if (first && signing->delete) {
6747 * Remove the key we are deleting from consideration.
6749 for (i = 0, j = 0; i < nkeys; i++) {
6751 * Find the key we want to remove.
6753 if (ALG(zone_keys[i]) == signing->algorithm &&
6754 dst_key_id(zone_keys[i]) == signing->keyid)
6756 if (KSK(zone_keys[i]))
6757 dst_key_free(&zone_keys[i]);
6760 zone_keys[j] = zone_keys[i];
6766 dns_dbiterator_current(signing->dbiterator, &node, name);
6768 if (signing->delete) {
6769 dns_dbiterator_pause(signing->dbiterator);
6770 CHECK(del_sig(db, version, name, node, nkeys,
6771 signing->algorithm, signing->keyid,
6776 * On the first pass we need to check if the current node
6777 * has not been obscured.
6780 dns_fixedname_t ffound;
6782 dns_fixedname_init(&ffound);
6783 found = dns_fixedname_name(&ffound);
6784 result = dns_db_find(db, name, version,
6786 DNS_DBFIND_NOWILD, 0, NULL, found,
6788 if ((result == DNS_R_DELEGATION ||
6789 result == DNS_R_DNAME) &&
6790 !dns_name_equal(name, found)) {
6792 * Remember the obscuring name so that
6793 * we skip all obscured names.
6795 dns_name_copy(found, name, NULL);
6796 delegation = ISC_TRUE;
6804 dns_dbiterator_pause(signing->dbiterator);
6805 for (i = 0; i < nkeys; i++) {
6806 isc_boolean_t both = ISC_FALSE;
6809 * Find the keys we want to sign with.
6811 if (!dst_key_isprivate(zone_keys[i]))
6815 * When adding look for the specific key.
6817 if (!signing->delete &&
6818 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
6819 dst_key_id(zone_keys[i]) != signing->keyid))
6823 * When deleting make sure we are properly signed
6824 * with the algorithm that was being removed.
6826 if (signing->delete &&
6827 ALG(zone_keys[i]) != signing->algorithm)
6831 * Do we do KSK processing?
6833 if (check_ksk && !REVOKE(zone_keys[i])) {
6834 isc_boolean_t have_ksk, have_nonksk;
6835 if (KSK(zone_keys[i])) {
6836 have_ksk = ISC_TRUE;
6837 have_nonksk = ISC_FALSE;
6839 have_ksk = ISC_FALSE;
6840 have_nonksk = ISC_TRUE;
6842 for (j = 0; j < nkeys; j++) {
6844 ALG(zone_keys[i]) !=
6847 if (REVOKE(zone_keys[j]))
6849 if (KSK(zone_keys[j]))
6850 have_ksk = ISC_TRUE;
6852 have_nonksk = ISC_TRUE;
6853 both = have_ksk && have_nonksk;
6858 if (both || REVOKE(zone_keys[i]))
6859 is_ksk = KSK(zone_keys[i]);
6863 CHECK(sign_a_node(db, name, node, version, build_nsec3,
6864 build_nsec, zone_keys[i], inception,
6865 expire, zone->minimum, is_ksk,
6866 ISC_TF(both && keyset_kskonly),
6867 &delegation, &sig_diff,
6868 &signatures, zone->mctx));
6870 * If we are adding we are done. Look for other keys
6871 * of the same algorithm if deleting.
6873 if (!signing->delete)
6878 * Go onto next node.
6882 dns_db_detachnode(db, &node);
6884 result = dns_dbiterator_next(signing->dbiterator);
6885 if (result == ISC_R_NOMORE) {
6886 ISC_LIST_UNLINK(zone->signing, signing, link);
6887 ISC_LIST_APPEND(cleanup, signing, link);
6888 dns_dbiterator_pause(signing->dbiterator);
6889 if (nkeys != 0 && build_nsec) {
6891 * We have finished regenerating the
6892 * zone with a zone signing key.
6893 * The NSEC chain is now complete and
6894 * there is a full set of signatures
6895 * for the zone. We can now clear the
6896 * OPT bit from the NSEC record.
6898 result = updatesecure(db, version,
6903 if (result != ISC_R_SUCCESS) {
6906 "updatesecure -> %s\n",
6907 dns_result_totext(result));
6911 result = updatesignwithkey(zone, signing,
6916 if (result != ISC_R_SUCCESS) {
6917 dns_zone_log(zone, ISC_LOG_ERROR,
6918 "updatesignwithkey "
6920 dns_result_totext(result));
6923 build_nsec = ISC_FALSE;
6925 } else if (result != ISC_R_SUCCESS) {
6926 dns_zone_log(zone, ISC_LOG_ERROR,
6927 "zone_sign:dns_dbiterator_next -> %s\n",
6928 dns_result_totext(result));
6930 } else if (delegation) {
6931 dns_dbiterator_current(signing->dbiterator,
6933 dns_db_detachnode(db, &node);
6934 if (!dns_name_issubdomain(nextname, name))
6942 dns_dbiterator_pause(signing->dbiterator);
6943 signing = nextsigning;
6947 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
6948 result = update_sigs(&post_diff, db, version, zone_keys,
6949 nkeys, zone, inception, expire, now,
6950 check_ksk, keyset_kskonly, &sig_diff);
6951 if (result != ISC_R_SUCCESS) {
6952 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
6953 "update_sigs -> %s\n",
6954 dns_result_totext(result));
6960 * Have we changed anything?
6962 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) {
6963 result = ISC_R_SUCCESS;
6969 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6970 &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
6971 if (result != ISC_R_SUCCESS) {
6972 dns_zone_log(zone, ISC_LOG_ERROR,
6973 "zone_sign:del_sigs -> %s\n",
6974 dns_result_totext(result));
6978 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
6979 if (result != ISC_R_SUCCESS) {
6980 dns_zone_log(zone, ISC_LOG_ERROR,
6981 "zone_sign:increment_soa_serial -> %s\n",
6982 dns_result_totext(result));
6987 * Generate maximum life time signatures so that the above loop
6988 * termination is sensible.
6990 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6991 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
6992 soaexpire, check_ksk, keyset_kskonly);
6993 if (result != ISC_R_SUCCESS) {
6994 dns_zone_log(zone, ISC_LOG_ERROR,
6995 "zone_sign:add_sigs -> %s\n",
6996 dns_result_totext(result));
7001 * Write changes to journal file.
7003 CHECK(zone_journal(zone, &sig_diff, "zone_sign"));
7007 * Pause all iterators so that dns_db_closeversion() can succeed.
7009 for (signing = ISC_LIST_HEAD(zone->signing);
7011 signing = ISC_LIST_NEXT(signing, link))
7012 dns_dbiterator_pause(signing->dbiterator);
7014 for (signing = ISC_LIST_HEAD(cleanup);
7016 signing = ISC_LIST_NEXT(signing, link))
7017 dns_dbiterator_pause(signing->dbiterator);
7020 * Everything has succeeded. Commit the changes.
7022 dns_db_closeversion(db, &version, commit);
7025 * Everything succeeded so we can clean these up now.
7027 signing = ISC_LIST_HEAD(cleanup);
7028 while (signing != NULL) {
7029 ISC_LIST_UNLINK(cleanup, signing, link);
7030 dns_db_detach(&signing->db);
7031 dns_dbiterator_destroy(&signing->dbiterator);
7032 isc_mem_put(zone->mctx, signing, sizeof *signing);
7033 signing = ISC_LIST_HEAD(cleanup);
7036 set_resigntime(zone);
7040 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7041 zone_needdump(zone, DNS_DUMP_DELAY);
7047 * Rollback the cleanup list.
7049 signing = ISC_LIST_HEAD(cleanup);
7050 while (signing != NULL) {
7051 ISC_LIST_UNLINK(cleanup, signing, link);
7052 ISC_LIST_PREPEND(zone->signing, signing, link);
7053 dns_dbiterator_first(signing->dbiterator);
7054 dns_dbiterator_pause(signing->dbiterator);
7055 signing = ISC_LIST_HEAD(cleanup);
7058 for (signing = ISC_LIST_HEAD(zone->signing);
7060 signing = ISC_LIST_NEXT(signing, link))
7061 dns_dbiterator_pause(signing->dbiterator);
7063 dns_diff_clear(&sig_diff);
7065 for (i = 0; i < nkeys; i++)
7066 dst_key_free(&zone_keys[i]);
7069 dns_db_detachnode(db, &node);
7071 if (version != NULL) {
7072 dns_db_closeversion(db, &version, ISC_FALSE);
7074 } else if (db != NULL)
7077 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7079 if (zone->update_disabled || result != ISC_R_SUCCESS)
7080 isc_interval_set(&i, 60, 0); /* 1 minute */
7082 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7083 isc_time_nowplusinterval(&zone->signingtime, &i);
7085 isc_time_settoepoch(&zone->signingtime);
7089 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7090 unsigned char *data, int size) {
7091 dns_rdata_dnskey_t dnskey;
7092 dns_rdata_keydata_t keydata;
7095 dns_rdata_reset(target);
7096 isc_buffer_init(&buf, data, size);
7099 case dns_rdatatype_dnskey:
7100 dns_rdata_tostruct(rr, &dnskey, NULL);
7101 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7102 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7105 case dns_rdatatype_keydata:
7106 dns_rdata_tostruct(rr, &keydata, NULL);
7107 dns_keydata_todnskey(&keydata, &dnskey, NULL);
7108 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7117 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
7118 * a KEYDATA rdataset from the key zone.
7120 * 'rr' contains either a DNSKEY record, or a KEYDATA record
7122 * After normalizing keys to the same format (DNSKEY, with revoke bit
7123 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
7124 * 'rdset', or ISC_FALSE if not.
7127 static isc_boolean_t
7128 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
7129 unsigned char data1[4096], data2[4096];
7130 dns_rdata_t rdata, rdata1, rdata2;
7131 isc_result_t result;
7133 dns_rdata_init(&rdata);
7134 dns_rdata_init(&rdata1);
7135 dns_rdata_init(&rdata2);
7137 normalize_key(rr, &rdata1, data1, sizeof(data1));
7139 for (result = dns_rdataset_first(rdset);
7140 result == ISC_R_SUCCESS;
7141 result = dns_rdataset_next(rdset)) {
7142 dns_rdata_reset(&rdata);
7143 dns_rdataset_current(rdset, &rdata);
7144 normalize_key(&rdata, &rdata2, data2, sizeof(data2));
7145 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
7153 * Calculate the refresh interval for a keydata zone, per
7154 * RFC5011: MAX(1 hr,
7157 * 1/2 * RRSigExpirationInterval))
7158 * or for retries: MAX(1 hr,
7161 * 1/10 * RRSigExpirationInterval))
7163 static inline isc_stdtime_t
7164 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
7165 isc_result_t result;
7167 dns_rdataset_t *rdset;
7168 dns_rdata_t sigrr = DNS_RDATA_INIT;
7169 dns_rdata_sig_t sig;
7172 isc_stdtime_get(&now);
7174 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7175 rdset = &kfetch->dnskeysigset;
7177 return (now + HOUR);
7179 result = dns_rdataset_first(rdset);
7180 if (result != ISC_R_SUCCESS)
7181 return (now + HOUR);
7183 dns_rdataset_current(rdset, &sigrr);
7184 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7185 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7188 t = sig.originalttl / 2;
7190 if (isc_serial_gt(sig.timeexpire, now)) {
7191 isc_uint32_t exp = (sig.timeexpire - now) / 2;
7202 t = sig.originalttl / 10;
7204 if (isc_serial_gt(sig.timeexpire, now)) {
7205 isc_uint32_t exp = (sig.timeexpire - now) / 10;
7221 * This routine is called when no changes are needed in a KEYDATA
7222 * record except to simply update the refresh timer. Caller should
7226 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
7228 isc_result_t result;
7230 unsigned char key_buf[4096];
7231 dns_rdata_t rdata = DNS_RDATA_INIT;
7232 dns_rdata_keydata_t keydata;
7234 dns_zone_t *zone = kfetch->zone;
7237 name = dns_fixedname_name(&kfetch->name);
7238 isc_stdtime_get(&now);
7240 for (result = dns_rdataset_first(&kfetch->keydataset);
7241 result == ISC_R_SUCCESS;
7242 result = dns_rdataset_next(&kfetch->keydataset)) {
7243 dns_rdata_reset(&rdata);
7244 dns_rdataset_current(&kfetch->keydataset, &rdata);
7246 /* Delete old version */
7247 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
7250 /* Update refresh timer */
7251 CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL));
7252 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
7253 set_refreshkeytimer(zone, &keydata, now);
7255 dns_rdata_reset(&rdata);
7256 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7257 CHECK(dns_rdata_fromstruct(&rdata,
7258 zone->rdclass, dns_rdatatype_keydata,
7261 /* Insert updated version */
7262 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
7265 result = ISC_R_SUCCESS;
7271 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
7273 static isc_boolean_t
7274 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
7275 isc_result_t result;
7276 dns_name_t *keyname;
7278 dns_rdata_t sigrr = DNS_RDATA_INIT;
7279 dns_rdata_t rr = DNS_RDATA_INIT;
7280 dns_rdata_rrsig_t sig;
7281 dns_rdata_dnskey_t dnskey;
7282 dst_key_t *dstkey = NULL;
7283 unsigned char key_buf[4096];
7285 isc_boolean_t answer = ISC_FALSE;
7287 REQUIRE(kfetch != NULL && keydata != NULL);
7288 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
7290 keyname = dns_fixedname_name(&kfetch->name);
7291 mctx = kfetch->zone->view->mctx;
7293 /* Generate a key from keydata */
7294 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7295 dns_keydata_todnskey(keydata, &dnskey, NULL);
7296 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
7298 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
7299 if (result != ISC_R_SUCCESS)
7302 /* See if that key generated any of the signatures */
7303 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7304 result == ISC_R_SUCCESS;
7305 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7306 dns_fixedname_t fixed;
7307 dns_fixedname_init(&fixed);
7309 dns_rdata_reset(&sigrr);
7310 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7311 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7312 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7314 if (dst_key_alg(dstkey) == sig.algorithm &&
7315 (dst_key_id(dstkey) == sig.keyid ||
7316 dst_key_rid(dstkey) == sig.keyid)) {
7317 result = dns_dnssec_verify2(keyname,
7319 dstkey, ISC_FALSE, mctx, &sigrr,
7320 dns_fixedname_name(&fixed));
7322 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
7323 "Confirm revoked DNSKEY is self-signed: "
7324 "%s", dns_result_totext(result));
7326 if (result == ISC_R_SUCCESS) {
7333 dst_key_free(&dstkey);
7338 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
7339 * anchors are being managed; scan the keyset, and update the key zone and the
7340 * local trust anchors according to RFC5011.
7343 keyfetch_done(isc_task_t *task, isc_event_t *event) {
7344 isc_result_t result, eresult;
7345 dns_fetchevent_t *devent;
7346 dns_keyfetch_t *kfetch;
7348 isc_mem_t *mctx = NULL;
7349 dns_keytable_t *secroots = NULL;
7350 dns_dbversion_t *ver = NULL;
7352 isc_boolean_t alldone = ISC_FALSE;
7353 isc_boolean_t commit = ISC_FALSE;
7354 dns_name_t *keyname;
7355 dns_rdata_t sigrr = DNS_RDATA_INIT;
7356 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
7357 dns_rdata_t keydatarr = DNS_RDATA_INIT;
7358 dns_rdata_rrsig_t sig;
7359 dns_rdata_dnskey_t dnskey;
7360 dns_rdata_keydata_t keydata;
7361 isc_boolean_t initializing;
7362 char namebuf[DNS_NAME_FORMATSIZE];
7363 unsigned char key_buf[4096];
7368 isc_boolean_t secure;
7369 isc_boolean_t free_needed;
7372 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
7373 INSIST(event->ev_arg != NULL);
7375 kfetch = event->ev_arg;
7376 zone = kfetch->zone;
7377 isc_mem_attach(zone->mctx, &mctx);
7378 keyname = dns_fixedname_name(&kfetch->name);
7380 devent = (dns_fetchevent_t *) event;
7381 eresult = devent->result;
7383 /* Free resources which are not of interest */
7384 if (devent->node != NULL)
7385 dns_db_detachnode(devent->db, &devent->node);
7386 if (devent->db != NULL)
7387 dns_db_detach(&devent->db);
7388 isc_event_free(&event);
7389 dns_resolver_destroyfetch(&kfetch->fetch);
7392 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
7395 isc_stdtime_get(&now);
7396 dns_name_format(keyname, namebuf, sizeof(namebuf));
7398 result = dns_view_getsecroots(zone->view, &secroots);
7399 INSIST(result == ISC_R_SUCCESS);
7401 dns_diff_init(mctx, &diff);
7402 diff.resign = zone->sigresigninginterval;
7404 CHECK(dns_db_newversion(kfetch->db, &ver));
7406 zone->refreshkeycount--;
7407 alldone = ISC_TF(zone->refreshkeycount == 0);
7410 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
7413 if (eresult != ISC_R_SUCCESS ||
7414 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
7415 dns_zone_log(zone, ISC_LOG_WARNING,
7416 "Unable to fetch DNSKEY set "
7417 "'%s': %s", namebuf, dns_result_totext(eresult));
7418 CHECK(minimal_update(kfetch, ver, &diff));
7422 /* No RRSIGs found */
7423 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
7424 dns_zone_log(zone, ISC_LOG_WARNING,
7425 "No DNSKEY RRSIGs found for "
7426 "'%s': %s", namebuf, dns_result_totext(eresult));
7427 CHECK(minimal_update(kfetch, ver, &diff));
7432 * Validate the dnskeyset against the current trusted keys.
7434 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7435 result == ISC_R_SUCCESS;
7436 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7437 dns_keynode_t *keynode = NULL;
7439 dns_rdata_reset(&sigrr);
7440 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7441 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7442 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7444 result = dns_keytable_find(secroots, keyname, &keynode);
7445 while (result == ISC_R_SUCCESS) {
7446 dns_keynode_t *nextnode = NULL;
7447 dns_fixedname_t fixed;
7448 dns_fixedname_init(&fixed);
7450 dstkey = dns_keynode_key(keynode);
7451 if (dstkey == NULL) /* fail_secure() was called */
7454 if (dst_key_alg(dstkey) == sig.algorithm &&
7455 dst_key_id(dstkey) == sig.keyid) {
7456 result = dns_dnssec_verify2(keyname,
7459 zone->view->mctx, &sigrr,
7460 dns_fixedname_name(&fixed));
7462 dns_zone_log(zone, ISC_LOG_DEBUG(3),
7463 "Verifying DNSKEY set for zone "
7464 "'%s': %s", namebuf,
7465 dns_result_totext(result));
7467 if (result == ISC_R_SUCCESS) {
7468 kfetch->dnskeyset.trust =
7470 kfetch->dnskeysigset.trust =
7472 dns_keytable_detachkeynode(secroots,
7478 result = dns_keytable_nextkeynode(secroots,
7479 keynode, &nextnode);
7480 dns_keytable_detachkeynode(secroots, &keynode);
7484 if (kfetch->dnskeyset.trust == dns_trust_secure)
7489 * If we were not able to verify the answer using the current
7490 * trusted keys then all we can do is look at any revoked keys.
7492 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
7495 * First scan keydataset to find keys that are not in dnskeyset
7496 * - Missing keys which are not scheduled for removal,
7498 * - Missing keys which are scheduled for removal and
7499 * the remove hold-down timer has completed should
7500 * be removed from the key zone
7501 * - Missing keys whose acceptance timers have not yet
7502 * completed, log a warning and reset the acceptance
7503 * timer to 30 days in the future
7504 * - All keys not being removed have their refresh timers
7507 initializing = ISC_TRUE;
7508 for (result = dns_rdataset_first(&kfetch->keydataset);
7509 result == ISC_R_SUCCESS;
7510 result = dns_rdataset_next(&kfetch->keydataset)) {
7511 dns_rdata_reset(&keydatarr);
7512 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7513 dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7516 * If any keydata record has a nonzero add holddown, then
7517 * there was a pre-existing trust anchor for this domain;
7518 * that means we are *not* initializing it and shouldn't
7519 * automatically trust all the keys we find at the zone apex.
7521 initializing = initializing && ISC_TF(keydata.addhd == 0);
7523 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
7524 isc_boolean_t deletekey = ISC_FALSE;
7527 if (now > keydata.removehd)
7528 deletekey = ISC_TRUE;
7529 } else if (now < keydata.addhd) {
7530 dns_zone_log(zone, ISC_LOG_WARNING,
7531 "Pending key unexpectedly missing "
7532 "from %s; restarting acceptance "
7534 keydata.addhd = now + MONTH;
7535 keydata.refresh = refresh_time(kfetch,
7537 } else if (keydata.addhd == 0) {
7538 keydata.addhd = now;
7539 } else if (keydata.removehd == 0) {
7540 dns_zone_log(zone, ISC_LOG_WARNING,
7541 "Active key unexpectedly missing "
7542 "from %s", namebuf);
7543 keydata.refresh = now + HOUR;
7544 } else if (now > keydata.removehd) {
7545 deletekey = ISC_TRUE;
7547 keydata.refresh = refresh_time(kfetch,
7551 if (secure || deletekey) {
7552 /* Delete old version */
7553 CHECK(update_one_rr(kfetch->db, ver, &diff,
7554 DNS_DIFFOP_DEL, keyname, 0,
7558 if (!secure || deletekey)
7561 dns_rdata_reset(&keydatarr);
7562 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7563 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7564 dns_rdatatype_keydata,
7567 /* Insert updated version */
7568 CHECK(update_one_rr(kfetch->db, ver, &diff,
7569 DNS_DIFFOP_ADD, keyname, 0,
7572 set_refreshkeytimer(zone, &keydata, now);
7577 * Next scan dnskeyset:
7578 * - If new keys are found (i.e., lacking a match in keydataset)
7579 * add them to the key zone and set the acceptance timer
7580 * to 30 days in the future (or to immediately if we've
7581 * determined that we're initializing the zone for the
7583 * - Previously-known keys that have been revoked
7584 * must be scheduled for removal from the key zone (or,
7585 * if they hadn't been accepted as trust anchors yet
7586 * anyway, removed at once)
7587 * - Previously-known unrevoked keys whose acceptance timers
7588 * have completed are promoted to trust anchors
7589 * - All keys not being removed have their refresh
7592 for (result = dns_rdataset_first(&kfetch->dnskeyset);
7593 result == ISC_R_SUCCESS;
7594 result = dns_rdataset_next(&kfetch->dnskeyset)) {
7595 isc_boolean_t revoked = ISC_FALSE;
7596 isc_boolean_t newkey = ISC_FALSE;
7597 isc_boolean_t updatekey = ISC_FALSE;
7598 isc_boolean_t deletekey = ISC_FALSE;
7599 isc_boolean_t trustkey = ISC_FALSE;
7601 dns_rdata_reset(&dnskeyrr);
7602 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
7603 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7606 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
7609 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
7611 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
7612 dns_rdata_reset(&keydatarr);
7613 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7614 dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7616 if (revoked && revocable(kfetch, &keydata)) {
7617 if (keydata.addhd > now) {
7619 * Key wasn't trusted yet, and now
7620 * it's been revoked? Just remove it
7622 deletekey = ISC_TRUE;
7623 } else if (keydata.removehd == 0) {
7624 /* Remove from secroots */
7625 dns_view_untrust(zone->view, keyname,
7628 /* If initializing, delete now */
7629 if (keydata.addhd == 0)
7630 deletekey = ISC_TRUE;
7632 keydata.removehd = now + MONTH;
7633 } else if (keydata.removehd < now) {
7634 /* Scheduled for removal */
7635 deletekey = ISC_TRUE;
7637 } else if (revoked) {
7638 if (secure && keydata.removehd == 0) {
7639 dns_zone_log(zone, ISC_LOG_WARNING,
7640 "Active key for zone "
7641 "'%s' is revoked but "
7642 "did not self-sign; "
7643 "ignoring.", namebuf);
7646 } else if (secure) {
7647 if (keydata.removehd != 0) {
7649 * Key isn't revoked--but it
7650 * seems it used to be.
7651 * Remove it now and add it
7652 * back as if it were a fresh key.
7654 deletekey = ISC_TRUE;
7656 } else if (keydata.addhd > now)
7658 else if (keydata.addhd == 0)
7659 keydata.addhd = now;
7661 if (keydata.addhd <= now)
7662 trustkey = ISC_TRUE;
7665 if (!deletekey && !newkey)
7666 updatekey = ISC_TRUE;
7667 } else if (secure) {
7669 * Key wasn't in the key zone but it's
7670 * revoked now anyway, so just skip it
7675 /* Key wasn't in the key zone: add it */
7679 dns_keytag_t tag = 0;
7680 CHECK(compute_tag(keyname, &dnskey,
7682 dns_zone_log(zone, ISC_LOG_WARNING,
7683 "Initializing automatic trust "
7684 "anchor management for zone '%s'; "
7685 "DNSKEY ID %d is now trusted, "
7686 "waiving the normal 30-day "
7689 trustkey = ISC_TRUE;
7693 /* Delete old version */
7694 if (deletekey || !newkey)
7695 CHECK(update_one_rr(kfetch->db, ver, &diff,
7696 DNS_DIFFOP_DEL, keyname, 0,
7700 /* Set refresh timer */
7701 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7702 dns_rdata_reset(&keydatarr);
7703 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7704 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7705 dns_rdatatype_keydata,
7708 /* Insert updated version */
7709 CHECK(update_one_rr(kfetch->db, ver, &diff,
7710 DNS_DIFFOP_ADD, keyname, 0,
7712 } else if (newkey) {
7713 /* Convert DNSKEY to KEYDATA */
7714 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7715 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
7717 keydata.addhd = initializing ? now : now + MONTH;
7718 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7719 dns_rdata_reset(&keydatarr);
7720 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7721 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7722 dns_rdatatype_keydata,
7725 /* Insert into key zone */
7726 CHECK(update_one_rr(kfetch->db, ver, &diff,
7727 DNS_DIFFOP_ADD, keyname, 0,
7732 /* Trust this key. */
7733 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7734 trust_key(zone, keyname, &dnskey, mctx);
7738 set_refreshkeytimer(zone, &keydata, now);
7742 * RFC5011 says, "A trust point that has all of its trust anchors
7743 * revoked is considered deleted and is treated as if the trust
7744 * point was never configured." But if someone revoked their
7745 * active key before the standby was trusted, that would mean the
7746 * zone would suddenly be nonsecured. We avoid this by checking to
7747 * see if there's pending keydata. If so, we put a null key in
7748 * the security roots; then all queries to the zone will fail.
7751 fail_secure(zone, keyname);
7755 if (!ISC_LIST_EMPTY(diff.tuples)) {
7756 /* Write changes to journal file. */
7757 CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx));
7758 CHECK(zone_journal(zone, &diff, "keyfetch_done"));
7761 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
7762 zone_needdump(zone, 30);
7767 dns_diff_clear(&diff);
7769 dns_db_closeversion(kfetch->db, &ver, commit);
7772 dns_db_detach(&kfetch->db);
7774 INSIST(zone->irefs > 0);
7776 kfetch->zone = NULL;
7778 if (dns_rdataset_isassociated(&kfetch->keydataset))
7779 dns_rdataset_disassociate(&kfetch->keydataset);
7780 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
7781 dns_rdataset_disassociate(&kfetch->dnskeyset);
7782 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7783 dns_rdataset_disassociate(&kfetch->dnskeysigset);
7785 dns_name_free(keyname, mctx);
7786 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
7787 isc_mem_detach(&mctx);
7789 if (secroots != NULL)
7790 dns_keytable_detach(&secroots);
7792 free_needed = exit_check(zone);
7799 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
7800 * records from the zone apex.
7803 zone_refreshkeys(dns_zone_t *zone) {
7804 const char me[] = "zone_refreshkeys";
7805 isc_result_t result;
7806 dns_rriterator_t rrit;
7807 dns_db_t *db = NULL;
7808 dns_dbversion_t *ver = NULL;
7810 dns_rdata_t rdata = DNS_RDATA_INIT;
7811 dns_rdata_keydata_t kd;
7813 isc_boolean_t commit = ISC_FALSE;
7814 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
7817 REQUIRE(zone->db != NULL);
7819 isc_stdtime_get(&now);
7822 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7823 isc_time_settoepoch(&zone->refreshkeytime);
7828 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7829 dns_db_attach(zone->db, &db);
7830 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7832 dns_diff_init(zone->mctx, &diff);
7834 CHECK(dns_db_newversion(db, &ver));
7836 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
7838 dns_rriterator_init(&rrit, db, ver, 0);
7839 for (result = dns_rriterator_first(&rrit);
7840 result == ISC_R_SUCCESS;
7841 result = dns_rriterator_nextrrset(&rrit)) {
7842 isc_stdtime_t timer = 0xffffffff;
7843 dns_name_t *name = NULL, *kname = NULL;
7844 dns_rdataset_t *kdset = NULL;
7845 dns_keyfetch_t *kfetch;
7848 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
7849 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
7850 !dns_rdataset_isassociated(kdset))
7854 * Scan the stored keys looking for ones that need
7855 * removal or refreshing
7857 for (result = dns_rdataset_first(kdset);
7858 result == ISC_R_SUCCESS;
7859 result = dns_rdataset_next(kdset)) {
7860 dns_rdata_reset(&rdata);
7861 dns_rdataset_current(kdset, &rdata);
7862 result = dns_rdata_tostruct(&rdata, &kd, NULL);
7863 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7865 /* Removal timer expired? */
7866 if (kd.removehd != 0 && kd.removehd < now) {
7867 CHECK(update_one_rr(db, ver, &diff,
7868 DNS_DIFFOP_DEL, name, ttl,
7873 /* Acceptance timer expired? */
7874 if (kd.addhd != 0 && kd.addhd < now)
7877 /* Or do we just need to refresh the keyset? */
7878 if (timer > kd.refresh)
7885 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
7886 if (kfetch == NULL) {
7887 fetch_err = ISC_TRUE;
7891 zone->refreshkeycount++;
7892 kfetch->zone = zone;
7894 INSIST(zone->irefs != 0);
7895 dns_fixedname_init(&kfetch->name);
7896 kname = dns_fixedname_name(&kfetch->name);
7897 dns_name_dup(name, zone->mctx, kname);
7898 dns_rdataset_init(&kfetch->dnskeyset);
7899 dns_rdataset_init(&kfetch->dnskeysigset);
7900 dns_rdataset_init(&kfetch->keydataset);
7901 dns_rdataset_clone(kdset, &kfetch->keydataset);
7903 dns_db_attach(db, &kfetch->db);
7904 kfetch->fetch = NULL;
7906 result = dns_resolver_createfetch(zone->view->resolver,
7907 kname, dns_rdatatype_dnskey,
7909 DNS_FETCHOPT_NOVALIDATE,
7911 keyfetch_done, kfetch,
7913 &kfetch->dnskeysigset,
7915 if (result == ISC_R_SUCCESS)
7916 fetching = ISC_TRUE;
7918 zone->refreshkeycount--;
7920 dns_db_detach(&kfetch->db);
7921 dns_rdataset_disassociate(&kfetch->keydataset);
7922 dns_name_free(kname, zone->mctx);
7923 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
7924 dns_zone_log(zone, ISC_LOG_WARNING,
7925 "Failed to create fetch for "
7927 fetch_err = ISC_TRUE;
7930 if (!ISC_LIST_EMPTY(diff.tuples)) {
7931 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
7932 CHECK(zone_journal(zone, &diff, "zone_refreshkeys"));
7934 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
7935 zone_needdump(zone, 30);
7941 * Error during a key fetch; retry in an hour.
7943 isc_time_t timenow, timethen;
7947 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
7948 zone->refreshkeytime = timethen;
7949 zone_settimer(zone, &timenow);
7951 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
7952 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
7956 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
7961 dns_diff_clear(&diff);
7963 dns_rriterator_destroy(&rrit);
7964 dns_db_closeversion(db, &ver, commit);
7970 zone_maintenance(dns_zone_t *zone) {
7971 const char me[] = "zone_maintenance";
7973 isc_result_t result;
7974 isc_boolean_t dumping;
7976 REQUIRE(DNS_ZONE_VALID(zone));
7980 * Configuring the view of this zone may have
7981 * failed, for example because the config file
7982 * had a syntax error. In that case, the view
7983 * db or resolver will be NULL, and we had better not try
7984 * to do maintenance on it.
7986 if (zone->view == NULL || zone->view->adb == NULL)
7994 switch (zone->type) {
7995 case dns_zone_slave:
7998 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
7999 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8001 zone->refreshtime = now;
8012 switch (zone->type) {
8013 case dns_zone_slave:
8015 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8016 isc_time_compare(&now, &zone->refreshtime) >= 0)
8017 dns_zone_refresh(zone);
8024 * Do we need to consolidate the backing store?
8026 switch (zone->type) {
8027 case dns_zone_master:
8028 case dns_zone_slave:
8032 if (zone->masterfile != NULL &&
8033 isc_time_compare(&now, &zone->dumptime) >= 0 &&
8034 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8035 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
8036 dumping = was_dumping(zone);
8041 result = zone_dump(zone, ISC_TRUE); /* task locked */
8042 if (result != ISC_R_SUCCESS)
8043 dns_zone_log(zone, ISC_LOG_WARNING,
8045 dns_result_totext(result));
8053 * Do we need to refresh keys?
8055 switch (zone->type) {
8057 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
8058 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8059 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
8060 zone_refreshkeys(zone);
8062 case dns_zone_master:
8063 if (!isc_time_isepoch(&zone->refreshkeytime) &&
8064 isc_time_compare(&now, &zone->refreshkeytime) >= 0)
8070 switch (zone->type) {
8071 case dns_zone_master:
8072 case dns_zone_slave:
8074 * Do we need to send out notify messages?
8076 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8077 isc_time_compare(&now, &zone->notifytime) >= 0)
8078 zone_notify(zone, &now);
8080 * Do we need to sign/resign some RRsets?
8082 if (!isc_time_isepoch(&zone->signingtime) &&
8083 isc_time_compare(&now, &zone->signingtime) >= 0)
8085 else if (!isc_time_isepoch(&zone->resigntime) &&
8086 isc_time_compare(&now, &zone->resigntime) >= 0)
8087 zone_resigninc(zone);
8088 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
8089 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
8090 zone_nsec3chain(zone);
8092 * Do we need to issue a key expiry warning.
8094 if (!isc_time_isepoch(&zone->keywarntime) &&
8095 isc_time_compare(&now, &zone->keywarntime) >= 0)
8096 set_key_expiry_warning(zone, zone->key_expiry,
8097 isc_time_seconds(&now));
8102 zone_settimer(zone, &now);
8106 dns_zone_markdirty(dns_zone_t *zone) {
8109 if (zone->type == dns_zone_master)
8110 set_resigntime(zone); /* XXXMPA make separate call back */
8111 zone_needdump(zone, DNS_DUMP_DELAY);
8116 dns_zone_expire(dns_zone_t *zone) {
8117 REQUIRE(DNS_ZONE_VALID(zone));
8125 zone_expire(dns_zone_t *zone) {
8127 * 'zone' locked by caller.
8130 REQUIRE(LOCKED_ZONE(zone));
8132 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
8134 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
8135 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
8136 zone->retry = DNS_ZONE_DEFAULTRETRY;
8137 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
8142 dns_zone_refresh(dns_zone_t *zone) {
8144 isc_uint32_t oldflags;
8146 isc_result_t result;
8148 REQUIRE(DNS_ZONE_VALID(zone));
8150 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8154 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
8155 * in progress at a time.
8159 oldflags = zone->flags;
8160 if (zone->masterscnt == 0) {
8161 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
8162 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
8163 dns_zone_log(zone, ISC_LOG_ERROR,
8164 "cannot refresh: no masters");
8167 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
8168 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
8169 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
8170 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
8174 * Set the next refresh time as if refresh check has failed.
8175 * Setting this to the retry time will do that. XXXMLG
8176 * If we are successful it will be reset using zone->refresh.
8178 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
8180 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
8181 if (result != ISC_R_SUCCESS)
8182 dns_zone_log(zone, ISC_LOG_WARNING,
8183 "isc_time_nowplusinterval() failed: %s",
8184 dns_result_totext(result));
8187 * When lacking user-specified timer values from the SOA,
8188 * do exponential backoff of the retry time up to a
8189 * maximum of six hours.
8191 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
8192 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
8194 zone->curmaster = 0;
8195 for (j = 0; j < zone->masterscnt; j++)
8196 zone->mastersok[j] = ISC_FALSE;
8197 /* initiate soa query */
8198 queue_soa_query(zone);
8204 dns_zone_flush(dns_zone_t *zone) {
8205 isc_result_t result = ISC_R_SUCCESS;
8206 isc_boolean_t dumping;
8208 REQUIRE(DNS_ZONE_VALID(zone));
8211 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
8212 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8213 zone->masterfile != NULL) {
8214 result = ISC_R_ALREADYRUNNING;
8215 dumping = was_dumping(zone);
8220 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8225 dns_zone_dump(dns_zone_t *zone) {
8226 isc_result_t result = ISC_R_ALREADYRUNNING;
8227 isc_boolean_t dumping;
8229 REQUIRE(DNS_ZONE_VALID(zone));
8232 dumping = was_dumping(zone);
8235 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8240 zone_needdump(dns_zone_t *zone, unsigned int delay) {
8241 isc_time_t dumptime;
8245 * 'zone' locked by caller
8248 REQUIRE(DNS_ZONE_VALID(zone));
8249 REQUIRE(LOCKED_ZONE(zone));
8252 * Do we have a place to dump to and are we loaded?
8254 if (zone->masterfile == NULL ||
8255 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
8259 /* add some noise */
8260 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
8262 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8263 if (isc_time_isepoch(&zone->dumptime) ||
8264 isc_time_compare(&zone->dumptime, &dumptime) > 0)
8265 zone->dumptime = dumptime;
8266 if (zone->task != NULL)
8267 zone_settimer(zone, &now);
8271 dump_done(void *arg, isc_result_t result) {
8272 const char me[] = "dump_done";
8273 dns_zone_t *zone = arg;
8275 dns_dbversion_t *version;
8276 isc_boolean_t again = ISC_FALSE;
8277 isc_boolean_t compact = ISC_FALSE;
8278 isc_uint32_t serial;
8279 isc_result_t tresult;
8281 REQUIRE(DNS_ZONE_VALID(zone));
8285 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
8286 zone->journalsize != -1) {
8289 * We don't own these, zone->dctx must stay valid.
8291 db = dns_dumpctx_db(zone->dctx);
8292 version = dns_dumpctx_version(zone->dctx);
8294 tresult = dns_db_getsoaserial(db, version, &serial);
8296 * Note: we are task locked here so we can test
8299 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
8300 tresult = dns_journal_compact(zone->mctx,
8307 case ISC_R_NOTFOUND:
8308 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8309 "dns_journal_compact: %s",
8310 dns_result_totext(tresult));
8313 dns_zone_log(zone, ISC_LOG_ERROR,
8314 "dns_journal_compact failed: %s",
8315 dns_result_totext(tresult));
8318 } else if (tresult == ISC_R_SUCCESS) {
8320 zone->compact_serial = serial;
8325 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8327 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
8328 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
8330 * Try again in a short while.
8332 zone_needdump(zone, DNS_DUMP_DELAY);
8333 } else if (result == ISC_R_SUCCESS &&
8334 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8335 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8336 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8337 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8338 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8339 isc_time_settoepoch(&zone->dumptime);
8341 } else if (result == ISC_R_SUCCESS)
8342 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8344 if (zone->dctx != NULL)
8345 dns_dumpctx_detach(&zone->dctx);
8346 zonemgr_putio(&zone->writeio);
8349 (void)zone_dump(zone, ISC_FALSE);
8350 dns_zone_idetach(&zone);
8354 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
8355 const char me[] = "zone_dump";
8356 isc_result_t result;
8357 dns_dbversion_t *version = NULL;
8358 isc_boolean_t again;
8359 dns_db_t *db = NULL;
8360 char *masterfile = NULL;
8361 dns_masterformat_t masterformat = dns_masterformat_none;
8364 * 'compact' MUST only be set if we are task locked.
8367 REQUIRE(DNS_ZONE_VALID(zone));
8371 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8372 if (zone->db != NULL)
8373 dns_db_attach(zone->db, &db);
8374 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8376 if (zone->masterfile != NULL) {
8377 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
8378 masterformat = zone->masterformat;
8382 result = DNS_R_NOTLOADED;
8385 if (masterfile == NULL) {
8386 result = DNS_R_NOMASTERFILE;
8390 if (compact && zone->type != dns_zone_stub) {
8391 dns_zone_t *dummy = NULL;
8393 zone_iattach(zone, &dummy);
8394 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
8395 zone_gotwritehandle, zone,
8397 if (result != ISC_R_SUCCESS)
8398 zone_idetach(&dummy);
8400 result = DNS_R_CONTINUE;
8403 dns_db_currentversion(db, &version);
8404 result = dns_master_dump2(zone->mctx, db, version,
8405 &dns_master_style_default,
8406 masterfile, masterformat);
8407 dns_db_closeversion(db, &version, ISC_FALSE);
8412 if (masterfile != NULL)
8413 isc_mem_free(zone->mctx, masterfile);
8416 if (result == DNS_R_CONTINUE)
8417 return (ISC_R_SUCCESS); /* XXXMPA */
8421 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8422 if (result != ISC_R_SUCCESS) {
8424 * Try again in a short while.
8426 zone_needdump(zone, DNS_DUMP_DELAY);
8427 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8428 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8429 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8430 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8431 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8432 isc_time_settoepoch(&zone->dumptime);
8435 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8444 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
8445 dns_masterformat_t format)
8447 isc_result_t result;
8448 dns_dbversion_t *version = NULL;
8449 dns_db_t *db = NULL;
8451 REQUIRE(DNS_ZONE_VALID(zone));
8453 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8454 if (zone->db != NULL)
8455 dns_db_attach(zone->db, &db);
8456 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8458 return (DNS_R_NOTLOADED);
8460 dns_db_currentversion(db, &version);
8461 result = dns_master_dumptostream2(zone->mctx, db, version, style,
8463 dns_db_closeversion(db, &version, ISC_FALSE);
8469 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
8470 const dns_master_style_t *style) {
8471 return dumptostream(zone, fd, style, format);
8475 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
8476 return dumptostream(zone, fd, &dns_master_style_default,
8477 dns_masterformat_text);
8481 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
8482 return dumptostream(zone, fd, &dns_master_style_full,
8483 dns_masterformat_text);
8487 dns_zone_unload(dns_zone_t *zone) {
8488 REQUIRE(DNS_ZONE_VALID(zone));
8496 notify_cancel(dns_zone_t *zone) {
8497 dns_notify_t *notify;
8500 * 'zone' locked by caller.
8503 REQUIRE(LOCKED_ZONE(zone));
8505 for (notify = ISC_LIST_HEAD(zone->notifies);
8507 notify = ISC_LIST_NEXT(notify, link)) {
8508 if (notify->find != NULL)
8509 dns_adb_cancelfind(notify->find);
8510 if (notify->request != NULL)
8511 dns_request_cancel(notify->request);
8516 forward_cancel(dns_zone_t *zone) {
8517 dns_forward_t *forward;
8520 * 'zone' locked by caller.
8523 REQUIRE(LOCKED_ZONE(zone));
8525 for (forward = ISC_LIST_HEAD(zone->forwards);
8527 forward = ISC_LIST_NEXT(forward, link)) {
8528 if (forward->request != NULL)
8529 dns_request_cancel(forward->request);
8534 zone_unload(dns_zone_t *zone) {
8537 * 'zone' locked by caller.
8540 REQUIRE(LOCKED_ZONE(zone));
8542 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8543 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8544 if (zone->writeio != NULL)
8545 zonemgr_cancelio(zone->writeio);
8547 if (zone->dctx != NULL)
8548 dns_dumpctx_cancel(zone->dctx);
8550 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
8551 zone_detachdb(zone);
8552 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
8553 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
8554 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8558 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8559 REQUIRE(DNS_ZONE_VALID(zone));
8562 zone->minrefresh = val;
8566 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8567 REQUIRE(DNS_ZONE_VALID(zone));
8570 zone->maxrefresh = val;
8574 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
8575 REQUIRE(DNS_ZONE_VALID(zone));
8578 zone->minretry = val;
8582 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
8583 REQUIRE(DNS_ZONE_VALID(zone));
8586 zone->maxretry = val;
8589 static isc_boolean_t
8590 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
8591 dns_notify_t *notify;
8593 for (notify = ISC_LIST_HEAD(zone->notifies);
8595 notify = ISC_LIST_NEXT(notify, link)) {
8596 if (notify->request != NULL)
8598 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
8599 dns_name_equal(name, ¬ify->ns))
8601 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
8607 static isc_boolean_t
8608 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
8609 dns_tsigkey_t *key = NULL;
8612 isc_boolean_t isself;
8613 isc_netaddr_t dstaddr;
8614 isc_result_t result;
8616 if (zone->view == NULL || zone->isself == NULL)
8619 switch (isc_sockaddr_pf(dst)) {
8621 src = zone->notifysrc4;
8622 isc_sockaddr_any(&any);
8625 src = zone->notifysrc6;
8626 isc_sockaddr_any6(&any);
8633 * When sending from any the kernel will assign a source address
8634 * that matches the destination address.
8636 if (isc_sockaddr_eqaddr(&any, &src))
8639 isc_netaddr_fromsockaddr(&dstaddr, dst);
8640 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
8641 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
8643 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
8646 dns_tsigkey_detach(&key);
8651 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
8655 * Caller holds zone lock.
8657 REQUIRE(DNS_NOTIFY_VALID(notify));
8659 if (notify->zone != NULL) {
8661 LOCK_ZONE(notify->zone);
8662 REQUIRE(LOCKED_ZONE(notify->zone));
8663 if (ISC_LINK_LINKED(notify, link))
8664 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
8666 UNLOCK_ZONE(notify->zone);
8668 zone_idetach(¬ify->zone);
8670 dns_zone_idetach(¬ify->zone);
8672 if (notify->find != NULL)
8673 dns_adb_destroyfind(¬ify->find);
8674 if (notify->request != NULL)
8675 dns_request_destroy(¬ify->request);
8676 if (dns_name_dynamic(¬ify->ns))
8677 dns_name_free(¬ify->ns, notify->mctx);
8678 mctx = notify->mctx;
8679 isc_mem_put(notify->mctx, notify, sizeof(*notify));
8680 isc_mem_detach(&mctx);
8684 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
8685 dns_notify_t *notify;
8687 REQUIRE(notifyp != NULL && *notifyp == NULL);
8689 notify = isc_mem_get(mctx, sizeof(*notify));
8691 return (ISC_R_NOMEMORY);
8693 notify->mctx = NULL;
8694 isc_mem_attach(mctx, ¬ify->mctx);
8695 notify->flags = flags;
8696 notify->zone = NULL;
8697 notify->find = NULL;
8698 notify->request = NULL;
8699 isc_sockaddr_any(¬ify->dst);
8700 dns_name_init(¬ify->ns, NULL);
8701 ISC_LINK_INIT(notify, link);
8702 notify->magic = NOTIFY_MAGIC;
8704 return (ISC_R_SUCCESS);
8708 * XXXAG should check for DNS_ZONEFLG_EXITING
8711 process_adb_event(isc_task_t *task, isc_event_t *ev) {
8712 dns_notify_t *notify;
8713 isc_eventtype_t result;
8717 notify = ev->ev_arg;
8718 REQUIRE(DNS_NOTIFY_VALID(notify));
8719 INSIST(task == notify->zone->task);
8720 result = ev->ev_type;
8721 isc_event_free(&ev);
8722 if (result == DNS_EVENT_ADBMOREADDRESSES) {
8723 dns_adb_destroyfind(¬ify->find);
8724 notify_find_address(notify);
8727 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
8728 LOCK_ZONE(notify->zone);
8729 notify_send(notify);
8730 UNLOCK_ZONE(notify->zone);
8732 notify_destroy(notify, ISC_FALSE);
8736 notify_find_address(dns_notify_t *notify) {
8737 isc_result_t result;
8738 unsigned int options;
8740 REQUIRE(DNS_NOTIFY_VALID(notify));
8741 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
8742 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
8744 if (notify->zone->view->adb == NULL)
8747 result = dns_adb_createfind(notify->zone->view->adb,
8749 process_adb_event, notify,
8750 ¬ify->ns, dns_rootname, 0,
8752 notify->zone->view->dstport,
8755 /* Something failed? */
8756 if (result != ISC_R_SUCCESS)
8759 /* More addresses pending? */
8760 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
8763 /* We have as many addresses as we can get. */
8764 LOCK_ZONE(notify->zone);
8765 notify_send(notify);
8766 UNLOCK_ZONE(notify->zone);
8769 notify_destroy(notify, ISC_FALSE);
8774 notify_send_queue(dns_notify_t *notify) {
8776 isc_result_t result;
8778 e = isc_event_allocate(notify->mctx, NULL,
8779 DNS_EVENT_NOTIFYSENDTOADDR,
8781 notify, sizeof(isc_event_t));
8783 return (ISC_R_NOMEMORY);
8785 e->ev_sender = NULL;
8786 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
8787 notify->zone->task, &e);
8788 if (result != ISC_R_SUCCESS)
8794 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
8795 dns_notify_t *notify;
8796 isc_result_t result;
8797 dns_message_t *message = NULL;
8798 isc_netaddr_t dstip;
8799 dns_tsigkey_t *key = NULL;
8800 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
8803 isc_boolean_t have_notifysource = ISC_FALSE;
8805 notify = event->ev_arg;
8806 REQUIRE(DNS_NOTIFY_VALID(notify));
8810 LOCK_ZONE(notify->zone);
8812 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
8813 result = ISC_R_CANCELED;
8817 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
8818 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
8819 notify->zone->view->requestmgr == NULL ||
8820 notify->zone->db == NULL) {
8821 result = ISC_R_CANCELED;
8826 * The raw IPv4 address should also exist. Don't send to the
8829 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
8830 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
8831 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
8832 notify_log(notify->zone, ISC_LOG_DEBUG(3),
8833 "notify: ignoring IPv6 mapped IPV4 address: %s",
8835 result = ISC_R_CANCELED;
8839 result = notify_createmessage(notify->zone, notify->flags, &message);
8840 if (result != ISC_R_SUCCESS)
8843 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
8844 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
8845 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
8846 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8847 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
8848 "sent. Peer TSIG key lookup failure.", addrbuf);
8849 goto cleanup_message;
8852 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
8854 if (notify->zone->view->peers != NULL) {
8855 dns_peer_t *peer = NULL;
8856 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
8858 if (result == ISC_R_SUCCESS) {
8859 result = dns_peer_getnotifysource(peer, &src);
8860 if (result == ISC_R_SUCCESS)
8861 have_notifysource = ISC_TRUE;
8864 switch (isc_sockaddr_pf(¬ify->dst)) {
8866 if (!have_notifysource)
8867 src = notify->zone->notifysrc4;
8870 if (!have_notifysource)
8871 src = notify->zone->notifysrc6;
8874 result = ISC_R_NOTIMPLEMENTED;
8878 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
8880 result = dns_request_createvia2(notify->zone->view->requestmgr,
8881 message, &src, ¬ify->dst, 0, key,
8882 timeout * 3, timeout,
8883 notify->zone->task, notify_done,
8884 notify, ¬ify->request);
8885 if (result == ISC_R_SUCCESS) {
8886 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
8887 inc_stats(notify->zone,
8888 dns_zonestatscounter_notifyoutv4);
8890 inc_stats(notify->zone,
8891 dns_zonestatscounter_notifyoutv6);
8897 dns_tsigkey_detach(&key);
8899 dns_message_destroy(&message);
8901 UNLOCK_ZONE(notify->zone);
8902 if (result != ISC_R_SUCCESS)
8903 notify_destroy(notify, ISC_FALSE);
8904 isc_event_free(&event);
8908 notify_send(dns_notify_t *notify) {
8909 dns_adbaddrinfo_t *ai;
8911 isc_result_t result;
8912 dns_notify_t *new = NULL;
8915 * Zone lock held by caller.
8917 REQUIRE(DNS_NOTIFY_VALID(notify));
8918 REQUIRE(LOCKED_ZONE(notify->zone));
8920 for (ai = ISC_LIST_HEAD(notify->find->list);
8922 ai = ISC_LIST_NEXT(ai, publink)) {
8924 if (notify_isqueued(notify->zone, NULL, &dst))
8926 if (notify_isself(notify->zone, &dst))
8929 result = notify_create(notify->mctx,
8930 (notify->flags & DNS_NOTIFY_NOSOA),
8932 if (result != ISC_R_SUCCESS)
8934 zone_iattach(notify->zone, &new->zone);
8935 ISC_LIST_APPEND(new->zone->notifies, new, link);
8937 result = notify_send_queue(new);
8938 if (result != ISC_R_SUCCESS)
8945 notify_destroy(new, ISC_TRUE);
8949 dns_zone_notify(dns_zone_t *zone) {
8952 REQUIRE(DNS_ZONE_VALID(zone));
8955 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8958 zone_settimer(zone, &now);
8963 zone_notify(dns_zone_t *zone, isc_time_t *now) {
8964 dns_dbnode_t *node = NULL;
8965 dns_db_t *zonedb = NULL;
8966 dns_dbversion_t *version = NULL;
8967 dns_name_t *origin = NULL;
8970 dns_rdata_soa_t soa;
8971 isc_uint32_t serial;
8972 dns_rdata_t rdata = DNS_RDATA_INIT;
8973 dns_rdataset_t nsrdset;
8974 dns_rdataset_t soardset;
8975 isc_result_t result;
8976 dns_notify_t *notify = NULL;
8979 isc_boolean_t isqueued;
8980 dns_notifytype_t notifytype;
8981 unsigned int flags = 0;
8982 isc_boolean_t loggednotify = ISC_FALSE;
8984 REQUIRE(DNS_ZONE_VALID(zone));
8987 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8988 notifytype = zone->notifytype;
8989 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
8992 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
8995 if (notifytype == dns_notifytype_no)
8998 if (notifytype == dns_notifytype_masteronly &&
8999 zone->type != dns_zone_master)
9002 origin = &zone->origin;
9005 * If the zone is dialup we are done as we don't want to send
9006 * the current soa so as to force a refresh query.
9008 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
9009 flags |= DNS_NOTIFY_NOSOA;
9014 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9015 if (zone->db != NULL)
9016 dns_db_attach(zone->db, &zonedb);
9017 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9020 dns_db_currentversion(zonedb, &version);
9021 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
9022 if (result != ISC_R_SUCCESS)
9025 dns_rdataset_init(&soardset);
9026 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
9027 dns_rdatatype_none, 0, &soardset, NULL);
9028 if (result != ISC_R_SUCCESS)
9032 * Find serial and master server's name.
9034 dns_name_init(&master, NULL);
9035 result = dns_rdataset_first(&soardset);
9036 if (result != ISC_R_SUCCESS)
9038 dns_rdataset_current(&soardset, &rdata);
9039 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9040 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9041 dns_rdata_reset(&rdata);
9042 result = dns_name_dup(&soa.origin, zone->mctx, &master);
9043 serial = soa.serial;
9044 dns_rdataset_disassociate(&soardset);
9045 if (result != ISC_R_SUCCESS)
9049 * Enqueue notify requests for 'also-notify' servers.
9052 for (i = 0; i < zone->notifycnt; i++) {
9053 dst = zone->notify[i];
9054 if (notify_isqueued(zone, NULL, &dst))
9056 result = notify_create(zone->mctx, flags, ¬ify);
9057 if (result != ISC_R_SUCCESS)
9059 zone_iattach(zone, ¬ify->zone);
9061 ISC_LIST_APPEND(zone->notifies, notify, link);
9062 result = notify_send_queue(notify);
9063 if (result != ISC_R_SUCCESS)
9064 notify_destroy(notify, ISC_TRUE);
9065 if (!loggednotify) {
9066 notify_log(zone, ISC_LOG_INFO,
9067 "sending notifies (serial %u)",
9069 loggednotify = ISC_TRUE;
9075 if (notifytype == dns_notifytype_explicit)
9079 * Process NS RRset to generate notifies.
9082 dns_rdataset_init(&nsrdset);
9083 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
9084 dns_rdatatype_none, 0, &nsrdset, NULL);
9085 if (result != ISC_R_SUCCESS)
9088 result = dns_rdataset_first(&nsrdset);
9089 while (result == ISC_R_SUCCESS) {
9090 dns_rdataset_current(&nsrdset, &rdata);
9091 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9092 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9093 dns_rdata_reset(&rdata);
9095 * Don't notify the master server unless explicitly
9096 * configured to do so.
9098 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
9099 dns_name_compare(&master, &ns.name) == 0) {
9100 result = dns_rdataset_next(&nsrdset);
9104 if (!loggednotify) {
9105 notify_log(zone, ISC_LOG_INFO,
9106 "sending notifies (serial %u)",
9108 loggednotify = ISC_TRUE;
9112 isqueued = notify_isqueued(zone, &ns.name, NULL);
9115 result = dns_rdataset_next(&nsrdset);
9118 result = notify_create(zone->mctx, flags, ¬ify);
9119 if (result != ISC_R_SUCCESS)
9121 dns_zone_iattach(zone, ¬ify->zone);
9122 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
9123 if (result != ISC_R_SUCCESS) {
9125 notify_destroy(notify, ISC_TRUE);
9130 ISC_LIST_APPEND(zone->notifies, notify, link);
9132 notify_find_address(notify);
9134 result = dns_rdataset_next(&nsrdset);
9136 dns_rdataset_disassociate(&nsrdset);
9139 if (dns_name_dynamic(&master))
9140 dns_name_free(&master, zone->mctx);
9142 dns_db_detachnode(zonedb, &node);
9144 dns_db_closeversion(zonedb, &version, ISC_FALSE);
9145 dns_db_detach(&zonedb);
9152 static inline isc_result_t
9153 save_nsrrset(dns_message_t *message, dns_name_t *name,
9154 dns_db_t *db, dns_dbversion_t *version)
9156 dns_rdataset_t *nsrdataset = NULL;
9157 dns_rdataset_t *rdataset = NULL;
9158 dns_dbnode_t *node = NULL;
9160 isc_result_t result;
9161 dns_rdata_t rdata = DNS_RDATA_INIT;
9164 * Extract NS RRset from message.
9166 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
9167 dns_rdatatype_ns, dns_rdatatype_none,
9169 if (result != ISC_R_SUCCESS)
9175 result = dns_db_findnode(db, name, ISC_TRUE, &node);
9176 if (result != ISC_R_SUCCESS)
9178 result = dns_db_addrdataset(db, node, version, 0,
9179 nsrdataset, 0, NULL);
9180 dns_db_detachnode(db, &node);
9181 if (result != ISC_R_SUCCESS)
9184 * Add glue rdatasets.
9186 for (result = dns_rdataset_first(nsrdataset);
9187 result == ISC_R_SUCCESS;
9188 result = dns_rdataset_next(nsrdataset)) {
9189 dns_rdataset_current(nsrdataset, &rdata);
9190 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9191 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9192 dns_rdata_reset(&rdata);
9193 if (!dns_name_issubdomain(&ns.name, name))
9196 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9197 &ns.name, dns_rdatatype_aaaa,
9198 dns_rdatatype_none, NULL,
9200 if (result == ISC_R_SUCCESS) {
9201 result = dns_db_findnode(db, &ns.name,
9203 if (result != ISC_R_SUCCESS)
9205 result = dns_db_addrdataset(db, node, version, 0,
9207 dns_db_detachnode(db, &node);
9208 if (result != ISC_R_SUCCESS)
9212 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9213 &ns.name, dns_rdatatype_a,
9214 dns_rdatatype_none, NULL,
9216 if (result == ISC_R_SUCCESS) {
9217 result = dns_db_findnode(db, &ns.name,
9219 if (result != ISC_R_SUCCESS)
9221 result = dns_db_addrdataset(db, node, version, 0,
9223 dns_db_detachnode(db, &node);
9224 if (result != ISC_R_SUCCESS)
9228 if (result != ISC_R_NOMORE)
9231 return (ISC_R_SUCCESS);
9238 stub_callback(isc_task_t *task, isc_event_t *event) {
9239 const char me[] = "stub_callback";
9240 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9241 dns_stub_t *stub = NULL;
9242 dns_message_t *msg = NULL;
9243 dns_zone_t *zone = NULL;
9244 char master[ISC_SOCKADDR_FORMATSIZE];
9245 char source[ISC_SOCKADDR_FORMATSIZE];
9246 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
9247 isc_result_t result;
9249 isc_boolean_t exiting = ISC_FALSE;
9253 stub = revent->ev_arg;
9254 INSIST(DNS_STUB_VALID(stub));
9266 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9267 zone_debuglog(zone, me, 1, "exiting");
9272 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9273 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9275 if (revent->result != ISC_R_SUCCESS) {
9276 if (revent->result == ISC_R_TIMEDOUT &&
9277 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9278 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9279 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9280 "refreshing stub: timeout retrying "
9281 " without EDNS master %s (source %s)",
9285 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
9286 &zone->sourceaddr, &now);
9287 dns_zone_log(zone, ISC_LOG_INFO,
9288 "could not refresh stub from master %s"
9289 " (source %s): %s", master, source,
9290 dns_result_totext(revent->result));
9294 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9295 if (result != ISC_R_SUCCESS)
9298 result = dns_request_getresponse(revent->request, msg, 0);
9299 if (result != ISC_R_SUCCESS)
9305 if (msg->rcode != dns_rcode_noerror) {
9309 isc_buffer_init(&rb, rcode, sizeof(rcode));
9310 (void)dns_rcode_totext(msg->rcode, &rb);
9312 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9313 (msg->rcode == dns_rcode_servfail ||
9314 msg->rcode == dns_rcode_notimp ||
9315 msg->rcode == dns_rcode_formerr)) {
9316 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9317 "refreshing stub: rcode (%.*s) retrying "
9318 "without EDNS master %s (source %s)",
9319 (int)rb.used, rcode, master, source);
9320 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9324 dns_zone_log(zone, ISC_LOG_INFO,
9326 "unexpected rcode (%.*s) from %s (source %s)",
9327 (int)rb.used, rcode, master, source);
9332 * We need complete messages.
9334 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9335 if (dns_request_usedtcp(revent->request)) {
9336 dns_zone_log(zone, ISC_LOG_INFO,
9337 "refreshing stub: truncated TCP "
9338 "response from master %s (source %s)",
9342 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9347 * If non-auth log and next master.
9349 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9350 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
9351 "non-authoritative answer from "
9352 "master %s (source %s)", master, source);
9359 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9360 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
9362 if (cnamecnt != 0) {
9363 dns_zone_log(zone, ISC_LOG_INFO,
9364 "refreshing stub: unexpected CNAME response "
9365 "from master %s (source %s)", master, source);
9370 dns_zone_log(zone, ISC_LOG_INFO,
9371 "refreshing stub: no NS records in response "
9372 "from master %s (source %s)", master, source);
9379 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
9380 if (result != ISC_R_SUCCESS) {
9381 dns_zone_log(zone, ISC_LOG_INFO,
9382 "refreshing stub: unable to save NS records "
9383 "from master %s (source %s)", master, source);
9390 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
9391 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9392 if (zone->db == NULL)
9393 zone_attachdb(zone, stub->db);
9394 result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh,
9395 &retry, &expire, NULL, NULL);
9396 if (result == ISC_R_SUCCESS) {
9397 zone->refresh = RANGE(refresh, zone->minrefresh,
9399 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
9400 zone->expire = RANGE(expire, zone->refresh + zone->retry,
9402 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9404 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9405 dns_db_detach(&stub->db);
9407 dns_message_destroy(&msg);
9408 isc_event_free(&event);
9409 dns_request_destroy(&zone->request);
9411 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9412 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
9413 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9414 isc_interval_set(&i, zone->expire, 0);
9415 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9417 if (zone->masterfile != NULL)
9418 zone_needdump(zone, 0);
9420 zone_settimer(zone, &now);
9424 if (stub->version != NULL)
9425 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
9426 if (stub->db != NULL)
9427 dns_db_detach(&stub->db);
9429 dns_message_destroy(&msg);
9430 isc_event_free(&event);
9431 dns_request_destroy(&zone->request);
9433 * Skip to next failed / untried master.
9437 } while (zone->curmaster < zone->masterscnt &&
9438 zone->mastersok[zone->curmaster]);
9439 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9440 if (exiting || zone->curmaster >= zone->masterscnt) {
9441 isc_boolean_t done = ISC_TRUE;
9443 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9444 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9446 * Did we get a good answer from all the masters?
9448 for (j = 0; j < zone->masterscnt; j++)
9449 if (zone->mastersok[j] == ISC_FALSE) {
9456 zone->curmaster = 0;
9458 * Find the next failed master.
9460 while (zone->curmaster < zone->masterscnt &&
9461 zone->mastersok[zone->curmaster])
9463 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9465 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9467 zone_settimer(zone, &now);
9471 queue_soa_query(zone);
9476 dns_message_destroy(&msg);
9477 isc_event_free(&event);
9478 dns_request_destroy(&zone->request);
9479 ns_query(zone, NULL, stub);
9486 dns_zone_idetach(&stub->zone);
9487 INSIST(stub->db == NULL);
9488 INSIST(stub->version == NULL);
9489 isc_mem_put(stub->mctx, stub, sizeof(*stub));
9492 INSIST(event == NULL);
9497 * An SOA query has finished (successfully or not).
9500 refresh_callback(isc_task_t *task, isc_event_t *event) {
9501 const char me[] = "refresh_callback";
9502 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9504 dns_message_t *msg = NULL;
9505 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
9507 char master[ISC_SOCKADDR_FORMATSIZE];
9508 char source[ISC_SOCKADDR_FORMATSIZE];
9509 dns_rdataset_t *rdataset = NULL;
9510 dns_rdata_t rdata = DNS_RDATA_INIT;
9511 dns_rdata_soa_t soa;
9512 isc_result_t result;
9513 isc_uint32_t serial, oldserial = 0;
9515 isc_boolean_t do_queue_xfrin = ISC_FALSE;
9517 zone = revent->ev_arg;
9518 INSIST(DNS_ZONE_VALID(zone));
9529 * if timeout log and next master;
9532 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9533 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9535 if (revent->result != ISC_R_SUCCESS) {
9536 if (revent->result == ISC_R_TIMEDOUT &&
9537 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9538 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9539 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9540 "refresh: timeout retrying without EDNS "
9541 "master %s (source %s)", master, source);
9544 if (revent->result == ISC_R_TIMEDOUT &&
9545 !dns_request_usedtcp(revent->request)) {
9546 dns_zone_log(zone, ISC_LOG_INFO,
9547 "refresh: retry limit for "
9548 "master %s exceeded (source %s)",
9550 /* Try with slave with TCP. */
9551 if (zone->type == dns_zone_slave &&
9552 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
9553 if (!dns_zonemgr_unreachable(zone->zmgr,
9558 DNS_ZONE_SETFLAG(zone,
9559 DNS_ZONEFLG_SOABEFOREAXFR);
9562 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9563 "refresh: skipped tcp fallback "
9564 "as master %s (source %s) is "
9565 "unreachable (cached)",
9569 dns_zone_log(zone, ISC_LOG_INFO,
9570 "refresh: failure trying master "
9571 "%s (source %s): %s", master, source,
9572 dns_result_totext(revent->result));
9576 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9577 if (result != ISC_R_SUCCESS)
9579 result = dns_request_getresponse(revent->request, msg, 0);
9580 if (result != ISC_R_SUCCESS) {
9581 dns_zone_log(zone, ISC_LOG_INFO,
9582 "refresh: failure trying master "
9583 "%s (source %s): %s", master, source,
9584 dns_result_totext(result));
9591 if (msg->rcode != dns_rcode_noerror) {
9595 isc_buffer_init(&rb, rcode, sizeof(rcode));
9596 (void)dns_rcode_totext(msg->rcode, &rb);
9598 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9599 (msg->rcode == dns_rcode_servfail ||
9600 msg->rcode == dns_rcode_notimp ||
9601 msg->rcode == dns_rcode_formerr)) {
9602 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9603 "refresh: rcode (%.*s) retrying without "
9604 "EDNS master %s (source %s)",
9605 (int)rb.used, rcode, master, source);
9606 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9609 dns_zone_log(zone, ISC_LOG_INFO,
9610 "refresh: unexpected rcode (%.*s) from "
9611 "master %s (source %s)", (int)rb.used, rcode,
9614 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
9616 if (msg->rcode == dns_rcode_refused &&
9617 zone->type == dns_zone_slave)
9623 * If truncated punt to zone transfer which will query again.
9625 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9626 if (zone->type == dns_zone_slave) {
9627 dns_zone_log(zone, ISC_LOG_INFO,
9628 "refresh: truncated UDP answer, "
9629 "initiating TCP zone xfer "
9630 "for master %s (source %s)",
9632 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9635 INSIST(zone->type == dns_zone_stub);
9636 if (dns_request_usedtcp(revent->request)) {
9637 dns_zone_log(zone, ISC_LOG_INFO,
9638 "refresh: truncated TCP response "
9639 "from master %s (source %s)",
9643 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9649 * if non-auth log and next master;
9651 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9652 dns_zone_log(zone, ISC_LOG_INFO,
9653 "refresh: non-authoritative answer from "
9654 "master %s (source %s)", master, source);
9658 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9659 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
9660 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
9661 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
9665 * There should not be a CNAME record at top of zone.
9667 if (cnamecnt != 0) {
9668 dns_zone_log(zone, ISC_LOG_INFO,
9669 "refresh: CNAME at top of zone "
9670 "in master %s (source %s)", master, source);
9675 * if referral log and next master;
9677 if (soacnt == 0 && soacount == 0 && nscount != 0) {
9678 dns_zone_log(zone, ISC_LOG_INFO,
9679 "refresh: referral response "
9680 "from master %s (source %s)", master, source);
9685 * if nodata log and next master;
9687 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
9688 dns_zone_log(zone, ISC_LOG_INFO,
9689 "refresh: NODATA response "
9690 "from master %s (source %s)", master, source);
9695 * Only one soa at top of zone.
9698 dns_zone_log(zone, ISC_LOG_INFO,
9699 "refresh: answer SOA count (%d) != 1 "
9700 "from master %s (source %s)",
9701 soacnt, master, source);
9709 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
9710 dns_rdatatype_soa, dns_rdatatype_none,
9712 if (result != ISC_R_SUCCESS) {
9713 dns_zone_log(zone, ISC_LOG_INFO,
9714 "refresh: unable to get SOA record "
9715 "from master %s (source %s)", master, source);
9719 result = dns_rdataset_first(rdataset);
9720 if (result != ISC_R_SUCCESS) {
9721 dns_zone_log(zone, ISC_LOG_INFO,
9722 "refresh: dns_rdataset_first() failed");
9726 dns_rdataset_current(rdataset, &rdata);
9727 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9728 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9730 serial = soa.serial;
9731 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9732 result = zone_get_from_db(zone, zone->db, NULL, NULL,
9733 &oldserial, NULL, NULL, NULL, NULL,
9735 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9736 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
9739 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
9742 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
9743 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
9744 isc_serial_gt(serial, oldserial)) {
9745 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
9746 &zone->sourceaddr, &now))
9748 dns_zone_log(zone, ISC_LOG_INFO,
9749 "refresh: skipping %s as master %s "
9750 "(source %s) is unreachable (cached)",
9751 zone->type == dns_zone_slave ?
9752 "zone transfer" : "NS query",
9757 isc_event_free(&event);
9758 dns_request_destroy(&zone->request);
9759 if (zone->type == dns_zone_slave) {
9760 do_queue_xfrin = ISC_TRUE;
9762 INSIST(zone->type == dns_zone_stub);
9763 ns_query(zone, rdataset, NULL);
9766 dns_message_destroy(&msg);
9767 } else if (isc_serial_eq(soa.serial, oldserial)) {
9768 if (zone->masterfile != NULL) {
9769 result = ISC_R_FAILURE;
9770 if (zone->journal != NULL)
9771 result = isc_file_settime(zone->journal, &now);
9772 if (result == ISC_R_SUCCESS &&
9773 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9774 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
9775 result = isc_file_settime(zone->masterfile,
9777 } else if (result != ISC_R_SUCCESS)
9778 result = isc_file_settime(zone->masterfile,
9780 /* Someone removed the file from underneath us! */
9781 if (result == ISC_R_FILENOTFOUND) {
9782 zone_needdump(zone, DNS_DUMP_DELAY);
9783 } else if (result != ISC_R_SUCCESS)
9784 dns_zone_log(zone, ISC_LOG_ERROR,
9785 "refresh: could not set file "
9786 "modification time of '%s': %s",
9788 dns_result_totext(result));
9790 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9791 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9792 zone->mastersok[zone->curmaster] = ISC_TRUE;
9795 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
9796 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
9797 "received from master %s < ours (%u)",
9798 soa.serial, master, oldserial);
9800 zone_debuglog(zone, me, 1, "ahead");
9801 zone->mastersok[zone->curmaster] = ISC_TRUE;
9805 dns_message_destroy(&msg);
9810 dns_message_destroy(&msg);
9811 isc_event_free(&event);
9812 dns_request_destroy(&zone->request);
9814 * Skip to next failed / untried master.
9818 } while (zone->curmaster < zone->masterscnt &&
9819 zone->mastersok[zone->curmaster]);
9820 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9821 if (zone->curmaster >= zone->masterscnt) {
9822 isc_boolean_t done = ISC_TRUE;
9823 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9824 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9826 * Did we get a good answer from all the masters?
9828 for (j = 0; j < zone->masterscnt; j++)
9829 if (zone->mastersok[j] == ISC_FALSE) {
9836 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9837 zone->curmaster = 0;
9839 * Find the next failed master.
9841 while (zone->curmaster < zone->masterscnt &&
9842 zone->mastersok[zone->curmaster])
9846 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9847 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9848 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9849 zone->refreshtime = now;
9851 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9852 zone_settimer(zone, &now);
9857 queue_soa_query(zone);
9862 dns_message_destroy(&msg);
9863 isc_event_free(&event);
9864 dns_request_destroy(&zone->request);
9865 queue_soa_query(zone);
9871 dns_zone_idetach(&zone);
9876 queue_soa_query(dns_zone_t *zone) {
9877 const char me[] = "queue_soa_query";
9879 dns_zone_t *dummy = NULL;
9880 isc_result_t result;
9886 REQUIRE(LOCKED_ZONE(zone));
9888 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9889 cancel_refresh(zone);
9893 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
9894 soa_query, zone, sizeof(isc_event_t));
9896 cancel_refresh(zone);
9901 * Attach so that we won't clean up
9902 * until the event is delivered.
9904 zone_iattach(zone, &dummy);
9907 e->ev_sender = NULL;
9908 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
9909 if (result != ISC_R_SUCCESS) {
9910 zone_idetach(&dummy);
9912 cancel_refresh(zone);
9916 static inline isc_result_t
9917 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
9918 dns_message_t **messagep)
9920 dns_message_t *message = NULL;
9921 dns_name_t *qname = NULL;
9922 dns_rdataset_t *qrdataset = NULL;
9923 isc_result_t result;
9925 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
9927 if (result != ISC_R_SUCCESS)
9930 message->opcode = dns_opcode_query;
9931 message->rdclass = zone->rdclass;
9933 result = dns_message_gettempname(message, &qname);
9934 if (result != ISC_R_SUCCESS)
9937 result = dns_message_gettemprdataset(message, &qrdataset);
9938 if (result != ISC_R_SUCCESS)
9944 dns_name_init(qname, NULL);
9945 dns_name_clone(&zone->origin, qname);
9946 dns_rdataset_init(qrdataset);
9947 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
9948 ISC_LIST_APPEND(qname->list, qrdataset, link);
9949 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
9951 *messagep = message;
9952 return (ISC_R_SUCCESS);
9956 dns_message_puttempname(message, &qname);
9957 if (qrdataset != NULL)
9958 dns_message_puttemprdataset(message, &qrdataset);
9959 if (message != NULL)
9960 dns_message_destroy(&message);
9965 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
9966 dns_rdataset_t *rdataset = NULL;
9967 dns_rdatalist_t *rdatalist = NULL;
9968 dns_rdata_t *rdata = NULL;
9969 isc_result_t result;
9971 result = dns_message_gettemprdatalist(message, &rdatalist);
9972 if (result != ISC_R_SUCCESS)
9974 result = dns_message_gettemprdata(message, &rdata);
9975 if (result != ISC_R_SUCCESS)
9977 result = dns_message_gettemprdataset(message, &rdataset);
9978 if (result != ISC_R_SUCCESS)
9980 dns_rdataset_init(rdataset);
9982 rdatalist->type = dns_rdatatype_opt;
9983 rdatalist->covers = 0;
9986 * Set Maximum UDP buffer size.
9988 rdatalist->rdclass = udpsize;
9991 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
9995 /* Set EDNS options if applicable */
9997 unsigned char data[4];
10000 isc_buffer_init(&buf, data, sizeof(data));
10001 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
10002 isc_buffer_putuint16(&buf, 0);
10003 rdata->data = data;
10004 rdata->length = sizeof(data);
10006 rdata->data = NULL;
10010 rdata->rdclass = rdatalist->rdclass;
10011 rdata->type = rdatalist->type;
10014 ISC_LIST_INIT(rdatalist->rdata);
10015 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
10016 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
10019 return (dns_message_setopt(message, rdataset));
10022 if (rdatalist != NULL)
10023 dns_message_puttemprdatalist(message, &rdatalist);
10024 if (rdataset != NULL)
10025 dns_message_puttemprdataset(message, &rdataset);
10027 dns_message_puttemprdata(message, &rdata);
10033 soa_query(isc_task_t *task, isc_event_t *event) {
10034 const char me[] = "soa_query";
10035 isc_result_t result = ISC_R_FAILURE;
10036 dns_message_t *message = NULL;
10037 dns_zone_t *zone = event->ev_arg;
10038 dns_zone_t *dummy = NULL;
10039 isc_netaddr_t masterip;
10040 dns_tsigkey_t *key = NULL;
10041 isc_uint32_t options;
10042 isc_boolean_t cancel = ISC_TRUE;
10044 isc_boolean_t have_xfrsource, reqnsid;
10045 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10047 REQUIRE(DNS_ZONE_VALID(zone));
10054 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
10055 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
10056 zone->view->requestmgr == NULL) {
10057 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10058 cancel = ISC_FALSE;
10063 * XXX Optimisation: Create message when zone is setup and reuse.
10065 result = create_query(zone, dns_rdatatype_soa, &message);
10066 if (result != ISC_R_SUCCESS)
10070 INSIST(zone->masterscnt > 0);
10071 INSIST(zone->curmaster < zone->masterscnt);
10073 zone->masteraddr = zone->masters[zone->curmaster];
10075 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10077 * First, look for a tsig key in the master statement, then
10078 * try for a server key.
10080 if ((zone->masterkeynames != NULL) &&
10081 (zone->masterkeynames[zone->curmaster] != NULL)) {
10082 dns_view_t *view = dns_zone_getview(zone);
10083 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10084 result = dns_view_gettsig(view, keyname, &key);
10085 if (result != ISC_R_SUCCESS) {
10086 char namebuf[DNS_NAME_FORMATSIZE];
10087 dns_name_format(keyname, namebuf, sizeof(namebuf));
10088 dns_zone_log(zone, ISC_LOG_ERROR,
10089 "unable to find key: %s", namebuf);
10094 result = dns_view_getpeertsig(zone->view, &masterip, &key);
10095 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10096 char addrbuf[ISC_NETADDR_FORMATSIZE];
10097 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
10098 dns_zone_log(zone, ISC_LOG_ERROR,
10099 "unable to find TSIG key for %s", addrbuf);
10104 have_xfrsource = ISC_FALSE;
10105 reqnsid = zone->view->requestnsid;
10106 if (zone->view->peers != NULL) {
10107 dns_peer_t *peer = NULL;
10108 isc_boolean_t edns;
10109 result = dns_peerlist_peerbyaddr(zone->view->peers,
10111 if (result == ISC_R_SUCCESS) {
10112 result = dns_peer_getsupportedns(peer, &edns);
10113 if (result == ISC_R_SUCCESS && !edns)
10114 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10115 result = dns_peer_gettransfersource(peer,
10116 &zone->sourceaddr);
10117 if (result == ISC_R_SUCCESS)
10118 have_xfrsource = ISC_TRUE;
10119 if (zone->view->resolver != NULL)
10121 dns_resolver_getudpsize(zone->view->resolver);
10122 (void)dns_peer_getudpsize(peer, &udpsize);
10123 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10127 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10129 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10130 if (isc_sockaddr_equal(&zone->altxfrsource4,
10131 &zone->xfrsource4))
10133 zone->sourceaddr = zone->altxfrsource4;
10134 } else if (!have_xfrsource)
10135 zone->sourceaddr = zone->xfrsource4;
10138 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10139 if (isc_sockaddr_equal(&zone->altxfrsource6,
10140 &zone->xfrsource6))
10142 zone->sourceaddr = zone->altxfrsource6;
10143 } else if (!have_xfrsource)
10144 zone->sourceaddr = zone->xfrsource6;
10147 result = ISC_R_NOTIMPLEMENTED;
10151 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
10152 DNS_REQUESTOPT_TCP : 0;
10154 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10155 result = add_opt(message, udpsize, reqnsid);
10156 if (result != ISC_R_SUCCESS)
10157 zone_debuglog(zone, me, 1,
10158 "unable to add opt record: %s",
10159 dns_result_totext(result));
10162 zone_iattach(zone, &dummy);
10164 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10166 result = dns_request_createvia2(zone->view->requestmgr, message,
10167 &zone->sourceaddr, &zone->masteraddr,
10168 options, key, timeout * 3, timeout,
10169 zone->task, refresh_callback, zone,
10171 if (result != ISC_R_SUCCESS) {
10172 zone_idetach(&dummy);
10173 zone_debuglog(zone, me, 1,
10174 "dns_request_createvia2() failed: %s",
10175 dns_result_totext(result));
10178 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
10179 inc_stats(zone, dns_zonestatscounter_soaoutv4);
10181 inc_stats(zone, dns_zonestatscounter_soaoutv6);
10183 cancel = ISC_FALSE;
10187 dns_tsigkey_detach(&key);
10188 if (result != ISC_R_SUCCESS)
10189 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10190 if (message != NULL)
10191 dns_message_destroy(&message);
10193 cancel_refresh(zone);
10194 isc_event_free(&event);
10196 dns_zone_idetach(&zone);
10201 dns_tsigkey_detach(&key);
10203 * Skip to next failed / untried master.
10207 } while (zone->curmaster < zone->masterscnt &&
10208 zone->mastersok[zone->curmaster]);
10209 if (zone->curmaster < zone->masterscnt)
10211 zone->curmaster = 0;
10216 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
10217 const char me[] = "ns_query";
10218 isc_result_t result;
10219 dns_message_t *message = NULL;
10220 isc_netaddr_t masterip;
10221 dns_tsigkey_t *key = NULL;
10222 dns_dbnode_t *node = NULL;
10224 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
10225 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10227 REQUIRE(DNS_ZONE_VALID(zone));
10228 REQUIRE(LOCKED_ZONE(zone));
10229 REQUIRE((soardataset != NULL && stub == NULL) ||
10230 (soardataset == NULL && stub != NULL));
10231 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
10235 if (stub == NULL) {
10236 stub = isc_mem_get(zone->mctx, sizeof(*stub));
10239 stub->magic = STUB_MAGIC;
10240 stub->mctx = zone->mctx;
10243 stub->version = NULL;
10246 * Attach so that the zone won't disappear from under us.
10248 zone_iattach(zone, &stub->zone);
10251 * If a db exists we will update it, otherwise we create a
10252 * new one and attach it to the zone once we have the NS
10255 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10256 if (zone->db != NULL) {
10257 dns_db_attach(zone->db, &stub->db);
10258 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10260 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10262 INSIST(zone->db_argc >= 1);
10263 result = dns_db_create(zone->mctx, zone->db_argv[0],
10264 &zone->origin, dns_dbtype_stub,
10269 if (result != ISC_R_SUCCESS) {
10270 dns_zone_log(zone, ISC_LOG_ERROR,
10271 "refreshing stub: "
10272 "could not create "
10274 dns_result_totext(result));
10277 dns_db_settask(stub->db, zone->task);
10280 result = dns_db_newversion(stub->db, &stub->version);
10281 if (result != ISC_R_SUCCESS) {
10282 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10283 "dns_db_newversion() failed: %s",
10284 dns_result_totext(result));
10289 * Update SOA record.
10291 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
10293 if (result != ISC_R_SUCCESS) {
10294 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10295 "dns_db_findnode() failed: %s",
10296 dns_result_totext(result));
10300 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
10301 soardataset, 0, NULL);
10302 dns_db_detachnode(stub->db, &node);
10303 if (result != ISC_R_SUCCESS) {
10304 dns_zone_log(zone, ISC_LOG_INFO,
10305 "refreshing stub: "
10306 "dns_db_addrdataset() failed: %s",
10307 dns_result_totext(result));
10313 * XXX Optimisation: Create message when zone is setup and reuse.
10315 result = create_query(zone, dns_rdatatype_ns, &message);
10316 INSIST(result == ISC_R_SUCCESS);
10318 INSIST(zone->masterscnt > 0);
10319 INSIST(zone->curmaster < zone->masterscnt);
10320 zone->masteraddr = zone->masters[zone->curmaster];
10322 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10324 * First, look for a tsig key in the master statement, then
10325 * try for a server key.
10327 if ((zone->masterkeynames != NULL) &&
10328 (zone->masterkeynames[zone->curmaster] != NULL)) {
10329 dns_view_t *view = dns_zone_getview(zone);
10330 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10331 result = dns_view_gettsig(view, keyname, &key);
10332 if (result != ISC_R_SUCCESS) {
10333 char namebuf[DNS_NAME_FORMATSIZE];
10334 dns_name_format(keyname, namebuf, sizeof(namebuf));
10335 dns_zone_log(zone, ISC_LOG_ERROR,
10336 "unable to find key: %s", namebuf);
10340 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
10342 reqnsid = zone->view->requestnsid;
10343 if (zone->view->peers != NULL) {
10344 dns_peer_t *peer = NULL;
10345 isc_boolean_t edns;
10346 result = dns_peerlist_peerbyaddr(zone->view->peers,
10348 if (result == ISC_R_SUCCESS) {
10349 result = dns_peer_getsupportedns(peer, &edns);
10350 if (result == ISC_R_SUCCESS && !edns)
10351 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10352 result = dns_peer_gettransfersource(peer,
10353 &zone->sourceaddr);
10354 if (result == ISC_R_SUCCESS)
10355 have_xfrsource = ISC_TRUE;
10356 if (zone->view->resolver != NULL)
10358 dns_resolver_getudpsize(zone->view->resolver);
10359 (void)dns_peer_getudpsize(peer, &udpsize);
10360 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10364 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10365 result = add_opt(message, udpsize, reqnsid);
10366 if (result != ISC_R_SUCCESS)
10367 zone_debuglog(zone, me, 1,
10368 "unable to add opt record: %s",
10369 dns_result_totext(result));
10373 * Always use TCP so that we shouldn't truncate in additional section.
10375 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10377 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10378 zone->sourceaddr = zone->altxfrsource4;
10379 else if (!have_xfrsource)
10380 zone->sourceaddr = zone->xfrsource4;
10383 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10384 zone->sourceaddr = zone->altxfrsource6;
10385 else if (!have_xfrsource)
10386 zone->sourceaddr = zone->xfrsource6;
10389 result = ISC_R_NOTIMPLEMENTED;
10394 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10396 result = dns_request_createvia2(zone->view->requestmgr, message,
10397 &zone->sourceaddr, &zone->masteraddr,
10398 DNS_REQUESTOPT_TCP, key, timeout * 3,
10399 timeout, zone->task, stub_callback,
10400 stub, &zone->request);
10401 if (result != ISC_R_SUCCESS) {
10402 zone_debuglog(zone, me, 1,
10403 "dns_request_createvia() failed: %s",
10404 dns_result_totext(result));
10407 dns_message_destroy(&message);
10411 cancel_refresh(zone);
10412 if (stub != NULL) {
10414 if (stub->version != NULL)
10415 dns_db_closeversion(stub->db, &stub->version,
10417 if (stub->db != NULL)
10418 dns_db_detach(&stub->db);
10419 if (stub->zone != NULL)
10420 zone_idetach(&stub->zone);
10421 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10423 if (message != NULL)
10424 dns_message_destroy(&message);
10427 dns_tsigkey_detach(&key);
10432 * Handle the control event. Note that although this event causes the zone
10433 * to shut down, it is not a shutdown event in the sense of the task library.
10436 zone_shutdown(isc_task_t *task, isc_event_t *event) {
10437 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
10438 isc_boolean_t free_needed, linked = ISC_FALSE;
10441 REQUIRE(DNS_ZONE_VALID(zone));
10442 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
10443 INSIST(isc_refcount_current(&zone->erefs) == 0);
10445 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
10448 * Stop things being restarted after we cancel them below.
10451 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
10455 * If we were waiting for xfrin quota, step out of
10457 * If there's no zone manager, we can't be waiting for the
10460 if (zone->zmgr != NULL) {
10461 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10462 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
10463 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
10466 zone->statelist = NULL;
10468 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10472 * In task context, no locking required. See zone_xfrdone().
10474 if (zone->xfr != NULL)
10475 dns_xfrin_shutdown(zone->xfr);
10479 INSIST(zone->irefs > 0);
10482 if (zone->request != NULL) {
10483 dns_request_cancel(zone->request);
10486 if (zone->readio != NULL)
10487 zonemgr_cancelio(zone->readio);
10489 if (zone->lctx != NULL)
10490 dns_loadctx_cancel(zone->lctx);
10492 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10493 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10494 if (zone->writeio != NULL)
10495 zonemgr_cancelio(zone->writeio);
10497 if (zone->dctx != NULL)
10498 dns_dumpctx_cancel(zone->dctx);
10501 notify_cancel(zone);
10503 forward_cancel(zone);
10505 if (zone->timer != NULL) {
10506 isc_timer_detach(&zone->timer);
10507 INSIST(zone->irefs > 0);
10511 if (zone->view != NULL)
10512 dns_view_weakdetach(&zone->view);
10515 * We have now canceled everything set the flag to allow exit_check()
10516 * to succeed. We must not unlock between setting this flag and
10517 * calling exit_check().
10519 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
10520 free_needed = exit_check(zone);
10527 zone_timer(isc_task_t *task, isc_event_t *event) {
10528 const char me[] = "zone_timer";
10529 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
10532 REQUIRE(DNS_ZONE_VALID(zone));
10536 zone_maintenance(zone);
10538 isc_event_free(&event);
10542 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
10543 const char me[] = "zone_settimer";
10545 isc_result_t result;
10548 REQUIRE(DNS_ZONE_VALID(zone));
10549 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10552 isc_time_settoepoch(&next);
10554 switch (zone->type) {
10555 case dns_zone_master:
10556 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10557 next = zone->notifytime;
10558 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10559 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10560 INSIST(!isc_time_isepoch(&zone->dumptime));
10561 if (isc_time_isepoch(&next) ||
10562 isc_time_compare(&zone->dumptime, &next) < 0)
10563 next = zone->dumptime;
10565 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
10566 !isc_time_isepoch(&zone->refreshkeytime)) {
10567 if (isc_time_isepoch(&next) ||
10568 isc_time_compare(&zone->refreshkeytime, &next) < 0)
10569 next = zone->refreshkeytime;
10571 if (!isc_time_isepoch(&zone->resigntime)) {
10572 if (isc_time_isepoch(&next) ||
10573 isc_time_compare(&zone->resigntime, &next) < 0)
10574 next = zone->resigntime;
10576 if (!isc_time_isepoch(&zone->keywarntime)) {
10577 if (isc_time_isepoch(&next) ||
10578 isc_time_compare(&zone->keywarntime, &next) < 0)
10579 next = zone->keywarntime;
10581 if (!isc_time_isepoch(&zone->signingtime)) {
10582 if (isc_time_isepoch(&next) ||
10583 isc_time_compare(&zone->signingtime, &next) < 0)
10584 next = zone->signingtime;
10586 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
10587 if (isc_time_isepoch(&next) ||
10588 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
10589 next = zone->nsec3chaintime;
10593 case dns_zone_slave:
10594 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10595 next = zone->notifytime;
10598 case dns_zone_stub:
10599 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
10600 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
10601 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
10602 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
10603 INSIST(!isc_time_isepoch(&zone->refreshtime));
10604 if (isc_time_isepoch(&next) ||
10605 isc_time_compare(&zone->refreshtime, &next) < 0)
10606 next = zone->refreshtime;
10608 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10609 INSIST(!isc_time_isepoch(&zone->expiretime));
10610 if (isc_time_isepoch(&next) ||
10611 isc_time_compare(&zone->expiretime, &next) < 0)
10612 next = zone->expiretime;
10614 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10615 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10616 INSIST(!isc_time_isepoch(&zone->dumptime));
10617 if (isc_time_isepoch(&next) ||
10618 isc_time_compare(&zone->dumptime, &next) < 0)
10619 next = zone->dumptime;
10624 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10625 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10626 INSIST(!isc_time_isepoch(&zone->dumptime));
10627 if (isc_time_isepoch(&next) ||
10628 isc_time_compare(&zone->dumptime, &next) < 0)
10629 next = zone->dumptime;
10631 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
10632 if (isc_time_isepoch(&next) ||
10633 (!isc_time_isepoch(&zone->refreshkeytime) &&
10634 isc_time_compare(&zone->refreshkeytime, &next) < 0))
10635 next = zone->refreshkeytime;
10643 if (isc_time_isepoch(&next)) {
10644 zone_debuglog(zone, me, 10, "settimer inactive");
10645 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
10646 NULL, NULL, ISC_TRUE);
10647 if (result != ISC_R_SUCCESS)
10648 dns_zone_log(zone, ISC_LOG_ERROR,
10649 "could not deactivate zone timer: %s",
10650 isc_result_totext(result));
10652 if (isc_time_compare(&next, now) <= 0)
10654 result = isc_timer_reset(zone->timer, isc_timertype_once,
10655 &next, NULL, ISC_TRUE);
10656 if (result != ISC_R_SUCCESS)
10657 dns_zone_log(zone, ISC_LOG_ERROR,
10658 "could not reset zone timer: %s",
10659 isc_result_totext(result));
10664 cancel_refresh(dns_zone_t *zone) {
10665 const char me[] = "cancel_refresh";
10669 * 'zone' locked by caller.
10672 REQUIRE(DNS_ZONE_VALID(zone));
10673 REQUIRE(LOCKED_ZONE(zone));
10677 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10679 zone_settimer(zone, &now);
10682 static isc_result_t
10683 notify_createmessage(dns_zone_t *zone, unsigned int flags,
10684 dns_message_t **messagep)
10686 dns_db_t *zonedb = NULL;
10687 dns_dbnode_t *node = NULL;
10688 dns_dbversion_t *version = NULL;
10689 dns_message_t *message = NULL;
10690 dns_rdataset_t rdataset;
10691 dns_rdata_t rdata = DNS_RDATA_INIT;
10693 dns_name_t *tempname = NULL;
10694 dns_rdata_t *temprdata = NULL;
10695 dns_rdatalist_t *temprdatalist = NULL;
10696 dns_rdataset_t *temprdataset = NULL;
10698 isc_result_t result;
10700 isc_buffer_t *b = NULL;
10702 REQUIRE(DNS_ZONE_VALID(zone));
10703 REQUIRE(messagep != NULL && *messagep == NULL);
10705 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10707 if (result != ISC_R_SUCCESS)
10710 message->opcode = dns_opcode_notify;
10711 message->flags |= DNS_MESSAGEFLAG_AA;
10712 message->rdclass = zone->rdclass;
10714 result = dns_message_gettempname(message, &tempname);
10715 if (result != ISC_R_SUCCESS)
10718 result = dns_message_gettemprdataset(message, &temprdataset);
10719 if (result != ISC_R_SUCCESS)
10725 dns_name_init(tempname, NULL);
10726 dns_name_clone(&zone->origin, tempname);
10727 dns_rdataset_init(temprdataset);
10728 dns_rdataset_makequestion(temprdataset, zone->rdclass,
10729 dns_rdatatype_soa);
10730 ISC_LIST_APPEND(tempname->list, temprdataset, link);
10731 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
10733 temprdataset = NULL;
10735 if ((flags & DNS_NOTIFY_NOSOA) != 0)
10738 result = dns_message_gettempname(message, &tempname);
10739 if (result != ISC_R_SUCCESS)
10741 result = dns_message_gettemprdata(message, &temprdata);
10742 if (result != ISC_R_SUCCESS)
10744 result = dns_message_gettemprdataset(message, &temprdataset);
10745 if (result != ISC_R_SUCCESS)
10747 result = dns_message_gettemprdatalist(message, &temprdatalist);
10748 if (result != ISC_R_SUCCESS)
10751 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10752 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
10753 dns_db_attach(zone->db, &zonedb);
10754 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10756 dns_name_init(tempname, NULL);
10757 dns_name_clone(&zone->origin, tempname);
10758 dns_db_currentversion(zonedb, &version);
10759 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
10760 if (result != ISC_R_SUCCESS)
10763 dns_rdataset_init(&rdataset);
10764 result = dns_db_findrdataset(zonedb, node, version,
10766 dns_rdatatype_none, 0, &rdataset,
10768 if (result != ISC_R_SUCCESS)
10770 result = dns_rdataset_first(&rdataset);
10771 if (result != ISC_R_SUCCESS)
10773 dns_rdataset_current(&rdataset, &rdata);
10774 dns_rdata_toregion(&rdata, &r);
10775 result = isc_buffer_allocate(zone->mctx, &b, r.length);
10776 if (result != ISC_R_SUCCESS)
10778 isc_buffer_putmem(b, r.base, r.length);
10779 isc_buffer_usedregion(b, &r);
10780 dns_rdata_init(temprdata);
10781 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
10782 dns_message_takebuffer(message, &b);
10783 result = dns_rdataset_next(&rdataset);
10784 dns_rdataset_disassociate(&rdataset);
10785 if (result != ISC_R_NOMORE)
10787 temprdatalist->rdclass = rdata.rdclass;
10788 temprdatalist->type = rdata.type;
10789 temprdatalist->covers = 0;
10790 temprdatalist->ttl = rdataset.ttl;
10791 ISC_LIST_INIT(temprdatalist->rdata);
10792 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
10794 dns_rdataset_init(temprdataset);
10795 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
10796 if (result != ISC_R_SUCCESS)
10799 ISC_LIST_APPEND(tempname->list, temprdataset, link);
10800 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
10801 temprdatalist = NULL;
10802 temprdataset = NULL;
10808 dns_db_detachnode(zonedb, &node);
10809 if (version != NULL)
10810 dns_db_closeversion(zonedb, &version, ISC_FALSE);
10811 if (zonedb != NULL)
10812 dns_db_detach(&zonedb);
10813 if (tempname != NULL)
10814 dns_message_puttempname(message, &tempname);
10815 if (temprdata != NULL)
10816 dns_message_puttemprdata(message, &temprdata);
10817 if (temprdataset != NULL)
10818 dns_message_puttemprdataset(message, &temprdataset);
10819 if (temprdatalist != NULL)
10820 dns_message_puttemprdatalist(message, &temprdatalist);
10823 *messagep = message;
10824 return (ISC_R_SUCCESS);
10827 if (tempname != NULL)
10828 dns_message_puttempname(message, &tempname);
10829 if (temprdataset != NULL)
10830 dns_message_puttemprdataset(message, &temprdataset);
10831 dns_message_destroy(&message);
10836 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
10837 dns_message_t *msg)
10840 dns_rdata_soa_t soa;
10841 dns_rdataset_t *rdataset = NULL;
10842 dns_rdata_t rdata = DNS_RDATA_INIT;
10843 isc_result_t result;
10844 char fromtext[ISC_SOCKADDR_FORMATSIZE];
10846 isc_netaddr_t netaddr;
10847 isc_sockaddr_t local, remote;
10849 REQUIRE(DNS_ZONE_VALID(zone));
10852 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
10856 * Check that 'from' is a valid notify source, (zone->masters).
10857 * Return DNS_R_REFUSED if not.
10859 * If the notify message contains a serial number check it
10860 * against the zones serial and return if <= current serial
10862 * If a refresh check is progress, if so just record the
10863 * fact we received a NOTIFY and from where and return.
10864 * We will perform a new refresh check when the current one
10865 * completes. Return ISC_R_SUCCESS.
10867 * Otherwise initiate a refresh check using 'from' as the
10868 * first address to check. Return ISC_R_SUCCESS.
10871 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
10874 * We only handle NOTIFY (SOA) at the present.
10877 if (isc_sockaddr_pf(from) == PF_INET)
10878 inc_stats(zone, dns_zonestatscounter_notifyinv4);
10880 inc_stats(zone, dns_zonestatscounter_notifyinv6);
10881 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
10882 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
10883 dns_rdatatype_soa, dns_rdatatype_none,
10884 NULL, NULL) != ISC_R_SUCCESS) {
10886 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
10887 dns_zone_log(zone, ISC_LOG_NOTICE,
10889 "question section from: %s", fromtext);
10890 return (DNS_R_FORMERR);
10892 dns_zone_log(zone, ISC_LOG_NOTICE,
10893 "NOTIFY zone does not match");
10894 return (DNS_R_NOTIMP);
10898 * If we are a master zone just succeed.
10900 if (zone->type == dns_zone_master) {
10902 return (ISC_R_SUCCESS);
10905 isc_netaddr_fromsockaddr(&netaddr, from);
10906 for (i = 0; i < zone->masterscnt; i++) {
10907 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
10909 if (zone->view->aclenv.match_mapped &&
10910 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
10911 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
10912 isc_netaddr_t na1, na2;
10913 isc_netaddr_fromv4mapped(&na1, &netaddr);
10914 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
10915 if (isc_netaddr_equal(&na1, &na2))
10921 * Accept notify requests from non masters if they are on
10922 * 'zone->notify_acl'.
10924 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
10925 dns_acl_match(&netaddr, NULL, zone->notify_acl,
10926 &zone->view->aclenv,
10927 &match, NULL) == ISC_R_SUCCESS &&
10930 /* Accept notify. */
10931 } else if (i >= zone->masterscnt) {
10933 dns_zone_log(zone, ISC_LOG_INFO,
10934 "refused notify from non-master: %s", fromtext);
10935 inc_stats(zone, dns_zonestatscounter_notifyrej);
10936 return (DNS_R_REFUSED);
10940 * If the zone is loaded and there are answers check the serial
10941 * to see if we need to do a refresh. Do not worry about this
10942 * check if we are a dialup zone as we use the notify request
10943 * to trigger a refresh check.
10945 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
10946 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10947 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
10948 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
10951 dns_rdatatype_none, NULL,
10953 if (result == ISC_R_SUCCESS)
10954 result = dns_rdataset_first(rdataset);
10955 if (result == ISC_R_SUCCESS) {
10956 isc_uint32_t serial = 0, oldserial;
10958 dns_rdataset_current(rdataset, &rdata);
10959 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10960 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10961 serial = soa.serial;
10963 * The following should safely be performed without DB
10964 * lock and succeed in this context.
10966 result = zone_get_from_db(zone, zone->db, NULL, NULL,
10967 &oldserial, NULL, NULL, NULL,
10969 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10970 if (isc_serial_le(serial, oldserial)) {
10974 "zone is up to date",
10977 return (ISC_R_SUCCESS);
10983 * If we got this far and there was a refresh in progress just
10984 * let it complete. Record where we got the notify from so we
10985 * can perform a refresh check when the current one completes
10987 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
10988 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
10989 zone->notifyfrom = *from;
10991 dns_zone_log(zone, ISC_LOG_INFO,
10992 "notify from %s: refresh in progress, "
10993 "refresh check queued",
10995 return (ISC_R_SUCCESS);
10997 zone->notifyfrom = *from;
10998 local = zone->masteraddr;
10999 remote = zone->sourceaddr;
11001 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
11002 dns_zone_refresh(zone);
11003 return (ISC_R_SUCCESS);
11007 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
11009 REQUIRE(DNS_ZONE_VALID(zone));
11012 if (zone->notify_acl != NULL)
11013 dns_acl_detach(&zone->notify_acl);
11014 dns_acl_attach(acl, &zone->notify_acl);
11019 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
11021 REQUIRE(DNS_ZONE_VALID(zone));
11024 if (zone->query_acl != NULL)
11025 dns_acl_detach(&zone->query_acl);
11026 dns_acl_attach(acl, &zone->query_acl);
11031 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
11033 REQUIRE(DNS_ZONE_VALID(zone));
11036 if (zone->queryon_acl != NULL)
11037 dns_acl_detach(&zone->queryon_acl);
11038 dns_acl_attach(acl, &zone->queryon_acl);
11043 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
11045 REQUIRE(DNS_ZONE_VALID(zone));
11048 if (zone->update_acl != NULL)
11049 dns_acl_detach(&zone->update_acl);
11050 dns_acl_attach(acl, &zone->update_acl);
11055 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
11057 REQUIRE(DNS_ZONE_VALID(zone));
11060 if (zone->forward_acl != NULL)
11061 dns_acl_detach(&zone->forward_acl);
11062 dns_acl_attach(acl, &zone->forward_acl);
11067 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
11069 REQUIRE(DNS_ZONE_VALID(zone));
11072 if (zone->xfr_acl != NULL)
11073 dns_acl_detach(&zone->xfr_acl);
11074 dns_acl_attach(acl, &zone->xfr_acl);
11079 dns_zone_getnotifyacl(dns_zone_t *zone) {
11081 REQUIRE(DNS_ZONE_VALID(zone));
11083 return (zone->notify_acl);
11087 dns_zone_getqueryacl(dns_zone_t *zone) {
11089 REQUIRE(DNS_ZONE_VALID(zone));
11091 return (zone->query_acl);
11095 dns_zone_getqueryonacl(dns_zone_t *zone) {
11097 REQUIRE(DNS_ZONE_VALID(zone));
11099 return (zone->queryon_acl);
11103 dns_zone_getupdateacl(dns_zone_t *zone) {
11105 REQUIRE(DNS_ZONE_VALID(zone));
11107 return (zone->update_acl);
11111 dns_zone_getforwardacl(dns_zone_t *zone) {
11113 REQUIRE(DNS_ZONE_VALID(zone));
11115 return (zone->forward_acl);
11119 dns_zone_getxfracl(dns_zone_t *zone) {
11121 REQUIRE(DNS_ZONE_VALID(zone));
11123 return (zone->xfr_acl);
11127 dns_zone_clearupdateacl(dns_zone_t *zone) {
11129 REQUIRE(DNS_ZONE_VALID(zone));
11132 if (zone->update_acl != NULL)
11133 dns_acl_detach(&zone->update_acl);
11138 dns_zone_clearforwardacl(dns_zone_t *zone) {
11140 REQUIRE(DNS_ZONE_VALID(zone));
11143 if (zone->forward_acl != NULL)
11144 dns_acl_detach(&zone->forward_acl);
11149 dns_zone_clearnotifyacl(dns_zone_t *zone) {
11151 REQUIRE(DNS_ZONE_VALID(zone));
11154 if (zone->notify_acl != NULL)
11155 dns_acl_detach(&zone->notify_acl);
11160 dns_zone_clearqueryacl(dns_zone_t *zone) {
11162 REQUIRE(DNS_ZONE_VALID(zone));
11165 if (zone->query_acl != NULL)
11166 dns_acl_detach(&zone->query_acl);
11171 dns_zone_clearqueryonacl(dns_zone_t *zone) {
11173 REQUIRE(DNS_ZONE_VALID(zone));
11176 if (zone->queryon_acl != NULL)
11177 dns_acl_detach(&zone->queryon_acl);
11182 dns_zone_clearxfracl(dns_zone_t *zone) {
11184 REQUIRE(DNS_ZONE_VALID(zone));
11187 if (zone->xfr_acl != NULL)
11188 dns_acl_detach(&zone->xfr_acl);
11193 dns_zone_getupdatedisabled(dns_zone_t *zone) {
11194 REQUIRE(DNS_ZONE_VALID(zone));
11195 return (zone->update_disabled);
11200 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
11201 REQUIRE(DNS_ZONE_VALID(zone));
11202 zone->update_disabled = state;
11206 dns_zone_getzeronosoattl(dns_zone_t *zone) {
11207 REQUIRE(DNS_ZONE_VALID(zone));
11208 return (zone->zero_no_soa_ttl);
11213 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
11214 REQUIRE(DNS_ZONE_VALID(zone));
11215 zone->zero_no_soa_ttl = state;
11219 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
11221 REQUIRE(DNS_ZONE_VALID(zone));
11223 zone->check_names = severity;
11227 dns_zone_getchecknames(dns_zone_t *zone) {
11229 REQUIRE(DNS_ZONE_VALID(zone));
11231 return (zone->check_names);
11235 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
11237 REQUIRE(DNS_ZONE_VALID(zone));
11239 zone->journalsize = size;
11243 dns_zone_getjournalsize(dns_zone_t *zone) {
11245 REQUIRE(DNS_ZONE_VALID(zone));
11247 return (zone->journalsize);
11251 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
11252 isc_result_t result = ISC_R_FAILURE;
11253 isc_buffer_t buffer;
11255 REQUIRE(buf != NULL);
11256 REQUIRE(length > 1U);
11259 * Leave space for terminating '\0'.
11261 isc_buffer_init(&buffer, buf, length - 1);
11262 if (dns_name_dynamic(&zone->origin))
11263 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11264 if (result != ISC_R_SUCCESS &&
11265 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11266 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11268 if (isc_buffer_availablelength(&buffer) > 0)
11269 isc_buffer_putstr(&buffer, "/");
11270 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11272 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
11273 strcmp(zone->view->name, "_default") != 0 &&
11274 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
11275 isc_buffer_putstr(&buffer, "/");
11276 isc_buffer_putstr(&buffer, zone->view->name);
11279 buf[isc_buffer_usedlength(&buffer)] = '\0';
11283 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
11284 isc_result_t result = ISC_R_FAILURE;
11285 isc_buffer_t buffer;
11287 REQUIRE(buf != NULL);
11288 REQUIRE(length > 1U);
11291 * Leave space for terminating '\0'.
11293 isc_buffer_init(&buffer, buf, length - 1);
11294 if (dns_name_dynamic(&zone->origin))
11295 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11296 if (result != ISC_R_SUCCESS &&
11297 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11298 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11300 buf[isc_buffer_usedlength(&buffer)] = '\0';
11304 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
11305 isc_buffer_t buffer;
11307 REQUIRE(buf != NULL);
11308 REQUIRE(length > 1U);
11311 * Leave space for terminating '\0'.
11313 isc_buffer_init(&buffer, buf, length - 1);
11314 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11316 buf[isc_buffer_usedlength(&buffer)] = '\0';
11320 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
11321 isc_buffer_t buffer;
11323 REQUIRE(buf != NULL);
11324 REQUIRE(length > 1U);
11328 * Leave space for terminating '\0'.
11330 isc_buffer_init(&buffer, buf, length - 1);
11332 if (zone->view == NULL) {
11333 isc_buffer_putstr(&buffer, "_none");
11334 } else if (strlen(zone->view->name)
11335 < isc_buffer_availablelength(&buffer)) {
11336 isc_buffer_putstr(&buffer, zone->view->name);
11338 isc_buffer_putstr(&buffer, "_toolong");
11341 buf[isc_buffer_usedlength(&buffer)] = '\0';
11345 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
11346 REQUIRE(DNS_ZONE_VALID(zone));
11347 REQUIRE(buf != NULL);
11348 zone_namerd_tostr(zone, buf, length);
11352 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11354 char message[4096];
11356 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11360 vsnprintf(message, sizeof(message), fmt, ap);
11362 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
11363 level, "zone %s: %s", zone->strnamerd, message);
11367 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
11368 int level, const char *fmt, ...) {
11370 char message[4096];
11372 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11376 vsnprintf(message, sizeof(message), fmt, ap);
11378 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
11379 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11380 "managed-keys-zone" : "zone", zone->strnamerd, message);
11384 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11386 char message[4096];
11388 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11392 vsnprintf(message, sizeof(message), fmt, ap);
11394 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11395 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11396 "managed-keys-zone" : "zone", zone->strnamerd, message);
11400 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
11401 const char *fmt, ...)
11404 char message[4096];
11405 int level = ISC_LOG_DEBUG(debuglevel);
11407 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11411 vsnprintf(message, sizeof(message), fmt, ap);
11413 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11414 level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
11415 "zone" : "managed-keys-zone", zone->strnamerd, message);
11419 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
11421 isc_result_t result;
11423 dns_rdataset_t *curr;
11426 result = dns_message_firstname(msg, section);
11427 while (result == ISC_R_SUCCESS) {
11429 dns_message_currentname(msg, section, &name);
11431 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
11432 curr = ISC_LIST_PREV(curr, link)) {
11433 if (curr->type == type)
11436 result = dns_message_nextname(msg, section);
11443 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
11444 REQUIRE(DNS_ZONE_VALID(zone));
11446 zone->maxxfrin = maxxfrin;
11450 dns_zone_getmaxxfrin(dns_zone_t *zone) {
11451 REQUIRE(DNS_ZONE_VALID(zone));
11453 return (zone->maxxfrin);
11457 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
11458 REQUIRE(DNS_ZONE_VALID(zone));
11459 zone->maxxfrout = maxxfrout;
11463 dns_zone_getmaxxfrout(dns_zone_t *zone) {
11464 REQUIRE(DNS_ZONE_VALID(zone));
11466 return (zone->maxxfrout);
11470 dns_zone_gettype(dns_zone_t *zone) {
11471 REQUIRE(DNS_ZONE_VALID(zone));
11473 return (zone->type);
11477 dns_zone_getorigin(dns_zone_t *zone) {
11478 REQUIRE(DNS_ZONE_VALID(zone));
11480 return (&zone->origin);
11484 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
11485 REQUIRE(DNS_ZONE_VALID(zone));
11488 if (zone->task != NULL)
11489 isc_task_detach(&zone->task);
11490 isc_task_attach(task, &zone->task);
11491 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11492 if (zone->db != NULL)
11493 dns_db_settask(zone->db, zone->task);
11494 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11499 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
11500 REQUIRE(DNS_ZONE_VALID(zone));
11501 isc_task_attach(zone->task, target);
11505 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
11506 REQUIRE(DNS_ZONE_VALID(zone));
11509 idlein = DNS_DEFAULT_IDLEIN;
11510 zone->idlein = idlein;
11514 dns_zone_getidlein(dns_zone_t *zone) {
11515 REQUIRE(DNS_ZONE_VALID(zone));
11517 return (zone->idlein);
11521 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
11522 REQUIRE(DNS_ZONE_VALID(zone));
11524 zone->idleout = idleout;
11528 dns_zone_getidleout(dns_zone_t *zone) {
11529 REQUIRE(DNS_ZONE_VALID(zone));
11531 return (zone->idleout);
11535 notify_done(isc_task_t *task, isc_event_t *event) {
11536 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11537 dns_notify_t *notify;
11538 isc_result_t result;
11539 dns_message_t *message = NULL;
11542 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
11546 notify = event->ev_arg;
11547 REQUIRE(DNS_NOTIFY_VALID(notify));
11548 INSIST(task == notify->zone->task);
11550 isc_buffer_init(&buf, rcode, sizeof(rcode));
11551 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11553 result = revent->result;
11554 if (result == ISC_R_SUCCESS)
11555 result = dns_message_create(notify->zone->mctx,
11556 DNS_MESSAGE_INTENTPARSE, &message);
11557 if (result == ISC_R_SUCCESS)
11558 result = dns_request_getresponse(revent->request, message,
11559 DNS_MESSAGEPARSE_PRESERVEORDER);
11560 if (result == ISC_R_SUCCESS)
11561 result = dns_rcode_totext(message->rcode, &buf);
11562 if (result == ISC_R_SUCCESS)
11563 notify_log(notify->zone, ISC_LOG_DEBUG(3),
11564 "notify response from %s: %.*s",
11565 addrbuf, (int)buf.used, rcode);
11567 notify_log(notify->zone, ISC_LOG_DEBUG(2),
11568 "notify to %s failed: %s", addrbuf,
11569 dns_result_totext(result));
11572 * Old bind's return formerr if they see a soa record. Retry w/o
11573 * the soa if we see a formerr and had sent a SOA.
11575 isc_event_free(&event);
11576 if (message != NULL && message->rcode == dns_rcode_formerr &&
11577 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
11578 notify->flags |= DNS_NOTIFY_NOSOA;
11579 dns_request_destroy(¬ify->request);
11580 result = notify_send_queue(notify);
11581 if (result != ISC_R_SUCCESS)
11582 notify_destroy(notify, ISC_FALSE);
11584 if (result == ISC_R_TIMEDOUT)
11585 notify_log(notify->zone, ISC_LOG_DEBUG(1),
11586 "notify to %s: retries exceeded", addrbuf);
11587 notify_destroy(notify, ISC_FALSE);
11589 if (message != NULL)
11590 dns_message_destroy(&message);
11594 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11595 isc_result_t result;
11597 REQUIRE(DNS_ZONE_VALID(zone));
11599 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11600 result = zone_replacedb(zone, db, dump);
11601 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11606 static isc_result_t
11607 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11608 dns_dbversion_t *ver;
11609 isc_result_t result;
11610 unsigned int soacount = 0;
11611 unsigned int nscount = 0;
11614 * 'zone' and 'zonedb' locked by caller.
11616 REQUIRE(DNS_ZONE_VALID(zone));
11617 REQUIRE(LOCKED_ZONE(zone));
11619 result = zone_get_from_db(zone, db, &nscount, &soacount,
11620 NULL, NULL, NULL, NULL, NULL, NULL);
11621 if (result == ISC_R_SUCCESS) {
11622 if (soacount != 1) {
11623 dns_zone_log(zone, ISC_LOG_ERROR,
11624 "has %d SOA records", soacount);
11625 result = DNS_R_BADZONE;
11627 if (nscount == 0 && zone->type != dns_zone_key) {
11628 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
11629 result = DNS_R_BADZONE;
11631 if (result != ISC_R_SUCCESS)
11634 dns_zone_log(zone, ISC_LOG_ERROR,
11635 "retrieving SOA and NS records failed: %s",
11636 dns_result_totext(result));
11640 result = check_nsec3param(zone, db);
11641 if (result != ISC_R_SUCCESS)
11645 dns_db_currentversion(db, &ver);
11648 * The initial version of a slave zone is always dumped;
11649 * subsequent versions may be journaled instead if this
11650 * is enabled in the configuration.
11652 if (zone->db != NULL && zone->journal != NULL &&
11653 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
11654 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
11655 isc_uint32_t serial, oldserial;
11657 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
11659 result = dns_db_getsoaserial(db, ver, &serial);
11660 if (result != ISC_R_SUCCESS) {
11661 dns_zone_log(zone, ISC_LOG_ERROR,
11662 "ixfr-from-differences: unable to get "
11668 * This is checked in zone_postload() for master zones.
11670 result = zone_get_from_db(zone, zone->db, NULL, NULL,
11671 &oldserial, NULL, NULL, NULL, NULL,
11673 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11674 if (zone->type == dns_zone_slave &&
11675 !isc_serial_gt(serial, oldserial)) {
11676 isc_uint32_t serialmin, serialmax;
11677 serialmin = (oldserial + 1) & 0xffffffffU;
11678 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
11679 dns_zone_log(zone, ISC_LOG_ERROR,
11680 "ixfr-from-differences: failed: "
11681 "new serial (%u) out of range [%u - %u]",
11682 serial, serialmin, serialmax);
11683 result = ISC_R_RANGE;
11687 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
11689 if (result != ISC_R_SUCCESS)
11692 zone_needdump(zone, DNS_DUMP_DELAY);
11693 else if (zone->journalsize != -1) {
11694 result = dns_journal_compact(zone->mctx, zone->journal,
11695 serial, zone->journalsize);
11697 case ISC_R_SUCCESS:
11698 case ISC_R_NOSPACE:
11699 case ISC_R_NOTFOUND:
11700 dns_zone_log(zone, ISC_LOG_DEBUG(3),
11701 "dns_journal_compact: %s",
11702 dns_result_totext(result));
11705 dns_zone_log(zone, ISC_LOG_ERROR,
11706 "dns_journal_compact failed: %s",
11707 dns_result_totext(result));
11712 if (dump && zone->masterfile != NULL) {
11714 * If DNS_ZONEFLG_FORCEXFER was set we don't want
11715 * to keep the old masterfile.
11717 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
11718 remove(zone->masterfile) < 0 && errno != ENOENT) {
11719 char strbuf[ISC_STRERRORSIZE];
11720 isc__strerror(errno, strbuf, sizeof(strbuf));
11721 isc_log_write(dns_lctx,
11722 DNS_LOGCATEGORY_GENERAL,
11723 DNS_LOGMODULE_ZONE,
11725 "unable to remove masterfile "
11727 zone->masterfile, strbuf);
11729 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
11730 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
11732 zone_needdump(zone, 0);
11734 if (dump && zone->journal != NULL) {
11736 * The in-memory database just changed, and
11737 * because 'dump' is set, it didn't change by
11738 * being loaded from disk. Also, we have not
11739 * journaled diffs for this change.
11740 * Therefore, the on-disk journal is missing
11741 * the deltas for this change. Since it can
11742 * no longer be used to bring the zone
11743 * up-to-date, it is useless and should be
11746 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11747 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11748 "removing journal file");
11749 if (remove(zone->journal) < 0 && errno != ENOENT) {
11750 char strbuf[ISC_STRERRORSIZE];
11751 isc__strerror(errno, strbuf, sizeof(strbuf));
11752 isc_log_write(dns_lctx,
11753 DNS_LOGCATEGORY_GENERAL,
11754 DNS_LOGMODULE_ZONE,
11756 "unable to remove journal "
11758 zone->journal, strbuf);
11763 dns_db_closeversion(db, &ver, ISC_FALSE);
11765 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11766 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11767 "replacing zone database");
11769 if (zone->db != NULL)
11770 zone_detachdb(zone);
11771 zone_attachdb(zone, db);
11772 dns_db_settask(zone->db, zone->task);
11773 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
11774 return (ISC_R_SUCCESS);
11777 dns_db_closeversion(db, &ver, ISC_FALSE);
11781 /* The caller must hold the dblock as a writer. */
11783 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
11784 REQUIRE(zone->db == NULL && db != NULL);
11786 dns_db_attach(db, &zone->db);
11787 if (zone->acache != NULL) {
11788 isc_result_t result;
11789 result = dns_acache_setdb(zone->acache, db);
11790 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
11791 UNEXPECTED_ERROR(__FILE__, __LINE__,
11792 "dns_acache_setdb() failed: %s",
11793 isc_result_totext(result));
11798 /* The caller must hold the dblock as a writer. */
11800 zone_detachdb(dns_zone_t *zone) {
11801 REQUIRE(zone->db != NULL);
11803 if (zone->acache != NULL)
11804 (void)dns_acache_putdb(zone->acache, zone->db);
11805 dns_db_detach(&zone->db);
11809 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
11811 isc_boolean_t again = ISC_FALSE;
11812 unsigned int soacount;
11813 unsigned int nscount;
11814 isc_uint32_t serial, refresh, retry, expire, minimum;
11815 isc_result_t xfrresult = result;
11816 isc_boolean_t free_needed;
11818 REQUIRE(DNS_ZONE_VALID(zone));
11820 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11821 "zone transfer finished: %s", dns_result_totext(result));
11824 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
11825 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11826 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
11830 case ISC_R_SUCCESS:
11831 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11833 case DNS_R_UPTODATE:
11834 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11836 * Has the zone expired underneath us?
11838 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11839 if (zone->db == NULL) {
11840 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11845 * Update the zone structure's data from the actual
11850 INSIST(zone->db != NULL);
11851 result = zone_get_from_db(zone, zone->db, &nscount,
11852 &soacount, &serial, &refresh,
11853 &retry, &expire, &minimum, NULL);
11854 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11855 if (result == ISC_R_SUCCESS) {
11857 dns_zone_log(zone, ISC_LOG_ERROR,
11858 "transferred zone "
11859 "has %d SOA record%s", soacount,
11860 (soacount != 0) ? "s" : "");
11861 if (nscount == 0) {
11862 dns_zone_log(zone, ISC_LOG_ERROR,
11863 "transferred zone "
11864 "has no NS records");
11865 if (DNS_ZONE_FLAG(zone,
11866 DNS_ZONEFLG_HAVETIMERS)) {
11867 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
11868 zone->retry = DNS_ZONE_DEFAULTRETRY;
11870 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11874 zone->refresh = RANGE(refresh, zone->minrefresh,
11876 zone->retry = RANGE(retry, zone->minretry,
11878 zone->expire = RANGE(expire,
11879 zone->refresh + zone->retry,
11881 zone->minimum = minimum;
11882 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11886 * Set our next update/expire times.
11888 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
11889 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11890 zone->refreshtime = now;
11891 DNS_ZONE_TIME_ADD(&now, zone->expire,
11892 &zone->expiretime);
11894 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
11895 &zone->refreshtime);
11896 DNS_ZONE_TIME_ADD(&now, zone->expire,
11897 &zone->expiretime);
11899 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
11900 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
11901 if (zone->tsigkey != NULL) {
11902 char namebuf[DNS_NAME_FORMATSIZE];
11903 dns_name_format(&zone->tsigkey->name, namebuf,
11905 snprintf(buf, sizeof(buf), ": TSIG '%s'",
11909 dns_zone_log(zone, ISC_LOG_INFO,
11910 "transferred serial %u%s",
11915 * This is not necessary if we just performed a AXFR
11916 * however it is necessary for an IXFR / UPTODATE and
11917 * won't hurt with an AXFR.
11919 if (zone->masterfile != NULL || zone->journal != NULL) {
11920 result = ISC_R_FAILURE;
11921 if (zone->journal != NULL)
11922 result = isc_file_settime(zone->journal, &now);
11923 if (result != ISC_R_SUCCESS &&
11924 zone->masterfile != NULL)
11925 result = isc_file_settime(zone->masterfile,
11927 /* Someone removed the file from underneath us! */
11928 if (result == ISC_R_FILENOTFOUND &&
11929 zone->masterfile != NULL) {
11930 unsigned int delay = DNS_DUMP_DELAY;
11931 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY))
11933 zone_needdump(zone, delay);
11934 } else if (result != ISC_R_SUCCESS)
11935 dns_zone_log(zone, ISC_LOG_ERROR,
11936 "transfer: could not set file "
11937 "modification time of '%s': %s",
11939 dns_result_totext(result));
11941 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
11942 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
11945 case DNS_R_BADIXFR:
11946 /* Force retry with AXFR. */
11947 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
11953 * Skip to next failed / untried master.
11957 } while (zone->curmaster < zone->masterscnt &&
11958 zone->mastersok[zone->curmaster]);
11961 if (zone->curmaster >= zone->masterscnt) {
11962 zone->curmaster = 0;
11963 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11964 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11965 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
11966 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11967 while (zone->curmaster < zone->masterscnt &&
11968 zone->mastersok[zone->curmaster])
11972 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11974 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
11977 inc_stats(zone, dns_zonestatscounter_xfrfail);
11980 zone_settimer(zone, &now);
11983 * If creating the transfer object failed, zone->xfr is NULL.
11984 * Otherwise, we are called as the done callback of a zone
11985 * transfer object that just entered its shutting-down
11986 * state. Since we are no longer responsible for shutting
11987 * it down, we can detach our reference.
11989 if (zone->xfr != NULL)
11990 dns_xfrin_detach(&zone->xfr);
11992 if (zone->tsigkey != NULL)
11993 dns_tsigkey_detach(&zone->tsigkey);
11996 * Handle any deferred journal compaction.
11998 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
11999 result = dns_journal_compact(zone->mctx, zone->journal,
12000 zone->compact_serial,
12001 zone->journalsize);
12003 case ISC_R_SUCCESS:
12004 case ISC_R_NOSPACE:
12005 case ISC_R_NOTFOUND:
12006 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12007 "dns_journal_compact: %s",
12008 dns_result_totext(result));
12011 dns_zone_log(zone, ISC_LOG_ERROR,
12012 "dns_journal_compact failed: %s",
12013 dns_result_totext(result));
12016 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
12020 * This transfer finishing freed up a transfer quota slot.
12021 * Let any other zones waiting for quota have it.
12024 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12025 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
12026 zone->statelist = NULL;
12027 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
12028 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12032 * Retry with a different server if necessary.
12034 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12035 queue_soa_query(zone);
12037 INSIST(zone->irefs > 0);
12039 free_needed = exit_check(zone);
12046 zone_loaddone(void *arg, isc_result_t result) {
12047 static char me[] = "zone_loaddone";
12048 dns_load_t *load = arg;
12050 isc_result_t tresult;
12052 REQUIRE(DNS_LOAD_VALID(load));
12057 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
12058 if (tresult != ISC_R_SUCCESS &&
12059 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
12062 LOCK_ZONE(load->zone);
12063 (void)zone_postload(load->zone, load->db, load->loadtime, result);
12064 zonemgr_putio(&load->zone->readio);
12065 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
12067 * Leave the zone frozen if the reload fails.
12069 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
12070 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
12071 zone->update_disabled = ISC_FALSE;
12072 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
12073 UNLOCK_ZONE(load->zone);
12076 dns_db_detach(&load->db);
12077 if (load->zone->lctx != NULL)
12078 dns_loadctx_detach(&load->zone->lctx);
12079 dns_zone_idetach(&load->zone);
12080 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
12084 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
12085 REQUIRE(DNS_ZONE_VALID(zone));
12086 REQUIRE(table != NULL);
12087 REQUIRE(*table == NULL);
12090 if (zone->ssutable != NULL)
12091 dns_ssutable_attach(zone->ssutable, table);
12096 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
12097 REQUIRE(DNS_ZONE_VALID(zone));
12100 if (zone->ssutable != NULL)
12101 dns_ssutable_detach(&zone->ssutable);
12103 dns_ssutable_attach(table, &zone->ssutable);
12108 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
12109 REQUIRE(DNS_ZONE_VALID(zone));
12111 zone->sigvalidityinterval = interval;
12115 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
12116 REQUIRE(DNS_ZONE_VALID(zone));
12118 return (zone->sigvalidityinterval);
12122 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
12123 REQUIRE(DNS_ZONE_VALID(zone));
12125 zone->sigresigninginterval = interval;
12129 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
12130 REQUIRE(DNS_ZONE_VALID(zone));
12132 return (zone->sigresigninginterval);
12136 queue_xfrin(dns_zone_t *zone) {
12137 const char me[] = "queue_xfrin";
12138 isc_result_t result;
12139 dns_zonemgr_t *zmgr = zone->zmgr;
12143 INSIST(zone->statelist == NULL);
12145 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12146 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
12150 zone->statelist = &zmgr->waiting_for_xfrin;
12151 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12152 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12154 if (result == ISC_R_QUOTA) {
12155 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
12156 "zone transfer deferred due to quota");
12157 } else if (result != ISC_R_SUCCESS) {
12158 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
12159 "starting zone transfer: %s",
12160 isc_result_totext(result));
12165 * This event callback is called when a zone has received
12166 * any necessary zone transfer quota. This is the time
12167 * to go ahead and start the transfer.
12170 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
12171 isc_result_t result;
12172 dns_peer_t *peer = NULL;
12173 char master[ISC_SOCKADDR_FORMATSIZE];
12174 char source[ISC_SOCKADDR_FORMATSIZE];
12175 dns_rdatatype_t xfrtype;
12176 dns_zone_t *zone = event->ev_arg;
12177 isc_netaddr_t masterip;
12178 isc_sockaddr_t sourceaddr;
12179 isc_sockaddr_t masteraddr;
12181 const char *soa_before = "";
12185 INSIST(task == zone->task);
12187 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12188 result = ISC_R_CANCELED;
12194 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12195 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
12196 &zone->sourceaddr, &now))
12198 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12199 dns_zone_log(zone, ISC_LOG_INFO,
12200 "got_transfer_quota: skipping zone transfer as "
12201 "master %s (source %s) is unreachable (cached)",
12203 result = ISC_R_CANCELED;
12207 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12208 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
12210 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12211 soa_before = "SOA before ";
12213 * Decide whether we should request IXFR or AXFR.
12215 if (zone->db == NULL) {
12216 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12217 "no database exists yet, requesting AXFR of "
12218 "initial version from %s", master);
12219 xfrtype = dns_rdatatype_axfr;
12220 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
12221 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
12222 "set, requesting %sAXFR from %s", soa_before,
12224 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12225 xfrtype = dns_rdatatype_soa;
12227 xfrtype = dns_rdatatype_axfr;
12228 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
12229 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12230 "forced reload, requesting AXFR of "
12231 "initial version from %s", master);
12232 xfrtype = dns_rdatatype_axfr;
12233 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
12234 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12235 "retrying with AXFR from %s due to "
12236 "previous IXFR failure", master);
12237 xfrtype = dns_rdatatype_axfr;
12239 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
12242 isc_boolean_t use_ixfr = ISC_TRUE;
12243 if (peer != NULL &&
12244 dns_peer_getrequestixfr(peer, &use_ixfr) ==
12246 ; /* Using peer setting */
12248 use_ixfr = zone->view->requestixfr;
12250 if (use_ixfr == ISC_FALSE) {
12251 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12252 "IXFR disabled, requesting %sAXFR from %s",
12253 soa_before, master);
12254 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12255 xfrtype = dns_rdatatype_soa;
12257 xfrtype = dns_rdatatype_axfr;
12259 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12260 "requesting IXFR from %s", master);
12261 xfrtype = dns_rdatatype_ixfr;
12266 * Determine if we should attempt to sign the request with TSIG.
12268 result = ISC_R_NOTFOUND;
12270 * First, look for a tsig key in the master statement, then
12271 * try for a server key.
12273 if ((zone->masterkeynames != NULL) &&
12274 (zone->masterkeynames[zone->curmaster] != NULL)) {
12275 dns_view_t *view = dns_zone_getview(zone);
12276 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12277 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
12279 if (zone->tsigkey == NULL)
12280 result = dns_view_getpeertsig(zone->view, &masterip,
12283 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
12284 dns_zone_log(zone, ISC_LOG_ERROR,
12285 "could not get TSIG key for zone transfer: %s",
12286 isc_result_totext(result));
12290 masteraddr = zone->masteraddr;
12291 sourceaddr = zone->sourceaddr;
12293 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
12294 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
12295 zone->tsigkey, zone->mctx,
12296 zone->zmgr->timermgr, zone->zmgr->socketmgr,
12297 zone->task, zone_xfrdone, &zone->xfr);
12298 if (result == ISC_R_SUCCESS) {
12300 if (xfrtype == dns_rdatatype_axfr) {
12301 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12302 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
12304 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
12305 } else if (xfrtype == dns_rdatatype_ixfr) {
12306 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12307 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
12309 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
12315 * Any failure in this function is handled like a failed
12316 * zone transfer. This ensures that we get removed from
12317 * zmgr->xfrin_in_progress.
12319 if (result != ISC_R_SUCCESS)
12320 zone_xfrdone(zone, result);
12322 isc_event_free(&event);
12326 * Update forwarding support.
12330 forward_destroy(dns_forward_t *forward) {
12332 forward->magic = 0;
12333 if (forward->request != NULL)
12334 dns_request_destroy(&forward->request);
12335 if (forward->msgbuf != NULL)
12336 isc_buffer_free(&forward->msgbuf);
12337 if (forward->zone != NULL) {
12338 LOCK(&forward->zone->lock);
12339 if (ISC_LINK_LINKED(forward, link))
12340 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
12341 UNLOCK(&forward->zone->lock);
12342 dns_zone_idetach(&forward->zone);
12344 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
12347 static isc_result_t
12348 sendtomaster(dns_forward_t *forward) {
12349 isc_result_t result;
12350 isc_sockaddr_t src;
12352 LOCK_ZONE(forward->zone);
12354 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
12355 UNLOCK_ZONE(forward->zone);
12356 return (ISC_R_CANCELED);
12359 if (forward->which >= forward->zone->masterscnt) {
12360 UNLOCK_ZONE(forward->zone);
12361 return (ISC_R_NOMORE);
12364 forward->addr = forward->zone->masters[forward->which];
12366 * Always use TCP regardless of whether the original update
12368 * XXX The timeout may but a bit small if we are far down a
12369 * transfer graph and the master has to try several masters.
12371 switch (isc_sockaddr_pf(&forward->addr)) {
12373 src = forward->zone->xfrsource4;
12376 src = forward->zone->xfrsource6;
12379 result = ISC_R_NOTIMPLEMENTED;
12382 result = dns_request_createraw(forward->zone->view->requestmgr,
12384 &src, &forward->addr,
12385 DNS_REQUESTOPT_TCP, 15 /* XXX */,
12386 forward->zone->task,
12387 forward_callback, forward,
12388 &forward->request);
12389 if (result == ISC_R_SUCCESS) {
12390 if (!ISC_LINK_LINKED(forward, link))
12391 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
12395 UNLOCK_ZONE(forward->zone);
12400 forward_callback(isc_task_t *task, isc_event_t *event) {
12401 const char me[] = "forward_callback";
12402 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12403 dns_message_t *msg = NULL;
12404 char master[ISC_SOCKADDR_FORMATSIZE];
12405 isc_result_t result;
12406 dns_forward_t *forward;
12411 forward = revent->ev_arg;
12412 INSIST(DNS_FORWARD_VALID(forward));
12413 zone = forward->zone;
12414 INSIST(DNS_ZONE_VALID(zone));
12418 isc_sockaddr_format(&forward->addr, master, sizeof(master));
12420 if (revent->result != ISC_R_SUCCESS) {
12421 dns_zone_log(zone, ISC_LOG_INFO,
12422 "could not forward dynamic update to %s: %s",
12423 master, dns_result_totext(revent->result));
12427 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12428 if (result != ISC_R_SUCCESS)
12431 result = dns_request_getresponse(revent->request, msg,
12432 DNS_MESSAGEPARSE_PRESERVEORDER |
12433 DNS_MESSAGEPARSE_CLONEBUFFER);
12434 if (result != ISC_R_SUCCESS)
12437 switch (msg->rcode) {
12439 * Pass these rcodes back to client.
12441 case dns_rcode_noerror:
12442 case dns_rcode_yxdomain:
12443 case dns_rcode_yxrrset:
12444 case dns_rcode_nxrrset:
12445 case dns_rcode_refused:
12446 case dns_rcode_nxdomain:
12449 /* These should not occur if the masters/zone are valid. */
12450 case dns_rcode_notzone:
12451 case dns_rcode_notauth: {
12455 isc_buffer_init(&rb, rcode, sizeof(rcode));
12456 (void)dns_rcode_totext(msg->rcode, &rb);
12457 dns_zone_log(zone, ISC_LOG_WARNING,
12458 "forwarding dynamic update: "
12459 "unexpected response: master %s returned: %.*s",
12460 master, (int)rb.used, rcode);
12464 /* Try another server for these rcodes. */
12465 case dns_rcode_formerr:
12466 case dns_rcode_servfail:
12467 case dns_rcode_notimp:
12468 case dns_rcode_badvers:
12473 /* call callback */
12474 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
12476 dns_request_destroy(&forward->request);
12477 forward_destroy(forward);
12478 isc_event_free(&event);
12483 dns_message_destroy(&msg);
12484 isc_event_free(&event);
12486 dns_request_destroy(&forward->request);
12487 result = sendtomaster(forward);
12488 if (result != ISC_R_SUCCESS) {
12489 /* call callback */
12490 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12491 "exhausted dynamic update forwarder list");
12492 (forward->callback)(forward->callback_arg, result, NULL);
12493 forward_destroy(forward);
12498 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
12499 dns_updatecallback_t callback, void *callback_arg)
12501 dns_forward_t *forward;
12502 isc_result_t result;
12505 REQUIRE(DNS_ZONE_VALID(zone));
12506 REQUIRE(msg != NULL);
12507 REQUIRE(callback != NULL);
12509 forward = isc_mem_get(zone->mctx, sizeof(*forward));
12510 if (forward == NULL)
12511 return (ISC_R_NOMEMORY);
12513 forward->request = NULL;
12514 forward->zone = NULL;
12515 forward->msgbuf = NULL;
12516 forward->which = 0;
12518 forward->callback = callback;
12519 forward->callback_arg = callback_arg;
12520 ISC_LINK_INIT(forward, link);
12521 forward->magic = FORWARD_MAGIC;
12523 mr = dns_message_getrawmessage(msg);
12525 result = ISC_R_UNEXPECTEDEND;
12529 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
12530 if (result != ISC_R_SUCCESS)
12532 result = isc_buffer_copyregion(forward->msgbuf, mr);
12533 if (result != ISC_R_SUCCESS)
12536 isc_mem_attach(zone->mctx, &forward->mctx);
12537 dns_zone_iattach(zone, &forward->zone);
12538 result = sendtomaster(forward);
12541 if (result != ISC_R_SUCCESS) {
12542 forward_destroy(forward);
12548 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
12549 REQUIRE(DNS_ZONE_VALID(zone));
12550 REQUIRE(next != NULL && *next == NULL);
12552 *next = ISC_LIST_NEXT(zone, link);
12554 return (ISC_R_NOMORE);
12556 return (ISC_R_SUCCESS);
12560 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
12561 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12562 REQUIRE(first != NULL && *first == NULL);
12564 *first = ISC_LIST_HEAD(zmgr->zones);
12565 if (*first == NULL)
12566 return (ISC_R_NOMORE);
12568 return (ISC_R_SUCCESS);
12576 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
12577 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
12578 dns_zonemgr_t **zmgrp)
12580 dns_zonemgr_t *zmgr;
12581 isc_result_t result;
12582 isc_interval_t interval;
12584 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
12586 return (ISC_R_NOMEMORY);
12589 isc_mem_attach(mctx, &zmgr->mctx);
12590 zmgr->taskmgr = taskmgr;
12591 zmgr->timermgr = timermgr;
12592 zmgr->socketmgr = socketmgr;
12593 zmgr->zonetasks = NULL;
12596 ISC_LIST_INIT(zmgr->zones);
12597 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
12598 ISC_LIST_INIT(zmgr->xfrin_in_progress);
12599 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
12600 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
12601 if (result != ISC_R_SUCCESS)
12604 zmgr->transfersin = 10;
12605 zmgr->transfersperns = 2;
12607 /* Unreachable lock. */
12608 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
12609 if (result != ISC_R_SUCCESS)
12612 /* Create a single task for queueing of SOA queries. */
12613 result = isc_task_create(taskmgr, 1, &zmgr->task);
12614 if (result != ISC_R_SUCCESS)
12617 isc_task_setname(zmgr->task, "zmgr", zmgr);
12618 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
12620 if (result != ISC_R_SUCCESS)
12623 /* default to 20 refresh queries / notifies per second. */
12624 isc_interval_set(&interval, 0, 1000000000/2);
12625 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
12626 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12627 isc_ratelimiter_setpertic(zmgr->rl, 10);
12630 zmgr->ioactive = 0;
12631 ISC_LIST_INIT(zmgr->high);
12632 ISC_LIST_INIT(zmgr->low);
12634 result = isc_mutex_init(&zmgr->iolock);
12635 if (result != ISC_R_SUCCESS)
12638 zmgr->magic = ZONEMGR_MAGIC;
12641 return (ISC_R_SUCCESS);
12645 DESTROYLOCK(&zmgr->iolock);
12648 isc_ratelimiter_detach(&zmgr->rl);
12650 isc_task_detach(&zmgr->task);
12652 isc_rwlock_destroy(&zmgr->urlock);
12654 isc_rwlock_destroy(&zmgr->rwlock);
12656 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12657 isc_mem_detach(&mctx);
12662 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12663 isc_result_t result;
12665 REQUIRE(DNS_ZONE_VALID(zone));
12666 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12668 if (zmgr->zonetasks == NULL)
12669 return (ISC_R_FAILURE);
12671 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12673 REQUIRE(zone->task == NULL);
12674 REQUIRE(zone->timer == NULL);
12675 REQUIRE(zone->zmgr == NULL);
12677 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
12680 * Set the task name. The tag will arbitrarily point to one
12681 * of the zones sharing the task (in practice, the one
12682 * to be managed last).
12684 isc_task_setname(zone->task, "zone", zone);
12686 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
12688 zone->task, zone_timer, zone,
12691 if (result != ISC_R_SUCCESS)
12695 * The timer "holds" a iref.
12698 INSIST(zone->irefs != 0);
12700 ISC_LIST_APPEND(zmgr->zones, zone, link);
12707 isc_task_detach(&zone->task);
12711 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12716 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12717 isc_boolean_t free_now = ISC_FALSE;
12719 REQUIRE(DNS_ZONE_VALID(zone));
12720 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12721 REQUIRE(zone->zmgr == zmgr);
12723 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12726 ISC_LIST_UNLINK(zmgr->zones, zone, link);
12729 if (zmgr->refs == 0)
12730 free_now = ISC_TRUE;
12733 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12736 zonemgr_free(zmgr);
12737 ENSURE(zone->zmgr == NULL);
12741 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
12742 REQUIRE(DNS_ZONEMGR_VALID(source));
12743 REQUIRE(target != NULL && *target == NULL);
12745 RWLOCK(&source->rwlock, isc_rwlocktype_write);
12746 REQUIRE(source->refs > 0);
12748 INSIST(source->refs > 0);
12749 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
12754 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
12755 dns_zonemgr_t *zmgr;
12756 isc_boolean_t free_now = ISC_FALSE;
12758 REQUIRE(zmgrp != NULL);
12760 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12762 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12764 if (zmgr->refs == 0)
12765 free_now = ISC_TRUE;
12766 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12769 zonemgr_free(zmgr);
12774 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
12777 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12779 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12780 for (p = ISC_LIST_HEAD(zmgr->zones);
12782 p = ISC_LIST_NEXT(p, link))
12784 dns_zone_maintenance(p);
12786 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12789 * Recent configuration changes may have increased the
12790 * amount of available transfers quota. Make sure any
12791 * transfers currently blocked on quota get started if
12794 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12795 zmgr_resume_xfrs(zmgr, ISC_TRUE);
12796 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12797 return (ISC_R_SUCCESS);
12801 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
12803 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12805 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12806 zmgr_resume_xfrs(zmgr, ISC_TRUE);
12807 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12811 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
12814 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12816 isc_ratelimiter_shutdown(zmgr->rl);
12818 if (zmgr->task != NULL)
12819 isc_task_destroy(&zmgr->task);
12820 if (zmgr->zonetasks != NULL)
12821 isc_taskpool_destroy(&zmgr->zonetasks);
12823 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12824 for (zone = ISC_LIST_HEAD(zmgr->zones);
12826 zone = ISC_LIST_NEXT(zone, link))
12829 forward_cancel(zone);
12832 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12836 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
12837 isc_result_t result;
12838 int ntasks = num_zones / 100;
12839 isc_taskpool_t *pool = NULL;
12841 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12844 * For anything fewer than 1000 zones we use 10 tasks in
12845 * the task pool. More than that, and we'll scale at one
12846 * task per 100 zones.
12851 /* Create or resize the zone task pool. */
12852 if (zmgr->zonetasks == NULL)
12853 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
12856 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
12858 if (result == ISC_R_SUCCESS)
12859 zmgr->zonetasks = pool;
12865 zonemgr_free(dns_zonemgr_t *zmgr) {
12868 INSIST(zmgr->refs == 0);
12869 INSIST(ISC_LIST_EMPTY(zmgr->zones));
12873 DESTROYLOCK(&zmgr->iolock);
12874 isc_ratelimiter_detach(&zmgr->rl);
12876 isc_rwlock_destroy(&zmgr->urlock);
12877 isc_rwlock_destroy(&zmgr->rwlock);
12879 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12880 isc_mem_detach(&mctx);
12884 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
12885 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12887 zmgr->transfersin = value;
12891 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
12892 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12894 return (zmgr->transfersin);
12898 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
12899 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12901 zmgr->transfersperns = value;
12905 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
12906 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12908 return (zmgr->transfersperns);
12912 * Try to start a new incoming zone transfer to fill a quota
12913 * slot that was just vacated.
12916 * The zone manager is locked by the caller.
12919 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
12923 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
12927 isc_result_t result;
12928 next = ISC_LIST_NEXT(zone, statelink);
12929 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12930 if (result == ISC_R_SUCCESS) {
12934 * We successfully filled the slot. We're done.
12937 } else if (result == ISC_R_QUOTA) {
12939 * Not enough quota. This is probably the per-server
12940 * quota, because we usually get called when a unit of
12941 * global quota has just been freed. Try the next
12942 * zone, it may succeed if it uses another master.
12946 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12947 "starting zone transfer: %s",
12948 isc_result_totext(result));
12955 * Try to start an incoming zone transfer for 'zone', quota permitting.
12958 * The zone manager is locked by the caller.
12961 * ISC_R_SUCCESS There was enough quota and we attempted to
12962 * start a transfer. zone_xfrdone() has been or will
12964 * ISC_R_QUOTA Not enough quota.
12967 static isc_result_t
12968 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12969 dns_peer_t *peer = NULL;
12970 isc_netaddr_t masterip;
12971 isc_uint32_t nxfrsin, nxfrsperns;
12973 isc_uint32_t maxtransfersin, maxtransfersperns;
12977 * If we are exiting just pretend we got quota so the zone will
12978 * be cleaned up in the zone's task context.
12981 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12987 * Find any configured information about the server we'd
12988 * like to transfer this zone from.
12990 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12991 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
12995 * Determine the total maximum number of simultaneous
12996 * transfers allowed, and the maximum for this specific
12999 maxtransfersin = zmgr->transfersin;
13000 maxtransfersperns = zmgr->transfersperns;
13002 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
13005 * Count the total number of transfers that are in progress,
13006 * and the number of transfers in progress from this master.
13007 * We linearly scan a list of all transfers; if this turns
13008 * out to be too slow, we could hash on the master address.
13010 nxfrsin = nxfrsperns = 0;
13011 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13013 x = ISC_LIST_NEXT(x, statelink))
13018 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
13022 if (isc_netaddr_equal(&xip, &masterip))
13026 /* Enforce quota. */
13027 if (nxfrsin >= maxtransfersin)
13028 return (ISC_R_QUOTA);
13030 if (nxfrsperns >= maxtransfersperns)
13031 return (ISC_R_QUOTA);
13035 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
13036 * list and send it an event to let it start the actual transfer in the
13037 * context of its own task.
13039 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
13040 got_transfer_quota, zone, sizeof(isc_event_t));
13042 return (ISC_R_NOMEMORY);
13045 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
13046 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
13047 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
13048 zone->statelist = &zmgr->xfrin_in_progress;
13049 isc_task_send(zone->task, &e);
13050 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
13053 return (ISC_R_SUCCESS);
13057 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
13059 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13060 REQUIRE(iolimit > 0);
13062 zmgr->iolimit = iolimit;
13066 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
13068 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13070 return (zmgr->iolimit);
13074 * Get permission to request a file handle from the OS.
13075 * An event will be sent to action when one is available.
13076 * There are two queues available (high and low), the high
13077 * queue will be serviced before the low one.
13079 * zonemgr_putio() must be called after the event is delivered to
13083 static isc_result_t
13084 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
13085 isc_task_t *task, isc_taskaction_t action, void *arg,
13089 isc_boolean_t queue;
13091 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13092 REQUIRE(iop != NULL && *iop == NULL);
13094 io = isc_mem_get(zmgr->mctx, sizeof(*io));
13096 return (ISC_R_NOMEMORY);
13097 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
13098 action, arg, sizeof(*io->event));
13099 if (io->event == NULL) {
13100 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13101 return (ISC_R_NOMEMORY);
13106 isc_task_attach(task, &io->task);
13107 ISC_LINK_INIT(io, link);
13108 io->magic = IO_MAGIC;
13110 LOCK(&zmgr->iolock);
13112 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
13115 ISC_LIST_APPEND(zmgr->high, io, link);
13117 ISC_LIST_APPEND(zmgr->low, io, link);
13119 UNLOCK(&zmgr->iolock);
13123 isc_task_send(io->task, &io->event);
13125 return (ISC_R_SUCCESS);
13129 zonemgr_putio(dns_io_t **iop) {
13132 dns_zonemgr_t *zmgr;
13134 REQUIRE(iop != NULL);
13136 REQUIRE(DNS_IO_VALID(io));
13140 INSIST(!ISC_LINK_LINKED(io, link));
13141 INSIST(io->event == NULL);
13144 isc_task_detach(&io->task);
13146 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13148 LOCK(&zmgr->iolock);
13149 INSIST(zmgr->ioactive > 0);
13151 next = HEAD(zmgr->high);
13153 next = HEAD(zmgr->low);
13154 if (next != NULL) {
13156 ISC_LIST_UNLINK(zmgr->high, next, link);
13158 ISC_LIST_UNLINK(zmgr->low, next, link);
13159 INSIST(next->event != NULL);
13161 UNLOCK(&zmgr->iolock);
13163 isc_task_send(next->task, &next->event);
13167 zonemgr_cancelio(dns_io_t *io) {
13168 isc_boolean_t send_event = ISC_FALSE;
13170 REQUIRE(DNS_IO_VALID(io));
13173 * If we are queued to be run then dequeue.
13175 LOCK(&io->zmgr->iolock);
13176 if (ISC_LINK_LINKED(io, link)) {
13178 ISC_LIST_UNLINK(io->zmgr->high, io, link);
13180 ISC_LIST_UNLINK(io->zmgr->low, io, link);
13182 send_event = ISC_TRUE;
13183 INSIST(io->event != NULL);
13185 UNLOCK(&io->zmgr->iolock);
13187 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
13188 isc_task_send(io->task, &io->event);
13193 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
13196 isc_result_t result;
13198 buflen = strlen(path) + strlen(templat) + 2;
13200 buf = isc_mem_get(zone->mctx, buflen);
13204 result = isc_file_template(path, templat, buf, buflen);
13205 if (result != ISC_R_SUCCESS)
13208 result = isc_file_renameunique(path, buf);
13209 if (result != ISC_R_SUCCESS)
13212 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
13213 "renaming file to '%s' for failure analysis and "
13214 "retransferring.", path, buf);
13217 isc_mem_put(zone->mctx, buf, buflen);
13221 /* Hook for ondestroy notification from a database. */
13224 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
13225 dns_db_t *db = event->sender;
13228 isc_event_free(&event);
13230 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13231 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13232 "database (%p) destroyed", (void*) db);
13237 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
13238 isc_interval_t interval;
13239 isc_uint32_t s, ns;
13240 isc_uint32_t pertic;
13241 isc_result_t result;
13243 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13252 } else if (value <= 10) {
13254 ns = 1000000000 / value;
13258 ns = (1000000000 / value) * 10;
13262 isc_interval_set(&interval, s, ns);
13263 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
13264 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13265 isc_ratelimiter_setpertic(zmgr->rl, pertic);
13267 zmgr->serialqueryrate = value;
13271 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
13272 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13274 return (zmgr->serialqueryrate);
13278 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13279 isc_sockaddr_t *local, isc_time_t *now)
13282 isc_rwlocktype_t locktype;
13283 isc_result_t result;
13284 isc_uint32_t seconds = isc_time_seconds(now);
13286 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13288 locktype = isc_rwlocktype_read;
13289 RWLOCK(&zmgr->urlock, locktype);
13290 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13291 if (zmgr->unreachable[i].expire >= seconds &&
13292 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13293 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13294 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13295 if (result == ISC_R_SUCCESS) {
13296 locktype = isc_rwlocktype_write;
13297 zmgr->unreachable[i].last = seconds;
13302 RWUNLOCK(&zmgr->urlock, locktype);
13303 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
13307 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13308 isc_sockaddr_t *local)
13311 isc_rwlocktype_t locktype;
13312 isc_result_t result;
13314 char master[ISC_SOCKADDR_FORMATSIZE];
13315 char source[ISC_SOCKADDR_FORMATSIZE];
13317 isc_sockaddr_format(remote, master, sizeof(master));
13318 isc_sockaddr_format(local, source, sizeof(source));
13320 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13322 locktype = isc_rwlocktype_read;
13323 RWLOCK(&zmgr->urlock, locktype);
13324 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13325 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13326 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13327 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13328 if (result == ISC_R_SUCCESS) {
13329 locktype = isc_rwlocktype_write;
13330 zmgr->unreachable[i].expire = 0;
13331 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13332 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
13333 "master %s (source %s) deleted "
13334 "from unreachable cache",
13340 RWUNLOCK(&zmgr->urlock, locktype);
13344 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13345 isc_sockaddr_t *local, isc_time_t *now)
13347 isc_uint32_t seconds = isc_time_seconds(now);
13348 isc_uint32_t last = seconds;
13349 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
13351 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13353 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
13354 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13355 /* Existing entry? */
13356 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13357 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
13360 if (zmgr->unreachable[i].expire < seconds)
13362 /* Least recently used slot? */
13363 if (zmgr->unreachable[i].last < last) {
13364 last = zmgr->unreachable[i].last;
13368 if (i < UNREACH_CHACHE_SIZE) {
13370 * Found a existing entry. Update the expire timer and
13371 * last usage timestamps.
13373 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
13374 zmgr->unreachable[i].last = seconds;
13375 } else if (slot != UNREACH_CHACHE_SIZE) {
13377 * Found a empty slot. Add a new entry to the cache.
13379 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
13380 zmgr->unreachable[slot].last = seconds;
13381 zmgr->unreachable[slot].remote = *remote;
13382 zmgr->unreachable[slot].local = *local;
13385 * Replace the least recently used entry in the cache.
13387 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
13388 zmgr->unreachable[oldest].last = seconds;
13389 zmgr->unreachable[oldest].remote = *remote;
13390 zmgr->unreachable[oldest].local = *local;
13392 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
13396 dns_zone_forcereload(dns_zone_t *zone) {
13397 REQUIRE(DNS_ZONE_VALID(zone));
13399 if (zone->type == dns_zone_master)
13403 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13405 dns_zone_refresh(zone);
13409 dns_zone_isforced(dns_zone_t *zone) {
13410 REQUIRE(DNS_ZONE_VALID(zone));
13412 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
13416 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
13418 * This function is obsoleted.
13422 return (ISC_R_NOTIMPLEMENTED);
13426 dns_zone_getstatscounters(dns_zone_t *zone) {
13428 * This function is obsoleted.
13435 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
13436 REQUIRE(DNS_ZONE_VALID(zone));
13437 REQUIRE(zone->stats == NULL);
13440 zone->stats = NULL;
13441 isc_stats_attach(stats, &zone->stats);
13446 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
13447 REQUIRE(DNS_ZONE_VALID(zone));
13450 if (zone->requeststats_on && stats == NULL)
13451 zone->requeststats_on = ISC_FALSE;
13452 else if (!zone->requeststats_on && stats != NULL) {
13453 if (zone->requeststats == NULL) {
13454 isc_stats_attach(stats, &zone->requeststats);
13455 zone->requeststats_on = ISC_TRUE;
13464 dns_zone_getrequeststats(dns_zone_t *zone) {
13466 * We don't lock zone for efficiency reason. This is not catastrophic
13467 * because requeststats must always be valid when requeststats_on is
13469 * Some counters may be incremented while requeststats_on is becoming
13470 * false, or some cannot be incremented just after the statistics are
13471 * installed, but it shouldn't matter much in practice.
13473 if (zone->requeststats_on)
13474 return (zone->requeststats);
13480 dns_zone_dialup(dns_zone_t *zone) {
13482 REQUIRE(DNS_ZONE_VALID(zone));
13484 zone_debuglog(zone, "dns_zone_dialup", 3,
13485 "notify = %d, refresh = %d",
13486 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
13487 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
13489 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
13490 dns_zone_notify(zone);
13491 if (zone->type != dns_zone_master &&
13492 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
13493 dns_zone_refresh(zone);
13497 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
13498 REQUIRE(DNS_ZONE_VALID(zone));
13501 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
13502 DNS_ZONEFLG_DIALREFRESH |
13503 DNS_ZONEFLG_NOREFRESH);
13505 case dns_dialuptype_no:
13507 case dns_dialuptype_yes:
13508 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
13509 DNS_ZONEFLG_DIALREFRESH |
13510 DNS_ZONEFLG_NOREFRESH));
13512 case dns_dialuptype_notify:
13513 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13515 case dns_dialuptype_notifypassive:
13516 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13517 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13519 case dns_dialuptype_refresh:
13520 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
13521 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13523 case dns_dialuptype_passive:
13524 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13533 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
13534 isc_result_t result = ISC_R_SUCCESS;
13536 REQUIRE(DNS_ZONE_VALID(zone));
13539 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
13546 dns_zone_getkeydirectory(dns_zone_t *zone) {
13547 REQUIRE(DNS_ZONE_VALID(zone));
13549 return (zone->keydirectory);
13553 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
13555 unsigned int count = 0;
13557 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13559 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13561 case DNS_ZONESTATE_XFERRUNNING:
13562 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13564 zone = ISC_LIST_NEXT(zone, statelink))
13567 case DNS_ZONESTATE_XFERDEFERRED:
13568 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
13570 zone = ISC_LIST_NEXT(zone, statelink))
13573 case DNS_ZONESTATE_SOAQUERY:
13574 for (zone = ISC_LIST_HEAD(zmgr->zones);
13576 zone = ISC_LIST_NEXT(zone, link))
13577 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
13580 case DNS_ZONESTATE_ANY:
13581 for (zone = ISC_LIST_HEAD(zmgr->zones);
13583 zone = ISC_LIST_NEXT(zone, link)) {
13584 dns_view_t *view = zone->view;
13585 if (view != NULL && strcmp(view->name, "_bind") == 0)
13594 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13600 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
13601 isc_boolean_t ok = ISC_TRUE;
13602 isc_boolean_t fail = ISC_FALSE;
13603 char namebuf[DNS_NAME_FORMATSIZE];
13604 char namebuf2[DNS_NAME_FORMATSIZE];
13605 char typebuf[DNS_RDATATYPE_FORMATSIZE];
13606 int level = ISC_LOG_WARNING;
13609 REQUIRE(DNS_ZONE_VALID(zone));
13611 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
13612 return (ISC_R_SUCCESS);
13614 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
13615 level = ISC_LOG_ERROR;
13619 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
13621 dns_name_format(name, namebuf, sizeof(namebuf));
13622 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13623 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
13624 dns_result_totext(DNS_R_BADOWNERNAME));
13626 return (DNS_R_BADOWNERNAME);
13629 dns_name_init(&bad, NULL);
13630 ok = dns_rdata_checknames(rdata, name, &bad);
13632 dns_name_format(name, namebuf, sizeof(namebuf));
13633 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
13634 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13635 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
13636 namebuf2, dns_result_totext(DNS_R_BADNAME));
13638 return (DNS_R_BADNAME);
13641 return (ISC_R_SUCCESS);
13645 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
13646 REQUIRE(DNS_ZONE_VALID(zone));
13647 zone->checkmx = checkmx;
13651 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
13652 REQUIRE(DNS_ZONE_VALID(zone));
13653 zone->checksrv = checksrv;
13657 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
13658 REQUIRE(DNS_ZONE_VALID(zone));
13659 zone->checkns = checkns;
13663 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
13664 REQUIRE(DNS_ZONE_VALID(zone));
13667 zone->isself = isself;
13668 zone->isselfarg = arg;
13673 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
13674 REQUIRE(DNS_ZONE_VALID(zone));
13677 zone->notifydelay = delay;
13682 dns_zone_getnotifydelay(dns_zone_t *zone) {
13683 REQUIRE(DNS_ZONE_VALID(zone));
13685 return (zone->notifydelay);
13689 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
13690 isc_uint16_t keyid, isc_boolean_t delete)
13692 isc_result_t result;
13693 REQUIRE(DNS_ZONE_VALID(zone));
13695 dns_zone_log(zone, ISC_LOG_NOTICE,
13696 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
13699 result = zone_signwithkey(zone, algorithm, keyid, delete);
13705 static const char *hex = "0123456789ABCDEF";
13708 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
13709 isc_result_t result;
13710 char salt[255*2+1];
13713 REQUIRE(DNS_ZONE_VALID(zone));
13715 if (nsec3param->salt_length != 0) {
13716 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
13717 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
13718 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
13719 salt[j++] = hex[nsec3param->salt[i] & 0xf];
13724 dns_zone_log(zone, ISC_LOG_NOTICE,
13725 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
13726 nsec3param->hash, nsec3param->iterations,
13729 result = zone_addnsec3chain(zone, nsec3param);
13736 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
13737 REQUIRE(DNS_ZONE_VALID(zone));
13741 zone->nodes = nodes;
13745 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
13746 REQUIRE(DNS_ZONE_VALID(zone));
13749 * We treat signatures as a signed value so explicitly
13750 * limit its range here.
13752 if (signatures > ISC_INT32_MAX)
13753 signatures = ISC_INT32_MAX;
13754 else if (signatures == 0)
13756 zone->signatures = signatures;
13760 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
13761 REQUIRE(DNS_ZONE_VALID(zone));
13762 zone->privatetype = type;
13766 dns_zone_getprivatetype(dns_zone_t *zone) {
13767 REQUIRE(DNS_ZONE_VALID(zone));
13768 return (zone->privatetype);
13771 static isc_result_t
13772 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
13773 isc_boolean_t delete)
13775 dns_signing_t *signing;
13776 dns_signing_t *current;
13777 isc_result_t result = ISC_R_SUCCESS;
13780 signing = isc_mem_get(zone->mctx, sizeof *signing);
13781 if (signing == NULL)
13782 return (ISC_R_NOMEMORY);
13784 signing->magic = 0;
13785 signing->db = NULL;
13786 signing->dbiterator = NULL;
13787 signing->algorithm = algorithm;
13788 signing->keyid = keyid;
13789 signing->delete = delete;
13790 signing->done = ISC_FALSE;
13794 for (current = ISC_LIST_HEAD(zone->signing);
13796 current = ISC_LIST_NEXT(current, link)) {
13797 if (current->db == zone->db &&
13798 current->algorithm == signing->algorithm &&
13799 current->keyid == signing->keyid) {
13800 if (current->delete != signing->delete)
13801 current->done = ISC_TRUE;
13807 if (zone->db != NULL) {
13808 dns_db_attach(zone->db, &signing->db);
13809 result = dns_db_createiterator(signing->db, 0,
13810 &signing->dbiterator);
13812 if (result == ISC_R_SUCCESS)
13813 result = dns_dbiterator_first(signing->dbiterator);
13814 if (result == ISC_R_SUCCESS) {
13815 dns_dbiterator_pause(signing->dbiterator);
13816 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
13818 if (isc_time_isepoch(&zone->signingtime)) {
13819 zone->signingtime = now;
13820 if (zone->task != NULL)
13821 zone_settimer(zone, &now);
13825 result = ISC_R_NOTFOUND;
13828 if (signing != NULL) {
13829 if (signing->db != NULL)
13830 dns_db_detach(&signing->db);
13831 if (signing->dbiterator != NULL)
13832 dns_dbiterator_destroy(&signing->dbiterator);
13833 isc_mem_put(zone->mctx, signing, sizeof *signing);
13839 logmsg(const char *format, ...) {
13841 va_start(args, format);
13842 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
13843 ISC_LOG_DEBUG(1), format, args);
13848 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
13849 dns_dnsseckey_t *key;
13850 while (!ISC_LIST_EMPTY(*list)) {
13851 key = ISC_LIST_HEAD(*list);
13852 ISC_LIST_UNLINK(*list, key, link);
13853 dns_dnsseckey_destroy(mctx, &key);
13857 /* Called once; *timep should be set to the current time. */
13858 static isc_result_t
13859 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
13860 isc_result_t result;
13861 isc_stdtime_t now, then = 0, event;
13866 for (i = 0; i <= DST_MAX_TIMES; i++) {
13867 result = dst_key_gettime(key, i, &event);
13868 if (result == ISC_R_SUCCESS && event > now &&
13869 (then == 0 || event < then))
13875 return (ISC_R_SUCCESS);
13878 return (ISC_R_NOTFOUND);
13881 static isc_result_t
13882 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
13883 const dns_rdata_t *rdata, isc_boolean_t *flag)
13885 dns_rdataset_t rdataset;
13886 dns_dbnode_t *node = NULL;
13887 isc_result_t result;
13889 dns_rdataset_init(&rdataset);
13890 if (rdata->type == dns_rdatatype_nsec3)
13891 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
13893 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
13894 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
13895 (isc_stdtime_t) 0, &rdataset, NULL);
13896 if (result == ISC_R_NOTFOUND) {
13898 result = ISC_R_SUCCESS;
13902 for (result = dns_rdataset_first(&rdataset);
13903 result == ISC_R_SUCCESS;
13904 result = dns_rdataset_next(&rdataset)) {
13905 dns_rdata_t myrdata = DNS_RDATA_INIT;
13906 dns_rdataset_current(&rdataset, &myrdata);
13907 if (!dns_rdata_compare(&myrdata, rdata))
13910 dns_rdataset_disassociate(&rdataset);
13911 if (result == ISC_R_SUCCESS) {
13913 } else if (result == ISC_R_NOMORE) {
13915 result = ISC_R_SUCCESS;
13920 dns_db_detachnode(db, &node);
13925 * Add records to signal the state of signing or of key removal.
13927 static isc_result_t
13928 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
13929 dns_dbversion_t *ver, dns_diff_t *diff,
13930 isc_boolean_t sign_all)
13932 dns_difftuple_t *tuple, *newtuple = NULL;
13933 dns_rdata_dnskey_t dnskey;
13934 dns_rdata_t rdata = DNS_RDATA_INIT;
13935 isc_boolean_t flag;
13937 isc_result_t result = ISC_R_SUCCESS;
13938 isc_uint16_t keyid;
13939 unsigned char buf[5];
13940 dns_name_t *name = dns_db_origin(db);
13942 for (tuple = ISC_LIST_HEAD(diff->tuples);
13944 tuple = ISC_LIST_NEXT(tuple, link)) {
13945 if (tuple->rdata.type != dns_rdatatype_dnskey)
13948 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
13949 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13950 if ((dnskey.flags &
13951 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
13952 != DNS_KEYOWNER_ZONE)
13955 dns_rdata_toregion(&tuple->rdata, &r);
13957 keyid = dst_region_computeid(&r, dnskey.algorithm);
13959 buf[0] = dnskey.algorithm;
13960 buf[1] = (keyid & 0xff00) >> 8;
13961 buf[2] = (keyid & 0xff);
13962 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
13965 rdata.length = sizeof(buf);
13966 rdata.type = privatetype;
13967 rdata.rdclass = tuple->rdata.rdclass;
13969 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
13970 CHECK(rr_exists(db, ver, name, &rdata, &flag));
13973 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
13974 name, 0, &rdata, &newtuple));
13975 CHECK(do_one_tuple(&newtuple, db, ver, diff));
13976 INSIST(newtuple == NULL);
13980 * Remove any record which says this operation has already
13984 CHECK(rr_exists(db, ver, name, &rdata, &flag));
13986 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
13987 name, 0, &rdata, &newtuple));
13988 CHECK(do_one_tuple(&newtuple, db, ver, diff));
13989 INSIST(newtuple == NULL);
13996 static isc_result_t
13997 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
13998 dns_diff_t *diff, dns_diff_t *sig_diff)
14000 isc_result_t result;
14001 isc_stdtime_t now, inception, soaexpire;
14002 isc_boolean_t check_ksk, keyset_kskonly;
14003 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
14004 unsigned int nkeys = 0, i;
14005 dns_difftuple_t *tuple;
14007 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
14008 zone_keys, &nkeys);
14009 if (result != ISC_R_SUCCESS) {
14010 dns_zone_log(zone, ISC_LOG_ERROR,
14011 "sign_apex:find_zone_keys -> %s\n",
14012 dns_result_totext(result));
14016 isc_stdtime_get(&now);
14017 inception = now - 3600; /* Allow for clock skew. */
14018 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
14020 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14021 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
14024 * See if update_sigs will update DNSKEY signature and if not
14025 * cause them to sign so that so that newly activated keys
14028 for (tuple = ISC_LIST_HEAD(diff->tuples);
14030 tuple = ISC_LIST_NEXT(tuple, link)) {
14031 if (tuple->rdata.type == dns_rdatatype_dnskey &&
14032 dns_name_equal(&tuple->name, &zone->origin))
14036 if (tuple == NULL) {
14037 result = del_sigs(zone, db, ver, &zone->origin,
14038 dns_rdatatype_dnskey, sig_diff,
14039 zone_keys, nkeys, now, ISC_FALSE);
14040 if (result != ISC_R_SUCCESS) {
14041 dns_zone_log(zone, ISC_LOG_ERROR,
14042 "sign_apex:del_sigs -> %s\n",
14043 dns_result_totext(result));
14046 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
14047 sig_diff, zone_keys, nkeys, zone->mctx,
14048 inception, soaexpire, check_ksk,
14050 if (result != ISC_R_SUCCESS) {
14051 dns_zone_log(zone, ISC_LOG_ERROR,
14052 "sign_apex:add_sigs -> %s\n",
14053 dns_result_totext(result));
14058 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
14059 inception, soaexpire, now, check_ksk,
14060 keyset_kskonly, sig_diff);
14062 if (result != ISC_R_SUCCESS) {
14063 dns_zone_log(zone, ISC_LOG_ERROR,
14064 "sign_apex:update_sigs -> %s\n",
14065 dns_result_totext(result));
14070 for (i = 0; i < nkeys; i++)
14071 dst_key_free(&zone_keys[i]);
14076 * Prevent the zone entering a inconsistent state where
14077 * NSEC only DNSKEYs are present with NSEC3 chains.
14078 * See update.c:check_dnssec()
14080 static isc_boolean_t
14081 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14084 isc_result_t result;
14085 dns_difftuple_t *tuple;
14086 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
14087 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
14089 /* Scan the tuples for an NSEC-only DNSKEY */
14090 for (tuple = ISC_LIST_HEAD(diff->tuples);
14092 tuple = ISC_LIST_NEXT(tuple, link)) {
14094 if (tuple->rdata.type != dns_rdatatype_dnskey ||
14095 tuple->op != DNS_DIFFOP_ADD)
14098 alg = tuple->rdata.data[3];
14099 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
14100 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
14101 nseconly = ISC_TRUE;
14106 /* Check existing DB for NSEC-only DNSKEY */
14108 CHECK(dns_nsec_nseconly(db, ver, &nseconly));
14110 /* Check existing DB for NSEC3 */
14112 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
14113 privatetype, &nsec3));
14115 /* Refuse to allow NSEC3 with NSEC-only keys */
14116 if (nseconly && nsec3) {
14117 dns_zone_log(zone, ISC_LOG_ERROR,
14118 "NSEC only DNSKEYs and NSEC3 chains not allowed");
14125 return (ISC_FALSE);
14128 static isc_result_t
14129 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14132 isc_result_t result;
14133 dns_dbnode_t *node = NULL;
14134 dns_rdataset_t rdataset;
14136 dns_rdataset_init(&rdataset);
14137 CHECK(dns_db_getoriginnode(db, &node));
14139 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14140 dns_rdatatype_none, 0, &rdataset, NULL);
14141 if (dns_rdataset_isassociated(&rdataset))
14142 dns_rdataset_disassociate(&rdataset);
14143 if (result != ISC_R_NOTFOUND)
14146 result = dns_nsec3param_deletechains(db, ver, zone, diff);
14150 dns_db_detachnode(db, &node);
14155 * Given an RRSIG rdataset and an algorithm, determine whether there
14156 * are any signatures using that algorithm.
14158 static isc_boolean_t
14159 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
14160 dns_rdata_t rdata = DNS_RDATA_INIT;
14161 dns_rdata_rrsig_t rrsig;
14162 isc_result_t result;
14164 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
14165 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
14166 return (ISC_FALSE);
14169 for (result = dns_rdataset_first(rdataset);
14170 result == ISC_R_SUCCESS;
14171 result = dns_rdataset_next(rdataset))
14173 dns_rdataset_current(rdataset, &rdata);
14174 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
14175 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14176 dns_rdata_reset(&rdata);
14177 if (rrsig.algorithm == alg)
14181 return (ISC_FALSE);
14184 static isc_result_t
14185 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14188 dns_name_t *origin;
14189 isc_boolean_t build_nsec3;
14190 isc_result_t result;
14192 origin = dns_db_origin(db);
14193 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
14196 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
14197 ISC_FALSE, zone->privatetype, diff));
14198 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
14205 zone_rekey(dns_zone_t *zone) {
14206 isc_result_t result;
14207 dns_db_t *db = NULL;
14208 dns_dbnode_t *node = NULL;
14209 dns_dbversion_t *ver = NULL;
14210 dns_rdataset_t soaset, soasigs, keyset, keysigs;
14211 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
14212 dns_dnsseckey_t *key;
14213 dns_diff_t diff, sig_diff;
14214 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
14215 isc_boolean_t newalg = ISC_FALSE;
14216 isc_boolean_t fullsign;
14217 dns_ttl_t ttl = 3600;
14221 isc_time_t timenow;
14222 isc_interval_t ival;
14225 REQUIRE(DNS_ZONE_VALID(zone));
14227 ISC_LIST_INIT(dnskeys);
14228 ISC_LIST_INIT(keys);
14229 ISC_LIST_INIT(rmkeys);
14230 dns_rdataset_init(&soaset);
14231 dns_rdataset_init(&soasigs);
14232 dns_rdataset_init(&keyset);
14233 dns_rdataset_init(&keysigs);
14234 dir = dns_zone_getkeydirectory(zone);
14236 dns_diff_init(mctx, &diff);
14237 dns_diff_init(mctx, &sig_diff);
14238 sig_diff.resign = zone->sigresigninginterval;
14240 CHECK(dns_zone_getdb(zone, &db));
14241 CHECK(dns_db_newversion(db, &ver));
14242 CHECK(dns_db_getoriginnode(db, &node));
14244 TIME_NOW(&timenow);
14245 now = isc_time_seconds(&timenow);
14247 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
14249 /* Get the SOA record's TTL */
14250 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
14251 dns_rdatatype_none, 0, &soaset, &soasigs));
14253 dns_rdataset_disassociate(&soaset);
14255 /* Get the DNSKEY rdataset */
14256 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14257 dns_rdatatype_none, 0, &keyset, &keysigs);
14258 if (result == ISC_R_SUCCESS) {
14260 result = dns_dnssec_keylistfromrdataset(&zone->origin, dir,
14262 &keysigs, &soasigs,
14263 ISC_FALSE, ISC_FALSE,
14265 /* Can't get keys for some reason; try again later. */
14266 if (result != ISC_R_SUCCESS)
14268 } else if (result != ISC_R_NOTFOUND)
14272 * True when called from "rndc sign". Indicates the zone should be
14273 * fully signed now.
14275 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
14277 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
14278 if (result == ISC_R_SUCCESS) {
14279 isc_boolean_t check_ksk;
14280 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14282 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
14283 &zone->origin, ttl, &diff,
14284 ISC_TF(!check_ksk),
14287 /* Keys couldn't be updated for some reason;
14288 * try again later. */
14289 if (result != ISC_R_SUCCESS) {
14290 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
14291 "couldn't update zone keys: %s",
14292 isc_result_totext(result));
14297 * See if any pre-existing keys have newly become active;
14298 * also, see if any new key is for a new algorithm, as in that
14299 * event, we need to sign the zone fully. (If there's a new
14300 * key, but it's for an already-existing algorithm, then
14301 * the zone signing can be handled incrementally.)
14303 for (key = ISC_LIST_HEAD(dnskeys);
14305 key = ISC_LIST_NEXT(key, link)) {
14306 if (!key->first_sign)
14309 newactive = ISC_TRUE;
14311 if (!dns_rdataset_isassociated(&keysigs)) {
14316 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
14318 * This isn't a new algorithm; clear
14319 * first_sign so we won't sign the
14320 * whole zone with this key later
14322 key->first_sign = ISC_FALSE;
14329 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
14330 dnskey_sane(zone, db, ver, &diff)) {
14331 CHECK(dns_diff_apply(&diff, db, ver));
14332 CHECK(clean_nsec3param(zone, db, ver, &diff));
14333 CHECK(add_signing_records(db, zone->privatetype,
14335 ISC_TF(newalg || fullsign)));
14336 CHECK(increment_soa_serial(db, ver, &diff, mctx));
14337 CHECK(add_chains(zone, db, ver, &diff));
14338 CHECK(sign_apex(zone, db, ver, &diff, &sig_diff));
14339 CHECK(zone_journal(zone, &sig_diff, "zone_rekey"));
14344 dns_db_closeversion(db, &ver, commit);
14347 dns_difftuple_t *tuple;
14350 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14352 zone_needdump(zone, DNS_DUMP_DELAY);
14354 zone_settimer(zone, &timenow);
14356 /* Remove any signatures from removed keys. */
14357 if (!ISC_LIST_EMPTY(rmkeys)) {
14358 for (key = ISC_LIST_HEAD(rmkeys);
14360 key = ISC_LIST_NEXT(key, link)) {
14361 result = zone_signwithkey(zone,
14362 dst_key_alg(key->key),
14363 dst_key_id(key->key),
14365 if (result != ISC_R_SUCCESS) {
14366 dns_zone_log(zone, ISC_LOG_ERROR,
14367 "zone_signwithkey failed: %s",
14368 dns_result_totext(result));
14375 * "rndc sign" was called, so we now sign the zone
14376 * with all active keys, whether they're new or not.
14378 for (key = ISC_LIST_HEAD(dnskeys);
14380 key = ISC_LIST_NEXT(key, link)) {
14381 if (!key->force_sign && !key->hint_sign)
14384 result = zone_signwithkey(zone,
14385 dst_key_alg(key->key),
14386 dst_key_id(key->key),
14388 if (result != ISC_R_SUCCESS) {
14389 dns_zone_log(zone, ISC_LOG_ERROR,
14390 "zone_signwithkey failed: %s",
14391 dns_result_totext(result));
14394 } else if (newalg) {
14396 * We haven't been told to sign fully, but a new
14397 * algorithm was added to the DNSKEY. We sign
14398 * the full zone, but only with newly active
14401 for (key = ISC_LIST_HEAD(dnskeys);
14403 key = ISC_LIST_NEXT(key, link)) {
14404 if (!key->first_sign)
14407 result = zone_signwithkey(zone,
14408 dst_key_alg(key->key),
14409 dst_key_id(key->key),
14411 if (result != ISC_R_SUCCESS) {
14412 dns_zone_log(zone, ISC_LOG_ERROR,
14413 "zone_signwithkey failed: %s",
14414 dns_result_totext(result));
14420 * Clear fullsign flag, if it was set, so we don't do
14421 * another full signing next time
14423 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
14426 * Cause the zone to add/delete NSEC3 chains for the
14427 * deferred NSEC3PARAM changes.
14429 for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
14431 tuple = ISC_LIST_NEXT(tuple, link)) {
14432 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
14433 dns_rdata_t rdata = DNS_RDATA_INIT;
14434 dns_rdata_nsec3param_t nsec3param;
14436 if (tuple->rdata.type != zone->privatetype ||
14437 tuple->op != DNS_DIFFOP_ADD)
14440 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
14443 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
14444 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14445 if (nsec3param.flags == 0)
14448 result = zone_addnsec3chain(zone, &nsec3param);
14449 if (result != ISC_R_SUCCESS) {
14450 dns_zone_log(zone, ISC_LOG_ERROR,
14451 "zone_addnsec3chain failed: %s",
14452 dns_result_totext(result));
14457 * Schedule the next resigning event
14459 set_resigntime(zone);
14463 isc_time_settoepoch(&zone->refreshkeytime);
14466 * If we're doing key maintenance, set the key refresh timer to
14467 * the next scheduled key event or to one hour in the future,
14468 * whichever is sooner.
14470 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
14471 isc_time_t timethen;
14472 isc_stdtime_t then;
14475 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
14476 zone->refreshkeytime = timethen;
14479 for (key = ISC_LIST_HEAD(dnskeys);
14481 key = ISC_LIST_NEXT(key, link)) {
14483 result = next_keyevent(key->key, &then);
14484 if (result != ISC_R_SUCCESS)
14487 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
14489 if (isc_time_compare(&timethen,
14490 &zone->refreshkeytime) < 0) {
14491 zone->refreshkeytime = timethen;
14496 zone_settimer(zone, &timenow);
14498 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
14499 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
14503 dns_diff_clear(&diff);
14504 dns_diff_clear(&sig_diff);
14506 clear_keylist(&dnskeys, mctx);
14507 clear_keylist(&keys, mctx);
14508 clear_keylist(&rmkeys, mctx);
14511 dns_db_closeversion(db, &ver, ISC_FALSE);
14512 if (dns_rdataset_isassociated(&keyset))
14513 dns_rdataset_disassociate(&keyset);
14514 if (dns_rdataset_isassociated(&keysigs))
14515 dns_rdataset_disassociate(&keysigs);
14516 if (dns_rdataset_isassociated(&soasigs))
14517 dns_rdataset_disassociate(&soasigs);
14519 dns_db_detachnode(db, &node);
14521 dns_db_detach(&db);
14525 isc_interval_set(&ival, HOUR, 0);
14526 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
14531 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
14534 if (zone->type == dns_zone_master && zone->task != NULL) {
14538 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
14541 zone->refreshkeytime = now;
14542 zone_settimer(zone, &now);
14549 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
14550 unsigned int *errors)
14552 isc_result_t result;
14553 dns_dbnode_t *node = NULL;
14555 REQUIRE(DNS_ZONE_VALID(zone));
14556 REQUIRE(errors != NULL);
14558 result = dns_db_getoriginnode(db, &node);
14559 if (result != ISC_R_SUCCESS)
14561 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
14563 dns_db_detachnode(db, &node);
14568 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
14569 REQUIRE(DNS_ZONE_VALID(zone));
14571 zone->added = added;
14576 dns_zone_getadded(dns_zone_t *zone) {
14577 REQUIRE(DNS_ZONE_VALID(zone));
14578 return (zone->added);
14582 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
14584 isc_time_t loadtime;
14585 isc_result_t result;
14586 TIME_NOW(&loadtime);
14589 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);