2 * Copyright (C) 2004-2011 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.
18 /* $Id: zone.c,v 1.582.8.26 2011-08-09 02:34:24 marka Exp $ */
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>
78 #include <dns/xfrin.h>
83 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
84 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
86 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
87 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
89 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
90 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
92 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
93 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
95 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
96 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
98 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
99 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
101 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
102 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
105 * Ensure 'a' is at least 'min' but not more than 'max'.
107 #define RANGE(a, min, max) \
108 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
110 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
115 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
116 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
117 #define ALG(x) dst_key_alg(x)
122 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
123 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
124 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
125 #define RESIGN_DELAY 3600 /*%< 1 hour */
127 #ifndef DNS_MAX_EXPIRE
128 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
131 #ifndef DNS_DUMP_DELAY
132 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
135 typedef struct dns_notify dns_notify_t;
136 typedef struct dns_stub dns_stub_t;
137 typedef struct dns_load dns_load_t;
138 typedef struct dns_forward dns_forward_t;
139 typedef struct dns_io dns_io_t;
140 typedef ISC_LIST(dns_io_t) dns_iolist_t;
141 typedef struct dns_signing dns_signing_t;
142 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
143 typedef struct dns_nsec3chain dns_nsec3chain_t;
144 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
145 typedef struct dns_keyfetch dns_keyfetch_t;
147 #define DNS_ZONE_CHECKLOCK
148 #ifdef DNS_ZONE_CHECKLOCK
149 #define LOCK_ZONE(z) \
150 do { LOCK(&(z)->lock); \
151 INSIST((z)->locked == ISC_FALSE); \
152 (z)->locked = ISC_TRUE; \
154 #define UNLOCK_ZONE(z) \
155 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
156 #define LOCKED_ZONE(z) ((z)->locked)
158 #define LOCK_ZONE(z) LOCK(&(z)->lock)
159 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
160 #define LOCKED_ZONE(z) ISC_TRUE
163 #ifdef ISC_RWLOCK_USEATOMIC
164 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
165 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
166 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
167 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
169 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
170 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
171 #define ZONEDB_LOCK(l, t) LOCK(l)
172 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
179 #ifdef DNS_ZONE_CHECKLOCK
180 isc_boolean_t locked;
183 isc_refcount_t erefs;
185 #ifdef ISC_RWLOCK_USEATOMIC
190 dns_db_t *db; /* Locked by dblock */
194 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
199 dns_masterformat_t masterformat;
201 isc_int32_t journalsize;
202 dns_rdataclass_t rdclass;
205 unsigned int options;
206 unsigned int db_argc;
208 isc_time_t expiretime;
209 isc_time_t refreshtime;
212 isc_time_t notifytime;
213 isc_time_t resigntime;
214 isc_time_t keywarntime;
215 isc_time_t signingtime;
216 isc_time_t nsec3chaintime;
217 isc_time_t refreshkeytime;
218 isc_uint32_t refreshkeycount;
219 isc_uint32_t refresh;
222 isc_uint32_t minimum;
223 isc_stdtime_t key_expiry;
224 isc_stdtime_t log_key_expired_timer;
227 isc_uint32_t maxrefresh;
228 isc_uint32_t minrefresh;
229 isc_uint32_t maxretry;
230 isc_uint32_t minretry;
232 isc_sockaddr_t *masters;
233 dns_name_t **masterkeynames;
234 isc_boolean_t *mastersok;
235 unsigned int masterscnt;
236 unsigned int curmaster;
237 isc_sockaddr_t masteraddr;
238 dns_notifytype_t notifytype;
239 isc_sockaddr_t *notify;
240 unsigned int notifycnt;
241 isc_sockaddr_t notifyfrom;
243 isc_sockaddr_t notifysrc4;
244 isc_sockaddr_t notifysrc6;
245 isc_sockaddr_t xfrsource4;
246 isc_sockaddr_t xfrsource6;
247 isc_sockaddr_t altxfrsource4;
248 isc_sockaddr_t altxfrsource6;
249 isc_sockaddr_t sourceaddr;
250 dns_xfrin_ctx_t *xfr; /* task locked */
251 dns_tsigkey_t *tsigkey; /* key used for xfr */
252 /* Access Control Lists */
253 dns_acl_t *update_acl;
254 dns_acl_t *forward_acl;
255 dns_acl_t *notify_acl;
256 dns_acl_t *query_acl;
257 dns_acl_t *queryon_acl;
259 isc_boolean_t update_disabled;
260 isc_boolean_t zero_no_soa_ttl;
261 dns_severity_t check_names;
262 ISC_LIST(dns_notify_t) notifies;
263 dns_request_t *request;
268 isc_uint32_t maxxfrin;
269 isc_uint32_t maxxfrout;
271 isc_uint32_t idleout;
272 isc_event_t ctlevent;
273 dns_ssutable_t *ssutable;
274 isc_uint32_t sigvalidityinterval;
275 isc_uint32_t sigresigninginterval;
277 dns_acache_t *acache;
278 dns_checkmxfunc_t checkmx;
279 dns_checksrvfunc_t checksrv;
280 dns_checknsfunc_t checkns;
282 * Zones in certain states such as "waiting for zone transfer"
283 * or "zone transfer in progress" are kept on per-state linked lists
284 * in the zone manager using the 'statelink' field. The 'statelist'
285 * field points at the list the zone is currently on. It the zone
286 * is not on any such list, statelist is NULL.
288 ISC_LINK(dns_zone_t) statelink;
289 dns_zonelist_t *statelist;
291 * Statistics counters about zone management.
295 * Optional per-zone statistics counters. Counted outside of this
298 isc_boolean_t requeststats_on;
299 isc_stats_t *requeststats;
300 isc_uint32_t notifydelay;
301 dns_isselffunc_t isself;
310 * Serial number for deferred journal compaction.
312 isc_uint32_t compact_serial;
314 * Keys that are signing the zone for the first time.
316 dns_signinglist_t signing;
317 dns_nsec3chainlist_t nsec3chain;
319 * Signing / re-signing quantum stopping parameters.
321 isc_uint32_t signatures;
323 dns_rdatatype_t privatetype;
326 * Autosigning/key-maintenance options
328 isc_uint32_t keyopts;
331 * True if added by "rndc addzone"
336 * whether a rpz radix was needed when last loaded
338 isc_boolean_t rpz_zone;
341 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
342 #define DNS_ZONE_SETFLAG(z,f) do { \
343 INSIST(LOCKED_ZONE(z)); \
346 #define DNS_ZONE_CLRFLAG(z,f) do { \
347 INSIST(LOCKED_ZONE(z)); \
348 (z)->flags &= ~(f); \
350 /* XXX MPA these may need to go back into zone.h */
351 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
352 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
353 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
354 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
355 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
356 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
357 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
358 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
359 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
360 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
362 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
364 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
366 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
367 * zone with no masters
369 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
370 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
371 * from SOA (if not set, we
373 * default timer values) */
374 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
375 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
376 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
377 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
378 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
379 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
380 #define DNS_ZONEFLG_FLUSH 0x00200000U
381 #define DNS_ZONEFLG_NOEDNS 0x00400000U
382 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
383 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
384 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
385 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
386 #define DNS_ZONEFLG_THAW 0x08000000U
387 /* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */
388 #define DNS_ZONEFLG_NODELAY 0x20000000U
390 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
391 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
393 /* Flags for zone_load() */
394 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
395 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
398 #define UNREACH_CHACHE_SIZE 10U
399 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
402 do { result = (op); \
403 if (result != ISC_R_SUCCESS) goto failure; \
406 struct dns_unreachable {
407 isc_sockaddr_t remote;
408 isc_sockaddr_t local;
416 int refs; /* Locked by rwlock */
417 isc_taskmgr_t * taskmgr;
418 isc_timermgr_t * timermgr;
419 isc_socketmgr_t * socketmgr;
420 isc_taskpool_t * zonetasks;
422 isc_ratelimiter_t * rl;
426 /* Locked by rwlock. */
427 dns_zonelist_t zones;
428 dns_zonelist_t waiting_for_xfrin;
429 dns_zonelist_t xfrin_in_progress;
431 /* Configuration data. */
432 isc_uint32_t transfersin;
433 isc_uint32_t transfersperns;
434 unsigned int serialqueryrate;
436 /* Locked by iolock */
437 isc_uint32_t iolimit;
438 isc_uint32_t ioactive;
442 /* Locked by rwlock. */
444 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
456 dns_request_t *request;
459 ISC_LINK(dns_notify_t) link;
462 #define DNS_NOTIFY_NOSOA 0x0001U
465 * dns_stub holds state while performing a 'stub' transfer.
466 * 'db' is the zone's 'db' or a new one if this is the initial
475 dns_dbversion_t *version;
487 dns_rdatacallbacks_t callbacks;
491 * Hold forward state.
497 isc_buffer_t *msgbuf;
498 dns_request_t *request;
501 dns_updatecallback_t callback;
506 * Hold IO request state.
513 ISC_LINK(dns_io_t) link;
518 * Hold state for when we are signing a zone with a new
519 * DNSKEY as result of an update.
524 dns_dbiterator_t *dbiterator;
525 dns_secalg_t algorithm;
527 isc_boolean_t delete;
529 ISC_LINK(dns_signing_t) link;
532 struct dns_nsec3chain {
535 dns_dbiterator_t *dbiterator;
536 dns_rdata_nsec3param_t nsec3param;
537 unsigned char salt[255];
539 isc_boolean_t seen_nsec;
540 isc_boolean_t delete_nsec;
541 isc_boolean_t save_delete_nsec;
542 ISC_LINK(dns_nsec3chain_t) link;
545 * 'dbiterator' contains a iterator for the database. If we are creating
546 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
547 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
550 * 'nsec3param' contains the parameters of the NSEC3 chain being created
553 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
555 * 'seen_nsec' will be set to true if, while iterating the zone to create a
556 * NSEC3 chain, a NSEC record is seen.
558 * 'delete_nsec' will be set to true if, at the completion of the creation
559 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
560 * are in the process of deleting the NSEC chain.
562 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
563 * so it can be recovered in the event of a error.
566 struct dns_keyfetch {
567 dns_fixedname_t name;
568 dns_rdataset_t keydataset;
569 dns_rdataset_t dnskeyset;
570 dns_rdataset_t dnskeysigset;
577 #define DAY (24*HOUR)
578 #define MONTH (30*DAY)
580 #define SEND_BUFFER_SIZE 2048
582 static void zone_settimer(dns_zone_t *, isc_time_t *);
583 static void cancel_refresh(dns_zone_t *);
584 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
585 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
586 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
587 ISC_FORMAT_PRINTF(3, 4);
588 static void queue_xfrin(dns_zone_t *zone);
589 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
590 dns_diff_t *diff, dns_diffop_t op,
591 dns_name_t *name, dns_ttl_t ttl,
593 static void zone_unload(dns_zone_t *zone);
594 static void zone_expire(dns_zone_t *zone);
595 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
596 static void zone_idetach(dns_zone_t **zonep);
597 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
599 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
600 static inline void zone_detachdb(dns_zone_t *zone);
601 static isc_result_t default_journal(dns_zone_t *zone);
602 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
603 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
604 isc_time_t loadtime, isc_result_t result);
605 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
606 static void zone_shutdown(isc_task_t *, isc_event_t *);
607 static void zone_loaddone(void *arg, isc_result_t result);
608 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
609 isc_time_t loadtime);
610 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
611 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
612 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
613 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
616 /* ondestroy example */
617 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
620 static void refresh_callback(isc_task_t *, isc_event_t *);
621 static void stub_callback(isc_task_t *, isc_event_t *);
622 static void queue_soa_query(dns_zone_t *zone);
623 static void soa_query(isc_task_t *, isc_event_t *);
624 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
626 static int message_count(dns_message_t *msg, dns_section_t section,
627 dns_rdatatype_t type);
628 static void notify_cancel(dns_zone_t *zone);
629 static void notify_find_address(dns_notify_t *notify);
630 static void notify_send(dns_notify_t *notify);
631 static isc_result_t notify_createmessage(dns_zone_t *zone,
633 dns_message_t **messagep);
634 static void notify_done(isc_task_t *task, isc_event_t *event);
635 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
636 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
637 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
638 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
640 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
641 static void zonemgr_free(dns_zonemgr_t *zmgr);
642 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
643 isc_task_t *task, isc_taskaction_t action,
644 void *arg, dns_io_t **iop);
645 static void zonemgr_putio(dns_io_t **iop);
646 static void zonemgr_cancelio(dns_io_t *io);
649 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
650 unsigned int *soacount, isc_uint32_t *serial,
651 isc_uint32_t *refresh, isc_uint32_t *retry,
652 isc_uint32_t *expire, isc_uint32_t *minimum,
653 unsigned int *errors);
655 static void zone_freedbargs(dns_zone_t *zone);
656 static void forward_callback(isc_task_t *task, isc_event_t *event);
657 static void zone_saveunique(dns_zone_t *zone, const char *path,
658 const char *templat);
659 static void zone_maintenance(dns_zone_t *zone);
660 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
661 static void dump_done(void *arg, isc_result_t result);
662 static isc_boolean_t dns_zonemgr_unreachable(dns_zonemgr_t *zmgr,
663 isc_sockaddr_t *remote,
664 isc_sockaddr_t *local,
666 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
667 isc_uint16_t keyid, isc_boolean_t delete);
668 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
669 dns_dbnode_t *node, dns_name_t *name,
671 static void zone_rekey(dns_zone_t *zone);
672 static isc_boolean_t delsig_ok(dns_rdata_rrsig_t *rrsig_ptr,
673 dst_key_t **keys, unsigned int nkeys);
675 #define ENTER zone_debuglog(zone, me, 1, "enter")
677 static const unsigned int dbargc_default = 1;
678 static const char *dbargv_default[] = { "rbt" };
680 #define DNS_ZONE_JITTER_ADD(a, b, c) \
684 _j = isc_random_jitter((b), (b)/4); \
685 isc_interval_set(&_i, _j, 0); \
686 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
687 dns_zone_log(zone, ISC_LOG_WARNING, \
688 "epoch approaching: upgrade required: " \
689 "now + %s failed", #b); \
690 isc_interval_set(&_i, _j/2, 0); \
691 (void)isc_time_add((a), &_i, (c)); \
695 #define DNS_ZONE_TIME_ADD(a, b, c) \
698 isc_interval_set(&_i, (b), 0); \
699 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
700 dns_zone_log(zone, ISC_LOG_WARNING, \
701 "epoch approaching: upgrade required: " \
702 "now + %s failed", #b); \
703 isc_interval_set(&_i, (b)/2, 0); \
704 (void)isc_time_add((a), &_i, (c)); \
709 * Increment resolver-related statistics counters. Zone must be locked.
712 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
713 if (zone->stats != NULL)
714 isc_stats_increment(zone->stats, counter);
718 *** Public functions.
722 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
727 REQUIRE(zonep != NULL && *zonep == NULL);
728 REQUIRE(mctx != NULL);
731 zone = isc_mem_get(mctx, sizeof(*zone));
733 return (ISC_R_NOMEMORY);
736 isc_mem_attach(mctx, &zone->mctx);
738 result = isc_mutex_init(&zone->lock);
739 if (result != ISC_R_SUCCESS)
742 result = ZONEDB_INITLOCK(&zone->dblock);
743 if (result != ISC_R_SUCCESS)
746 /* XXX MPA check that all elements are initialised */
747 #ifdef DNS_ZONE_CHECKLOCK
748 zone->locked = ISC_FALSE;
752 ISC_LINK_INIT(zone, link);
753 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
754 if (result != ISC_R_SUCCESS)
757 dns_name_init(&zone->origin, NULL);
758 zone->strnamerd = NULL;
759 zone->strname = NULL;
760 zone->strrdclass = NULL;
761 zone->strviewname = NULL;
762 zone->masterfile = NULL;
763 zone->masterformat = dns_masterformat_none;
764 zone->keydirectory = NULL;
765 zone->journalsize = -1;
766 zone->journal = NULL;
767 zone->rdclass = dns_rdataclass_none;
768 zone->type = dns_zone_none;
773 zone->db_argv = NULL;
774 isc_time_settoepoch(&zone->expiretime);
775 isc_time_settoepoch(&zone->refreshtime);
776 isc_time_settoepoch(&zone->dumptime);
777 isc_time_settoepoch(&zone->loadtime);
778 zone->notifytime = now;
779 isc_time_settoepoch(&zone->resigntime);
780 isc_time_settoepoch(&zone->keywarntime);
781 isc_time_settoepoch(&zone->signingtime);
782 isc_time_settoepoch(&zone->nsec3chaintime);
783 isc_time_settoepoch(&zone->refreshkeytime);
784 zone->refreshkeycount = 0;
785 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
786 zone->retry = DNS_ZONE_DEFAULTRETRY;
789 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
790 zone->minrefresh = DNS_ZONE_MINREFRESH;
791 zone->maxretry = DNS_ZONE_MAXRETRY;
792 zone->minretry = DNS_ZONE_MINRETRY;
793 zone->masters = NULL;
794 zone->masterkeynames = NULL;
795 zone->mastersok = NULL;
796 zone->masterscnt = 0;
799 zone->notifytype = dns_notifytype_yes;
802 zone->update_acl = NULL;
803 zone->forward_acl = NULL;
804 zone->notify_acl = NULL;
805 zone->query_acl = NULL;
806 zone->queryon_acl = NULL;
807 zone->xfr_acl = NULL;
808 zone->update_disabled = ISC_FALSE;
809 zone->zero_no_soa_ttl = ISC_TRUE;
810 zone->check_names = dns_severity_ignore;
811 zone->request = NULL;
815 zone->writeio = NULL;
817 zone->idlein = DNS_DEFAULT_IDLEIN;
818 zone->idleout = DNS_DEFAULT_IDLEOUT;
819 zone->log_key_expired_timer = 0;
820 ISC_LIST_INIT(zone->notifies);
821 isc_sockaddr_any(&zone->notifysrc4);
822 isc_sockaddr_any6(&zone->notifysrc6);
823 isc_sockaddr_any(&zone->xfrsource4);
824 isc_sockaddr_any6(&zone->xfrsource6);
825 isc_sockaddr_any(&zone->altxfrsource4);
826 isc_sockaddr_any6(&zone->altxfrsource6);
828 zone->tsigkey = NULL;
829 zone->maxxfrin = MAX_XFER_TIME;
830 zone->maxxfrout = MAX_XFER_TIME;
831 zone->ssutable = NULL;
832 zone->sigvalidityinterval = 30 * 24 * 3600;
833 zone->sigresigninginterval = 7 * 24 * 3600;
836 zone->checkmx = NULL;
837 zone->checksrv = NULL;
838 zone->checkns = NULL;
839 ISC_LINK_INIT(zone, statelink);
840 zone->statelist = NULL;
842 zone->requeststats_on = ISC_FALSE;
843 zone->requeststats = NULL;
844 zone->notifydelay = 5;
846 zone->isselfarg = NULL;
847 ISC_LIST_INIT(zone->signing);
848 ISC_LIST_INIT(zone->nsec3chain);
849 zone->signatures = 10;
851 zone->privatetype = (dns_rdatatype_t)0xffffU;
852 zone->added = ISC_FALSE;
853 zone->rpz_zone = ISC_FALSE;
855 zone->magic = ZONE_MAGIC;
857 /* Must be after magic is set. */
858 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
859 if (result != ISC_R_SUCCESS)
862 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
863 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
866 return (ISC_R_SUCCESS);
869 isc_refcount_decrement(&zone->erefs, NULL);
870 isc_refcount_destroy(&zone->erefs);
873 ZONEDB_DESTROYLOCK(&zone->dblock);
876 DESTROYLOCK(&zone->lock);
879 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
884 * Free a zone. Because we require that there be no more
885 * outstanding events or references, no locking is necessary.
888 zone_free(dns_zone_t *zone) {
889 isc_mem_t *mctx = NULL;
890 dns_signing_t *signing;
891 dns_nsec3chain_t *nsec3chain;
893 REQUIRE(DNS_ZONE_VALID(zone));
894 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
895 REQUIRE(zone->irefs == 0);
896 REQUIRE(!LOCKED_ZONE(zone));
897 REQUIRE(zone->timer == NULL);
900 * Managed objects. Order is important.
902 if (zone->request != NULL)
903 dns_request_destroy(&zone->request); /* XXXMPA */
904 INSIST(zone->readio == NULL);
905 INSIST(zone->statelist == NULL);
906 INSIST(zone->writeio == NULL);
908 if (zone->task != NULL)
909 isc_task_detach(&zone->task);
910 if (zone->zmgr != NULL)
911 dns_zonemgr_releasezone(zone->zmgr, zone);
913 /* Unmanaged objects */
914 for (signing = ISC_LIST_HEAD(zone->signing);
916 signing = ISC_LIST_HEAD(zone->signing)) {
917 ISC_LIST_UNLINK(zone->signing, signing, link);
918 dns_db_detach(&signing->db);
919 dns_dbiterator_destroy(&signing->dbiterator);
920 isc_mem_put(zone->mctx, signing, sizeof *signing);
922 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
924 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
925 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
926 dns_db_detach(&nsec3chain->db);
927 dns_dbiterator_destroy(&nsec3chain->dbiterator);
928 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
930 if (zone->masterfile != NULL)
931 isc_mem_free(zone->mctx, zone->masterfile);
932 zone->masterfile = NULL;
933 if (zone->keydirectory != NULL)
934 isc_mem_free(zone->mctx, zone->keydirectory);
935 zone->keydirectory = NULL;
936 zone->journalsize = -1;
937 if (zone->journal != NULL)
938 isc_mem_free(zone->mctx, zone->journal);
939 zone->journal = NULL;
940 if (zone->stats != NULL)
941 isc_stats_detach(&zone->stats);
942 if (zone->requeststats != NULL)
943 isc_stats_detach(&zone->requeststats);
944 if (zone->db != NULL)
946 if (zone->acache != NULL)
947 dns_acache_detach(&zone->acache);
948 zone_freedbargs(zone);
949 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
951 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
953 zone->check_names = dns_severity_ignore;
954 if (zone->update_acl != NULL)
955 dns_acl_detach(&zone->update_acl);
956 if (zone->forward_acl != NULL)
957 dns_acl_detach(&zone->forward_acl);
958 if (zone->notify_acl != NULL)
959 dns_acl_detach(&zone->notify_acl);
960 if (zone->query_acl != NULL)
961 dns_acl_detach(&zone->query_acl);
962 if (zone->queryon_acl != NULL)
963 dns_acl_detach(&zone->queryon_acl);
964 if (zone->xfr_acl != NULL)
965 dns_acl_detach(&zone->xfr_acl);
966 if (dns_name_dynamic(&zone->origin))
967 dns_name_free(&zone->origin, zone->mctx);
968 if (zone->strnamerd != NULL)
969 isc_mem_free(zone->mctx, zone->strnamerd);
970 if (zone->strname != NULL)
971 isc_mem_free(zone->mctx, zone->strname);
972 if (zone->strrdclass != NULL)
973 isc_mem_free(zone->mctx, zone->strrdclass);
974 if (zone->strviewname != NULL)
975 isc_mem_free(zone->mctx, zone->strviewname);
976 if (zone->ssutable != NULL)
977 dns_ssutable_detach(&zone->ssutable);
980 ZONEDB_DESTROYLOCK(&zone->dblock);
981 DESTROYLOCK(&zone->lock);
982 isc_refcount_destroy(&zone->erefs);
985 isc_mem_put(mctx, zone, sizeof(*zone));
986 isc_mem_detach(&mctx);
993 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
996 REQUIRE(DNS_ZONE_VALID(zone));
997 REQUIRE(rdclass != dns_rdataclass_none);
1003 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1004 zone->rdclass == rdclass);
1005 zone->rdclass = rdclass;
1007 if (zone->strnamerd != NULL)
1008 isc_mem_free(zone->mctx, zone->strnamerd);
1009 if (zone->strrdclass != NULL)
1010 isc_mem_free(zone->mctx, zone->strrdclass);
1012 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1013 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1014 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1015 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1021 dns_zone_getclass(dns_zone_t *zone) {
1022 REQUIRE(DNS_ZONE_VALID(zone));
1024 return (zone->rdclass);
1028 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1029 REQUIRE(DNS_ZONE_VALID(zone));
1032 zone->notifytype = notifytype;
1037 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1038 isc_result_t result;
1040 REQUIRE(DNS_ZONE_VALID(zone));
1041 REQUIRE(serialp != NULL);
1044 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1045 if (zone->db != NULL) {
1046 result = zone_get_from_db(zone, zone->db, NULL, NULL, serialp,
1047 NULL, NULL, NULL, NULL, NULL);
1049 result = DNS_R_NOTLOADED;
1050 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1057 dns_zone_getserial(dns_zone_t *zone) {
1058 isc_result_t result;
1059 isc_uint32_t serial;
1061 result = dns_zone_getserial2(zone, &serial);
1062 if (result != ISC_R_SUCCESS)
1063 serial = 0; /* XXX: not really correct, but no other choice */
1072 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1074 REQUIRE(DNS_ZONE_VALID(zone));
1075 REQUIRE(type != dns_zone_none);
1081 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1087 zone_freedbargs(dns_zone_t *zone) {
1090 /* Free the old database argument list. */
1091 if (zone->db_argv != NULL) {
1092 for (i = 0; i < zone->db_argc; i++)
1093 isc_mem_free(zone->mctx, zone->db_argv[i]);
1094 isc_mem_put(zone->mctx, zone->db_argv,
1095 zone->db_argc * sizeof(*zone->db_argv));
1098 zone->db_argv = NULL;
1102 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1105 isc_result_t result = ISC_R_SUCCESS;
1109 REQUIRE(DNS_ZONE_VALID(zone));
1110 REQUIRE(argv != NULL && *argv == NULL);
1113 size = (zone->db_argc + 1) * sizeof(char *);
1114 for (i = 0; i < zone->db_argc; i++)
1115 size += strlen(zone->db_argv[i]) + 1;
1116 mem = isc_mem_allocate(mctx, size);
1120 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1121 for (i = 0; i < zone->db_argc; i++) {
1123 strcpy(tmp2, zone->db_argv[i]);
1124 tmp2 += strlen(tmp2) + 1;
1128 result = ISC_R_NOMEMORY;
1135 dns_zone_setdbtype(dns_zone_t *zone,
1136 unsigned int dbargc, const char * const *dbargv) {
1137 isc_result_t result = ISC_R_SUCCESS;
1141 REQUIRE(DNS_ZONE_VALID(zone));
1142 REQUIRE(dbargc >= 1);
1143 REQUIRE(dbargv != NULL);
1147 /* Set up a new database argument list. */
1148 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1151 for (i = 0; i < dbargc; i++)
1153 for (i = 0; i < dbargc; i++) {
1154 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1159 /* Free the old list. */
1160 zone_freedbargs(zone);
1162 zone->db_argc = dbargc;
1163 zone->db_argv = new;
1164 result = ISC_R_SUCCESS;
1169 for (i = 0; i < dbargc; i++)
1171 isc_mem_free(zone->mctx, new[i]);
1172 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1174 result = ISC_R_NOMEMORY;
1182 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1184 REQUIRE(DNS_ZONE_VALID(zone));
1187 if (zone->view != NULL)
1188 dns_view_weakdetach(&zone->view);
1189 dns_view_weakattach(view, &zone->view);
1191 if (zone->strviewname != NULL)
1192 isc_mem_free(zone->mctx, zone->strviewname);
1193 if (zone->strnamerd != NULL)
1194 isc_mem_free(zone->mctx, zone->strnamerd);
1196 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1197 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1198 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1199 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1206 dns_zone_getview(dns_zone_t *zone) {
1207 REQUIRE(DNS_ZONE_VALID(zone));
1209 return (zone->view);
1214 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1215 isc_result_t result;
1218 REQUIRE(DNS_ZONE_VALID(zone));
1219 REQUIRE(origin != NULL);
1222 if (dns_name_dynamic(&zone->origin)) {
1223 dns_name_free(&zone->origin, zone->mctx);
1224 dns_name_init(&zone->origin, NULL);
1226 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1228 if (zone->strnamerd != NULL)
1229 isc_mem_free(zone->mctx, zone->strnamerd);
1230 if (zone->strname != NULL)
1231 isc_mem_free(zone->mctx, zone->strname);
1233 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1234 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1235 zone_name_tostr(zone, namebuf, sizeof namebuf);
1236 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1243 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1244 REQUIRE(DNS_ZONE_VALID(zone));
1245 REQUIRE(acache != NULL);
1248 if (zone->acache != NULL)
1249 dns_acache_detach(&zone->acache);
1250 dns_acache_attach(acache, &zone->acache);
1251 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1252 if (zone->db != NULL) {
1253 isc_result_t result;
1256 * If the zone reuses an existing DB, the DB needs to be
1257 * set in the acache explicitly. We can safely ignore the
1258 * case where the DB is already set. If other error happens,
1259 * the acache will not work effectively.
1261 result = dns_acache_setdb(acache, zone->db);
1262 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1263 UNEXPECTED_ERROR(__FILE__, __LINE__,
1264 "dns_acache_setdb() failed: %s",
1265 isc_result_totext(result));
1268 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1273 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1276 if (value != NULL) {
1277 copy = isc_mem_strdup(zone->mctx, value);
1279 return (ISC_R_NOMEMORY);
1285 isc_mem_free(zone->mctx, *field);
1288 return (ISC_R_SUCCESS);
1292 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1293 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1297 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1298 dns_masterformat_t format) {
1299 isc_result_t result = ISC_R_SUCCESS;
1301 REQUIRE(DNS_ZONE_VALID(zone));
1304 result = dns_zone_setstring(zone, &zone->masterfile, file);
1305 if (result == ISC_R_SUCCESS) {
1306 zone->masterformat = format;
1307 result = default_journal(zone);
1315 dns_zone_getfile(dns_zone_t *zone) {
1316 REQUIRE(DNS_ZONE_VALID(zone));
1318 return (zone->masterfile);
1322 default_journal(dns_zone_t *zone) {
1323 isc_result_t result;
1326 REQUIRE(DNS_ZONE_VALID(zone));
1327 REQUIRE(LOCKED_ZONE(zone));
1329 if (zone->masterfile != NULL) {
1330 /* Calculate string length including '\0'. */
1331 int len = strlen(zone->masterfile) + sizeof(".jnl");
1332 journal = isc_mem_allocate(zone->mctx, len);
1333 if (journal == NULL)
1334 return (ISC_R_NOMEMORY);
1335 strcpy(journal, zone->masterfile);
1336 strcat(journal, ".jnl");
1340 result = dns_zone_setstring(zone, &zone->journal, journal);
1341 if (journal != NULL)
1342 isc_mem_free(zone->mctx, journal);
1347 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1348 isc_result_t result = ISC_R_SUCCESS;
1350 REQUIRE(DNS_ZONE_VALID(zone));
1353 result = dns_zone_setstring(zone, &zone->journal, journal);
1360 dns_zone_getjournal(dns_zone_t *zone) {
1361 REQUIRE(DNS_ZONE_VALID(zone));
1363 return (zone->journal);
1367 * Return true iff the zone is "dynamic", in the sense that the zone's
1368 * master file (if any) is written by the server, rather than being
1369 * updated manually and read by the server.
1371 * This is true for slave zones, stub zones, key zones, and zones that
1372 * allow dynamic updates either by having an update policy ("ssutable")
1373 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1375 static isc_boolean_t
1376 zone_isdynamic(dns_zone_t *zone) {
1377 REQUIRE(DNS_ZONE_VALID(zone));
1379 return (ISC_TF(zone->type == dns_zone_slave ||
1380 zone->type == dns_zone_stub ||
1381 zone->type == dns_zone_key ||
1382 (!zone->update_disabled && zone->ssutable != NULL) ||
1383 (!zone->update_disabled && zone->update_acl != NULL &&
1384 !dns_acl_isnone(zone->update_acl))));
1389 zone_load(dns_zone_t *zone, unsigned int flags) {
1390 isc_result_t result;
1392 isc_time_t loadtime, filetime;
1393 dns_db_t *db = NULL;
1396 REQUIRE(DNS_ZONE_VALID(zone));
1401 INSIST(zone->type != dns_zone_none);
1403 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1404 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1405 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1406 result = DNS_R_CONTINUE;
1411 INSIST(zone->db_argc >= 1);
1413 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1414 strcmp(zone->db_argv[0], "rbt64") == 0;
1416 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1418 * The zone has no master file configured.
1420 result = ISC_R_SUCCESS;
1424 if (zone->db != NULL && zone_isdynamic(zone)) {
1426 * This is a slave, stub, or dynamically updated
1427 * zone being reloaded. Do nothing - the database
1428 * we already have is guaranteed to be up-to-date.
1430 if (zone->type == dns_zone_master)
1431 result = DNS_R_DYNAMIC;
1433 result = ISC_R_SUCCESS;
1438 * Store the current time before the zone is loaded, so that if the
1439 * file changes between the time of the load and the time that
1440 * zone->loadtime is set, then the file will still be reloaded
1441 * the next time dns_zone_load is called.
1443 TIME_NOW(&loadtime);
1446 * Don't do the load if the file that stores the zone is older
1447 * than the last time the zone was loaded. If the zone has not
1448 * been loaded yet, zone->loadtime will be the epoch.
1450 if (zone->masterfile != NULL) {
1452 * The file is already loaded. If we are just doing a
1453 * "rndc reconfig", we are done.
1455 if (!isc_time_isepoch(&zone->loadtime) &&
1456 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0 &&
1457 zone->rpz_zone == dns_rpz_needed()) {
1458 result = ISC_R_SUCCESS;
1462 result = isc_file_getmodtime(zone->masterfile, &filetime);
1463 if (result == ISC_R_SUCCESS) {
1464 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1465 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1466 isc_time_compare(&filetime, &zone->loadtime) <= 0 &&
1467 zone->rpz_zone == dns_rpz_needed()) {
1468 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1469 "skipping load: master file "
1470 "older than last load");
1471 result = DNS_R_UPTODATE;
1474 loadtime = filetime;
1475 zone->rpz_zone = dns_rpz_needed();
1480 * Built in zones (with the exception of empty zones) don't need
1483 if (zone->type == dns_zone_master &&
1484 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1485 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1486 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1487 result = ISC_R_SUCCESS;
1491 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1493 if (zone->masterfile == NULL ||
1494 !isc_file_exists(zone->masterfile)) {
1495 if (zone->masterfile != NULL) {
1496 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1499 zone->refreshtime = now;
1500 if (zone->task != NULL)
1501 zone_settimer(zone, &now);
1502 result = ISC_R_SUCCESS;
1507 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1509 result = dns_db_create(zone->mctx, zone->db_argv[0],
1510 &zone->origin, (zone->type == dns_zone_stub) ?
1511 dns_dbtype_stub : dns_dbtype_zone,
1513 zone->db_argc - 1, zone->db_argv + 1,
1516 if (result != ISC_R_SUCCESS) {
1517 dns_zone_log(zone, ISC_LOG_ERROR,
1518 "loading zone: creating database: %s",
1519 isc_result_totext(result));
1522 dns_db_settask(db, zone->task);
1524 if (! dns_db_ispersistent(db)) {
1525 if (zone->masterfile != NULL) {
1526 result = zone_startload(db, zone, loadtime);
1528 result = DNS_R_NOMASTERFILE;
1529 if (zone->type == dns_zone_master) {
1530 dns_zone_log(zone, ISC_LOG_ERROR,
1532 "no master file configured");
1535 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1536 "no master file configured: continuing");
1540 if (result == DNS_R_CONTINUE) {
1541 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1542 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1543 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1547 result = zone_postload(zone, db, loadtime, result);
1557 dns_zone_load(dns_zone_t *zone) {
1558 return (zone_load(zone, 0));
1562 dns_zone_loadnew(dns_zone_t *zone) {
1563 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1567 dns_zone_loadandthaw(dns_zone_t *zone) {
1568 isc_result_t result;
1570 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1572 case DNS_R_CONTINUE:
1573 /* Deferred thaw. */
1576 case DNS_R_UPTODATE:
1577 case DNS_R_SEENINCLUDE:
1578 zone->update_disabled = ISC_FALSE;
1580 case DNS_R_NOMASTERFILE:
1581 zone->update_disabled = ISC_FALSE;
1584 /* Error, remain in disabled state. */
1591 get_master_options(dns_zone_t *zone) {
1592 unsigned int options;
1594 options = DNS_MASTER_ZONE;
1595 if (zone->type == dns_zone_slave)
1596 options |= DNS_MASTER_SLAVE;
1597 if (zone->type == dns_zone_key)
1598 options |= DNS_MASTER_KEY;
1599 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1600 options |= DNS_MASTER_CHECKNS;
1601 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1602 options |= DNS_MASTER_FATALNS;
1603 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1604 options |= DNS_MASTER_CHECKNAMES;
1605 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1606 options |= DNS_MASTER_CHECKNAMESFAIL;
1607 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1608 options |= DNS_MASTER_CHECKMX;
1609 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1610 options |= DNS_MASTER_CHECKMXFAIL;
1611 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1612 options |= DNS_MASTER_CHECKWILDCARD;
1613 if (zone->type == dns_zone_master &&
1614 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1615 zone->ssutable != NULL))
1616 options |= DNS_MASTER_RESIGN;
1621 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1622 dns_load_t *load = event->ev_arg;
1623 isc_result_t result = ISC_R_SUCCESS;
1624 unsigned int options;
1626 REQUIRE(DNS_LOAD_VALID(load));
1628 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1629 result = ISC_R_CANCELED;
1630 isc_event_free(&event);
1631 if (result == ISC_R_CANCELED)
1634 options = get_master_options(load->zone);
1636 result = dns_master_loadfileinc3(load->zone->masterfile,
1637 dns_db_origin(load->db),
1638 dns_db_origin(load->db),
1639 load->zone->rdclass,
1641 load->zone->sigresigninginterval,
1642 &load->callbacks, task,
1643 zone_loaddone, load,
1644 &load->zone->lctx, load->zone->mctx,
1645 load->zone->masterformat);
1646 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1647 result != DNS_R_SEENINCLUDE)
1652 zone_loaddone(load, result);
1656 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1657 const char me[] = "zone_gotwritehandle";
1658 dns_zone_t *zone = event->ev_arg;
1659 isc_result_t result = ISC_R_SUCCESS;
1660 dns_dbversion_t *version = NULL;
1662 REQUIRE(DNS_ZONE_VALID(zone));
1663 INSIST(task == zone->task);
1666 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1667 result = ISC_R_CANCELED;
1668 isc_event_free(&event);
1669 if (result == ISC_R_CANCELED)
1673 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1674 dns_db_currentversion(zone->db, &version);
1675 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1676 &dns_master_style_default,
1677 zone->masterfile, zone->task, dump_done,
1678 zone, &zone->dctx, zone->masterformat);
1679 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1680 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1682 if (result != DNS_R_CONTINUE)
1687 dump_done(zone, result);
1691 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1693 isc_result_t result;
1694 isc_result_t tresult;
1695 unsigned int options;
1697 options = get_master_options(zone);
1699 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1700 options |= DNS_MASTER_MANYERRORS;
1702 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1703 load = isc_mem_get(zone->mctx, sizeof(*load));
1705 return (ISC_R_NOMEMORY);
1710 load->loadtime = loadtime;
1711 load->magic = LOAD_MAGIC;
1713 isc_mem_attach(zone->mctx, &load->mctx);
1714 zone_iattach(zone, &load->zone);
1715 dns_db_attach(db, &load->db);
1716 dns_rdatacallbacks_init(&load->callbacks);
1717 result = dns_db_beginload(db, &load->callbacks.add,
1718 &load->callbacks.add_private);
1719 if (result != ISC_R_SUCCESS)
1721 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1722 zone_gotreadhandle, load,
1724 if (result != ISC_R_SUCCESS) {
1726 * We can't report multiple errors so ignore
1727 * the result of dns_db_endload().
1729 (void)dns_db_endload(load->db,
1730 &load->callbacks.add_private);
1733 result = DNS_R_CONTINUE;
1735 dns_rdatacallbacks_t callbacks;
1737 dns_rdatacallbacks_init(&callbacks);
1738 result = dns_db_beginload(db, &callbacks.add,
1739 &callbacks.add_private);
1740 if (result != ISC_R_SUCCESS)
1742 result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1743 &zone->origin, zone->rdclass,
1744 options, zone->sigresigninginterval,
1745 &callbacks, zone->mctx,
1746 zone->masterformat);
1747 tresult = dns_db_endload(db, &callbacks.add_private);
1748 if (result == ISC_R_SUCCESS)
1756 dns_db_detach(&load->db);
1757 zone_idetach(&load->zone);
1758 isc_mem_detach(&load->mctx);
1759 isc_mem_put(zone->mctx, load, sizeof(*load));
1763 static isc_boolean_t
1764 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1767 isc_result_t result;
1768 char ownerbuf[DNS_NAME_FORMATSIZE];
1769 char namebuf[DNS_NAME_FORMATSIZE];
1770 char altbuf[DNS_NAME_FORMATSIZE];
1771 dns_fixedname_t fixed;
1772 dns_name_t *foundname;
1776 * "." means the services does not exist.
1778 if (dns_name_equal(name, dns_rootname))
1784 if (!dns_name_issubdomain(name, &zone->origin)) {
1785 if (zone->checkmx != NULL)
1786 return ((zone->checkmx)(zone, name, owner));
1790 if (zone->type == dns_zone_master)
1791 level = ISC_LOG_ERROR;
1793 level = ISC_LOG_WARNING;
1795 dns_fixedname_init(&fixed);
1796 foundname = dns_fixedname_name(&fixed);
1798 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1799 0, 0, NULL, foundname, NULL, NULL);
1800 if (result == ISC_R_SUCCESS)
1803 if (result == DNS_R_NXRRSET) {
1804 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1805 0, 0, NULL, foundname, NULL, NULL);
1806 if (result == ISC_R_SUCCESS)
1810 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1811 dns_name_format(name, namebuf, sizeof namebuf);
1812 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1813 result == DNS_R_EMPTYNAME) {
1814 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1815 level = ISC_LOG_WARNING;
1816 dns_zone_log(zone, level,
1817 "%s/MX '%s' has no address records (A or AAAA)",
1819 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1822 if (result == DNS_R_CNAME) {
1823 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1824 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1825 level = ISC_LOG_WARNING;
1826 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1827 dns_zone_log(zone, level,
1828 "%s/MX '%s' is a CNAME (illegal)",
1830 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1833 if (result == DNS_R_DNAME) {
1834 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1835 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1836 level = ISC_LOG_WARNING;
1837 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1838 dns_name_format(foundname, altbuf, sizeof altbuf);
1839 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1840 " '%s' (illegal)", ownerbuf, namebuf,
1843 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1846 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1847 return ((zone->checkmx)(zone, name, owner));
1852 static isc_boolean_t
1853 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1856 isc_result_t result;
1857 char ownerbuf[DNS_NAME_FORMATSIZE];
1858 char namebuf[DNS_NAME_FORMATSIZE];
1859 char altbuf[DNS_NAME_FORMATSIZE];
1860 dns_fixedname_t fixed;
1861 dns_name_t *foundname;
1865 * "." means the services does not exist.
1867 if (dns_name_equal(name, dns_rootname))
1873 if (!dns_name_issubdomain(name, &zone->origin)) {
1874 if (zone->checksrv != NULL)
1875 return ((zone->checksrv)(zone, name, owner));
1879 if (zone->type == dns_zone_master)
1880 level = ISC_LOG_ERROR;
1882 level = ISC_LOG_WARNING;
1884 dns_fixedname_init(&fixed);
1885 foundname = dns_fixedname_name(&fixed);
1887 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1888 0, 0, NULL, foundname, NULL, NULL);
1889 if (result == ISC_R_SUCCESS)
1892 if (result == DNS_R_NXRRSET) {
1893 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1894 0, 0, NULL, foundname, NULL, NULL);
1895 if (result == ISC_R_SUCCESS)
1899 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1900 dns_name_format(name, namebuf, sizeof namebuf);
1901 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1902 result == DNS_R_EMPTYNAME) {
1903 dns_zone_log(zone, level,
1904 "%s/SRV '%s' has no address records (A or AAAA)",
1906 /* XXX950 make fatal for 9.5.0. */
1910 if (result == DNS_R_CNAME) {
1911 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1912 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1913 level = ISC_LOG_WARNING;
1914 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1915 dns_zone_log(zone, level,
1916 "%s/SRV '%s' is a CNAME (illegal)",
1918 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1921 if (result == DNS_R_DNAME) {
1922 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1923 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1924 level = ISC_LOG_WARNING;
1925 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1926 dns_name_format(foundname, altbuf, sizeof altbuf);
1927 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1928 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1931 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1934 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1935 return ((zone->checksrv)(zone, name, owner));
1940 static isc_boolean_t
1941 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1944 isc_boolean_t answer = ISC_TRUE;
1945 isc_result_t result, tresult;
1946 char ownerbuf[DNS_NAME_FORMATSIZE];
1947 char namebuf[DNS_NAME_FORMATSIZE];
1948 char altbuf[DNS_NAME_FORMATSIZE];
1949 dns_fixedname_t fixed;
1950 dns_name_t *foundname;
1952 dns_rdataset_t aaaa;
1958 if (!dns_name_issubdomain(name, &zone->origin)) {
1959 if (zone->checkns != NULL)
1960 return ((zone->checkns)(zone, name, owner, NULL, NULL));
1964 if (zone->type == dns_zone_master)
1965 level = ISC_LOG_ERROR;
1967 level = ISC_LOG_WARNING;
1969 dns_fixedname_init(&fixed);
1970 foundname = dns_fixedname_name(&fixed);
1971 dns_rdataset_init(&a);
1972 dns_rdataset_init(&aaaa);
1974 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1975 DNS_DBFIND_GLUEOK, 0, NULL,
1976 foundname, &a, NULL);
1978 if (result == ISC_R_SUCCESS) {
1979 dns_rdataset_disassociate(&a);
1981 } else if (result == DNS_R_DELEGATION)
1982 dns_rdataset_disassociate(&a);
1984 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
1985 result == DNS_R_GLUE) {
1986 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1987 DNS_DBFIND_GLUEOK, 0, NULL,
1988 foundname, &aaaa, NULL);
1989 if (tresult == ISC_R_SUCCESS) {
1990 dns_rdataset_disassociate(&aaaa);
1993 if (tresult == DNS_R_DELEGATION)
1994 dns_rdataset_disassociate(&aaaa);
1995 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
1997 * Check glue against child zone.
1999 if (zone->checkns != NULL)
2000 answer = (zone->checkns)(zone, name, owner,
2002 if (dns_rdataset_isassociated(&a))
2003 dns_rdataset_disassociate(&a);
2004 if (dns_rdataset_isassociated(&aaaa))
2005 dns_rdataset_disassociate(&aaaa);
2010 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2011 dns_name_format(name, namebuf, sizeof namebuf);
2012 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2013 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2015 isc_boolean_t required = ISC_FALSE;
2016 if (dns_name_issubdomain(name, owner)) {
2017 what = "REQUIRED GLUE ";
2018 required = ISC_TRUE;
2019 } else if (result == DNS_R_DELEGATION)
2020 what = "SIBLING GLUE ";
2024 if (result != DNS_R_DELEGATION || required ||
2025 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2026 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2027 "address records (A or AAAA)",
2028 ownerbuf, namebuf, what);
2030 * Log missing address record.
2032 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2033 (void)(zone->checkns)(zone, name, owner,
2035 /* XXX950 make fatal for 9.5.0. */
2036 /* answer = ISC_FALSE; */
2038 } else if (result == DNS_R_CNAME) {
2039 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2041 /* XXX950 make fatal for 9.5.0. */
2042 /* answer = ISC_FALSE; */
2043 } else if (result == DNS_R_DNAME) {
2044 dns_name_format(foundname, altbuf, sizeof altbuf);
2045 dns_zone_log(zone, level,
2046 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2047 ownerbuf, namebuf, altbuf);
2048 /* XXX950 make fatal for 9.5.0. */
2049 /* answer = ISC_FALSE; */
2052 if (dns_rdataset_isassociated(&a))
2053 dns_rdataset_disassociate(&a);
2054 if (dns_rdataset_isassociated(&aaaa))
2055 dns_rdataset_disassociate(&aaaa);
2059 static isc_boolean_t
2060 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2061 dns_rdataset_t *rdataset)
2063 dns_rdataset_t tmprdataset;
2064 isc_result_t result;
2065 isc_boolean_t answer = ISC_TRUE;
2066 isc_boolean_t format = ISC_TRUE;
2067 int level = ISC_LOG_WARNING;
2068 char ownerbuf[DNS_NAME_FORMATSIZE];
2069 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2070 unsigned int count1 = 0;
2072 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2073 level = ISC_LOG_ERROR;
2075 dns_rdataset_init(&tmprdataset);
2076 for (result = dns_rdataset_first(rdataset);
2077 result == ISC_R_SUCCESS;
2078 result = dns_rdataset_next(rdataset)) {
2079 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2080 unsigned int count2 = 0;
2083 dns_rdataset_current(rdataset, &rdata1);
2084 dns_rdataset_clone(rdataset, &tmprdataset);
2085 for (result = dns_rdataset_first(&tmprdataset);
2086 result == ISC_R_SUCCESS;
2087 result = dns_rdataset_next(&tmprdataset)) {
2088 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2090 if (count1 >= count2)
2092 dns_rdataset_current(&tmprdataset, &rdata2);
2093 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2095 dns_name_format(owner, ownerbuf,
2097 dns_rdatatype_format(rdata1.type,
2102 dns_zone_log(zone, level, "%s/%s has "
2103 "semantically identical records",
2105 if (level == ISC_LOG_ERROR)
2110 dns_rdataset_disassociate(&tmprdataset);
2117 static isc_boolean_t
2118 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2119 dns_dbiterator_t *dbiterator = NULL;
2120 dns_dbnode_t *node = NULL;
2121 dns_fixedname_t fixed;
2123 dns_rdataset_t rdataset;
2124 dns_rdatasetiter_t *rdsit = NULL;
2125 isc_boolean_t ok = ISC_TRUE;
2126 isc_result_t result;
2128 dns_fixedname_init(&fixed);
2129 name = dns_fixedname_name(&fixed);
2130 dns_rdataset_init(&rdataset);
2132 result = dns_db_createiterator(db, 0, &dbiterator);
2133 if (result != ISC_R_SUCCESS)
2136 for (result = dns_dbiterator_first(dbiterator);
2137 result == ISC_R_SUCCESS;
2138 result = dns_dbiterator_next(dbiterator)) {
2139 result = dns_dbiterator_current(dbiterator, &node, name);
2140 if (result != ISC_R_SUCCESS)
2143 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2144 if (result != ISC_R_SUCCESS)
2147 for (result = dns_rdatasetiter_first(rdsit);
2148 result == ISC_R_SUCCESS;
2149 result = dns_rdatasetiter_next(rdsit)) {
2150 dns_rdatasetiter_current(rdsit, &rdataset);
2151 if (!zone_rrset_check_dup(zone, name, &rdataset))
2153 dns_rdataset_disassociate(&rdataset);
2155 dns_rdatasetiter_destroy(&rdsit);
2156 dns_db_detachnode(db, &node);
2160 dns_db_detachnode(db, &node);
2161 dns_dbiterator_destroy(&dbiterator);
2166 static isc_boolean_t
2167 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2168 dns_dbiterator_t *dbiterator = NULL;
2169 dns_dbnode_t *node = NULL;
2170 dns_rdataset_t rdataset;
2171 dns_fixedname_t fixed;
2172 dns_fixedname_t fixedbottom;
2175 dns_rdata_in_srv_t srv;
2179 isc_result_t result;
2180 isc_boolean_t ok = ISC_TRUE;
2182 dns_fixedname_init(&fixed);
2183 name = dns_fixedname_name(&fixed);
2184 dns_fixedname_init(&fixedbottom);
2185 bottom = dns_fixedname_name(&fixedbottom);
2186 dns_rdataset_init(&rdataset);
2187 dns_rdata_init(&rdata);
2189 result = dns_db_createiterator(db, 0, &dbiterator);
2190 if (result != ISC_R_SUCCESS)
2193 result = dns_dbiterator_first(dbiterator);
2194 while (result == ISC_R_SUCCESS) {
2195 result = dns_dbiterator_current(dbiterator, &node, name);
2196 if (result != ISC_R_SUCCESS)
2200 * Is this name visible in the zone?
2202 if (!dns_name_issubdomain(name, &zone->origin) ||
2203 (dns_name_countlabels(bottom) > 0 &&
2204 dns_name_issubdomain(name, bottom)))
2208 * Don't check the NS records at the origin.
2210 if (dns_name_equal(name, &zone->origin))
2213 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2214 0, 0, &rdataset, NULL);
2215 if (result != ISC_R_SUCCESS)
2218 * Remember bottom of zone.
2220 dns_name_copy(name, bottom, NULL);
2222 result = dns_rdataset_first(&rdataset);
2223 while (result == ISC_R_SUCCESS) {
2224 dns_rdataset_current(&rdataset, &rdata);
2225 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2226 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2227 if (!zone_check_glue(zone, db, &ns.name, name))
2229 dns_rdata_reset(&rdata);
2230 result = dns_rdataset_next(&rdataset);
2232 dns_rdataset_disassociate(&rdataset);
2236 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2237 0, 0, &rdataset, NULL);
2238 if (result != ISC_R_SUCCESS)
2240 result = dns_rdataset_first(&rdataset);
2241 while (result == ISC_R_SUCCESS) {
2242 dns_rdataset_current(&rdataset, &rdata);
2243 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2244 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2245 if (!zone_check_mx(zone, db, &mx.mx, name))
2247 dns_rdata_reset(&rdata);
2248 result = dns_rdataset_next(&rdataset);
2250 dns_rdataset_disassociate(&rdataset);
2253 if (zone->rdclass != dns_rdataclass_in)
2255 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2256 0, 0, &rdataset, NULL);
2257 if (result != ISC_R_SUCCESS)
2259 result = dns_rdataset_first(&rdataset);
2260 while (result == ISC_R_SUCCESS) {
2261 dns_rdataset_current(&rdataset, &rdata);
2262 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2263 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2264 if (!zone_check_srv(zone, db, &srv.target, name))
2266 dns_rdata_reset(&rdata);
2267 result = dns_rdataset_next(&rdataset);
2269 dns_rdataset_disassociate(&rdataset);
2272 dns_db_detachnode(db, &node);
2273 result = dns_dbiterator_next(dbiterator);
2278 dns_db_detachnode(db, &node);
2279 dns_dbiterator_destroy(&dbiterator);
2285 * OpenSSL verification of RSA keys with exponent 3 is known to be
2286 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2287 * if they are in use.
2290 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2291 dns_dbnode_t *node = NULL;
2292 dns_dbversion_t *version = NULL;
2293 dns_rdata_dnskey_t dnskey;
2294 dns_rdata_t rdata = DNS_RDATA_INIT;
2295 dns_rdataset_t rdataset;
2296 isc_result_t result;
2297 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2298 const char *algorithm;
2300 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2301 if (result != ISC_R_SUCCESS)
2304 dns_db_currentversion(db, &version);
2305 dns_rdataset_init(&rdataset);
2306 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2307 dns_rdatatype_none, 0, &rdataset, NULL);
2308 if (result != ISC_R_SUCCESS)
2311 for (result = dns_rdataset_first(&rdataset);
2312 result == ISC_R_SUCCESS;
2313 result = dns_rdataset_next(&rdataset))
2315 dns_rdataset_current(&rdataset, &rdata);
2316 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2317 INSIST(result == ISC_R_SUCCESS);
2319 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2320 dnskey.algorithm == DST_ALG_RSAMD5) &&
2321 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2322 dnskey.data[1] == 3)
2324 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2326 foundrsa = ISC_TRUE;
2327 algorithm = "RSASHA1";
2330 foundmd5 = ISC_TRUE;
2331 algorithm = "RSAMD5";
2334 dns_zone_log(zone, ISC_LOG_WARNING,
2335 "weak %s (%u) key found "
2336 "(exponent=3)", algorithm,
2338 if (foundrsa && foundmd5)
2341 dns_rdata_reset(&rdata);
2343 dns_rdataset_disassociate(&rdataset);
2347 dns_db_detachnode(db, &node);
2348 if (version != NULL)
2349 dns_db_closeversion(db, &version, ISC_FALSE);
2353 resume_signingwithkey(dns_zone_t *zone) {
2354 dns_dbnode_t *node = NULL;
2355 dns_dbversion_t *version = NULL;
2356 dns_rdata_t rdata = DNS_RDATA_INIT;
2357 dns_rdataset_t rdataset;
2358 isc_result_t result;
2360 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2361 if (result != ISC_R_SUCCESS)
2364 dns_db_currentversion(zone->db, &version);
2365 dns_rdataset_init(&rdataset);
2366 result = dns_db_findrdataset(zone->db, node, version,
2368 dns_rdatatype_none, 0,
2370 if (result != ISC_R_SUCCESS) {
2371 INSIST(!dns_rdataset_isassociated(&rdataset));
2375 for (result = dns_rdataset_first(&rdataset);
2376 result == ISC_R_SUCCESS;
2377 result = dns_rdataset_next(&rdataset))
2379 dns_rdataset_current(&rdataset, &rdata);
2380 if (rdata.length != 5 ||
2381 rdata.data[0] == 0 || rdata.data[4] != 0) {
2382 dns_rdata_reset(&rdata);
2386 result = zone_signwithkey(zone, rdata.data[0],
2387 (rdata.data[1] << 8) | rdata.data[2],
2388 ISC_TF(rdata.data[3]));
2389 if (result != ISC_R_SUCCESS) {
2390 dns_zone_log(zone, ISC_LOG_ERROR,
2391 "zone_signwithkey failed: %s",
2392 dns_result_totext(result));
2394 dns_rdata_reset(&rdata);
2396 dns_rdataset_disassociate(&rdataset);
2400 dns_db_detachnode(zone->db, &node);
2401 if (version != NULL)
2402 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2406 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2407 dns_nsec3chain_t *nsec3chain, *current;
2408 isc_result_t result;
2410 unsigned int options = 0;
2411 char saltbuf[255*2+1];
2412 char flags[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")];
2415 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2416 if (nsec3chain == NULL)
2417 return (ISC_R_NOMEMORY);
2419 nsec3chain->magic = 0;
2420 nsec3chain->done = ISC_FALSE;
2421 nsec3chain->db = NULL;
2422 nsec3chain->dbiterator = NULL;
2423 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2424 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2425 nsec3chain->nsec3param.hash = nsec3param->hash;
2426 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2427 nsec3chain->nsec3param.flags = nsec3param->flags;
2428 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2429 memcpy(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2430 nsec3chain->nsec3param.salt = nsec3chain->salt;
2431 nsec3chain->seen_nsec = ISC_FALSE;
2432 nsec3chain->delete_nsec = ISC_FALSE;
2433 nsec3chain->save_delete_nsec = ISC_FALSE;
2435 if (nsec3param->flags == 0)
2436 strlcpy(flags, "NONE", sizeof(flags));
2439 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
2440 strlcat(flags, "REMOVE", sizeof(flags));
2441 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
2442 if (flags[0] == '\0')
2443 strlcpy(flags, "CREATE", sizeof(flags));
2445 strlcat(flags, "|CREATE", sizeof(flags));
2447 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
2448 if (flags[0] == '\0')
2449 strlcpy(flags, "NONSEC", sizeof(flags));
2451 strlcat(flags, "|NONSEC", sizeof(flags));
2453 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
2454 if (flags[0] == '\0')
2455 strlcpy(flags, "OPTOUT", sizeof(flags));
2457 strlcat(flags, "|OPTOUT", sizeof(flags));
2460 if (nsec3param->salt_length == 0)
2461 strlcpy(saltbuf, "-", sizeof(saltbuf));
2463 for (i = 0; i < nsec3param->salt_length; i++)
2464 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
2465 dns_zone_log(zone, ISC_LOG_INFO,
2466 "zone_addnsec3chain(%u,%s,%u,%s)",
2467 nsec3param->hash, flags, nsec3param->iterations,
2469 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2471 current = ISC_LIST_NEXT(current, link)) {
2472 if (current->db == zone->db &&
2473 current->nsec3param.hash == nsec3param->hash &&
2474 current->nsec3param.iterations == nsec3param->iterations &&
2475 current->nsec3param.salt_length == nsec3param->salt_length
2476 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2477 nsec3param->salt_length))
2478 current->done = ISC_TRUE;
2481 if (zone->db != NULL) {
2482 dns_db_attach(zone->db, &nsec3chain->db);
2483 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2484 options = DNS_DB_NONSEC3;
2485 result = dns_db_createiterator(nsec3chain->db, options,
2486 &nsec3chain->dbiterator);
2487 if (result == ISC_R_SUCCESS)
2488 dns_dbiterator_first(nsec3chain->dbiterator);
2489 if (result == ISC_R_SUCCESS) {
2490 dns_dbiterator_pause(nsec3chain->dbiterator);
2491 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2494 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2496 zone->nsec3chaintime = now;
2497 if (zone->task != NULL)
2498 zone_settimer(zone, &now);
2502 result = ISC_R_NOTFOUND;
2504 if (nsec3chain != NULL) {
2505 if (nsec3chain->db != NULL)
2506 dns_db_detach(&nsec3chain->db);
2507 if (nsec3chain->dbiterator != NULL)
2508 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2509 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2515 resume_addnsec3chain(dns_zone_t *zone) {
2516 dns_dbnode_t *node = NULL;
2517 dns_dbversion_t *version = NULL;
2518 dns_rdataset_t rdataset;
2519 isc_result_t result;
2520 dns_rdata_nsec3param_t nsec3param;
2522 if (zone->privatetype == 0)
2525 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2526 if (result != ISC_R_SUCCESS)
2529 dns_db_currentversion(zone->db, &version);
2530 dns_rdataset_init(&rdataset);
2531 result = dns_db_findrdataset(zone->db, node, version,
2532 zone->privatetype, dns_rdatatype_none,
2533 0, &rdataset, NULL);
2534 if (result != ISC_R_SUCCESS) {
2535 INSIST(!dns_rdataset_isassociated(&rdataset));
2539 for (result = dns_rdataset_first(&rdataset);
2540 result == ISC_R_SUCCESS;
2541 result = dns_rdataset_next(&rdataset))
2543 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
2544 dns_rdata_t rdata = DNS_RDATA_INIT;
2545 dns_rdata_t private = DNS_RDATA_INIT;
2547 dns_rdataset_current(&rdataset, &private);
2548 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2551 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2552 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2553 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2554 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2555 result = zone_addnsec3chain(zone, &nsec3param);
2556 if (result != ISC_R_SUCCESS) {
2557 dns_zone_log(zone, ISC_LOG_ERROR,
2558 "zone_addnsec3chain failed: %s",
2559 dns_result_totext(result));
2563 dns_rdataset_disassociate(&rdataset);
2566 dns_db_detachnode(zone->db, &node);
2567 if (version != NULL)
2568 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2572 set_resigntime(dns_zone_t *zone) {
2573 dns_rdataset_t rdataset;
2574 dns_fixedname_t fixed;
2575 unsigned int resign;
2576 isc_result_t result;
2577 isc_uint32_t nanosecs;
2579 dns_rdataset_init(&rdataset);
2580 dns_fixedname_init(&fixed);
2581 result = dns_db_getsigningtime(zone->db, &rdataset,
2582 dns_fixedname_name(&fixed));
2583 if (result != ISC_R_SUCCESS) {
2584 isc_time_settoepoch(&zone->resigntime);
2587 resign = rdataset.resign;
2588 dns_rdataset_disassociate(&rdataset);
2589 isc_random_get(&nanosecs);
2590 nanosecs %= 1000000000;
2591 isc_time_set(&zone->resigntime, resign, nanosecs);
2595 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2596 dns_dbnode_t *node = NULL;
2597 dns_rdataset_t rdataset;
2598 dns_dbversion_t *version = NULL;
2599 dns_rdata_nsec3param_t nsec3param;
2600 isc_boolean_t ok = ISC_FALSE;
2601 isc_result_t result;
2602 dns_rdata_t rdata = DNS_RDATA_INIT;
2603 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2604 zone_isdynamic(zone) : ISC_FALSE;
2606 dns_rdataset_init(&rdataset);
2607 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2608 if (result != ISC_R_SUCCESS) {
2609 dns_zone_log(zone, ISC_LOG_ERROR,
2610 "nsec3param lookup failure: %s",
2611 dns_result_totext(result));
2614 dns_db_currentversion(db, &version);
2616 result = dns_db_findrdataset(db, node, version,
2617 dns_rdatatype_nsec3param,
2618 dns_rdatatype_none, 0, &rdataset, NULL);
2619 if (result == ISC_R_NOTFOUND) {
2620 INSIST(!dns_rdataset_isassociated(&rdataset));
2621 result = ISC_R_SUCCESS;
2624 if (result != ISC_R_SUCCESS) {
2625 INSIST(!dns_rdataset_isassociated(&rdataset));
2626 dns_zone_log(zone, ISC_LOG_ERROR,
2627 "nsec3param lookup failure: %s",
2628 dns_result_totext(result));
2633 * For dynamic zones we must support every algorithm so we can
2634 * regenerate all the NSEC3 chains.
2635 * For non-dynamic zones we only need to find a supported algorithm.
2637 for (result = dns_rdataset_first(&rdataset);
2638 result == ISC_R_SUCCESS;
2639 result = dns_rdataset_next(&rdataset))
2641 dns_rdataset_current(&rdataset, &rdata);
2642 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2643 dns_rdata_reset(&rdata);
2644 INSIST(result == ISC_R_SUCCESS);
2645 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2646 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2648 dns_zone_log(zone, ISC_LOG_WARNING,
2649 "nsec3 test \"unknown\" hash algorithm found: %u",
2652 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2654 dns_zone_log(zone, ISC_LOG_ERROR,
2655 "unsupported nsec3 hash algorithm"
2656 " in dynamic zone: %u",
2658 result = DNS_R_BADZONE;
2659 /* Stop second error message. */
2663 dns_zone_log(zone, ISC_LOG_WARNING,
2664 "unsupported nsec3 hash algorithm: %u",
2669 if (result == ISC_R_NOMORE)
2670 result = ISC_R_SUCCESS;
2673 result = DNS_R_BADZONE;
2674 dns_zone_log(zone, ISC_LOG_ERROR,
2675 "no supported nsec3 hash algorithm");
2679 if (dns_rdataset_isassociated(&rdataset))
2680 dns_rdataset_disassociate(&rdataset);
2681 dns_db_closeversion(db, &version, ISC_FALSE);
2682 dns_db_detachnode(db, &node);
2687 * Set the timer for refreshing the key zone to the soonest future time
2688 * of the set (current timer, keydata->refresh, keydata->addhd,
2689 * keydata->removehd).
2692 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
2693 isc_stdtime_t now) {
2694 const char me[] = "set_refreshkeytimer";
2696 isc_time_t timenow, timethen;
2700 then = key->refresh;
2701 if (key->addhd > now && key->addhd < then)
2703 if (key->removehd > now && key->removehd < then)
2704 then = key->removehd;
2708 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
2711 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
2712 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
2713 zone->refreshkeytime = timethen;
2715 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
2716 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
2717 zone_settimer(zone, &timenow);
2721 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
2722 * If the key zone is changed, set '*changed' to ISC_TRUE.
2725 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
2726 dns_diff_t *diff, dns_keytable_t *keytable,
2727 dns_keynode_t **keynodep, isc_boolean_t *changed)
2729 const char me[] = "create_keydata";
2730 isc_result_t result = ISC_R_SUCCESS;
2731 isc_buffer_t keyb, dstb;
2732 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
2733 dns_rdata_keydata_t keydata;
2734 dns_rdata_dnskey_t dnskey;
2735 dns_rdata_t rdata = DNS_RDATA_INIT;
2736 dns_keynode_t *keynode;
2741 REQUIRE(keynodep != NULL);
2742 keynode = *keynodep;
2745 isc_stdtime_get(&now);
2747 /* Loop in case there's more than one key. */
2748 while (result == ISC_R_SUCCESS) {
2749 dns_keynode_t *nextnode = NULL;
2751 key = dns_keynode_key(keynode);
2755 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
2756 CHECK(dst_key_todns(key, &dstb));
2758 /* Convert DST key to DNSKEY. */
2759 dns_rdata_reset(&rdata);
2760 isc_buffer_usedregion(&dstb, &r);
2761 dns_rdata_fromregion(&rdata, dst_key_class(key),
2762 dns_rdatatype_dnskey, &r);
2764 /* DSTKEY to KEYDATA. */
2765 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
2766 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
2769 /* KEYDATA to rdata. */
2770 dns_rdata_reset(&rdata);
2771 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
2772 CHECK(dns_rdata_fromstruct(&rdata,
2773 zone->rdclass, dns_rdatatype_keydata,
2776 /* Add rdata to zone. */
2777 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
2778 dst_key_name(key), 0, &rdata));
2779 *changed = ISC_TRUE;
2782 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
2783 if (result != ISC_R_NOTFOUND) {
2784 dns_keytable_detachkeynode(keytable, &keynode);
2789 /* Refresh new keys from the zone apex as soon as possible. */
2791 set_refreshkeytimer(zone, &keydata, now);
2793 if (keynode != NULL)
2794 dns_keytable_detachkeynode(keytable, &keynode);
2797 return (ISC_R_SUCCESS);
2804 * Remove from the key zone all the KEYDATA records found in rdataset.
2807 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
2808 dns_name_t *name, dns_rdataset_t *rdataset)
2810 dns_rdata_t rdata = DNS_RDATA_INIT;
2811 isc_result_t result, uresult;
2813 for (result = dns_rdataset_first(rdataset);
2814 result == ISC_R_SUCCESS;
2815 result = dns_rdataset_next(rdataset)) {
2816 dns_rdata_reset(&rdata);
2817 dns_rdataset_current(rdataset, &rdata);
2818 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
2820 if (uresult != ISC_R_SUCCESS)
2823 if (result == ISC_R_NOMORE)
2824 result = ISC_R_SUCCESS;
2829 * Compute the DNSSEC key ID for a DNSKEY record.
2832 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
2835 isc_result_t result;
2836 dns_rdata_t rdata = DNS_RDATA_INIT;
2837 unsigned char data[4096];
2838 isc_buffer_t buffer;
2839 dst_key_t *dstkey = NULL;
2841 isc_buffer_init(&buffer, data, sizeof(data));
2842 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
2843 dns_rdatatype_dnskey, dnskey, &buffer);
2845 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
2846 if (result == ISC_R_SUCCESS)
2847 *tag = dst_key_id(dstkey);
2848 dst_key_free(&dstkey);
2854 * Add key to the security roots.
2857 trust_key(dns_zone_t *zone, dns_name_t *keyname,
2858 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
2859 isc_result_t result;
2860 dns_rdata_t rdata = DNS_RDATA_INIT;
2861 unsigned char data[4096];
2862 isc_buffer_t buffer;
2863 dns_keytable_t *sr = NULL;
2864 dst_key_t *dstkey = NULL;
2866 /* Convert dnskey to DST key. */
2867 isc_buffer_init(&buffer, data, sizeof(data));
2868 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
2869 dns_rdatatype_dnskey, dnskey, &buffer);
2871 result = dns_view_getsecroots(zone->view, &sr);
2872 if (result != ISC_R_SUCCESS)
2875 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
2876 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
2877 dns_keytable_detach(&sr);
2881 dst_key_free(&dstkey);
2883 dns_keytable_detach(&sr);
2888 * Add a null key to the security roots for so that all queries
2889 * to the zone will fail.
2892 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
2893 isc_result_t result;
2894 dns_keytable_t *sr = NULL;
2896 result = dns_view_getsecroots(zone->view, &sr);
2897 if (result == ISC_R_SUCCESS) {
2898 dns_keytable_marksecure(sr, keyname);
2899 dns_keytable_detach(&sr);
2904 * Scan a set of KEYDATA records from the key zone. The ones that are
2905 * valid (i.e., the add holddown timer has expired) become trusted keys.
2908 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
2909 isc_result_t result;
2910 dns_rdata_t rdata = DNS_RDATA_INIT;
2911 dns_rdata_keydata_t keydata;
2912 dns_rdata_dnskey_t dnskey;
2913 isc_mem_t *mctx = zone->mctx;
2914 int trusted = 0, revoked = 0, pending = 0;
2916 dns_keytable_t *sr = NULL;
2918 isc_stdtime_get(&now);
2920 result = dns_view_getsecroots(zone->view, &sr);
2921 if (result == ISC_R_SUCCESS) {
2922 dns_keytable_delete(sr, name);
2923 dns_keytable_detach(&sr);
2926 /* Now insert all the accepted trust anchors from this keydata set. */
2927 for (result = dns_rdataset_first(rdataset);
2928 result == ISC_R_SUCCESS;
2929 result = dns_rdataset_next(rdataset)) {
2930 dns_rdata_reset(&rdata);
2931 dns_rdataset_current(rdataset, &rdata);
2933 /* Convert rdata to keydata. */
2934 dns_rdata_tostruct(&rdata, &keydata, NULL);
2936 /* Set the key refresh timer. */
2937 set_refreshkeytimer(zone, &keydata, now);
2939 /* If the removal timer is nonzero, this key was revoked. */
2940 if (keydata.removehd != 0) {
2946 * If the add timer is still pending, this key is not
2949 if (now < keydata.addhd) {
2954 /* Convert keydata to dnskey. */
2955 dns_keydata_todnskey(&keydata, &dnskey, NULL);
2957 /* Add to keytables. */
2959 trust_key(zone, name, &dnskey, mctx);
2962 if (trusted == 0 && pending != 0) {
2963 char namebuf[DNS_NAME_FORMATSIZE];
2964 dns_name_format(name, namebuf, sizeof namebuf);
2965 dns_zone_log(zone, ISC_LOG_ERROR,
2966 "No valid trust anchors for '%s'!", namebuf);
2967 dns_zone_log(zone, ISC_LOG_ERROR,
2968 "%d key(s) revoked, %d still pending",
2970 dns_zone_log(zone, ISC_LOG_ERROR,
2971 "All queries to '%s' will fail", namebuf);
2972 fail_secure(zone, name);
2977 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
2980 dns_diff_t temp_diff;
2981 isc_result_t result;
2984 * Create a singleton diff.
2986 dns_diff_init(diff->mctx, &temp_diff);
2987 temp_diff.resign = diff->resign;
2988 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
2991 * Apply it to the database.
2993 result = dns_diff_apply(&temp_diff, db, ver);
2994 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
2995 if (result != ISC_R_SUCCESS) {
2996 dns_difftuple_free(tuple);
3001 * Merge it into the current pending journal entry.
3003 dns_diff_appendminimal(diff, tuple);
3006 * Do not clear temp_diff.
3008 return (ISC_R_SUCCESS);
3012 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3013 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3016 dns_difftuple_t *tuple = NULL;
3017 isc_result_t result;
3018 result = dns_difftuple_create(diff->mctx, op,
3019 name, ttl, rdata, &tuple);
3020 if (result != ISC_R_SUCCESS)
3022 return (do_one_tuple(&tuple, db, ver, diff));
3026 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3027 dns_diff_t *diff, isc_mem_t *mctx) {
3028 dns_difftuple_t *deltuple = NULL;
3029 dns_difftuple_t *addtuple = NULL;
3030 isc_uint32_t serial;
3031 isc_result_t result;
3033 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3034 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3035 addtuple->op = DNS_DIFFOP_ADD;
3037 serial = dns_soa_getserial(&addtuple->rdata);
3040 serial = (serial + 1) & 0xFFFFFFFF;
3044 dns_soa_setserial(serial, &addtuple->rdata);
3045 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3046 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3047 result = ISC_R_SUCCESS;
3050 if (addtuple != NULL)
3051 dns_difftuple_free(&addtuple);
3052 if (deltuple != NULL)
3053 dns_difftuple_free(&deltuple);
3058 * Write all transactions in 'diff' to the zone journal file.
3061 zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) {
3062 const char me[] = "zone_journal";
3063 const char *journalfile;
3064 isc_result_t result = ISC_R_SUCCESS;
3065 dns_journal_t *journal = NULL;
3068 journalfile = dns_zone_getjournal(zone);
3069 if (journalfile != NULL) {
3070 result = dns_journal_open(zone->mctx, journalfile,
3071 ISC_TRUE, &journal);
3072 if (result != ISC_R_SUCCESS) {
3073 dns_zone_log(zone, ISC_LOG_ERROR,
3074 "%s:dns_journal_open -> %s\n",
3075 caller, dns_result_totext(result));
3079 result = dns_journal_write_transaction(journal, diff);
3080 dns_journal_destroy(&journal);
3081 if (result != ISC_R_SUCCESS) {
3082 dns_zone_log(zone, ISC_LOG_ERROR,
3083 "%s:dns_journal_write_transaction -> %s\n",
3084 caller, dns_result_totext(result));
3092 * Create an SOA record for a newly-created zone
3095 add_soa(dns_zone_t *zone, dns_db_t *db) {
3096 isc_result_t result;
3097 dns_rdata_t rdata = DNS_RDATA_INIT;
3098 unsigned char buf[DNS_SOA_BUFFERSIZE];
3099 dns_dbversion_t *ver = NULL;
3102 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3104 dns_diff_init(zone->mctx, &diff);
3105 result = dns_db_newversion(db, &ver);
3106 if (result != ISC_R_SUCCESS) {
3107 dns_zone_log(zone, ISC_LOG_ERROR,
3108 "add_soa:dns_db_newversion -> %s\n",
3109 dns_result_totext(result));
3113 /* Build SOA record */
3114 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3115 0, 0, 0, 0, 0, buf, &rdata);
3116 if (result != ISC_R_SUCCESS) {
3117 dns_zone_log(zone, ISC_LOG_ERROR,
3118 "add_soa:dns_soa_buildrdata -> %s\n",
3119 dns_result_totext(result));
3123 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3124 &zone->origin, 0, &rdata);
3127 dns_diff_clear(&diff);
3129 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3135 * Synchronize the set of initializing keys found in managed-keys {}
3136 * statements with the set of trust anchors found in the managed-keys.bind
3137 * zone. If a domain is no longer named in managed-keys, delete all keys
3138 * from that domain from the key zone. If a domain is mentioned in in
3139 * managed-keys but there are no references to it in the key zone, load
3140 * the key zone with the initializing key(s) for that domain.
3143 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3144 isc_result_t result = ISC_R_SUCCESS;
3145 isc_boolean_t changed = ISC_FALSE;
3146 isc_boolean_t commit = ISC_FALSE;
3147 dns_rbtnodechain_t chain;
3149 dns_name_t foundname, *origin;
3150 dns_keynode_t *keynode = NULL;
3151 dns_view_t *view = zone->view;
3152 dns_keytable_t *sr = NULL;
3153 dns_dbversion_t *ver = NULL;
3155 dns_rriterator_t rrit;
3157 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3159 dns_name_init(&foundname, NULL);
3160 dns_fixedname_init(&fn);
3161 origin = dns_fixedname_name(&fn);
3163 dns_diff_init(zone->mctx, &diff);
3165 CHECK(dns_view_getsecroots(view, &sr));
3167 result = dns_db_newversion(db, &ver);
3168 if (result != ISC_R_SUCCESS) {
3169 dns_zone_log(zone, ISC_LOG_ERROR,
3170 "sync_keyzone:dns_db_newversion -> %s\n",
3171 dns_result_totext(result));
3176 * Walk the zone DB. If we find any keys whose names are no longer
3177 * in managed-keys (or *are* in trusted-keys, meaning they are
3178 * permanent and not RFC5011-maintained), delete them from the
3179 * zone. Otherwise call load_secroots(), which loads keys into
3180 * secroots as appropriate.
3182 dns_rriterator_init(&rrit, db, ver, 0);
3183 for (result = dns_rriterator_first(&rrit);
3184 result == ISC_R_SUCCESS;
3185 result = dns_rriterator_nextrrset(&rrit)) {
3186 dns_rdataset_t *rdataset;
3187 dns_name_t *rrname = NULL;
3190 dns_rriterator_current(&rrit, &rrname, &ttl,
3192 if (!dns_rdataset_isassociated(rdataset)) {
3193 dns_rriterator_destroy(&rrit);
3197 if (rdataset->type != dns_rdatatype_keydata)
3200 result = dns_keytable_find(sr, rrname, &keynode);
3201 if ((result != ISC_R_SUCCESS &&
3202 result != DNS_R_PARTIALMATCH) ||
3203 dns_keynode_managed(keynode) == ISC_FALSE) {
3204 CHECK(delete_keydata(db, ver, &diff,
3208 load_secroots(zone, rrname, rdataset);
3211 if (keynode != NULL)
3212 dns_keytable_detachkeynode(sr, &keynode);
3214 dns_rriterator_destroy(&rrit);
3217 * Now walk secroots to find any managed keys that aren't
3218 * in the zone. If we find any, we add them to the zone.
3220 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3221 dns_rbtnodechain_init(&chain, zone->mctx);
3222 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3223 if (result == ISC_R_NOTFOUND)
3224 result = ISC_R_NOMORE;
3225 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3226 dns_rbtnode_t *rbtnode = NULL;
3228 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3229 if (rbtnode->data == NULL)
3232 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
3233 if (dns_keynode_managed(keynode)) {
3234 dns_fixedname_t fname;
3235 dns_name_t *keyname;
3238 key = dns_keynode_key(keynode);
3239 dns_fixedname_init(&fname);
3241 if (key == NULL) /* fail_secure() was called. */
3244 keyname = dst_key_name(key);
3245 result = dns_db_find(db, keyname, ver,
3246 dns_rdatatype_keydata,
3247 DNS_DBFIND_NOWILD, 0, NULL,
3248 dns_fixedname_name(&fname),
3250 if (result != ISC_R_SUCCESS)
3251 result = create_keydata(zone, db, ver, &diff,
3252 sr, &keynode, &changed);
3253 if (result != ISC_R_SUCCESS)
3257 result = dns_rbtnodechain_next(&chain, &foundname, origin);
3258 if (keynode != NULL)
3259 dns_keytable_detachkeynode(sr, &keynode);
3261 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
3263 if (result == ISC_R_NOMORE)
3264 result = ISC_R_SUCCESS;
3267 /* Write changes to journal file. */
3268 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
3269 CHECK(zone_journal(zone, &diff, "sync_keyzone"));
3271 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
3272 zone_needdump(zone, 30);
3277 if (keynode != NULL)
3278 dns_keytable_detachkeynode(sr, &keynode);
3280 dns_keytable_detach(&sr);
3282 dns_db_closeversion(db, &ver, commit);
3283 dns_diff_clear(&diff);
3289 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
3290 isc_result_t result)
3292 unsigned int soacount = 0;
3293 unsigned int nscount = 0;
3294 unsigned int errors = 0;
3295 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
3297 isc_boolean_t needdump = ISC_FALSE;
3298 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3299 isc_boolean_t nomaster = ISC_FALSE;
3300 unsigned int options;
3305 * Initiate zone transfer? We may need a error code that
3306 * indicates that the "permanent" form does not exist.
3307 * XXX better error feedback to log.
3309 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
3310 if (zone->type == dns_zone_slave ||
3311 zone->type == dns_zone_stub) {
3312 if (result == ISC_R_FILENOTFOUND)
3313 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3315 else if (result != DNS_R_NOMASTERFILE)
3316 dns_zone_log(zone, ISC_LOG_ERROR,
3317 "loading from master file %s "
3320 dns_result_totext(result));
3322 dns_zone_log(zone, ISC_LOG_ERROR,
3323 "loading from master file %s failed: %s",
3325 dns_result_totext(result));
3326 nomaster = ISC_TRUE;
3329 if (zone->type != dns_zone_key)
3333 dns_zone_log(zone, ISC_LOG_DEBUG(2),
3334 "number of nodes in database: %u",
3335 dns_db_nodecount(db));
3337 if (result == DNS_R_SEENINCLUDE)
3338 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3340 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3343 * If there's no master file for a key zone, then the zone is new:
3344 * create an SOA record. (We do this now, instead of later, so that
3345 * if there happens to be a journal file, we can roll forward from
3346 * a sane starting point.)
3348 if (nomaster && zone->type == dns_zone_key) {
3349 result = add_soa(zone, db);
3350 if (result != ISC_R_SUCCESS)
3355 * Apply update log, if any, on initial load.
3357 if (zone->journal != NULL &&
3358 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
3359 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3361 if (zone->type == dns_zone_master &&
3362 (zone->update_acl != NULL || zone->ssutable != NULL))
3363 options = DNS_JOURNALOPT_RESIGN;
3366 result = dns_journal_rollforward2(zone->mctx, db, options,
3367 zone->sigresigninginterval,
3369 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
3370 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
3371 result != ISC_R_RANGE) {
3372 dns_zone_log(zone, ISC_LOG_ERROR,
3373 "journal rollforward failed: %s",
3374 dns_result_totext(result));
3377 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
3378 dns_zone_log(zone, ISC_LOG_ERROR,
3379 "journal rollforward failed: "
3380 "journal out of sync with zone");
3383 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3384 "journal rollforward completed "
3386 dns_result_totext(result));
3387 if (result == ISC_R_SUCCESS)
3388 needdump = ISC_TRUE;
3391 zone->loadtime = loadtime;
3393 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded");
3395 * Obtain ns, soa and cname counts for top of zone.
3398 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
3399 &refresh, &retry, &expire, &minimum,
3401 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
3402 dns_zone_log(zone, ISC_LOG_ERROR,
3403 "could not find NS and/or SOA records");
3407 * Master / Slave / Stub zones require both NS and SOA records at
3408 * the top of the zone.
3411 switch (zone->type) {
3413 case dns_zone_master:
3414 case dns_zone_slave:
3416 if (soacount != 1) {
3417 dns_zone_log(zone, ISC_LOG_ERROR,
3418 "has %d SOA records", soacount);
3419 result = DNS_R_BADZONE;
3422 dns_zone_log(zone, ISC_LOG_ERROR,
3423 "has no NS records");
3424 result = DNS_R_BADZONE;
3426 if (result != ISC_R_SUCCESS)
3428 if (zone->type == dns_zone_master && errors != 0) {
3429 result = DNS_R_BADZONE;
3432 if (zone->type != dns_zone_stub) {
3433 result = check_nsec3param(zone, db);
3434 if (result != ISC_R_SUCCESS)
3437 if (zone->type == dns_zone_master &&
3438 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
3439 !integrity_checks(zone, db)) {
3440 result = DNS_R_BADZONE;
3444 if (zone->type == dns_zone_master &&
3445 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
3446 !zone_check_dup(zone, db)) {
3447 result = DNS_R_BADZONE;
3451 if (zone->db != NULL) {
3453 * This is checked in zone_replacedb() for slave zones
3454 * as they don't reload from disk.
3456 result = zone_get_from_db(zone, zone->db, NULL, NULL,
3457 &oldserial, NULL, NULL, NULL,
3459 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3460 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
3461 !isc_serial_gt(serial, oldserial)) {
3462 isc_uint32_t serialmin, serialmax;
3464 INSIST(zone->type == dns_zone_master);
3466 serialmin = (oldserial + 1) & 0xffffffffU;
3467 serialmax = (oldserial + 0x7fffffffU) &
3469 dns_zone_log(zone, ISC_LOG_ERROR,
3470 "ixfr-from-differences: "
3471 "new serial (%u) out of range "
3472 "[%u - %u]", serial, serialmin,
3474 result = DNS_R_BADZONE;
3476 } else if (!isc_serial_ge(serial, oldserial))
3477 dns_zone_log(zone, ISC_LOG_ERROR,
3478 "zone serial (%u/%u) has gone "
3479 "backwards", serial, oldserial);
3480 else if (serial == oldserial && !hasinclude &&
3481 strcmp(zone->db_argv[0], "_builtin") != 0)
3482 dns_zone_log(zone, ISC_LOG_ERROR,
3483 "zone serial (%u) unchanged. "
3484 "zone may fail to transfer "
3485 "to slaves.", serial);
3488 if (zone->type == dns_zone_master &&
3489 (zone->update_acl != NULL || zone->ssutable != NULL) &&
3490 zone->sigresigninginterval < (3 * refresh) &&
3491 dns_db_issecure(db))
3493 dns_zone_log(zone, ISC_LOG_WARNING,
3494 "sig-re-signing-interval less than "
3498 zone->refresh = RANGE(refresh,
3499 zone->minrefresh, zone->maxrefresh);
3500 zone->retry = RANGE(retry,
3501 zone->minretry, zone->maxretry);
3502 zone->expire = RANGE(expire, zone->refresh + zone->retry,
3504 zone->minimum = minimum;
3505 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
3507 if (zone->type == dns_zone_slave ||
3508 zone->type == dns_zone_stub) {
3512 result = isc_file_getmodtime(zone->journal, &t);
3513 if (result != ISC_R_SUCCESS)
3514 result = isc_file_getmodtime(zone->masterfile,
3516 if (result == ISC_R_SUCCESS)
3517 DNS_ZONE_TIME_ADD(&t, zone->expire,
3520 DNS_ZONE_TIME_ADD(&now, zone->retry,
3523 delay = isc_random_jitter(zone->retry,
3524 (zone->retry * 3) / 4);
3525 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
3526 if (isc_time_compare(&zone->refreshtime,
3527 &zone->expiretime) >= 0)
3528 zone->refreshtime = now;
3533 result = sync_keyzone(zone, db);
3534 if (result != ISC_R_SUCCESS)
3539 UNEXPECTED_ERROR(__FILE__, __LINE__,
3540 "unexpected zone type %d", zone->type);
3541 result = ISC_R_UNEXPECTED;
3546 * Check for weak DNSKEY's.
3548 if (zone->type == dns_zone_master)
3549 zone_check_dnskeys(zone, db);
3552 * Schedule DNSSEC key refresh.
3554 if (zone->type == dns_zone_master &&
3555 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
3556 zone->refreshkeytime = now;
3559 /* destroy notification example. */
3561 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
3562 DNS_EVENT_DBDESTROYED,
3563 dns_zonemgr_dbdestroyed,
3565 sizeof(isc_event_t));
3566 dns_db_ondestroy(db, zone->task, &e);
3570 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
3571 if (zone->db != NULL) {
3572 result = zone_replacedb(zone, db, ISC_FALSE);
3573 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3574 if (result != ISC_R_SUCCESS)
3577 zone_attachdb(zone, db);
3578 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3579 DNS_ZONE_SETFLAG(zone,
3580 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
3583 result = ISC_R_SUCCESS;
3586 if (zone->type == dns_zone_key)
3587 zone_needdump(zone, 30);
3589 zone_needdump(zone, DNS_DUMP_DELAY);
3592 if (zone->task != NULL) {
3593 if (zone->type == dns_zone_master) {
3594 set_resigntime(zone);
3595 resume_signingwithkey(zone);
3596 resume_addnsec3chain(zone);
3599 if (zone->type == dns_zone_master &&
3600 zone_isdynamic(zone) &&
3601 dns_db_issecure(db)) {
3603 dns_fixedname_t fixed;
3604 dns_rdataset_t next;
3606 dns_rdataset_init(&next);
3607 dns_fixedname_init(&fixed);
3608 name = dns_fixedname_name(&fixed);
3610 result = dns_db_getsigningtime(db, &next, name);
3611 if (result == ISC_R_SUCCESS) {
3612 isc_stdtime_t timenow;
3613 char namebuf[DNS_NAME_FORMATSIZE];
3614 char typebuf[DNS_RDATATYPE_FORMATSIZE];
3616 isc_stdtime_get(&timenow);
3617 dns_name_format(name, namebuf, sizeof(namebuf));
3618 dns_rdatatype_format(next.covers,
3619 typebuf, sizeof(typebuf));
3620 dns_zone_log(zone, ISC_LOG_DEBUG(3),
3621 "next resign: %s/%s in %d seconds",
3623 next.resign - timenow);
3624 dns_rdataset_disassociate(&next);
3626 dns_zone_log(zone, ISC_LOG_WARNING,
3627 "signed dynamic zone has no "
3628 "resign event scheduled");
3631 zone_settimer(zone, &now);
3634 if (! dns_db_ispersistent(db))
3635 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
3636 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
3641 if (zone->type == dns_zone_slave ||
3642 zone->type == dns_zone_stub ||
3643 zone->type == dns_zone_key) {
3644 if (zone->journal != NULL)
3645 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
3646 if (zone->masterfile != NULL)
3647 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
3649 /* Mark the zone for immediate refresh. */
3650 zone->refreshtime = now;
3651 if (zone->task != NULL)
3652 zone_settimer(zone, &now);
3653 result = ISC_R_SUCCESS;
3654 } else if (zone->type == dns_zone_master)
3655 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
3659 static isc_boolean_t
3660 exit_check(dns_zone_t *zone) {
3662 REQUIRE(LOCKED_ZONE(zone));
3664 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
3668 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
3670 INSIST(isc_refcount_current(&zone->erefs) == 0);
3676 static isc_boolean_t
3677 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
3678 dns_name_t *name, isc_boolean_t logit)
3680 isc_result_t result;
3681 char namebuf[DNS_NAME_FORMATSIZE];
3682 char altbuf[DNS_NAME_FORMATSIZE];
3683 dns_fixedname_t fixed;
3684 dns_name_t *foundname;
3687 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
3690 if (zone->type == dns_zone_master)
3691 level = ISC_LOG_ERROR;
3693 level = ISC_LOG_WARNING;
3695 dns_fixedname_init(&fixed);
3696 foundname = dns_fixedname_name(&fixed);
3698 result = dns_db_find(db, name, version, dns_rdatatype_a,
3699 0, 0, NULL, foundname, NULL, NULL);
3700 if (result == ISC_R_SUCCESS)
3703 if (result == DNS_R_NXRRSET) {
3704 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
3705 0, 0, NULL, foundname, NULL, NULL);
3706 if (result == ISC_R_SUCCESS)
3710 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
3711 result == DNS_R_EMPTYNAME) {
3713 dns_name_format(name, namebuf, sizeof namebuf);
3714 dns_zone_log(zone, level, "NS '%s' has no address "
3715 "records (A or AAAA)", namebuf);
3720 if (result == DNS_R_CNAME) {
3722 dns_name_format(name, namebuf, sizeof namebuf);
3723 dns_zone_log(zone, level, "NS '%s' is a CNAME "
3724 "(illegal)", namebuf);
3729 if (result == DNS_R_DNAME) {
3731 dns_name_format(name, namebuf, sizeof namebuf);
3732 dns_name_format(foundname, altbuf, sizeof altbuf);
3733 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
3734 "'%s' (illegal)", namebuf, altbuf);
3743 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
3744 dns_dbversion_t *version, unsigned int *nscount,
3745 unsigned int *errors, isc_boolean_t logit)
3747 isc_result_t result;
3748 unsigned int count = 0;
3749 unsigned int ecount = 0;
3750 dns_rdataset_t rdataset;
3754 dns_rdataset_init(&rdataset);
3755 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
3756 dns_rdatatype_none, 0, &rdataset, NULL);
3757 if (result == ISC_R_NOTFOUND) {
3758 INSIST(!dns_rdataset_isassociated(&rdataset));
3761 if (result != ISC_R_SUCCESS) {
3762 INSIST(!dns_rdataset_isassociated(&rdataset));
3763 goto invalidate_rdataset;
3766 result = dns_rdataset_first(&rdataset);
3767 while (result == ISC_R_SUCCESS) {
3768 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
3769 (zone->type == dns_zone_master ||
3770 zone->type == dns_zone_slave)) {
3771 dns_rdata_init(&rdata);
3772 dns_rdataset_current(&rdataset, &rdata);
3773 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3774 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3775 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
3776 !zone_check_ns(zone, db, version, &ns.name, logit))
3780 result = dns_rdataset_next(&rdataset);
3782 dns_rdataset_disassociate(&rdataset);
3785 if (nscount != NULL)
3790 result = ISC_R_SUCCESS;
3792 invalidate_rdataset:
3793 dns_rdataset_invalidate(&rdataset);
3799 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
3800 unsigned int *soacount,
3801 isc_uint32_t *serial, isc_uint32_t *refresh,
3802 isc_uint32_t *retry, isc_uint32_t *expire,
3803 isc_uint32_t *minimum)
3805 isc_result_t result;
3807 dns_rdataset_t rdataset;
3808 dns_rdata_t rdata = DNS_RDATA_INIT;
3809 dns_rdata_soa_t soa;
3811 dns_rdataset_init(&rdataset);
3812 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
3813 dns_rdatatype_none, 0, &rdataset, NULL);
3814 if (result == ISC_R_NOTFOUND) {
3815 INSIST(!dns_rdataset_isassociated(&rdataset));
3816 if (soacount != NULL)
3820 if (refresh != NULL)
3826 if (minimum != NULL)
3828 result = ISC_R_SUCCESS;
3829 goto invalidate_rdataset;
3831 if (result != ISC_R_SUCCESS) {
3832 INSIST(!dns_rdataset_isassociated(&rdataset));
3833 goto invalidate_rdataset;
3837 result = dns_rdataset_first(&rdataset);
3838 while (result == ISC_R_SUCCESS) {
3839 dns_rdata_init(&rdata);
3840 dns_rdataset_current(&rdataset, &rdata);
3843 result = dns_rdata_tostruct(&rdata, &soa, NULL);
3844 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3847 result = dns_rdataset_next(&rdataset);
3848 dns_rdata_reset(&rdata);
3850 dns_rdataset_disassociate(&rdataset);
3852 if (soacount != NULL)
3857 *serial = soa.serial;
3858 if (refresh != NULL)
3859 *refresh = soa.refresh;
3863 *expire = soa.expire;
3864 if (minimum != NULL)
3865 *minimum = soa.minimum;
3868 result = ISC_R_SUCCESS;
3870 invalidate_rdataset:
3871 dns_rdataset_invalidate(&rdataset);
3877 * zone must be locked.
3880 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
3881 unsigned int *soacount, isc_uint32_t *serial,
3882 isc_uint32_t *refresh, isc_uint32_t *retry,
3883 isc_uint32_t *expire, isc_uint32_t *minimum,
3884 unsigned int *errors)
3886 isc_result_t result;
3887 isc_result_t answer = ISC_R_SUCCESS;
3888 dns_dbversion_t *version = NULL;
3891 REQUIRE(db != NULL);
3892 REQUIRE(zone != NULL);
3894 dns_db_currentversion(db, &version);
3897 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
3898 if (result != ISC_R_SUCCESS) {
3903 if (nscount != NULL || errors != NULL) {
3904 result = zone_count_ns_rr(zone, db, node, version,
3905 nscount, errors, ISC_TRUE);
3906 if (result != ISC_R_SUCCESS)
3910 if (soacount != NULL || serial != NULL || refresh != NULL
3911 || retry != NULL || expire != NULL || minimum != NULL) {
3912 result = zone_load_soa_rr(db, node, version, soacount,
3913 serial, refresh, retry, expire,
3915 if (result != ISC_R_SUCCESS)
3919 dns_db_detachnode(db, &node);
3921 dns_db_closeversion(db, &version, ISC_FALSE);
3927 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
3928 REQUIRE(DNS_ZONE_VALID(source));
3929 REQUIRE(target != NULL && *target == NULL);
3930 isc_refcount_increment(&source->erefs, NULL);
3935 dns_zone_detach(dns_zone_t **zonep) {
3938 isc_boolean_t free_now = ISC_FALSE;
3940 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
3944 isc_refcount_decrement(&zone->erefs, &refs);
3949 * We just detached the last external reference.
3951 if (zone->task != NULL) {
3953 * This zone is being managed. Post
3954 * its control event and let it clean
3955 * up synchronously in the context of
3958 isc_event_t *ev = &zone->ctlevent;
3959 isc_task_send(zone->task, &ev);
3962 * This zone is not being managed; it has
3963 * no task and can have no outstanding
3964 * events. Free it immediately.
3967 * Unmanaged zones should not have non-null views;
3968 * we have no way of detaching from the view here
3969 * without causing deadlock because this code is called
3970 * with the view already locked.
3972 INSIST(zone->view == NULL);
3973 free_now = ISC_TRUE;
3983 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3984 REQUIRE(DNS_ZONE_VALID(source));
3985 REQUIRE(target != NULL && *target == NULL);
3987 zone_iattach(source, target);
3988 UNLOCK_ZONE(source);
3992 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
3995 * 'source' locked by caller.
3997 REQUIRE(LOCKED_ZONE(source));
3998 REQUIRE(DNS_ZONE_VALID(source));
3999 REQUIRE(target != NULL && *target == NULL);
4000 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
4002 INSIST(source->irefs != 0);
4007 zone_idetach(dns_zone_t **zonep) {
4011 * 'zone' locked by caller.
4013 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4015 REQUIRE(LOCKED_ZONE(*zonep));
4018 INSIST(zone->irefs > 0);
4020 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
4024 dns_zone_idetach(dns_zone_t **zonep) {
4026 isc_boolean_t free_needed;
4028 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4033 INSIST(zone->irefs > 0);
4035 free_needed = exit_check(zone);
4042 dns_zone_getmctx(dns_zone_t *zone) {
4043 REQUIRE(DNS_ZONE_VALID(zone));
4045 return (zone->mctx);
4049 dns_zone_getmgr(dns_zone_t *zone) {
4050 REQUIRE(DNS_ZONE_VALID(zone));
4052 return (zone->zmgr);
4056 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
4057 REQUIRE(DNS_ZONE_VALID(zone));
4061 DNS_ZONE_SETFLAG(zone, flags);
4063 DNS_ZONE_CLRFLAG(zone, flags);
4068 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
4070 REQUIRE(DNS_ZONE_VALID(zone));
4074 zone->options |= option;
4076 zone->options &= ~option;
4081 dns_zone_getoptions(dns_zone_t *zone) {
4083 REQUIRE(DNS_ZONE_VALID(zone));
4085 return (zone->options);
4089 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
4091 REQUIRE(DNS_ZONE_VALID(zone));
4095 zone->keyopts |= keyopt;
4097 zone->keyopts &= ~keyopt;
4102 dns_zone_getkeyopts(dns_zone_t *zone) {
4104 REQUIRE(DNS_ZONE_VALID(zone));
4106 return (zone->keyopts);
4110 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4111 REQUIRE(DNS_ZONE_VALID(zone));
4114 zone->xfrsource4 = *xfrsource;
4117 return (ISC_R_SUCCESS);
4121 dns_zone_getxfrsource4(dns_zone_t *zone) {
4122 REQUIRE(DNS_ZONE_VALID(zone));
4123 return (&zone->xfrsource4);
4127 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4128 REQUIRE(DNS_ZONE_VALID(zone));
4131 zone->xfrsource6 = *xfrsource;
4134 return (ISC_R_SUCCESS);
4138 dns_zone_getxfrsource6(dns_zone_t *zone) {
4139 REQUIRE(DNS_ZONE_VALID(zone));
4140 return (&zone->xfrsource6);
4144 dns_zone_setaltxfrsource4(dns_zone_t *zone,
4145 const isc_sockaddr_t *altxfrsource)
4147 REQUIRE(DNS_ZONE_VALID(zone));
4150 zone->altxfrsource4 = *altxfrsource;
4153 return (ISC_R_SUCCESS);
4157 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
4158 REQUIRE(DNS_ZONE_VALID(zone));
4159 return (&zone->altxfrsource4);
4163 dns_zone_setaltxfrsource6(dns_zone_t *zone,
4164 const isc_sockaddr_t *altxfrsource)
4166 REQUIRE(DNS_ZONE_VALID(zone));
4169 zone->altxfrsource6 = *altxfrsource;
4172 return (ISC_R_SUCCESS);
4176 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
4177 REQUIRE(DNS_ZONE_VALID(zone));
4178 return (&zone->altxfrsource6);
4182 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4183 REQUIRE(DNS_ZONE_VALID(zone));
4186 zone->notifysrc4 = *notifysrc;
4189 return (ISC_R_SUCCESS);
4193 dns_zone_getnotifysrc4(dns_zone_t *zone) {
4194 REQUIRE(DNS_ZONE_VALID(zone));
4195 return (&zone->notifysrc4);
4199 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4200 REQUIRE(DNS_ZONE_VALID(zone));
4203 zone->notifysrc6 = *notifysrc;
4206 return (ISC_R_SUCCESS);
4210 dns_zone_getnotifysrc6(dns_zone_t *zone) {
4211 REQUIRE(DNS_ZONE_VALID(zone));
4212 return (&zone->notifysrc6);
4216 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
4219 isc_sockaddr_t *new;
4221 REQUIRE(DNS_ZONE_VALID(zone));
4222 REQUIRE(count == 0 || notify != NULL);
4225 if (zone->notify != NULL) {
4226 isc_mem_put(zone->mctx, zone->notify,
4227 zone->notifycnt * sizeof(*new));
4228 zone->notify = NULL;
4229 zone->notifycnt = 0;
4232 new = isc_mem_get(zone->mctx, count * sizeof(*new));
4235 return (ISC_R_NOMEMORY);
4237 memcpy(new, notify, count * sizeof(*new));
4239 zone->notifycnt = count;
4242 return (ISC_R_SUCCESS);
4246 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
4249 isc_result_t result;
4251 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
4255 static isc_boolean_t
4256 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
4261 for (i = 0; i < count; i++)
4262 if (!isc_sockaddr_equal(&old[i], &new[i]))
4267 static isc_boolean_t
4268 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
4271 if (old == NULL && new == NULL)
4273 if (old == NULL || new == NULL)
4276 for (i = 0; i < count; i++) {
4277 if (old[i] == NULL && new[i] == NULL)
4279 if (old[i] == NULL || new[i] == NULL ||
4280 !dns_name_equal(old[i], new[i]))
4287 dns_zone_setmasterswithkeys(dns_zone_t *zone,
4288 const isc_sockaddr_t *masters,
4289 dns_name_t **keynames,
4292 isc_sockaddr_t *new;
4293 isc_result_t result = ISC_R_SUCCESS;
4294 dns_name_t **newname;
4295 isc_boolean_t *newok;
4298 REQUIRE(DNS_ZONE_VALID(zone));
4299 REQUIRE(count == 0 || masters != NULL);
4300 if (keynames != NULL) {
4301 REQUIRE(count != 0);
4306 * The refresh code assumes that 'masters' wouldn't change under it.
4307 * If it will change then kill off any current refresh in progress
4308 * and update the masters info. If it won't change then we can just
4311 if (count != zone->masterscnt ||
4312 !same_masters(zone->masters, masters, count) ||
4313 !same_keynames(zone->masterkeynames, keynames, count)) {
4314 if (zone->request != NULL)
4315 dns_request_cancel(zone->request);
4318 if (zone->masters != NULL) {
4319 isc_mem_put(zone->mctx, zone->masters,
4320 zone->masterscnt * sizeof(*new));
4321 zone->masters = NULL;
4323 if (zone->masterkeynames != NULL) {
4324 for (i = 0; i < zone->masterscnt; i++) {
4325 if (zone->masterkeynames[i] != NULL) {
4326 dns_name_free(zone->masterkeynames[i],
4328 isc_mem_put(zone->mctx,
4329 zone->masterkeynames[i],
4330 sizeof(dns_name_t));
4331 zone->masterkeynames[i] = NULL;
4334 isc_mem_put(zone->mctx, zone->masterkeynames,
4335 zone->masterscnt * sizeof(dns_name_t *));
4336 zone->masterkeynames = NULL;
4338 if (zone->mastersok != NULL) {
4339 isc_mem_put(zone->mctx, zone->mastersok,
4340 zone->masterscnt * sizeof(isc_boolean_t));
4341 zone->mastersok = NULL;
4343 zone->masterscnt = 0;
4345 * If count == 0, don't allocate any space for masters, mastersok or
4346 * keynames so internally, those pointers are NULL if count == 0
4352 * masters must contain count elements!
4354 new = isc_mem_get(zone->mctx, count * sizeof(*new));
4356 result = ISC_R_NOMEMORY;
4359 memcpy(new, masters, count * sizeof(*new));
4362 * Similarly for mastersok.
4364 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
4365 if (newok == NULL) {
4366 result = ISC_R_NOMEMORY;
4367 isc_mem_put(zone->mctx, new, count * sizeof(*new));
4370 for (i = 0; i < count; i++)
4371 newok[i] = ISC_FALSE;
4374 * if keynames is non-NULL, it must contain count elements!
4377 if (keynames != NULL) {
4378 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
4379 if (newname == NULL) {
4380 result = ISC_R_NOMEMORY;
4381 isc_mem_put(zone->mctx, new, count * sizeof(*new));
4382 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
4385 for (i = 0; i < count; i++)
4387 for (i = 0; i < count; i++) {
4388 if (keynames[i] != NULL) {
4389 newname[i] = isc_mem_get(zone->mctx,
4390 sizeof(dns_name_t));
4391 if (newname[i] == NULL)
4393 dns_name_init(newname[i], NULL);
4394 result = dns_name_dup(keynames[i], zone->mctx,
4396 if (result != ISC_R_SUCCESS) {
4398 for (i = 0; i < count; i++)
4399 if (newname[i] != NULL)
4403 isc_mem_put(zone->mctx, new,
4404 count * sizeof(*new));
4405 isc_mem_put(zone->mctx, newok,
4406 count * sizeof(*newok));
4407 isc_mem_put(zone->mctx, newname,
4408 count * sizeof(*newname));
4416 * Everything is ok so attach to the zone.
4418 zone->masters = new;
4419 zone->mastersok = newok;
4420 zone->masterkeynames = newname;
4421 zone->masterscnt = count;
4422 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
4430 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
4431 isc_result_t result = ISC_R_SUCCESS;
4433 REQUIRE(DNS_ZONE_VALID(zone));
4435 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4436 if (zone->db == NULL)
4437 result = DNS_R_NOTLOADED;
4439 dns_db_attach(zone->db, dpb);
4440 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4446 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
4447 REQUIRE(DNS_ZONE_VALID(zone));
4448 REQUIRE(zone->type == dns_zone_staticstub);
4450 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4451 REQUIRE(zone->db == NULL);
4452 dns_db_attach(db, &zone->db);
4453 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4457 * Co-ordinates the starting of routine jobs.
4461 dns_zone_maintenance(dns_zone_t *zone) {
4462 const char me[] = "dns_zone_maintenance";
4465 REQUIRE(DNS_ZONE_VALID(zone));
4470 zone_settimer(zone, &now);
4474 static inline isc_boolean_t
4475 was_dumping(dns_zone_t *zone) {
4476 isc_boolean_t dumping;
4478 REQUIRE(LOCKED_ZONE(zone));
4480 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
4481 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
4483 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
4484 isc_time_settoepoch(&zone->dumptime);
4489 #define MAXZONEKEYS 10
4492 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
4493 isc_mem_t *mctx, unsigned int maxkeys,
4494 dst_key_t **keys, unsigned int *nkeys)
4496 isc_result_t result;
4497 dns_dbnode_t *node = NULL;
4498 const char *directory = dns_zone_getkeydirectory(zone);
4500 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
4501 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
4502 directory, mctx, maxkeys, keys,
4504 if (result == ISC_R_NOTFOUND)
4505 result = ISC_R_SUCCESS;
4508 dns_db_detachnode(db, &node);
4513 offline(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff, dns_name_t *name,
4514 dns_ttl_t ttl, dns_rdata_t *rdata)
4516 isc_result_t result;
4518 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
4519 return (ISC_R_SUCCESS);
4520 result = update_one_rr(db, ver, diff, DNS_DIFFOP_DELRESIGN,
4522 if (result != ISC_R_SUCCESS)
4524 rdata->flags |= DNS_RDATA_OFFLINE;
4525 result = update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
4531 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
4536 zone->key_expiry = when;
4538 dns_zone_log(zone, ISC_LOG_ERROR,
4539 "DNSKEY RRSIG(s) have expired");
4540 isc_time_settoepoch(&zone->keywarntime);
4541 } else if (when < now + 7 * 24 * 3600) {
4543 isc_time_set(&t, when, 0);
4544 isc_time_formattimestamp(&t, timebuf, 80);
4545 dns_zone_log(zone, ISC_LOG_WARNING,
4546 "DNSKEY RRSIG(s) will expire within 7 days: %s",
4549 delta--; /* loop prevention */
4550 delta /= 24 * 3600; /* to whole days */
4551 delta *= 24 * 3600; /* to seconds */
4552 isc_time_set(&zone->keywarntime, when - delta, 0);
4554 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
4555 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
4556 dns_zone_log(zone, ISC_LOG_NOTICE,
4557 "setting keywarntime to %s", timebuf);
4562 * Helper function to del_sigs(). We don't want to delete RRSIGs that
4565 static isc_boolean_t
4566 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys) {
4570 * It's okay to delete a signature if there is an active ZSK
4571 * with the same algorithm
4573 for (i = 0; i < nkeys; i++) {
4574 if (rrsig_ptr->algorithm == dst_key_alg(keys[i]) &&
4575 (dst_key_isprivate(keys[i])) && !KSK(keys[i]))
4580 * Failing that, it is *not* okay to delete a signature
4581 * if the associated public key is still in the DNSKEY RRset
4583 for (i = 0; i < nkeys; i++) {
4584 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
4585 (rrsig_ptr->keyid == dst_key_id(keys[i])))
4590 * But if the key is gone, then go ahead.
4596 * Delete expired RRsigs and any RRsigs we are about to re-sign.
4597 * See also update.c:del_keysigs().
4600 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
4601 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
4602 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
4604 isc_result_t result;
4605 dns_dbnode_t *node = NULL;
4606 dns_rdataset_t rdataset;
4607 dns_rdata_t rdata = DNS_RDATA_INIT;
4609 dns_rdata_rrsig_t rrsig;
4610 isc_boolean_t found, changed;
4611 isc_stdtime_t warn = 0, maybe = 0;
4613 dns_rdataset_init(&rdataset);
4615 if (type == dns_rdatatype_nsec3)
4616 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
4618 result = dns_db_findnode(db, name, ISC_FALSE, &node);
4619 if (result == ISC_R_NOTFOUND)
4620 return (ISC_R_SUCCESS);
4621 if (result != ISC_R_SUCCESS)
4623 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
4624 (isc_stdtime_t) 0, &rdataset, NULL);
4625 dns_db_detachnode(db, &node);
4627 if (result == ISC_R_NOTFOUND) {
4628 INSIST(!dns_rdataset_isassociated(&rdataset));
4629 return (ISC_R_SUCCESS);
4631 if (result != ISC_R_SUCCESS) {
4632 INSIST(!dns_rdataset_isassociated(&rdataset));
4636 changed = ISC_FALSE;
4637 for (result = dns_rdataset_first(&rdataset);
4638 result == ISC_R_SUCCESS;
4639 result = dns_rdataset_next(&rdataset)) {
4640 dns_rdataset_current(&rdataset, &rdata);
4641 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4642 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4644 if (type != dns_rdatatype_dnskey) {
4645 if (delsig_ok(&rrsig, keys, nkeys)) {
4646 result = update_one_rr(db, ver, diff,
4647 DNS_DIFFOP_DELRESIGN, name,
4648 rdataset.ttl, &rdata);
4651 dns_rdata_reset(&rdata);
4652 if (result != ISC_R_SUCCESS)
4656 * At this point, we've got an RRSIG,
4657 * which is signed by an inactive key.
4658 * An administrator needs to provide a new
4659 * key/alg, but until that time, we want to
4660 * keep the old RRSIG. Marking the key as
4661 * offline will prevent us spinning waiting
4662 * for the private part.
4665 result = offline(db, ver, diff, name,
4666 rdataset.ttl, &rdata);
4668 if (result != ISC_R_SUCCESS)
4673 * Log the key id and algorithm of
4674 * the inactive key with no replacement
4676 if (zone->log_key_expired_timer <= now) {
4677 char origin[DNS_NAME_FORMATSIZE];
4678 char algbuf[DNS_NAME_FORMATSIZE];
4679 dns_name_format(&zone->origin, origin,
4681 dns_secalg_format(rrsig.algorithm,
4684 dns_zone_log(zone, ISC_LOG_WARNING,
4686 "missing or inactive "
4687 "and has no replacement: "
4688 "retaining signatures.",
4691 zone->log_key_expired_timer = now +
4699 * RRSIG(DNSKEY) requires special processing.
4702 for (i = 0; i < nkeys; i++) {
4703 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
4704 rrsig.keyid == dst_key_id(keys[i])) {
4707 * Mark offline RRSIG(DNSKEY).
4708 * We want the earliest offline expire time
4709 * iff there is a new offline signature.
4711 if (!dst_key_isprivate(keys[i])) {
4713 warn > rrsig.timeexpire)
4714 warn = rrsig.timeexpire;
4715 if (rdata.flags & DNS_RDATA_OFFLINE) {
4717 maybe > rrsig.timeexpire)
4725 warn > rrsig.timeexpire)
4726 warn = rrsig.timeexpire;
4727 result = offline(db, ver, diff, name,
4728 rdataset.ttl, &rdata);
4731 result = update_one_rr(db, ver, diff,
4732 DNS_DIFFOP_DELRESIGN,
4740 * If there is not a matching DNSKEY then
4744 result = update_one_rr(db, ver, diff,
4745 DNS_DIFFOP_DELRESIGN, name,
4746 rdataset.ttl, &rdata);
4747 dns_rdata_reset(&rdata);
4748 if (result != ISC_R_SUCCESS)
4752 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
4753 dns_db_resigned(db, &rdataset, ver);
4755 dns_rdataset_disassociate(&rdataset);
4756 if (result == ISC_R_NOMORE)
4757 result = ISC_R_SUCCESS;
4759 set_key_expiry_warning(zone, warn, now);
4762 dns_db_detachnode(db, &node);
4767 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
4768 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
4769 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
4770 isc_stdtime_t expire, isc_boolean_t check_ksk,
4771 isc_boolean_t keyset_kskonly)
4773 isc_result_t result;
4774 dns_dbnode_t *node = NULL;
4775 dns_rdataset_t rdataset;
4776 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
4777 unsigned char data[1024]; /* XXX */
4778 isc_buffer_t buffer;
4781 dns_rdataset_init(&rdataset);
4782 isc_buffer_init(&buffer, data, sizeof(data));
4784 if (type == dns_rdatatype_nsec3)
4785 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
4787 result = dns_db_findnode(db, name, ISC_FALSE, &node);
4788 if (result == ISC_R_NOTFOUND)
4789 return (ISC_R_SUCCESS);
4790 if (result != ISC_R_SUCCESS)
4792 result = dns_db_findrdataset(db, node, ver, type, 0,
4793 (isc_stdtime_t) 0, &rdataset, NULL);
4794 dns_db_detachnode(db, &node);
4795 if (result == ISC_R_NOTFOUND) {
4796 INSIST(!dns_rdataset_isassociated(&rdataset));
4797 return (ISC_R_SUCCESS);
4799 if (result != ISC_R_SUCCESS) {
4800 INSIST(!dns_rdataset_isassociated(&rdataset));
4804 for (i = 0; i < nkeys; i++) {
4805 isc_boolean_t both = ISC_FALSE;
4807 if (!dst_key_isprivate(keys[i]))
4810 if (check_ksk && !REVOKE(keys[i])) {
4811 isc_boolean_t have_ksk, have_nonksk;
4813 have_ksk = ISC_TRUE;
4814 have_nonksk = ISC_FALSE;
4816 have_ksk = ISC_FALSE;
4817 have_nonksk = ISC_TRUE;
4819 for (j = 0; j < nkeys; j++) {
4820 if (j == i || ALG(keys[i]) != ALG(keys[j]))
4822 if (REVOKE(keys[j]))
4825 have_ksk = ISC_TRUE;
4827 have_nonksk = ISC_TRUE;
4828 both = have_ksk && have_nonksk;
4834 if (type == dns_rdatatype_dnskey) {
4835 if (!KSK(keys[i]) && keyset_kskonly)
4837 } else if (KSK(keys[i]))
4839 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
4842 /* Calculate the signature, creating a RRSIG RDATA. */
4843 isc_buffer_clear(&buffer);
4844 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
4845 &inception, &expire,
4846 mctx, &buffer, &sig_rdata));
4847 /* Update the database and journal with the RRSIG. */
4848 /* XXX inefficient - will cause dataset merging */
4849 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
4850 name, rdataset.ttl, &sig_rdata));
4851 dns_rdata_reset(&sig_rdata);
4852 isc_buffer_init(&buffer, data, sizeof(data));
4856 if (dns_rdataset_isassociated(&rdataset))
4857 dns_rdataset_disassociate(&rdataset);
4859 dns_db_detachnode(db, &node);
4864 zone_resigninc(dns_zone_t *zone) {
4865 dns_db_t *db = NULL;
4866 dns_dbversion_t *version = NULL;
4867 dns_diff_t sig_diff;
4868 dns_fixedname_t fixed;
4870 dns_rdataset_t rdataset;
4871 dns_rdatatype_t covers;
4872 dst_key_t *zone_keys[MAXZONEKEYS];
4873 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
4874 isc_result_t result;
4875 isc_stdtime_t now, inception, soaexpire, expire, stop;
4876 isc_uint32_t jitter;
4878 unsigned int nkeys = 0;
4879 unsigned int resign;
4881 dns_rdataset_init(&rdataset);
4882 dns_fixedname_init(&fixed);
4883 dns_diff_init(zone->mctx, &sig_diff);
4884 sig_diff.resign = zone->sigresigninginterval;
4887 * Updates are disabled. Pause for 5 minutes.
4889 if (zone->update_disabled) {
4890 result = ISC_R_FAILURE;
4894 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4895 dns_db_attach(zone->db, &db);
4896 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4898 result = dns_db_newversion(db, &version);
4899 if (result != ISC_R_SUCCESS) {
4900 dns_zone_log(zone, ISC_LOG_ERROR,
4901 "zone_resigninc:dns_db_newversion -> %s\n",
4902 dns_result_totext(result));
4906 result = find_zone_keys(zone, db, version, zone->mctx, MAXZONEKEYS,
4908 if (result != ISC_R_SUCCESS) {
4909 dns_zone_log(zone, ISC_LOG_ERROR,
4910 "zone_resigninc:find_zone_keys -> %s\n",
4911 dns_result_totext(result));
4915 isc_stdtime_get(&now);
4916 inception = now - 3600; /* Allow for clock skew. */
4917 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
4919 * Spread out signatures over time if they happen to be
4920 * clumped. We don't do this for each add_sigs() call as
4921 * we still want some clustering to occur.
4923 isc_random_get(&jitter);
4924 expire = soaexpire - jitter % 3600;
4927 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
4928 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
4930 name = dns_fixedname_name(&fixed);
4931 result = dns_db_getsigningtime(db, &rdataset, name);
4932 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
4933 dns_zone_log(zone, ISC_LOG_ERROR,
4934 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4935 dns_result_totext(result));
4939 while (result == ISC_R_SUCCESS) {
4940 resign = rdataset.resign;
4941 covers = rdataset.covers;
4942 dns_rdataset_disassociate(&rdataset);
4945 * Stop if we hit the SOA as that means we have walked the
4946 * entire zone. The SOA record should always be the most
4949 /* XXXMPA increase number of RRsets signed pre call */
4950 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
4954 result = del_sigs(zone, db, version, name, covers, &sig_diff,
4955 zone_keys, nkeys, now, ISC_TRUE);
4956 if (result != ISC_R_SUCCESS) {
4957 dns_zone_log(zone, ISC_LOG_ERROR,
4958 "zone_resigninc:del_sigs -> %s\n",
4959 dns_result_totext(result));
4963 result = add_sigs(db, version, name, covers, &sig_diff,
4964 zone_keys, nkeys, zone->mctx, inception,
4965 expire, check_ksk, keyset_kskonly);
4966 if (result != ISC_R_SUCCESS) {
4967 dns_zone_log(zone, ISC_LOG_ERROR,
4968 "zone_resigninc:add_sigs -> %s\n",
4969 dns_result_totext(result));
4972 result = dns_db_getsigningtime(db, &rdataset,
4973 dns_fixedname_name(&fixed));
4974 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
4975 result = ISC_R_SUCCESS;
4978 if (result != ISC_R_SUCCESS)
4979 dns_zone_log(zone, ISC_LOG_ERROR,
4980 "zone_resigninc:dns_db_getsigningtime -> %s\n",
4981 dns_result_totext(result));
4984 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
4987 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
4988 &sig_diff, zone_keys, nkeys, now, ISC_TRUE);
4989 if (result != ISC_R_SUCCESS) {
4990 dns_zone_log(zone, ISC_LOG_ERROR,
4991 "zone_resigninc:del_sigs -> %s\n",
4992 dns_result_totext(result));
4997 * Did we change anything in the zone?
4999 if (ISC_LIST_EMPTY(sig_diff.tuples))
5002 /* Increment SOA serial if we have made changes */
5003 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
5004 if (result != ISC_R_SUCCESS) {
5005 dns_zone_log(zone, ISC_LOG_ERROR,
5006 "zone_resigninc:increment_soa_serial -> %s\n",
5007 dns_result_totext(result));
5012 * Generate maximum life time signatures so that the above loop
5013 * termination is sensible.
5015 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5016 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
5017 soaexpire, check_ksk, keyset_kskonly);
5018 if (result != ISC_R_SUCCESS) {
5019 dns_zone_log(zone, ISC_LOG_ERROR,
5020 "zone_resigninc:add_sigs -> %s\n",
5021 dns_result_totext(result));
5025 /* Write changes to journal file. */
5026 CHECK(zone_journal(zone, &sig_diff, "zone_resigninc"));
5028 /* Everything has succeeded. Commit the changes. */
5029 dns_db_closeversion(db, &version, ISC_TRUE);
5032 dns_diff_clear(&sig_diff);
5033 for (i = 0; i < nkeys; i++)
5034 dst_key_free(&zone_keys[i]);
5035 if (version != NULL) {
5036 dns_db_closeversion(zone->db, &version, ISC_FALSE);
5038 } else if (db != NULL)
5040 if (result == ISC_R_SUCCESS) {
5041 set_resigntime(zone);
5043 zone_needdump(zone, DNS_DUMP_DELAY);
5044 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5048 * Something failed. Retry in 5 minutes.
5050 isc_interval_t ival;
5051 isc_interval_set(&ival, 300, 0);
5052 isc_time_nowplusinterval(&zone->resigntime, &ival);
5057 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
5058 dns_name_t *newname, isc_boolean_t bottom)
5060 isc_result_t result;
5061 dns_dbiterator_t *dbit = NULL;
5062 dns_rdatasetiter_t *rdsit = NULL;
5063 dns_dbnode_t *node = NULL;
5065 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
5066 CHECK(dns_dbiterator_seek(dbit, oldname));
5068 result = dns_dbiterator_next(dbit);
5069 if (result == ISC_R_NOMORE)
5070 CHECK(dns_dbiterator_first(dbit));
5071 CHECK(dns_dbiterator_current(dbit, &node, newname));
5072 if (bottom && dns_name_issubdomain(newname, oldname) &&
5073 !dns_name_equal(newname, oldname)) {
5074 dns_db_detachnode(db, &node);
5078 * Is this node empty?
5080 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
5081 result = dns_rdatasetiter_first(rdsit);
5082 dns_db_detachnode(db, &node);
5083 dns_rdatasetiter_destroy(&rdsit);
5084 if (result != ISC_R_NOMORE)
5089 dns_db_detachnode(db, &node);
5091 dns_dbiterator_destroy(&dbit);
5095 static isc_boolean_t
5096 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5097 dns_rdatatype_t type, dst_key_t *key)
5099 isc_result_t result;
5100 dns_rdataset_t rdataset;
5101 dns_rdata_t rdata = DNS_RDATA_INIT;
5102 dns_rdata_rrsig_t rrsig;
5104 dns_rdataset_init(&rdataset);
5105 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
5106 type, 0, &rdataset, NULL);
5107 if (result != ISC_R_SUCCESS) {
5108 INSIST(!dns_rdataset_isassociated(&rdataset));
5111 for (result = dns_rdataset_first(&rdataset);
5112 result == ISC_R_SUCCESS;
5113 result = dns_rdataset_next(&rdataset)) {
5114 dns_rdataset_current(&rdataset, &rdata);
5115 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5116 INSIST(result == ISC_R_SUCCESS);
5117 if (rrsig.algorithm == dst_key_alg(key) &&
5118 rrsig.keyid == dst_key_id(key)) {
5119 dns_rdataset_disassociate(&rdataset);
5122 dns_rdata_reset(&rdata);
5124 dns_rdataset_disassociate(&rdataset);
5129 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5130 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
5133 dns_fixedname_t fixed;
5135 dns_rdata_t rdata = DNS_RDATA_INIT;
5136 isc_result_t result;
5137 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
5139 dns_fixedname_init(&fixed);
5140 next = dns_fixedname_name(&fixed);
5142 CHECK(next_active(db, version, name, next, bottom));
5143 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
5145 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
5152 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
5153 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5154 isc_boolean_t build_nsec, dst_key_t *key,
5155 isc_stdtime_t inception, isc_stdtime_t expire,
5156 unsigned int minimum, isc_boolean_t is_ksk,
5157 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
5158 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
5160 isc_result_t result;
5161 dns_rdatasetiter_t *iterator = NULL;
5162 dns_rdataset_t rdataset;
5163 dns_rdata_t rdata = DNS_RDATA_INIT;
5164 isc_buffer_t buffer;
5165 unsigned char data[1024];
5166 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
5167 seen_nsec3, seen_ds;
5168 isc_boolean_t bottom;
5170 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5171 if (result != ISC_R_SUCCESS) {
5172 if (result == ISC_R_NOTFOUND)
5173 result = ISC_R_SUCCESS;
5177 dns_rdataset_init(&rdataset);
5178 isc_buffer_init(&buffer, data, sizeof(data));
5179 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
5180 seen_nsec3 = seen_ds = ISC_FALSE;
5181 for (result = dns_rdatasetiter_first(iterator);
5182 result == ISC_R_SUCCESS;
5183 result = dns_rdatasetiter_next(iterator)) {
5184 dns_rdatasetiter_current(iterator, &rdataset);
5185 if (rdataset.type == dns_rdatatype_soa)
5186 seen_soa = ISC_TRUE;
5187 else if (rdataset.type == dns_rdatatype_ns)
5189 else if (rdataset.type == dns_rdatatype_ds)
5191 else if (rdataset.type == dns_rdatatype_dname)
5192 seen_dname = ISC_TRUE;
5193 else if (rdataset.type == dns_rdatatype_nsec)
5194 seen_nsec = ISC_TRUE;
5195 else if (rdataset.type == dns_rdatatype_nsec3)
5196 seen_nsec3 = ISC_TRUE;
5197 if (rdataset.type != dns_rdatatype_rrsig)
5199 dns_rdataset_disassociate(&rdataset);
5201 if (result != ISC_R_NOMORE)
5203 if (seen_ns && !seen_soa)
5204 *delegation = ISC_TRUE;
5206 * Going from insecure to NSEC3.
5207 * Don't generate NSEC3 records for NSEC3 records.
5209 if (build_nsec3 && !seen_nsec3 && seen_rr) {
5210 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
5211 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
5216 * Going from insecure to NSEC.
5217 * Don't generate NSEC records for NSEC3 records.
5219 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
5220 /* Build and add NSEC. */
5221 bottom = (seen_ns && !seen_soa) || seen_dname;
5223 * Build a NSEC record except at the origin.
5225 if (!dns_name_equal(name, dns_db_origin(db))) {
5226 CHECK(add_nsec(db, version, name, node, minimum,
5228 /* Count a NSEC generation as a signature generation. */
5232 result = dns_rdatasetiter_first(iterator);
5233 while (result == ISC_R_SUCCESS) {
5234 dns_rdatasetiter_current(iterator, &rdataset);
5235 if (rdataset.type == dns_rdatatype_soa ||
5236 rdataset.type == dns_rdatatype_rrsig)
5238 if (rdataset.type == dns_rdatatype_dnskey) {
5239 if (!is_ksk && keyset_kskonly)
5244 rdataset.type != dns_rdatatype_ds &&
5245 rdataset.type != dns_rdatatype_nsec)
5247 if (signed_with_key(db, node, version, rdataset.type, key))
5249 /* Calculate the signature, creating a RRSIG RDATA. */
5250 isc_buffer_clear(&buffer);
5251 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
5252 &expire, mctx, &buffer, &rdata));
5253 /* Update the database and journal with the RRSIG. */
5254 /* XXX inefficient - will cause dataset merging */
5255 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
5256 name, rdataset.ttl, &rdata));
5257 dns_rdata_reset(&rdata);
5260 dns_rdataset_disassociate(&rdataset);
5261 result = dns_rdatasetiter_next(iterator);
5263 if (result == ISC_R_NOMORE)
5264 result = ISC_R_SUCCESS;
5266 *delegation = ISC_TRUE;
5268 if (dns_rdataset_isassociated(&rdataset))
5269 dns_rdataset_disassociate(&rdataset);
5270 if (iterator != NULL)
5271 dns_rdatasetiter_destroy(&iterator);
5276 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
5279 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5280 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
5282 isc_result_t result;
5283 dns_rdataset_t rdataset;
5284 dns_dbnode_t *node = NULL;
5286 CHECK(dns_db_getoriginnode(db, &node));
5288 dns_rdataset_init(&rdataset);
5289 result = dns_db_findrdataset(db, node, version,
5292 0, &rdataset, NULL);
5293 if (dns_rdataset_isassociated(&rdataset))
5294 dns_rdataset_disassociate(&rdataset);
5295 if (result == ISC_R_NOTFOUND)
5297 if (result != ISC_R_SUCCESS)
5300 CHECK(delete_nsec(db, version, node, name, diff));
5301 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
5303 result = ISC_R_SUCCESS;
5306 dns_db_detachnode(db, &node);
5311 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
5312 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5313 dns_ttl_t minimum, dns_diff_t *diff)
5315 isc_result_t result;
5316 dns_dbnode_t *node = NULL;
5317 dns_rdataset_t rdataset;
5318 dns_rdata_t rdata = DNS_RDATA_INIT;
5319 unsigned char data[5];
5320 isc_boolean_t seen_done = ISC_FALSE;
5321 isc_boolean_t have_rr = ISC_FALSE;
5323 dns_rdataset_init(&rdataset);
5324 result = dns_db_getoriginnode(signing->db, &node);
5325 if (result != ISC_R_SUCCESS)
5328 result = dns_db_findrdataset(signing->db, node, version,
5329 zone->privatetype, dns_rdatatype_none,
5330 0, &rdataset, NULL);
5331 if (result == ISC_R_NOTFOUND) {
5332 INSIST(!dns_rdataset_isassociated(&rdataset));
5333 result = ISC_R_SUCCESS;
5336 if (result != ISC_R_SUCCESS) {
5337 INSIST(!dns_rdataset_isassociated(&rdataset));
5340 for (result = dns_rdataset_first(&rdataset);
5341 result == ISC_R_SUCCESS;
5342 result = dns_rdataset_next(&rdataset)) {
5343 dns_rdataset_current(&rdataset, &rdata);
5345 * If we don't match the algorithm or keyid skip the record.
5347 if (rdata.length != 5 ||
5348 rdata.data[0] != signing->algorithm ||
5349 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
5350 rdata.data[2] != (signing->keyid & 0xff)) {
5352 dns_rdata_reset(&rdata);
5356 * We have a match. If we were signing (!signing->delete)
5357 * and we already have a record indicating that we have
5358 * finished signing (rdata.data[4] != 0) then keep it.
5359 * Otherwise it needs to be deleted as we have removed all
5360 * the signatures (signing->delete), so any record indicating
5361 * completion is now out of date, or we have finished signing
5362 * with the new record so we no longer need to remember that
5363 * we need to sign the zone with the matching key across a
5364 * nameserver re-start.
5366 if (!signing->delete && rdata.data[4] != 0) {
5367 seen_done = ISC_TRUE;
5370 CHECK(update_one_rr(signing->db, version, diff,
5371 DNS_DIFFOP_DEL, &zone->origin,
5372 rdataset.ttl, &rdata));
5373 dns_rdata_reset(&rdata);
5375 if (result == ISC_R_NOMORE)
5376 result = ISC_R_SUCCESS;
5377 if (!signing->delete && !seen_done) {
5379 * If we were signing then we need to indicate that we have
5380 * finished signing the zone with this key. If it is already
5381 * there we don't need to add it a second time.
5383 data[0] = signing->algorithm;
5384 data[1] = (signing->keyid >> 8) & 0xff;
5385 data[2] = signing->keyid & 0xff;
5388 rdata.length = sizeof(data);
5390 rdata.type = zone->privatetype;
5391 rdata.rdclass = dns_db_class(signing->db);
5392 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
5393 &zone->origin, rdataset.ttl, &rdata));
5394 } else if (!have_rr) {
5395 dns_name_t *origin = dns_db_origin(signing->db);
5397 * Rebuild the NSEC/NSEC3 record for the origin as we no
5398 * longer have any private records.
5401 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
5402 minimum, ISC_FALSE, diff));
5403 CHECK(updatesecure(signing->db, version, origin, minimum,
5408 if (dns_rdataset_isassociated(&rdataset))
5409 dns_rdataset_disassociate(&rdataset);
5411 dns_db_detachnode(signing->db, &node);
5416 * If 'active' is set then we are not done with the chain yet so only
5417 * delete the nsec3param record which indicates a full chain exists
5421 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
5422 isc_boolean_t active, dns_rdatatype_t privatetype,
5425 dns_dbnode_t *node = NULL;
5426 dns_name_t *name = dns_db_origin(db);
5427 dns_rdata_t rdata = DNS_RDATA_INIT;
5428 dns_rdataset_t rdataset;
5429 dns_rdata_nsec3param_t nsec3param;
5430 isc_result_t result;
5431 isc_buffer_t buffer;
5432 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
5435 dns_rdataset_init(&rdataset);
5437 result = dns_db_getoriginnode(db, &node);
5438 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5439 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
5440 0, 0, &rdataset, NULL);
5441 if (result == ISC_R_NOTFOUND)
5443 if (result != ISC_R_SUCCESS)
5447 * Preserve the existing ttl.
5452 * Delete all NSEC3PARAM records which match that in nsec3chain.
5454 for (result = dns_rdataset_first(&rdataset);
5455 result == ISC_R_SUCCESS;
5456 result = dns_rdataset_next(&rdataset)) {
5458 dns_rdataset_current(&rdataset, &rdata);
5459 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
5461 if (nsec3param.hash != chain->nsec3param.hash ||
5462 (active && nsec3param.flags != 0) ||
5463 nsec3param.iterations != chain->nsec3param.iterations ||
5464 nsec3param.salt_length != chain->nsec3param.salt_length ||
5465 memcmp(nsec3param.salt, chain->nsec3param.salt,
5466 nsec3param.salt_length)) {
5467 dns_rdata_reset(&rdata);
5471 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
5472 name, rdataset.ttl, &rdata));
5473 dns_rdata_reset(&rdata);
5475 if (result != ISC_R_NOMORE)
5478 dns_rdataset_disassociate(&rdataset);
5485 * Delete all private records which match that in nsec3chain.
5487 result = dns_db_findrdataset(db, node, ver, privatetype,
5488 0, 0, &rdataset, NULL);
5489 if (result == ISC_R_NOTFOUND)
5491 if (result != ISC_R_SUCCESS)
5494 for (result = dns_rdataset_first(&rdataset);
5495 result == ISC_R_SUCCESS;
5496 result = dns_rdataset_next(&rdataset)) {
5497 dns_rdata_t private = DNS_RDATA_INIT;
5498 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
5500 dns_rdataset_current(&rdataset, &private);
5501 if (!dns_nsec3param_fromprivate(&private, &rdata,
5504 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
5506 if (nsec3param.hash != chain->nsec3param.hash ||
5507 nsec3param.iterations != chain->nsec3param.iterations ||
5508 nsec3param.salt_length != chain->nsec3param.salt_length ||
5509 memcmp(nsec3param.salt, chain->nsec3param.salt,
5510 nsec3param.salt_length)) {
5511 dns_rdata_reset(&rdata);
5515 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
5516 name, rdataset.ttl, &private));
5517 dns_rdata_reset(&rdata);
5519 if (result != ISC_R_NOMORE)
5523 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
5524 result = ISC_R_SUCCESS;
5529 * Add a NSEC3PARAM record which matches that in nsec3chain but
5530 * with all flags bits cleared.
5532 * Note: we do not clear chain->nsec3param.flags as this change
5535 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
5536 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
5537 dns_rdatatype_nsec3param,
5538 &chain->nsec3param, &buffer));
5539 rdata.data[1] = 0; /* Clear flag bits. */
5540 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
5543 dns_db_detachnode(db, &node);
5544 if (dns_rdataset_isassociated(&rdataset))
5545 dns_rdataset_disassociate(&rdataset);
5550 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
5551 dns_name_t *name, dns_diff_t *diff)
5553 dns_rdataset_t rdataset;
5554 isc_result_t result;
5556 dns_rdataset_init(&rdataset);
5558 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
5559 0, 0, &rdataset, NULL);
5560 if (result == ISC_R_NOTFOUND)
5561 return (ISC_R_SUCCESS);
5562 if (result != ISC_R_SUCCESS)
5564 for (result = dns_rdataset_first(&rdataset);
5565 result == ISC_R_SUCCESS;
5566 result = dns_rdataset_next(&rdataset)) {
5567 dns_rdata_t rdata = DNS_RDATA_INIT;
5569 dns_rdataset_current(&rdataset, &rdata);
5570 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
5571 rdataset.ttl, &rdata));
5573 if (result == ISC_R_NOMORE)
5574 result = ISC_R_SUCCESS;
5576 dns_rdataset_disassociate(&rdataset);
5581 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
5582 dns_name_t *name, const dns_rdata_nsec3param_t *param,
5585 dns_rdataset_t rdataset;
5586 dns_rdata_nsec3_t nsec3;
5587 isc_result_t result;
5589 dns_rdataset_init(&rdataset);
5590 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
5591 0, 0, &rdataset, NULL);
5592 if (result == ISC_R_NOTFOUND)
5593 return (ISC_R_SUCCESS);
5594 if (result != ISC_R_SUCCESS)
5597 for (result = dns_rdataset_first(&rdataset);
5598 result == ISC_R_SUCCESS;
5599 result = dns_rdataset_next(&rdataset)) {
5600 dns_rdata_t rdata = DNS_RDATA_INIT;
5602 dns_rdataset_current(&rdataset, &rdata);
5603 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
5604 if (nsec3.hash != param->hash ||
5605 nsec3.iterations != param->iterations ||
5606 nsec3.salt_length != param->salt_length ||
5607 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
5609 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
5610 rdataset.ttl, &rdata));
5612 if (result == ISC_R_NOMORE)
5613 result = ISC_R_SUCCESS;
5615 dns_rdataset_disassociate(&rdataset);
5620 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
5621 const dns_rdata_nsec3param_t *param,
5622 isc_boolean_t *answer)
5624 dns_dbnode_t *node = NULL;
5625 dns_rdata_t rdata = DNS_RDATA_INIT;
5626 dns_rdata_nsec3param_t myparam;
5627 dns_rdataset_t rdataset;
5628 isc_result_t result;
5630 *answer = ISC_FALSE;
5632 result = dns_db_getoriginnode(db, &node);
5633 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5635 dns_rdataset_init(&rdataset);
5637 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
5638 0, 0, &rdataset, NULL);
5639 if (result == ISC_R_SUCCESS) {
5640 dns_rdataset_disassociate(&rdataset);
5641 dns_db_detachnode(db, &node);
5644 if (result != ISC_R_NOTFOUND) {
5645 dns_db_detachnode(db, &node);
5649 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
5650 0, 0, &rdataset, NULL);
5651 if (result == ISC_R_NOTFOUND) {
5653 dns_db_detachnode(db, &node);
5654 return (ISC_R_SUCCESS);
5656 if (result != ISC_R_SUCCESS) {
5657 dns_db_detachnode(db, &node);
5661 for (result = dns_rdataset_first(&rdataset);
5662 result == ISC_R_SUCCESS;
5663 result = dns_rdataset_next(&rdataset)) {
5664 dns_rdataset_current(&rdataset, &rdata);
5665 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
5666 dns_rdata_reset(&rdata);
5668 * Ignore any NSEC3PARAM removals.
5670 if (NSEC3REMOVE(myparam.flags))
5673 * Ignore the chain that we are in the process of deleting.
5675 if (myparam.hash == param->hash &&
5676 myparam.iterations == param->iterations &&
5677 myparam.salt_length == param->salt_length &&
5678 !memcmp(myparam.salt, param->salt, myparam.salt_length))
5681 * Found an active NSEC3 chain.
5685 if (result == ISC_R_NOMORE) {
5687 result = ISC_R_SUCCESS;
5691 if (dns_rdataset_isassociated(&rdataset))
5692 dns_rdataset_disassociate(&rdataset);
5693 dns_db_detachnode(db, &node);
5698 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
5699 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
5700 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
5701 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
5702 dns_diff_t *sig_diff)
5704 dns_difftuple_t *tuple;
5705 isc_result_t result;
5707 for (tuple = ISC_LIST_HEAD(diff->tuples);
5709 tuple = ISC_LIST_HEAD(diff->tuples)) {
5710 result = del_sigs(zone, db, version, &tuple->name,
5711 tuple->rdata.type, sig_diff,
5712 zone_keys, nkeys, now, ISC_FALSE);
5713 if (result != ISC_R_SUCCESS) {
5714 dns_zone_log(zone, ISC_LOG_ERROR,
5715 "update_sigs:del_sigs -> %s\n",
5716 dns_result_totext(result));
5719 result = add_sigs(db, version, &tuple->name,
5720 tuple->rdata.type, sig_diff,
5721 zone_keys, nkeys, zone->mctx, inception,
5722 expire, check_ksk, keyset_kskonly);
5723 if (result != ISC_R_SUCCESS) {
5724 dns_zone_log(zone, ISC_LOG_ERROR,
5725 "update_sigs:add_sigs -> %s\n",
5726 dns_result_totext(result));
5731 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5732 while (next != NULL &&
5733 (tuple->rdata.type != next->rdata.type ||
5734 !dns_name_equal(&tuple->name, &next->name)))
5735 next = ISC_LIST_NEXT(next, link);
5736 ISC_LIST_UNLINK(diff->tuples, tuple, link);
5737 dns_diff_appendminimal(sig_diff, &tuple);
5738 INSIST(tuple == NULL);
5740 } while (tuple != NULL);
5742 return (ISC_R_SUCCESS);
5746 * Incrementally build and sign a new NSEC3 chain using the parameters
5750 zone_nsec3chain(dns_zone_t *zone) {
5751 dns_db_t *db = NULL;
5752 dns_dbnode_t *node = NULL;
5753 dns_dbversion_t *version = NULL;
5754 dns_diff_t sig_diff;
5755 dns_diff_t nsec_diff;
5756 dns_diff_t nsec3_diff;
5757 dns_diff_t param_diff;
5758 dns_fixedname_t fixed;
5759 dns_fixedname_t nextfixed;
5760 dns_name_t *name, *nextname;
5761 dns_rdataset_t rdataset;
5762 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
5763 dns_nsec3chainlist_t cleanup;
5764 dst_key_t *zone_keys[MAXZONEKEYS];
5765 isc_int32_t signatures;
5766 isc_boolean_t check_ksk, keyset_kskonly;
5767 isc_boolean_t delegation;
5768 isc_boolean_t first;
5769 isc_result_t result;
5770 isc_stdtime_t now, inception, soaexpire, expire;
5771 isc_uint32_t jitter;
5773 unsigned int nkeys = 0;
5775 isc_boolean_t unsecure = ISC_FALSE;
5776 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
5777 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
5778 dns_rdatasetiter_t *iterator = NULL;
5779 isc_boolean_t buildnsecchain;
5780 isc_boolean_t updatensec = ISC_FALSE;
5781 dns_rdatatype_t privatetype = zone->privatetype;
5783 dns_rdataset_init(&rdataset);
5784 dns_fixedname_init(&fixed);
5785 name = dns_fixedname_name(&fixed);
5786 dns_fixedname_init(&nextfixed);
5787 nextname = dns_fixedname_name(&nextfixed);
5788 dns_diff_init(zone->mctx, ¶m_diff);
5789 dns_diff_init(zone->mctx, &nsec3_diff);
5790 dns_diff_init(zone->mctx, &nsec_diff);
5791 dns_diff_init(zone->mctx, &sig_diff);
5792 sig_diff.resign = zone->sigresigninginterval;
5793 ISC_LIST_INIT(cleanup);
5796 * Updates are disabled. Pause for 5 minutes.
5798 if (zone->update_disabled) {
5799 result = ISC_R_FAILURE;
5803 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5804 dns_db_attach(zone->db, &db);
5805 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5807 result = dns_db_newversion(db, &version);
5808 if (result != ISC_R_SUCCESS) {
5809 dns_zone_log(zone, ISC_LOG_ERROR,
5810 "zone_nsec3chain:dns_db_newversion -> %s\n",
5811 dns_result_totext(result));
5815 result = find_zone_keys(zone, db, version, zone->mctx,
5816 MAXZONEKEYS, zone_keys, &nkeys);
5817 if (result != ISC_R_SUCCESS) {
5818 dns_zone_log(zone, ISC_LOG_ERROR,
5819 "zone_nsec3chain:find_zone_keys -> %s\n",
5820 dns_result_totext(result));
5824 isc_stdtime_get(&now);
5825 inception = now - 3600; /* Allow for clock skew. */
5826 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5829 * Spread out signatures over time if they happen to be
5830 * clumped. We don't do this for each add_sigs() call as
5831 * we still want some clustering to occur.
5833 isc_random_get(&jitter);
5834 expire = soaexpire - jitter % 3600;
5836 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5837 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
5840 * We keep pulling nodes off each iterator in turn until
5841 * we have no more nodes to pull off or we reach the limits
5844 nodes = zone->nodes;
5845 signatures = zone->signatures;
5847 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
5851 if (nsec3chain != NULL)
5852 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
5854 * Generate new NSEC3 chains first.
5856 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
5858 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
5860 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5861 if (nsec3chain->done || nsec3chain->db != zone->db) {
5862 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
5863 ISC_LIST_APPEND(cleanup, nsec3chain, link);
5865 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5867 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
5871 * Possible future db.
5873 if (nsec3chain->db != db) {
5877 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
5880 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
5882 if (nsec3chain->delete_nsec) {
5883 delegation = ISC_FALSE;
5884 dns_dbiterator_pause(nsec3chain->dbiterator);
5885 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
5889 * On the first pass we need to check if the current node
5890 * has not been obscured.
5892 delegation = ISC_FALSE;
5893 unsecure = ISC_FALSE;
5895 dns_fixedname_t ffound;
5897 dns_fixedname_init(&ffound);
5898 found = dns_fixedname_name(&ffound);
5899 result = dns_db_find(db, name, version,
5901 DNS_DBFIND_NOWILD, 0, NULL, found,
5903 if ((result == DNS_R_DELEGATION ||
5904 result == DNS_R_DNAME) &&
5905 !dns_name_equal(name, found)) {
5907 * Remember the obscuring name so that
5908 * we skip all obscured names.
5910 dns_name_copy(found, name, NULL);
5911 delegation = ISC_TRUE;
5917 * Check to see if this is a bottom of zone node.
5919 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5920 if (result == ISC_R_NOTFOUND) /* Empty node? */
5922 if (result != ISC_R_SUCCESS)
5925 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
5927 for (result = dns_rdatasetiter_first(iterator);
5928 result == ISC_R_SUCCESS;
5929 result = dns_rdatasetiter_next(iterator)) {
5930 dns_rdatasetiter_current(iterator, &rdataset);
5931 INSIST(rdataset.type != dns_rdatatype_nsec3);
5932 if (rdataset.type == dns_rdatatype_soa)
5933 seen_soa = ISC_TRUE;
5934 else if (rdataset.type == dns_rdatatype_ns)
5936 else if (rdataset.type == dns_rdatatype_dname)
5937 seen_dname = ISC_TRUE;
5938 else if (rdataset.type == dns_rdatatype_ds)
5940 else if (rdataset.type == dns_rdatatype_nsec)
5941 seen_nsec = ISC_TRUE;
5942 dns_rdataset_disassociate(&rdataset);
5944 dns_rdatasetiter_destroy(&iterator);
5946 * Is there a NSEC chain than needs to be cleaned up?
5949 nsec3chain->seen_nsec = ISC_TRUE;
5950 if (seen_ns && !seen_soa && !seen_ds)
5951 unsecure = ISC_TRUE;
5952 if ((seen_ns && !seen_soa) || seen_dname)
5953 delegation = ISC_TRUE;
5958 dns_dbiterator_pause(nsec3chain->dbiterator);
5959 result = dns_nsec3_addnsec3(db, version, name,
5960 &nsec3chain->nsec3param,
5961 zone->minimum, unsecure,
5963 if (result != ISC_R_SUCCESS) {
5964 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
5965 "dns_nsec3_addnsec3 -> %s\n",
5966 dns_result_totext(result));
5971 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
5972 * two signatures. Additionally there will, in general, be
5973 * two signature generated below.
5975 * If we are only changing the optout flag the cost is half
5976 * that of the cost of generating a completely new chain.
5981 * Go onto next node.
5985 dns_db_detachnode(db, &node);
5987 result = dns_dbiterator_next(nsec3chain->dbiterator);
5989 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
5990 CHECK(fixup_nsec3param(db, version, nsec3chain,
5991 ISC_FALSE, privatetype,
5994 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
5997 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6000 if (result == ISC_R_NOMORE) {
6001 dns_dbiterator_pause(nsec3chain->dbiterator);
6002 if (nsec3chain->seen_nsec) {
6003 CHECK(fixup_nsec3param(db, version,
6008 nsec3chain->delete_nsec = ISC_TRUE;
6011 CHECK(fixup_nsec3param(db, version, nsec3chain,
6012 ISC_FALSE, privatetype,
6015 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6018 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6020 } else if (result != ISC_R_SUCCESS) {
6021 dns_zone_log(zone, ISC_LOG_ERROR,
6023 "dns_dbiterator_next -> %s\n",
6024 dns_result_totext(result));
6026 } else if (delegation) {
6027 dns_dbiterator_current(nsec3chain->dbiterator,
6029 dns_db_detachnode(db, &node);
6030 if (!dns_name_issubdomain(nextname, name))
6038 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6043 dns_dbiterator_pause(nsec3chain->dbiterator);
6044 nsec3chain = nextnsec3chain;
6046 if (nsec3chain != NULL)
6047 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6054 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6057 buildnsecchain = ISC_FALSE;
6058 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6060 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6063 if (nsec3chain->db != db)
6064 goto next_removechain;
6066 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
6067 goto next_removechain;
6070 * Work out if we need to build a NSEC chain as a consequence
6071 * of removing this NSEC3 chain.
6073 if (first && !updatensec &&
6074 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) {
6075 result = need_nsec_chain(db, version,
6076 &nsec3chain->nsec3param,
6078 if (result != ISC_R_SUCCESS) {
6079 dns_zone_log(zone, ISC_LOG_ERROR,
6081 "need_nsec_chain -> %s\n",
6082 dns_result_totext(result));
6088 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
6089 "buildnsecchain = %u\n", buildnsecchain);
6091 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6092 delegation = ISC_FALSE;
6094 if (!buildnsecchain) {
6096 * Delete the NSECPARAM record that matches this chain.
6099 result = fixup_nsec3param(db, version,
6101 ISC_TRUE, privatetype,
6103 if (result != ISC_R_SUCCESS) {
6104 dns_zone_log(zone, ISC_LOG_ERROR,
6106 "fixup_nsec3param -> %s\n",
6107 dns_result_totext(result));
6113 * Delete the NSEC3 records.
6115 result = deletematchingnsec3(db, version, node, name,
6116 &nsec3chain->nsec3param,
6118 if (result != ISC_R_SUCCESS) {
6119 dns_zone_log(zone, ISC_LOG_ERROR,
6121 "deletematchingnsec3 -> %s\n",
6122 dns_result_totext(result));
6125 goto next_removenode;
6129 dns_fixedname_t ffound;
6131 dns_fixedname_init(&ffound);
6132 found = dns_fixedname_name(&ffound);
6133 result = dns_db_find(db, name, version,
6135 DNS_DBFIND_NOWILD, 0, NULL, found,
6137 if ((result == DNS_R_DELEGATION ||
6138 result == DNS_R_DNAME) &&
6139 !dns_name_equal(name, found)) {
6141 * Remember the obscuring name so that
6142 * we skip all obscured names.
6144 dns_name_copy(found, name, NULL);
6145 delegation = ISC_TRUE;
6146 goto next_removenode;
6151 * Check to see if this is a bottom of zone node.
6153 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6154 if (result == ISC_R_NOTFOUND) /* Empty node? */
6155 goto next_removenode;
6156 if (result != ISC_R_SUCCESS)
6159 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
6160 seen_rr = ISC_FALSE;
6161 for (result = dns_rdatasetiter_first(iterator);
6162 result == ISC_R_SUCCESS;
6163 result = dns_rdatasetiter_next(iterator)) {
6164 dns_rdatasetiter_current(iterator, &rdataset);
6165 if (rdataset.type == dns_rdatatype_soa)
6166 seen_soa = ISC_TRUE;
6167 else if (rdataset.type == dns_rdatatype_ns)
6169 else if (rdataset.type == dns_rdatatype_dname)
6170 seen_dname = ISC_TRUE;
6171 else if (rdataset.type == dns_rdatatype_nsec)
6172 seen_nsec = ISC_TRUE;
6173 else if (rdataset.type == dns_rdatatype_nsec3)
6174 seen_nsec3 = ISC_TRUE;
6175 if (rdataset.type != dns_rdatatype_rrsig)
6177 dns_rdataset_disassociate(&rdataset);
6179 dns_rdatasetiter_destroy(&iterator);
6181 if (!seen_rr || seen_nsec3 || seen_nsec)
6182 goto next_removenode;
6183 if ((seen_ns && !seen_soa) || seen_dname)
6184 delegation = ISC_TRUE;
6187 * Add a NSEC record except at the origin.
6189 if (!dns_name_equal(name, dns_db_origin(db))) {
6190 dns_dbiterator_pause(nsec3chain->dbiterator);
6191 CHECK(add_nsec(db, version, name, node, zone->minimum,
6192 delegation, &nsec_diff));
6197 dns_db_detachnode(db, &node);
6199 result = dns_dbiterator_next(nsec3chain->dbiterator);
6200 if (result == ISC_R_NOMORE && buildnsecchain) {
6202 * The NSEC chain should now be built.
6203 * We can now remove the NSEC3 chain.
6205 updatensec = ISC_TRUE;
6206 goto same_removechain;
6208 if (result == ISC_R_NOMORE) {
6210 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6213 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6214 dns_dbiterator_pause(nsec3chain->dbiterator);
6215 result = fixup_nsec3param(db, version,
6216 nsec3chain, ISC_FALSE,
6219 if (result != ISC_R_SUCCESS) {
6220 dns_zone_log(zone, ISC_LOG_ERROR,
6222 "fixup_nsec3param -> %s\n",
6223 dns_result_totext(result));
6226 goto next_removechain;
6227 } else if (result != ISC_R_SUCCESS) {
6228 dns_zone_log(zone, ISC_LOG_ERROR,
6230 "dns_dbiterator_next -> %s\n",
6231 dns_result_totext(result));
6233 } else if (delegation) {
6234 dns_dbiterator_current(nsec3chain->dbiterator,
6236 dns_db_detachnode(db, &node);
6237 if (!dns_name_issubdomain(nextname, name))
6245 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6246 buildnsecchain = ISC_FALSE;
6251 dns_dbiterator_pause(nsec3chain->dbiterator);
6252 nsec3chain = nextnsec3chain;
6257 * We may need to update the NSEC/NSEC3 records for the zone apex.
6259 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
6260 isc_boolean_t rebuild_nsec = ISC_FALSE,
6261 rebuild_nsec3 = ISC_FALSE;
6262 result = dns_db_getoriginnode(db, &node);
6263 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6264 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6265 if (result != ISC_R_SUCCESS) {
6266 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6267 "dns_db_allrdatasets -> %s\n",
6268 dns_result_totext(result));
6271 for (result = dns_rdatasetiter_first(iterator);
6272 result == ISC_R_SUCCESS;
6273 result = dns_rdatasetiter_next(iterator)) {
6274 dns_rdatasetiter_current(iterator, &rdataset);
6275 if (rdataset.type == dns_rdatatype_nsec)
6276 rebuild_nsec = ISC_TRUE;
6277 if (rdataset.type == dns_rdatatype_nsec3param)
6278 rebuild_nsec3 = ISC_TRUE;
6279 dns_rdataset_disassociate(&rdataset);
6281 dns_rdatasetiter_destroy(&iterator);
6282 dns_db_detachnode(db, &node);
6285 if (nsec3chain != NULL)
6286 dns_dbiterator_pause(nsec3chain->dbiterator);
6287 result = updatesecure(db, version, &zone->origin,
6288 zone->minimum, ISC_TRUE,
6290 if (result != ISC_R_SUCCESS) {
6291 dns_zone_log(zone, ISC_LOG_ERROR,
6293 "updatesecure -> %s\n",
6294 dns_result_totext(result));
6298 if (rebuild_nsec3) {
6299 result = dns_nsec3_addnsec3s(db, version,
6301 zone->minimum, ISC_FALSE,
6303 if (result != ISC_R_SUCCESS) {
6304 dns_zone_log(zone, ISC_LOG_ERROR,
6306 "dns_nsec3_addnsec3s -> %s\n",
6307 dns_result_totext(result));
6314 * Add / update signatures for the NSEC3 records.
6316 result = update_sigs(&nsec3_diff, db, version, zone_keys,
6317 nkeys, zone, inception, expire, now,
6318 check_ksk, keyset_kskonly, &sig_diff);
6319 if (result != ISC_R_SUCCESS) {
6320 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6321 "update_sigs -> %s\n", dns_result_totext(result));
6326 * We have changed the NSEC3PARAM or private RRsets
6327 * above so we need to update the signatures.
6329 result = update_sigs(¶m_diff, db, version, zone_keys,
6330 nkeys, zone, inception, expire, now,
6331 check_ksk, keyset_kskonly, &sig_diff);
6332 if (result != ISC_R_SUCCESS) {
6333 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6334 "update_sigs -> %s\n", dns_result_totext(result));
6339 if (nsec3chain != NULL)
6340 dns_dbiterator_pause(nsec3chain->dbiterator);
6341 result = updatesecure(db, version, &zone->origin,
6342 zone->minimum, ISC_FALSE, &nsec_diff);
6343 if (result != ISC_R_SUCCESS) {
6344 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6345 "updatesecure -> %s\n",
6346 dns_result_totext(result));
6351 result = update_sigs(&nsec_diff, db, version, zone_keys,
6352 nkeys, zone, inception, expire, now,
6353 check_ksk, keyset_kskonly, &sig_diff);
6354 if (result != ISC_R_SUCCESS) {
6355 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6356 "update_sigs -> %s\n", dns_result_totext(result));
6361 * If we made no effective changes to the zone then we can just
6362 * cleanup otherwise we need to increment the serial.
6364 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL)
6367 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6368 &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
6369 if (result != ISC_R_SUCCESS) {
6370 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6371 "del_sigs -> %s\n", dns_result_totext(result));
6375 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
6376 if (result != ISC_R_SUCCESS) {
6377 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6378 "increment_soa_serial -> %s\n",
6379 dns_result_totext(result));
6383 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6384 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
6385 soaexpire, check_ksk, keyset_kskonly);
6386 if (result != ISC_R_SUCCESS) {
6387 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6388 "add_sigs -> %s\n", dns_result_totext(result));
6392 /* Write changes to journal file. */
6393 CHECK(zone_journal(zone, &sig_diff, "zone_nsec3chain"));
6396 zone_needdump(zone, DNS_DUMP_DELAY);
6397 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6402 * Pause all iterators so that dns_db_closeversion() can succeed.
6405 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6407 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
6408 dns_dbiterator_pause(nsec3chain->dbiterator);
6412 * Everything has succeeded. Commit the changes.
6414 dns_db_closeversion(db, &version, ISC_TRUE);
6417 * Everything succeeded so we can clean these up now.
6419 nsec3chain = ISC_LIST_HEAD(cleanup);
6420 while (nsec3chain != NULL) {
6421 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
6422 dns_db_detach(&nsec3chain->db);
6423 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6424 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6425 nsec3chain = ISC_LIST_HEAD(cleanup);
6428 set_resigntime(zone);
6431 if (result != ISC_R_SUCCESS)
6432 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s\n",
6433 dns_result_totext(result));
6435 * On error roll back the current nsec3chain.
6437 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
6438 if (nsec3chain->done) {
6439 dns_db_detach(&nsec3chain->db);
6440 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6441 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6443 result = dns_dbiterator_first(nsec3chain->dbiterator);
6444 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6445 dns_dbiterator_pause(nsec3chain->dbiterator);
6446 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
6451 * Rollback the cleanup list.
6453 nsec3chain = ISC_LIST_TAIL(cleanup);
6454 while (nsec3chain != NULL) {
6455 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
6456 if (nsec3chain->done) {
6457 dns_db_detach(&nsec3chain->db);
6458 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6459 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6462 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
6464 result = dns_dbiterator_first(nsec3chain->dbiterator);
6465 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6466 dns_dbiterator_pause(nsec3chain->dbiterator);
6467 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
6469 nsec3chain = ISC_LIST_TAIL(cleanup);
6473 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6475 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
6476 dns_dbiterator_pause(nsec3chain->dbiterator);
6479 dns_diff_clear(¶m_diff);
6480 dns_diff_clear(&nsec3_diff);
6481 dns_diff_clear(&nsec_diff);
6482 dns_diff_clear(&sig_diff);
6484 if (iterator != NULL)
6485 dns_rdatasetiter_destroy(&iterator);
6487 for (i = 0; i < nkeys; i++)
6488 dst_key_free(&zone_keys[i]);
6491 dns_db_detachnode(db, &node);
6492 if (version != NULL) {
6493 dns_db_closeversion(db, &version, ISC_FALSE);
6495 } else if (db != NULL)
6499 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
6501 if (zone->update_disabled || result != ISC_R_SUCCESS)
6502 isc_interval_set(&i, 60, 0); /* 1 minute */
6504 isc_interval_set(&i, 0, 10000000); /* 10 ms */
6505 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
6507 isc_time_settoepoch(&zone->nsec3chaintime);
6512 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6513 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
6514 isc_uint16_t keyid, dns_diff_t *diff)
6516 dns_rdata_rrsig_t rrsig;
6517 dns_rdataset_t rdataset;
6518 dns_rdatasetiter_t *iterator = NULL;
6519 isc_result_t result;
6521 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6522 if (result != ISC_R_SUCCESS) {
6523 if (result == ISC_R_NOTFOUND)
6524 result = ISC_R_SUCCESS;
6528 dns_rdataset_init(&rdataset);
6529 for (result = dns_rdatasetiter_first(iterator);
6530 result == ISC_R_SUCCESS;
6531 result = dns_rdatasetiter_next(iterator)) {
6532 dns_rdatasetiter_current(iterator, &rdataset);
6533 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
6534 for (result = dns_rdataset_first(&rdataset);
6535 result == ISC_R_SUCCESS;
6536 result = dns_rdataset_next(&rdataset)) {
6537 dns_rdata_t rdata = DNS_RDATA_INIT;
6538 dns_rdataset_current(&rdataset, &rdata);
6539 CHECK(update_one_rr(db, version, diff,
6540 DNS_DIFFOP_DEL, name,
6541 rdataset.ttl, &rdata));
6543 if (result != ISC_R_NOMORE)
6545 dns_rdataset_disassociate(&rdataset);
6548 if (rdataset.type != dns_rdatatype_rrsig) {
6549 dns_rdataset_disassociate(&rdataset);
6552 for (result = dns_rdataset_first(&rdataset);
6553 result == ISC_R_SUCCESS;
6554 result = dns_rdataset_next(&rdataset)) {
6555 dns_rdata_t rdata = DNS_RDATA_INIT;
6556 dns_rdataset_current(&rdataset, &rdata);
6557 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
6558 if (rrsig.algorithm != algorithm ||
6559 rrsig.keyid != keyid)
6561 CHECK(update_one_rr(db, version, diff,
6562 DNS_DIFFOP_DELRESIGN, name,
6563 rdataset.ttl, &rdata));
6565 dns_rdataset_disassociate(&rdataset);
6566 if (result != ISC_R_NOMORE)
6569 if (result == ISC_R_NOMORE)
6570 result = ISC_R_SUCCESS;
6572 if (dns_rdataset_isassociated(&rdataset))
6573 dns_rdataset_disassociate(&rdataset);
6574 dns_rdatasetiter_destroy(&iterator);
6579 * Incrementally sign the zone using the keys requested.
6580 * Builds the NSEC chain if required.
6583 zone_sign(dns_zone_t *zone) {
6584 dns_db_t *db = NULL;
6585 dns_dbnode_t *node = NULL;
6586 dns_dbversion_t *version = NULL;
6587 dns_diff_t sig_diff;
6588 dns_diff_t post_diff;
6589 dns_fixedname_t fixed;
6590 dns_fixedname_t nextfixed;
6591 dns_name_t *name, *nextname;
6592 dns_rdataset_t rdataset;
6593 dns_signing_t *signing, *nextsigning;
6594 dns_signinglist_t cleanup;
6595 dst_key_t *zone_keys[MAXZONEKEYS];
6596 isc_int32_t signatures;
6597 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
6598 isc_boolean_t commit = ISC_FALSE;
6599 isc_boolean_t delegation;
6600 isc_boolean_t build_nsec = ISC_FALSE;
6601 isc_boolean_t build_nsec3 = ISC_FALSE;
6602 isc_boolean_t first;
6603 isc_result_t result;
6604 isc_stdtime_t now, inception, soaexpire, expire;
6605 isc_uint32_t jitter;
6607 unsigned int nkeys = 0;
6610 dns_rdataset_init(&rdataset);
6611 dns_fixedname_init(&fixed);
6612 name = dns_fixedname_name(&fixed);
6613 dns_fixedname_init(&nextfixed);
6614 nextname = dns_fixedname_name(&nextfixed);
6615 dns_diff_init(zone->mctx, &sig_diff);
6616 sig_diff.resign = zone->sigresigninginterval;
6617 dns_diff_init(zone->mctx, &post_diff);
6618 ISC_LIST_INIT(cleanup);
6621 * Updates are disabled. Pause for 5 minutes.
6623 if (zone->update_disabled) {
6624 result = ISC_R_FAILURE;
6628 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6629 dns_db_attach(zone->db, &db);
6630 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6632 result = dns_db_newversion(db, &version);
6633 if (result != ISC_R_SUCCESS) {
6634 dns_zone_log(zone, ISC_LOG_ERROR,
6635 "zone_sign:dns_db_newversion -> %s\n",
6636 dns_result_totext(result));
6640 result = find_zone_keys(zone, db, version, zone->mctx,
6641 MAXZONEKEYS, zone_keys, &nkeys);
6642 if (result != ISC_R_SUCCESS) {
6643 dns_zone_log(zone, ISC_LOG_ERROR,
6644 "zone_sign:find_zone_keys -> %s\n",
6645 dns_result_totext(result));
6649 isc_stdtime_get(&now);
6650 inception = now - 3600; /* Allow for clock skew. */
6651 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6654 * Spread out signatures over time if they happen to be
6655 * clumped. We don't do this for each add_sigs() call as
6656 * we still want some clustering to occur.
6658 isc_random_get(&jitter);
6659 expire = soaexpire - jitter % 3600;
6662 * We keep pulling nodes off each iterator in turn until
6663 * we have no more nodes to pull off or we reach the limits
6666 nodes = zone->nodes;
6667 signatures = zone->signatures;
6668 signing = ISC_LIST_HEAD(zone->signing);
6671 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6672 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6674 /* Determine which type of chain to build */
6675 CHECK(dns_private_chains(db, version, zone->privatetype,
6676 &build_nsec, &build_nsec3));
6678 /* If neither chain is found, default to NSEC */
6679 if (!build_nsec && !build_nsec3)
6680 build_nsec = ISC_TRUE;
6682 while (signing != NULL && nodes-- > 0 && signatures > 0) {
6683 nextsigning = ISC_LIST_NEXT(signing, link);
6685 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6686 if (signing->done || signing->db != zone->db) {
6688 * The zone has been reloaded. We will have
6689 * created new signings as part of the reload
6690 * process so we can destroy this one.
6692 ISC_LIST_UNLINK(zone->signing, signing, link);
6693 ISC_LIST_APPEND(cleanup, signing, link);
6694 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6697 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6699 if (signing->db != db)
6702 delegation = ISC_FALSE;
6704 if (first && signing->delete) {
6706 * Remove the key we are deleting from consideration.
6708 for (i = 0, j = 0; i < nkeys; i++) {
6710 * Find the key we want to remove.
6712 if (ALG(zone_keys[i]) == signing->algorithm &&
6713 dst_key_id(zone_keys[i]) == signing->keyid)
6715 if (KSK(zone_keys[i]))
6716 dst_key_free(&zone_keys[i]);
6719 zone_keys[j] = zone_keys[i];
6725 dns_dbiterator_current(signing->dbiterator, &node, name);
6727 if (signing->delete) {
6728 dns_dbiterator_pause(signing->dbiterator);
6729 CHECK(del_sig(db, version, name, node, nkeys,
6730 signing->algorithm, signing->keyid,
6735 * On the first pass we need to check if the current node
6736 * has not been obscured.
6739 dns_fixedname_t ffound;
6741 dns_fixedname_init(&ffound);
6742 found = dns_fixedname_name(&ffound);
6743 result = dns_db_find(db, name, version,
6745 DNS_DBFIND_NOWILD, 0, NULL, found,
6747 if ((result == DNS_R_DELEGATION ||
6748 result == DNS_R_DNAME) &&
6749 !dns_name_equal(name, found)) {
6751 * Remember the obscuring name so that
6752 * we skip all obscured names.
6754 dns_name_copy(found, name, NULL);
6755 delegation = ISC_TRUE;
6763 dns_dbiterator_pause(signing->dbiterator);
6764 for (i = 0; i < nkeys; i++) {
6765 isc_boolean_t both = ISC_FALSE;
6768 * Find the keys we want to sign with.
6770 if (!dst_key_isprivate(zone_keys[i]))
6774 * When adding look for the specific key.
6776 if (!signing->delete &&
6777 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
6778 dst_key_id(zone_keys[i]) != signing->keyid))
6782 * When deleting make sure we are properly signed
6783 * with the algorithm that was being removed.
6785 if (signing->delete &&
6786 ALG(zone_keys[i]) != signing->algorithm)
6790 * Do we do KSK processing?
6792 if (check_ksk && !REVOKE(zone_keys[i])) {
6793 isc_boolean_t have_ksk, have_nonksk;
6794 if (KSK(zone_keys[i])) {
6795 have_ksk = ISC_TRUE;
6796 have_nonksk = ISC_FALSE;
6798 have_ksk = ISC_FALSE;
6799 have_nonksk = ISC_TRUE;
6801 for (j = 0; j < nkeys; j++) {
6803 ALG(zone_keys[i]) !=
6806 if (REVOKE(zone_keys[j]))
6808 if (KSK(zone_keys[j]))
6809 have_ksk = ISC_TRUE;
6811 have_nonksk = ISC_TRUE;
6812 both = have_ksk && have_nonksk;
6817 if (both || REVOKE(zone_keys[i]))
6818 is_ksk = KSK(zone_keys[i]);
6822 CHECK(sign_a_node(db, name, node, version, build_nsec3,
6823 build_nsec, zone_keys[i], inception,
6824 expire, zone->minimum, is_ksk,
6825 ISC_TF(both && keyset_kskonly),
6826 &delegation, &sig_diff,
6827 &signatures, zone->mctx));
6829 * If we are adding we are done. Look for other keys
6830 * of the same algorithm if deleting.
6832 if (!signing->delete)
6837 * Go onto next node.
6841 dns_db_detachnode(db, &node);
6843 result = dns_dbiterator_next(signing->dbiterator);
6844 if (result == ISC_R_NOMORE) {
6845 ISC_LIST_UNLINK(zone->signing, signing, link);
6846 ISC_LIST_APPEND(cleanup, signing, link);
6847 dns_dbiterator_pause(signing->dbiterator);
6848 if (nkeys != 0 && build_nsec) {
6850 * We have finished regenerating the
6851 * zone with a zone signing key.
6852 * The NSEC chain is now complete and
6853 * there is a full set of signatures
6854 * for the zone. We can now clear the
6855 * OPT bit from the NSEC record.
6857 result = updatesecure(db, version,
6862 if (result != ISC_R_SUCCESS) {
6865 "updatesecure -> %s\n",
6866 dns_result_totext(result));
6870 result = updatesignwithkey(zone, signing,
6875 if (result != ISC_R_SUCCESS) {
6876 dns_zone_log(zone, ISC_LOG_ERROR,
6877 "updatesignwithkey "
6879 dns_result_totext(result));
6882 build_nsec = ISC_FALSE;
6884 } else if (result != ISC_R_SUCCESS) {
6885 dns_zone_log(zone, ISC_LOG_ERROR,
6886 "zone_sign:dns_dbiterator_next -> %s\n",
6887 dns_result_totext(result));
6889 } else if (delegation) {
6890 dns_dbiterator_current(signing->dbiterator,
6892 dns_db_detachnode(db, &node);
6893 if (!dns_name_issubdomain(nextname, name))
6901 dns_dbiterator_pause(signing->dbiterator);
6902 signing = nextsigning;
6906 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
6907 result = update_sigs(&post_diff, db, version, zone_keys,
6908 nkeys, zone, inception, expire, now,
6909 check_ksk, keyset_kskonly, &sig_diff);
6910 if (result != ISC_R_SUCCESS) {
6911 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
6912 "update_sigs -> %s\n",
6913 dns_result_totext(result));
6919 * Have we changed anything?
6921 if (ISC_LIST_HEAD(sig_diff.tuples) == NULL) {
6922 result = ISC_R_SUCCESS;
6928 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6929 &sig_diff, zone_keys, nkeys, now, ISC_FALSE);
6930 if (result != ISC_R_SUCCESS) {
6931 dns_zone_log(zone, ISC_LOG_ERROR,
6932 "zone_sign:del_sigs -> %s\n",
6933 dns_result_totext(result));
6937 result = increment_soa_serial(db, version, &sig_diff, zone->mctx);
6938 if (result != ISC_R_SUCCESS) {
6939 dns_zone_log(zone, ISC_LOG_ERROR,
6940 "zone_sign:increment_soa_serial -> %s\n",
6941 dns_result_totext(result));
6946 * Generate maximum life time signatures so that the above loop
6947 * termination is sensible.
6949 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6950 &sig_diff, zone_keys, nkeys, zone->mctx, inception,
6951 soaexpire, check_ksk, keyset_kskonly);
6952 if (result != ISC_R_SUCCESS) {
6953 dns_zone_log(zone, ISC_LOG_ERROR,
6954 "zone_sign:add_sigs -> %s\n",
6955 dns_result_totext(result));
6960 * Write changes to journal file.
6962 CHECK(zone_journal(zone, &sig_diff, "zone_sign"));
6966 * Pause all iterators so that dns_db_closeversion() can succeed.
6968 for (signing = ISC_LIST_HEAD(zone->signing);
6970 signing = ISC_LIST_NEXT(signing, link))
6971 dns_dbiterator_pause(signing->dbiterator);
6973 for (signing = ISC_LIST_HEAD(cleanup);
6975 signing = ISC_LIST_NEXT(signing, link))
6976 dns_dbiterator_pause(signing->dbiterator);
6979 * Everything has succeeded. Commit the changes.
6981 dns_db_closeversion(db, &version, commit);
6984 * Everything succeeded so we can clean these up now.
6986 signing = ISC_LIST_HEAD(cleanup);
6987 while (signing != NULL) {
6988 ISC_LIST_UNLINK(cleanup, signing, link);
6989 dns_db_detach(&signing->db);
6990 dns_dbiterator_destroy(&signing->dbiterator);
6991 isc_mem_put(zone->mctx, signing, sizeof *signing);
6992 signing = ISC_LIST_HEAD(cleanup);
6995 set_resigntime(zone);
6999 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7000 zone_needdump(zone, DNS_DUMP_DELAY);
7006 * Rollback the cleanup list.
7008 signing = ISC_LIST_HEAD(cleanup);
7009 while (signing != NULL) {
7010 ISC_LIST_UNLINK(cleanup, signing, link);
7011 ISC_LIST_PREPEND(zone->signing, signing, link);
7012 dns_dbiterator_first(signing->dbiterator);
7013 dns_dbiterator_pause(signing->dbiterator);
7014 signing = ISC_LIST_HEAD(cleanup);
7017 for (signing = ISC_LIST_HEAD(zone->signing);
7019 signing = ISC_LIST_NEXT(signing, link))
7020 dns_dbiterator_pause(signing->dbiterator);
7022 dns_diff_clear(&sig_diff);
7024 for (i = 0; i < nkeys; i++)
7025 dst_key_free(&zone_keys[i]);
7028 dns_db_detachnode(db, &node);
7030 if (version != NULL) {
7031 dns_db_closeversion(db, &version, ISC_FALSE);
7033 } else if (db != NULL)
7036 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7038 if (zone->update_disabled || result != ISC_R_SUCCESS)
7039 isc_interval_set(&i, 60, 0); /* 1 minute */
7041 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7042 isc_time_nowplusinterval(&zone->signingtime, &i);
7044 isc_time_settoepoch(&zone->signingtime);
7048 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7049 unsigned char *data, int size) {
7050 dns_rdata_dnskey_t dnskey;
7051 dns_rdata_keydata_t keydata;
7054 dns_rdata_reset(target);
7055 isc_buffer_init(&buf, data, size);
7058 case dns_rdatatype_dnskey:
7059 dns_rdata_tostruct(rr, &dnskey, NULL);
7060 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7061 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7064 case dns_rdatatype_keydata:
7065 dns_rdata_tostruct(rr, &keydata, NULL);
7066 dns_keydata_todnskey(&keydata, &dnskey, NULL);
7067 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7076 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
7077 * a KEYDATA rdataset from the key zone.
7079 * 'rr' contains either a DNSKEY record, or a KEYDATA record
7081 * After normalizing keys to the same format (DNSKEY, with revoke bit
7082 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
7083 * 'rdset', or ISC_FALSE if not.
7086 static isc_boolean_t
7087 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
7088 unsigned char data1[4096], data2[4096];
7089 dns_rdata_t rdata, rdata1, rdata2;
7090 isc_result_t result;
7092 dns_rdata_init(&rdata);
7093 dns_rdata_init(&rdata1);
7094 dns_rdata_init(&rdata2);
7096 normalize_key(rr, &rdata1, data1, sizeof(data1));
7098 for (result = dns_rdataset_first(rdset);
7099 result == ISC_R_SUCCESS;
7100 result = dns_rdataset_next(rdset)) {
7101 dns_rdata_reset(&rdata);
7102 dns_rdataset_current(rdset, &rdata);
7103 normalize_key(&rdata, &rdata2, data2, sizeof(data2));
7104 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
7112 * Calculate the refresh interval for a keydata zone, per
7113 * RFC5011: MAX(1 hr,
7116 * 1/2 * RRSigExpirationInterval))
7117 * or for retries: MAX(1 hr,
7120 * 1/10 * RRSigExpirationInterval))
7122 static inline isc_stdtime_t
7123 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
7124 isc_result_t result;
7126 dns_rdataset_t *rdset;
7127 dns_rdata_t sigrr = DNS_RDATA_INIT;
7128 dns_rdata_sig_t sig;
7131 isc_stdtime_get(&now);
7133 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7134 rdset = &kfetch->dnskeysigset;
7136 return (now + HOUR);
7138 result = dns_rdataset_first(rdset);
7139 if (result != ISC_R_SUCCESS)
7140 return (now + HOUR);
7142 dns_rdataset_current(rdset, &sigrr);
7143 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7144 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7147 t = sig.originalttl / 2;
7149 if (isc_serial_gt(sig.timeexpire, now)) {
7150 isc_uint32_t exp = (sig.timeexpire - now) / 2;
7161 t = sig.originalttl / 10;
7163 if (isc_serial_gt(sig.timeexpire, now)) {
7164 isc_uint32_t exp = (sig.timeexpire - now) / 10;
7180 * This routine is called when no changes are needed in a KEYDATA
7181 * record except to simply update the refresh timer. Caller should
7185 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
7187 isc_result_t result;
7189 unsigned char key_buf[4096];
7190 dns_rdata_t rdata = DNS_RDATA_INIT;
7191 dns_rdata_keydata_t keydata;
7193 dns_zone_t *zone = kfetch->zone;
7196 name = dns_fixedname_name(&kfetch->name);
7197 isc_stdtime_get(&now);
7199 for (result = dns_rdataset_first(&kfetch->keydataset);
7200 result == ISC_R_SUCCESS;
7201 result = dns_rdataset_next(&kfetch->keydataset)) {
7202 dns_rdata_reset(&rdata);
7203 dns_rdataset_current(&kfetch->keydataset, &rdata);
7205 /* Delete old version */
7206 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
7209 /* Update refresh timer */
7210 CHECK(dns_rdata_tostruct(&rdata, &keydata, NULL));
7211 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
7212 set_refreshkeytimer(zone, &keydata, now);
7214 dns_rdata_reset(&rdata);
7215 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7216 CHECK(dns_rdata_fromstruct(&rdata,
7217 zone->rdclass, dns_rdatatype_keydata,
7220 /* Insert updated version */
7221 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
7224 result = ISC_R_SUCCESS;
7230 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
7232 static isc_boolean_t
7233 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
7234 isc_result_t result;
7235 dns_name_t *keyname;
7237 dns_rdata_t sigrr = DNS_RDATA_INIT;
7238 dns_rdata_t rr = DNS_RDATA_INIT;
7239 dns_rdata_rrsig_t sig;
7240 dns_rdata_dnskey_t dnskey;
7241 dst_key_t *dstkey = NULL;
7242 unsigned char key_buf[4096];
7244 isc_boolean_t answer = ISC_FALSE;
7246 REQUIRE(kfetch != NULL && keydata != NULL);
7247 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
7249 keyname = dns_fixedname_name(&kfetch->name);
7250 mctx = kfetch->zone->view->mctx;
7252 /* Generate a key from keydata */
7253 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7254 dns_keydata_todnskey(keydata, &dnskey, NULL);
7255 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
7257 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
7258 if (result != ISC_R_SUCCESS)
7261 /* See if that key generated any of the signatures */
7262 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7263 result == ISC_R_SUCCESS;
7264 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7265 dns_fixedname_t fixed;
7266 dns_fixedname_init(&fixed);
7268 dns_rdata_reset(&sigrr);
7269 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7270 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7271 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7273 if (dst_key_alg(dstkey) == sig.algorithm &&
7274 (dst_key_id(dstkey) == sig.keyid ||
7275 (sig.algorithm != 1 && sig.keyid ==
7276 ((dst_key_id(dstkey) + 128) & 0xffff)))) {
7277 result = dns_dnssec_verify2(keyname,
7279 dstkey, ISC_FALSE, mctx, &sigrr,
7280 dns_fixedname_name(&fixed));
7282 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
7283 "Confirm revoked DNSKEY is self-signed: "
7284 "%s", dns_result_totext(result));
7286 if (result == ISC_R_SUCCESS) {
7293 dst_key_free(&dstkey);
7298 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
7299 * anchors are being managed; scan the keyset, and update the key zone and the
7300 * local trust anchors according to RFC5011.
7303 keyfetch_done(isc_task_t *task, isc_event_t *event) {
7304 isc_result_t result, eresult;
7305 dns_fetchevent_t *devent;
7306 dns_keyfetch_t *kfetch;
7308 isc_mem_t *mctx = NULL;
7309 dns_keytable_t *secroots = NULL;
7310 dns_dbversion_t *ver = NULL;
7312 isc_boolean_t alldone = ISC_FALSE;
7313 isc_boolean_t commit = ISC_FALSE;
7314 dns_name_t *keyname;
7315 dns_rdata_t sigrr = DNS_RDATA_INIT;
7316 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
7317 dns_rdata_t keydatarr = DNS_RDATA_INIT;
7318 dns_rdata_rrsig_t sig;
7319 dns_rdata_dnskey_t dnskey;
7320 dns_rdata_keydata_t keydata;
7321 isc_boolean_t initializing;
7322 char namebuf[DNS_NAME_FORMATSIZE];
7323 unsigned char key_buf[4096];
7328 isc_boolean_t secure;
7329 isc_boolean_t free_needed;
7332 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
7333 INSIST(event->ev_arg != NULL);
7335 kfetch = event->ev_arg;
7336 zone = kfetch->zone;
7337 isc_mem_attach(zone->mctx, &mctx);
7338 keyname = dns_fixedname_name(&kfetch->name);
7340 devent = (dns_fetchevent_t *) event;
7341 eresult = devent->result;
7343 /* Free resources which are not of interest */
7344 if (devent->node != NULL)
7345 dns_db_detachnode(devent->db, &devent->node);
7346 if (devent->db != NULL)
7347 dns_db_detach(&devent->db);
7348 isc_event_free(&event);
7349 dns_resolver_destroyfetch(&kfetch->fetch);
7352 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
7355 isc_stdtime_get(&now);
7356 dns_name_format(keyname, namebuf, sizeof(namebuf));
7358 result = dns_view_getsecroots(zone->view, &secroots);
7359 INSIST(result == ISC_R_SUCCESS);
7361 dns_diff_init(mctx, &diff);
7362 diff.resign = zone->sigresigninginterval;
7364 CHECK(dns_db_newversion(kfetch->db, &ver));
7366 zone->refreshkeycount--;
7367 alldone = ISC_TF(zone->refreshkeycount == 0);
7370 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
7373 if (eresult != ISC_R_SUCCESS ||
7374 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
7375 dns_zone_log(zone, ISC_LOG_WARNING,
7376 "Unable to fetch DNSKEY set "
7377 "'%s': %s", namebuf, dns_result_totext(eresult));
7378 CHECK(minimal_update(kfetch, ver, &diff));
7382 /* No RRSIGs found */
7383 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
7384 dns_zone_log(zone, ISC_LOG_WARNING,
7385 "No DNSKEY RRSIGs found for "
7386 "'%s': %s", namebuf, dns_result_totext(eresult));
7387 CHECK(minimal_update(kfetch, ver, &diff));
7392 * Validate the dnskeyset against the current trusted keys.
7394 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7395 result == ISC_R_SUCCESS;
7396 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7397 dns_keynode_t *keynode = NULL;
7399 dns_rdata_reset(&sigrr);
7400 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7401 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7402 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7404 result = dns_keytable_find(secroots, keyname, &keynode);
7405 while (result == ISC_R_SUCCESS) {
7406 dns_keynode_t *nextnode = NULL;
7407 dns_fixedname_t fixed;
7408 dns_fixedname_init(&fixed);
7410 dstkey = dns_keynode_key(keynode);
7411 if (dstkey == NULL) /* fail_secure() was called */
7414 if (dst_key_alg(dstkey) == sig.algorithm &&
7415 dst_key_id(dstkey) == sig.keyid) {
7416 result = dns_dnssec_verify2(keyname,
7419 zone->view->mctx, &sigrr,
7420 dns_fixedname_name(&fixed));
7422 dns_zone_log(zone, ISC_LOG_DEBUG(3),
7423 "Verifying DNSKEY set for zone "
7424 "'%s': %s", namebuf,
7425 dns_result_totext(result));
7427 if (result == ISC_R_SUCCESS) {
7428 kfetch->dnskeyset.trust =
7430 kfetch->dnskeysigset.trust =
7432 dns_keytable_detachkeynode(secroots,
7438 result = dns_keytable_nextkeynode(secroots,
7439 keynode, &nextnode);
7440 dns_keytable_detachkeynode(secroots, &keynode);
7444 if (kfetch->dnskeyset.trust == dns_trust_secure)
7449 * If we were not able to verify the answer using the current
7450 * trusted keys then all we can do is look at any revoked keys.
7452 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
7455 * First scan keydataset to find keys that are not in dnskeyset
7456 * - Missing keys which are not scheduled for removal,
7458 * - Missing keys which are scheduled for removal and
7459 * the remove hold-down timer has completed should
7460 * be removed from the key zone
7461 * - Missing keys whose acceptance timers have not yet
7462 * completed, log a warning and reset the acceptance
7463 * timer to 30 days in the future
7464 * - All keys not being removed have their refresh timers
7467 initializing = ISC_TRUE;
7468 for (result = dns_rdataset_first(&kfetch->keydataset);
7469 result == ISC_R_SUCCESS;
7470 result = dns_rdataset_next(&kfetch->keydataset)) {
7471 dns_rdata_reset(&keydatarr);
7472 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7473 dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7476 * If any keydata record has a nonzero add holddown, then
7477 * there was a pre-existing trust anchor for this domain;
7478 * that means we are *not* initializing it and shouldn't
7479 * automatically trust all the keys we find at the zone apex.
7481 initializing = initializing && ISC_TF(keydata.addhd == 0);
7483 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
7484 isc_boolean_t deletekey = ISC_FALSE;
7487 if (now > keydata.removehd)
7488 deletekey = ISC_TRUE;
7489 } else if (now < keydata.addhd) {
7490 dns_zone_log(zone, ISC_LOG_WARNING,
7491 "Pending key unexpectedly missing "
7492 "from %s; restarting acceptance "
7494 keydata.addhd = now + MONTH;
7495 keydata.refresh = refresh_time(kfetch,
7497 } else if (keydata.addhd == 0) {
7498 keydata.addhd = now;
7499 } else if (keydata.removehd == 0) {
7500 dns_zone_log(zone, ISC_LOG_WARNING,
7501 "Active key unexpectedly missing "
7502 "from %s", namebuf);
7503 keydata.refresh = now + HOUR;
7504 } else if (now > keydata.removehd) {
7505 deletekey = ISC_TRUE;
7507 keydata.refresh = refresh_time(kfetch,
7511 if (secure || deletekey) {
7512 /* Delete old version */
7513 CHECK(update_one_rr(kfetch->db, ver, &diff,
7514 DNS_DIFFOP_DEL, keyname, 0,
7518 if (!secure || deletekey)
7521 dns_rdata_reset(&keydatarr);
7522 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7523 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7524 dns_rdatatype_keydata,
7527 /* Insert updated version */
7528 CHECK(update_one_rr(kfetch->db, ver, &diff,
7529 DNS_DIFFOP_ADD, keyname, 0,
7532 set_refreshkeytimer(zone, &keydata, now);
7537 * Next scan dnskeyset:
7538 * - If new keys are found (i.e., lacking a match in keydataset)
7539 * add them to the key zone and set the acceptance timer
7540 * to 30 days in the future (or to immediately if we've
7541 * determined that we're initializing the zone for the
7543 * - Previously-known keys that have been revoked
7544 * must be scheduled for removal from the key zone (or,
7545 * if they hadn't been accepted as trust anchors yet
7546 * anyway, removed at once)
7547 * - Previously-known unrevoked keys whose acceptance timers
7548 * have completed are promoted to trust anchors
7549 * - All keys not being removed have their refresh
7552 for (result = dns_rdataset_first(&kfetch->dnskeyset);
7553 result == ISC_R_SUCCESS;
7554 result = dns_rdataset_next(&kfetch->dnskeyset)) {
7555 isc_boolean_t revoked = ISC_FALSE;
7556 isc_boolean_t newkey = ISC_FALSE;
7557 isc_boolean_t updatekey = ISC_FALSE;
7558 isc_boolean_t deletekey = ISC_FALSE;
7559 isc_boolean_t trustkey = ISC_FALSE;
7561 dns_rdata_reset(&dnskeyrr);
7562 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
7563 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7566 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
7569 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
7571 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
7572 dns_rdata_reset(&keydatarr);
7573 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7574 dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7576 if (revoked && revocable(kfetch, &keydata)) {
7577 if (keydata.addhd > now) {
7579 * Key wasn't trusted yet, and now
7580 * it's been revoked? Just remove it
7582 deletekey = ISC_TRUE;
7583 } else if (keydata.removehd == 0) {
7584 /* Remove from secroots */
7585 dns_view_untrust(zone->view, keyname,
7588 /* If initializing, delete now */
7589 if (keydata.addhd == 0)
7590 deletekey = ISC_TRUE;
7592 keydata.removehd = now + MONTH;
7593 } else if (keydata.removehd < now) {
7594 /* Scheduled for removal */
7595 deletekey = ISC_TRUE;
7597 } else if (revoked) {
7598 if (secure && keydata.removehd == 0) {
7599 dns_zone_log(zone, ISC_LOG_WARNING,
7600 "Active key for zone "
7601 "'%s' is revoked but "
7602 "did not self-sign; "
7603 "ignoring.", namebuf);
7606 } else if (secure) {
7607 if (keydata.removehd != 0) {
7609 * Key isn't revoked--but it
7610 * seems it used to be.
7611 * Remove it now and add it
7612 * back as if it were a fresh key.
7614 deletekey = ISC_TRUE;
7616 } else if (keydata.addhd > now)
7618 else if (keydata.addhd == 0)
7619 keydata.addhd = now;
7621 if (keydata.addhd <= now)
7622 trustkey = ISC_TRUE;
7625 if (!deletekey && !newkey)
7626 updatekey = ISC_TRUE;
7627 } else if (secure) {
7629 * Key wasn't in the key zone but it's
7630 * revoked now anyway, so just skip it
7635 /* Key wasn't in the key zone: add it */
7639 dns_keytag_t tag = 0;
7640 CHECK(compute_tag(keyname, &dnskey,
7642 dns_zone_log(zone, ISC_LOG_WARNING,
7643 "Initializing automatic trust "
7644 "anchor management for zone '%s'; "
7645 "DNSKEY ID %d is now trusted, "
7646 "waiving the normal 30-day "
7649 trustkey = ISC_TRUE;
7653 /* Delete old version */
7654 if (deletekey || !newkey)
7655 CHECK(update_one_rr(kfetch->db, ver, &diff,
7656 DNS_DIFFOP_DEL, keyname, 0,
7660 /* Set refresh timer */
7661 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7662 dns_rdata_reset(&keydatarr);
7663 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7664 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7665 dns_rdatatype_keydata,
7668 /* Insert updated version */
7669 CHECK(update_one_rr(kfetch->db, ver, &diff,
7670 DNS_DIFFOP_ADD, keyname, 0,
7672 } else if (newkey) {
7673 /* Convert DNSKEY to KEYDATA */
7674 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7675 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
7677 keydata.addhd = initializing ? now : now + MONTH;
7678 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7679 dns_rdata_reset(&keydatarr);
7680 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7681 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7682 dns_rdatatype_keydata,
7685 /* Insert into key zone */
7686 CHECK(update_one_rr(kfetch->db, ver, &diff,
7687 DNS_DIFFOP_ADD, keyname, 0,
7692 /* Trust this key. */
7693 dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7694 trust_key(zone, keyname, &dnskey, mctx);
7698 set_refreshkeytimer(zone, &keydata, now);
7702 * RFC5011 says, "A trust point that has all of its trust anchors
7703 * revoked is considered deleted and is treated as if the trust
7704 * point was never configured." But if someone revoked their
7705 * active key before the standby was trusted, that would mean the
7706 * zone would suddenly be nonsecured. We avoid this by checking to
7707 * see if there's pending keydata. If so, we put a null key in
7708 * the security roots; then all queries to the zone will fail.
7711 fail_secure(zone, keyname);
7715 if (!ISC_LIST_EMPTY(diff.tuples)) {
7716 /* Write changes to journal file. */
7717 CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx));
7718 CHECK(zone_journal(zone, &diff, "keyfetch_done"));
7721 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
7722 zone_needdump(zone, 30);
7727 dns_diff_clear(&diff);
7729 dns_db_closeversion(kfetch->db, &ver, commit);
7732 dns_db_detach(&kfetch->db);
7734 INSIST(zone->irefs > 0);
7736 kfetch->zone = NULL;
7738 if (dns_rdataset_isassociated(&kfetch->keydataset))
7739 dns_rdataset_disassociate(&kfetch->keydataset);
7740 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
7741 dns_rdataset_disassociate(&kfetch->dnskeyset);
7742 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7743 dns_rdataset_disassociate(&kfetch->dnskeysigset);
7745 dns_name_free(keyname, mctx);
7746 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
7747 isc_mem_detach(&mctx);
7749 if (secroots != NULL)
7750 dns_keytable_detach(&secroots);
7752 free_needed = exit_check(zone);
7759 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
7760 * records from the zone apex.
7763 zone_refreshkeys(dns_zone_t *zone) {
7764 const char me[] = "zone_refreshkeys";
7765 isc_result_t result;
7766 dns_rriterator_t rrit;
7767 dns_db_t *db = NULL;
7768 dns_dbversion_t *ver = NULL;
7770 dns_rdata_t rdata = DNS_RDATA_INIT;
7771 dns_rdata_keydata_t kd;
7773 isc_boolean_t commit = ISC_FALSE;
7776 REQUIRE(zone->db != NULL);
7778 isc_stdtime_get(&now);
7781 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
7782 isc_time_settoepoch(&zone->refreshkeytime);
7787 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
7788 dns_db_attach(zone->db, &db);
7789 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
7791 dns_diff_init(zone->mctx, &diff);
7793 CHECK(dns_db_newversion(db, &ver));
7795 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
7797 dns_rriterator_init(&rrit, db, ver, 0);
7798 for (result = dns_rriterator_first(&rrit);
7799 result == ISC_R_SUCCESS;
7800 result = dns_rriterator_nextrrset(&rrit)) {
7801 isc_stdtime_t timer = 0xffffffff;
7802 dns_keyfetch_t *kfetch;
7803 dns_rdataset_t *kdset;
7804 dns_name_t *name = NULL;
7807 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
7808 if (!dns_rdataset_isassociated(kdset))
7811 if (kdset->type != dns_rdatatype_keydata)
7815 * Scan the stored keys looking for ones that need
7816 * removal or refreshing
7818 for (result = dns_rdataset_first(kdset);
7819 result == ISC_R_SUCCESS;
7820 result = dns_rdataset_next(kdset)) {
7821 dns_rdata_reset(&rdata);
7822 dns_rdataset_current(kdset, &rdata);
7823 result = dns_rdata_tostruct(&rdata, &kd, NULL);
7824 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7826 /* Removal timer expired? */
7827 if (kd.removehd != 0 && kd.removehd < now) {
7828 CHECK(update_one_rr(db, ver, &diff,
7829 DNS_DIFFOP_DEL, name, ttl,
7834 /* Acceptance timer expired? */
7835 if (kd.addhd != 0 && kd.addhd < now)
7838 /* Or do we just need to refresh the keyset? */
7839 if (timer > kd.refresh)
7846 zone->refreshkeycount++;
7848 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
7849 kfetch->zone = zone;
7851 INSIST(zone->irefs != 0);
7852 dns_fixedname_init(&kfetch->name);
7853 dns_name_dup(name, zone->mctx,
7854 dns_fixedname_name(&kfetch->name));
7855 dns_rdataset_init(&kfetch->dnskeyset);
7856 dns_rdataset_init(&kfetch->dnskeysigset);
7857 dns_rdataset_init(&kfetch->keydataset);
7858 dns_rdataset_clone(kdset, &kfetch->keydataset);
7860 dns_db_attach(db, &kfetch->db);
7861 kfetch->fetch = NULL;
7863 dns_resolver_createfetch(zone->view->resolver,
7864 dns_fixedname_name(&kfetch->name),
7865 dns_rdatatype_dnskey,
7867 DNS_FETCHOPT_NOVALIDATE,
7868 zone->task, keyfetch_done, kfetch,
7870 &kfetch->dnskeysigset,
7873 if (!ISC_LIST_EMPTY(diff.tuples)) {
7874 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
7875 CHECK(zone_journal(zone, &diff, "sync_keyzone"));
7877 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
7878 zone_needdump(zone, 30);
7884 dns_diff_clear(&diff);
7886 dns_rriterator_destroy(&rrit);
7887 dns_db_closeversion(db, &ver, commit);
7893 zone_maintenance(dns_zone_t *zone) {
7894 const char me[] = "zone_maintenance";
7896 isc_result_t result;
7897 isc_boolean_t dumping;
7899 REQUIRE(DNS_ZONE_VALID(zone));
7903 * Configuring the view of this zone may have
7904 * failed, for example because the config file
7905 * had a syntax error. In that case, the view
7906 * adb or resolver, and we had better not try
7907 * to do maintenance on it.
7909 if (zone->view == NULL || zone->view->adb == NULL)
7917 switch (zone->type) {
7918 case dns_zone_slave:
7921 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
7922 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
7924 zone->refreshtime = now;
7935 switch (zone->type) {
7936 case dns_zone_slave:
7938 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
7939 isc_time_compare(&now, &zone->refreshtime) >= 0)
7940 dns_zone_refresh(zone);
7947 * Do we need to consolidate the backing store?
7949 switch (zone->type) {
7950 case dns_zone_master:
7951 case dns_zone_slave:
7954 if (zone->masterfile != NULL &&
7955 isc_time_compare(&now, &zone->dumptime) >= 0 &&
7956 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
7957 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
7958 dumping = was_dumping(zone);
7963 result = zone_dump(zone, ISC_TRUE); /* task locked */
7964 if (result != ISC_R_SUCCESS)
7965 dns_zone_log(zone, ISC_LOG_WARNING,
7967 dns_result_totext(result));
7975 * Do we need to refresh keys?
7977 switch (zone->type) {
7979 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0 &&
7980 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
7981 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING))
7982 zone_refreshkeys(zone);
7984 case dns_zone_master:
7985 if (!isc_time_isepoch(&zone->refreshkeytime) &&
7986 isc_time_compare(&now, &zone->refreshkeytime) >= 0)
7992 switch (zone->type) {
7993 case dns_zone_master:
7994 case dns_zone_slave:
7996 * Do we need to send out notify messages?
7998 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
7999 isc_time_compare(&now, &zone->notifytime) >= 0)
8000 zone_notify(zone, &now);
8002 * Do we need to sign/resign some RRsets?
8004 if (!isc_time_isepoch(&zone->signingtime) &&
8005 isc_time_compare(&now, &zone->signingtime) >= 0)
8007 else if (!isc_time_isepoch(&zone->resigntime) &&
8008 isc_time_compare(&now, &zone->resigntime) >= 0)
8009 zone_resigninc(zone);
8010 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
8011 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
8012 zone_nsec3chain(zone);
8014 * Do we need to issue a key expiry warning.
8016 if (!isc_time_isepoch(&zone->keywarntime) &&
8017 isc_time_compare(&now, &zone->keywarntime) >= 0)
8018 set_key_expiry_warning(zone, zone->key_expiry,
8019 isc_time_seconds(&now));
8024 zone_settimer(zone, &now);
8028 dns_zone_markdirty(dns_zone_t *zone) {
8031 if (zone->type == dns_zone_master)
8032 set_resigntime(zone); /* XXXMPA make separate call back */
8033 zone_needdump(zone, DNS_DUMP_DELAY);
8038 dns_zone_expire(dns_zone_t *zone) {
8039 REQUIRE(DNS_ZONE_VALID(zone));
8047 zone_expire(dns_zone_t *zone) {
8049 * 'zone' locked by caller.
8052 REQUIRE(LOCKED_ZONE(zone));
8054 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
8056 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
8057 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
8058 zone->retry = DNS_ZONE_DEFAULTRETRY;
8059 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
8064 dns_zone_refresh(dns_zone_t *zone) {
8066 isc_uint32_t oldflags;
8068 isc_result_t result;
8070 REQUIRE(DNS_ZONE_VALID(zone));
8072 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8076 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
8077 * in progress at a time.
8081 oldflags = zone->flags;
8082 if (zone->masterscnt == 0) {
8083 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
8084 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
8085 dns_zone_log(zone, ISC_LOG_ERROR,
8086 "cannot refresh: no masters");
8089 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
8090 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
8091 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
8092 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
8096 * Set the next refresh time as if refresh check has failed.
8097 * Setting this to the retry time will do that. XXXMLG
8098 * If we are successful it will be reset using zone->refresh.
8100 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
8102 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
8103 if (result != ISC_R_SUCCESS)
8104 dns_zone_log(zone, ISC_LOG_WARNING,
8105 "isc_time_nowplusinterval() failed: %s",
8106 dns_result_totext(result));
8109 * When lacking user-specified timer values from the SOA,
8110 * do exponential backoff of the retry time up to a
8111 * maximum of six hours.
8113 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
8114 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
8116 zone->curmaster = 0;
8117 for (j = 0; j < zone->masterscnt; j++)
8118 zone->mastersok[j] = ISC_FALSE;
8119 /* initiate soa query */
8120 queue_soa_query(zone);
8126 dns_zone_flush(dns_zone_t *zone) {
8127 isc_result_t result = ISC_R_SUCCESS;
8128 isc_boolean_t dumping;
8130 REQUIRE(DNS_ZONE_VALID(zone));
8133 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
8134 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8135 zone->masterfile != NULL) {
8136 result = ISC_R_ALREADYRUNNING;
8137 dumping = was_dumping(zone);
8142 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8147 dns_zone_dump(dns_zone_t *zone) {
8148 isc_result_t result = ISC_R_ALREADYRUNNING;
8149 isc_boolean_t dumping;
8151 REQUIRE(DNS_ZONE_VALID(zone));
8154 dumping = was_dumping(zone);
8157 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8162 zone_needdump(dns_zone_t *zone, unsigned int delay) {
8163 isc_time_t dumptime;
8167 * 'zone' locked by caller
8170 REQUIRE(DNS_ZONE_VALID(zone));
8171 REQUIRE(LOCKED_ZONE(zone));
8174 * Do we have a place to dump to and are we loaded?
8176 if (zone->masterfile == NULL ||
8177 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
8181 /* add some noise */
8182 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
8184 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8185 if (isc_time_isepoch(&zone->dumptime) ||
8186 isc_time_compare(&zone->dumptime, &dumptime) > 0)
8187 zone->dumptime = dumptime;
8188 if (zone->task != NULL)
8189 zone_settimer(zone, &now);
8193 dump_done(void *arg, isc_result_t result) {
8194 const char me[] = "dump_done";
8195 dns_zone_t *zone = arg;
8197 dns_dbversion_t *version;
8198 isc_boolean_t again = ISC_FALSE;
8199 isc_boolean_t compact = ISC_FALSE;
8200 isc_uint32_t serial;
8201 isc_result_t tresult;
8203 REQUIRE(DNS_ZONE_VALID(zone));
8207 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
8208 zone->journalsize != -1) {
8211 * We don't own these, zone->dctx must stay valid.
8213 db = dns_dumpctx_db(zone->dctx);
8214 version = dns_dumpctx_version(zone->dctx);
8216 tresult = dns_db_getsoaserial(db, version, &serial);
8218 * Note: we are task locked here so we can test
8221 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
8222 tresult = dns_journal_compact(zone->mctx,
8229 case ISC_R_NOTFOUND:
8230 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8231 "dns_journal_compact: %s",
8232 dns_result_totext(tresult));
8235 dns_zone_log(zone, ISC_LOG_ERROR,
8236 "dns_journal_compact failed: %s",
8237 dns_result_totext(tresult));
8240 } else if (tresult == ISC_R_SUCCESS) {
8242 zone->compact_serial = serial;
8247 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8249 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
8250 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
8252 * Try again in a short while.
8254 zone_needdump(zone, DNS_DUMP_DELAY);
8255 } else if (result == ISC_R_SUCCESS &&
8256 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8257 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8258 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8259 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8260 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8261 isc_time_settoepoch(&zone->dumptime);
8263 } else if (result == ISC_R_SUCCESS)
8264 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8266 if (zone->dctx != NULL)
8267 dns_dumpctx_detach(&zone->dctx);
8268 zonemgr_putio(&zone->writeio);
8271 (void)zone_dump(zone, ISC_FALSE);
8272 dns_zone_idetach(&zone);
8276 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
8277 const char me[] = "zone_dump";
8278 isc_result_t result;
8279 dns_dbversion_t *version = NULL;
8280 isc_boolean_t again;
8281 dns_db_t *db = NULL;
8282 char *masterfile = NULL;
8283 dns_masterformat_t masterformat = dns_masterformat_none;
8286 * 'compact' MUST only be set if we are task locked.
8289 REQUIRE(DNS_ZONE_VALID(zone));
8293 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8294 if (zone->db != NULL)
8295 dns_db_attach(zone->db, &db);
8296 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8298 if (zone->masterfile != NULL) {
8299 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
8300 masterformat = zone->masterformat;
8304 result = DNS_R_NOTLOADED;
8307 if (masterfile == NULL) {
8308 result = DNS_R_NOMASTERFILE;
8313 dns_zone_t *dummy = NULL;
8315 zone_iattach(zone, &dummy);
8316 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
8317 zone_gotwritehandle, zone,
8319 if (result != ISC_R_SUCCESS)
8320 zone_idetach(&dummy);
8322 result = DNS_R_CONTINUE;
8325 dns_db_currentversion(db, &version);
8326 result = dns_master_dump2(zone->mctx, db, version,
8327 &dns_master_style_default,
8328 masterfile, masterformat);
8329 dns_db_closeversion(db, &version, ISC_FALSE);
8334 if (masterfile != NULL)
8335 isc_mem_free(zone->mctx, masterfile);
8338 if (result == DNS_R_CONTINUE)
8339 return (ISC_R_SUCCESS); /* XXXMPA */
8343 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8344 if (result != ISC_R_SUCCESS) {
8346 * Try again in a short while.
8348 zone_needdump(zone, DNS_DUMP_DELAY);
8349 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8350 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8351 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8352 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8353 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8354 isc_time_settoepoch(&zone->dumptime);
8357 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8366 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
8367 dns_masterformat_t format)
8369 isc_result_t result;
8370 dns_dbversion_t *version = NULL;
8371 dns_db_t *db = NULL;
8373 REQUIRE(DNS_ZONE_VALID(zone));
8375 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8376 if (zone->db != NULL)
8377 dns_db_attach(zone->db, &db);
8378 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8380 return (DNS_R_NOTLOADED);
8382 dns_db_currentversion(db, &version);
8383 result = dns_master_dumptostream2(zone->mctx, db, version, style,
8385 dns_db_closeversion(db, &version, ISC_FALSE);
8391 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
8392 const dns_master_style_t *style) {
8393 return dumptostream(zone, fd, style, format);
8397 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
8398 return dumptostream(zone, fd, &dns_master_style_default,
8399 dns_masterformat_text);
8403 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
8404 return dumptostream(zone, fd, &dns_master_style_full,
8405 dns_masterformat_text);
8409 dns_zone_unload(dns_zone_t *zone) {
8410 REQUIRE(DNS_ZONE_VALID(zone));
8418 notify_cancel(dns_zone_t *zone) {
8419 dns_notify_t *notify;
8422 * 'zone' locked by caller.
8425 REQUIRE(LOCKED_ZONE(zone));
8427 for (notify = ISC_LIST_HEAD(zone->notifies);
8429 notify = ISC_LIST_NEXT(notify, link)) {
8430 if (notify->find != NULL)
8431 dns_adb_cancelfind(notify->find);
8432 if (notify->request != NULL)
8433 dns_request_cancel(notify->request);
8438 zone_unload(dns_zone_t *zone) {
8441 * 'zone' locked by caller.
8444 REQUIRE(LOCKED_ZONE(zone));
8446 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
8447 zone_detachdb(zone);
8448 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
8449 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
8450 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8454 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8455 REQUIRE(DNS_ZONE_VALID(zone));
8458 zone->minrefresh = val;
8462 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8463 REQUIRE(DNS_ZONE_VALID(zone));
8466 zone->maxrefresh = val;
8470 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
8471 REQUIRE(DNS_ZONE_VALID(zone));
8474 zone->minretry = val;
8478 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
8479 REQUIRE(DNS_ZONE_VALID(zone));
8482 zone->maxretry = val;
8485 static isc_boolean_t
8486 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
8487 dns_notify_t *notify;
8489 for (notify = ISC_LIST_HEAD(zone->notifies);
8491 notify = ISC_LIST_NEXT(notify, link)) {
8492 if (notify->request != NULL)
8494 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
8495 dns_name_equal(name, ¬ify->ns))
8497 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
8503 static isc_boolean_t
8504 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
8505 dns_tsigkey_t *key = NULL;
8508 isc_boolean_t isself;
8509 isc_netaddr_t dstaddr;
8510 isc_result_t result;
8512 if (zone->view == NULL || zone->isself == NULL)
8515 switch (isc_sockaddr_pf(dst)) {
8517 src = zone->notifysrc4;
8518 isc_sockaddr_any(&any);
8521 src = zone->notifysrc6;
8522 isc_sockaddr_any6(&any);
8529 * When sending from any the kernel will assign a source address
8530 * that matches the destination address.
8532 if (isc_sockaddr_eqaddr(&any, &src))
8535 isc_netaddr_fromsockaddr(&dstaddr, dst);
8536 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
8537 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
8539 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
8542 dns_tsigkey_detach(&key);
8547 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
8551 * Caller holds zone lock.
8553 REQUIRE(DNS_NOTIFY_VALID(notify));
8555 if (notify->zone != NULL) {
8557 LOCK_ZONE(notify->zone);
8558 REQUIRE(LOCKED_ZONE(notify->zone));
8559 if (ISC_LINK_LINKED(notify, link))
8560 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
8562 UNLOCK_ZONE(notify->zone);
8564 zone_idetach(¬ify->zone);
8566 dns_zone_idetach(¬ify->zone);
8568 if (notify->find != NULL)
8569 dns_adb_destroyfind(¬ify->find);
8570 if (notify->request != NULL)
8571 dns_request_destroy(¬ify->request);
8572 if (dns_name_dynamic(¬ify->ns))
8573 dns_name_free(¬ify->ns, notify->mctx);
8574 mctx = notify->mctx;
8575 isc_mem_put(notify->mctx, notify, sizeof(*notify));
8576 isc_mem_detach(&mctx);
8580 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
8581 dns_notify_t *notify;
8583 REQUIRE(notifyp != NULL && *notifyp == NULL);
8585 notify = isc_mem_get(mctx, sizeof(*notify));
8587 return (ISC_R_NOMEMORY);
8589 notify->mctx = NULL;
8590 isc_mem_attach(mctx, ¬ify->mctx);
8591 notify->flags = flags;
8592 notify->zone = NULL;
8593 notify->find = NULL;
8594 notify->request = NULL;
8595 isc_sockaddr_any(¬ify->dst);
8596 dns_name_init(¬ify->ns, NULL);
8597 ISC_LINK_INIT(notify, link);
8598 notify->magic = NOTIFY_MAGIC;
8600 return (ISC_R_SUCCESS);
8604 * XXXAG should check for DNS_ZONEFLG_EXITING
8607 process_adb_event(isc_task_t *task, isc_event_t *ev) {
8608 dns_notify_t *notify;
8609 isc_eventtype_t result;
8613 notify = ev->ev_arg;
8614 REQUIRE(DNS_NOTIFY_VALID(notify));
8615 INSIST(task == notify->zone->task);
8616 result = ev->ev_type;
8617 isc_event_free(&ev);
8618 if (result == DNS_EVENT_ADBMOREADDRESSES) {
8619 dns_adb_destroyfind(¬ify->find);
8620 notify_find_address(notify);
8623 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
8624 LOCK_ZONE(notify->zone);
8625 notify_send(notify);
8626 UNLOCK_ZONE(notify->zone);
8628 notify_destroy(notify, ISC_FALSE);
8632 notify_find_address(dns_notify_t *notify) {
8633 isc_result_t result;
8634 unsigned int options;
8636 REQUIRE(DNS_NOTIFY_VALID(notify));
8637 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
8638 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
8640 if (notify->zone->view->adb == NULL)
8643 result = dns_adb_createfind(notify->zone->view->adb,
8645 process_adb_event, notify,
8646 ¬ify->ns, dns_rootname, 0,
8648 notify->zone->view->dstport,
8651 /* Something failed? */
8652 if (result != ISC_R_SUCCESS)
8655 /* More addresses pending? */
8656 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
8659 /* We have as many addresses as we can get. */
8660 LOCK_ZONE(notify->zone);
8661 notify_send(notify);
8662 UNLOCK_ZONE(notify->zone);
8665 notify_destroy(notify, ISC_FALSE);
8670 notify_send_queue(dns_notify_t *notify) {
8672 isc_result_t result;
8674 e = isc_event_allocate(notify->mctx, NULL,
8675 DNS_EVENT_NOTIFYSENDTOADDR,
8677 notify, sizeof(isc_event_t));
8679 return (ISC_R_NOMEMORY);
8681 e->ev_sender = NULL;
8682 result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
8683 notify->zone->task, &e);
8684 if (result != ISC_R_SUCCESS)
8690 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
8691 dns_notify_t *notify;
8692 isc_result_t result;
8693 dns_message_t *message = NULL;
8694 isc_netaddr_t dstip;
8695 dns_tsigkey_t *key = NULL;
8696 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
8699 isc_boolean_t have_notifysource = ISC_FALSE;
8701 notify = event->ev_arg;
8702 REQUIRE(DNS_NOTIFY_VALID(notify));
8706 LOCK_ZONE(notify->zone);
8708 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
8709 result = ISC_R_CANCELED;
8713 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
8714 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
8715 notify->zone->view->requestmgr == NULL ||
8716 notify->zone->db == NULL) {
8717 result = ISC_R_CANCELED;
8722 * The raw IPv4 address should also exist. Don't send to the
8725 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
8726 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
8727 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
8728 notify_log(notify->zone, ISC_LOG_DEBUG(3),
8729 "notify: ignoring IPv6 mapped IPV4 address: %s",
8731 result = ISC_R_CANCELED;
8735 result = notify_createmessage(notify->zone, notify->flags, &message);
8736 if (result != ISC_R_SUCCESS)
8739 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
8740 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
8741 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
8742 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
8743 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
8744 "sent. Peer TSIG key lookup failure.", addrbuf);
8745 goto cleanup_message;
8748 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
8750 if (notify->zone->view->peers != NULL) {
8751 dns_peer_t *peer = NULL;
8752 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
8754 if (result == ISC_R_SUCCESS) {
8755 result = dns_peer_getnotifysource(peer, &src);
8756 if (result == ISC_R_SUCCESS)
8757 have_notifysource = ISC_TRUE;
8760 switch (isc_sockaddr_pf(¬ify->dst)) {
8762 if (!have_notifysource)
8763 src = notify->zone->notifysrc4;
8766 if (!have_notifysource)
8767 src = notify->zone->notifysrc6;
8770 result = ISC_R_NOTIMPLEMENTED;
8774 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
8776 result = dns_request_createvia2(notify->zone->view->requestmgr,
8777 message, &src, ¬ify->dst, 0, key,
8778 timeout * 3, timeout,
8779 notify->zone->task, notify_done,
8780 notify, ¬ify->request);
8781 if (result == ISC_R_SUCCESS) {
8782 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
8783 inc_stats(notify->zone,
8784 dns_zonestatscounter_notifyoutv4);
8786 inc_stats(notify->zone,
8787 dns_zonestatscounter_notifyoutv6);
8793 dns_tsigkey_detach(&key);
8795 dns_message_destroy(&message);
8797 UNLOCK_ZONE(notify->zone);
8798 if (result != ISC_R_SUCCESS)
8799 notify_destroy(notify, ISC_FALSE);
8800 isc_event_free(&event);
8804 notify_send(dns_notify_t *notify) {
8805 dns_adbaddrinfo_t *ai;
8807 isc_result_t result;
8808 dns_notify_t *new = NULL;
8811 * Zone lock held by caller.
8813 REQUIRE(DNS_NOTIFY_VALID(notify));
8814 REQUIRE(LOCKED_ZONE(notify->zone));
8816 for (ai = ISC_LIST_HEAD(notify->find->list);
8818 ai = ISC_LIST_NEXT(ai, publink)) {
8820 if (notify_isqueued(notify->zone, NULL, &dst))
8822 if (notify_isself(notify->zone, &dst))
8825 result = notify_create(notify->mctx,
8826 (notify->flags & DNS_NOTIFY_NOSOA),
8828 if (result != ISC_R_SUCCESS)
8830 zone_iattach(notify->zone, &new->zone);
8831 ISC_LIST_APPEND(new->zone->notifies, new, link);
8833 result = notify_send_queue(new);
8834 if (result != ISC_R_SUCCESS)
8841 notify_destroy(new, ISC_TRUE);
8845 dns_zone_notify(dns_zone_t *zone) {
8848 REQUIRE(DNS_ZONE_VALID(zone));
8851 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8854 zone_settimer(zone, &now);
8859 zone_notify(dns_zone_t *zone, isc_time_t *now) {
8860 dns_dbnode_t *node = NULL;
8861 dns_db_t *zonedb = NULL;
8862 dns_dbversion_t *version = NULL;
8863 dns_name_t *origin = NULL;
8866 dns_rdata_soa_t soa;
8867 isc_uint32_t serial;
8868 dns_rdata_t rdata = DNS_RDATA_INIT;
8869 dns_rdataset_t nsrdset;
8870 dns_rdataset_t soardset;
8871 isc_result_t result;
8872 dns_notify_t *notify = NULL;
8875 isc_boolean_t isqueued;
8876 dns_notifytype_t notifytype;
8877 unsigned int flags = 0;
8878 isc_boolean_t loggednotify = ISC_FALSE;
8880 REQUIRE(DNS_ZONE_VALID(zone));
8883 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
8884 notifytype = zone->notifytype;
8885 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
8888 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
8891 if (notifytype == dns_notifytype_no)
8894 if (notifytype == dns_notifytype_masteronly &&
8895 zone->type != dns_zone_master)
8898 origin = &zone->origin;
8901 * If the zone is dialup we are done as we don't want to send
8902 * the current soa so as to force a refresh query.
8904 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
8905 flags |= DNS_NOTIFY_NOSOA;
8910 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8911 if (zone->db != NULL)
8912 dns_db_attach(zone->db, &zonedb);
8913 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8916 dns_db_currentversion(zonedb, &version);
8917 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
8918 if (result != ISC_R_SUCCESS)
8921 dns_rdataset_init(&soardset);
8922 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
8923 dns_rdatatype_none, 0, &soardset, NULL);
8924 if (result != ISC_R_SUCCESS)
8928 * Find serial and master server's name.
8930 dns_name_init(&master, NULL);
8931 result = dns_rdataset_first(&soardset);
8932 if (result != ISC_R_SUCCESS)
8934 dns_rdataset_current(&soardset, &rdata);
8935 result = dns_rdata_tostruct(&rdata, &soa, NULL);
8936 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8937 dns_rdata_reset(&rdata);
8938 result = dns_name_dup(&soa.origin, zone->mctx, &master);
8939 serial = soa.serial;
8940 dns_rdataset_disassociate(&soardset);
8941 if (result != ISC_R_SUCCESS)
8945 * Enqueue notify requests for 'also-notify' servers.
8948 for (i = 0; i < zone->notifycnt; i++) {
8949 dst = zone->notify[i];
8950 if (notify_isqueued(zone, NULL, &dst))
8952 result = notify_create(zone->mctx, flags, ¬ify);
8953 if (result != ISC_R_SUCCESS)
8955 zone_iattach(zone, ¬ify->zone);
8957 ISC_LIST_APPEND(zone->notifies, notify, link);
8958 result = notify_send_queue(notify);
8959 if (result != ISC_R_SUCCESS)
8960 notify_destroy(notify, ISC_TRUE);
8961 if (!loggednotify) {
8962 notify_log(zone, ISC_LOG_INFO,
8963 "sending notifies (serial %u)",
8965 loggednotify = ISC_TRUE;
8971 if (notifytype == dns_notifytype_explicit)
8975 * Process NS RRset to generate notifies.
8978 dns_rdataset_init(&nsrdset);
8979 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
8980 dns_rdatatype_none, 0, &nsrdset, NULL);
8981 if (result != ISC_R_SUCCESS)
8984 result = dns_rdataset_first(&nsrdset);
8985 while (result == ISC_R_SUCCESS) {
8986 dns_rdataset_current(&nsrdset, &rdata);
8987 result = dns_rdata_tostruct(&rdata, &ns, NULL);
8988 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8989 dns_rdata_reset(&rdata);
8991 * Don't notify the master server unless explicitly
8992 * configured to do so.
8994 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
8995 dns_name_compare(&master, &ns.name) == 0) {
8996 result = dns_rdataset_next(&nsrdset);
9000 if (!loggednotify) {
9001 notify_log(zone, ISC_LOG_INFO,
9002 "sending notifies (serial %u)",
9004 loggednotify = ISC_TRUE;
9008 isqueued = notify_isqueued(zone, &ns.name, NULL);
9011 result = dns_rdataset_next(&nsrdset);
9014 result = notify_create(zone->mctx, flags, ¬ify);
9015 if (result != ISC_R_SUCCESS)
9017 dns_zone_iattach(zone, ¬ify->zone);
9018 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
9019 if (result != ISC_R_SUCCESS) {
9021 notify_destroy(notify, ISC_TRUE);
9026 ISC_LIST_APPEND(zone->notifies, notify, link);
9028 notify_find_address(notify);
9030 result = dns_rdataset_next(&nsrdset);
9032 dns_rdataset_disassociate(&nsrdset);
9035 if (dns_name_dynamic(&master))
9036 dns_name_free(&master, zone->mctx);
9038 dns_db_detachnode(zonedb, &node);
9040 dns_db_closeversion(zonedb, &version, ISC_FALSE);
9041 dns_db_detach(&zonedb);
9048 static inline isc_result_t
9049 save_nsrrset(dns_message_t *message, dns_name_t *name,
9050 dns_db_t *db, dns_dbversion_t *version)
9052 dns_rdataset_t *nsrdataset = NULL;
9053 dns_rdataset_t *rdataset = NULL;
9054 dns_dbnode_t *node = NULL;
9056 isc_result_t result;
9057 dns_rdata_t rdata = DNS_RDATA_INIT;
9060 * Extract NS RRset from message.
9062 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
9063 dns_rdatatype_ns, dns_rdatatype_none,
9065 if (result != ISC_R_SUCCESS)
9071 result = dns_db_findnode(db, name, ISC_TRUE, &node);
9072 if (result != ISC_R_SUCCESS)
9074 result = dns_db_addrdataset(db, node, version, 0,
9075 nsrdataset, 0, NULL);
9076 dns_db_detachnode(db, &node);
9077 if (result != ISC_R_SUCCESS)
9080 * Add glue rdatasets.
9082 for (result = dns_rdataset_first(nsrdataset);
9083 result == ISC_R_SUCCESS;
9084 result = dns_rdataset_next(nsrdataset)) {
9085 dns_rdataset_current(nsrdataset, &rdata);
9086 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9087 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9088 dns_rdata_reset(&rdata);
9089 if (!dns_name_issubdomain(&ns.name, name))
9092 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9093 &ns.name, dns_rdatatype_aaaa,
9094 dns_rdatatype_none, NULL,
9096 if (result == ISC_R_SUCCESS) {
9097 result = dns_db_findnode(db, &ns.name,
9099 if (result != ISC_R_SUCCESS)
9101 result = dns_db_addrdataset(db, node, version, 0,
9103 dns_db_detachnode(db, &node);
9104 if (result != ISC_R_SUCCESS)
9108 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9109 &ns.name, dns_rdatatype_a,
9110 dns_rdatatype_none, NULL,
9112 if (result == ISC_R_SUCCESS) {
9113 result = dns_db_findnode(db, &ns.name,
9115 if (result != ISC_R_SUCCESS)
9117 result = dns_db_addrdataset(db, node, version, 0,
9119 dns_db_detachnode(db, &node);
9120 if (result != ISC_R_SUCCESS)
9124 if (result != ISC_R_NOMORE)
9127 return (ISC_R_SUCCESS);
9134 stub_callback(isc_task_t *task, isc_event_t *event) {
9135 const char me[] = "stub_callback";
9136 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9137 dns_stub_t *stub = NULL;
9138 dns_message_t *msg = NULL;
9139 dns_zone_t *zone = NULL;
9140 char master[ISC_SOCKADDR_FORMATSIZE];
9141 char source[ISC_SOCKADDR_FORMATSIZE];
9142 isc_uint32_t nscnt, cnamecnt;
9143 isc_result_t result;
9145 isc_boolean_t exiting = ISC_FALSE;
9149 stub = revent->ev_arg;
9150 INSIST(DNS_STUB_VALID(stub));
9160 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9161 zone_debuglog(zone, me, 1, "exiting");
9166 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9167 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9169 if (revent->result != ISC_R_SUCCESS) {
9170 if (revent->result == ISC_R_TIMEDOUT &&
9171 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9173 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9175 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9176 "refreshing stub: timeout retrying "
9177 " without EDNS master %s (source %s)",
9181 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
9182 &zone->sourceaddr, &now);
9183 dns_zone_log(zone, ISC_LOG_INFO,
9184 "could not refresh stub from master %s"
9185 " (source %s): %s", master, source,
9186 dns_result_totext(revent->result));
9190 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9191 if (result != ISC_R_SUCCESS)
9194 result = dns_request_getresponse(revent->request, msg, 0);
9195 if (result != ISC_R_SUCCESS)
9201 if (msg->rcode != dns_rcode_noerror) {
9205 isc_buffer_init(&rb, rcode, sizeof(rcode));
9206 (void)dns_rcode_totext(msg->rcode, &rb);
9208 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9209 (msg->rcode == dns_rcode_servfail ||
9210 msg->rcode == dns_rcode_notimp ||
9211 msg->rcode == dns_rcode_formerr)) {
9212 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9213 "refreshing stub: rcode (%.*s) retrying "
9214 "without EDNS master %s (source %s)",
9215 (int)rb.used, rcode, master, source);
9217 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9222 dns_zone_log(zone, ISC_LOG_INFO,
9224 "unexpected rcode (%.*s) from %s (source %s)",
9225 (int)rb.used, rcode, master, source);
9230 * We need complete messages.
9232 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9233 if (dns_request_usedtcp(revent->request)) {
9234 dns_zone_log(zone, ISC_LOG_INFO,
9235 "refreshing stub: truncated TCP "
9236 "response from master %s (source %s)",
9241 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9247 * If non-auth log and next master.
9249 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9250 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
9251 "non-authoritative answer from "
9252 "master %s (source %s)", master, source);
9259 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9260 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
9262 if (cnamecnt != 0) {
9263 dns_zone_log(zone, ISC_LOG_INFO,
9264 "refreshing stub: unexpected CNAME response "
9265 "from master %s (source %s)", master, source);
9270 dns_zone_log(zone, ISC_LOG_INFO,
9271 "refreshing stub: no NS records in response "
9272 "from master %s (source %s)", master, source);
9279 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
9280 if (result != ISC_R_SUCCESS) {
9281 dns_zone_log(zone, ISC_LOG_INFO,
9282 "refreshing stub: unable to save NS records "
9283 "from master %s (source %s)", master, source);
9290 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
9291 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9292 if (zone->db == NULL)
9293 zone_attachdb(zone, stub->db);
9294 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9295 dns_db_detach(&stub->db);
9297 if (zone->masterfile != NULL) {
9298 dns_zone_dump(zone);
9299 TIME_NOW(&zone->loadtime);
9302 dns_message_destroy(&msg);
9303 isc_event_free(&event);
9305 dns_request_destroy(&zone->request);
9306 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9307 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9308 isc_interval_set(&i, zone->expire, 0);
9309 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9310 zone_settimer(zone, &now);
9315 if (stub->version != NULL)
9316 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
9317 if (stub->db != NULL)
9318 dns_db_detach(&stub->db);
9320 dns_message_destroy(&msg);
9321 isc_event_free(&event);
9323 dns_request_destroy(&zone->request);
9325 * Skip to next failed / untried master.
9329 } while (zone->curmaster < zone->masterscnt &&
9330 zone->mastersok[zone->curmaster]);
9331 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9332 if (exiting || zone->curmaster >= zone->masterscnt) {
9333 isc_boolean_t done = ISC_TRUE;
9335 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9336 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9338 * Did we get a good answer from all the masters?
9340 for (j = 0; j < zone->masterscnt; j++)
9341 if (zone->mastersok[j] == ISC_FALSE) {
9348 zone->curmaster = 0;
9350 * Find the next failed master.
9352 while (zone->curmaster < zone->masterscnt &&
9353 zone->mastersok[zone->curmaster])
9355 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9357 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9359 zone_settimer(zone, &now);
9364 queue_soa_query(zone);
9370 dns_message_destroy(&msg);
9371 isc_event_free(&event);
9373 dns_request_destroy(&zone->request);
9375 ns_query(zone, NULL, stub);
9380 dns_zone_idetach(&stub->zone);
9381 INSIST(stub->db == NULL);
9382 INSIST(stub->version == NULL);
9383 isc_mem_put(stub->mctx, stub, sizeof(*stub));
9386 INSIST(event == NULL);
9391 * An SOA query has finished (successfully or not).
9394 refresh_callback(isc_task_t *task, isc_event_t *event) {
9395 const char me[] = "refresh_callback";
9396 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9398 dns_message_t *msg = NULL;
9399 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
9401 char master[ISC_SOCKADDR_FORMATSIZE];
9402 char source[ISC_SOCKADDR_FORMATSIZE];
9403 dns_rdataset_t *rdataset = NULL;
9404 dns_rdata_t rdata = DNS_RDATA_INIT;
9405 dns_rdata_soa_t soa;
9406 isc_result_t result;
9407 isc_uint32_t serial, oldserial;
9410 zone = revent->ev_arg;
9411 INSIST(DNS_ZONE_VALID(zone));
9418 * if timeout log and next master;
9421 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9422 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9426 if (revent->result != ISC_R_SUCCESS) {
9427 if (revent->result == ISC_R_TIMEDOUT &&
9428 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9430 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9432 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9433 "refresh: timeout retrying without EDNS "
9434 "master %s (source %s)", master, source);
9437 if (revent->result == ISC_R_TIMEDOUT &&
9438 !dns_request_usedtcp(revent->request)) {
9439 dns_zone_log(zone, ISC_LOG_INFO,
9440 "refresh: retry limit for "
9441 "master %s exceeded (source %s)",
9443 /* Try with slave with TCP. */
9444 if (zone->type == dns_zone_slave &&
9445 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
9446 if (!dns_zonemgr_unreachable(zone->zmgr,
9451 DNS_ZONE_SETFLAG(zone,
9452 DNS_ZONEFLG_SOABEFOREAXFR);
9456 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9457 "refresh: skipped tcp fallback "
9458 "as master %s (source %s) is "
9459 "unreachable (cached)",
9463 dns_zone_log(zone, ISC_LOG_INFO,
9464 "refresh: failure trying master "
9465 "%s (source %s): %s", master, source,
9466 dns_result_totext(revent->result));
9470 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9471 if (result != ISC_R_SUCCESS)
9473 result = dns_request_getresponse(revent->request, msg, 0);
9474 if (result != ISC_R_SUCCESS) {
9475 dns_zone_log(zone, ISC_LOG_INFO,
9476 "refresh: failure trying master "
9477 "%s (source %s): %s", master, source,
9478 dns_result_totext(result));
9485 if (msg->rcode != dns_rcode_noerror) {
9489 isc_buffer_init(&rb, rcode, sizeof(rcode));
9490 (void)dns_rcode_totext(msg->rcode, &rb);
9492 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9493 (msg->rcode == dns_rcode_servfail ||
9494 msg->rcode == dns_rcode_notimp ||
9495 msg->rcode == dns_rcode_formerr)) {
9496 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9497 "refresh: rcode (%.*s) retrying without "
9498 "EDNS master %s (source %s)",
9499 (int)rb.used, rcode, master, source);
9501 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9505 dns_zone_log(zone, ISC_LOG_INFO,
9506 "refresh: unexpected rcode (%.*s) from "
9507 "master %s (source %s)", (int)rb.used, rcode,
9510 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
9512 if (msg->rcode == dns_rcode_refused &&
9513 zone->type == dns_zone_slave)
9519 * If truncated punt to zone transfer which will query again.
9521 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9522 if (zone->type == dns_zone_slave) {
9523 dns_zone_log(zone, ISC_LOG_INFO,
9524 "refresh: truncated UDP answer, "
9525 "initiating TCP zone xfer "
9526 "for master %s (source %s)",
9529 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9533 INSIST(zone->type == dns_zone_stub);
9534 if (dns_request_usedtcp(revent->request)) {
9535 dns_zone_log(zone, ISC_LOG_INFO,
9536 "refresh: truncated TCP response "
9537 "from master %s (source %s)",
9542 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9549 * if non-auth log and next master;
9551 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9552 dns_zone_log(zone, ISC_LOG_INFO,
9553 "refresh: non-authoritative answer from "
9554 "master %s (source %s)", master, source);
9558 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9559 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
9560 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
9561 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
9565 * There should not be a CNAME record at top of zone.
9567 if (cnamecnt != 0) {
9568 dns_zone_log(zone, ISC_LOG_INFO,
9569 "refresh: CNAME at top of zone "
9570 "in master %s (source %s)", master, source);
9575 * if referral log and next master;
9577 if (soacnt == 0 && soacount == 0 && nscount != 0) {
9578 dns_zone_log(zone, ISC_LOG_INFO,
9579 "refresh: referral response "
9580 "from master %s (source %s)", master, source);
9585 * if nodata log and next master;
9587 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
9588 dns_zone_log(zone, ISC_LOG_INFO,
9589 "refresh: NODATA response "
9590 "from master %s (source %s)", master, source);
9595 * Only one soa at top of zone.
9598 dns_zone_log(zone, ISC_LOG_INFO,
9599 "refresh: answer SOA count (%d) != 1 "
9600 "from master %s (source %s)",
9601 soacnt, master, source);
9608 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
9609 dns_rdatatype_soa, dns_rdatatype_none,
9611 if (result != ISC_R_SUCCESS) {
9612 dns_zone_log(zone, ISC_LOG_INFO,
9613 "refresh: unable to get SOA record "
9614 "from master %s (source %s)", master, source);
9618 result = dns_rdataset_first(rdataset);
9619 if (result != ISC_R_SUCCESS) {
9620 dns_zone_log(zone, ISC_LOG_INFO,
9621 "refresh: dns_rdataset_first() failed");
9625 dns_rdataset_current(rdataset, &rdata);
9626 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9627 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9629 serial = soa.serial;
9630 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
9631 result = dns_zone_getserial2(zone, &oldserial);
9632 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9633 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
9636 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
9639 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
9640 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
9641 isc_serial_gt(serial, oldserial)) {
9642 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
9643 &zone->sourceaddr, &now)) {
9644 dns_zone_log(zone, ISC_LOG_INFO,
9645 "refresh: skipping %s as master %s "
9646 "(source %s) is unreachable (cached)",
9647 zone->type == dns_zone_slave ?
9648 "zone transfer" : "NS query",
9653 isc_event_free(&event);
9655 dns_request_destroy(&zone->request);
9657 if (zone->type == dns_zone_slave) {
9660 INSIST(zone->type == dns_zone_stub);
9661 ns_query(zone, rdataset, NULL);
9664 dns_message_destroy(&msg);
9665 } else if (isc_serial_eq(soa.serial, oldserial)) {
9666 if (zone->masterfile != NULL) {
9667 result = ISC_R_FAILURE;
9668 if (zone->journal != NULL)
9669 result = isc_file_settime(zone->journal, &now);
9670 if (result == ISC_R_SUCCESS &&
9671 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
9672 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
9673 result = isc_file_settime(zone->masterfile,
9675 } else if (result != ISC_R_SUCCESS)
9676 result = isc_file_settime(zone->masterfile,
9678 /* Someone removed the file from underneath us! */
9679 if (result == ISC_R_FILENOTFOUND) {
9681 zone_needdump(zone, DNS_DUMP_DELAY);
9683 } else if (result != ISC_R_SUCCESS)
9684 dns_zone_log(zone, ISC_LOG_ERROR,
9685 "refresh: could not set file "
9686 "modification time of '%s': %s",
9688 dns_result_totext(result));
9690 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9691 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9692 zone->mastersok[zone->curmaster] = ISC_TRUE;
9695 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
9696 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
9697 "received from master %s < ours (%u)",
9698 soa.serial, master, oldserial);
9700 zone_debuglog(zone, me, 1, "ahead");
9701 zone->mastersok[zone->curmaster] = ISC_TRUE;
9705 dns_message_destroy(&msg);
9710 dns_message_destroy(&msg);
9711 isc_event_free(&event);
9713 dns_request_destroy(&zone->request);
9715 * Skip to next failed / untried master.
9719 } while (zone->curmaster < zone->masterscnt &&
9720 zone->mastersok[zone->curmaster]);
9721 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9722 if (zone->curmaster >= zone->masterscnt) {
9723 isc_boolean_t done = ISC_TRUE;
9724 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9725 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9727 * Did we get a good answer from all the masters?
9729 for (j = 0; j < zone->masterscnt; j++)
9730 if (zone->mastersok[j] == ISC_FALSE) {
9737 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9738 zone->curmaster = 0;
9740 * Find the next failed master.
9742 while (zone->curmaster < zone->masterscnt &&
9743 zone->mastersok[zone->curmaster])
9747 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9748 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
9749 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
9750 zone->refreshtime = now;
9752 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9753 zone_settimer(zone, &now);
9759 queue_soa_query(zone);
9765 dns_message_destroy(&msg);
9766 isc_event_free(&event);
9768 dns_request_destroy(&zone->request);
9769 queue_soa_query(zone);
9773 dns_zone_idetach(&zone);
9778 queue_soa_query(dns_zone_t *zone) {
9779 const char me[] = "queue_soa_query";
9781 dns_zone_t *dummy = NULL;
9782 isc_result_t result;
9788 REQUIRE(LOCKED_ZONE(zone));
9790 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9791 cancel_refresh(zone);
9795 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
9796 soa_query, zone, sizeof(isc_event_t));
9798 cancel_refresh(zone);
9803 * Attach so that we won't clean up
9804 * until the event is delivered.
9806 zone_iattach(zone, &dummy);
9809 e->ev_sender = NULL;
9810 result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
9811 if (result != ISC_R_SUCCESS) {
9812 zone_idetach(&dummy);
9814 cancel_refresh(zone);
9818 static inline isc_result_t
9819 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
9820 dns_message_t **messagep)
9822 dns_message_t *message = NULL;
9823 dns_name_t *qname = NULL;
9824 dns_rdataset_t *qrdataset = NULL;
9825 isc_result_t result;
9827 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
9829 if (result != ISC_R_SUCCESS)
9832 message->opcode = dns_opcode_query;
9833 message->rdclass = zone->rdclass;
9835 result = dns_message_gettempname(message, &qname);
9836 if (result != ISC_R_SUCCESS)
9839 result = dns_message_gettemprdataset(message, &qrdataset);
9840 if (result != ISC_R_SUCCESS)
9846 dns_name_init(qname, NULL);
9847 dns_name_clone(&zone->origin, qname);
9848 dns_rdataset_init(qrdataset);
9849 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
9850 ISC_LIST_APPEND(qname->list, qrdataset, link);
9851 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
9853 *messagep = message;
9854 return (ISC_R_SUCCESS);
9858 dns_message_puttempname(message, &qname);
9859 if (qrdataset != NULL)
9860 dns_message_puttemprdataset(message, &qrdataset);
9861 if (message != NULL)
9862 dns_message_destroy(&message);
9867 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
9868 dns_rdataset_t *rdataset = NULL;
9869 dns_rdatalist_t *rdatalist = NULL;
9870 dns_rdata_t *rdata = NULL;
9871 isc_result_t result;
9873 result = dns_message_gettemprdatalist(message, &rdatalist);
9874 if (result != ISC_R_SUCCESS)
9876 result = dns_message_gettemprdata(message, &rdata);
9877 if (result != ISC_R_SUCCESS)
9879 result = dns_message_gettemprdataset(message, &rdataset);
9880 if (result != ISC_R_SUCCESS)
9882 dns_rdataset_init(rdataset);
9884 rdatalist->type = dns_rdatatype_opt;
9885 rdatalist->covers = 0;
9888 * Set Maximum UDP buffer size.
9890 rdatalist->rdclass = udpsize;
9893 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
9897 /* Set EDNS options if applicable */
9899 unsigned char data[4];
9902 isc_buffer_init(&buf, data, sizeof(data));
9903 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
9904 isc_buffer_putuint16(&buf, 0);
9906 rdata->length = sizeof(data);
9912 rdata->rdclass = rdatalist->rdclass;
9913 rdata->type = rdatalist->type;
9916 ISC_LIST_INIT(rdatalist->rdata);
9917 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
9918 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
9921 return (dns_message_setopt(message, rdataset));
9924 if (rdatalist != NULL)
9925 dns_message_puttemprdatalist(message, &rdatalist);
9926 if (rdataset != NULL)
9927 dns_message_puttemprdataset(message, &rdataset);
9929 dns_message_puttemprdata(message, &rdata);
9935 soa_query(isc_task_t *task, isc_event_t *event) {
9936 const char me[] = "soa_query";
9937 isc_result_t result = ISC_R_FAILURE;
9938 dns_message_t *message = NULL;
9939 dns_zone_t *zone = event->ev_arg;
9940 dns_zone_t *dummy = NULL;
9941 isc_netaddr_t masterip;
9942 dns_tsigkey_t *key = NULL;
9943 isc_uint32_t options;
9944 isc_boolean_t cancel = ISC_TRUE;
9946 isc_boolean_t have_xfrsource, reqnsid;
9947 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
9949 REQUIRE(DNS_ZONE_VALID(zone));
9956 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
9957 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
9958 zone->view->requestmgr == NULL) {
9959 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
9965 * XXX Optimisation: Create message when zone is setup and reuse.
9967 result = create_query(zone, dns_rdatatype_soa, &message);
9968 if (result != ISC_R_SUCCESS)
9972 INSIST(zone->masterscnt > 0);
9973 INSIST(zone->curmaster < zone->masterscnt);
9975 zone->masteraddr = zone->masters[zone->curmaster];
9977 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
9979 * First, look for a tsig key in the master statement, then
9980 * try for a server key.
9982 if ((zone->masterkeynames != NULL) &&
9983 (zone->masterkeynames[zone->curmaster] != NULL)) {
9984 dns_view_t *view = dns_zone_getview(zone);
9985 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
9986 result = dns_view_gettsig(view, keyname, &key);
9987 if (result != ISC_R_SUCCESS) {
9988 char namebuf[DNS_NAME_FORMATSIZE];
9989 dns_name_format(keyname, namebuf, sizeof(namebuf));
9990 dns_zone_log(zone, ISC_LOG_ERROR,
9991 "unable to find key: %s", namebuf);
9996 result = dns_view_getpeertsig(zone->view, &masterip, &key);
9997 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
9998 char addrbuf[ISC_NETADDR_FORMATSIZE];
9999 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
10000 dns_zone_log(zone, ISC_LOG_ERROR,
10001 "unable to find TSIG key for %s", addrbuf);
10006 have_xfrsource = ISC_FALSE;
10007 reqnsid = zone->view->requestnsid;
10008 if (zone->view->peers != NULL) {
10009 dns_peer_t *peer = NULL;
10010 isc_boolean_t edns;
10011 result = dns_peerlist_peerbyaddr(zone->view->peers,
10013 if (result == ISC_R_SUCCESS) {
10014 result = dns_peer_getsupportedns(peer, &edns);
10015 if (result == ISC_R_SUCCESS && !edns)
10016 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10017 result = dns_peer_gettransfersource(peer,
10018 &zone->sourceaddr);
10019 if (result == ISC_R_SUCCESS)
10020 have_xfrsource = ISC_TRUE;
10021 if (zone->view->resolver != NULL)
10023 dns_resolver_getudpsize(zone->view->resolver);
10024 (void)dns_peer_getudpsize(peer, &udpsize);
10025 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10029 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10031 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10032 if (isc_sockaddr_equal(&zone->altxfrsource4,
10033 &zone->xfrsource4))
10035 zone->sourceaddr = zone->altxfrsource4;
10036 } else if (!have_xfrsource)
10037 zone->sourceaddr = zone->xfrsource4;
10040 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10041 if (isc_sockaddr_equal(&zone->altxfrsource6,
10042 &zone->xfrsource6))
10044 zone->sourceaddr = zone->altxfrsource6;
10045 } else if (!have_xfrsource)
10046 zone->sourceaddr = zone->xfrsource6;
10049 result = ISC_R_NOTIMPLEMENTED;
10053 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
10054 DNS_REQUESTOPT_TCP : 0;
10056 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10057 result = add_opt(message, udpsize, reqnsid);
10058 if (result != ISC_R_SUCCESS)
10059 zone_debuglog(zone, me, 1,
10060 "unable to add opt record: %s",
10061 dns_result_totext(result));
10064 zone_iattach(zone, &dummy);
10066 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10068 result = dns_request_createvia2(zone->view->requestmgr, message,
10069 &zone->sourceaddr, &zone->masteraddr,
10070 options, key, timeout * 3, timeout,
10071 zone->task, refresh_callback, zone,
10073 if (result != ISC_R_SUCCESS) {
10074 zone_idetach(&dummy);
10075 zone_debuglog(zone, me, 1,
10076 "dns_request_createvia2() failed: %s",
10077 dns_result_totext(result));
10080 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
10081 inc_stats(zone, dns_zonestatscounter_soaoutv4);
10083 inc_stats(zone, dns_zonestatscounter_soaoutv6);
10085 cancel = ISC_FALSE;
10089 dns_tsigkey_detach(&key);
10090 if (result != ISC_R_SUCCESS)
10091 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10092 if (message != NULL)
10093 dns_message_destroy(&message);
10095 cancel_refresh(zone);
10096 isc_event_free(&event);
10098 dns_zone_idetach(&zone);
10103 dns_tsigkey_detach(&key);
10105 * Skip to next failed / untried master.
10109 } while (zone->curmaster < zone->masterscnt &&
10110 zone->mastersok[zone->curmaster]);
10111 if (zone->curmaster < zone->masterscnt)
10113 zone->curmaster = 0;
10118 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
10119 const char me[] = "ns_query";
10120 isc_result_t result;
10121 dns_message_t *message = NULL;
10122 isc_netaddr_t masterip;
10123 dns_tsigkey_t *key = NULL;
10124 dns_dbnode_t *node = NULL;
10126 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
10127 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10129 REQUIRE(DNS_ZONE_VALID(zone));
10130 REQUIRE((soardataset != NULL && stub == NULL) ||
10131 (soardataset == NULL && stub != NULL));
10132 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
10137 if (stub == NULL) {
10138 stub = isc_mem_get(zone->mctx, sizeof(*stub));
10141 stub->magic = STUB_MAGIC;
10142 stub->mctx = zone->mctx;
10145 stub->version = NULL;
10148 * Attach so that the zone won't disappear from under us.
10150 zone_iattach(zone, &stub->zone);
10153 * If a db exists we will update it, otherwise we create a
10154 * new one and attach it to the zone once we have the NS
10157 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10158 if (zone->db != NULL) {
10159 dns_db_attach(zone->db, &stub->db);
10160 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10162 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10164 INSIST(zone->db_argc >= 1);
10165 result = dns_db_create(zone->mctx, zone->db_argv[0],
10166 &zone->origin, dns_dbtype_stub,
10171 if (result != ISC_R_SUCCESS) {
10172 dns_zone_log(zone, ISC_LOG_ERROR,
10173 "refreshing stub: "
10174 "could not create "
10176 dns_result_totext(result));
10179 dns_db_settask(stub->db, zone->task);
10182 result = dns_db_newversion(stub->db, &stub->version);
10183 if (result != ISC_R_SUCCESS) {
10184 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10185 "dns_db_newversion() failed: %s",
10186 dns_result_totext(result));
10191 * Update SOA record.
10193 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
10195 if (result != ISC_R_SUCCESS) {
10196 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10197 "dns_db_findnode() failed: %s",
10198 dns_result_totext(result));
10202 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
10203 soardataset, 0, NULL);
10204 dns_db_detachnode(stub->db, &node);
10205 if (result != ISC_R_SUCCESS) {
10206 dns_zone_log(zone, ISC_LOG_INFO,
10207 "refreshing stub: "
10208 "dns_db_addrdataset() failed: %s",
10209 dns_result_totext(result));
10215 * XXX Optimisation: Create message when zone is setup and reuse.
10217 result = create_query(zone, dns_rdatatype_ns, &message);
10218 INSIST(result == ISC_R_SUCCESS);
10220 INSIST(zone->masterscnt > 0);
10221 INSIST(zone->curmaster < zone->masterscnt);
10222 zone->masteraddr = zone->masters[zone->curmaster];
10224 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10226 * First, look for a tsig key in the master statement, then
10227 * try for a server key.
10229 if ((zone->masterkeynames != NULL) &&
10230 (zone->masterkeynames[zone->curmaster] != NULL)) {
10231 dns_view_t *view = dns_zone_getview(zone);
10232 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10233 result = dns_view_gettsig(view, keyname, &key);
10234 if (result != ISC_R_SUCCESS) {
10235 char namebuf[DNS_NAME_FORMATSIZE];
10236 dns_name_format(keyname, namebuf, sizeof(namebuf));
10237 dns_zone_log(zone, ISC_LOG_ERROR,
10238 "unable to find key: %s", namebuf);
10242 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
10244 reqnsid = zone->view->requestnsid;
10245 if (zone->view->peers != NULL) {
10246 dns_peer_t *peer = NULL;
10247 isc_boolean_t edns;
10248 result = dns_peerlist_peerbyaddr(zone->view->peers,
10250 if (result == ISC_R_SUCCESS) {
10251 result = dns_peer_getsupportedns(peer, &edns);
10252 if (result == ISC_R_SUCCESS && !edns)
10253 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10254 result = dns_peer_gettransfersource(peer,
10255 &zone->sourceaddr);
10256 if (result == ISC_R_SUCCESS)
10257 have_xfrsource = ISC_TRUE;
10258 if (zone->view->resolver != NULL)
10260 dns_resolver_getudpsize(zone->view->resolver);
10261 (void)dns_peer_getudpsize(peer, &udpsize);
10262 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10266 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10267 result = add_opt(message, udpsize, reqnsid);
10268 if (result != ISC_R_SUCCESS)
10269 zone_debuglog(zone, me, 1,
10270 "unable to add opt record: %s",
10271 dns_result_totext(result));
10275 * Always use TCP so that we shouldn't truncate in additional section.
10277 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10279 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10280 zone->sourceaddr = zone->altxfrsource4;
10281 else if (!have_xfrsource)
10282 zone->sourceaddr = zone->xfrsource4;
10285 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10286 zone->sourceaddr = zone->altxfrsource6;
10287 else if (!have_xfrsource)
10288 zone->sourceaddr = zone->xfrsource6;
10291 result = ISC_R_NOTIMPLEMENTED;
10296 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10298 result = dns_request_createvia2(zone->view->requestmgr, message,
10299 &zone->sourceaddr, &zone->masteraddr,
10300 DNS_REQUESTOPT_TCP, key, timeout * 3,
10301 timeout, zone->task, stub_callback,
10302 stub, &zone->request);
10303 if (result != ISC_R_SUCCESS) {
10304 zone_debuglog(zone, me, 1,
10305 "dns_request_createvia() failed: %s",
10306 dns_result_totext(result));
10309 dns_message_destroy(&message);
10313 cancel_refresh(zone);
10314 if (stub != NULL) {
10316 if (stub->version != NULL)
10317 dns_db_closeversion(stub->db, &stub->version,
10319 if (stub->db != NULL)
10320 dns_db_detach(&stub->db);
10321 if (stub->zone != NULL)
10322 zone_idetach(&stub->zone);
10323 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10325 if (message != NULL)
10326 dns_message_destroy(&message);
10329 dns_tsigkey_detach(&key);
10335 * Handle the control event. Note that although this event causes the zone
10336 * to shut down, it is not a shutdown event in the sense of the task library.
10339 zone_shutdown(isc_task_t *task, isc_event_t *event) {
10340 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
10341 isc_boolean_t free_needed, linked = ISC_FALSE;
10344 REQUIRE(DNS_ZONE_VALID(zone));
10345 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
10346 INSIST(isc_refcount_current(&zone->erefs) == 0);
10347 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
10350 * Stop things being restarted after we cancel them below.
10353 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
10357 * If we were waiting for xfrin quota, step out of
10359 * If there's no zone manager, we can't be waiting for the
10362 if (zone->zmgr != NULL) {
10363 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10364 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
10365 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
10368 zone->statelist = NULL;
10370 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10374 * In task context, no locking required. See zone_xfrdone().
10376 if (zone->xfr != NULL)
10377 dns_xfrin_shutdown(zone->xfr);
10381 INSIST(zone->irefs > 0);
10384 if (zone->request != NULL) {
10385 dns_request_cancel(zone->request);
10388 if (zone->readio != NULL)
10389 zonemgr_cancelio(zone->readio);
10391 if (zone->lctx != NULL)
10392 dns_loadctx_cancel(zone->lctx);
10394 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10395 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10396 if (zone->writeio != NULL)
10397 zonemgr_cancelio(zone->writeio);
10399 if (zone->dctx != NULL)
10400 dns_dumpctx_cancel(zone->dctx);
10403 notify_cancel(zone);
10405 if (zone->timer != NULL) {
10406 isc_timer_detach(&zone->timer);
10407 INSIST(zone->irefs > 0);
10411 if (zone->view != NULL)
10412 dns_view_weakdetach(&zone->view);
10415 * We have now canceled everything set the flag to allow exit_check()
10416 * to succeed. We must not unlock between setting this flag and
10417 * calling exit_check().
10419 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
10420 free_needed = exit_check(zone);
10427 zone_timer(isc_task_t *task, isc_event_t *event) {
10428 const char me[] = "zone_timer";
10429 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
10432 REQUIRE(DNS_ZONE_VALID(zone));
10436 zone_maintenance(zone);
10438 isc_event_free(&event);
10442 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
10443 const char me[] = "zone_settimer";
10445 isc_result_t result;
10448 REQUIRE(DNS_ZONE_VALID(zone));
10449 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10452 isc_time_settoepoch(&next);
10454 switch (zone->type) {
10455 case dns_zone_master:
10456 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10457 next = zone->notifytime;
10458 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10459 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10460 INSIST(!isc_time_isepoch(&zone->dumptime));
10461 if (isc_time_isepoch(&next) ||
10462 isc_time_compare(&zone->dumptime, &next) < 0)
10463 next = zone->dumptime;
10465 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
10466 !isc_time_isepoch(&zone->refreshkeytime)) {
10467 if (isc_time_isepoch(&next) ||
10468 isc_time_compare(&zone->refreshkeytime, &next) < 0)
10469 next = zone->refreshkeytime;
10471 if (!isc_time_isepoch(&zone->resigntime)) {
10472 if (isc_time_isepoch(&next) ||
10473 isc_time_compare(&zone->resigntime, &next) < 0)
10474 next = zone->resigntime;
10476 if (!isc_time_isepoch(&zone->keywarntime)) {
10477 if (isc_time_isepoch(&next) ||
10478 isc_time_compare(&zone->keywarntime, &next) < 0)
10479 next = zone->keywarntime;
10481 if (!isc_time_isepoch(&zone->signingtime)) {
10482 if (isc_time_isepoch(&next) ||
10483 isc_time_compare(&zone->signingtime, &next) < 0)
10484 next = zone->signingtime;
10486 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
10487 if (isc_time_isepoch(&next) ||
10488 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
10489 next = zone->nsec3chaintime;
10493 case dns_zone_slave:
10494 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10495 next = zone->notifytime;
10498 case dns_zone_stub:
10499 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
10500 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
10501 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
10502 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
10503 INSIST(!isc_time_isepoch(&zone->refreshtime));
10504 if (isc_time_isepoch(&next) ||
10505 isc_time_compare(&zone->refreshtime, &next) < 0)
10506 next = zone->refreshtime;
10508 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10509 INSIST(!isc_time_isepoch(&zone->expiretime));
10510 if (isc_time_isepoch(&next) ||
10511 isc_time_compare(&zone->expiretime, &next) < 0)
10512 next = zone->expiretime;
10514 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10515 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10516 INSIST(!isc_time_isepoch(&zone->dumptime));
10517 if (isc_time_isepoch(&next) ||
10518 isc_time_compare(&zone->dumptime, &next) < 0)
10519 next = zone->dumptime;
10524 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10525 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10526 INSIST(!isc_time_isepoch(&zone->dumptime));
10527 if (isc_time_isepoch(&next) ||
10528 isc_time_compare(&zone->dumptime, &next) < 0)
10529 next = zone->dumptime;
10531 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
10532 if (isc_time_isepoch(&next) ||
10533 (!isc_time_isepoch(&zone->refreshkeytime) &&
10534 isc_time_compare(&zone->refreshkeytime, &next) < 0))
10535 next = zone->refreshkeytime;
10543 if (isc_time_isepoch(&next)) {
10544 zone_debuglog(zone, me, 10, "settimer inactive");
10545 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
10546 NULL, NULL, ISC_TRUE);
10547 if (result != ISC_R_SUCCESS)
10548 dns_zone_log(zone, ISC_LOG_ERROR,
10549 "could not deactivate zone timer: %s",
10550 isc_result_totext(result));
10552 if (isc_time_compare(&next, now) <= 0)
10554 result = isc_timer_reset(zone->timer, isc_timertype_once,
10555 &next, NULL, ISC_TRUE);
10556 if (result != ISC_R_SUCCESS)
10557 dns_zone_log(zone, ISC_LOG_ERROR,
10558 "could not reset zone timer: %s",
10559 isc_result_totext(result));
10564 cancel_refresh(dns_zone_t *zone) {
10565 const char me[] = "cancel_refresh";
10569 * 'zone' locked by caller.
10572 REQUIRE(DNS_ZONE_VALID(zone));
10573 REQUIRE(LOCKED_ZONE(zone));
10577 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10579 zone_settimer(zone, &now);
10582 static isc_result_t
10583 notify_createmessage(dns_zone_t *zone, unsigned int flags,
10584 dns_message_t **messagep)
10586 dns_db_t *zonedb = NULL;
10587 dns_dbnode_t *node = NULL;
10588 dns_dbversion_t *version = NULL;
10589 dns_message_t *message = NULL;
10590 dns_rdataset_t rdataset;
10591 dns_rdata_t rdata = DNS_RDATA_INIT;
10593 dns_name_t *tempname = NULL;
10594 dns_rdata_t *temprdata = NULL;
10595 dns_rdatalist_t *temprdatalist = NULL;
10596 dns_rdataset_t *temprdataset = NULL;
10598 isc_result_t result;
10600 isc_buffer_t *b = NULL;
10602 REQUIRE(DNS_ZONE_VALID(zone));
10603 REQUIRE(messagep != NULL && *messagep == NULL);
10605 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10607 if (result != ISC_R_SUCCESS)
10610 message->opcode = dns_opcode_notify;
10611 message->flags |= DNS_MESSAGEFLAG_AA;
10612 message->rdclass = zone->rdclass;
10614 result = dns_message_gettempname(message, &tempname);
10615 if (result != ISC_R_SUCCESS)
10618 result = dns_message_gettemprdataset(message, &temprdataset);
10619 if (result != ISC_R_SUCCESS)
10625 dns_name_init(tempname, NULL);
10626 dns_name_clone(&zone->origin, tempname);
10627 dns_rdataset_init(temprdataset);
10628 dns_rdataset_makequestion(temprdataset, zone->rdclass,
10629 dns_rdatatype_soa);
10630 ISC_LIST_APPEND(tempname->list, temprdataset, link);
10631 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
10633 temprdataset = NULL;
10635 if ((flags & DNS_NOTIFY_NOSOA) != 0)
10638 result = dns_message_gettempname(message, &tempname);
10639 if (result != ISC_R_SUCCESS)
10641 result = dns_message_gettemprdata(message, &temprdata);
10642 if (result != ISC_R_SUCCESS)
10644 result = dns_message_gettemprdataset(message, &temprdataset);
10645 if (result != ISC_R_SUCCESS)
10647 result = dns_message_gettemprdatalist(message, &temprdatalist);
10648 if (result != ISC_R_SUCCESS)
10651 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10652 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
10653 dns_db_attach(zone->db, &zonedb);
10654 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10656 dns_name_init(tempname, NULL);
10657 dns_name_clone(&zone->origin, tempname);
10658 dns_db_currentversion(zonedb, &version);
10659 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
10660 if (result != ISC_R_SUCCESS)
10663 dns_rdataset_init(&rdataset);
10664 result = dns_db_findrdataset(zonedb, node, version,
10666 dns_rdatatype_none, 0, &rdataset,
10668 if (result != ISC_R_SUCCESS)
10670 result = dns_rdataset_first(&rdataset);
10671 if (result != ISC_R_SUCCESS)
10673 dns_rdataset_current(&rdataset, &rdata);
10674 dns_rdata_toregion(&rdata, &r);
10675 result = isc_buffer_allocate(zone->mctx, &b, r.length);
10676 if (result != ISC_R_SUCCESS)
10678 isc_buffer_putmem(b, r.base, r.length);
10679 isc_buffer_usedregion(b, &r);
10680 dns_rdata_init(temprdata);
10681 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
10682 dns_message_takebuffer(message, &b);
10683 result = dns_rdataset_next(&rdataset);
10684 dns_rdataset_disassociate(&rdataset);
10685 if (result != ISC_R_NOMORE)
10687 temprdatalist->rdclass = rdata.rdclass;
10688 temprdatalist->type = rdata.type;
10689 temprdatalist->covers = 0;
10690 temprdatalist->ttl = rdataset.ttl;
10691 ISC_LIST_INIT(temprdatalist->rdata);
10692 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
10694 dns_rdataset_init(temprdataset);
10695 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
10696 if (result != ISC_R_SUCCESS)
10699 ISC_LIST_APPEND(tempname->list, temprdataset, link);
10700 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
10701 temprdatalist = NULL;
10702 temprdataset = NULL;
10708 dns_db_detachnode(zonedb, &node);
10709 if (version != NULL)
10710 dns_db_closeversion(zonedb, &version, ISC_FALSE);
10711 if (zonedb != NULL)
10712 dns_db_detach(&zonedb);
10713 if (tempname != NULL)
10714 dns_message_puttempname(message, &tempname);
10715 if (temprdata != NULL)
10716 dns_message_puttemprdata(message, &temprdata);
10717 if (temprdataset != NULL)
10718 dns_message_puttemprdataset(message, &temprdataset);
10719 if (temprdatalist != NULL)
10720 dns_message_puttemprdatalist(message, &temprdatalist);
10723 *messagep = message;
10724 return (ISC_R_SUCCESS);
10727 if (tempname != NULL)
10728 dns_message_puttempname(message, &tempname);
10729 if (temprdataset != NULL)
10730 dns_message_puttemprdataset(message, &temprdataset);
10731 dns_message_destroy(&message);
10736 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
10737 dns_message_t *msg)
10740 dns_rdata_soa_t soa;
10741 dns_rdataset_t *rdataset = NULL;
10742 dns_rdata_t rdata = DNS_RDATA_INIT;
10743 isc_result_t result;
10744 char fromtext[ISC_SOCKADDR_FORMATSIZE];
10746 isc_netaddr_t netaddr;
10748 REQUIRE(DNS_ZONE_VALID(zone));
10751 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
10755 * Check that 'from' is a valid notify source, (zone->masters).
10756 * Return DNS_R_REFUSED if not.
10758 * If the notify message contains a serial number check it
10759 * against the zones serial and return if <= current serial
10761 * If a refresh check is progress, if so just record the
10762 * fact we received a NOTIFY and from where and return.
10763 * We will perform a new refresh check when the current one
10764 * completes. Return ISC_R_SUCCESS.
10766 * Otherwise initiate a refresh check using 'from' as the
10767 * first address to check. Return ISC_R_SUCCESS.
10770 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
10773 * We only handle NOTIFY (SOA) at the present.
10776 if (isc_sockaddr_pf(from) == PF_INET)
10777 inc_stats(zone, dns_zonestatscounter_notifyinv4);
10779 inc_stats(zone, dns_zonestatscounter_notifyinv6);
10780 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
10781 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
10782 dns_rdatatype_soa, dns_rdatatype_none,
10783 NULL, NULL) != ISC_R_SUCCESS) {
10785 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
10786 dns_zone_log(zone, ISC_LOG_NOTICE,
10788 "question section from: %s", fromtext);
10789 return (DNS_R_FORMERR);
10791 dns_zone_log(zone, ISC_LOG_NOTICE,
10792 "NOTIFY zone does not match");
10793 return (DNS_R_NOTIMP);
10797 * If we are a master zone just succeed.
10799 if (zone->type == dns_zone_master) {
10801 return (ISC_R_SUCCESS);
10804 isc_netaddr_fromsockaddr(&netaddr, from);
10805 for (i = 0; i < zone->masterscnt; i++) {
10806 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
10808 if (zone->view->aclenv.match_mapped &&
10809 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
10810 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
10811 isc_netaddr_t na1, na2;
10812 isc_netaddr_fromv4mapped(&na1, &netaddr);
10813 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
10814 if (isc_netaddr_equal(&na1, &na2))
10820 * Accept notify requests from non masters if they are on
10821 * 'zone->notify_acl'.
10823 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
10824 dns_acl_match(&netaddr, NULL, zone->notify_acl,
10825 &zone->view->aclenv,
10826 &match, NULL) == ISC_R_SUCCESS &&
10829 /* Accept notify. */
10830 } else if (i >= zone->masterscnt) {
10832 dns_zone_log(zone, ISC_LOG_INFO,
10833 "refused notify from non-master: %s", fromtext);
10834 inc_stats(zone, dns_zonestatscounter_notifyrej);
10835 return (DNS_R_REFUSED);
10839 * If the zone is loaded and there are answers check the serial
10840 * to see if we need to do a refresh. Do not worry about this
10841 * check if we are a dialup zone as we use the notify request
10842 * to trigger a refresh check.
10844 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
10845 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10846 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
10847 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
10850 dns_rdatatype_none, NULL,
10852 if (result == ISC_R_SUCCESS)
10853 result = dns_rdataset_first(rdataset);
10854 if (result == ISC_R_SUCCESS) {
10855 isc_uint32_t serial = 0, oldserial;
10857 dns_rdataset_current(rdataset, &rdata);
10858 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10859 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10860 serial = soa.serial;
10862 * The following should safely be performed without DB
10863 * lock and succeed in this context.
10865 result = zone_get_from_db(zone, zone->db, NULL, NULL,
10866 &oldserial, NULL, NULL, NULL,
10868 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10869 if (isc_serial_le(serial, oldserial)) {
10873 "zone is up to date",
10876 return (ISC_R_SUCCESS);
10882 * If we got this far and there was a refresh in progress just
10883 * let it complete. Record where we got the notify from so we
10884 * can perform a refresh check when the current one completes
10886 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
10887 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
10888 zone->notifyfrom = *from;
10890 dns_zone_log(zone, ISC_LOG_INFO,
10891 "notify from %s: refresh in progress, "
10892 "refresh check queued",
10894 return (ISC_R_SUCCESS);
10896 zone->notifyfrom = *from;
10898 dns_zone_refresh(zone);
10899 return (ISC_R_SUCCESS);
10903 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
10905 REQUIRE(DNS_ZONE_VALID(zone));
10908 if (zone->notify_acl != NULL)
10909 dns_acl_detach(&zone->notify_acl);
10910 dns_acl_attach(acl, &zone->notify_acl);
10915 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
10917 REQUIRE(DNS_ZONE_VALID(zone));
10920 if (zone->query_acl != NULL)
10921 dns_acl_detach(&zone->query_acl);
10922 dns_acl_attach(acl, &zone->query_acl);
10927 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
10929 REQUIRE(DNS_ZONE_VALID(zone));
10932 if (zone->queryon_acl != NULL)
10933 dns_acl_detach(&zone->queryon_acl);
10934 dns_acl_attach(acl, &zone->queryon_acl);
10939 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
10941 REQUIRE(DNS_ZONE_VALID(zone));
10944 if (zone->update_acl != NULL)
10945 dns_acl_detach(&zone->update_acl);
10946 dns_acl_attach(acl, &zone->update_acl);
10951 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
10953 REQUIRE(DNS_ZONE_VALID(zone));
10956 if (zone->forward_acl != NULL)
10957 dns_acl_detach(&zone->forward_acl);
10958 dns_acl_attach(acl, &zone->forward_acl);
10963 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
10965 REQUIRE(DNS_ZONE_VALID(zone));
10968 if (zone->xfr_acl != NULL)
10969 dns_acl_detach(&zone->xfr_acl);
10970 dns_acl_attach(acl, &zone->xfr_acl);
10975 dns_zone_getnotifyacl(dns_zone_t *zone) {
10977 REQUIRE(DNS_ZONE_VALID(zone));
10979 return (zone->notify_acl);
10983 dns_zone_getqueryacl(dns_zone_t *zone) {
10985 REQUIRE(DNS_ZONE_VALID(zone));
10987 return (zone->query_acl);
10991 dns_zone_getqueryonacl(dns_zone_t *zone) {
10993 REQUIRE(DNS_ZONE_VALID(zone));
10995 return (zone->queryon_acl);
10999 dns_zone_getupdateacl(dns_zone_t *zone) {
11001 REQUIRE(DNS_ZONE_VALID(zone));
11003 return (zone->update_acl);
11007 dns_zone_getforwardacl(dns_zone_t *zone) {
11009 REQUIRE(DNS_ZONE_VALID(zone));
11011 return (zone->forward_acl);
11015 dns_zone_getxfracl(dns_zone_t *zone) {
11017 REQUIRE(DNS_ZONE_VALID(zone));
11019 return (zone->xfr_acl);
11023 dns_zone_clearupdateacl(dns_zone_t *zone) {
11025 REQUIRE(DNS_ZONE_VALID(zone));
11028 if (zone->update_acl != NULL)
11029 dns_acl_detach(&zone->update_acl);
11034 dns_zone_clearforwardacl(dns_zone_t *zone) {
11036 REQUIRE(DNS_ZONE_VALID(zone));
11039 if (zone->forward_acl != NULL)
11040 dns_acl_detach(&zone->forward_acl);
11045 dns_zone_clearnotifyacl(dns_zone_t *zone) {
11047 REQUIRE(DNS_ZONE_VALID(zone));
11050 if (zone->notify_acl != NULL)
11051 dns_acl_detach(&zone->notify_acl);
11056 dns_zone_clearqueryacl(dns_zone_t *zone) {
11058 REQUIRE(DNS_ZONE_VALID(zone));
11061 if (zone->query_acl != NULL)
11062 dns_acl_detach(&zone->query_acl);
11067 dns_zone_clearqueryonacl(dns_zone_t *zone) {
11069 REQUIRE(DNS_ZONE_VALID(zone));
11072 if (zone->queryon_acl != NULL)
11073 dns_acl_detach(&zone->queryon_acl);
11078 dns_zone_clearxfracl(dns_zone_t *zone) {
11080 REQUIRE(DNS_ZONE_VALID(zone));
11083 if (zone->xfr_acl != NULL)
11084 dns_acl_detach(&zone->xfr_acl);
11089 dns_zone_getupdatedisabled(dns_zone_t *zone) {
11090 REQUIRE(DNS_ZONE_VALID(zone));
11091 return (zone->update_disabled);
11096 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
11097 REQUIRE(DNS_ZONE_VALID(zone));
11098 zone->update_disabled = state;
11102 dns_zone_getzeronosoattl(dns_zone_t *zone) {
11103 REQUIRE(DNS_ZONE_VALID(zone));
11104 return (zone->zero_no_soa_ttl);
11109 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
11110 REQUIRE(DNS_ZONE_VALID(zone));
11111 zone->zero_no_soa_ttl = state;
11115 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
11117 REQUIRE(DNS_ZONE_VALID(zone));
11119 zone->check_names = severity;
11123 dns_zone_getchecknames(dns_zone_t *zone) {
11125 REQUIRE(DNS_ZONE_VALID(zone));
11127 return (zone->check_names);
11131 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
11133 REQUIRE(DNS_ZONE_VALID(zone));
11135 zone->journalsize = size;
11139 dns_zone_getjournalsize(dns_zone_t *zone) {
11141 REQUIRE(DNS_ZONE_VALID(zone));
11143 return (zone->journalsize);
11147 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
11148 isc_result_t result = ISC_R_FAILURE;
11149 isc_buffer_t buffer;
11151 REQUIRE(buf != NULL);
11152 REQUIRE(length > 1U);
11155 * Leave space for terminating '\0'.
11157 isc_buffer_init(&buffer, buf, length - 1);
11158 if (dns_name_dynamic(&zone->origin))
11159 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11160 if (result != ISC_R_SUCCESS &&
11161 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11162 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11164 if (isc_buffer_availablelength(&buffer) > 0)
11165 isc_buffer_putstr(&buffer, "/");
11166 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11168 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
11169 strcmp(zone->view->name, "_default") != 0 &&
11170 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
11171 isc_buffer_putstr(&buffer, "/");
11172 isc_buffer_putstr(&buffer, zone->view->name);
11175 buf[isc_buffer_usedlength(&buffer)] = '\0';
11179 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
11180 isc_result_t result = ISC_R_FAILURE;
11181 isc_buffer_t buffer;
11183 REQUIRE(buf != NULL);
11184 REQUIRE(length > 1U);
11187 * Leave space for terminating '\0'.
11189 isc_buffer_init(&buffer, buf, length - 1);
11190 if (dns_name_dynamic(&zone->origin))
11191 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11192 if (result != ISC_R_SUCCESS &&
11193 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11194 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11196 buf[isc_buffer_usedlength(&buffer)] = '\0';
11200 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
11201 isc_buffer_t buffer;
11203 REQUIRE(buf != NULL);
11204 REQUIRE(length > 1U);
11207 * Leave space for terminating '\0'.
11209 isc_buffer_init(&buffer, buf, length - 1);
11210 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11212 buf[isc_buffer_usedlength(&buffer)] = '\0';
11216 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
11217 isc_buffer_t buffer;
11219 REQUIRE(buf != NULL);
11220 REQUIRE(length > 1U);
11224 * Leave space for terminating '\0'.
11226 isc_buffer_init(&buffer, buf, length - 1);
11228 if (zone->view == NULL) {
11229 isc_buffer_putstr(&buffer, "_none");
11230 } else if (strlen(zone->view->name)
11231 < isc_buffer_availablelength(&buffer)) {
11232 isc_buffer_putstr(&buffer, zone->view->name);
11234 isc_buffer_putstr(&buffer, "_toolong");
11237 buf[isc_buffer_usedlength(&buffer)] = '\0';
11241 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
11242 REQUIRE(DNS_ZONE_VALID(zone));
11243 REQUIRE(buf != NULL);
11244 zone_namerd_tostr(zone, buf, length);
11248 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11250 char message[4096];
11252 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11256 vsnprintf(message, sizeof(message), fmt, ap);
11258 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
11259 level, "zone %s: %s", zone->strnamerd, message);
11263 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
11264 int level, const char *fmt, ...) {
11266 char message[4096];
11268 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11272 vsnprintf(message, sizeof(message), fmt, ap);
11274 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
11275 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11276 "managed-keys-zone" : "zone", zone->strnamerd, message);
11280 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11282 char message[4096];
11284 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11288 vsnprintf(message, sizeof(message), fmt, ap);
11290 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11291 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11292 "managed-keys-zone" : "zone", zone->strnamerd, message);
11296 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
11297 const char *fmt, ...)
11300 char message[4096];
11301 int level = ISC_LOG_DEBUG(debuglevel);
11303 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11307 vsnprintf(message, sizeof(message), fmt, ap);
11309 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11310 level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
11311 "zone" : "managed-keys-zone", zone->strnamerd, message);
11315 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
11317 isc_result_t result;
11319 dns_rdataset_t *curr;
11322 result = dns_message_firstname(msg, section);
11323 while (result == ISC_R_SUCCESS) {
11325 dns_message_currentname(msg, section, &name);
11327 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
11328 curr = ISC_LIST_PREV(curr, link)) {
11329 if (curr->type == type)
11332 result = dns_message_nextname(msg, section);
11339 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
11340 REQUIRE(DNS_ZONE_VALID(zone));
11342 zone->maxxfrin = maxxfrin;
11346 dns_zone_getmaxxfrin(dns_zone_t *zone) {
11347 REQUIRE(DNS_ZONE_VALID(zone));
11349 return (zone->maxxfrin);
11353 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
11354 REQUIRE(DNS_ZONE_VALID(zone));
11355 zone->maxxfrout = maxxfrout;
11359 dns_zone_getmaxxfrout(dns_zone_t *zone) {
11360 REQUIRE(DNS_ZONE_VALID(zone));
11362 return (zone->maxxfrout);
11366 dns_zone_gettype(dns_zone_t *zone) {
11367 REQUIRE(DNS_ZONE_VALID(zone));
11369 return (zone->type);
11373 dns_zone_getorigin(dns_zone_t *zone) {
11374 REQUIRE(DNS_ZONE_VALID(zone));
11376 return (&zone->origin);
11380 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
11381 REQUIRE(DNS_ZONE_VALID(zone));
11384 if (zone->task != NULL)
11385 isc_task_detach(&zone->task);
11386 isc_task_attach(task, &zone->task);
11387 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11388 if (zone->db != NULL)
11389 dns_db_settask(zone->db, zone->task);
11390 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11395 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
11396 REQUIRE(DNS_ZONE_VALID(zone));
11397 isc_task_attach(zone->task, target);
11401 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
11402 REQUIRE(DNS_ZONE_VALID(zone));
11405 idlein = DNS_DEFAULT_IDLEIN;
11406 zone->idlein = idlein;
11410 dns_zone_getidlein(dns_zone_t *zone) {
11411 REQUIRE(DNS_ZONE_VALID(zone));
11413 return (zone->idlein);
11417 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
11418 REQUIRE(DNS_ZONE_VALID(zone));
11420 zone->idleout = idleout;
11424 dns_zone_getidleout(dns_zone_t *zone) {
11425 REQUIRE(DNS_ZONE_VALID(zone));
11427 return (zone->idleout);
11431 notify_done(isc_task_t *task, isc_event_t *event) {
11432 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11433 dns_notify_t *notify;
11434 isc_result_t result;
11435 dns_message_t *message = NULL;
11438 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
11442 notify = event->ev_arg;
11443 REQUIRE(DNS_NOTIFY_VALID(notify));
11444 INSIST(task == notify->zone->task);
11446 isc_buffer_init(&buf, rcode, sizeof(rcode));
11447 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11449 result = revent->result;
11450 if (result == ISC_R_SUCCESS)
11451 result = dns_message_create(notify->zone->mctx,
11452 DNS_MESSAGE_INTENTPARSE, &message);
11453 if (result == ISC_R_SUCCESS)
11454 result = dns_request_getresponse(revent->request, message,
11455 DNS_MESSAGEPARSE_PRESERVEORDER);
11456 if (result == ISC_R_SUCCESS)
11457 result = dns_rcode_totext(message->rcode, &buf);
11458 if (result == ISC_R_SUCCESS)
11459 notify_log(notify->zone, ISC_LOG_DEBUG(3),
11460 "notify response from %s: %.*s",
11461 addrbuf, (int)buf.used, rcode);
11463 notify_log(notify->zone, ISC_LOG_DEBUG(2),
11464 "notify to %s failed: %s", addrbuf,
11465 dns_result_totext(result));
11468 * Old bind's return formerr if they see a soa record. Retry w/o
11469 * the soa if we see a formerr and had sent a SOA.
11471 isc_event_free(&event);
11472 if (message != NULL && message->rcode == dns_rcode_formerr &&
11473 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
11474 notify->flags |= DNS_NOTIFY_NOSOA;
11475 dns_request_destroy(¬ify->request);
11476 result = notify_send_queue(notify);
11477 if (result != ISC_R_SUCCESS)
11478 notify_destroy(notify, ISC_FALSE);
11480 if (result == ISC_R_TIMEDOUT)
11481 notify_log(notify->zone, ISC_LOG_DEBUG(1),
11482 "notify to %s: retries exceeded", addrbuf);
11483 notify_destroy(notify, ISC_FALSE);
11485 if (message != NULL)
11486 dns_message_destroy(&message);
11490 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11491 isc_result_t result;
11493 REQUIRE(DNS_ZONE_VALID(zone));
11495 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11496 result = zone_replacedb(zone, db, dump);
11497 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11502 static isc_result_t
11503 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11504 dns_dbversion_t *ver;
11505 isc_result_t result;
11506 unsigned int soacount = 0;
11507 unsigned int nscount = 0;
11510 * 'zone' and 'zonedb' locked by caller.
11512 REQUIRE(DNS_ZONE_VALID(zone));
11513 REQUIRE(LOCKED_ZONE(zone));
11515 result = zone_get_from_db(zone, db, &nscount, &soacount,
11516 NULL, NULL, NULL, NULL, NULL, NULL);
11517 if (result == ISC_R_SUCCESS) {
11518 if (soacount != 1) {
11519 dns_zone_log(zone, ISC_LOG_ERROR,
11520 "has %d SOA records", soacount);
11521 result = DNS_R_BADZONE;
11523 if (nscount == 0 && zone->type != dns_zone_key) {
11524 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
11525 result = DNS_R_BADZONE;
11527 if (result != ISC_R_SUCCESS)
11530 dns_zone_log(zone, ISC_LOG_ERROR,
11531 "retrieving SOA and NS records failed: %s",
11532 dns_result_totext(result));
11536 result = check_nsec3param(zone, db);
11537 if (result != ISC_R_SUCCESS)
11541 dns_db_currentversion(db, &ver);
11544 * The initial version of a slave zone is always dumped;
11545 * subsequent versions may be journaled instead if this
11546 * is enabled in the configuration.
11548 if (zone->db != NULL && zone->journal != NULL &&
11549 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
11550 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
11551 isc_uint32_t serial, oldserial;
11553 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
11555 result = dns_db_getsoaserial(db, ver, &serial);
11556 if (result != ISC_R_SUCCESS) {
11557 dns_zone_log(zone, ISC_LOG_ERROR,
11558 "ixfr-from-differences: unable to get "
11564 * This is checked in zone_postload() for master zones.
11566 result = zone_get_from_db(zone, zone->db, NULL, NULL,
11567 &oldserial, NULL, NULL, NULL, NULL,
11569 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11570 if (zone->type == dns_zone_slave &&
11571 !isc_serial_gt(serial, oldserial)) {
11572 isc_uint32_t serialmin, serialmax;
11573 serialmin = (oldserial + 1) & 0xffffffffU;
11574 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
11575 dns_zone_log(zone, ISC_LOG_ERROR,
11576 "ixfr-from-differences: failed: "
11577 "new serial (%u) out of range [%u - %u]",
11578 serial, serialmin, serialmax);
11579 result = ISC_R_RANGE;
11583 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
11585 if (result != ISC_R_SUCCESS)
11588 zone_needdump(zone, DNS_DUMP_DELAY);
11589 else if (zone->journalsize != -1) {
11590 result = dns_journal_compact(zone->mctx, zone->journal,
11591 serial, zone->journalsize);
11593 case ISC_R_SUCCESS:
11594 case ISC_R_NOSPACE:
11595 case ISC_R_NOTFOUND:
11596 dns_zone_log(zone, ISC_LOG_DEBUG(3),
11597 "dns_journal_compact: %s",
11598 dns_result_totext(result));
11601 dns_zone_log(zone, ISC_LOG_ERROR,
11602 "dns_journal_compact failed: %s",
11603 dns_result_totext(result));
11608 if (dump && zone->masterfile != NULL) {
11610 * If DNS_ZONEFLG_FORCEXFER was set we don't want
11611 * to keep the old masterfile.
11613 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
11614 remove(zone->masterfile) < 0 && errno != ENOENT) {
11615 char strbuf[ISC_STRERRORSIZE];
11616 isc__strerror(errno, strbuf, sizeof(strbuf));
11617 isc_log_write(dns_lctx,
11618 DNS_LOGCATEGORY_GENERAL,
11619 DNS_LOGMODULE_ZONE,
11621 "unable to remove masterfile "
11623 zone->masterfile, strbuf);
11625 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
11626 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
11628 zone_needdump(zone, 0);
11630 if (dump && zone->journal != NULL) {
11632 * The in-memory database just changed, and
11633 * because 'dump' is set, it didn't change by
11634 * being loaded from disk. Also, we have not
11635 * journaled diffs for this change.
11636 * Therefore, the on-disk journal is missing
11637 * the deltas for this change. Since it can
11638 * no longer be used to bring the zone
11639 * up-to-date, it is useless and should be
11642 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11643 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11644 "removing journal file");
11645 if (remove(zone->journal) < 0 && errno != ENOENT) {
11646 char strbuf[ISC_STRERRORSIZE];
11647 isc__strerror(errno, strbuf, sizeof(strbuf));
11648 isc_log_write(dns_lctx,
11649 DNS_LOGCATEGORY_GENERAL,
11650 DNS_LOGMODULE_ZONE,
11652 "unable to remove journal "
11654 zone->journal, strbuf);
11659 dns_db_closeversion(db, &ver, ISC_FALSE);
11661 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
11662 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
11663 "replacing zone database");
11665 if (zone->db != NULL)
11666 zone_detachdb(zone);
11667 zone_attachdb(zone, db);
11668 dns_db_settask(zone->db, zone->task);
11669 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
11670 return (ISC_R_SUCCESS);
11673 dns_db_closeversion(db, &ver, ISC_FALSE);
11677 /* The caller must hold the dblock as a writer. */
11679 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
11680 REQUIRE(zone->db == NULL && db != NULL);
11682 dns_db_attach(db, &zone->db);
11683 if (zone->acache != NULL) {
11684 isc_result_t result;
11685 result = dns_acache_setdb(zone->acache, db);
11686 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
11687 UNEXPECTED_ERROR(__FILE__, __LINE__,
11688 "dns_acache_setdb() failed: %s",
11689 isc_result_totext(result));
11694 /* The caller must hold the dblock as a writer. */
11696 zone_detachdb(dns_zone_t *zone) {
11697 REQUIRE(zone->db != NULL);
11699 if (zone->acache != NULL)
11700 (void)dns_acache_putdb(zone->acache, zone->db);
11701 dns_db_detach(&zone->db);
11705 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
11707 isc_boolean_t again = ISC_FALSE;
11708 unsigned int soacount;
11709 unsigned int nscount;
11710 isc_uint32_t serial, refresh, retry, expire, minimum;
11711 isc_result_t xfrresult = result;
11712 isc_boolean_t free_needed;
11714 REQUIRE(DNS_ZONE_VALID(zone));
11716 dns_zone_log(zone, ISC_LOG_DEBUG(1),
11717 "zone transfer finished: %s", dns_result_totext(result));
11720 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
11721 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
11722 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
11726 case ISC_R_SUCCESS:
11727 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
11729 case DNS_R_UPTODATE:
11730 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
11732 * Has the zone expired underneath us?
11734 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11735 if (zone->db == NULL) {
11736 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11741 * Update the zone structure's data from the actual
11746 INSIST(zone->db != NULL);
11747 result = zone_get_from_db(zone, zone->db, &nscount,
11748 &soacount, &serial, &refresh,
11749 &retry, &expire, &minimum, NULL);
11750 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11751 if (result == ISC_R_SUCCESS) {
11753 dns_zone_log(zone, ISC_LOG_ERROR,
11754 "transferred zone "
11755 "has %d SOA record%s", soacount,
11756 (soacount != 0) ? "s" : "");
11757 if (nscount == 0) {
11758 dns_zone_log(zone, ISC_LOG_ERROR,
11759 "transferred zone "
11760 "has no NS records");
11761 if (DNS_ZONE_FLAG(zone,
11762 DNS_ZONEFLG_HAVETIMERS)) {
11763 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
11764 zone->retry = DNS_ZONE_DEFAULTRETRY;
11766 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11770 zone->refresh = RANGE(refresh, zone->minrefresh,
11772 zone->retry = RANGE(retry, zone->minretry,
11774 zone->expire = RANGE(expire,
11775 zone->refresh + zone->retry,
11777 zone->minimum = minimum;
11778 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
11782 * Set our next update/expire times.
11784 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
11785 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11786 zone->refreshtime = now;
11787 DNS_ZONE_TIME_ADD(&now, zone->expire,
11788 &zone->expiretime);
11790 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
11791 &zone->refreshtime);
11792 DNS_ZONE_TIME_ADD(&now, zone->expire,
11793 &zone->expiretime);
11795 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
11796 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
11797 if (zone->tsigkey != NULL) {
11798 char namebuf[DNS_NAME_FORMATSIZE];
11799 dns_name_format(&zone->tsigkey->name, namebuf,
11801 snprintf(buf, sizeof(buf), ": TSIG '%s'",
11805 dns_zone_log(zone, ISC_LOG_INFO,
11806 "transferred serial %u%s",
11811 * This is not necessary if we just performed a AXFR
11812 * however it is necessary for an IXFR / UPTODATE and
11813 * won't hurt with an AXFR.
11815 if (zone->masterfile != NULL || zone->journal != NULL) {
11816 result = ISC_R_FAILURE;
11817 if (zone->journal != NULL)
11818 result = isc_file_settime(zone->journal, &now);
11819 if (result != ISC_R_SUCCESS &&
11820 zone->masterfile != NULL)
11821 result = isc_file_settime(zone->masterfile,
11823 /* Someone removed the file from underneath us! */
11824 if (result == ISC_R_FILENOTFOUND &&
11825 zone->masterfile != NULL) {
11826 unsigned int delay = DNS_DUMP_DELAY;
11827 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY))
11829 zone_needdump(zone, delay);
11830 } else if (result != ISC_R_SUCCESS)
11831 dns_zone_log(zone, ISC_LOG_ERROR,
11832 "transfer: could not set file "
11833 "modification time of '%s': %s",
11835 dns_result_totext(result));
11837 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
11838 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
11841 case DNS_R_BADIXFR:
11842 /* Force retry with AXFR. */
11843 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
11849 * Skip to next failed / untried master.
11853 } while (zone->curmaster < zone->masterscnt &&
11854 zone->mastersok[zone->curmaster]);
11857 if (zone->curmaster >= zone->masterscnt) {
11858 zone->curmaster = 0;
11859 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
11860 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
11861 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
11862 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11863 while (zone->curmaster < zone->masterscnt &&
11864 zone->mastersok[zone->curmaster])
11868 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
11870 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
11873 inc_stats(zone, dns_zonestatscounter_xfrfail);
11876 zone_settimer(zone, &now);
11879 * If creating the transfer object failed, zone->xfr is NULL.
11880 * Otherwise, we are called as the done callback of a zone
11881 * transfer object that just entered its shutting-down
11882 * state. Since we are no longer responsible for shutting
11883 * it down, we can detach our reference.
11885 if (zone->xfr != NULL)
11886 dns_xfrin_detach(&zone->xfr);
11888 if (zone->tsigkey != NULL)
11889 dns_tsigkey_detach(&zone->tsigkey);
11892 * Handle any deferred journal compaction.
11894 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
11895 result = dns_journal_compact(zone->mctx, zone->journal,
11896 zone->compact_serial,
11897 zone->journalsize);
11899 case ISC_R_SUCCESS:
11900 case ISC_R_NOSPACE:
11901 case ISC_R_NOTFOUND:
11902 dns_zone_log(zone, ISC_LOG_DEBUG(3),
11903 "dns_journal_compact: %s",
11904 dns_result_totext(result));
11907 dns_zone_log(zone, ISC_LOG_ERROR,
11908 "dns_journal_compact failed: %s",
11909 dns_result_totext(result));
11912 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
11916 * This transfer finishing freed up a transfer quota slot.
11917 * Let any other zones waiting for quota have it.
11919 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11920 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
11921 zone->statelist = NULL;
11922 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
11923 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
11926 * Retry with a different server if necessary.
11928 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
11929 queue_soa_query(zone);
11931 INSIST(zone->irefs > 0);
11933 free_needed = exit_check(zone);
11940 zone_loaddone(void *arg, isc_result_t result) {
11941 static char me[] = "zone_loaddone";
11942 dns_load_t *load = arg;
11944 isc_result_t tresult;
11946 REQUIRE(DNS_LOAD_VALID(load));
11951 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
11952 if (tresult != ISC_R_SUCCESS &&
11953 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
11956 LOCK_ZONE(load->zone);
11957 (void)zone_postload(load->zone, load->db, load->loadtime, result);
11958 zonemgr_putio(&load->zone->readio);
11959 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
11961 * Leave the zone frozen if the reload fails.
11963 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
11964 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
11965 zone->update_disabled = ISC_FALSE;
11966 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
11967 UNLOCK_ZONE(load->zone);
11970 dns_db_detach(&load->db);
11971 if (load->zone->lctx != NULL)
11972 dns_loadctx_detach(&load->zone->lctx);
11973 dns_zone_idetach(&load->zone);
11974 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
11978 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
11979 REQUIRE(DNS_ZONE_VALID(zone));
11980 REQUIRE(table != NULL);
11981 REQUIRE(*table == NULL);
11984 if (zone->ssutable != NULL)
11985 dns_ssutable_attach(zone->ssutable, table);
11990 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
11991 REQUIRE(DNS_ZONE_VALID(zone));
11994 if (zone->ssutable != NULL)
11995 dns_ssutable_detach(&zone->ssutable);
11997 dns_ssutable_attach(table, &zone->ssutable);
12002 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
12003 REQUIRE(DNS_ZONE_VALID(zone));
12005 zone->sigvalidityinterval = interval;
12009 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
12010 REQUIRE(DNS_ZONE_VALID(zone));
12012 return (zone->sigvalidityinterval);
12016 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
12017 REQUIRE(DNS_ZONE_VALID(zone));
12019 zone->sigresigninginterval = interval;
12023 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
12024 REQUIRE(DNS_ZONE_VALID(zone));
12026 return (zone->sigresigninginterval);
12030 queue_xfrin(dns_zone_t *zone) {
12031 const char me[] = "queue_xfrin";
12032 isc_result_t result;
12033 dns_zonemgr_t *zmgr = zone->zmgr;
12037 INSIST(zone->statelist == NULL);
12039 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12040 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
12044 zone->statelist = &zmgr->waiting_for_xfrin;
12045 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12046 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12048 if (result == ISC_R_QUOTA) {
12049 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
12050 "zone transfer deferred due to quota");
12051 } else if (result != ISC_R_SUCCESS) {
12052 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
12053 "starting zone transfer: %s",
12054 isc_result_totext(result));
12059 * This event callback is called when a zone has received
12060 * any necessary zone transfer quota. This is the time
12061 * to go ahead and start the transfer.
12064 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
12065 isc_result_t result;
12066 dns_peer_t *peer = NULL;
12067 char master[ISC_SOCKADDR_FORMATSIZE];
12068 char source[ISC_SOCKADDR_FORMATSIZE];
12069 dns_rdatatype_t xfrtype;
12070 dns_zone_t *zone = event->ev_arg;
12071 isc_netaddr_t masterip;
12072 isc_sockaddr_t sourceaddr;
12073 isc_sockaddr_t masteraddr;
12075 const char *soa_before = "";
12079 INSIST(task == zone->task);
12081 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12082 result = ISC_R_CANCELED;
12088 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12089 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
12090 &zone->sourceaddr, &now)) {
12091 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12092 dns_zone_log(zone, ISC_LOG_INFO,
12093 "got_transfer_quota: skipping zone transfer as "
12094 "master %s (source %s) is unreachable (cached)",
12096 result = ISC_R_CANCELED;
12100 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12101 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
12103 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12104 soa_before = "SOA before ";
12106 * Decide whether we should request IXFR or AXFR.
12108 if (zone->db == NULL) {
12109 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12110 "no database exists yet, requesting AXFR of "
12111 "initial version from %s", master);
12112 xfrtype = dns_rdatatype_axfr;
12113 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
12114 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
12115 "set, requesting %sAXFR from %s", soa_before,
12117 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12118 xfrtype = dns_rdatatype_soa;
12120 xfrtype = dns_rdatatype_axfr;
12121 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
12122 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12123 "forced reload, requesting AXFR of "
12124 "initial version from %s", master);
12125 xfrtype = dns_rdatatype_axfr;
12126 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
12127 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12128 "retrying with AXFR from %s due to "
12129 "previous IXFR failure", master);
12130 xfrtype = dns_rdatatype_axfr;
12132 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
12135 isc_boolean_t use_ixfr = ISC_TRUE;
12136 if (peer != NULL &&
12137 dns_peer_getrequestixfr(peer, &use_ixfr) ==
12139 ; /* Using peer setting */
12141 use_ixfr = zone->view->requestixfr;
12143 if (use_ixfr == ISC_FALSE) {
12144 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12145 "IXFR disabled, requesting %sAXFR from %s",
12146 soa_before, master);
12147 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12148 xfrtype = dns_rdatatype_soa;
12150 xfrtype = dns_rdatatype_axfr;
12152 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12153 "requesting IXFR from %s", master);
12154 xfrtype = dns_rdatatype_ixfr;
12159 * Determine if we should attempt to sign the request with TSIG.
12161 result = ISC_R_NOTFOUND;
12163 * First, look for a tsig key in the master statement, then
12164 * try for a server key.
12166 if ((zone->masterkeynames != NULL) &&
12167 (zone->masterkeynames[zone->curmaster] != NULL)) {
12168 dns_view_t *view = dns_zone_getview(zone);
12169 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12170 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
12172 if (zone->tsigkey == NULL)
12173 result = dns_view_getpeertsig(zone->view, &masterip,
12176 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
12177 dns_zone_log(zone, ISC_LOG_ERROR,
12178 "could not get TSIG key for zone transfer: %s",
12179 isc_result_totext(result));
12183 masteraddr = zone->masteraddr;
12184 sourceaddr = zone->sourceaddr;
12186 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
12187 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
12188 zone->tsigkey, zone->mctx,
12189 zone->zmgr->timermgr, zone->zmgr->socketmgr,
12190 zone->task, zone_xfrdone, &zone->xfr);
12191 if (result == ISC_R_SUCCESS) {
12193 if (xfrtype == dns_rdatatype_axfr) {
12194 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12195 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
12197 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
12198 } else if (xfrtype == dns_rdatatype_ixfr) {
12199 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12200 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
12202 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
12208 * Any failure in this function is handled like a failed
12209 * zone transfer. This ensures that we get removed from
12210 * zmgr->xfrin_in_progress.
12212 if (result != ISC_R_SUCCESS)
12213 zone_xfrdone(zone, result);
12215 isc_event_free(&event);
12219 * Update forwarding support.
12223 forward_destroy(dns_forward_t *forward) {
12225 forward->magic = 0;
12226 if (forward->request != NULL)
12227 dns_request_destroy(&forward->request);
12228 if (forward->msgbuf != NULL)
12229 isc_buffer_free(&forward->msgbuf);
12230 if (forward->zone != NULL)
12231 dns_zone_idetach(&forward->zone);
12232 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
12235 static isc_result_t
12236 sendtomaster(dns_forward_t *forward) {
12237 isc_result_t result;
12238 isc_sockaddr_t src;
12240 LOCK_ZONE(forward->zone);
12241 if (forward->which >= forward->zone->masterscnt) {
12242 UNLOCK_ZONE(forward->zone);
12243 return (ISC_R_NOMORE);
12246 forward->addr = forward->zone->masters[forward->which];
12248 * Always use TCP regardless of whether the original update
12250 * XXX The timeout may but a bit small if we are far down a
12251 * transfer graph and the master has to try several masters.
12253 switch (isc_sockaddr_pf(&forward->addr)) {
12255 src = forward->zone->xfrsource4;
12258 src = forward->zone->xfrsource6;
12261 result = ISC_R_NOTIMPLEMENTED;
12264 result = dns_request_createraw(forward->zone->view->requestmgr,
12266 &src, &forward->addr,
12267 DNS_REQUESTOPT_TCP, 15 /* XXX */,
12268 forward->zone->task,
12269 forward_callback, forward,
12270 &forward->request);
12272 UNLOCK_ZONE(forward->zone);
12277 forward_callback(isc_task_t *task, isc_event_t *event) {
12278 const char me[] = "forward_callback";
12279 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12280 dns_message_t *msg = NULL;
12281 char master[ISC_SOCKADDR_FORMATSIZE];
12282 isc_result_t result;
12283 dns_forward_t *forward;
12288 forward = revent->ev_arg;
12289 INSIST(DNS_FORWARD_VALID(forward));
12290 zone = forward->zone;
12291 INSIST(DNS_ZONE_VALID(zone));
12295 isc_sockaddr_format(&forward->addr, master, sizeof(master));
12297 if (revent->result != ISC_R_SUCCESS) {
12298 dns_zone_log(zone, ISC_LOG_INFO,
12299 "could not forward dynamic update to %s: %s",
12300 master, dns_result_totext(revent->result));
12304 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12305 if (result != ISC_R_SUCCESS)
12308 result = dns_request_getresponse(revent->request, msg,
12309 DNS_MESSAGEPARSE_PRESERVEORDER |
12310 DNS_MESSAGEPARSE_CLONEBUFFER);
12311 if (result != ISC_R_SUCCESS)
12314 switch (msg->rcode) {
12316 * Pass these rcodes back to client.
12318 case dns_rcode_noerror:
12319 case dns_rcode_yxdomain:
12320 case dns_rcode_yxrrset:
12321 case dns_rcode_nxrrset:
12322 case dns_rcode_refused:
12323 case dns_rcode_nxdomain:
12326 /* These should not occur if the masters/zone are valid. */
12327 case dns_rcode_notzone:
12328 case dns_rcode_notauth: {
12332 isc_buffer_init(&rb, rcode, sizeof(rcode));
12333 (void)dns_rcode_totext(msg->rcode, &rb);
12334 dns_zone_log(zone, ISC_LOG_WARNING,
12335 "forwarding dynamic update: "
12336 "unexpected response: master %s returned: %.*s",
12337 master, (int)rb.used, rcode);
12341 /* Try another server for these rcodes. */
12342 case dns_rcode_formerr:
12343 case dns_rcode_servfail:
12344 case dns_rcode_notimp:
12345 case dns_rcode_badvers:
12350 /* call callback */
12351 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
12353 dns_request_destroy(&forward->request);
12354 forward_destroy(forward);
12355 isc_event_free(&event);
12360 dns_message_destroy(&msg);
12361 isc_event_free(&event);
12363 dns_request_destroy(&forward->request);
12364 result = sendtomaster(forward);
12365 if (result != ISC_R_SUCCESS) {
12366 /* call callback */
12367 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12368 "exhausted dynamic update forwarder list");
12369 (forward->callback)(forward->callback_arg, result, NULL);
12370 forward_destroy(forward);
12375 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
12376 dns_updatecallback_t callback, void *callback_arg)
12378 dns_forward_t *forward;
12379 isc_result_t result;
12382 REQUIRE(DNS_ZONE_VALID(zone));
12383 REQUIRE(msg != NULL);
12384 REQUIRE(callback != NULL);
12386 forward = isc_mem_get(zone->mctx, sizeof(*forward));
12387 if (forward == NULL)
12388 return (ISC_R_NOMEMORY);
12390 forward->request = NULL;
12391 forward->zone = NULL;
12392 forward->msgbuf = NULL;
12393 forward->which = 0;
12395 forward->callback = callback;
12396 forward->callback_arg = callback_arg;
12397 forward->magic = FORWARD_MAGIC;
12399 mr = dns_message_getrawmessage(msg);
12401 result = ISC_R_UNEXPECTEDEND;
12405 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
12406 if (result != ISC_R_SUCCESS)
12408 result = isc_buffer_copyregion(forward->msgbuf, mr);
12409 if (result != ISC_R_SUCCESS)
12412 isc_mem_attach(zone->mctx, &forward->mctx);
12413 dns_zone_iattach(zone, &forward->zone);
12414 result = sendtomaster(forward);
12417 if (result != ISC_R_SUCCESS) {
12418 forward_destroy(forward);
12424 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
12425 REQUIRE(DNS_ZONE_VALID(zone));
12426 REQUIRE(next != NULL && *next == NULL);
12428 *next = ISC_LIST_NEXT(zone, link);
12430 return (ISC_R_NOMORE);
12432 return (ISC_R_SUCCESS);
12436 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
12437 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12438 REQUIRE(first != NULL && *first == NULL);
12440 *first = ISC_LIST_HEAD(zmgr->zones);
12441 if (*first == NULL)
12442 return (ISC_R_NOMORE);
12444 return (ISC_R_SUCCESS);
12452 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
12453 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
12454 dns_zonemgr_t **zmgrp)
12456 dns_zonemgr_t *zmgr;
12457 isc_result_t result;
12458 isc_interval_t interval;
12460 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
12462 return (ISC_R_NOMEMORY);
12465 isc_mem_attach(mctx, &zmgr->mctx);
12466 zmgr->taskmgr = taskmgr;
12467 zmgr->timermgr = timermgr;
12468 zmgr->socketmgr = socketmgr;
12469 zmgr->zonetasks = NULL;
12472 ISC_LIST_INIT(zmgr->zones);
12473 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
12474 ISC_LIST_INIT(zmgr->xfrin_in_progress);
12475 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
12476 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
12477 if (result != ISC_R_SUCCESS)
12480 zmgr->transfersin = 10;
12481 zmgr->transfersperns = 2;
12483 /* Create a single task for queueing of SOA queries. */
12484 result = isc_task_create(taskmgr, 1, &zmgr->task);
12485 if (result != ISC_R_SUCCESS)
12487 isc_task_setname(zmgr->task, "zmgr", zmgr);
12488 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
12490 if (result != ISC_R_SUCCESS)
12492 /* default to 20 refresh queries / notifies per second. */
12493 isc_interval_set(&interval, 0, 1000000000/2);
12494 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
12495 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12496 isc_ratelimiter_setpertic(zmgr->rl, 10);
12499 zmgr->ioactive = 0;
12500 ISC_LIST_INIT(zmgr->high);
12501 ISC_LIST_INIT(zmgr->low);
12503 result = isc_mutex_init(&zmgr->iolock);
12504 if (result != ISC_R_SUCCESS)
12507 zmgr->magic = ZONEMGR_MAGIC;
12510 return (ISC_R_SUCCESS);
12514 DESTROYLOCK(&zmgr->iolock);
12517 isc_ratelimiter_detach(&zmgr->rl);
12519 isc_task_detach(&zmgr->task);
12521 isc_rwlock_destroy(&zmgr->rwlock);
12523 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12524 isc_mem_detach(&mctx);
12529 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12530 isc_result_t result;
12532 REQUIRE(DNS_ZONE_VALID(zone));
12533 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12535 if (zmgr->zonetasks == NULL)
12536 return (ISC_R_FAILURE);
12538 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12540 REQUIRE(zone->task == NULL);
12541 REQUIRE(zone->timer == NULL);
12542 REQUIRE(zone->zmgr == NULL);
12544 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
12547 * Set the task name. The tag will arbitrarily point to one
12548 * of the zones sharing the task (in practice, the one
12549 * to be managed last).
12551 isc_task_setname(zone->task, "zone", zone);
12553 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
12555 zone->task, zone_timer, zone,
12558 if (result != ISC_R_SUCCESS)
12562 * The timer "holds" a iref.
12565 INSIST(zone->irefs != 0);
12567 ISC_LIST_APPEND(zmgr->zones, zone, link);
12574 isc_task_detach(&zone->task);
12578 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12583 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12584 isc_boolean_t free_now = ISC_FALSE;
12586 REQUIRE(DNS_ZONE_VALID(zone));
12587 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12588 REQUIRE(zone->zmgr == zmgr);
12590 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12593 ISC_LIST_UNLINK(zmgr->zones, zone, link);
12596 if (zmgr->refs == 0)
12597 free_now = ISC_TRUE;
12600 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12603 zonemgr_free(zmgr);
12604 ENSURE(zone->zmgr == NULL);
12608 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
12609 REQUIRE(DNS_ZONEMGR_VALID(source));
12610 REQUIRE(target != NULL && *target == NULL);
12612 RWLOCK(&source->rwlock, isc_rwlocktype_write);
12613 REQUIRE(source->refs > 0);
12615 INSIST(source->refs > 0);
12616 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
12621 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
12622 dns_zonemgr_t *zmgr;
12623 isc_boolean_t free_now = ISC_FALSE;
12625 REQUIRE(zmgrp != NULL);
12627 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12629 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12631 if (zmgr->refs == 0)
12632 free_now = ISC_TRUE;
12633 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12636 zonemgr_free(zmgr);
12641 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
12644 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12646 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12647 for (p = ISC_LIST_HEAD(zmgr->zones);
12649 p = ISC_LIST_NEXT(p, link))
12651 dns_zone_maintenance(p);
12653 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
12656 * Recent configuration changes may have increased the
12657 * amount of available transfers quota. Make sure any
12658 * transfers currently blocked on quota get started if
12661 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12662 zmgr_resume_xfrs(zmgr, ISC_TRUE);
12663 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12664 return (ISC_R_SUCCESS);
12668 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
12670 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12672 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12673 zmgr_resume_xfrs(zmgr, ISC_TRUE);
12674 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12678 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
12679 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12681 isc_ratelimiter_shutdown(zmgr->rl);
12683 if (zmgr->task != NULL)
12684 isc_task_destroy(&zmgr->task);
12685 if (zmgr->zonetasks != NULL)
12686 isc_taskpool_destroy(&zmgr->zonetasks);
12690 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
12691 isc_result_t result;
12692 int ntasks = num_zones / 100;
12693 isc_taskpool_t *pool = NULL;
12695 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12698 * For anything fewer than 1000 zones we use 10 tasks in
12699 * the task pool. More than that, and we'll scale at one
12700 * task per 100 zones.
12705 /* Create or resize the zone task pool. */
12706 if (zmgr->zonetasks == NULL)
12707 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
12710 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
12712 if (result == ISC_R_SUCCESS)
12713 zmgr->zonetasks = pool;
12719 zonemgr_free(dns_zonemgr_t *zmgr) {
12722 INSIST(zmgr->refs == 0);
12723 INSIST(ISC_LIST_EMPTY(zmgr->zones));
12727 DESTROYLOCK(&zmgr->iolock);
12728 isc_ratelimiter_detach(&zmgr->rl);
12730 isc_rwlock_destroy(&zmgr->rwlock);
12732 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12733 isc_mem_detach(&mctx);
12737 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
12738 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12740 zmgr->transfersin = value;
12744 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
12745 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12747 return (zmgr->transfersin);
12751 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
12752 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12754 zmgr->transfersperns = value;
12758 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
12759 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12761 return (zmgr->transfersperns);
12765 * Try to start a new incoming zone transfer to fill a quota
12766 * slot that was just vacated.
12769 * The zone manager is locked by the caller.
12772 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
12776 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
12780 isc_result_t result;
12781 next = ISC_LIST_NEXT(zone, statelink);
12782 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12783 if (result == ISC_R_SUCCESS) {
12787 * We successfully filled the slot. We're done.
12790 } else if (result == ISC_R_QUOTA) {
12792 * Not enough quota. This is probably the per-server
12793 * quota, because we usually get called when a unit of
12794 * global quota has just been freed. Try the next
12795 * zone, it may succeed if it uses another master.
12799 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12800 "starting zone transfer: %s",
12801 isc_result_totext(result));
12808 * Try to start an incoming zone transfer for 'zone', quota permitting.
12811 * The zone manager is locked by the caller.
12814 * ISC_R_SUCCESS There was enough quota and we attempted to
12815 * start a transfer. zone_xfrdone() has been or will
12817 * ISC_R_QUOTA Not enough quota.
12820 static isc_result_t
12821 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12822 dns_peer_t *peer = NULL;
12823 isc_netaddr_t masterip;
12824 isc_uint32_t nxfrsin, nxfrsperns;
12826 isc_uint32_t maxtransfersin, maxtransfersperns;
12830 * Find any configured information about the server we'd
12831 * like to transfer this zone from.
12833 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12834 (void)dns_peerlist_peerbyaddr(zone->view->peers,
12838 * Determine the total maximum number of simultaneous
12839 * transfers allowed, and the maximum for this specific
12842 maxtransfersin = zmgr->transfersin;
12843 maxtransfersperns = zmgr->transfersperns;
12845 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
12848 * Count the total number of transfers that are in progress,
12849 * and the number of transfers in progress from this master.
12850 * We linearly scan a list of all transfers; if this turns
12851 * out to be too slow, we could hash on the master address.
12853 nxfrsin = nxfrsperns = 0;
12854 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
12856 x = ISC_LIST_NEXT(x, statelink))
12859 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
12861 if (isc_netaddr_equal(&xip, &masterip))
12865 /* Enforce quota. */
12866 if (nxfrsin >= maxtransfersin)
12867 return (ISC_R_QUOTA);
12869 if (nxfrsperns >= maxtransfersperns)
12870 return (ISC_R_QUOTA);
12873 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
12874 * list and send it an event to let it start the actual transfer in the
12875 * context of its own task.
12877 e = isc_event_allocate(zmgr->mctx, zmgr,
12878 DNS_EVENT_ZONESTARTXFRIN,
12879 got_transfer_quota, zone,
12880 sizeof(isc_event_t));
12882 return (ISC_R_NOMEMORY);
12885 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
12886 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
12887 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
12888 zone->statelist = &zmgr->xfrin_in_progress;
12889 isc_task_send(zone->task, &e);
12890 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
12893 return (ISC_R_SUCCESS);
12897 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
12899 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12900 REQUIRE(iolimit > 0);
12902 zmgr->iolimit = iolimit;
12906 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
12908 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12910 return (zmgr->iolimit);
12914 * Get permission to request a file handle from the OS.
12915 * An event will be sent to action when one is available.
12916 * There are two queues available (high and low), the high
12917 * queue will be serviced before the low one.
12919 * zonemgr_putio() must be called after the event is delivered to
12923 static isc_result_t
12924 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
12925 isc_task_t *task, isc_taskaction_t action, void *arg,
12929 isc_boolean_t queue;
12931 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12932 REQUIRE(iop != NULL && *iop == NULL);
12934 io = isc_mem_get(zmgr->mctx, sizeof(*io));
12936 return (ISC_R_NOMEMORY);
12937 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
12938 action, arg, sizeof(*io->event));
12939 if (io->event == NULL) {
12940 isc_mem_put(zmgr->mctx, io, sizeof(*io));
12941 return (ISC_R_NOMEMORY);
12946 isc_task_attach(task, &io->task);
12947 ISC_LINK_INIT(io, link);
12948 io->magic = IO_MAGIC;
12950 LOCK(&zmgr->iolock);
12952 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
12955 ISC_LIST_APPEND(zmgr->high, io, link);
12957 ISC_LIST_APPEND(zmgr->low, io, link);
12959 UNLOCK(&zmgr->iolock);
12963 isc_task_send(io->task, &io->event);
12965 return (ISC_R_SUCCESS);
12969 zonemgr_putio(dns_io_t **iop) {
12972 dns_zonemgr_t *zmgr;
12974 REQUIRE(iop != NULL);
12976 REQUIRE(DNS_IO_VALID(io));
12980 INSIST(!ISC_LINK_LINKED(io, link));
12981 INSIST(io->event == NULL);
12984 isc_task_detach(&io->task);
12986 isc_mem_put(zmgr->mctx, io, sizeof(*io));
12988 LOCK(&zmgr->iolock);
12989 INSIST(zmgr->ioactive > 0);
12991 next = HEAD(zmgr->high);
12993 next = HEAD(zmgr->low);
12994 if (next != NULL) {
12996 ISC_LIST_UNLINK(zmgr->high, next, link);
12998 ISC_LIST_UNLINK(zmgr->low, next, link);
12999 INSIST(next->event != NULL);
13001 UNLOCK(&zmgr->iolock);
13003 isc_task_send(next->task, &next->event);
13007 zonemgr_cancelio(dns_io_t *io) {
13008 isc_boolean_t send_event = ISC_FALSE;
13010 REQUIRE(DNS_IO_VALID(io));
13013 * If we are queued to be run then dequeue.
13015 LOCK(&io->zmgr->iolock);
13016 if (ISC_LINK_LINKED(io, link)) {
13018 ISC_LIST_UNLINK(io->zmgr->high, io, link);
13020 ISC_LIST_UNLINK(io->zmgr->low, io, link);
13022 send_event = ISC_TRUE;
13023 INSIST(io->event != NULL);
13025 UNLOCK(&io->zmgr->iolock);
13027 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
13028 isc_task_send(io->task, &io->event);
13033 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
13036 isc_result_t result;
13038 buflen = strlen(path) + strlen(templat) + 2;
13040 buf = isc_mem_get(zone->mctx, buflen);
13044 result = isc_file_template(path, templat, buf, buflen);
13045 if (result != ISC_R_SUCCESS)
13048 result = isc_file_renameunique(path, buf);
13049 if (result != ISC_R_SUCCESS)
13052 dns_zone_log(zone, ISC_LOG_WARNING, "saved '%s' as '%s'",
13056 isc_mem_put(zone->mctx, buf, buflen);
13060 /* Hook for ondestroy notification from a database. */
13063 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
13064 dns_db_t *db = event->sender;
13067 isc_event_free(&event);
13069 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13070 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13071 "database (%p) destroyed", (void*) db);
13076 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
13077 isc_interval_t interval;
13078 isc_uint32_t s, ns;
13079 isc_uint32_t pertic;
13080 isc_result_t result;
13082 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13091 } else if (value <= 10) {
13093 ns = 1000000000 / value;
13097 ns = (1000000000 / value) * 10;
13101 isc_interval_set(&interval, s, ns);
13102 result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
13103 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13104 isc_ratelimiter_setpertic(zmgr->rl, pertic);
13106 zmgr->serialqueryrate = value;
13110 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
13111 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13113 return (zmgr->serialqueryrate);
13116 static isc_boolean_t
13117 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13118 isc_sockaddr_t *local, isc_time_t *now)
13121 isc_rwlocktype_t locktype;
13122 isc_result_t result;
13123 isc_uint32_t seconds = isc_time_seconds(now);
13125 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13127 locktype = isc_rwlocktype_read;
13128 RWLOCK(&zmgr->rwlock, locktype);
13129 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13130 if (zmgr->unreachable[i].expire >= seconds &&
13131 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13132 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13133 result = isc_rwlock_tryupgrade(&zmgr->rwlock);
13134 if (result == ISC_R_SUCCESS) {
13135 locktype = isc_rwlocktype_write;
13136 zmgr->unreachable[i].last = seconds;
13141 RWUNLOCK(&zmgr->rwlock, locktype);
13142 return (ISC_TF(i < UNREACH_CHACHE_SIZE));
13146 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13147 isc_sockaddr_t *local, isc_time_t *now)
13149 isc_uint32_t seconds = isc_time_seconds(now);
13150 isc_uint32_t last = seconds;
13151 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
13153 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13155 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13156 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13157 /* Existing entry? */
13158 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13159 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
13162 if (zmgr->unreachable[i].expire < seconds)
13164 /* Least recently used slot? */
13165 if (zmgr->unreachable[i].last < last) {
13166 last = zmgr->unreachable[i].last;
13170 if (i < UNREACH_CHACHE_SIZE) {
13172 * Found a existing entry. Update the expire timer and
13173 * last usage timestamps.
13175 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
13176 zmgr->unreachable[i].last = seconds;
13177 } else if (slot != UNREACH_CHACHE_SIZE) {
13179 * Found a empty slot. Add a new entry to the cache.
13181 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
13182 zmgr->unreachable[slot].last = seconds;
13183 zmgr->unreachable[slot].remote = *remote;
13184 zmgr->unreachable[slot].local = *local;
13187 * Replace the least recently used entry in the cache.
13189 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
13190 zmgr->unreachable[oldest].last = seconds;
13191 zmgr->unreachable[oldest].remote = *remote;
13192 zmgr->unreachable[oldest].local = *local;
13194 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13198 dns_zone_forcereload(dns_zone_t *zone) {
13199 REQUIRE(DNS_ZONE_VALID(zone));
13201 if (zone->type == dns_zone_master)
13205 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13207 dns_zone_refresh(zone);
13211 dns_zone_isforced(dns_zone_t *zone) {
13212 REQUIRE(DNS_ZONE_VALID(zone));
13214 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
13218 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
13220 * This function is obsoleted.
13224 return (ISC_R_NOTIMPLEMENTED);
13228 dns_zone_getstatscounters(dns_zone_t *zone) {
13230 * This function is obsoleted.
13237 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
13238 REQUIRE(DNS_ZONE_VALID(zone));
13239 REQUIRE(zone->stats == NULL);
13242 zone->stats = NULL;
13243 isc_stats_attach(stats, &zone->stats);
13248 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
13249 REQUIRE(DNS_ZONE_VALID(zone));
13252 if (zone->requeststats_on && stats == NULL)
13253 zone->requeststats_on = ISC_FALSE;
13254 else if (!zone->requeststats_on && stats != NULL) {
13255 if (zone->requeststats == NULL) {
13256 isc_stats_attach(stats, &zone->requeststats);
13257 zone->requeststats_on = ISC_TRUE;
13266 dns_zone_getrequeststats(dns_zone_t *zone) {
13268 * We don't lock zone for efficiency reason. This is not catastrophic
13269 * because requeststats must always be valid when requeststats_on is
13271 * Some counters may be incremented while requeststats_on is becoming
13272 * false, or some cannot be incremented just after the statistics are
13273 * installed, but it shouldn't matter much in practice.
13275 if (zone->requeststats_on)
13276 return (zone->requeststats);
13282 dns_zone_dialup(dns_zone_t *zone) {
13284 REQUIRE(DNS_ZONE_VALID(zone));
13286 zone_debuglog(zone, "dns_zone_dialup", 3,
13287 "notify = %d, refresh = %d",
13288 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
13289 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
13291 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
13292 dns_zone_notify(zone);
13293 if (zone->type != dns_zone_master &&
13294 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
13295 dns_zone_refresh(zone);
13299 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
13300 REQUIRE(DNS_ZONE_VALID(zone));
13303 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
13304 DNS_ZONEFLG_DIALREFRESH |
13305 DNS_ZONEFLG_NOREFRESH);
13307 case dns_dialuptype_no:
13309 case dns_dialuptype_yes:
13310 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
13311 DNS_ZONEFLG_DIALREFRESH |
13312 DNS_ZONEFLG_NOREFRESH));
13314 case dns_dialuptype_notify:
13315 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13317 case dns_dialuptype_notifypassive:
13318 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13319 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13321 case dns_dialuptype_refresh:
13322 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
13323 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13325 case dns_dialuptype_passive:
13326 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13335 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
13336 isc_result_t result = ISC_R_SUCCESS;
13338 REQUIRE(DNS_ZONE_VALID(zone));
13341 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
13348 dns_zone_getkeydirectory(dns_zone_t *zone) {
13349 REQUIRE(DNS_ZONE_VALID(zone));
13351 return (zone->keydirectory);
13355 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
13357 unsigned int count = 0;
13359 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13361 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13363 case DNS_ZONESTATE_XFERRUNNING:
13364 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13366 zone = ISC_LIST_NEXT(zone, statelink))
13369 case DNS_ZONESTATE_XFERDEFERRED:
13370 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
13372 zone = ISC_LIST_NEXT(zone, statelink))
13375 case DNS_ZONESTATE_SOAQUERY:
13376 for (zone = ISC_LIST_HEAD(zmgr->zones);
13378 zone = ISC_LIST_NEXT(zone, link))
13379 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
13382 case DNS_ZONESTATE_ANY:
13383 for (zone = ISC_LIST_HEAD(zmgr->zones);
13385 zone = ISC_LIST_NEXT(zone, link)) {
13386 dns_view_t *view = zone->view;
13387 if (view != NULL && strcmp(view->name, "_bind") == 0)
13396 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13402 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
13403 isc_boolean_t ok = ISC_TRUE;
13404 isc_boolean_t fail = ISC_FALSE;
13405 char namebuf[DNS_NAME_FORMATSIZE];
13406 char namebuf2[DNS_NAME_FORMATSIZE];
13407 char typebuf[DNS_RDATATYPE_FORMATSIZE];
13408 int level = ISC_LOG_WARNING;
13411 REQUIRE(DNS_ZONE_VALID(zone));
13413 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
13414 return (ISC_R_SUCCESS);
13416 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
13417 level = ISC_LOG_ERROR;
13421 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
13423 dns_name_format(name, namebuf, sizeof(namebuf));
13424 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13425 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
13426 dns_result_totext(DNS_R_BADOWNERNAME));
13428 return (DNS_R_BADOWNERNAME);
13431 dns_name_init(&bad, NULL);
13432 ok = dns_rdata_checknames(rdata, name, &bad);
13434 dns_name_format(name, namebuf, sizeof(namebuf));
13435 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
13436 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13437 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
13438 namebuf2, dns_result_totext(DNS_R_BADNAME));
13440 return (DNS_R_BADNAME);
13443 return (ISC_R_SUCCESS);
13447 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
13448 REQUIRE(DNS_ZONE_VALID(zone));
13449 zone->checkmx = checkmx;
13453 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
13454 REQUIRE(DNS_ZONE_VALID(zone));
13455 zone->checksrv = checksrv;
13459 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
13460 REQUIRE(DNS_ZONE_VALID(zone));
13461 zone->checkns = checkns;
13465 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
13466 REQUIRE(DNS_ZONE_VALID(zone));
13469 zone->isself = isself;
13470 zone->isselfarg = arg;
13475 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
13476 REQUIRE(DNS_ZONE_VALID(zone));
13479 zone->notifydelay = delay;
13484 dns_zone_getnotifydelay(dns_zone_t *zone) {
13485 REQUIRE(DNS_ZONE_VALID(zone));
13487 return (zone->notifydelay);
13491 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
13492 isc_uint16_t keyid, isc_boolean_t delete)
13494 isc_result_t result;
13495 REQUIRE(DNS_ZONE_VALID(zone));
13497 dns_zone_log(zone, ISC_LOG_NOTICE,
13498 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
13501 result = zone_signwithkey(zone, algorithm, keyid, delete);
13507 static const char *hex = "0123456789ABCDEF";
13510 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
13511 isc_result_t result;
13512 char salt[255*2+1];
13515 REQUIRE(DNS_ZONE_VALID(zone));
13517 if (nsec3param->salt_length != 0) {
13518 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
13519 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
13520 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
13521 salt[j++] = hex[nsec3param->salt[i] & 0xf];
13526 dns_zone_log(zone, ISC_LOG_NOTICE,
13527 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
13528 nsec3param->hash, nsec3param->iterations,
13531 result = zone_addnsec3chain(zone, nsec3param);
13538 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
13539 REQUIRE(DNS_ZONE_VALID(zone));
13543 zone->nodes = nodes;
13547 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
13548 REQUIRE(DNS_ZONE_VALID(zone));
13551 * We treat signatures as a signed value so explicitly
13552 * limit its range here.
13554 if (signatures > ISC_INT32_MAX)
13555 signatures = ISC_INT32_MAX;
13556 else if (signatures == 0)
13558 zone->signatures = signatures;
13562 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
13563 REQUIRE(DNS_ZONE_VALID(zone));
13564 zone->privatetype = type;
13568 dns_zone_getprivatetype(dns_zone_t *zone) {
13569 REQUIRE(DNS_ZONE_VALID(zone));
13570 return (zone->privatetype);
13573 static isc_result_t
13574 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
13575 isc_boolean_t delete)
13577 dns_signing_t *signing;
13578 dns_signing_t *current;
13579 isc_result_t result = ISC_R_SUCCESS;
13582 signing = isc_mem_get(zone->mctx, sizeof *signing);
13583 if (signing == NULL)
13584 return (ISC_R_NOMEMORY);
13586 signing->magic = 0;
13587 signing->db = NULL;
13588 signing->dbiterator = NULL;
13589 signing->algorithm = algorithm;
13590 signing->keyid = keyid;
13591 signing->delete = delete;
13592 signing->done = ISC_FALSE;
13596 for (current = ISC_LIST_HEAD(zone->signing);
13598 current = ISC_LIST_NEXT(current, link)) {
13599 if (current->db == zone->db &&
13600 current->algorithm == signing->algorithm &&
13601 current->keyid == signing->keyid) {
13602 if (current->delete != signing->delete)
13603 current->done = ISC_TRUE;
13609 if (zone->db != NULL) {
13610 dns_db_attach(zone->db, &signing->db);
13611 result = dns_db_createiterator(signing->db, 0,
13612 &signing->dbiterator);
13614 if (result == ISC_R_SUCCESS)
13615 result = dns_dbiterator_first(signing->dbiterator);
13616 if (result == ISC_R_SUCCESS) {
13617 dns_dbiterator_pause(signing->dbiterator);
13618 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
13620 if (isc_time_isepoch(&zone->signingtime)) {
13621 zone->signingtime = now;
13622 if (zone->task != NULL)
13623 zone_settimer(zone, &now);
13627 result = ISC_R_NOTFOUND;
13630 if (signing != NULL) {
13631 if (signing->db != NULL)
13632 dns_db_detach(&signing->db);
13633 if (signing->dbiterator != NULL)
13634 dns_dbiterator_destroy(&signing->dbiterator);
13635 isc_mem_put(zone->mctx, signing, sizeof *signing);
13641 logmsg(const char *format, ...) {
13643 va_start(args, format);
13644 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
13645 ISC_LOG_DEBUG(1), format, args);
13650 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
13651 dns_dnsseckey_t *key;
13652 while (!ISC_LIST_EMPTY(*list)) {
13653 key = ISC_LIST_HEAD(*list);
13654 ISC_LIST_UNLINK(*list, key, link);
13655 dns_dnsseckey_destroy(mctx, &key);
13659 /* Called once; *timep should be set to the current time. */
13660 static isc_result_t
13661 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
13662 isc_result_t result;
13663 isc_stdtime_t now, then = 0, event;
13668 for (i = 0; i <= DST_MAX_TIMES; i++) {
13669 result = dst_key_gettime(key, i, &event);
13670 if (result == ISC_R_SUCCESS && event > now &&
13671 (then == 0 || event < then))
13677 return (ISC_R_SUCCESS);
13680 return (ISC_R_NOTFOUND);
13683 static isc_result_t
13684 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
13685 const dns_rdata_t *rdata, isc_boolean_t *flag)
13687 dns_rdataset_t rdataset;
13688 dns_dbnode_t *node = NULL;
13689 isc_result_t result;
13691 dns_rdataset_init(&rdataset);
13692 if (rdata->type == dns_rdatatype_nsec3)
13693 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
13695 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
13696 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
13697 (isc_stdtime_t) 0, &rdataset, NULL);
13698 if (result == ISC_R_NOTFOUND) {
13700 result = ISC_R_SUCCESS;
13704 for (result = dns_rdataset_first(&rdataset);
13705 result == ISC_R_SUCCESS;
13706 result = dns_rdataset_next(&rdataset)) {
13707 dns_rdata_t myrdata = DNS_RDATA_INIT;
13708 dns_rdataset_current(&rdataset, &myrdata);
13709 if (!dns_rdata_compare(&myrdata, rdata))
13712 dns_rdataset_disassociate(&rdataset);
13713 if (result == ISC_R_SUCCESS) {
13715 } else if (result == ISC_R_NOMORE) {
13717 result = ISC_R_SUCCESS;
13722 dns_db_detachnode(db, &node);
13727 * Add records to signal the state of signing or of key removal.
13729 static isc_result_t
13730 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
13731 dns_dbversion_t *ver, dns_diff_t *diff,
13732 isc_boolean_t sign_all)
13734 dns_difftuple_t *tuple, *newtuple = NULL;
13735 dns_rdata_dnskey_t dnskey;
13736 dns_rdata_t rdata = DNS_RDATA_INIT;
13737 isc_boolean_t flag;
13739 isc_result_t result = ISC_R_SUCCESS;
13740 isc_uint16_t keyid;
13741 unsigned char buf[5];
13742 dns_name_t *name = dns_db_origin(db);
13744 for (tuple = ISC_LIST_HEAD(diff->tuples);
13746 tuple = ISC_LIST_NEXT(tuple, link)) {
13747 if (tuple->rdata.type != dns_rdatatype_dnskey)
13750 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
13751 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13752 if ((dnskey.flags &
13753 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
13754 != DNS_KEYOWNER_ZONE)
13757 dns_rdata_toregion(&tuple->rdata, &r);
13759 keyid = dst_region_computeid(&r, dnskey.algorithm);
13761 buf[0] = dnskey.algorithm;
13762 buf[1] = (keyid & 0xff00) >> 8;
13763 buf[2] = (keyid & 0xff);
13764 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
13767 rdata.length = sizeof(buf);
13768 rdata.type = privatetype;
13769 rdata.rdclass = tuple->rdata.rdclass;
13771 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
13772 CHECK(rr_exists(db, ver, name, &rdata, &flag));
13775 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
13776 name, 0, &rdata, &newtuple));
13777 CHECK(do_one_tuple(&newtuple, db, ver, diff));
13778 INSIST(newtuple == NULL);
13782 * Remove any record which says this operation has already
13786 CHECK(rr_exists(db, ver, name, &rdata, &flag));
13788 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
13789 name, 0, &rdata, &newtuple));
13790 CHECK(do_one_tuple(&newtuple, db, ver, diff));
13791 INSIST(newtuple == NULL);
13798 static isc_result_t
13799 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
13800 dns_diff_t *diff, dns_diff_t *sig_diff)
13802 isc_result_t result;
13803 isc_stdtime_t now, inception, soaexpire;
13804 isc_boolean_t check_ksk, keyset_kskonly;
13805 dst_key_t *zone_keys[MAXZONEKEYS];
13806 unsigned int nkeys = 0, i;
13807 dns_difftuple_t *tuple;
13809 result = find_zone_keys(zone, db, ver, zone->mctx, MAXZONEKEYS,
13810 zone_keys, &nkeys);
13811 if (result != ISC_R_SUCCESS) {
13812 dns_zone_log(zone, ISC_LOG_ERROR,
13813 "sign_apex:find_zone_keys -> %s\n",
13814 dns_result_totext(result));
13818 isc_stdtime_get(&now);
13819 inception = now - 3600; /* Allow for clock skew. */
13820 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
13822 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
13823 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
13826 * See if update_sigs will update DNSKEY signature and if not
13827 * cause them to sign so that so that newly activated keys
13830 for (tuple = ISC_LIST_HEAD(diff->tuples);
13832 tuple = ISC_LIST_NEXT(tuple, link)) {
13833 if (tuple->rdata.type == dns_rdatatype_dnskey &&
13834 dns_name_equal(&tuple->name, &zone->origin))
13838 if (tuple == NULL) {
13839 result = del_sigs(zone, db, ver, &zone->origin,
13840 dns_rdatatype_dnskey, sig_diff,
13841 zone_keys, nkeys, now, ISC_FALSE);
13842 if (result != ISC_R_SUCCESS) {
13843 dns_zone_log(zone, ISC_LOG_ERROR,
13844 "sign_apex:del_sigs -> %s\n",
13845 dns_result_totext(result));
13848 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
13849 sig_diff, zone_keys, nkeys, zone->mctx,
13850 inception, soaexpire, check_ksk,
13852 if (result != ISC_R_SUCCESS) {
13853 dns_zone_log(zone, ISC_LOG_ERROR,
13854 "sign_apex:add_sigs -> %s\n",
13855 dns_result_totext(result));
13860 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
13861 inception, soaexpire, now, check_ksk,
13862 keyset_kskonly, sig_diff);
13864 if (result != ISC_R_SUCCESS) {
13865 dns_zone_log(zone, ISC_LOG_ERROR,
13866 "sign_apex:update_sigs -> %s\n",
13867 dns_result_totext(result));
13872 for (i = 0; i < nkeys; i++)
13873 dst_key_free(&zone_keys[i]);
13878 * Prevent the zone entering a inconsistent state where
13879 * NSEC only DNSKEYs are present with NSEC3 chains.
13880 * See update.c:check_dnssec()
13882 static isc_boolean_t
13883 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
13886 isc_result_t result;
13887 dns_difftuple_t *tuple;
13888 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
13889 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
13891 /* Scan the tuples for an NSEC-only DNSKEY */
13892 for (tuple = ISC_LIST_HEAD(diff->tuples);
13894 tuple = ISC_LIST_NEXT(tuple, link)) {
13896 if (tuple->rdata.type != dns_rdatatype_dnskey ||
13897 tuple->op != DNS_DIFFOP_ADD)
13900 alg = tuple->rdata.data[3];
13901 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
13902 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
13903 nseconly = ISC_TRUE;
13908 /* Check existing DB for NSEC-only DNSKEY */
13910 CHECK(dns_nsec_nseconly(db, ver, &nseconly));
13912 /* Check existing DB for NSEC3 */
13914 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
13915 privatetype, &nsec3));
13917 /* Refuse to allow NSEC3 with NSEC-only keys */
13918 if (nseconly && nsec3) {
13919 dns_zone_log(zone, ISC_LOG_ERROR,
13920 "NSEC only DNSKEYs and NSEC3 chains not allowed");
13927 return (ISC_FALSE);
13930 static isc_result_t
13931 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
13934 isc_result_t result;
13935 dns_dbnode_t *node = NULL;
13936 dns_rdataset_t rdataset;
13938 dns_rdataset_init(&rdataset);
13939 CHECK(dns_db_getoriginnode(db, &node));
13941 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
13942 dns_rdatatype_none, 0, &rdataset, NULL);
13943 if (dns_rdataset_isassociated(&rdataset))
13944 dns_rdataset_disassociate(&rdataset);
13945 if (result != ISC_R_NOTFOUND)
13948 result = dns_nsec3param_deletechains(db, ver, zone, diff);
13952 dns_db_detachnode(db, &node);
13957 * Given an RRSIG rdataset and an algorithm, determine whether there
13958 * are any signatures using that algorithm.
13960 static isc_boolean_t
13961 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
13962 dns_rdata_t rdata = DNS_RDATA_INIT;
13963 dns_rdata_rrsig_t rrsig;
13964 isc_result_t result;
13966 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
13967 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
13968 return (ISC_FALSE);
13971 for (result = dns_rdataset_first(rdataset);
13972 result == ISC_R_SUCCESS;
13973 result = dns_rdataset_next(rdataset))
13975 dns_rdataset_current(rdataset, &rdata);
13976 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
13977 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13978 dns_rdata_reset(&rdata);
13979 if (rrsig.algorithm == alg)
13983 return (ISC_FALSE);
13986 static isc_result_t
13987 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
13990 dns_name_t *origin;
13991 isc_boolean_t build_nsec3;
13992 isc_result_t result;
13994 origin = dns_db_origin(db);
13995 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
13998 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
13999 ISC_FALSE, zone->privatetype, diff));
14000 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
14007 zone_rekey(dns_zone_t *zone) {
14008 isc_result_t result;
14009 dns_db_t *db = NULL;
14010 dns_dbnode_t *node = NULL;
14011 dns_dbversion_t *ver = NULL;
14012 dns_rdataset_t soaset, soasigs, keyset, keysigs;
14013 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
14014 dns_dnsseckey_t *key;
14015 dns_diff_t diff, sig_diff;
14016 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
14017 isc_boolean_t newalg = ISC_FALSE;
14018 isc_boolean_t fullsign;
14019 dns_ttl_t ttl = 3600;
14023 isc_time_t timenow;
14024 isc_interval_t ival;
14027 REQUIRE(DNS_ZONE_VALID(zone));
14029 ISC_LIST_INIT(dnskeys);
14030 ISC_LIST_INIT(keys);
14031 ISC_LIST_INIT(rmkeys);
14032 dns_rdataset_init(&soaset);
14033 dns_rdataset_init(&soasigs);
14034 dns_rdataset_init(&keyset);
14035 dns_rdataset_init(&keysigs);
14036 dir = dns_zone_getkeydirectory(zone);
14038 dns_diff_init(mctx, &diff);
14039 dns_diff_init(mctx, &sig_diff);
14040 sig_diff.resign = zone->sigresigninginterval;
14042 CHECK(dns_zone_getdb(zone, &db));
14043 CHECK(dns_db_newversion(db, &ver));
14044 CHECK(dns_db_getoriginnode(db, &node));
14046 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
14048 /* Get the SOA record's TTL */
14049 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
14050 dns_rdatatype_none, 0, &soaset, &soasigs));
14052 dns_rdataset_disassociate(&soaset);
14054 /* Get the DNSKEY rdataset */
14055 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14056 dns_rdatatype_none, 0, &keyset, &keysigs);
14057 if (result == ISC_R_SUCCESS) {
14059 result = dns_dnssec_keylistfromrdataset(&zone->origin, dir,
14061 &keysigs, &soasigs,
14062 ISC_FALSE, ISC_FALSE,
14064 /* Can't get keys for some reason; try again later. */
14065 if (result != ISC_R_SUCCESS)
14067 } else if (result != ISC_R_NOTFOUND)
14071 * True when called from "rndc sign". Indicates the zone should be
14072 * fully signed now.
14074 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
14076 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
14077 if (result == ISC_R_SUCCESS) {
14078 isc_boolean_t check_ksk;
14079 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14081 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
14082 &zone->origin, ttl, &diff,
14083 ISC_TF(!check_ksk),
14086 /* Keys couldn't be updated for some reason;
14087 * try again later. */
14088 if (result != ISC_R_SUCCESS) {
14089 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
14090 "couldn't update zone keys: %s",
14091 isc_result_totext(result));
14095 /* See if any pre-existing keys have newly become active;
14096 * also, see if any new key is for a new algorithm, as in that
14097 * event, we need to sign the zone fully. (If there's a new
14098 * key, but it's for an already-existing algorithm, then
14099 * the zone signing can be handled incrementally.)
14101 for (key = ISC_LIST_HEAD(dnskeys);
14103 key = ISC_LIST_NEXT(key, link)) {
14104 if (!key->first_sign)
14107 newactive = ISC_TRUE;
14109 if (!dns_rdataset_isassociated(&keysigs)) {
14114 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
14116 * This isn't a new algorithm; clear
14117 * first_sign so we won't sign the
14118 * whole zone with this key later
14120 key->first_sign = ISC_FALSE;
14127 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
14128 dnskey_sane(zone, db, ver, &diff)) {
14129 CHECK(dns_diff_apply(&diff, db, ver));
14130 CHECK(clean_nsec3param(zone, db, ver, &diff));
14131 CHECK(add_signing_records(db, zone->privatetype,
14133 ISC_TF(newalg || fullsign)));
14134 CHECK(increment_soa_serial(db, ver, &diff, mctx));
14135 CHECK(add_chains(zone, db, ver, &diff));
14136 CHECK(sign_apex(zone, db, ver, &diff, &sig_diff));
14137 CHECK(zone_journal(zone, &sig_diff, "zone_rekey"));
14142 dns_db_closeversion(db, &ver, commit);
14145 isc_time_t timenow;
14146 dns_difftuple_t *tuple;
14149 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14151 zone_needdump(zone, DNS_DUMP_DELAY);
14153 TIME_NOW(&timenow);
14154 zone_settimer(zone, &timenow);
14156 /* Remove any signatures from removed keys. */
14157 if (!ISC_LIST_EMPTY(rmkeys)) {
14158 for (key = ISC_LIST_HEAD(rmkeys);
14160 key = ISC_LIST_NEXT(key, link)) {
14161 result = zone_signwithkey(zone,
14162 dst_key_alg(key->key),
14163 dst_key_id(key->key),
14165 if (result != ISC_R_SUCCESS) {
14166 dns_zone_log(zone, ISC_LOG_ERROR,
14167 "zone_signwithkey failed: %s",
14168 dns_result_totext(result));
14175 * "rndc sign" was called, so we now sign the zone
14176 * with all active keys, whether they're new or not.
14178 for (key = ISC_LIST_HEAD(dnskeys);
14180 key = ISC_LIST_NEXT(key, link)) {
14181 if (!key->force_sign && !key->hint_sign)
14184 result = zone_signwithkey(zone,
14185 dst_key_alg(key->key),
14186 dst_key_id(key->key),
14188 if (result != ISC_R_SUCCESS) {
14189 dns_zone_log(zone, ISC_LOG_ERROR,
14190 "zone_signwithkey failed: %s",
14191 dns_result_totext(result));
14194 } else if (newalg) {
14196 * We haven't been told to sign fully, but a new
14197 * algorithm was added to the DNSKEY. We sign
14198 * the full zone, but only with newly active
14201 for (key = ISC_LIST_HEAD(dnskeys);
14203 key = ISC_LIST_NEXT(key, link)) {
14204 if (!key->first_sign)
14207 result = zone_signwithkey(zone,
14208 dst_key_alg(key->key),
14209 dst_key_id(key->key),
14211 if (result != ISC_R_SUCCESS) {
14212 dns_zone_log(zone, ISC_LOG_ERROR,
14213 "zone_signwithkey failed: %s",
14214 dns_result_totext(result));
14220 * Clear fullsign flag, if it was set, so we don't do
14221 * another full signing next time
14223 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
14226 * Cause the zone to add/delete NSEC3 chains for the
14227 * deferred NSEC3PARAM changes.
14229 for (tuple = ISC_LIST_HEAD(sig_diff.tuples);
14231 tuple = ISC_LIST_NEXT(tuple, link)) {
14232 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
14233 dns_rdata_t rdata = DNS_RDATA_INIT;
14234 dns_rdata_nsec3param_t nsec3param;
14236 if (tuple->rdata.type != zone->privatetype ||
14237 tuple->op != DNS_DIFFOP_ADD)
14240 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
14243 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
14244 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14245 if (nsec3param.flags == 0)
14248 result = zone_addnsec3chain(zone, &nsec3param);
14249 if (result != ISC_R_SUCCESS) {
14250 dns_zone_log(zone, ISC_LOG_ERROR,
14251 "zone_addnsec3chain failed: %s",
14252 dns_result_totext(result));
14257 * Schedule the next resigning event
14259 set_resigntime(zone);
14264 * If we are doing automatic key maintenance and the key metadata
14265 * indicates there is a key change event scheduled in the future,
14266 * set the key refresh timer.
14268 isc_stdtime_get(&now);
14269 TIME_NOW(&timenow);
14270 isc_time_settoepoch(&zone->refreshkeytime);
14273 * If we're doing key maintenance, set the key refresh timer to
14274 * the next scheduled key event or to one hour in the future,
14275 * whichever is sooner.
14277 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
14278 isc_time_t timethen;
14279 isc_stdtime_t then;
14282 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
14283 zone->refreshkeytime = timethen;
14286 for (key = ISC_LIST_HEAD(dnskeys);
14288 key = ISC_LIST_NEXT(key, link)) {
14290 result = next_keyevent(key->key, &then);
14291 if (result != ISC_R_SUCCESS)
14294 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
14296 if (isc_time_compare(&timethen,
14297 &zone->refreshkeytime) < 0) {
14298 zone->refreshkeytime = timethen;
14303 zone_settimer(zone, &timenow);
14305 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
14306 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
14310 dns_diff_clear(&diff);
14311 dns_diff_clear(&sig_diff);
14313 clear_keylist(&dnskeys, mctx);
14314 clear_keylist(&keys, mctx);
14315 clear_keylist(&rmkeys, mctx);
14318 dns_db_closeversion(db, &ver, ISC_FALSE);
14319 if (dns_rdataset_isassociated(&keyset))
14320 dns_rdataset_disassociate(&keyset);
14321 if (dns_rdataset_isassociated(&keysigs))
14322 dns_rdataset_disassociate(&keysigs);
14323 if (dns_rdataset_isassociated(&soasigs))
14324 dns_rdataset_disassociate(&soasigs);
14326 dns_db_detachnode(db, &node);
14328 dns_db_detach(&db);
14332 isc_interval_set(&ival, HOUR, 0);
14333 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
14338 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
14341 if (zone->type == dns_zone_master && zone->task != NULL) {
14345 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
14348 zone->refreshkeytime = now;
14349 zone_settimer(zone, &now);
14356 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
14357 unsigned int *errors)
14359 isc_result_t result;
14360 dns_dbnode_t *node = NULL;
14362 REQUIRE(DNS_ZONE_VALID(zone));
14363 REQUIRE(errors != NULL);
14365 result = dns_db_getoriginnode(db, &node);
14366 if (result != ISC_R_SUCCESS)
14368 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
14370 dns_db_detachnode(db, &node);
14375 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
14376 REQUIRE(DNS_ZONE_VALID(zone));
14378 zone->added = added;
14383 dns_zone_getadded(dns_zone_t *zone) {
14384 REQUIRE(DNS_ZONE_VALID(zone));
14385 return (zone->added);
14389 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
14391 isc_time_t loadtime;
14392 isc_result_t result;
14393 TIME_NOW(&loadtime);
14396 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);