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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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",
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", 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", 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",
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", 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", 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",
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", 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",
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",
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",
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",
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 -> %s",
6919 dns_result_totext(result));
6922 build_nsec = ISC_FALSE;
6924 } else if (result != ISC_R_SUCCESS) {
6925 dns_zone_log(zone, ISC_LOG_ERROR,
6926 "zone_sign:dns_dbiterator_next -> %s",
6927 dns_result_totext(result));
6929 } else if (delegation) {
6930 dns_dbiterator_current(signing->dbiterator,
6932 dns_db_detachnode(db, &node);
6933 if (!dns_name_issubdomain(nextname, name))
6941 dns_dbiterator_pause(signing->dbiterator);
6942 signing = nextsigning;
6946 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
6947 result = update_sigs(&post_diff, db, version, zone_keys,
6948 nkeys, zone, inception, expire, now,
6949 check_ksk, keyset_kskonly, &sig_diff);
6950 if (result != ISC_R_SUCCESS) {
6951 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
6952 "update_sigs -> %s",
6953 dns_result_totext(result));
6959 * Have we changed anything?
6961 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) {
6962 result = ISC_R_SUCCESS;
6968 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6969 &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
6970 if (result != ISC_R_SUCCESS) {
6971 dns_zone_log(zone, ISC_LOG_ERROR,
6972 "zone_sign:del_sigs -> %s",
6973 dns_result_totext(result));
6977 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
6978 if (result != ISC_R_SUCCESS) {
6979 dns_zone_log(zone, ISC_LOG_ERROR,
6980 "zone_sign:increment_soa_serial -> %s",
6981 dns_result_totext(result));
6986 * Generate maximum life time signatures so that the above loop
6987 * termination is sensible.
6989 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6990 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
6991 soaexpire, check_ksk, keyset_kskonly);
6992 if (result != ISC_R_SUCCESS) {
6993 dns_zone_log(zone, ISC_LOG_ERROR,
6994 "zone_sign:add_sigs -> %s",
6995 dns_result_totext(result));
7000 * Write changes to journal file.
7002 CHECK(zone_journal(zone, &sig_diff, "zone_sign"));
7006 * Pause all iterators so that dns_db_closeversion() can succeed.
7008 for (signing = ISC_LIST_HEAD(zone->signing);
7010 signing = ISC_LIST_NEXT(signing, link))
7011 dns_dbiterator_pause(signing->dbiterator);
7013 for (signing = ISC_LIST_HEAD(cleanup);
7015 signing = ISC_LIST_NEXT(signing, link))
7016 dns_dbiterator_pause(signing->dbiterator);
7019 * Everything has succeeded. Commit the changes.
7021 dns_db_closeversion(db, &version, commit);
7024 * Everything succeeded so we can clean these up now.
7026 signing = ISC_LIST_HEAD(cleanup);
7027 while (signing != NULL) {
7028 ISC_LIST_UNLINK(cleanup, signing, link);
7029 dns_db_detach(&signing->db);
7030 dns_dbiterator_destroy(&signing->dbiterator);
7031 isc_mem_put(zone->mctx, signing, sizeof *signing);
7032 signing = ISC_LIST_HEAD(cleanup);
7035 set_resigntime(zone);
7039 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7040 zone_needdump(zone, DNS_DUMP_DELAY);
7046 * Rollback the cleanup list.
7048 signing = ISC_LIST_HEAD(cleanup);
7049 while (signing != NULL) {
7050 ISC_LIST_UNLINK(cleanup, signing, link);
7051 ISC_LIST_PREPEND(zone->signing, signing, link);
7052 dns_dbiterator_first(signing->dbiterator);
7053 dns_dbiterator_pause(signing->dbiterator);
7054 signing = ISC_LIST_HEAD(cleanup);
7057 for (signing = ISC_LIST_HEAD(zone->signing);
7059 signing = ISC_LIST_NEXT(signing, link))
7060 dns_dbiterator_pause(signing->dbiterator);
7062 dns_diff_clear(&sig_diff);
7064 for (i = 0; i < nkeys; i++)
7065 dst_key_free(&zone_keys[i]);
7068 dns_db_detachnode(db, &node);
7070 if (version != NULL) {
7071 dns_db_closeversion(db, &version, ISC_FALSE);
7073 } else if (db != NULL)
7076 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7078 if (zone->update_disabled || result != ISC_R_SUCCESS)
7079 isc_interval_set(&i, 60, 0); /* 1 minute */
7081 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7082 isc_time_nowplusinterval(&zone->signingtime, &i);
7084 isc_time_settoepoch(&zone->signingtime);
7088 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7089 unsigned char *data, int size) {
7090 dns_rdata_dnskey_t dnskey;
7091 dns_rdata_keydata_t keydata;
7094 dns_rdata_reset(target);
7095 isc_buffer_init(&buf, data, size);
7098 case dns_rdatatype_dnskey:
7099 dns_rdata_tostruct(rr, &dnskey, NULL);
7100 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7101 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7104 case dns_rdatatype_keydata:
7105 dns_rdata_tostruct(rr, &keydata, NULL);
7106 dns_keydata_todnskey(&keydata, &dnskey, NULL);
7107 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7116 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
7117 * a KEYDATA rdataset from the key zone.
7119 * 'rr' contains either a DNSKEY record, or a KEYDATA record
7121 * After normalizing keys to the same format (DNSKEY, with revoke bit
7122 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
7123 * 'rdset', or ISC_FALSE if not.
7126 static isc_boolean_t
7127 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
7128 unsigned char data1[4096], data2[4096];
7129 dns_rdata_t rdata, rdata1, rdata2;
7130 isc_result_t result;
7132 dns_rdata_init(&rdata);
7133 dns_rdata_init(&rdata1);
7134 dns_rdata_init(&rdata2);
7136 normalize_key(rr, &rdata1, data1, sizeof(data1));
7138 for (result = dns_rdataset_first(rdset);
7139 result == ISC_R_SUCCESS;
7140 result = dns_rdataset_next(rdset)) {
7141 dns_rdata_reset(&rdata);
7142 dns_rdataset_current(rdset, &rdata);
7143 normalize_key(&rdata, &rdata2, data2, sizeof(data2));
7144 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
7152 * Calculate the refresh interval for a keydata zone, per
7153 * RFC5011: MAX(1 hr,
7156 * 1/2 * RRSigExpirationInterval))
7157 * or for retries: MAX(1 hr,
7160 * 1/10 * RRSigExpirationInterval))
7162 static inline isc_stdtime_t
7163 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
7164 isc_result_t result;
7166 dns_rdataset_t *rdset;
7167 dns_rdata_t sigrr = DNS_RDATA_INIT;
7168 dns_rdata_sig_t sig;
7171 isc_stdtime_get(&now);
7173 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7174 rdset = &kfetch->dnskeysigset;
7176 return (now + HOUR);
7178 result = dns_rdataset_first(rdset);
7179 if (result != ISC_R_SUCCESS)
7180 return (now + HOUR);
7182 dns_rdataset_current(rdset, &sigrr);
7183 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7184 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7187 t = sig.originalttl / 2;
7189 if (isc_serial_gt(sig.timeexpire, now)) {
7190 isc_uint32_t exp = (sig.timeexpire - now) / 2;
7201 t = sig.originalttl / 10;
7203 if (isc_serial_gt(sig.timeexpire, now)) {
7204 isc_uint32_t exp = (sig.timeexpire - now) / 10;
7220 * This routine is called when no changes are needed in a KEYDATA
7221 * record except to simply update the refresh timer. Caller should
7225 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
7227 isc_result_t result;
7229 unsigned char key_buf[4096];
7230 dns_rdata_t rdata = DNS_RDATA_INIT;
7231 dns_rdata_keydata_t keydata;
7233 dns_zone_t *zone = kfetch->zone;
7236 name = dns_fixedname_name(&kfetch->name);
7237 isc_stdtime_get(&now);
7239 for (result = dns_rdataset_first(&kfetch->keydataset);
7240 result == ISC_R_SUCCESS;
7241 result = dns_rdataset_next(&kfetch->keydataset)) {
7242 dns_rdata_reset(&rdata);
7243 dns_rdataset_current(&kfetch->keydataset, &rdata);
7245 /* Delete old version */
7246 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
7249 /* Update refresh timer */
7250 CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL));
7251 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
7252 set_refreshkeytimer(zone, &keydata, now);
7254 dns_rdata_reset(&rdata);
7255 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7256 CHECK(dns_rdata_fromstruct(&rdata,
7257 zone->rdclass, dns_rdatatype_keydata,
7260 /* Insert updated version */
7261 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
7264 result = ISC_R_SUCCESS;
7270 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
7272 static isc_boolean_t
7273 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
7274 isc_result_t result;
7275 dns_name_t *keyname;
7277 dns_rdata_t sigrr = DNS_RDATA_INIT;
7278 dns_rdata_t rr = DNS_RDATA_INIT;
7279 dns_rdata_rrsig_t sig;
7280 dns_rdata_dnskey_t dnskey;
7281 dst_key_t *dstkey = NULL;
7282 unsigned char key_buf[4096];
7284 isc_boolean_t answer = ISC_FALSE;
7286 REQUIRE(kfetch != NULL && keydata != NULL);
7287 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
7289 keyname = dns_fixedname_name(&kfetch->name);
7290 mctx = kfetch->zone->view->mctx;
7292 /* Generate a key from keydata */
7293 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7294 dns_keydata_todnskey(keydata, &dnskey, NULL);
7295 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
7297 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
7298 if (result != ISC_R_SUCCESS)
7301 /* See if that key generated any of the signatures */
7302 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7303 result == ISC_R_SUCCESS;
7304 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7305 dns_fixedname_t fixed;
7306 dns_fixedname_init(&fixed);
7308 dns_rdata_reset(&sigrr);
7309 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7310 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7311 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7313 if (dst_key_alg(dstkey) == sig.algorithm &&
7314 (dst_key_id(dstkey) == sig.keyid ||
7315 dst_key_rid(dstkey) == sig.keyid)) {
7316 result = dns_dnssec_verify2(keyname,
7318 dstkey, ISC_FALSE, mctx, &sigrr,
7319 dns_fixedname_name(&fixed));
7321 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
7322 "Confirm revoked DNSKEY is self-signed: "
7323 "%s", dns_result_totext(result));
7325 if (result == ISC_R_SUCCESS) {
7332 dst_key_free(&dstkey);
7337 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
7338 * anchors are being managed; scan the keyset, and update the key zone and the
7339 * local trust anchors according to RFC5011.
7342 keyfetch_done(isc_task_t *task, isc_event_t *event) {
7343 isc_result_t result, eresult;
7344 dns_fetchevent_t *devent;
7345 dns_keyfetch_t *kfetch;
7347 isc_mem_t *mctx = NULL;
7348 dns_keytable_t *secroots = NULL;
7349 dns_dbversion_t *ver = NULL;
7351 isc_boolean_t alldone = ISC_FALSE;
7352 isc_boolean_t commit = ISC_FALSE;
7353 dns_name_t *keyname;
7354 dns_rdata_t sigrr = DNS_RDATA_INIT;
7355 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
7356 dns_rdata_t keydatarr = DNS_RDATA_INIT;
7357 dns_rdata_rrsig_t sig;
7358 dns_rdata_dnskey_t dnskey;
7359 dns_rdata_keydata_t keydata;
7360 isc_boolean_t initializing;
7361 char namebuf[DNS_NAME_FORMATSIZE];
7362 unsigned char key_buf[4096];
7367 isc_boolean_t secure;
7368 isc_boolean_t free_needed;
7371 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
7372 INSIST(event->ev_arg != NULL);
7374 kfetch = event->ev_arg;
7375 zone = kfetch->zone;
7376 isc_mem_attach(zone->mctx, &mctx);
7377 keyname = dns_fixedname_name(&kfetch->name);
7379 devent = (dns_fetchevent_t *) event;
7380 eresult = devent->result;
7382 /* Free resources which are not of interest */
7383 if (devent->node != NULL)
7384 dns_db_detachnode(devent->db, &devent->node);
7385 if (devent->db != NULL)
7386 dns_db_detach(&devent->db);
7387 isc_event_free(&event);
7388 dns_resolver_destroyfetch(&kfetch->fetch);
7391 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
7394 isc_stdtime_get(&now);
7395 dns_name_format(keyname, namebuf, sizeof(namebuf));
7397 result = dns_view_getsecroots(zone->view, &secroots);
7398 INSIST(result == ISC_R_SUCCESS);
7400 dns_diff_init(mctx, &diff);
7401 diff.resign = zone->sigresigninginterval;
7403 CHECK(dns_db_newversion(kfetch->db, &ver));
7405 zone->refreshkeycount--;
7406 alldone = ISC_TF(zone->refreshkeycount == 0);
7409 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
7412 if (eresult != ISC_R_SUCCESS ||
7413 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
7414 dns_zone_log(zone, ISC_LOG_WARNING,
7415 "Unable to fetch DNSKEY set "
7416 "'%s': %s", namebuf, dns_result_totext(eresult));
7417 CHECK(minimal_update(kfetch, ver, &diff));
7421 /* No RRSIGs found */
7422 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
7423 dns_zone_log(zone, ISC_LOG_WARNING,
7424 "No DNSKEY RRSIGs found for "
7425 "'%s': %s", namebuf, dns_result_totext(eresult));
7426 CHECK(minimal_update(kfetch, ver, &diff));
7431 * Validate the dnskeyset against the current trusted keys.
7433 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7434 result == ISC_R_SUCCESS;
7435 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7436 dns_keynode_t *keynode = NULL;
7438 dns_rdata_reset(&sigrr);
7439 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7440 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7441 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7443 result = dns_keytable_find(secroots, keyname, &keynode);
7444 while (result == ISC_R_SUCCESS) {
7445 dns_keynode_t *nextnode = NULL;
7446 dns_fixedname_t fixed;
7447 dns_fixedname_init(&fixed);
7449 dstkey = dns_keynode_key(keynode);
7450 if (dstkey == NULL) /* fail_secure() was called */
7453 if (dst_key_alg(dstkey) == sig.algorithm &&
7454 dst_key_id(dstkey) == sig.keyid) {
7455 result = dns_dnssec_verify2(keyname,
7458 zone->view->mctx, &sigrr,
7459 dns_fixedname_name(&fixed));
7461 dns_zone_log(zone, ISC_LOG_DEBUG(3),
7462 "Verifying DNSKEY set for zone "
7463 "'%s': %s", namebuf,
7464 dns_result_totext(result));
7466 if (result == ISC_R_SUCCESS) {
7467 kfetch->dnskeyset.trust =
7469 kfetch->dnskeysigset.trust =
7471 dns_keytable_detachkeynode(secroots,
7477 result = dns_keytable_nextkeynode(secroots,
7478 keynode, &nextnode);
7479 dns_keytable_detachkeynode(secroots, &keynode);
7483 if (kfetch->dnskeyset.trust == dns_trust_secure)
7488 * If we were not able to verify the answer using the current
7489 * trusted keys then all we can do is look at any revoked keys.
7491 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
7494 * First scan keydataset to find keys that are not in dnskeyset
7495 * - Missing keys which are not scheduled for removal,
7497 * - Missing keys which are scheduled for removal and
7498 * the remove hold-down timer has completed should
7499 * be removed from the key zone
7500 * - Missing keys whose acceptance timers have not yet
7501 * completed, log a warning and reset the acceptance
7502 * timer to 30 days in the future
7503 * - All keys not being removed have their refresh timers
7506 initializing = ISC_TRUE;
7507 for (result = dns_rdataset_first(&kfetch->keydataset);
7508 result == ISC_R_SUCCESS;
7509 result = dns_rdataset_next(&kfetch->keydataset)) {
7510 dns_rdata_reset(&keydatarr);
7511 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7512 dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7515 * If any keydata record has a nonzero add holddown, then
7516 * there was a pre-existing trust anchor for this domain;
7517 * that means we are *not* initializing it and shouldn't
7518 * automatically trust all the keys we find at the zone apex.
7520 initializing = initializing && ISC_TF(keydata.addhd == 0);
7522 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
7523 isc_boolean_t deletekey = ISC_FALSE;
7526 if (now > keydata.removehd)
7527 deletekey = ISC_TRUE;
7528 } else if (now < keydata.addhd) {
7529 dns_zone_log(zone, ISC_LOG_WARNING,
7530 "Pending key unexpectedly missing "
7531 "from %s; restarting acceptance "
7533 keydata.addhd = now + MONTH;
7534 keydata.refresh = refresh_time(kfetch,
7536 } else if (keydata.addhd == 0) {
7537 keydata.addhd = now;
7538 } else if (keydata.removehd == 0) {
7539 dns_zone_log(zone, ISC_LOG_WARNING,
7540 "Active key unexpectedly missing "
7541 "from %s", namebuf);
7542 keydata.refresh = now + HOUR;
7543 } else if (now > keydata.removehd) {
7544 deletekey = ISC_TRUE;
7546 keydata.refresh = refresh_time(kfetch,
7550 if (secure || deletekey) {
7551 /* Delete old version */
7552 CHECK(update_one_rr(kfetch->db, ver, &diff,
7553 DNS_DIFFOP_DEL, keyname, 0,
7557 if (!secure || deletekey)
7560 dns_rdata_reset(&keydatarr);
7561 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7562 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7563 dns_rdatatype_keydata,
7566 /* Insert updated version */
7567 CHECK(update_one_rr(kfetch->db, ver, &diff,
7568 DNS_DIFFOP_ADD, keyname, 0,
7571 set_refreshkeytimer(zone, &keydata, now);
7576 * Next scan dnskeyset:
7577 * - If new keys are found (i.e., lacking a match in keydataset)
7578 * add them to the key zone and set the acceptance timer
7579 * to 30 days in the future (or to immediately if we've
7580 * determined that we're initializing the zone for the
7582 * - Previously-known keys that have been revoked
7583 * must be scheduled for removal from the key zone (or,
7584 * if they hadn't been accepted as trust anchors yet
7585 * anyway, removed at once)
7586 * - Previously-known unrevoked keys whose acceptance timers
7587 * have completed are promoted to trust anchors
7588 * - All keys not being removed have their refresh
7591 for (result = dns_rdataset_first(&kfetch->dnskeyset);
7592 result == ISC_R_SUCCESS;
7593 result = dns_rdataset_next(&kfetch->dnskeyset)) {
7594 isc_boolean_t revoked = ISC_FALSE;
7595 isc_boolean_t newkey = ISC_FALSE;
7596 isc_boolean_t updatekey = ISC_FALSE;
7597 isc_boolean_t deletekey = ISC_FALSE;
7598 isc_boolean_t trustkey = ISC_FALSE;
7600 dns_rdata_reset(&dnskeyrr);
7601 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
7602 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7605 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
7608 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
7610 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
7611 dns_rdata_reset(&keydatarr);
7612 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7613 dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7615 if (revoked && revocable(kfetch, &keydata)) {
7616 if (keydata.addhd > now) {
7618 * Key wasn't trusted yet, and now
7619 * it's been revoked? Just remove it
7621 deletekey = ISC_TRUE;
7622 } else if (keydata.removehd == 0) {
7623 /* Remove from secroots */
7624 dns_view_untrust(zone->view, keyname,
7627 /* If initializing, delete now */
7628 if (keydata.addhd == 0)
7629 deletekey = ISC_TRUE;
7631 keydata.removehd = now + MONTH;
7632 } else if (keydata.removehd < now) {
7633 /* Scheduled for removal */
7634 deletekey = ISC_TRUE;
7636 } else if (revoked) {
7637 if (secure && keydata.removehd == 0) {
7638 dns_zone_log(zone, ISC_LOG_WARNING,
7639 "Active key for zone "
7640 "'%s' is revoked but "
7641 "did not self-sign; "
7642 "ignoring.", namebuf);
7645 } else if (secure) {
7646 if (keydata.removehd != 0) {
7648 * Key isn't revoked--but it
7649 * seems it used to be.
7650 * Remove it now and add it
7651 * back as if it were a fresh key.
7653 deletekey = ISC_TRUE;
7655 } else if (keydata.addhd > now)
7657 else if (keydata.addhd == 0)
7658 keydata.addhd = now;
7660 if (keydata.addhd <= now)
7661 trustkey = ISC_TRUE;
7664 if (!deletekey && !newkey)
7665 updatekey = ISC_TRUE;
7666 } else if (secure) {
7668 * Key wasn't in the key zone but it's
7669 * revoked now anyway, so just skip it
7674 /* Key wasn't in the key zone: add it */
7678 dns_keytag_t tag = 0;
7679 CHECK(compute_tag(keyname, &dnskey,
7681 dns_zone_log(zone, ISC_LOG_WARNING,
7682 "Initializing automatic trust "
7683 "anchor management for zone '%s'; "
7684 "DNSKEY ID %d is now trusted, "
7685 "waiving the normal 30-day "
7688 trustkey = ISC_TRUE;
7692 /* Delete old version */
7693 if (deletekey || !newkey)
7694 CHECK(update_one_rr(kfetch->db, ver, &diff,
7695 DNS_DIFFOP_DEL, keyname, 0,
7699 /* Set refresh timer */
7700 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7701 dns_rdata_reset(&keydatarr);
7702 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7703 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7704 dns_rdatatype_keydata,
7707 /* Insert updated version */
7708 CHECK(update_one_rr(kfetch->db, ver, &diff,
7709 DNS_DIFFOP_ADD, keyname, 0,
7711 } else if (newkey) {
7712 /* Convert DNSKEY to KEYDATA */
7713 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7714 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
7716 keydata.addhd = initializing ? now : now + MONTH;
7717 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7718 dns_rdata_reset(&keydatarr);
7719 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7720 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7721 dns_rdatatype_keydata,
7724 /* Insert into key zone */
7725 CHECK(update_one_rr(kfetch->db, ver, &diff,
7726 DNS_DIFFOP_ADD, keyname, 0,
7731 /* Trust this key. */
7732 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7733 trust_key(zone, keyname, &dnskey, mctx);
7737 set_refreshkeytimer(zone, &keydata, now);
7741 * RFC5011 says, "A trust point that has all of its trust anchors
7742 * revoked is considered deleted and is treated as if the trust
7743 * point was never configured." But if someone revoked their
7744 * active key before the standby was trusted, that would mean the
7745 * zone would suddenly be nonsecured. We avoid this by checking to
7746 * see if there's pending keydata. If so, we put a null key in
7747 * the security roots; then all queries to the zone will fail.
7750 fail_secure(zone, keyname);
7754 if (!ISC_LIST_EMPTY(diff.tuples)) {
7755 /* Write changes to journal file. */
7756 CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx));
7757 CHECK(zone_journal(zone, &diff, "keyfetch_done"));
7760 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
7761 zone_needdump(zone, 30);
7766 dns_diff_clear(&diff);
7768 dns_db_closeversion(kfetch->db, &ver, commit);
7771 dns_db_detach(&kfetch->db);
7773 INSIST(zone->irefs > 0);
7775 kfetch->zone = NULL;
7777 if (dns_rdataset_isassociated(&kfetch->keydataset))
7778 dns_rdataset_disassociate(&kfetch->keydataset);
7779 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
7780 dns_rdataset_disassociate(&kfetch->dnskeyset);
7781 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7782 dns_rdataset_disassociate(&kfetch->dnskeysigset);
7784 dns_name_free(keyname, mctx);
7785 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
7786 isc_mem_detach(&mctx);
7788 if (secroots != NULL)
7789 dns_keytable_detach(&secroots);
7791 free_needed = exit_check(zone);
7798 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
7799 * records from the zone apex.
7802 zone_refreshkeys(dns_zone_t *zone) {
7803 const char me[] = "zone_refreshkeys";
7804 isc_result_t result;
7805 dns_rriterator_t rrit;
7806 dns_db_t *db = NULL;
7807 dns_dbversion_t *ver = NULL;
7809 dns_rdata_t rdata = DNS_RDATA_INIT;
7810 dns_rdata_keydata_t kd;
7812 isc_boolean_t commit = ISC_FALSE;
7813 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
7816 REQUIRE(zone->db != NULL);
7818 isc_stdtime_get(&now);
7821 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7822 isc_time_settoepoch(&zone->refreshkeytime);
7827 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7828 dns_db_attach(zone->db, &db);
7829 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7831 dns_diff_init(zone->mctx, &diff);
7833 CHECK(dns_db_newversion(db, &ver));
7835 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
7837 dns_rriterator_init(&rrit, db, ver, 0);
7838 for (result = dns_rriterator_first(&rrit);
7839 result == ISC_R_SUCCESS;
7840 result = dns_rriterator_nextrrset(&rrit)) {
7841 isc_stdtime_t timer = 0xffffffff;
7842 dns_name_t *name = NULL, *kname = NULL;
7843 dns_rdataset_t *kdset = NULL;
7844 dns_keyfetch_t *kfetch;
7847 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
7848 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
7849 !dns_rdataset_isassociated(kdset))
7853 * Scan the stored keys looking for ones that need
7854 * removal or refreshing
7856 for (result = dns_rdataset_first(kdset);
7857 result == ISC_R_SUCCESS;
7858 result = dns_rdataset_next(kdset)) {
7859 dns_rdata_reset(&rdata);
7860 dns_rdataset_current(kdset, &rdata);
7861 result = dns_rdata_tostruct(&rdata, &kd, NULL);
7862 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7864 /* Removal timer expired? */
7865 if (kd.removehd != 0 && kd.removehd < now) {
7866 CHECK(update_one_rr(db, ver, &diff,
7867 DNS_DIFFOP_DEL, name, ttl,
7872 /* Acceptance timer expired? */
7873 if (kd.addhd != 0 && kd.addhd < now)
7876 /* Or do we just need to refresh the keyset? */
7877 if (timer > kd.refresh)
7884 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
7885 if (kfetch == NULL) {
7886 fetch_err = ISC_TRUE;
7890 zone->refreshkeycount++;
7891 kfetch->zone = zone;
7893 INSIST(zone->irefs != 0);
7894 dns_fixedname_init(&kfetch->name);
7895 kname = dns_fixedname_name(&kfetch->name);
7896 dns_name_dup(name, zone->mctx, kname);
7897 dns_rdataset_init(&kfetch->dnskeyset);
7898 dns_rdataset_init(&kfetch->dnskeysigset);
7899 dns_rdataset_init(&kfetch->keydataset);
7900 dns_rdataset_clone(kdset, &kfetch->keydataset);
7902 dns_db_attach(db, &kfetch->db);
7903 kfetch->fetch = NULL;
7905 result = dns_resolver_createfetch(zone->view->resolver,
7906 kname, dns_rdatatype_dnskey,
7908 DNS_FETCHOPT_NOVALIDATE,
7910 keyfetch_done, kfetch,
7912 &kfetch->dnskeysigset,
7914 if (result == ISC_R_SUCCESS)
7915 fetching = ISC_TRUE;
7917 zone->refreshkeycount--;
7919 dns_db_detach(&kfetch->db);
7920 dns_rdataset_disassociate(&kfetch->keydataset);
7921 dns_name_free(kname, zone->mctx);
7922 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
7923 dns_zone_log(zone, ISC_LOG_WARNING,
7924 "Failed to create fetch for "
7926 fetch_err = ISC_TRUE;
7929 if (!ISC_LIST_EMPTY(diff.tuples)) {
7930 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
7931 CHECK(zone_journal(zone, &diff, "zone_refreshkeys"));
7933 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
7934 zone_needdump(zone, 30);
7940 * Error during a key fetch; retry in an hour.
7942 isc_time_t timenow, timethen;
7946 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
7947 zone->refreshkeytime = timethen;
7948 zone_settimer(zone, &timenow);
7950 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
7951 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
7955 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
7960 dns_diff_clear(&diff);
7962 dns_rriterator_destroy(&rrit);
7963 dns_db_closeversion(db, &ver, commit);
7969 zone_maintenance(dns_zone_t *zone) {
7970 const char me[] = "zone_maintenance";
7972 isc_result_t result;
7973 isc_boolean_t dumping;
7975 REQUIRE(DNS_ZONE_VALID(zone));
7979 * Configuring the view of this zone may have
7980 * failed, for example because the config file
7981 * had a syntax error. In that case, the view
7982 * db or resolver will be NULL, and we had better not try
7983 * to do maintenance on it.
7985 if (zone->view == NULL || zone->view->adb == NULL)
7993 switch (zone->type) {
7994 case dns_zone_slave:
7997 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
7998 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8000 zone->refreshtime = now;
8011 switch (zone->type) {
8012 case dns_zone_slave:
8014 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8015 isc_time_compare(&now, &zone->refreshtime) >= 0)
8016 dns_zone_refresh(zone);
8023 * Do we need to consolidate the backing store?
8025 switch (zone->type) {
8026 case dns_zone_master:
8027 case dns_zone_slave:
8031 if (zone->masterfile != NULL &&
8032 isc_time_compare(&now, &zone->dumptime) >= 0 &&
8033 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8034 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
8035 dumping = was_dumping(zone);
8040 result = zone_dump(zone, ISC_TRUE); /* task locked */
8041 if (result != ISC_R_SUCCESS)
8042 dns_zone_log(zone, ISC_LOG_WARNING,
8044 dns_result_totext(result));
8052 * Do we need to refresh keys?
8054 switch (zone->type) {
8056 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
8057 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8058 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
8059 zone_refreshkeys(zone);
8061 case dns_zone_master:
8062 if (!isc_time_isepoch(&zone->refreshkeytime) &&
8063 isc_time_compare(&now, &zone->refreshkeytime) >= 0)
8069 switch (zone->type) {
8070 case dns_zone_master:
8071 case dns_zone_slave:
8073 * Do we need to send out notify messages?
8075 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8076 isc_time_compare(&now, &zone->notifytime) >= 0)
8077 zone_notify(zone, &now);
8079 * Do we need to sign/resign some RRsets?
8081 if (!isc_time_isepoch(&zone->signingtime) &&
8082 isc_time_compare(&now, &zone->signingtime) >= 0)
8084 else if (!isc_time_isepoch(&zone->resigntime) &&
8085 isc_time_compare(&now, &zone->resigntime) >= 0)
8086 zone_resigninc(zone);
8087 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
8088 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
8089 zone_nsec3chain(zone);
8091 * Do we need to issue a key expiry warning.
8093 if (!isc_time_isepoch(&zone->keywarntime) &&
8094 isc_time_compare(&now, &zone->keywarntime) >= 0)
8095 set_key_expiry_warning(zone, zone->key_expiry,
8096 isc_time_seconds(&now));
8101 zone_settimer(zone, &now);
8105 dns_zone_markdirty(dns_zone_t *zone) {
8108 if (zone->type == dns_zone_master)
8109 set_resigntime(zone); /* XXXMPA make separate call back */
8110 zone_needdump(zone, DNS_DUMP_DELAY);
8115 dns_zone_expire(dns_zone_t *zone) {
8116 REQUIRE(DNS_ZONE_VALID(zone));
8124 zone_expire(dns_zone_t *zone) {
8126 * 'zone' locked by caller.
8129 REQUIRE(LOCKED_ZONE(zone));
8131 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
8133 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
8134 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
8135 zone->retry = DNS_ZONE_DEFAULTRETRY;
8136 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
8141 dns_zone_refresh(dns_zone_t *zone) {
8143 isc_uint32_t oldflags;
8145 isc_result_t result;
8147 REQUIRE(DNS_ZONE_VALID(zone));
8149 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8153 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
8154 * in progress at a time.
8158 oldflags = zone->flags;
8159 if (zone->masterscnt == 0) {
8160 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
8161 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
8162 dns_zone_log(zone, ISC_LOG_ERROR,
8163 "cannot refresh: no masters");
8166 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
8167 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
8168 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
8169 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
8173 * Set the next refresh time as if refresh check has failed.
8174 * Setting this to the retry time will do that. XXXMLG
8175 * If we are successful it will be reset using zone->refresh.
8177 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
8179 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
8180 if (result != ISC_R_SUCCESS)
8181 dns_zone_log(zone, ISC_LOG_WARNING,
8182 "isc_time_nowplusinterval() failed: %s",
8183 dns_result_totext(result));
8186 * When lacking user-specified timer values from the SOA,
8187 * do exponential backoff of the retry time up to a
8188 * maximum of six hours.
8190 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
8191 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
8193 zone->curmaster = 0;
8194 for (j = 0; j < zone->masterscnt; j++)
8195 zone->mastersok[j] = ISC_FALSE;
8196 /* initiate soa query */
8197 queue_soa_query(zone);
8203 dns_zone_flush(dns_zone_t *zone) {
8204 isc_result_t result = ISC_R_SUCCESS;
8205 isc_boolean_t dumping;
8207 REQUIRE(DNS_ZONE_VALID(zone));
8210 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
8211 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8212 zone->masterfile != NULL) {
8213 result = ISC_R_ALREADYRUNNING;
8214 dumping = was_dumping(zone);
8219 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8224 dns_zone_dump(dns_zone_t *zone) {
8225 isc_result_t result = ISC_R_ALREADYRUNNING;
8226 isc_boolean_t dumping;
8228 REQUIRE(DNS_ZONE_VALID(zone));
8231 dumping = was_dumping(zone);
8234 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8239 zone_needdump(dns_zone_t *zone, unsigned int delay) {
8240 isc_time_t dumptime;
8244 * 'zone' locked by caller
8247 REQUIRE(DNS_ZONE_VALID(zone));
8248 REQUIRE(LOCKED_ZONE(zone));
8251 * Do we have a place to dump to and are we loaded?
8253 if (zone->masterfile == NULL ||
8254 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
8258 /* add some noise */
8259 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
8261 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8262 if (isc_time_isepoch(&zone->dumptime) ||
8263 isc_time_compare(&zone->dumptime, &dumptime) > 0)
8264 zone->dumptime = dumptime;
8265 if (zone->task != NULL)
8266 zone_settimer(zone, &now);
8270 dump_done(void *arg, isc_result_t result) {
8271 const char me[] = "dump_done";
8272 dns_zone_t *zone = arg;
8274 dns_dbversion_t *version;
8275 isc_boolean_t again = ISC_FALSE;
8276 isc_boolean_t compact = ISC_FALSE;
8277 isc_uint32_t serial;
8278 isc_result_t tresult;
8280 REQUIRE(DNS_ZONE_VALID(zone));
8284 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
8285 zone->journalsize != -1) {
8288 * We don't own these, zone->dctx must stay valid.
8290 db = dns_dumpctx_db(zone->dctx);
8291 version = dns_dumpctx_version(zone->dctx);
8293 tresult = dns_db_getsoaserial(db, version, &serial);
8295 * Note: we are task locked here so we can test
8298 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
8299 tresult = dns_journal_compact(zone->mctx,
8306 case ISC_R_NOTFOUND:
8307 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8308 "dns_journal_compact: %s",
8309 dns_result_totext(tresult));
8312 dns_zone_log(zone, ISC_LOG_ERROR,
8313 "dns_journal_compact failed: %s",
8314 dns_result_totext(tresult));
8317 } else if (tresult == ISC_R_SUCCESS) {
8319 zone->compact_serial = serial;
8324 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8326 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
8327 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
8329 * Try again in a short while.
8331 zone_needdump(zone, DNS_DUMP_DELAY);
8332 } else if (result == ISC_R_SUCCESS &&
8333 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8334 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8335 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8336 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8337 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8338 isc_time_settoepoch(&zone->dumptime);
8340 } else if (result == ISC_R_SUCCESS)
8341 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8343 if (zone->dctx != NULL)
8344 dns_dumpctx_detach(&zone->dctx);
8345 zonemgr_putio(&zone->writeio);
8348 (void)zone_dump(zone, ISC_FALSE);
8349 dns_zone_idetach(&zone);
8353 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
8354 const char me[] = "zone_dump";
8355 isc_result_t result;
8356 dns_dbversion_t *version = NULL;
8357 isc_boolean_t again;
8358 dns_db_t *db = NULL;
8359 char *masterfile = NULL;
8360 dns_masterformat_t masterformat = dns_masterformat_none;
8363 * 'compact' MUST only be set if we are task locked.
8366 REQUIRE(DNS_ZONE_VALID(zone));
8370 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8371 if (zone->db != NULL)
8372 dns_db_attach(zone->db, &db);
8373 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8375 if (zone->masterfile != NULL) {
8376 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
8377 masterformat = zone->masterformat;
8381 result = DNS_R_NOTLOADED;
8384 if (masterfile == NULL) {
8385 result = DNS_R_NOMASTERFILE;
8389 if (compact && zone->type != dns_zone_stub) {
8390 dns_zone_t *dummy = NULL;
8392 zone_iattach(zone, &dummy);
8393 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
8394 zone_gotwritehandle, zone,
8396 if (result != ISC_R_SUCCESS)
8397 zone_idetach(&dummy);
8399 result = DNS_R_CONTINUE;
8402 dns_db_currentversion(db, &version);
8403 result = dns_master_dump2(zone->mctx, db, version,
8404 &dns_master_style_default,
8405 masterfile, masterformat);
8406 dns_db_closeversion(db, &version, ISC_FALSE);
8411 if (masterfile != NULL)
8412 isc_mem_free(zone->mctx, masterfile);
8415 if (result == DNS_R_CONTINUE)
8416 return (ISC_R_SUCCESS); /* XXXMPA */
8420 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8421 if (result != ISC_R_SUCCESS) {
8423 * Try again in a short while.
8425 zone_needdump(zone, DNS_DUMP_DELAY);
8426 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8427 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8428 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8429 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8430 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8431 isc_time_settoepoch(&zone->dumptime);
8434 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8443 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
8444 dns_masterformat_t format)
8446 isc_result_t result;
8447 dns_dbversion_t *version = NULL;
8448 dns_db_t *db = NULL;
8450 REQUIRE(DNS_ZONE_VALID(zone));
8452 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8453 if (zone->db != NULL)
8454 dns_db_attach(zone->db, &db);
8455 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8457 return (DNS_R_NOTLOADED);
8459 dns_db_currentversion(db, &version);
8460 result = dns_master_dumptostream2(zone->mctx, db, version, style,
8462 dns_db_closeversion(db, &version, ISC_FALSE);
8468 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
8469 const dns_master_style_t *style) {
8470 return dumptostream(zone, fd, style, format);
8474 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
8475 return dumptostream(zone, fd, &dns_master_style_default,
8476 dns_masterformat_text);
8480 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
8481 return dumptostream(zone, fd, &dns_master_style_full,
8482 dns_masterformat_text);
8486 dns_zone_unload(dns_zone_t *zone) {
8487 REQUIRE(DNS_ZONE_VALID(zone));
8495 notify_cancel(dns_zone_t *zone) {
8496 dns_notify_t *notify;
8499 * 'zone' locked by caller.
8502 REQUIRE(LOCKED_ZONE(zone));
8504 for (notify = ISC_LIST_HEAD(zone->notifies);
8506 notify = ISC_LIST_NEXT(notify, link)) {
8507 if (notify->find != NULL)
8508 dns_adb_cancelfind(notify->find);
8509 if (notify->request != NULL)
8510 dns_request_cancel(notify->request);
8515 forward_cancel(dns_zone_t *zone) {
8516 dns_forward_t *forward;
8519 * 'zone' locked by caller.
8522 REQUIRE(LOCKED_ZONE(zone));
8524 for (forward = ISC_LIST_HEAD(zone->forwards);
8526 forward = ISC_LIST_NEXT(forward, link)) {
8527 if (forward->request != NULL)
8528 dns_request_cancel(forward->request);
8533 zone_unload(dns_zone_t *zone) {
8536 * 'zone' locked by caller.
8539 REQUIRE(LOCKED_ZONE(zone));
8541 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8542 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8543 if (zone->writeio != NULL)
8544 zonemgr_cancelio(zone->writeio);
8546 if (zone->dctx != NULL)
8547 dns_dumpctx_cancel(zone->dctx);
8549 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
8550 zone_detachdb(zone);
8551 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
8552 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
8553 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8557 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8558 REQUIRE(DNS_ZONE_VALID(zone));
8561 zone->minrefresh = val;
8565 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8566 REQUIRE(DNS_ZONE_VALID(zone));
8569 zone->maxrefresh = val;
8573 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
8574 REQUIRE(DNS_ZONE_VALID(zone));
8577 zone->minretry = val;
8581 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
8582 REQUIRE(DNS_ZONE_VALID(zone));
8585 zone->maxretry = val;
8588 static isc_boolean_t
8589 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
8590 dns_notify_t *notify;
8592 for (notify = ISC_LIST_HEAD(zone->notifies);
8594 notify = ISC_LIST_NEXT(notify, link)) {
8595 if (notify->request != NULL)
8597 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
8598 dns_name_equal(name, ¬ify->ns))
8600 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
8606 static isc_boolean_t
8607 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
8608 dns_tsigkey_t *key = NULL;
8611 isc_boolean_t isself;
8612 isc_netaddr_t dstaddr;
8613 isc_result_t result;
8615 if (zone->view == NULL || zone->isself == NULL)
8618 switch (isc_sockaddr_pf(dst)) {
8620 src = zone->notifysrc4;
8621 isc_sockaddr_any(&any);
8624 src = zone->notifysrc6;
8625 isc_sockaddr_any6(&any);
8632 * When sending from any the kernel will assign a source address
8633 * that matches the destination address.
8635 if (isc_sockaddr_eqaddr(&any, &src))
8638 isc_netaddr_fromsockaddr(&dstaddr, dst);
8639 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
8640 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
8642 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
8645 dns_tsigkey_detach(&key);
8650 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
8654 * Caller holds zone lock.
8656 REQUIRE(DNS_NOTIFY_VALID(notify));
8658 if (notify->zone != NULL) {
8660 LOCK_ZONE(notify->zone);
8661 REQUIRE(LOCKED_ZONE(notify->zone));
8662 if (ISC_LINK_LINKED(notify, link))
8663 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
8665 UNLOCK_ZONE(notify->zone);
8667 zone_idetach(¬ify->zone);
8669 dns_zone_idetach(¬ify->zone);
8671 if (notify->find != NULL)
8672 dns_adb_destroyfind(¬ify->find);
8673 if (notify->request != NULL)
8674 dns_request_destroy(¬ify->request);
8675 if (dns_name_dynamic(¬ify->ns))
8676 dns_name_free(¬ify->ns, notify->mctx);
8677 mctx = notify->mctx;
8678 isc_mem_put(notify->mctx, notify, sizeof(*notify));
8679 isc_mem_detach(&mctx);
8683 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
8684 dns_notify_t *notify;
8686 REQUIRE(notifyp != NULL && *notifyp == NULL);
8688 notify = isc_mem_get(mctx, sizeof(*notify));
8690 return (ISC_R_NOMEMORY);
8692 notify->mctx = NULL;
8693 isc_mem_attach(mctx, ¬ify->mctx);
8694 notify->flags = flags;
8695 notify->zone = NULL;
8696 notify->find = NULL;
8697 notify->request = NULL;
8698 isc_sockaddr_any(¬ify->dst);
8699 dns_name_init(¬ify->ns, NULL);
8700 ISC_LINK_INIT(notify, link);
8701 notify->magic = NOTIFY_MAGIC;
8703 return (ISC_R_SUCCESS);
8707 * XXXAG should check for DNS_ZONEFLG_EXITING
8710 process_adb_event(isc_task_t *task, isc_event_t *ev) {
8711 dns_notify_t *notify;
8712 isc_eventtype_t result;
8716 notify = ev->ev_arg;
8717 REQUIRE(DNS_NOTIFY_VALID(notify));
8718 INSIST(task == notify->zone->task);
8719 result = ev->ev_type;
8720 isc_event_free(&ev);
8721 if (result == DNS_EVENT_ADBMOREADDRESSES) {
8722 dns_adb_destroyfind(¬ify->find);
8723 notify_find_address(notify);
8726 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
8727 LOCK_ZONE(notify->zone);
8728 notify_send(notify);
8729 UNLOCK_ZONE(notify->zone);
8731 notify_destroy(notify, ISC_FALSE);
8735 notify_find_address(dns_notify_t *notify) {
8736 isc_result_t result;
8737 unsigned int options;
8739 REQUIRE(DNS_NOTIFY_VALID(notify));
8740 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
8741 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
8743 if (notify->zone->view->adb == NULL)
8746 result = dns_adb_createfind(notify->zone->view->adb,
8748 process_adb_event, notify,
8749 ¬ify->ns, dns_rootname, 0,
8751 notify->zone->view->dstport,
8754 /* Something failed? */
8755 if (result != ISC_R_SUCCESS)
8758 /* More addresses pending? */
8759 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
8762 /* We have as many addresses as we can get. */
8763 LOCK_ZONE(notify->zone);
8764 notify_send(notify);
8765 UNLOCK_ZONE(notify->zone);
8768 notify_destroy(notify, ISC_FALSE);
8773 notify_send_queue(dns_notify_t *notify) {
8775 isc_result_t result;
8777 e = isc_event_allocate(notify->mctx, NULL,
8778 DNS_EVENT_NOTIFYSENDTOADDR,
8780 notify, sizeof(isc_event_t));
8782 return (ISC_R_NOMEMORY);
8784 e->ev_sender = NULL;
8785 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
8786 notify->zone->task, &e);
8787 if (result != ISC_R_SUCCESS)
8793 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
8794 dns_notify_t *notify;
8795 isc_result_t result;
8796 dns_message_t *message = NULL;
8797 isc_netaddr_t dstip;
8798 dns_tsigkey_t *key = NULL;
8799 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
8802 isc_boolean_t have_notifysource = ISC_FALSE;
8804 notify = event->ev_arg;
8805 REQUIRE(DNS_NOTIFY_VALID(notify));
8809 LOCK_ZONE(notify->zone);
8811 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
8812 result = ISC_R_CANCELED;
8816 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
8817 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
8818 notify->zone->view->requestmgr == NULL ||
8819 notify->zone->db == NULL) {
8820 result = ISC_R_CANCELED;
8825 * The raw IPv4 address should also exist. Don't send to the
8828 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
8829 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
8830 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
8831 notify_log(notify->zone, ISC_LOG_DEBUG(3),
8832 "notify: ignoring IPv6 mapped IPV4 address: %s",
8834 result = ISC_R_CANCELED;
8838 result = notify_createmessage(notify->zone, notify->flags, &message);
8839 if (result != ISC_R_SUCCESS)
8842 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
8843 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
8844 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
8845 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8846 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
8847 "sent. Peer TSIG key lookup failure.", addrbuf);
8848 goto cleanup_message;
8851 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
8853 if (notify->zone->view->peers != NULL) {
8854 dns_peer_t *peer = NULL;
8855 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
8857 if (result == ISC_R_SUCCESS) {
8858 result = dns_peer_getnotifysource(peer, &src);
8859 if (result == ISC_R_SUCCESS)
8860 have_notifysource = ISC_TRUE;
8863 switch (isc_sockaddr_pf(¬ify->dst)) {
8865 if (!have_notifysource)
8866 src = notify->zone->notifysrc4;
8869 if (!have_notifysource)
8870 src = notify->zone->notifysrc6;
8873 result = ISC_R_NOTIMPLEMENTED;
8877 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
8879 result = dns_request_createvia2(notify->zone->view->requestmgr,
8880 message, &src, ¬ify->dst, 0, key,
8881 timeout * 3, timeout,
8882 notify->zone->task, notify_done,
8883 notify, ¬ify->request);
8884 if (result == ISC_R_SUCCESS) {
8885 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
8886 inc_stats(notify->zone,
8887 dns_zonestatscounter_notifyoutv4);
8889 inc_stats(notify->zone,
8890 dns_zonestatscounter_notifyoutv6);
8896 dns_tsigkey_detach(&key);
8898 dns_message_destroy(&message);
8900 UNLOCK_ZONE(notify->zone);
8901 if (result != ISC_R_SUCCESS)
8902 notify_destroy(notify, ISC_FALSE);
8903 isc_event_free(&event);
8907 notify_send(dns_notify_t *notify) {
8908 dns_adbaddrinfo_t *ai;
8910 isc_result_t result;
8911 dns_notify_t *new = NULL;
8914 * Zone lock held by caller.
8916 REQUIRE(DNS_NOTIFY_VALID(notify));
8917 REQUIRE(LOCKED_ZONE(notify->zone));
8919 for (ai = ISC_LIST_HEAD(notify->find->list);
8921 ai = ISC_LIST_NEXT(ai, publink)) {
8923 if (notify_isqueued(notify->zone, NULL, &dst))
8925 if (notify_isself(notify->zone, &dst))
8928 result = notify_create(notify->mctx,
8929 (notify->flags & DNS_NOTIFY_NOSOA),
8931 if (result != ISC_R_SUCCESS)
8933 zone_iattach(notify->zone, &new->zone);
8934 ISC_LIST_APPEND(new->zone->notifies, new, link);
8936 result = notify_send_queue(new);
8937 if (result != ISC_R_SUCCESS)
8944 notify_destroy(new, ISC_TRUE);
8948 dns_zone_notify(dns_zone_t *zone) {
8951 REQUIRE(DNS_ZONE_VALID(zone));
8954 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8957 zone_settimer(zone, &now);
8962 zone_notify(dns_zone_t *zone, isc_time_t *now) {
8963 dns_dbnode_t *node = NULL;
8964 dns_db_t *zonedb = NULL;
8965 dns_dbversion_t *version = NULL;
8966 dns_name_t *origin = NULL;
8969 dns_rdata_soa_t soa;
8970 isc_uint32_t serial;
8971 dns_rdata_t rdata = DNS_RDATA_INIT;
8972 dns_rdataset_t nsrdset;
8973 dns_rdataset_t soardset;
8974 isc_result_t result;
8975 dns_notify_t *notify = NULL;
8978 isc_boolean_t isqueued;
8979 dns_notifytype_t notifytype;
8980 unsigned int flags = 0;
8981 isc_boolean_t loggednotify = ISC_FALSE;
8983 REQUIRE(DNS_ZONE_VALID(zone));
8986 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8987 notifytype = zone->notifytype;
8988 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
8991 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
8994 if (notifytype == dns_notifytype_no)
8997 if (notifytype == dns_notifytype_masteronly &&
8998 zone->type != dns_zone_master)
9001 origin = &zone->origin;
9004 * If the zone is dialup we are done as we don't want to send
9005 * the current soa so as to force a refresh query.
9007 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
9008 flags |= DNS_NOTIFY_NOSOA;
9013 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9014 if (zone->db != NULL)
9015 dns_db_attach(zone->db, &zonedb);
9016 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9019 dns_db_currentversion(zonedb, &version);
9020 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
9021 if (result != ISC_R_SUCCESS)
9024 dns_rdataset_init(&soardset);
9025 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
9026 dns_rdatatype_none, 0, &soardset, NULL);
9027 if (result != ISC_R_SUCCESS)
9031 * Find serial and master server's name.
9033 dns_name_init(&master, NULL);
9034 result = dns_rdataset_first(&soardset);
9035 if (result != ISC_R_SUCCESS)
9037 dns_rdataset_current(&soardset, &rdata);
9038 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9039 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9040 dns_rdata_reset(&rdata);
9041 result = dns_name_dup(&soa.origin, zone->mctx, &master);
9042 serial = soa.serial;
9043 dns_rdataset_disassociate(&soardset);
9044 if (result != ISC_R_SUCCESS)
9048 * Enqueue notify requests for 'also-notify' servers.
9051 for (i = 0; i < zone->notifycnt; i++) {
9052 dst = zone->notify[i];
9053 if (notify_isqueued(zone, NULL, &dst))
9055 result = notify_create(zone->mctx, flags, ¬ify);
9056 if (result != ISC_R_SUCCESS)
9058 zone_iattach(zone, ¬ify->zone);
9060 ISC_LIST_APPEND(zone->notifies, notify, link);
9061 result = notify_send_queue(notify);
9062 if (result != ISC_R_SUCCESS)
9063 notify_destroy(notify, ISC_TRUE);
9064 if (!loggednotify) {
9065 notify_log(zone, ISC_LOG_INFO,
9066 "sending notifies (serial %u)",
9068 loggednotify = ISC_TRUE;
9074 if (notifytype == dns_notifytype_explicit)
9078 * Process NS RRset to generate notifies.
9081 dns_rdataset_init(&nsrdset);
9082 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
9083 dns_rdatatype_none, 0, &nsrdset, NULL);
9084 if (result != ISC_R_SUCCESS)
9087 result = dns_rdataset_first(&nsrdset);
9088 while (result == ISC_R_SUCCESS) {
9089 dns_rdataset_current(&nsrdset, &rdata);
9090 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9091 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9092 dns_rdata_reset(&rdata);
9094 * Don't notify the master server unless explicitly
9095 * configured to do so.
9097 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
9098 dns_name_compare(&master, &ns.name) == 0) {
9099 result = dns_rdataset_next(&nsrdset);
9103 if (!loggednotify) {
9104 notify_log(zone, ISC_LOG_INFO,
9105 "sending notifies (serial %u)",
9107 loggednotify = ISC_TRUE;
9111 isqueued = notify_isqueued(zone, &ns.name, NULL);
9114 result = dns_rdataset_next(&nsrdset);
9117 result = notify_create(zone->mctx, flags, ¬ify);
9118 if (result != ISC_R_SUCCESS)
9120 dns_zone_iattach(zone, ¬ify->zone);
9121 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
9122 if (result != ISC_R_SUCCESS) {
9124 notify_destroy(notify, ISC_TRUE);
9129 ISC_LIST_APPEND(zone->notifies, notify, link);
9131 notify_find_address(notify);
9133 result = dns_rdataset_next(&nsrdset);
9135 dns_rdataset_disassociate(&nsrdset);
9138 if (dns_name_dynamic(&master))
9139 dns_name_free(&master, zone->mctx);
9141 dns_db_detachnode(zonedb, &node);
9143 dns_db_closeversion(zonedb, &version, ISC_FALSE);
9144 dns_db_detach(&zonedb);
9151 static inline isc_result_t
9152 save_nsrrset(dns_message_t *message, dns_name_t *name,
9153 dns_db_t *db, dns_dbversion_t *version)
9155 dns_rdataset_t *nsrdataset = NULL;
9156 dns_rdataset_t *rdataset = NULL;
9157 dns_dbnode_t *node = NULL;
9159 isc_result_t result;
9160 dns_rdata_t rdata = DNS_RDATA_INIT;
9163 * Extract NS RRset from message.
9165 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
9166 dns_rdatatype_ns, dns_rdatatype_none,
9168 if (result != ISC_R_SUCCESS)
9174 result = dns_db_findnode(db, name, ISC_TRUE, &node);
9175 if (result != ISC_R_SUCCESS)
9177 result = dns_db_addrdataset(db, node, version, 0,
9178 nsrdataset, 0, NULL);
9179 dns_db_detachnode(db, &node);
9180 if (result != ISC_R_SUCCESS)
9183 * Add glue rdatasets.
9185 for (result = dns_rdataset_first(nsrdataset);
9186 result == ISC_R_SUCCESS;
9187 result = dns_rdataset_next(nsrdataset)) {
9188 dns_rdataset_current(nsrdataset, &rdata);
9189 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9190 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9191 dns_rdata_reset(&rdata);
9192 if (!dns_name_issubdomain(&ns.name, name))
9195 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9196 &ns.name, dns_rdatatype_aaaa,
9197 dns_rdatatype_none, NULL,
9199 if (result == ISC_R_SUCCESS) {
9200 result = dns_db_findnode(db, &ns.name,
9202 if (result != ISC_R_SUCCESS)
9204 result = dns_db_addrdataset(db, node, version, 0,
9206 dns_db_detachnode(db, &node);
9207 if (result != ISC_R_SUCCESS)
9211 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9212 &ns.name, dns_rdatatype_a,
9213 dns_rdatatype_none, NULL,
9215 if (result == ISC_R_SUCCESS) {
9216 result = dns_db_findnode(db, &ns.name,
9218 if (result != ISC_R_SUCCESS)
9220 result = dns_db_addrdataset(db, node, version, 0,
9222 dns_db_detachnode(db, &node);
9223 if (result != ISC_R_SUCCESS)
9227 if (result != ISC_R_NOMORE)
9230 return (ISC_R_SUCCESS);
9237 stub_callback(isc_task_t *task, isc_event_t *event) {
9238 const char me[] = "stub_callback";
9239 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9240 dns_stub_t *stub = NULL;
9241 dns_message_t *msg = NULL;
9242 dns_zone_t *zone = NULL;
9243 char master[ISC_SOCKADDR_FORMATSIZE];
9244 char source[ISC_SOCKADDR_FORMATSIZE];
9245 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
9246 isc_result_t result;
9248 isc_boolean_t exiting = ISC_FALSE;
9252 stub = revent->ev_arg;
9253 INSIST(DNS_STUB_VALID(stub));
9265 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9266 zone_debuglog(zone, me, 1, "exiting");
9271 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9272 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9274 if (revent->result != ISC_R_SUCCESS) {
9275 if (revent->result == ISC_R_TIMEDOUT &&
9276 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9277 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9278 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9279 "refreshing stub: timeout retrying "
9280 " without EDNS master %s (source %s)",
9284 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
9285 &zone->sourceaddr, &now);
9286 dns_zone_log(zone, ISC_LOG_INFO,
9287 "could not refresh stub from master %s"
9288 " (source %s): %s", master, source,
9289 dns_result_totext(revent->result));
9293 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9294 if (result != ISC_R_SUCCESS)
9297 result = dns_request_getresponse(revent->request, msg, 0);
9298 if (result != ISC_R_SUCCESS)
9304 if (msg->rcode != dns_rcode_noerror) {
9308 isc_buffer_init(&rb, rcode, sizeof(rcode));
9309 (void)dns_rcode_totext(msg->rcode, &rb);
9311 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9312 (msg->rcode == dns_rcode_servfail ||
9313 msg->rcode == dns_rcode_notimp ||
9314 msg->rcode == dns_rcode_formerr)) {
9315 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9316 "refreshing stub: rcode (%.*s) retrying "
9317 "without EDNS master %s (source %s)",
9318 (int)rb.used, rcode, master, source);
9319 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9323 dns_zone_log(zone, ISC_LOG_INFO,
9325 "unexpected rcode (%.*s) from %s (source %s)",
9326 (int)rb.used, rcode, master, source);
9331 * We need complete messages.
9333 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9334 if (dns_request_usedtcp(revent->request)) {
9335 dns_zone_log(zone, ISC_LOG_INFO,
9336 "refreshing stub: truncated TCP "
9337 "response from master %s (source %s)",
9341 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9346 * If non-auth log and next master.
9348 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9349 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
9350 "non-authoritative answer from "
9351 "master %s (source %s)", master, source);
9358 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9359 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
9361 if (cnamecnt != 0) {
9362 dns_zone_log(zone, ISC_LOG_INFO,
9363 "refreshing stub: unexpected CNAME response "
9364 "from master %s (source %s)", master, source);
9369 dns_zone_log(zone, ISC_LOG_INFO,
9370 "refreshing stub: no NS records in response "
9371 "from master %s (source %s)", master, source);
9378 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
9379 if (result != ISC_R_SUCCESS) {
9380 dns_zone_log(zone, ISC_LOG_INFO,
9381 "refreshing stub: unable to save NS records "
9382 "from master %s (source %s)", master, source);
9389 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
9390 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9391 if (zone->db == NULL)
9392 zone_attachdb(zone, stub->db);
9393 result = zone_get_from_db(zone, zone->db, NULL, NULL, NULL, &refresh,
9394 &retry, &expire, NULL, NULL);
9395 if (result == ISC_R_SUCCESS) {
9396 zone->refresh = RANGE(refresh, zone->minrefresh,
9398 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
9399 zone->expire = RANGE(expire, zone->refresh + zone->retry,
9401 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9403 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9404 dns_db_detach(&stub->db);
9406 dns_message_destroy(&msg);
9407 isc_event_free(&event);
9408 dns_request_destroy(&zone->request);
9410 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9411 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
9412 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9413 isc_interval_set(&i, zone->expire, 0);
9414 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9416 if (zone->masterfile != NULL)
9417 zone_needdump(zone, 0);
9419 zone_settimer(zone, &now);
9423 if (stub->version != NULL)
9424 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
9425 if (stub->db != NULL)
9426 dns_db_detach(&stub->db);
9428 dns_message_destroy(&msg);
9429 isc_event_free(&event);
9430 dns_request_destroy(&zone->request);
9432 * Skip to next failed / untried master.
9436 } while (zone->curmaster < zone->masterscnt &&
9437 zone->mastersok[zone->curmaster]);
9438 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9439 if (exiting || zone->curmaster >= zone->masterscnt) {
9440 isc_boolean_t done = ISC_TRUE;
9442 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9443 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9445 * Did we get a good answer from all the masters?
9447 for (j = 0; j < zone->masterscnt; j++)
9448 if (zone->mastersok[j] == ISC_FALSE) {
9455 zone->curmaster = 0;
9457 * Find the next failed master.
9459 while (zone->curmaster < zone->masterscnt &&
9460 zone->mastersok[zone->curmaster])
9462 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9464 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9466 zone_settimer(zone, &now);
9470 queue_soa_query(zone);
9475 dns_message_destroy(&msg);
9476 isc_event_free(&event);
9477 dns_request_destroy(&zone->request);
9478 ns_query(zone, NULL, stub);
9485 dns_zone_idetach(&stub->zone);
9486 INSIST(stub->db == NULL);
9487 INSIST(stub->version == NULL);
9488 isc_mem_put(stub->mctx, stub, sizeof(*stub));
9491 INSIST(event == NULL);
9496 * An SOA query has finished (successfully or not).
9499 refresh_callback(isc_task_t *task, isc_event_t *event) {
9500 const char me[] = "refresh_callback";
9501 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9503 dns_message_t *msg = NULL;
9504 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
9506 char master[ISC_SOCKADDR_FORMATSIZE];
9507 char source[ISC_SOCKADDR_FORMATSIZE];
9508 dns_rdataset_t *rdataset = NULL;
9509 dns_rdata_t rdata = DNS_RDATA_INIT;
9510 dns_rdata_soa_t soa;
9511 isc_result_t result;
9512 isc_uint32_t serial, oldserial = 0;
9514 isc_boolean_t do_queue_xfrin = ISC_FALSE;
9516 zone = revent->ev_arg;
9517 INSIST(DNS_ZONE_VALID(zone));
9528 * if timeout log and next master;
9531 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9532 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9534 if (revent->result != ISC_R_SUCCESS) {
9535 if (revent->result == ISC_R_TIMEDOUT &&
9536 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9537 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9538 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9539 "refresh: timeout retrying without EDNS "
9540 "master %s (source %s)", master, source);
9543 if (revent->result == ISC_R_TIMEDOUT &&
9544 !dns_request_usedtcp(revent->request)) {
9545 dns_zone_log(zone, ISC_LOG_INFO,
9546 "refresh: retry limit for "
9547 "master %s exceeded (source %s)",
9549 /* Try with slave with TCP. */
9550 if (zone->type == dns_zone_slave &&
9551 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
9552 if (!dns_zonemgr_unreachable(zone->zmgr,
9557 DNS_ZONE_SETFLAG(zone,
9558 DNS_ZONEFLG_SOABEFOREAXFR);
9561 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9562 "refresh: skipped tcp fallback "
9563 "as master %s (source %s) is "
9564 "unreachable (cached)",
9568 dns_zone_log(zone, ISC_LOG_INFO,
9569 "refresh: failure trying master "
9570 "%s (source %s): %s", master, source,
9571 dns_result_totext(revent->result));
9575 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9576 if (result != ISC_R_SUCCESS)
9578 result = dns_request_getresponse(revent->request, msg, 0);
9579 if (result != ISC_R_SUCCESS) {
9580 dns_zone_log(zone, ISC_LOG_INFO,
9581 "refresh: failure trying master "
9582 "%s (source %s): %s", master, source,
9583 dns_result_totext(result));
9590 if (msg->rcode != dns_rcode_noerror) {
9594 isc_buffer_init(&rb, rcode, sizeof(rcode));
9595 (void)dns_rcode_totext(msg->rcode, &rb);
9597 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9598 (msg->rcode == dns_rcode_servfail ||
9599 msg->rcode == dns_rcode_notimp ||
9600 msg->rcode == dns_rcode_formerr)) {
9601 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9602 "refresh: rcode (%.*s) retrying without "
9603 "EDNS master %s (source %s)",
9604 (int)rb.used, rcode, master, source);
9605 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9608 dns_zone_log(zone, ISC_LOG_INFO,
9609 "refresh: unexpected rcode (%.*s) from "
9610 "master %s (source %s)", (int)rb.used, rcode,
9613 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
9615 if (msg->rcode == dns_rcode_refused &&
9616 zone->type == dns_zone_slave)
9622 * If truncated punt to zone transfer which will query again.
9624 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9625 if (zone->type == dns_zone_slave) {
9626 dns_zone_log(zone, ISC_LOG_INFO,
9627 "refresh: truncated UDP answer, "
9628 "initiating TCP zone xfer "
9629 "for master %s (source %s)",
9631 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9634 INSIST(zone->type == dns_zone_stub);
9635 if (dns_request_usedtcp(revent->request)) {
9636 dns_zone_log(zone, ISC_LOG_INFO,
9637 "refresh: truncated TCP response "
9638 "from master %s (source %s)",
9642 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9648 * if non-auth log and next master;
9650 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9651 dns_zone_log(zone, ISC_LOG_INFO,
9652 "refresh: non-authoritative answer from "
9653 "master %s (source %s)", master, source);
9657 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9658 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
9659 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
9660 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
9664 * There should not be a CNAME record at top of zone.
9666 if (cnamecnt != 0) {
9667 dns_zone_log(zone, ISC_LOG_INFO,
9668 "refresh: CNAME at top of zone "
9669 "in master %s (source %s)", master, source);
9674 * if referral log and next master;
9676 if (soacnt == 0 && soacount == 0 && nscount != 0) {
9677 dns_zone_log(zone, ISC_LOG_INFO,
9678 "refresh: referral response "
9679 "from master %s (source %s)", master, source);
9684 * if nodata log and next master;
9686 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
9687 dns_zone_log(zone, ISC_LOG_INFO,
9688 "refresh: NODATA response "
9689 "from master %s (source %s)", master, source);
9694 * Only one soa at top of zone.
9697 dns_zone_log(zone, ISC_LOG_INFO,
9698 "refresh: answer SOA count (%d) != 1 "
9699 "from master %s (source %s)",
9700 soacnt, master, source);
9708 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
9709 dns_rdatatype_soa, dns_rdatatype_none,
9711 if (result != ISC_R_SUCCESS) {
9712 dns_zone_log(zone, ISC_LOG_INFO,
9713 "refresh: unable to get SOA record "
9714 "from master %s (source %s)", master, source);
9718 result = dns_rdataset_first(rdataset);
9719 if (result != ISC_R_SUCCESS) {
9720 dns_zone_log(zone, ISC_LOG_INFO,
9721 "refresh: dns_rdataset_first() failed");
9725 dns_rdataset_current(rdataset, &rdata);
9726 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9727 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9729 serial = soa.serial;
9730 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9731 result = zone_get_from_db(zone, zone->db, NULL, NULL,
9732 &oldserial, NULL, NULL, NULL, NULL,
9734 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9735 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
9738 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
9741 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
9742 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
9743 isc_serial_gt(serial, oldserial)) {
9744 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
9745 &zone->sourceaddr, &now))
9747 dns_zone_log(zone, ISC_LOG_INFO,
9748 "refresh: skipping %s as master %s "
9749 "(source %s) is unreachable (cached)",
9750 zone->type == dns_zone_slave ?
9751 "zone transfer" : "NS query",
9756 isc_event_free(&event);
9757 dns_request_destroy(&zone->request);
9758 if (zone->type == dns_zone_slave) {
9759 do_queue_xfrin = ISC_TRUE;
9761 INSIST(zone->type == dns_zone_stub);
9762 ns_query(zone, rdataset, NULL);
9765 dns_message_destroy(&msg);
9766 } else if (isc_serial_eq(soa.serial, oldserial)) {
9767 if (zone->masterfile != NULL) {
9768 result = ISC_R_FAILURE;
9769 if (zone->journal != NULL)
9770 result = isc_file_settime(zone->journal, &now);
9771 if (result == ISC_R_SUCCESS &&
9772 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9773 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
9774 result = isc_file_settime(zone->masterfile,
9776 } else if (result != ISC_R_SUCCESS)
9777 result = isc_file_settime(zone->masterfile,
9779 /* Someone removed the file from underneath us! */
9780 if (result == ISC_R_FILENOTFOUND) {
9781 zone_needdump(zone, DNS_DUMP_DELAY);
9782 } else if (result != ISC_R_SUCCESS)
9783 dns_zone_log(zone, ISC_LOG_ERROR,
9784 "refresh: could not set file "
9785 "modification time of '%s': %s",
9787 dns_result_totext(result));
9789 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9790 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9791 zone->mastersok[zone->curmaster] = ISC_TRUE;
9794 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
9795 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
9796 "received from master %s < ours (%u)",
9797 soa.serial, master, oldserial);
9799 zone_debuglog(zone, me, 1, "ahead");
9800 zone->mastersok[zone->curmaster] = ISC_TRUE;
9804 dns_message_destroy(&msg);
9809 dns_message_destroy(&msg);
9810 isc_event_free(&event);
9811 dns_request_destroy(&zone->request);
9813 * Skip to next failed / untried master.
9817 } while (zone->curmaster < zone->masterscnt &&
9818 zone->mastersok[zone->curmaster]);
9819 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9820 if (zone->curmaster >= zone->masterscnt) {
9821 isc_boolean_t done = ISC_TRUE;
9822 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9823 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9825 * Did we get a good answer from all the masters?
9827 for (j = 0; j < zone->masterscnt; j++)
9828 if (zone->mastersok[j] == ISC_FALSE) {
9835 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9836 zone->curmaster = 0;
9838 * Find the next failed master.
9840 while (zone->curmaster < zone->masterscnt &&
9841 zone->mastersok[zone->curmaster])
9845 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9846 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9847 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9848 zone->refreshtime = now;
9850 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9851 zone_settimer(zone, &now);
9856 queue_soa_query(zone);
9861 dns_message_destroy(&msg);
9862 isc_event_free(&event);
9863 dns_request_destroy(&zone->request);
9864 queue_soa_query(zone);
9870 dns_zone_idetach(&zone);
9875 queue_soa_query(dns_zone_t *zone) {
9876 const char me[] = "queue_soa_query";
9878 dns_zone_t *dummy = NULL;
9879 isc_result_t result;
9885 REQUIRE(LOCKED_ZONE(zone));
9887 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9888 cancel_refresh(zone);
9892 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
9893 soa_query, zone, sizeof(isc_event_t));
9895 cancel_refresh(zone);
9900 * Attach so that we won't clean up
9901 * until the event is delivered.
9903 zone_iattach(zone, &dummy);
9906 e->ev_sender = NULL;
9907 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
9908 if (result != ISC_R_SUCCESS) {
9909 zone_idetach(&dummy);
9911 cancel_refresh(zone);
9915 static inline isc_result_t
9916 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
9917 dns_message_t **messagep)
9919 dns_message_t *message = NULL;
9920 dns_name_t *qname = NULL;
9921 dns_rdataset_t *qrdataset = NULL;
9922 isc_result_t result;
9924 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
9926 if (result != ISC_R_SUCCESS)
9929 message->opcode = dns_opcode_query;
9930 message->rdclass = zone->rdclass;
9932 result = dns_message_gettempname(message, &qname);
9933 if (result != ISC_R_SUCCESS)
9936 result = dns_message_gettemprdataset(message, &qrdataset);
9937 if (result != ISC_R_SUCCESS)
9943 dns_name_init(qname, NULL);
9944 dns_name_clone(&zone->origin, qname);
9945 dns_rdataset_init(qrdataset);
9946 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
9947 ISC_LIST_APPEND(qname->list, qrdataset, link);
9948 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
9950 *messagep = message;
9951 return (ISC_R_SUCCESS);
9955 dns_message_puttempname(message, &qname);
9956 if (qrdataset != NULL)
9957 dns_message_puttemprdataset(message, &qrdataset);
9958 if (message != NULL)
9959 dns_message_destroy(&message);
9964 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
9965 dns_rdataset_t *rdataset = NULL;
9966 dns_rdatalist_t *rdatalist = NULL;
9967 dns_rdata_t *rdata = NULL;
9968 isc_result_t result;
9970 result = dns_message_gettemprdatalist(message, &rdatalist);
9971 if (result != ISC_R_SUCCESS)
9973 result = dns_message_gettemprdata(message, &rdata);
9974 if (result != ISC_R_SUCCESS)
9976 result = dns_message_gettemprdataset(message, &rdataset);
9977 if (result != ISC_R_SUCCESS)
9979 dns_rdataset_init(rdataset);
9981 rdatalist->type = dns_rdatatype_opt;
9982 rdatalist->covers = 0;
9985 * Set Maximum UDP buffer size.
9987 rdatalist->rdclass = udpsize;
9990 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
9994 /* Set EDNS options if applicable */
9996 unsigned char data[4];
9999 isc_buffer_init(&buf, data, sizeof(data));
10000 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
10001 isc_buffer_putuint16(&buf, 0);
10002 rdata->data = data;
10003 rdata->length = sizeof(data);
10005 rdata->data = NULL;
10009 rdata->rdclass = rdatalist->rdclass;
10010 rdata->type = rdatalist->type;
10013 ISC_LIST_INIT(rdatalist->rdata);
10014 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
10015 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
10018 return (dns_message_setopt(message, rdataset));
10021 if (rdatalist != NULL)
10022 dns_message_puttemprdatalist(message, &rdatalist);
10023 if (rdataset != NULL)
10024 dns_message_puttemprdataset(message, &rdataset);
10026 dns_message_puttemprdata(message, &rdata);
10032 soa_query(isc_task_t *task, isc_event_t *event) {
10033 const char me[] = "soa_query";
10034 isc_result_t result = ISC_R_FAILURE;
10035 dns_message_t *message = NULL;
10036 dns_zone_t *zone = event->ev_arg;
10037 dns_zone_t *dummy = NULL;
10038 isc_netaddr_t masterip;
10039 dns_tsigkey_t *key = NULL;
10040 isc_uint32_t options;
10041 isc_boolean_t cancel = ISC_TRUE;
10043 isc_boolean_t have_xfrsource, reqnsid;
10044 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10046 REQUIRE(DNS_ZONE_VALID(zone));
10053 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
10054 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
10055 zone->view->requestmgr == NULL) {
10056 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10057 cancel = ISC_FALSE;
10062 * XXX Optimisation: Create message when zone is setup and reuse.
10064 result = create_query(zone, dns_rdatatype_soa, &message);
10065 if (result != ISC_R_SUCCESS)
10069 INSIST(zone->masterscnt > 0);
10070 INSIST(zone->curmaster < zone->masterscnt);
10072 zone->masteraddr = zone->masters[zone->curmaster];
10074 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10076 * First, look for a tsig key in the master statement, then
10077 * try for a server key.
10079 if ((zone->masterkeynames != NULL) &&
10080 (zone->masterkeynames[zone->curmaster] != NULL)) {
10081 dns_view_t *view = dns_zone_getview(zone);
10082 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10083 result = dns_view_gettsig(view, keyname, &key);
10084 if (result != ISC_R_SUCCESS) {
10085 char namebuf[DNS_NAME_FORMATSIZE];
10086 dns_name_format(keyname, namebuf, sizeof(namebuf));
10087 dns_zone_log(zone, ISC_LOG_ERROR,
10088 "unable to find key: %s", namebuf);
10093 result = dns_view_getpeertsig(zone->view, &masterip, &key);
10094 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10095 char addrbuf[ISC_NETADDR_FORMATSIZE];
10096 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
10097 dns_zone_log(zone, ISC_LOG_ERROR,
10098 "unable to find TSIG key for %s", addrbuf);
10103 have_xfrsource = ISC_FALSE;
10104 reqnsid = zone->view->requestnsid;
10105 if (zone->view->peers != NULL) {
10106 dns_peer_t *peer = NULL;
10107 isc_boolean_t edns;
10108 result = dns_peerlist_peerbyaddr(zone->view->peers,
10110 if (result == ISC_R_SUCCESS) {
10111 result = dns_peer_getsupportedns(peer, &edns);
10112 if (result == ISC_R_SUCCESS && !edns)
10113 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10114 result = dns_peer_gettransfersource(peer,
10115 &zone->sourceaddr);
10116 if (result == ISC_R_SUCCESS)
10117 have_xfrsource = ISC_TRUE;
10118 if (zone->view->resolver != NULL)
10120 dns_resolver_getudpsize(zone->view->resolver);
10121 (void)dns_peer_getudpsize(peer, &udpsize);
10122 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10126 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10128 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10129 if (isc_sockaddr_equal(&zone->altxfrsource4,
10130 &zone->xfrsource4))
10132 zone->sourceaddr = zone->altxfrsource4;
10133 } else if (!have_xfrsource)
10134 zone->sourceaddr = zone->xfrsource4;
10137 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10138 if (isc_sockaddr_equal(&zone->altxfrsource6,
10139 &zone->xfrsource6))
10141 zone->sourceaddr = zone->altxfrsource6;
10142 } else if (!have_xfrsource)
10143 zone->sourceaddr = zone->xfrsource6;
10146 result = ISC_R_NOTIMPLEMENTED;
10150 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
10151 DNS_REQUESTOPT_TCP : 0;
10153 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10154 result = add_opt(message, udpsize, reqnsid);
10155 if (result != ISC_R_SUCCESS)
10156 zone_debuglog(zone, me, 1,
10157 "unable to add opt record: %s",
10158 dns_result_totext(result));
10161 zone_iattach(zone, &dummy);
10163 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10165 result = dns_request_createvia2(zone->view->requestmgr, message,
10166 &zone->sourceaddr, &zone->masteraddr,
10167 options, key, timeout * 3, timeout,
10168 zone->task, refresh_callback, zone,
10170 if (result != ISC_R_SUCCESS) {
10171 zone_idetach(&dummy);
10172 zone_debuglog(zone, me, 1,
10173 "dns_request_createvia2() failed: %s",
10174 dns_result_totext(result));
10177 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
10178 inc_stats(zone, dns_zonestatscounter_soaoutv4);
10180 inc_stats(zone, dns_zonestatscounter_soaoutv6);
10182 cancel = ISC_FALSE;
10186 dns_tsigkey_detach(&key);
10187 if (result != ISC_R_SUCCESS)
10188 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10189 if (message != NULL)
10190 dns_message_destroy(&message);
10192 cancel_refresh(zone);
10193 isc_event_free(&event);
10195 dns_zone_idetach(&zone);
10200 dns_tsigkey_detach(&key);
10202 * Skip to next failed / untried master.
10206 } while (zone->curmaster < zone->masterscnt &&
10207 zone->mastersok[zone->curmaster]);
10208 if (zone->curmaster < zone->masterscnt)
10210 zone->curmaster = 0;
10215 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
10216 const char me[] = "ns_query";
10217 isc_result_t result;
10218 dns_message_t *message = NULL;
10219 isc_netaddr_t masterip;
10220 dns_tsigkey_t *key = NULL;
10221 dns_dbnode_t *node = NULL;
10223 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
10224 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10226 REQUIRE(DNS_ZONE_VALID(zone));
10227 REQUIRE(LOCKED_ZONE(zone));
10228 REQUIRE((soardataset != NULL && stub == NULL) ||
10229 (soardataset == NULL && stub != NULL));
10230 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
10234 if (stub == NULL) {
10235 stub = isc_mem_get(zone->mctx, sizeof(*stub));
10238 stub->magic = STUB_MAGIC;
10239 stub->mctx = zone->mctx;
10242 stub->version = NULL;
10245 * Attach so that the zone won't disappear from under us.
10247 zone_iattach(zone, &stub->zone);
10250 * If a db exists we will update it, otherwise we create a
10251 * new one and attach it to the zone once we have the NS
10254 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10255 if (zone->db != NULL) {
10256 dns_db_attach(zone->db, &stub->db);
10257 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10259 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10261 INSIST(zone->db_argc >= 1);
10262 result = dns_db_create(zone->mctx, zone->db_argv[0],
10263 &zone->origin, dns_dbtype_stub,
10268 if (result != ISC_R_SUCCESS) {
10269 dns_zone_log(zone, ISC_LOG_ERROR,
10270 "refreshing stub: "
10271 "could not create "
10273 dns_result_totext(result));
10276 dns_db_settask(stub->db, zone->task);
10279 result = dns_db_newversion(stub->db, &stub->version);
10280 if (result != ISC_R_SUCCESS) {
10281 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10282 "dns_db_newversion() failed: %s",
10283 dns_result_totext(result));
10288 * Update SOA record.
10290 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
10292 if (result != ISC_R_SUCCESS) {
10293 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10294 "dns_db_findnode() failed: %s",
10295 dns_result_totext(result));
10299 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
10300 soardataset, 0, NULL);
10301 dns_db_detachnode(stub->db, &node);
10302 if (result != ISC_R_SUCCESS) {
10303 dns_zone_log(zone, ISC_LOG_INFO,
10304 "refreshing stub: "
10305 "dns_db_addrdataset() failed: %s",
10306 dns_result_totext(result));
10312 * XXX Optimisation: Create message when zone is setup and reuse.
10314 result = create_query(zone, dns_rdatatype_ns, &message);
10315 INSIST(result == ISC_R_SUCCESS);
10317 INSIST(zone->masterscnt > 0);
10318 INSIST(zone->curmaster < zone->masterscnt);
10319 zone->masteraddr = zone->masters[zone->curmaster];
10321 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10323 * First, look for a tsig key in the master statement, then
10324 * try for a server key.
10326 if ((zone->masterkeynames != NULL) &&
10327 (zone->masterkeynames[zone->curmaster] != NULL)) {
10328 dns_view_t *view = dns_zone_getview(zone);
10329 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10330 result = dns_view_gettsig(view, keyname, &key);
10331 if (result != ISC_R_SUCCESS) {
10332 char namebuf[DNS_NAME_FORMATSIZE];
10333 dns_name_format(keyname, namebuf, sizeof(namebuf));
10334 dns_zone_log(zone, ISC_LOG_ERROR,
10335 "unable to find key: %s", namebuf);
10339 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
10341 reqnsid = zone->view->requestnsid;
10342 if (zone->view->peers != NULL) {
10343 dns_peer_t *peer = NULL;
10344 isc_boolean_t edns;
10345 result = dns_peerlist_peerbyaddr(zone->view->peers,
10347 if (result == ISC_R_SUCCESS) {
10348 result = dns_peer_getsupportedns(peer, &edns);
10349 if (result == ISC_R_SUCCESS && !edns)
10350 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10351 result = dns_peer_gettransfersource(peer,
10352 &zone->sourceaddr);
10353 if (result == ISC_R_SUCCESS)
10354 have_xfrsource = ISC_TRUE;
10355 if (zone->view->resolver != NULL)
10357 dns_resolver_getudpsize(zone->view->resolver);
10358 (void)dns_peer_getudpsize(peer, &udpsize);
10359 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10363 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10364 result = add_opt(message, udpsize, reqnsid);
10365 if (result != ISC_R_SUCCESS)
10366 zone_debuglog(zone, me, 1,
10367 "unable to add opt record: %s",
10368 dns_result_totext(result));
10372 * Always use TCP so that we shouldn't truncate in additional section.
10374 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10376 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10377 zone->sourceaddr = zone->altxfrsource4;
10378 else if (!have_xfrsource)
10379 zone->sourceaddr = zone->xfrsource4;
10382 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10383 zone->sourceaddr = zone->altxfrsource6;
10384 else if (!have_xfrsource)
10385 zone->sourceaddr = zone->xfrsource6;
10388 result = ISC_R_NOTIMPLEMENTED;
10393 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10395 result = dns_request_createvia2(zone->view->requestmgr, message,
10396 &zone->sourceaddr, &zone->masteraddr,
10397 DNS_REQUESTOPT_TCP, key, timeout * 3,
10398 timeout, zone->task, stub_callback,
10399 stub, &zone->request);
10400 if (result != ISC_R_SUCCESS) {
10401 zone_debuglog(zone, me, 1,
10402 "dns_request_createvia() failed: %s",
10403 dns_result_totext(result));
10406 dns_message_destroy(&message);
10410 cancel_refresh(zone);
10411 if (stub != NULL) {
10413 if (stub->version != NULL)
10414 dns_db_closeversion(stub->db, &stub->version,
10416 if (stub->db != NULL)
10417 dns_db_detach(&stub->db);
10418 if (stub->zone != NULL)
10419 zone_idetach(&stub->zone);
10420 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10422 if (message != NULL)
10423 dns_message_destroy(&message);
10426 dns_tsigkey_detach(&key);
10431 * Handle the control event. Note that although this event causes the zone
10432 * to shut down, it is not a shutdown event in the sense of the task library.
10435 zone_shutdown(isc_task_t *task, isc_event_t *event) {
10436 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
10437 isc_boolean_t free_needed, linked = ISC_FALSE;
10440 REQUIRE(DNS_ZONE_VALID(zone));
10441 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
10442 INSIST(isc_refcount_current(&zone->erefs) == 0);
10444 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
10447 * Stop things being restarted after we cancel them below.
10450 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
10454 * If we were waiting for xfrin quota, step out of
10456 * If there's no zone manager, we can't be waiting for the
10459 if (zone->zmgr != NULL) {
10460 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10461 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
10462 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
10465 zone->statelist = NULL;
10467 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10471 * In task context, no locking required. See zone_xfrdone().
10473 if (zone->xfr != NULL)
10474 dns_xfrin_shutdown(zone->xfr);
10478 INSIST(zone->irefs > 0);
10481 if (zone->request != NULL) {
10482 dns_request_cancel(zone->request);
10485 if (zone->readio != NULL)
10486 zonemgr_cancelio(zone->readio);
10488 if (zone->lctx != NULL)
10489 dns_loadctx_cancel(zone->lctx);
10491 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10492 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10493 if (zone->writeio != NULL)
10494 zonemgr_cancelio(zone->writeio);
10496 if (zone->dctx != NULL)
10497 dns_dumpctx_cancel(zone->dctx);
10500 notify_cancel(zone);
10502 forward_cancel(zone);
10504 if (zone->timer != NULL) {
10505 isc_timer_detach(&zone->timer);
10506 INSIST(zone->irefs > 0);
10510 if (zone->view != NULL)
10511 dns_view_weakdetach(&zone->view);
10514 * We have now canceled everything set the flag to allow exit_check()
10515 * to succeed. We must not unlock between setting this flag and
10516 * calling exit_check().
10518 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
10519 free_needed = exit_check(zone);
10526 zone_timer(isc_task_t *task, isc_event_t *event) {
10527 const char me[] = "zone_timer";
10528 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
10531 REQUIRE(DNS_ZONE_VALID(zone));
10535 zone_maintenance(zone);
10537 isc_event_free(&event);
10541 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
10542 const char me[] = "zone_settimer";
10544 isc_result_t result;
10547 REQUIRE(DNS_ZONE_VALID(zone));
10548 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10551 isc_time_settoepoch(&next);
10553 switch (zone->type) {
10554 case dns_zone_master:
10555 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10556 next = zone->notifytime;
10557 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10558 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10559 INSIST(!isc_time_isepoch(&zone->dumptime));
10560 if (isc_time_isepoch(&next) ||
10561 isc_time_compare(&zone->dumptime, &next) < 0)
10562 next = zone->dumptime;
10564 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
10565 !isc_time_isepoch(&zone->refreshkeytime)) {
10566 if (isc_time_isepoch(&next) ||
10567 isc_time_compare(&zone->refreshkeytime, &next) < 0)
10568 next = zone->refreshkeytime;
10570 if (!isc_time_isepoch(&zone->resigntime)) {
10571 if (isc_time_isepoch(&next) ||
10572 isc_time_compare(&zone->resigntime, &next) < 0)
10573 next = zone->resigntime;
10575 if (!isc_time_isepoch(&zone->keywarntime)) {
10576 if (isc_time_isepoch(&next) ||
10577 isc_time_compare(&zone->keywarntime, &next) < 0)
10578 next = zone->keywarntime;
10580 if (!isc_time_isepoch(&zone->signingtime)) {
10581 if (isc_time_isepoch(&next) ||
10582 isc_time_compare(&zone->signingtime, &next) < 0)
10583 next = zone->signingtime;
10585 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
10586 if (isc_time_isepoch(&next) ||
10587 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
10588 next = zone->nsec3chaintime;
10592 case dns_zone_slave:
10593 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10594 next = zone->notifytime;
10597 case dns_zone_stub:
10598 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
10599 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
10600 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
10601 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
10602 INSIST(!isc_time_isepoch(&zone->refreshtime));
10603 if (isc_time_isepoch(&next) ||
10604 isc_time_compare(&zone->refreshtime, &next) < 0)
10605 next = zone->refreshtime;
10607 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10608 INSIST(!isc_time_isepoch(&zone->expiretime));
10609 if (isc_time_isepoch(&next) ||
10610 isc_time_compare(&zone->expiretime, &next) < 0)
10611 next = zone->expiretime;
10613 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10614 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10615 INSIST(!isc_time_isepoch(&zone->dumptime));
10616 if (isc_time_isepoch(&next) ||
10617 isc_time_compare(&zone->dumptime, &next) < 0)
10618 next = zone->dumptime;
10623 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10624 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10625 INSIST(!isc_time_isepoch(&zone->dumptime));
10626 if (isc_time_isepoch(&next) ||
10627 isc_time_compare(&zone->dumptime, &next) < 0)
10628 next = zone->dumptime;
10630 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
10631 if (isc_time_isepoch(&next) ||
10632 (!isc_time_isepoch(&zone->refreshkeytime) &&
10633 isc_time_compare(&zone->refreshkeytime, &next) < 0))
10634 next = zone->refreshkeytime;
10642 if (isc_time_isepoch(&next)) {
10643 zone_debuglog(zone, me, 10, "settimer inactive");
10644 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
10645 NULL, NULL, ISC_TRUE);
10646 if (result != ISC_R_SUCCESS)
10647 dns_zone_log(zone, ISC_LOG_ERROR,
10648 "could not deactivate zone timer: %s",
10649 isc_result_totext(result));
10651 if (isc_time_compare(&next, now) <= 0)
10653 result = isc_timer_reset(zone->timer, isc_timertype_once,
10654 &next, NULL, ISC_TRUE);
10655 if (result != ISC_R_SUCCESS)
10656 dns_zone_log(zone, ISC_LOG_ERROR,
10657 "could not reset zone timer: %s",
10658 isc_result_totext(result));
10663 cancel_refresh(dns_zone_t *zone) {
10664 const char me[] = "cancel_refresh";
10668 * 'zone' locked by caller.
10671 REQUIRE(DNS_ZONE_VALID(zone));
10672 REQUIRE(LOCKED_ZONE(zone));
10676 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10678 zone_settimer(zone, &now);
10681 static isc_result_t
10682 notify_createmessage(dns_zone_t *zone, unsigned int flags,
10683 dns_message_t **messagep)
10685 dns_db_t *zonedb = NULL;
10686 dns_dbnode_t *node = NULL;
10687 dns_dbversion_t *version = NULL;
10688 dns_message_t *message = NULL;
10689 dns_rdataset_t rdataset;
10690 dns_rdata_t rdata = DNS_RDATA_INIT;
10692 dns_name_t *tempname = NULL;
10693 dns_rdata_t *temprdata = NULL;
10694 dns_rdatalist_t *temprdatalist = NULL;
10695 dns_rdataset_t *temprdataset = NULL;
10697 isc_result_t result;
10699 isc_buffer_t *b = NULL;
10701 REQUIRE(DNS_ZONE_VALID(zone));
10702 REQUIRE(messagep != NULL && *messagep == NULL);
10704 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10706 if (result != ISC_R_SUCCESS)
10709 message->opcode = dns_opcode_notify;
10710 message->flags |= DNS_MESSAGEFLAG_AA;
10711 message->rdclass = zone->rdclass;
10713 result = dns_message_gettempname(message, &tempname);
10714 if (result != ISC_R_SUCCESS)
10717 result = dns_message_gettemprdataset(message, &temprdataset);
10718 if (result != ISC_R_SUCCESS)
10724 dns_name_init(tempname, NULL);
10725 dns_name_clone(&zone->origin, tempname);
10726 dns_rdataset_init(temprdataset);
10727 dns_rdataset_makequestion(temprdataset, zone->rdclass,
10728 dns_rdatatype_soa);
10729 ISC_LIST_APPEND(tempname->list, temprdataset, link);
10730 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
10732 temprdataset = NULL;
10734 if ((flags & DNS_NOTIFY_NOSOA) != 0)
10737 result = dns_message_gettempname(message, &tempname);
10738 if (result != ISC_R_SUCCESS)
10740 result = dns_message_gettemprdata(message, &temprdata);
10741 if (result != ISC_R_SUCCESS)
10743 result = dns_message_gettemprdataset(message, &temprdataset);
10744 if (result != ISC_R_SUCCESS)
10746 result = dns_message_gettemprdatalist(message, &temprdatalist);
10747 if (result != ISC_R_SUCCESS)
10750 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10751 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
10752 dns_db_attach(zone->db, &zonedb);
10753 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10755 dns_name_init(tempname, NULL);
10756 dns_name_clone(&zone->origin, tempname);
10757 dns_db_currentversion(zonedb, &version);
10758 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
10759 if (result != ISC_R_SUCCESS)
10762 dns_rdataset_init(&rdataset);
10763 result = dns_db_findrdataset(zonedb, node, version,
10765 dns_rdatatype_none, 0, &rdataset,
10767 if (result != ISC_R_SUCCESS)
10769 result = dns_rdataset_first(&rdataset);
10770 if (result != ISC_R_SUCCESS)
10772 dns_rdataset_current(&rdataset, &rdata);
10773 dns_rdata_toregion(&rdata, &r);
10774 result = isc_buffer_allocate(zone->mctx, &b, r.length);
10775 if (result != ISC_R_SUCCESS)
10777 isc_buffer_putmem(b, r.base, r.length);
10778 isc_buffer_usedregion(b, &r);
10779 dns_rdata_init(temprdata);
10780 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
10781 dns_message_takebuffer(message, &b);
10782 result = dns_rdataset_next(&rdataset);
10783 dns_rdataset_disassociate(&rdataset);
10784 if (result != ISC_R_NOMORE)
10786 temprdatalist->rdclass = rdata.rdclass;
10787 temprdatalist->type = rdata.type;
10788 temprdatalist->covers = 0;
10789 temprdatalist->ttl = rdataset.ttl;
10790 ISC_LIST_INIT(temprdatalist->rdata);
10791 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
10793 dns_rdataset_init(temprdataset);
10794 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
10795 if (result != ISC_R_SUCCESS)
10798 ISC_LIST_APPEND(tempname->list, temprdataset, link);
10799 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
10800 temprdatalist = NULL;
10801 temprdataset = NULL;
10807 dns_db_detachnode(zonedb, &node);
10808 if (version != NULL)
10809 dns_db_closeversion(zonedb, &version, ISC_FALSE);
10810 if (zonedb != NULL)
10811 dns_db_detach(&zonedb);
10812 if (tempname != NULL)
10813 dns_message_puttempname(message, &tempname);
10814 if (temprdata != NULL)
10815 dns_message_puttemprdata(message, &temprdata);
10816 if (temprdataset != NULL)
10817 dns_message_puttemprdataset(message, &temprdataset);
10818 if (temprdatalist != NULL)
10819 dns_message_puttemprdatalist(message, &temprdatalist);
10822 *messagep = message;
10823 return (ISC_R_SUCCESS);
10826 if (tempname != NULL)
10827 dns_message_puttempname(message, &tempname);
10828 if (temprdataset != NULL)
10829 dns_message_puttemprdataset(message, &temprdataset);
10830 dns_message_destroy(&message);
10835 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
10836 dns_message_t *msg)
10839 dns_rdata_soa_t soa;
10840 dns_rdataset_t *rdataset = NULL;
10841 dns_rdata_t rdata = DNS_RDATA_INIT;
10842 isc_result_t result;
10843 char fromtext[ISC_SOCKADDR_FORMATSIZE];
10845 isc_netaddr_t netaddr;
10846 isc_sockaddr_t local, remote;
10848 REQUIRE(DNS_ZONE_VALID(zone));
10851 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
10855 * Check that 'from' is a valid notify source, (zone->masters).
10856 * Return DNS_R_REFUSED if not.
10858 * If the notify message contains a serial number check it
10859 * against the zones serial and return if <= current serial
10861 * If a refresh check is progress, if so just record the
10862 * fact we received a NOTIFY and from where and return.
10863 * We will perform a new refresh check when the current one
10864 * completes. Return ISC_R_SUCCESS.
10866 * Otherwise initiate a refresh check using 'from' as the
10867 * first address to check. Return ISC_R_SUCCESS.
10870 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
10873 * We only handle NOTIFY (SOA) at the present.
10876 if (isc_sockaddr_pf(from) == PF_INET)
10877 inc_stats(zone, dns_zonestatscounter_notifyinv4);
10879 inc_stats(zone, dns_zonestatscounter_notifyinv6);
10880 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
10881 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
10882 dns_rdatatype_soa, dns_rdatatype_none,
10883 NULL, NULL) != ISC_R_SUCCESS) {
10885 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
10886 dns_zone_log(zone, ISC_LOG_NOTICE,
10888 "question section from: %s", fromtext);
10889 return (DNS_R_FORMERR);
10891 dns_zone_log(zone, ISC_LOG_NOTICE,
10892 "NOTIFY zone does not match");
10893 return (DNS_R_NOTIMP);
10897 * If we are a master zone just succeed.
10899 if (zone->type == dns_zone_master) {
10901 return (ISC_R_SUCCESS);
10904 isc_netaddr_fromsockaddr(&netaddr, from);
10905 for (i = 0; i < zone->masterscnt; i++) {
10906 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
10908 if (zone->view->aclenv.match_mapped &&
10909 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
10910 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
10911 isc_netaddr_t na1, na2;
10912 isc_netaddr_fromv4mapped(&na1, &netaddr);
10913 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
10914 if (isc_netaddr_equal(&na1, &na2))
10920 * Accept notify requests from non masters if they are on
10921 * 'zone->notify_acl'.
10923 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
10924 dns_acl_match(&netaddr, NULL, zone->notify_acl,
10925 &zone->view->aclenv,
10926 &match, NULL) == ISC_R_SUCCESS &&
10929 /* Accept notify. */
10930 } else if (i >= zone->masterscnt) {
10932 dns_zone_log(zone, ISC_LOG_INFO,
10933 "refused notify from non-master: %s", fromtext);
10934 inc_stats(zone, dns_zonestatscounter_notifyrej);
10935 return (DNS_R_REFUSED);
10939 * If the zone is loaded and there are answers check the serial
10940 * to see if we need to do a refresh. Do not worry about this
10941 * check if we are a dialup zone as we use the notify request
10942 * to trigger a refresh check.
10944 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
10945 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10946 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
10947 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
10950 dns_rdatatype_none, NULL,
10952 if (result == ISC_R_SUCCESS)
10953 result = dns_rdataset_first(rdataset);
10954 if (result == ISC_R_SUCCESS) {
10955 isc_uint32_t serial = 0, oldserial;
10957 dns_rdataset_current(rdataset, &rdata);
10958 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10959 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10960 serial = soa.serial;
10962 * The following should safely be performed without DB
10963 * lock and succeed in this context.
10965 result = zone_get_from_db(zone, zone->db, NULL, NULL,
10966 &oldserial, NULL, NULL, NULL,
10968 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10969 if (isc_serial_le(serial, oldserial)) {
10973 "zone is up to date",
10976 return (ISC_R_SUCCESS);
10982 * If we got this far and there was a refresh in progress just
10983 * let it complete. Record where we got the notify from so we
10984 * can perform a refresh check when the current one completes
10986 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
10987 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
10988 zone->notifyfrom = *from;
10990 dns_zone_log(zone, ISC_LOG_INFO,
10991 "notify from %s: refresh in progress, "
10992 "refresh check queued",
10994 return (ISC_R_SUCCESS);
10996 zone->notifyfrom = *from;
10997 local = zone->masteraddr;
10998 remote = zone->sourceaddr;
11000 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
11001 dns_zone_refresh(zone);
11002 return (ISC_R_SUCCESS);
11006 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
11008 REQUIRE(DNS_ZONE_VALID(zone));
11011 if (zone->notify_acl != NULL)
11012 dns_acl_detach(&zone->notify_acl);
11013 dns_acl_attach(acl, &zone->notify_acl);
11018 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
11020 REQUIRE(DNS_ZONE_VALID(zone));
11023 if (zone->query_acl != NULL)
11024 dns_acl_detach(&zone->query_acl);
11025 dns_acl_attach(acl, &zone->query_acl);
11030 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
11032 REQUIRE(DNS_ZONE_VALID(zone));
11035 if (zone->queryon_acl != NULL)
11036 dns_acl_detach(&zone->queryon_acl);
11037 dns_acl_attach(acl, &zone->queryon_acl);
11042 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
11044 REQUIRE(DNS_ZONE_VALID(zone));
11047 if (zone->update_acl != NULL)
11048 dns_acl_detach(&zone->update_acl);
11049 dns_acl_attach(acl, &zone->update_acl);
11054 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
11056 REQUIRE(DNS_ZONE_VALID(zone));
11059 if (zone->forward_acl != NULL)
11060 dns_acl_detach(&zone->forward_acl);
11061 dns_acl_attach(acl, &zone->forward_acl);
11066 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
11068 REQUIRE(DNS_ZONE_VALID(zone));
11071 if (zone->xfr_acl != NULL)
11072 dns_acl_detach(&zone->xfr_acl);
11073 dns_acl_attach(acl, &zone->xfr_acl);
11078 dns_zone_getnotifyacl(dns_zone_t *zone) {
11080 REQUIRE(DNS_ZONE_VALID(zone));
11082 return (zone->notify_acl);
11086 dns_zone_getqueryacl(dns_zone_t *zone) {
11088 REQUIRE(DNS_ZONE_VALID(zone));
11090 return (zone->query_acl);
11094 dns_zone_getqueryonacl(dns_zone_t *zone) {
11096 REQUIRE(DNS_ZONE_VALID(zone));
11098 return (zone->queryon_acl);
11102 dns_zone_getupdateacl(dns_zone_t *zone) {
11104 REQUIRE(DNS_ZONE_VALID(zone));
11106 return (zone->update_acl);
11110 dns_zone_getforwardacl(dns_zone_t *zone) {
11112 REQUIRE(DNS_ZONE_VALID(zone));
11114 return (zone->forward_acl);
11118 dns_zone_getxfracl(dns_zone_t *zone) {
11120 REQUIRE(DNS_ZONE_VALID(zone));
11122 return (zone->xfr_acl);
11126 dns_zone_clearupdateacl(dns_zone_t *zone) {
11128 REQUIRE(DNS_ZONE_VALID(zone));
11131 if (zone->update_acl != NULL)
11132 dns_acl_detach(&zone->update_acl);
11137 dns_zone_clearforwardacl(dns_zone_t *zone) {
11139 REQUIRE(DNS_ZONE_VALID(zone));
11142 if (zone->forward_acl != NULL)
11143 dns_acl_detach(&zone->forward_acl);
11148 dns_zone_clearnotifyacl(dns_zone_t *zone) {
11150 REQUIRE(DNS_ZONE_VALID(zone));
11153 if (zone->notify_acl != NULL)
11154 dns_acl_detach(&zone->notify_acl);
11159 dns_zone_clearqueryacl(dns_zone_t *zone) {
11161 REQUIRE(DNS_ZONE_VALID(zone));
11164 if (zone->query_acl != NULL)
11165 dns_acl_detach(&zone->query_acl);
11170 dns_zone_clearqueryonacl(dns_zone_t *zone) {
11172 REQUIRE(DNS_ZONE_VALID(zone));
11175 if (zone->queryon_acl != NULL)
11176 dns_acl_detach(&zone->queryon_acl);
11181 dns_zone_clearxfracl(dns_zone_t *zone) {
11183 REQUIRE(DNS_ZONE_VALID(zone));
11186 if (zone->xfr_acl != NULL)
11187 dns_acl_detach(&zone->xfr_acl);
11192 dns_zone_getupdatedisabled(dns_zone_t *zone) {
11193 REQUIRE(DNS_ZONE_VALID(zone));
11194 return (zone->update_disabled);
11199 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
11200 REQUIRE(DNS_ZONE_VALID(zone));
11201 zone->update_disabled = state;
11205 dns_zone_getzeronosoattl(dns_zone_t *zone) {
11206 REQUIRE(DNS_ZONE_VALID(zone));
11207 return (zone->zero_no_soa_ttl);
11212 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
11213 REQUIRE(DNS_ZONE_VALID(zone));
11214 zone->zero_no_soa_ttl = state;
11218 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
11220 REQUIRE(DNS_ZONE_VALID(zone));
11222 zone->check_names = severity;
11226 dns_zone_getchecknames(dns_zone_t *zone) {
11228 REQUIRE(DNS_ZONE_VALID(zone));
11230 return (zone->check_names);
11234 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
11236 REQUIRE(DNS_ZONE_VALID(zone));
11238 zone->journalsize = size;
11242 dns_zone_getjournalsize(dns_zone_t *zone) {
11244 REQUIRE(DNS_ZONE_VALID(zone));
11246 return (zone->journalsize);
11250 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
11251 isc_result_t result = ISC_R_FAILURE;
11252 isc_buffer_t buffer;
11254 REQUIRE(buf != NULL);
11255 REQUIRE(length > 1U);
11258 * Leave space for terminating '\0'.
11260 isc_buffer_init(&buffer, buf, length - 1);
11261 if (dns_name_dynamic(&zone->origin))
11262 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11263 if (result != ISC_R_SUCCESS &&
11264 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11265 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11267 if (isc_buffer_availablelength(&buffer) > 0)
11268 isc_buffer_putstr(&buffer, "/");
11269 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11271 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
11272 strcmp(zone->view->name, "_default") != 0 &&
11273 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
11274 isc_buffer_putstr(&buffer, "/");
11275 isc_buffer_putstr(&buffer, zone->view->name);
11278 buf[isc_buffer_usedlength(&buffer)] = '\0';
11282 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
11283 isc_result_t result = ISC_R_FAILURE;
11284 isc_buffer_t buffer;
11286 REQUIRE(buf != NULL);
11287 REQUIRE(length > 1U);
11290 * Leave space for terminating '\0'.
11292 isc_buffer_init(&buffer, buf, length - 1);
11293 if (dns_name_dynamic(&zone->origin))
11294 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11295 if (result != ISC_R_SUCCESS &&
11296 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11297 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11299 buf[isc_buffer_usedlength(&buffer)] = '\0';
11303 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
11304 isc_buffer_t buffer;
11306 REQUIRE(buf != NULL);
11307 REQUIRE(length > 1U);
11310 * Leave space for terminating '\0'.
11312 isc_buffer_init(&buffer, buf, length - 1);
11313 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11315 buf[isc_buffer_usedlength(&buffer)] = '\0';
11319 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
11320 isc_buffer_t buffer;
11322 REQUIRE(buf != NULL);
11323 REQUIRE(length > 1U);
11327 * Leave space for terminating '\0'.
11329 isc_buffer_init(&buffer, buf, length - 1);
11331 if (zone->view == NULL) {
11332 isc_buffer_putstr(&buffer, "_none");
11333 } else if (strlen(zone->view->name)
11334 < isc_buffer_availablelength(&buffer)) {
11335 isc_buffer_putstr(&buffer, zone->view->name);
11337 isc_buffer_putstr(&buffer, "_toolong");
11340 buf[isc_buffer_usedlength(&buffer)] = '\0';
11344 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
11345 REQUIRE(DNS_ZONE_VALID(zone));
11346 REQUIRE(buf != NULL);
11347 zone_namerd_tostr(zone, buf, length);
11351 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11353 char message[4096];
11355 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11359 vsnprintf(message, sizeof(message), fmt, ap);
11361 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
11362 level, "zone %s: %s", zone->strnamerd, message);
11366 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
11367 int level, const char *fmt, ...) {
11369 char message[4096];
11371 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11375 vsnprintf(message, sizeof(message), fmt, ap);
11377 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
11378 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11379 "managed-keys-zone" : "zone", zone->strnamerd, message);
11383 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11385 char message[4096];
11387 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11391 vsnprintf(message, sizeof(message), fmt, ap);
11393 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11394 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11395 "managed-keys-zone" : "zone", zone->strnamerd, message);
11399 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
11400 const char *fmt, ...)
11403 char message[4096];
11404 int level = ISC_LOG_DEBUG(debuglevel);
11406 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11410 vsnprintf(message, sizeof(message), fmt, ap);
11412 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11413 level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
11414 "zone" : "managed-keys-zone", zone->strnamerd, message);
11418 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
11420 isc_result_t result;
11422 dns_rdataset_t *curr;
11425 result = dns_message_firstname(msg, section);
11426 while (result == ISC_R_SUCCESS) {
11428 dns_message_currentname(msg, section, &name);
11430 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
11431 curr = ISC_LIST_PREV(curr, link)) {
11432 if (curr->type == type)
11435 result = dns_message_nextname(msg, section);
11442 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
11443 REQUIRE(DNS_ZONE_VALID(zone));
11445 zone->maxxfrin = maxxfrin;
11449 dns_zone_getmaxxfrin(dns_zone_t *zone) {
11450 REQUIRE(DNS_ZONE_VALID(zone));
11452 return (zone->maxxfrin);
11456 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
11457 REQUIRE(DNS_ZONE_VALID(zone));
11458 zone->maxxfrout = maxxfrout;
11462 dns_zone_getmaxxfrout(dns_zone_t *zone) {
11463 REQUIRE(DNS_ZONE_VALID(zone));
11465 return (zone->maxxfrout);
11469 dns_zone_gettype(dns_zone_t *zone) {
11470 REQUIRE(DNS_ZONE_VALID(zone));
11472 return (zone->type);
11476 dns_zone_getorigin(dns_zone_t *zone) {
11477 REQUIRE(DNS_ZONE_VALID(zone));
11479 return (&zone->origin);
11483 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
11484 REQUIRE(DNS_ZONE_VALID(zone));
11487 if (zone->task != NULL)
11488 isc_task_detach(&zone->task);
11489 isc_task_attach(task, &zone->task);
11490 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11491 if (zone->db != NULL)
11492 dns_db_settask(zone->db, zone->task);
11493 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11498 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
11499 REQUIRE(DNS_ZONE_VALID(zone));
11500 isc_task_attach(zone->task, target);
11504 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
11505 REQUIRE(DNS_ZONE_VALID(zone));
11508 idlein = DNS_DEFAULT_IDLEIN;
11509 zone->idlein = idlein;
11513 dns_zone_getidlein(dns_zone_t *zone) {
11514 REQUIRE(DNS_ZONE_VALID(zone));
11516 return (zone->idlein);
11520 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
11521 REQUIRE(DNS_ZONE_VALID(zone));
11523 zone->idleout = idleout;
11527 dns_zone_getidleout(dns_zone_t *zone) {
11528 REQUIRE(DNS_ZONE_VALID(zone));
11530 return (zone->idleout);
11534 notify_done(isc_task_t *task, isc_event_t *event) {
11535 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11536 dns_notify_t *notify;
11537 isc_result_t result;
11538 dns_message_t *message = NULL;
11541 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
11545 notify = event->ev_arg;
11546 REQUIRE(DNS_NOTIFY_VALID(notify));
11547 INSIST(task == notify->zone->task);
11549 isc_buffer_init(&buf, rcode, sizeof(rcode));
11550 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11552 result = revent->result;
11553 if (result == ISC_R_SUCCESS)
11554 result = dns_message_create(notify->zone->mctx,
11555 DNS_MESSAGE_INTENTPARSE, &message);
11556 if (result == ISC_R_SUCCESS)
11557 result = dns_request_getresponse(revent->request, message,
11558 DNS_MESSAGEPARSE_PRESERVEORDER);
11559 if (result == ISC_R_SUCCESS)
11560 result = dns_rcode_totext(message->rcode, &buf);
11561 if (result == ISC_R_SUCCESS)
11562 notify_log(notify->zone, ISC_LOG_DEBUG(3),
11563 "notify response from %s: %.*s",
11564 addrbuf, (int)buf.used, rcode);
11566 notify_log(notify->zone, ISC_LOG_DEBUG(2),
11567 "notify to %s failed: %s", addrbuf,
11568 dns_result_totext(result));
11571 * Old bind's return formerr if they see a soa record. Retry w/o
11572 * the soa if we see a formerr and had sent a SOA.
11574 isc_event_free(&event);
11575 if (message != NULL && message->rcode == dns_rcode_formerr &&
11576 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
11577 notify->flags |= DNS_NOTIFY_NOSOA;
11578 dns_request_destroy(¬ify->request);
11579 result = notify_send_queue(notify);
11580 if (result != ISC_R_SUCCESS)
11581 notify_destroy(notify, ISC_FALSE);
11583 if (result == ISC_R_TIMEDOUT)
11584 notify_log(notify->zone, ISC_LOG_DEBUG(1),
11585 "notify to %s: retries exceeded", addrbuf);
11586 notify_destroy(notify, ISC_FALSE);
11588 if (message != NULL)
11589 dns_message_destroy(&message);
11593 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11594 isc_result_t result;
11596 REQUIRE(DNS_ZONE_VALID(zone));
11598 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11599 result = zone_replacedb(zone, db, dump);
11600 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11605 static isc_result_t
11606 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11607 dns_dbversion_t *ver;
11608 isc_result_t result;
11609 unsigned int soacount = 0;
11610 unsigned int nscount = 0;
11613 * 'zone' and 'zonedb' locked by caller.
11615 REQUIRE(DNS_ZONE_VALID(zone));
11616 REQUIRE(LOCKED_ZONE(zone));
11618 result = zone_get_from_db(zone, db, &nscount, &soacount,
11619 NULL, NULL, NULL, NULL, NULL, NULL);
11620 if (result == ISC_R_SUCCESS) {
11621 if (soacount != 1) {
11622 dns_zone_log(zone, ISC_LOG_ERROR,
11623 "has %d SOA records", soacount);
11624 result = DNS_R_BADZONE;
11626 if (nscount == 0 && zone->type != dns_zone_key) {
11627 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
11628 result = DNS_R_BADZONE;
11630 if (result != ISC_R_SUCCESS)
11633 dns_zone_log(zone, ISC_LOG_ERROR,
11634 "retrieving SOA and NS records failed: %s",
11635 dns_result_totext(result));
11639 result = check_nsec3param(zone, db);
11640 if (result != ISC_R_SUCCESS)
11644 dns_db_currentversion(db, &ver);
11647 * The initial version of a slave zone is always dumped;
11648 * subsequent versions may be journaled instead if this
11649 * is enabled in the configuration.
11651 if (zone->db != NULL && zone->journal != NULL &&
11652 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
11653 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
11654 isc_uint32_t serial, oldserial;
11656 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
11658 result = dns_db_getsoaserial(db, ver, &serial);
11659 if (result != ISC_R_SUCCESS) {
11660 dns_zone_log(zone, ISC_LOG_ERROR,
11661 "ixfr-from-differences: unable to get "
11667 * This is checked in zone_postload() for master zones.
11669 result = zone_get_from_db(zone, zone->db, NULL, NULL,
11670 &oldserial, NULL, NULL, NULL, NULL,
11672 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11673 if (zone->type == dns_zone_slave &&
11674 !isc_serial_gt(serial, oldserial)) {
11675 isc_uint32_t serialmin, serialmax;
11676 serialmin = (oldserial + 1) & 0xffffffffU;
11677 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
11678 dns_zone_log(zone, ISC_LOG_ERROR,
11679 "ixfr-from-differences: failed: "
11680 "new serial (%u) out of range [%u - %u]",
11681 serial, serialmin, serialmax);
11682 result = ISC_R_RANGE;
11686 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
11688 if (result != ISC_R_SUCCESS)
11691 zone_needdump(zone, DNS_DUMP_DELAY);
11692 else if (zone->journalsize != -1) {
11693 result = dns_journal_compact(zone->mctx, zone->journal,
11694 serial, zone->journalsize);
11696 case ISC_R_SUCCESS:
11697 case ISC_R_NOSPACE:
11698 case ISC_R_NOTFOUND:
11699 dns_zone_log(zone, ISC_LOG_DEBUG(3),
11700 "dns_journal_compact: %s",
11701 dns_result_totext(result));
11704 dns_zone_log(zone, ISC_LOG_ERROR,
11705 "dns_journal_compact failed: %s",
11706 dns_result_totext(result));
11711 if (dump && zone->masterfile != NULL) {
11713 * If DNS_ZONEFLG_FORCEXFER was set we don't want
11714 * to keep the old masterfile.
11716 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
11717 remove(zone->masterfile) < 0 && errno != ENOENT) {
11718 char strbuf[ISC_STRERRORSIZE];
11719 isc__strerror(errno, strbuf, sizeof(strbuf));
11720 isc_log_write(dns_lctx,
11721 DNS_LOGCATEGORY_GENERAL,
11722 DNS_LOGMODULE_ZONE,
11724 "unable to remove masterfile "
11726 zone->masterfile, strbuf);
11728 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
11729 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
11731 zone_needdump(zone, 0);
11733 if (dump && zone->journal != NULL) {
11735 * The in-memory database just changed, and
11736 * because 'dump' is set, it didn't change by
11737 * being loaded from disk. Also, we have not
11738 * journaled diffs for this change.
11739 * Therefore, the on-disk journal is missing
11740 * the deltas for this change. Since it can
11741 * no longer be used to bring the zone
11742 * up-to-date, it is useless and should be
11745 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11746 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11747 "removing journal file");
11748 if (remove(zone->journal) < 0 && errno != ENOENT) {
11749 char strbuf[ISC_STRERRORSIZE];
11750 isc__strerror(errno, strbuf, sizeof(strbuf));
11751 isc_log_write(dns_lctx,
11752 DNS_LOGCATEGORY_GENERAL,
11753 DNS_LOGMODULE_ZONE,
11755 "unable to remove journal "
11757 zone->journal, strbuf);
11762 dns_db_closeversion(db, &ver, ISC_FALSE);
11764 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11765 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11766 "replacing zone database");
11768 if (zone->db != NULL)
11769 zone_detachdb(zone);
11770 zone_attachdb(zone, db);
11771 dns_db_settask(zone->db, zone->task);
11772 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
11773 return (ISC_R_SUCCESS);
11776 dns_db_closeversion(db, &ver, ISC_FALSE);
11780 /* The caller must hold the dblock as a writer. */
11782 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
11783 REQUIRE(zone->db == NULL && db != NULL);
11785 dns_db_attach(db, &zone->db);
11786 if (zone->acache != NULL) {
11787 isc_result_t result;
11788 result = dns_acache_setdb(zone->acache, db);
11789 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
11790 UNEXPECTED_ERROR(__FILE__, __LINE__,
11791 "dns_acache_setdb() failed: %s",
11792 isc_result_totext(result));
11797 /* The caller must hold the dblock as a writer. */
11799 zone_detachdb(dns_zone_t *zone) {
11800 REQUIRE(zone->db != NULL);
11802 if (zone->acache != NULL)
11803 (void)dns_acache_putdb(zone->acache, zone->db);
11804 dns_db_detach(&zone->db);
11808 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
11810 isc_boolean_t again = ISC_FALSE;
11811 unsigned int soacount;
11812 unsigned int nscount;
11813 isc_uint32_t serial, refresh, retry, expire, minimum;
11814 isc_result_t xfrresult = result;
11815 isc_boolean_t free_needed;
11817 REQUIRE(DNS_ZONE_VALID(zone));
11819 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11820 "zone transfer finished: %s", dns_result_totext(result));
11823 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
11824 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11825 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
11829 case ISC_R_SUCCESS:
11830 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11832 case DNS_R_UPTODATE:
11833 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11835 * Has the zone expired underneath us?
11837 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11838 if (zone->db == NULL) {
11839 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11844 * Update the zone structure's data from the actual
11849 INSIST(zone->db != NULL);
11850 result = zone_get_from_db(zone, zone->db, &nscount,
11851 &soacount, &serial, &refresh,
11852 &retry, &expire, &minimum, NULL);
11853 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11854 if (result == ISC_R_SUCCESS) {
11856 dns_zone_log(zone, ISC_LOG_ERROR,
11857 "transferred zone "
11858 "has %d SOA record%s", soacount,
11859 (soacount != 0) ? "s" : "");
11860 if (nscount == 0) {
11861 dns_zone_log(zone, ISC_LOG_ERROR,
11862 "transferred zone "
11863 "has no NS records");
11864 if (DNS_ZONE_FLAG(zone,
11865 DNS_ZONEFLG_HAVETIMERS)) {
11866 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
11867 zone->retry = DNS_ZONE_DEFAULTRETRY;
11869 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11873 zone->refresh = RANGE(refresh, zone->minrefresh,
11875 zone->retry = RANGE(retry, zone->minretry,
11877 zone->expire = RANGE(expire,
11878 zone->refresh + zone->retry,
11880 zone->minimum = minimum;
11881 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11885 * Set our next update/expire times.
11887 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
11888 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11889 zone->refreshtime = now;
11890 DNS_ZONE_TIME_ADD(&now, zone->expire,
11891 &zone->expiretime);
11893 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
11894 &zone->refreshtime);
11895 DNS_ZONE_TIME_ADD(&now, zone->expire,
11896 &zone->expiretime);
11898 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
11899 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
11900 if (zone->tsigkey != NULL) {
11901 char namebuf[DNS_NAME_FORMATSIZE];
11902 dns_name_format(&zone->tsigkey->name, namebuf,
11904 snprintf(buf, sizeof(buf), ": TSIG '%s'",
11908 dns_zone_log(zone, ISC_LOG_INFO,
11909 "transferred serial %u%s",
11914 * This is not necessary if we just performed a AXFR
11915 * however it is necessary for an IXFR / UPTODATE and
11916 * won't hurt with an AXFR.
11918 if (zone->masterfile != NULL || zone->journal != NULL) {
11919 result = ISC_R_FAILURE;
11920 if (zone->journal != NULL)
11921 result = isc_file_settime(zone->journal, &now);
11922 if (result != ISC_R_SUCCESS &&
11923 zone->masterfile != NULL)
11924 result = isc_file_settime(zone->masterfile,
11926 /* Someone removed the file from underneath us! */
11927 if (result == ISC_R_FILENOTFOUND &&
11928 zone->masterfile != NULL) {
11929 unsigned int delay = DNS_DUMP_DELAY;
11930 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY))
11932 zone_needdump(zone, delay);
11933 } else if (result != ISC_R_SUCCESS)
11934 dns_zone_log(zone, ISC_LOG_ERROR,
11935 "transfer: could not set file "
11936 "modification time of '%s': %s",
11938 dns_result_totext(result));
11940 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
11941 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
11944 case DNS_R_BADIXFR:
11945 /* Force retry with AXFR. */
11946 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
11952 * Skip to next failed / untried master.
11956 } while (zone->curmaster < zone->masterscnt &&
11957 zone->mastersok[zone->curmaster]);
11960 if (zone->curmaster >= zone->masterscnt) {
11961 zone->curmaster = 0;
11962 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11963 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11964 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
11965 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11966 while (zone->curmaster < zone->masterscnt &&
11967 zone->mastersok[zone->curmaster])
11971 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11973 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
11976 inc_stats(zone, dns_zonestatscounter_xfrfail);
11979 zone_settimer(zone, &now);
11982 * If creating the transfer object failed, zone->xfr is NULL.
11983 * Otherwise, we are called as the done callback of a zone
11984 * transfer object that just entered its shutting-down
11985 * state. Since we are no longer responsible for shutting
11986 * it down, we can detach our reference.
11988 if (zone->xfr != NULL)
11989 dns_xfrin_detach(&zone->xfr);
11991 if (zone->tsigkey != NULL)
11992 dns_tsigkey_detach(&zone->tsigkey);
11995 * Handle any deferred journal compaction.
11997 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
11998 result = dns_journal_compact(zone->mctx, zone->journal,
11999 zone->compact_serial,
12000 zone->journalsize);
12002 case ISC_R_SUCCESS:
12003 case ISC_R_NOSPACE:
12004 case ISC_R_NOTFOUND:
12005 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12006 "dns_journal_compact: %s",
12007 dns_result_totext(result));
12010 dns_zone_log(zone, ISC_LOG_ERROR,
12011 "dns_journal_compact failed: %s",
12012 dns_result_totext(result));
12015 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
12019 * This transfer finishing freed up a transfer quota slot.
12020 * Let any other zones waiting for quota have it.
12023 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12024 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
12025 zone->statelist = NULL;
12026 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
12027 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12031 * Retry with a different server if necessary.
12033 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12034 queue_soa_query(zone);
12036 INSIST(zone->irefs > 0);
12038 free_needed = exit_check(zone);
12045 zone_loaddone(void *arg, isc_result_t result) {
12046 static char me[] = "zone_loaddone";
12047 dns_load_t *load = arg;
12049 isc_result_t tresult;
12051 REQUIRE(DNS_LOAD_VALID(load));
12056 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
12057 if (tresult != ISC_R_SUCCESS &&
12058 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
12061 LOCK_ZONE(load->zone);
12062 (void)zone_postload(load->zone, load->db, load->loadtime, result);
12063 zonemgr_putio(&load->zone->readio);
12064 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
12066 * Leave the zone frozen if the reload fails.
12068 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
12069 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
12070 zone->update_disabled = ISC_FALSE;
12071 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
12072 UNLOCK_ZONE(load->zone);
12075 dns_db_detach(&load->db);
12076 if (load->zone->lctx != NULL)
12077 dns_loadctx_detach(&load->zone->lctx);
12078 dns_zone_idetach(&load->zone);
12079 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
12083 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
12084 REQUIRE(DNS_ZONE_VALID(zone));
12085 REQUIRE(table != NULL);
12086 REQUIRE(*table == NULL);
12089 if (zone->ssutable != NULL)
12090 dns_ssutable_attach(zone->ssutable, table);
12095 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
12096 REQUIRE(DNS_ZONE_VALID(zone));
12099 if (zone->ssutable != NULL)
12100 dns_ssutable_detach(&zone->ssutable);
12102 dns_ssutable_attach(table, &zone->ssutable);
12107 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
12108 REQUIRE(DNS_ZONE_VALID(zone));
12110 zone->sigvalidityinterval = interval;
12114 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
12115 REQUIRE(DNS_ZONE_VALID(zone));
12117 return (zone->sigvalidityinterval);
12121 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
12122 REQUIRE(DNS_ZONE_VALID(zone));
12124 zone->sigresigninginterval = interval;
12128 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
12129 REQUIRE(DNS_ZONE_VALID(zone));
12131 return (zone->sigresigninginterval);
12135 queue_xfrin(dns_zone_t *zone) {
12136 const char me[] = "queue_xfrin";
12137 isc_result_t result;
12138 dns_zonemgr_t *zmgr = zone->zmgr;
12142 INSIST(zone->statelist == NULL);
12144 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12145 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
12149 zone->statelist = &zmgr->waiting_for_xfrin;
12150 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12151 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12153 if (result == ISC_R_QUOTA) {
12154 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
12155 "zone transfer deferred due to quota");
12156 } else if (result != ISC_R_SUCCESS) {
12157 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
12158 "starting zone transfer: %s",
12159 isc_result_totext(result));
12164 * This event callback is called when a zone has received
12165 * any necessary zone transfer quota. This is the time
12166 * to go ahead and start the transfer.
12169 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
12170 isc_result_t result;
12171 dns_peer_t *peer = NULL;
12172 char master[ISC_SOCKADDR_FORMATSIZE];
12173 char source[ISC_SOCKADDR_FORMATSIZE];
12174 dns_rdatatype_t xfrtype;
12175 dns_zone_t *zone = event->ev_arg;
12176 isc_netaddr_t masterip;
12177 isc_sockaddr_t sourceaddr;
12178 isc_sockaddr_t masteraddr;
12180 const char *soa_before = "";
12184 INSIST(task == zone->task);
12186 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12187 result = ISC_R_CANCELED;
12193 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12194 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
12195 &zone->sourceaddr, &now))
12197 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12198 dns_zone_log(zone, ISC_LOG_INFO,
12199 "got_transfer_quota: skipping zone transfer as "
12200 "master %s (source %s) is unreachable (cached)",
12202 result = ISC_R_CANCELED;
12206 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12207 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
12209 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12210 soa_before = "SOA before ";
12212 * Decide whether we should request IXFR or AXFR.
12214 if (zone->db == NULL) {
12215 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12216 "no database exists yet, requesting AXFR of "
12217 "initial version from %s", master);
12218 xfrtype = dns_rdatatype_axfr;
12219 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
12220 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
12221 "set, requesting %sAXFR from %s", soa_before,
12223 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12224 xfrtype = dns_rdatatype_soa;
12226 xfrtype = dns_rdatatype_axfr;
12227 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
12228 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12229 "forced reload, requesting AXFR of "
12230 "initial version from %s", master);
12231 xfrtype = dns_rdatatype_axfr;
12232 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
12233 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12234 "retrying with AXFR from %s due to "
12235 "previous IXFR failure", master);
12236 xfrtype = dns_rdatatype_axfr;
12238 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
12241 isc_boolean_t use_ixfr = ISC_TRUE;
12242 if (peer != NULL &&
12243 dns_peer_getrequestixfr(peer, &use_ixfr) ==
12245 ; /* Using peer setting */
12247 use_ixfr = zone->view->requestixfr;
12249 if (use_ixfr == ISC_FALSE) {
12250 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12251 "IXFR disabled, requesting %sAXFR from %s",
12252 soa_before, master);
12253 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12254 xfrtype = dns_rdatatype_soa;
12256 xfrtype = dns_rdatatype_axfr;
12258 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12259 "requesting IXFR from %s", master);
12260 xfrtype = dns_rdatatype_ixfr;
12265 * Determine if we should attempt to sign the request with TSIG.
12267 result = ISC_R_NOTFOUND;
12269 * First, look for a tsig key in the master statement, then
12270 * try for a server key.
12272 if ((zone->masterkeynames != NULL) &&
12273 (zone->masterkeynames[zone->curmaster] != NULL)) {
12274 dns_view_t *view = dns_zone_getview(zone);
12275 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12276 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
12278 if (zone->tsigkey == NULL)
12279 result = dns_view_getpeertsig(zone->view, &masterip,
12282 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
12283 dns_zone_log(zone, ISC_LOG_ERROR,
12284 "could not get TSIG key for zone transfer: %s",
12285 isc_result_totext(result));
12289 masteraddr = zone->masteraddr;
12290 sourceaddr = zone->sourceaddr;
12292 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
12293 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
12294 zone->tsigkey, zone->mctx,
12295 zone->zmgr->timermgr, zone->zmgr->socketmgr,
12296 zone->task, zone_xfrdone, &zone->xfr);
12297 if (result == ISC_R_SUCCESS) {
12299 if (xfrtype == dns_rdatatype_axfr) {
12300 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12301 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
12303 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
12304 } else if (xfrtype == dns_rdatatype_ixfr) {
12305 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12306 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
12308 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
12314 * Any failure in this function is handled like a failed
12315 * zone transfer. This ensures that we get removed from
12316 * zmgr->xfrin_in_progress.
12318 if (result != ISC_R_SUCCESS)
12319 zone_xfrdone(zone, result);
12321 isc_event_free(&event);
12325 * Update forwarding support.
12329 forward_destroy(dns_forward_t *forward) {
12331 forward->magic = 0;
12332 if (forward->request != NULL)
12333 dns_request_destroy(&forward->request);
12334 if (forward->msgbuf != NULL)
12335 isc_buffer_free(&forward->msgbuf);
12336 if (forward->zone != NULL) {
12337 LOCK(&forward->zone->lock);
12338 if (ISC_LINK_LINKED(forward, link))
12339 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
12340 UNLOCK(&forward->zone->lock);
12341 dns_zone_idetach(&forward->zone);
12343 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
12346 static isc_result_t
12347 sendtomaster(dns_forward_t *forward) {
12348 isc_result_t result;
12349 isc_sockaddr_t src;
12351 LOCK_ZONE(forward->zone);
12353 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
12354 UNLOCK_ZONE(forward->zone);
12355 return (ISC_R_CANCELED);
12358 if (forward->which >= forward->zone->masterscnt) {
12359 UNLOCK_ZONE(forward->zone);
12360 return (ISC_R_NOMORE);
12363 forward->addr = forward->zone->masters[forward->which];
12365 * Always use TCP regardless of whether the original update
12367 * XXX The timeout may but a bit small if we are far down a
12368 * transfer graph and the master has to try several masters.
12370 switch (isc_sockaddr_pf(&forward->addr)) {
12372 src = forward->zone->xfrsource4;
12375 src = forward->zone->xfrsource6;
12378 result = ISC_R_NOTIMPLEMENTED;
12381 result = dns_request_createraw(forward->zone->view->requestmgr,
12383 &src, &forward->addr,
12384 DNS_REQUESTOPT_TCP, 15 /* XXX */,
12385 forward->zone->task,
12386 forward_callback, forward,
12387 &forward->request);
12388 if (result == ISC_R_SUCCESS) {
12389 if (!ISC_LINK_LINKED(forward, link))
12390 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
12394 UNLOCK_ZONE(forward->zone);
12399 forward_callback(isc_task_t *task, isc_event_t *event) {
12400 const char me[] = "forward_callback";
12401 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12402 dns_message_t *msg = NULL;
12403 char master[ISC_SOCKADDR_FORMATSIZE];
12404 isc_result_t result;
12405 dns_forward_t *forward;
12410 forward = revent->ev_arg;
12411 INSIST(DNS_FORWARD_VALID(forward));
12412 zone = forward->zone;
12413 INSIST(DNS_ZONE_VALID(zone));
12417 isc_sockaddr_format(&forward->addr, master, sizeof(master));
12419 if (revent->result != ISC_R_SUCCESS) {
12420 dns_zone_log(zone, ISC_LOG_INFO,
12421 "could not forward dynamic update to %s: %s",
12422 master, dns_result_totext(revent->result));
12426 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12427 if (result != ISC_R_SUCCESS)
12430 result = dns_request_getresponse(revent->request, msg,
12431 DNS_MESSAGEPARSE_PRESERVEORDER |
12432 DNS_MESSAGEPARSE_CLONEBUFFER);
12433 if (result != ISC_R_SUCCESS)
12436 switch (msg->rcode) {
12438 * Pass these rcodes back to client.
12440 case dns_rcode_noerror:
12441 case dns_rcode_yxdomain:
12442 case dns_rcode_yxrrset:
12443 case dns_rcode_nxrrset:
12444 case dns_rcode_refused:
12445 case dns_rcode_nxdomain:
12448 /* These should not occur if the masters/zone are valid. */
12449 case dns_rcode_notzone:
12450 case dns_rcode_notauth: {
12454 isc_buffer_init(&rb, rcode, sizeof(rcode));
12455 (void)dns_rcode_totext(msg->rcode, &rb);
12456 dns_zone_log(zone, ISC_LOG_WARNING,
12457 "forwarding dynamic update: "
12458 "unexpected response: master %s returned: %.*s",
12459 master, (int)rb.used, rcode);
12463 /* Try another server for these rcodes. */
12464 case dns_rcode_formerr:
12465 case dns_rcode_servfail:
12466 case dns_rcode_notimp:
12467 case dns_rcode_badvers:
12472 /* call callback */
12473 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
12475 dns_request_destroy(&forward->request);
12476 forward_destroy(forward);
12477 isc_event_free(&event);
12482 dns_message_destroy(&msg);
12483 isc_event_free(&event);
12485 dns_request_destroy(&forward->request);
12486 result = sendtomaster(forward);
12487 if (result != ISC_R_SUCCESS) {
12488 /* call callback */
12489 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12490 "exhausted dynamic update forwarder list");
12491 (forward->callback)(forward->callback_arg, result, NULL);
12492 forward_destroy(forward);
12497 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
12498 dns_updatecallback_t callback, void *callback_arg)
12500 dns_forward_t *forward;
12501 isc_result_t result;
12504 REQUIRE(DNS_ZONE_VALID(zone));
12505 REQUIRE(msg != NULL);
12506 REQUIRE(callback != NULL);
12508 forward = isc_mem_get(zone->mctx, sizeof(*forward));
12509 if (forward == NULL)
12510 return (ISC_R_NOMEMORY);
12512 forward->request = NULL;
12513 forward->zone = NULL;
12514 forward->msgbuf = NULL;
12515 forward->which = 0;
12517 forward->callback = callback;
12518 forward->callback_arg = callback_arg;
12519 ISC_LINK_INIT(forward, link);
12520 forward->magic = FORWARD_MAGIC;
12522 mr = dns_message_getrawmessage(msg);
12524 result = ISC_R_UNEXPECTEDEND;
12528 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
12529 if (result != ISC_R_SUCCESS)
12531 result = isc_buffer_copyregion(forward->msgbuf, mr);
12532 if (result != ISC_R_SUCCESS)
12535 isc_mem_attach(zone->mctx, &forward->mctx);
12536 dns_zone_iattach(zone, &forward->zone);
12537 result = sendtomaster(forward);
12540 if (result != ISC_R_SUCCESS) {
12541 forward_destroy(forward);
12547 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
12548 REQUIRE(DNS_ZONE_VALID(zone));
12549 REQUIRE(next != NULL && *next == NULL);
12551 *next = ISC_LIST_NEXT(zone, link);
12553 return (ISC_R_NOMORE);
12555 return (ISC_R_SUCCESS);
12559 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
12560 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12561 REQUIRE(first != NULL && *first == NULL);
12563 *first = ISC_LIST_HEAD(zmgr->zones);
12564 if (*first == NULL)
12565 return (ISC_R_NOMORE);
12567 return (ISC_R_SUCCESS);
12575 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
12576 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
12577 dns_zonemgr_t **zmgrp)
12579 dns_zonemgr_t *zmgr;
12580 isc_result_t result;
12581 isc_interval_t interval;
12583 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
12585 return (ISC_R_NOMEMORY);
12588 isc_mem_attach(mctx, &zmgr->mctx);
12589 zmgr->taskmgr = taskmgr;
12590 zmgr->timermgr = timermgr;
12591 zmgr->socketmgr = socketmgr;
12592 zmgr->zonetasks = NULL;
12595 ISC_LIST_INIT(zmgr->zones);
12596 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
12597 ISC_LIST_INIT(zmgr->xfrin_in_progress);
12598 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
12599 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
12600 if (result != ISC_R_SUCCESS)
12603 zmgr->transfersin = 10;
12604 zmgr->transfersperns = 2;
12606 /* Unreachable lock. */
12607 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
12608 if (result != ISC_R_SUCCESS)
12611 /* Create a single task for queueing of SOA queries. */
12612 result = isc_task_create(taskmgr, 1, &zmgr->task);
12613 if (result != ISC_R_SUCCESS)
12616 isc_task_setname(zmgr->task, "zmgr", zmgr);
12617 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
12619 if (result != ISC_R_SUCCESS)
12622 /* default to 20 refresh queries / notifies per second. */
12623 isc_interval_set(&interval, 0, 1000000000/2);
12624 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
12625 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12626 isc_ratelimiter_setpertic(zmgr->rl, 10);
12629 zmgr->ioactive = 0;
12630 ISC_LIST_INIT(zmgr->high);
12631 ISC_LIST_INIT(zmgr->low);
12633 result = isc_mutex_init(&zmgr->iolock);
12634 if (result != ISC_R_SUCCESS)
12637 zmgr->magic = ZONEMGR_MAGIC;
12640 return (ISC_R_SUCCESS);
12644 DESTROYLOCK(&zmgr->iolock);
12647 isc_ratelimiter_detach(&zmgr->rl);
12649 isc_task_detach(&zmgr->task);
12651 isc_rwlock_destroy(&zmgr->urlock);
12653 isc_rwlock_destroy(&zmgr->rwlock);
12655 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12656 isc_mem_detach(&mctx);
12661 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12662 isc_result_t result;
12664 REQUIRE(DNS_ZONE_VALID(zone));
12665 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12667 if (zmgr->zonetasks == NULL)
12668 return (ISC_R_FAILURE);
12670 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12672 REQUIRE(zone->task == NULL);
12673 REQUIRE(zone->timer == NULL);
12674 REQUIRE(zone->zmgr == NULL);
12676 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
12679 * Set the task name. The tag will arbitrarily point to one
12680 * of the zones sharing the task (in practice, the one
12681 * to be managed last).
12683 isc_task_setname(zone->task, "zone", zone);
12685 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
12687 zone->task, zone_timer, zone,
12690 if (result != ISC_R_SUCCESS)
12694 * The timer "holds" a iref.
12697 INSIST(zone->irefs != 0);
12699 ISC_LIST_APPEND(zmgr->zones, zone, link);
12706 isc_task_detach(&zone->task);
12710 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12715 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12716 isc_boolean_t free_now = ISC_FALSE;
12718 REQUIRE(DNS_ZONE_VALID(zone));
12719 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12720 REQUIRE(zone->zmgr == zmgr);
12722 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12725 ISC_LIST_UNLINK(zmgr->zones, zone, link);
12728 if (zmgr->refs == 0)
12729 free_now = ISC_TRUE;
12732 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12735 zonemgr_free(zmgr);
12736 ENSURE(zone->zmgr == NULL);
12740 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
12741 REQUIRE(DNS_ZONEMGR_VALID(source));
12742 REQUIRE(target != NULL && *target == NULL);
12744 RWLOCK(&source->rwlock, isc_rwlocktype_write);
12745 REQUIRE(source->refs > 0);
12747 INSIST(source->refs > 0);
12748 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
12753 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
12754 dns_zonemgr_t *zmgr;
12755 isc_boolean_t free_now = ISC_FALSE;
12757 REQUIRE(zmgrp != NULL);
12759 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12761 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12763 if (zmgr->refs == 0)
12764 free_now = ISC_TRUE;
12765 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12768 zonemgr_free(zmgr);
12773 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
12776 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12778 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12779 for (p = ISC_LIST_HEAD(zmgr->zones);
12781 p = ISC_LIST_NEXT(p, link))
12783 dns_zone_maintenance(p);
12785 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12788 * Recent configuration changes may have increased the
12789 * amount of available transfers quota. Make sure any
12790 * transfers currently blocked on quota get started if
12793 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12794 zmgr_resume_xfrs(zmgr, ISC_TRUE);
12795 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12796 return (ISC_R_SUCCESS);
12800 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
12802 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12804 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12805 zmgr_resume_xfrs(zmgr, ISC_TRUE);
12806 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12810 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
12813 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12815 isc_ratelimiter_shutdown(zmgr->rl);
12817 if (zmgr->task != NULL)
12818 isc_task_destroy(&zmgr->task);
12819 if (zmgr->zonetasks != NULL)
12820 isc_taskpool_destroy(&zmgr->zonetasks);
12822 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12823 for (zone = ISC_LIST_HEAD(zmgr->zones);
12825 zone = ISC_LIST_NEXT(zone, link))
12828 forward_cancel(zone);
12831 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12835 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
12836 isc_result_t result;
12837 int ntasks = num_zones / 100;
12838 isc_taskpool_t *pool = NULL;
12840 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12843 * For anything fewer than 1000 zones we use 10 tasks in
12844 * the task pool. More than that, and we'll scale at one
12845 * task per 100 zones.
12850 /* Create or resize the zone task pool. */
12851 if (zmgr->zonetasks == NULL)
12852 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
12855 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
12857 if (result == ISC_R_SUCCESS)
12858 zmgr->zonetasks = pool;
12864 zonemgr_free(dns_zonemgr_t *zmgr) {
12867 INSIST(zmgr->refs == 0);
12868 INSIST(ISC_LIST_EMPTY(zmgr->zones));
12872 DESTROYLOCK(&zmgr->iolock);
12873 isc_ratelimiter_detach(&zmgr->rl);
12875 isc_rwlock_destroy(&zmgr->urlock);
12876 isc_rwlock_destroy(&zmgr->rwlock);
12878 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12879 isc_mem_detach(&mctx);
12883 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
12884 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12886 zmgr->transfersin = value;
12890 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
12891 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12893 return (zmgr->transfersin);
12897 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
12898 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12900 zmgr->transfersperns = value;
12904 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
12905 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12907 return (zmgr->transfersperns);
12911 * Try to start a new incoming zone transfer to fill a quota
12912 * slot that was just vacated.
12915 * The zone manager is locked by the caller.
12918 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
12922 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
12926 isc_result_t result;
12927 next = ISC_LIST_NEXT(zone, statelink);
12928 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12929 if (result == ISC_R_SUCCESS) {
12933 * We successfully filled the slot. We're done.
12936 } else if (result == ISC_R_QUOTA) {
12938 * Not enough quota. This is probably the per-server
12939 * quota, because we usually get called when a unit of
12940 * global quota has just been freed. Try the next
12941 * zone, it may succeed if it uses another master.
12945 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12946 "starting zone transfer: %s",
12947 isc_result_totext(result));
12954 * Try to start an incoming zone transfer for 'zone', quota permitting.
12957 * The zone manager is locked by the caller.
12960 * ISC_R_SUCCESS There was enough quota and we attempted to
12961 * start a transfer. zone_xfrdone() has been or will
12963 * ISC_R_QUOTA Not enough quota.
12966 static isc_result_t
12967 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12968 dns_peer_t *peer = NULL;
12969 isc_netaddr_t masterip;
12970 isc_uint32_t nxfrsin, nxfrsperns;
12972 isc_uint32_t maxtransfersin, maxtransfersperns;
12976 * If we are exiting just pretend we got quota so the zone will
12977 * be cleaned up in the zone's task context.
12980 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12986 * Find any configured information about the server we'd
12987 * like to transfer this zone from.
12989 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12990 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
12994 * Determine the total maximum number of simultaneous
12995 * transfers allowed, and the maximum for this specific
12998 maxtransfersin = zmgr->transfersin;
12999 maxtransfersperns = zmgr->transfersperns;
13001 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
13004 * Count the total number of transfers that are in progress,
13005 * and the number of transfers in progress from this master.
13006 * We linearly scan a list of all transfers; if this turns
13007 * out to be too slow, we could hash on the master address.
13009 nxfrsin = nxfrsperns = 0;
13010 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13012 x = ISC_LIST_NEXT(x, statelink))
13017 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
13021 if (isc_netaddr_equal(&xip, &masterip))
13025 /* Enforce quota. */
13026 if (nxfrsin >= maxtransfersin)
13027 return (ISC_R_QUOTA);
13029 if (nxfrsperns >= maxtransfersperns)
13030 return (ISC_R_QUOTA);
13034 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
13035 * list and send it an event to let it start the actual transfer in the
13036 * context of its own task.
13038 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
13039 got_transfer_quota, zone, sizeof(isc_event_t));
13041 return (ISC_R_NOMEMORY);
13044 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
13045 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
13046 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
13047 zone->statelist = &zmgr->xfrin_in_progress;
13048 isc_task_send(zone->task, &e);
13049 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
13052 return (ISC_R_SUCCESS);
13056 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
13058 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13059 REQUIRE(iolimit > 0);
13061 zmgr->iolimit = iolimit;
13065 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
13067 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13069 return (zmgr->iolimit);
13073 * Get permission to request a file handle from the OS.
13074 * An event will be sent to action when one is available.
13075 * There are two queues available (high and low), the high
13076 * queue will be serviced before the low one.
13078 * zonemgr_putio() must be called after the event is delivered to
13082 static isc_result_t
13083 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
13084 isc_task_t *task, isc_taskaction_t action, void *arg,
13088 isc_boolean_t queue;
13090 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13091 REQUIRE(iop != NULL && *iop == NULL);
13093 io = isc_mem_get(zmgr->mctx, sizeof(*io));
13095 return (ISC_R_NOMEMORY);
13096 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
13097 action, arg, sizeof(*io->event));
13098 if (io->event == NULL) {
13099 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13100 return (ISC_R_NOMEMORY);
13105 isc_task_attach(task, &io->task);
13106 ISC_LINK_INIT(io, link);
13107 io->magic = IO_MAGIC;
13109 LOCK(&zmgr->iolock);
13111 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
13114 ISC_LIST_APPEND(zmgr->high, io, link);
13116 ISC_LIST_APPEND(zmgr->low, io, link);
13118 UNLOCK(&zmgr->iolock);
13122 isc_task_send(io->task, &io->event);
13124 return (ISC_R_SUCCESS);
13128 zonemgr_putio(dns_io_t **iop) {
13131 dns_zonemgr_t *zmgr;
13133 REQUIRE(iop != NULL);
13135 REQUIRE(DNS_IO_VALID(io));
13139 INSIST(!ISC_LINK_LINKED(io, link));
13140 INSIST(io->event == NULL);
13143 isc_task_detach(&io->task);
13145 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13147 LOCK(&zmgr->iolock);
13148 INSIST(zmgr->ioactive > 0);
13150 next = HEAD(zmgr->high);
13152 next = HEAD(zmgr->low);
13153 if (next != NULL) {
13155 ISC_LIST_UNLINK(zmgr->high, next, link);
13157 ISC_LIST_UNLINK(zmgr->low, next, link);
13158 INSIST(next->event != NULL);
13160 UNLOCK(&zmgr->iolock);
13162 isc_task_send(next->task, &next->event);
13166 zonemgr_cancelio(dns_io_t *io) {
13167 isc_boolean_t send_event = ISC_FALSE;
13169 REQUIRE(DNS_IO_VALID(io));
13172 * If we are queued to be run then dequeue.
13174 LOCK(&io->zmgr->iolock);
13175 if (ISC_LINK_LINKED(io, link)) {
13177 ISC_LIST_UNLINK(io->zmgr->high, io, link);
13179 ISC_LIST_UNLINK(io->zmgr->low, io, link);
13181 send_event = ISC_TRUE;
13182 INSIST(io->event != NULL);
13184 UNLOCK(&io->zmgr->iolock);
13186 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
13187 isc_task_send(io->task, &io->event);
13192 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
13195 isc_result_t result;
13197 buflen = strlen(path) + strlen(templat) + 2;
13199 buf = isc_mem_get(zone->mctx, buflen);
13203 result = isc_file_template(path, templat, buf, buflen);
13204 if (result != ISC_R_SUCCESS)
13207 result = isc_file_renameunique(path, buf);
13208 if (result != ISC_R_SUCCESS)
13211 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
13212 "renaming file to '%s' for failure analysis and "
13213 "retransferring.", path, buf);
13216 isc_mem_put(zone->mctx, buf, buflen);
13220 /* Hook for ondestroy notification from a database. */
13223 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
13224 dns_db_t *db = event->sender;
13227 isc_event_free(&event);
13229 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13230 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13231 "database (%p) destroyed", (void*) db);
13236 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
13237 isc_interval_t interval;
13238 isc_uint32_t s, ns;
13239 isc_uint32_t pertic;
13240 isc_result_t result;
13242 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13251 } else if (value <= 10) {
13253 ns = 1000000000 / value;
13257 ns = (1000000000 / value) * 10;
13261 isc_interval_set(&interval, s, ns);
13262 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
13263 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13264 isc_ratelimiter_setpertic(zmgr->rl, pertic);
13266 zmgr->serialqueryrate = value;
13270 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
13271 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13273 return (zmgr->serialqueryrate);
13277 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13278 isc_sockaddr_t *local, isc_time_t *now)
13281 isc_rwlocktype_t locktype;
13282 isc_result_t result;
13283 isc_uint32_t seconds = isc_time_seconds(now);
13285 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13287 locktype = isc_rwlocktype_read;
13288 RWLOCK(&zmgr->urlock, locktype);
13289 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13290 if (zmgr->unreachable[i].expire >= seconds &&
13291 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13292 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13293 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13294 if (result == ISC_R_SUCCESS) {
13295 locktype = isc_rwlocktype_write;
13296 zmgr->unreachable[i].last = seconds;
13301 RWUNLOCK(&zmgr->urlock, locktype);
13302 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
13306 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13307 isc_sockaddr_t *local)
13310 isc_rwlocktype_t locktype;
13311 isc_result_t result;
13313 char master[ISC_SOCKADDR_FORMATSIZE];
13314 char source[ISC_SOCKADDR_FORMATSIZE];
13316 isc_sockaddr_format(remote, master, sizeof(master));
13317 isc_sockaddr_format(local, source, sizeof(source));
13319 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13321 locktype = isc_rwlocktype_read;
13322 RWLOCK(&zmgr->urlock, locktype);
13323 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13324 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13325 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13326 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13327 if (result == ISC_R_SUCCESS) {
13328 locktype = isc_rwlocktype_write;
13329 zmgr->unreachable[i].expire = 0;
13330 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13331 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
13332 "master %s (source %s) deleted "
13333 "from unreachable cache",
13339 RWUNLOCK(&zmgr->urlock, locktype);
13343 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13344 isc_sockaddr_t *local, isc_time_t *now)
13346 isc_uint32_t seconds = isc_time_seconds(now);
13347 isc_uint32_t last = seconds;
13348 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
13350 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13352 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
13353 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13354 /* Existing entry? */
13355 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13356 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
13359 if (zmgr->unreachable[i].expire < seconds)
13361 /* Least recently used slot? */
13362 if (zmgr->unreachable[i].last < last) {
13363 last = zmgr->unreachable[i].last;
13367 if (i < UNREACH_CHACHE_SIZE) {
13369 * Found a existing entry. Update the expire timer and
13370 * last usage timestamps.
13372 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
13373 zmgr->unreachable[i].last = seconds;
13374 } else if (slot != UNREACH_CHACHE_SIZE) {
13376 * Found a empty slot. Add a new entry to the cache.
13378 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
13379 zmgr->unreachable[slot].last = seconds;
13380 zmgr->unreachable[slot].remote = *remote;
13381 zmgr->unreachable[slot].local = *local;
13384 * Replace the least recently used entry in the cache.
13386 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
13387 zmgr->unreachable[oldest].last = seconds;
13388 zmgr->unreachable[oldest].remote = *remote;
13389 zmgr->unreachable[oldest].local = *local;
13391 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
13395 dns_zone_forcereload(dns_zone_t *zone) {
13396 REQUIRE(DNS_ZONE_VALID(zone));
13398 if (zone->type == dns_zone_master)
13402 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13404 dns_zone_refresh(zone);
13408 dns_zone_isforced(dns_zone_t *zone) {
13409 REQUIRE(DNS_ZONE_VALID(zone));
13411 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
13415 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
13417 * This function is obsoleted.
13421 return (ISC_R_NOTIMPLEMENTED);
13425 dns_zone_getstatscounters(dns_zone_t *zone) {
13427 * This function is obsoleted.
13434 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
13435 REQUIRE(DNS_ZONE_VALID(zone));
13436 REQUIRE(zone->stats == NULL);
13439 zone->stats = NULL;
13440 isc_stats_attach(stats, &zone->stats);
13445 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
13446 REQUIRE(DNS_ZONE_VALID(zone));
13449 if (zone->requeststats_on && stats == NULL)
13450 zone->requeststats_on = ISC_FALSE;
13451 else if (!zone->requeststats_on && stats != NULL) {
13452 if (zone->requeststats == NULL) {
13453 isc_stats_attach(stats, &zone->requeststats);
13454 zone->requeststats_on = ISC_TRUE;
13463 dns_zone_getrequeststats(dns_zone_t *zone) {
13465 * We don't lock zone for efficiency reason. This is not catastrophic
13466 * because requeststats must always be valid when requeststats_on is
13468 * Some counters may be incremented while requeststats_on is becoming
13469 * false, or some cannot be incremented just after the statistics are
13470 * installed, but it shouldn't matter much in practice.
13472 if (zone->requeststats_on)
13473 return (zone->requeststats);
13479 dns_zone_dialup(dns_zone_t *zone) {
13481 REQUIRE(DNS_ZONE_VALID(zone));
13483 zone_debuglog(zone, "dns_zone_dialup", 3,
13484 "notify = %d, refresh = %d",
13485 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
13486 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
13488 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
13489 dns_zone_notify(zone);
13490 if (zone->type != dns_zone_master &&
13491 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
13492 dns_zone_refresh(zone);
13496 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
13497 REQUIRE(DNS_ZONE_VALID(zone));
13500 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
13501 DNS_ZONEFLG_DIALREFRESH |
13502 DNS_ZONEFLG_NOREFRESH);
13504 case dns_dialuptype_no:
13506 case dns_dialuptype_yes:
13507 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
13508 DNS_ZONEFLG_DIALREFRESH |
13509 DNS_ZONEFLG_NOREFRESH));
13511 case dns_dialuptype_notify:
13512 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13514 case dns_dialuptype_notifypassive:
13515 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13516 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13518 case dns_dialuptype_refresh:
13519 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
13520 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13522 case dns_dialuptype_passive:
13523 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13532 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
13533 isc_result_t result = ISC_R_SUCCESS;
13535 REQUIRE(DNS_ZONE_VALID(zone));
13538 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
13545 dns_zone_getkeydirectory(dns_zone_t *zone) {
13546 REQUIRE(DNS_ZONE_VALID(zone));
13548 return (zone->keydirectory);
13552 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
13554 unsigned int count = 0;
13556 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13558 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13560 case DNS_ZONESTATE_XFERRUNNING:
13561 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13563 zone = ISC_LIST_NEXT(zone, statelink))
13566 case DNS_ZONESTATE_XFERDEFERRED:
13567 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
13569 zone = ISC_LIST_NEXT(zone, statelink))
13572 case DNS_ZONESTATE_SOAQUERY:
13573 for (zone = ISC_LIST_HEAD(zmgr->zones);
13575 zone = ISC_LIST_NEXT(zone, link))
13576 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
13579 case DNS_ZONESTATE_ANY:
13580 for (zone = ISC_LIST_HEAD(zmgr->zones);
13582 zone = ISC_LIST_NEXT(zone, link)) {
13583 dns_view_t *view = zone->view;
13584 if (view != NULL && strcmp(view->name, "_bind") == 0)
13593 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13599 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
13600 isc_boolean_t ok = ISC_TRUE;
13601 isc_boolean_t fail = ISC_FALSE;
13602 char namebuf[DNS_NAME_FORMATSIZE];
13603 char namebuf2[DNS_NAME_FORMATSIZE];
13604 char typebuf[DNS_RDATATYPE_FORMATSIZE];
13605 int level = ISC_LOG_WARNING;
13608 REQUIRE(DNS_ZONE_VALID(zone));
13610 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
13611 return (ISC_R_SUCCESS);
13613 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
13614 level = ISC_LOG_ERROR;
13618 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
13620 dns_name_format(name, namebuf, sizeof(namebuf));
13621 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13622 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
13623 dns_result_totext(DNS_R_BADOWNERNAME));
13625 return (DNS_R_BADOWNERNAME);
13628 dns_name_init(&bad, NULL);
13629 ok = dns_rdata_checknames(rdata, name, &bad);
13631 dns_name_format(name, namebuf, sizeof(namebuf));
13632 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
13633 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13634 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
13635 namebuf2, dns_result_totext(DNS_R_BADNAME));
13637 return (DNS_R_BADNAME);
13640 return (ISC_R_SUCCESS);
13644 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
13645 REQUIRE(DNS_ZONE_VALID(zone));
13646 zone->checkmx = checkmx;
13650 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
13651 REQUIRE(DNS_ZONE_VALID(zone));
13652 zone->checksrv = checksrv;
13656 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
13657 REQUIRE(DNS_ZONE_VALID(zone));
13658 zone->checkns = checkns;
13662 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
13663 REQUIRE(DNS_ZONE_VALID(zone));
13666 zone->isself = isself;
13667 zone->isselfarg = arg;
13672 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
13673 REQUIRE(DNS_ZONE_VALID(zone));
13676 zone->notifydelay = delay;
13681 dns_zone_getnotifydelay(dns_zone_t *zone) {
13682 REQUIRE(DNS_ZONE_VALID(zone));
13684 return (zone->notifydelay);
13688 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
13689 isc_uint16_t keyid, isc_boolean_t delete)
13691 isc_result_t result;
13692 REQUIRE(DNS_ZONE_VALID(zone));
13694 dns_zone_log(zone, ISC_LOG_NOTICE,
13695 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
13698 result = zone_signwithkey(zone, algorithm, keyid, delete);
13704 static const char *hex = "0123456789ABCDEF";
13707 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
13708 isc_result_t result;
13709 char salt[255*2+1];
13712 REQUIRE(DNS_ZONE_VALID(zone));
13714 if (nsec3param->salt_length != 0) {
13715 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
13716 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
13717 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
13718 salt[j++] = hex[nsec3param->salt[i] & 0xf];
13723 dns_zone_log(zone, ISC_LOG_NOTICE,
13724 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
13725 nsec3param->hash, nsec3param->iterations,
13728 result = zone_addnsec3chain(zone, nsec3param);
13735 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
13736 REQUIRE(DNS_ZONE_VALID(zone));
13740 zone->nodes = nodes;
13744 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
13745 REQUIRE(DNS_ZONE_VALID(zone));
13748 * We treat signatures as a signed value so explicitly
13749 * limit its range here.
13751 if (signatures > ISC_INT32_MAX)
13752 signatures = ISC_INT32_MAX;
13753 else if (signatures == 0)
13755 zone->signatures = signatures;
13759 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
13760 REQUIRE(DNS_ZONE_VALID(zone));
13761 zone->privatetype = type;
13765 dns_zone_getprivatetype(dns_zone_t *zone) {
13766 REQUIRE(DNS_ZONE_VALID(zone));
13767 return (zone->privatetype);
13770 static isc_result_t
13771 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
13772 isc_boolean_t delete)
13774 dns_signing_t *signing;
13775 dns_signing_t *current;
13776 isc_result_t result = ISC_R_SUCCESS;
13779 signing = isc_mem_get(zone->mctx, sizeof *signing);
13780 if (signing == NULL)
13781 return (ISC_R_NOMEMORY);
13783 signing->magic = 0;
13784 signing->db = NULL;
13785 signing->dbiterator = NULL;
13786 signing->algorithm = algorithm;
13787 signing->keyid = keyid;
13788 signing->delete = delete;
13789 signing->done = ISC_FALSE;
13793 for (current = ISC_LIST_HEAD(zone->signing);
13795 current = ISC_LIST_NEXT(current, link)) {
13796 if (current->db == zone->db &&
13797 current->algorithm == signing->algorithm &&
13798 current->keyid == signing->keyid) {
13799 if (current->delete != signing->delete)
13800 current->done = ISC_TRUE;
13806 if (zone->db != NULL) {
13807 dns_db_attach(zone->db, &signing->db);
13808 result = dns_db_createiterator(signing->db, 0,
13809 &signing->dbiterator);
13811 if (result == ISC_R_SUCCESS)
13812 result = dns_dbiterator_first(signing->dbiterator);
13813 if (result == ISC_R_SUCCESS) {
13814 dns_dbiterator_pause(signing->dbiterator);
13815 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
13817 if (isc_time_isepoch(&zone->signingtime)) {
13818 zone->signingtime = now;
13819 if (zone->task != NULL)
13820 zone_settimer(zone, &now);
13824 result = ISC_R_NOTFOUND;
13827 if (signing != NULL) {
13828 if (signing->db != NULL)
13829 dns_db_detach(&signing->db);
13830 if (signing->dbiterator != NULL)
13831 dns_dbiterator_destroy(&signing->dbiterator);
13832 isc_mem_put(zone->mctx, signing, sizeof *signing);
13838 logmsg(const char *format, ...) {
13840 va_start(args, format);
13841 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
13842 ISC_LOG_DEBUG(1), format, args);
13847 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
13848 dns_dnsseckey_t *key;
13849 while (!ISC_LIST_EMPTY(*list)) {
13850 key = ISC_LIST_HEAD(*list);
13851 ISC_LIST_UNLINK(*list, key, link);
13852 dns_dnsseckey_destroy(mctx, &key);
13856 /* Called once; *timep should be set to the current time. */
13857 static isc_result_t
13858 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
13859 isc_result_t result;
13860 isc_stdtime_t now, then = 0, event;
13865 for (i = 0; i <= DST_MAX_TIMES; i++) {
13866 result = dst_key_gettime(key, i, &event);
13867 if (result == ISC_R_SUCCESS && event > now &&
13868 (then == 0 || event < then))
13874 return (ISC_R_SUCCESS);
13877 return (ISC_R_NOTFOUND);
13880 static isc_result_t
13881 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
13882 const dns_rdata_t *rdata, isc_boolean_t *flag)
13884 dns_rdataset_t rdataset;
13885 dns_dbnode_t *node = NULL;
13886 isc_result_t result;
13888 dns_rdataset_init(&rdataset);
13889 if (rdata->type == dns_rdatatype_nsec3)
13890 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
13892 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
13893 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
13894 (isc_stdtime_t) 0, &rdataset, NULL);
13895 if (result == ISC_R_NOTFOUND) {
13897 result = ISC_R_SUCCESS;
13901 for (result = dns_rdataset_first(&rdataset);
13902 result == ISC_R_SUCCESS;
13903 result = dns_rdataset_next(&rdataset)) {
13904 dns_rdata_t myrdata = DNS_RDATA_INIT;
13905 dns_rdataset_current(&rdataset, &myrdata);
13906 if (!dns_rdata_compare(&myrdata, rdata))
13909 dns_rdataset_disassociate(&rdataset);
13910 if (result == ISC_R_SUCCESS) {
13912 } else if (result == ISC_R_NOMORE) {
13914 result = ISC_R_SUCCESS;
13919 dns_db_detachnode(db, &node);
13924 * Add records to signal the state of signing or of key removal.
13926 static isc_result_t
13927 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
13928 dns_dbversion_t *ver, dns_diff_t *diff,
13929 isc_boolean_t sign_all)
13931 dns_difftuple_t *tuple, *newtuple = NULL;
13932 dns_rdata_dnskey_t dnskey;
13933 dns_rdata_t rdata = DNS_RDATA_INIT;
13934 isc_boolean_t flag;
13936 isc_result_t result = ISC_R_SUCCESS;
13937 isc_uint16_t keyid;
13938 unsigned char buf[5];
13939 dns_name_t *name = dns_db_origin(db);
13941 for (tuple = ISC_LIST_HEAD(diff->tuples);
13943 tuple = ISC_LIST_NEXT(tuple, link)) {
13944 if (tuple->rdata.type != dns_rdatatype_dnskey)
13947 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
13948 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13949 if ((dnskey.flags &
13950 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
13951 != DNS_KEYOWNER_ZONE)
13954 dns_rdata_toregion(&tuple->rdata, &r);
13956 keyid = dst_region_computeid(&r, dnskey.algorithm);
13958 buf[0] = dnskey.algorithm;
13959 buf[1] = (keyid & 0xff00) >> 8;
13960 buf[2] = (keyid & 0xff);
13961 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
13964 rdata.length = sizeof(buf);
13965 rdata.type = privatetype;
13966 rdata.rdclass = tuple->rdata.rdclass;
13968 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
13969 CHECK(rr_exists(db, ver, name, &rdata, &flag));
13972 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
13973 name, 0, &rdata, &newtuple));
13974 CHECK(do_one_tuple(&newtuple, db, ver, diff));
13975 INSIST(newtuple == NULL);
13979 * Remove any record which says this operation has already
13983 CHECK(rr_exists(db, ver, name, &rdata, &flag));
13985 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
13986 name, 0, &rdata, &newtuple));
13987 CHECK(do_one_tuple(&newtuple, db, ver, diff));
13988 INSIST(newtuple == NULL);
13995 static isc_result_t
13996 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
13997 dns_diff_t *diff, dns_diff_t *sig_diff)
13999 isc_result_t result;
14000 isc_stdtime_t now, inception, soaexpire;
14001 isc_boolean_t check_ksk, keyset_kskonly;
14002 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
14003 unsigned int nkeys = 0, i;
14004 dns_difftuple_t *tuple;
14006 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
14007 zone_keys, &nkeys);
14008 if (result != ISC_R_SUCCESS) {
14009 dns_zone_log(zone, ISC_LOG_ERROR,
14010 "sign_apex:find_zone_keys -> %s",
14011 dns_result_totext(result));
14015 isc_stdtime_get(&now);
14016 inception = now - 3600; /* Allow for clock skew. */
14017 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
14019 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14020 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
14023 * See if update_sigs will update DNSKEY signature and if not
14024 * cause them to sign so that so that newly activated keys
14027 for (tuple = ISC_LIST_HEAD(diff->tuples);
14029 tuple = ISC_LIST_NEXT(tuple, link)) {
14030 if (tuple->rdata.type == dns_rdatatype_dnskey &&
14031 dns_name_equal(&tuple->name, &zone->origin))
14035 if (tuple == NULL) {
14036 result = del_sigs(zone, db, ver, &zone->origin,
14037 dns_rdatatype_dnskey, sig_diff,
14038 zone_keys, nkeys, now, ISC_FALSE);
14039 if (result != ISC_R_SUCCESS) {
14040 dns_zone_log(zone, ISC_LOG_ERROR,
14041 "sign_apex:del_sigs -> %s",
14042 dns_result_totext(result));
14045 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
14046 sig_diff, zone_keys, nkeys, zone->mctx,
14047 inception, soaexpire, check_ksk,
14049 if (result != ISC_R_SUCCESS) {
14050 dns_zone_log(zone, ISC_LOG_ERROR,
14051 "sign_apex:add_sigs -> %s",
14052 dns_result_totext(result));
14057 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
14058 inception, soaexpire, now, check_ksk,
14059 keyset_kskonly, sig_diff);
14061 if (result != ISC_R_SUCCESS) {
14062 dns_zone_log(zone, ISC_LOG_ERROR,
14063 "sign_apex:update_sigs -> %s",
14064 dns_result_totext(result));
14069 for (i = 0; i < nkeys; i++)
14070 dst_key_free(&zone_keys[i]);
14075 * Prevent the zone entering a inconsistent state where
14076 * NSEC only DNSKEYs are present with NSEC3 chains.
14077 * See update.c:check_dnssec()
14079 static isc_boolean_t
14080 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14083 isc_result_t result;
14084 dns_difftuple_t *tuple;
14085 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
14086 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
14088 /* Scan the tuples for an NSEC-only DNSKEY */
14089 for (tuple = ISC_LIST_HEAD(diff->tuples);
14091 tuple = ISC_LIST_NEXT(tuple, link)) {
14093 if (tuple->rdata.type != dns_rdatatype_dnskey ||
14094 tuple->op != DNS_DIFFOP_ADD)
14097 alg = tuple->rdata.data[3];
14098 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
14099 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
14100 nseconly = ISC_TRUE;
14105 /* Check existing DB for NSEC-only DNSKEY */
14107 CHECK(dns_nsec_nseconly(db, ver, &nseconly));
14109 /* Check existing DB for NSEC3 */
14111 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
14112 privatetype, &nsec3));
14114 /* Refuse to allow NSEC3 with NSEC-only keys */
14115 if (nseconly && nsec3) {
14116 dns_zone_log(zone, ISC_LOG_ERROR,
14117 "NSEC only DNSKEYs and NSEC3 chains not allowed");
14124 return (ISC_FALSE);
14127 static isc_result_t
14128 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14131 isc_result_t result;
14132 dns_dbnode_t *node = NULL;
14133 dns_rdataset_t rdataset;
14135 dns_rdataset_init(&rdataset);
14136 CHECK(dns_db_getoriginnode(db, &node));
14138 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14139 dns_rdatatype_none, 0, &rdataset, NULL);
14140 if (dns_rdataset_isassociated(&rdataset))
14141 dns_rdataset_disassociate(&rdataset);
14142 if (result != ISC_R_NOTFOUND)
14145 result = dns_nsec3param_deletechains(db, ver, zone, diff);
14149 dns_db_detachnode(db, &node);
14154 * Given an RRSIG rdataset and an algorithm, determine whether there
14155 * are any signatures using that algorithm.
14157 static isc_boolean_t
14158 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
14159 dns_rdata_t rdata = DNS_RDATA_INIT;
14160 dns_rdata_rrsig_t rrsig;
14161 isc_result_t result;
14163 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
14164 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
14165 return (ISC_FALSE);
14168 for (result = dns_rdataset_first(rdataset);
14169 result == ISC_R_SUCCESS;
14170 result = dns_rdataset_next(rdataset))
14172 dns_rdataset_current(rdataset, &rdata);
14173 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
14174 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14175 dns_rdata_reset(&rdata);
14176 if (rrsig.algorithm == alg)
14180 return (ISC_FALSE);
14183 static isc_result_t
14184 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14187 dns_name_t *origin;
14188 isc_boolean_t build_nsec3;
14189 isc_result_t result;
14191 origin = dns_db_origin(db);
14192 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
14195 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
14196 ISC_FALSE, zone->privatetype, diff));
14197 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
14204 zone_rekey(dns_zone_t *zone) {
14205 isc_result_t result;
14206 dns_db_t *db = NULL;
14207 dns_dbnode_t *node = NULL;
14208 dns_dbversion_t *ver = NULL;
14209 dns_rdataset_t soaset, soasigs, keyset, keysigs;
14210 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
14211 dns_dnsseckey_t *key;
14212 dns_diff_t diff, sig_diff;
14213 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
14214 isc_boolean_t newalg = ISC_FALSE;
14215 isc_boolean_t fullsign;
14216 dns_ttl_t ttl = 3600;
14220 isc_time_t timenow;
14221 isc_interval_t ival;
14224 REQUIRE(DNS_ZONE_VALID(zone));
14226 ISC_LIST_INIT(dnskeys);
14227 ISC_LIST_INIT(keys);
14228 ISC_LIST_INIT(rmkeys);
14229 dns_rdataset_init(&soaset);
14230 dns_rdataset_init(&soasigs);
14231 dns_rdataset_init(&keyset);
14232 dns_rdataset_init(&keysigs);
14233 dir = dns_zone_getkeydirectory(zone);
14235 dns_diff_init(mctx, &diff);
14236 dns_diff_init(mctx, &sig_diff);
14237 sig_diff.resign = zone->sigresigninginterval;
14239 CHECK(dns_zone_getdb(zone, &db));
14240 CHECK(dns_db_newversion(db, &ver));
14241 CHECK(dns_db_getoriginnode(db, &node));
14243 TIME_NOW(&timenow);
14244 now = isc_time_seconds(&timenow);
14246 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
14248 /* Get the SOA record's TTL */
14249 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
14250 dns_rdatatype_none, 0, &soaset, &soasigs));
14252 dns_rdataset_disassociate(&soaset);
14254 /* Get the DNSKEY rdataset */
14255 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14256 dns_rdatatype_none, 0, &keyset, &keysigs);
14257 if (result == ISC_R_SUCCESS) {
14259 result = dns_dnssec_keylistfromrdataset(&zone->origin, dir,
14261 &keysigs, &soasigs,
14262 ISC_FALSE, ISC_FALSE,
14264 /* Can't get keys for some reason; try again later. */
14265 if (result != ISC_R_SUCCESS)
14267 } else if (result != ISC_R_NOTFOUND)
14271 * True when called from "rndc sign". Indicates the zone should be
14272 * fully signed now.
14274 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
14276 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
14277 if (result == ISC_R_SUCCESS) {
14278 isc_boolean_t check_ksk;
14279 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14281 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
14282 &zone->origin, ttl, &diff,
14283 ISC_TF(!check_ksk),
14286 /* Keys couldn't be updated for some reason;
14287 * try again later. */
14288 if (result != ISC_R_SUCCESS) {
14289 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
14290 "couldn't update zone keys: %s",
14291 isc_result_totext(result));
14296 * See if any pre-existing keys have newly become active;
14297 * also, see if any new key is for a new algorithm, as in that
14298 * event, we need to sign the zone fully. (If there's a new
14299 * key, but it's for an already-existing algorithm, then
14300 * the zone signing can be handled incrementally.)
14302 for (key = ISC_LIST_HEAD(dnskeys);
14304 key = ISC_LIST_NEXT(key, link)) {
14305 if (!key->first_sign)
14308 newactive = ISC_TRUE;
14310 if (!dns_rdataset_isassociated(&keysigs)) {
14315 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
14317 * This isn't a new algorithm; clear
14318 * first_sign so we won't sign the
14319 * whole zone with this key later
14321 key->first_sign = ISC_FALSE;
14328 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
14329 dnskey_sane(zone, db, ver, &diff)) {
14330 CHECK(dns_diff_apply(&diff, db, ver));
14331 CHECK(clean_nsec3param(zone, db, ver, &diff));
14332 CHECK(add_signing_records(db, zone->privatetype,
14334 ISC_TF(newalg || fullsign)));
14335 CHECK(increment_soa_serial(db, ver, &diff, mctx));
14336 CHECK(add_chains(zone, db, ver, &diff));
14337 CHECK(sign_apex(zone, db, ver, &diff, &sig_diff));
14338 CHECK(zone_journal(zone, &sig_diff, "zone_rekey"));
14343 dns_db_closeversion(db, &ver, commit);
14346 dns_difftuple_t *tuple;
14349 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14351 zone_needdump(zone, DNS_DUMP_DELAY);
14353 zone_settimer(zone, &timenow);
14355 /* Remove any signatures from removed keys. */
14356 if (!ISC_LIST_EMPTY(rmkeys)) {
14357 for (key = ISC_LIST_HEAD(rmkeys);
14359 key = ISC_LIST_NEXT(key, link)) {
14360 result = zone_signwithkey(zone,
14361 dst_key_alg(key->key),
14362 dst_key_id(key->key),
14364 if (result != ISC_R_SUCCESS) {
14365 dns_zone_log(zone, ISC_LOG_ERROR,
14366 "zone_signwithkey failed: %s",
14367 dns_result_totext(result));
14374 * "rndc sign" was called, so we now sign the zone
14375 * with all active keys, whether they're new or not.
14377 for (key = ISC_LIST_HEAD(dnskeys);
14379 key = ISC_LIST_NEXT(key, link)) {
14380 if (!key->force_sign && !key->hint_sign)
14383 result = zone_signwithkey(zone,
14384 dst_key_alg(key->key),
14385 dst_key_id(key->key),
14387 if (result != ISC_R_SUCCESS) {
14388 dns_zone_log(zone, ISC_LOG_ERROR,
14389 "zone_signwithkey failed: %s",
14390 dns_result_totext(result));
14393 } else if (newalg) {
14395 * We haven't been told to sign fully, but a new
14396 * algorithm was added to the DNSKEY. We sign
14397 * the full zone, but only with newly active
14400 for (key = ISC_LIST_HEAD(dnskeys);
14402 key = ISC_LIST_NEXT(key, link)) {
14403 if (!key->first_sign)
14406 result = zone_signwithkey(zone,
14407 dst_key_alg(key->key),
14408 dst_key_id(key->key),
14410 if (result != ISC_R_SUCCESS) {
14411 dns_zone_log(zone, ISC_LOG_ERROR,
14412 "zone_signwithkey failed: %s",
14413 dns_result_totext(result));
14419 * Clear fullsign flag, if it was set, so we don't do
14420 * another full signing next time
14422 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
14425 * Cause the zone to add/delete NSEC3 chains for the
14426 * deferred NSEC3PARAM changes.
14428 for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
14430 tuple = ISC_LIST_NEXT(tuple, link)) {
14431 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
14432 dns_rdata_t rdata = DNS_RDATA_INIT;
14433 dns_rdata_nsec3param_t nsec3param;
14435 if (tuple->rdata.type != zone->privatetype ||
14436 tuple->op != DNS_DIFFOP_ADD)
14439 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
14442 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
14443 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14444 if (nsec3param.flags == 0)
14447 result = zone_addnsec3chain(zone, &nsec3param);
14448 if (result != ISC_R_SUCCESS) {
14449 dns_zone_log(zone, ISC_LOG_ERROR,
14450 "zone_addnsec3chain failed: %s",
14451 dns_result_totext(result));
14456 * Schedule the next resigning event
14458 set_resigntime(zone);
14462 isc_time_settoepoch(&zone->refreshkeytime);
14465 * If we're doing key maintenance, set the key refresh timer to
14466 * the next scheduled key event or to one hour in the future,
14467 * whichever is sooner.
14469 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
14470 isc_time_t timethen;
14471 isc_stdtime_t then;
14474 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
14475 zone->refreshkeytime = timethen;
14478 for (key = ISC_LIST_HEAD(dnskeys);
14480 key = ISC_LIST_NEXT(key, link)) {
14482 result = next_keyevent(key->key, &then);
14483 if (result != ISC_R_SUCCESS)
14486 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
14488 if (isc_time_compare(&timethen,
14489 &zone->refreshkeytime) < 0) {
14490 zone->refreshkeytime = timethen;
14495 zone_settimer(zone, &timenow);
14497 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
14498 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
14502 dns_diff_clear(&diff);
14503 dns_diff_clear(&sig_diff);
14505 clear_keylist(&dnskeys, mctx);
14506 clear_keylist(&keys, mctx);
14507 clear_keylist(&rmkeys, mctx);
14510 dns_db_closeversion(db, &ver, ISC_FALSE);
14511 if (dns_rdataset_isassociated(&keyset))
14512 dns_rdataset_disassociate(&keyset);
14513 if (dns_rdataset_isassociated(&keysigs))
14514 dns_rdataset_disassociate(&keysigs);
14515 if (dns_rdataset_isassociated(&soasigs))
14516 dns_rdataset_disassociate(&soasigs);
14518 dns_db_detachnode(db, &node);
14520 dns_db_detach(&db);
14524 isc_interval_set(&ival, HOUR, 0);
14525 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
14530 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
14533 if (zone->type == dns_zone_master && zone->task != NULL) {
14537 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
14540 zone->refreshkeytime = now;
14541 zone_settimer(zone, &now);
14548 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
14549 unsigned int *errors)
14551 isc_result_t result;
14552 dns_dbnode_t *node = NULL;
14554 REQUIRE(DNS_ZONE_VALID(zone));
14555 REQUIRE(errors != NULL);
14557 result = dns_db_getoriginnode(db, &node);
14558 if (result != ISC_R_SUCCESS)
14560 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
14562 dns_db_detachnode(db, &node);
14567 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
14568 REQUIRE(DNS_ZONE_VALID(zone));
14570 zone->added = added;
14575 dns_zone_getadded(dns_zone_t *zone) {
14576 REQUIRE(DNS_ZONE_VALID(zone));
14577 return (zone->added);
14581 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
14583 isc_time_t loadtime;
14584 isc_result_t result;
14585 TIME_NOW(&loadtime);
14588 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);