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 * No previously known key, and the key is not
7937 * secure, so skip it.
7942 /* Delete old version */
7943 if (deletekey || !newkey)
7944 CHECK(update_one_rr(kfetch->db, ver, &diff,
7945 DNS_DIFFOP_DEL, keyname, 0,
7949 /* Set refresh timer */
7950 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7951 dns_rdata_reset(&keydatarr);
7952 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7953 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7954 dns_rdatatype_keydata,
7957 /* Insert updated version */
7958 CHECK(update_one_rr(kfetch->db, ver, &diff,
7959 DNS_DIFFOP_ADD, keyname, 0,
7961 } else if (newkey) {
7962 /* Convert DNSKEY to KEYDATA */
7963 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7964 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7965 dns_keydata_fromdnskey(&keydata, &dnskey, 0, 0, 0,
7967 keydata.addhd = initializing ? now : now + MONTH;
7968 keydata.refresh = refresh_time(kfetch, ISC_FALSE);
7969 dns_rdata_reset(&keydatarr);
7970 isc_buffer_init(&keyb, key_buf, sizeof(key_buf));
7971 dns_rdata_fromstruct(&keydatarr, zone->rdclass,
7972 dns_rdatatype_keydata,
7975 /* Insert into key zone */
7976 CHECK(update_one_rr(kfetch->db, ver, &diff,
7977 DNS_DIFFOP_ADD, keyname, 0,
7982 /* Trust this key. */
7983 result = dns_rdata_tostruct(&dnskeyrr, &dnskey, NULL);
7984 RUNTIME_CHECK(result == ISC_R_SUCCESS);
7985 trust_key(zone, keyname, &dnskey, mctx);
7988 if (secure && !deletekey)
7989 set_refreshkeytimer(zone, &keydata, now);
7993 * RFC5011 says, "A trust point that has all of its trust anchors
7994 * revoked is considered deleted and is treated as if the trust
7995 * point was never configured." But if someone revoked their
7996 * active key before the standby was trusted, that would mean the
7997 * zone would suddenly be nonsecured. We avoid this by checking to
7998 * see if there's pending keydata. If so, we put a null key in
7999 * the security roots; then all queries to the zone will fail.
8002 fail_secure(zone, keyname);
8006 if (!ISC_LIST_EMPTY(diff.tuples)) {
8007 /* Write changes to journal file. */
8008 CHECK(increment_soa_serial(kfetch->db, ver, &diff, mctx));
8009 CHECK(zone_journal(zone, &diff, "keyfetch_done"));
8012 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8013 zone_needdump(zone, 30);
8018 dns_diff_clear(&diff);
8020 dns_db_closeversion(kfetch->db, &ver, commit);
8023 dns_db_detach(&kfetch->db);
8025 INSIST(zone->irefs > 0);
8027 kfetch->zone = NULL;
8029 if (dns_rdataset_isassociated(&kfetch->keydataset))
8030 dns_rdataset_disassociate(&kfetch->keydataset);
8031 if (dns_rdataset_isassociated(&kfetch->dnskeyset))
8032 dns_rdataset_disassociate(&kfetch->dnskeyset);
8033 if (dns_rdataset_isassociated(&kfetch->dnskeysigset))
8034 dns_rdataset_disassociate(&kfetch->dnskeysigset);
8036 dns_name_free(keyname, mctx);
8037 isc_mem_put(mctx, kfetch, sizeof(dns_keyfetch_t));
8038 isc_mem_detach(&mctx);
8040 if (secroots != NULL)
8041 dns_keytable_detach(&secroots);
8043 free_needed = exit_check(zone);
8050 * Refresh the data in the key zone. Initiate a fetch to get new DNSKEY
8051 * records from the zone apex.
8054 zone_refreshkeys(dns_zone_t *zone) {
8055 const char me[] = "zone_refreshkeys";
8056 isc_result_t result;
8057 dns_rriterator_t rrit;
8058 dns_db_t *db = NULL;
8059 dns_dbversion_t *ver = NULL;
8061 dns_rdata_t rdata = DNS_RDATA_INIT;
8062 dns_rdata_keydata_t kd;
8064 isc_boolean_t commit = ISC_FALSE;
8065 isc_boolean_t fetching = ISC_FALSE, fetch_err = ISC_FALSE;
8068 REQUIRE(zone->db != NULL);
8070 isc_stdtime_get(&now);
8073 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
8074 isc_time_settoepoch(&zone->refreshkeytime);
8079 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8080 dns_db_attach(zone->db, &db);
8081 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8083 dns_diff_init(zone->mctx, &diff);
8085 CHECK(dns_db_newversion(db, &ver));
8087 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESHING);
8089 dns_rriterator_init(&rrit, db, ver, 0);
8090 for (result = dns_rriterator_first(&rrit);
8091 result == ISC_R_SUCCESS;
8092 result = dns_rriterator_nextrrset(&rrit)) {
8093 isc_stdtime_t timer = 0xffffffff;
8094 dns_name_t *name = NULL, *kname = NULL;
8095 dns_rdataset_t *kdset = NULL;
8096 dns_keyfetch_t *kfetch;
8099 dns_rriterator_current(&rrit, &name, &ttl, &kdset, NULL);
8100 if (kdset == NULL || kdset->type != dns_rdatatype_keydata ||
8101 !dns_rdataset_isassociated(kdset))
8105 * Scan the stored keys looking for ones that need
8106 * removal or refreshing
8108 for (result = dns_rdataset_first(kdset);
8109 result == ISC_R_SUCCESS;
8110 result = dns_rdataset_next(kdset)) {
8111 dns_rdata_reset(&rdata);
8112 dns_rdataset_current(kdset, &rdata);
8113 result = dns_rdata_tostruct(&rdata, &kd, NULL);
8114 RUNTIME_CHECK(result == ISC_R_SUCCESS);
8116 /* Removal timer expired? */
8117 if (kd.removehd != 0 && kd.removehd < now) {
8118 CHECK(update_one_rr(db, ver, &diff,
8119 DNS_DIFFOP_DEL, name, ttl,
8124 /* Acceptance timer expired? */
8125 if (kd.addhd != 0 && kd.addhd < now)
8128 /* Or do we just need to refresh the keyset? */
8129 if (timer > kd.refresh)
8136 kfetch = isc_mem_get(zone->mctx, sizeof(dns_keyfetch_t));
8137 if (kfetch == NULL) {
8138 fetch_err = ISC_TRUE;
8142 zone->refreshkeycount++;
8143 kfetch->zone = zone;
8145 INSIST(zone->irefs != 0);
8146 dns_fixedname_init(&kfetch->name);
8147 kname = dns_fixedname_name(&kfetch->name);
8148 dns_name_dup(name, zone->mctx, kname);
8149 dns_rdataset_init(&kfetch->dnskeyset);
8150 dns_rdataset_init(&kfetch->dnskeysigset);
8151 dns_rdataset_init(&kfetch->keydataset);
8152 dns_rdataset_clone(kdset, &kfetch->keydataset);
8154 dns_db_attach(db, &kfetch->db);
8155 kfetch->fetch = NULL;
8157 result = dns_resolver_createfetch(zone->view->resolver,
8158 kname, dns_rdatatype_dnskey,
8160 DNS_FETCHOPT_NOVALIDATE,
8162 keyfetch_done, kfetch,
8164 &kfetch->dnskeysigset,
8166 if (result == ISC_R_SUCCESS)
8167 fetching = ISC_TRUE;
8169 zone->refreshkeycount--;
8171 dns_db_detach(&kfetch->db);
8172 dns_rdataset_disassociate(&kfetch->keydataset);
8173 dns_name_free(kname, zone->mctx);
8174 isc_mem_put(zone->mctx, kfetch, sizeof(dns_keyfetch_t));
8175 dns_zone_log(zone, ISC_LOG_WARNING,
8176 "Failed to create fetch for "
8178 fetch_err = ISC_TRUE;
8181 if (!ISC_LIST_EMPTY(diff.tuples)) {
8182 CHECK(increment_soa_serial(db, ver, &diff, zone->mctx));
8183 CHECK(zone_journal(zone, &diff, "zone_refreshkeys"));
8185 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
8186 zone_needdump(zone, 30);
8192 * Error during a key fetch; retry in an hour.
8194 isc_time_t timenow, timethen;
8198 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
8199 zone->refreshkeytime = timethen;
8200 zone_settimer(zone, &timenow);
8202 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
8203 dns_zone_log(zone, ISC_LOG_DEBUG(1), "retry key refresh: %s",
8207 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESHING);
8212 dns_diff_clear(&diff);
8214 dns_rriterator_destroy(&rrit);
8215 dns_db_closeversion(db, &ver, commit);
8221 zone_maintenance(dns_zone_t *zone) {
8222 const char me[] = "zone_maintenance";
8224 isc_result_t result;
8225 isc_boolean_t dumping;
8227 REQUIRE(DNS_ZONE_VALID(zone));
8231 * Configuring the view of this zone may have
8232 * failed, for example because the config file
8233 * had a syntax error. In that case, the view
8234 * db or resolver will be NULL, and we had better not try
8235 * to do maintenance on it.
8237 if (zone->view == NULL || zone->view->adb == NULL)
8245 switch (zone->type) {
8246 case dns_zone_slave:
8249 if (isc_time_compare(&now, &zone->expiretime) >= 0 &&
8250 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8252 zone->refreshtime = now;
8263 switch (zone->type) {
8264 case dns_zone_slave:
8266 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH) &&
8267 isc_time_compare(&now, &zone->refreshtime) >= 0)
8268 dns_zone_refresh(zone);
8275 * Slaves send notifies before backing up to disk, masters after.
8277 if (zone->type == dns_zone_slave &&
8278 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8279 isc_time_compare(&now, &zone->notifytime) >= 0)
8280 zone_notify(zone, &now);
8283 * Do we need to consolidate the backing store?
8285 switch (zone->type) {
8286 case dns_zone_master:
8287 case dns_zone_slave:
8291 if (zone->masterfile != NULL &&
8292 isc_time_compare(&now, &zone->dumptime) >= 0 &&
8293 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8294 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP)) {
8295 dumping = was_dumping(zone);
8300 result = zone_dump(zone, ISC_TRUE); /* task locked */
8301 if (result != ISC_R_SUCCESS)
8302 dns_zone_log(zone, ISC_LOG_WARNING,
8304 dns_result_totext(result));
8312 * Master/redirect zones send notifies now, if needed
8314 switch (zone->type) {
8315 case dns_zone_master:
8316 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY) &&
8317 isc_time_compare(&now, &zone->notifytime) >= 0)
8318 zone_notify(zone, &now);
8324 * Do we need to refresh keys?
8326 switch (zone->type) {
8328 if (isc_time_compare(&now, &zone->refreshkeytime) >= 0) {
8329 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
8330 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
8331 zone_refreshkeys(zone);
8335 case dns_zone_master:
8336 if (!isc_time_isepoch(&zone->refreshkeytime) &&
8337 isc_time_compare(&now, &zone->refreshkeytime) >= 0)
8343 switch (zone->type) {
8344 case dns_zone_master:
8345 case dns_zone_slave:
8347 * Do we need to sign/resign some RRsets?
8349 if (!isc_time_isepoch(&zone->signingtime) &&
8350 isc_time_compare(&now, &zone->signingtime) >= 0)
8352 else if (!isc_time_isepoch(&zone->resigntime) &&
8353 isc_time_compare(&now, &zone->resigntime) >= 0)
8354 zone_resigninc(zone);
8355 else if (!isc_time_isepoch(&zone->nsec3chaintime) &&
8356 isc_time_compare(&now, &zone->nsec3chaintime) >= 0)
8357 zone_nsec3chain(zone);
8359 * Do we need to issue a key expiry warning?
8361 if (!isc_time_isepoch(&zone->keywarntime) &&
8362 isc_time_compare(&now, &zone->keywarntime) >= 0)
8363 set_key_expiry_warning(zone, zone->key_expiry,
8364 isc_time_seconds(&now));
8369 zone_settimer(zone, &now);
8373 dns_zone_markdirty(dns_zone_t *zone) {
8376 if (zone->type == dns_zone_master)
8377 set_resigntime(zone); /* XXXMPA make separate call back */
8378 zone_needdump(zone, DNS_DUMP_DELAY);
8383 dns_zone_expire(dns_zone_t *zone) {
8384 REQUIRE(DNS_ZONE_VALID(zone));
8392 zone_expire(dns_zone_t *zone) {
8394 * 'zone' locked by caller.
8397 REQUIRE(LOCKED_ZONE(zone));
8399 dns_zone_log(zone, ISC_LOG_WARNING, "expired");
8401 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXPIRED);
8402 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
8403 zone->retry = DNS_ZONE_DEFAULTRETRY;
8404 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
8409 dns_zone_refresh(dns_zone_t *zone) {
8411 isc_uint32_t oldflags;
8413 isc_result_t result;
8415 REQUIRE(DNS_ZONE_VALID(zone));
8417 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
8421 * Set DNS_ZONEFLG_REFRESH so that there is only one refresh operation
8422 * in progress at a time.
8426 oldflags = zone->flags;
8427 if (zone->masterscnt == 0) {
8428 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOMASTERS);
8429 if ((oldflags & DNS_ZONEFLG_NOMASTERS) == 0)
8430 dns_zone_log(zone, ISC_LOG_ERROR,
8431 "cannot refresh: no masters");
8434 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
8435 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
8436 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
8437 if ((oldflags & (DNS_ZONEFLG_REFRESH|DNS_ZONEFLG_LOADING)) != 0)
8441 * Set the next refresh time as if refresh check has failed.
8442 * Setting this to the retry time will do that. XXXMLG
8443 * If we are successful it will be reset using zone->refresh.
8445 isc_interval_set(&i, isc_random_jitter(zone->retry, zone->retry / 4),
8447 result = isc_time_nowplusinterval(&zone->refreshtime, &i);
8448 if (result != ISC_R_SUCCESS)
8449 dns_zone_log(zone, ISC_LOG_WARNING,
8450 "isc_time_nowplusinterval() failed: %s",
8451 dns_result_totext(result));
8454 * When lacking user-specified timer values from the SOA,
8455 * do exponential backoff of the retry time up to a
8456 * maximum of six hours.
8458 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_HAVETIMERS))
8459 zone->retry = ISC_MIN(zone->retry * 2, 6 * 3600);
8461 zone->curmaster = 0;
8462 for (j = 0; j < zone->masterscnt; j++)
8463 zone->mastersok[j] = ISC_FALSE;
8464 /* initiate soa query */
8465 queue_soa_query(zone);
8471 dns_zone_flush(dns_zone_t *zone) {
8472 isc_result_t result = ISC_R_SUCCESS;
8473 isc_boolean_t dumping;
8475 REQUIRE(DNS_ZONE_VALID(zone));
8478 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FLUSH);
8479 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8480 zone->masterfile != NULL) {
8481 result = ISC_R_ALREADYRUNNING;
8482 dumping = was_dumping(zone);
8487 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8492 dns_zone_dump(dns_zone_t *zone) {
8493 isc_result_t result = ISC_R_ALREADYRUNNING;
8494 isc_boolean_t dumping;
8496 REQUIRE(DNS_ZONE_VALID(zone));
8499 dumping = was_dumping(zone);
8502 result = zone_dump(zone, ISC_FALSE); /* Unknown task. */
8507 zone_needdump(dns_zone_t *zone, unsigned int delay) {
8508 const char me[] = "zone_needdump";
8509 isc_time_t dumptime;
8513 * 'zone' locked by caller
8516 REQUIRE(DNS_ZONE_VALID(zone));
8517 REQUIRE(LOCKED_ZONE(zone));
8521 * Do we have a place to dump to and are we loaded?
8523 if (zone->masterfile == NULL ||
8524 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
8528 /* add some noise */
8529 DNS_ZONE_JITTER_ADD(&now, delay, &dumptime);
8531 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8532 if (isc_time_isepoch(&zone->dumptime) ||
8533 isc_time_compare(&zone->dumptime, &dumptime) > 0)
8534 zone->dumptime = dumptime;
8535 if (zone->task != NULL)
8536 zone_settimer(zone, &now);
8540 dump_done(void *arg, isc_result_t result) {
8541 const char me[] = "dump_done";
8542 dns_zone_t *zone = arg;
8544 dns_dbversion_t *version;
8545 isc_boolean_t again = ISC_FALSE;
8546 isc_boolean_t compact = ISC_FALSE;
8547 isc_uint32_t serial;
8548 isc_result_t tresult;
8550 REQUIRE(DNS_ZONE_VALID(zone));
8554 if (result == ISC_R_SUCCESS && zone->journal != NULL &&
8555 zone->journalsize != -1) {
8558 * We don't own these, zone->dctx must stay valid.
8560 db = dns_dumpctx_db(zone->dctx);
8561 version = dns_dumpctx_version(zone->dctx);
8563 tresult = dns_db_getsoaserial(db, version, &serial);
8565 * Note: we are task locked here so we can test
8568 if (tresult == ISC_R_SUCCESS && zone->xfr == NULL) {
8569 tresult = dns_journal_compact(zone->mctx,
8576 case ISC_R_NOTFOUND:
8577 dns_zone_log(zone, ISC_LOG_DEBUG(3),
8578 "dns_journal_compact: %s",
8579 dns_result_totext(tresult));
8582 dns_zone_log(zone, ISC_LOG_ERROR,
8583 "dns_journal_compact failed: %s",
8584 dns_result_totext(tresult));
8587 } else if (tresult == ISC_R_SUCCESS) {
8589 zone->compact_serial = serial;
8594 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8596 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
8597 if (result != ISC_R_SUCCESS && result != ISC_R_CANCELED) {
8599 * Try again in a short while.
8601 zone_needdump(zone, DNS_DUMP_DELAY);
8602 } else if (result == ISC_R_SUCCESS &&
8603 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8604 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8605 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8606 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8607 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8608 isc_time_settoepoch(&zone->dumptime);
8610 } else if (result == ISC_R_SUCCESS)
8611 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8613 if (zone->dctx != NULL)
8614 dns_dumpctx_detach(&zone->dctx);
8615 zonemgr_putio(&zone->writeio);
8618 (void)zone_dump(zone, ISC_FALSE);
8619 dns_zone_idetach(&zone);
8623 zone_dump(dns_zone_t *zone, isc_boolean_t compact) {
8624 const char me[] = "zone_dump";
8625 isc_result_t result;
8626 dns_dbversion_t *version = NULL;
8627 isc_boolean_t again;
8628 dns_db_t *db = NULL;
8629 char *masterfile = NULL;
8630 dns_masterformat_t masterformat = dns_masterformat_none;
8633 * 'compact' MUST only be set if we are task locked.
8636 REQUIRE(DNS_ZONE_VALID(zone));
8640 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8641 if (zone->db != NULL)
8642 dns_db_attach(zone->db, &db);
8643 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8645 if (zone->masterfile != NULL) {
8646 masterfile = isc_mem_strdup(zone->mctx, zone->masterfile);
8647 masterformat = zone->masterformat;
8651 result = DNS_R_NOTLOADED;
8654 if (masterfile == NULL) {
8655 result = DNS_R_NOMASTERFILE;
8659 if (compact && zone->type != dns_zone_stub) {
8660 dns_zone_t *dummy = NULL;
8662 zone_iattach(zone, &dummy);
8663 result = zonemgr_getio(zone->zmgr, ISC_FALSE, zone->task,
8664 zone_gotwritehandle, zone,
8666 if (result != ISC_R_SUCCESS)
8667 zone_idetach(&dummy);
8669 result = DNS_R_CONTINUE;
8672 const dns_master_style_t *output_style;
8674 if (zone->type == dns_zone_key)
8675 output_style = &dns_master_style_keyzone;
8677 output_style = &dns_master_style_default;
8678 dns_db_currentversion(db, &version);
8679 result = dns_master_dump2(zone->mctx, db, version,
8680 output_style, masterfile,
8682 dns_db_closeversion(db, &version, ISC_FALSE);
8687 if (masterfile != NULL)
8688 isc_mem_free(zone->mctx, masterfile);
8691 if (result == DNS_R_CONTINUE)
8692 return (ISC_R_SUCCESS); /* XXXMPA */
8696 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DUMPING);
8697 if (result != ISC_R_SUCCESS) {
8699 * Try again in a short while.
8701 zone_needdump(zone, DNS_DUMP_DELAY);
8702 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) &&
8703 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
8704 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
8705 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8706 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DUMPING);
8707 isc_time_settoepoch(&zone->dumptime);
8710 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FLUSH);
8719 dumptostream(dns_zone_t *zone, FILE *fd, const dns_master_style_t *style,
8720 dns_masterformat_t format)
8722 isc_result_t result;
8723 dns_dbversion_t *version = NULL;
8724 dns_db_t *db = NULL;
8726 REQUIRE(DNS_ZONE_VALID(zone));
8728 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
8729 if (zone->db != NULL)
8730 dns_db_attach(zone->db, &db);
8731 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
8733 return (DNS_R_NOTLOADED);
8735 dns_db_currentversion(db, &version);
8736 result = dns_master_dumptostream2(zone->mctx, db, version, style,
8738 dns_db_closeversion(db, &version, ISC_FALSE);
8744 dns_zone_dumptostream2(dns_zone_t *zone, FILE *fd, dns_masterformat_t format,
8745 const dns_master_style_t *style) {
8746 return dumptostream(zone, fd, style, format);
8750 dns_zone_dumptostream(dns_zone_t *zone, FILE *fd) {
8751 return dumptostream(zone, fd, &dns_master_style_default,
8752 dns_masterformat_text);
8756 dns_zone_fulldumptostream(dns_zone_t *zone, FILE *fd) {
8757 return dumptostream(zone, fd, &dns_master_style_full,
8758 dns_masterformat_text);
8762 dns_zone_unload(dns_zone_t *zone) {
8763 REQUIRE(DNS_ZONE_VALID(zone));
8771 notify_cancel(dns_zone_t *zone) {
8772 dns_notify_t *notify;
8775 * 'zone' locked by caller.
8778 REQUIRE(LOCKED_ZONE(zone));
8780 for (notify = ISC_LIST_HEAD(zone->notifies);
8782 notify = ISC_LIST_NEXT(notify, link)) {
8783 if (notify->find != NULL)
8784 dns_adb_cancelfind(notify->find);
8785 if (notify->request != NULL)
8786 dns_request_cancel(notify->request);
8791 forward_cancel(dns_zone_t *zone) {
8792 dns_forward_t *forward;
8795 * 'zone' locked by caller.
8798 REQUIRE(LOCKED_ZONE(zone));
8800 for (forward = ISC_LIST_HEAD(zone->forwards);
8802 forward = ISC_LIST_NEXT(forward, link)) {
8803 if (forward->request != NULL)
8804 dns_request_cancel(forward->request);
8809 zone_unload(dns_zone_t *zone) {
8812 * 'zone' locked by caller.
8815 REQUIRE(LOCKED_ZONE(zone));
8817 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
8818 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
8819 if (zone->writeio != NULL)
8820 zonemgr_cancelio(zone->writeio);
8822 if (zone->dctx != NULL)
8823 dns_dumpctx_cancel(zone->dctx);
8825 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
8826 zone_detachdb(zone);
8827 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
8828 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_LOADED);
8829 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDDUMP);
8833 dns_zone_setminrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8834 REQUIRE(DNS_ZONE_VALID(zone));
8837 zone->minrefresh = val;
8841 dns_zone_setmaxrefreshtime(dns_zone_t *zone, isc_uint32_t val) {
8842 REQUIRE(DNS_ZONE_VALID(zone));
8845 zone->maxrefresh = val;
8849 dns_zone_setminretrytime(dns_zone_t *zone, isc_uint32_t val) {
8850 REQUIRE(DNS_ZONE_VALID(zone));
8853 zone->minretry = val;
8857 dns_zone_setmaxretrytime(dns_zone_t *zone, isc_uint32_t val) {
8858 REQUIRE(DNS_ZONE_VALID(zone));
8861 zone->maxretry = val;
8864 static isc_boolean_t
8865 notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
8866 dns_notify_t *notify;
8868 for (notify = ISC_LIST_HEAD(zone->notifies);
8870 notify = ISC_LIST_NEXT(notify, link)) {
8871 if (notify->request != NULL)
8873 if (name != NULL && dns_name_dynamic(¬ify->ns) &&
8874 dns_name_equal(name, ¬ify->ns))
8876 if (addr != NULL && isc_sockaddr_equal(addr, ¬ify->dst))
8882 static isc_boolean_t
8883 notify_isself(dns_zone_t *zone, isc_sockaddr_t *dst) {
8884 dns_tsigkey_t *key = NULL;
8887 isc_boolean_t isself;
8888 isc_netaddr_t dstaddr;
8889 isc_result_t result;
8891 if (zone->view == NULL || zone->isself == NULL)
8894 switch (isc_sockaddr_pf(dst)) {
8896 src = zone->notifysrc4;
8897 isc_sockaddr_any(&any);
8900 src = zone->notifysrc6;
8901 isc_sockaddr_any6(&any);
8908 * When sending from any the kernel will assign a source address
8909 * that matches the destination address.
8911 if (isc_sockaddr_eqaddr(&any, &src))
8914 isc_netaddr_fromsockaddr(&dstaddr, dst);
8915 result = dns_view_getpeertsig(zone->view, &dstaddr, &key);
8916 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND)
8918 isself = (zone->isself)(zone->view, key, &src, dst, zone->rdclass,
8921 dns_tsigkey_detach(&key);
8926 notify_destroy(dns_notify_t *notify, isc_boolean_t locked) {
8930 * Caller holds zone lock.
8932 REQUIRE(DNS_NOTIFY_VALID(notify));
8934 if (notify->zone != NULL) {
8936 LOCK_ZONE(notify->zone);
8937 REQUIRE(LOCKED_ZONE(notify->zone));
8938 if (ISC_LINK_LINKED(notify, link))
8939 ISC_LIST_UNLINK(notify->zone->notifies, notify, link);
8941 UNLOCK_ZONE(notify->zone);
8943 zone_idetach(¬ify->zone);
8945 dns_zone_idetach(¬ify->zone);
8947 if (notify->find != NULL)
8948 dns_adb_destroyfind(¬ify->find);
8949 if (notify->request != NULL)
8950 dns_request_destroy(¬ify->request);
8951 if (dns_name_dynamic(¬ify->ns))
8952 dns_name_free(¬ify->ns, notify->mctx);
8953 mctx = notify->mctx;
8954 isc_mem_put(notify->mctx, notify, sizeof(*notify));
8955 isc_mem_detach(&mctx);
8959 notify_create(isc_mem_t *mctx, unsigned int flags, dns_notify_t **notifyp) {
8960 dns_notify_t *notify;
8962 REQUIRE(notifyp != NULL && *notifyp == NULL);
8964 notify = isc_mem_get(mctx, sizeof(*notify));
8966 return (ISC_R_NOMEMORY);
8968 notify->mctx = NULL;
8969 isc_mem_attach(mctx, ¬ify->mctx);
8970 notify->flags = flags;
8971 notify->zone = NULL;
8972 notify->find = NULL;
8973 notify->request = NULL;
8974 isc_sockaddr_any(¬ify->dst);
8975 dns_name_init(¬ify->ns, NULL);
8976 ISC_LINK_INIT(notify, link);
8977 notify->magic = NOTIFY_MAGIC;
8979 return (ISC_R_SUCCESS);
8983 * XXXAG should check for DNS_ZONEFLG_EXITING
8986 process_adb_event(isc_task_t *task, isc_event_t *ev) {
8987 dns_notify_t *notify;
8988 isc_eventtype_t result;
8992 notify = ev->ev_arg;
8993 REQUIRE(DNS_NOTIFY_VALID(notify));
8994 INSIST(task == notify->zone->task);
8995 result = ev->ev_type;
8996 isc_event_free(&ev);
8997 if (result == DNS_EVENT_ADBMOREADDRESSES) {
8998 dns_adb_destroyfind(¬ify->find);
8999 notify_find_address(notify);
9002 if (result == DNS_EVENT_ADBNOMOREADDRESSES) {
9003 LOCK_ZONE(notify->zone);
9004 notify_send(notify);
9005 UNLOCK_ZONE(notify->zone);
9007 notify_destroy(notify, ISC_FALSE);
9011 notify_find_address(dns_notify_t *notify) {
9012 isc_result_t result;
9013 unsigned int options;
9015 REQUIRE(DNS_NOTIFY_VALID(notify));
9016 options = DNS_ADBFIND_WANTEVENT | DNS_ADBFIND_INET |
9017 DNS_ADBFIND_INET6 | DNS_ADBFIND_RETURNLAME;
9019 if (notify->zone->view->adb == NULL)
9022 result = dns_adb_createfind(notify->zone->view->adb,
9024 process_adb_event, notify,
9025 ¬ify->ns, dns_rootname, 0,
9027 notify->zone->view->dstport,
9030 /* Something failed? */
9031 if (result != ISC_R_SUCCESS)
9034 /* More addresses pending? */
9035 if ((notify->find->options & DNS_ADBFIND_WANTEVENT) != 0)
9038 /* We have as many addresses as we can get. */
9039 LOCK_ZONE(notify->zone);
9040 notify_send(notify);
9041 UNLOCK_ZONE(notify->zone);
9044 notify_destroy(notify, ISC_FALSE);
9049 notify_send_queue(dns_notify_t *notify) {
9051 isc_result_t result;
9053 e = isc_event_allocate(notify->mctx, NULL,
9054 DNS_EVENT_NOTIFYSENDTOADDR,
9056 notify, sizeof(isc_event_t));
9058 return (ISC_R_NOMEMORY);
9060 e->ev_sender = NULL;
9061 result = isc_ratelimiter_enqueue(notify->zone->zmgr->notifyrl,
9062 notify->zone->task, &e);
9063 if (result != ISC_R_SUCCESS)
9069 notify_send_toaddr(isc_task_t *task, isc_event_t *event) {
9070 dns_notify_t *notify;
9071 isc_result_t result;
9072 dns_message_t *message = NULL;
9073 isc_netaddr_t dstip;
9074 dns_tsigkey_t *key = NULL;
9075 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
9078 isc_boolean_t have_notifysource = ISC_FALSE;
9080 notify = event->ev_arg;
9081 REQUIRE(DNS_NOTIFY_VALID(notify));
9085 LOCK_ZONE(notify->zone);
9087 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_LOADED) == 0) {
9088 result = ISC_R_CANCELED;
9092 if ((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0 ||
9093 DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_EXITING) ||
9094 notify->zone->view->requestmgr == NULL ||
9095 notify->zone->db == NULL) {
9096 result = ISC_R_CANCELED;
9101 * The raw IPv4 address should also exist. Don't send to the
9104 if (isc_sockaddr_pf(¬ify->dst) == PF_INET6 &&
9105 IN6_IS_ADDR_V4MAPPED(¬ify->dst.type.sin6.sin6_addr)) {
9106 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9107 notify_log(notify->zone, ISC_LOG_DEBUG(3),
9108 "notify: ignoring IPv6 mapped IPV4 address: %s",
9110 result = ISC_R_CANCELED;
9114 result = notify_createmessage(notify->zone, notify->flags, &message);
9115 if (result != ISC_R_SUCCESS)
9118 isc_netaddr_fromsockaddr(&dstip, ¬ify->dst);
9119 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
9120 result = dns_view_getpeertsig(notify->zone->view, &dstip, &key);
9121 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
9122 notify_log(notify->zone, ISC_LOG_ERROR, "NOTIFY to %s not "
9123 "sent. Peer TSIG key lookup failure.", addrbuf);
9124 goto cleanup_message;
9127 notify_log(notify->zone, ISC_LOG_DEBUG(3), "sending notify to %s",
9129 if (notify->zone->view->peers != NULL) {
9130 dns_peer_t *peer = NULL;
9131 result = dns_peerlist_peerbyaddr(notify->zone->view->peers,
9133 if (result == ISC_R_SUCCESS) {
9134 result = dns_peer_getnotifysource(peer, &src);
9135 if (result == ISC_R_SUCCESS)
9136 have_notifysource = ISC_TRUE;
9139 switch (isc_sockaddr_pf(¬ify->dst)) {
9141 if (!have_notifysource)
9142 src = notify->zone->notifysrc4;
9145 if (!have_notifysource)
9146 src = notify->zone->notifysrc6;
9149 result = ISC_R_NOTIMPLEMENTED;
9153 if (DNS_ZONE_FLAG(notify->zone, DNS_ZONEFLG_DIALNOTIFY))
9155 result = dns_request_createvia2(notify->zone->view->requestmgr,
9156 message, &src, ¬ify->dst, 0, key,
9157 timeout * 3, timeout,
9158 notify->zone->task, notify_done,
9159 notify, ¬ify->request);
9160 if (result == ISC_R_SUCCESS) {
9161 if (isc_sockaddr_pf(¬ify->dst) == AF_INET) {
9162 inc_stats(notify->zone,
9163 dns_zonestatscounter_notifyoutv4);
9165 inc_stats(notify->zone,
9166 dns_zonestatscounter_notifyoutv6);
9172 dns_tsigkey_detach(&key);
9174 dns_message_destroy(&message);
9176 UNLOCK_ZONE(notify->zone);
9177 isc_event_free(&event);
9178 if (result != ISC_R_SUCCESS)
9179 notify_destroy(notify, ISC_FALSE);
9183 notify_send(dns_notify_t *notify) {
9184 dns_adbaddrinfo_t *ai;
9186 isc_result_t result;
9187 dns_notify_t *new = NULL;
9190 * Zone lock held by caller.
9192 REQUIRE(DNS_NOTIFY_VALID(notify));
9193 REQUIRE(LOCKED_ZONE(notify->zone));
9195 for (ai = ISC_LIST_HEAD(notify->find->list);
9197 ai = ISC_LIST_NEXT(ai, publink)) {
9199 if (notify_isqueued(notify->zone, NULL, &dst))
9201 if (notify_isself(notify->zone, &dst))
9204 result = notify_create(notify->mctx,
9205 (notify->flags & DNS_NOTIFY_NOSOA),
9207 if (result != ISC_R_SUCCESS)
9209 zone_iattach(notify->zone, &new->zone);
9210 ISC_LIST_APPEND(new->zone->notifies, new, link);
9212 result = notify_send_queue(new);
9213 if (result != ISC_R_SUCCESS)
9220 notify_destroy(new, ISC_TRUE);
9224 dns_zone_notify(dns_zone_t *zone) {
9227 REQUIRE(DNS_ZONE_VALID(zone));
9230 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9233 zone_settimer(zone, &now);
9238 zone_notify(dns_zone_t *zone, isc_time_t *now) {
9239 dns_dbnode_t *node = NULL;
9240 dns_db_t *zonedb = NULL;
9241 dns_dbversion_t *version = NULL;
9242 dns_name_t *origin = NULL;
9245 dns_rdata_soa_t soa;
9246 isc_uint32_t serial;
9247 dns_rdata_t rdata = DNS_RDATA_INIT;
9248 dns_rdataset_t nsrdset;
9249 dns_rdataset_t soardset;
9250 isc_result_t result;
9251 dns_notify_t *notify = NULL;
9254 isc_boolean_t isqueued;
9255 dns_notifytype_t notifytype;
9256 unsigned int flags = 0;
9257 isc_boolean_t loggednotify = ISC_FALSE;
9259 REQUIRE(DNS_ZONE_VALID(zone));
9262 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
9263 notifytype = zone->notifytype;
9264 DNS_ZONE_TIME_ADD(now, zone->notifydelay, &zone->notifytime);
9267 if (! DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED))
9270 if (notifytype == dns_notifytype_no)
9273 if (notifytype == dns_notifytype_masteronly &&
9274 zone->type != dns_zone_master)
9277 origin = &zone->origin;
9280 * If the zone is dialup we are done as we don't want to send
9281 * the current soa so as to force a refresh query.
9283 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
9284 flags |= DNS_NOTIFY_NOSOA;
9289 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
9290 if (zone->db != NULL)
9291 dns_db_attach(zone->db, &zonedb);
9292 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
9295 dns_db_currentversion(zonedb, &version);
9296 result = dns_db_findnode(zonedb, origin, ISC_FALSE, &node);
9297 if (result != ISC_R_SUCCESS)
9300 dns_rdataset_init(&soardset);
9301 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_soa,
9302 dns_rdatatype_none, 0, &soardset, NULL);
9303 if (result != ISC_R_SUCCESS)
9307 * Find serial and master server's name.
9309 dns_name_init(&master, NULL);
9310 result = dns_rdataset_first(&soardset);
9311 if (result != ISC_R_SUCCESS)
9313 dns_rdataset_current(&soardset, &rdata);
9314 result = dns_rdata_tostruct(&rdata, &soa, NULL);
9315 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9316 dns_rdata_reset(&rdata);
9317 result = dns_name_dup(&soa.origin, zone->mctx, &master);
9318 serial = soa.serial;
9319 dns_rdataset_disassociate(&soardset);
9320 if (result != ISC_R_SUCCESS)
9324 * Enqueue notify requests for 'also-notify' servers.
9327 for (i = 0; i < zone->notifycnt; i++) {
9328 dst = zone->notify[i];
9329 if (notify_isqueued(zone, NULL, &dst))
9331 result = notify_create(zone->mctx, flags, ¬ify);
9332 if (result != ISC_R_SUCCESS)
9334 zone_iattach(zone, ¬ify->zone);
9336 ISC_LIST_APPEND(zone->notifies, notify, link);
9337 result = notify_send_queue(notify);
9338 if (result != ISC_R_SUCCESS)
9339 notify_destroy(notify, ISC_TRUE);
9340 if (!loggednotify) {
9341 notify_log(zone, ISC_LOG_INFO,
9342 "sending notifies (serial %u)",
9344 loggednotify = ISC_TRUE;
9350 if (notifytype == dns_notifytype_explicit)
9354 * Process NS RRset to generate notifies.
9357 dns_rdataset_init(&nsrdset);
9358 result = dns_db_findrdataset(zonedb, node, version, dns_rdatatype_ns,
9359 dns_rdatatype_none, 0, &nsrdset, NULL);
9360 if (result != ISC_R_SUCCESS)
9363 result = dns_rdataset_first(&nsrdset);
9364 while (result == ISC_R_SUCCESS) {
9365 dns_rdataset_current(&nsrdset, &rdata);
9366 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9367 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9368 dns_rdata_reset(&rdata);
9370 * Don't notify the master server unless explicitly
9371 * configured to do so.
9373 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_NOTIFYTOSOA) &&
9374 dns_name_compare(&master, &ns.name) == 0) {
9375 result = dns_rdataset_next(&nsrdset);
9379 if (!loggednotify) {
9380 notify_log(zone, ISC_LOG_INFO,
9381 "sending notifies (serial %u)",
9383 loggednotify = ISC_TRUE;
9387 isqueued = notify_isqueued(zone, &ns.name, NULL);
9390 result = dns_rdataset_next(&nsrdset);
9393 result = notify_create(zone->mctx, flags, ¬ify);
9394 if (result != ISC_R_SUCCESS)
9396 dns_zone_iattach(zone, ¬ify->zone);
9397 result = dns_name_dup(&ns.name, zone->mctx, ¬ify->ns);
9398 if (result != ISC_R_SUCCESS) {
9400 notify_destroy(notify, ISC_TRUE);
9405 ISC_LIST_APPEND(zone->notifies, notify, link);
9407 notify_find_address(notify);
9409 result = dns_rdataset_next(&nsrdset);
9411 dns_rdataset_disassociate(&nsrdset);
9414 if (dns_name_dynamic(&master))
9415 dns_name_free(&master, zone->mctx);
9417 dns_db_detachnode(zonedb, &node);
9419 dns_db_closeversion(zonedb, &version, ISC_FALSE);
9420 dns_db_detach(&zonedb);
9427 static inline isc_result_t
9428 save_nsrrset(dns_message_t *message, dns_name_t *name,
9429 dns_db_t *db, dns_dbversion_t *version)
9431 dns_rdataset_t *nsrdataset = NULL;
9432 dns_rdataset_t *rdataset = NULL;
9433 dns_dbnode_t *node = NULL;
9435 isc_result_t result;
9436 dns_rdata_t rdata = DNS_RDATA_INIT;
9439 * Extract NS RRset from message.
9441 result = dns_message_findname(message, DNS_SECTION_ANSWER, name,
9442 dns_rdatatype_ns, dns_rdatatype_none,
9444 if (result != ISC_R_SUCCESS)
9450 result = dns_db_findnode(db, name, ISC_TRUE, &node);
9451 if (result != ISC_R_SUCCESS)
9453 result = dns_db_addrdataset(db, node, version, 0,
9454 nsrdataset, 0, NULL);
9455 dns_db_detachnode(db, &node);
9456 if (result != ISC_R_SUCCESS)
9459 * Add glue rdatasets.
9461 for (result = dns_rdataset_first(nsrdataset);
9462 result == ISC_R_SUCCESS;
9463 result = dns_rdataset_next(nsrdataset)) {
9464 dns_rdataset_current(nsrdataset, &rdata);
9465 result = dns_rdata_tostruct(&rdata, &ns, NULL);
9466 RUNTIME_CHECK(result == ISC_R_SUCCESS);
9467 dns_rdata_reset(&rdata);
9468 if (!dns_name_issubdomain(&ns.name, name))
9471 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9472 &ns.name, dns_rdatatype_aaaa,
9473 dns_rdatatype_none, NULL,
9475 if (result == ISC_R_SUCCESS) {
9476 result = dns_db_findnode(db, &ns.name,
9478 if (result != ISC_R_SUCCESS)
9480 result = dns_db_addrdataset(db, node, version, 0,
9482 dns_db_detachnode(db, &node);
9483 if (result != ISC_R_SUCCESS)
9487 result = dns_message_findname(message, DNS_SECTION_ADDITIONAL,
9488 &ns.name, dns_rdatatype_a,
9489 dns_rdatatype_none, NULL,
9491 if (result == ISC_R_SUCCESS) {
9492 result = dns_db_findnode(db, &ns.name,
9494 if (result != ISC_R_SUCCESS)
9496 result = dns_db_addrdataset(db, node, version, 0,
9498 dns_db_detachnode(db, &node);
9499 if (result != ISC_R_SUCCESS)
9503 if (result != ISC_R_NOMORE)
9506 return (ISC_R_SUCCESS);
9513 stub_callback(isc_task_t *task, isc_event_t *event) {
9514 const char me[] = "stub_callback";
9515 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9516 dns_stub_t *stub = NULL;
9517 dns_message_t *msg = NULL;
9518 dns_zone_t *zone = NULL;
9519 char master[ISC_SOCKADDR_FORMATSIZE];
9520 char source[ISC_SOCKADDR_FORMATSIZE];
9521 isc_uint32_t nscnt, cnamecnt, refresh, retry, expire;
9522 isc_result_t result;
9524 isc_boolean_t exiting = ISC_FALSE;
9526 unsigned int j, soacount;
9528 stub = revent->ev_arg;
9529 INSIST(DNS_STUB_VALID(stub));
9541 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
9542 zone_debuglog(zone, me, 1, "exiting");
9547 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9548 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9550 if (revent->result != ISC_R_SUCCESS) {
9551 if (revent->result == ISC_R_TIMEDOUT &&
9552 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9553 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9554 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9555 "refreshing stub: timeout retrying "
9556 " without EDNS master %s (source %s)",
9560 dns_zonemgr_unreachableadd(zone->zmgr, &zone->masteraddr,
9561 &zone->sourceaddr, &now);
9562 dns_zone_log(zone, ISC_LOG_INFO,
9563 "could not refresh stub from master %s"
9564 " (source %s): %s", master, source,
9565 dns_result_totext(revent->result));
9569 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9570 if (result != ISC_R_SUCCESS)
9573 result = dns_request_getresponse(revent->request, msg, 0);
9574 if (result != ISC_R_SUCCESS)
9580 if (msg->rcode != dns_rcode_noerror) {
9584 isc_buffer_init(&rb, rcode, sizeof(rcode));
9585 (void)dns_rcode_totext(msg->rcode, &rb);
9587 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9588 (msg->rcode == dns_rcode_servfail ||
9589 msg->rcode == dns_rcode_notimp ||
9590 msg->rcode == dns_rcode_formerr)) {
9591 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9592 "refreshing stub: rcode (%.*s) retrying "
9593 "without EDNS master %s (source %s)",
9594 (int)rb.used, rcode, master, source);
9595 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9599 dns_zone_log(zone, ISC_LOG_INFO,
9601 "unexpected rcode (%.*s) from %s (source %s)",
9602 (int)rb.used, rcode, master, source);
9607 * We need complete messages.
9609 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9610 if (dns_request_usedtcp(revent->request)) {
9611 dns_zone_log(zone, ISC_LOG_INFO,
9612 "refreshing stub: truncated TCP "
9613 "response from master %s (source %s)",
9617 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9622 * If non-auth log and next master.
9624 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9625 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
9626 "non-authoritative answer from "
9627 "master %s (source %s)", master, source);
9634 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9635 nscnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_ns);
9637 if (cnamecnt != 0) {
9638 dns_zone_log(zone, ISC_LOG_INFO,
9639 "refreshing stub: unexpected CNAME response "
9640 "from master %s (source %s)", master, source);
9645 dns_zone_log(zone, ISC_LOG_INFO,
9646 "refreshing stub: no NS records in response "
9647 "from master %s (source %s)", master, source);
9654 result = save_nsrrset(msg, &zone->origin, stub->db, stub->version);
9655 if (result != ISC_R_SUCCESS) {
9656 dns_zone_log(zone, ISC_LOG_INFO,
9657 "refreshing stub: unable to save NS records "
9658 "from master %s (source %s)", master, source);
9665 dns_db_closeversion(stub->db, &stub->version, ISC_TRUE);
9666 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
9667 if (zone->db == NULL)
9668 zone_attachdb(zone, stub->db);
9669 result = zone_get_from_db(zone, zone->db, NULL, &soacount, NULL,
9670 &refresh, &retry, &expire, NULL, NULL);
9671 if (result == ISC_R_SUCCESS && soacount > 0U) {
9672 zone->refresh = RANGE(refresh, zone->minrefresh,
9674 zone->retry = RANGE(retry, zone->minretry, zone->maxretry);
9675 zone->expire = RANGE(expire, zone->refresh + zone->retry,
9677 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
9679 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
9680 dns_db_detach(&stub->db);
9682 dns_message_destroy(&msg);
9683 isc_event_free(&event);
9684 dns_request_destroy(&zone->request);
9686 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9687 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED);
9688 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
9689 isc_interval_set(&i, zone->expire, 0);
9690 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
9692 if (zone->masterfile != NULL)
9693 zone_needdump(zone, 0);
9695 zone_settimer(zone, &now);
9699 if (stub->version != NULL)
9700 dns_db_closeversion(stub->db, &stub->version, ISC_FALSE);
9701 if (stub->db != NULL)
9702 dns_db_detach(&stub->db);
9704 dns_message_destroy(&msg);
9705 isc_event_free(&event);
9706 dns_request_destroy(&zone->request);
9708 * Skip to next failed / untried master.
9712 } while (zone->curmaster < zone->masterscnt &&
9713 zone->mastersok[zone->curmaster]);
9714 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
9715 if (exiting || zone->curmaster >= zone->masterscnt) {
9716 isc_boolean_t done = ISC_TRUE;
9718 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
9719 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
9721 * Did we get a good answer from all the masters?
9723 for (j = 0; j < zone->masterscnt; j++)
9724 if (zone->mastersok[j] == ISC_FALSE) {
9731 zone->curmaster = 0;
9733 * Find the next failed master.
9735 while (zone->curmaster < zone->masterscnt &&
9736 zone->mastersok[zone->curmaster])
9738 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
9740 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
9742 zone_settimer(zone, &now);
9746 queue_soa_query(zone);
9751 dns_message_destroy(&msg);
9752 isc_event_free(&event);
9753 dns_request_destroy(&zone->request);
9754 ns_query(zone, NULL, stub);
9761 dns_zone_idetach(&stub->zone);
9762 INSIST(stub->db == NULL);
9763 INSIST(stub->version == NULL);
9764 isc_mem_put(stub->mctx, stub, sizeof(*stub));
9767 INSIST(event == NULL);
9772 * An SOA query has finished (successfully or not).
9775 refresh_callback(isc_task_t *task, isc_event_t *event) {
9776 const char me[] = "refresh_callback";
9777 dns_requestevent_t *revent = (dns_requestevent_t *)event;
9779 dns_message_t *msg = NULL;
9780 isc_uint32_t soacnt, cnamecnt, soacount, nscount;
9782 char master[ISC_SOCKADDR_FORMATSIZE];
9783 char source[ISC_SOCKADDR_FORMATSIZE];
9784 dns_rdataset_t *rdataset = NULL;
9785 dns_rdata_t rdata = DNS_RDATA_INIT;
9786 dns_rdata_soa_t soa;
9787 isc_result_t result;
9788 isc_uint32_t serial, oldserial = 0;
9790 isc_boolean_t do_queue_xfrin = ISC_FALSE;
9792 zone = revent->ev_arg;
9793 INSIST(DNS_ZONE_VALID(zone));
9804 * if timeout log and next master;
9807 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
9808 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
9810 if (revent->result != ISC_R_SUCCESS) {
9811 if (revent->result == ISC_R_TIMEDOUT &&
9812 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
9813 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9814 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9815 "refresh: timeout retrying without EDNS "
9816 "master %s (source %s)", master, source);
9819 if (revent->result == ISC_R_TIMEDOUT &&
9820 !dns_request_usedtcp(revent->request)) {
9821 dns_zone_log(zone, ISC_LOG_INFO,
9822 "refresh: retry limit for "
9823 "master %s exceeded (source %s)",
9825 /* Try with slave with TCP. */
9826 if (zone->type == dns_zone_slave &&
9827 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_TRYTCPREFRESH)) {
9828 if (!dns_zonemgr_unreachable(zone->zmgr,
9833 DNS_ZONE_SETFLAG(zone,
9834 DNS_ZONEFLG_SOABEFOREAXFR);
9837 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9838 "refresh: skipped tcp fallback "
9839 "as master %s (source %s) is "
9840 "unreachable (cached)",
9844 dns_zone_log(zone, ISC_LOG_INFO,
9845 "refresh: failure trying master "
9846 "%s (source %s): %s", master, source,
9847 dns_result_totext(revent->result));
9851 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
9852 if (result != ISC_R_SUCCESS)
9854 result = dns_request_getresponse(revent->request, msg, 0);
9855 if (result != ISC_R_SUCCESS) {
9856 dns_zone_log(zone, ISC_LOG_INFO,
9857 "refresh: failure trying master "
9858 "%s (source %s): %s", master, source,
9859 dns_result_totext(result));
9866 if (msg->rcode != dns_rcode_noerror) {
9870 isc_buffer_init(&rb, rcode, sizeof(rcode));
9871 (void)dns_rcode_totext(msg->rcode, &rb);
9873 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS) &&
9874 (msg->rcode == dns_rcode_servfail ||
9875 msg->rcode == dns_rcode_notimp ||
9876 msg->rcode == dns_rcode_formerr)) {
9877 dns_zone_log(zone, ISC_LOG_DEBUG(1),
9878 "refresh: rcode (%.*s) retrying without "
9879 "EDNS master %s (source %s)",
9880 (int)rb.used, rcode, master, source);
9881 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
9884 dns_zone_log(zone, ISC_LOG_INFO,
9885 "refresh: unexpected rcode (%.*s) from "
9886 "master %s (source %s)", (int)rb.used, rcode,
9889 * Perhaps AXFR/IXFR is allowed even if SOA queries aren't.
9891 if (msg->rcode == dns_rcode_refused &&
9892 zone->type == dns_zone_slave)
9898 * If truncated punt to zone transfer which will query again.
9900 if ((msg->flags & DNS_MESSAGEFLAG_TC) != 0) {
9901 if (zone->type == dns_zone_slave) {
9902 dns_zone_log(zone, ISC_LOG_INFO,
9903 "refresh: truncated UDP answer, "
9904 "initiating TCP zone xfer "
9905 "for master %s (source %s)",
9907 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
9910 INSIST(zone->type == dns_zone_stub);
9911 if (dns_request_usedtcp(revent->request)) {
9912 dns_zone_log(zone, ISC_LOG_INFO,
9913 "refresh: truncated TCP response "
9914 "from master %s (source %s)",
9918 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEVC);
9924 * if non-auth log and next master;
9926 if ((msg->flags & DNS_MESSAGEFLAG_AA) == 0) {
9927 dns_zone_log(zone, ISC_LOG_INFO,
9928 "refresh: non-authoritative answer from "
9929 "master %s (source %s)", master, source);
9933 cnamecnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_cname);
9934 soacnt = message_count(msg, DNS_SECTION_ANSWER, dns_rdatatype_soa);
9935 nscount = message_count(msg, DNS_SECTION_AUTHORITY, dns_rdatatype_ns);
9936 soacount = message_count(msg, DNS_SECTION_AUTHORITY,
9940 * There should not be a CNAME record at top of zone.
9942 if (cnamecnt != 0) {
9943 dns_zone_log(zone, ISC_LOG_INFO,
9944 "refresh: CNAME at top of zone "
9945 "in master %s (source %s)", master, source);
9950 * if referral log and next master;
9952 if (soacnt == 0 && soacount == 0 && nscount != 0) {
9953 dns_zone_log(zone, ISC_LOG_INFO,
9954 "refresh: referral response "
9955 "from master %s (source %s)", master, source);
9960 * if nodata log and next master;
9962 if (soacnt == 0 && (nscount == 0 || soacount != 0)) {
9963 dns_zone_log(zone, ISC_LOG_INFO,
9964 "refresh: NODATA response "
9965 "from master %s (source %s)", master, source);
9970 * Only one soa at top of zone.
9973 dns_zone_log(zone, ISC_LOG_INFO,
9974 "refresh: answer SOA count (%d) != 1 "
9975 "from master %s (source %s)",
9976 soacnt, master, source);
9984 result = dns_message_findname(msg, DNS_SECTION_ANSWER, &zone->origin,
9985 dns_rdatatype_soa, dns_rdatatype_none,
9987 if (result != ISC_R_SUCCESS) {
9988 dns_zone_log(zone, ISC_LOG_INFO,
9989 "refresh: unable to get SOA record "
9990 "from master %s (source %s)", master, source);
9994 result = dns_rdataset_first(rdataset);
9995 if (result != ISC_R_SUCCESS) {
9996 dns_zone_log(zone, ISC_LOG_INFO,
9997 "refresh: dns_rdataset_first() failed");
10001 dns_rdataset_current(rdataset, &rdata);
10002 result = dns_rdata_tostruct(&rdata, &soa, NULL);
10003 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10005 serial = soa.serial;
10006 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED)) {
10007 unsigned int soacount;
10008 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
10009 &oldserial, NULL, NULL, NULL, NULL,
10011 RUNTIME_CHECK(result == ISC_R_SUCCESS);
10012 RUNTIME_CHECK(soacount > 0U);
10013 zone_debuglog(zone, me, 1, "serial: new %u, old %u",
10014 serial, oldserial);
10016 zone_debuglog(zone, me, 1, "serial: new %u, old not loaded",
10019 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) ||
10020 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) ||
10021 isc_serial_gt(serial, oldserial)) {
10022 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
10023 &zone->sourceaddr, &now))
10025 dns_zone_log(zone, ISC_LOG_INFO,
10026 "refresh: skipping %s as master %s "
10027 "(source %s) is unreachable (cached)",
10028 zone->type == dns_zone_slave ?
10029 "zone transfer" : "NS query",
10034 isc_event_free(&event);
10035 dns_request_destroy(&zone->request);
10036 if (zone->type == dns_zone_slave) {
10037 do_queue_xfrin = ISC_TRUE;
10039 INSIST(zone->type == dns_zone_stub);
10040 ns_query(zone, rdataset, NULL);
10043 dns_message_destroy(&msg);
10044 } else if (isc_serial_eq(soa.serial, oldserial)) {
10045 if (zone->masterfile != NULL) {
10046 result = ISC_R_FAILURE;
10047 if (zone->journal != NULL)
10048 result = isc_file_settime(zone->journal, &now);
10049 if (result == ISC_R_SUCCESS &&
10050 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10051 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10052 result = isc_file_settime(zone->masterfile,
10054 } else if (result != ISC_R_SUCCESS)
10055 result = isc_file_settime(zone->masterfile,
10057 /* Someone removed the file from underneath us! */
10058 if (result == ISC_R_FILENOTFOUND) {
10059 zone_needdump(zone, DNS_DUMP_DELAY);
10060 } else if (result != ISC_R_SUCCESS)
10061 dns_zone_log(zone, ISC_LOG_ERROR,
10062 "refresh: could not set file "
10063 "modification time of '%s': %s",
10065 dns_result_totext(result));
10067 DNS_ZONE_JITTER_ADD(&now, zone->refresh, &zone->refreshtime);
10068 DNS_ZONE_TIME_ADD(&now, zone->expire, &zone->expiretime);
10069 zone->mastersok[zone->curmaster] = ISC_TRUE;
10072 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_MULTIMASTER))
10073 dns_zone_log(zone, ISC_LOG_INFO, "serial number (%u) "
10074 "received from master %s < ours (%u)",
10075 soa.serial, master, oldserial);
10077 zone_debuglog(zone, me, 1, "ahead");
10078 zone->mastersok[zone->curmaster] = ISC_TRUE;
10082 dns_message_destroy(&msg);
10087 dns_message_destroy(&msg);
10088 isc_event_free(&event);
10089 dns_request_destroy(&zone->request);
10091 * Skip to next failed / untried master.
10095 } while (zone->curmaster < zone->masterscnt &&
10096 zone->mastersok[zone->curmaster]);
10097 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NOEDNS);
10098 if (zone->curmaster >= zone->masterscnt) {
10099 isc_boolean_t done = ISC_TRUE;
10100 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
10101 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10103 * Did we get a good answer from all the masters?
10105 for (j = 0; j < zone->masterscnt; j++)
10106 if (zone->mastersok[j] == ISC_FALSE) {
10113 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10114 zone->curmaster = 0;
10116 * Find the next failed master.
10118 while (zone->curmaster < zone->masterscnt &&
10119 zone->mastersok[zone->curmaster])
10123 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10124 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
10125 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
10126 zone->refreshtime = now;
10128 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
10129 zone_settimer(zone, &now);
10134 queue_soa_query(zone);
10139 dns_message_destroy(&msg);
10140 isc_event_free(&event);
10141 dns_request_destroy(&zone->request);
10142 queue_soa_query(zone);
10146 if (do_queue_xfrin)
10148 dns_zone_idetach(&zone);
10153 queue_soa_query(dns_zone_t *zone) {
10154 const char me[] = "queue_soa_query";
10156 dns_zone_t *dummy = NULL;
10157 isc_result_t result;
10163 REQUIRE(LOCKED_ZONE(zone));
10165 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
10166 cancel_refresh(zone);
10170 e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
10171 soa_query, zone, sizeof(isc_event_t));
10173 cancel_refresh(zone);
10178 * Attach so that we won't clean up
10179 * until the event is delivered.
10181 zone_iattach(zone, &dummy);
10184 e->ev_sender = NULL;
10185 result = isc_ratelimiter_enqueue(zone->zmgr->refreshrl, zone->task, &e);
10186 if (result != ISC_R_SUCCESS) {
10187 zone_idetach(&dummy);
10188 isc_event_free(&e);
10189 cancel_refresh(zone);
10193 static inline isc_result_t
10194 create_query(dns_zone_t *zone, dns_rdatatype_t rdtype,
10195 dns_message_t **messagep)
10197 dns_message_t *message = NULL;
10198 dns_name_t *qname = NULL;
10199 dns_rdataset_t *qrdataset = NULL;
10200 isc_result_t result;
10202 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10204 if (result != ISC_R_SUCCESS)
10207 message->opcode = dns_opcode_query;
10208 message->rdclass = zone->rdclass;
10210 result = dns_message_gettempname(message, &qname);
10211 if (result != ISC_R_SUCCESS)
10214 result = dns_message_gettemprdataset(message, &qrdataset);
10215 if (result != ISC_R_SUCCESS)
10221 dns_name_init(qname, NULL);
10222 dns_name_clone(&zone->origin, qname);
10223 dns_rdataset_init(qrdataset);
10224 dns_rdataset_makequestion(qrdataset, zone->rdclass, rdtype);
10225 ISC_LIST_APPEND(qname->list, qrdataset, link);
10226 dns_message_addname(message, qname, DNS_SECTION_QUESTION);
10228 *messagep = message;
10229 return (ISC_R_SUCCESS);
10233 dns_message_puttempname(message, &qname);
10234 if (qrdataset != NULL)
10235 dns_message_puttemprdataset(message, &qrdataset);
10236 if (message != NULL)
10237 dns_message_destroy(&message);
10241 static isc_result_t
10242 add_opt(dns_message_t *message, isc_uint16_t udpsize, isc_boolean_t reqnsid) {
10243 dns_rdataset_t *rdataset = NULL;
10244 dns_rdatalist_t *rdatalist = NULL;
10245 dns_rdata_t *rdata = NULL;
10246 isc_result_t result;
10248 result = dns_message_gettemprdatalist(message, &rdatalist);
10249 if (result != ISC_R_SUCCESS)
10251 result = dns_message_gettemprdata(message, &rdata);
10252 if (result != ISC_R_SUCCESS)
10254 result = dns_message_gettemprdataset(message, &rdataset);
10255 if (result != ISC_R_SUCCESS)
10257 dns_rdataset_init(rdataset);
10259 rdatalist->type = dns_rdatatype_opt;
10260 rdatalist->covers = 0;
10263 * Set Maximum UDP buffer size.
10265 rdatalist->rdclass = udpsize;
10268 * Set EXTENDED-RCODE, VERSION, DO and Z to 0.
10270 rdatalist->ttl = 0;
10272 /* Set EDNS options if applicable */
10274 unsigned char data[4];
10277 isc_buffer_init(&buf, data, sizeof(data));
10278 isc_buffer_putuint16(&buf, DNS_OPT_NSID);
10279 isc_buffer_putuint16(&buf, 0);
10280 rdata->data = data;
10281 rdata->length = sizeof(data);
10283 rdata->data = NULL;
10287 rdata->rdclass = rdatalist->rdclass;
10288 rdata->type = rdatalist->type;
10291 ISC_LIST_INIT(rdatalist->rdata);
10292 ISC_LIST_APPEND(rdatalist->rdata, rdata, link);
10293 RUNTIME_CHECK(dns_rdatalist_tordataset(rdatalist, rdataset)
10296 return (dns_message_setopt(message, rdataset));
10299 if (rdatalist != NULL)
10300 dns_message_puttemprdatalist(message, &rdatalist);
10301 if (rdataset != NULL)
10302 dns_message_puttemprdataset(message, &rdataset);
10304 dns_message_puttemprdata(message, &rdata);
10310 soa_query(isc_task_t *task, isc_event_t *event) {
10311 const char me[] = "soa_query";
10312 isc_result_t result = ISC_R_FAILURE;
10313 dns_message_t *message = NULL;
10314 dns_zone_t *zone = event->ev_arg;
10315 dns_zone_t *dummy = NULL;
10316 isc_netaddr_t masterip;
10317 dns_tsigkey_t *key = NULL;
10318 isc_uint32_t options;
10319 isc_boolean_t cancel = ISC_TRUE;
10321 isc_boolean_t have_xfrsource, reqnsid;
10322 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10324 REQUIRE(DNS_ZONE_VALID(zone));
10331 if (((event->ev_attributes & ISC_EVENTATTR_CANCELED) != 0) ||
10332 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) ||
10333 zone->view->requestmgr == NULL) {
10334 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10335 cancel = ISC_FALSE;
10340 * XXX Optimisation: Create message when zone is setup and reuse.
10342 result = create_query(zone, dns_rdatatype_soa, &message);
10343 if (result != ISC_R_SUCCESS)
10347 INSIST(zone->masterscnt > 0);
10348 INSIST(zone->curmaster < zone->masterscnt);
10350 zone->masteraddr = zone->masters[zone->curmaster];
10352 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10354 * First, look for a tsig key in the master statement, then
10355 * try for a server key.
10357 if ((zone->masterkeynames != NULL) &&
10358 (zone->masterkeynames[zone->curmaster] != NULL)) {
10359 dns_view_t *view = dns_zone_getview(zone);
10360 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10361 result = dns_view_gettsig(view, keyname, &key);
10362 if (result != ISC_R_SUCCESS) {
10363 char namebuf[DNS_NAME_FORMATSIZE];
10364 dns_name_format(keyname, namebuf, sizeof(namebuf));
10365 dns_zone_log(zone, ISC_LOG_ERROR,
10366 "unable to find key: %s", namebuf);
10371 result = dns_view_getpeertsig(zone->view, &masterip, &key);
10372 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
10373 char addrbuf[ISC_NETADDR_FORMATSIZE];
10374 isc_netaddr_format(&masterip, addrbuf, sizeof(addrbuf));
10375 dns_zone_log(zone, ISC_LOG_ERROR,
10376 "unable to find TSIG key for %s", addrbuf);
10381 have_xfrsource = ISC_FALSE;
10382 reqnsid = zone->view->requestnsid;
10383 if (zone->view->peers != NULL) {
10384 dns_peer_t *peer = NULL;
10385 isc_boolean_t edns;
10386 result = dns_peerlist_peerbyaddr(zone->view->peers,
10388 if (result == ISC_R_SUCCESS) {
10389 result = dns_peer_getsupportedns(peer, &edns);
10390 if (result == ISC_R_SUCCESS && !edns)
10391 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10392 result = dns_peer_gettransfersource(peer,
10393 &zone->sourceaddr);
10394 if (result == ISC_R_SUCCESS)
10395 have_xfrsource = ISC_TRUE;
10396 if (zone->view->resolver != NULL)
10398 dns_resolver_getudpsize(zone->view->resolver);
10399 (void)dns_peer_getudpsize(peer, &udpsize);
10400 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10404 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10406 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10407 if (isc_sockaddr_equal(&zone->altxfrsource4,
10408 &zone->xfrsource4))
10410 zone->sourceaddr = zone->altxfrsource4;
10411 } else if (!have_xfrsource)
10412 zone->sourceaddr = zone->xfrsource4;
10415 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
10416 if (isc_sockaddr_equal(&zone->altxfrsource6,
10417 &zone->xfrsource6))
10419 zone->sourceaddr = zone->altxfrsource6;
10420 } else if (!have_xfrsource)
10421 zone->sourceaddr = zone->xfrsource6;
10424 result = ISC_R_NOTIMPLEMENTED;
10428 options = DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEVC) ?
10429 DNS_REQUESTOPT_TCP : 0;
10431 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10432 result = add_opt(message, udpsize, reqnsid);
10433 if (result != ISC_R_SUCCESS)
10434 zone_debuglog(zone, me, 1,
10435 "unable to add opt record: %s",
10436 dns_result_totext(result));
10439 zone_iattach(zone, &dummy);
10441 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10443 result = dns_request_createvia2(zone->view->requestmgr, message,
10444 &zone->sourceaddr, &zone->masteraddr,
10445 options, key, timeout * 3, timeout,
10446 zone->task, refresh_callback, zone,
10448 if (result != ISC_R_SUCCESS) {
10449 zone_idetach(&dummy);
10450 zone_debuglog(zone, me, 1,
10451 "dns_request_createvia2() failed: %s",
10452 dns_result_totext(result));
10455 if (isc_sockaddr_pf(&zone->masteraddr) == PF_INET)
10456 inc_stats(zone, dns_zonestatscounter_soaoutv4);
10458 inc_stats(zone, dns_zonestatscounter_soaoutv6);
10460 cancel = ISC_FALSE;
10464 dns_tsigkey_detach(&key);
10465 if (result != ISC_R_SUCCESS)
10466 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10467 if (message != NULL)
10468 dns_message_destroy(&message);
10470 cancel_refresh(zone);
10471 isc_event_free(&event);
10473 dns_zone_idetach(&zone);
10478 dns_tsigkey_detach(&key);
10480 * Skip to next failed / untried master.
10484 } while (zone->curmaster < zone->masterscnt &&
10485 zone->mastersok[zone->curmaster]);
10486 if (zone->curmaster < zone->masterscnt)
10488 zone->curmaster = 0;
10493 ns_query(dns_zone_t *zone, dns_rdataset_t *soardataset, dns_stub_t *stub) {
10494 const char me[] = "ns_query";
10495 isc_result_t result;
10496 dns_message_t *message = NULL;
10497 isc_netaddr_t masterip;
10498 dns_tsigkey_t *key = NULL;
10499 dns_dbnode_t *node = NULL;
10501 isc_boolean_t have_xfrsource = ISC_FALSE, reqnsid;
10502 isc_uint16_t udpsize = SEND_BUFFER_SIZE;
10504 REQUIRE(DNS_ZONE_VALID(zone));
10505 REQUIRE(LOCKED_ZONE(zone));
10506 REQUIRE((soardataset != NULL && stub == NULL) ||
10507 (soardataset == NULL && stub != NULL));
10508 REQUIRE(stub == NULL || DNS_STUB_VALID(stub));
10512 if (stub == NULL) {
10513 stub = isc_mem_get(zone->mctx, sizeof(*stub));
10516 stub->magic = STUB_MAGIC;
10517 stub->mctx = zone->mctx;
10520 stub->version = NULL;
10523 * Attach so that the zone won't disappear from under us.
10525 zone_iattach(zone, &stub->zone);
10528 * If a db exists we will update it, otherwise we create a
10529 * new one and attach it to the zone once we have the NS
10532 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
10533 if (zone->db != NULL) {
10534 dns_db_attach(zone->db, &stub->db);
10535 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10537 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
10539 INSIST(zone->db_argc >= 1);
10540 result = dns_db_create(zone->mctx, zone->db_argv[0],
10541 &zone->origin, dns_dbtype_stub,
10546 if (result != ISC_R_SUCCESS) {
10547 dns_zone_log(zone, ISC_LOG_ERROR,
10548 "refreshing stub: "
10549 "could not create "
10551 dns_result_totext(result));
10554 dns_db_settask(stub->db, zone->task);
10557 result = dns_db_newversion(stub->db, &stub->version);
10558 if (result != ISC_R_SUCCESS) {
10559 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10560 "dns_db_newversion() failed: %s",
10561 dns_result_totext(result));
10566 * Update SOA record.
10568 result = dns_db_findnode(stub->db, &zone->origin, ISC_TRUE,
10570 if (result != ISC_R_SUCCESS) {
10571 dns_zone_log(zone, ISC_LOG_INFO, "refreshing stub: "
10572 "dns_db_findnode() failed: %s",
10573 dns_result_totext(result));
10577 result = dns_db_addrdataset(stub->db, node, stub->version, 0,
10578 soardataset, 0, NULL);
10579 dns_db_detachnode(stub->db, &node);
10580 if (result != ISC_R_SUCCESS) {
10581 dns_zone_log(zone, ISC_LOG_INFO,
10582 "refreshing stub: "
10583 "dns_db_addrdataset() failed: %s",
10584 dns_result_totext(result));
10590 * XXX Optimisation: Create message when zone is setup and reuse.
10592 result = create_query(zone, dns_rdatatype_ns, &message);
10593 INSIST(result == ISC_R_SUCCESS);
10595 INSIST(zone->masterscnt > 0);
10596 INSIST(zone->curmaster < zone->masterscnt);
10597 zone->masteraddr = zone->masters[zone->curmaster];
10599 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
10601 * First, look for a tsig key in the master statement, then
10602 * try for a server key.
10604 if ((zone->masterkeynames != NULL) &&
10605 (zone->masterkeynames[zone->curmaster] != NULL)) {
10606 dns_view_t *view = dns_zone_getview(zone);
10607 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
10608 result = dns_view_gettsig(view, keyname, &key);
10609 if (result != ISC_R_SUCCESS) {
10610 char namebuf[DNS_NAME_FORMATSIZE];
10611 dns_name_format(keyname, namebuf, sizeof(namebuf));
10612 dns_zone_log(zone, ISC_LOG_ERROR,
10613 "unable to find key: %s", namebuf);
10617 (void)dns_view_getpeertsig(zone->view, &masterip, &key);
10619 reqnsid = zone->view->requestnsid;
10620 if (zone->view->peers != NULL) {
10621 dns_peer_t *peer = NULL;
10622 isc_boolean_t edns;
10623 result = dns_peerlist_peerbyaddr(zone->view->peers,
10625 if (result == ISC_R_SUCCESS) {
10626 result = dns_peer_getsupportedns(peer, &edns);
10627 if (result == ISC_R_SUCCESS && !edns)
10628 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOEDNS);
10629 result = dns_peer_gettransfersource(peer,
10630 &zone->sourceaddr);
10631 if (result == ISC_R_SUCCESS)
10632 have_xfrsource = ISC_TRUE;
10633 if (zone->view->resolver != NULL)
10635 dns_resolver_getudpsize(zone->view->resolver);
10636 (void)dns_peer_getudpsize(peer, &udpsize);
10637 (void)dns_peer_getrequestnsid(peer, &reqnsid);
10641 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOEDNS)) {
10642 result = add_opt(message, udpsize, reqnsid);
10643 if (result != ISC_R_SUCCESS)
10644 zone_debuglog(zone, me, 1,
10645 "unable to add opt record: %s",
10646 dns_result_totext(result));
10650 * Always use TCP so that we shouldn't truncate in additional section.
10652 switch (isc_sockaddr_pf(&zone->masteraddr)) {
10654 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10655 zone->sourceaddr = zone->altxfrsource4;
10656 else if (!have_xfrsource)
10657 zone->sourceaddr = zone->xfrsource4;
10660 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC))
10661 zone->sourceaddr = zone->altxfrsource6;
10662 else if (!have_xfrsource)
10663 zone->sourceaddr = zone->xfrsource6;
10666 result = ISC_R_NOTIMPLEMENTED;
10671 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
10673 result = dns_request_createvia2(zone->view->requestmgr, message,
10674 &zone->sourceaddr, &zone->masteraddr,
10675 DNS_REQUESTOPT_TCP, key, timeout * 3,
10676 timeout, zone->task, stub_callback,
10677 stub, &zone->request);
10678 if (result != ISC_R_SUCCESS) {
10679 zone_debuglog(zone, me, 1,
10680 "dns_request_createvia() failed: %s",
10681 dns_result_totext(result));
10684 dns_message_destroy(&message);
10688 cancel_refresh(zone);
10689 if (stub != NULL) {
10691 if (stub->version != NULL)
10692 dns_db_closeversion(stub->db, &stub->version,
10694 if (stub->db != NULL)
10695 dns_db_detach(&stub->db);
10696 if (stub->zone != NULL)
10697 zone_idetach(&stub->zone);
10698 isc_mem_put(stub->mctx, stub, sizeof(*stub));
10700 if (message != NULL)
10701 dns_message_destroy(&message);
10704 dns_tsigkey_detach(&key);
10709 * Handle the control event. Note that although this event causes the zone
10710 * to shut down, it is not a shutdown event in the sense of the task library.
10713 zone_shutdown(isc_task_t *task, isc_event_t *event) {
10714 dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
10715 isc_boolean_t free_needed, linked = ISC_FALSE;
10718 REQUIRE(DNS_ZONE_VALID(zone));
10719 INSIST(event->ev_type == DNS_EVENT_ZONECONTROL);
10720 INSIST(isc_refcount_current(&zone->erefs) == 0);
10722 zone_debuglog(zone, "zone_shutdown", 3, "shutting down");
10725 * Stop things being restarted after we cancel them below.
10728 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING);
10732 * If we were waiting for xfrin quota, step out of
10734 * If there's no zone manager, we can't be waiting for the
10737 if (zone->zmgr != NULL) {
10738 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10739 if (zone->statelist == &zone->zmgr->waiting_for_xfrin) {
10740 ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone,
10743 zone->statelist = NULL;
10745 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
10749 * In task context, no locking required. See zone_xfrdone().
10751 if (zone->xfr != NULL)
10752 dns_xfrin_shutdown(zone->xfr);
10756 INSIST(zone->irefs > 0);
10759 if (zone->request != NULL) {
10760 dns_request_cancel(zone->request);
10763 if (zone->readio != NULL)
10764 zonemgr_cancelio(zone->readio);
10766 if (zone->lctx != NULL)
10767 dns_loadctx_cancel(zone->lctx);
10769 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FLUSH) ||
10770 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10771 if (zone->writeio != NULL)
10772 zonemgr_cancelio(zone->writeio);
10774 if (zone->dctx != NULL)
10775 dns_dumpctx_cancel(zone->dctx);
10778 notify_cancel(zone);
10780 forward_cancel(zone);
10782 if (zone->timer != NULL) {
10783 isc_timer_detach(&zone->timer);
10784 INSIST(zone->irefs > 0);
10788 if (zone->view != NULL)
10789 dns_view_weakdetach(&zone->view);
10792 * We have now canceled everything set the flag to allow exit_check()
10793 * to succeed. We must not unlock between setting this flag and
10794 * calling exit_check().
10796 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN);
10797 free_needed = exit_check(zone);
10804 zone_timer(isc_task_t *task, isc_event_t *event) {
10805 const char me[] = "zone_timer";
10806 dns_zone_t *zone = (dns_zone_t *)event->ev_arg;
10809 REQUIRE(DNS_ZONE_VALID(zone));
10813 zone_maintenance(zone);
10815 isc_event_free(&event);
10819 zone_settimer(dns_zone_t *zone, isc_time_t *now) {
10820 const char me[] = "zone_settimer";
10822 isc_result_t result;
10825 REQUIRE(DNS_ZONE_VALID(zone));
10826 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
10829 isc_time_settoepoch(&next);
10831 switch (zone->type) {
10832 case dns_zone_master:
10833 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10834 next = zone->notifytime;
10835 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10836 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10837 INSIST(!isc_time_isepoch(&zone->dumptime));
10838 if (isc_time_isepoch(&next) ||
10839 isc_time_compare(&zone->dumptime, &next) < 0)
10840 next = zone->dumptime;
10842 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING) &&
10843 !isc_time_isepoch(&zone->refreshkeytime)) {
10844 if (isc_time_isepoch(&next) ||
10845 isc_time_compare(&zone->refreshkeytime, &next) < 0)
10846 next = zone->refreshkeytime;
10848 if (!isc_time_isepoch(&zone->resigntime)) {
10849 if (isc_time_isepoch(&next) ||
10850 isc_time_compare(&zone->resigntime, &next) < 0)
10851 next = zone->resigntime;
10853 if (!isc_time_isepoch(&zone->keywarntime)) {
10854 if (isc_time_isepoch(&next) ||
10855 isc_time_compare(&zone->keywarntime, &next) < 0)
10856 next = zone->keywarntime;
10858 if (!isc_time_isepoch(&zone->signingtime)) {
10859 if (isc_time_isepoch(&next) ||
10860 isc_time_compare(&zone->signingtime, &next) < 0)
10861 next = zone->signingtime;
10863 if (!isc_time_isepoch(&zone->nsec3chaintime)) {
10864 if (isc_time_isepoch(&next) ||
10865 isc_time_compare(&zone->nsec3chaintime, &next) < 0)
10866 next = zone->nsec3chaintime;
10870 case dns_zone_slave:
10871 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDNOTIFY))
10872 next = zone->notifytime;
10875 case dns_zone_stub:
10876 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH) &&
10877 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOMASTERS) &&
10878 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH) &&
10879 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADING)) {
10880 INSIST(!isc_time_isepoch(&zone->refreshtime));
10881 if (isc_time_isepoch(&next) ||
10882 isc_time_compare(&zone->refreshtime, &next) < 0)
10883 next = zone->refreshtime;
10885 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
10886 !isc_time_isepoch(&zone->expiretime)) {
10887 if (isc_time_isepoch(&next) ||
10888 isc_time_compare(&zone->expiretime, &next) < 0)
10889 next = zone->expiretime;
10891 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10892 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10893 INSIST(!isc_time_isepoch(&zone->dumptime));
10894 if (isc_time_isepoch(&next) ||
10895 isc_time_compare(&zone->dumptime, &next) < 0)
10896 next = zone->dumptime;
10901 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDDUMP) &&
10902 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DUMPING)) {
10903 INSIST(!isc_time_isepoch(&zone->dumptime));
10904 if (isc_time_isepoch(&next) ||
10905 isc_time_compare(&zone->dumptime, &next) < 0)
10906 next = zone->dumptime;
10908 if (!DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESHING)) {
10909 if (isc_time_isepoch(&next) ||
10910 (!isc_time_isepoch(&zone->refreshkeytime) &&
10911 isc_time_compare(&zone->refreshkeytime, &next) < 0))
10912 next = zone->refreshkeytime;
10920 if (isc_time_isepoch(&next)) {
10921 zone_debuglog(zone, me, 10, "settimer inactive");
10922 result = isc_timer_reset(zone->timer, isc_timertype_inactive,
10923 NULL, NULL, ISC_TRUE);
10924 if (result != ISC_R_SUCCESS)
10925 dns_zone_log(zone, ISC_LOG_ERROR,
10926 "could not deactivate zone timer: %s",
10927 isc_result_totext(result));
10929 if (isc_time_compare(&next, now) <= 0)
10931 result = isc_timer_reset(zone->timer, isc_timertype_once,
10932 &next, NULL, ISC_TRUE);
10933 if (result != ISC_R_SUCCESS)
10934 dns_zone_log(zone, ISC_LOG_ERROR,
10935 "could not reset zone timer: %s",
10936 isc_result_totext(result));
10941 cancel_refresh(dns_zone_t *zone) {
10942 const char me[] = "cancel_refresh";
10946 * 'zone' locked by caller.
10949 REQUIRE(DNS_ZONE_VALID(zone));
10950 REQUIRE(LOCKED_ZONE(zone));
10954 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
10956 zone_settimer(zone, &now);
10959 static isc_result_t
10960 notify_createmessage(dns_zone_t *zone, unsigned int flags,
10961 dns_message_t **messagep)
10963 dns_db_t *zonedb = NULL;
10964 dns_dbnode_t *node = NULL;
10965 dns_dbversion_t *version = NULL;
10966 dns_message_t *message = NULL;
10967 dns_rdataset_t rdataset;
10968 dns_rdata_t rdata = DNS_RDATA_INIT;
10970 dns_name_t *tempname = NULL;
10971 dns_rdata_t *temprdata = NULL;
10972 dns_rdatalist_t *temprdatalist = NULL;
10973 dns_rdataset_t *temprdataset = NULL;
10975 isc_result_t result;
10977 isc_buffer_t *b = NULL;
10979 REQUIRE(DNS_ZONE_VALID(zone));
10980 REQUIRE(messagep != NULL && *messagep == NULL);
10982 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTRENDER,
10984 if (result != ISC_R_SUCCESS)
10987 message->opcode = dns_opcode_notify;
10988 message->flags |= DNS_MESSAGEFLAG_AA;
10989 message->rdclass = zone->rdclass;
10991 result = dns_message_gettempname(message, &tempname);
10992 if (result != ISC_R_SUCCESS)
10995 result = dns_message_gettemprdataset(message, &temprdataset);
10996 if (result != ISC_R_SUCCESS)
11002 dns_name_init(tempname, NULL);
11003 dns_name_clone(&zone->origin, tempname);
11004 dns_rdataset_init(temprdataset);
11005 dns_rdataset_makequestion(temprdataset, zone->rdclass,
11006 dns_rdatatype_soa);
11007 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11008 dns_message_addname(message, tempname, DNS_SECTION_QUESTION);
11010 temprdataset = NULL;
11012 if ((flags & DNS_NOTIFY_NOSOA) != 0)
11015 result = dns_message_gettempname(message, &tempname);
11016 if (result != ISC_R_SUCCESS)
11018 result = dns_message_gettemprdata(message, &temprdata);
11019 if (result != ISC_R_SUCCESS)
11021 result = dns_message_gettemprdataset(message, &temprdataset);
11022 if (result != ISC_R_SUCCESS)
11024 result = dns_message_gettemprdatalist(message, &temprdatalist);
11025 if (result != ISC_R_SUCCESS)
11028 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11029 INSIST(zone->db != NULL); /* XXXJT: is this assumption correct? */
11030 dns_db_attach(zone->db, &zonedb);
11031 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11033 dns_name_init(tempname, NULL);
11034 dns_name_clone(&zone->origin, tempname);
11035 dns_db_currentversion(zonedb, &version);
11036 result = dns_db_findnode(zonedb, tempname, ISC_FALSE, &node);
11037 if (result != ISC_R_SUCCESS)
11040 dns_rdataset_init(&rdataset);
11041 result = dns_db_findrdataset(zonedb, node, version,
11043 dns_rdatatype_none, 0, &rdataset,
11045 if (result != ISC_R_SUCCESS)
11047 result = dns_rdataset_first(&rdataset);
11048 if (result != ISC_R_SUCCESS)
11050 dns_rdataset_current(&rdataset, &rdata);
11051 dns_rdata_toregion(&rdata, &r);
11052 result = isc_buffer_allocate(zone->mctx, &b, r.length);
11053 if (result != ISC_R_SUCCESS)
11055 isc_buffer_putmem(b, r.base, r.length);
11056 isc_buffer_usedregion(b, &r);
11057 dns_rdata_init(temprdata);
11058 dns_rdata_fromregion(temprdata, rdata.rdclass, rdata.type, &r);
11059 dns_message_takebuffer(message, &b);
11060 result = dns_rdataset_next(&rdataset);
11061 dns_rdataset_disassociate(&rdataset);
11062 if (result != ISC_R_NOMORE)
11064 temprdatalist->rdclass = rdata.rdclass;
11065 temprdatalist->type = rdata.type;
11066 temprdatalist->covers = 0;
11067 temprdatalist->ttl = rdataset.ttl;
11068 ISC_LIST_INIT(temprdatalist->rdata);
11069 ISC_LIST_APPEND(temprdatalist->rdata, temprdata, link);
11071 dns_rdataset_init(temprdataset);
11072 result = dns_rdatalist_tordataset(temprdatalist, temprdataset);
11073 if (result != ISC_R_SUCCESS)
11076 ISC_LIST_APPEND(tempname->list, temprdataset, link);
11077 dns_message_addname(message, tempname, DNS_SECTION_ANSWER);
11078 temprdatalist = NULL;
11079 temprdataset = NULL;
11085 dns_db_detachnode(zonedb, &node);
11086 if (version != NULL)
11087 dns_db_closeversion(zonedb, &version, ISC_FALSE);
11088 if (zonedb != NULL)
11089 dns_db_detach(&zonedb);
11090 if (tempname != NULL)
11091 dns_message_puttempname(message, &tempname);
11092 if (temprdata != NULL)
11093 dns_message_puttemprdata(message, &temprdata);
11094 if (temprdataset != NULL)
11095 dns_message_puttemprdataset(message, &temprdataset);
11096 if (temprdatalist != NULL)
11097 dns_message_puttemprdatalist(message, &temprdatalist);
11100 *messagep = message;
11101 return (ISC_R_SUCCESS);
11104 if (tempname != NULL)
11105 dns_message_puttempname(message, &tempname);
11106 if (temprdataset != NULL)
11107 dns_message_puttemprdataset(message, &temprdataset);
11108 dns_message_destroy(&message);
11113 dns_zone_notifyreceive(dns_zone_t *zone, isc_sockaddr_t *from,
11114 dns_message_t *msg)
11117 dns_rdata_soa_t soa;
11118 dns_rdataset_t *rdataset = NULL;
11119 dns_rdata_t rdata = DNS_RDATA_INIT;
11120 isc_result_t result;
11121 char fromtext[ISC_SOCKADDR_FORMATSIZE];
11123 isc_netaddr_t netaddr;
11124 isc_sockaddr_t local, remote;
11126 REQUIRE(DNS_ZONE_VALID(zone));
11129 * If type != T_SOA return DNS_R_NOTIMP. We don't yet support
11133 * Check that 'from' is a valid notify source, (zone->masters).
11134 * Return DNS_R_REFUSED if not.
11136 * If the notify message contains a serial number check it
11137 * against the zones serial and return if <= current serial
11139 * If a refresh check is progress, if so just record the
11140 * fact we received a NOTIFY and from where and return.
11141 * We will perform a new refresh check when the current one
11142 * completes. Return ISC_R_SUCCESS.
11144 * Otherwise initiate a refresh check using 'from' as the
11145 * first address to check. Return ISC_R_SUCCESS.
11148 isc_sockaddr_format(from, fromtext, sizeof(fromtext));
11151 * We only handle NOTIFY (SOA) at the present.
11154 if (isc_sockaddr_pf(from) == PF_INET)
11155 inc_stats(zone, dns_zonestatscounter_notifyinv4);
11157 inc_stats(zone, dns_zonestatscounter_notifyinv6);
11158 if (msg->counts[DNS_SECTION_QUESTION] == 0 ||
11159 dns_message_findname(msg, DNS_SECTION_QUESTION, &zone->origin,
11160 dns_rdatatype_soa, dns_rdatatype_none,
11161 NULL, NULL) != ISC_R_SUCCESS) {
11163 if (msg->counts[DNS_SECTION_QUESTION] == 0) {
11164 dns_zone_log(zone, ISC_LOG_NOTICE,
11166 "question section from: %s", fromtext);
11167 return (DNS_R_FORMERR);
11169 dns_zone_log(zone, ISC_LOG_NOTICE,
11170 "NOTIFY zone does not match");
11171 return (DNS_R_NOTIMP);
11175 * If we are a master zone just succeed.
11177 if (zone->type == dns_zone_master) {
11179 return (ISC_R_SUCCESS);
11182 isc_netaddr_fromsockaddr(&netaddr, from);
11183 for (i = 0; i < zone->masterscnt; i++) {
11184 if (isc_sockaddr_eqaddr(from, &zone->masters[i]))
11186 if (zone->view->aclenv.match_mapped &&
11187 IN6_IS_ADDR_V4MAPPED(&from->type.sin6.sin6_addr) &&
11188 isc_sockaddr_pf(&zone->masters[i]) == AF_INET) {
11189 isc_netaddr_t na1, na2;
11190 isc_netaddr_fromv4mapped(&na1, &netaddr);
11191 isc_netaddr_fromsockaddr(&na2, &zone->masters[i]);
11192 if (isc_netaddr_equal(&na1, &na2))
11198 * Accept notify requests from non masters if they are on
11199 * 'zone->notify_acl'.
11201 if (i >= zone->masterscnt && zone->notify_acl != NULL &&
11202 dns_acl_match(&netaddr, NULL, zone->notify_acl,
11203 &zone->view->aclenv,
11204 &match, NULL) == ISC_R_SUCCESS &&
11207 /* Accept notify. */
11208 } else if (i >= zone->masterscnt) {
11210 dns_zone_log(zone, ISC_LOG_INFO,
11211 "refused notify from non-master: %s", fromtext);
11212 inc_stats(zone, dns_zonestatscounter_notifyrej);
11213 return (DNS_R_REFUSED);
11217 * If the zone is loaded and there are answers check the serial
11218 * to see if we need to do a refresh. Do not worry about this
11219 * check if we are a dialup zone as we use the notify request
11220 * to trigger a refresh check.
11222 if (msg->counts[DNS_SECTION_ANSWER] > 0 &&
11223 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) &&
11224 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NOREFRESH)) {
11225 result = dns_message_findname(msg, DNS_SECTION_ANSWER,
11228 dns_rdatatype_none, NULL,
11230 if (result == ISC_R_SUCCESS)
11231 result = dns_rdataset_first(rdataset);
11232 if (result == ISC_R_SUCCESS) {
11233 isc_uint32_t serial = 0, oldserial;
11234 unsigned int soacount;
11236 dns_rdataset_current(rdataset, &rdata);
11237 result = dns_rdata_tostruct(&rdata, &soa, NULL);
11238 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11239 serial = soa.serial;
11241 * The following should safely be performed without DB
11242 * lock and succeed in this context.
11244 result = zone_get_from_db(zone, zone->db, NULL,
11245 &soacount, &oldserial, NULL,
11246 NULL, NULL, NULL, NULL);
11247 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11248 RUNTIME_CHECK(soacount > 0U);
11249 if (isc_serial_le(serial, oldserial)) {
11253 "zone is up to date",
11256 return (ISC_R_SUCCESS);
11262 * If we got this far and there was a refresh in progress just
11263 * let it complete. Record where we got the notify from so we
11264 * can perform a refresh check when the current one completes
11266 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH)) {
11267 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
11268 zone->notifyfrom = *from;
11270 dns_zone_log(zone, ISC_LOG_INFO,
11271 "notify from %s: refresh in progress, "
11272 "refresh check queued",
11274 return (ISC_R_SUCCESS);
11276 zone->notifyfrom = *from;
11277 local = zone->masteraddr;
11278 remote = zone->sourceaddr;
11280 dns_zonemgr_unreachabledel(zone->zmgr, &local, &remote);
11281 dns_zone_refresh(zone);
11282 return (ISC_R_SUCCESS);
11286 dns_zone_setnotifyacl(dns_zone_t *zone, dns_acl_t *acl) {
11288 REQUIRE(DNS_ZONE_VALID(zone));
11291 if (zone->notify_acl != NULL)
11292 dns_acl_detach(&zone->notify_acl);
11293 dns_acl_attach(acl, &zone->notify_acl);
11298 dns_zone_setqueryacl(dns_zone_t *zone, dns_acl_t *acl) {
11300 REQUIRE(DNS_ZONE_VALID(zone));
11303 if (zone->query_acl != NULL)
11304 dns_acl_detach(&zone->query_acl);
11305 dns_acl_attach(acl, &zone->query_acl);
11310 dns_zone_setqueryonacl(dns_zone_t *zone, dns_acl_t *acl) {
11312 REQUIRE(DNS_ZONE_VALID(zone));
11315 if (zone->queryon_acl != NULL)
11316 dns_acl_detach(&zone->queryon_acl);
11317 dns_acl_attach(acl, &zone->queryon_acl);
11322 dns_zone_setupdateacl(dns_zone_t *zone, dns_acl_t *acl) {
11324 REQUIRE(DNS_ZONE_VALID(zone));
11327 if (zone->update_acl != NULL)
11328 dns_acl_detach(&zone->update_acl);
11329 dns_acl_attach(acl, &zone->update_acl);
11334 dns_zone_setforwardacl(dns_zone_t *zone, dns_acl_t *acl) {
11336 REQUIRE(DNS_ZONE_VALID(zone));
11339 if (zone->forward_acl != NULL)
11340 dns_acl_detach(&zone->forward_acl);
11341 dns_acl_attach(acl, &zone->forward_acl);
11346 dns_zone_setxfracl(dns_zone_t *zone, dns_acl_t *acl) {
11348 REQUIRE(DNS_ZONE_VALID(zone));
11351 if (zone->xfr_acl != NULL)
11352 dns_acl_detach(&zone->xfr_acl);
11353 dns_acl_attach(acl, &zone->xfr_acl);
11358 dns_zone_getnotifyacl(dns_zone_t *zone) {
11360 REQUIRE(DNS_ZONE_VALID(zone));
11362 return (zone->notify_acl);
11366 dns_zone_getqueryacl(dns_zone_t *zone) {
11368 REQUIRE(DNS_ZONE_VALID(zone));
11370 return (zone->query_acl);
11374 dns_zone_getqueryonacl(dns_zone_t *zone) {
11376 REQUIRE(DNS_ZONE_VALID(zone));
11378 return (zone->queryon_acl);
11382 dns_zone_getupdateacl(dns_zone_t *zone) {
11384 REQUIRE(DNS_ZONE_VALID(zone));
11386 return (zone->update_acl);
11390 dns_zone_getforwardacl(dns_zone_t *zone) {
11392 REQUIRE(DNS_ZONE_VALID(zone));
11394 return (zone->forward_acl);
11398 dns_zone_getxfracl(dns_zone_t *zone) {
11400 REQUIRE(DNS_ZONE_VALID(zone));
11402 return (zone->xfr_acl);
11406 dns_zone_clearupdateacl(dns_zone_t *zone) {
11408 REQUIRE(DNS_ZONE_VALID(zone));
11411 if (zone->update_acl != NULL)
11412 dns_acl_detach(&zone->update_acl);
11417 dns_zone_clearforwardacl(dns_zone_t *zone) {
11419 REQUIRE(DNS_ZONE_VALID(zone));
11422 if (zone->forward_acl != NULL)
11423 dns_acl_detach(&zone->forward_acl);
11428 dns_zone_clearnotifyacl(dns_zone_t *zone) {
11430 REQUIRE(DNS_ZONE_VALID(zone));
11433 if (zone->notify_acl != NULL)
11434 dns_acl_detach(&zone->notify_acl);
11439 dns_zone_clearqueryacl(dns_zone_t *zone) {
11441 REQUIRE(DNS_ZONE_VALID(zone));
11444 if (zone->query_acl != NULL)
11445 dns_acl_detach(&zone->query_acl);
11450 dns_zone_clearqueryonacl(dns_zone_t *zone) {
11452 REQUIRE(DNS_ZONE_VALID(zone));
11455 if (zone->queryon_acl != NULL)
11456 dns_acl_detach(&zone->queryon_acl);
11461 dns_zone_clearxfracl(dns_zone_t *zone) {
11463 REQUIRE(DNS_ZONE_VALID(zone));
11466 if (zone->xfr_acl != NULL)
11467 dns_acl_detach(&zone->xfr_acl);
11472 dns_zone_getupdatedisabled(dns_zone_t *zone) {
11473 REQUIRE(DNS_ZONE_VALID(zone));
11474 return (zone->update_disabled);
11479 dns_zone_setupdatedisabled(dns_zone_t *zone, isc_boolean_t state) {
11480 REQUIRE(DNS_ZONE_VALID(zone));
11481 zone->update_disabled = state;
11485 dns_zone_getzeronosoattl(dns_zone_t *zone) {
11486 REQUIRE(DNS_ZONE_VALID(zone));
11487 return (zone->zero_no_soa_ttl);
11492 dns_zone_setzeronosoattl(dns_zone_t *zone, isc_boolean_t state) {
11493 REQUIRE(DNS_ZONE_VALID(zone));
11494 zone->zero_no_soa_ttl = state;
11498 dns_zone_setchecknames(dns_zone_t *zone, dns_severity_t severity) {
11500 REQUIRE(DNS_ZONE_VALID(zone));
11502 zone->check_names = severity;
11506 dns_zone_getchecknames(dns_zone_t *zone) {
11508 REQUIRE(DNS_ZONE_VALID(zone));
11510 return (zone->check_names);
11514 dns_zone_setjournalsize(dns_zone_t *zone, isc_int32_t size) {
11516 REQUIRE(DNS_ZONE_VALID(zone));
11518 zone->journalsize = size;
11522 dns_zone_getjournalsize(dns_zone_t *zone) {
11524 REQUIRE(DNS_ZONE_VALID(zone));
11526 return (zone->journalsize);
11530 zone_namerd_tostr(dns_zone_t *zone, char *buf, size_t length) {
11531 isc_result_t result = ISC_R_FAILURE;
11532 isc_buffer_t buffer;
11534 REQUIRE(buf != NULL);
11535 REQUIRE(length > 1U);
11538 * Leave space for terminating '\0'.
11540 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11541 if (dns_name_dynamic(&zone->origin))
11542 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11543 if (result != ISC_R_SUCCESS &&
11544 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11545 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11547 if (isc_buffer_availablelength(&buffer) > 0)
11548 isc_buffer_putstr(&buffer, "/");
11549 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11551 if (zone->view != NULL && strcmp(zone->view->name, "_bind") != 0 &&
11552 strcmp(zone->view->name, "_default") != 0 &&
11553 strlen(zone->view->name) < isc_buffer_availablelength(&buffer)) {
11554 isc_buffer_putstr(&buffer, "/");
11555 isc_buffer_putstr(&buffer, zone->view->name);
11558 buf[isc_buffer_usedlength(&buffer)] = '\0';
11562 zone_name_tostr(dns_zone_t *zone, char *buf, size_t length) {
11563 isc_result_t result = ISC_R_FAILURE;
11564 isc_buffer_t buffer;
11566 REQUIRE(buf != NULL);
11567 REQUIRE(length > 1U);
11570 * Leave space for terminating '\0'.
11572 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11573 if (dns_name_dynamic(&zone->origin))
11574 result = dns_name_totext(&zone->origin, ISC_TRUE, &buffer);
11575 if (result != ISC_R_SUCCESS &&
11576 isc_buffer_availablelength(&buffer) >= (sizeof("<UNKNOWN>") - 1))
11577 isc_buffer_putstr(&buffer, "<UNKNOWN>");
11579 buf[isc_buffer_usedlength(&buffer)] = '\0';
11583 zone_rdclass_tostr(dns_zone_t *zone, char *buf, size_t length) {
11584 isc_buffer_t buffer;
11586 REQUIRE(buf != NULL);
11587 REQUIRE(length > 1U);
11590 * Leave space for terminating '\0'.
11592 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11593 (void)dns_rdataclass_totext(zone->rdclass, &buffer);
11595 buf[isc_buffer_usedlength(&buffer)] = '\0';
11599 zone_viewname_tostr(dns_zone_t *zone, char *buf, size_t length) {
11600 isc_buffer_t buffer;
11602 REQUIRE(buf != NULL);
11603 REQUIRE(length > 1U);
11607 * Leave space for terminating '\0'.
11609 isc_buffer_init(&buffer, buf, (unsigned int)length - 1);
11611 if (zone->view == NULL) {
11612 isc_buffer_putstr(&buffer, "_none");
11613 } else if (strlen(zone->view->name)
11614 < isc_buffer_availablelength(&buffer)) {
11615 isc_buffer_putstr(&buffer, zone->view->name);
11617 isc_buffer_putstr(&buffer, "_toolong");
11620 buf[isc_buffer_usedlength(&buffer)] = '\0';
11624 dns_zone_name(dns_zone_t *zone, char *buf, size_t length) {
11625 REQUIRE(DNS_ZONE_VALID(zone));
11626 REQUIRE(buf != NULL);
11627 zone_namerd_tostr(zone, buf, length);
11631 notify_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11633 char message[4096];
11635 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11639 vsnprintf(message, sizeof(message), fmt, ap);
11641 isc_log_write(dns_lctx, DNS_LOGCATEGORY_NOTIFY, DNS_LOGMODULE_ZONE,
11642 level, "zone %s: %s", zone->strnamerd, message);
11646 dns_zone_logc(dns_zone_t *zone, isc_logcategory_t *category,
11647 int level, const char *fmt, ...) {
11649 char message[4096];
11651 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11655 vsnprintf(message, sizeof(message), fmt, ap);
11657 isc_log_write(dns_lctx, category, DNS_LOGMODULE_ZONE,
11658 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11659 "managed-keys-zone" : "zone", zone->strnamerd, message);
11663 dns_zone_log(dns_zone_t *zone, int level, const char *fmt, ...) {
11665 char message[4096];
11667 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11671 vsnprintf(message, sizeof(message), fmt, ap);
11673 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11674 level, "%s %s: %s", (zone->type == dns_zone_key) ?
11675 "managed-keys-zone" : "zone", zone->strnamerd, message);
11679 zone_debuglog(dns_zone_t *zone, const char *me, int debuglevel,
11680 const char *fmt, ...)
11683 char message[4096];
11684 int level = ISC_LOG_DEBUG(debuglevel);
11686 if (isc_log_wouldlog(dns_lctx, level) == ISC_FALSE)
11690 vsnprintf(message, sizeof(message), fmt, ap);
11692 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
11693 level, "%s: %s %s: %s", me, zone->type != dns_zone_key ?
11694 "zone" : "managed-keys-zone", zone->strnamerd, message);
11698 message_count(dns_message_t *msg, dns_section_t section, dns_rdatatype_t type)
11700 isc_result_t result;
11702 dns_rdataset_t *curr;
11705 result = dns_message_firstname(msg, section);
11706 while (result == ISC_R_SUCCESS) {
11708 dns_message_currentname(msg, section, &name);
11710 for (curr = ISC_LIST_TAIL(name->list); curr != NULL;
11711 curr = ISC_LIST_PREV(curr, link)) {
11712 if (curr->type == type)
11715 result = dns_message_nextname(msg, section);
11722 dns_zone_setmaxxfrin(dns_zone_t *zone, isc_uint32_t maxxfrin) {
11723 REQUIRE(DNS_ZONE_VALID(zone));
11725 zone->maxxfrin = maxxfrin;
11729 dns_zone_getmaxxfrin(dns_zone_t *zone) {
11730 REQUIRE(DNS_ZONE_VALID(zone));
11732 return (zone->maxxfrin);
11736 dns_zone_setmaxxfrout(dns_zone_t *zone, isc_uint32_t maxxfrout) {
11737 REQUIRE(DNS_ZONE_VALID(zone));
11738 zone->maxxfrout = maxxfrout;
11742 dns_zone_getmaxxfrout(dns_zone_t *zone) {
11743 REQUIRE(DNS_ZONE_VALID(zone));
11745 return (zone->maxxfrout);
11749 dns_zone_gettype(dns_zone_t *zone) {
11750 REQUIRE(DNS_ZONE_VALID(zone));
11752 return (zone->type);
11756 dns_zone_getorigin(dns_zone_t *zone) {
11757 REQUIRE(DNS_ZONE_VALID(zone));
11759 return (&zone->origin);
11763 dns_zone_settask(dns_zone_t *zone, isc_task_t *task) {
11764 REQUIRE(DNS_ZONE_VALID(zone));
11767 if (zone->task != NULL)
11768 isc_task_detach(&zone->task);
11769 isc_task_attach(task, &zone->task);
11770 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
11771 if (zone->db != NULL)
11772 dns_db_settask(zone->db, zone->task);
11773 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
11778 dns_zone_gettask(dns_zone_t *zone, isc_task_t **target) {
11779 REQUIRE(DNS_ZONE_VALID(zone));
11780 isc_task_attach(zone->task, target);
11784 dns_zone_setidlein(dns_zone_t *zone, isc_uint32_t idlein) {
11785 REQUIRE(DNS_ZONE_VALID(zone));
11788 idlein = DNS_DEFAULT_IDLEIN;
11789 zone->idlein = idlein;
11793 dns_zone_getidlein(dns_zone_t *zone) {
11794 REQUIRE(DNS_ZONE_VALID(zone));
11796 return (zone->idlein);
11800 dns_zone_setidleout(dns_zone_t *zone, isc_uint32_t idleout) {
11801 REQUIRE(DNS_ZONE_VALID(zone));
11803 zone->idleout = idleout;
11807 dns_zone_getidleout(dns_zone_t *zone) {
11808 REQUIRE(DNS_ZONE_VALID(zone));
11810 return (zone->idleout);
11814 notify_done(isc_task_t *task, isc_event_t *event) {
11815 dns_requestevent_t *revent = (dns_requestevent_t *)event;
11816 dns_notify_t *notify;
11817 isc_result_t result;
11818 dns_message_t *message = NULL;
11821 char addrbuf[ISC_SOCKADDR_FORMATSIZE];
11825 notify = event->ev_arg;
11826 REQUIRE(DNS_NOTIFY_VALID(notify));
11827 INSIST(task == notify->zone->task);
11829 isc_buffer_init(&buf, rcode, sizeof(rcode));
11830 isc_sockaddr_format(¬ify->dst, addrbuf, sizeof(addrbuf));
11832 result = revent->result;
11833 if (result == ISC_R_SUCCESS)
11834 result = dns_message_create(notify->zone->mctx,
11835 DNS_MESSAGE_INTENTPARSE, &message);
11836 if (result == ISC_R_SUCCESS)
11837 result = dns_request_getresponse(revent->request, message,
11838 DNS_MESSAGEPARSE_PRESERVEORDER);
11839 if (result == ISC_R_SUCCESS)
11840 result = dns_rcode_totext(message->rcode, &buf);
11841 if (result == ISC_R_SUCCESS)
11842 notify_log(notify->zone, ISC_LOG_DEBUG(3),
11843 "notify response from %s: %.*s",
11844 addrbuf, (int)buf.used, rcode);
11846 notify_log(notify->zone, ISC_LOG_DEBUG(2),
11847 "notify to %s failed: %s", addrbuf,
11848 dns_result_totext(result));
11851 * Old bind's return formerr if they see a soa record. Retry w/o
11852 * the soa if we see a formerr and had sent a SOA.
11854 isc_event_free(&event);
11855 if (message != NULL && message->rcode == dns_rcode_formerr &&
11856 (notify->flags & DNS_NOTIFY_NOSOA) == 0) {
11857 notify->flags |= DNS_NOTIFY_NOSOA;
11858 dns_request_destroy(¬ify->request);
11859 result = notify_send_queue(notify);
11860 if (result != ISC_R_SUCCESS)
11861 notify_destroy(notify, ISC_FALSE);
11863 if (result == ISC_R_TIMEDOUT)
11864 notify_log(notify->zone, ISC_LOG_DEBUG(1),
11865 "notify to %s: retries exceeded", addrbuf);
11866 notify_destroy(notify, ISC_FALSE);
11868 if (message != NULL)
11869 dns_message_destroy(&message);
11873 dns_zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11874 isc_result_t result;
11876 REQUIRE(DNS_ZONE_VALID(zone));
11878 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_write);
11879 result = zone_replacedb(zone, db, dump);
11880 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_write);
11885 static isc_result_t
11886 zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
11887 dns_dbversion_t *ver;
11888 isc_result_t result;
11889 unsigned int soacount = 0;
11890 unsigned int nscount = 0;
11893 * 'zone' and 'zonedb' locked by caller.
11895 REQUIRE(DNS_ZONE_VALID(zone));
11896 REQUIRE(LOCKED_ZONE(zone));
11898 result = zone_get_from_db(zone, db, &nscount, &soacount,
11899 NULL, NULL, NULL, NULL, NULL, NULL);
11900 if (result == ISC_R_SUCCESS) {
11901 if (soacount != 1) {
11902 dns_zone_log(zone, ISC_LOG_ERROR,
11903 "has %d SOA records", soacount);
11904 result = DNS_R_BADZONE;
11906 if (nscount == 0 && zone->type != dns_zone_key) {
11907 dns_zone_log(zone, ISC_LOG_ERROR, "has no NS records");
11908 result = DNS_R_BADZONE;
11910 if (result != ISC_R_SUCCESS)
11913 dns_zone_log(zone, ISC_LOG_ERROR,
11914 "retrieving SOA and NS records failed: %s",
11915 dns_result_totext(result));
11919 result = check_nsec3param(zone, db);
11920 if (result != ISC_R_SUCCESS)
11924 dns_db_currentversion(db, &ver);
11927 * The initial version of a slave zone is always dumped;
11928 * subsequent versions may be journaled instead if this
11929 * is enabled in the configuration.
11931 if (zone->db != NULL && zone->journal != NULL &&
11932 DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS) &&
11933 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
11934 isc_uint32_t serial, oldserial;
11935 unsigned int soacount;
11937 dns_zone_log(zone, ISC_LOG_DEBUG(3), "generating diffs");
11939 result = dns_db_getsoaserial(db, ver, &serial);
11940 if (result != ISC_R_SUCCESS) {
11941 dns_zone_log(zone, ISC_LOG_ERROR,
11942 "ixfr-from-differences: unable to get "
11948 * This is checked in zone_postload() for master zones.
11950 result = zone_get_from_db(zone, zone->db, NULL, &soacount,
11951 &oldserial, NULL, NULL, NULL, NULL,
11953 RUNTIME_CHECK(result == ISC_R_SUCCESS);
11954 RUNTIME_CHECK(soacount > 0U);
11955 if (zone->type == dns_zone_slave &&
11956 !isc_serial_gt(serial, oldserial)) {
11957 isc_uint32_t serialmin, serialmax;
11958 serialmin = (oldserial + 1) & 0xffffffffU;
11959 serialmax = (oldserial + 0x7fffffffU) & 0xffffffffU;
11960 dns_zone_log(zone, ISC_LOG_ERROR,
11961 "ixfr-from-differences: failed: "
11962 "new serial (%u) out of range [%u - %u]",
11963 serial, serialmin, serialmax);
11964 result = ISC_R_RANGE;
11968 result = dns_db_diff(zone->mctx, db, ver, zone->db, NULL,
11970 if (result != ISC_R_SUCCESS)
11973 zone_needdump(zone, DNS_DUMP_DELAY);
11974 else if (zone->journalsize != -1) {
11975 result = dns_journal_compact(zone->mctx, zone->journal,
11976 serial, zone->journalsize);
11978 case ISC_R_SUCCESS:
11979 case ISC_R_NOSPACE:
11980 case ISC_R_NOTFOUND:
11981 dns_zone_log(zone, ISC_LOG_DEBUG(3),
11982 "dns_journal_compact: %s",
11983 dns_result_totext(result));
11986 dns_zone_log(zone, ISC_LOG_ERROR,
11987 "dns_journal_compact failed: %s",
11988 dns_result_totext(result));
11993 if (dump && zone->masterfile != NULL) {
11995 * If DNS_ZONEFLG_FORCEXFER was set we don't want
11996 * to keep the old masterfile.
11998 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER) &&
11999 remove(zone->masterfile) < 0 && errno != ENOENT) {
12000 char strbuf[ISC_STRERRORSIZE];
12001 isc__strerror(errno, strbuf, sizeof(strbuf));
12002 isc_log_write(dns_lctx,
12003 DNS_LOGCATEGORY_GENERAL,
12004 DNS_LOGMODULE_ZONE,
12006 "unable to remove masterfile "
12008 zone->masterfile, strbuf);
12010 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_LOADED) == 0)
12011 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NODELAY);
12013 zone_needdump(zone, 0);
12015 if (dump && zone->journal != NULL) {
12017 * The in-memory database just changed, and
12018 * because 'dump' is set, it didn't change by
12019 * being loaded from disk. Also, we have not
12020 * journaled diffs for this change.
12021 * Therefore, the on-disk journal is missing
12022 * the deltas for this change. Since it can
12023 * no longer be used to bring the zone
12024 * up-to-date, it is useless and should be
12027 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
12028 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
12029 "removing journal file");
12030 if (remove(zone->journal) < 0 && errno != ENOENT) {
12031 char strbuf[ISC_STRERRORSIZE];
12032 isc__strerror(errno, strbuf, sizeof(strbuf));
12033 isc_log_write(dns_lctx,
12034 DNS_LOGCATEGORY_GENERAL,
12035 DNS_LOGMODULE_ZONE,
12037 "unable to remove journal "
12039 zone->journal, strbuf);
12044 dns_db_closeversion(db, &ver, ISC_FALSE);
12046 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
12047 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
12048 "replacing zone database");
12050 if (zone->db != NULL)
12051 zone_detachdb(zone);
12052 zone_attachdb(zone, db);
12053 dns_db_settask(zone->db, zone->task);
12054 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_LOADED|DNS_ZONEFLG_NEEDNOTIFY);
12055 return (ISC_R_SUCCESS);
12058 dns_db_closeversion(db, &ver, ISC_FALSE);
12062 /* The caller must hold the dblock as a writer. */
12064 zone_attachdb(dns_zone_t *zone, dns_db_t *db) {
12065 REQUIRE(zone->db == NULL && db != NULL);
12067 dns_db_attach(db, &zone->db);
12068 if (zone->acache != NULL) {
12069 isc_result_t result;
12070 result = dns_acache_setdb(zone->acache, db);
12071 if (result != ISC_R_SUCCESS && result != ISC_R_EXISTS) {
12072 UNEXPECTED_ERROR(__FILE__, __LINE__,
12073 "dns_acache_setdb() failed: %s",
12074 isc_result_totext(result));
12079 /* The caller must hold the dblock as a writer. */
12081 zone_detachdb(dns_zone_t *zone) {
12082 REQUIRE(zone->db != NULL);
12084 if (zone->acache != NULL)
12085 (void)dns_acache_putdb(zone->acache, zone->db);
12086 dns_db_detach(&zone->db);
12090 zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
12092 isc_boolean_t again = ISC_FALSE;
12093 unsigned int soacount;
12094 unsigned int nscount;
12095 isc_uint32_t serial, refresh, retry, expire, minimum;
12096 isc_result_t xfrresult = result;
12097 isc_boolean_t free_needed;
12099 REQUIRE(DNS_ZONE_VALID(zone));
12101 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12102 "zone transfer finished: %s", dns_result_totext(result));
12105 INSIST((zone->flags & DNS_ZONEFLG_REFRESH) != 0);
12106 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_REFRESH);
12107 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR);
12111 case ISC_R_SUCCESS:
12112 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
12114 case DNS_R_UPTODATE:
12115 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_FORCEXFER);
12117 * Has the zone expired underneath us?
12119 ZONEDB_LOCK(&zone->dblock, isc_rwlocktype_read);
12120 if (zone->db == NULL) {
12121 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12126 * Update the zone structure's data from the actual
12131 INSIST(zone->db != NULL);
12132 result = zone_get_from_db(zone, zone->db, &nscount,
12133 &soacount, &serial, &refresh,
12134 &retry, &expire, &minimum, NULL);
12135 ZONEDB_UNLOCK(&zone->dblock, isc_rwlocktype_read);
12136 if (result == ISC_R_SUCCESS) {
12138 dns_zone_log(zone, ISC_LOG_ERROR,
12139 "transferred zone "
12140 "has %d SOA record%s", soacount,
12141 (soacount != 0) ? "s" : "");
12142 if (nscount == 0) {
12143 dns_zone_log(zone, ISC_LOG_ERROR,
12144 "transferred zone "
12145 "has no NS records");
12146 if (DNS_ZONE_FLAG(zone,
12147 DNS_ZONEFLG_HAVETIMERS)) {
12148 zone->refresh = DNS_ZONE_DEFAULTREFRESH;
12149 zone->retry = DNS_ZONE_DEFAULTRETRY;
12151 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
12155 zone->refresh = RANGE(refresh, zone->minrefresh,
12157 zone->retry = RANGE(retry, zone->minretry,
12159 zone->expire = RANGE(expire,
12160 zone->refresh + zone->retry,
12162 zone->minimum = minimum;
12163 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_HAVETIMERS);
12167 * Set our next update/expire times.
12169 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDREFRESH)) {
12170 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDREFRESH);
12171 zone->refreshtime = now;
12172 DNS_ZONE_TIME_ADD(&now, zone->expire,
12173 &zone->expiretime);
12175 DNS_ZONE_JITTER_ADD(&now, zone->refresh,
12176 &zone->refreshtime);
12177 DNS_ZONE_TIME_ADD(&now, zone->expire,
12178 &zone->expiretime);
12180 if (result == ISC_R_SUCCESS && xfrresult == ISC_R_SUCCESS) {
12181 char buf[DNS_NAME_FORMATSIZE + sizeof(": TSIG ''")];
12182 if (zone->tsigkey != NULL) {
12183 char namebuf[DNS_NAME_FORMATSIZE];
12184 dns_name_format(&zone->tsigkey->name, namebuf,
12186 snprintf(buf, sizeof(buf), ": TSIG '%s'",
12190 dns_zone_log(zone, ISC_LOG_INFO,
12191 "transferred serial %u%s",
12196 * This is not necessary if we just performed a AXFR
12197 * however it is necessary for an IXFR / UPTODATE and
12198 * won't hurt with an AXFR.
12200 if (zone->masterfile != NULL || zone->journal != NULL) {
12201 unsigned int delay = DNS_DUMP_DELAY;
12203 result = ISC_R_FAILURE;
12204 if (zone->journal != NULL)
12205 result = isc_file_settime(zone->journal, &now);
12206 if (result != ISC_R_SUCCESS &&
12207 zone->masterfile != NULL)
12208 result = isc_file_settime(zone->masterfile,
12211 if ((DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NODELAY) != 0) ||
12212 result == ISC_R_FILENOTFOUND)
12215 if ((result == ISC_R_SUCCESS ||
12216 result == ISC_R_FILENOTFOUND) &&
12217 zone->masterfile != NULL)
12218 zone_needdump(zone, delay);
12219 else if (result != ISC_R_SUCCESS)
12220 dns_zone_log(zone, ISC_LOG_ERROR,
12221 "transfer: could not set file "
12222 "modification time of '%s': %s",
12224 dns_result_totext(result));
12226 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NODELAY);
12227 inc_stats(zone, dns_zonestatscounter_xfrsuccess);
12230 case DNS_R_BADIXFR:
12231 /* Force retry with AXFR. */
12232 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLAG_NOIXFR);
12238 * Skip to next failed / untried master.
12242 } while (zone->curmaster < zone->masterscnt &&
12243 zone->mastersok[zone->curmaster]);
12246 if (zone->curmaster >= zone->masterscnt) {
12247 zone->curmaster = 0;
12248 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_USEALTXFRSRC) &&
12249 !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_USEALTXFRSRC)) {
12250 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
12251 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12252 while (zone->curmaster < zone->masterscnt &&
12253 zone->mastersok[zone->curmaster])
12257 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_USEALTXFRSRC);
12259 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_REFRESH);
12262 inc_stats(zone, dns_zonestatscounter_xfrfail);
12265 zone_settimer(zone, &now);
12268 * If creating the transfer object failed, zone->xfr is NULL.
12269 * Otherwise, we are called as the done callback of a zone
12270 * transfer object that just entered its shutting-down
12271 * state. Since we are no longer responsible for shutting
12272 * it down, we can detach our reference.
12274 if (zone->xfr != NULL)
12275 dns_xfrin_detach(&zone->xfr);
12277 if (zone->tsigkey != NULL)
12278 dns_tsigkey_detach(&zone->tsigkey);
12281 * Handle any deferred journal compaction.
12283 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_NEEDCOMPACT)) {
12284 result = dns_journal_compact(zone->mctx, zone->journal,
12285 zone->compact_serial,
12286 zone->journalsize);
12288 case ISC_R_SUCCESS:
12289 case ISC_R_NOSPACE:
12290 case ISC_R_NOTFOUND:
12291 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12292 "dns_journal_compact: %s",
12293 dns_result_totext(result));
12296 dns_zone_log(zone, ISC_LOG_ERROR,
12297 "dns_journal_compact failed: %s",
12298 dns_result_totext(result));
12301 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_NEEDCOMPACT);
12305 * This transfer finishing freed up a transfer quota slot.
12306 * Let any other zones waiting for quota have it.
12309 RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12310 ISC_LIST_UNLINK(zone->zmgr->xfrin_in_progress, zone, statelink);
12311 zone->statelist = NULL;
12312 zmgr_resume_xfrs(zone->zmgr, ISC_FALSE);
12313 RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write);
12317 * Retry with a different server if necessary.
12319 if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
12320 queue_soa_query(zone);
12322 INSIST(zone->irefs > 0);
12324 free_needed = exit_check(zone);
12331 zone_loaddone(void *arg, isc_result_t result) {
12332 static char me[] = "zone_loaddone";
12333 dns_load_t *load = arg;
12335 isc_result_t tresult;
12337 REQUIRE(DNS_LOAD_VALID(load));
12342 tresult = dns_db_endload(load->db, &load->callbacks.add_private);
12343 if (tresult != ISC_R_SUCCESS &&
12344 (result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE))
12347 LOCK_ZONE(load->zone);
12348 (void)zone_postload(load->zone, load->db, load->loadtime, result);
12349 zonemgr_putio(&load->zone->readio);
12350 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_LOADING);
12352 * Leave the zone frozen if the reload fails.
12354 if ((result == ISC_R_SUCCESS || result == DNS_R_SEENINCLUDE) &&
12355 DNS_ZONE_FLAG(load->zone, DNS_ZONEFLG_THAW))
12356 zone->update_disabled = ISC_FALSE;
12357 DNS_ZONE_CLRFLAG(load->zone, DNS_ZONEFLG_THAW);
12358 UNLOCK_ZONE(load->zone);
12361 dns_db_detach(&load->db);
12362 if (load->zone->lctx != NULL)
12363 dns_loadctx_detach(&load->zone->lctx);
12364 dns_zone_idetach(&load->zone);
12365 isc_mem_putanddetach(&load->mctx, load, sizeof(*load));
12369 dns_zone_getssutable(dns_zone_t *zone, dns_ssutable_t **table) {
12370 REQUIRE(DNS_ZONE_VALID(zone));
12371 REQUIRE(table != NULL);
12372 REQUIRE(*table == NULL);
12375 if (zone->ssutable != NULL)
12376 dns_ssutable_attach(zone->ssutable, table);
12381 dns_zone_setssutable(dns_zone_t *zone, dns_ssutable_t *table) {
12382 REQUIRE(DNS_ZONE_VALID(zone));
12385 if (zone->ssutable != NULL)
12386 dns_ssutable_detach(&zone->ssutable);
12388 dns_ssutable_attach(table, &zone->ssutable);
12393 dns_zone_setsigvalidityinterval(dns_zone_t *zone, isc_uint32_t interval) {
12394 REQUIRE(DNS_ZONE_VALID(zone));
12396 zone->sigvalidityinterval = interval;
12400 dns_zone_getsigvalidityinterval(dns_zone_t *zone) {
12401 REQUIRE(DNS_ZONE_VALID(zone));
12403 return (zone->sigvalidityinterval);
12407 dns_zone_setsigresigninginterval(dns_zone_t *zone, isc_uint32_t interval) {
12410 REQUIRE(DNS_ZONE_VALID(zone));
12413 zone->sigresigninginterval = interval;
12414 set_resigntime(zone);
12415 if (zone->task != NULL) {
12417 zone_settimer(zone, &now);
12423 dns_zone_getsigresigninginterval(dns_zone_t *zone) {
12424 REQUIRE(DNS_ZONE_VALID(zone));
12426 return (zone->sigresigninginterval);
12430 queue_xfrin(dns_zone_t *zone) {
12431 const char me[] = "queue_xfrin";
12432 isc_result_t result;
12433 dns_zonemgr_t *zmgr = zone->zmgr;
12437 INSIST(zone->statelist == NULL);
12439 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12440 ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
12444 zone->statelist = &zmgr->waiting_for_xfrin;
12445 result = zmgr_start_xfrin_ifquota(zmgr, zone);
12446 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12448 if (result == ISC_R_QUOTA) {
12449 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_INFO,
12450 "zone transfer deferred due to quota");
12451 } else if (result != ISC_R_SUCCESS) {
12452 dns_zone_logc(zone, DNS_LOGCATEGORY_XFER_IN, ISC_LOG_ERROR,
12453 "starting zone transfer: %s",
12454 isc_result_totext(result));
12459 * This event callback is called when a zone has received
12460 * any necessary zone transfer quota. This is the time
12461 * to go ahead and start the transfer.
12464 got_transfer_quota(isc_task_t *task, isc_event_t *event) {
12465 isc_result_t result;
12466 dns_peer_t *peer = NULL;
12467 char master[ISC_SOCKADDR_FORMATSIZE];
12468 char source[ISC_SOCKADDR_FORMATSIZE];
12469 dns_rdatatype_t xfrtype;
12470 dns_zone_t *zone = event->ev_arg;
12471 isc_netaddr_t masterip;
12472 isc_sockaddr_t sourceaddr;
12473 isc_sockaddr_t masteraddr;
12475 const char *soa_before = "";
12479 INSIST(task == zone->task);
12481 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
12482 result = ISC_R_CANCELED;
12488 isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
12489 if (dns_zonemgr_unreachable(zone->zmgr, &zone->masteraddr,
12490 &zone->sourceaddr, &now))
12492 isc_sockaddr_format(&zone->sourceaddr, source, sizeof(source));
12493 dns_zone_log(zone, ISC_LOG_INFO,
12494 "got_transfer_quota: skipping zone transfer as "
12495 "master %s (source %s) is unreachable (cached)",
12497 result = ISC_R_CANCELED;
12501 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
12502 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
12504 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12505 soa_before = "SOA before ";
12507 * Decide whether we should request IXFR or AXFR.
12509 if (zone->db == NULL) {
12510 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12511 "no database exists yet, requesting AXFR of "
12512 "initial version from %s", master);
12513 xfrtype = dns_rdatatype_axfr;
12514 } else if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_IXFRFROMDIFFS)) {
12515 dns_zone_log(zone, ISC_LOG_DEBUG(1), "ixfr-from-differences "
12516 "set, requesting %sAXFR from %s", soa_before,
12518 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12519 xfrtype = dns_rdatatype_soa;
12521 xfrtype = dns_rdatatype_axfr;
12522 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER)) {
12523 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12524 "forced reload, requesting AXFR of "
12525 "initial version from %s", master);
12526 xfrtype = dns_rdatatype_axfr;
12527 } else if (DNS_ZONE_FLAG(zone, DNS_ZONEFLAG_NOIXFR)) {
12528 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12529 "retrying with AXFR from %s due to "
12530 "previous IXFR failure", master);
12531 xfrtype = dns_rdatatype_axfr;
12533 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLAG_NOIXFR);
12536 isc_boolean_t use_ixfr = ISC_TRUE;
12537 if (peer != NULL &&
12538 dns_peer_getrequestixfr(peer, &use_ixfr) ==
12540 ; /* Using peer setting */
12542 use_ixfr = zone->view->requestixfr;
12544 if (use_ixfr == ISC_FALSE) {
12545 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12546 "IXFR disabled, requesting %sAXFR from %s",
12547 soa_before, master);
12548 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SOABEFOREAXFR))
12549 xfrtype = dns_rdatatype_soa;
12551 xfrtype = dns_rdatatype_axfr;
12553 dns_zone_log(zone, ISC_LOG_DEBUG(1),
12554 "requesting IXFR from %s", master);
12555 xfrtype = dns_rdatatype_ixfr;
12560 * Determine if we should attempt to sign the request with TSIG.
12562 result = ISC_R_NOTFOUND;
12564 * First, look for a tsig key in the master statement, then
12565 * try for a server key.
12567 if ((zone->masterkeynames != NULL) &&
12568 (zone->masterkeynames[zone->curmaster] != NULL)) {
12569 dns_view_t *view = dns_zone_getview(zone);
12570 dns_name_t *keyname = zone->masterkeynames[zone->curmaster];
12571 result = dns_view_gettsig(view, keyname, &zone->tsigkey);
12573 if (zone->tsigkey == NULL)
12574 result = dns_view_getpeertsig(zone->view, &masterip,
12577 if (result != ISC_R_SUCCESS && result != ISC_R_NOTFOUND) {
12578 dns_zone_log(zone, ISC_LOG_ERROR,
12579 "could not get TSIG key for zone transfer: %s",
12580 isc_result_totext(result));
12584 masteraddr = zone->masteraddr;
12585 sourceaddr = zone->sourceaddr;
12587 INSIST(isc_sockaddr_pf(&masteraddr) == isc_sockaddr_pf(&sourceaddr));
12588 result = dns_xfrin_create2(zone, xfrtype, &masteraddr, &sourceaddr,
12589 zone->tsigkey, zone->mctx,
12590 zone->zmgr->timermgr, zone->zmgr->socketmgr,
12591 zone->task, zone_xfrdone, &zone->xfr);
12592 if (result == ISC_R_SUCCESS) {
12594 if (xfrtype == dns_rdatatype_axfr) {
12595 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12596 inc_stats(zone, dns_zonestatscounter_axfrreqv4);
12598 inc_stats(zone, dns_zonestatscounter_axfrreqv6);
12599 } else if (xfrtype == dns_rdatatype_ixfr) {
12600 if (isc_sockaddr_pf(&masteraddr) == PF_INET)
12601 inc_stats(zone, dns_zonestatscounter_ixfrreqv4);
12603 inc_stats(zone, dns_zonestatscounter_ixfrreqv6);
12609 * Any failure in this function is handled like a failed
12610 * zone transfer. This ensures that we get removed from
12611 * zmgr->xfrin_in_progress.
12613 if (result != ISC_R_SUCCESS)
12614 zone_xfrdone(zone, result);
12616 isc_event_free(&event);
12620 * Update forwarding support.
12624 forward_destroy(dns_forward_t *forward) {
12626 forward->magic = 0;
12627 if (forward->request != NULL)
12628 dns_request_destroy(&forward->request);
12629 if (forward->msgbuf != NULL)
12630 isc_buffer_free(&forward->msgbuf);
12631 if (forward->zone != NULL) {
12632 LOCK(&forward->zone->lock);
12633 if (ISC_LINK_LINKED(forward, link))
12634 ISC_LIST_UNLINK(forward->zone->forwards, forward, link);
12635 UNLOCK(&forward->zone->lock);
12636 dns_zone_idetach(&forward->zone);
12638 isc_mem_putanddetach(&forward->mctx, forward, sizeof(*forward));
12641 static isc_result_t
12642 sendtomaster(dns_forward_t *forward) {
12643 isc_result_t result;
12644 isc_sockaddr_t src;
12646 LOCK_ZONE(forward->zone);
12648 if (DNS_ZONE_FLAG(forward->zone, DNS_ZONEFLG_EXITING)) {
12649 UNLOCK_ZONE(forward->zone);
12650 return (ISC_R_CANCELED);
12653 if (forward->which >= forward->zone->masterscnt) {
12654 UNLOCK_ZONE(forward->zone);
12655 return (ISC_R_NOMORE);
12658 forward->addr = forward->zone->masters[forward->which];
12660 * Always use TCP regardless of whether the original update
12662 * XXX The timeout may but a bit small if we are far down a
12663 * transfer graph and the master has to try several masters.
12665 switch (isc_sockaddr_pf(&forward->addr)) {
12667 src = forward->zone->xfrsource4;
12670 src = forward->zone->xfrsource6;
12673 result = ISC_R_NOTIMPLEMENTED;
12676 result = dns_request_createraw(forward->zone->view->requestmgr,
12678 &src, &forward->addr,
12679 DNS_REQUESTOPT_TCP, 15 /* XXX */,
12680 forward->zone->task,
12681 forward_callback, forward,
12682 &forward->request);
12683 if (result == ISC_R_SUCCESS) {
12684 if (!ISC_LINK_LINKED(forward, link))
12685 ISC_LIST_APPEND(forward->zone->forwards, forward, link);
12689 UNLOCK_ZONE(forward->zone);
12694 forward_callback(isc_task_t *task, isc_event_t *event) {
12695 const char me[] = "forward_callback";
12696 dns_requestevent_t *revent = (dns_requestevent_t *)event;
12697 dns_message_t *msg = NULL;
12698 char master[ISC_SOCKADDR_FORMATSIZE];
12699 isc_result_t result;
12700 dns_forward_t *forward;
12705 forward = revent->ev_arg;
12706 INSIST(DNS_FORWARD_VALID(forward));
12707 zone = forward->zone;
12708 INSIST(DNS_ZONE_VALID(zone));
12712 isc_sockaddr_format(&forward->addr, master, sizeof(master));
12714 if (revent->result != ISC_R_SUCCESS) {
12715 dns_zone_log(zone, ISC_LOG_INFO,
12716 "could not forward dynamic update to %s: %s",
12717 master, dns_result_totext(revent->result));
12721 result = dns_message_create(zone->mctx, DNS_MESSAGE_INTENTPARSE, &msg);
12722 if (result != ISC_R_SUCCESS)
12725 result = dns_request_getresponse(revent->request, msg,
12726 DNS_MESSAGEPARSE_PRESERVEORDER |
12727 DNS_MESSAGEPARSE_CLONEBUFFER);
12728 if (result != ISC_R_SUCCESS)
12731 switch (msg->rcode) {
12733 * Pass these rcodes back to client.
12735 case dns_rcode_noerror:
12736 case dns_rcode_yxdomain:
12737 case dns_rcode_yxrrset:
12738 case dns_rcode_nxrrset:
12739 case dns_rcode_refused:
12740 case dns_rcode_nxdomain: {
12744 isc_buffer_init(&rb, rcode, sizeof(rcode));
12745 (void)dns_rcode_totext(msg->rcode, &rb);
12746 dns_zone_log(zone, ISC_LOG_INFO,
12747 "forwarded dynamic update: "
12748 "master %s returned: %.*s",
12749 master, (int)rb.used, rcode);
12753 /* These should not occur if the masters/zone are valid. */
12754 case dns_rcode_notzone:
12755 case dns_rcode_notauth: {
12759 isc_buffer_init(&rb, rcode, sizeof(rcode));
12760 (void)dns_rcode_totext(msg->rcode, &rb);
12761 dns_zone_log(zone, ISC_LOG_WARNING,
12762 "forwarding dynamic update: "
12763 "unexpected response: master %s returned: %.*s",
12764 master, (int)rb.used, rcode);
12768 /* Try another server for these rcodes. */
12769 case dns_rcode_formerr:
12770 case dns_rcode_servfail:
12771 case dns_rcode_notimp:
12772 case dns_rcode_badvers:
12777 /* call callback */
12778 (forward->callback)(forward->callback_arg, ISC_R_SUCCESS, msg);
12780 dns_request_destroy(&forward->request);
12781 forward_destroy(forward);
12782 isc_event_free(&event);
12787 dns_message_destroy(&msg);
12788 isc_event_free(&event);
12790 dns_request_destroy(&forward->request);
12791 result = sendtomaster(forward);
12792 if (result != ISC_R_SUCCESS) {
12793 /* call callback */
12794 dns_zone_log(zone, ISC_LOG_DEBUG(3),
12795 "exhausted dynamic update forwarder list");
12796 (forward->callback)(forward->callback_arg, result, NULL);
12797 forward_destroy(forward);
12802 dns_zone_forwardupdate(dns_zone_t *zone, dns_message_t *msg,
12803 dns_updatecallback_t callback, void *callback_arg)
12805 dns_forward_t *forward;
12806 isc_result_t result;
12809 REQUIRE(DNS_ZONE_VALID(zone));
12810 REQUIRE(msg != NULL);
12811 REQUIRE(callback != NULL);
12813 forward = isc_mem_get(zone->mctx, sizeof(*forward));
12814 if (forward == NULL)
12815 return (ISC_R_NOMEMORY);
12817 forward->request = NULL;
12818 forward->zone = NULL;
12819 forward->msgbuf = NULL;
12820 forward->which = 0;
12822 forward->callback = callback;
12823 forward->callback_arg = callback_arg;
12824 ISC_LINK_INIT(forward, link);
12825 forward->magic = FORWARD_MAGIC;
12827 mr = dns_message_getrawmessage(msg);
12829 result = ISC_R_UNEXPECTEDEND;
12833 result = isc_buffer_allocate(zone->mctx, &forward->msgbuf, mr->length);
12834 if (result != ISC_R_SUCCESS)
12836 result = isc_buffer_copyregion(forward->msgbuf, mr);
12837 if (result != ISC_R_SUCCESS)
12840 isc_mem_attach(zone->mctx, &forward->mctx);
12841 dns_zone_iattach(zone, &forward->zone);
12842 result = sendtomaster(forward);
12845 if (result != ISC_R_SUCCESS) {
12846 forward_destroy(forward);
12852 dns_zone_next(dns_zone_t *zone, dns_zone_t **next) {
12853 REQUIRE(DNS_ZONE_VALID(zone));
12854 REQUIRE(next != NULL && *next == NULL);
12856 *next = ISC_LIST_NEXT(zone, link);
12858 return (ISC_R_NOMORE);
12860 return (ISC_R_SUCCESS);
12864 dns_zone_first(dns_zonemgr_t *zmgr, dns_zone_t **first) {
12865 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12866 REQUIRE(first != NULL && *first == NULL);
12868 *first = ISC_LIST_HEAD(zmgr->zones);
12869 if (*first == NULL)
12870 return (ISC_R_NOMORE);
12872 return (ISC_R_SUCCESS);
12880 dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
12881 isc_timermgr_t *timermgr, isc_socketmgr_t *socketmgr,
12882 dns_zonemgr_t **zmgrp)
12884 dns_zonemgr_t *zmgr;
12885 isc_result_t result;
12886 isc_interval_t interval;
12888 zmgr = isc_mem_get(mctx, sizeof(*zmgr));
12890 return (ISC_R_NOMEMORY);
12893 isc_mem_attach(mctx, &zmgr->mctx);
12894 zmgr->taskmgr = taskmgr;
12895 zmgr->timermgr = timermgr;
12896 zmgr->socketmgr = socketmgr;
12897 zmgr->zonetasks = NULL;
12899 zmgr->notifyrl = NULL;
12900 zmgr->refreshrl = NULL;
12901 ISC_LIST_INIT(zmgr->zones);
12902 ISC_LIST_INIT(zmgr->waiting_for_xfrin);
12903 ISC_LIST_INIT(zmgr->xfrin_in_progress);
12904 memset(zmgr->unreachable, 0, sizeof(zmgr->unreachable));
12905 result = isc_rwlock_init(&zmgr->rwlock, 0, 0);
12906 if (result != ISC_R_SUCCESS)
12909 zmgr->transfersin = 10;
12910 zmgr->transfersperns = 2;
12912 /* Unreachable lock. */
12913 result = isc_rwlock_init(&zmgr->urlock, 0, 0);
12914 if (result != ISC_R_SUCCESS)
12917 /* Create a single task for queueing of SOA queries. */
12918 result = isc_task_create(taskmgr, 1, &zmgr->task);
12919 if (result != ISC_R_SUCCESS)
12922 isc_task_setname(zmgr->task, "zmgr", zmgr);
12923 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
12925 if (result != ISC_R_SUCCESS)
12928 result = isc_ratelimiter_create(mctx, timermgr, zmgr->task,
12930 if (result != ISC_R_SUCCESS)
12931 goto free_notifyrl;
12933 /* default to 20 refresh queries / notifies per second. */
12934 isc_interval_set(&interval, 0, 1000000000/2);
12935 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
12936 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12937 isc_ratelimiter_setpertic(zmgr->notifyrl, 10);
12939 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
12940 RUNTIME_CHECK(result == ISC_R_SUCCESS);
12941 isc_ratelimiter_setpertic(zmgr->refreshrl, 10);
12944 zmgr->ioactive = 0;
12945 ISC_LIST_INIT(zmgr->high);
12946 ISC_LIST_INIT(zmgr->low);
12948 result = isc_mutex_init(&zmgr->iolock);
12949 if (result != ISC_R_SUCCESS)
12950 goto free_refreshrl;
12952 zmgr->magic = ZONEMGR_MAGIC;
12955 return (ISC_R_SUCCESS);
12959 DESTROYLOCK(&zmgr->iolock);
12962 isc_ratelimiter_detach(&zmgr->refreshrl);
12964 isc_ratelimiter_detach(&zmgr->notifyrl);
12966 isc_task_detach(&zmgr->task);
12968 isc_rwlock_destroy(&zmgr->urlock);
12970 isc_rwlock_destroy(&zmgr->rwlock);
12972 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
12973 isc_mem_detach(&mctx);
12978 dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
12979 isc_result_t result;
12981 REQUIRE(DNS_ZONE_VALID(zone));
12982 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
12984 if (zmgr->zonetasks == NULL)
12985 return (ISC_R_FAILURE);
12987 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
12989 REQUIRE(zone->task == NULL);
12990 REQUIRE(zone->timer == NULL);
12991 REQUIRE(zone->zmgr == NULL);
12993 isc_taskpool_gettask(zmgr->zonetasks, &zone->task);
12996 * Set the task name. The tag will arbitrarily point to one
12997 * of the zones sharing the task (in practice, the one
12998 * to be managed last).
13000 isc_task_setname(zone->task, "zone", zone);
13002 result = isc_timer_create(zmgr->timermgr, isc_timertype_inactive,
13004 zone->task, zone_timer, zone,
13007 if (result != ISC_R_SUCCESS)
13011 * The timer "holds" a iref.
13014 INSIST(zone->irefs != 0);
13016 ISC_LIST_APPEND(zmgr->zones, zone, link);
13023 isc_task_detach(&zone->task);
13027 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13032 dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
13033 isc_boolean_t free_now = ISC_FALSE;
13035 REQUIRE(DNS_ZONE_VALID(zone));
13036 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13037 REQUIRE(zone->zmgr == zmgr);
13039 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13042 ISC_LIST_UNLINK(zmgr->zones, zone, link);
13045 if (zmgr->refs == 0)
13046 free_now = ISC_TRUE;
13049 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13052 zonemgr_free(zmgr);
13053 ENSURE(zone->zmgr == NULL);
13057 dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
13058 REQUIRE(DNS_ZONEMGR_VALID(source));
13059 REQUIRE(target != NULL && *target == NULL);
13061 RWLOCK(&source->rwlock, isc_rwlocktype_write);
13062 REQUIRE(source->refs > 0);
13064 INSIST(source->refs > 0);
13065 RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
13070 dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
13071 dns_zonemgr_t *zmgr;
13072 isc_boolean_t free_now = ISC_FALSE;
13074 REQUIRE(zmgrp != NULL);
13076 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13078 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13080 if (zmgr->refs == 0)
13081 free_now = ISC_TRUE;
13082 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13085 zonemgr_free(zmgr);
13090 dns_zonemgr_forcemaint(dns_zonemgr_t *zmgr) {
13093 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13095 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13096 for (p = ISC_LIST_HEAD(zmgr->zones);
13098 p = ISC_LIST_NEXT(p, link))
13100 dns_zone_maintenance(p);
13102 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13105 * Recent configuration changes may have increased the
13106 * amount of available transfers quota. Make sure any
13107 * transfers currently blocked on quota get started if
13110 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13111 zmgr_resume_xfrs(zmgr, ISC_TRUE);
13112 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13113 return (ISC_R_SUCCESS);
13117 dns_zonemgr_resumexfrs(dns_zonemgr_t *zmgr) {
13119 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13121 RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13122 zmgr_resume_xfrs(zmgr, ISC_TRUE);
13123 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
13127 dns_zonemgr_shutdown(dns_zonemgr_t *zmgr) {
13130 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13132 isc_ratelimiter_shutdown(zmgr->notifyrl);
13133 isc_ratelimiter_shutdown(zmgr->refreshrl);
13135 if (zmgr->task != NULL)
13136 isc_task_destroy(&zmgr->task);
13137 if (zmgr->zonetasks != NULL)
13138 isc_taskpool_destroy(&zmgr->zonetasks);
13140 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13141 for (zone = ISC_LIST_HEAD(zmgr->zones);
13143 zone = ISC_LIST_NEXT(zone, link))
13146 forward_cancel(zone);
13149 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13153 dns_zonemgr_setsize(dns_zonemgr_t *zmgr, int num_zones) {
13154 isc_result_t result;
13155 int ntasks = num_zones / 100;
13156 isc_taskpool_t *pool = NULL;
13158 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13161 * For anything fewer than 1000 zones we use 10 tasks in
13162 * the task pool. More than that, and we'll scale at one
13163 * task per 100 zones.
13168 /* Create or resize the zone task pool. */
13169 if (zmgr->zonetasks == NULL)
13170 result = isc_taskpool_create(zmgr->taskmgr, zmgr->mctx,
13173 result = isc_taskpool_expand(&zmgr->zonetasks, ntasks, &pool);
13175 if (result == ISC_R_SUCCESS)
13176 zmgr->zonetasks = pool;
13182 zonemgr_free(dns_zonemgr_t *zmgr) {
13185 INSIST(zmgr->refs == 0);
13186 INSIST(ISC_LIST_EMPTY(zmgr->zones));
13190 DESTROYLOCK(&zmgr->iolock);
13191 isc_ratelimiter_detach(&zmgr->notifyrl);
13192 isc_ratelimiter_detach(&zmgr->refreshrl);
13194 isc_rwlock_destroy(&zmgr->urlock);
13195 isc_rwlock_destroy(&zmgr->rwlock);
13197 isc_mem_put(zmgr->mctx, zmgr, sizeof(*zmgr));
13198 isc_mem_detach(&mctx);
13202 dns_zonemgr_settransfersin(dns_zonemgr_t *zmgr, isc_uint32_t value) {
13203 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13205 zmgr->transfersin = value;
13209 dns_zonemgr_getttransfersin(dns_zonemgr_t *zmgr) {
13210 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13212 return (zmgr->transfersin);
13216 dns_zonemgr_settransfersperns(dns_zonemgr_t *zmgr, isc_uint32_t value) {
13217 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13219 zmgr->transfersperns = value;
13223 dns_zonemgr_getttransfersperns(dns_zonemgr_t *zmgr) {
13224 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13226 return (zmgr->transfersperns);
13230 * Try to start a new incoming zone transfer to fill a quota
13231 * slot that was just vacated.
13234 * The zone manager is locked by the caller.
13237 zmgr_resume_xfrs(dns_zonemgr_t *zmgr, isc_boolean_t multi) {
13241 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
13245 isc_result_t result;
13246 next = ISC_LIST_NEXT(zone, statelink);
13247 result = zmgr_start_xfrin_ifquota(zmgr, zone);
13248 if (result == ISC_R_SUCCESS) {
13252 * We successfully filled the slot. We're done.
13255 } else if (result == ISC_R_QUOTA) {
13257 * Not enough quota. This is probably the per-server
13258 * quota, because we usually get called when a unit of
13259 * global quota has just been freed. Try the next
13260 * zone, it may succeed if it uses another master.
13264 dns_zone_log(zone, ISC_LOG_DEBUG(1),
13265 "starting zone transfer: %s",
13266 isc_result_totext(result));
13273 * Try to start an incoming zone transfer for 'zone', quota permitting.
13276 * The zone manager is locked by the caller.
13279 * ISC_R_SUCCESS There was enough quota and we attempted to
13280 * start a transfer. zone_xfrdone() has been or will
13282 * ISC_R_QUOTA Not enough quota.
13285 static isc_result_t
13286 zmgr_start_xfrin_ifquota(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
13287 dns_peer_t *peer = NULL;
13288 isc_netaddr_t masterip;
13289 isc_uint32_t nxfrsin, nxfrsperns;
13291 isc_uint32_t maxtransfersin, maxtransfersperns;
13295 * If we are exiting just pretend we got quota so the zone will
13296 * be cleaned up in the zone's task context.
13299 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) {
13305 * Find any configured information about the server we'd
13306 * like to transfer this zone from.
13308 isc_netaddr_fromsockaddr(&masterip, &zone->masteraddr);
13309 (void)dns_peerlist_peerbyaddr(zone->view->peers, &masterip, &peer);
13313 * Determine the total maximum number of simultaneous
13314 * transfers allowed, and the maximum for this specific
13317 maxtransfersin = zmgr->transfersin;
13318 maxtransfersperns = zmgr->transfersperns;
13320 (void)dns_peer_gettransfers(peer, &maxtransfersperns);
13323 * Count the total number of transfers that are in progress,
13324 * and the number of transfers in progress from this master.
13325 * We linearly scan a list of all transfers; if this turns
13326 * out to be too slow, we could hash on the master address.
13328 nxfrsin = nxfrsperns = 0;
13329 for (x = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13331 x = ISC_LIST_NEXT(x, statelink))
13336 isc_netaddr_fromsockaddr(&xip, &x->masteraddr);
13340 if (isc_netaddr_equal(&xip, &masterip))
13344 /* Enforce quota. */
13345 if (nxfrsin >= maxtransfersin)
13346 return (ISC_R_QUOTA);
13348 if (nxfrsperns >= maxtransfersperns)
13349 return (ISC_R_QUOTA);
13353 * We have sufficient quota. Move the zone to the "xfrin_in_progress"
13354 * list and send it an event to let it start the actual transfer in the
13355 * context of its own task.
13357 e = isc_event_allocate(zmgr->mctx, zmgr, DNS_EVENT_ZONESTARTXFRIN,
13358 got_transfer_quota, zone, sizeof(isc_event_t));
13360 return (ISC_R_NOMEMORY);
13363 INSIST(zone->statelist == &zmgr->waiting_for_xfrin);
13364 ISC_LIST_UNLINK(zmgr->waiting_for_xfrin, zone, statelink);
13365 ISC_LIST_APPEND(zmgr->xfrin_in_progress, zone, statelink);
13366 zone->statelist = &zmgr->xfrin_in_progress;
13367 isc_task_send(zone->task, &e);
13368 dns_zone_log(zone, ISC_LOG_INFO, "Transfer started.");
13371 return (ISC_R_SUCCESS);
13375 dns_zonemgr_setiolimit(dns_zonemgr_t *zmgr, isc_uint32_t iolimit) {
13377 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13378 REQUIRE(iolimit > 0);
13380 zmgr->iolimit = iolimit;
13384 dns_zonemgr_getiolimit(dns_zonemgr_t *zmgr) {
13386 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13388 return (zmgr->iolimit);
13392 * Get permission to request a file handle from the OS.
13393 * An event will be sent to action when one is available.
13394 * There are two queues available (high and low), the high
13395 * queue will be serviced before the low one.
13397 * zonemgr_putio() must be called after the event is delivered to
13401 static isc_result_t
13402 zonemgr_getio(dns_zonemgr_t *zmgr, isc_boolean_t high,
13403 isc_task_t *task, isc_taskaction_t action, void *arg,
13407 isc_boolean_t queue;
13409 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13410 REQUIRE(iop != NULL && *iop == NULL);
13412 io = isc_mem_get(zmgr->mctx, sizeof(*io));
13414 return (ISC_R_NOMEMORY);
13415 io->event = isc_event_allocate(zmgr->mctx, task, DNS_EVENT_IOREADY,
13416 action, arg, sizeof(*io->event));
13417 if (io->event == NULL) {
13418 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13419 return (ISC_R_NOMEMORY);
13424 isc_task_attach(task, &io->task);
13425 ISC_LINK_INIT(io, link);
13426 io->magic = IO_MAGIC;
13428 LOCK(&zmgr->iolock);
13430 queue = ISC_TF(zmgr->ioactive > zmgr->iolimit);
13433 ISC_LIST_APPEND(zmgr->high, io, link);
13435 ISC_LIST_APPEND(zmgr->low, io, link);
13437 UNLOCK(&zmgr->iolock);
13441 isc_task_send(io->task, &io->event);
13443 return (ISC_R_SUCCESS);
13447 zonemgr_putio(dns_io_t **iop) {
13450 dns_zonemgr_t *zmgr;
13452 REQUIRE(iop != NULL);
13454 REQUIRE(DNS_IO_VALID(io));
13458 INSIST(!ISC_LINK_LINKED(io, link));
13459 INSIST(io->event == NULL);
13462 isc_task_detach(&io->task);
13464 isc_mem_put(zmgr->mctx, io, sizeof(*io));
13466 LOCK(&zmgr->iolock);
13467 INSIST(zmgr->ioactive > 0);
13469 next = HEAD(zmgr->high);
13471 next = HEAD(zmgr->low);
13472 if (next != NULL) {
13474 ISC_LIST_UNLINK(zmgr->high, next, link);
13476 ISC_LIST_UNLINK(zmgr->low, next, link);
13477 INSIST(next->event != NULL);
13479 UNLOCK(&zmgr->iolock);
13481 isc_task_send(next->task, &next->event);
13485 zonemgr_cancelio(dns_io_t *io) {
13486 isc_boolean_t send_event = ISC_FALSE;
13488 REQUIRE(DNS_IO_VALID(io));
13491 * If we are queued to be run then dequeue.
13493 LOCK(&io->zmgr->iolock);
13494 if (ISC_LINK_LINKED(io, link)) {
13496 ISC_LIST_UNLINK(io->zmgr->high, io, link);
13498 ISC_LIST_UNLINK(io->zmgr->low, io, link);
13500 send_event = ISC_TRUE;
13501 INSIST(io->event != NULL);
13503 UNLOCK(&io->zmgr->iolock);
13505 io->event->ev_attributes |= ISC_EVENTATTR_CANCELED;
13506 isc_task_send(io->task, &io->event);
13511 zone_saveunique(dns_zone_t *zone, const char *path, const char *templat) {
13514 isc_result_t result;
13516 buflen = strlen(path) + strlen(templat) + 2;
13518 buf = isc_mem_get(zone->mctx, buflen);
13522 result = isc_file_template(path, templat, buf, buflen);
13523 if (result != ISC_R_SUCCESS)
13526 result = isc_file_renameunique(path, buf);
13527 if (result != ISC_R_SUCCESS)
13530 dns_zone_log(zone, ISC_LOG_WARNING, "unable to load from '%s'; "
13531 "renaming file to '%s' for failure analysis and "
13532 "retransferring.", path, buf);
13535 isc_mem_put(zone->mctx, buf, buflen);
13539 /* Hook for ondestroy notification from a database. */
13542 dns_zonemgr_dbdestroyed(isc_task_t *task, isc_event_t *event) {
13543 dns_db_t *db = event->sender;
13546 isc_event_free(&event);
13548 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13549 DNS_LOGMODULE_ZONE, ISC_LOG_DEBUG(3),
13550 "database (%p) destroyed", (void*) db);
13555 dns_zonemgr_setserialqueryrate(dns_zonemgr_t *zmgr, unsigned int value) {
13556 isc_interval_t interval;
13557 isc_uint32_t s, ns;
13558 isc_uint32_t pertic;
13559 isc_result_t result;
13561 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13570 } else if (value <= 10) {
13572 ns = 1000000000 / value;
13576 ns = (1000000000 / value) * 10;
13580 isc_interval_set(&interval, s, ns);
13582 result = isc_ratelimiter_setinterval(zmgr->notifyrl, &interval);
13583 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13584 isc_ratelimiter_setpertic(zmgr->notifyrl, pertic);
13586 result = isc_ratelimiter_setinterval(zmgr->refreshrl, &interval);
13587 RUNTIME_CHECK(result == ISC_R_SUCCESS);
13588 isc_ratelimiter_setpertic(zmgr->refreshrl, pertic);
13590 zmgr->serialqueryrate = value;
13594 dns_zonemgr_getserialqueryrate(dns_zonemgr_t *zmgr) {
13595 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13597 return (zmgr->serialqueryrate);
13601 dns_zonemgr_unreachable(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13602 isc_sockaddr_t *local, isc_time_t *now)
13605 isc_rwlocktype_t locktype;
13606 isc_result_t result;
13607 isc_uint32_t seconds = isc_time_seconds(now);
13608 isc_uint32_t count = 0;
13610 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13612 locktype = isc_rwlocktype_read;
13613 RWLOCK(&zmgr->urlock, locktype);
13614 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13615 if (zmgr->unreachable[i].expire >= seconds &&
13616 isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13617 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13618 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13619 if (result == ISC_R_SUCCESS) {
13620 locktype = isc_rwlocktype_write;
13621 zmgr->unreachable[i].last = seconds;
13622 count = zmgr->unreachable[i].count;
13627 RWUNLOCK(&zmgr->urlock, locktype);
13628 return (ISC_TF(i < UNREACH_CHACHE_SIZE && count > 1U));
13632 dns_zonemgr_unreachabledel(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13633 isc_sockaddr_t *local)
13636 isc_rwlocktype_t locktype;
13637 isc_result_t result;
13639 char master[ISC_SOCKADDR_FORMATSIZE];
13640 char source[ISC_SOCKADDR_FORMATSIZE];
13642 isc_sockaddr_format(remote, master, sizeof(master));
13643 isc_sockaddr_format(local, source, sizeof(source));
13645 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13647 locktype = isc_rwlocktype_read;
13648 RWLOCK(&zmgr->urlock, locktype);
13649 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13650 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13651 isc_sockaddr_equal(&zmgr->unreachable[i].local, local)) {
13652 if (zmgr->unreachable[i].expire == 0)
13654 result = isc_rwlock_tryupgrade(&zmgr->urlock);
13655 if (result == ISC_R_SUCCESS) {
13656 locktype = isc_rwlocktype_write;
13657 zmgr->unreachable[i].expire = 0;
13658 isc_log_write(dns_lctx, DNS_LOGCATEGORY_GENERAL,
13659 DNS_LOGMODULE_ZONE, ISC_LOG_INFO,
13660 "master %s (source %s) deleted "
13661 "from unreachable cache",
13667 RWUNLOCK(&zmgr->urlock, locktype);
13671 dns_zonemgr_unreachableadd(dns_zonemgr_t *zmgr, isc_sockaddr_t *remote,
13672 isc_sockaddr_t *local, isc_time_t *now)
13674 isc_uint32_t seconds = isc_time_seconds(now);
13675 isc_uint32_t last = seconds;
13676 unsigned int i, slot = UNREACH_CHACHE_SIZE, oldest = 0;
13678 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13680 RWLOCK(&zmgr->urlock, isc_rwlocktype_write);
13681 for (i = 0; i < UNREACH_CHACHE_SIZE; i++) {
13682 /* Existing entry? */
13683 if (isc_sockaddr_equal(&zmgr->unreachable[i].remote, remote) &&
13684 isc_sockaddr_equal(&zmgr->unreachable[i].local, local))
13687 if (zmgr->unreachable[i].expire < seconds)
13689 /* Least recently used slot? */
13690 if (zmgr->unreachable[i].last < last) {
13691 last = zmgr->unreachable[i].last;
13695 if (i < UNREACH_CHACHE_SIZE) {
13697 * Found a existing entry. Update the expire timer and
13698 * last usage timestamps.
13700 zmgr->unreachable[i].expire = seconds + UNREACH_HOLD_TIME;
13701 zmgr->unreachable[i].last = seconds;
13702 if (zmgr->unreachable[i].expire < seconds)
13703 zmgr->unreachable[i].count = 1;
13705 zmgr->unreachable[i].count++;
13706 } else if (slot != UNREACH_CHACHE_SIZE) {
13708 * Found a empty slot. Add a new entry to the cache.
13710 zmgr->unreachable[slot].expire = seconds + UNREACH_HOLD_TIME;
13711 zmgr->unreachable[slot].last = seconds;
13712 zmgr->unreachable[slot].remote = *remote;
13713 zmgr->unreachable[slot].local = *local;
13714 zmgr->unreachable[slot].count = 1;
13717 * Replace the least recently used entry in the cache.
13719 zmgr->unreachable[oldest].expire = seconds + UNREACH_HOLD_TIME;
13720 zmgr->unreachable[oldest].last = seconds;
13721 zmgr->unreachable[oldest].remote = *remote;
13722 zmgr->unreachable[oldest].local = *local;
13723 zmgr->unreachable[oldest].count = 1;
13725 RWUNLOCK(&zmgr->urlock, isc_rwlocktype_write);
13729 dns_zone_forcereload(dns_zone_t *zone) {
13730 REQUIRE(DNS_ZONE_VALID(zone));
13732 if (zone->type == dns_zone_master)
13736 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_FORCEXFER);
13738 dns_zone_refresh(zone);
13742 dns_zone_isforced(dns_zone_t *zone) {
13743 REQUIRE(DNS_ZONE_VALID(zone));
13745 return (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_FORCEXFER));
13749 dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
13751 * This function is obsoleted.
13755 return (ISC_R_NOTIMPLEMENTED);
13759 dns_zone_getstatscounters(dns_zone_t *zone) {
13761 * This function is obsoleted.
13768 dns_zone_setstats(dns_zone_t *zone, isc_stats_t *stats) {
13769 REQUIRE(DNS_ZONE_VALID(zone));
13770 REQUIRE(zone->stats == NULL);
13773 zone->stats = NULL;
13774 isc_stats_attach(stats, &zone->stats);
13779 dns_zone_setrequeststats(dns_zone_t *zone, isc_stats_t *stats) {
13780 REQUIRE(DNS_ZONE_VALID(zone));
13783 if (zone->requeststats_on && stats == NULL)
13784 zone->requeststats_on = ISC_FALSE;
13785 else if (!zone->requeststats_on && stats != NULL) {
13786 if (zone->requeststats == NULL) {
13787 isc_stats_attach(stats, &zone->requeststats);
13788 zone->requeststats_on = ISC_TRUE;
13797 dns_zone_getrequeststats(dns_zone_t *zone) {
13799 * We don't lock zone for efficiency reason. This is not catastrophic
13800 * because requeststats must always be valid when requeststats_on is
13802 * Some counters may be incremented while requeststats_on is becoming
13803 * false, or some cannot be incremented just after the statistics are
13804 * installed, but it shouldn't matter much in practice.
13806 if (zone->requeststats_on)
13807 return (zone->requeststats);
13813 dns_zone_dialup(dns_zone_t *zone) {
13815 REQUIRE(DNS_ZONE_VALID(zone));
13817 zone_debuglog(zone, "dns_zone_dialup", 3,
13818 "notify = %d, refresh = %d",
13819 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY),
13820 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH));
13822 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALNOTIFY))
13823 dns_zone_notify(zone);
13824 if (zone->type != dns_zone_master &&
13825 DNS_ZONE_FLAG(zone, DNS_ZONEFLG_DIALREFRESH))
13826 dns_zone_refresh(zone);
13830 dns_zone_setdialup(dns_zone_t *zone, dns_dialuptype_t dialup) {
13831 REQUIRE(DNS_ZONE_VALID(zone));
13834 DNS_ZONE_CLRFLAG(zone, DNS_ZONEFLG_DIALNOTIFY |
13835 DNS_ZONEFLG_DIALREFRESH |
13836 DNS_ZONEFLG_NOREFRESH);
13838 case dns_dialuptype_no:
13840 case dns_dialuptype_yes:
13841 DNS_ZONE_SETFLAG(zone, (DNS_ZONEFLG_DIALNOTIFY |
13842 DNS_ZONEFLG_DIALREFRESH |
13843 DNS_ZONEFLG_NOREFRESH));
13845 case dns_dialuptype_notify:
13846 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13848 case dns_dialuptype_notifypassive:
13849 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALNOTIFY);
13850 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13852 case dns_dialuptype_refresh:
13853 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_DIALREFRESH);
13854 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13856 case dns_dialuptype_passive:
13857 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NOREFRESH);
13866 dns_zone_setkeydirectory(dns_zone_t *zone, const char *directory) {
13867 isc_result_t result = ISC_R_SUCCESS;
13869 REQUIRE(DNS_ZONE_VALID(zone));
13872 result = dns_zone_setstring(zone, &zone->keydirectory, directory);
13879 dns_zone_getkeydirectory(dns_zone_t *zone) {
13880 REQUIRE(DNS_ZONE_VALID(zone));
13882 return (zone->keydirectory);
13886 dns_zonemgr_getcount(dns_zonemgr_t *zmgr, int state) {
13888 unsigned int count = 0;
13890 REQUIRE(DNS_ZONEMGR_VALID(zmgr));
13892 RWLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13894 case DNS_ZONESTATE_XFERRUNNING:
13895 for (zone = ISC_LIST_HEAD(zmgr->xfrin_in_progress);
13897 zone = ISC_LIST_NEXT(zone, statelink))
13900 case DNS_ZONESTATE_XFERDEFERRED:
13901 for (zone = ISC_LIST_HEAD(zmgr->waiting_for_xfrin);
13903 zone = ISC_LIST_NEXT(zone, statelink))
13906 case DNS_ZONESTATE_SOAQUERY:
13907 for (zone = ISC_LIST_HEAD(zmgr->zones);
13909 zone = ISC_LIST_NEXT(zone, link))
13910 if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_REFRESH))
13913 case DNS_ZONESTATE_ANY:
13914 for (zone = ISC_LIST_HEAD(zmgr->zones);
13916 zone = ISC_LIST_NEXT(zone, link)) {
13917 dns_view_t *view = zone->view;
13918 if (view != NULL && strcmp(view->name, "_bind") == 0)
13927 RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_read);
13933 dns_zone_checknames(dns_zone_t *zone, dns_name_t *name, dns_rdata_t *rdata) {
13934 isc_boolean_t ok = ISC_TRUE;
13935 isc_boolean_t fail = ISC_FALSE;
13936 char namebuf[DNS_NAME_FORMATSIZE];
13937 char namebuf2[DNS_NAME_FORMATSIZE];
13938 char typebuf[DNS_RDATATYPE_FORMATSIZE];
13939 int level = ISC_LOG_WARNING;
13942 REQUIRE(DNS_ZONE_VALID(zone));
13944 if (!DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMES))
13945 return (ISC_R_SUCCESS);
13947 if (DNS_ZONE_OPTION(zone, DNS_ZONEOPT_CHECKNAMESFAIL)) {
13948 level = ISC_LOG_ERROR;
13952 ok = dns_rdata_checkowner(name, rdata->rdclass, rdata->type, ISC_TRUE);
13954 dns_name_format(name, namebuf, sizeof(namebuf));
13955 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13956 dns_zone_log(zone, level, "%s/%s: %s", namebuf, typebuf,
13957 dns_result_totext(DNS_R_BADOWNERNAME));
13959 return (DNS_R_BADOWNERNAME);
13962 dns_name_init(&bad, NULL);
13963 ok = dns_rdata_checknames(rdata, name, &bad);
13965 dns_name_format(name, namebuf, sizeof(namebuf));
13966 dns_name_format(&bad, namebuf2, sizeof(namebuf2));
13967 dns_rdatatype_format(rdata->type, typebuf, sizeof(typebuf));
13968 dns_zone_log(zone, level, "%s/%s: %s: %s ", namebuf, typebuf,
13969 namebuf2, dns_result_totext(DNS_R_BADNAME));
13971 return (DNS_R_BADNAME);
13974 return (ISC_R_SUCCESS);
13978 dns_zone_setcheckmx(dns_zone_t *zone, dns_checkmxfunc_t checkmx) {
13979 REQUIRE(DNS_ZONE_VALID(zone));
13980 zone->checkmx = checkmx;
13984 dns_zone_setchecksrv(dns_zone_t *zone, dns_checksrvfunc_t checksrv) {
13985 REQUIRE(DNS_ZONE_VALID(zone));
13986 zone->checksrv = checksrv;
13990 dns_zone_setcheckns(dns_zone_t *zone, dns_checknsfunc_t checkns) {
13991 REQUIRE(DNS_ZONE_VALID(zone));
13992 zone->checkns = checkns;
13996 dns_zone_setisself(dns_zone_t *zone, dns_isselffunc_t isself, void *arg) {
13997 REQUIRE(DNS_ZONE_VALID(zone));
14000 zone->isself = isself;
14001 zone->isselfarg = arg;
14006 dns_zone_setnotifydelay(dns_zone_t *zone, isc_uint32_t delay) {
14007 REQUIRE(DNS_ZONE_VALID(zone));
14010 zone->notifydelay = delay;
14015 dns_zone_getnotifydelay(dns_zone_t *zone) {
14016 REQUIRE(DNS_ZONE_VALID(zone));
14018 return (zone->notifydelay);
14022 dns_zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm,
14023 isc_uint16_t keyid, isc_boolean_t delete)
14025 isc_result_t result;
14026 REQUIRE(DNS_ZONE_VALID(zone));
14028 dns_zone_log(zone, ISC_LOG_NOTICE,
14029 "dns_zone_signwithkey(algorithm=%u, keyid=%u)",
14032 result = zone_signwithkey(zone, algorithm, keyid, delete);
14038 static const char *hex = "0123456789ABCDEF";
14041 dns_zone_addnsec3chain(dns_zone_t *zone, dns_rdata_nsec3param_t *nsec3param) {
14042 isc_result_t result;
14043 char salt[255*2+1];
14046 REQUIRE(DNS_ZONE_VALID(zone));
14048 if (nsec3param->salt_length != 0) {
14049 INSIST((nsec3param->salt_length * 2U) < sizeof(salt));
14050 for (i = 0, j = 0; i < nsec3param->salt_length; i++) {
14051 salt[j++] = hex[(nsec3param->salt[i] >> 4) & 0xf];
14052 salt[j++] = hex[nsec3param->salt[i] & 0xf];
14057 dns_zone_log(zone, ISC_LOG_NOTICE,
14058 "dns_zone_addnsec3chain(hash=%u, iterations=%u, salt=%s)",
14059 nsec3param->hash, nsec3param->iterations,
14062 result = zone_addnsec3chain(zone, nsec3param);
14069 dns_zone_setnodes(dns_zone_t *zone, isc_uint32_t nodes) {
14070 REQUIRE(DNS_ZONE_VALID(zone));
14074 zone->nodes = nodes;
14078 dns_zone_setsignatures(dns_zone_t *zone, isc_uint32_t signatures) {
14079 REQUIRE(DNS_ZONE_VALID(zone));
14082 * We treat signatures as a signed value so explicitly
14083 * limit its range here.
14085 if (signatures > ISC_INT32_MAX)
14086 signatures = ISC_INT32_MAX;
14087 else if (signatures == 0)
14089 zone->signatures = signatures;
14093 dns_zone_setprivatetype(dns_zone_t *zone, dns_rdatatype_t type) {
14094 REQUIRE(DNS_ZONE_VALID(zone));
14095 zone->privatetype = type;
14099 dns_zone_getprivatetype(dns_zone_t *zone) {
14100 REQUIRE(DNS_ZONE_VALID(zone));
14101 return (zone->privatetype);
14104 static isc_result_t
14105 zone_signwithkey(dns_zone_t *zone, dns_secalg_t algorithm, isc_uint16_t keyid,
14106 isc_boolean_t delete)
14108 dns_signing_t *signing;
14109 dns_signing_t *current;
14110 isc_result_t result = ISC_R_SUCCESS;
14113 signing = isc_mem_get(zone->mctx, sizeof *signing);
14114 if (signing == NULL)
14115 return (ISC_R_NOMEMORY);
14117 signing->magic = 0;
14118 signing->db = NULL;
14119 signing->dbiterator = NULL;
14120 signing->algorithm = algorithm;
14121 signing->keyid = keyid;
14122 signing->delete = delete;
14123 signing->done = ISC_FALSE;
14127 for (current = ISC_LIST_HEAD(zone->signing);
14129 current = ISC_LIST_NEXT(current, link)) {
14130 if (current->db == zone->db &&
14131 current->algorithm == signing->algorithm &&
14132 current->keyid == signing->keyid) {
14133 if (current->delete != signing->delete)
14134 current->done = ISC_TRUE;
14140 if (zone->db != NULL) {
14141 dns_db_attach(zone->db, &signing->db);
14142 result = dns_db_createiterator(signing->db, 0,
14143 &signing->dbiterator);
14145 if (result == ISC_R_SUCCESS)
14146 result = dns_dbiterator_first(signing->dbiterator);
14147 if (result == ISC_R_SUCCESS) {
14148 dns_dbiterator_pause(signing->dbiterator);
14149 ISC_LIST_INITANDAPPEND(zone->signing, signing, link);
14151 if (isc_time_isepoch(&zone->signingtime)) {
14152 zone->signingtime = now;
14153 if (zone->task != NULL)
14154 zone_settimer(zone, &now);
14158 result = ISC_R_NOTFOUND;
14161 if (signing != NULL) {
14162 if (signing->db != NULL)
14163 dns_db_detach(&signing->db);
14164 if (signing->dbiterator != NULL)
14165 dns_dbiterator_destroy(&signing->dbiterator);
14166 isc_mem_put(zone->mctx, signing, sizeof *signing);
14172 logmsg(const char *format, ...) {
14174 va_start(args, format);
14175 isc_log_vwrite(dns_lctx, DNS_LOGCATEGORY_GENERAL, DNS_LOGMODULE_ZONE,
14176 ISC_LOG_DEBUG(1), format, args);
14181 clear_keylist(dns_dnsseckeylist_t *list, isc_mem_t *mctx) {
14182 dns_dnsseckey_t *key;
14183 while (!ISC_LIST_EMPTY(*list)) {
14184 key = ISC_LIST_HEAD(*list);
14185 ISC_LIST_UNLINK(*list, key, link);
14186 dns_dnsseckey_destroy(mctx, &key);
14190 /* Called once; *timep should be set to the current time. */
14191 static isc_result_t
14192 next_keyevent(dst_key_t *key, isc_stdtime_t *timep) {
14193 isc_result_t result;
14194 isc_stdtime_t now, then = 0, event;
14199 for (i = 0; i <= DST_MAX_TIMES; i++) {
14200 result = dst_key_gettime(key, i, &event);
14201 if (result == ISC_R_SUCCESS && event > now &&
14202 (then == 0 || event < then))
14208 return (ISC_R_SUCCESS);
14211 return (ISC_R_NOTFOUND);
14214 static isc_result_t
14215 rr_exists(dns_db_t *db, dns_dbversion_t *ver, dns_name_t *name,
14216 const dns_rdata_t *rdata, isc_boolean_t *flag)
14218 dns_rdataset_t rdataset;
14219 dns_dbnode_t *node = NULL;
14220 isc_result_t result;
14222 dns_rdataset_init(&rdataset);
14223 if (rdata->type == dns_rdatatype_nsec3)
14224 CHECK(dns_db_findnsec3node(db, name, ISC_FALSE, &node));
14226 CHECK(dns_db_findnode(db, name, ISC_FALSE, &node));
14227 result = dns_db_findrdataset(db, node, ver, rdata->type, 0,
14228 (isc_stdtime_t) 0, &rdataset, NULL);
14229 if (result == ISC_R_NOTFOUND) {
14231 result = ISC_R_SUCCESS;
14235 for (result = dns_rdataset_first(&rdataset);
14236 result == ISC_R_SUCCESS;
14237 result = dns_rdataset_next(&rdataset)) {
14238 dns_rdata_t myrdata = DNS_RDATA_INIT;
14239 dns_rdataset_current(&rdataset, &myrdata);
14240 if (!dns_rdata_compare(&myrdata, rdata))
14243 dns_rdataset_disassociate(&rdataset);
14244 if (result == ISC_R_SUCCESS) {
14246 } else if (result == ISC_R_NOMORE) {
14248 result = ISC_R_SUCCESS;
14253 dns_db_detachnode(db, &node);
14258 * Add records to signal the state of signing or of key removal.
14260 static isc_result_t
14261 add_signing_records(dns_db_t *db, dns_rdatatype_t privatetype,
14262 dns_dbversion_t *ver, dns_diff_t *diff,
14263 isc_boolean_t sign_all)
14265 dns_difftuple_t *tuple, *newtuple = NULL;
14266 dns_rdata_dnskey_t dnskey;
14267 dns_rdata_t rdata = DNS_RDATA_INIT;
14268 isc_boolean_t flag;
14270 isc_result_t result = ISC_R_SUCCESS;
14271 isc_uint16_t keyid;
14272 unsigned char buf[5];
14273 dns_name_t *name = dns_db_origin(db);
14275 for (tuple = ISC_LIST_HEAD(diff->tuples);
14277 tuple = ISC_LIST_NEXT(tuple, link)) {
14278 if (tuple->rdata.type != dns_rdatatype_dnskey)
14281 result = dns_rdata_tostruct(&tuple->rdata, &dnskey, NULL);
14282 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14283 if ((dnskey.flags &
14284 (DNS_KEYFLAG_OWNERMASK|DNS_KEYTYPE_NOAUTH))
14285 != DNS_KEYOWNER_ZONE)
14288 dns_rdata_toregion(&tuple->rdata, &r);
14290 keyid = dst_region_computeid(&r, dnskey.algorithm);
14292 buf[0] = dnskey.algorithm;
14293 buf[1] = (keyid & 0xff00) >> 8;
14294 buf[2] = (keyid & 0xff);
14295 buf[3] = (tuple->op == DNS_DIFFOP_ADD) ? 0 : 1;
14298 rdata.length = sizeof(buf);
14299 rdata.type = privatetype;
14300 rdata.rdclass = tuple->rdata.rdclass;
14302 if (sign_all || tuple->op == DNS_DIFFOP_DEL) {
14303 CHECK(rr_exists(db, ver, name, &rdata, &flag));
14306 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_ADD,
14307 name, 0, &rdata, &newtuple));
14308 CHECK(do_one_tuple(&newtuple, db, ver, diff));
14309 INSIST(newtuple == NULL);
14313 * Remove any record which says this operation has already
14317 CHECK(rr_exists(db, ver, name, &rdata, &flag));
14319 CHECK(dns_difftuple_create(diff->mctx, DNS_DIFFOP_DEL,
14320 name, 0, &rdata, &newtuple));
14321 CHECK(do_one_tuple(&newtuple, db, ver, diff));
14322 INSIST(newtuple == NULL);
14329 static isc_result_t
14330 sign_apex(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14331 dns_diff_t *diff, zonediff_t *zonediff)
14333 isc_result_t result;
14334 isc_stdtime_t now, inception, soaexpire;
14335 isc_boolean_t check_ksk, keyset_kskonly;
14336 dst_key_t *zone_keys[DNS_MAXZONEKEYS];
14337 unsigned int nkeys = 0, i;
14338 dns_difftuple_t *tuple;
14340 result = find_zone_keys(zone, db, ver, zone->mctx, DNS_MAXZONEKEYS,
14341 zone_keys, &nkeys);
14342 if (result != ISC_R_SUCCESS) {
14343 dns_zone_log(zone, ISC_LOG_ERROR,
14344 "sign_apex:find_zone_keys -> %s",
14345 dns_result_totext(result));
14349 isc_stdtime_get(&now);
14350 inception = now - 3600; /* Allow for clock skew. */
14351 soaexpire = now + dns_zone_getsigvalidityinterval(zone);
14353 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14354 keyset_kskonly = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_DNSKEYKSKONLY);
14357 * See if update_sigs will update DNSKEY signature and if not
14358 * cause them to sign so that so that newly activated keys
14361 for (tuple = ISC_LIST_HEAD(diff->tuples);
14363 tuple = ISC_LIST_NEXT(tuple, link)) {
14364 if (tuple->rdata.type == dns_rdatatype_dnskey &&
14365 dns_name_equal(&tuple->name, &zone->origin))
14369 if (tuple == NULL) {
14370 result = del_sigs(zone, db, ver, &zone->origin,
14371 dns_rdatatype_dnskey, zonediff,
14372 zone_keys, nkeys, now, ISC_FALSE);
14373 if (result != ISC_R_SUCCESS) {
14374 dns_zone_log(zone, ISC_LOG_ERROR,
14375 "sign_apex:del_sigs -> %s",
14376 dns_result_totext(result));
14379 result = add_sigs(db, ver, &zone->origin, dns_rdatatype_dnskey,
14380 zonediff->diff, zone_keys, nkeys, zone->mctx,
14381 inception, soaexpire, check_ksk,
14383 if (result != ISC_R_SUCCESS) {
14384 dns_zone_log(zone, ISC_LOG_ERROR,
14385 "sign_apex:add_sigs -> %s",
14386 dns_result_totext(result));
14391 result = update_sigs(diff, db, ver, zone_keys, nkeys, zone,
14392 inception, soaexpire, now, check_ksk,
14393 keyset_kskonly, zonediff);
14395 if (result != ISC_R_SUCCESS) {
14396 dns_zone_log(zone, ISC_LOG_ERROR,
14397 "sign_apex:update_sigs -> %s",
14398 dns_result_totext(result));
14403 for (i = 0; i < nkeys; i++)
14404 dst_key_free(&zone_keys[i]);
14409 * Prevent the zone entering a inconsistent state where
14410 * NSEC only DNSKEYs are present with NSEC3 chains.
14411 * See update.c:check_dnssec()
14413 static isc_boolean_t
14414 dnskey_sane(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14417 isc_result_t result;
14418 dns_difftuple_t *tuple;
14419 isc_boolean_t nseconly = ISC_FALSE, nsec3 = ISC_FALSE;
14420 dns_rdatatype_t privatetype = dns_zone_getprivatetype(zone);
14422 /* Scan the tuples for an NSEC-only DNSKEY */
14423 for (tuple = ISC_LIST_HEAD(diff->tuples);
14425 tuple = ISC_LIST_NEXT(tuple, link)) {
14427 if (tuple->rdata.type != dns_rdatatype_dnskey ||
14428 tuple->op != DNS_DIFFOP_ADD)
14431 alg = tuple->rdata.data[3];
14432 if (alg == DST_ALG_RSAMD5 || alg == DST_ALG_RSASHA1 ||
14433 alg == DST_ALG_DSA || alg == DST_ALG_ECC) {
14434 nseconly = ISC_TRUE;
14439 /* Check existing DB for NSEC-only DNSKEY */
14441 CHECK(dns_nsec_nseconly(db, ver, &nseconly));
14443 /* Check existing DB for NSEC3 */
14445 CHECK(dns_nsec3_activex(db, ver, ISC_FALSE,
14446 privatetype, &nsec3));
14448 /* Refuse to allow NSEC3 with NSEC-only keys */
14449 if (nseconly && nsec3) {
14450 dns_zone_log(zone, ISC_LOG_ERROR,
14451 "NSEC only DNSKEYs and NSEC3 chains not allowed");
14458 return (ISC_FALSE);
14461 static isc_result_t
14462 clean_nsec3param(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14465 isc_result_t result;
14466 dns_dbnode_t *node = NULL;
14467 dns_rdataset_t rdataset;
14469 dns_rdataset_init(&rdataset);
14470 CHECK(dns_db_getoriginnode(db, &node));
14472 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14473 dns_rdatatype_none, 0, &rdataset, NULL);
14474 if (dns_rdataset_isassociated(&rdataset))
14475 dns_rdataset_disassociate(&rdataset);
14476 if (result != ISC_R_NOTFOUND)
14479 result = dns_nsec3param_deletechains(db, ver, zone, diff);
14483 dns_db_detachnode(db, &node);
14488 * Given an RRSIG rdataset and an algorithm, determine whether there
14489 * are any signatures using that algorithm.
14491 static isc_boolean_t
14492 signed_with_alg(dns_rdataset_t *rdataset, dns_secalg_t alg) {
14493 dns_rdata_t rdata = DNS_RDATA_INIT;
14494 dns_rdata_rrsig_t rrsig;
14495 isc_result_t result;
14497 REQUIRE(rdataset == NULL || rdataset->type == dns_rdatatype_rrsig);
14498 if (rdataset == NULL || !dns_rdataset_isassociated(rdataset)) {
14499 return (ISC_FALSE);
14502 for (result = dns_rdataset_first(rdataset);
14503 result == ISC_R_SUCCESS;
14504 result = dns_rdataset_next(rdataset))
14506 dns_rdataset_current(rdataset, &rdata);
14507 result = dns_rdata_tostruct(&rdata, &rrsig, NULL);
14508 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14509 dns_rdata_reset(&rdata);
14510 if (rrsig.algorithm == alg)
14514 return (ISC_FALSE);
14517 static isc_result_t
14518 add_chains(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *ver,
14521 dns_name_t *origin;
14522 isc_boolean_t build_nsec3;
14523 isc_result_t result;
14525 origin = dns_db_origin(db);
14526 CHECK(dns_private_chains(db, ver, zone->privatetype, NULL,
14529 CHECK(dns_nsec3_addnsec3sx(db, ver, origin, zone->minimum,
14530 ISC_FALSE, zone->privatetype, diff));
14531 CHECK(updatesecure(db, ver, origin, zone->minimum, ISC_TRUE, diff));
14538 zone_rekey(dns_zone_t *zone) {
14539 isc_result_t result;
14540 dns_db_t *db = NULL;
14541 dns_dbnode_t *node = NULL;
14542 dns_dbversion_t *ver = NULL;
14543 dns_rdataset_t soaset, soasigs, keyset, keysigs;
14544 dns_dnsseckeylist_t dnskeys, keys, rmkeys;
14545 dns_dnsseckey_t *key;
14546 dns_diff_t diff, _sig_diff;
14547 zonediff_t zonediff;
14548 isc_boolean_t commit = ISC_FALSE, newactive = ISC_FALSE;
14549 isc_boolean_t newalg = ISC_FALSE;
14550 isc_boolean_t fullsign;
14551 dns_ttl_t ttl = 3600;
14555 isc_time_t timenow;
14556 isc_interval_t ival;
14559 REQUIRE(DNS_ZONE_VALID(zone));
14561 ISC_LIST_INIT(dnskeys);
14562 ISC_LIST_INIT(keys);
14563 ISC_LIST_INIT(rmkeys);
14564 dns_rdataset_init(&soaset);
14565 dns_rdataset_init(&soasigs);
14566 dns_rdataset_init(&keyset);
14567 dns_rdataset_init(&keysigs);
14568 dir = dns_zone_getkeydirectory(zone);
14570 dns_diff_init(mctx, &diff);
14571 dns_diff_init(mctx, &_sig_diff);
14572 zonediff_init(&zonediff, &_sig_diff);
14574 CHECK(dns_zone_getdb(zone, &db));
14575 CHECK(dns_db_newversion(db, &ver));
14576 CHECK(dns_db_getoriginnode(db, &node));
14578 TIME_NOW(&timenow);
14579 now = isc_time_seconds(&timenow);
14581 dns_zone_log(zone, ISC_LOG_INFO, "reconfiguring zone keys");
14583 /* Get the SOA record's TTL */
14584 CHECK(dns_db_findrdataset(db, node, ver, dns_rdatatype_soa,
14585 dns_rdatatype_none, 0, &soaset, &soasigs));
14587 dns_rdataset_disassociate(&soaset);
14589 /* Get the DNSKEY rdataset */
14590 result = dns_db_findrdataset(db, node, ver, dns_rdatatype_dnskey,
14591 dns_rdatatype_none, 0, &keyset, &keysigs);
14592 if (result == ISC_R_SUCCESS) {
14594 result = dns_dnssec_keylistfromrdataset(&zone->origin, dir,
14596 &keysigs, &soasigs,
14597 ISC_FALSE, ISC_FALSE,
14599 /* Can't get keys for some reason; try again later. */
14600 if (result != ISC_R_SUCCESS)
14602 } else if (result != ISC_R_NOTFOUND)
14606 * True when called from "rndc sign". Indicates the zone should be
14607 * fully signed now.
14609 fullsign = ISC_TF(DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_FULLSIGN) != 0);
14611 result = dns_dnssec_findmatchingkeys(&zone->origin, dir, mctx, &keys);
14612 if (result == ISC_R_SUCCESS) {
14613 isc_boolean_t check_ksk;
14614 check_ksk = DNS_ZONE_OPTION(zone, DNS_ZONEOPT_UPDATECHECKKSK);
14616 result = dns_dnssec_updatekeys(&dnskeys, &keys, &rmkeys,
14617 &zone->origin, ttl, &diff,
14618 ISC_TF(!check_ksk),
14621 /* Keys couldn't be updated for some reason;
14622 * try again later. */
14623 if (result != ISC_R_SUCCESS) {
14624 dns_zone_log(zone, ISC_LOG_ERROR, "zone_rekey:"
14625 "couldn't update zone keys: %s",
14626 isc_result_totext(result));
14631 * See if any pre-existing keys have newly become active;
14632 * also, see if any new key is for a new algorithm, as in that
14633 * event, we need to sign the zone fully. (If there's a new
14634 * key, but it's for an already-existing algorithm, then
14635 * the zone signing can be handled incrementally.)
14637 for (key = ISC_LIST_HEAD(dnskeys);
14639 key = ISC_LIST_NEXT(key, link)) {
14640 if (!key->first_sign)
14643 newactive = ISC_TRUE;
14645 if (!dns_rdataset_isassociated(&keysigs)) {
14650 if (signed_with_alg(&keysigs, dst_key_alg(key->key))) {
14652 * This isn't a new algorithm; clear
14653 * first_sign so we won't sign the
14654 * whole zone with this key later
14656 key->first_sign = ISC_FALSE;
14663 if ((newactive || fullsign || !ISC_LIST_EMPTY(diff.tuples)) &&
14664 dnskey_sane(zone, db, ver, &diff)) {
14665 CHECK(dns_diff_apply(&diff, db, ver));
14666 CHECK(clean_nsec3param(zone, db, ver, &diff));
14667 CHECK(add_signing_records(db, zone->privatetype,
14669 ISC_TF(newalg || fullsign)));
14670 CHECK(increment_soa_serial(db, ver, &diff, mctx));
14671 CHECK(add_chains(zone, db, ver, &diff));
14672 CHECK(sign_apex(zone, db, ver, &diff, &zonediff));
14673 CHECK(zone_journal(zone, zonediff.diff, "zone_rekey"));
14678 dns_db_closeversion(db, &ver, commit);
14681 dns_difftuple_t *tuple;
14684 DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_NEEDNOTIFY);
14686 zone_needdump(zone, DNS_DUMP_DELAY);
14688 zone_settimer(zone, &timenow);
14690 /* Remove any signatures from removed keys. */
14691 if (!ISC_LIST_EMPTY(rmkeys)) {
14692 for (key = ISC_LIST_HEAD(rmkeys);
14694 key = ISC_LIST_NEXT(key, link)) {
14695 result = zone_signwithkey(zone,
14696 dst_key_alg(key->key),
14697 dst_key_id(key->key),
14699 if (result != ISC_R_SUCCESS) {
14700 dns_zone_log(zone, ISC_LOG_ERROR,
14701 "zone_signwithkey failed: %s",
14702 dns_result_totext(result));
14709 * "rndc sign" was called, so we now sign the zone
14710 * with all active keys, whether they're new or not.
14712 for (key = ISC_LIST_HEAD(dnskeys);
14714 key = ISC_LIST_NEXT(key, link)) {
14715 if (!key->force_sign && !key->hint_sign)
14718 result = zone_signwithkey(zone,
14719 dst_key_alg(key->key),
14720 dst_key_id(key->key),
14722 if (result != ISC_R_SUCCESS) {
14723 dns_zone_log(zone, ISC_LOG_ERROR,
14724 "zone_signwithkey failed: %s",
14725 dns_result_totext(result));
14728 } else if (newalg) {
14730 * We haven't been told to sign fully, but a new
14731 * algorithm was added to the DNSKEY. We sign
14732 * the full zone, but only with newly active
14735 for (key = ISC_LIST_HEAD(dnskeys);
14737 key = ISC_LIST_NEXT(key, link)) {
14738 if (!key->first_sign)
14741 result = zone_signwithkey(zone,
14742 dst_key_alg(key->key),
14743 dst_key_id(key->key),
14745 if (result != ISC_R_SUCCESS) {
14746 dns_zone_log(zone, ISC_LOG_ERROR,
14747 "zone_signwithkey failed: %s",
14748 dns_result_totext(result));
14754 * Clear fullsign flag, if it was set, so we don't do
14755 * another full signing next time
14757 zone->keyopts &= ~DNS_ZONEKEY_FULLSIGN;
14760 * Cause the zone to add/delete NSEC3 chains for the
14761 * deferred NSEC3PARAM changes.
14763 for (tuple = ISC_LIST_HEAD(zonediff.diff->tuples);
14765 tuple = ISC_LIST_NEXT(tuple, link)) {
14766 unsigned char buf[DNS_NSEC3PARAM_BUFFERSIZE];
14767 dns_rdata_t rdata = DNS_RDATA_INIT;
14768 dns_rdata_nsec3param_t nsec3param;
14770 if (tuple->rdata.type != zone->privatetype ||
14771 tuple->op != DNS_DIFFOP_ADD)
14774 if (!dns_nsec3param_fromprivate(&tuple->rdata, &rdata,
14777 result = dns_rdata_tostruct(&rdata, &nsec3param, NULL);
14778 RUNTIME_CHECK(result == ISC_R_SUCCESS);
14779 if (nsec3param.flags == 0)
14782 result = zone_addnsec3chain(zone, &nsec3param);
14783 if (result != ISC_R_SUCCESS) {
14784 dns_zone_log(zone, ISC_LOG_ERROR,
14785 "zone_addnsec3chain failed: %s",
14786 dns_result_totext(result));
14791 * Schedule the next resigning event
14793 set_resigntime(zone);
14797 isc_time_settoepoch(&zone->refreshkeytime);
14800 * If we're doing key maintenance, set the key refresh timer to
14801 * the next scheduled key event or to one hour in the future,
14802 * whichever is sooner.
14804 if (DNS_ZONEKEY_OPTION(zone, DNS_ZONEKEY_MAINTAIN)) {
14805 isc_time_t timethen;
14806 isc_stdtime_t then;
14809 DNS_ZONE_TIME_ADD(&timenow, HOUR, &timethen);
14810 zone->refreshkeytime = timethen;
14813 for (key = ISC_LIST_HEAD(dnskeys);
14815 key = ISC_LIST_NEXT(key, link)) {
14817 result = next_keyevent(key->key, &then);
14818 if (result != ISC_R_SUCCESS)
14821 DNS_ZONE_TIME_ADD(&timenow, then - now, &timethen);
14823 if (isc_time_compare(&timethen,
14824 &zone->refreshkeytime) < 0) {
14825 zone->refreshkeytime = timethen;
14830 zone_settimer(zone, &timenow);
14832 isc_time_formattimestamp(&zone->refreshkeytime, timebuf, 80);
14833 dns_zone_log(zone, ISC_LOG_INFO, "next key event: %s", timebuf);
14837 dns_diff_clear(&diff);
14838 dns_diff_clear(&_sig_diff);
14840 clear_keylist(&dnskeys, mctx);
14841 clear_keylist(&keys, mctx);
14842 clear_keylist(&rmkeys, mctx);
14845 dns_db_closeversion(db, &ver, ISC_FALSE);
14846 if (dns_rdataset_isassociated(&keyset))
14847 dns_rdataset_disassociate(&keyset);
14848 if (dns_rdataset_isassociated(&keysigs))
14849 dns_rdataset_disassociate(&keysigs);
14850 if (dns_rdataset_isassociated(&soasigs))
14851 dns_rdataset_disassociate(&soasigs);
14853 dns_db_detachnode(db, &node);
14855 dns_db_detach(&db);
14859 isc_interval_set(&ival, HOUR, 0);
14860 isc_time_nowplusinterval(&zone->refreshkeytime, &ival);
14865 dns_zone_rekey(dns_zone_t *zone, isc_boolean_t fullsign) {
14868 if (zone->type == dns_zone_master && zone->task != NULL) {
14872 zone->keyopts |= DNS_ZONEKEY_FULLSIGN;
14875 zone->refreshkeytime = now;
14876 zone_settimer(zone, &now);
14883 dns_zone_nscheck(dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
14884 unsigned int *errors)
14886 isc_result_t result;
14887 dns_dbnode_t *node = NULL;
14889 REQUIRE(DNS_ZONE_VALID(zone));
14890 REQUIRE(errors != NULL);
14892 result = dns_db_getoriginnode(db, &node);
14893 if (result != ISC_R_SUCCESS)
14895 result = zone_count_ns_rr(zone, db, node, version, NULL, errors,
14897 dns_db_detachnode(db, &node);
14902 dns_zone_setadded(dns_zone_t *zone, isc_boolean_t added) {
14903 REQUIRE(DNS_ZONE_VALID(zone));
14905 zone->added = added;
14910 dns_zone_getadded(dns_zone_t *zone) {
14911 REQUIRE(DNS_ZONE_VALID(zone));
14912 return (zone->added);
14916 dns_zone_dlzpostload(dns_zone_t *zone, dns_db_t *db)
14918 isc_time_t loadtime;
14919 isc_result_t result;
14920 TIME_NOW(&loadtime);
14923 result = zone_postload(zone, db, loadtime, ISC_R_SUCCESS);