2 * Copyright (C) 2004-2014 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 1999-2003 Internet Software Consortium.
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15 * PERFORMANCE OF THIS SOFTWARE.
26 #include <isc/mutex.h>
27 #include <isc/print.h>
28 #include <isc/random.h>
29 #include <isc/ratelimiter.h>
30 #include <isc/refcount.h>
31 #include <isc/rwlock.h>
32 #include <isc/serial.h>
33 #include <isc/strerror.h>
34 #include <isc/stats.h>
35 #include <isc/stdtime.h>
36 #include <isc/string.h>
37 #include <isc/taskpool.h>
38 #include <isc/timer.h>
41 #include <dns/acache.h>
44 #include <dns/callbacks.h>
46 #include <dns/dbiterator.h>
47 #include <dns/dnssec.h>
48 #include <dns/events.h>
49 #include <dns/journal.h>
50 #include <dns/keydata.h>
51 #include <dns/keytable.h>
52 #include <dns/keyvalues.h>
54 #include <dns/master.h>
55 #include <dns/masterdump.h>
56 #include <dns/message.h>
59 #include <dns/nsec3.h>
61 #include <dns/private.h>
63 #include <dns/rcode.h>
64 #include <dns/rdataclass.h>
65 #include <dns/rdatalist.h>
66 #include <dns/rdataset.h>
67 #include <dns/rdatasetiter.h>
68 #include <dns/rdatastruct.h>
69 #include <dns/rdatatype.h>
70 #include <dns/request.h>
71 #include <dns/resolver.h>
72 #include <dns/result.h>
73 #include <dns/rriterator.h>
76 #include <dns/stats.h>
79 #include <dns/xfrin.h>
84 #define ZONE_MAGIC ISC_MAGIC('Z', 'O', 'N', 'E')
85 #define DNS_ZONE_VALID(zone) ISC_MAGIC_VALID(zone, ZONE_MAGIC)
87 #define NOTIFY_MAGIC ISC_MAGIC('N', 't', 'f', 'y')
88 #define DNS_NOTIFY_VALID(notify) ISC_MAGIC_VALID(notify, NOTIFY_MAGIC)
90 #define STUB_MAGIC ISC_MAGIC('S', 't', 'u', 'b')
91 #define DNS_STUB_VALID(stub) ISC_MAGIC_VALID(stub, STUB_MAGIC)
93 #define ZONEMGR_MAGIC ISC_MAGIC('Z', 'm', 'g', 'r')
94 #define DNS_ZONEMGR_VALID(stub) ISC_MAGIC_VALID(stub, ZONEMGR_MAGIC)
96 #define LOAD_MAGIC ISC_MAGIC('L', 'o', 'a', 'd')
97 #define DNS_LOAD_VALID(load) ISC_MAGIC_VALID(load, LOAD_MAGIC)
99 #define FORWARD_MAGIC ISC_MAGIC('F', 'o', 'r', 'w')
100 #define DNS_FORWARD_VALID(load) ISC_MAGIC_VALID(load, FORWARD_MAGIC)
102 #define IO_MAGIC ISC_MAGIC('Z', 'm', 'I', 'O')
103 #define DNS_IO_VALID(load) ISC_MAGIC_VALID(load, IO_MAGIC)
106 * Ensure 'a' is at least 'min' but not more than 'max'.
108 #define RANGE(a, min, max) \
109 (((a) < (min)) ? (min) : ((a) < (max) ? (a) : (max)))
111 #define NSEC3REMOVE(x) (((x) & DNS_NSEC3FLAG_REMOVE) != 0)
116 #define REVOKE(x) ((dst_key_flags(x) & DNS_KEYFLAG_REVOKE) != 0)
117 #define KSK(x) ((dst_key_flags(x) & DNS_KEYFLAG_KSK) != 0)
118 #define ALG(x) dst_key_alg(x)
123 #define DNS_DEFAULT_IDLEIN 3600 /*%< 1 hour */
124 #define DNS_DEFAULT_IDLEOUT 3600 /*%< 1 hour */
125 #define MAX_XFER_TIME (2*3600) /*%< Documented default is 2 hours */
126 #define RESIGN_DELAY 3600 /*%< 1 hour */
128 #ifndef DNS_MAX_EXPIRE
129 #define DNS_MAX_EXPIRE 14515200 /*%< 24 weeks */
132 #ifndef DNS_DUMP_DELAY
133 #define DNS_DUMP_DELAY 900 /*%< 15 minutes */
136 typedef struct dns_notify dns_notify_t;
137 typedef struct dns_stub dns_stub_t;
138 typedef struct dns_load dns_load_t;
139 typedef struct dns_forward dns_forward_t;
140 typedef ISC_LIST(dns_forward_t) dns_forwardlist_t;
141 typedef struct dns_io dns_io_t;
142 typedef ISC_LIST(dns_io_t) dns_iolist_t;
143 typedef struct dns_signing dns_signing_t;
144 typedef ISC_LIST(dns_signing_t) dns_signinglist_t;
145 typedef struct dns_nsec3chain dns_nsec3chain_t;
146 typedef ISC_LIST(dns_nsec3chain_t) dns_nsec3chainlist_t;
147 typedef struct dns_keyfetch dns_keyfetch_t;
149 #define DNS_ZONE_CHECKLOCK
150 #ifdef DNS_ZONE_CHECKLOCK
151 #define LOCK_ZONE(z) \
152 do { LOCK(&(z)->lock); \
153 INSIST((z)->locked == ISC_FALSE); \
154 (z)->locked = ISC_TRUE; \
156 #define UNLOCK_ZONE(z) \
157 do { (z)->locked = ISC_FALSE; UNLOCK(&(z)->lock); } while (0)
158 #define LOCKED_ZONE(z) ((z)->locked)
160 #define LOCK_ZONE(z) LOCK(&(z)->lock)
161 #define UNLOCK_ZONE(z) UNLOCK(&(z)->lock)
162 #define LOCKED_ZONE(z) ISC_TRUE
165 #ifdef ISC_RWLOCK_USEATOMIC
166 #define ZONEDB_INITLOCK(l) isc_rwlock_init((l), 0, 0)
167 #define ZONEDB_DESTROYLOCK(l) isc_rwlock_destroy(l)
168 #define ZONEDB_LOCK(l, t) RWLOCK((l), (t))
169 #define ZONEDB_UNLOCK(l, t) RWUNLOCK((l), (t))
171 #define ZONEDB_INITLOCK(l) isc_mutex_init(l)
172 #define ZONEDB_DESTROYLOCK(l) DESTROYLOCK(l)
173 #define ZONEDB_LOCK(l, t) LOCK(l)
174 #define ZONEDB_UNLOCK(l, t) UNLOCK(l)
181 #ifdef DNS_ZONE_CHECKLOCK
182 isc_boolean_t locked;
185 isc_refcount_t erefs;
187 #ifdef ISC_RWLOCK_USEATOMIC
192 dns_db_t *db; /* Locked by dblock */
196 ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
201 dns_masterformat_t masterformat;
203 isc_int32_t journalsize;
204 dns_rdataclass_t rdclass;
207 unsigned int options;
208 unsigned int db_argc;
210 isc_time_t expiretime;
211 isc_time_t refreshtime;
214 isc_time_t notifytime;
215 isc_time_t resigntime;
216 isc_time_t keywarntime;
217 isc_time_t signingtime;
218 isc_time_t nsec3chaintime;
219 isc_time_t refreshkeytime;
220 isc_uint32_t refreshkeycount;
221 isc_uint32_t refresh;
224 isc_uint32_t minimum;
225 isc_stdtime_t key_expiry;
226 isc_stdtime_t log_key_expired_timer;
229 isc_uint32_t maxrefresh;
230 isc_uint32_t minrefresh;
231 isc_uint32_t maxretry;
232 isc_uint32_t minretry;
234 isc_sockaddr_t *masters;
235 dns_name_t **masterkeynames;
236 isc_boolean_t *mastersok;
237 unsigned int masterscnt;
238 unsigned int curmaster;
239 isc_sockaddr_t masteraddr;
240 dns_notifytype_t notifytype;
241 isc_sockaddr_t *notify;
242 unsigned int notifycnt;
243 isc_sockaddr_t notifyfrom;
245 isc_sockaddr_t notifysrc4;
246 isc_sockaddr_t notifysrc6;
247 isc_sockaddr_t xfrsource4;
248 isc_sockaddr_t xfrsource6;
249 isc_sockaddr_t altxfrsource4;
250 isc_sockaddr_t altxfrsource6;
251 isc_sockaddr_t sourceaddr;
252 dns_xfrin_ctx_t *xfr; /* task locked */
253 dns_tsigkey_t *tsigkey; /* key used for xfr */
254 /* Access Control Lists */
255 dns_acl_t *update_acl;
256 dns_acl_t *forward_acl;
257 dns_acl_t *notify_acl;
258 dns_acl_t *query_acl;
259 dns_acl_t *queryon_acl;
261 isc_boolean_t update_disabled;
262 isc_boolean_t zero_no_soa_ttl;
263 dns_severity_t check_names;
264 ISC_LIST(dns_notify_t) notifies;
265 dns_request_t *request;
270 isc_uint32_t maxxfrin;
271 isc_uint32_t maxxfrout;
273 isc_uint32_t idleout;
274 isc_event_t ctlevent;
275 dns_ssutable_t *ssutable;
276 isc_uint32_t sigvalidityinterval;
277 isc_uint32_t sigresigninginterval;
279 dns_acache_t *acache;
280 dns_checkmxfunc_t checkmx;
281 dns_checksrvfunc_t checksrv;
282 dns_checknsfunc_t checkns;
284 * Zones in certain states such as "waiting for zone transfer"
285 * or "zone transfer in progress" are kept on per-state linked lists
286 * in the zone manager using the 'statelink' field. The 'statelist'
287 * field points at the list the zone is currently on. It the zone
288 * is not on any such list, statelist is NULL.
290 ISC_LINK(dns_zone_t) statelink;
291 dns_zonelist_t *statelist;
293 * Statistics counters about zone management.
297 * Optional per-zone statistics counters. Counted outside of this
300 isc_boolean_t requeststats_on;
301 isc_stats_t *requeststats;
302 isc_uint32_t notifydelay;
303 dns_isselffunc_t isself;
312 * Serial number for deferred journal compaction.
314 isc_uint32_t compact_serial;
316 * Keys that are signing the zone for the first time.
318 dns_signinglist_t signing;
319 dns_nsec3chainlist_t nsec3chain;
321 * Signing / re-signing quantum stopping parameters.
323 isc_uint32_t signatures;
325 dns_rdatatype_t privatetype;
328 * Autosigning/key-maintenance options
330 isc_uint32_t keyopts;
333 * True if added by "rndc addzone"
338 * whether this is a response policy zone
340 isc_boolean_t is_rpz;
343 * Outstanding forwarded UPDATE requests.
345 dns_forwardlist_t forwards;
350 isc_boolean_t offline;
353 #define zonediff_init(z, d) \
355 zonediff_t *_z = (z); \
357 (_z)->offline = ISC_FALSE; \
360 #define DNS_ZONE_FLAG(z,f) (ISC_TF(((z)->flags & (f)) != 0))
361 #define DNS_ZONE_SETFLAG(z,f) do { \
362 INSIST(LOCKED_ZONE(z)); \
365 #define DNS_ZONE_CLRFLAG(z,f) do { \
366 INSIST(LOCKED_ZONE(z)); \
367 (z)->flags &= ~(f); \
369 /* XXX MPA these may need to go back into zone.h */
370 #define DNS_ZONEFLG_REFRESH 0x00000001U /*%< refresh check in progress */
371 #define DNS_ZONEFLG_NEEDDUMP 0x00000002U /*%< zone need consolidation */
372 #define DNS_ZONEFLG_USEVC 0x00000004U /*%< use tcp for refresh query */
373 #define DNS_ZONEFLG_DUMPING 0x00000008U /*%< a dump is in progress */
374 #define DNS_ZONEFLG_HASINCLUDE 0x00000010U /*%< $INCLUDE in zone file */
375 #define DNS_ZONEFLG_LOADED 0x00000020U /*%< database has loaded */
376 #define DNS_ZONEFLG_EXITING 0x00000040U /*%< zone is being destroyed */
377 #define DNS_ZONEFLG_EXPIRED 0x00000080U /*%< zone has expired */
378 #define DNS_ZONEFLG_NEEDREFRESH 0x00000100U /*%< refresh check needed */
379 #define DNS_ZONEFLG_UPTODATE 0x00000200U /*%< zone contents are
381 #define DNS_ZONEFLG_NEEDNOTIFY 0x00000400U /*%< need to send out notify
383 #define DNS_ZONEFLG_DIFFONRELOAD 0x00000800U /*%< generate a journal diff on
385 #define DNS_ZONEFLG_NOMASTERS 0x00001000U /*%< an attempt to refresh a
386 * zone with no masters
388 #define DNS_ZONEFLG_LOADING 0x00002000U /*%< load from disk in progress*/
389 #define DNS_ZONEFLG_HAVETIMERS 0x00004000U /*%< timer values have been set
390 * from SOA (if not set, we
392 * default timer values) */
393 #define DNS_ZONEFLG_FORCEXFER 0x00008000U /*%< Force a zone xfer */
394 #define DNS_ZONEFLG_NOREFRESH 0x00010000U
395 #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U
396 #define DNS_ZONEFLG_DIALREFRESH 0x00040000U
397 #define DNS_ZONEFLG_SHUTDOWN 0x00080000U
398 #define DNS_ZONEFLAG_NOIXFR 0x00100000U /*%< IXFR failed, force AXFR */
399 #define DNS_ZONEFLG_FLUSH 0x00200000U
400 #define DNS_ZONEFLG_NOEDNS 0x00400000U
401 #define DNS_ZONEFLG_USEALTXFRSRC 0x00800000U
402 #define DNS_ZONEFLG_SOABEFOREAXFR 0x01000000U
403 #define DNS_ZONEFLG_NEEDCOMPACT 0x02000000U
404 #define DNS_ZONEFLG_REFRESHING 0x04000000U /*%< Refreshing keydata */
405 #define DNS_ZONEFLG_THAW 0x08000000U
406 /* #define DNS_ZONEFLG_XXXXX 0x10000000U XXXMPA unused. */
407 #define DNS_ZONEFLG_NODELAY 0x20000000U
409 #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0)
410 #define DNS_ZONEKEY_OPTION(z,o) (((z)->keyopts & (o)) != 0)
412 /* Flags for zone_load() */
413 #define DNS_ZONELOADFLAG_NOSTAT 0x00000001U /* Do not stat() master files */
414 #define DNS_ZONELOADFLAG_THAW 0x00000002U /* Thaw the zone on successful
417 #define UNREACH_CHACHE_SIZE 10U
418 #define UNREACH_HOLD_TIME 600 /* 10 minutes */
421 do { result = (op); \
422 if (result != ISC_R_SUCCESS) goto failure; \
425 struct dns_unreachable {
426 isc_sockaddr_t remote;
427 isc_sockaddr_t local;
436 int refs; /* Locked by rwlock */
437 isc_taskmgr_t * taskmgr;
438 isc_timermgr_t * timermgr;
439 isc_socketmgr_t * socketmgr;
440 isc_taskpool_t * zonetasks;
442 isc_ratelimiter_t * notifyrl;
443 isc_ratelimiter_t * refreshrl;
448 /* Locked by rwlock. */
449 dns_zonelist_t zones;
450 dns_zonelist_t waiting_for_xfrin;
451 dns_zonelist_t xfrin_in_progress;
453 /* Configuration data. */
454 isc_uint32_t transfersin;
455 isc_uint32_t transfersperns;
456 unsigned int serialqueryrate;
458 /* Locked by iolock */
459 isc_uint32_t iolimit;
460 isc_uint32_t ioactive;
464 /* Locked by urlock. */
466 struct dns_unreachable unreachable[UNREACH_CHACHE_SIZE];
478 dns_request_t *request;
481 ISC_LINK(dns_notify_t) link;
484 #define DNS_NOTIFY_NOSOA 0x0001U
487 * dns_stub holds state while performing a 'stub' transfer.
488 * 'db' is the zone's 'db' or a new one if this is the initial
497 dns_dbversion_t *version;
509 dns_rdatacallbacks_t callbacks;
513 * Hold forward state.
519 isc_buffer_t *msgbuf;
520 dns_request_t *request;
523 dns_updatecallback_t callback;
525 ISC_LINK(dns_forward_t) link;
529 * Hold IO request state.
536 ISC_LINK(dns_io_t) link;
541 * Hold state for when we are signing a zone with a new
542 * DNSKEY as result of an update.
547 dns_dbiterator_t *dbiterator;
548 dns_secalg_t algorithm;
550 isc_boolean_t delete;
552 ISC_LINK(dns_signing_t) link;
555 struct dns_nsec3chain {
558 dns_dbiterator_t *dbiterator;
559 dns_rdata_nsec3param_t nsec3param;
560 unsigned char salt[255];
562 isc_boolean_t seen_nsec;
563 isc_boolean_t delete_nsec;
564 isc_boolean_t save_delete_nsec;
565 ISC_LINK(dns_nsec3chain_t) link;
568 * 'dbiterator' contains a iterator for the database. If we are creating
569 * a NSEC3 chain only the non-NSEC3 nodes will be iterated. If we are
570 * removing a NSEC3 chain then both NSEC3 and non-NSEC3 nodes will be
573 * 'nsec3param' contains the parameters of the NSEC3 chain being created
576 * 'salt' is buffer space and is referenced via 'nsec3param.salt'.
578 * 'seen_nsec' will be set to true if, while iterating the zone to create a
579 * NSEC3 chain, a NSEC record is seen.
581 * 'delete_nsec' will be set to true if, at the completion of the creation
582 * of a NSEC3 chain, 'seen_nsec' is true. If 'delete_nsec' is true then we
583 * are in the process of deleting the NSEC chain.
585 * 'save_delete_nsec' is used to store the initial state of 'delete_nsec'
586 * so it can be recovered in the event of a error.
589 struct dns_keyfetch {
590 dns_fixedname_t name;
591 dns_rdataset_t keydataset;
592 dns_rdataset_t dnskeyset;
593 dns_rdataset_t dnskeysigset;
600 #define DAY (24*HOUR)
601 #define MONTH (30*DAY)
603 #define SEND_BUFFER_SIZE 2048
605 static void zone_settimer(dns_zone_t *, isc_time_t *);
606 static void cancel_refresh(dns_zone_t *);
607 static void zone_debuglog(dns_zone_t *zone, const char *, int debuglevel,
608 const char *msg, ...) ISC_FORMAT_PRINTF(4, 5);
609 static void notify_log(dns_zone_t *zone, int level, const char *fmt, ...)
610 ISC_FORMAT_PRINTF(3, 4);
611 static void queue_xfrin(dns_zone_t *zone);
612 static isc_result_t update_one_rr(dns_db_t *db, dns_dbversion_t *ver,
613 dns_diff_t *diff, dns_diffop_t op,
614 dns_name_t *name, dns_ttl_t ttl,
616 static void zone_unload(dns_zone_t *zone);
617 static void zone_expire(dns_zone_t *zone);
618 static void zone_iattach(dns_zone_t *source, dns_zone_t **target);
619 static void zone_idetach(dns_zone_t **zonep);
620 static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
622 static inline void zone_attachdb(dns_zone_t *zone, dns_db_t *db);
623 static inline void zone_detachdb(dns_zone_t *zone);
624 static isc_result_t default_journal(dns_zone_t *zone);
625 static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
626 static isc_result_t zone_postload(dns_zone_t *zone, dns_db_t *db,
627 isc_time_t loadtime, isc_result_t result);
628 static void zone_needdump(dns_zone_t *zone, unsigned int delay);
629 static void zone_shutdown(isc_task_t *, isc_event_t *);
630 static void zone_loaddone(void *arg, isc_result_t result);
631 static isc_result_t zone_startload(dns_db_t *db, dns_zone_t *zone,
632 isc_time_t loadtime);
633 static void zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length);
634 static void zone_name_tostr(dns_zone_t *zone, char *buf, size_t length);
635 static void zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length);
636 static void zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length);
639 /* ondestroy example */
640 static void dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event);
643 static void refresh_callback(isc_task_t *, isc_event_t *);
644 static void stub_callback(isc_task_t *, isc_event_t *);
645 static void queue_soa_query(dns_zone_t *zone);
646 static void soa_query(isc_task_t *, isc_event_t *);
647 static void ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset,
649 static int message_count(dns_message_t *msg, dns_section_t section,
650 dns_rdatatype_t type);
651 static void notify_cancel(dns_zone_t *zone);
652 static void notify_find_address(dns_notify_t *notify);
653 static void notify_send(dns_notify_t *notify);
654 static isc_result_t notify_createmessage(dns_zone_t *zone,
656 dns_message_t **messagep);
657 static void notify_done(isc_task_t *task, isc_event_t *event);
658 static void notify_send_toaddr(isc_task_t *task, isc_event_t *event);
659 static isc_result_t zone_dump(dns_zone_t *, isc_boolean_t);
660 static void got_transfer_quota(isc_task_t *task, isc_event_t *event);
661 static isc_result_t zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr,
663 static void zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi);
664 static void zonemgr_free(dns_zonemgr_t *zmgr);
665 static isc_result_t zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
666 isc_task_t *task, isc_taskaction_t action,
667 void *arg, dns_io_t **iop);
668 static void zonemgr_putio(dns_io_t **iop);
669 static void zonemgr_cancelio(dns_io_t *io);
672 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
673 unsigned int *soacount, isc_uint32_t *serial,
674 isc_uint32_t *refresh, isc_uint32_t *retry,
675 isc_uint32_t *expire, isc_uint32_t *minimum,
676 unsigned int *errors);
678 static void zone_freedbargs(dns_zone_t *zone);
679 static void forward_callback(isc_task_t *task, isc_event_t *event);
680 static void zone_saveunique(dns_zone_t *zone, const char *path,
681 const char *templat);
682 static void zone_maintenance(dns_zone_t *zone);
683 static void zone_notify(dns_zone_t *zone, isc_time_t *now);
684 static void dump_done(void *arg, isc_result_t result);
685 static isc_result_t zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
686 isc_uint16_t keyid, isc_boolean_t delete);
687 static isc_result_t delete_nsec(dns_db_t *db, dns_dbversion_t *ver,
688 dns_dbnode_t *node, dns_name_t *name,
690 static void zone_rekey(dns_zone_t *zone);
692 #define ENTER zone_debuglog(zone, me, 1, "enter")
694 static const unsigned int dbargc_default = 1;
695 static const char *dbargv_default[] = { "rbt" };
697 #define DNS_ZONE_JITTER_ADD(a, b, c) \
701 _j = isc_random_jitter((b), (b)/4); \
702 isc_interval_set(&_i, _j, 0); \
703 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
704 dns_zone_log(zone, ISC_LOG_WARNING, \
705 "epoch approaching: upgrade required: " \
706 "now + %s failed", #b); \
707 isc_interval_set(&_i, _j/2, 0); \
708 (void)isc_time_add((a), &_i, (c)); \
712 #define DNS_ZONE_TIME_ADD(a, b, c) \
715 isc_interval_set(&_i, (b), 0); \
716 if (isc_time_add((a), &_i, (c)) != ISC_R_SUCCESS) { \
717 dns_zone_log(zone, ISC_LOG_WARNING, \
718 "epoch approaching: upgrade required: " \
719 "now + %s failed", #b); \
720 isc_interval_set(&_i, (b)/2, 0); \
721 (void)isc_time_add((a), &_i, (c)); \
726 * Increment resolver-related statistics counters. Zone must be locked.
729 inc_stats(dns_zone_t *zone, isc_statscounter_t counter) {
730 if (zone->stats != NULL)
731 isc_stats_increment(zone->stats, counter);
735 *** Public functions.
739 dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
744 REQUIRE(zonep != NULL && *zonep == NULL);
745 REQUIRE(mctx != NULL);
748 zone = isc_mem_get(mctx, sizeof(*zone));
750 return (ISC_R_NOMEMORY);
753 isc_mem_attach(mctx, &zone->mctx);
755 result = isc_mutex_init(&zone->lock);
756 if (result != ISC_R_SUCCESS)
759 result = ZONEDB_INITLOCK(&zone->dblock);
760 if (result != ISC_R_SUCCESS)
763 /* XXX MPA check that all elements are initialised */
764 #ifdef DNS_ZONE_CHECKLOCK
765 zone->locked = ISC_FALSE;
769 ISC_LINK_INIT(zone, link);
770 result = isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */
771 if (result != ISC_R_SUCCESS)
774 dns_name_init(&zone->origin, NULL);
775 zone->strnamerd = NULL;
776 zone->strname = NULL;
777 zone->strrdclass = NULL;
778 zone->strviewname = NULL;
779 zone->masterfile = NULL;
780 zone->masterformat = dns_masterformat_none;
781 zone->keydirectory = NULL;
782 zone->journalsize = -1;
783 zone->journal = NULL;
784 zone->rdclass = dns_rdataclass_none;
785 zone->type = dns_zone_none;
790 zone->db_argv = NULL;
791 isc_time_settoepoch(&zone->expiretime);
792 isc_time_settoepoch(&zone->refreshtime);
793 isc_time_settoepoch(&zone->dumptime);
794 isc_time_settoepoch(&zone->loadtime);
795 zone->notifytime = now;
796 isc_time_settoepoch(&zone->resigntime);
797 isc_time_settoepoch(&zone->keywarntime);
798 isc_time_settoepoch(&zone->signingtime);
799 isc_time_settoepoch(&zone->nsec3chaintime);
800 isc_time_settoepoch(&zone->refreshkeytime);
801 zone->refreshkeycount = 0;
802 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
803 zone->retry = DNS_ZONE_DEFAULTRETRY;
806 zone->maxrefresh = DNS_ZONE_MAXREFRESH;
807 zone->minrefresh = DNS_ZONE_MINREFRESH;
808 zone->maxretry = DNS_ZONE_MAXRETRY;
809 zone->minretry = DNS_ZONE_MINRETRY;
810 zone->masters = NULL;
811 zone->masterkeynames = NULL;
812 zone->mastersok = NULL;
813 zone->masterscnt = 0;
816 zone->notifytype = dns_notifytype_yes;
819 zone->update_acl = NULL;
820 zone->forward_acl = NULL;
821 zone->notify_acl = NULL;
822 zone->query_acl = NULL;
823 zone->queryon_acl = NULL;
824 zone->xfr_acl = NULL;
825 zone->update_disabled = ISC_FALSE;
826 zone->zero_no_soa_ttl = ISC_TRUE;
827 zone->check_names = dns_severity_ignore;
828 zone->request = NULL;
832 zone->writeio = NULL;
834 zone->idlein = DNS_DEFAULT_IDLEIN;
835 zone->idleout = DNS_DEFAULT_IDLEOUT;
836 zone->log_key_expired_timer = 0;
837 ISC_LIST_INIT(zone->notifies);
838 isc_sockaddr_any(&zone->notifysrc4);
839 isc_sockaddr_any6(&zone->notifysrc6);
840 isc_sockaddr_any(&zone->xfrsource4);
841 isc_sockaddr_any6(&zone->xfrsource6);
842 isc_sockaddr_any(&zone->altxfrsource4);
843 isc_sockaddr_any6(&zone->altxfrsource6);
845 zone->tsigkey = NULL;
846 zone->maxxfrin = MAX_XFER_TIME;
847 zone->maxxfrout = MAX_XFER_TIME;
848 zone->ssutable = NULL;
849 zone->sigvalidityinterval = 30 * 24 * 3600;
850 zone->sigresigninginterval = 7 * 24 * 3600;
853 zone->checkmx = NULL;
854 zone->checksrv = NULL;
855 zone->checkns = NULL;
856 ISC_LINK_INIT(zone, statelink);
857 zone->statelist = NULL;
859 zone->requeststats_on = ISC_FALSE;
860 zone->requeststats = NULL;
861 zone->notifydelay = 5;
863 zone->isselfarg = NULL;
864 ISC_LIST_INIT(zone->signing);
865 ISC_LIST_INIT(zone->nsec3chain);
866 zone->signatures = 10;
868 zone->privatetype = (dns_rdatatype_t)0xffffU;
869 zone->added = ISC_FALSE;
870 zone->is_rpz = ISC_FALSE;
871 ISC_LIST_INIT(zone->forwards);
873 zone->magic = ZONE_MAGIC;
875 /* Must be after magic is set. */
876 result = dns_zone_setdbtype(zone, dbargc_default, dbargv_default);
877 if (result != ISC_R_SUCCESS)
880 ISC_EVENT_INIT(&zone->ctlevent, sizeof(zone->ctlevent), 0, NULL,
881 DNS_EVENT_ZONECONTROL, zone_shutdown, zone, zone,
884 return (ISC_R_SUCCESS);
887 isc_refcount_decrement(&zone->erefs, NULL);
888 isc_refcount_destroy(&zone->erefs);
891 ZONEDB_DESTROYLOCK(&zone->dblock);
894 DESTROYLOCK(&zone->lock);
897 isc_mem_putanddetach(&zone->mctx, zone, sizeof(*zone));
902 * Free a zone. Because we require that there be no more
903 * outstanding events or references, no locking is necessary.
906 zone_free(dns_zone_t *zone) {
907 isc_mem_t *mctx = NULL;
908 dns_signing_t *signing;
909 dns_nsec3chain_t *nsec3chain;
911 REQUIRE(DNS_ZONE_VALID(zone));
912 REQUIRE(isc_refcount_current(&zone->erefs) == 0);
913 REQUIRE(zone->irefs == 0);
914 REQUIRE(!LOCKED_ZONE(zone));
915 REQUIRE(zone->timer == NULL);
918 * Managed objects. Order is important.
920 if (zone->request != NULL)
921 dns_request_destroy(&zone->request); /* XXXMPA */
922 INSIST(zone->readio == NULL);
923 INSIST(zone->statelist == NULL);
924 INSIST(zone->writeio == NULL);
926 if (zone->task != NULL)
927 isc_task_detach(&zone->task);
928 if (zone->zmgr != NULL)
929 dns_zonemgr_releasezone(zone->zmgr, zone);
931 /* Unmanaged objects */
932 for (signing = ISC_LIST_HEAD(zone->signing);
934 signing = ISC_LIST_HEAD(zone->signing)) {
935 ISC_LIST_UNLINK(zone->signing, signing, link);
936 dns_db_detach(&signing->db);
937 dns_dbiterator_destroy(&signing->dbiterator);
938 isc_mem_put(zone->mctx, signing, sizeof *signing);
940 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
942 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain)) {
943 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
944 dns_db_detach(&nsec3chain->db);
945 dns_dbiterator_destroy(&nsec3chain->dbiterator);
946 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
948 if (zone->masterfile != NULL)
949 isc_mem_free(zone->mctx, zone->masterfile);
950 zone->masterfile = NULL;
951 if (zone->keydirectory != NULL)
952 isc_mem_free(zone->mctx, zone->keydirectory);
953 zone->keydirectory = NULL;
954 zone->journalsize = -1;
955 if (zone->journal != NULL)
956 isc_mem_free(zone->mctx, zone->journal);
957 zone->journal = NULL;
958 if (zone->stats != NULL)
959 isc_stats_detach(&zone->stats);
960 if (zone->requeststats != NULL)
961 isc_stats_detach(&zone->requeststats);
962 if (zone->db != NULL)
964 if (zone->acache != NULL)
965 dns_acache_detach(&zone->acache);
966 zone_freedbargs(zone);
967 RUNTIME_CHECK(dns_zone_setmasterswithkeys(zone, NULL, NULL, 0)
969 RUNTIME_CHECK(dns_zone_setalsonotify(zone, NULL, 0)
971 zone->check_names = dns_severity_ignore;
972 if (zone->update_acl != NULL)
973 dns_acl_detach(&zone->update_acl);
974 if (zone->forward_acl != NULL)
975 dns_acl_detach(&zone->forward_acl);
976 if (zone->notify_acl != NULL)
977 dns_acl_detach(&zone->notify_acl);
978 if (zone->query_acl != NULL)
979 dns_acl_detach(&zone->query_acl);
980 if (zone->queryon_acl != NULL)
981 dns_acl_detach(&zone->queryon_acl);
982 if (zone->xfr_acl != NULL)
983 dns_acl_detach(&zone->xfr_acl);
984 if (dns_name_dynamic(&zone->origin))
985 dns_name_free(&zone->origin, zone->mctx);
986 if (zone->strnamerd != NULL)
987 isc_mem_free(zone->mctx, zone->strnamerd);
988 if (zone->strname != NULL)
989 isc_mem_free(zone->mctx, zone->strname);
990 if (zone->strrdclass != NULL)
991 isc_mem_free(zone->mctx, zone->strrdclass);
992 if (zone->strviewname != NULL)
993 isc_mem_free(zone->mctx, zone->strviewname);
994 if (zone->ssutable != NULL)
995 dns_ssutable_detach(&zone->ssutable);
998 ZONEDB_DESTROYLOCK(&zone->dblock);
999 DESTROYLOCK(&zone->lock);
1000 isc_refcount_destroy(&zone->erefs);
1003 isc_mem_put(mctx, zone, sizeof(*zone));
1004 isc_mem_detach(&mctx);
1011 dns_zone_setclass(dns_zone_t *zone, dns_rdataclass_t rdclass) {
1014 REQUIRE(DNS_ZONE_VALID(zone));
1015 REQUIRE(rdclass != dns_rdataclass_none);
1021 REQUIRE(zone->rdclass == dns_rdataclass_none ||
1022 zone->rdclass == rdclass);
1023 zone->rdclass = rdclass;
1025 if (zone->strnamerd != NULL)
1026 isc_mem_free(zone->mctx, zone->strnamerd);
1027 if (zone->strrdclass != NULL)
1028 isc_mem_free(zone->mctx, zone->strrdclass);
1030 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1031 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1032 zone_rdclass_tostr(zone, namebuf, sizeof namebuf);
1033 zone->strrdclass = isc_mem_strdup(zone->mctx, namebuf);
1039 dns_zone_getclass(dns_zone_t *zone) {
1040 REQUIRE(DNS_ZONE_VALID(zone));
1042 return (zone->rdclass);
1046 dns_zone_setnotifytype(dns_zone_t *zone, dns_notifytype_t notifytype) {
1047 REQUIRE(DNS_ZONE_VALID(zone));
1050 zone->notifytype = notifytype;
1055 dns_zone_getserial2(dns_zone_t *zone, isc_uint32_t *serialp) {
1056 isc_result_t result;
1057 unsigned int soacount;
1059 REQUIRE(DNS_ZONE_VALID(zone));
1060 REQUIRE(serialp != NULL);
1063 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1064 if (zone->db != NULL) {
1065 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
1066 serialp, NULL, NULL, NULL, NULL,
1068 if (result == ISC_R_SUCCESS && soacount == 0)
1069 result = ISC_R_FAILURE;
1071 result = DNS_R_NOTLOADED;
1072 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1079 dns_zone_getserial(dns_zone_t *zone) {
1080 isc_result_t result;
1081 isc_uint32_t serial;
1083 result = dns_zone_getserial2(zone, &serial);
1084 if (result != ISC_R_SUCCESS)
1085 serial = 0; /* XXX: not really correct, but no other choice */
1094 dns_zone_settype(dns_zone_t *zone, dns_zonetype_t type) {
1096 REQUIRE(DNS_ZONE_VALID(zone));
1097 REQUIRE(type != dns_zone_none);
1103 REQUIRE(zone->type == dns_zone_none || zone->type == type);
1109 zone_freedbargs(dns_zone_t *zone) {
1112 /* Free the old database argument list. */
1113 if (zone->db_argv != NULL) {
1114 for (i = 0; i < zone->db_argc; i++)
1115 isc_mem_free(zone->mctx, zone->db_argv[i]);
1116 isc_mem_put(zone->mctx, zone->db_argv,
1117 zone->db_argc * sizeof(*zone->db_argv));
1120 zone->db_argv = NULL;
1124 dns_zone_getdbtype(dns_zone_t *zone, char ***argv, isc_mem_t *mctx) {
1127 isc_result_t result = ISC_R_SUCCESS;
1131 REQUIRE(DNS_ZONE_VALID(zone));
1132 REQUIRE(argv != NULL && *argv == NULL);
1135 size = (zone->db_argc + 1) * sizeof(char *);
1136 for (i = 0; i < zone->db_argc; i++)
1137 size += strlen(zone->db_argv[i]) + 1;
1138 mem = isc_mem_allocate(mctx, size);
1142 tmp2 += (zone->db_argc + 1) * sizeof(char *);
1143 for (i = 0; i < zone->db_argc; i++) {
1145 strcpy(tmp2, zone->db_argv[i]);
1146 tmp2 += strlen(tmp2) + 1;
1150 result = ISC_R_NOMEMORY;
1157 dns_zone_setdbtype(dns_zone_t *zone,
1158 unsigned int dbargc, const char * const *dbargv) {
1159 isc_result_t result = ISC_R_SUCCESS;
1163 REQUIRE(DNS_ZONE_VALID(zone));
1164 REQUIRE(dbargc >= 1);
1165 REQUIRE(dbargv != NULL);
1169 /* Set up a new database argument list. */
1170 new = isc_mem_get(zone->mctx, dbargc * sizeof(*new));
1173 for (i = 0; i < dbargc; i++)
1175 for (i = 0; i < dbargc; i++) {
1176 new[i] = isc_mem_strdup(zone->mctx, dbargv[i]);
1181 /* Free the old list. */
1182 zone_freedbargs(zone);
1184 zone->db_argc = dbargc;
1185 zone->db_argv = new;
1186 result = ISC_R_SUCCESS;
1191 for (i = 0; i < dbargc; i++)
1193 isc_mem_free(zone->mctx, new[i]);
1194 isc_mem_put(zone->mctx, new, dbargc * sizeof(*new));
1196 result = ISC_R_NOMEMORY;
1204 dns_zone_setview(dns_zone_t *zone, dns_view_t *view) {
1206 REQUIRE(DNS_ZONE_VALID(zone));
1209 if (zone->view != NULL)
1210 dns_view_weakdetach(&zone->view);
1211 dns_view_weakattach(view, &zone->view);
1213 if (zone->strviewname != NULL)
1214 isc_mem_free(zone->mctx, zone->strviewname);
1215 if (zone->strnamerd != NULL)
1216 isc_mem_free(zone->mctx, zone->strnamerd);
1218 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1219 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1220 zone_viewname_tostr(zone, namebuf, sizeof namebuf);
1221 zone->strviewname = isc_mem_strdup(zone->mctx, namebuf);
1228 dns_zone_getview(dns_zone_t *zone) {
1229 REQUIRE(DNS_ZONE_VALID(zone));
1231 return (zone->view);
1236 dns_zone_setorigin(dns_zone_t *zone, const dns_name_t *origin) {
1237 isc_result_t result;
1240 REQUIRE(DNS_ZONE_VALID(zone));
1241 REQUIRE(origin != NULL);
1244 if (dns_name_dynamic(&zone->origin)) {
1245 dns_name_free(&zone->origin, zone->mctx);
1246 dns_name_init(&zone->origin, NULL);
1248 result = dns_name_dup(origin, zone->mctx, &zone->origin);
1250 if (zone->strnamerd != NULL)
1251 isc_mem_free(zone->mctx, zone->strnamerd);
1252 if (zone->strname != NULL)
1253 isc_mem_free(zone->mctx, zone->strname);
1255 zone_namerd_tostr(zone, namebuf, sizeof namebuf);
1256 zone->strnamerd = isc_mem_strdup(zone->mctx, namebuf);
1257 zone_name_tostr(zone, namebuf, sizeof namebuf);
1258 zone->strname = isc_mem_strdup(zone->mctx, namebuf);
1265 dns_zone_setacache(dns_zone_t *zone, dns_acache_t *acache) {
1266 REQUIRE(DNS_ZONE_VALID(zone));
1267 REQUIRE(acache != NULL);
1270 if (zone->acache != NULL)
1271 dns_acache_detach(&zone->acache);
1272 dns_acache_attach(acache, &zone->acache);
1273 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1274 if (zone->db != NULL) {
1275 isc_result_t result;
1278 * If the zone reuses an existing DB, the DB needs to be
1279 * set in the acache explicitly. We can safely ignore the
1280 * case where the DB is already set. If other error happens,
1281 * the acache will not work effectively.
1283 result = dns_acache_setdb(acache, zone->db);
1284 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
1285 UNEXPECTED_ERROR(__FILE__, __LINE__,
1286 "dns_acache_setdb() failed: %s",
1287 isc_result_totext(result));
1290 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1295 dns_zone_setstring(dns_zone_t *zone, char **field, const char *value) {
1298 if (value != NULL) {
1299 copy = isc_mem_strdup(zone->mctx, value);
1301 return (ISC_R_NOMEMORY);
1307 isc_mem_free(zone->mctx, *field);
1310 return (ISC_R_SUCCESS);
1314 dns_zone_setfile(dns_zone_t *zone, const char *file) {
1315 return (dns_zone_setfile2(zone, file, dns_masterformat_text));
1319 dns_zone_setfile2(dns_zone_t *zone, const char *file,
1320 dns_masterformat_t format) {
1321 isc_result_t result = ISC_R_SUCCESS;
1323 REQUIRE(DNS_ZONE_VALID(zone));
1326 result = dns_zone_setstring(zone, &zone->masterfile, file);
1327 if (result == ISC_R_SUCCESS) {
1328 zone->masterformat = format;
1329 result = default_journal(zone);
1337 dns_zone_getfile(dns_zone_t *zone) {
1338 REQUIRE(DNS_ZONE_VALID(zone));
1340 return (zone->masterfile);
1344 default_journal(dns_zone_t *zone) {
1345 isc_result_t result;
1348 REQUIRE(DNS_ZONE_VALID(zone));
1349 REQUIRE(LOCKED_ZONE(zone));
1351 if (zone->masterfile != NULL) {
1352 /* Calculate string length including '\0'. */
1353 int len = strlen(zone->masterfile) + sizeof(".jnl");
1354 journal = isc_mem_allocate(zone->mctx, len);
1355 if (journal == NULL)
1356 return (ISC_R_NOMEMORY);
1357 strcpy(journal, zone->masterfile);
1358 strcat(journal, ".jnl");
1362 result = dns_zone_setstring(zone, &zone->journal, journal);
1363 if (journal != NULL)
1364 isc_mem_free(zone->mctx, journal);
1369 dns_zone_setjournal(dns_zone_t *zone, const char *journal) {
1370 isc_result_t result = ISC_R_SUCCESS;
1372 REQUIRE(DNS_ZONE_VALID(zone));
1375 result = dns_zone_setstring(zone, &zone->journal, journal);
1382 dns_zone_getjournal(dns_zone_t *zone) {
1383 REQUIRE(DNS_ZONE_VALID(zone));
1385 return (zone->journal);
1389 * Return true iff the zone is "dynamic", in the sense that the zone's
1390 * master file (if any) is written by the server, rather than being
1391 * updated manually and read by the server.
1393 * This is true for slave zones, stub zones, key zones, and zones that
1394 * allow dynamic updates either by having an update policy ("ssutable")
1395 * or an "allow-update" ACL with a value other than exactly "{ none; }".
1397 static isc_boolean_t
1398 zone_isdynamic(dns_zone_t *zone) {
1399 REQUIRE(DNS_ZONE_VALID(zone));
1401 return (ISC_TF(zone->type == dns_zone_slave ||
1402 zone->type == dns_zone_stub ||
1403 zone->type == dns_zone_key ||
1404 (!zone->update_disabled && zone->ssutable != NULL) ||
1405 (!zone->update_disabled && zone->update_acl != NULL &&
1406 !dns_acl_isnone(zone->update_acl))));
1410 * Set the response policy index and information for a zone.
1413 dns_zone_rpz_enable(dns_zone_t *zone) {
1415 * Only RBTDB zones can be used for response policy zones,
1416 * because only they have the code to load the create the summary data.
1417 * Only zones that are loaded instead of mmap()ed create the
1418 * summary data and so can be policy zones.
1420 if (strcmp(zone->db_argv[0], "rbt") != 0 &&
1421 strcmp(zone->db_argv[0], "rbt64") != 0)
1422 return (ISC_R_NOTIMPLEMENTED);
1424 zone->is_rpz = ISC_TRUE;
1426 return (ISC_R_SUCCESS);
1430 dns_zone_get_rpz(dns_zone_t *zone) {
1431 return (zone->is_rpz);
1435 * If a zone is a response policy zone, mark its new database.
1438 dns_zone_rpz_enable_db(dns_zone_t *zone, dns_db_t *db) {
1441 return (dns_db_rpz_enabled(db, NULL));
1443 return (ISC_R_SUCCESS);
1447 zone_load(dns_zone_t *zone, unsigned int flags) {
1448 isc_result_t result;
1450 isc_time_t loadtime, filetime;
1451 dns_db_t *db = NULL;
1454 REQUIRE(DNS_ZONE_VALID(zone));
1459 INSIST(zone->type != dns_zone_none);
1461 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
1462 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1463 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1464 result = DNS_R_CONTINUE;
1469 INSIST(zone->db_argc >= 1);
1471 rbt = strcmp(zone->db_argv[0], "rbt") == 0 ||
1472 strcmp(zone->db_argv[0], "rbt64") == 0;
1474 if (zone->db != NULL && zone->masterfile == NULL && rbt) {
1476 * The zone has no master file configured.
1478 result = ISC_R_SUCCESS;
1482 if (zone->db != NULL && zone_isdynamic(zone)) {
1484 * This is a slave, stub, or dynamically updated
1485 * zone being reloaded. Do nothing - the database
1486 * we already have is guaranteed to be up-to-date.
1488 if (zone->type == dns_zone_master)
1489 result = DNS_R_DYNAMIC;
1491 result = ISC_R_SUCCESS;
1496 * Store the current time before the zone is loaded, so that if the
1497 * file changes between the time of the load and the time that
1498 * zone->loadtime is set, then the file will still be reloaded
1499 * the next time dns_zone_load is called.
1501 TIME_NOW(&loadtime);
1504 * Don't do the load if the file that stores the zone is older
1505 * than the last time the zone was loaded. If the zone has not
1506 * been loaded yet, zone->loadtime will be the epoch.
1508 if (zone->masterfile != NULL) {
1510 * The file is already loaded. If we are just doing a
1511 * "rndc reconfig", we are done.
1513 if (!isc_time_isepoch(&zone->loadtime) &&
1514 (flags & DNS_ZONELOADFLAG_NOSTAT) != 0) {
1515 result = ISC_R_SUCCESS;
1519 result = isc_file_getmodtime(zone->masterfile, &filetime);
1520 if (result == ISC_R_SUCCESS) {
1521 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
1522 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE) &&
1523 isc_time_compare(&filetime, &zone->loadtime) <= 0) {
1524 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1525 "skipping load: master file "
1526 "older than last load");
1527 result = DNS_R_UPTODATE;
1530 loadtime = filetime;
1535 * Built in zones (with the exception of empty zones) don't need
1538 if (zone->type == dns_zone_master &&
1539 strcmp(zone->db_argv[0], "_builtin") == 0 &&
1540 (zone->db_argc < 2 || strcmp(zone->db_argv[1], "empty") != 0) &&
1541 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
1542 result = ISC_R_SUCCESS;
1546 if ((zone->type == dns_zone_slave || zone->type == dns_zone_stub) &&
1548 if (zone->masterfile == NULL ||
1549 !isc_file_exists(zone->masterfile)) {
1550 if (zone->masterfile != NULL) {
1551 dns_zone_log(zone, ISC_LOG_DEBUG(1),
1554 zone->refreshtime = now;
1555 if (zone->task != NULL)
1556 zone_settimer(zone, &now);
1557 result = ISC_R_SUCCESS;
1562 dns_zone_log(zone, ISC_LOG_DEBUG(1), "starting load");
1564 result = dns_db_create(zone->mctx, zone->db_argv[0],
1565 &zone->origin, (zone->type == dns_zone_stub) ?
1566 dns_dbtype_stub : dns_dbtype_zone,
1568 zone->db_argc - 1, zone->db_argv + 1,
1571 if (result != ISC_R_SUCCESS) {
1572 dns_zone_log(zone, ISC_LOG_ERROR,
1573 "loading zone: creating database: %s",
1574 isc_result_totext(result));
1577 dns_db_settask(db, zone->task);
1579 if (! dns_db_ispersistent(db)) {
1580 if (zone->masterfile != NULL) {
1581 result = zone_startload(db, zone, loadtime);
1583 result = DNS_R_NOMASTERFILE;
1584 if (zone->type == dns_zone_master) {
1585 dns_zone_log(zone, ISC_LOG_ERROR,
1587 "no master file configured");
1590 dns_zone_log(zone, ISC_LOG_INFO, "loading zone: "
1591 "no master file configured: continuing");
1595 if (result == DNS_R_CONTINUE) {
1596 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADING);
1597 if ((flags & DNS_ZONELOADFLAG_THAW) != 0)
1598 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_THAW);
1602 result = zone_postload(zone, db, loadtime, result);
1612 dns_zone_load(dns_zone_t *zone) {
1613 return (zone_load(zone, 0));
1617 dns_zone_loadnew(dns_zone_t *zone) {
1618 return (zone_load(zone, DNS_ZONELOADFLAG_NOSTAT));
1622 dns_zone_loadandthaw(dns_zone_t *zone) {
1623 isc_result_t result;
1625 result = zone_load(zone, DNS_ZONELOADFLAG_THAW);
1627 case DNS_R_CONTINUE:
1628 /* Deferred thaw. */
1631 case DNS_R_UPTODATE:
1632 case DNS_R_SEENINCLUDE:
1633 zone->update_disabled = ISC_FALSE;
1635 case DNS_R_NOMASTERFILE:
1636 zone->update_disabled = ISC_FALSE;
1639 /* Error, remain in disabled state. */
1646 get_master_options(dns_zone_t *zone) {
1647 unsigned int options;
1649 options = DNS_MASTER_ZONE;
1650 if (zone->type == dns_zone_slave)
1651 options |= DNS_MASTER_SLAVE;
1652 if (zone->type == dns_zone_key)
1653 options |= DNS_MASTER_KEY;
1654 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNS))
1655 options |= DNS_MASTER_CHECKNS;
1656 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_FATALNS))
1657 options |= DNS_MASTER_FATALNS;
1658 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
1659 options |= DNS_MASTER_CHECKNAMES;
1660 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL))
1661 options |= DNS_MASTER_CHECKNAMESFAIL;
1662 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMX))
1663 options |= DNS_MASTER_CHECKMX;
1664 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1665 options |= DNS_MASTER_CHECKMXFAIL;
1666 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKWILDCARD))
1667 options |= DNS_MASTER_CHECKWILDCARD;
1668 if (zone->type == dns_zone_master &&
1669 ((zone->update_acl != NULL && !dns_acl_isnone(zone->update_acl)) ||
1670 zone->ssutable != NULL))
1671 options |= DNS_MASTER_RESIGN;
1676 zone_gotreadhandle(isc_task_t *task, isc_event_t *event) {
1677 dns_load_t *load = event->ev_arg;
1678 isc_result_t result = ISC_R_SUCCESS;
1679 unsigned int options;
1681 REQUIRE(DNS_LOAD_VALID(load));
1683 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1684 result = ISC_R_CANCELED;
1685 isc_event_free(&event);
1686 if (result == ISC_R_CANCELED)
1689 options = get_master_options(load->zone);
1691 result = dns_master_loadfileinc3(load->zone->masterfile,
1692 dns_db_origin(load->db),
1693 dns_db_origin(load->db),
1694 load->zone->rdclass, options, 0,
1695 &load->callbacks, task,
1696 zone_loaddone, load,
1697 &load->zone->lctx, load->zone->mctx,
1698 load->zone->masterformat);
1699 if (result != ISC_R_SUCCESS && result != DNS_R_CONTINUE &&
1700 result != DNS_R_SEENINCLUDE)
1705 zone_loaddone(load, result);
1709 zone_gotwritehandle(isc_task_t *task, isc_event_t *event) {
1710 const char me[] = "zone_gotwritehandle";
1711 dns_zone_t *zone = event->ev_arg;
1712 isc_result_t result = ISC_R_SUCCESS;
1713 dns_dbversion_t *version = NULL;
1715 REQUIRE(DNS_ZONE_VALID(zone));
1716 INSIST(task == zone->task);
1719 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0)
1720 result = ISC_R_CANCELED;
1721 isc_event_free(&event);
1722 if (result == ISC_R_CANCELED)
1726 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
1727 if (zone->db != NULL) {
1728 const dns_master_style_t *output_style;
1730 dns_db_currentversion(zone->db, &version);
1731 if (zone->type == dns_zone_key)
1732 output_style = &dns_master_style_keyzone;
1734 output_style = &dns_master_style_default;
1735 result = dns_master_dumpinc2(zone->mctx, zone->db, version,
1736 output_style, zone->masterfile,
1737 zone->task, dump_done, zone,
1738 &zone->dctx, zone->masterformat);
1739 dns_db_closeversion(zone->db, &version, ISC_FALSE);
1741 result = ISC_R_CANCELED;
1742 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
1744 if (result != DNS_R_CONTINUE)
1749 dump_done(zone, result);
1753 zone_startload(dns_db_t *db, dns_zone_t *zone, isc_time_t loadtime) {
1755 isc_result_t result;
1756 isc_result_t tresult;
1757 unsigned int options;
1759 result = dns_zone_rpz_enable_db(zone, db);
1760 if (result != ISC_R_SUCCESS)
1762 options = get_master_options(zone);
1763 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MANYERRORS))
1764 options |= DNS_MASTER_MANYERRORS;
1766 if (zone->zmgr != NULL && zone->db != NULL && zone->task != NULL) {
1767 load = isc_mem_get(zone->mctx, sizeof(*load));
1769 return (ISC_R_NOMEMORY);
1774 load->loadtime = loadtime;
1775 load->magic = LOAD_MAGIC;
1777 isc_mem_attach(zone->mctx, &load->mctx);
1778 zone_iattach(zone, &load->zone);
1779 dns_db_attach(db, &load->db);
1780 dns_rdatacallbacks_init(&load->callbacks);
1781 result = dns_db_beginload(db, &load->callbacks.add,
1782 &load->callbacks.add_private);
1783 if (result != ISC_R_SUCCESS)
1785 result = zonemgr_getio(zone->zmgr, ISC_TRUE, zone->task,
1786 zone_gotreadhandle, load,
1788 if (result != ISC_R_SUCCESS) {
1790 * We can't report multiple errors so ignore
1791 * the result of dns_db_endload().
1793 (void)dns_db_endload(load->db,
1794 &load->callbacks.add_private);
1797 result = DNS_R_CONTINUE;
1799 dns_rdatacallbacks_t callbacks;
1801 dns_rdatacallbacks_init(&callbacks);
1802 result = dns_db_beginload(db, &callbacks.add,
1803 &callbacks.add_private);
1804 if (result != ISC_R_SUCCESS)
1806 result = dns_master_loadfile3(zone->masterfile, &zone->origin,
1807 &zone->origin, zone->rdclass,
1808 options, 0, &callbacks,
1809 zone->mctx, zone->masterformat);
1810 tresult = dns_db_endload(db, &callbacks.add_private);
1811 if (result == ISC_R_SUCCESS)
1819 dns_db_detach(&load->db);
1820 zone_idetach(&load->zone);
1821 isc_mem_detach(&load->mctx);
1822 isc_mem_put(zone->mctx, load, sizeof(*load));
1826 static isc_boolean_t
1827 zone_check_mx(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1830 isc_result_t result;
1831 char ownerbuf[DNS_NAME_FORMATSIZE];
1832 char namebuf[DNS_NAME_FORMATSIZE];
1833 char altbuf[DNS_NAME_FORMATSIZE];
1834 dns_fixedname_t fixed;
1835 dns_name_t *foundname;
1839 * "." means the services does not exist.
1841 if (dns_name_equal(name, dns_rootname))
1847 if (!dns_name_issubdomain(name, &zone->origin)) {
1848 if (zone->checkmx != NULL)
1849 return ((zone->checkmx)(zone, name, owner));
1853 if (zone->type == dns_zone_master)
1854 level = ISC_LOG_ERROR;
1856 level = ISC_LOG_WARNING;
1858 dns_fixedname_init(&fixed);
1859 foundname = dns_fixedname_name(&fixed);
1861 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1862 0, 0, NULL, foundname, NULL, NULL);
1863 if (result == ISC_R_SUCCESS)
1866 if (result == DNS_R_NXRRSET) {
1867 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1868 0, 0, NULL, foundname, NULL, NULL);
1869 if (result == ISC_R_SUCCESS)
1873 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1874 dns_name_format(name, namebuf, sizeof namebuf);
1875 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1876 result == DNS_R_EMPTYNAME) {
1877 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKMXFAIL))
1878 level = ISC_LOG_WARNING;
1879 dns_zone_log(zone, level,
1880 "%s/MX '%s' has no address records (A or AAAA)",
1882 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1885 if (result == DNS_R_CNAME) {
1886 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1887 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1888 level = ISC_LOG_WARNING;
1889 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1890 dns_zone_log(zone, level,
1891 "%s/MX '%s' is a CNAME (illegal)",
1893 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1896 if (result == DNS_R_DNAME) {
1897 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNMXCNAME) ||
1898 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME))
1899 level = ISC_LOG_WARNING;
1900 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNOREMXCNAME)) {
1901 dns_name_format(foundname, altbuf, sizeof altbuf);
1902 dns_zone_log(zone, level, "%s/MX '%s' is below a DNAME"
1903 " '%s' (illegal)", ownerbuf, namebuf,
1906 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1909 if (zone->checkmx != NULL && result == DNS_R_DELEGATION)
1910 return ((zone->checkmx)(zone, name, owner));
1915 static isc_boolean_t
1916 zone_check_srv(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
1919 isc_result_t result;
1920 char ownerbuf[DNS_NAME_FORMATSIZE];
1921 char namebuf[DNS_NAME_FORMATSIZE];
1922 char altbuf[DNS_NAME_FORMATSIZE];
1923 dns_fixedname_t fixed;
1924 dns_name_t *foundname;
1928 * "." means the services does not exist.
1930 if (dns_name_equal(name, dns_rootname))
1936 if (!dns_name_issubdomain(name, &zone->origin)) {
1937 if (zone->checksrv != NULL)
1938 return ((zone->checksrv)(zone, name, owner));
1942 if (zone->type == dns_zone_master)
1943 level = ISC_LOG_ERROR;
1945 level = ISC_LOG_WARNING;
1947 dns_fixedname_init(&fixed);
1948 foundname = dns_fixedname_name(&fixed);
1950 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
1951 0, 0, NULL, foundname, NULL, NULL);
1952 if (result == ISC_R_SUCCESS)
1955 if (result == DNS_R_NXRRSET) {
1956 result = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
1957 0, 0, NULL, foundname, NULL, NULL);
1958 if (result == ISC_R_SUCCESS)
1962 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
1963 dns_name_format(name, namebuf, sizeof namebuf);
1964 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
1965 result == DNS_R_EMPTYNAME) {
1966 dns_zone_log(zone, level,
1967 "%s/SRV '%s' has no address records (A or AAAA)",
1969 /* XXX950 make fatal for 9.5.0. */
1973 if (result == DNS_R_CNAME) {
1974 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1975 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1976 level = ISC_LOG_WARNING;
1977 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1978 dns_zone_log(zone, level,
1979 "%s/SRV '%s' is a CNAME (illegal)",
1981 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1984 if (result == DNS_R_DNAME) {
1985 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_WARNSRVCNAME) ||
1986 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME))
1987 level = ISC_LOG_WARNING;
1988 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IGNORESRVCNAME)) {
1989 dns_name_format(foundname, altbuf, sizeof altbuf);
1990 dns_zone_log(zone, level, "%s/SRV '%s' is below a "
1991 "DNAME '%s' (illegal)", ownerbuf, namebuf,
1994 return ((level == ISC_LOG_WARNING) ? ISC_TRUE : ISC_FALSE);
1997 if (zone->checksrv != NULL && result == DNS_R_DELEGATION)
1998 return ((zone->checksrv)(zone, name, owner));
2003 static isc_boolean_t
2004 zone_check_glue(dns_zone_t *zone, dns_db_t *db, dns_name_t *name,
2007 isc_boolean_t answer = ISC_TRUE;
2008 isc_result_t result, tresult;
2009 char ownerbuf[DNS_NAME_FORMATSIZE];
2010 char namebuf[DNS_NAME_FORMATSIZE];
2011 char altbuf[DNS_NAME_FORMATSIZE];
2012 dns_fixedname_t fixed;
2013 dns_name_t *foundname;
2015 dns_rdataset_t aaaa;
2021 if (!dns_name_issubdomain(name, &zone->origin)) {
2022 if (zone->checkns != NULL)
2023 return ((zone->checkns)(zone, name, owner, NULL, NULL));
2027 if (zone->type == dns_zone_master)
2028 level = ISC_LOG_ERROR;
2030 level = ISC_LOG_WARNING;
2032 dns_fixedname_init(&fixed);
2033 foundname = dns_fixedname_name(&fixed);
2034 dns_rdataset_init(&a);
2035 dns_rdataset_init(&aaaa);
2037 result = dns_db_find(db, name, NULL, dns_rdatatype_a,
2038 DNS_DBFIND_GLUEOK, 0, NULL,
2039 foundname, &a, NULL);
2041 if (result == ISC_R_SUCCESS) {
2042 dns_rdataset_disassociate(&a);
2044 } else if (result == DNS_R_DELEGATION)
2045 dns_rdataset_disassociate(&a);
2047 if (result == DNS_R_NXRRSET || result == DNS_R_DELEGATION ||
2048 result == DNS_R_GLUE) {
2049 tresult = dns_db_find(db, name, NULL, dns_rdatatype_aaaa,
2050 DNS_DBFIND_GLUEOK, 0, NULL,
2051 foundname, &aaaa, NULL);
2052 if (tresult == ISC_R_SUCCESS) {
2053 dns_rdataset_disassociate(&aaaa);
2056 if (tresult == DNS_R_DELEGATION)
2057 dns_rdataset_disassociate(&aaaa);
2058 if (result == DNS_R_GLUE || tresult == DNS_R_GLUE) {
2060 * Check glue against child zone.
2062 if (zone->checkns != NULL)
2063 answer = (zone->checkns)(zone, name, owner,
2065 if (dns_rdataset_isassociated(&a))
2066 dns_rdataset_disassociate(&a);
2067 if (dns_rdataset_isassociated(&aaaa))
2068 dns_rdataset_disassociate(&aaaa);
2073 dns_name_format(owner, ownerbuf, sizeof ownerbuf);
2074 dns_name_format(name, namebuf, sizeof namebuf);
2075 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
2076 result == DNS_R_EMPTYNAME || result == DNS_R_DELEGATION) {
2078 isc_boolean_t required = ISC_FALSE;
2079 if (dns_name_issubdomain(name, owner)) {
2080 what = "REQUIRED GLUE ";
2081 required = ISC_TRUE;
2082 } else if (result == DNS_R_DELEGATION)
2083 what = "SIBLING GLUE ";
2087 if (result != DNS_R_DELEGATION || required ||
2088 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSIBLING)) {
2089 dns_zone_log(zone, level, "%s/NS '%s' has no %s"
2090 "address records (A or AAAA)",
2091 ownerbuf, namebuf, what);
2093 * Log missing address record.
2095 if (result == DNS_R_DELEGATION && zone->checkns != NULL)
2096 (void)(zone->checkns)(zone, name, owner,
2098 /* XXX950 make fatal for 9.5.0. */
2099 /* answer = ISC_FALSE; */
2101 } else if (result == DNS_R_CNAME) {
2102 dns_zone_log(zone, level, "%s/NS '%s' is a CNAME (illegal)",
2104 /* XXX950 make fatal for 9.5.0. */
2105 /* answer = ISC_FALSE; */
2106 } else if (result == DNS_R_DNAME) {
2107 dns_name_format(foundname, altbuf, sizeof altbuf);
2108 dns_zone_log(zone, level,
2109 "%s/NS '%s' is below a DNAME '%s' (illegal)",
2110 ownerbuf, namebuf, altbuf);
2111 /* XXX950 make fatal for 9.5.0. */
2112 /* answer = ISC_FALSE; */
2115 if (dns_rdataset_isassociated(&a))
2116 dns_rdataset_disassociate(&a);
2117 if (dns_rdataset_isassociated(&aaaa))
2118 dns_rdataset_disassociate(&aaaa);
2122 static isc_boolean_t
2123 zone_rrset_check_dup(dns_zone_t *zone, dns_name_t *owner,
2124 dns_rdataset_t *rdataset)
2126 dns_rdataset_t tmprdataset;
2127 isc_result_t result;
2128 isc_boolean_t answer = ISC_TRUE;
2129 isc_boolean_t format = ISC_TRUE;
2130 int level = ISC_LOG_WARNING;
2131 char ownerbuf[DNS_NAME_FORMATSIZE];
2132 char typebuf[DNS_RDATATYPE_FORMATSIZE];
2133 unsigned int count1 = 0;
2135 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRRFAIL))
2136 level = ISC_LOG_ERROR;
2138 dns_rdataset_init(&tmprdataset);
2139 for (result = dns_rdataset_first(rdataset);
2140 result == ISC_R_SUCCESS;
2141 result = dns_rdataset_next(rdataset)) {
2142 dns_rdata_t rdata1 = DNS_RDATA_INIT;
2143 unsigned int count2 = 0;
2146 dns_rdataset_current(rdataset, &rdata1);
2147 dns_rdataset_clone(rdataset, &tmprdataset);
2148 for (result = dns_rdataset_first(&tmprdataset);
2149 result == ISC_R_SUCCESS;
2150 result = dns_rdataset_next(&tmprdataset)) {
2151 dns_rdata_t rdata2 = DNS_RDATA_INIT;
2153 if (count1 >= count2)
2155 dns_rdataset_current(&tmprdataset, &rdata2);
2156 if (dns_rdata_casecompare(&rdata1, &rdata2) == 0) {
2158 dns_name_format(owner, ownerbuf,
2160 dns_rdatatype_format(rdata1.type,
2165 dns_zone_log(zone, level, "%s/%s has "
2166 "semantically identical records",
2168 if (level == ISC_LOG_ERROR)
2173 dns_rdataset_disassociate(&tmprdataset);
2180 static isc_boolean_t
2181 zone_check_dup(dns_zone_t *zone, dns_db_t *db) {
2182 dns_dbiterator_t *dbiterator = NULL;
2183 dns_dbnode_t *node = NULL;
2184 dns_fixedname_t fixed;
2186 dns_rdataset_t rdataset;
2187 dns_rdatasetiter_t *rdsit = NULL;
2188 isc_boolean_t ok = ISC_TRUE;
2189 isc_result_t result;
2191 dns_fixedname_init(&fixed);
2192 name = dns_fixedname_name(&fixed);
2193 dns_rdataset_init(&rdataset);
2195 result = dns_db_createiterator(db, 0, &dbiterator);
2196 if (result != ISC_R_SUCCESS)
2199 for (result = dns_dbiterator_first(dbiterator);
2200 result == ISC_R_SUCCESS;
2201 result = dns_dbiterator_next(dbiterator)) {
2202 result = dns_dbiterator_current(dbiterator, &node, name);
2203 if (result != ISC_R_SUCCESS)
2206 result = dns_db_allrdatasets(db, node, NULL, 0, &rdsit);
2207 if (result != ISC_R_SUCCESS)
2210 for (result = dns_rdatasetiter_first(rdsit);
2211 result == ISC_R_SUCCESS;
2212 result = dns_rdatasetiter_next(rdsit)) {
2213 dns_rdatasetiter_current(rdsit, &rdataset);
2214 if (!zone_rrset_check_dup(zone, name, &rdataset))
2216 dns_rdataset_disassociate(&rdataset);
2218 dns_rdatasetiter_destroy(&rdsit);
2219 dns_db_detachnode(db, &node);
2223 dns_db_detachnode(db, &node);
2224 dns_dbiterator_destroy(&dbiterator);
2229 static isc_boolean_t
2230 isspf(const dns_rdata_t *rdata) {
2232 const unsigned char *data = rdata->data;
2233 unsigned int rdl = rdata->length, i = 0, tl, len;
2240 if (len > sizeof(buf) - i - 1)
2241 len = sizeof(buf) - i - 1;
2242 memmove(buf + i, data, len);
2252 if (strncmp(buf, "v=spf1", 6) == 0 && (buf[6] == 0 || buf[6] == ' '))
2257 static isc_boolean_t
2258 integrity_checks(dns_zone_t *zone, dns_db_t *db) {
2259 dns_dbiterator_t *dbiterator = NULL;
2260 dns_dbnode_t *node = NULL;
2261 dns_rdataset_t rdataset;
2262 dns_fixedname_t fixed;
2263 dns_fixedname_t fixedbottom;
2266 dns_rdata_in_srv_t srv;
2270 isc_result_t result;
2271 isc_boolean_t ok = ISC_TRUE, have_spf, have_txt;
2273 dns_fixedname_init(&fixed);
2274 name = dns_fixedname_name(&fixed);
2275 dns_fixedname_init(&fixedbottom);
2276 bottom = dns_fixedname_name(&fixedbottom);
2277 dns_rdataset_init(&rdataset);
2278 dns_rdata_init(&rdata);
2280 result = dns_db_createiterator(db, 0, &dbiterator);
2281 if (result != ISC_R_SUCCESS)
2284 result = dns_dbiterator_first(dbiterator);
2285 while (result == ISC_R_SUCCESS) {
2286 result = dns_dbiterator_current(dbiterator, &node, name);
2287 if (result != ISC_R_SUCCESS)
2291 * Is this name visible in the zone?
2293 if (!dns_name_issubdomain(name, &zone->origin) ||
2294 (dns_name_countlabels(bottom) > 0 &&
2295 dns_name_issubdomain(name, bottom)))
2299 * Don't check the NS records at the origin.
2301 if (dns_name_equal(name, &zone->origin))
2304 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_ns,
2305 0, 0, &rdataset, NULL);
2306 if (result != ISC_R_SUCCESS)
2309 * Remember bottom of zone.
2311 dns_name_copy(name, bottom, NULL);
2313 result = dns_rdataset_first(&rdataset);
2314 while (result == ISC_R_SUCCESS) {
2315 dns_rdataset_current(&rdataset, &rdata);
2316 result = dns_rdata_tostruct(&rdata, &ns, NULL);
2317 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2318 if (!zone_check_glue(zone, db, &ns.name, name))
2320 dns_rdata_reset(&rdata);
2321 result = dns_rdataset_next(&rdataset);
2323 dns_rdataset_disassociate(&rdataset);
2327 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_mx,
2328 0, 0, &rdataset, NULL);
2329 if (result != ISC_R_SUCCESS)
2331 result = dns_rdataset_first(&rdataset);
2332 while (result == ISC_R_SUCCESS) {
2333 dns_rdataset_current(&rdataset, &rdata);
2334 result = dns_rdata_tostruct(&rdata, &mx, NULL);
2335 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2336 if (!zone_check_mx(zone, db, &mx.mx, name))
2338 dns_rdata_reset(&rdata);
2339 result = dns_rdataset_next(&rdataset);
2341 dns_rdataset_disassociate(&rdataset);
2344 if (zone->rdclass != dns_rdataclass_in)
2346 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_srv,
2347 0, 0, &rdataset, NULL);
2348 if (result != ISC_R_SUCCESS)
2350 result = dns_rdataset_first(&rdataset);
2351 while (result == ISC_R_SUCCESS) {
2352 dns_rdataset_current(&rdataset, &rdata);
2353 result = dns_rdata_tostruct(&rdata, &srv, NULL);
2354 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2355 if (!zone_check_srv(zone, db, &srv.target, name))
2357 dns_rdata_reset(&rdata);
2358 result = dns_rdataset_next(&rdataset);
2360 dns_rdataset_disassociate(&rdataset);
2364 * Check if there is a type TXT spf record without a type SPF
2365 * RRset being present.
2367 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKSPF))
2369 if (zone->rdclass != dns_rdataclass_in)
2371 have_spf = have_txt = ISC_FALSE;
2372 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_spf,
2373 0, 0, &rdataset, NULL);
2374 if (result == ISC_R_SUCCESS) {
2375 dns_rdataset_disassociate(&rdataset);
2376 have_spf = ISC_TRUE;
2378 result = dns_db_findrdataset(db, node, NULL, dns_rdatatype_txt,
2379 0, 0, &rdataset, NULL);
2380 if (result != ISC_R_SUCCESS)
2382 result = dns_rdataset_first(&rdataset);
2383 while (result == ISC_R_SUCCESS) {
2384 dns_rdataset_current(&rdataset, &rdata);
2385 have_txt = isspf(&rdata);
2386 dns_rdata_reset(&rdata);
2389 result = dns_rdataset_next(&rdataset);
2391 dns_rdataset_disassociate(&rdataset);
2394 if (have_spf != have_txt) {
2395 char namebuf[DNS_NAME_FORMATSIZE];
2396 const char *found = have_txt ? "TXT" : "SPF";
2397 const char *need = have_txt ? "SPF" : "TXT";
2399 dns_name_format(name, namebuf, sizeof(namebuf));
2400 dns_zone_log(zone, ISC_LOG_WARNING, "'%s' found SPF/%s "
2401 "record but no SPF/%s record found, add "
2402 "matching type %s record", namebuf, found,
2407 dns_db_detachnode(db, &node);
2408 result = dns_dbiterator_next(dbiterator);
2413 dns_db_detachnode(db, &node);
2414 dns_dbiterator_destroy(&dbiterator);
2420 * OpenSSL verification of RSA keys with exponent 3 is known to be
2421 * broken prior OpenSSL 0.9.8c/0.9.7k. Look for such keys and warn
2422 * if they are in use.
2425 zone_check_dnskeys(dns_zone_t *zone, dns_db_t *db) {
2426 dns_dbnode_t *node = NULL;
2427 dns_dbversion_t *version = NULL;
2428 dns_rdata_dnskey_t dnskey;
2429 dns_rdata_t rdata = DNS_RDATA_INIT;
2430 dns_rdataset_t rdataset;
2431 isc_result_t result;
2432 isc_boolean_t logit, foundrsa = ISC_FALSE, foundmd5 = ISC_FALSE;
2433 const char *algorithm;
2435 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2436 if (result != ISC_R_SUCCESS)
2439 dns_db_currentversion(db, &version);
2440 dns_rdataset_init(&rdataset);
2441 result = dns_db_findrdataset(db, node, version, dns_rdatatype_dnskey,
2442 dns_rdatatype_none, 0, &rdataset, NULL);
2443 if (result != ISC_R_SUCCESS)
2446 for (result = dns_rdataset_first(&rdataset);
2447 result == ISC_R_SUCCESS;
2448 result = dns_rdataset_next(&rdataset))
2450 dns_rdataset_current(&rdataset, &rdata);
2451 result = dns_rdata_tostruct(&rdata, &dnskey, NULL);
2452 INSIST(result == ISC_R_SUCCESS);
2454 if ((dnskey.algorithm == DST_ALG_RSASHA1 ||
2455 dnskey.algorithm == DST_ALG_RSAMD5) &&
2456 dnskey.datalen > 1 && dnskey.data[0] == 1 &&
2457 dnskey.data[1] == 3)
2459 if (dnskey.algorithm == DST_ALG_RSASHA1) {
2461 foundrsa = ISC_TRUE;
2462 algorithm = "RSASHA1";
2465 foundmd5 = ISC_TRUE;
2466 algorithm = "RSAMD5";
2469 dns_zone_log(zone, ISC_LOG_WARNING,
2470 "weak %s (%u) key found "
2471 "(exponent=3)", algorithm,
2473 if (foundrsa && foundmd5)
2476 dns_rdata_reset(&rdata);
2478 dns_rdataset_disassociate(&rdataset);
2482 dns_db_detachnode(db, &node);
2483 if (version != NULL)
2484 dns_db_closeversion(db, &version, ISC_FALSE);
2488 resume_signingwithkey(dns_zone_t *zone) {
2489 dns_dbnode_t *node = NULL;
2490 dns_dbversion_t *version = NULL;
2491 dns_rdata_t rdata = DNS_RDATA_INIT;
2492 dns_rdataset_t rdataset;
2493 isc_result_t result;
2495 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2496 if (result != ISC_R_SUCCESS)
2499 dns_db_currentversion(zone->db, &version);
2500 dns_rdataset_init(&rdataset);
2501 result = dns_db_findrdataset(zone->db, node, version,
2503 dns_rdatatype_none, 0,
2505 if (result != ISC_R_SUCCESS) {
2506 INSIST(!dns_rdataset_isassociated(&rdataset));
2510 for (result = dns_rdataset_first(&rdataset);
2511 result == ISC_R_SUCCESS;
2512 result = dns_rdataset_next(&rdataset))
2514 dns_rdataset_current(&rdataset, &rdata);
2515 if (rdata.length != 5 ||
2516 rdata.data[0] == 0 || rdata.data[4] != 0) {
2517 dns_rdata_reset(&rdata);
2521 result = zone_signwithkey(zone, rdata.data[0],
2522 (rdata.data[1] << 8) | rdata.data[2],
2523 ISC_TF(rdata.data[3]));
2524 if (result != ISC_R_SUCCESS) {
2525 dns_zone_log(zone, ISC_LOG_ERROR,
2526 "zone_signwithkey failed: %s",
2527 dns_result_totext(result));
2529 dns_rdata_reset(&rdata);
2531 dns_rdataset_disassociate(&rdataset);
2535 dns_db_detachnode(zone->db, &node);
2536 if (version != NULL)
2537 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2541 zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
2542 dns_nsec3chain_t *nsec3chain, *current;
2543 isc_result_t result;
2545 unsigned int options = 0;
2546 char saltbuf[255*2+1];
2547 char flags[sizeof("REMOVE|CREATE|NONSEC|OPTOUT")];
2550 nsec3chain = isc_mem_get(zone->mctx, sizeof *nsec3chain);
2551 if (nsec3chain == NULL)
2552 return (ISC_R_NOMEMORY);
2554 nsec3chain->magic = 0;
2555 nsec3chain->done = ISC_FALSE;
2556 nsec3chain->db = NULL;
2557 nsec3chain->dbiterator = NULL;
2558 nsec3chain->nsec3param.common.rdclass = nsec3param->common.rdclass;
2559 nsec3chain->nsec3param.common.rdtype = nsec3param->common.rdtype;
2560 nsec3chain->nsec3param.hash = nsec3param->hash;
2561 nsec3chain->nsec3param.iterations = nsec3param->iterations;
2562 nsec3chain->nsec3param.flags = nsec3param->flags;
2563 nsec3chain->nsec3param.salt_length = nsec3param->salt_length;
2564 memmove(nsec3chain->salt, nsec3param->salt, nsec3param->salt_length);
2565 nsec3chain->nsec3param.salt = nsec3chain->salt;
2566 nsec3chain->seen_nsec = ISC_FALSE;
2567 nsec3chain->delete_nsec = ISC_FALSE;
2568 nsec3chain->save_delete_nsec = ISC_FALSE;
2570 if (nsec3param->flags == 0)
2571 strlcpy(flags, "NONE", sizeof(flags));
2574 if (nsec3param->flags & DNS_NSEC3FLAG_REMOVE)
2575 strlcat(flags, "REMOVE", sizeof(flags));
2576 if (nsec3param->flags & DNS_NSEC3FLAG_CREATE) {
2577 if (flags[0] == '\0')
2578 strlcpy(flags, "CREATE", sizeof(flags));
2580 strlcat(flags, "|CREATE", sizeof(flags));
2582 if (nsec3param->flags & DNS_NSEC3FLAG_NONSEC) {
2583 if (flags[0] == '\0')
2584 strlcpy(flags, "NONSEC", sizeof(flags));
2586 strlcat(flags, "|NONSEC", sizeof(flags));
2588 if (nsec3param->flags & DNS_NSEC3FLAG_OPTOUT) {
2589 if (flags[0] == '\0')
2590 strlcpy(flags, "OPTOUT", sizeof(flags));
2592 strlcat(flags, "|OPTOUT", sizeof(flags));
2595 if (nsec3param->salt_length == 0)
2596 strlcpy(saltbuf, "-", sizeof(saltbuf));
2598 for (i = 0; i < nsec3param->salt_length; i++)
2599 sprintf(&saltbuf[i*2], "%02X", nsec3chain->salt[i]);
2600 dns_zone_log(zone, ISC_LOG_INFO,
2601 "zone_addnsec3chain(%u,%s,%u,%s)",
2602 nsec3param->hash, flags, nsec3param->iterations,
2604 for (current = ISC_LIST_HEAD(zone->nsec3chain);
2606 current = ISC_LIST_NEXT(current, link)) {
2607 if (current->db == zone->db &&
2608 current->nsec3param.hash == nsec3param->hash &&
2609 current->nsec3param.iterations == nsec3param->iterations &&
2610 current->nsec3param.salt_length == nsec3param->salt_length
2611 && !memcmp(current->nsec3param.salt, nsec3param->salt,
2612 nsec3param->salt_length))
2613 current->done = ISC_TRUE;
2616 if (zone->db != NULL) {
2617 dns_db_attach(zone->db, &nsec3chain->db);
2618 if ((nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0)
2619 options = DNS_DB_NONSEC3;
2620 result = dns_db_createiterator(nsec3chain->db, options,
2621 &nsec3chain->dbiterator);
2622 if (result == ISC_R_SUCCESS)
2623 dns_dbiterator_first(nsec3chain->dbiterator);
2624 if (result == ISC_R_SUCCESS) {
2625 dns_dbiterator_pause(nsec3chain->dbiterator);
2626 ISC_LIST_INITANDAPPEND(zone->nsec3chain,
2629 if (isc_time_isepoch(&zone->nsec3chaintime)) {
2631 zone->nsec3chaintime = now;
2632 if (zone->task != NULL)
2633 zone_settimer(zone, &now);
2637 result = ISC_R_NOTFOUND;
2639 if (nsec3chain != NULL) {
2640 if (nsec3chain->db != NULL)
2641 dns_db_detach(&nsec3chain->db);
2642 if (nsec3chain->dbiterator != NULL)
2643 dns_dbiterator_destroy(&nsec3chain->dbiterator);
2644 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
2650 resume_addnsec3chain(dns_zone_t *zone) {
2651 dns_dbnode_t *node = NULL;
2652 dns_dbversion_t *version = NULL;
2653 dns_rdataset_t rdataset;
2654 isc_result_t result;
2655 dns_rdata_nsec3param_t nsec3param;
2657 if (zone->privatetype == 0)
2660 result = dns_db_findnode(zone->db, &zone->origin, ISC_FALSE, &node);
2661 if (result != ISC_R_SUCCESS)
2664 dns_db_currentversion(zone->db, &version);
2665 dns_rdataset_init(&rdataset);
2666 result = dns_db_findrdataset(zone->db, node, version,
2667 zone->privatetype, dns_rdatatype_none,
2668 0, &rdataset, NULL);
2669 if (result != ISC_R_SUCCESS) {
2670 INSIST(!dns_rdataset_isassociated(&rdataset));
2674 for (result = dns_rdataset_first(&rdataset);
2675 result == ISC_R_SUCCESS;
2676 result = dns_rdataset_next(&rdataset))
2678 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
2679 dns_rdata_t rdata = DNS_RDATA_INIT;
2680 dns_rdata_t private = DNS_RDATA_INIT;
2682 dns_rdataset_current(&rdataset, &private);
2683 if (!dns_nsec3param_fromprivate(&private, &rdata, buf,
2686 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2687 RUNTIME_CHECK(result == ISC_R_SUCCESS);
2688 if ((nsec3param.flags & DNS_NSEC3FLAG_CREATE) != 0 ||
2689 (nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
2690 result = zone_addnsec3chain(zone, &nsec3param);
2691 if (result != ISC_R_SUCCESS) {
2692 dns_zone_log(zone, ISC_LOG_ERROR,
2693 "zone_addnsec3chain failed: %s",
2694 dns_result_totext(result));
2698 dns_rdataset_disassociate(&rdataset);
2701 dns_db_detachnode(zone->db, &node);
2702 if (version != NULL)
2703 dns_db_closeversion(zone->db, &version, ISC_FALSE);
2707 set_resigntime(dns_zone_t *zone) {
2708 dns_rdataset_t rdataset;
2709 dns_fixedname_t fixed;
2710 unsigned int resign;
2711 isc_result_t result;
2712 isc_uint32_t nanosecs;
2713 dns_db_t *db = NULL;
2715 dns_rdataset_init(&rdataset);
2716 dns_fixedname_init(&fixed);
2718 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
2719 if (zone->db != NULL)
2720 dns_db_attach(zone->db, &db);
2721 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
2723 isc_time_settoepoch(&zone->resigntime);
2727 result = dns_db_getsigningtime(db, &rdataset,
2728 dns_fixedname_name(&fixed));
2729 if (result != ISC_R_SUCCESS) {
2730 isc_time_settoepoch(&zone->resigntime);
2734 resign = rdataset.resign - zone->sigresigninginterval;
2735 dns_rdataset_disassociate(&rdataset);
2736 isc_random_get(&nanosecs);
2737 nanosecs %= 1000000000;
2738 isc_time_set(&zone->resigntime, resign, nanosecs);
2745 check_nsec3param(dns_zone_t *zone, dns_db_t *db) {
2746 dns_dbnode_t *node = NULL;
2747 dns_rdataset_t rdataset;
2748 dns_dbversion_t *version = NULL;
2749 dns_rdata_nsec3param_t nsec3param;
2750 isc_boolean_t ok = ISC_FALSE;
2751 isc_result_t result;
2752 dns_rdata_t rdata = DNS_RDATA_INIT;
2753 isc_boolean_t dynamic = (zone->type == dns_zone_master) ?
2754 zone_isdynamic(zone) : ISC_FALSE;
2756 dns_rdataset_init(&rdataset);
2757 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
2758 if (result != ISC_R_SUCCESS) {
2759 dns_zone_log(zone, ISC_LOG_ERROR,
2760 "nsec3param lookup failure: %s",
2761 dns_result_totext(result));
2764 dns_db_currentversion(db, &version);
2766 result = dns_db_findrdataset(db, node, version,
2767 dns_rdatatype_nsec3param,
2768 dns_rdatatype_none, 0, &rdataset, NULL);
2769 if (result == ISC_R_NOTFOUND) {
2770 INSIST(!dns_rdataset_isassociated(&rdataset));
2771 result = ISC_R_SUCCESS;
2774 if (result != ISC_R_SUCCESS) {
2775 INSIST(!dns_rdataset_isassociated(&rdataset));
2776 dns_zone_log(zone, ISC_LOG_ERROR,
2777 "nsec3param lookup failure: %s",
2778 dns_result_totext(result));
2783 * For dynamic zones we must support every algorithm so we can
2784 * regenerate all the NSEC3 chains.
2785 * For non-dynamic zones we only need to find a supported algorithm.
2787 for (result = dns_rdataset_first(&rdataset);
2788 result == ISC_R_SUCCESS;
2789 result = dns_rdataset_next(&rdataset))
2791 dns_rdataset_current(&rdataset, &rdata);
2792 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
2793 dns_rdata_reset(&rdata);
2794 INSIST(result == ISC_R_SUCCESS);
2795 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NSEC3TESTZONE) &&
2796 nsec3param.hash == DNS_NSEC3_UNKNOWNALG && !dynamic)
2798 dns_zone_log(zone, ISC_LOG_WARNING,
2799 "nsec3 test \"unknown\" hash algorithm found: %u",
2802 } else if (!dns_nsec3_supportedhash(nsec3param.hash)) {
2804 dns_zone_log(zone, ISC_LOG_ERROR,
2805 "unsupported nsec3 hash algorithm"
2806 " in dynamic zone: %u",
2808 result = DNS_R_BADZONE;
2809 /* Stop second error message. */
2813 dns_zone_log(zone, ISC_LOG_WARNING,
2814 "unsupported nsec3 hash algorithm: %u",
2819 if (result == ISC_R_NOMORE)
2820 result = ISC_R_SUCCESS;
2823 result = DNS_R_BADZONE;
2824 dns_zone_log(zone, ISC_LOG_ERROR,
2825 "no supported nsec3 hash algorithm");
2829 if (dns_rdataset_isassociated(&rdataset))
2830 dns_rdataset_disassociate(&rdataset);
2831 dns_db_closeversion(db, &version, ISC_FALSE);
2832 dns_db_detachnode(db, &node);
2837 * Set the timer for refreshing the key zone to the soonest future time
2838 * of the set (current timer, keydata->refresh, keydata->addhd,
2839 * keydata->removehd).
2842 set_refreshkeytimer(dns_zone_t *zone, dns_rdata_keydata_t *key,
2845 const char me[] = "set_refreshkeytimer";
2847 isc_time_t timenow, timethen;
2851 then = key->refresh;
2852 if (key->addhd > now && key->addhd < then)
2854 if (key->removehd > now && key->removehd < then)
2855 then = key->removehd;
2859 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
2862 if (isc_time_compare(&zone->refreshkeytime, &timenow) < 0 ||
2863 isc_time_compare(&timethen, &zone->refreshkeytime) < 0)
2864 zone->refreshkeytime = timethen;
2866 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
2867 dns_zone_log(zone, ISC_LOG_DEBUG(1), "next key refresh: %s", timebuf);
2868 zone_settimer(zone, &timenow);
2872 * Convert key(s) linked from 'keynode' to KEYDATA and add to the key zone.
2873 * If the key zone is changed, set '*changed' to ISC_TRUE.
2876 create_keydata(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
2877 dns_diff_t *diff, dns_keytable_t *keytable,
2878 dns_keynode_t **keynodep, isc_boolean_t *changed)
2880 const char me[] = "create_keydata";
2881 isc_result_t result = ISC_R_SUCCESS;
2882 isc_buffer_t keyb, dstb;
2883 unsigned char key_buf[4096], dst_buf[DST_KEY_MAXSIZE];
2884 dns_rdata_keydata_t keydata;
2885 dns_rdata_dnskey_t dnskey;
2886 dns_rdata_t rdata = DNS_RDATA_INIT;
2887 dns_keynode_t *keynode;
2892 REQUIRE(keynodep != NULL);
2893 keynode = *keynodep;
2896 isc_stdtime_get(&now);
2898 /* Loop in case there's more than one key. */
2899 while (result == ISC_R_SUCCESS) {
2900 dns_keynode_t *nextnode = NULL;
2902 key = dns_keynode_key(keynode);
2906 isc_buffer_init(&dstb, dst_buf, sizeof(dst_buf));
2907 CHECK(dst_key_todns(key, &dstb));
2909 /* Convert DST key to DNSKEY. */
2910 dns_rdata_reset(&rdata);
2911 isc_buffer_usedregion(&dstb, &r);
2912 dns_rdata_fromregion(&rdata, dst_key_class(key),
2913 dns_rdatatype_dnskey, &r);
2915 /* DSTKEY to KEYDATA. */
2916 CHECK(dns_rdata_tostruct(&rdata, &dnskey, NULL));
2917 CHECK(dns_keydata_fromdnskey(&keydata, &dnskey, now, 0, 0,
2920 /* KEYDATA to rdata. */
2921 dns_rdata_reset(&rdata);
2922 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
2923 CHECK(dns_rdata_fromstruct(&rdata,
2924 zone->rdclass, dns_rdatatype_keydata,
2927 /* Add rdata to zone. */
2928 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD,
2929 dst_key_name(key), 0, &rdata));
2930 *changed = ISC_TRUE;
2931 /* Refresh new keys from the zone apex as soon as possible. */
2932 set_refreshkeytimer(zone, &keydata, now);
2935 result = dns_keytable_nextkeynode(keytable, keynode, &nextnode);
2936 if (result != ISC_R_NOTFOUND) {
2937 dns_keytable_detachkeynode(keytable, &keynode);
2942 if (keynode != NULL)
2943 dns_keytable_detachkeynode(keytable, &keynode);
2946 return (ISC_R_SUCCESS);
2953 * Remove from the key zone all the KEYDATA records found in rdataset.
2956 delete_keydata(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
2957 dns_name_t *name, dns_rdataset_t *rdataset)
2959 dns_rdata_t rdata = DNS_RDATA_INIT;
2960 isc_result_t result, uresult;
2962 for (result = dns_rdataset_first(rdataset);
2963 result == ISC_R_SUCCESS;
2964 result = dns_rdataset_next(rdataset)) {
2965 dns_rdata_reset(&rdata);
2966 dns_rdataset_current(rdataset, &rdata);
2967 uresult = update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
2969 if (uresult != ISC_R_SUCCESS)
2972 if (result == ISC_R_NOMORE)
2973 result = ISC_R_SUCCESS;
2978 * Compute the DNSSEC key ID for a DNSKEY record.
2981 compute_tag(dns_name_t *name, dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx,
2984 isc_result_t result;
2985 dns_rdata_t rdata = DNS_RDATA_INIT;
2986 unsigned char data[4096];
2987 isc_buffer_t buffer;
2988 dst_key_t *dstkey = NULL;
2990 isc_buffer_init(&buffer, data, sizeof(data));
2991 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
2992 dns_rdatatype_dnskey, dnskey, &buffer);
2994 result = dns_dnssec_keyfromrdata(name, &rdata, mctx, &dstkey);
2995 if (result == ISC_R_SUCCESS)
2996 *tag = dst_key_id(dstkey);
2997 dst_key_free(&dstkey);
3003 * Add key to the security roots.
3006 trust_key(dns_zone_t *zone, dns_name_t *keyname,
3007 dns_rdata_dnskey_t *dnskey, isc_mem_t *mctx) {
3008 isc_result_t result;
3009 dns_rdata_t rdata = DNS_RDATA_INIT;
3010 unsigned char data[4096];
3011 isc_buffer_t buffer;
3012 dns_keytable_t *sr = NULL;
3013 dst_key_t *dstkey = NULL;
3015 /* Convert dnskey to DST key. */
3016 isc_buffer_init(&buffer, data, sizeof(data));
3017 dns_rdata_fromstruct(&rdata, dnskey->common.rdclass,
3018 dns_rdatatype_dnskey, dnskey, &buffer);
3020 result = dns_view_getsecroots(zone->view, &sr);
3021 if (result != ISC_R_SUCCESS)
3024 CHECK(dns_dnssec_keyfromrdata(keyname, &rdata, mctx, &dstkey));
3025 CHECK(dns_keytable_add(sr, ISC_TRUE, &dstkey));
3026 dns_keytable_detach(&sr);
3030 dst_key_free(&dstkey);
3032 dns_keytable_detach(&sr);
3037 * Add a null key to the security roots for so that all queries
3038 * to the zone will fail.
3041 fail_secure(dns_zone_t *zone, dns_name_t *keyname) {
3042 isc_result_t result;
3043 dns_keytable_t *sr = NULL;
3045 result = dns_view_getsecroots(zone->view, &sr);
3046 if (result == ISC_R_SUCCESS) {
3047 dns_keytable_marksecure(sr, keyname);
3048 dns_keytable_detach(&sr);
3053 * Scan a set of KEYDATA records from the key zone. The ones that are
3054 * valid (i.e., the add holddown timer has expired) become trusted keys.
3057 load_secroots(dns_zone_t *zone, dns_name_t *name, dns_rdataset_t *rdataset) {
3058 isc_result_t result;
3059 dns_rdata_t rdata = DNS_RDATA_INIT;
3060 dns_rdata_keydata_t keydata;
3061 dns_rdata_dnskey_t dnskey;
3062 isc_mem_t *mctx = zone->mctx;
3063 int trusted = 0, revoked = 0, pending = 0;
3065 dns_keytable_t *sr = NULL;
3067 isc_stdtime_get(&now);
3069 result = dns_view_getsecroots(zone->view, &sr);
3070 if (result == ISC_R_SUCCESS) {
3071 dns_keytable_delete(sr, name);
3072 dns_keytable_detach(&sr);
3075 /* Now insert all the accepted trust anchors from this keydata set. */
3076 for (result = dns_rdataset_first(rdataset);
3077 result == ISC_R_SUCCESS;
3078 result = dns_rdataset_next(rdataset)) {
3079 dns_rdata_reset(&rdata);
3080 dns_rdataset_current(rdataset, &rdata);
3082 /* Convert rdata to keydata. */
3083 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
3084 if (result == ISC_R_UNEXPECTEDEND)
3086 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3088 /* Set the key refresh timer. */
3089 set_refreshkeytimer(zone, &keydata, now);
3091 /* If the removal timer is nonzero, this key was revoked. */
3092 if (keydata.removehd != 0) {
3098 * If the add timer is still pending, this key is not
3101 if (now < keydata.addhd) {
3106 /* Convert keydata to dnskey. */
3107 dns_keydata_todnskey(&keydata, &dnskey, NULL);
3109 /* Add to keytables. */
3111 trust_key(zone, name, &dnskey, mctx);
3114 if (trusted == 0 && pending != 0) {
3115 char namebuf[DNS_NAME_FORMATSIZE];
3116 dns_name_format(name, namebuf, sizeof namebuf);
3117 dns_zone_log(zone, ISC_LOG_ERROR,
3118 "No valid trust anchors for '%s'!", namebuf);
3119 dns_zone_log(zone, ISC_LOG_ERROR,
3120 "%d key(s) revoked, %d still pending",
3122 dns_zone_log(zone, ISC_LOG_ERROR,
3123 "All queries to '%s' will fail", namebuf);
3124 fail_secure(zone, name);
3129 do_one_tuple(dns_difftuple_t **tuple, dns_db_t *db, dns_dbversion_t *ver,
3132 dns_diff_t temp_diff;
3133 isc_result_t result;
3136 * Create a singleton diff.
3138 dns_diff_init(diff->mctx, &temp_diff);
3139 ISC_LIST_APPEND(temp_diff.tuples, *tuple, link);
3142 * Apply it to the database.
3144 result = dns_diff_apply(&temp_diff, db, ver);
3145 ISC_LIST_UNLINK(temp_diff.tuples, *tuple, link);
3146 if (result != ISC_R_SUCCESS) {
3147 dns_difftuple_free(tuple);
3152 * Merge it into the current pending journal entry.
3154 dns_diff_appendminimal(diff, tuple);
3157 * Do not clear temp_diff.
3159 return (ISC_R_SUCCESS);
3163 update_one_rr(dns_db_t *db, dns_dbversion_t *ver, dns_diff_t *diff,
3164 dns_diffop_t op, dns_name_t *name, dns_ttl_t ttl,
3167 dns_difftuple_t *tuple = NULL;
3168 isc_result_t result;
3169 result = dns_difftuple_create(diff->mctx, op,
3170 name, ttl, rdata, &tuple);
3171 if (result != ISC_R_SUCCESS)
3173 return (do_one_tuple(&tuple, db, ver, diff));
3177 increment_soa_serial(dns_db_t *db, dns_dbversion_t *ver,
3178 dns_diff_t *diff, isc_mem_t *mctx) {
3179 dns_difftuple_t *deltuple = NULL;
3180 dns_difftuple_t *addtuple = NULL;
3181 isc_uint32_t serial;
3182 isc_result_t result;
3184 CHECK(dns_db_createsoatuple(db, ver, mctx, DNS_DIFFOP_DEL, &deltuple));
3185 CHECK(dns_difftuple_copy(deltuple, &addtuple));
3186 addtuple->op = DNS_DIFFOP_ADD;
3188 serial = dns_soa_getserial(&addtuple->rdata);
3191 serial = (serial + 1) & 0xFFFFFFFF;
3195 dns_soa_setserial(serial, &addtuple->rdata);
3196 CHECK(do_one_tuple(&deltuple, db, ver, diff));
3197 CHECK(do_one_tuple(&addtuple, db, ver, diff));
3198 result = ISC_R_SUCCESS;
3201 if (addtuple != NULL)
3202 dns_difftuple_free(&addtuple);
3203 if (deltuple != NULL)
3204 dns_difftuple_free(&deltuple);
3209 * Write all transactions in 'diff' to the zone journal file.
3212 zone_journal(dns_zone_t *zone, dns_diff_t *diff, const char *caller) {
3213 const char me[] = "zone_journal";
3214 const char *journalfile;
3215 isc_result_t result = ISC_R_SUCCESS;
3216 dns_journal_t *journal = NULL;
3219 journalfile = dns_zone_getjournal(zone);
3220 if (journalfile != NULL) {
3221 result = dns_journal_open(zone->mctx, journalfile,
3222 ISC_TRUE, &journal);
3223 if (result != ISC_R_SUCCESS) {
3224 dns_zone_log(zone, ISC_LOG_ERROR,
3225 "%s:dns_journal_open -> %s",
3226 caller, dns_result_totext(result));
3230 result = dns_journal_write_transaction(journal, diff);
3231 dns_journal_destroy(&journal);
3232 if (result != ISC_R_SUCCESS) {
3233 dns_zone_log(zone, ISC_LOG_ERROR,
3234 "%s:dns_journal_write_transaction -> %s",
3235 caller, dns_result_totext(result));
3243 * Create an SOA record for a newly-created zone
3246 add_soa(dns_zone_t *zone, dns_db_t *db) {
3247 isc_result_t result;
3248 dns_rdata_t rdata = DNS_RDATA_INIT;
3249 unsigned char buf[DNS_SOA_BUFFERSIZE];
3250 dns_dbversion_t *ver = NULL;
3253 dns_zone_log(zone, ISC_LOG_DEBUG(1), "creating SOA");
3255 dns_diff_init(zone->mctx, &diff);
3256 result = dns_db_newversion(db, &ver);
3257 if (result != ISC_R_SUCCESS) {
3258 dns_zone_log(zone, ISC_LOG_ERROR,
3259 "add_soa:dns_db_newversion -> %s",
3260 dns_result_totext(result));
3264 /* Build SOA record */
3265 result = dns_soa_buildrdata(&zone->origin, dns_rootname, zone->rdclass,
3266 0, 0, 0, 0, 0, buf, &rdata);
3267 if (result != ISC_R_SUCCESS) {
3268 dns_zone_log(zone, ISC_LOG_ERROR,
3269 "add_soa:dns_soa_buildrdata -> %s",
3270 dns_result_totext(result));
3274 result = update_one_rr(db, ver, &diff, DNS_DIFFOP_ADD,
3275 &zone->origin, 0, &rdata);
3278 dns_diff_clear(&diff);
3280 dns_db_closeversion(db, &ver, ISC_TF(result == ISC_R_SUCCESS));
3286 * Synchronize the set of initializing keys found in managed-keys {}
3287 * statements with the set of trust anchors found in the managed-keys.bind
3288 * zone. If a domain is no longer named in managed-keys, delete all keys
3289 * from that domain from the key zone. If a domain is mentioned in in
3290 * managed-keys but there are no references to it in the key zone, load
3291 * the key zone with the initializing key(s) for that domain.
3294 sync_keyzone(dns_zone_t *zone, dns_db_t *db) {
3295 isc_result_t result = ISC_R_SUCCESS;
3296 isc_boolean_t changed = ISC_FALSE;
3297 isc_boolean_t commit = ISC_FALSE;
3298 dns_rbtnodechain_t chain;
3300 dns_name_t foundname, *origin;
3301 dns_keynode_t *keynode = NULL;
3302 dns_view_t *view = zone->view;
3303 dns_keytable_t *sr = NULL;
3304 dns_dbversion_t *ver = NULL;
3306 dns_rriterator_t rrit;
3308 dns_zone_log(zone, ISC_LOG_DEBUG(1), "synchronizing trusted keys");
3310 dns_name_init(&foundname, NULL);
3311 dns_fixedname_init(&fn);
3312 origin = dns_fixedname_name(&fn);
3314 dns_diff_init(zone->mctx, &diff);
3316 CHECK(dns_view_getsecroots(view, &sr));
3318 result = dns_db_newversion(db, &ver);
3319 if (result != ISC_R_SUCCESS) {
3320 dns_zone_log(zone, ISC_LOG_ERROR,
3321 "sync_keyzone:dns_db_newversion -> %s",
3322 dns_result_totext(result));
3327 * Walk the zone DB. If we find any keys whose names are no longer
3328 * in managed-keys (or *are* in trusted-keys, meaning they are
3329 * permanent and not RFC5011-maintained), delete them from the
3330 * zone. Otherwise call load_secroots(), which loads keys into
3331 * secroots as appropriate.
3333 dns_rriterator_init(&rrit, db, ver, 0);
3334 for (result = dns_rriterator_first(&rrit);
3335 result == ISC_R_SUCCESS;
3336 result = dns_rriterator_nextrrset(&rrit)) {
3337 dns_rdataset_t *rdataset = NULL;
3338 dns_name_t *rrname = NULL;
3341 dns_rriterator_current(&rrit, &rrname, &ttl,
3343 if (!dns_rdataset_isassociated(rdataset)) {
3344 dns_rriterator_destroy(&rrit);
3348 if (rdataset->type != dns_rdatatype_keydata)
3351 result = dns_keytable_find(sr, rrname, &keynode);
3352 if ((result != ISC_R_SUCCESS &&
3353 result != DNS_R_PARTIALMATCH) ||
3354 dns_keynode_managed(keynode) == ISC_FALSE) {
3355 CHECK(delete_keydata(db, ver, &diff,
3359 load_secroots(zone, rrname, rdataset);
3362 if (keynode != NULL)
3363 dns_keytable_detachkeynode(sr, &keynode);
3365 dns_rriterator_destroy(&rrit);
3368 * Now walk secroots to find any managed keys that aren't
3369 * in the zone. If we find any, we add them to the zone.
3371 RWLOCK(&sr->rwlock, isc_rwlocktype_write);
3372 dns_rbtnodechain_init(&chain, zone->mctx);
3373 result = dns_rbtnodechain_first(&chain, sr->table, &foundname, origin);
3374 if (result == ISC_R_NOTFOUND)
3375 result = ISC_R_NOMORE;
3376 while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) {
3377 dns_rbtnode_t *rbtnode = NULL;
3379 dns_rbtnodechain_current(&chain, &foundname, origin, &rbtnode);
3380 if (rbtnode->data == NULL)
3383 dns_keytable_attachkeynode(sr, rbtnode->data, &keynode);
3384 if (dns_keynode_managed(keynode)) {
3385 dns_fixedname_t fname;
3386 dns_name_t *keyname;
3389 key = dns_keynode_key(keynode);
3390 dns_fixedname_init(&fname);
3392 if (key == NULL) /* fail_secure() was called. */
3395 keyname = dst_key_name(key);
3396 result = dns_db_find(db, keyname, ver,
3397 dns_rdatatype_keydata,
3398 DNS_DBFIND_NOWILD, 0, NULL,
3399 dns_fixedname_name(&fname),
3401 if (result != ISC_R_SUCCESS)
3402 result = create_keydata(zone, db, ver, &diff,
3403 sr, &keynode, &changed);
3404 if (result != ISC_R_SUCCESS)
3408 result = dns_rbtnodechain_next(&chain, &foundname, origin);
3409 if (keynode != NULL)
3410 dns_keytable_detachkeynode(sr, &keynode);
3412 RWUNLOCK(&sr->rwlock, isc_rwlocktype_write);
3414 if (result == ISC_R_NOMORE)
3415 result = ISC_R_SUCCESS;
3418 /* Write changes to journal file. */
3419 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
3420 CHECK(zone_journal(zone, &diff, "sync_keyzone"));
3422 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
3423 zone_needdump(zone, 30);
3428 if (result != ISC_R_SUCCESS &&
3429 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
3430 dns_zone_log(zone, ISC_LOG_ERROR,
3431 "unable to synchronize managed keys: %s",
3432 dns_result_totext(result));
3433 isc_time_settoepoch(&zone->refreshkeytime);
3435 if (keynode != NULL)
3436 dns_keytable_detachkeynode(sr, &keynode);
3438 dns_keytable_detach(&sr);
3440 dns_db_closeversion(db, &ver, commit);
3441 dns_diff_clear(&diff);
3447 zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime,
3448 isc_result_t result)
3450 unsigned int soacount = 0;
3451 unsigned int nscount = 0;
3452 unsigned int errors = 0;
3453 isc_uint32_t serial, oldserial, refresh, retry, expire, minimum;
3455 isc_boolean_t needdump = ISC_FALSE;
3456 isc_boolean_t hasinclude = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3457 isc_boolean_t nomaster = ISC_FALSE;
3458 unsigned int options;
3463 * Initiate zone transfer? We may need a error code that
3464 * indicates that the "permanent" form does not exist.
3465 * XXX better error feedback to log.
3467 if (result != ISC_R_SUCCESS && result != DNS_R_SEENINCLUDE) {
3468 if (zone->type == dns_zone_slave ||
3469 zone->type == dns_zone_stub) {
3470 if (result == ISC_R_FILENOTFOUND)
3471 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3473 else if (result != DNS_R_NOMASTERFILE)
3474 dns_zone_log(zone, ISC_LOG_ERROR,
3475 "loading from master file %s "
3478 dns_result_totext(result));
3480 int level = ISC_LOG_ERROR;
3481 if (zone->type == dns_zone_key &&
3482 result == ISC_R_FILENOTFOUND)
3483 level = ISC_LOG_DEBUG(1);
3484 dns_zone_log(zone, level,
3485 "loading from master file %s failed: %s",
3487 dns_result_totext(result));
3488 nomaster = ISC_TRUE;
3491 if (zone->type != dns_zone_key)
3495 dns_zone_log(zone, ISC_LOG_DEBUG(2),
3496 "number of nodes in database: %u",
3497 dns_db_nodecount(db));
3499 if (result == DNS_R_SEENINCLUDE)
3500 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3502 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HASINCLUDE);
3505 * If there's no master file for a key zone, then the zone is new:
3506 * create an SOA record. (We do this now, instead of later, so that
3507 * if there happens to be a journal file, we can roll forward from
3508 * a sane starting point.)
3510 if (nomaster && zone->type == dns_zone_key) {
3511 result = add_soa(zone, db);
3512 if (result != ISC_R_SUCCESS)
3517 * Apply update log, if any, on initial load.
3519 if (zone->journal != NULL &&
3520 ! DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOMERGE) &&
3521 ! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
3523 if (zone->type == dns_zone_master &&
3524 (zone->update_acl != NULL || zone->ssutable != NULL))
3525 options = DNS_JOURNALOPT_RESIGN;
3528 result = dns_journal_rollforward2(zone->mctx, db, options,
3530 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND &&
3531 result != DNS_R_UPTODATE && result != DNS_R_NOJOURNAL &&
3532 result != ISC_R_RANGE) {
3533 dns_zone_log(zone, ISC_LOG_ERROR,
3534 "journal rollforward failed: %s",
3535 dns_result_totext(result));
3538 if (result == ISC_R_NOTFOUND || result == ISC_R_RANGE) {
3539 dns_zone_log(zone, ISC_LOG_ERROR,
3540 "journal rollforward failed: "
3541 "journal out of sync with zone");
3544 dns_zone_log(zone, ISC_LOG_DEBUG(1),
3545 "journal rollforward completed "
3547 dns_result_totext(result));
3548 if (result == ISC_R_SUCCESS)
3549 needdump = ISC_TRUE;
3552 dns_zone_log(zone, ISC_LOG_DEBUG(1), "loaded; checking validity");
3554 * Obtain ns, soa and cname counts for top of zone.
3557 result = zone_get_from_db(zone, db, &nscount, &soacount, &serial,
3558 &refresh, &retry, &expire, &minimum,
3560 if (result != ISC_R_SUCCESS && zone->type != dns_zone_key) {
3561 dns_zone_log(zone, ISC_LOG_ERROR,
3562 "could not find NS and/or SOA records");
3566 * Master / Slave / Stub zones require both NS and SOA records at
3567 * the top of the zone.
3570 switch (zone->type) {
3572 case dns_zone_master:
3573 case dns_zone_slave:
3575 if (soacount != 1) {
3576 dns_zone_log(zone, ISC_LOG_ERROR,
3577 "has %d SOA records", soacount);
3578 result = DNS_R_BADZONE;
3581 dns_zone_log(zone, ISC_LOG_ERROR,
3582 "has no NS records");
3583 result = DNS_R_BADZONE;
3585 if (result != ISC_R_SUCCESS)
3587 if (zone->type == dns_zone_master && errors != 0) {
3588 result = DNS_R_BADZONE;
3591 if (zone->type != dns_zone_stub) {
3592 result = check_nsec3param(zone, db);
3593 if (result != ISC_R_SUCCESS)
3596 if (zone->type == dns_zone_master &&
3597 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKINTEGRITY) &&
3598 !integrity_checks(zone, db)) {
3599 result = DNS_R_BADZONE;
3603 if (zone->type == dns_zone_master &&
3604 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKDUPRR) &&
3605 !zone_check_dup(zone, db)) {
3606 result = DNS_R_BADZONE;
3610 if (zone->db != NULL) {
3611 unsigned int oldsoacount;
3614 * This is checked in zone_replacedb() for slave zones
3615 * as they don't reload from disk.
3617 result = zone_get_from_db(zone, zone->db, NULL,
3618 &oldsoacount, &oldserial,
3619 NULL, NULL, NULL, NULL,
3621 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3622 RUNTIME_CHECK(soacount > 0U);
3623 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
3624 !isc_serial_gt(serial, oldserial)) {
3625 isc_uint32_t serialmin, serialmax;
3627 INSIST(zone->type == dns_zone_master);
3629 serialmin = (oldserial + 1) & 0xffffffffU;
3630 serialmax = (oldserial + 0x7fffffffU) &
3632 dns_zone_log(zone, ISC_LOG_ERROR,
3633 "ixfr-from-differences: "
3634 "new serial (%u) out of range "
3635 "[%u - %u]", serial, serialmin,
3637 result = DNS_R_BADZONE;
3639 } else if (!isc_serial_ge(serial, oldserial))
3640 dns_zone_log(zone, ISC_LOG_ERROR,
3641 "zone serial (%u/%u) has gone "
3642 "backwards", serial, oldserial);
3643 else if (serial == oldserial && !hasinclude &&
3644 strcmp(zone->db_argv[0], "_builtin") != 0)
3645 dns_zone_log(zone, ISC_LOG_ERROR,
3646 "zone serial (%u) unchanged. "
3647 "zone may fail to transfer "
3648 "to slaves.", serial);
3651 if (zone->type == dns_zone_master &&
3652 (zone->update_acl != NULL || zone->ssutable != NULL) &&
3653 zone->sigresigninginterval < (3 * refresh) &&
3654 dns_db_issecure(db))
3656 dns_zone_log(zone, ISC_LOG_WARNING,
3657 "sig-re-signing-interval less than "
3661 zone->refresh = RANGE(refresh,
3662 zone->minrefresh, zone->maxrefresh);
3663 zone->retry = RANGE(retry,
3664 zone->minretry, zone->maxretry);
3665 zone->expire = RANGE(expire, zone->refresh + zone->retry,
3667 zone->minimum = minimum;
3668 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
3670 if (zone->type == dns_zone_slave ||
3671 zone->type == dns_zone_stub) {
3675 result = isc_file_getmodtime(zone->journal, &t);
3676 if (result != ISC_R_SUCCESS)
3677 result = isc_file_getmodtime(zone->masterfile,
3679 if (result == ISC_R_SUCCESS)
3680 DNS_ZONE_TIME_ADD(&t, zone->expire,
3683 DNS_ZONE_TIME_ADD(&now, zone->retry,
3686 delay = isc_random_jitter(zone->retry,
3687 (zone->retry * 3) / 4);
3688 DNS_ZONE_TIME_ADD(&now, delay, &zone->refreshtime);
3689 if (isc_time_compare(&zone->refreshtime,
3690 &zone->expiretime) >= 0)
3691 zone->refreshtime = now;
3696 result = sync_keyzone(zone, db);
3697 if (result != ISC_R_SUCCESS)
3702 UNEXPECTED_ERROR(__FILE__, __LINE__,
3703 "unexpected zone type %d", zone->type);
3704 result = ISC_R_UNEXPECTED;
3709 * Check for weak DNSKEY's.
3711 if (zone->type == dns_zone_master)
3712 zone_check_dnskeys(zone, db);
3715 * Schedule DNSSEC key refresh.
3717 if (zone->type == dns_zone_master &&
3718 DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN))
3719 zone->refreshkeytime = now;
3722 /* destroy notification example. */
3724 isc_event_t *e = isc_event_allocate(zone->mctx, NULL,
3725 DNS_EVENT_DBDESTROYED,
3726 dns_zonemgr_dbdestroyed,
3728 sizeof(isc_event_t));
3729 dns_db_ondestroy(db, zone->task, &e);
3733 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
3734 if (zone->db != NULL) {
3735 result = zone_replacedb(zone, db, ISC_FALSE);
3736 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3737 if (result != ISC_R_SUCCESS)
3740 zone_attachdb(zone, db);
3741 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
3742 DNS_ZONE_SETFLAG(zone,
3743 DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
3746 result = ISC_R_SUCCESS;
3749 if (zone->type == dns_zone_key)
3750 zone_needdump(zone, 30);
3752 zone_needdump(zone, DNS_DUMP_DELAY);
3755 if (zone->task != NULL) {
3756 if (zone->type == dns_zone_master) {
3757 set_resigntime(zone);
3758 resume_signingwithkey(zone);
3759 resume_addnsec3chain(zone);
3762 if (zone->type == dns_zone_master &&
3763 zone_isdynamic(zone) &&
3764 dns_db_issecure(db)) {
3766 dns_fixedname_t fixed;
3767 dns_rdataset_t next;
3769 dns_rdataset_init(&next);
3770 dns_fixedname_init(&fixed);
3771 name = dns_fixedname_name(&fixed);
3773 result = dns_db_getsigningtime(db, &next, name);
3774 if (result == ISC_R_SUCCESS) {
3775 isc_stdtime_t timenow;
3776 char namebuf[DNS_NAME_FORMATSIZE];
3777 char typebuf[DNS_RDATATYPE_FORMATSIZE];
3779 isc_stdtime_get(&timenow);
3780 dns_name_format(name, namebuf, sizeof(namebuf));
3781 dns_rdatatype_format(next.covers,
3782 typebuf, sizeof(typebuf));
3783 dns_zone_log(zone, ISC_LOG_DEBUG(3),
3784 "next resign: %s/%s in %d seconds",
3786 next.resign - timenow -
3787 zone->sigresigninginterval);
3788 dns_rdataset_disassociate(&next);
3790 dns_zone_log(zone, ISC_LOG_WARNING,
3791 "signed dynamic zone has no "
3792 "resign event scheduled");
3795 zone_settimer(zone, &now);
3798 if (! dns_db_ispersistent(db))
3799 dns_zone_log(zone, ISC_LOG_INFO, "loaded serial %u%s", serial,
3800 dns_db_issecure(db) ? " (DNSSEC signed)" : "");
3802 zone->loadtime = loadtime;
3806 if (zone->type == dns_zone_slave ||
3807 zone->type == dns_zone_stub ||
3808 zone->type == dns_zone_key) {
3809 if (zone->journal != NULL)
3810 zone_saveunique(zone, zone->journal, "jn-XXXXXXXX");
3811 if (zone->masterfile != NULL)
3812 zone_saveunique(zone, zone->masterfile, "db-XXXXXXXX");
3814 /* Mark the zone for immediate refresh. */
3815 zone->refreshtime = now;
3816 if (zone->task != NULL)
3817 zone_settimer(zone, &now);
3818 result = ISC_R_SUCCESS;
3819 } else if (zone->type == dns_zone_master)
3820 dns_zone_log(zone, ISC_LOG_ERROR, "not loaded due to errors.");
3824 static isc_boolean_t
3825 exit_check(dns_zone_t *zone) {
3827 REQUIRE(LOCKED_ZONE(zone));
3829 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
3833 * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
3835 INSIST(isc_refcount_current(&zone->erefs) == 0);
3841 static isc_boolean_t
3842 zone_check_ns(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
3843 dns_name_t *name, isc_boolean_t logit)
3845 isc_result_t result;
3846 char namebuf[DNS_NAME_FORMATSIZE];
3847 char altbuf[DNS_NAME_FORMATSIZE];
3848 dns_fixedname_t fixed;
3849 dns_name_t *foundname;
3852 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOCHECKNS))
3855 if (zone->type == dns_zone_master)
3856 level = ISC_LOG_ERROR;
3858 level = ISC_LOG_WARNING;
3860 dns_fixedname_init(&fixed);
3861 foundname = dns_fixedname_name(&fixed);
3863 result = dns_db_find(db, name, version, dns_rdatatype_a,
3864 0, 0, NULL, foundname, NULL, NULL);
3865 if (result == ISC_R_SUCCESS)
3868 if (result == DNS_R_NXRRSET) {
3869 result = dns_db_find(db, name, version, dns_rdatatype_aaaa,
3870 0, 0, NULL, foundname, NULL, NULL);
3871 if (result == ISC_R_SUCCESS)
3875 if (result == DNS_R_NXRRSET || result == DNS_R_NXDOMAIN ||
3876 result == DNS_R_EMPTYNAME) {
3878 dns_name_format(name, namebuf, sizeof namebuf);
3879 dns_zone_log(zone, level, "NS '%s' has no address "
3880 "records (A or AAAA)", namebuf);
3885 if (result == DNS_R_CNAME) {
3887 dns_name_format(name, namebuf, sizeof namebuf);
3888 dns_zone_log(zone, level, "NS '%s' is a CNAME "
3889 "(illegal)", namebuf);
3894 if (result == DNS_R_DNAME) {
3896 dns_name_format(name, namebuf, sizeof namebuf);
3897 dns_name_format(foundname, altbuf, sizeof altbuf);
3898 dns_zone_log(zone, level, "NS '%s' is below a DNAME "
3899 "'%s' (illegal)", namebuf, altbuf);
3908 zone_count_ns_rr(dns_zone_t *zone, dns_db_t *db, dns_dbnode_t *node,
3909 dns_dbversion_t *version, unsigned int *nscount,
3910 unsigned int *errors, isc_boolean_t logit)
3912 isc_result_t result;
3913 unsigned int count = 0;
3914 unsigned int ecount = 0;
3915 dns_rdataset_t rdataset;
3919 dns_rdataset_init(&rdataset);
3920 result = dns_db_findrdataset(db, node, version, dns_rdatatype_ns,
3921 dns_rdatatype_none, 0, &rdataset, NULL);
3922 if (result == ISC_R_NOTFOUND) {
3923 INSIST(!dns_rdataset_isassociated(&rdataset));
3926 if (result != ISC_R_SUCCESS) {
3927 INSIST(!dns_rdataset_isassociated(&rdataset));
3928 goto invalidate_rdataset;
3931 result = dns_rdataset_first(&rdataset);
3932 while (result == ISC_R_SUCCESS) {
3933 if (errors != NULL && zone->rdclass == dns_rdataclass_in &&
3934 (zone->type == dns_zone_master ||
3935 zone->type == dns_zone_slave)) {
3936 dns_rdata_init(&rdata);
3937 dns_rdataset_current(&rdataset, &rdata);
3938 result = dns_rdata_tostruct(&rdata, &ns, NULL);
3939 RUNTIME_CHECK(result == ISC_R_SUCCESS);
3940 if (dns_name_issubdomain(&ns.name, &zone->origin) &&
3941 !zone_check_ns(zone, db, version, &ns.name, logit))
3945 result = dns_rdataset_next(&rdataset);
3947 dns_rdataset_disassociate(&rdataset);
3950 if (nscount != NULL)
3955 result = ISC_R_SUCCESS;
3957 invalidate_rdataset:
3958 dns_rdataset_invalidate(&rdataset);
3964 zone_load_soa_rr(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
3965 unsigned int *soacount,
3966 isc_uint32_t *serial, isc_uint32_t *refresh,
3967 isc_uint32_t *retry, isc_uint32_t *expire,
3968 isc_uint32_t *minimum)
3970 isc_result_t result;
3972 dns_rdataset_t rdataset;
3973 dns_rdata_t rdata = DNS_RDATA_INIT;
3974 dns_rdata_soa_t soa;
3976 dns_rdataset_init(&rdataset);
3977 result = dns_db_findrdataset(db, node, version, dns_rdatatype_soa,
3978 dns_rdatatype_none, 0, &rdataset, NULL);
3979 if (result == ISC_R_NOTFOUND) {
3980 INSIST(!dns_rdataset_isassociated(&rdataset));
3981 if (soacount != NULL)
3985 if (refresh != NULL)
3991 if (minimum != NULL)
3993 result = ISC_R_SUCCESS;
3994 goto invalidate_rdataset;
3996 if (result != ISC_R_SUCCESS) {
3997 INSIST(!dns_rdataset_isassociated(&rdataset));
3998 goto invalidate_rdataset;
4002 result = dns_rdataset_first(&rdataset);
4003 while (result == ISC_R_SUCCESS) {
4004 dns_rdata_init(&rdata);
4005 dns_rdataset_current(&rdataset, &rdata);
4008 result = dns_rdata_tostruct(&rdata, &soa, NULL);
4009 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4012 result = dns_rdataset_next(&rdataset);
4013 dns_rdata_reset(&rdata);
4015 dns_rdataset_disassociate(&rdataset);
4017 if (soacount != NULL)
4022 *serial = soa.serial;
4023 if (refresh != NULL)
4024 *refresh = soa.refresh;
4028 *expire = soa.expire;
4029 if (minimum != NULL)
4030 *minimum = soa.minimum;
4032 if (soacount != NULL)
4036 if (refresh != NULL)
4042 if (minimum != NULL)
4046 result = ISC_R_SUCCESS;
4048 invalidate_rdataset:
4049 dns_rdataset_invalidate(&rdataset);
4055 * zone must be locked.
4058 zone_get_from_db(dns_zone_t *zone, dns_db_t *db, unsigned int *nscount,
4059 unsigned int *soacount, isc_uint32_t *serial,
4060 isc_uint32_t *refresh, isc_uint32_t *retry,
4061 isc_uint32_t *expire, isc_uint32_t *minimum,
4062 unsigned int *errors)
4064 isc_result_t result;
4065 isc_result_t answer = ISC_R_SUCCESS;
4066 dns_dbversion_t *version = NULL;
4069 REQUIRE(db != NULL);
4070 REQUIRE(zone != NULL);
4072 dns_db_currentversion(db, &version);
4075 result = dns_db_findnode(db, &zone->origin, ISC_FALSE, &node);
4076 if (result != ISC_R_SUCCESS) {
4081 if (nscount != NULL || errors != NULL) {
4082 result = zone_count_ns_rr(zone, db, node, version,
4083 nscount, errors, ISC_TRUE);
4084 if (result != ISC_R_SUCCESS)
4088 if (soacount != NULL || serial != NULL || refresh != NULL
4089 || retry != NULL || expire != NULL || minimum != NULL) {
4090 result = zone_load_soa_rr(db, node, version, soacount,
4091 serial, refresh, retry, expire,
4093 if (result != ISC_R_SUCCESS)
4097 dns_db_detachnode(db, &node);
4099 dns_db_closeversion(db, &version, ISC_FALSE);
4105 dns_zone_attach(dns_zone_t *source, dns_zone_t **target) {
4106 REQUIRE(DNS_ZONE_VALID(source));
4107 REQUIRE(target != NULL && *target == NULL);
4108 isc_refcount_increment(&source->erefs, NULL);
4113 dns_zone_detach(dns_zone_t **zonep) {
4116 isc_boolean_t free_now = ISC_FALSE;
4118 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4122 isc_refcount_decrement(&zone->erefs, &refs);
4127 * We just detached the last external reference.
4129 if (zone->task != NULL) {
4131 * This zone is being managed. Post
4132 * its control event and let it clean
4133 * up synchronously in the context of
4136 isc_event_t *ev = &zone->ctlevent;
4137 isc_task_send(zone->task, &ev);
4140 * This zone is not being managed; it has
4141 * no task and can have no outstanding
4142 * events. Free it immediately.
4145 * Unmanaged zones should not have non-null views;
4146 * we have no way of detaching from the view here
4147 * without causing deadlock because this code is called
4148 * with the view already locked.
4150 INSIST(zone->view == NULL);
4151 free_now = ISC_TRUE;
4161 dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4162 REQUIRE(DNS_ZONE_VALID(source));
4163 REQUIRE(target != NULL && *target == NULL);
4165 zone_iattach(source, target);
4166 UNLOCK_ZONE(source);
4170 dns_zone_synckeyzone(dns_zone_t *zone) {
4171 isc_result_t result;
4172 dns_db_t *db = NULL;
4174 if (zone->type != dns_zone_key)
4175 return (DNS_R_BADZONE);
4177 CHECK(dns_zone_getdb(zone, &db));
4180 result = sync_keyzone(zone, db);
4190 zone_iattach(dns_zone_t *source, dns_zone_t **target) {
4193 * 'source' locked by caller.
4195 REQUIRE(LOCKED_ZONE(source));
4196 REQUIRE(DNS_ZONE_VALID(source));
4197 REQUIRE(target != NULL && *target == NULL);
4198 INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0);
4200 INSIST(source->irefs != 0);
4205 zone_idetach(dns_zone_t **zonep) {
4209 * 'zone' locked by caller.
4211 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4213 REQUIRE(LOCKED_ZONE(*zonep));
4216 INSIST(zone->irefs > 0);
4218 INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
4222 dns_zone_idetach(dns_zone_t **zonep) {
4224 isc_boolean_t free_needed;
4226 REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep));
4231 INSIST(zone->irefs > 0);
4233 free_needed = exit_check(zone);
4240 dns_zone_getmctx(dns_zone_t *zone) {
4241 REQUIRE(DNS_ZONE_VALID(zone));
4243 return (zone->mctx);
4247 dns_zone_getmgr(dns_zone_t *zone) {
4248 REQUIRE(DNS_ZONE_VALID(zone));
4250 return (zone->zmgr);
4254 dns_zone_setflag(dns_zone_t *zone, unsigned int flags, isc_boolean_t value) {
4255 REQUIRE(DNS_ZONE_VALID(zone));
4259 DNS_ZONE_SETFLAG(zone, flags);
4261 DNS_ZONE_CLRFLAG(zone, flags);
4266 dns_zone_setoption(dns_zone_t *zone, unsigned int option, isc_boolean_t value)
4268 REQUIRE(DNS_ZONE_VALID(zone));
4272 zone->options |= option;
4274 zone->options &= ~option;
4279 dns_zone_getoptions(dns_zone_t *zone) {
4281 REQUIRE(DNS_ZONE_VALID(zone));
4283 return (zone->options);
4287 dns_zone_setkeyopt(dns_zone_t *zone, unsigned int keyopt, isc_boolean_t value)
4289 REQUIRE(DNS_ZONE_VALID(zone));
4293 zone->keyopts |= keyopt;
4295 zone->keyopts &= ~keyopt;
4300 dns_zone_getkeyopts(dns_zone_t *zone) {
4302 REQUIRE(DNS_ZONE_VALID(zone));
4304 return (zone->keyopts);
4308 dns_zone_setxfrsource4(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4309 REQUIRE(DNS_ZONE_VALID(zone));
4312 zone->xfrsource4 = *xfrsource;
4315 return (ISC_R_SUCCESS);
4319 dns_zone_getxfrsource4(dns_zone_t *zone) {
4320 REQUIRE(DNS_ZONE_VALID(zone));
4321 return (&zone->xfrsource4);
4325 dns_zone_setxfrsource6(dns_zone_t *zone, const isc_sockaddr_t *xfrsource) {
4326 REQUIRE(DNS_ZONE_VALID(zone));
4329 zone->xfrsource6 = *xfrsource;
4332 return (ISC_R_SUCCESS);
4336 dns_zone_getxfrsource6(dns_zone_t *zone) {
4337 REQUIRE(DNS_ZONE_VALID(zone));
4338 return (&zone->xfrsource6);
4342 dns_zone_setaltxfrsource4(dns_zone_t *zone,
4343 const isc_sockaddr_t *altxfrsource)
4345 REQUIRE(DNS_ZONE_VALID(zone));
4348 zone->altxfrsource4 = *altxfrsource;
4351 return (ISC_R_SUCCESS);
4355 dns_zone_getaltxfrsource4(dns_zone_t *zone) {
4356 REQUIRE(DNS_ZONE_VALID(zone));
4357 return (&zone->altxfrsource4);
4361 dns_zone_setaltxfrsource6(dns_zone_t *zone,
4362 const isc_sockaddr_t *altxfrsource)
4364 REQUIRE(DNS_ZONE_VALID(zone));
4367 zone->altxfrsource6 = *altxfrsource;
4370 return (ISC_R_SUCCESS);
4374 dns_zone_getaltxfrsource6(dns_zone_t *zone) {
4375 REQUIRE(DNS_ZONE_VALID(zone));
4376 return (&zone->altxfrsource6);
4380 dns_zone_setnotifysrc4(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4381 REQUIRE(DNS_ZONE_VALID(zone));
4384 zone->notifysrc4 = *notifysrc;
4387 return (ISC_R_SUCCESS);
4391 dns_zone_getnotifysrc4(dns_zone_t *zone) {
4392 REQUIRE(DNS_ZONE_VALID(zone));
4393 return (&zone->notifysrc4);
4397 dns_zone_setnotifysrc6(dns_zone_t *zone, const isc_sockaddr_t *notifysrc) {
4398 REQUIRE(DNS_ZONE_VALID(zone));
4401 zone->notifysrc6 = *notifysrc;
4404 return (ISC_R_SUCCESS);
4408 dns_zone_getnotifysrc6(dns_zone_t *zone) {
4409 REQUIRE(DNS_ZONE_VALID(zone));
4410 return (&zone->notifysrc6);
4414 dns_zone_setalsonotify(dns_zone_t *zone, const isc_sockaddr_t *notify,
4417 isc_sockaddr_t *new;
4419 REQUIRE(DNS_ZONE_VALID(zone));
4420 REQUIRE(count == 0 || notify != NULL);
4423 if (zone->notify != NULL) {
4424 isc_mem_put(zone->mctx, zone->notify,
4425 zone->notifycnt * sizeof(*new));
4426 zone->notify = NULL;
4427 zone->notifycnt = 0;
4430 new = isc_mem_get(zone->mctx, count * sizeof(*new));
4433 return (ISC_R_NOMEMORY);
4435 memmove(new, notify, count * sizeof(*new));
4437 zone->notifycnt = count;
4440 return (ISC_R_SUCCESS);
4444 dns_zone_setmasters(dns_zone_t *zone, const isc_sockaddr_t *masters,
4447 isc_result_t result;
4449 result = dns_zone_setmasterswithkeys(zone, masters, NULL, count);
4453 static isc_boolean_t
4454 same_masters(const isc_sockaddr_t *old, const isc_sockaddr_t *new,
4459 for (i = 0; i < count; i++)
4460 if (!isc_sockaddr_equal(&old[i], &new[i]))
4465 static isc_boolean_t
4466 same_keynames(dns_name_t **old, dns_name_t **new, isc_uint32_t count) {
4469 if (old == NULL && new == NULL)
4471 if (old == NULL || new == NULL)
4474 for (i = 0; i < count; i++) {
4475 if (old[i] == NULL && new[i] == NULL)
4477 if (old[i] == NULL || new[i] == NULL ||
4478 !dns_name_equal(old[i], new[i]))
4485 dns_zone_setmasterswithkeys(dns_zone_t *zone,
4486 const isc_sockaddr_t *masters,
4487 dns_name_t **keynames,
4490 isc_sockaddr_t *new;
4491 isc_result_t result = ISC_R_SUCCESS;
4492 dns_name_t **newname;
4493 isc_boolean_t *newok;
4496 REQUIRE(DNS_ZONE_VALID(zone));
4497 REQUIRE(count == 0 || masters != NULL);
4498 if (keynames != NULL) {
4499 REQUIRE(count != 0);
4504 * The refresh code assumes that 'masters' wouldn't change under it.
4505 * If it will change then kill off any current refresh in progress
4506 * and update the masters info. If it won't change then we can just
4509 if (count != zone->masterscnt ||
4510 !same_masters(zone->masters, masters, count) ||
4511 !same_keynames(zone->masterkeynames, keynames, count)) {
4512 if (zone->request != NULL)
4513 dns_request_cancel(zone->request);
4516 if (zone->masters != NULL) {
4517 isc_mem_put(zone->mctx, zone->masters,
4518 zone->masterscnt * sizeof(*new));
4519 zone->masters = NULL;
4521 if (zone->masterkeynames != NULL) {
4522 for (i = 0; i < zone->masterscnt; i++) {
4523 if (zone->masterkeynames[i] != NULL) {
4524 dns_name_free(zone->masterkeynames[i],
4526 isc_mem_put(zone->mctx,
4527 zone->masterkeynames[i],
4528 sizeof(dns_name_t));
4529 zone->masterkeynames[i] = NULL;
4532 isc_mem_put(zone->mctx, zone->masterkeynames,
4533 zone->masterscnt * sizeof(dns_name_t *));
4534 zone->masterkeynames = NULL;
4536 if (zone->mastersok != NULL) {
4537 isc_mem_put(zone->mctx, zone->mastersok,
4538 zone->masterscnt * sizeof(isc_boolean_t));
4539 zone->mastersok = NULL;
4541 zone->masterscnt = 0;
4543 * If count == 0, don't allocate any space for masters, mastersok or
4544 * keynames so internally, those pointers are NULL if count == 0
4550 * masters must contain count elements!
4552 new = isc_mem_get(zone->mctx, count * sizeof(*new));
4554 result = ISC_R_NOMEMORY;
4557 memmove(new, masters, count * sizeof(*new));
4560 * Similarly for mastersok.
4562 newok = isc_mem_get(zone->mctx, count * sizeof(*newok));
4563 if (newok == NULL) {
4564 result = ISC_R_NOMEMORY;
4565 isc_mem_put(zone->mctx, new, count * sizeof(*new));
4568 for (i = 0; i < count; i++)
4569 newok[i] = ISC_FALSE;
4572 * if keynames is non-NULL, it must contain count elements!
4575 if (keynames != NULL) {
4576 newname = isc_mem_get(zone->mctx, count * sizeof(*newname));
4577 if (newname == NULL) {
4578 result = ISC_R_NOMEMORY;
4579 isc_mem_put(zone->mctx, new, count * sizeof(*new));
4580 isc_mem_put(zone->mctx, newok, count * sizeof(*newok));
4583 for (i = 0; i < count; i++)
4585 for (i = 0; i < count; i++) {
4586 if (keynames[i] != NULL) {
4587 newname[i] = isc_mem_get(zone->mctx,
4588 sizeof(dns_name_t));
4589 if (newname[i] == NULL)
4591 dns_name_init(newname[i], NULL);
4592 result = dns_name_dup(keynames[i], zone->mctx,
4594 if (result != ISC_R_SUCCESS) {
4596 for (i = 0; i < count; i++)
4597 if (newname[i] != NULL)
4601 isc_mem_put(zone->mctx, new,
4602 count * sizeof(*new));
4603 isc_mem_put(zone->mctx, newok,
4604 count * sizeof(*newok));
4605 isc_mem_put(zone->mctx, newname,
4606 count * sizeof(*newname));
4614 * Everything is ok so attach to the zone.
4616 zone->curmaster = 0;
4617 zone->masters = new;
4618 zone->mastersok = newok;
4619 zone->masterkeynames = newname;
4620 zone->masterscnt = count;
4621 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOMASTERS);
4629 dns_zone_getdb(dns_zone_t *zone, dns_db_t **dpb) {
4630 isc_result_t result = ISC_R_SUCCESS;
4632 REQUIRE(DNS_ZONE_VALID(zone));
4634 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
4635 if (zone->db == NULL)
4636 result = DNS_R_NOTLOADED;
4638 dns_db_attach(zone->db, dpb);
4639 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
4645 dns_zone_setdb(dns_zone_t *zone, dns_db_t *db) {
4646 REQUIRE(DNS_ZONE_VALID(zone));
4647 REQUIRE(zone->type == dns_zone_staticstub);
4649 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
4650 REQUIRE(zone->db == NULL);
4651 dns_db_attach(db, &zone->db);
4652 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
4656 * Co-ordinates the starting of routine jobs.
4660 dns_zone_maintenance(dns_zone_t *zone) {
4661 const char me[] = "dns_zone_maintenance";
4664 REQUIRE(DNS_ZONE_VALID(zone));
4669 zone_settimer(zone, &now);
4673 static inline isc_boolean_t
4674 was_dumping(dns_zone_t *zone) {
4675 isc_boolean_t dumping;
4677 REQUIRE(LOCKED_ZONE(zone));
4679 dumping = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING);
4680 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
4682 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
4683 isc_time_settoepoch(&zone->dumptime);
4689 find_zone_keys(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
4690 isc_mem_t *mctx, unsigned int maxkeys,
4691 dst_key_t **keys, unsigned int *nkeys)
4693 isc_result_t result;
4694 dns_dbnode_t *node = NULL;
4695 const char *directory = dns_zone_getkeydirectory(zone);
4697 CHECK(dns_db_findnode(db, dns_db_origin(db), ISC_FALSE, &node));
4698 result = dns_dnssec_findzonekeys2(db, ver, node, dns_db_origin(db),
4699 directory, mctx, maxkeys, keys,
4701 if (result == ISC_R_NOTFOUND)
4702 result = ISC_R_SUCCESS;
4705 dns_db_detachnode(db, &node);
4710 offline(dns_db_t *db, dns_dbversion_t *ver, zonediff_t *zonediff,
4711 dns_name_t *name, dns_ttl_t ttl, dns_rdata_t *rdata)
4713 isc_result_t result;
4715 if ((rdata->flags & DNS_RDATA_OFFLINE) != 0)
4716 return (ISC_R_SUCCESS);
4717 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_DELRESIGN,
4719 if (result != ISC_R_SUCCESS)
4721 rdata->flags |= DNS_RDATA_OFFLINE;
4722 result = update_one_rr(db, ver, zonediff->diff, DNS_DIFFOP_ADDRESIGN,
4724 zonediff->offline = ISC_TRUE;
4729 set_key_expiry_warning(dns_zone_t *zone, isc_stdtime_t when, isc_stdtime_t now)
4734 zone->key_expiry = when;
4736 dns_zone_log(zone, ISC_LOG_ERROR,
4737 "DNSKEY RRSIG(s) have expired");
4738 isc_time_settoepoch(&zone->keywarntime);
4739 } else if (when < now + 7 * 24 * 3600) {
4741 isc_time_set(&t, when, 0);
4742 isc_time_formattimestamp(&t, timebuf, 80);
4743 dns_zone_log(zone, ISC_LOG_WARNING,
4744 "DNSKEY RRSIG(s) will expire within 7 days: %s",
4747 delta--; /* loop prevention */
4748 delta /= 24 * 3600; /* to whole days */
4749 delta *= 24 * 3600; /* to seconds */
4750 isc_time_set(&zone->keywarntime, when - delta, 0);
4752 isc_time_set(&zone->keywarntime, when - 7 * 24 * 3600, 0);
4753 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
4754 dns_zone_log(zone, ISC_LOG_NOTICE,
4755 "setting keywarntime to %s", timebuf);
4760 * Helper function to del_sigs(). We don't want to delete RRSIGs that
4763 static isc_boolean_t
4764 delsig_ok(dns_rdata_rrsig_t *rrsig_ptr, dst_key_t **keys, unsigned int nkeys,
4765 isc_boolean_t *warn)
4768 isc_boolean_t have_ksk = ISC_FALSE, have_zsk = ISC_FALSE;
4769 isc_boolean_t have_pksk = ISC_FALSE, have_pzsk = ISC_FALSE;
4771 for (i = 0; i < nkeys; i++) {
4772 if (rrsig_ptr->algorithm != dst_key_alg(keys[i]))
4774 if (dst_key_isprivate(keys[i])) {
4776 have_ksk = have_pksk = ISC_TRUE;
4778 have_zsk = have_pzsk = ISC_TRUE;
4781 have_ksk = ISC_TRUE;
4783 have_zsk = ISC_TRUE;
4787 if (have_zsk && have_ksk && !have_pzsk)
4791 * It's okay to delete a signature if there is an active key
4792 * with the same algorithm to replace it.
4794 if (have_pksk || have_pzsk)
4798 * Failing that, it is *not* okay to delete a signature
4799 * if the associated public key is still in the DNSKEY RRset
4801 for (i = 0; i < nkeys; i++) {
4802 if ((rrsig_ptr->algorithm == dst_key_alg(keys[i])) &&
4803 (rrsig_ptr->keyid == dst_key_id(keys[i])))
4808 * But if the key is gone, then go ahead.
4814 * Delete expired RRsigs and any RRsigs we are about to re-sign.
4815 * See also update.c:del_keysigs().
4818 del_sigs(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
4819 dns_rdatatype_t type, zonediff_t *zonediff, dst_key_t **keys,
4820 unsigned int nkeys, isc_stdtime_t now, isc_boolean_t incremental)
4822 isc_result_t result;
4823 dns_dbnode_t *node = NULL;
4824 dns_rdataset_t rdataset;
4826 dns_rdata_rrsig_t rrsig;
4827 isc_boolean_t found, changed;
4828 isc_int64_t warn = 0, maybe = 0;
4830 dns_rdataset_init(&rdataset);
4832 if (type == dns_rdatatype_nsec3)
4833 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
4835 result = dns_db_findnode(db, name, ISC_FALSE, &node);
4836 if (result == ISC_R_NOTFOUND)
4837 return (ISC_R_SUCCESS);
4838 if (result != ISC_R_SUCCESS)
4840 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_rrsig, type,
4841 (isc_stdtime_t) 0, &rdataset, NULL);
4842 dns_db_detachnode(db, &node);
4844 if (result == ISC_R_NOTFOUND) {
4845 INSIST(!dns_rdataset_isassociated(&rdataset));
4846 return (ISC_R_SUCCESS);
4848 if (result != ISC_R_SUCCESS) {
4849 INSIST(!dns_rdataset_isassociated(&rdataset));
4853 changed = ISC_FALSE;
4854 for (result = dns_rdataset_first(&rdataset);
4855 result == ISC_R_SUCCESS;
4856 result = dns_rdataset_next(&rdataset)) {
4857 dns_rdata_t rdata = DNS_RDATA_INIT;
4859 dns_rdataset_current(&rdataset, &rdata);
4860 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
4861 RUNTIME_CHECK(result == ISC_R_SUCCESS);
4863 if (type != dns_rdatatype_dnskey) {
4864 isc_boolean_t warn = ISC_FALSE, deleted = ISC_FALSE;
4865 if (delsig_ok(&rrsig, keys, nkeys, &warn)) {
4866 result = update_one_rr(db, ver, zonediff->diff,
4867 DNS_DIFFOP_DELRESIGN, name,
4868 rdataset.ttl, &rdata);
4871 if (result != ISC_R_SUCCESS)
4877 * At this point, we've got an RRSIG,
4878 * which is signed by an inactive key.
4879 * An administrator needs to provide a new
4880 * key/alg, but until that time, we want to
4881 * keep the old RRSIG. Marking the key as
4882 * offline will prevent us spinning waiting
4883 * for the private part.
4885 if (incremental && !deleted) {
4886 result = offline(db, ver, zonediff,
4890 if (result != ISC_R_SUCCESS)
4895 * Log the key id and algorithm of
4896 * the inactive key with no replacement
4898 if (zone->log_key_expired_timer <= now) {
4899 char origin[DNS_NAME_FORMATSIZE];
4900 char algbuf[DNS_NAME_FORMATSIZE];
4901 dns_name_format(&zone->origin, origin,
4903 dns_secalg_format(rrsig.algorithm,
4906 dns_zone_log(zone, ISC_LOG_WARNING,
4908 "missing or inactive "
4909 "and has no replacement: "
4910 "retaining signatures.",
4913 zone->log_key_expired_timer = now +
4921 * RRSIG(DNSKEY) requires special processing.
4924 for (i = 0; i < nkeys; i++) {
4925 if (rrsig.algorithm == dst_key_alg(keys[i]) &&
4926 rrsig.keyid == dst_key_id(keys[i])) {
4929 * Mark offline RRSIG(DNSKEY).
4930 * We want the earliest offline expire time
4931 * iff there is a new offline signature.
4933 if (!dst_key_inactive(keys[i]) &&
4934 !dst_key_isprivate(keys[i]))
4936 isc_int64_t timeexpire =
4937 dns_time64_from32(rrsig.timeexpire);
4938 if (warn != 0 && warn > timeexpire)
4940 if (rdata.flags & DNS_RDATA_OFFLINE) {
4948 if (warn == 0 || warn > timeexpire)
4950 result = offline(db, ver, zonediff,
4956 result = update_one_rr(db, ver, zonediff->diff,
4957 DNS_DIFFOP_DELRESIGN,
4965 * If there is not a matching DNSKEY then
4969 result = update_one_rr(db, ver, zonediff->diff,
4970 DNS_DIFFOP_DELRESIGN, name,
4971 rdataset.ttl, &rdata);
4972 if (result != ISC_R_SUCCESS)
4976 if (changed && (rdataset.attributes & DNS_RDATASETATTR_RESIGN) != 0)
4977 dns_db_resigned(db, &rdataset, ver);
4979 dns_rdataset_disassociate(&rdataset);
4980 if (result == ISC_R_NOMORE)
4981 result = ISC_R_SUCCESS;
4983 #if defined(STDTIME_ON_32BITS)
4984 isc_stdtime_t stdwarn = (isc_stdtime_t)warn;
4985 if (warn == stdwarn)
4987 set_key_expiry_warning(zone, (isc_stdtime_t)warn, now);
4988 #if defined(STDTIME_ON_32BITS)
4990 dns_zone_log(zone, ISC_LOG_ERROR,
4991 "key expiry warning time out of range");
4996 dns_db_detachnode(db, &node);
5001 add_sigs(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
5002 dns_rdatatype_t type, dns_diff_t *diff, dst_key_t **keys,
5003 unsigned int nkeys, isc_mem_t *mctx, isc_stdtime_t inception,
5004 isc_stdtime_t expire, isc_boolean_t check_ksk,
5005 isc_boolean_t keyset_kskonly)
5007 isc_result_t result;
5008 dns_dbnode_t *node = NULL;
5009 dns_rdataset_t rdataset;
5010 dns_rdata_t sig_rdata = DNS_RDATA_INIT;
5011 unsigned char data[1024]; /* XXX */
5012 isc_buffer_t buffer;
5015 dns_rdataset_init(&rdataset);
5016 isc_buffer_init(&buffer, data, sizeof(data));
5018 if (type == dns_rdatatype_nsec3)
5019 result = dns_db_findnsec3node(db, name, ISC_FALSE, &node);
5021 result = dns_db_findnode(db, name, ISC_FALSE, &node);
5022 if (result == ISC_R_NOTFOUND)
5023 return (ISC_R_SUCCESS);
5024 if (result != ISC_R_SUCCESS)
5026 result = dns_db_findrdataset(db, node, ver, type, 0,
5027 (isc_stdtime_t) 0, &rdataset, NULL);
5028 dns_db_detachnode(db, &node);
5029 if (result == ISC_R_NOTFOUND) {
5030 INSIST(!dns_rdataset_isassociated(&rdataset));
5031 return (ISC_R_SUCCESS);
5033 if (result != ISC_R_SUCCESS) {
5034 INSIST(!dns_rdataset_isassociated(&rdataset));
5038 for (i = 0; i < nkeys; i++) {
5039 isc_boolean_t both = ISC_FALSE;
5041 if (!dst_key_isprivate(keys[i]))
5044 if (check_ksk && !REVOKE(keys[i])) {
5045 isc_boolean_t have_ksk, have_nonksk;
5047 have_ksk = ISC_TRUE;
5048 have_nonksk = ISC_FALSE;
5050 have_ksk = ISC_FALSE;
5051 have_nonksk = ISC_TRUE;
5053 for (j = 0; j < nkeys; j++) {
5054 if (j == i || ALG(keys[i]) != ALG(keys[j]))
5056 if (REVOKE(keys[j]))
5059 have_ksk = ISC_TRUE;
5061 have_nonksk = ISC_TRUE;
5062 both = have_ksk && have_nonksk;
5068 if (type == dns_rdatatype_dnskey) {
5069 if (!KSK(keys[i]) && keyset_kskonly)
5071 } else if (KSK(keys[i]))
5073 } else if (REVOKE(keys[i]) && type != dns_rdatatype_dnskey)
5076 /* Calculate the signature, creating a RRSIG RDATA. */
5077 isc_buffer_clear(&buffer);
5078 CHECK(dns_dnssec_sign(name, &rdataset, keys[i],
5079 &inception, &expire,
5080 mctx, &buffer, &sig_rdata));
5081 /* Update the database and journal with the RRSIG. */
5082 /* XXX inefficient - will cause dataset merging */
5083 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADDRESIGN,
5084 name, rdataset.ttl, &sig_rdata));
5085 dns_rdata_reset(&sig_rdata);
5086 isc_buffer_init(&buffer, data, sizeof(data));
5090 if (dns_rdataset_isassociated(&rdataset))
5091 dns_rdataset_disassociate(&rdataset);
5093 dns_db_detachnode(db, &node);
5098 zone_resigninc(dns_zone_t *zone) {
5099 const char *me = "zone_resigninc";
5100 dns_db_t *db = NULL;
5101 dns_dbversion_t *version = NULL;
5102 dns_diff_t _sig_diff;
5103 zonediff_t zonediff;
5104 dns_fixedname_t fixed;
5106 dns_rdataset_t rdataset;
5107 dns_rdatatype_t covers;
5108 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
5109 isc_boolean_t check_ksk, keyset_kskonly = ISC_FALSE;
5110 isc_result_t result;
5111 isc_stdtime_t now, inception, soaexpire, expire, stop;
5112 isc_uint32_t jitter;
5114 unsigned int nkeys = 0;
5115 unsigned int resign;
5119 dns_rdataset_init(&rdataset);
5120 dns_fixedname_init(&fixed);
5121 dns_diff_init(zone->mctx, &_sig_diff);
5122 zonediff_init(&zonediff, &_sig_diff);
5125 * Updates are disabled. Pause for 5 minutes.
5127 if (zone->update_disabled) {
5128 result = ISC_R_FAILURE;
5132 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
5133 dns_db_attach(zone->db, &db);
5134 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
5136 result = dns_db_newversion(db, &version);
5137 if (result != ISC_R_SUCCESS) {
5138 dns_zone_log(zone, ISC_LOG_ERROR,
5139 "zone_resigninc:dns_db_newversion -> %s",
5140 dns_result_totext(result));
5144 result = find_zone_keys(zone, db, version, zone->mctx, DNS_MAXZONEKEYS,
5146 if (result != ISC_R_SUCCESS) {
5147 dns_zone_log(zone, ISC_LOG_ERROR,
5148 "zone_resigninc:find_zone_keys -> %s",
5149 dns_result_totext(result));
5153 isc_stdtime_get(&now);
5154 inception = now - 3600; /* Allow for clock skew. */
5155 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
5157 * Spread out signatures over time if they happen to be
5158 * clumped. We don't do this for each add_sigs() call as
5159 * we still want some clustering to occur.
5161 isc_random_get(&jitter);
5162 expire = soaexpire - jitter % 3600;
5165 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
5166 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
5168 name = dns_fixedname_name(&fixed);
5169 result = dns_db_getsigningtime(db, &rdataset, name);
5170 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
5171 dns_zone_log(zone, ISC_LOG_ERROR,
5172 "zone_resigninc:dns_db_getsigningtime -> %s",
5173 dns_result_totext(result));
5177 while (result == ISC_R_SUCCESS) {
5178 resign = rdataset.resign - zone->sigresigninginterval;
5179 covers = rdataset.covers;
5180 dns_rdataset_disassociate(&rdataset);
5183 * Stop if we hit the SOA as that means we have walked the
5184 * entire zone. The SOA record should always be the most
5187 /* XXXMPA increase number of RRsets signed pre call */
5188 if (covers == dns_rdatatype_soa || i++ > zone->signatures ||
5192 result = del_sigs(zone, db, version, name, covers, &zonediff,
5193 zone_keys, nkeys, now, ISC_TRUE);
5194 if (result != ISC_R_SUCCESS) {
5195 dns_zone_log(zone, ISC_LOG_ERROR,
5196 "zone_resigninc:del_sigs -> %s",
5197 dns_result_totext(result));
5201 result = add_sigs(db, version, name, covers, zonediff.diff,
5202 zone_keys, nkeys, zone->mctx, inception,
5203 expire, check_ksk, keyset_kskonly);
5204 if (result != ISC_R_SUCCESS) {
5205 dns_zone_log(zone, ISC_LOG_ERROR,
5206 "zone_resigninc:add_sigs -> %s",
5207 dns_result_totext(result));
5210 result = dns_db_getsigningtime(db, &rdataset,
5211 dns_fixedname_name(&fixed));
5212 if (nkeys == 0 && result == ISC_R_NOTFOUND) {
5213 result = ISC_R_SUCCESS;
5216 if (result != ISC_R_SUCCESS)
5217 dns_zone_log(zone, ISC_LOG_ERROR,
5218 "zone_resigninc:dns_db_getsigningtime -> %s",
5219 dns_result_totext(result));
5222 if (result != ISC_R_NOMORE && result != ISC_R_SUCCESS)
5225 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
5226 &zonediff, zone_keys, nkeys, now, ISC_TRUE);
5227 if (result != ISC_R_SUCCESS) {
5228 dns_zone_log(zone, ISC_LOG_ERROR,
5229 "zone_resigninc:del_sigs -> %s",
5230 dns_result_totext(result));
5235 * Did we change anything in the zone?
5237 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
5239 * Commit the changes if any key has been marked as offline.
5241 if (zonediff.offline)
5242 dns_db_closeversion(db, &version, ISC_TRUE);
5246 /* Increment SOA serial if we have made changes */
5247 result = increment_soa_serial(db, version, zonediff.diff, zone->mctx);
5248 if (result != ISC_R_SUCCESS) {
5249 dns_zone_log(zone, ISC_LOG_ERROR,
5250 "zone_resigninc:increment_soa_serial -> %s",
5251 dns_result_totext(result));
5256 * Generate maximum life time signatures so that the above loop
5257 * termination is sensible.
5259 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
5260 zonediff.diff, zone_keys, nkeys, zone->mctx,
5261 inception, soaexpire, check_ksk, keyset_kskonly);
5262 if (result != ISC_R_SUCCESS) {
5263 dns_zone_log(zone, ISC_LOG_ERROR,
5264 "zone_resigninc:add_sigs -> %s",
5265 dns_result_totext(result));
5269 /* Write changes to journal file. */
5270 CHECK(zone_journal(zone, zonediff.diff, "zone_resigninc"));
5272 /* Everything has succeeded. Commit the changes. */
5273 dns_db_closeversion(db, &version, ISC_TRUE);
5276 dns_diff_clear(&_sig_diff);
5277 for (i = 0; i < nkeys; i++)
5278 dst_key_free(&zone_keys[i]);
5279 if (version != NULL) {
5280 dns_db_closeversion(zone->db, &version, ISC_FALSE);
5282 } else if (db != NULL)
5284 if (result == ISC_R_SUCCESS) {
5285 set_resigntime(zone);
5287 zone_needdump(zone, DNS_DUMP_DELAY);
5288 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
5292 * Something failed. Retry in 5 minutes.
5294 isc_interval_t ival;
5295 isc_interval_set(&ival, 300, 0);
5296 isc_time_nowplusinterval(&zone->resigntime, &ival);
5301 next_active(dns_db_t *db, dns_dbversion_t *version, dns_name_t *oldname,
5302 dns_name_t *newname, isc_boolean_t bottom)
5304 isc_result_t result;
5305 dns_dbiterator_t *dbit = NULL;
5306 dns_rdatasetiter_t *rdsit = NULL;
5307 dns_dbnode_t *node = NULL;
5309 CHECK(dns_db_createiterator(db, DNS_DB_NONSEC3, &dbit));
5310 CHECK(dns_dbiterator_seek(dbit, oldname));
5312 result = dns_dbiterator_next(dbit);
5313 if (result == ISC_R_NOMORE)
5314 CHECK(dns_dbiterator_first(dbit));
5315 CHECK(dns_dbiterator_current(dbit, &node, newname));
5316 if (bottom && dns_name_issubdomain(newname, oldname) &&
5317 !dns_name_equal(newname, oldname)) {
5318 dns_db_detachnode(db, &node);
5322 * Is this node empty?
5324 CHECK(dns_db_allrdatasets(db, node, version, 0, &rdsit));
5325 result = dns_rdatasetiter_first(rdsit);
5326 dns_db_detachnode(db, &node);
5327 dns_rdatasetiter_destroy(&rdsit);
5328 if (result != ISC_R_NOMORE)
5333 dns_db_detachnode(db, &node);
5335 dns_dbiterator_destroy(&dbit);
5339 static isc_boolean_t
5340 signed_with_key(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
5341 dns_rdatatype_t type, dst_key_t *key)
5343 isc_result_t result;
5344 dns_rdataset_t rdataset;
5345 dns_rdata_t rdata = DNS_RDATA_INIT;
5346 dns_rdata_rrsig_t rrsig;
5348 dns_rdataset_init(&rdataset);
5349 result = dns_db_findrdataset(db, node, version, dns_rdatatype_rrsig,
5350 type, 0, &rdataset, NULL);
5351 if (result != ISC_R_SUCCESS) {
5352 INSIST(!dns_rdataset_isassociated(&rdataset));
5355 for (result = dns_rdataset_first(&rdataset);
5356 result == ISC_R_SUCCESS;
5357 result = dns_rdataset_next(&rdataset)) {
5358 dns_rdataset_current(&rdataset, &rdata);
5359 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
5360 INSIST(result == ISC_R_SUCCESS);
5361 if (rrsig.algorithm == dst_key_alg(key) &&
5362 rrsig.keyid == dst_key_id(key)) {
5363 dns_rdataset_disassociate(&rdataset);
5366 dns_rdata_reset(&rdata);
5368 dns_rdataset_disassociate(&rdataset);
5373 add_nsec(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5374 dns_dbnode_t *node, dns_ttl_t ttl, isc_boolean_t bottom,
5377 dns_fixedname_t fixed;
5379 dns_rdata_t rdata = DNS_RDATA_INIT;
5380 isc_result_t result;
5381 unsigned char nsecbuffer[DNS_NSEC_BUFFERSIZE];
5383 dns_fixedname_init(&fixed);
5384 next = dns_fixedname_name(&fixed);
5386 CHECK(next_active(db, version, name, next, bottom));
5387 CHECK(dns_nsec_buildrdata(db, version, node, next, nsecbuffer,
5389 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADD, name, ttl,
5396 sign_a_node(dns_db_t *db, dns_name_t *name, dns_dbnode_t *node,
5397 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5398 isc_boolean_t build_nsec, dst_key_t *key,
5399 isc_stdtime_t inception, isc_stdtime_t expire,
5400 unsigned int minimum, isc_boolean_t is_ksk,
5401 isc_boolean_t keyset_kskonly, isc_boolean_t *delegation,
5402 dns_diff_t *diff, isc_int32_t *signatures, isc_mem_t *mctx)
5404 isc_result_t result;
5405 dns_rdatasetiter_t *iterator = NULL;
5406 dns_rdataset_t rdataset;
5407 dns_rdata_t rdata = DNS_RDATA_INIT;
5408 isc_buffer_t buffer;
5409 unsigned char data[1024];
5410 isc_boolean_t seen_soa, seen_ns, seen_rr, seen_dname, seen_nsec,
5411 seen_nsec3, seen_ds;
5412 isc_boolean_t bottom;
5414 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
5415 if (result != ISC_R_SUCCESS) {
5416 if (result == ISC_R_NOTFOUND)
5417 result = ISC_R_SUCCESS;
5421 dns_rdataset_init(&rdataset);
5422 isc_buffer_init(&buffer, data, sizeof(data));
5423 seen_rr = seen_soa = seen_ns = seen_dname = seen_nsec =
5424 seen_nsec3 = seen_ds = ISC_FALSE;
5425 for (result = dns_rdatasetiter_first(iterator);
5426 result == ISC_R_SUCCESS;
5427 result = dns_rdatasetiter_next(iterator)) {
5428 dns_rdatasetiter_current(iterator, &rdataset);
5429 if (rdataset.type == dns_rdatatype_soa)
5430 seen_soa = ISC_TRUE;
5431 else if (rdataset.type == dns_rdatatype_ns)
5433 else if (rdataset.type == dns_rdatatype_ds)
5435 else if (rdataset.type == dns_rdatatype_dname)
5436 seen_dname = ISC_TRUE;
5437 else if (rdataset.type == dns_rdatatype_nsec)
5438 seen_nsec = ISC_TRUE;
5439 else if (rdataset.type == dns_rdatatype_nsec3)
5440 seen_nsec3 = ISC_TRUE;
5441 if (rdataset.type != dns_rdatatype_rrsig)
5443 dns_rdataset_disassociate(&rdataset);
5445 if (result != ISC_R_NOMORE)
5447 if (seen_ns && !seen_soa)
5448 *delegation = ISC_TRUE;
5450 * Going from insecure to NSEC3.
5451 * Don't generate NSEC3 records for NSEC3 records.
5453 if (build_nsec3 && !seen_nsec3 && seen_rr) {
5454 isc_boolean_t unsecure = !seen_ds && seen_ns && !seen_soa;
5455 CHECK(dns_nsec3_addnsec3s(db, version, name, minimum,
5460 * Going from insecure to NSEC.
5461 * Don't generate NSEC records for NSEC3 records.
5463 if (build_nsec && !seen_nsec3 && !seen_nsec && seen_rr) {
5464 /* Build and add NSEC. */
5465 bottom = (seen_ns && !seen_soa) || seen_dname;
5467 * Build a NSEC record except at the origin.
5469 if (!dns_name_equal(name, dns_db_origin(db))) {
5470 CHECK(add_nsec(db, version, name, node, minimum,
5472 /* Count a NSEC generation as a signature generation. */
5476 result = dns_rdatasetiter_first(iterator);
5477 while (result == ISC_R_SUCCESS) {
5478 dns_rdatasetiter_current(iterator, &rdataset);
5479 if (rdataset.type == dns_rdatatype_soa ||
5480 rdataset.type == dns_rdatatype_rrsig)
5482 if (rdataset.type == dns_rdatatype_dnskey) {
5483 if (!is_ksk && keyset_kskonly)
5488 rdataset.type != dns_rdatatype_ds &&
5489 rdataset.type != dns_rdatatype_nsec)
5491 if (signed_with_key(db, node, version, rdataset.type, key))
5493 /* Calculate the signature, creating a RRSIG RDATA. */
5494 isc_buffer_clear(&buffer);
5495 CHECK(dns_dnssec_sign(name, &rdataset, key, &inception,
5496 &expire, mctx, &buffer, &rdata));
5497 /* Update the database and journal with the RRSIG. */
5498 /* XXX inefficient - will cause dataset merging */
5499 CHECK(update_one_rr(db, version, diff, DNS_DIFFOP_ADDRESIGN,
5500 name, rdataset.ttl, &rdata));
5501 dns_rdata_reset(&rdata);
5504 dns_rdataset_disassociate(&rdataset);
5505 result = dns_rdatasetiter_next(iterator);
5507 if (result == ISC_R_NOMORE)
5508 result = ISC_R_SUCCESS;
5510 *delegation = ISC_TRUE;
5512 if (dns_rdataset_isassociated(&rdataset))
5513 dns_rdataset_disassociate(&rdataset);
5514 if (iterator != NULL)
5515 dns_rdatasetiter_destroy(&iterator);
5520 * If 'update_only' is set then don't create a NSEC RRset if it doesn't exist.
5523 updatesecure(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
5524 dns_ttl_t minimum, isc_boolean_t update_only, dns_diff_t *diff)
5526 isc_result_t result;
5527 dns_rdataset_t rdataset;
5528 dns_dbnode_t *node = NULL;
5530 CHECK(dns_db_getoriginnode(db, &node));
5532 dns_rdataset_init(&rdataset);
5533 result = dns_db_findrdataset(db, node, version,
5536 0, &rdataset, NULL);
5537 if (dns_rdataset_isassociated(&rdataset))
5538 dns_rdataset_disassociate(&rdataset);
5539 if (result == ISC_R_NOTFOUND)
5541 if (result != ISC_R_SUCCESS)
5544 CHECK(delete_nsec(db, version, node, name, diff));
5545 CHECK(add_nsec(db, version, name, node, minimum, ISC_FALSE, diff));
5547 result = ISC_R_SUCCESS;
5550 dns_db_detachnode(db, &node);
5555 updatesignwithkey(dns_zone_t *zone, dns_signing_t *signing,
5556 dns_dbversion_t *version, isc_boolean_t build_nsec3,
5557 dns_ttl_t minimum, dns_diff_t *diff)
5559 isc_result_t result;
5560 dns_dbnode_t *node = NULL;
5561 dns_rdataset_t rdataset;
5562 dns_rdata_t rdata = DNS_RDATA_INIT;
5563 unsigned char data[5];
5564 isc_boolean_t seen_done = ISC_FALSE;
5565 isc_boolean_t have_rr = ISC_FALSE;
5567 dns_rdataset_init(&rdataset);
5568 result = dns_db_getoriginnode(signing->db, &node);
5569 if (result != ISC_R_SUCCESS)
5572 result = dns_db_findrdataset(signing->db, node, version,
5573 zone->privatetype, dns_rdatatype_none,
5574 0, &rdataset, NULL);
5575 if (result == ISC_R_NOTFOUND) {
5576 INSIST(!dns_rdataset_isassociated(&rdataset));
5577 result = ISC_R_SUCCESS;
5580 if (result != ISC_R_SUCCESS) {
5581 INSIST(!dns_rdataset_isassociated(&rdataset));
5584 for (result = dns_rdataset_first(&rdataset);
5585 result == ISC_R_SUCCESS;
5586 result = dns_rdataset_next(&rdataset)) {
5587 dns_rdataset_current(&rdataset, &rdata);
5589 * If we don't match the algorithm or keyid skip the record.
5591 if (rdata.length != 5 ||
5592 rdata.data[0] != signing->algorithm ||
5593 rdata.data[1] != ((signing->keyid >> 8) & 0xff) ||
5594 rdata.data[2] != (signing->keyid & 0xff)) {
5596 dns_rdata_reset(&rdata);
5600 * We have a match. If we were signing (!signing->delete)
5601 * and we already have a record indicating that we have
5602 * finished signing (rdata.data[4] != 0) then keep it.
5603 * Otherwise it needs to be deleted as we have removed all
5604 * the signatures (signing->delete), so any record indicating
5605 * completion is now out of date, or we have finished signing
5606 * with the new record so we no longer need to remember that
5607 * we need to sign the zone with the matching key across a
5608 * nameserver re-start.
5610 if (!signing->delete && rdata.data[4] != 0) {
5611 seen_done = ISC_TRUE;
5614 CHECK(update_one_rr(signing->db, version, diff,
5615 DNS_DIFFOP_DEL, &zone->origin,
5616 rdataset.ttl, &rdata));
5617 dns_rdata_reset(&rdata);
5619 if (result == ISC_R_NOMORE)
5620 result = ISC_R_SUCCESS;
5621 if (!signing->delete && !seen_done) {
5623 * If we were signing then we need to indicate that we have
5624 * finished signing the zone with this key. If it is already
5625 * there we don't need to add it a second time.
5627 data[0] = signing->algorithm;
5628 data[1] = (signing->keyid >> 8) & 0xff;
5629 data[2] = signing->keyid & 0xff;
5632 rdata.length = sizeof(data);
5634 rdata.type = zone->privatetype;
5635 rdata.rdclass = dns_db_class(signing->db);
5636 CHECK(update_one_rr(signing->db, version, diff, DNS_DIFFOP_ADD,
5637 &zone->origin, rdataset.ttl, &rdata));
5638 } else if (!have_rr) {
5639 dns_name_t *origin = dns_db_origin(signing->db);
5641 * Rebuild the NSEC/NSEC3 record for the origin as we no
5642 * longer have any private records.
5645 CHECK(dns_nsec3_addnsec3s(signing->db, version, origin,
5646 minimum, ISC_FALSE, diff));
5647 CHECK(updatesecure(signing->db, version, origin, minimum,
5652 if (dns_rdataset_isassociated(&rdataset))
5653 dns_rdataset_disassociate(&rdataset);
5655 dns_db_detachnode(signing->db, &node);
5660 * If 'active' is set then we are not done with the chain yet so only
5661 * delete the nsec3param record which indicates a full chain exists
5665 fixup_nsec3param(dns_db_t *db, dns_dbversion_t *ver, dns_nsec3chain_t *chain,
5666 isc_boolean_t active, dns_rdatatype_t privatetype,
5669 dns_dbnode_t *node = NULL;
5670 dns_name_t *name = dns_db_origin(db);
5671 dns_rdata_t rdata = DNS_RDATA_INIT;
5672 dns_rdataset_t rdataset;
5673 dns_rdata_nsec3param_t nsec3param;
5674 isc_result_t result;
5675 isc_buffer_t buffer;
5676 unsigned char parambuf[DNS_NSEC3PARAM_BUFFERSIZE];
5679 dns_rdataset_init(&rdataset);
5681 result = dns_db_getoriginnode(db, &node);
5682 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5683 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
5684 0, 0, &rdataset, NULL);
5685 if (result == ISC_R_NOTFOUND)
5687 if (result != ISC_R_SUCCESS)
5691 * Preserve the existing ttl.
5696 * Delete all NSEC3PARAM records which match that in nsec3chain.
5698 for (result = dns_rdataset_first(&rdataset);
5699 result == ISC_R_SUCCESS;
5700 result = dns_rdataset_next(&rdataset)) {
5702 dns_rdataset_current(&rdataset, &rdata);
5703 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
5705 if (nsec3param.hash != chain->nsec3param.hash ||
5706 (active && nsec3param.flags != 0) ||
5707 nsec3param.iterations != chain->nsec3param.iterations ||
5708 nsec3param.salt_length != chain->nsec3param.salt_length ||
5709 memcmp(nsec3param.salt, chain->nsec3param.salt,
5710 nsec3param.salt_length)) {
5711 dns_rdata_reset(&rdata);
5715 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
5716 name, rdataset.ttl, &rdata));
5717 dns_rdata_reset(&rdata);
5719 if (result != ISC_R_NOMORE)
5722 dns_rdataset_disassociate(&rdataset);
5729 * Delete all private records which match that in nsec3chain.
5731 result = dns_db_findrdataset(db, node, ver, privatetype,
5732 0, 0, &rdataset, NULL);
5733 if (result == ISC_R_NOTFOUND)
5735 if (result != ISC_R_SUCCESS)
5738 for (result = dns_rdataset_first(&rdataset);
5739 result == ISC_R_SUCCESS;
5740 result = dns_rdataset_next(&rdataset)) {
5741 dns_rdata_t private = DNS_RDATA_INIT;
5742 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
5744 dns_rdataset_current(&rdataset, &private);
5745 if (!dns_nsec3param_fromprivate(&private, &rdata,
5748 CHECK(dns_rdata_tostruct(&rdata, &nsec3param, NULL));
5750 if (nsec3param.hash != chain->nsec3param.hash ||
5751 nsec3param.iterations != chain->nsec3param.iterations ||
5752 nsec3param.salt_length != chain->nsec3param.salt_length ||
5753 memcmp(nsec3param.salt, chain->nsec3param.salt,
5754 nsec3param.salt_length)) {
5755 dns_rdata_reset(&rdata);
5759 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL,
5760 name, rdataset.ttl, &private));
5761 dns_rdata_reset(&rdata);
5763 if (result != ISC_R_NOMORE)
5767 if ((chain->nsec3param.flags & DNS_NSEC3FLAG_REMOVE) != 0) {
5768 result = ISC_R_SUCCESS;
5773 * Add a NSEC3PARAM record which matches that in nsec3chain but
5774 * with all flags bits cleared.
5776 * Note: we do not clear chain->nsec3param.flags as this change
5779 isc_buffer_init(&buffer, ¶mbuf, sizeof(parambuf));
5780 CHECK(dns_rdata_fromstruct(&rdata, dns_db_class(db),
5781 dns_rdatatype_nsec3param,
5782 &chain->nsec3param, &buffer));
5783 rdata.data[1] = 0; /* Clear flag bits. */
5784 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_ADD, name, ttl, &rdata));
5787 dns_db_detachnode(db, &node);
5788 if (dns_rdataset_isassociated(&rdataset))
5789 dns_rdataset_disassociate(&rdataset);
5794 delete_nsec(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
5795 dns_name_t *name, dns_diff_t *diff)
5797 dns_rdataset_t rdataset;
5798 isc_result_t result;
5800 dns_rdataset_init(&rdataset);
5802 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
5803 0, 0, &rdataset, NULL);
5804 if (result == ISC_R_NOTFOUND)
5805 return (ISC_R_SUCCESS);
5806 if (result != ISC_R_SUCCESS)
5808 for (result = dns_rdataset_first(&rdataset);
5809 result == ISC_R_SUCCESS;
5810 result = dns_rdataset_next(&rdataset)) {
5811 dns_rdata_t rdata = DNS_RDATA_INIT;
5813 dns_rdataset_current(&rdataset, &rdata);
5814 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
5815 rdataset.ttl, &rdata));
5817 if (result == ISC_R_NOMORE)
5818 result = ISC_R_SUCCESS;
5820 dns_rdataset_disassociate(&rdataset);
5825 deletematchingnsec3(dns_db_t *db, dns_dbversion_t *ver, dns_dbnode_t *node,
5826 dns_name_t *name, const dns_rdata_nsec3param_t *param,
5829 dns_rdataset_t rdataset;
5830 dns_rdata_nsec3_t nsec3;
5831 isc_result_t result;
5833 dns_rdataset_init(&rdataset);
5834 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3,
5835 0, 0, &rdataset, NULL);
5836 if (result == ISC_R_NOTFOUND)
5837 return (ISC_R_SUCCESS);
5838 if (result != ISC_R_SUCCESS)
5841 for (result = dns_rdataset_first(&rdataset);
5842 result == ISC_R_SUCCESS;
5843 result = dns_rdataset_next(&rdataset)) {
5844 dns_rdata_t rdata = DNS_RDATA_INIT;
5846 dns_rdataset_current(&rdataset, &rdata);
5847 CHECK(dns_rdata_tostruct(&rdata, &nsec3, NULL));
5848 if (nsec3.hash != param->hash ||
5849 nsec3.iterations != param->iterations ||
5850 nsec3.salt_length != param->salt_length ||
5851 memcmp(nsec3.salt, param->salt, nsec3.salt_length))
5853 CHECK(update_one_rr(db, ver, diff, DNS_DIFFOP_DEL, name,
5854 rdataset.ttl, &rdata));
5856 if (result == ISC_R_NOMORE)
5857 result = ISC_R_SUCCESS;
5859 dns_rdataset_disassociate(&rdataset);
5864 need_nsec_chain(dns_db_t *db, dns_dbversion_t *ver,
5865 const dns_rdata_nsec3param_t *param,
5866 isc_boolean_t *answer)
5868 dns_dbnode_t *node = NULL;
5869 dns_rdata_t rdata = DNS_RDATA_INIT;
5870 dns_rdata_nsec3param_t myparam;
5871 dns_rdataset_t rdataset;
5872 isc_result_t result;
5874 *answer = ISC_FALSE;
5876 result = dns_db_getoriginnode(db, &node);
5877 RUNTIME_CHECK(result == ISC_R_SUCCESS);
5879 dns_rdataset_init(&rdataset);
5881 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec,
5882 0, 0, &rdataset, NULL);
5883 if (result == ISC_R_SUCCESS) {
5884 dns_rdataset_disassociate(&rdataset);
5885 dns_db_detachnode(db, &node);
5888 if (result != ISC_R_NOTFOUND) {
5889 dns_db_detachnode(db, &node);
5893 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_nsec3param,
5894 0, 0, &rdataset, NULL);
5895 if (result == ISC_R_NOTFOUND) {
5897 dns_db_detachnode(db, &node);
5898 return (ISC_R_SUCCESS);
5900 if (result != ISC_R_SUCCESS) {
5901 dns_db_detachnode(db, &node);
5905 for (result = dns_rdataset_first(&rdataset);
5906 result == ISC_R_SUCCESS;
5907 result = dns_rdataset_next(&rdataset)) {
5908 dns_rdataset_current(&rdataset, &rdata);
5909 CHECK(dns_rdata_tostruct(&rdata, &myparam, NULL));
5910 dns_rdata_reset(&rdata);
5912 * Ignore any NSEC3PARAM removals.
5914 if (NSEC3REMOVE(myparam.flags))
5917 * Ignore the chain that we are in the process of deleting.
5919 if (myparam.hash == param->hash &&
5920 myparam.iterations == param->iterations &&
5921 myparam.salt_length == param->salt_length &&
5922 !memcmp(myparam.salt, param->salt, myparam.salt_length))
5925 * Found an active NSEC3 chain.
5929 if (result == ISC_R_NOMORE) {
5931 result = ISC_R_SUCCESS;
5935 if (dns_rdataset_isassociated(&rdataset))
5936 dns_rdataset_disassociate(&rdataset);
5937 dns_db_detachnode(db, &node);
5942 update_sigs(dns_diff_t *diff, dns_db_t *db, dns_dbversion_t *version,
5943 dst_key_t *zone_keys[], unsigned int nkeys, dns_zone_t *zone,
5944 isc_stdtime_t inception, isc_stdtime_t expire, isc_stdtime_t now,
5945 isc_boolean_t check_ksk, isc_boolean_t keyset_kskonly,
5946 zonediff_t *zonediff)
5948 dns_difftuple_t *tuple;
5949 isc_result_t result;
5951 for (tuple = ISC_LIST_HEAD(diff->tuples);
5953 tuple = ISC_LIST_HEAD(diff->tuples)) {
5954 result = del_sigs(zone, db, version, &tuple->name,
5955 tuple->rdata.type, zonediff,
5956 zone_keys, nkeys, now, ISC_FALSE);
5957 if (result != ISC_R_SUCCESS) {
5958 dns_zone_log(zone, ISC_LOG_ERROR,
5959 "update_sigs:del_sigs -> %s",
5960 dns_result_totext(result));
5963 result = add_sigs(db, version, &tuple->name,
5964 tuple->rdata.type, zonediff->diff,
5965 zone_keys, nkeys, zone->mctx, inception,
5966 expire, check_ksk, keyset_kskonly);
5967 if (result != ISC_R_SUCCESS) {
5968 dns_zone_log(zone, ISC_LOG_ERROR,
5969 "update_sigs:add_sigs -> %s",
5970 dns_result_totext(result));
5975 dns_difftuple_t *next = ISC_LIST_NEXT(tuple, link);
5976 while (next != NULL &&
5977 (tuple->rdata.type != next->rdata.type ||
5978 !dns_name_equal(&tuple->name, &next->name)))
5979 next = ISC_LIST_NEXT(next, link);
5980 ISC_LIST_UNLINK(diff->tuples, tuple, link);
5981 dns_diff_appendminimal(zonediff->diff, &tuple);
5982 INSIST(tuple == NULL);
5984 } while (tuple != NULL);
5986 return (ISC_R_SUCCESS);
5990 * Incrementally build and sign a new NSEC3 chain using the parameters
5994 zone_nsec3chain(dns_zone_t *zone) {
5995 const char *me = "zone_nsec3chain";
5996 dns_db_t *db = NULL;
5997 dns_dbnode_t *node = NULL;
5998 dns_dbversion_t *version = NULL;
5999 dns_diff_t _sig_diff;
6000 dns_diff_t nsec_diff;
6001 dns_diff_t nsec3_diff;
6002 dns_diff_t param_diff;
6003 zonediff_t zonediff;
6004 dns_fixedname_t fixed;
6005 dns_fixedname_t nextfixed;
6006 dns_name_t *name, *nextname;
6007 dns_rdataset_t rdataset;
6008 dns_nsec3chain_t *nsec3chain = NULL, *nextnsec3chain;
6009 dns_nsec3chainlist_t cleanup;
6010 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6011 isc_int32_t signatures;
6012 isc_boolean_t check_ksk, keyset_kskonly;
6013 isc_boolean_t delegation;
6014 isc_boolean_t first;
6015 isc_result_t result;
6016 isc_stdtime_t now, inception, soaexpire, expire;
6017 isc_uint32_t jitter;
6019 unsigned int nkeys = 0;
6021 isc_boolean_t unsecure = ISC_FALSE;
6022 isc_boolean_t seen_soa, seen_ns, seen_dname, seen_ds;
6023 isc_boolean_t seen_nsec, seen_nsec3, seen_rr;
6024 dns_rdatasetiter_t *iterator = NULL;
6025 isc_boolean_t buildnsecchain;
6026 isc_boolean_t updatensec = ISC_FALSE;
6027 dns_rdatatype_t privatetype = zone->privatetype;
6031 dns_rdataset_init(&rdataset);
6032 dns_fixedname_init(&fixed);
6033 name = dns_fixedname_name(&fixed);
6034 dns_fixedname_init(&nextfixed);
6035 nextname = dns_fixedname_name(&nextfixed);
6036 dns_diff_init(zone->mctx, ¶m_diff);
6037 dns_diff_init(zone->mctx, &nsec3_diff);
6038 dns_diff_init(zone->mctx, &nsec_diff);
6039 dns_diff_init(zone->mctx, &_sig_diff);
6040 zonediff_init(&zonediff, &_sig_diff);
6041 ISC_LIST_INIT(cleanup);
6044 * Updates are disabled. Pause for 5 minutes.
6046 if (zone->update_disabled) {
6047 result = ISC_R_FAILURE;
6051 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6052 dns_db_attach(zone->db, &db);
6053 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6055 result = dns_db_newversion(db, &version);
6056 if (result != ISC_R_SUCCESS) {
6057 dns_zone_log(zone, ISC_LOG_ERROR,
6058 "zone_nsec3chain:dns_db_newversion -> %s",
6059 dns_result_totext(result));
6063 result = find_zone_keys(zone, db, version, zone->mctx,
6064 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6065 if (result != ISC_R_SUCCESS) {
6066 dns_zone_log(zone, ISC_LOG_ERROR,
6067 "zone_nsec3chain:find_zone_keys -> %s",
6068 dns_result_totext(result));
6072 isc_stdtime_get(&now);
6073 inception = now - 3600; /* Allow for clock skew. */
6074 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6077 * Spread out signatures over time if they happen to be
6078 * clumped. We don't do this for each add_sigs() call as
6079 * we still want some clustering to occur.
6081 isc_random_get(&jitter);
6082 expire = soaexpire - jitter % 3600;
6084 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6085 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6088 * We keep pulling nodes off each iterator in turn until
6089 * we have no more nodes to pull off or we reach the limits
6092 nodes = zone->nodes;
6093 signatures = zone->signatures;
6095 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6099 if (nsec3chain != NULL)
6100 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6102 * Generate new NSEC3 chains first.
6104 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6106 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6108 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6109 if (nsec3chain->done || nsec3chain->db != zone->db) {
6110 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain, link);
6111 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6113 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6115 if (ISC_LIST_TAIL(cleanup) == nsec3chain)
6119 * Possible future db.
6121 if (nsec3chain->db != db) {
6125 if (NSEC3REMOVE(nsec3chain->nsec3param.flags))
6128 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6130 if (nsec3chain->delete_nsec) {
6131 delegation = ISC_FALSE;
6132 dns_dbiterator_pause(nsec3chain->dbiterator);
6133 CHECK(delete_nsec(db, version, node, name, &nsec_diff));
6137 * On the first pass we need to check if the current node
6138 * has not been obscured.
6140 delegation = ISC_FALSE;
6141 unsecure = ISC_FALSE;
6143 dns_fixedname_t ffound;
6145 dns_fixedname_init(&ffound);
6146 found = dns_fixedname_name(&ffound);
6147 result = dns_db_find(db, name, version,
6149 DNS_DBFIND_NOWILD, 0, NULL, found,
6151 if ((result == DNS_R_DELEGATION ||
6152 result == DNS_R_DNAME) &&
6153 !dns_name_equal(name, found)) {
6155 * Remember the obscuring name so that
6156 * we skip all obscured names.
6158 dns_name_copy(found, name, NULL);
6159 delegation = ISC_TRUE;
6165 * Check to see if this is a bottom of zone node.
6167 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6168 if (result == ISC_R_NOTFOUND) /* Empty node? */
6170 if (result != ISC_R_SUCCESS)
6173 seen_soa = seen_ns = seen_dname = seen_ds = seen_nsec =
6175 for (result = dns_rdatasetiter_first(iterator);
6176 result == ISC_R_SUCCESS;
6177 result = dns_rdatasetiter_next(iterator)) {
6178 dns_rdatasetiter_current(iterator, &rdataset);
6179 INSIST(rdataset.type != dns_rdatatype_nsec3);
6180 if (rdataset.type == dns_rdatatype_soa)
6181 seen_soa = ISC_TRUE;
6182 else if (rdataset.type == dns_rdatatype_ns)
6184 else if (rdataset.type == dns_rdatatype_dname)
6185 seen_dname = ISC_TRUE;
6186 else if (rdataset.type == dns_rdatatype_ds)
6188 else if (rdataset.type == dns_rdatatype_nsec)
6189 seen_nsec = ISC_TRUE;
6190 dns_rdataset_disassociate(&rdataset);
6192 dns_rdatasetiter_destroy(&iterator);
6194 * Is there a NSEC chain than needs to be cleaned up?
6197 nsec3chain->seen_nsec = ISC_TRUE;
6198 if (seen_ns && !seen_soa && !seen_ds)
6199 unsecure = ISC_TRUE;
6200 if ((seen_ns && !seen_soa) || seen_dname)
6201 delegation = ISC_TRUE;
6206 dns_dbiterator_pause(nsec3chain->dbiterator);
6207 result = dns_nsec3_addnsec3(db, version, name,
6208 &nsec3chain->nsec3param,
6209 zone->minimum, unsecure,
6211 if (result != ISC_R_SUCCESS) {
6212 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6213 "dns_nsec3_addnsec3 -> %s",
6214 dns_result_totext(result));
6219 * Treat each call to dns_nsec3_addnsec3() as if it's cost is
6220 * two signatures. Additionally there will, in general, be
6221 * two signature generated below.
6223 * If we are only changing the optout flag the cost is half
6224 * that of the cost of generating a completely new chain.
6229 * Go onto next node.
6233 dns_db_detachnode(db, &node);
6235 result = dns_dbiterator_next(nsec3chain->dbiterator);
6237 if (result == ISC_R_NOMORE && nsec3chain->delete_nsec) {
6238 dns_dbiterator_pause(nsec3chain->dbiterator);
6239 CHECK(fixup_nsec3param(db, version, nsec3chain,
6240 ISC_FALSE, privatetype,
6243 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6246 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6249 if (result == ISC_R_NOMORE) {
6250 dns_dbiterator_pause(nsec3chain->dbiterator);
6251 if (nsec3chain->seen_nsec) {
6252 CHECK(fixup_nsec3param(db, version,
6257 nsec3chain->delete_nsec = ISC_TRUE;
6260 CHECK(fixup_nsec3param(db, version, nsec3chain,
6261 ISC_FALSE, privatetype,
6264 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6267 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6269 } else if (result != ISC_R_SUCCESS) {
6270 dns_zone_log(zone, ISC_LOG_ERROR,
6272 "dns_dbiterator_next -> %s",
6273 dns_result_totext(result));
6275 } else if (delegation) {
6276 dns_dbiterator_current(nsec3chain->dbiterator,
6278 dns_db_detachnode(db, &node);
6279 if (!dns_name_issubdomain(nextname, name))
6287 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6292 dns_dbiterator_pause(nsec3chain->dbiterator);
6293 nsec3chain = nextnsec3chain;
6295 if (nsec3chain != NULL)
6296 nsec3chain->save_delete_nsec = nsec3chain->delete_nsec;
6303 nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6306 buildnsecchain = ISC_FALSE;
6307 while (nsec3chain != NULL && nodes-- > 0 && signatures > 0) {
6309 nextnsec3chain = ISC_LIST_NEXT(nsec3chain, link);
6312 if (nsec3chain->db != db)
6313 goto next_removechain;
6315 if (!NSEC3REMOVE(nsec3chain->nsec3param.flags))
6316 goto next_removechain;
6319 * Work out if we need to build a NSEC chain as a consequence
6320 * of removing this NSEC3 chain.
6322 if (first && !updatensec &&
6323 (nsec3chain->nsec3param.flags & DNS_NSEC3FLAG_NONSEC) == 0) {
6324 result = need_nsec_chain(db, version,
6325 &nsec3chain->nsec3param,
6327 if (result != ISC_R_SUCCESS) {
6328 dns_zone_log(zone, ISC_LOG_ERROR,
6330 "need_nsec_chain -> %s",
6331 dns_result_totext(result));
6337 dns_zone_log(zone, ISC_LOG_DEBUG(3), "zone_nsec3chain:"
6338 "buildnsecchain = %u\n", buildnsecchain);
6340 dns_dbiterator_current(nsec3chain->dbiterator, &node, name);
6341 delegation = ISC_FALSE;
6343 if (!buildnsecchain) {
6345 * Delete the NSECPARAM record that matches this chain.
6348 result = fixup_nsec3param(db, version,
6350 ISC_TRUE, privatetype,
6352 if (result != ISC_R_SUCCESS) {
6353 dns_zone_log(zone, ISC_LOG_ERROR,
6355 "fixup_nsec3param -> %s",
6356 dns_result_totext(result));
6362 * Delete the NSEC3 records.
6364 result = deletematchingnsec3(db, version, node, name,
6365 &nsec3chain->nsec3param,
6367 if (result != ISC_R_SUCCESS) {
6368 dns_zone_log(zone, ISC_LOG_ERROR,
6370 "deletematchingnsec3 -> %s",
6371 dns_result_totext(result));
6374 goto next_removenode;
6378 dns_fixedname_t ffound;
6380 dns_fixedname_init(&ffound);
6381 found = dns_fixedname_name(&ffound);
6382 result = dns_db_find(db, name, version,
6384 DNS_DBFIND_NOWILD, 0, NULL, found,
6386 if ((result == DNS_R_DELEGATION ||
6387 result == DNS_R_DNAME) &&
6388 !dns_name_equal(name, found)) {
6390 * Remember the obscuring name so that
6391 * we skip all obscured names.
6393 dns_name_copy(found, name, NULL);
6394 delegation = ISC_TRUE;
6395 goto next_removenode;
6400 * Check to see if this is a bottom of zone node.
6402 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6403 if (result == ISC_R_NOTFOUND) /* Empty node? */
6404 goto next_removenode;
6405 if (result != ISC_R_SUCCESS)
6408 seen_soa = seen_ns = seen_dname = seen_nsec3 = seen_nsec =
6409 seen_rr = ISC_FALSE;
6410 for (result = dns_rdatasetiter_first(iterator);
6411 result == ISC_R_SUCCESS;
6412 result = dns_rdatasetiter_next(iterator)) {
6413 dns_rdatasetiter_current(iterator, &rdataset);
6414 if (rdataset.type == dns_rdatatype_soa)
6415 seen_soa = ISC_TRUE;
6416 else if (rdataset.type == dns_rdatatype_ns)
6418 else if (rdataset.type == dns_rdatatype_dname)
6419 seen_dname = ISC_TRUE;
6420 else if (rdataset.type == dns_rdatatype_nsec)
6421 seen_nsec = ISC_TRUE;
6422 else if (rdataset.type == dns_rdatatype_nsec3)
6423 seen_nsec3 = ISC_TRUE;
6424 if (rdataset.type != dns_rdatatype_rrsig)
6426 dns_rdataset_disassociate(&rdataset);
6428 dns_rdatasetiter_destroy(&iterator);
6430 if (!seen_rr || seen_nsec3 || seen_nsec)
6431 goto next_removenode;
6432 if ((seen_ns && !seen_soa) || seen_dname)
6433 delegation = ISC_TRUE;
6436 * Add a NSEC record except at the origin.
6438 if (!dns_name_equal(name, dns_db_origin(db))) {
6439 dns_dbiterator_pause(nsec3chain->dbiterator);
6440 CHECK(add_nsec(db, version, name, node, zone->minimum,
6441 delegation, &nsec_diff));
6446 dns_db_detachnode(db, &node);
6448 result = dns_dbiterator_next(nsec3chain->dbiterator);
6449 if (result == ISC_R_NOMORE && buildnsecchain) {
6451 * The NSEC chain should now be built.
6452 * We can now remove the NSEC3 chain.
6454 updatensec = ISC_TRUE;
6455 goto same_removechain;
6457 if (result == ISC_R_NOMORE) {
6459 ISC_LIST_UNLINK(zone->nsec3chain, nsec3chain,
6462 ISC_LIST_APPEND(cleanup, nsec3chain, link);
6463 dns_dbiterator_pause(nsec3chain->dbiterator);
6464 result = fixup_nsec3param(db, version,
6465 nsec3chain, ISC_FALSE,
6468 if (result != ISC_R_SUCCESS) {
6469 dns_zone_log(zone, ISC_LOG_ERROR,
6471 "fixup_nsec3param -> %s",
6472 dns_result_totext(result));
6475 goto next_removechain;
6476 } else if (result != ISC_R_SUCCESS) {
6477 dns_zone_log(zone, ISC_LOG_ERROR,
6479 "dns_dbiterator_next -> %s",
6480 dns_result_totext(result));
6482 } else if (delegation) {
6483 dns_dbiterator_current(nsec3chain->dbiterator,
6485 dns_db_detachnode(db, &node);
6486 if (!dns_name_issubdomain(nextname, name))
6494 CHECK(dns_dbiterator_first(nsec3chain->dbiterator));
6495 buildnsecchain = ISC_FALSE;
6500 dns_dbiterator_pause(nsec3chain->dbiterator);
6501 nsec3chain = nextnsec3chain;
6506 * We may need to update the NSEC/NSEC3 records for the zone apex.
6508 if (!ISC_LIST_EMPTY(param_diff.tuples)) {
6509 isc_boolean_t rebuild_nsec = ISC_FALSE,
6510 rebuild_nsec3 = ISC_FALSE;
6511 result = dns_db_getoriginnode(db, &node);
6512 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6513 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6514 if (result != ISC_R_SUCCESS) {
6515 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6516 "dns_db_allrdatasets -> %s",
6517 dns_result_totext(result));
6520 for (result = dns_rdatasetiter_first(iterator);
6521 result == ISC_R_SUCCESS;
6522 result = dns_rdatasetiter_next(iterator)) {
6523 dns_rdatasetiter_current(iterator, &rdataset);
6524 if (rdataset.type == dns_rdatatype_nsec)
6525 rebuild_nsec = ISC_TRUE;
6526 if (rdataset.type == dns_rdatatype_nsec3param)
6527 rebuild_nsec3 = ISC_TRUE;
6528 dns_rdataset_disassociate(&rdataset);
6530 dns_rdatasetiter_destroy(&iterator);
6531 dns_db_detachnode(db, &node);
6534 if (nsec3chain != NULL)
6535 dns_dbiterator_pause(nsec3chain->dbiterator);
6537 result = updatesecure(db, version, &zone->origin,
6538 zone->minimum, ISC_TRUE,
6540 if (result != ISC_R_SUCCESS) {
6541 dns_zone_log(zone, ISC_LOG_ERROR,
6543 "updatesecure -> %s",
6544 dns_result_totext(result));
6549 if (rebuild_nsec3) {
6550 if (nsec3chain != NULL)
6551 dns_dbiterator_pause(nsec3chain->dbiterator);
6553 result = dns_nsec3_addnsec3s(db, version,
6555 zone->minimum, ISC_FALSE,
6557 if (result != ISC_R_SUCCESS) {
6558 dns_zone_log(zone, ISC_LOG_ERROR,
6560 "dns_nsec3_addnsec3s -> %s",
6561 dns_result_totext(result));
6567 if (nsec3chain != NULL)
6568 dns_dbiterator_pause(nsec3chain->dbiterator);
6571 * Add / update signatures for the NSEC3 records.
6573 if (nsec3chain != NULL)
6574 dns_dbiterator_pause(nsec3chain->dbiterator);
6575 result = update_sigs(&nsec3_diff, db, version, zone_keys,
6576 nkeys, zone, inception, expire, now,
6577 check_ksk, keyset_kskonly, &zonediff);
6578 if (result != ISC_R_SUCCESS) {
6579 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6580 "update_sigs -> %s", dns_result_totext(result));
6585 * We have changed the NSEC3PARAM or private RRsets
6586 * above so we need to update the signatures.
6588 result = update_sigs(¶m_diff, db, version, zone_keys,
6589 nkeys, zone, inception, expire, now,
6590 check_ksk, keyset_kskonly, &zonediff);
6591 if (result != ISC_R_SUCCESS) {
6592 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6593 "update_sigs -> %s", dns_result_totext(result));
6598 result = updatesecure(db, version, &zone->origin,
6599 zone->minimum, ISC_FALSE, &nsec_diff);
6600 if (result != ISC_R_SUCCESS) {
6601 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6602 "updatesecure -> %s",
6603 dns_result_totext(result));
6608 result = update_sigs(&nsec_diff, db, version, zone_keys,
6609 nkeys, zone, inception, expire, now,
6610 check_ksk, keyset_kskonly, &zonediff);
6611 if (result != ISC_R_SUCCESS) {
6612 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6613 "update_sigs -> %s", dns_result_totext(result));
6618 * If we made no effective changes to the zone then we can just
6619 * cleanup otherwise we need to increment the serial.
6621 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
6623 * No need to call dns_db_closeversion() here as it is
6624 * called with commit = ISC_TRUE below.
6629 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
6630 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
6631 if (result != ISC_R_SUCCESS) {
6632 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6633 "del_sigs -> %s", dns_result_totext(result));
6637 result = increment_soa_serial(db, version, zonediff.diff, zone->mctx);
6638 if (result != ISC_R_SUCCESS) {
6639 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6640 "increment_soa_serial -> %s",
6641 dns_result_totext(result));
6645 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
6646 zonediff.diff, zone_keys, nkeys, zone->mctx,
6647 inception, soaexpire, check_ksk, keyset_kskonly);
6648 if (result != ISC_R_SUCCESS) {
6649 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain:"
6650 "add_sigs -> %s", dns_result_totext(result));
6654 /* Write changes to journal file. */
6655 CHECK(zone_journal(zone, zonediff.diff, "zone_nsec3chain"));
6658 zone_needdump(zone, DNS_DUMP_DELAY);
6659 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
6664 * Pause all iterators so that dns_db_closeversion() can succeed.
6667 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6669 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
6670 dns_dbiterator_pause(nsec3chain->dbiterator);
6674 * Everything has succeeded. Commit the changes.
6675 * Unconditionally commit as zonediff.offline not checked above.
6677 dns_db_closeversion(db, &version, ISC_TRUE);
6680 * Everything succeeded so we can clean these up now.
6682 nsec3chain = ISC_LIST_HEAD(cleanup);
6683 while (nsec3chain != NULL) {
6684 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
6685 dns_db_detach(&nsec3chain->db);
6686 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6687 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6688 nsec3chain = ISC_LIST_HEAD(cleanup);
6691 set_resigntime(zone);
6694 if (result != ISC_R_SUCCESS)
6695 dns_zone_log(zone, ISC_LOG_ERROR, "zone_nsec3chain: %s",
6696 dns_result_totext(result));
6698 * On error roll back the current nsec3chain.
6700 if (result != ISC_R_SUCCESS && nsec3chain != NULL) {
6701 if (nsec3chain->done) {
6702 dns_db_detach(&nsec3chain->db);
6703 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6704 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6706 result = dns_dbiterator_first(nsec3chain->dbiterator);
6707 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6708 dns_dbiterator_pause(nsec3chain->dbiterator);
6709 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
6714 * Rollback the cleanup list.
6716 nsec3chain = ISC_LIST_TAIL(cleanup);
6717 while (nsec3chain != NULL) {
6718 ISC_LIST_UNLINK(cleanup, nsec3chain, link);
6719 if (nsec3chain->done) {
6720 dns_db_detach(&nsec3chain->db);
6721 dns_dbiterator_destroy(&nsec3chain->dbiterator);
6722 isc_mem_put(zone->mctx, nsec3chain, sizeof *nsec3chain);
6725 ISC_LIST_PREPEND(zone->nsec3chain, nsec3chain, link);
6727 result = dns_dbiterator_first(nsec3chain->dbiterator);
6728 RUNTIME_CHECK(result == ISC_R_SUCCESS);
6729 dns_dbiterator_pause(nsec3chain->dbiterator);
6730 nsec3chain->delete_nsec = nsec3chain->save_delete_nsec;
6732 nsec3chain = ISC_LIST_TAIL(cleanup);
6736 for (nsec3chain = ISC_LIST_HEAD(zone->nsec3chain);
6738 nsec3chain = ISC_LIST_NEXT(nsec3chain, link))
6739 dns_dbiterator_pause(nsec3chain->dbiterator);
6742 dns_diff_clear(¶m_diff);
6743 dns_diff_clear(&nsec3_diff);
6744 dns_diff_clear(&nsec_diff);
6745 dns_diff_clear(&_sig_diff);
6747 if (iterator != NULL)
6748 dns_rdatasetiter_destroy(&iterator);
6750 for (i = 0; i < nkeys; i++)
6751 dst_key_free(&zone_keys[i]);
6754 dns_db_detachnode(db, &node);
6755 if (version != NULL) {
6756 dns_db_closeversion(db, &version, ISC_FALSE);
6758 } else if (db != NULL)
6762 if (ISC_LIST_HEAD(zone->nsec3chain) != NULL) {
6764 if (zone->update_disabled || result != ISC_R_SUCCESS)
6765 isc_interval_set(&i, 60, 0); /* 1 minute */
6767 isc_interval_set(&i, 0, 10000000); /* 10 ms */
6768 isc_time_nowplusinterval(&zone->nsec3chaintime, &i);
6770 isc_time_settoepoch(&zone->nsec3chaintime);
6775 del_sig(dns_db_t *db, dns_dbversion_t *version, dns_name_t *name,
6776 dns_dbnode_t *node, unsigned int nkeys, dns_secalg_t algorithm,
6777 isc_uint16_t keyid, dns_diff_t *diff)
6779 dns_rdata_rrsig_t rrsig;
6780 dns_rdataset_t rdataset;
6781 dns_rdatasetiter_t *iterator = NULL;
6782 isc_result_t result;
6784 result = dns_db_allrdatasets(db, node, version, 0, &iterator);
6785 if (result != ISC_R_SUCCESS) {
6786 if (result == ISC_R_NOTFOUND)
6787 result = ISC_R_SUCCESS;
6791 dns_rdataset_init(&rdataset);
6792 for (result = dns_rdatasetiter_first(iterator);
6793 result == ISC_R_SUCCESS;
6794 result = dns_rdatasetiter_next(iterator)) {
6795 dns_rdatasetiter_current(iterator, &rdataset);
6796 if (nkeys == 0 && rdataset.type == dns_rdatatype_nsec) {
6797 for (result = dns_rdataset_first(&rdataset);
6798 result == ISC_R_SUCCESS;
6799 result = dns_rdataset_next(&rdataset)) {
6800 dns_rdata_t rdata = DNS_RDATA_INIT;
6801 dns_rdataset_current(&rdataset, &rdata);
6802 CHECK(update_one_rr(db, version, diff,
6803 DNS_DIFFOP_DEL, name,
6804 rdataset.ttl, &rdata));
6806 if (result != ISC_R_NOMORE)
6808 dns_rdataset_disassociate(&rdataset);
6811 if (rdataset.type != dns_rdatatype_rrsig) {
6812 dns_rdataset_disassociate(&rdataset);
6815 for (result = dns_rdataset_first(&rdataset);
6816 result == ISC_R_SUCCESS;
6817 result = dns_rdataset_next(&rdataset)) {
6818 dns_rdata_t rdata = DNS_RDATA_INIT;
6819 dns_rdataset_current(&rdataset, &rdata);
6820 CHECK(dns_rdata_tostruct(&rdata, &rrsig, NULL));
6821 if (rrsig.algorithm != algorithm ||
6822 rrsig.keyid != keyid)
6824 CHECK(update_one_rr(db, version, diff,
6825 DNS_DIFFOP_DELRESIGN, name,
6826 rdataset.ttl, &rdata));
6828 dns_rdataset_disassociate(&rdataset);
6829 if (result != ISC_R_NOMORE)
6832 if (result == ISC_R_NOMORE)
6833 result = ISC_R_SUCCESS;
6835 if (dns_rdataset_isassociated(&rdataset))
6836 dns_rdataset_disassociate(&rdataset);
6837 dns_rdatasetiter_destroy(&iterator);
6842 * Incrementally sign the zone using the keys requested.
6843 * Builds the NSEC chain if required.
6846 zone_sign(dns_zone_t *zone) {
6847 const char *me = "zone_sign";
6848 dns_db_t *db = NULL;
6849 dns_dbnode_t *node = NULL;
6850 dns_dbversion_t *version = NULL;
6851 dns_diff_t _sig_diff;
6852 dns_diff_t post_diff;
6853 zonediff_t zonediff;
6854 dns_fixedname_t fixed;
6855 dns_fixedname_t nextfixed;
6856 dns_name_t *name, *nextname;
6857 dns_rdataset_t rdataset;
6858 dns_signing_t *signing, *nextsigning;
6859 dns_signinglist_t cleanup;
6860 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
6861 isc_int32_t signatures;
6862 isc_boolean_t check_ksk, keyset_kskonly, is_ksk;
6863 isc_boolean_t commit = ISC_FALSE;
6864 isc_boolean_t delegation;
6865 isc_boolean_t build_nsec = ISC_FALSE;
6866 isc_boolean_t build_nsec3 = ISC_FALSE;
6867 isc_boolean_t first;
6868 isc_result_t result;
6869 isc_stdtime_t now, inception, soaexpire, expire;
6870 isc_uint32_t jitter;
6872 unsigned int nkeys = 0;
6877 dns_rdataset_init(&rdataset);
6878 dns_fixedname_init(&fixed);
6879 name = dns_fixedname_name(&fixed);
6880 dns_fixedname_init(&nextfixed);
6881 nextname = dns_fixedname_name(&nextfixed);
6882 dns_diff_init(zone->mctx, &_sig_diff);
6883 dns_diff_init(zone->mctx, &post_diff);
6884 zonediff_init(&zonediff, &_sig_diff);
6885 ISC_LIST_INIT(cleanup);
6888 * Updates are disabled. Pause for 5 minutes.
6890 if (zone->update_disabled) {
6891 result = ISC_R_FAILURE;
6895 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6896 dns_db_attach(zone->db, &db);
6897 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6899 result = dns_db_newversion(db, &version);
6900 if (result != ISC_R_SUCCESS) {
6901 dns_zone_log(zone, ISC_LOG_ERROR,
6902 "zone_sign:dns_db_newversion -> %s",
6903 dns_result_totext(result));
6907 result = find_zone_keys(zone, db, version, zone->mctx,
6908 DNS_MAXZONEKEYS, zone_keys, &nkeys);
6909 if (result != ISC_R_SUCCESS) {
6910 dns_zone_log(zone, ISC_LOG_ERROR,
6911 "zone_sign:find_zone_keys -> %s",
6912 dns_result_totext(result));
6916 isc_stdtime_get(&now);
6917 inception = now - 3600; /* Allow for clock skew. */
6918 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
6921 * Spread out signatures over time if they happen to be
6922 * clumped. We don't do this for each add_sigs() call as
6923 * we still want some clustering to occur.
6925 isc_random_get(&jitter);
6926 expire = soaexpire - jitter % 3600;
6929 * We keep pulling nodes off each iterator in turn until
6930 * we have no more nodes to pull off or we reach the limits
6933 nodes = zone->nodes;
6934 signatures = zone->signatures;
6935 signing = ISC_LIST_HEAD(zone->signing);
6938 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
6939 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
6941 /* Determine which type of chain to build */
6942 CHECK(dns_private_chains(db, version, zone->privatetype,
6943 &build_nsec, &build_nsec3));
6945 /* If neither chain is found, default to NSEC */
6946 if (!build_nsec && !build_nsec3)
6947 build_nsec = ISC_TRUE;
6949 while (signing != NULL && nodes-- > 0 && signatures > 0) {
6950 nextsigning = ISC_LIST_NEXT(signing, link);
6952 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
6953 if (signing->done || signing->db != zone->db) {
6955 * The zone has been reloaded. We will have
6956 * created new signings as part of the reload
6957 * process so we can destroy this one.
6959 ISC_LIST_UNLINK(zone->signing, signing, link);
6960 ISC_LIST_APPEND(cleanup, signing, link);
6961 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6964 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
6966 if (signing->db != db)
6969 delegation = ISC_FALSE;
6971 if (first && signing->delete) {
6973 * Remove the key we are deleting from consideration.
6975 for (i = 0, j = 0; i < nkeys; i++) {
6977 * Find the key we want to remove.
6979 if (ALG(zone_keys[i]) == signing->algorithm &&
6980 dst_key_id(zone_keys[i]) == signing->keyid)
6982 if (KSK(zone_keys[i]))
6983 dst_key_free(&zone_keys[i]);
6986 zone_keys[j] = zone_keys[i];
6992 dns_dbiterator_current(signing->dbiterator, &node, name);
6994 if (signing->delete) {
6995 dns_dbiterator_pause(signing->dbiterator);
6996 CHECK(del_sig(db, version, name, node, nkeys,
6997 signing->algorithm, signing->keyid,
7002 * On the first pass we need to check if the current node
7003 * has not been obscured.
7006 dns_fixedname_t ffound;
7008 dns_fixedname_init(&ffound);
7009 found = dns_fixedname_name(&ffound);
7010 result = dns_db_find(db, name, version,
7012 DNS_DBFIND_NOWILD, 0, NULL, found,
7014 if ((result == DNS_R_DELEGATION ||
7015 result == DNS_R_DNAME) &&
7016 !dns_name_equal(name, found)) {
7018 * Remember the obscuring name so that
7019 * we skip all obscured names.
7021 dns_name_copy(found, name, NULL);
7022 delegation = ISC_TRUE;
7030 dns_dbiterator_pause(signing->dbiterator);
7031 for (i = 0; i < nkeys; i++) {
7032 isc_boolean_t both = ISC_FALSE;
7035 * Find the keys we want to sign with.
7037 if (!dst_key_isprivate(zone_keys[i]))
7041 * When adding look for the specific key.
7043 if (!signing->delete &&
7044 (dst_key_alg(zone_keys[i]) != signing->algorithm ||
7045 dst_key_id(zone_keys[i]) != signing->keyid))
7049 * When deleting make sure we are properly signed
7050 * with the algorithm that was being removed.
7052 if (signing->delete &&
7053 ALG(zone_keys[i]) != signing->algorithm)
7057 * Do we do KSK processing?
7059 if (check_ksk && !REVOKE(zone_keys[i])) {
7060 isc_boolean_t have_ksk, have_nonksk;
7061 if (KSK(zone_keys[i])) {
7062 have_ksk = ISC_TRUE;
7063 have_nonksk = ISC_FALSE;
7065 have_ksk = ISC_FALSE;
7066 have_nonksk = ISC_TRUE;
7068 for (j = 0; j < nkeys; j++) {
7070 ALG(zone_keys[i]) !=
7073 if (REVOKE(zone_keys[j]))
7075 if (KSK(zone_keys[j]))
7076 have_ksk = ISC_TRUE;
7078 have_nonksk = ISC_TRUE;
7079 both = have_ksk && have_nonksk;
7084 if (both || REVOKE(zone_keys[i]))
7085 is_ksk = KSK(zone_keys[i]);
7089 CHECK(sign_a_node(db, name, node, version, build_nsec3,
7090 build_nsec, zone_keys[i], inception,
7091 expire, zone->minimum, is_ksk,
7092 ISC_TF(both && keyset_kskonly),
7093 &delegation, zonediff.diff,
7094 &signatures, zone->mctx));
7096 * If we are adding we are done. Look for other keys
7097 * of the same algorithm if deleting.
7099 if (!signing->delete)
7104 * Go onto next node.
7108 dns_db_detachnode(db, &node);
7110 result = dns_dbiterator_next(signing->dbiterator);
7111 if (result == ISC_R_NOMORE) {
7112 ISC_LIST_UNLINK(zone->signing, signing, link);
7113 ISC_LIST_APPEND(cleanup, signing, link);
7114 dns_dbiterator_pause(signing->dbiterator);
7115 if (nkeys != 0 && build_nsec) {
7117 * We have finished regenerating the
7118 * zone with a zone signing key.
7119 * The NSEC chain is now complete and
7120 * there is a full set of signatures
7121 * for the zone. We can now clear the
7122 * OPT bit from the NSEC record.
7124 result = updatesecure(db, version,
7129 if (result != ISC_R_SUCCESS) {
7132 "updatesecure -> %s",
7133 dns_result_totext(result));
7137 result = updatesignwithkey(zone, signing,
7142 if (result != ISC_R_SUCCESS) {
7143 dns_zone_log(zone, ISC_LOG_ERROR,
7144 "updatesignwithkey -> %s",
7145 dns_result_totext(result));
7148 build_nsec = ISC_FALSE;
7150 } else if (result != ISC_R_SUCCESS) {
7151 dns_zone_log(zone, ISC_LOG_ERROR,
7152 "zone_sign:dns_dbiterator_next -> %s",
7153 dns_result_totext(result));
7155 } else if (delegation) {
7156 dns_dbiterator_current(signing->dbiterator,
7158 dns_db_detachnode(db, &node);
7159 if (!dns_name_issubdomain(nextname, name))
7167 dns_dbiterator_pause(signing->dbiterator);
7168 signing = nextsigning;
7172 if (ISC_LIST_HEAD(post_diff.tuples) != NULL) {
7173 result = update_sigs(&post_diff, db, version, zone_keys,
7174 nkeys, zone, inception, expire, now,
7175 check_ksk, keyset_kskonly, &zonediff);
7176 if (result != ISC_R_SUCCESS) {
7177 dns_zone_log(zone, ISC_LOG_ERROR, "zone_sign:"
7178 "update_sigs -> %s",
7179 dns_result_totext(result));
7185 * Have we changed anything?
7187 if (ISC_LIST_EMPTY(zonediff.diff->tuples)) {
7188 if (zonediff.offline)
7190 result = ISC_R_SUCCESS;
7196 result = del_sigs(zone, db, version, &zone->origin, dns_rdatatype_soa,
7197 &zonediff, zone_keys, nkeys, now, ISC_FALSE);
7198 if (result != ISC_R_SUCCESS) {
7199 dns_zone_log(zone, ISC_LOG_ERROR,
7200 "zone_sign:del_sigs -> %s",
7201 dns_result_totext(result));
7205 result = increment_soa_serial(db, version, zonediff.diff, zone->mctx);
7206 if (result != ISC_R_SUCCESS) {
7207 dns_zone_log(zone, ISC_LOG_ERROR,
7208 "zone_sign:increment_soa_serial -> %s",
7209 dns_result_totext(result));
7214 * Generate maximum life time signatures so that the above loop
7215 * termination is sensible.
7217 result = add_sigs(db, version, &zone->origin, dns_rdatatype_soa,
7218 zonediff.diff, zone_keys, nkeys, zone->mctx,
7219 inception, soaexpire, check_ksk, keyset_kskonly);
7220 if (result != ISC_R_SUCCESS) {
7221 dns_zone_log(zone, ISC_LOG_ERROR,
7222 "zone_sign:add_sigs -> %s",
7223 dns_result_totext(result));
7228 * Write changes to journal file.
7230 CHECK(zone_journal(zone, zonediff.diff, "zone_sign"));
7234 * Pause all iterators so that dns_db_closeversion() can succeed.
7236 for (signing = ISC_LIST_HEAD(zone->signing);
7238 signing = ISC_LIST_NEXT(signing, link))
7239 dns_dbiterator_pause(signing->dbiterator);
7241 for (signing = ISC_LIST_HEAD(cleanup);
7243 signing = ISC_LIST_NEXT(signing, link))
7244 dns_dbiterator_pause(signing->dbiterator);
7247 * Everything has succeeded. Commit the changes.
7249 dns_db_closeversion(db, &version, commit);
7252 * Everything succeeded so we can clean these up now.
7254 signing = ISC_LIST_HEAD(cleanup);
7255 while (signing != NULL) {
7256 ISC_LIST_UNLINK(cleanup, signing, link);
7257 dns_db_detach(&signing->db);
7258 dns_dbiterator_destroy(&signing->dbiterator);
7259 isc_mem_put(zone->mctx, signing, sizeof *signing);
7260 signing = ISC_LIST_HEAD(cleanup);
7263 set_resigntime(zone);
7267 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
7268 zone_needdump(zone, DNS_DUMP_DELAY);
7274 * Rollback the cleanup list.
7276 signing = ISC_LIST_HEAD(cleanup);
7277 while (signing != NULL) {
7278 ISC_LIST_UNLINK(cleanup, signing, link);
7279 ISC_LIST_PREPEND(zone->signing, signing, link);
7280 dns_dbiterator_first(signing->dbiterator);
7281 dns_dbiterator_pause(signing->dbiterator);
7282 signing = ISC_LIST_HEAD(cleanup);
7285 for (signing = ISC_LIST_HEAD(zone->signing);
7287 signing = ISC_LIST_NEXT(signing, link))
7288 dns_dbiterator_pause(signing->dbiterator);
7290 dns_diff_clear(&_sig_diff);
7292 for (i = 0; i < nkeys; i++)
7293 dst_key_free(&zone_keys[i]);
7296 dns_db_detachnode(db, &node);
7298 if (version != NULL) {
7299 dns_db_closeversion(db, &version, ISC_FALSE);
7301 } else if (db != NULL)
7304 if (ISC_LIST_HEAD(zone->signing) != NULL) {
7306 if (zone->update_disabled || result != ISC_R_SUCCESS)
7307 isc_interval_set(&i, 60, 0); /* 1 minute */
7309 isc_interval_set(&i, 0, 10000000); /* 10 ms */
7310 isc_time_nowplusinterval(&zone->signingtime, &i);
7312 isc_time_settoepoch(&zone->signingtime);
7316 normalize_key(dns_rdata_t *rr, dns_rdata_t *target,
7317 unsigned char *data, int size) {
7318 dns_rdata_dnskey_t dnskey;
7319 dns_rdata_keydata_t keydata;
7321 isc_result_t result;
7323 dns_rdata_reset(target);
7324 isc_buffer_init(&buf, data, size);
7327 case dns_rdatatype_dnskey:
7328 result = dns_rdata_tostruct(rr, &dnskey, NULL);
7329 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7330 dnskey.flags &= ~DNS_KEYFLAG_REVOKE;
7331 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7334 case dns_rdatatype_keydata:
7335 result = dns_rdata_tostruct(rr, &keydata, NULL);
7336 if (result == ISC_R_UNEXPECTEDEND)
7338 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7339 dns_keydata_todnskey(&keydata, &dnskey, NULL);
7340 dns_rdata_fromstruct(target, rr->rdclass, dns_rdatatype_dnskey,
7346 return (ISC_R_SUCCESS);
7350 * 'rdset' contains either a DNSKEY rdataset from the zone apex, or
7351 * a KEYDATA rdataset from the key zone.
7353 * 'rr' contains either a DNSKEY record, or a KEYDATA record
7355 * After normalizing keys to the same format (DNSKEY, with revoke bit
7356 * cleared), return ISC_TRUE if a key that matches 'rr' is found in
7357 * 'rdset', or ISC_FALSE if not.
7360 static isc_boolean_t
7361 matchkey(dns_rdataset_t *rdset, dns_rdata_t *rr) {
7362 unsigned char data1[4096], data2[4096];
7363 dns_rdata_t rdata, rdata1, rdata2;
7364 isc_result_t result;
7366 dns_rdata_init(&rdata);
7367 dns_rdata_init(&rdata1);
7368 dns_rdata_init(&rdata2);
7370 result = normalize_key(rr, &rdata1, data1, sizeof(data1));
7371 if (result != ISC_R_SUCCESS)
7374 for (result = dns_rdataset_first(rdset);
7375 result == ISC_R_SUCCESS;
7376 result = dns_rdataset_next(rdset)) {
7377 dns_rdata_reset(&rdata);
7378 dns_rdataset_current(rdset, &rdata);
7379 result = normalize_key(&rdata, &rdata2, data2, sizeof(data2));
7380 if (result != ISC_R_SUCCESS)
7382 if (dns_rdata_compare(&rdata1, &rdata2) == 0)
7390 * Calculate the refresh interval for a keydata zone, per
7391 * RFC5011: MAX(1 hr,
7394 * 1/2 * RRSigExpirationInterval))
7395 * or for retries: MAX(1 hr,
7398 * 1/10 * RRSigExpirationInterval))
7400 static inline isc_stdtime_t
7401 refresh_time(dns_keyfetch_t *kfetch, isc_boolean_t retry) {
7402 isc_result_t result;
7404 dns_rdataset_t *rdset;
7405 dns_rdata_t sigrr = DNS_RDATA_INIT;
7406 dns_rdata_sig_t sig;
7409 isc_stdtime_get(&now);
7411 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
7412 rdset = &kfetch->dnskeysigset;
7414 return (now + HOUR);
7416 result = dns_rdataset_first(rdset);
7417 if (result != ISC_R_SUCCESS)
7418 return (now + HOUR);
7420 dns_rdataset_current(rdset, &sigrr);
7421 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7422 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7425 t = sig.originalttl / 2;
7427 if (isc_serial_gt(sig.timeexpire, now)) {
7428 isc_uint32_t exp = (sig.timeexpire - now) / 2;
7439 t = sig.originalttl / 10;
7441 if (isc_serial_gt(sig.timeexpire, now)) {
7442 isc_uint32_t exp = (sig.timeexpire - now) / 10;
7458 * This routine is called when no changes are needed in a KEYDATA
7459 * record except to simply update the refresh timer. Caller should
7463 minimal_update(dns_keyfetch_t *kfetch, dns_dbversion_t *ver, dns_diff_t *diff)
7465 isc_result_t result;
7467 unsigned char key_buf[4096];
7468 dns_rdata_t rdata = DNS_RDATA_INIT;
7469 dns_rdata_keydata_t keydata;
7471 dns_zone_t *zone = kfetch->zone;
7474 name = dns_fixedname_name(&kfetch->name);
7475 isc_stdtime_get(&now);
7477 for (result = dns_rdataset_first(&kfetch->keydataset);
7478 result == ISC_R_SUCCESS;
7479 result = dns_rdataset_next(&kfetch->keydataset)) {
7480 dns_rdata_reset(&rdata);
7481 dns_rdataset_current(&kfetch->keydataset, &rdata);
7483 /* Delete old version */
7484 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_DEL,
7487 /* Update refresh timer */
7488 result = dns_rdata_tostruct(&rdata, &keydata, NULL);
7489 if (result == ISC_R_UNEXPECTEDEND)
7491 if (result != ISC_R_SUCCESS)
7493 keydata.refresh = refresh_time(kfetch, ISC_TRUE);
7494 set_refreshkeytimer(zone, &keydata, now);
7496 dns_rdata_reset(&rdata);
7497 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7498 CHECK(dns_rdata_fromstruct(&rdata,
7499 zone->rdclass, dns_rdatatype_keydata,
7502 /* Insert updated version */
7503 CHECK(update_one_rr(kfetch->db, ver, diff, DNS_DIFFOP_ADD,
7506 result = ISC_R_SUCCESS;
7512 * Verify that DNSKEY set is signed by the key specified in 'keydata'.
7514 static isc_boolean_t
7515 revocable(dns_keyfetch_t *kfetch, dns_rdata_keydata_t *keydata) {
7516 isc_result_t result;
7517 dns_name_t *keyname;
7519 dns_rdata_t sigrr = DNS_RDATA_INIT;
7520 dns_rdata_t rr = DNS_RDATA_INIT;
7521 dns_rdata_rrsig_t sig;
7522 dns_rdata_dnskey_t dnskey;
7523 dst_key_t *dstkey = NULL;
7524 unsigned char key_buf[4096];
7526 isc_boolean_t answer = ISC_FALSE;
7528 REQUIRE(kfetch != NULL && keydata != NULL);
7529 REQUIRE(dns_rdataset_isassociated(&kfetch->dnskeysigset));
7531 keyname = dns_fixedname_name(&kfetch->name);
7532 mctx = kfetch->zone->view->mctx;
7534 /* Generate a key from keydata */
7535 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7536 dns_keydata_todnskey(keydata, &dnskey, NULL);
7537 dns_rdata_fromstruct(&rr, keydata->common.rdclass, dns_rdatatype_dnskey,
7539 result = dns_dnssec_keyfromrdata(keyname, &rr, mctx, &dstkey);
7540 if (result != ISC_R_SUCCESS)
7543 /* See if that key generated any of the signatures */
7544 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7545 result == ISC_R_SUCCESS;
7546 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7547 dns_fixedname_t fixed;
7548 dns_fixedname_init(&fixed);
7550 dns_rdata_reset(&sigrr);
7551 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7552 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7553 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7555 if (dst_key_alg(dstkey) == sig.algorithm &&
7556 (dst_key_id(dstkey) == sig.keyid ||
7557 dst_key_rid(dstkey) == sig.keyid)) {
7558 result = dns_dnssec_verify2(keyname,
7560 dstkey, ISC_FALSE, mctx, &sigrr,
7561 dns_fixedname_name(&fixed));
7563 dns_zone_log(kfetch->zone, ISC_LOG_DEBUG(3),
7564 "Confirm revoked DNSKEY is self-signed: "
7565 "%s", dns_result_totext(result));
7567 if (result == ISC_R_SUCCESS) {
7574 dst_key_free(&dstkey);
7579 * A DNSKEY set has been fetched from the zone apex of a zone whose trust
7580 * anchors are being managed; scan the keyset, and update the key zone and the
7581 * local trust anchors according to RFC5011.
7584 keyfetch_done(isc_task_t *task, isc_event_t *event) {
7585 isc_result_t result, eresult;
7586 dns_fetchevent_t *devent;
7587 dns_keyfetch_t *kfetch;
7589 isc_mem_t *mctx = NULL;
7590 dns_keytable_t *secroots = NULL;
7591 dns_dbversion_t *ver = NULL;
7593 isc_boolean_t alldone = ISC_FALSE;
7594 isc_boolean_t commit = ISC_FALSE;
7595 dns_name_t *keyname;
7596 dns_rdata_t sigrr = DNS_RDATA_INIT;
7597 dns_rdata_t dnskeyrr = DNS_RDATA_INIT;
7598 dns_rdata_t keydatarr = DNS_RDATA_INIT;
7599 dns_rdata_rrsig_t sig;
7600 dns_rdata_dnskey_t dnskey;
7601 dns_rdata_keydata_t keydata;
7602 isc_boolean_t initializing;
7603 char namebuf[DNS_NAME_FORMATSIZE];
7604 unsigned char key_buf[4096];
7609 isc_boolean_t secure;
7610 isc_boolean_t free_needed;
7613 INSIST(event != NULL && event->ev_type == DNS_EVENT_FETCHDONE);
7614 INSIST(event->ev_arg != NULL);
7616 kfetch = event->ev_arg;
7617 zone = kfetch->zone;
7618 isc_mem_attach(zone->mctx, &mctx);
7619 keyname = dns_fixedname_name(&kfetch->name);
7621 devent = (dns_fetchevent_t *) event;
7622 eresult = devent->result;
7624 /* Free resources which are not of interest */
7625 if (devent->node != NULL)
7626 dns_db_detachnode(devent->db, &devent->node);
7627 if (devent->db != NULL)
7628 dns_db_detach(&devent->db);
7629 isc_event_free(&event);
7630 dns_resolver_destroyfetch(&kfetch->fetch);
7633 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) || zone->view == NULL)
7636 isc_stdtime_get(&now);
7637 dns_name_format(keyname, namebuf, sizeof(namebuf));
7639 result = dns_view_getsecroots(zone->view, &secroots);
7640 INSIST(result == ISC_R_SUCCESS);
7642 dns_diff_init(mctx, &diff);
7644 CHECK(dns_db_newversion(kfetch->db, &ver));
7646 zone->refreshkeycount--;
7647 alldone = ISC_TF(zone->refreshkeycount == 0);
7650 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
7653 if (eresult != ISC_R_SUCCESS ||
7654 !dns_rdataset_isassociated(&kfetch->dnskeyset)) {
7655 dns_zone_log(zone, ISC_LOG_WARNING,
7656 "Unable to fetch DNSKEY set "
7657 "'%s': %s", namebuf, dns_result_totext(eresult));
7658 CHECK(minimal_update(kfetch, ver, &diff));
7662 /* No RRSIGs found */
7663 if (!dns_rdataset_isassociated(&kfetch->dnskeysigset)) {
7664 dns_zone_log(zone, ISC_LOG_WARNING,
7665 "No DNSKEY RRSIGs found for "
7666 "'%s': %s", namebuf, dns_result_totext(eresult));
7667 CHECK(minimal_update(kfetch, ver, &diff));
7672 * Validate the dnskeyset against the current trusted keys.
7674 for (result = dns_rdataset_first(&kfetch->dnskeysigset);
7675 result == ISC_R_SUCCESS;
7676 result = dns_rdataset_next(&kfetch->dnskeysigset)) {
7677 dns_keynode_t *keynode = NULL;
7679 dns_rdata_reset(&sigrr);
7680 dns_rdataset_current(&kfetch->dnskeysigset, &sigrr);
7681 result = dns_rdata_tostruct(&sigrr, &sig, NULL);
7682 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7684 result = dns_keytable_find(secroots, keyname, &keynode);
7685 while (result == ISC_R_SUCCESS) {
7686 dns_keynode_t *nextnode = NULL;
7687 dns_fixedname_t fixed;
7688 dns_fixedname_init(&fixed);
7690 dstkey = dns_keynode_key(keynode);
7691 if (dstkey == NULL) /* fail_secure() was called */
7694 if (dst_key_alg(dstkey) == sig.algorithm &&
7695 dst_key_id(dstkey) == sig.keyid) {
7696 result = dns_dnssec_verify2(keyname,
7699 zone->view->mctx, &sigrr,
7700 dns_fixedname_name(&fixed));
7702 dns_zone_log(zone, ISC_LOG_DEBUG(3),
7703 "Verifying DNSKEY set for zone "
7704 "'%s': %s", namebuf,
7705 dns_result_totext(result));
7707 if (result == ISC_R_SUCCESS) {
7708 kfetch->dnskeyset.trust =
7710 kfetch->dnskeysigset.trust =
7712 dns_keytable_detachkeynode(secroots,
7718 result = dns_keytable_nextkeynode(secroots,
7719 keynode, &nextnode);
7720 dns_keytable_detachkeynode(secroots, &keynode);
7724 if (kfetch->dnskeyset.trust == dns_trust_secure)
7729 * If we were not able to verify the answer using the current
7730 * trusted keys then all we can do is look at any revoked keys.
7732 secure = ISC_TF(kfetch->dnskeyset.trust == dns_trust_secure);
7735 * First scan keydataset to find keys that are not in dnskeyset
7736 * - Missing keys which are not scheduled for removal,
7738 * - Missing keys which are scheduled for removal and
7739 * the remove hold-down timer has completed should
7740 * be removed from the key zone
7741 * - Missing keys whose acceptance timers have not yet
7742 * completed, log a warning and reset the acceptance
7743 * timer to 30 days in the future
7744 * - All keys not being removed have their refresh timers
7747 initializing = ISC_TRUE;
7748 for (result = dns_rdataset_first(&kfetch->keydataset);
7749 result == ISC_R_SUCCESS;
7750 result = dns_rdataset_next(&kfetch->keydataset)) {
7751 dns_rdata_reset(&keydatarr);
7752 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7753 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7754 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7757 * If any keydata record has a nonzero add holddown, then
7758 * there was a pre-existing trust anchor for this domain;
7759 * that means we are *not* initializing it and shouldn't
7760 * automatically trust all the keys we find at the zone apex.
7762 initializing = initializing && ISC_TF(keydata.addhd == 0);
7764 if (! matchkey(&kfetch->dnskeyset, &keydatarr)) {
7765 isc_boolean_t deletekey = ISC_FALSE;
7768 if (now > keydata.removehd)
7769 deletekey = ISC_TRUE;
7770 } else if (now < keydata.addhd) {
7771 dns_zone_log(zone, ISC_LOG_WARNING,
7772 "Pending key unexpectedly missing "
7773 "from %s; restarting acceptance "
7775 keydata.addhd = now + MONTH;
7776 keydata.refresh = refresh_time(kfetch,
7778 } else if (keydata.addhd == 0) {
7779 keydata.addhd = now;
7780 } else if (keydata.removehd == 0) {
7781 dns_zone_log(zone, ISC_LOG_WARNING,
7782 "Active key unexpectedly missing "
7783 "from %s", namebuf);
7784 keydata.refresh = now + HOUR;
7785 } else if (now > keydata.removehd) {
7786 deletekey = ISC_TRUE;
7788 keydata.refresh = refresh_time(kfetch,
7792 if (secure || deletekey) {
7793 /* Delete old version */
7794 CHECK(update_one_rr(kfetch->db, ver, &diff,
7795 DNS_DIFFOP_DEL, keyname, 0,
7799 if (!secure || deletekey)
7802 dns_rdata_reset(&keydatarr);
7803 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7804 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7805 dns_rdatatype_keydata,
7808 /* Insert updated version */
7809 CHECK(update_one_rr(kfetch->db, ver, &diff,
7810 DNS_DIFFOP_ADD, keyname, 0,
7813 set_refreshkeytimer(zone, &keydata, now);
7818 * Next scan dnskeyset:
7819 * - If new keys are found (i.e., lacking a match in keydataset)
7820 * add them to the key zone and set the acceptance timer
7821 * to 30 days in the future (or to immediately if we've
7822 * determined that we're initializing the zone for the
7824 * - Previously-known keys that have been revoked
7825 * must be scheduled for removal from the key zone (or,
7826 * if they hadn't been accepted as trust anchors yet
7827 * anyway, removed at once)
7828 * - Previously-known unrevoked keys whose acceptance timers
7829 * have completed are promoted to trust anchors
7830 * - All keys not being removed have their refresh
7833 for (result = dns_rdataset_first(&kfetch->dnskeyset);
7834 result == ISC_R_SUCCESS;
7835 result = dns_rdataset_next(&kfetch->dnskeyset)) {
7836 isc_boolean_t revoked = ISC_FALSE;
7837 isc_boolean_t newkey = ISC_FALSE;
7838 isc_boolean_t updatekey = ISC_FALSE;
7839 isc_boolean_t deletekey = ISC_FALSE;
7840 isc_boolean_t trustkey = ISC_FALSE;
7842 dns_rdata_reset(&dnskeyrr);
7843 dns_rdataset_current(&kfetch->dnskeyset, &dnskeyrr);
7844 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7845 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7848 if (!ISC_TF(dnskey.flags & DNS_KEYFLAG_KSK))
7851 revoked = ISC_TF(dnskey.flags & DNS_KEYFLAG_REVOKE);
7853 if (matchkey(&kfetch->keydataset, &dnskeyrr)) {
7854 dns_rdata_reset(&keydatarr);
7855 dns_rdataset_current(&kfetch->keydataset, &keydatarr);
7856 result = dns_rdata_tostruct(&keydatarr, &keydata, NULL);
7857 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7859 if (revoked && revocable(kfetch, &keydata)) {
7860 if (keydata.addhd > now) {
7862 * Key wasn't trusted yet, and now
7863 * it's been revoked? Just remove it
7865 deletekey = ISC_TRUE;
7866 } else if (keydata.removehd == 0) {
7867 /* Remove from secroots */
7868 dns_view_untrust(zone->view, keyname,
7871 /* If initializing, delete now */
7872 if (keydata.addhd == 0)
7873 deletekey = ISC_TRUE;
7875 keydata.removehd = now + MONTH;
7876 } else if (keydata.removehd < now) {
7877 /* Scheduled for removal */
7878 deletekey = ISC_TRUE;
7880 } else if (revoked) {
7881 if (secure && keydata.removehd == 0) {
7882 dns_zone_log(zone, ISC_LOG_WARNING,
7883 "Active key for zone "
7884 "'%s' is revoked but "
7885 "did not self-sign; "
7886 "ignoring.", namebuf);
7889 } else if (secure) {
7890 if (keydata.removehd != 0) {
7892 * Key isn't revoked--but it
7893 * seems it used to be.
7894 * Remove it now and add it
7895 * back as if it were a fresh key.
7897 deletekey = ISC_TRUE;
7899 } else if (keydata.addhd > now)
7901 else if (keydata.addhd == 0)
7902 keydata.addhd = now;
7904 if (keydata.addhd <= now)
7905 trustkey = ISC_TRUE;
7908 if (!deletekey && !newkey)
7909 updatekey = ISC_TRUE;
7910 } else if (secure) {
7912 * Key wasn't in the key zone but it's
7913 * revoked now anyway, so just skip it
7918 /* Key wasn't in the key zone: add it */
7922 dns_keytag_t tag = 0;
7923 CHECK(compute_tag(keyname, &dnskey,
7925 dns_zone_log(zone, ISC_LOG_WARNING,
7926 "Initializing automatic trust "
7927 "anchor management for zone '%s'; "
7928 "DNSKEY ID %d is now trusted, "
7929 "waiving the normal 30-day "
7932 trustkey = ISC_TRUE;
7936 /* Delete old version */
7937 if (deletekey || !newkey)
7938 CHECK(update_one_rr(kfetch->db, ver, &diff,
7939 DNS_DIFFOP_DEL, keyname, 0,
7943 /* Set refresh timer */
7944 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7945 dns_rdata_reset(&keydatarr);
7946 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7947 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7948 dns_rdatatype_keydata,
7951 /* Insert updated version */
7952 CHECK(update_one_rr(kfetch->db, ver, &diff,
7953 DNS_DIFFOP_ADD, keyname, 0,
7955 } else if (newkey) {
7956 /* Convert DNSKEY to KEYDATA */
7957 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7958 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7959 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
7961 keydata.addhd = initializing ? now : now + MONTH;
7962 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7963 dns_rdata_reset(&keydatarr);
7964 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7965 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7966 dns_rdatatype_keydata,
7969 /* Insert into key zone */
7970 CHECK(update_one_rr(kfetch->db, ver, &diff,
7971 DNS_DIFFOP_ADD, keyname, 0,
7976 /* Trust this key. */
7977 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7978 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7979 trust_key(zone, keyname, &dnskey, mctx);
7983 set_refreshkeytimer(zone, &keydata, now);
7987 * RFC5011 says, "A trust point that has all of its trust anchors
7988 * revoked is considered deleted and is treated as if the trust
7989 * point was never configured." But if someone revoked their
7990 * active key before the standby was trusted, that would mean the
7991 * zone would suddenly be nonsecured. We avoid this by checking to
7992 * see if there's pending keydata. If so, we put a null key in
7993 * the security roots; then all queries to the zone will fail.
7996 fail_secure(zone, keyname);
8000 if (!ISC_LIST_EMPTY(diff.tuples)) {
8001 /* Write changes to journal file. */
8002 CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx));
8003 CHECK(zone_journal(zone, &diff, "keyfetch_done"));
8006 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8007 zone_needdump(zone, 30);
8012 dns_diff_clear(&diff);
8014 dns_db_closeversion(kfetch->db, &ver, commit);
8017 dns_db_detach(&kfetch->db);
8019 INSIST(zone->irefs > 0);
8021 kfetch->zone = NULL;
8023 if (dns_rdataset_isassociated(&kfetch->keydataset))
8024 dns_rdataset_disassociate(&kfetch->keydataset);
8025 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
8026 dns_rdataset_disassociate(&kfetch->dnskeyset);
8027 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8028 dns_rdataset_disassociate(&kfetch->dnskeysigset);
8030 dns_name_free(keyname, mctx);
8031 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
8032 isc_mem_detach(&mctx);
8034 if (secroots != NULL)
8035 dns_keytable_detach(&secroots);
8037 free_needed = exit_check(zone);
8044 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
8045 * records from the zone apex.
8048 zone_refreshkeys(dns_zone_t *zone) {
8049 const char me[] = "zone_refreshkeys";
8050 isc_result_t result;
8051 dns_rriterator_t rrit;
8052 dns_db_t *db = NULL;
8053 dns_dbversion_t *ver = NULL;
8055 dns_rdata_t rdata = DNS_RDATA_INIT;
8056 dns_rdata_keydata_t kd;
8058 isc_boolean_t commit = ISC_FALSE;
8059 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
8062 REQUIRE(zone->db != NULL);
8064 isc_stdtime_get(&now);
8067 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
8068 isc_time_settoepoch(&zone->refreshkeytime);
8073 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8074 dns_db_attach(zone->db, &db);
8075 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8077 dns_diff_init(zone->mctx, &diff);
8079 CHECK(dns_db_newversion(db, &ver));
8081 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
8083 dns_rriterator_init(&rrit, db, ver, 0);
8084 for (result = dns_rriterator_first(&rrit);
8085 result == ISC_R_SUCCESS;
8086 result = dns_rriterator_nextrrset(&rrit)) {
8087 isc_stdtime_t timer = 0xffffffff;
8088 dns_name_t *name = NULL, *kname = NULL;
8089 dns_rdataset_t *kdset = NULL;
8090 dns_keyfetch_t *kfetch;
8093 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
8094 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
8095 !dns_rdataset_isassociated(kdset))
8099 * Scan the stored keys looking for ones that need
8100 * removal or refreshing
8102 for (result = dns_rdataset_first(kdset);
8103 result == ISC_R_SUCCESS;
8104 result = dns_rdataset_next(kdset)) {
8105 dns_rdata_reset(&rdata);
8106 dns_rdataset_current(kdset, &rdata);
8107 result = dns_rdata_tostruct(&rdata, &kd, NULL);
8108 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8110 /* Removal timer expired? */
8111 if (kd.removehd != 0 && kd.removehd < now) {
8112 CHECK(update_one_rr(db, ver, &diff,
8113 DNS_DIFFOP_DEL, name, ttl,
8118 /* Acceptance timer expired? */
8119 if (kd.addhd != 0 && kd.addhd < now)
8122 /* Or do we just need to refresh the keyset? */
8123 if (timer > kd.refresh)
8130 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
8131 if (kfetch == NULL) {
8132 fetch_err = ISC_TRUE;
8136 zone->refreshkeycount++;
8137 kfetch->zone = zone;
8139 INSIST(zone->irefs != 0);
8140 dns_fixedname_init(&kfetch->name);
8141 kname = dns_fixedname_name(&kfetch->name);
8142 dns_name_dup(name, zone->mctx, kname);
8143 dns_rdataset_init(&kfetch->dnskeyset);
8144 dns_rdataset_init(&kfetch->dnskeysigset);
8145 dns_rdataset_init(&kfetch->keydataset);
8146 dns_rdataset_clone(kdset, &kfetch->keydataset);
8148 dns_db_attach(db, &kfetch->db);
8149 kfetch->fetch = NULL;
8151 result = dns_resolver_createfetch(zone->view->resolver,
8152 kname, dns_rdatatype_dnskey,
8154 DNS_FETCHOPT_NOVALIDATE,
8156 keyfetch_done, kfetch,
8158 &kfetch->dnskeysigset,
8160 if (result == ISC_R_SUCCESS)
8161 fetching = ISC_TRUE;
8163 zone->refreshkeycount--;
8165 dns_db_detach(&kfetch->db);
8166 dns_rdataset_disassociate(&kfetch->keydataset);
8167 dns_name_free(kname, zone->mctx);
8168 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
8169 dns_zone_log(zone, ISC_LOG_WARNING,
8170 "Failed to create fetch for "
8172 fetch_err = ISC_TRUE;
8175 if (!ISC_LIST_EMPTY(diff.tuples)) {
8176 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
8177 CHECK(zone_journal(zone, &diff, "zone_refreshkeys"));
8179 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8180 zone_needdump(zone, 30);
8186 * Error during a key fetch; retry in an hour.
8188 isc_time_t timenow, timethen;
8192 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
8193 zone->refreshkeytime = timethen;
8194 zone_settimer(zone, &timenow);
8196 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
8197 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
8201 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8206 dns_diff_clear(&diff);
8208 dns_rriterator_destroy(&rrit);
8209 dns_db_closeversion(db, &ver, commit);
8215 zone_maintenance(dns_zone_t *zone) {
8216 const char me[] = "zone_maintenance";
8218 isc_result_t result;
8219 isc_boolean_t dumping;
8221 REQUIRE(DNS_ZONE_VALID(zone));
8225 * Configuring the view of this zone may have
8226 * failed, for example because the config file
8227 * had a syntax error. In that case, the view
8228 * db or resolver will be NULL, and we had better not try
8229 * to do maintenance on it.
8231 if (zone->view == NULL || zone->view->adb == NULL)
8239 switch (zone->type) {
8240 case dns_zone_slave:
8243 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
8244 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8246 zone->refreshtime = now;
8257 switch (zone->type) {
8258 case dns_zone_slave:
8260 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8261 isc_time_compare(&now, &zone->refreshtime) >= 0)
8262 dns_zone_refresh(zone);
8269 * Slaves send notifies before backing up to disk, masters after.
8271 if (zone->type == dns_zone_slave &&
8272 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8273 isc_time_compare(&now, &zone->notifytime) >= 0)
8274 zone_notify(zone, &now);
8277 * Do we need to consolidate the backing store?
8279 switch (zone->type) {
8280 case dns_zone_master:
8281 case dns_zone_slave:
8285 if (zone->masterfile != NULL &&
8286 isc_time_compare(&now, &zone->dumptime) >= 0 &&
8287 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8288 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
8289 dumping = was_dumping(zone);
8294 result = zone_dump(zone, ISC_TRUE); /* task locked */
8295 if (result != ISC_R_SUCCESS)
8296 dns_zone_log(zone, ISC_LOG_WARNING,
8298 dns_result_totext(result));
8306 * Master/redirect zones send notifies now, if needed
8308 switch (zone->type) {
8309 case dns_zone_master:
8310 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8311 isc_time_compare(&now, &zone->notifytime) >= 0)
8312 zone_notify(zone, &now);
8318 * Do we need to refresh keys?
8320 switch (zone->type) {
8322 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
8323 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8324 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
8325 zone_refreshkeys(zone);
8329 case dns_zone_master:
8330 if (!isc_time_isepoch(&zone->refreshkeytime) &&
8331 isc_time_compare(&now, &zone->refreshkeytime) >= 0)
8337 switch (zone->type) {
8338 case dns_zone_master:
8339 case dns_zone_slave:
8341 * Do we need to sign/resign some RRsets?
8343 if (!isc_time_isepoch(&zone->signingtime) &&
8344 isc_time_compare(&now, &zone->signingtime) >= 0)
8346 else if (!isc_time_isepoch(&zone->resigntime) &&
8347 isc_time_compare(&now, &zone->resigntime) >= 0)
8348 zone_resigninc(zone);
8349 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
8350 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
8351 zone_nsec3chain(zone);
8353 * Do we need to issue a key expiry warning?
8355 if (!isc_time_isepoch(&zone->keywarntime) &&
8356 isc_time_compare(&now, &zone->keywarntime) >= 0)
8357 set_key_expiry_warning(zone, zone->key_expiry,
8358 isc_time_seconds(&now));
8363 zone_settimer(zone, &now);
8367 dns_zone_markdirty(dns_zone_t *zone) {
8370 if (zone->type == dns_zone_master)
8371 set_resigntime(zone); /* XXXMPA make separate call back */
8372 zone_needdump(zone, DNS_DUMP_DELAY);
8377 dns_zone_expire(dns_zone_t *zone) {
8378 REQUIRE(DNS_ZONE_VALID(zone));
8386 zone_expire(dns_zone_t *zone) {
8388 * 'zone' locked by caller.
8391 REQUIRE(LOCKED_ZONE(zone));
8393 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
8395 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
8396 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
8397 zone->retry = DNS_ZONE_DEFAULTRETRY;
8398 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
8403 dns_zone_refresh(dns_zone_t *zone) {
8405 isc_uint32_t oldflags;
8407 isc_result_t result;
8409 REQUIRE(DNS_ZONE_VALID(zone));
8411 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8415 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
8416 * in progress at a time.
8420 oldflags = zone->flags;
8421 if (zone->masterscnt == 0) {
8422 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
8423 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
8424 dns_zone_log(zone, ISC_LOG_ERROR,
8425 "cannot refresh: no masters");
8428 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
8429 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
8430 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
8431 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
8435 * Set the next refresh time as if refresh check has failed.
8436 * Setting this to the retry time will do that. XXXMLG
8437 * If we are successful it will be reset using zone->refresh.
8439 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
8441 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
8442 if (result != ISC_R_SUCCESS)
8443 dns_zone_log(zone, ISC_LOG_WARNING,
8444 "isc_time_nowplusinterval() failed: %s",
8445 dns_result_totext(result));
8448 * When lacking user-specified timer values from the SOA,
8449 * do exponential backoff of the retry time up to a
8450 * maximum of six hours.
8452 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
8453 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
8455 zone->curmaster = 0;
8456 for (j = 0; j < zone->masterscnt; j++)
8457 zone->mastersok[j] = ISC_FALSE;
8458 /* initiate soa query */
8459 queue_soa_query(zone);
8465 dns_zone_flush(dns_zone_t *zone) {
8466 isc_result_t result = ISC_R_SUCCESS;
8467 isc_boolean_t dumping;
8469 REQUIRE(DNS_ZONE_VALID(zone));
8472 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
8473 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8474 zone->masterfile != NULL) {
8475 result = ISC_R_ALREADYRUNNING;
8476 dumping = was_dumping(zone);
8481 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8486 dns_zone_dump(dns_zone_t *zone) {
8487 isc_result_t result = ISC_R_ALREADYRUNNING;
8488 isc_boolean_t dumping;
8490 REQUIRE(DNS_ZONE_VALID(zone));
8493 dumping = was_dumping(zone);
8496 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8501 zone_needdump(dns_zone_t *zone, unsigned int delay) {
8502 const char me[] = "zone_needdump";
8503 isc_time_t dumptime;
8507 * 'zone' locked by caller
8510 REQUIRE(DNS_ZONE_VALID(zone));
8511 REQUIRE(LOCKED_ZONE(zone));
8515 * Do we have a place to dump to and are we loaded?
8517 if (zone->masterfile == NULL ||
8518 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
8522 /* add some noise */
8523 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
8525 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8526 if (isc_time_isepoch(&zone->dumptime) ||
8527 isc_time_compare(&zone->dumptime, &dumptime) > 0)
8528 zone->dumptime = dumptime;
8529 if (zone->task != NULL)
8530 zone_settimer(zone, &now);
8534 dump_done(void *arg, isc_result_t result) {
8535 const char me[] = "dump_done";
8536 dns_zone_t *zone = arg;
8538 dns_dbversion_t *version;
8539 isc_boolean_t again = ISC_FALSE;
8540 isc_boolean_t compact = ISC_FALSE;
8541 isc_uint32_t serial;
8542 isc_result_t tresult;
8544 REQUIRE(DNS_ZONE_VALID(zone));
8548 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
8549 zone->journalsize != -1) {
8552 * We don't own these, zone->dctx must stay valid.
8554 db = dns_dumpctx_db(zone->dctx);
8555 version = dns_dumpctx_version(zone->dctx);
8557 tresult = dns_db_getsoaserial(db, version, &serial);
8559 * Note: we are task locked here so we can test
8562 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
8563 tresult = dns_journal_compact(zone->mctx,
8570 case ISC_R_NOTFOUND:
8571 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8572 "dns_journal_compact: %s",
8573 dns_result_totext(tresult));
8576 dns_zone_log(zone, ISC_LOG_ERROR,
8577 "dns_journal_compact failed: %s",
8578 dns_result_totext(tresult));
8581 } else if (tresult == ISC_R_SUCCESS) {
8583 zone->compact_serial = serial;
8588 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8590 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
8591 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
8593 * Try again in a short while.
8595 zone_needdump(zone, DNS_DUMP_DELAY);
8596 } else if (result == ISC_R_SUCCESS &&
8597 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8598 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8599 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8600 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8601 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8602 isc_time_settoepoch(&zone->dumptime);
8604 } else if (result == ISC_R_SUCCESS)
8605 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8607 if (zone->dctx != NULL)
8608 dns_dumpctx_detach(&zone->dctx);
8609 zonemgr_putio(&zone->writeio);
8612 (void)zone_dump(zone, ISC_FALSE);
8613 dns_zone_idetach(&zone);
8617 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
8618 const char me[] = "zone_dump";
8619 isc_result_t result;
8620 dns_dbversion_t *version = NULL;
8621 isc_boolean_t again;
8622 dns_db_t *db = NULL;
8623 char *masterfile = NULL;
8624 dns_masterformat_t masterformat = dns_masterformat_none;
8627 * 'compact' MUST only be set if we are task locked.
8630 REQUIRE(DNS_ZONE_VALID(zone));
8634 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8635 if (zone->db != NULL)
8636 dns_db_attach(zone->db, &db);
8637 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8639 if (zone->masterfile != NULL) {
8640 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
8641 masterformat = zone->masterformat;
8645 result = DNS_R_NOTLOADED;
8648 if (masterfile == NULL) {
8649 result = DNS_R_NOMASTERFILE;
8653 if (compact && zone->type != dns_zone_stub) {
8654 dns_zone_t *dummy = NULL;
8656 zone_iattach(zone, &dummy);
8657 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
8658 zone_gotwritehandle, zone,
8660 if (result != ISC_R_SUCCESS)
8661 zone_idetach(&dummy);
8663 result = DNS_R_CONTINUE;
8666 const dns_master_style_t *output_style;
8668 if (zone->type == dns_zone_key)
8669 output_style = &dns_master_style_keyzone;
8671 output_style = &dns_master_style_default;
8672 dns_db_currentversion(db, &version);
8673 result = dns_master_dump2(zone->mctx, db, version,
8674 output_style, masterfile,
8676 dns_db_closeversion(db, &version, ISC_FALSE);
8681 if (masterfile != NULL)
8682 isc_mem_free(zone->mctx, masterfile);
8685 if (result == DNS_R_CONTINUE)
8686 return (ISC_R_SUCCESS); /* XXXMPA */
8690 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8691 if (result != ISC_R_SUCCESS) {
8693 * Try again in a short while.
8695 zone_needdump(zone, DNS_DUMP_DELAY);
8696 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8697 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8698 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8699 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8700 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8701 isc_time_settoepoch(&zone->dumptime);
8704 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8713 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
8714 dns_masterformat_t format)
8716 isc_result_t result;
8717 dns_dbversion_t *version = NULL;
8718 dns_db_t *db = NULL;
8720 REQUIRE(DNS_ZONE_VALID(zone));
8722 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8723 if (zone->db != NULL)
8724 dns_db_attach(zone->db, &db);
8725 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8727 return (DNS_R_NOTLOADED);
8729 dns_db_currentversion(db, &version);
8730 result = dns_master_dumptostream2(zone->mctx, db, version, style,
8732 dns_db_closeversion(db, &version, ISC_FALSE);
8738 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
8739 const dns_master_style_t *style) {
8740 return dumptostream(zone, fd, style, format);
8744 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
8745 return dumptostream(zone, fd, &dns_master_style_default,
8746 dns_masterformat_text);
8750 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
8751 return dumptostream(zone, fd, &dns_master_style_full,
8752 dns_masterformat_text);
8756 dns_zone_unload(dns_zone_t *zone) {
8757 REQUIRE(DNS_ZONE_VALID(zone));
8765 notify_cancel(dns_zone_t *zone) {
8766 dns_notify_t *notify;
8769 * 'zone' locked by caller.
8772 REQUIRE(LOCKED_ZONE(zone));
8774 for (notify = ISC_LIST_HEAD(zone->notifies);
8776 notify = ISC_LIST_NEXT(notify, link)) {
8777 if (notify->find != NULL)
8778 dns_adb_cancelfind(notify->find);
8779 if (notify->request != NULL)
8780 dns_request_cancel(notify->request);
8785 forward_cancel(dns_zone_t *zone) {
8786 dns_forward_t *forward;
8789 * 'zone' locked by caller.
8792 REQUIRE(LOCKED_ZONE(zone));
8794 for (forward = ISC_LIST_HEAD(zone->forwards);
8796 forward = ISC_LIST_NEXT(forward, link)) {
8797 if (forward->request != NULL)
8798 dns_request_cancel(forward->request);
8803 zone_unload(dns_zone_t *zone) {
8806 * 'zone' locked by caller.
8809 REQUIRE(LOCKED_ZONE(zone));
8811 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8812 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8813 if (zone->writeio != NULL)
8814 zonemgr_cancelio(zone->writeio);
8816 if (zone->dctx != NULL)
8817 dns_dumpctx_cancel(zone->dctx);
8819 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
8820 zone_detachdb(zone);
8821 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
8822 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
8823 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8827 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8828 REQUIRE(DNS_ZONE_VALID(zone));
8831 zone->minrefresh = val;
8835 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8836 REQUIRE(DNS_ZONE_VALID(zone));
8839 zone->maxrefresh = val;
8843 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
8844 REQUIRE(DNS_ZONE_VALID(zone));
8847 zone->minretry = val;
8851 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
8852 REQUIRE(DNS_ZONE_VALID(zone));
8855 zone->maxretry = val;
8858 static isc_boolean_t
8859 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
8860 dns_notify_t *notify;
8862 for (notify = ISC_LIST_HEAD(zone->notifies);
8864 notify = ISC_LIST_NEXT(notify, link)) {
8865 if (notify->request != NULL)
8867 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
8868 dns_name_equal(name, ¬ify->ns))
8870 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
8876 static isc_boolean_t
8877 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
8878 dns_tsigkey_t *key = NULL;
8881 isc_boolean_t isself;
8882 isc_netaddr_t dstaddr;
8883 isc_result_t result;
8885 if (zone->view == NULL || zone->isself == NULL)
8888 switch (isc_sockaddr_pf(dst)) {
8890 src = zone->notifysrc4;
8891 isc_sockaddr_any(&any);
8894 src = zone->notifysrc6;
8895 isc_sockaddr_any6(&any);
8902 * When sending from any the kernel will assign a source address
8903 * that matches the destination address.
8905 if (isc_sockaddr_eqaddr(&any, &src))
8908 isc_netaddr_fromsockaddr(&dstaddr, dst);
8909 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
8910 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
8912 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
8915 dns_tsigkey_detach(&key);
8920 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
8924 * Caller holds zone lock.
8926 REQUIRE(DNS_NOTIFY_VALID(notify));
8928 if (notify->zone != NULL) {
8930 LOCK_ZONE(notify->zone);
8931 REQUIRE(LOCKED_ZONE(notify->zone));
8932 if (ISC_LINK_LINKED(notify, link))
8933 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
8935 UNLOCK_ZONE(notify->zone);
8937 zone_idetach(¬ify->zone);
8939 dns_zone_idetach(¬ify->zone);
8941 if (notify->find != NULL)
8942 dns_adb_destroyfind(¬ify->find);
8943 if (notify->request != NULL)
8944 dns_request_destroy(¬ify->request);
8945 if (dns_name_dynamic(¬ify->ns))
8946 dns_name_free(¬ify->ns, notify->mctx);
8947 mctx = notify->mctx;
8948 isc_mem_put(notify->mctx, notify, sizeof(*notify));
8949 isc_mem_detach(&mctx);
8953 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
8954 dns_notify_t *notify;
8956 REQUIRE(notifyp != NULL && *notifyp == NULL);
8958 notify = isc_mem_get(mctx, sizeof(*notify));
8960 return (ISC_R_NOMEMORY);
8962 notify->mctx = NULL;
8963 isc_mem_attach(mctx, ¬ify->mctx);
8964 notify->flags = flags;
8965 notify->zone = NULL;
8966 notify->find = NULL;
8967 notify->request = NULL;
8968 isc_sockaddr_any(¬ify->dst);
8969 dns_name_init(¬ify->ns, NULL);
8970 ISC_LINK_INIT(notify, link);
8971 notify->magic = NOTIFY_MAGIC;
8973 return (ISC_R_SUCCESS);
8977 * XXXAG should check for DNS_ZONEFLG_EXITING
8980 process_adb_event(isc_task_t *task, isc_event_t *ev) {
8981 dns_notify_t *notify;
8982 isc_eventtype_t result;
8986 notify = ev->ev_arg;
8987 REQUIRE(DNS_NOTIFY_VALID(notify));
8988 INSIST(task == notify->zone->task);
8989 result = ev->ev_type;
8990 isc_event_free(&ev);
8991 if (result == DNS_EVENT_ADBMOREADDRESSES) {
8992 dns_adb_destroyfind(¬ify->find);
8993 notify_find_address(notify);
8996 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
8997 LOCK_ZONE(notify->zone);
8998 notify_send(notify);
8999 UNLOCK_ZONE(notify->zone);
9001 notify_destroy(notify, ISC_FALSE);
9005 notify_find_address(dns_notify_t *notify) {
9006 isc_result_t result;
9007 unsigned int options;
9009 REQUIRE(DNS_NOTIFY_VALID(notify));
9010 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
9011 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
9013 if (notify->zone->view->adb == NULL)
9016 result = dns_adb_createfind(notify->zone->view->adb,
9018 process_adb_event, notify,
9019 ¬ify->ns, dns_rootname, 0,
9021 notify->zone->view->dstport,
9024 /* Something failed? */
9025 if (result != ISC_R_SUCCESS)
9028 /* More addresses pending? */
9029 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
9032 /* We have as many addresses as we can get. */
9033 LOCK_ZONE(notify->zone);
9034 notify_send(notify);
9035 UNLOCK_ZONE(notify->zone);
9038 notify_destroy(notify, ISC_FALSE);
9043 notify_send_queue(dns_notify_t *notify) {
9045 isc_result_t result;
9047 e = isc_event_allocate(notify->mctx, NULL,
9048 DNS_EVENT_NOTIFYSENDTOADDR,
9050 notify, sizeof(isc_event_t));
9052 return (ISC_R_NOMEMORY);
9054 e->ev_sender = NULL;
9055 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
9056 notify->zone->task, &e);
9057 if (result != ISC_R_SUCCESS)
9063 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
9064 dns_notify_t *notify;
9065 isc_result_t result;
9066 dns_message_t *message = NULL;
9067 isc_netaddr_t dstip;
9068 dns_tsigkey_t *key = NULL;
9069 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9072 isc_boolean_t have_notifysource = ISC_FALSE;
9074 notify = event->ev_arg;
9075 REQUIRE(DNS_NOTIFY_VALID(notify));
9079 LOCK_ZONE(notify->zone);
9081 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
9082 result = ISC_R_CANCELED;
9086 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
9087 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
9088 notify->zone->view->requestmgr == NULL ||
9089 notify->zone->db == NULL) {
9090 result = ISC_R_CANCELED;
9095 * The raw IPv4 address should also exist. Don't send to the
9098 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
9099 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
9100 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9101 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9102 "notify: ignoring IPv6 mapped IPV4 address: %s",
9104 result = ISC_R_CANCELED;
9108 result = notify_createmessage(notify->zone, notify->flags, &message);
9109 if (result != ISC_R_SUCCESS)
9112 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
9113 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9114 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
9115 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
9116 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
9117 "sent. Peer TSIG key lookup failure.", addrbuf);
9118 goto cleanup_message;
9121 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
9123 if (notify->zone->view->peers != NULL) {
9124 dns_peer_t *peer = NULL;
9125 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
9127 if (result == ISC_R_SUCCESS) {
9128 result = dns_peer_getnotifysource(peer, &src);
9129 if (result == ISC_R_SUCCESS)
9130 have_notifysource = ISC_TRUE;
9133 switch (isc_sockaddr_pf(¬ify->dst)) {
9135 if (!have_notifysource)
9136 src = notify->zone->notifysrc4;
9139 if (!have_notifysource)
9140 src = notify->zone->notifysrc6;
9143 result = ISC_R_NOTIMPLEMENTED;
9147 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
9149 result = dns_request_createvia2(notify->zone->view->requestmgr,
9150 message, &src, ¬ify->dst, 0, key,
9151 timeout * 3, timeout,
9152 notify->zone->task, notify_done,
9153 notify, ¬ify->request);
9154 if (result == ISC_R_SUCCESS) {
9155 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
9156 inc_stats(notify->zone,
9157 dns_zonestatscounter_notifyoutv4);
9159 inc_stats(notify->zone,
9160 dns_zonestatscounter_notifyoutv6);
9166 dns_tsigkey_detach(&key);
9168 dns_message_destroy(&message);
9170 UNLOCK_ZONE(notify->zone);
9171 isc_event_free(&event);
9172 if (result != ISC_R_SUCCESS)
9173 notify_destroy(notify, ISC_FALSE);
9177 notify_send(dns_notify_t *notify) {
9178 dns_adbaddrinfo_t *ai;
9180 isc_result_t result;
9181 dns_notify_t *new = NULL;
9184 * Zone lock held by caller.
9186 REQUIRE(DNS_NOTIFY_VALID(notify));
9187 REQUIRE(LOCKED_ZONE(notify->zone));
9189 for (ai = ISC_LIST_HEAD(notify->find->list);
9191 ai = ISC_LIST_NEXT(ai, publink)) {
9193 if (notify_isqueued(notify->zone, NULL, &dst))
9195 if (notify_isself(notify->zone, &dst))
9198 result = notify_create(notify->mctx,
9199 (notify->flags & DNS_NOTIFY_NOSOA),
9201 if (result != ISC_R_SUCCESS)
9203 zone_iattach(notify->zone, &new->zone);
9204 ISC_LIST_APPEND(new->zone->notifies, new, link);
9206 result = notify_send_queue(new);
9207 if (result != ISC_R_SUCCESS)
9214 notify_destroy(new, ISC_TRUE);
9218 dns_zone_notify(dns_zone_t *zone) {
9221 REQUIRE(DNS_ZONE_VALID(zone));
9224 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9227 zone_settimer(zone, &now);
9232 zone_notify(dns_zone_t *zone, isc_time_t *now) {
9233 dns_dbnode_t *node = NULL;
9234 dns_db_t *zonedb = NULL;
9235 dns_dbversion_t *version = NULL;
9236 dns_name_t *origin = NULL;
9239 dns_rdata_soa_t soa;
9240 isc_uint32_t serial;
9241 dns_rdata_t rdata = DNS_RDATA_INIT;
9242 dns_rdataset_t nsrdset;
9243 dns_rdataset_t soardset;
9244 isc_result_t result;
9245 dns_notify_t *notify = NULL;
9248 isc_boolean_t isqueued;
9249 dns_notifytype_t notifytype;
9250 unsigned int flags = 0;
9251 isc_boolean_t loggednotify = ISC_FALSE;
9253 REQUIRE(DNS_ZONE_VALID(zone));
9256 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9257 notifytype = zone->notifytype;
9258 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
9261 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
9264 if (notifytype == dns_notifytype_no)
9267 if (notifytype == dns_notifytype_masteronly &&
9268 zone->type != dns_zone_master)
9271 origin = &zone->origin;
9274 * If the zone is dialup we are done as we don't want to send
9275 * the current soa so as to force a refresh query.
9277 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
9278 flags |= DNS_NOTIFY_NOSOA;
9283 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9284 if (zone->db != NULL)
9285 dns_db_attach(zone->db, &zonedb);
9286 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9289 dns_db_currentversion(zonedb, &version);
9290 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
9291 if (result != ISC_R_SUCCESS)
9294 dns_rdataset_init(&soardset);
9295 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
9296 dns_rdatatype_none, 0, &soardset, NULL);
9297 if (result != ISC_R_SUCCESS)
9301 * Find serial and master server's name.
9303 dns_name_init(&master, NULL);
9304 result = dns_rdataset_first(&soardset);
9305 if (result != ISC_R_SUCCESS)
9307 dns_rdataset_current(&soardset, &rdata);
9308 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9309 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9310 dns_rdata_reset(&rdata);
9311 result = dns_name_dup(&soa.origin, zone->mctx, &master);
9312 serial = soa.serial;
9313 dns_rdataset_disassociate(&soardset);
9314 if (result != ISC_R_SUCCESS)
9318 * Enqueue notify requests for 'also-notify' servers.
9321 for (i = 0; i < zone->notifycnt; i++) {
9322 dst = zone->notify[i];
9323 if (notify_isqueued(zone, NULL, &dst))
9325 result = notify_create(zone->mctx, flags, ¬ify);
9326 if (result != ISC_R_SUCCESS)
9328 zone_iattach(zone, ¬ify->zone);
9330 ISC_LIST_APPEND(zone->notifies, notify, link);
9331 result = notify_send_queue(notify);
9332 if (result != ISC_R_SUCCESS)
9333 notify_destroy(notify, ISC_TRUE);
9334 if (!loggednotify) {
9335 notify_log(zone, ISC_LOG_INFO,
9336 "sending notifies (serial %u)",
9338 loggednotify = ISC_TRUE;
9344 if (notifytype == dns_notifytype_explicit)
9348 * Process NS RRset to generate notifies.
9351 dns_rdataset_init(&nsrdset);
9352 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
9353 dns_rdatatype_none, 0, &nsrdset, NULL);
9354 if (result != ISC_R_SUCCESS)
9357 result = dns_rdataset_first(&nsrdset);
9358 while (result == ISC_R_SUCCESS) {
9359 dns_rdataset_current(&nsrdset, &rdata);
9360 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9361 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9362 dns_rdata_reset(&rdata);
9364 * Don't notify the master server unless explicitly
9365 * configured to do so.
9367 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
9368 dns_name_compare(&master, &ns.name) == 0) {
9369 result = dns_rdataset_next(&nsrdset);
9373 if (!loggednotify) {
9374 notify_log(zone, ISC_LOG_INFO,
9375 "sending notifies (serial %u)",
9377 loggednotify = ISC_TRUE;
9381 isqueued = notify_isqueued(zone, &ns.name, NULL);
9384 result = dns_rdataset_next(&nsrdset);
9387 result = notify_create(zone->mctx, flags, ¬ify);
9388 if (result != ISC_R_SUCCESS)
9390 dns_zone_iattach(zone, ¬ify->zone);
9391 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
9392 if (result != ISC_R_SUCCESS) {
9394 notify_destroy(notify, ISC_TRUE);
9399 ISC_LIST_APPEND(zone->notifies, notify, link);
9401 notify_find_address(notify);
9403 result = dns_rdataset_next(&nsrdset);
9405 dns_rdataset_disassociate(&nsrdset);
9408 if (dns_name_dynamic(&master))
9409 dns_name_free(&master, zone->mctx);
9411 dns_db_detachnode(zonedb, &node);
9413 dns_db_closeversion(zonedb, &version, ISC_FALSE);
9414 dns_db_detach(&zonedb);
9421 static inline isc_result_t
9422 save_nsrrset(dns_message_t *message, dns_name_t *name,
9423 dns_db_t *db, dns_dbversion_t *version)
9425 dns_rdataset_t *nsrdataset = NULL;
9426 dns_rdataset_t *rdataset = NULL;
9427 dns_dbnode_t *node = NULL;
9429 isc_result_t result;
9430 dns_rdata_t rdata = DNS_RDATA_INIT;
9433 * Extract NS RRset from message.
9435 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
9436 dns_rdatatype_ns, dns_rdatatype_none,
9438 if (result != ISC_R_SUCCESS)
9444 result = dns_db_findnode(db, name, ISC_TRUE, &node);
9445 if (result != ISC_R_SUCCESS)
9447 result = dns_db_addrdataset(db, node, version, 0,
9448 nsrdataset, 0, NULL);
9449 dns_db_detachnode(db, &node);
9450 if (result != ISC_R_SUCCESS)
9453 * Add glue rdatasets.
9455 for (result = dns_rdataset_first(nsrdataset);
9456 result == ISC_R_SUCCESS;
9457 result = dns_rdataset_next(nsrdataset)) {
9458 dns_rdataset_current(nsrdataset, &rdata);
9459 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9460 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9461 dns_rdata_reset(&rdata);
9462 if (!dns_name_issubdomain(&ns.name, name))
9465 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9466 &ns.name, dns_rdatatype_aaaa,
9467 dns_rdatatype_none, NULL,
9469 if (result == ISC_R_SUCCESS) {
9470 result = dns_db_findnode(db, &ns.name,
9472 if (result != ISC_R_SUCCESS)
9474 result = dns_db_addrdataset(db, node, version, 0,
9476 dns_db_detachnode(db, &node);
9477 if (result != ISC_R_SUCCESS)
9481 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9482 &ns.name, dns_rdatatype_a,
9483 dns_rdatatype_none, NULL,
9485 if (result == ISC_R_SUCCESS) {
9486 result = dns_db_findnode(db, &ns.name,
9488 if (result != ISC_R_SUCCESS)
9490 result = dns_db_addrdataset(db, node, version, 0,
9492 dns_db_detachnode(db, &node);
9493 if (result != ISC_R_SUCCESS)
9497 if (result != ISC_R_NOMORE)
9500 return (ISC_R_SUCCESS);
9507 stub_callback(isc_task_t *task, isc_event_t *event) {
9508 const char me[] = "stub_callback";
9509 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9510 dns_stub_t *stub = NULL;
9511 dns_message_t *msg = NULL;
9512 dns_zone_t *zone = NULL;
9513 char master[ISC_SOCKADDR_FORMATSIZE];
9514 char source[ISC_SOCKADDR_FORMATSIZE];
9515 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
9516 isc_result_t result;
9518 isc_boolean_t exiting = ISC_FALSE;
9520 unsigned int j, soacount;
9522 stub = revent->ev_arg;
9523 INSIST(DNS_STUB_VALID(stub));
9535 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9536 zone_debuglog(zone, me, 1, "exiting");
9541 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9542 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9544 if (revent->result != ISC_R_SUCCESS) {
9545 if (revent->result == ISC_R_TIMEDOUT &&
9546 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9547 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9548 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9549 "refreshing stub: timeout retrying "
9550 " without EDNS master %s (source %s)",
9554 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
9555 &zone->sourceaddr, &now);
9556 dns_zone_log(zone, ISC_LOG_INFO,
9557 "could not refresh stub from master %s"
9558 " (source %s): %s", master, source,
9559 dns_result_totext(revent->result));
9563 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9564 if (result != ISC_R_SUCCESS)
9567 result = dns_request_getresponse(revent->request, msg, 0);
9568 if (result != ISC_R_SUCCESS)
9574 if (msg->rcode != dns_rcode_noerror) {
9578 isc_buffer_init(&rb, rcode, sizeof(rcode));
9579 (void)dns_rcode_totext(msg->rcode, &rb);
9581 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9582 (msg->rcode == dns_rcode_servfail ||
9583 msg->rcode == dns_rcode_notimp ||
9584 msg->rcode == dns_rcode_formerr)) {
9585 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9586 "refreshing stub: rcode (%.*s) retrying "
9587 "without EDNS master %s (source %s)",
9588 (int)rb.used, rcode, master, source);
9589 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9593 dns_zone_log(zone, ISC_LOG_INFO,
9595 "unexpected rcode (%.*s) from %s (source %s)",
9596 (int)rb.used, rcode, master, source);
9601 * We need complete messages.
9603 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9604 if (dns_request_usedtcp(revent->request)) {
9605 dns_zone_log(zone, ISC_LOG_INFO,
9606 "refreshing stub: truncated TCP "
9607 "response from master %s (source %s)",
9611 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9616 * If non-auth log and next master.
9618 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9619 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
9620 "non-authoritative answer from "
9621 "master %s (source %s)", master, source);
9628 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9629 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
9631 if (cnamecnt != 0) {
9632 dns_zone_log(zone, ISC_LOG_INFO,
9633 "refreshing stub: unexpected CNAME response "
9634 "from master %s (source %s)", master, source);
9639 dns_zone_log(zone, ISC_LOG_INFO,
9640 "refreshing stub: no NS records in response "
9641 "from master %s (source %s)", master, source);
9648 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
9649 if (result != ISC_R_SUCCESS) {
9650 dns_zone_log(zone, ISC_LOG_INFO,
9651 "refreshing stub: unable to save NS records "
9652 "from master %s (source %s)", master, source);
9659 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
9660 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9661 if (zone->db == NULL)
9662 zone_attachdb(zone, stub->db);
9663 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
9664 &refresh, &retry, &expire, NULL, NULL);
9665 if (result == ISC_R_SUCCESS && soacount > 0U) {
9666 zone->refresh = RANGE(refresh, zone->minrefresh,
9668 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
9669 zone->expire = RANGE(expire, zone->refresh + zone->retry,
9671 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9673 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9674 dns_db_detach(&stub->db);
9676 dns_message_destroy(&msg);
9677 isc_event_free(&event);
9678 dns_request_destroy(&zone->request);
9680 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9681 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
9682 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9683 isc_interval_set(&i, zone->expire, 0);
9684 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9686 if (zone->masterfile != NULL)
9687 zone_needdump(zone, 0);
9689 zone_settimer(zone, &now);
9693 if (stub->version != NULL)
9694 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
9695 if (stub->db != NULL)
9696 dns_db_detach(&stub->db);
9698 dns_message_destroy(&msg);
9699 isc_event_free(&event);
9700 dns_request_destroy(&zone->request);
9702 * Skip to next failed / untried master.
9706 } while (zone->curmaster < zone->masterscnt &&
9707 zone->mastersok[zone->curmaster]);
9708 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9709 if (exiting || zone->curmaster >= zone->masterscnt) {
9710 isc_boolean_t done = ISC_TRUE;
9712 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9713 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9715 * Did we get a good answer from all the masters?
9717 for (j = 0; j < zone->masterscnt; j++)
9718 if (zone->mastersok[j] == ISC_FALSE) {
9725 zone->curmaster = 0;
9727 * Find the next failed master.
9729 while (zone->curmaster < zone->masterscnt &&
9730 zone->mastersok[zone->curmaster])
9732 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9734 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9736 zone_settimer(zone, &now);
9740 queue_soa_query(zone);
9745 dns_message_destroy(&msg);
9746 isc_event_free(&event);
9747 dns_request_destroy(&zone->request);
9748 ns_query(zone, NULL, stub);
9755 dns_zone_idetach(&stub->zone);
9756 INSIST(stub->db == NULL);
9757 INSIST(stub->version == NULL);
9758 isc_mem_put(stub->mctx, stub, sizeof(*stub));
9761 INSIST(event == NULL);
9766 * An SOA query has finished (successfully or not).
9769 refresh_callback(isc_task_t *task, isc_event_t *event) {
9770 const char me[] = "refresh_callback";
9771 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9773 dns_message_t *msg = NULL;
9774 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
9776 char master[ISC_SOCKADDR_FORMATSIZE];
9777 char source[ISC_SOCKADDR_FORMATSIZE];
9778 dns_rdataset_t *rdataset = NULL;
9779 dns_rdata_t rdata = DNS_RDATA_INIT;
9780 dns_rdata_soa_t soa;
9781 isc_result_t result;
9782 isc_uint32_t serial, oldserial = 0;
9784 isc_boolean_t do_queue_xfrin = ISC_FALSE;
9786 zone = revent->ev_arg;
9787 INSIST(DNS_ZONE_VALID(zone));
9798 * if timeout log and next master;
9801 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9802 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9804 if (revent->result != ISC_R_SUCCESS) {
9805 if (revent->result == ISC_R_TIMEDOUT &&
9806 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9807 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9808 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9809 "refresh: timeout retrying without EDNS "
9810 "master %s (source %s)", master, source);
9813 if (revent->result == ISC_R_TIMEDOUT &&
9814 !dns_request_usedtcp(revent->request)) {
9815 dns_zone_log(zone, ISC_LOG_INFO,
9816 "refresh: retry limit for "
9817 "master %s exceeded (source %s)",
9819 /* Try with slave with TCP. */
9820 if (zone->type == dns_zone_slave &&
9821 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
9822 if (!dns_zonemgr_unreachable(zone->zmgr,
9827 DNS_ZONE_SETFLAG(zone,
9828 DNS_ZONEFLG_SOABEFOREAXFR);
9831 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9832 "refresh: skipped tcp fallback "
9833 "as master %s (source %s) is "
9834 "unreachable (cached)",
9838 dns_zone_log(zone, ISC_LOG_INFO,
9839 "refresh: failure trying master "
9840 "%s (source %s): %s", master, source,
9841 dns_result_totext(revent->result));
9845 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9846 if (result != ISC_R_SUCCESS)
9848 result = dns_request_getresponse(revent->request, msg, 0);
9849 if (result != ISC_R_SUCCESS) {
9850 dns_zone_log(zone, ISC_LOG_INFO,
9851 "refresh: failure trying master "
9852 "%s (source %s): %s", master, source,
9853 dns_result_totext(result));
9860 if (msg->rcode != dns_rcode_noerror) {
9864 isc_buffer_init(&rb, rcode, sizeof(rcode));
9865 (void)dns_rcode_totext(msg->rcode, &rb);
9867 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9868 (msg->rcode == dns_rcode_servfail ||
9869 msg->rcode == dns_rcode_notimp ||
9870 msg->rcode == dns_rcode_formerr)) {
9871 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9872 "refresh: rcode (%.*s) retrying without "
9873 "EDNS master %s (source %s)",
9874 (int)rb.used, rcode, master, source);
9875 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9878 dns_zone_log(zone, ISC_LOG_INFO,
9879 "refresh: unexpected rcode (%.*s) from "
9880 "master %s (source %s)", (int)rb.used, rcode,
9883 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
9885 if (msg->rcode == dns_rcode_refused &&
9886 zone->type == dns_zone_slave)
9892 * If truncated punt to zone transfer which will query again.
9894 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9895 if (zone->type == dns_zone_slave) {
9896 dns_zone_log(zone, ISC_LOG_INFO,
9897 "refresh: truncated UDP answer, "
9898 "initiating TCP zone xfer "
9899 "for master %s (source %s)",
9901 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9904 INSIST(zone->type == dns_zone_stub);
9905 if (dns_request_usedtcp(revent->request)) {
9906 dns_zone_log(zone, ISC_LOG_INFO,
9907 "refresh: truncated TCP response "
9908 "from master %s (source %s)",
9912 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9918 * if non-auth log and next master;
9920 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9921 dns_zone_log(zone, ISC_LOG_INFO,
9922 "refresh: non-authoritative answer from "
9923 "master %s (source %s)", master, source);
9927 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9928 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
9929 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
9930 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
9934 * There should not be a CNAME record at top of zone.
9936 if (cnamecnt != 0) {
9937 dns_zone_log(zone, ISC_LOG_INFO,
9938 "refresh: CNAME at top of zone "
9939 "in master %s (source %s)", master, source);
9944 * if referral log and next master;
9946 if (soacnt == 0 && soacount == 0 && nscount != 0) {
9947 dns_zone_log(zone, ISC_LOG_INFO,
9948 "refresh: referral response "
9949 "from master %s (source %s)", master, source);
9954 * if nodata log and next master;
9956 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
9957 dns_zone_log(zone, ISC_LOG_INFO,
9958 "refresh: NODATA response "
9959 "from master %s (source %s)", master, source);
9964 * Only one soa at top of zone.
9967 dns_zone_log(zone, ISC_LOG_INFO,
9968 "refresh: answer SOA count (%d) != 1 "
9969 "from master %s (source %s)",
9970 soacnt, master, source);
9978 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
9979 dns_rdatatype_soa, dns_rdatatype_none,
9981 if (result != ISC_R_SUCCESS) {
9982 dns_zone_log(zone, ISC_LOG_INFO,
9983 "refresh: unable to get SOA record "
9984 "from master %s (source %s)", master, source);
9988 result = dns_rdataset_first(rdataset);
9989 if (result != ISC_R_SUCCESS) {
9990 dns_zone_log(zone, ISC_LOG_INFO,
9991 "refresh: dns_rdataset_first() failed");
9995 dns_rdataset_current(rdataset, &rdata);
9996 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9997 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9999 serial = soa.serial;
10000 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10001 unsigned int soacount;
10002 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
10003 &oldserial, NULL, NULL, NULL, NULL,
10005 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10006 RUNTIME_CHECK(soacount > 0U);
10007 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
10008 serial, oldserial);
10010 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
10013 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
10014 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
10015 isc_serial_gt(serial, oldserial)) {
10016 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10017 &zone->sourceaddr, &now))
10019 dns_zone_log(zone, ISC_LOG_INFO,
10020 "refresh: skipping %s as master %s "
10021 "(source %s) is unreachable (cached)",
10022 zone->type == dns_zone_slave ?
10023 "zone transfer" : "NS query",
10028 isc_event_free(&event);
10029 dns_request_destroy(&zone->request);
10030 if (zone->type == dns_zone_slave) {
10031 do_queue_xfrin = ISC_TRUE;
10033 INSIST(zone->type == dns_zone_stub);
10034 ns_query(zone, rdataset, NULL);
10037 dns_message_destroy(&msg);
10038 } else if (isc_serial_eq(soa.serial, oldserial)) {
10039 if (zone->masterfile != NULL) {
10040 result = ISC_R_FAILURE;
10041 if (zone->journal != NULL)
10042 result = isc_file_settime(zone->journal, &now);
10043 if (result == ISC_R_SUCCESS &&
10044 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10045 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10046 result = isc_file_settime(zone->masterfile,
10048 } else if (result != ISC_R_SUCCESS)
10049 result = isc_file_settime(zone->masterfile,
10051 /* Someone removed the file from underneath us! */
10052 if (result == ISC_R_FILENOTFOUND) {
10053 zone_needdump(zone, DNS_DUMP_DELAY);
10054 } else if (result != ISC_R_SUCCESS)
10055 dns_zone_log(zone, ISC_LOG_ERROR,
10056 "refresh: could not set file "
10057 "modification time of '%s': %s",
10059 dns_result_totext(result));
10061 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10062 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10063 zone->mastersok[zone->curmaster] = ISC_TRUE;
10066 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
10067 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
10068 "received from master %s < ours (%u)",
10069 soa.serial, master, oldserial);
10071 zone_debuglog(zone, me, 1, "ahead");
10072 zone->mastersok[zone->curmaster] = ISC_TRUE;
10076 dns_message_destroy(&msg);
10081 dns_message_destroy(&msg);
10082 isc_event_free(&event);
10083 dns_request_destroy(&zone->request);
10085 * Skip to next failed / untried master.
10089 } while (zone->curmaster < zone->masterscnt &&
10090 zone->mastersok[zone->curmaster]);
10091 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10092 if (zone->curmaster >= zone->masterscnt) {
10093 isc_boolean_t done = ISC_TRUE;
10094 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10095 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10097 * Did we get a good answer from all the masters?
10099 for (j = 0; j < zone->masterscnt; j++)
10100 if (zone->mastersok[j] == ISC_FALSE) {
10107 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10108 zone->curmaster = 0;
10110 * Find the next failed master.
10112 while (zone->curmaster < zone->masterscnt &&
10113 zone->mastersok[zone->curmaster])
10117 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10118 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
10119 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
10120 zone->refreshtime = now;
10122 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10123 zone_settimer(zone, &now);
10128 queue_soa_query(zone);
10133 dns_message_destroy(&msg);
10134 isc_event_free(&event);
10135 dns_request_destroy(&zone->request);
10136 queue_soa_query(zone);
10140 if (do_queue_xfrin)
10142 dns_zone_idetach(&zone);
10147 queue_soa_query(dns_zone_t *zone) {
10148 const char me[] = "queue_soa_query";
10150 dns_zone_t *dummy = NULL;
10151 isc_result_t result;
10157 REQUIRE(LOCKED_ZONE(zone));
10159 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10160 cancel_refresh(zone);
10164 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
10165 soa_query, zone, sizeof(isc_event_t));
10167 cancel_refresh(zone);
10172 * Attach so that we won't clean up
10173 * until the event is delivered.
10175 zone_iattach(zone, &dummy);
10178 e->ev_sender = NULL;
10179 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
10180 if (result != ISC_R_SUCCESS) {
10181 zone_idetach(&dummy);
10182 isc_event_free(&e);
10183 cancel_refresh(zone);
10187 static inline isc_result_t
10188 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
10189 dns_message_t **messagep)
10191 dns_message_t *message = NULL;
10192 dns_name_t *qname = NULL;
10193 dns_rdataset_t *qrdataset = NULL;
10194 isc_result_t result;
10196 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10198 if (result != ISC_R_SUCCESS)
10201 message->opcode = dns_opcode_query;
10202 message->rdclass = zone->rdclass;
10204 result = dns_message_gettempname(message, &qname);
10205 if (result != ISC_R_SUCCESS)
10208 result = dns_message_gettemprdataset(message, &qrdataset);
10209 if (result != ISC_R_SUCCESS)
10215 dns_name_init(qname, NULL);
10216 dns_name_clone(&zone->origin, qname);
10217 dns_rdataset_init(qrdataset);
10218 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
10219 ISC_LIST_APPEND(qname->list, qrdataset, link);
10220 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
10222 *messagep = message;
10223 return (ISC_R_SUCCESS);
10227 dns_message_puttempname(message, &qname);
10228 if (qrdataset != NULL)
10229 dns_message_puttemprdataset(message, &qrdataset);
10230 if (message != NULL)
10231 dns_message_destroy(&message);
10235 static isc_result_t
10236 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
10237 dns_rdataset_t *rdataset = NULL;
10238 dns_rdatalist_t *rdatalist = NULL;
10239 dns_rdata_t *rdata = NULL;
10240 isc_result_t result;
10242 result = dns_message_gettemprdatalist(message, &rdatalist);
10243 if (result != ISC_R_SUCCESS)
10245 result = dns_message_gettemprdata(message, &rdata);
10246 if (result != ISC_R_SUCCESS)
10248 result = dns_message_gettemprdataset(message, &rdataset);
10249 if (result != ISC_R_SUCCESS)
10251 dns_rdataset_init(rdataset);
10253 rdatalist->type = dns_rdatatype_opt;
10254 rdatalist->covers = 0;
10257 * Set Maximum UDP buffer size.
10259 rdatalist->rdclass = udpsize;
10262 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
10264 rdatalist->ttl = 0;
10266 /* Set EDNS options if applicable */
10268 unsigned char data[4];
10271 isc_buffer_init(&buf, data, sizeof(data));
10272 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
10273 isc_buffer_putuint16(&buf, 0);
10274 rdata->data = data;
10275 rdata->length = sizeof(data);
10277 rdata->data = NULL;
10281 rdata->rdclass = rdatalist->rdclass;
10282 rdata->type = rdatalist->type;
10285 ISC_LIST_INIT(rdatalist->rdata);
10286 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
10287 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
10290 return (dns_message_setopt(message, rdataset));
10293 if (rdatalist != NULL)
10294 dns_message_puttemprdatalist(message, &rdatalist);
10295 if (rdataset != NULL)
10296 dns_message_puttemprdataset(message, &rdataset);
10298 dns_message_puttemprdata(message, &rdata);
10304 soa_query(isc_task_t *task, isc_event_t *event) {
10305 const char me[] = "soa_query";
10306 isc_result_t result = ISC_R_FAILURE;
10307 dns_message_t *message = NULL;
10308 dns_zone_t *zone = event->ev_arg;
10309 dns_zone_t *dummy = NULL;
10310 isc_netaddr_t masterip;
10311 dns_tsigkey_t *key = NULL;
10312 isc_uint32_t options;
10313 isc_boolean_t cancel = ISC_TRUE;
10315 isc_boolean_t have_xfrsource, reqnsid;
10316 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10318 REQUIRE(DNS_ZONE_VALID(zone));
10325 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
10326 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
10327 zone->view->requestmgr == NULL) {
10328 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10329 cancel = ISC_FALSE;
10334 * XXX Optimisation: Create message when zone is setup and reuse.
10336 result = create_query(zone, dns_rdatatype_soa, &message);
10337 if (result != ISC_R_SUCCESS)
10341 INSIST(zone->masterscnt > 0);
10342 INSIST(zone->curmaster < zone->masterscnt);
10344 zone->masteraddr = zone->masters[zone->curmaster];
10346 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10348 * First, look for a tsig key in the master statement, then
10349 * try for a server key.
10351 if ((zone->masterkeynames != NULL) &&
10352 (zone->masterkeynames[zone->curmaster] != NULL)) {
10353 dns_view_t *view = dns_zone_getview(zone);
10354 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10355 result = dns_view_gettsig(view, keyname, &key);
10356 if (result != ISC_R_SUCCESS) {
10357 char namebuf[DNS_NAME_FORMATSIZE];
10358 dns_name_format(keyname, namebuf, sizeof(namebuf));
10359 dns_zone_log(zone, ISC_LOG_ERROR,
10360 "unable to find key: %s", namebuf);
10365 result = dns_view_getpeertsig(zone->view, &masterip, &key);
10366 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10367 char addrbuf[ISC_NETADDR_FORMATSIZE];
10368 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
10369 dns_zone_log(zone, ISC_LOG_ERROR,
10370 "unable to find TSIG key for %s", addrbuf);
10375 have_xfrsource = ISC_FALSE;
10376 reqnsid = zone->view->requestnsid;
10377 if (zone->view->peers != NULL) {
10378 dns_peer_t *peer = NULL;
10379 isc_boolean_t edns;
10380 result = dns_peerlist_peerbyaddr(zone->view->peers,
10382 if (result == ISC_R_SUCCESS) {
10383 result = dns_peer_getsupportedns(peer, &edns);
10384 if (result == ISC_R_SUCCESS && !edns)
10385 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10386 result = dns_peer_gettransfersource(peer,
10387 &zone->sourceaddr);
10388 if (result == ISC_R_SUCCESS)
10389 have_xfrsource = ISC_TRUE;
10390 if (zone->view->resolver != NULL)
10392 dns_resolver_getudpsize(zone->view->resolver);
10393 (void)dns_peer_getudpsize(peer, &udpsize);
10394 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10398 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10400 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10401 if (isc_sockaddr_equal(&zone->altxfrsource4,
10402 &zone->xfrsource4))
10404 zone->sourceaddr = zone->altxfrsource4;
10405 } else if (!have_xfrsource)
10406 zone->sourceaddr = zone->xfrsource4;
10409 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10410 if (isc_sockaddr_equal(&zone->altxfrsource6,
10411 &zone->xfrsource6))
10413 zone->sourceaddr = zone->altxfrsource6;
10414 } else if (!have_xfrsource)
10415 zone->sourceaddr = zone->xfrsource6;
10418 result = ISC_R_NOTIMPLEMENTED;
10422 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
10423 DNS_REQUESTOPT_TCP : 0;
10425 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10426 result = add_opt(message, udpsize, reqnsid);
10427 if (result != ISC_R_SUCCESS)
10428 zone_debuglog(zone, me, 1,
10429 "unable to add opt record: %s",
10430 dns_result_totext(result));
10433 zone_iattach(zone, &dummy);
10435 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10437 result = dns_request_createvia2(zone->view->requestmgr, message,
10438 &zone->sourceaddr, &zone->masteraddr,
10439 options, key, timeout * 3, timeout,
10440 zone->task, refresh_callback, zone,
10442 if (result != ISC_R_SUCCESS) {
10443 zone_idetach(&dummy);
10444 zone_debuglog(zone, me, 1,
10445 "dns_request_createvia2() failed: %s",
10446 dns_result_totext(result));
10449 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
10450 inc_stats(zone, dns_zonestatscounter_soaoutv4);
10452 inc_stats(zone, dns_zonestatscounter_soaoutv6);
10454 cancel = ISC_FALSE;
10458 dns_tsigkey_detach(&key);
10459 if (result != ISC_R_SUCCESS)
10460 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10461 if (message != NULL)
10462 dns_message_destroy(&message);
10464 cancel_refresh(zone);
10465 isc_event_free(&event);
10467 dns_zone_idetach(&zone);
10472 dns_tsigkey_detach(&key);
10474 * Skip to next failed / untried master.
10478 } while (zone->curmaster < zone->masterscnt &&
10479 zone->mastersok[zone->curmaster]);
10480 if (zone->curmaster < zone->masterscnt)
10482 zone->curmaster = 0;
10487 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
10488 const char me[] = "ns_query";
10489 isc_result_t result;
10490 dns_message_t *message = NULL;
10491 isc_netaddr_t masterip;
10492 dns_tsigkey_t *key = NULL;
10493 dns_dbnode_t *node = NULL;
10495 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
10496 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10498 REQUIRE(DNS_ZONE_VALID(zone));
10499 REQUIRE(LOCKED_ZONE(zone));
10500 REQUIRE((soardataset != NULL && stub == NULL) ||
10501 (soardataset == NULL && stub != NULL));
10502 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
10506 if (stub == NULL) {
10507 stub = isc_mem_get(zone->mctx, sizeof(*stub));
10510 stub->magic = STUB_MAGIC;
10511 stub->mctx = zone->mctx;
10514 stub->version = NULL;
10517 * Attach so that the zone won't disappear from under us.
10519 zone_iattach(zone, &stub->zone);
10522 * If a db exists we will update it, otherwise we create a
10523 * new one and attach it to the zone once we have the NS
10526 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10527 if (zone->db != NULL) {
10528 dns_db_attach(zone->db, &stub->db);
10529 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10531 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10533 INSIST(zone->db_argc >= 1);
10534 result = dns_db_create(zone->mctx, zone->db_argv[0],
10535 &zone->origin, dns_dbtype_stub,
10540 if (result != ISC_R_SUCCESS) {
10541 dns_zone_log(zone, ISC_LOG_ERROR,
10542 "refreshing stub: "
10543 "could not create "
10545 dns_result_totext(result));
10548 dns_db_settask(stub->db, zone->task);
10551 result = dns_db_newversion(stub->db, &stub->version);
10552 if (result != ISC_R_SUCCESS) {
10553 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10554 "dns_db_newversion() failed: %s",
10555 dns_result_totext(result));
10560 * Update SOA record.
10562 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
10564 if (result != ISC_R_SUCCESS) {
10565 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10566 "dns_db_findnode() failed: %s",
10567 dns_result_totext(result));
10571 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
10572 soardataset, 0, NULL);
10573 dns_db_detachnode(stub->db, &node);
10574 if (result != ISC_R_SUCCESS) {
10575 dns_zone_log(zone, ISC_LOG_INFO,
10576 "refreshing stub: "
10577 "dns_db_addrdataset() failed: %s",
10578 dns_result_totext(result));
10584 * XXX Optimisation: Create message when zone is setup and reuse.
10586 result = create_query(zone, dns_rdatatype_ns, &message);
10587 INSIST(result == ISC_R_SUCCESS);
10589 INSIST(zone->masterscnt > 0);
10590 INSIST(zone->curmaster < zone->masterscnt);
10591 zone->masteraddr = zone->masters[zone->curmaster];
10593 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10595 * First, look for a tsig key in the master statement, then
10596 * try for a server key.
10598 if ((zone->masterkeynames != NULL) &&
10599 (zone->masterkeynames[zone->curmaster] != NULL)) {
10600 dns_view_t *view = dns_zone_getview(zone);
10601 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10602 result = dns_view_gettsig(view, keyname, &key);
10603 if (result != ISC_R_SUCCESS) {
10604 char namebuf[DNS_NAME_FORMATSIZE];
10605 dns_name_format(keyname, namebuf, sizeof(namebuf));
10606 dns_zone_log(zone, ISC_LOG_ERROR,
10607 "unable to find key: %s", namebuf);
10611 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
10613 reqnsid = zone->view->requestnsid;
10614 if (zone->view->peers != NULL) {
10615 dns_peer_t *peer = NULL;
10616 isc_boolean_t edns;
10617 result = dns_peerlist_peerbyaddr(zone->view->peers,
10619 if (result == ISC_R_SUCCESS) {
10620 result = dns_peer_getsupportedns(peer, &edns);
10621 if (result == ISC_R_SUCCESS && !edns)
10622 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10623 result = dns_peer_gettransfersource(peer,
10624 &zone->sourceaddr);
10625 if (result == ISC_R_SUCCESS)
10626 have_xfrsource = ISC_TRUE;
10627 if (zone->view->resolver != NULL)
10629 dns_resolver_getudpsize(zone->view->resolver);
10630 (void)dns_peer_getudpsize(peer, &udpsize);
10631 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10635 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10636 result = add_opt(message, udpsize, reqnsid);
10637 if (result != ISC_R_SUCCESS)
10638 zone_debuglog(zone, me, 1,
10639 "unable to add opt record: %s",
10640 dns_result_totext(result));
10644 * Always use TCP so that we shouldn't truncate in additional section.
10646 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10648 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10649 zone->sourceaddr = zone->altxfrsource4;
10650 else if (!have_xfrsource)
10651 zone->sourceaddr = zone->xfrsource4;
10654 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10655 zone->sourceaddr = zone->altxfrsource6;
10656 else if (!have_xfrsource)
10657 zone->sourceaddr = zone->xfrsource6;
10660 result = ISC_R_NOTIMPLEMENTED;
10665 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10667 result = dns_request_createvia2(zone->view->requestmgr, message,
10668 &zone->sourceaddr, &zone->masteraddr,
10669 DNS_REQUESTOPT_TCP, key, timeout * 3,
10670 timeout, zone->task, stub_callback,
10671 stub, &zone->request);
10672 if (result != ISC_R_SUCCESS) {
10673 zone_debuglog(zone, me, 1,
10674 "dns_request_createvia() failed: %s",
10675 dns_result_totext(result));
10678 dns_message_destroy(&message);
10682 cancel_refresh(zone);
10683 if (stub != NULL) {
10685 if (stub->version != NULL)
10686 dns_db_closeversion(stub->db, &stub->version,
10688 if (stub->db != NULL)
10689 dns_db_detach(&stub->db);
10690 if (stub->zone != NULL)
10691 zone_idetach(&stub->zone);
10692 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10694 if (message != NULL)
10695 dns_message_destroy(&message);
10698 dns_tsigkey_detach(&key);
10703 * Handle the control event. Note that although this event causes the zone
10704 * to shut down, it is not a shutdown event in the sense of the task library.
10707 zone_shutdown(isc_task_t *task, isc_event_t *event) {
10708 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
10709 isc_boolean_t free_needed, linked = ISC_FALSE;
10712 REQUIRE(DNS_ZONE_VALID(zone));
10713 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
10714 INSIST(isc_refcount_current(&zone->erefs) == 0);
10716 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
10719 * Stop things being restarted after we cancel them below.
10722 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
10726 * If we were waiting for xfrin quota, step out of
10728 * If there's no zone manager, we can't be waiting for the
10731 if (zone->zmgr != NULL) {
10732 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10733 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
10734 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
10737 zone->statelist = NULL;
10739 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10743 * In task context, no locking required. See zone_xfrdone().
10745 if (zone->xfr != NULL)
10746 dns_xfrin_shutdown(zone->xfr);
10750 INSIST(zone->irefs > 0);
10753 if (zone->request != NULL) {
10754 dns_request_cancel(zone->request);
10757 if (zone->readio != NULL)
10758 zonemgr_cancelio(zone->readio);
10760 if (zone->lctx != NULL)
10761 dns_loadctx_cancel(zone->lctx);
10763 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10764 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10765 if (zone->writeio != NULL)
10766 zonemgr_cancelio(zone->writeio);
10768 if (zone->dctx != NULL)
10769 dns_dumpctx_cancel(zone->dctx);
10772 notify_cancel(zone);
10774 forward_cancel(zone);
10776 if (zone->timer != NULL) {
10777 isc_timer_detach(&zone->timer);
10778 INSIST(zone->irefs > 0);
10782 if (zone->view != NULL)
10783 dns_view_weakdetach(&zone->view);
10786 * We have now canceled everything set the flag to allow exit_check()
10787 * to succeed. We must not unlock between setting this flag and
10788 * calling exit_check().
10790 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
10791 free_needed = exit_check(zone);
10798 zone_timer(isc_task_t *task, isc_event_t *event) {
10799 const char me[] = "zone_timer";
10800 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
10803 REQUIRE(DNS_ZONE_VALID(zone));
10807 zone_maintenance(zone);
10809 isc_event_free(&event);
10813 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
10814 const char me[] = "zone_settimer";
10816 isc_result_t result;
10819 REQUIRE(DNS_ZONE_VALID(zone));
10820 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10823 isc_time_settoepoch(&next);
10825 switch (zone->type) {
10826 case dns_zone_master:
10827 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10828 next = zone->notifytime;
10829 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10830 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10831 INSIST(!isc_time_isepoch(&zone->dumptime));
10832 if (isc_time_isepoch(&next) ||
10833 isc_time_compare(&zone->dumptime, &next) < 0)
10834 next = zone->dumptime;
10836 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
10837 !isc_time_isepoch(&zone->refreshkeytime)) {
10838 if (isc_time_isepoch(&next) ||
10839 isc_time_compare(&zone->refreshkeytime, &next) < 0)
10840 next = zone->refreshkeytime;
10842 if (!isc_time_isepoch(&zone->resigntime)) {
10843 if (isc_time_isepoch(&next) ||
10844 isc_time_compare(&zone->resigntime, &next) < 0)
10845 next = zone->resigntime;
10847 if (!isc_time_isepoch(&zone->keywarntime)) {
10848 if (isc_time_isepoch(&next) ||
10849 isc_time_compare(&zone->keywarntime, &next) < 0)
10850 next = zone->keywarntime;
10852 if (!isc_time_isepoch(&zone->signingtime)) {
10853 if (isc_time_isepoch(&next) ||
10854 isc_time_compare(&zone->signingtime, &next) < 0)
10855 next = zone->signingtime;
10857 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
10858 if (isc_time_isepoch(&next) ||
10859 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
10860 next = zone->nsec3chaintime;
10864 case dns_zone_slave:
10865 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10866 next = zone->notifytime;
10869 case dns_zone_stub:
10870 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
10871 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
10872 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
10873 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
10874 INSIST(!isc_time_isepoch(&zone->refreshtime));
10875 if (isc_time_isepoch(&next) ||
10876 isc_time_compare(&zone->refreshtime, &next) < 0)
10877 next = zone->refreshtime;
10879 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10880 !isc_time_isepoch(&zone->expiretime)) {
10881 if (isc_time_isepoch(&next) ||
10882 isc_time_compare(&zone->expiretime, &next) < 0)
10883 next = zone->expiretime;
10885 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10886 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10887 INSIST(!isc_time_isepoch(&zone->dumptime));
10888 if (isc_time_isepoch(&next) ||
10889 isc_time_compare(&zone->dumptime, &next) < 0)
10890 next = zone->dumptime;
10895 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10896 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10897 INSIST(!isc_time_isepoch(&zone->dumptime));
10898 if (isc_time_isepoch(&next) ||
10899 isc_time_compare(&zone->dumptime, &next) < 0)
10900 next = zone->dumptime;
10902 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
10903 if (isc_time_isepoch(&next) ||
10904 (!isc_time_isepoch(&zone->refreshkeytime) &&
10905 isc_time_compare(&zone->refreshkeytime, &next) < 0))
10906 next = zone->refreshkeytime;
10914 if (isc_time_isepoch(&next)) {
10915 zone_debuglog(zone, me, 10, "settimer inactive");
10916 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
10917 NULL, NULL, ISC_TRUE);
10918 if (result != ISC_R_SUCCESS)
10919 dns_zone_log(zone, ISC_LOG_ERROR,
10920 "could not deactivate zone timer: %s",
10921 isc_result_totext(result));
10923 if (isc_time_compare(&next, now) <= 0)
10925 result = isc_timer_reset(zone->timer, isc_timertype_once,
10926 &next, NULL, ISC_TRUE);
10927 if (result != ISC_R_SUCCESS)
10928 dns_zone_log(zone, ISC_LOG_ERROR,
10929 "could not reset zone timer: %s",
10930 isc_result_totext(result));
10935 cancel_refresh(dns_zone_t *zone) {
10936 const char me[] = "cancel_refresh";
10940 * 'zone' locked by caller.
10943 REQUIRE(DNS_ZONE_VALID(zone));
10944 REQUIRE(LOCKED_ZONE(zone));
10948 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10950 zone_settimer(zone, &now);
10953 static isc_result_t
10954 notify_createmessage(dns_zone_t *zone, unsigned int flags,
10955 dns_message_t **messagep)
10957 dns_db_t *zonedb = NULL;
10958 dns_dbnode_t *node = NULL;
10959 dns_dbversion_t *version = NULL;
10960 dns_message_t *message = NULL;
10961 dns_rdataset_t rdataset;
10962 dns_rdata_t rdata = DNS_RDATA_INIT;
10964 dns_name_t *tempname = NULL;
10965 dns_rdata_t *temprdata = NULL;
10966 dns_rdatalist_t *temprdatalist = NULL;
10967 dns_rdataset_t *temprdataset = NULL;
10969 isc_result_t result;
10971 isc_buffer_t *b = NULL;
10973 REQUIRE(DNS_ZONE_VALID(zone));
10974 REQUIRE(messagep != NULL && *messagep == NULL);
10976 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10978 if (result != ISC_R_SUCCESS)
10981 message->opcode = dns_opcode_notify;
10982 message->flags |= DNS_MESSAGEFLAG_AA;
10983 message->rdclass = zone->rdclass;
10985 result = dns_message_gettempname(message, &tempname);
10986 if (result != ISC_R_SUCCESS)
10989 result = dns_message_gettemprdataset(message, &temprdataset);
10990 if (result != ISC_R_SUCCESS)
10996 dns_name_init(tempname, NULL);
10997 dns_name_clone(&zone->origin, tempname);
10998 dns_rdataset_init(temprdataset);
10999 dns_rdataset_makequestion(temprdataset, zone->rdclass,
11000 dns_rdatatype_soa);
11001 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11002 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
11004 temprdataset = NULL;
11006 if ((flags & DNS_NOTIFY_NOSOA) != 0)
11009 result = dns_message_gettempname(message, &tempname);
11010 if (result != ISC_R_SUCCESS)
11012 result = dns_message_gettemprdata(message, &temprdata);
11013 if (result != ISC_R_SUCCESS)
11015 result = dns_message_gettemprdataset(message, &temprdataset);
11016 if (result != ISC_R_SUCCESS)
11018 result = dns_message_gettemprdatalist(message, &temprdatalist);
11019 if (result != ISC_R_SUCCESS)
11022 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11023 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
11024 dns_db_attach(zone->db, &zonedb);
11025 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11027 dns_name_init(tempname, NULL);
11028 dns_name_clone(&zone->origin, tempname);
11029 dns_db_currentversion(zonedb, &version);
11030 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
11031 if (result != ISC_R_SUCCESS)
11034 dns_rdataset_init(&rdataset);
11035 result = dns_db_findrdataset(zonedb, node, version,
11037 dns_rdatatype_none, 0, &rdataset,
11039 if (result != ISC_R_SUCCESS)
11041 result = dns_rdataset_first(&rdataset);
11042 if (result != ISC_R_SUCCESS)
11044 dns_rdataset_current(&rdataset, &rdata);
11045 dns_rdata_toregion(&rdata, &r);
11046 result = isc_buffer_allocate(zone->mctx, &b, r.length);
11047 if (result != ISC_R_SUCCESS)
11049 isc_buffer_putmem(b, r.base, r.length);
11050 isc_buffer_usedregion(b, &r);
11051 dns_rdata_init(temprdata);
11052 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
11053 dns_message_takebuffer(message, &b);
11054 result = dns_rdataset_next(&rdataset);
11055 dns_rdataset_disassociate(&rdataset);
11056 if (result != ISC_R_NOMORE)
11058 temprdatalist->rdclass = rdata.rdclass;
11059 temprdatalist->type = rdata.type;
11060 temprdatalist->covers = 0;
11061 temprdatalist->ttl = rdataset.ttl;
11062 ISC_LIST_INIT(temprdatalist->rdata);
11063 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
11065 dns_rdataset_init(temprdataset);
11066 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
11067 if (result != ISC_R_SUCCESS)
11070 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11071 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
11072 temprdatalist = NULL;
11073 temprdataset = NULL;
11079 dns_db_detachnode(zonedb, &node);
11080 if (version != NULL)
11081 dns_db_closeversion(zonedb, &version, ISC_FALSE);
11082 if (zonedb != NULL)
11083 dns_db_detach(&zonedb);
11084 if (tempname != NULL)
11085 dns_message_puttempname(message, &tempname);
11086 if (temprdata != NULL)
11087 dns_message_puttemprdata(message, &temprdata);
11088 if (temprdataset != NULL)
11089 dns_message_puttemprdataset(message, &temprdataset);
11090 if (temprdatalist != NULL)
11091 dns_message_puttemprdatalist(message, &temprdatalist);
11094 *messagep = message;
11095 return (ISC_R_SUCCESS);
11098 if (tempname != NULL)
11099 dns_message_puttempname(message, &tempname);
11100 if (temprdataset != NULL)
11101 dns_message_puttemprdataset(message, &temprdataset);
11102 dns_message_destroy(&message);
11107 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
11108 dns_message_t *msg)
11111 dns_rdata_soa_t soa;
11112 dns_rdataset_t *rdataset = NULL;
11113 dns_rdata_t rdata = DNS_RDATA_INIT;
11114 isc_result_t result;
11115 char fromtext[ISC_SOCKADDR_FORMATSIZE];
11117 isc_netaddr_t netaddr;
11118 isc_sockaddr_t local, remote;
11120 REQUIRE(DNS_ZONE_VALID(zone));
11123 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
11127 * Check that 'from' is a valid notify source, (zone->masters).
11128 * Return DNS_R_REFUSED if not.
11130 * If the notify message contains a serial number check it
11131 * against the zones serial and return if <= current serial
11133 * If a refresh check is progress, if so just record the
11134 * fact we received a NOTIFY and from where and return.
11135 * We will perform a new refresh check when the current one
11136 * completes. Return ISC_R_SUCCESS.
11138 * Otherwise initiate a refresh check using 'from' as the
11139 * first address to check. Return ISC_R_SUCCESS.
11142 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
11145 * We only handle NOTIFY (SOA) at the present.
11148 if (isc_sockaddr_pf(from) == PF_INET)
11149 inc_stats(zone, dns_zonestatscounter_notifyinv4);
11151 inc_stats(zone, dns_zonestatscounter_notifyinv6);
11152 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
11153 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
11154 dns_rdatatype_soa, dns_rdatatype_none,
11155 NULL, NULL) != ISC_R_SUCCESS) {
11157 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
11158 dns_zone_log(zone, ISC_LOG_NOTICE,
11160 "question section from: %s", fromtext);
11161 return (DNS_R_FORMERR);
11163 dns_zone_log(zone, ISC_LOG_NOTICE,
11164 "NOTIFY zone does not match");
11165 return (DNS_R_NOTIMP);
11169 * If we are a master zone just succeed.
11171 if (zone->type == dns_zone_master) {
11173 return (ISC_R_SUCCESS);
11176 isc_netaddr_fromsockaddr(&netaddr, from);
11177 for (i = 0; i < zone->masterscnt; i++) {
11178 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
11180 if (zone->view->aclenv.match_mapped &&
11181 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
11182 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
11183 isc_netaddr_t na1, na2;
11184 isc_netaddr_fromv4mapped(&na1, &netaddr);
11185 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
11186 if (isc_netaddr_equal(&na1, &na2))
11192 * Accept notify requests from non masters if they are on
11193 * 'zone->notify_acl'.
11195 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
11196 dns_acl_match(&netaddr, NULL, zone->notify_acl,
11197 &zone->view->aclenv,
11198 &match, NULL) == ISC_R_SUCCESS &&
11201 /* Accept notify. */
11202 } else if (i >= zone->masterscnt) {
11204 dns_zone_log(zone, ISC_LOG_INFO,
11205 "refused notify from non-master: %s", fromtext);
11206 inc_stats(zone, dns_zonestatscounter_notifyrej);
11207 return (DNS_R_REFUSED);
11211 * If the zone is loaded and there are answers check the serial
11212 * to see if we need to do a refresh. Do not worry about this
11213 * check if we are a dialup zone as we use the notify request
11214 * to trigger a refresh check.
11216 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
11217 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
11218 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
11219 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
11222 dns_rdatatype_none, NULL,
11224 if (result == ISC_R_SUCCESS)
11225 result = dns_rdataset_first(rdataset);
11226 if (result == ISC_R_SUCCESS) {
11227 isc_uint32_t serial = 0, oldserial;
11228 unsigned int soacount;
11230 dns_rdataset_current(rdataset, &rdata);
11231 result = dns_rdata_tostruct(&rdata, &soa, NULL);
11232 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11233 serial = soa.serial;
11235 * The following should safely be performed without DB
11236 * lock and succeed in this context.
11238 result = zone_get_from_db(zone, zone->db, NULL,
11239 &soacount, &oldserial, NULL,
11240 NULL, NULL, NULL, NULL);
11241 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11242 RUNTIME_CHECK(soacount > 0U);
11243 if (isc_serial_le(serial, oldserial)) {
11247 "zone is up to date",
11250 return (ISC_R_SUCCESS);
11256 * If we got this far and there was a refresh in progress just
11257 * let it complete. Record where we got the notify from so we
11258 * can perform a refresh check when the current one completes
11260 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
11261 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11262 zone->notifyfrom = *from;
11264 dns_zone_log(zone, ISC_LOG_INFO,
11265 "notify from %s: refresh in progress, "
11266 "refresh check queued",
11268 return (ISC_R_SUCCESS);
11270 zone->notifyfrom = *from;
11271 local = zone->masteraddr;
11272 remote = zone->sourceaddr;
11274 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
11275 dns_zone_refresh(zone);
11276 return (ISC_R_SUCCESS);
11280 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
11282 REQUIRE(DNS_ZONE_VALID(zone));
11285 if (zone->notify_acl != NULL)
11286 dns_acl_detach(&zone->notify_acl);
11287 dns_acl_attach(acl, &zone->notify_acl);
11292 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
11294 REQUIRE(DNS_ZONE_VALID(zone));
11297 if (zone->query_acl != NULL)
11298 dns_acl_detach(&zone->query_acl);
11299 dns_acl_attach(acl, &zone->query_acl);
11304 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
11306 REQUIRE(DNS_ZONE_VALID(zone));
11309 if (zone->queryon_acl != NULL)
11310 dns_acl_detach(&zone->queryon_acl);
11311 dns_acl_attach(acl, &zone->queryon_acl);
11316 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
11318 REQUIRE(DNS_ZONE_VALID(zone));
11321 if (zone->update_acl != NULL)
11322 dns_acl_detach(&zone->update_acl);
11323 dns_acl_attach(acl, &zone->update_acl);
11328 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
11330 REQUIRE(DNS_ZONE_VALID(zone));
11333 if (zone->forward_acl != NULL)
11334 dns_acl_detach(&zone->forward_acl);
11335 dns_acl_attach(acl, &zone->forward_acl);
11340 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
11342 REQUIRE(DNS_ZONE_VALID(zone));
11345 if (zone->xfr_acl != NULL)
11346 dns_acl_detach(&zone->xfr_acl);
11347 dns_acl_attach(acl, &zone->xfr_acl);
11352 dns_zone_getnotifyacl(dns_zone_t *zone) {
11354 REQUIRE(DNS_ZONE_VALID(zone));
11356 return (zone->notify_acl);
11360 dns_zone_getqueryacl(dns_zone_t *zone) {
11362 REQUIRE(DNS_ZONE_VALID(zone));
11364 return (zone->query_acl);
11368 dns_zone_getqueryonacl(dns_zone_t *zone) {
11370 REQUIRE(DNS_ZONE_VALID(zone));
11372 return (zone->queryon_acl);
11376 dns_zone_getupdateacl(dns_zone_t *zone) {
11378 REQUIRE(DNS_ZONE_VALID(zone));
11380 return (zone->update_acl);
11384 dns_zone_getforwardacl(dns_zone_t *zone) {
11386 REQUIRE(DNS_ZONE_VALID(zone));
11388 return (zone->forward_acl);
11392 dns_zone_getxfracl(dns_zone_t *zone) {
11394 REQUIRE(DNS_ZONE_VALID(zone));
11396 return (zone->xfr_acl);
11400 dns_zone_clearupdateacl(dns_zone_t *zone) {
11402 REQUIRE(DNS_ZONE_VALID(zone));
11405 if (zone->update_acl != NULL)
11406 dns_acl_detach(&zone->update_acl);
11411 dns_zone_clearforwardacl(dns_zone_t *zone) {
11413 REQUIRE(DNS_ZONE_VALID(zone));
11416 if (zone->forward_acl != NULL)
11417 dns_acl_detach(&zone->forward_acl);
11422 dns_zone_clearnotifyacl(dns_zone_t *zone) {
11424 REQUIRE(DNS_ZONE_VALID(zone));
11427 if (zone->notify_acl != NULL)
11428 dns_acl_detach(&zone->notify_acl);
11433 dns_zone_clearqueryacl(dns_zone_t *zone) {
11435 REQUIRE(DNS_ZONE_VALID(zone));
11438 if (zone->query_acl != NULL)
11439 dns_acl_detach(&zone->query_acl);
11444 dns_zone_clearqueryonacl(dns_zone_t *zone) {
11446 REQUIRE(DNS_ZONE_VALID(zone));
11449 if (zone->queryon_acl != NULL)
11450 dns_acl_detach(&zone->queryon_acl);
11455 dns_zone_clearxfracl(dns_zone_t *zone) {
11457 REQUIRE(DNS_ZONE_VALID(zone));
11460 if (zone->xfr_acl != NULL)
11461 dns_acl_detach(&zone->xfr_acl);
11466 dns_zone_getupdatedisabled(dns_zone_t *zone) {
11467 REQUIRE(DNS_ZONE_VALID(zone));
11468 return (zone->update_disabled);
11473 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
11474 REQUIRE(DNS_ZONE_VALID(zone));
11475 zone->update_disabled = state;
11479 dns_zone_getzeronosoattl(dns_zone_t *zone) {
11480 REQUIRE(DNS_ZONE_VALID(zone));
11481 return (zone->zero_no_soa_ttl);
11486 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
11487 REQUIRE(DNS_ZONE_VALID(zone));
11488 zone->zero_no_soa_ttl = state;
11492 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
11494 REQUIRE(DNS_ZONE_VALID(zone));
11496 zone->check_names = severity;
11500 dns_zone_getchecknames(dns_zone_t *zone) {
11502 REQUIRE(DNS_ZONE_VALID(zone));
11504 return (zone->check_names);
11508 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
11510 REQUIRE(DNS_ZONE_VALID(zone));
11512 zone->journalsize = size;
11516 dns_zone_getjournalsize(dns_zone_t *zone) {
11518 REQUIRE(DNS_ZONE_VALID(zone));
11520 return (zone->journalsize);
11524 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
11525 isc_result_t result = ISC_R_FAILURE;
11526 isc_buffer_t buffer;
11528 REQUIRE(buf != NULL);
11529 REQUIRE(length > 1U);
11532 * Leave space for terminating '\0'.
11534 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11535 if (dns_name_dynamic(&zone->origin))
11536 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11537 if (result != ISC_R_SUCCESS &&
11538 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11539 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11541 if (isc_buffer_availablelength(&buffer) > 0)
11542 isc_buffer_putstr(&buffer, "/");
11543 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11545 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
11546 strcmp(zone->view->name, "_default") != 0 &&
11547 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
11548 isc_buffer_putstr(&buffer, "/");
11549 isc_buffer_putstr(&buffer, zone->view->name);
11552 buf[isc_buffer_usedlength(&buffer)] = '\0';
11556 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
11557 isc_result_t result = ISC_R_FAILURE;
11558 isc_buffer_t buffer;
11560 REQUIRE(buf != NULL);
11561 REQUIRE(length > 1U);
11564 * Leave space for terminating '\0'.
11566 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11567 if (dns_name_dynamic(&zone->origin))
11568 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11569 if (result != ISC_R_SUCCESS &&
11570 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11571 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11573 buf[isc_buffer_usedlength(&buffer)] = '\0';
11577 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
11578 isc_buffer_t buffer;
11580 REQUIRE(buf != NULL);
11581 REQUIRE(length > 1U);
11584 * Leave space for terminating '\0'.
11586 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11587 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11589 buf[isc_buffer_usedlength(&buffer)] = '\0';
11593 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
11594 isc_buffer_t buffer;
11596 REQUIRE(buf != NULL);
11597 REQUIRE(length > 1U);
11601 * Leave space for terminating '\0'.
11603 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11605 if (zone->view == NULL) {
11606 isc_buffer_putstr(&buffer, "_none");
11607 } else if (strlen(zone->view->name)
11608 < isc_buffer_availablelength(&buffer)) {
11609 isc_buffer_putstr(&buffer, zone->view->name);
11611 isc_buffer_putstr(&buffer, "_toolong");
11614 buf[isc_buffer_usedlength(&buffer)] = '\0';
11618 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
11619 REQUIRE(DNS_ZONE_VALID(zone));
11620 REQUIRE(buf != NULL);
11621 zone_namerd_tostr(zone, buf, length);
11625 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11627 char message[4096];
11629 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11633 vsnprintf(message, sizeof(message), fmt, ap);
11635 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
11636 level, "zone %s: %s", zone->strnamerd, message);
11640 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
11641 int level, const char *fmt, ...) {
11643 char message[4096];
11645 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11649 vsnprintf(message, sizeof(message), fmt, ap);
11651 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
11652 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11653 "managed-keys-zone" : "zone", zone->strnamerd, message);
11657 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11659 char message[4096];
11661 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11665 vsnprintf(message, sizeof(message), fmt, ap);
11667 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11668 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11669 "managed-keys-zone" : "zone", zone->strnamerd, message);
11673 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
11674 const char *fmt, ...)
11677 char message[4096];
11678 int level = ISC_LOG_DEBUG(debuglevel);
11680 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11684 vsnprintf(message, sizeof(message), fmt, ap);
11686 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11687 level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
11688 "zone" : "managed-keys-zone", zone->strnamerd, message);
11692 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
11694 isc_result_t result;
11696 dns_rdataset_t *curr;
11699 result = dns_message_firstname(msg, section);
11700 while (result == ISC_R_SUCCESS) {
11702 dns_message_currentname(msg, section, &name);
11704 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
11705 curr = ISC_LIST_PREV(curr, link)) {
11706 if (curr->type == type)
11709 result = dns_message_nextname(msg, section);
11716 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
11717 REQUIRE(DNS_ZONE_VALID(zone));
11719 zone->maxxfrin = maxxfrin;
11723 dns_zone_getmaxxfrin(dns_zone_t *zone) {
11724 REQUIRE(DNS_ZONE_VALID(zone));
11726 return (zone->maxxfrin);
11730 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
11731 REQUIRE(DNS_ZONE_VALID(zone));
11732 zone->maxxfrout = maxxfrout;
11736 dns_zone_getmaxxfrout(dns_zone_t *zone) {
11737 REQUIRE(DNS_ZONE_VALID(zone));
11739 return (zone->maxxfrout);
11743 dns_zone_gettype(dns_zone_t *zone) {
11744 REQUIRE(DNS_ZONE_VALID(zone));
11746 return (zone->type);
11750 dns_zone_getorigin(dns_zone_t *zone) {
11751 REQUIRE(DNS_ZONE_VALID(zone));
11753 return (&zone->origin);
11757 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
11758 REQUIRE(DNS_ZONE_VALID(zone));
11761 if (zone->task != NULL)
11762 isc_task_detach(&zone->task);
11763 isc_task_attach(task, &zone->task);
11764 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11765 if (zone->db != NULL)
11766 dns_db_settask(zone->db, zone->task);
11767 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11772 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
11773 REQUIRE(DNS_ZONE_VALID(zone));
11774 isc_task_attach(zone->task, target);
11778 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
11779 REQUIRE(DNS_ZONE_VALID(zone));
11782 idlein = DNS_DEFAULT_IDLEIN;
11783 zone->idlein = idlein;
11787 dns_zone_getidlein(dns_zone_t *zone) {
11788 REQUIRE(DNS_ZONE_VALID(zone));
11790 return (zone->idlein);
11794 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
11795 REQUIRE(DNS_ZONE_VALID(zone));
11797 zone->idleout = idleout;
11801 dns_zone_getidleout(dns_zone_t *zone) {
11802 REQUIRE(DNS_ZONE_VALID(zone));
11804 return (zone->idleout);
11808 notify_done(isc_task_t *task, isc_event_t *event) {
11809 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11810 dns_notify_t *notify;
11811 isc_result_t result;
11812 dns_message_t *message = NULL;
11815 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
11819 notify = event->ev_arg;
11820 REQUIRE(DNS_NOTIFY_VALID(notify));
11821 INSIST(task == notify->zone->task);
11823 isc_buffer_init(&buf, rcode, sizeof(rcode));
11824 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11826 result = revent->result;
11827 if (result == ISC_R_SUCCESS)
11828 result = dns_message_create(notify->zone->mctx,
11829 DNS_MESSAGE_INTENTPARSE, &message);
11830 if (result == ISC_R_SUCCESS)
11831 result = dns_request_getresponse(revent->request, message,
11832 DNS_MESSAGEPARSE_PRESERVEORDER);
11833 if (result == ISC_R_SUCCESS)
11834 result = dns_rcode_totext(message->rcode, &buf);
11835 if (result == ISC_R_SUCCESS)
11836 notify_log(notify->zone, ISC_LOG_DEBUG(3),
11837 "notify response from %s: %.*s",
11838 addrbuf, (int)buf.used, rcode);
11840 notify_log(notify->zone, ISC_LOG_DEBUG(2),
11841 "notify to %s failed: %s", addrbuf,
11842 dns_result_totext(result));
11845 * Old bind's return formerr if they see a soa record. Retry w/o
11846 * the soa if we see a formerr and had sent a SOA.
11848 isc_event_free(&event);
11849 if (message != NULL && message->rcode == dns_rcode_formerr &&
11850 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
11851 notify->flags |= DNS_NOTIFY_NOSOA;
11852 dns_request_destroy(¬ify->request);
11853 result = notify_send_queue(notify);
11854 if (result != ISC_R_SUCCESS)
11855 notify_destroy(notify, ISC_FALSE);
11857 if (result == ISC_R_TIMEDOUT)
11858 notify_log(notify->zone, ISC_LOG_DEBUG(1),
11859 "notify to %s: retries exceeded", addrbuf);
11860 notify_destroy(notify, ISC_FALSE);
11862 if (message != NULL)
11863 dns_message_destroy(&message);
11867 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11868 isc_result_t result;
11870 REQUIRE(DNS_ZONE_VALID(zone));
11872 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11873 result = zone_replacedb(zone, db, dump);
11874 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11879 static isc_result_t
11880 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11881 dns_dbversion_t *ver;
11882 isc_result_t result;
11883 unsigned int soacount = 0;
11884 unsigned int nscount = 0;
11887 * 'zone' and 'zonedb' locked by caller.
11889 REQUIRE(DNS_ZONE_VALID(zone));
11890 REQUIRE(LOCKED_ZONE(zone));
11892 result = zone_get_from_db(zone, db, &nscount, &soacount,
11893 NULL, NULL, NULL, NULL, NULL, NULL);
11894 if (result == ISC_R_SUCCESS) {
11895 if (soacount != 1) {
11896 dns_zone_log(zone, ISC_LOG_ERROR,
11897 "has %d SOA records", soacount);
11898 result = DNS_R_BADZONE;
11900 if (nscount == 0 && zone->type != dns_zone_key) {
11901 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
11902 result = DNS_R_BADZONE;
11904 if (result != ISC_R_SUCCESS)
11907 dns_zone_log(zone, ISC_LOG_ERROR,
11908 "retrieving SOA and NS records failed: %s",
11909 dns_result_totext(result));
11913 result = check_nsec3param(zone, db);
11914 if (result != ISC_R_SUCCESS)
11918 dns_db_currentversion(db, &ver);
11921 * The initial version of a slave zone is always dumped;
11922 * subsequent versions may be journaled instead if this
11923 * is enabled in the configuration.
11925 if (zone->db != NULL && zone->journal != NULL &&
11926 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
11927 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
11928 isc_uint32_t serial, oldserial;
11929 unsigned int soacount;
11931 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
11933 result = dns_db_getsoaserial(db, ver, &serial);
11934 if (result != ISC_R_SUCCESS) {
11935 dns_zone_log(zone, ISC_LOG_ERROR,
11936 "ixfr-from-differences: unable to get "
11942 * This is checked in zone_postload() for master zones.
11944 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
11945 &oldserial, NULL, NULL, NULL, NULL,
11947 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11948 RUNTIME_CHECK(soacount > 0U);
11949 if (zone->type == dns_zone_slave &&
11950 !isc_serial_gt(serial, oldserial)) {
11951 isc_uint32_t serialmin, serialmax;
11952 serialmin = (oldserial + 1) & 0xffffffffU;
11953 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
11954 dns_zone_log(zone, ISC_LOG_ERROR,
11955 "ixfr-from-differences: failed: "
11956 "new serial (%u) out of range [%u - %u]",
11957 serial, serialmin, serialmax);
11958 result = ISC_R_RANGE;
11962 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
11964 if (result != ISC_R_SUCCESS)
11967 zone_needdump(zone, DNS_DUMP_DELAY);
11968 else if (zone->journalsize != -1) {
11969 result = dns_journal_compact(zone->mctx, zone->journal,
11970 serial, zone->journalsize);
11972 case ISC_R_SUCCESS:
11973 case ISC_R_NOSPACE:
11974 case ISC_R_NOTFOUND:
11975 dns_zone_log(zone, ISC_LOG_DEBUG(3),
11976 "dns_journal_compact: %s",
11977 dns_result_totext(result));
11980 dns_zone_log(zone, ISC_LOG_ERROR,
11981 "dns_journal_compact failed: %s",
11982 dns_result_totext(result));
11987 if (dump && zone->masterfile != NULL) {
11989 * If DNS_ZONEFLG_FORCEXFER was set we don't want
11990 * to keep the old masterfile.
11992 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
11993 remove(zone->masterfile) < 0 && errno != ENOENT) {
11994 char strbuf[ISC_STRERRORSIZE];
11995 isc__strerror(errno, strbuf, sizeof(strbuf));
11996 isc_log_write(dns_lctx,
11997 DNS_LOGCATEGORY_GENERAL,
11998 DNS_LOGMODULE_ZONE,
12000 "unable to remove masterfile "
12002 zone->masterfile, strbuf);
12004 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
12005 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
12007 zone_needdump(zone, 0);
12009 if (dump && zone->journal != NULL) {
12011 * The in-memory database just changed, and
12012 * because 'dump' is set, it didn't change by
12013 * being loaded from disk. Also, we have not
12014 * journaled diffs for this change.
12015 * Therefore, the on-disk journal is missing
12016 * the deltas for this change. Since it can
12017 * no longer be used to bring the zone
12018 * up-to-date, it is useless and should be
12021 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
12022 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
12023 "removing journal file");
12024 if (remove(zone->journal) < 0 && errno != ENOENT) {
12025 char strbuf[ISC_STRERRORSIZE];
12026 isc__strerror(errno, strbuf, sizeof(strbuf));
12027 isc_log_write(dns_lctx,
12028 DNS_LOGCATEGORY_GENERAL,
12029 DNS_LOGMODULE_ZONE,
12031 "unable to remove journal "
12033 zone->journal, strbuf);
12038 dns_db_closeversion(db, &ver, ISC_FALSE);
12040 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
12041 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
12042 "replacing zone database");
12044 if (zone->db != NULL)
12045 zone_detachdb(zone);
12046 zone_attachdb(zone, db);
12047 dns_db_settask(zone->db, zone->task);
12048 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
12049 return (ISC_R_SUCCESS);
12052 dns_db_closeversion(db, &ver, ISC_FALSE);
12056 /* The caller must hold the dblock as a writer. */
12058 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
12059 REQUIRE(zone->db == NULL && db != NULL);
12061 dns_db_attach(db, &zone->db);
12062 if (zone->acache != NULL) {
12063 isc_result_t result;
12064 result = dns_acache_setdb(zone->acache, db);
12065 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
12066 UNEXPECTED_ERROR(__FILE__, __LINE__,
12067 "dns_acache_setdb() failed: %s",
12068 isc_result_totext(result));
12073 /* The caller must hold the dblock as a writer. */
12075 zone_detachdb(dns_zone_t *zone) {
12076 REQUIRE(zone->db != NULL);
12078 if (zone->acache != NULL)
12079 (void)dns_acache_putdb(zone->acache, zone->db);
12080 dns_db_detach(&zone->db);
12084 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
12086 isc_boolean_t again = ISC_FALSE;
12087 unsigned int soacount;
12088 unsigned int nscount;
12089 isc_uint32_t serial, refresh, retry, expire, minimum;
12090 isc_result_t xfrresult = result;
12091 isc_boolean_t free_needed;
12093 REQUIRE(DNS_ZONE_VALID(zone));
12095 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12096 "zone transfer finished: %s", dns_result_totext(result));
12099 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
12100 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12101 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
12105 case ISC_R_SUCCESS:
12106 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
12108 case DNS_R_UPTODATE:
12109 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
12111 * Has the zone expired underneath us?
12113 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12114 if (zone->db == NULL) {
12115 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12120 * Update the zone structure's data from the actual
12125 INSIST(zone->db != NULL);
12126 result = zone_get_from_db(zone, zone->db, &nscount,
12127 &soacount, &serial, &refresh,
12128 &retry, &expire, &minimum, NULL);
12129 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12130 if (result == ISC_R_SUCCESS) {
12132 dns_zone_log(zone, ISC_LOG_ERROR,
12133 "transferred zone "
12134 "has %d SOA record%s", soacount,
12135 (soacount != 0) ? "s" : "");
12136 if (nscount == 0) {
12137 dns_zone_log(zone, ISC_LOG_ERROR,
12138 "transferred zone "
12139 "has no NS records");
12140 if (DNS_ZONE_FLAG(zone,
12141 DNS_ZONEFLG_HAVETIMERS)) {
12142 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
12143 zone->retry = DNS_ZONE_DEFAULTRETRY;
12145 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
12149 zone->refresh = RANGE(refresh, zone->minrefresh,
12151 zone->retry = RANGE(retry, zone->minretry,
12153 zone->expire = RANGE(expire,
12154 zone->refresh + zone->retry,
12156 zone->minimum = minimum;
12157 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
12161 * Set our next update/expire times.
12163 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
12164 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12165 zone->refreshtime = now;
12166 DNS_ZONE_TIME_ADD(&now, zone->expire,
12167 &zone->expiretime);
12169 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
12170 &zone->refreshtime);
12171 DNS_ZONE_TIME_ADD(&now, zone->expire,
12172 &zone->expiretime);
12174 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
12175 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
12176 if (zone->tsigkey != NULL) {
12177 char namebuf[DNS_NAME_FORMATSIZE];
12178 dns_name_format(&zone->tsigkey->name, namebuf,
12180 snprintf(buf, sizeof(buf), ": TSIG '%s'",
12184 dns_zone_log(zone, ISC_LOG_INFO,
12185 "transferred serial %u%s",
12190 * This is not necessary if we just performed a AXFR
12191 * however it is necessary for an IXFR / UPTODATE and
12192 * won't hurt with an AXFR.
12194 if (zone->masterfile != NULL || zone->journal != NULL) {
12195 unsigned int delay = DNS_DUMP_DELAY;
12197 result = ISC_R_FAILURE;
12198 if (zone->journal != NULL)
12199 result = isc_file_settime(zone->journal, &now);
12200 if (result != ISC_R_SUCCESS &&
12201 zone->masterfile != NULL)
12202 result = isc_file_settime(zone->masterfile,
12205 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
12206 result == ISC_R_FILENOTFOUND)
12209 if ((result == ISC_R_SUCCESS ||
12210 result == ISC_R_FILENOTFOUND) &&
12211 zone->masterfile != NULL)
12212 zone_needdump(zone, delay);
12213 else if (result != ISC_R_SUCCESS)
12214 dns_zone_log(zone, ISC_LOG_ERROR,
12215 "transfer: could not set file "
12216 "modification time of '%s': %s",
12218 dns_result_totext(result));
12220 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
12221 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
12224 case DNS_R_BADIXFR:
12225 /* Force retry with AXFR. */
12226 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
12232 * Skip to next failed / untried master.
12236 } while (zone->curmaster < zone->masterscnt &&
12237 zone->mastersok[zone->curmaster]);
12240 if (zone->curmaster >= zone->masterscnt) {
12241 zone->curmaster = 0;
12242 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
12243 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12244 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
12245 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12246 while (zone->curmaster < zone->masterscnt &&
12247 zone->mastersok[zone->curmaster])
12251 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12253 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
12256 inc_stats(zone, dns_zonestatscounter_xfrfail);
12259 zone_settimer(zone, &now);
12262 * If creating the transfer object failed, zone->xfr is NULL.
12263 * Otherwise, we are called as the done callback of a zone
12264 * transfer object that just entered its shutting-down
12265 * state. Since we are no longer responsible for shutting
12266 * it down, we can detach our reference.
12268 if (zone->xfr != NULL)
12269 dns_xfrin_detach(&zone->xfr);
12271 if (zone->tsigkey != NULL)
12272 dns_tsigkey_detach(&zone->tsigkey);
12275 * Handle any deferred journal compaction.
12277 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
12278 result = dns_journal_compact(zone->mctx, zone->journal,
12279 zone->compact_serial,
12280 zone->journalsize);
12282 case ISC_R_SUCCESS:
12283 case ISC_R_NOSPACE:
12284 case ISC_R_NOTFOUND:
12285 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12286 "dns_journal_compact: %s",
12287 dns_result_totext(result));
12290 dns_zone_log(zone, ISC_LOG_ERROR,
12291 "dns_journal_compact failed: %s",
12292 dns_result_totext(result));
12295 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
12299 * This transfer finishing freed up a transfer quota slot.
12300 * Let any other zones waiting for quota have it.
12303 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12304 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
12305 zone->statelist = NULL;
12306 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
12307 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12311 * Retry with a different server if necessary.
12313 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12314 queue_soa_query(zone);
12316 INSIST(zone->irefs > 0);
12318 free_needed = exit_check(zone);
12325 zone_loaddone(void *arg, isc_result_t result) {
12326 static char me[] = "zone_loaddone";
12327 dns_load_t *load = arg;
12329 isc_result_t tresult;
12331 REQUIRE(DNS_LOAD_VALID(load));
12336 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
12337 if (tresult != ISC_R_SUCCESS &&
12338 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
12341 LOCK_ZONE(load->zone);
12342 (void)zone_postload(load->zone, load->db, load->loadtime, result);
12343 zonemgr_putio(&load->zone->readio);
12344 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
12346 * Leave the zone frozen if the reload fails.
12348 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
12349 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
12350 zone->update_disabled = ISC_FALSE;
12351 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
12352 UNLOCK_ZONE(load->zone);
12355 dns_db_detach(&load->db);
12356 if (load->zone->lctx != NULL)
12357 dns_loadctx_detach(&load->zone->lctx);
12358 dns_zone_idetach(&load->zone);
12359 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
12363 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
12364 REQUIRE(DNS_ZONE_VALID(zone));
12365 REQUIRE(table != NULL);
12366 REQUIRE(*table == NULL);
12369 if (zone->ssutable != NULL)
12370 dns_ssutable_attach(zone->ssutable, table);
12375 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
12376 REQUIRE(DNS_ZONE_VALID(zone));
12379 if (zone->ssutable != NULL)
12380 dns_ssutable_detach(&zone->ssutable);
12382 dns_ssutable_attach(table, &zone->ssutable);
12387 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
12388 REQUIRE(DNS_ZONE_VALID(zone));
12390 zone->sigvalidityinterval = interval;
12394 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
12395 REQUIRE(DNS_ZONE_VALID(zone));
12397 return (zone->sigvalidityinterval);
12401 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
12404 REQUIRE(DNS_ZONE_VALID(zone));
12407 zone->sigresigninginterval = interval;
12408 set_resigntime(zone);
12409 if (zone->task != NULL) {
12411 zone_settimer(zone, &now);
12417 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
12418 REQUIRE(DNS_ZONE_VALID(zone));
12420 return (zone->sigresigninginterval);
12424 queue_xfrin(dns_zone_t *zone) {
12425 const char me[] = "queue_xfrin";
12426 isc_result_t result;
12427 dns_zonemgr_t *zmgr = zone->zmgr;
12431 INSIST(zone->statelist == NULL);
12433 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12434 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
12438 zone->statelist = &zmgr->waiting_for_xfrin;
12439 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12440 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12442 if (result == ISC_R_QUOTA) {
12443 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
12444 "zone transfer deferred due to quota");
12445 } else if (result != ISC_R_SUCCESS) {
12446 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
12447 "starting zone transfer: %s",
12448 isc_result_totext(result));
12453 * This event callback is called when a zone has received
12454 * any necessary zone transfer quota. This is the time
12455 * to go ahead and start the transfer.
12458 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
12459 isc_result_t result;
12460 dns_peer_t *peer = NULL;
12461 char master[ISC_SOCKADDR_FORMATSIZE];
12462 char source[ISC_SOCKADDR_FORMATSIZE];
12463 dns_rdatatype_t xfrtype;
12464 dns_zone_t *zone = event->ev_arg;
12465 isc_netaddr_t masterip;
12466 isc_sockaddr_t sourceaddr;
12467 isc_sockaddr_t masteraddr;
12469 const char *soa_before = "";
12473 INSIST(task == zone->task);
12475 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12476 result = ISC_R_CANCELED;
12482 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12483 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
12484 &zone->sourceaddr, &now))
12486 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12487 dns_zone_log(zone, ISC_LOG_INFO,
12488 "got_transfer_quota: skipping zone transfer as "
12489 "master %s (source %s) is unreachable (cached)",
12491 result = ISC_R_CANCELED;
12495 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12496 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
12498 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12499 soa_before = "SOA before ";
12501 * Decide whether we should request IXFR or AXFR.
12503 if (zone->db == NULL) {
12504 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12505 "no database exists yet, requesting AXFR of "
12506 "initial version from %s", master);
12507 xfrtype = dns_rdatatype_axfr;
12508 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
12509 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
12510 "set, requesting %sAXFR from %s", soa_before,
12512 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12513 xfrtype = dns_rdatatype_soa;
12515 xfrtype = dns_rdatatype_axfr;
12516 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
12517 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12518 "forced reload, requesting AXFR of "
12519 "initial version from %s", master);
12520 xfrtype = dns_rdatatype_axfr;
12521 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
12522 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12523 "retrying with AXFR from %s due to "
12524 "previous IXFR failure", master);
12525 xfrtype = dns_rdatatype_axfr;
12527 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
12530 isc_boolean_t use_ixfr = ISC_TRUE;
12531 if (peer != NULL &&
12532 dns_peer_getrequestixfr(peer, &use_ixfr) ==
12534 ; /* Using peer setting */
12536 use_ixfr = zone->view->requestixfr;
12538 if (use_ixfr == ISC_FALSE) {
12539 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12540 "IXFR disabled, requesting %sAXFR from %s",
12541 soa_before, master);
12542 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12543 xfrtype = dns_rdatatype_soa;
12545 xfrtype = dns_rdatatype_axfr;
12547 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12548 "requesting IXFR from %s", master);
12549 xfrtype = dns_rdatatype_ixfr;
12554 * Determine if we should attempt to sign the request with TSIG.
12556 result = ISC_R_NOTFOUND;
12558 * First, look for a tsig key in the master statement, then
12559 * try for a server key.
12561 if ((zone->masterkeynames != NULL) &&
12562 (zone->masterkeynames[zone->curmaster] != NULL)) {
12563 dns_view_t *view = dns_zone_getview(zone);
12564 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12565 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
12567 if (zone->tsigkey == NULL)
12568 result = dns_view_getpeertsig(zone->view, &masterip,
12571 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
12572 dns_zone_log(zone, ISC_LOG_ERROR,
12573 "could not get TSIG key for zone transfer: %s",
12574 isc_result_totext(result));
12578 masteraddr = zone->masteraddr;
12579 sourceaddr = zone->sourceaddr;
12581 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
12582 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
12583 zone->tsigkey, zone->mctx,
12584 zone->zmgr->timermgr, zone->zmgr->socketmgr,
12585 zone->task, zone_xfrdone, &zone->xfr);
12586 if (result == ISC_R_SUCCESS) {
12588 if (xfrtype == dns_rdatatype_axfr) {
12589 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12590 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
12592 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
12593 } else if (xfrtype == dns_rdatatype_ixfr) {
12594 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12595 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
12597 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
12603 * Any failure in this function is handled like a failed
12604 * zone transfer. This ensures that we get removed from
12605 * zmgr->xfrin_in_progress.
12607 if (result != ISC_R_SUCCESS)
12608 zone_xfrdone(zone, result);
12610 isc_event_free(&event);
12614 * Update forwarding support.
12618 forward_destroy(dns_forward_t *forward) {
12620 forward->magic = 0;
12621 if (forward->request != NULL)
12622 dns_request_destroy(&forward->request);
12623 if (forward->msgbuf != NULL)
12624 isc_buffer_free(&forward->msgbuf);
12625 if (forward->zone != NULL) {
12626 LOCK(&forward->zone->lock);
12627 if (ISC_LINK_LINKED(forward, link))
12628 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
12629 UNLOCK(&forward->zone->lock);
12630 dns_zone_idetach(&forward->zone);
12632 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
12635 static isc_result_t
12636 sendtomaster(dns_forward_t *forward) {
12637 isc_result_t result;
12638 isc_sockaddr_t src;
12640 LOCK_ZONE(forward->zone);
12642 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
12643 UNLOCK_ZONE(forward->zone);
12644 return (ISC_R_CANCELED);
12647 if (forward->which >= forward->zone->masterscnt) {
12648 UNLOCK_ZONE(forward->zone);
12649 return (ISC_R_NOMORE);
12652 forward->addr = forward->zone->masters[forward->which];
12654 * Always use TCP regardless of whether the original update
12656 * XXX The timeout may but a bit small if we are far down a
12657 * transfer graph and the master has to try several masters.
12659 switch (isc_sockaddr_pf(&forward->addr)) {
12661 src = forward->zone->xfrsource4;
12664 src = forward->zone->xfrsource6;
12667 result = ISC_R_NOTIMPLEMENTED;
12670 result = dns_request_createraw(forward->zone->view->requestmgr,
12672 &src, &forward->addr,
12673 DNS_REQUESTOPT_TCP, 15 /* XXX */,
12674 forward->zone->task,
12675 forward_callback, forward,
12676 &forward->request);
12677 if (result == ISC_R_SUCCESS) {
12678 if (!ISC_LINK_LINKED(forward, link))
12679 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
12683 UNLOCK_ZONE(forward->zone);
12688 forward_callback(isc_task_t *task, isc_event_t *event) {
12689 const char me[] = "forward_callback";
12690 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12691 dns_message_t *msg = NULL;
12692 char master[ISC_SOCKADDR_FORMATSIZE];
12693 isc_result_t result;
12694 dns_forward_t *forward;
12699 forward = revent->ev_arg;
12700 INSIST(DNS_FORWARD_VALID(forward));
12701 zone = forward->zone;
12702 INSIST(DNS_ZONE_VALID(zone));
12706 isc_sockaddr_format(&forward->addr, master, sizeof(master));
12708 if (revent->result != ISC_R_SUCCESS) {
12709 dns_zone_log(zone, ISC_LOG_INFO,
12710 "could not forward dynamic update to %s: %s",
12711 master, dns_result_totext(revent->result));
12715 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12716 if (result != ISC_R_SUCCESS)
12719 result = dns_request_getresponse(revent->request, msg,
12720 DNS_MESSAGEPARSE_PRESERVEORDER |
12721 DNS_MESSAGEPARSE_CLONEBUFFER);
12722 if (result != ISC_R_SUCCESS)
12725 switch (msg->rcode) {
12727 * Pass these rcodes back to client.
12729 case dns_rcode_noerror:
12730 case dns_rcode_yxdomain:
12731 case dns_rcode_yxrrset:
12732 case dns_rcode_nxrrset:
12733 case dns_rcode_refused:
12734 case dns_rcode_nxdomain: {
12738 isc_buffer_init(&rb, rcode, sizeof(rcode));
12739 (void)dns_rcode_totext(msg->rcode, &rb);
12740 dns_zone_log(zone, ISC_LOG_INFO,
12741 "forwarded dynamic update: "
12742 "master %s returned: %.*s",
12743 master, (int)rb.used, rcode);
12747 /* These should not occur if the masters/zone are valid. */
12748 case dns_rcode_notzone:
12749 case dns_rcode_notauth: {
12753 isc_buffer_init(&rb, rcode, sizeof(rcode));
12754 (void)dns_rcode_totext(msg->rcode, &rb);
12755 dns_zone_log(zone, ISC_LOG_WARNING,
12756 "forwarding dynamic update: "
12757 "unexpected response: master %s returned: %.*s",
12758 master, (int)rb.used, rcode);
12762 /* Try another server for these rcodes. */
12763 case dns_rcode_formerr:
12764 case dns_rcode_servfail:
12765 case dns_rcode_notimp:
12766 case dns_rcode_badvers:
12771 /* call callback */
12772 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
12774 dns_request_destroy(&forward->request);
12775 forward_destroy(forward);
12776 isc_event_free(&event);
12781 dns_message_destroy(&msg);
12782 isc_event_free(&event);
12784 dns_request_destroy(&forward->request);
12785 result = sendtomaster(forward);
12786 if (result != ISC_R_SUCCESS) {
12787 /* call callback */
12788 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12789 "exhausted dynamic update forwarder list");
12790 (forward->callback)(forward->callback_arg, result, NULL);
12791 forward_destroy(forward);
12796 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
12797 dns_updatecallback_t callback, void *callback_arg)
12799 dns_forward_t *forward;
12800 isc_result_t result;
12803 REQUIRE(DNS_ZONE_VALID(zone));
12804 REQUIRE(msg != NULL);
12805 REQUIRE(callback != NULL);
12807 forward = isc_mem_get(zone->mctx, sizeof(*forward));
12808 if (forward == NULL)
12809 return (ISC_R_NOMEMORY);
12811 forward->request = NULL;
12812 forward->zone = NULL;
12813 forward->msgbuf = NULL;
12814 forward->which = 0;
12816 forward->callback = callback;
12817 forward->callback_arg = callback_arg;
12818 ISC_LINK_INIT(forward, link);
12819 forward->magic = FORWARD_MAGIC;
12821 mr = dns_message_getrawmessage(msg);
12823 result = ISC_R_UNEXPECTEDEND;
12827 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
12828 if (result != ISC_R_SUCCESS)
12830 result = isc_buffer_copyregion(forward->msgbuf, mr);
12831 if (result != ISC_R_SUCCESS)
12834 isc_mem_attach(zone->mctx, &forward->mctx);
12835 dns_zone_iattach(zone, &forward->zone);
12836 result = sendtomaster(forward);
12839 if (result != ISC_R_SUCCESS) {
12840 forward_destroy(forward);
12846 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
12847 REQUIRE(DNS_ZONE_VALID(zone));
12848 REQUIRE(next != NULL && *next == NULL);
12850 *next = ISC_LIST_NEXT(zone, link);
12852 return (ISC_R_NOMORE);
12854 return (ISC_R_SUCCESS);
12858 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
12859 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12860 REQUIRE(first != NULL && *first == NULL);
12862 *first = ISC_LIST_HEAD(zmgr->zones);
12863 if (*first == NULL)
12864 return (ISC_R_NOMORE);
12866 return (ISC_R_SUCCESS);
12874 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
12875 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
12876 dns_zonemgr_t **zmgrp)
12878 dns_zonemgr_t *zmgr;
12879 isc_result_t result;
12880 isc_interval_t interval;
12882 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
12884 return (ISC_R_NOMEMORY);
12887 isc_mem_attach(mctx, &zmgr->mctx);
12888 zmgr->taskmgr = taskmgr;
12889 zmgr->timermgr = timermgr;
12890 zmgr->socketmgr = socketmgr;
12891 zmgr->zonetasks = NULL;
12893 zmgr->notifyrl = NULL;
12894 zmgr->refreshrl = NULL;
12895 ISC_LIST_INIT(zmgr->zones);
12896 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
12897 ISC_LIST_INIT(zmgr->xfrin_in_progress);
12898 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
12899 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
12900 if (result != ISC_R_SUCCESS)
12903 zmgr->transfersin = 10;
12904 zmgr->transfersperns = 2;
12906 /* Unreachable lock. */
12907 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
12908 if (result != ISC_R_SUCCESS)
12911 /* Create a single task for queueing of SOA queries. */
12912 result = isc_task_create(taskmgr, 1, &zmgr->task);
12913 if (result != ISC_R_SUCCESS)
12916 isc_task_setname(zmgr->task, "zmgr", zmgr);
12917 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
12919 if (result != ISC_R_SUCCESS)
12922 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
12924 if (result != ISC_R_SUCCESS)
12925 goto free_notifyrl;
12927 /* default to 20 refresh queries / notifies per second. */
12928 isc_interval_set(&interval, 0, 1000000000/2);
12929 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
12930 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12931 isc_ratelimiter_setpertic(zmgr->notifyrl, 10);
12933 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
12934 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12935 isc_ratelimiter_setpertic(zmgr->refreshrl, 10);
12938 zmgr->ioactive = 0;
12939 ISC_LIST_INIT(zmgr->high);
12940 ISC_LIST_INIT(zmgr->low);
12942 result = isc_mutex_init(&zmgr->iolock);
12943 if (result != ISC_R_SUCCESS)
12944 goto free_refreshrl;
12946 zmgr->magic = ZONEMGR_MAGIC;
12949 return (ISC_R_SUCCESS);
12953 DESTROYLOCK(&zmgr->iolock);
12956 isc_ratelimiter_detach(&zmgr->refreshrl);
12958 isc_ratelimiter_detach(&zmgr->notifyrl);
12960 isc_task_detach(&zmgr->task);
12962 isc_rwlock_destroy(&zmgr->urlock);
12964 isc_rwlock_destroy(&zmgr->rwlock);
12966 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12967 isc_mem_detach(&mctx);
12972 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12973 isc_result_t result;
12975 REQUIRE(DNS_ZONE_VALID(zone));
12976 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12978 if (zmgr->zonetasks == NULL)
12979 return (ISC_R_FAILURE);
12981 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12983 REQUIRE(zone->task == NULL);
12984 REQUIRE(zone->timer == NULL);
12985 REQUIRE(zone->zmgr == NULL);
12987 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
12990 * Set the task name. The tag will arbitrarily point to one
12991 * of the zones sharing the task (in practice, the one
12992 * to be managed last).
12994 isc_task_setname(zone->task, "zone", zone);
12996 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
12998 zone->task, zone_timer, zone,
13001 if (result != ISC_R_SUCCESS)
13005 * The timer "holds" a iref.
13008 INSIST(zone->irefs != 0);
13010 ISC_LIST_APPEND(zmgr->zones, zone, link);
13017 isc_task_detach(&zone->task);
13021 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13026 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
13027 isc_boolean_t free_now = ISC_FALSE;
13029 REQUIRE(DNS_ZONE_VALID(zone));
13030 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13031 REQUIRE(zone->zmgr == zmgr);
13033 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13036 ISC_LIST_UNLINK(zmgr->zones, zone, link);
13039 if (zmgr->refs == 0)
13040 free_now = ISC_TRUE;
13043 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13046 zonemgr_free(zmgr);
13047 ENSURE(zone->zmgr == NULL);
13051 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
13052 REQUIRE(DNS_ZONEMGR_VALID(source));
13053 REQUIRE(target != NULL && *target == NULL);
13055 RWLOCK(&source->rwlock, isc_rwlocktype_write);
13056 REQUIRE(source->refs > 0);
13058 INSIST(source->refs > 0);
13059 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
13064 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
13065 dns_zonemgr_t *zmgr;
13066 isc_boolean_t free_now = ISC_FALSE;
13068 REQUIRE(zmgrp != NULL);
13070 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13072 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13074 if (zmgr->refs == 0)
13075 free_now = ISC_TRUE;
13076 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13079 zonemgr_free(zmgr);
13084 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
13087 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13089 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13090 for (p = ISC_LIST_HEAD(zmgr->zones);
13092 p = ISC_LIST_NEXT(p, link))
13094 dns_zone_maintenance(p);
13096 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13099 * Recent configuration changes may have increased the
13100 * amount of available transfers quota. Make sure any
13101 * transfers currently blocked on quota get started if
13104 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13105 zmgr_resume_xfrs(zmgr, ISC_TRUE);
13106 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13107 return (ISC_R_SUCCESS);
13111 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
13113 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13115 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13116 zmgr_resume_xfrs(zmgr, ISC_TRUE);
13117 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13121 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
13124 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13126 isc_ratelimiter_shutdown(zmgr->notifyrl);
13127 isc_ratelimiter_shutdown(zmgr->refreshrl);
13129 if (zmgr->task != NULL)
13130 isc_task_destroy(&zmgr->task);
13131 if (zmgr->zonetasks != NULL)
13132 isc_taskpool_destroy(&zmgr->zonetasks);
13134 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13135 for (zone = ISC_LIST_HEAD(zmgr->zones);
13137 zone = ISC_LIST_NEXT(zone, link))
13140 forward_cancel(zone);
13143 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13147 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
13148 isc_result_t result;
13149 int ntasks = num_zones / 100;
13150 isc_taskpool_t *pool = NULL;
13152 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13155 * For anything fewer than 1000 zones we use 10 tasks in
13156 * the task pool. More than that, and we'll scale at one
13157 * task per 100 zones.
13162 /* Create or resize the zone task pool. */
13163 if (zmgr->zonetasks == NULL)
13164 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
13167 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
13169 if (result == ISC_R_SUCCESS)
13170 zmgr->zonetasks = pool;
13176 zonemgr_free(dns_zonemgr_t *zmgr) {
13179 INSIST(zmgr->refs == 0);
13180 INSIST(ISC_LIST_EMPTY(zmgr->zones));
13184 DESTROYLOCK(&zmgr->iolock);
13185 isc_ratelimiter_detach(&zmgr->notifyrl);
13186 isc_ratelimiter_detach(&zmgr->refreshrl);
13188 isc_rwlock_destroy(&zmgr->urlock);
13189 isc_rwlock_destroy(&zmgr->rwlock);
13191 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
13192 isc_mem_detach(&mctx);
13196 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
13197 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13199 zmgr->transfersin = value;
13203 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
13204 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13206 return (zmgr->transfersin);
13210 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
13211 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13213 zmgr->transfersperns = value;
13217 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
13218 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13220 return (zmgr->transfersperns);
13224 * Try to start a new incoming zone transfer to fill a quota
13225 * slot that was just vacated.
13228 * The zone manager is locked by the caller.
13231 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
13235 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
13239 isc_result_t result;
13240 next = ISC_LIST_NEXT(zone, statelink);
13241 result = zmgr_start_xfrin_ifquota(zmgr, zone);
13242 if (result == ISC_R_SUCCESS) {
13246 * We successfully filled the slot. We're done.
13249 } else if (result == ISC_R_QUOTA) {
13251 * Not enough quota. This is probably the per-server
13252 * quota, because we usually get called when a unit of
13253 * global quota has just been freed. Try the next
13254 * zone, it may succeed if it uses another master.
13258 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13259 "starting zone transfer: %s",
13260 isc_result_totext(result));
13267 * Try to start an incoming zone transfer for 'zone', quota permitting.
13270 * The zone manager is locked by the caller.
13273 * ISC_R_SUCCESS There was enough quota and we attempted to
13274 * start a transfer. zone_xfrdone() has been or will
13276 * ISC_R_QUOTA Not enough quota.
13279 static isc_result_t
13280 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
13281 dns_peer_t *peer = NULL;
13282 isc_netaddr_t masterip;
13283 isc_uint32_t nxfrsin, nxfrsperns;
13285 isc_uint32_t maxtransfersin, maxtransfersperns;
13289 * If we are exiting just pretend we got quota so the zone will
13290 * be cleaned up in the zone's task context.
13293 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
13299 * Find any configured information about the server we'd
13300 * like to transfer this zone from.
13302 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
13303 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
13307 * Determine the total maximum number of simultaneous
13308 * transfers allowed, and the maximum for this specific
13311 maxtransfersin = zmgr->transfersin;
13312 maxtransfersperns = zmgr->transfersperns;
13314 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
13317 * Count the total number of transfers that are in progress,
13318 * and the number of transfers in progress from this master.
13319 * We linearly scan a list of all transfers; if this turns
13320 * out to be too slow, we could hash on the master address.
13322 nxfrsin = nxfrsperns = 0;
13323 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13325 x = ISC_LIST_NEXT(x, statelink))
13330 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
13334 if (isc_netaddr_equal(&xip, &masterip))
13338 /* Enforce quota. */
13339 if (nxfrsin >= maxtransfersin)
13340 return (ISC_R_QUOTA);
13342 if (nxfrsperns >= maxtransfersperns)
13343 return (ISC_R_QUOTA);
13347 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
13348 * list and send it an event to let it start the actual transfer in the
13349 * context of its own task.
13351 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
13352 got_transfer_quota, zone, sizeof(isc_event_t));
13354 return (ISC_R_NOMEMORY);
13357 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
13358 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
13359 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
13360 zone->statelist = &zmgr->xfrin_in_progress;
13361 isc_task_send(zone->task, &e);
13362 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
13365 return (ISC_R_SUCCESS);
13369 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
13371 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13372 REQUIRE(iolimit > 0);
13374 zmgr->iolimit = iolimit;
13378 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
13380 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13382 return (zmgr->iolimit);
13386 * Get permission to request a file handle from the OS.
13387 * An event will be sent to action when one is available.
13388 * There are two queues available (high and low), the high
13389 * queue will be serviced before the low one.
13391 * zonemgr_putio() must be called after the event is delivered to
13395 static isc_result_t
13396 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
13397 isc_task_t *task, isc_taskaction_t action, void *arg,
13401 isc_boolean_t queue;
13403 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13404 REQUIRE(iop != NULL && *iop == NULL);
13406 io = isc_mem_get(zmgr->mctx, sizeof(*io));
13408 return (ISC_R_NOMEMORY);
13409 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
13410 action, arg, sizeof(*io->event));
13411 if (io->event == NULL) {
13412 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13413 return (ISC_R_NOMEMORY);
13418 isc_task_attach(task, &io->task);
13419 ISC_LINK_INIT(io, link);
13420 io->magic = IO_MAGIC;
13422 LOCK(&zmgr->iolock);
13424 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
13427 ISC_LIST_APPEND(zmgr->high, io, link);
13429 ISC_LIST_APPEND(zmgr->low, io, link);
13431 UNLOCK(&zmgr->iolock);
13435 isc_task_send(io->task, &io->event);
13437 return (ISC_R_SUCCESS);
13441 zonemgr_putio(dns_io_t **iop) {
13444 dns_zonemgr_t *zmgr;
13446 REQUIRE(iop != NULL);
13448 REQUIRE(DNS_IO_VALID(io));
13452 INSIST(!ISC_LINK_LINKED(io, link));
13453 INSIST(io->event == NULL);
13456 isc_task_detach(&io->task);
13458 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13460 LOCK(&zmgr->iolock);
13461 INSIST(zmgr->ioactive > 0);
13463 next = HEAD(zmgr->high);
13465 next = HEAD(zmgr->low);
13466 if (next != NULL) {
13468 ISC_LIST_UNLINK(zmgr->high, next, link);
13470 ISC_LIST_UNLINK(zmgr->low, next, link);
13471 INSIST(next->event != NULL);
13473 UNLOCK(&zmgr->iolock);
13475 isc_task_send(next->task, &next->event);
13479 zonemgr_cancelio(dns_io_t *io) {
13480 isc_boolean_t send_event = ISC_FALSE;
13482 REQUIRE(DNS_IO_VALID(io));
13485 * If we are queued to be run then dequeue.
13487 LOCK(&io->zmgr->iolock);
13488 if (ISC_LINK_LINKED(io, link)) {
13490 ISC_LIST_UNLINK(io->zmgr->high, io, link);
13492 ISC_LIST_UNLINK(io->zmgr->low, io, link);
13494 send_event = ISC_TRUE;
13495 INSIST(io->event != NULL);
13497 UNLOCK(&io->zmgr->iolock);
13499 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
13500 isc_task_send(io->task, &io->event);
13505 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
13508 isc_result_t result;
13510 buflen = strlen(path) + strlen(templat) + 2;
13512 buf = isc_mem_get(zone->mctx, buflen);
13516 result = isc_file_template(path, templat, buf, buflen);
13517 if (result != ISC_R_SUCCESS)
13520 result = isc_file_renameunique(path, buf);
13521 if (result != ISC_R_SUCCESS)
13524 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
13525 "renaming file to '%s' for failure analysis and "
13526 "retransferring.", path, buf);
13529 isc_mem_put(zone->mctx, buf, buflen);
13533 /* Hook for ondestroy notification from a database. */
13536 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
13537 dns_db_t *db = event->sender;
13540 isc_event_free(&event);
13542 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13543 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13544 "database (%p) destroyed", (void*) db);
13549 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
13550 isc_interval_t interval;
13551 isc_uint32_t s, ns;
13552 isc_uint32_t pertic;
13553 isc_result_t result;
13555 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13564 } else if (value <= 10) {
13566 ns = 1000000000 / value;
13570 ns = (1000000000 / value) * 10;
13574 isc_interval_set(&interval, s, ns);
13576 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
13577 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13578 isc_ratelimiter_setpertic(zmgr->notifyrl, pertic);
13580 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
13581 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13582 isc_ratelimiter_setpertic(zmgr->refreshrl, pertic);
13584 zmgr->serialqueryrate = value;
13588 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
13589 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13591 return (zmgr->serialqueryrate);
13595 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13596 isc_sockaddr_t *local, isc_time_t *now)
13599 isc_rwlocktype_t locktype;
13600 isc_result_t result;
13601 isc_uint32_t seconds = isc_time_seconds(now);
13602 isc_uint32_t count = 0;
13604 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13606 locktype = isc_rwlocktype_read;
13607 RWLOCK(&zmgr->urlock, locktype);
13608 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13609 if (zmgr->unreachable[i].expire >= seconds &&
13610 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13611 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13612 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13613 if (result == ISC_R_SUCCESS) {
13614 locktype = isc_rwlocktype_write;
13615 zmgr->unreachable[i].last = seconds;
13616 count = zmgr->unreachable[i].count;
13621 RWUNLOCK(&zmgr->urlock, locktype);
13622 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U));
13626 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13627 isc_sockaddr_t *local)
13630 isc_rwlocktype_t locktype;
13631 isc_result_t result;
13633 char master[ISC_SOCKADDR_FORMATSIZE];
13634 char source[ISC_SOCKADDR_FORMATSIZE];
13636 isc_sockaddr_format(remote, master, sizeof(master));
13637 isc_sockaddr_format(local, source, sizeof(source));
13639 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13641 locktype = isc_rwlocktype_read;
13642 RWLOCK(&zmgr->urlock, locktype);
13643 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13644 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13645 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13646 if (zmgr->unreachable[i].expire == 0)
13648 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13649 if (result == ISC_R_SUCCESS) {
13650 locktype = isc_rwlocktype_write;
13651 zmgr->unreachable[i].expire = 0;
13652 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13653 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
13654 "master %s (source %s) deleted "
13655 "from unreachable cache",
13661 RWUNLOCK(&zmgr->urlock, locktype);
13665 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13666 isc_sockaddr_t *local, isc_time_t *now)
13668 isc_uint32_t seconds = isc_time_seconds(now);
13669 isc_uint32_t last = seconds;
13670 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
13672 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13674 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
13675 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13676 /* Existing entry? */
13677 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13678 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
13681 if (zmgr->unreachable[i].expire < seconds)
13683 /* Least recently used slot? */
13684 if (zmgr->unreachable[i].last < last) {
13685 last = zmgr->unreachable[i].last;
13689 if (i < UNREACH_CHACHE_SIZE) {
13691 * Found a existing entry. Update the expire timer and
13692 * last usage timestamps.
13694 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
13695 zmgr->unreachable[i].last = seconds;
13696 if (zmgr->unreachable[i].expire < seconds)
13697 zmgr->unreachable[i].count = 1;
13699 zmgr->unreachable[i].count++;
13700 } else if (slot != UNREACH_CHACHE_SIZE) {
13702 * Found a empty slot. Add a new entry to the cache.
13704 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
13705 zmgr->unreachable[slot].last = seconds;
13706 zmgr->unreachable[slot].remote = *remote;
13707 zmgr->unreachable[slot].local = *local;
13708 zmgr->unreachable[slot].count = 1;
13711 * Replace the least recently used entry in the cache.
13713 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
13714 zmgr->unreachable[oldest].last = seconds;
13715 zmgr->unreachable[oldest].remote = *remote;
13716 zmgr->unreachable[oldest].local = *local;
13717 zmgr->unreachable[oldest].count = 1;
13719 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
13723 dns_zone_forcereload(dns_zone_t *zone) {
13724 REQUIRE(DNS_ZONE_VALID(zone));
13726 if (zone->type == dns_zone_master)
13730 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13732 dns_zone_refresh(zone);
13736 dns_zone_isforced(dns_zone_t *zone) {
13737 REQUIRE(DNS_ZONE_VALID(zone));
13739 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
13743 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
13745 * This function is obsoleted.
13749 return (ISC_R_NOTIMPLEMENTED);
13753 dns_zone_getstatscounters(dns_zone_t *zone) {
13755 * This function is obsoleted.
13762 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
13763 REQUIRE(DNS_ZONE_VALID(zone));
13764 REQUIRE(zone->stats == NULL);
13767 zone->stats = NULL;
13768 isc_stats_attach(stats, &zone->stats);
13773 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
13774 REQUIRE(DNS_ZONE_VALID(zone));
13777 if (zone->requeststats_on && stats == NULL)
13778 zone->requeststats_on = ISC_FALSE;
13779 else if (!zone->requeststats_on && stats != NULL) {
13780 if (zone->requeststats == NULL) {
13781 isc_stats_attach(stats, &zone->requeststats);
13782 zone->requeststats_on = ISC_TRUE;
13791 dns_zone_getrequeststats(dns_zone_t *zone) {
13793 * We don't lock zone for efficiency reason. This is not catastrophic
13794 * because requeststats must always be valid when requeststats_on is
13796 * Some counters may be incremented while requeststats_on is becoming
13797 * false, or some cannot be incremented just after the statistics are
13798 * installed, but it shouldn't matter much in practice.
13800 if (zone->requeststats_on)
13801 return (zone->requeststats);
13807 dns_zone_dialup(dns_zone_t *zone) {
13809 REQUIRE(DNS_ZONE_VALID(zone));
13811 zone_debuglog(zone, "dns_zone_dialup", 3,
13812 "notify = %d, refresh = %d",
13813 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
13814 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
13816 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
13817 dns_zone_notify(zone);
13818 if (zone->type != dns_zone_master &&
13819 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
13820 dns_zone_refresh(zone);
13824 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
13825 REQUIRE(DNS_ZONE_VALID(zone));
13828 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
13829 DNS_ZONEFLG_DIALREFRESH |
13830 DNS_ZONEFLG_NOREFRESH);
13832 case dns_dialuptype_no:
13834 case dns_dialuptype_yes:
13835 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
13836 DNS_ZONEFLG_DIALREFRESH |
13837 DNS_ZONEFLG_NOREFRESH));
13839 case dns_dialuptype_notify:
13840 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13842 case dns_dialuptype_notifypassive:
13843 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13844 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13846 case dns_dialuptype_refresh:
13847 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
13848 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13850 case dns_dialuptype_passive:
13851 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13860 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
13861 isc_result_t result = ISC_R_SUCCESS;
13863 REQUIRE(DNS_ZONE_VALID(zone));
13866 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
13873 dns_zone_getkeydirectory(dns_zone_t *zone) {
13874 REQUIRE(DNS_ZONE_VALID(zone));
13876 return (zone->keydirectory);
13880 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
13882 unsigned int count = 0;
13884 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13886 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13888 case DNS_ZONESTATE_XFERRUNNING:
13889 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13891 zone = ISC_LIST_NEXT(zone, statelink))
13894 case DNS_ZONESTATE_XFERDEFERRED:
13895 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
13897 zone = ISC_LIST_NEXT(zone, statelink))
13900 case DNS_ZONESTATE_SOAQUERY:
13901 for (zone = ISC_LIST_HEAD(zmgr->zones);
13903 zone = ISC_LIST_NEXT(zone, link))
13904 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
13907 case DNS_ZONESTATE_ANY:
13908 for (zone = ISC_LIST_HEAD(zmgr->zones);
13910 zone = ISC_LIST_NEXT(zone, link)) {
13911 dns_view_t *view = zone->view;
13912 if (view != NULL && strcmp(view->name, "_bind") == 0)
13921 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13927 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
13928 isc_boolean_t ok = ISC_TRUE;
13929 isc_boolean_t fail = ISC_FALSE;
13930 char namebuf[DNS_NAME_FORMATSIZE];
13931 char namebuf2[DNS_NAME_FORMATSIZE];
13932 char typebuf[DNS_RDATATYPE_FORMATSIZE];
13933 int level = ISC_LOG_WARNING;
13936 REQUIRE(DNS_ZONE_VALID(zone));
13938 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
13939 return (ISC_R_SUCCESS);
13941 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
13942 level = ISC_LOG_ERROR;
13946 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
13948 dns_name_format(name, namebuf, sizeof(namebuf));
13949 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13950 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
13951 dns_result_totext(DNS_R_BADOWNERNAME));
13953 return (DNS_R_BADOWNERNAME);
13956 dns_name_init(&bad, NULL);
13957 ok = dns_rdata_checknames(rdata, name, &bad);
13959 dns_name_format(name, namebuf, sizeof(namebuf));
13960 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
13961 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13962 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
13963 namebuf2, dns_result_totext(DNS_R_BADNAME));
13965 return (DNS_R_BADNAME);
13968 return (ISC_R_SUCCESS);
13972 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
13973 REQUIRE(DNS_ZONE_VALID(zone));
13974 zone->checkmx = checkmx;
13978 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
13979 REQUIRE(DNS_ZONE_VALID(zone));
13980 zone->checksrv = checksrv;
13984 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
13985 REQUIRE(DNS_ZONE_VALID(zone));
13986 zone->checkns = checkns;
13990 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
13991 REQUIRE(DNS_ZONE_VALID(zone));
13994 zone->isself = isself;
13995 zone->isselfarg = arg;
14000 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
14001 REQUIRE(DNS_ZONE_VALID(zone));
14004 zone->notifydelay = delay;
14009 dns_zone_getnotifydelay(dns_zone_t *zone) {
14010 REQUIRE(DNS_ZONE_VALID(zone));
14012 return (zone->notifydelay);
14016 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
14017 isc_uint16_t keyid, isc_boolean_t delete)
14019 isc_result_t result;
14020 REQUIRE(DNS_ZONE_VALID(zone));
14022 dns_zone_log(zone, ISC_LOG_NOTICE,
14023 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
14026 result = zone_signwithkey(zone, algorithm, keyid, delete);
14032 static const char *hex = "0123456789ABCDEF";
14035 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
14036 isc_result_t result;
14037 char salt[255*2+1];
14040 REQUIRE(DNS_ZONE_VALID(zone));
14042 if (nsec3param->salt_length != 0) {
14043 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
14044 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
14045 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
14046 salt[j++] = hex[nsec3param->salt[i] & 0xf];
14051 dns_zone_log(zone, ISC_LOG_NOTICE,
14052 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
14053 nsec3param->hash, nsec3param->iterations,
14056 result = zone_addnsec3chain(zone, nsec3param);
14063 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
14064 REQUIRE(DNS_ZONE_VALID(zone));
14068 zone->nodes = nodes;
14072 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
14073 REQUIRE(DNS_ZONE_VALID(zone));
14076 * We treat signatures as a signed value so explicitly
14077 * limit its range here.
14079 if (signatures > ISC_INT32_MAX)
14080 signatures = ISC_INT32_MAX;
14081 else if (signatures == 0)
14083 zone->signatures = signatures;
14087 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
14088 REQUIRE(DNS_ZONE_VALID(zone));
14089 zone->privatetype = type;
14093 dns_zone_getprivatetype(dns_zone_t *zone) {
14094 REQUIRE(DNS_ZONE_VALID(zone));
14095 return (zone->privatetype);
14098 static isc_result_t
14099 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
14100 isc_boolean_t delete)
14102 dns_signing_t *signing;
14103 dns_signing_t *current;
14104 isc_result_t result = ISC_R_SUCCESS;
14107 signing = isc_mem_get(zone->mctx, sizeof *signing);
14108 if (signing == NULL)
14109 return (ISC_R_NOMEMORY);
14111 signing->magic = 0;
14112 signing->db = NULL;
14113 signing->dbiterator = NULL;
14114 signing->algorithm = algorithm;
14115 signing->keyid = keyid;
14116 signing->delete = delete;
14117 signing->done = ISC_FALSE;
14121 for (current = ISC_LIST_HEAD(zone->signing);
14123 current = ISC_LIST_NEXT(current, link)) {
14124 if (current->db == zone->db &&
14125 current->algorithm == signing->algorithm &&
14126 current->keyid == signing->keyid) {
14127 if (current->delete != signing->delete)
14128 current->done = ISC_TRUE;
14134 if (zone->db != NULL) {
14135 dns_db_attach(zone->db, &signing->db);
14136 result = dns_db_createiterator(signing->db, 0,
14137 &signing->dbiterator);
14139 if (result == ISC_R_SUCCESS)
14140 result = dns_dbiterator_first(signing->dbiterator);
14141 if (result == ISC_R_SUCCESS) {
14142 dns_dbiterator_pause(signing->dbiterator);
14143 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
14145 if (isc_time_isepoch(&zone->signingtime)) {
14146 zone->signingtime = now;
14147 if (zone->task != NULL)
14148 zone_settimer(zone, &now);
14152 result = ISC_R_NOTFOUND;
14155 if (signing != NULL) {
14156 if (signing->db != NULL)
14157 dns_db_detach(&signing->db);
14158 if (signing->dbiterator != NULL)
14159 dns_dbiterator_destroy(&signing->dbiterator);
14160 isc_mem_put(zone->mctx, signing, sizeof *signing);
14166 logmsg(const char *format, ...) {
14168 va_start(args, format);
14169 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
14170 ISC_LOG_DEBUG(1), format, args);
14175 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
14176 dns_dnsseckey_t *key;
14177 while (!ISC_LIST_EMPTY(*list)) {
14178 key = ISC_LIST_HEAD(*list);
14179 ISC_LIST_UNLINK(*list, key, link);
14180 dns_dnsseckey_destroy(mctx, &key);
14184 /* Called once; *timep should be set to the current time. */
14185 static isc_result_t
14186 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
14187 isc_result_t result;
14188 isc_stdtime_t now, then = 0, event;
14193 for (i = 0; i <= DST_MAX_TIMES; i++) {
14194 result = dst_key_gettime(key, i, &event);
14195 if (result == ISC_R_SUCCESS && event > now &&
14196 (then == 0 || event < then))
14202 return (ISC_R_SUCCESS);
14205 return (ISC_R_NOTFOUND);
14208 static isc_result_t
14209 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
14210 const dns_rdata_t *rdata, isc_boolean_t *flag)
14212 dns_rdataset_t rdataset;
14213 dns_dbnode_t *node = NULL;
14214 isc_result_t result;
14216 dns_rdataset_init(&rdataset);
14217 if (rdata->type == dns_rdatatype_nsec3)
14218 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
14220 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
14221 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
14222 (isc_stdtime_t) 0, &rdataset, NULL);
14223 if (result == ISC_R_NOTFOUND) {
14225 result = ISC_R_SUCCESS;
14229 for (result = dns_rdataset_first(&rdataset);
14230 result == ISC_R_SUCCESS;
14231 result = dns_rdataset_next(&rdataset)) {
14232 dns_rdata_t myrdata = DNS_RDATA_INIT;
14233 dns_rdataset_current(&rdataset, &myrdata);
14234 if (!dns_rdata_compare(&myrdata, rdata))
14237 dns_rdataset_disassociate(&rdataset);
14238 if (result == ISC_R_SUCCESS) {
14240 } else if (result == ISC_R_NOMORE) {
14242 result = ISC_R_SUCCESS;
14247 dns_db_detachnode(db, &node);
14252 * Add records to signal the state of signing or of key removal.
14254 static isc_result_t
14255 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
14256 dns_dbversion_t *ver, dns_diff_t *diff,
14257 isc_boolean_t sign_all)
14259 dns_difftuple_t *tuple, *newtuple = NULL;
14260 dns_rdata_dnskey_t dnskey;
14261 dns_rdata_t rdata = DNS_RDATA_INIT;
14262 isc_boolean_t flag;
14264 isc_result_t result = ISC_R_SUCCESS;
14265 isc_uint16_t keyid;
14266 unsigned char buf[5];
14267 dns_name_t *name = dns_db_origin(db);
14269 for (tuple = ISC_LIST_HEAD(diff->tuples);
14271 tuple = ISC_LIST_NEXT(tuple, link)) {
14272 if (tuple->rdata.type != dns_rdatatype_dnskey)
14275 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
14276 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14277 if ((dnskey.flags &
14278 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
14279 != DNS_KEYOWNER_ZONE)
14282 dns_rdata_toregion(&tuple->rdata, &r);
14284 keyid = dst_region_computeid(&r, dnskey.algorithm);
14286 buf[0] = dnskey.algorithm;
14287 buf[1] = (keyid & 0xff00) >> 8;
14288 buf[2] = (keyid & 0xff);
14289 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
14292 rdata.length = sizeof(buf);
14293 rdata.type = privatetype;
14294 rdata.rdclass = tuple->rdata.rdclass;
14296 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
14297 CHECK(rr_exists(db, ver, name, &rdata, &flag));
14300 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
14301 name, 0, &rdata, &newtuple));
14302 CHECK(do_one_tuple(&newtuple, db, ver, diff));
14303 INSIST(newtuple == NULL);
14307 * Remove any record which says this operation has already
14311 CHECK(rr_exists(db, ver, name, &rdata, &flag));
14313 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
14314 name, 0, &rdata, &newtuple));
14315 CHECK(do_one_tuple(&newtuple, db, ver, diff));
14316 INSIST(newtuple == NULL);
14323 static isc_result_t
14324 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14325 dns_diff_t *diff, zonediff_t *zonediff)
14327 isc_result_t result;
14328 isc_stdtime_t now, inception, soaexpire;
14329 isc_boolean_t check_ksk, keyset_kskonly;
14330 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
14331 unsigned int nkeys = 0, i;
14332 dns_difftuple_t *tuple;
14334 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
14335 zone_keys, &nkeys);
14336 if (result != ISC_R_SUCCESS) {
14337 dns_zone_log(zone, ISC_LOG_ERROR,
14338 "sign_apex:find_zone_keys -> %s",
14339 dns_result_totext(result));
14343 isc_stdtime_get(&now);
14344 inception = now - 3600; /* Allow for clock skew. */
14345 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
14347 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14348 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
14351 * See if update_sigs will update DNSKEY signature and if not
14352 * cause them to sign so that so that newly activated keys
14355 for (tuple = ISC_LIST_HEAD(diff->tuples);
14357 tuple = ISC_LIST_NEXT(tuple, link)) {
14358 if (tuple->rdata.type == dns_rdatatype_dnskey &&
14359 dns_name_equal(&tuple->name, &zone->origin))
14363 if (tuple == NULL) {
14364 result = del_sigs(zone, db, ver, &zone->origin,
14365 dns_rdatatype_dnskey, zonediff,
14366 zone_keys, nkeys, now, ISC_FALSE);
14367 if (result != ISC_R_SUCCESS) {
14368 dns_zone_log(zone, ISC_LOG_ERROR,
14369 "sign_apex:del_sigs -> %s",
14370 dns_result_totext(result));
14373 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
14374 zonediff->diff, zone_keys, nkeys, zone->mctx,
14375 inception, soaexpire, check_ksk,
14377 if (result != ISC_R_SUCCESS) {
14378 dns_zone_log(zone, ISC_LOG_ERROR,
14379 "sign_apex:add_sigs -> %s",
14380 dns_result_totext(result));
14385 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
14386 inception, soaexpire, now, check_ksk,
14387 keyset_kskonly, zonediff);
14389 if (result != ISC_R_SUCCESS) {
14390 dns_zone_log(zone, ISC_LOG_ERROR,
14391 "sign_apex:update_sigs -> %s",
14392 dns_result_totext(result));
14397 for (i = 0; i < nkeys; i++)
14398 dst_key_free(&zone_keys[i]);
14403 * Prevent the zone entering a inconsistent state where
14404 * NSEC only DNSKEYs are present with NSEC3 chains.
14405 * See update.c:check_dnssec()
14407 static isc_boolean_t
14408 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14411 isc_result_t result;
14412 dns_difftuple_t *tuple;
14413 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
14414 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
14416 /* Scan the tuples for an NSEC-only DNSKEY */
14417 for (tuple = ISC_LIST_HEAD(diff->tuples);
14419 tuple = ISC_LIST_NEXT(tuple, link)) {
14421 if (tuple->rdata.type != dns_rdatatype_dnskey ||
14422 tuple->op != DNS_DIFFOP_ADD)
14425 alg = tuple->rdata.data[3];
14426 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
14427 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
14428 nseconly = ISC_TRUE;
14433 /* Check existing DB for NSEC-only DNSKEY */
14435 CHECK(dns_nsec_nseconly(db, ver, &nseconly));
14437 /* Check existing DB for NSEC3 */
14439 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
14440 privatetype, &nsec3));
14442 /* Refuse to allow NSEC3 with NSEC-only keys */
14443 if (nseconly && nsec3) {
14444 dns_zone_log(zone, ISC_LOG_ERROR,
14445 "NSEC only DNSKEYs and NSEC3 chains not allowed");
14452 return (ISC_FALSE);
14455 static isc_result_t
14456 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14459 isc_result_t result;
14460 dns_dbnode_t *node = NULL;
14461 dns_rdataset_t rdataset;
14463 dns_rdataset_init(&rdataset);
14464 CHECK(dns_db_getoriginnode(db, &node));
14466 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14467 dns_rdatatype_none, 0, &rdataset, NULL);
14468 if (dns_rdataset_isassociated(&rdataset))
14469 dns_rdataset_disassociate(&rdataset);
14470 if (result != ISC_R_NOTFOUND)
14473 result = dns_nsec3param_deletechains(db, ver, zone, diff);
14477 dns_db_detachnode(db, &node);
14482 * Given an RRSIG rdataset and an algorithm, determine whether there
14483 * are any signatures using that algorithm.
14485 static isc_boolean_t
14486 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
14487 dns_rdata_t rdata = DNS_RDATA_INIT;
14488 dns_rdata_rrsig_t rrsig;
14489 isc_result_t result;
14491 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
14492 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
14493 return (ISC_FALSE);
14496 for (result = dns_rdataset_first(rdataset);
14497 result == ISC_R_SUCCESS;
14498 result = dns_rdataset_next(rdataset))
14500 dns_rdataset_current(rdataset, &rdata);
14501 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
14502 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14503 dns_rdata_reset(&rdata);
14504 if (rrsig.algorithm == alg)
14508 return (ISC_FALSE);
14511 static isc_result_t
14512 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14515 dns_name_t *origin;
14516 isc_boolean_t build_nsec3;
14517 isc_result_t result;
14519 origin = dns_db_origin(db);
14520 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
14523 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
14524 ISC_FALSE, zone->privatetype, diff));
14525 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
14532 zone_rekey(dns_zone_t *zone) {
14533 isc_result_t result;
14534 dns_db_t *db = NULL;
14535 dns_dbnode_t *node = NULL;
14536 dns_dbversion_t *ver = NULL;
14537 dns_rdataset_t soaset, soasigs, keyset, keysigs;
14538 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
14539 dns_dnsseckey_t *key;
14540 dns_diff_t diff, _sig_diff;
14541 zonediff_t zonediff;
14542 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
14543 isc_boolean_t newalg = ISC_FALSE;
14544 isc_boolean_t fullsign;
14545 dns_ttl_t ttl = 3600;
14549 isc_time_t timenow;
14550 isc_interval_t ival;
14553 REQUIRE(DNS_ZONE_VALID(zone));
14555 ISC_LIST_INIT(dnskeys);
14556 ISC_LIST_INIT(keys);
14557 ISC_LIST_INIT(rmkeys);
14558 dns_rdataset_init(&soaset);
14559 dns_rdataset_init(&soasigs);
14560 dns_rdataset_init(&keyset);
14561 dns_rdataset_init(&keysigs);
14562 dir = dns_zone_getkeydirectory(zone);
14564 dns_diff_init(mctx, &diff);
14565 dns_diff_init(mctx, &_sig_diff);
14566 zonediff_init(&zonediff, &_sig_diff);
14568 CHECK(dns_zone_getdb(zone, &db));
14569 CHECK(dns_db_newversion(db, &ver));
14570 CHECK(dns_db_getoriginnode(db, &node));
14572 TIME_NOW(&timenow);
14573 now = isc_time_seconds(&timenow);
14575 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
14577 /* Get the SOA record's TTL */
14578 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
14579 dns_rdatatype_none, 0, &soaset, &soasigs));
14581 dns_rdataset_disassociate(&soaset);
14583 /* Get the DNSKEY rdataset */
14584 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14585 dns_rdatatype_none, 0, &keyset, &keysigs);
14586 if (result == ISC_R_SUCCESS) {
14588 result = dns_dnssec_keylistfromrdataset(&zone->origin, dir,
14590 &keysigs, &soasigs,
14591 ISC_FALSE, ISC_FALSE,
14593 /* Can't get keys for some reason; try again later. */
14594 if (result != ISC_R_SUCCESS)
14596 } else if (result != ISC_R_NOTFOUND)
14600 * True when called from "rndc sign". Indicates the zone should be
14601 * fully signed now.
14603 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
14605 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
14606 if (result == ISC_R_SUCCESS) {
14607 isc_boolean_t check_ksk;
14608 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14610 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
14611 &zone->origin, ttl, &diff,
14612 ISC_TF(!check_ksk),
14615 /* Keys couldn't be updated for some reason;
14616 * try again later. */
14617 if (result != ISC_R_SUCCESS) {
14618 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
14619 "couldn't update zone keys: %s",
14620 isc_result_totext(result));
14625 * See if any pre-existing keys have newly become active;
14626 * also, see if any new key is for a new algorithm, as in that
14627 * event, we need to sign the zone fully. (If there's a new
14628 * key, but it's for an already-existing algorithm, then
14629 * the zone signing can be handled incrementally.)
14631 for (key = ISC_LIST_HEAD(dnskeys);
14633 key = ISC_LIST_NEXT(key, link)) {
14634 if (!key->first_sign)
14637 newactive = ISC_TRUE;
14639 if (!dns_rdataset_isassociated(&keysigs)) {
14644 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
14646 * This isn't a new algorithm; clear
14647 * first_sign so we won't sign the
14648 * whole zone with this key later
14650 key->first_sign = ISC_FALSE;
14657 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
14658 dnskey_sane(zone, db, ver, &diff)) {
14659 CHECK(dns_diff_apply(&diff, db, ver));
14660 CHECK(clean_nsec3param(zone, db, ver, &diff));
14661 CHECK(add_signing_records(db, zone->privatetype,
14663 ISC_TF(newalg || fullsign)));
14664 CHECK(increment_soa_serial(db, ver, &diff, mctx));
14665 CHECK(add_chains(zone, db, ver, &diff));
14666 CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
14667 CHECK(zone_journal(zone, zonediff.diff, "zone_rekey"));
14672 dns_db_closeversion(db, &ver, commit);
14675 dns_difftuple_t *tuple;
14678 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14680 zone_needdump(zone, DNS_DUMP_DELAY);
14682 zone_settimer(zone, &timenow);
14684 /* Remove any signatures from removed keys. */
14685 if (!ISC_LIST_EMPTY(rmkeys)) {
14686 for (key = ISC_LIST_HEAD(rmkeys);
14688 key = ISC_LIST_NEXT(key, link)) {
14689 result = zone_signwithkey(zone,
14690 dst_key_alg(key->key),
14691 dst_key_id(key->key),
14693 if (result != ISC_R_SUCCESS) {
14694 dns_zone_log(zone, ISC_LOG_ERROR,
14695 "zone_signwithkey failed: %s",
14696 dns_result_totext(result));
14703 * "rndc sign" was called, so we now sign the zone
14704 * with all active keys, whether they're new or not.
14706 for (key = ISC_LIST_HEAD(dnskeys);
14708 key = ISC_LIST_NEXT(key, link)) {
14709 if (!key->force_sign && !key->hint_sign)
14712 result = zone_signwithkey(zone,
14713 dst_key_alg(key->key),
14714 dst_key_id(key->key),
14716 if (result != ISC_R_SUCCESS) {
14717 dns_zone_log(zone, ISC_LOG_ERROR,
14718 "zone_signwithkey failed: %s",
14719 dns_result_totext(result));
14722 } else if (newalg) {
14724 * We haven't been told to sign fully, but a new
14725 * algorithm was added to the DNSKEY. We sign
14726 * the full zone, but only with newly active
14729 for (key = ISC_LIST_HEAD(dnskeys);
14731 key = ISC_LIST_NEXT(key, link)) {
14732 if (!key->first_sign)
14735 result = zone_signwithkey(zone,
14736 dst_key_alg(key->key),
14737 dst_key_id(key->key),
14739 if (result != ISC_R_SUCCESS) {
14740 dns_zone_log(zone, ISC_LOG_ERROR,
14741 "zone_signwithkey failed: %s",
14742 dns_result_totext(result));
14748 * Clear fullsign flag, if it was set, so we don't do
14749 * another full signing next time
14751 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
14754 * Cause the zone to add/delete NSEC3 chains for the
14755 * deferred NSEC3PARAM changes.
14757 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
14759 tuple = ISC_LIST_NEXT(tuple, link)) {
14760 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
14761 dns_rdata_t rdata = DNS_RDATA_INIT;
14762 dns_rdata_nsec3param_t nsec3param;
14764 if (tuple->rdata.type != zone->privatetype ||
14765 tuple->op != DNS_DIFFOP_ADD)
14768 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
14771 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
14772 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14773 if (nsec3param.flags == 0)
14776 result = zone_addnsec3chain(zone, &nsec3param);
14777 if (result != ISC_R_SUCCESS) {
14778 dns_zone_log(zone, ISC_LOG_ERROR,
14779 "zone_addnsec3chain failed: %s",
14780 dns_result_totext(result));
14785 * Schedule the next resigning event
14787 set_resigntime(zone);
14791 isc_time_settoepoch(&zone->refreshkeytime);
14794 * If we're doing key maintenance, set the key refresh timer to
14795 * the next scheduled key event or to one hour in the future,
14796 * whichever is sooner.
14798 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
14799 isc_time_t timethen;
14800 isc_stdtime_t then;
14803 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
14804 zone->refreshkeytime = timethen;
14807 for (key = ISC_LIST_HEAD(dnskeys);
14809 key = ISC_LIST_NEXT(key, link)) {
14811 result = next_keyevent(key->key, &then);
14812 if (result != ISC_R_SUCCESS)
14815 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
14817 if (isc_time_compare(&timethen,
14818 &zone->refreshkeytime) < 0) {
14819 zone->refreshkeytime = timethen;
14824 zone_settimer(zone, &timenow);
14826 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
14827 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
14831 dns_diff_clear(&diff);
14832 dns_diff_clear(&_sig_diff);
14834 clear_keylist(&dnskeys, mctx);
14835 clear_keylist(&keys, mctx);
14836 clear_keylist(&rmkeys, mctx);
14839 dns_db_closeversion(db, &ver, ISC_FALSE);
14840 if (dns_rdataset_isassociated(&keyset))
14841 dns_rdataset_disassociate(&keyset);
14842 if (dns_rdataset_isassociated(&keysigs))
14843 dns_rdataset_disassociate(&keysigs);
14844 if (dns_rdataset_isassociated(&soasigs))
14845 dns_rdataset_disassociate(&soasigs);
14847 dns_db_detachnode(db, &node);
14849 dns_db_detach(&db);
14853 isc_interval_set(&ival, HOUR, 0);
14854 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
14859 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
14862 if (zone->type == dns_zone_master && zone->task != NULL) {
14866 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
14869 zone->refreshkeytime = now;
14870 zone_settimer(zone, &now);
14877 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
14878 unsigned int *errors)
14880 isc_result_t result;
14881 dns_dbnode_t *node = NULL;
14883 REQUIRE(DNS_ZONE_VALID(zone));
14884 REQUIRE(errors != NULL);
14886 result = dns_db_getoriginnode(db, &node);
14887 if (result != ISC_R_SUCCESS)
14889 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
14891 dns_db_detachnode(db, &node);
14896 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
14897 REQUIRE(DNS_ZONE_VALID(zone));
14899 zone->added = added;
14904 dns_zone_getadded(dns_zone_t *zone) {
14905 REQUIRE(DNS_ZONE_VALID(zone));
14906 return (zone->added);
14910 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
14912 isc_time_t loadtime;
14913 isc_result_t result;
14914 TIME_NOW(&loadtime);
14917 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);